Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull second set of media updates from Mauro Carvalho Chehab:
 "Despite its size, most of the stuff here is trivial.  This series
  contains:

   - s5p-mfc: additions at the driver and at the core to support H.264
     hardware codec;
   - Some improvements at s5p and davinci embedded drivers;
   - Some V4L2 compliance fixes applied on a few drivers;
   - Several random trivial patches, including several fixes and a few
     new board support additions;

  Notes:

   1) Some Exynos media patches were dependent on some -arm fixes that
      got merged on changeset 782cd9e.  That's why this pull request is
      based that changeset.

   2) As promised, I reviewed the pending VB2 DMABUF series.

      While setting a test environment, it was noticed that the upstream
      support for Samsung Exynos 4 boards (smdk310 and Origen) are
      broken upstream, likely due to regressions: both defconfigs are
      wrong and regulator settings for both boards are broken.  That,
      allied with some bug at the dummy regulator driver, causes OOPSes
      during boot time.

      Long story short: even fixing the above, the proposed patches
      OOPSed when running the DMABUF test.  Not sure yet if the OOPSes
      are due to some other undetected regressions, or due to some bug
      on the patches.

      Due to the above, DMABUF patches for vb2 got NACKed for 3.7."

* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (109 commits)
  [media] m5mols: Add missing #include <linux/sizes.h>
  [media] stk1160: Add support for S-Video input
  Revert "[media] omap3isp: Replace cpu_is_omap3630() with ISP revision check"
  [media]  dvb: LNA implementation changes
  [media] v4l2-ioctl: fix W=1 warnings
  [media] v4l2-ioctl: add blocks check for VIDIOC_SUBDEV_G/S_EDID
  [media] omap3isp: Fix compilation error in ispreg.h
  [media] rc-msi-digivox-ii: Add full scan keycodes
  [media] cx25821: testing the wrong variable
  [media] tda18271-common: hold the I2C adapter during write transfers
  [media] ds3000: add module parameter to force firmware upload
  [media] drivers/media: Remove unnecessary semicolon
  [media] winbond: remove space from driver name
  [media] iguanair: cannot send data from the stack
  [media] omap3isp: Replace cpu_is_omap3630() with ISP revision check
  [media] dvb-usb: print small buffers via %*ph
  [media] uvc: Add return code check at vb2_queue_init()
  [media] em28xx: Replace memcpy with struct assignment
  [media] bt8xx: Add video4linux control V4L2_CID_COLOR_KILLER
  [media] mem2mem_testdev: Use devm_kzalloc() in probe
  ...

Conflicts:
	arch/arm/mach-davinci/include/mach/da8xx.h
diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index 49c0513..f54273e 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -270,8 +270,6 @@
 	- info on locking under a preemptive kernel.
 printk-formats.txt
 	- how to get printk format specifiers right
-prio_tree.txt
-	- info on radix-priority-search-tree use for indexing vmas.
 ramoops.txt
 	- documentation of the ramoops oops/panic logging module.
 rbtree.txt
diff --git a/Documentation/ABI/obsolete/proc-pid-oom_adj b/Documentation/ABI/obsolete/proc-pid-oom_adj
deleted file mode 100644
index 9a3cb88..0000000
--- a/Documentation/ABI/obsolete/proc-pid-oom_adj
+++ /dev/null
@@ -1,22 +0,0 @@
-What:	/proc/<pid>/oom_adj
-When:	August 2012
-Why:	/proc/<pid>/oom_adj allows userspace to influence the oom killer's
-	badness heuristic used to determine which task to kill when the kernel
-	is out of memory.
-
-	The badness heuristic has since been rewritten since the introduction of
-	this tunable such that its meaning is deprecated.  The value was
-	implemented as a bitshift on a score generated by the badness()
-	function that did not have any precise units of measure.  With the
-	rewrite, the score is given as a proportion of available memory to the
-	task allocating pages, so using a bitshift which grows the score
-	exponentially is, thus, impossible to tune with fine granularity.
-
-	A much more powerful interface, /proc/<pid>/oom_score_adj, was
-	introduced with the oom killer rewrite that allows users to increase or
-	decrease the badness score linearly.  This interface will replace
-	/proc/<pid>/oom_adj.
-
-	A warning will be emitted to the kernel log if an application uses this
-	deprecated interface.  After it is printed once, future warnings will be
-	suppressed until the kernel is rebooted.
diff --git a/Documentation/ABI/testing/sysfs-block b/Documentation/ABI/testing/sysfs-block
index c1eb41c..279da08 100644
--- a/Documentation/ABI/testing/sysfs-block
+++ b/Documentation/ABI/testing/sysfs-block
@@ -206,3 +206,17 @@
 		when a discarded area is read the discard_zeroes_data
 		parameter will be set to one. Otherwise it will be 0 and
 		the result of reading a discarded area is undefined.
+
+What:		/sys/block/<disk>/queue/write_same_max_bytes
+Date:		January 2012
+Contact:	Martin K. Petersen <martin.petersen@oracle.com>
+Description:
+		Some devices support a write same operation in which a
+		single data block can be written to a range of several
+		contiguous blocks on storage. This can be used to wipe
+		areas on disk or to initialize drives in a RAID
+		configuration. write_same_max_bytes indicates how many
+		bytes can be written in a single write same command. If
+		write_same_max_bytes is 0, write same is not supported
+		by the device.
+
diff --git a/Documentation/ABI/testing/sysfs-bus-rbd b/Documentation/ABI/testing/sysfs-bus-rbd
index 3c17b62..1cf2adf 100644
--- a/Documentation/ABI/testing/sysfs-bus-rbd
+++ b/Documentation/ABI/testing/sysfs-bus-rbd
@@ -25,6 +25,10 @@
 
 	The ceph unique client id that was assigned for this specific session.
 
+features
+
+	A hexadecimal encoding of the feature bits for this image.
+
 major
 
 	The block device major number.
@@ -33,6 +37,11 @@
 
 	The name of the rbd image.
 
+image_id
+
+	The unique id for the rbd image.  (For rbd image format 1
+	this is empty.)
+
 pool
 
 	The name of the storage pool where this rbd image resides.
@@ -57,12 +66,6 @@
 
 	The current snapshot for which the device is mapped.
 
-create_snap
-
-	Create a snapshot:
-
-	 $ echo <snap-name> > /sys/bus/rbd/devices/<dev-id>/snap_create
-
 snap_*
 
 	A directory per each snapshot
@@ -79,4 +82,7 @@
 
 	The size of the image when this snapshot was taken.
 
+snap_features
+
+	A hexadecimal encoding of the feature bits for this snapshot.
 
diff --git a/Documentation/ABI/testing/sysfs-devices-firmware_node b/Documentation/ABI/testing/sysfs-devices-firmware_node
new file mode 100644
index 0000000..46badc9
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-devices-firmware_node
@@ -0,0 +1,17 @@
+What:		/sys/devices/.../firmware_node/
+Date:		September 2012
+Contact:	<>
+Description:
+		The /sys/devices/.../firmware_node directory contains attributes
+		allowing the user space to check and modify some firmware
+		related properties of given device.
+
+What:		/sys/devices/.../firmware_node/description
+Date:		September 2012
+Contact:	Lance Ortiz <lance.ortiz@hp.com>
+Description:
+		The /sys/devices/.../firmware/description attribute contains a string
+		that describes the device as provided by the _STR method in the ACPI
+		namespace.  This attribute is read-only.  If the device does not have
+		an _STR method associated with it in the ACPI namespace, this
+		attribute is not present.
diff --git a/Documentation/ABI/testing/sysfs-fs-ext4 b/Documentation/ABI/testing/sysfs-fs-ext4
index f22ac08..c631253 100644
--- a/Documentation/ABI/testing/sysfs-fs-ext4
+++ b/Documentation/ABI/testing/sysfs-fs-ext4
@@ -96,3 +96,16 @@
 Description:
 		The maximum number of megabytes the writeback code will
 		try to write out before move on to another inode.
+
+What:		/sys/fs/ext4/<disk>/extent_max_zeroout_kb
+Date:		August 2012
+Contact:	"Theodore Ts'o" <tytso@mit.edu>
+Description:
+		The maximum number of kilobytes which will be zeroed
+		out in preference to creating a new uninitialized
+		extent when manipulating an inode's extent tree.  Note
+		that using a larger value will increase the
+		variability of time necessary to complete a random
+		write operation (since a 4k random write might turn
+		into a much larger write due to the zeroout
+		operation).
diff --git a/Documentation/DocBook/mtdnand.tmpl b/Documentation/DocBook/mtdnand.tmpl
index e0aedb7..fe122d6 100644
--- a/Documentation/DocBook/mtdnand.tmpl
+++ b/Documentation/DocBook/mtdnand.tmpl
@@ -1216,8 +1216,6 @@
 #define	NAND_BBT_LASTBLOCK	0x00000010
 /* The bbt is at the given page, else we must scan for the bbt */
 #define NAND_BBT_ABSPAGE	0x00000020
-/* The bbt is at the given page, else we must scan for the bbt */
-#define NAND_BBT_SEARCH		0x00000040
 /* bbt is stored per chip on multichip devices */
 #define NAND_BBT_PERCHIP	0x00000080
 /* bbt has a version counter at offset veroffs */
diff --git a/Documentation/arm/Booting b/Documentation/arm/Booting
index a341d87..0c1f475 100644
--- a/Documentation/arm/Booting
+++ b/Documentation/arm/Booting
@@ -154,13 +154,33 @@
 
 - CPU mode
   All forms of interrupts must be disabled (IRQs and FIQs)
-  The CPU must be in SVC mode.  (A special exception exists for Angel)
+
+  For CPUs which do not include the ARM virtualization extensions, the
+  CPU must be in SVC mode.  (A special exception exists for Angel)
+
+  CPUs which include support for the virtualization extensions can be
+  entered in HYP mode in order to enable the kernel to make full use of
+  these extensions.  This is the recommended boot method for such CPUs,
+  unless the virtualisations are already in use by a pre-installed
+  hypervisor.
+
+  If the kernel is not entered in HYP mode for any reason, it must be
+  entered in SVC mode.
 
 - Caches, MMUs
   The MMU must be off.
   Instruction cache may be on or off.
   Data cache must be off.
 
+  If the kernel is entered in HYP mode, the above requirements apply to
+  the HYP mode configuration in addition to the ordinary PL1 (privileged
+  kernel modes) configuration.  In addition, all traps into the
+  hypervisor must be disabled, and PL1 access must be granted for all
+  peripherals and CPU resources for which this is architecturally
+  possible.  Except for entering in HYP mode, the system configuration
+  should be such that a kernel which does not include support for the
+  virtualization extensions can boot correctly without extra help.
+
 - The boot loader is expected to call the kernel image by jumping
   directly to the first instruction of the kernel image.
 
diff --git a/Documentation/block/biodoc.txt b/Documentation/block/biodoc.txt
index e418dc0..8df5e8e 100644
--- a/Documentation/block/biodoc.txt
+++ b/Documentation/block/biodoc.txt
@@ -465,7 +465,6 @@
        bio_end_io_t	*bi_end_io;  /* bi_end_io (bio) */
        atomic_t		bi_cnt;	     /* pin count: free when it hits zero */
        void             *bi_private;
-       bio_destructor_t *bi_destructor; /* bi_destructor (bio) */
 };
 
 With this multipage bio design:
@@ -647,10 +646,6 @@
 so bio_alloc(gfp_mask, nr_iovecs) will allocate a vec_list of the
 given size from these slabs.
 
-The bi_destructor() routine takes into account the possibility of the bio
-having originated from a different source (see later discussions on
-n/w to block transfers and kvec_cb)
-
 The bio_get() routine may be used to hold an extra reference on a bio prior
 to i/o submission, if the bio fields are likely to be accessed after the
 i/o is issued (since the bio may otherwise get freed in case i/o completion
diff --git a/Documentation/cgroups/memory.txt b/Documentation/cgroups/memory.txt
index 4372e6b..c07f7b4 100644
--- a/Documentation/cgroups/memory.txt
+++ b/Documentation/cgroups/memory.txt
@@ -18,16 +18,16 @@
 uses of the memory controller. The memory controller can be used to
 
 a. Isolate an application or a group of applications
-   Memory hungry applications can be isolated and limited to a smaller
+   Memory-hungry applications can be isolated and limited to a smaller
    amount of memory.
-b. Create a cgroup with limited amount of memory, this can be used
+b. Create a cgroup with a limited amount of memory; this can be used
    as a good alternative to booting with mem=XXXX.
 c. Virtualization solutions can control the amount of memory they want
    to assign to a virtual machine instance.
 d. A CD/DVD burner could control the amount of memory used by the
    rest of the system to ensure that burning does not fail due to lack
    of available memory.
-e. There are several other use cases, find one or use the controller just
+e. There are several other use cases; find one or use the controller just
    for fun (to learn and hack on the VM subsystem).
 
 Current Status: linux-2.6.34-mmotm(development version of 2010/April)
@@ -38,12 +38,12 @@
  - optionally, memory+swap usage can be accounted and limited.
  - hierarchical accounting
  - soft limit
- - moving(recharging) account at moving a task is selectable.
+ - moving (recharging) account at moving a task is selectable.
  - usage threshold notifier
  - oom-killer disable knob and oom-notifier
  - Root cgroup has no limit controls.
 
- Kernel memory support is work in progress, and the current version provides
+ Kernel memory support is a work in progress, and the current version provides
  basically functionality. (See Section 2.7)
 
 Brief summary of control files.
@@ -144,9 +144,9 @@
 3. Each page has a pointer to the page_cgroup, which in turn knows the
    cgroup it belongs to
 
-The accounting is done as follows: mem_cgroup_charge() is invoked to setup
+The accounting is done as follows: mem_cgroup_charge() is invoked to set up
 the necessary data structures and check if the cgroup that is being charged
-is over its limit. If it is then reclaim is invoked on the cgroup.
+is over its limit. If it is, then reclaim is invoked on the cgroup.
 More details can be found in the reclaim section of this document.
 If everything goes well, a page meta-data-structure called page_cgroup is
 updated. page_cgroup has its own LRU on cgroup.
@@ -163,13 +163,13 @@
 inserted into inode (radix-tree). While it's mapped into the page tables of
 processes, duplicate accounting is carefully avoided.
 
-A RSS page is unaccounted when it's fully unmapped. A PageCache page is
+An RSS page is unaccounted when it's fully unmapped. A PageCache page is
 unaccounted when it's removed from radix-tree. Even if RSS pages are fully
 unmapped (by kswapd), they may exist as SwapCache in the system until they
-are really freed. Such SwapCaches also also accounted.
+are really freed. Such SwapCaches are also accounted.
 A swapped-in page is not accounted until it's mapped.
 
-Note: The kernel does swapin-readahead and read multiple swaps at once.
+Note: The kernel does swapin-readahead and reads multiple swaps at once.
 This means swapped-in pages may contain pages for other tasks than a task
 causing page fault. So, we avoid accounting at swap-in I/O.
 
@@ -209,7 +209,7 @@
 Example: Assume a system with 4G of swap. A task which allocates 6G of memory
 (by mistake) under 2G memory limitation will use all swap.
 In this case, setting memsw.limit_in_bytes=3G will prevent bad use of swap.
-By using memsw limit, you can avoid system OOM which can be caused by swap
+By using the memsw limit, you can avoid system OOM which can be caused by swap
 shortage.
 
 * why 'memory+swap' rather than swap.
@@ -217,7 +217,7 @@
 to move account from memory to swap...there is no change in usage of
 memory+swap. In other words, when we want to limit the usage of swap without
 affecting global LRU, memory+swap limit is better than just limiting swap from
-OS point of view.
+an OS point of view.
 
 * What happens when a cgroup hits memory.memsw.limit_in_bytes
 When a cgroup hits memory.memsw.limit_in_bytes, it's useless to do swap-out
@@ -236,7 +236,7 @@
 cgroup. (See 10. OOM Control below.)
 
 The reclaim algorithm has not been modified for cgroups, except that
-pages that are selected for reclaiming come from the per cgroup LRU
+pages that are selected for reclaiming come from the per-cgroup LRU
 list.
 
 NOTE: Reclaim does not work for the root cgroup, since we cannot set any
@@ -316,7 +316,7 @@
 # cat /sys/fs/cgroup/memory/0/memory.usage_in_bytes
 1216512
 
-A successful write to this file does not guarantee a successful set of
+A successful write to this file does not guarantee a successful setting of
 this limit to the value written into the file. This can be due to a
 number of factors, such as rounding up to page boundaries or the total
 availability of memory on the system. The user is required to re-read
@@ -350,7 +350,7 @@
 4.1 Troubleshooting
 
 Sometimes a user might find that the application under a cgroup is
-terminated by OOM killer. There are several causes for this:
+terminated by the OOM killer. There are several causes for this:
 
 1. The cgroup limit is too low (just too low to do anything useful)
 2. The user is using anonymous memory and swap is turned off or too low
@@ -358,7 +358,7 @@
 A sync followed by echo 1 > /proc/sys/vm/drop_caches will help get rid of
 some of the pages cached in the cgroup (page cache pages).
 
-To know what happens, disable OOM_Kill by 10. OOM Control(see below) and
+To know what happens, disabling OOM_Kill as per "10. OOM Control" (below) and
 seeing what happens will be helpful.
 
 4.2 Task migration
@@ -399,10 +399,10 @@
 
   Almost all pages tracked by this memory cgroup will be unmapped and freed.
   Some pages cannot be freed because they are locked or in-use. Such pages are
-  moved to parent(if use_hierarchy==1) or root (if use_hierarchy==0) and this
+  moved to parent (if use_hierarchy==1) or root (if use_hierarchy==0) and this
   cgroup will be empty.
 
-  Typical use case of this interface is that calling this before rmdir().
+  The typical use case for this interface is before calling rmdir().
   Because rmdir() moves all pages to parent, some out-of-use page caches can be
   moved to the parent. If you want to avoid that, force_empty will be useful.
 
@@ -486,7 +486,7 @@
 
 For efficiency, as other kernel components, memory cgroup uses some optimization
 to avoid unnecessary cacheline false sharing. usage_in_bytes is affected by the
-method and doesn't show 'exact' value of memory(and swap) usage, it's an fuzz
+method and doesn't show 'exact' value of memory (and swap) usage, it's a fuzz
 value for efficient access. (Of course, when necessary, it's synchronized.)
 If you want to know more exact memory usage, you should use RSS+CACHE(+SWAP)
 value in memory.stat(see 5.2).
@@ -496,8 +496,8 @@
 This is similar to numa_maps but operates on a per-memcg basis.  This is
 useful for providing visibility into the numa locality information within
 an memcg since the pages are allowed to be allocated from any physical
-node.  One of the usecases is evaluating application performance by
-combining this information with the application's cpu allocation.
+node.  One of the use cases is evaluating application performance by
+combining this information with the application's CPU allocation.
 
 We export "total", "file", "anon" and "unevictable" pages per-node for
 each memcg.  The ouput format of memory.numa_stat is:
@@ -561,10 +561,10 @@
 group is very high, they are pushed back as much as possible to make
 sure that one control group does not starve the others of memory.
 
-Please note that soft limits is a best effort feature, it comes with
+Please note that soft limits is a best-effort feature; it comes with
 no guarantees, but it does its best to make sure that when memory is
 heavily contended for, memory is allocated based on the soft limit
-hints/setup. Currently soft limit based reclaim is setup such that
+hints/setup. Currently soft limit based reclaim is set up such that
 it gets invoked from balance_pgdat (kswapd).
 
 7.1 Interface
@@ -592,7 +592,7 @@
 
 8.1 Interface
 
-This feature is disabled by default. It can be enabled(and disabled again) by
+This feature is disabled by default. It can be enabledi (and disabled again) by
 writing to memory.move_charge_at_immigrate of the destination cgroup.
 
 If you want to enable it:
@@ -601,8 +601,8 @@
 
 Note: Each bits of move_charge_at_immigrate has its own meaning about what type
       of charges should be moved. See 8.2 for details.
-Note: Charges are moved only when you move mm->owner, IOW, a leader of a thread
-      group.
+Note: Charges are moved only when you move mm->owner, in other words,
+      a leader of a thread group.
 Note: If we cannot find enough space for the task in the destination cgroup, we
       try to make space by reclaiming memory. Task migration may fail if we
       cannot make enough space.
@@ -612,25 +612,25 @@
 
 # echo 0 > memory.move_charge_at_immigrate
 
-8.2 Type of charges which can be move
+8.2 Type of charges which can be moved
 
-Each bits of move_charge_at_immigrate has its own meaning about what type of
-charges should be moved. But in any cases, it must be noted that an account of
-a page or a swap can be moved only when it is charged to the task's current(old)
-memory cgroup.
+Each bit in move_charge_at_immigrate has its own meaning about what type of
+charges should be moved. But in any case, it must be noted that an account of
+a page or a swap can be moved only when it is charged to the task's current
+(old) memory cgroup.
 
   bit | what type of charges would be moved ?
  -----+------------------------------------------------------------------------
-   0  | A charge of an anonymous page(or swap of it) used by the target task.
-      | You must enable Swap Extension(see 2.4) to enable move of swap charges.
+   0  | A charge of an anonymous page (or swap of it) used by the target task.
+      | You must enable Swap Extension (see 2.4) to enable move of swap charges.
  -----+------------------------------------------------------------------------
-   1  | A charge of file pages(normal file, tmpfs file(e.g. ipc shared memory)
+   1  | A charge of file pages (normal file, tmpfs file (e.g. ipc shared memory)
       | and swaps of tmpfs file) mmapped by the target task. Unlike the case of
-      | anonymous pages, file pages(and swaps) in the range mmapped by the task
+      | anonymous pages, file pages (and swaps) in the range mmapped by the task
       | will be moved even if the task hasn't done page fault, i.e. they might
       | not be the task's "RSS", but other task's "RSS" that maps the same file.
-      | And mapcount of the page is ignored(the page can be moved even if
-      | page_mapcount(page) > 1). You must enable Swap Extension(see 2.4) to
+      | And mapcount of the page is ignored (the page can be moved even if
+      | page_mapcount(page) > 1). You must enable Swap Extension (see 2.4) to
       | enable move of swap charges.
 
 8.3 TODO
@@ -640,11 +640,11 @@
 
 9. Memory thresholds
 
-Memory cgroup implements memory thresholds using cgroups notification
+Memory cgroup implements memory thresholds using the cgroups notification
 API (see cgroups.txt). It allows to register multiple memory and memsw
 thresholds and gets notifications when it crosses.
 
-To register a threshold application need:
+To register a threshold, an application must:
 - create an eventfd using eventfd(2);
 - open memory.usage_in_bytes or memory.memsw.usage_in_bytes;
 - write string like "<event_fd> <fd of memory.usage_in_bytes> <threshold>" to
@@ -659,24 +659,24 @@
 
 memory.oom_control file is for OOM notification and other controls.
 
-Memory cgroup implements OOM notifier using cgroup notification
+Memory cgroup implements OOM notifier using the cgroup notification
 API (See cgroups.txt). It allows to register multiple OOM notification
 delivery and gets notification when OOM happens.
 
-To register a notifier, application need:
+To register a notifier, an application must:
  - create an eventfd using eventfd(2)
  - open memory.oom_control file
  - write string like "<event_fd> <fd of memory.oom_control>" to
    cgroup.event_control
 
-Application will be notified through eventfd when OOM happens.
-OOM notification doesn't work for root cgroup.
+The application will be notified through eventfd when OOM happens.
+OOM notification doesn't work for the root cgroup.
 
-You can disable OOM-killer by writing "1" to memory.oom_control file, as:
+You can disable the OOM-killer by writing "1" to memory.oom_control file, as:
 
 	#echo 1 > memory.oom_control
 
-This operation is only allowed to the top cgroup of sub-hierarchy.
+This operation is only allowed to the top cgroup of a sub-hierarchy.
 If OOM-killer is disabled, tasks under cgroup will hang/sleep
 in memory cgroup's OOM-waitqueue when they request accountable memory.
 
diff --git a/Documentation/devicetree/bindings/arm/davinci/nand.txt b/Documentation/devicetree/bindings/arm/davinci/nand.txt
new file mode 100644
index 0000000..e37241f
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/davinci/nand.txt
@@ -0,0 +1,51 @@
+* Texas Instruments Davinci NAND
+
+This file provides information, what the device node for the
+davinci nand interface contain.
+
+Required properties:
+- compatible: "ti,davinci-nand";
+- reg : contain 2 offset/length values:
+        - offset and length for the access window
+        - offset and length for accessing the aemif control registers
+- ti,davinci-chipselect: Indicates on the davinci_nand driver which
+                         chipselect is used for accessing the nand.
+
+Recommended properties :
+- ti,davinci-mask-ale: mask for ale
+- ti,davinci-mask-cle: mask for cle
+- ti,davinci-mask-chipsel: mask for chipselect
+- ti,davinci-ecc-mode: ECC mode valid values for davinci driver:
+		- "none"
+		- "soft"
+		- "hw"
+- ti,davinci-ecc-bits: used ECC bits, currently supported 1 or 4.
+- ti,davinci-nand-buswidth: buswidth 8 or 16
+- ti,davinci-nand-use-bbt: use flash based bad block table support.
+
+Example (enbw_cmc board):
+aemif@60000000 {
+	compatible = "ti,davinci-aemif";
+	#address-cells = <2>;
+	#size-cells = <1>;
+	reg = <0x68000000 0x80000>;
+	ranges = <2 0 0x60000000 0x02000000
+		  3 0 0x62000000 0x02000000
+		  4 0 0x64000000 0x02000000
+		  5 0 0x66000000 0x02000000
+		  6 0 0x68000000 0x02000000>;
+	nand@3,0 {
+		compatible = "ti,davinci-nand";
+		reg = <3 0x0 0x807ff
+			6 0x0 0x8000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ti,davinci-chipselect = <1>;
+		ti,davinci-mask-ale = <0>;
+		ti,davinci-mask-cle = <0>;
+		ti,davinci-mask-chipsel = <0>;
+		ti,davinci-ecc-mode = "hw";
+		ti,davinci-ecc-bits = <4>;
+		ti,davinci-nand-use-bbt;
+	};
+};
diff --git a/Documentation/devicetree/bindings/i2c/atmel-i2c.txt b/Documentation/devicetree/bindings/i2c/atmel-i2c.txt
new file mode 100644
index 0000000..b689a0d
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/atmel-i2c.txt
@@ -0,0 +1,30 @@
+I2C for Atmel platforms
+
+Required properties :
+- compatible : Must be "atmel,at91rm9200-i2c", "atmel,at91sam9261-i2c",
+     "atmel,at91sam9260-i2c", "atmel,at91sam9g20-i2c", "atmel,at91sam9g10-i2c"
+     or "atmel,at91sam9x5-i2c"
+- reg: physical base address of the controller and length of memory mapped
+     region.
+- interrupts: interrupt number to the cpu.
+- #address-cells = <1>;
+- #size-cells = <0>;
+
+Optional properties:
+- Child nodes conforming to i2c bus binding
+
+Examples :
+
+i2c0: i2c@fff84000 {
+	compatible = "atmel,at91sam9g20-i2c";
+	reg = <0xfff84000 0x100>;
+	interrupts = <12 4 6>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	24c512@50 {
+		compatible = "24c512";
+		reg = <0x50>;
+		pagesize = <128>;
+	}
+}
diff --git a/Documentation/devicetree/bindings/i2c/davinci.txt b/Documentation/devicetree/bindings/i2c/davinci.txt
new file mode 100644
index 0000000..2dc935b
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/davinci.txt
@@ -0,0 +1,28 @@
+* Texas Instruments Davinci I2C
+
+This file provides information, what the device node for the
+davinci i2c interface contain.
+
+Required properties:
+- compatible: "ti,davinci-i2c";
+- reg : Offset and length of the register set for the device
+
+Recommended properties :
+- interrupts : standard interrupt property.
+- clock-frequency : desired I2C bus clock frequency in Hz.
+
+Example (enbw_cmc board):
+	i2c@1c22000 {
+		compatible = "ti,davinci-i2c";
+		reg = <0x22000 0x1000>;
+		clock-frequency = <100000>;
+		interrupts = <15>;
+		interrupt-parent = <&intc>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		dtt@48 {
+			compatible = "national,lm75";
+			reg = <0x48>;
+		};
+	};
diff --git a/Documentation/devicetree/bindings/i2c/i2c-mxs.txt b/Documentation/devicetree/bindings/i2c/i2c-mxs.txt
index 30ac3a0..7a3fe9e 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-mxs.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-mxs.txt
@@ -6,6 +6,7 @@
 - interrupts: Should contain ERROR and DMA interrupts
 - clock-frequency: Desired I2C bus clock frequency in Hz.
                    Only 100000Hz and 400000Hz modes are supported.
+- fsl,i2c-dma-channel: APBX DMA channel for the I2C
 
 Examples:
 
@@ -16,4 +17,5 @@
 	reg = <0x80058000 2000>;
 	interrupts = <111 68>;
 	clock-frequency = <100000>;
+	fsl,i2c-dma-channel = <6>;
 };
diff --git a/Documentation/devicetree/bindings/i2c/nomadik.txt b/Documentation/devicetree/bindings/i2c/nomadik.txt
new file mode 100644
index 0000000..72065b0
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/nomadik.txt
@@ -0,0 +1,23 @@
+I2C for Nomadik based systems
+
+Required (non-standard) properties:
+ - Nil
+
+Recommended (non-standard) properties:
+ - clock-frequency : Maximum bus clock frequency for the device
+
+Optional (non-standard) properties:
+ - Nil
+
+Example :
+
+i2c@80004000 {
+        compatible = "stericsson,db8500-i2c", "st,nomadik-i2c";
+        reg = <0x80004000 0x1000>;
+        interrupts = <0 21 0x4>;
+        #address-cells = <1>;
+        #size-cells = <0>;
+        v-i2c-supply = <&db8500_vape_reg>;
+
+        clock-frequency = <400000>;
+};
diff --git a/Documentation/devicetree/bindings/mmc/atmel-hsmci.txt b/Documentation/devicetree/bindings/mmc/atmel-hsmci.txt
new file mode 100644
index 0000000..0a85c70
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/atmel-hsmci.txt
@@ -0,0 +1,68 @@
+* Atmel High Speed MultiMedia Card Interface
+
+This controller on atmel products provides an interface for MMC, SD and SDIO
+types of memory cards.
+
+This file documents differences between the core properties described
+by mmc.txt and the properties used by the atmel-mci driver.
+
+1) MCI node
+
+Required properties:
+- compatible: should be "atmel,hsmci"
+- #address-cells: should be one. The cell is the slot id.
+- #size-cells: should be zero.
+- at least one slot node
+
+The node contains child nodes for each slot that the platform uses
+
+Example MCI node:
+
+mmc0: mmc@f0008000 {
+	compatible = "atmel,hsmci";
+	reg = <0xf0008000 0x600>;
+	interrupts = <12 4>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	[ child node definitions...]
+};
+
+2) slot nodes
+
+Required properties:
+- reg: should contain the slot id.
+- bus-width: number of data lines connected to the controller
+
+Optional properties:
+- cd-gpios: specify GPIOs for card detection
+- cd-inverted: invert the value of external card detect gpio line
+- wp-gpios: specify GPIOs for write protection
+
+Example slot node:
+
+slot@0 {
+	reg = <0>;
+	bus-width = <4>;
+	cd-gpios = <&pioD 15 0>
+	cd-inverted;
+};
+
+Example full MCI node:
+mmc0: mmc@f0008000 {
+	compatible = "atmel,hsmci";
+	reg = <0xf0008000 0x600>;
+	interrupts = <12 4>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	slot@0 {
+		reg = <0>;
+		bus-width = <4>;
+		cd-gpios = <&pioD 15 0>
+		cd-inverted;
+	};
+	slot@1 {
+		reg = <1>;
+		bus-width = <4>;
+	};
+};
diff --git a/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
new file mode 100644
index 0000000..7927689
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/exynos-dw-mshc.txt
@@ -0,0 +1,87 @@
+* Samsung Exynos specific extensions to the Synopsis Designware Mobile
+  Storage Host Controller
+
+The Synopsis designware mobile storage host controller is used to interface
+a SoC with storage medium such as eMMC or SD/MMC cards. This file documents
+differences between the core Synopsis dw mshc controller properties described
+by synposis-dw-mshc.txt and the properties used by the Samsung Exynos specific
+extensions to the Synopsis Designware Mobile Storage Host Controller.
+
+Required Properties:
+
+* compatible: should be
+	- "samsung,exynos4210-dw-mshc": for controllers with Samsung Exynos4210
+	  specific extentions.
+	- "samsung,exynos4412-dw-mshc": for controllers with Samsung Exynos4412
+	  specific extentions.
+	- "samsung,exynos5250-dw-mshc": for controllers with Samsung Exynos5250
+	  specific extentions.
+
+* samsung,dw-mshc-ciu-div: Specifies the divider value for the card interface
+  unit (ciu) clock. This property is applicable only for Exynos5 SoC's and
+  ignored for Exynos4 SoC's. The valid range of divider value is 0 to 7.
+
+* samsung,dw-mshc-sdr-timing: Specifies the value of CIU clock phase shift value
+  in transmit mode and CIU clock phase shift value in receive mode for single
+  data rate mode operation. Refer notes below for the order of the cells and the
+  valid values.
+
+* samsung,dw-mshc-ddr-timing: Specifies the value of CUI clock phase shift value
+  in transmit mode and CIU clock phase shift value in receive mode for double
+  data rate mode operation. Refer notes below for the order of the cells and the
+  valid values.
+
+  Notes for the sdr-timing and ddr-timing values:
+
+    The order of the cells should be
+      - First Cell: CIU clock phase shift value for tx mode.
+      - Second Cell: CIU clock phase shift value for rx mode.
+
+    Valid values for SDR and DDR CIU clock timing for Exynos5250:
+      - valid value for tx phase shift and rx phase shift is 0 to 7.
+      - when CIU clock divider value is set to 3, all possible 8 phase shift
+        values can be used.
+      - if CIU clock divider value is 0 (that is divide by 1), both tx and rx
+        phase shift clocks should be 0.
+
+Required properties for a slot:
+
+* gpios: specifies a list of gpios used for command, clock and data bus. The
+  first gpio is the command line and the second gpio is the clock line. The
+  rest of the gpios (depending on the bus-width property) are the data lines in
+  no particular order. The format of the gpio specifier depends on the gpio
+  controller.
+
+Example:
+
+  The MSHC controller node can be split into two portions, SoC specific and
+  board specific portions as listed below.
+
+	dwmmc0@12200000 {
+		compatible = "samsung,exynos5250-dw-mshc";
+		reg = <0x12200000 0x1000>;
+		interrupts = <0 75 0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+
+	dwmmc0@12200000 {
+		num-slots = <1>;
+		supports-highspeed;
+		broken-cd;
+		fifo-depth = <0x80>;
+		card-detect-delay = <200>;
+		samsung,dw-mshc-ciu-div = <3>;
+		samsung,dw-mshc-sdr-timing = <2 3>;
+		samsung,dw-mshc-ddr-timing = <1 2>;
+
+		slot@0 {
+			reg = <0>;
+			bus-width = <8>;
+			gpios = <&gpc0 0 2 0 3>, <&gpc0 1 2 0 3>,
+				<&gpc1 0 2 3 3>, <&gpc1 1 2 3 3>,
+				<&gpc1 2 2 3 3>, <&gpc1 3 2 3 3>,
+				<&gpc0 3 2 3 3>, <&gpc0 4 2 3 3>,
+				<&gpc0 5 2 3 3>, <&gpc0 6 2 3 3>;
+		};
+	};
diff --git a/Documentation/devicetree/bindings/mmc/mmc.txt b/Documentation/devicetree/bindings/mmc/mmc.txt
index 8a6811f..8e2e0ba 100644
--- a/Documentation/devicetree/bindings/mmc/mmc.txt
+++ b/Documentation/devicetree/bindings/mmc/mmc.txt
@@ -9,12 +9,17 @@
 Required properties:
 - bus-width: Number of data lines, can be <1>, <4>, or <8>
 
+Card detection:
+If no property below is supplied, standard SDHCI card detect is used.
+Only one of the properties in this section should be supplied:
+  - broken-cd: There is no card detection available; polling must be used.
+  - cd-gpios: Specify GPIOs for card detection, see gpio binding
+  - non-removable: non-removable slot (like eMMC); assume always present.
+
 Optional properties:
-- cd-gpios: Specify GPIOs for card detection, see gpio binding
 - wp-gpios: Specify GPIOs for write protection, see gpio binding
 - cd-inverted: when present, polarity on the cd gpio line is inverted
 - wp-inverted: when present, polarity on the wp gpio line is inverted
-- non-removable: non-removable slot (like eMMC)
 - max-frequency: maximum operating clock frequency
 
 Example:
diff --git a/Documentation/devicetree/bindings/mmc/pxa-mmc.txt b/Documentation/devicetree/bindings/mmc/pxa-mmc.txt
new file mode 100644
index 0000000..b7025de
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/pxa-mmc.txt
@@ -0,0 +1,25 @@
+* PXA MMC drivers
+
+Driver bindings for the PXA MCI (MMC/SDIO) interfaces
+
+Required properties:
+- compatible: Should be "marvell,pxa-mmc".
+- vmmc-supply: A regulator for VMMC
+
+Optional properties:
+- marvell,detect-delay-ms: sets the detection delay timeout in ms.
+- marvell,gpio-power: GPIO spec for the card power enable pin
+
+This file documents differences between the core properties in mmc.txt
+and the properties used by the pxa-mmc driver.
+
+Examples:
+
+mmc0: mmc@41100000 {
+	compatible = "marvell,pxa-mmc";
+	reg = <0x41100000 0x1000>;
+	interrupts = <23>;
+	cd-gpios = <&gpio 23 0>;
+	wp-gpios = <&gpio 24 0>;
+};
+
diff --git a/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt b/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt
new file mode 100644
index 0000000..630a7d7
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/samsung-sdhci.txt
@@ -0,0 +1,53 @@
+* Samsung's SDHCI Controller device tree bindings
+
+Samsung's SDHCI controller is used as a connectivity interface with external
+MMC, SD and eMMC storage mediums. This file documents differences between the
+core mmc properties described by mmc.txt and the properties used by the
+Samsung implmentation of the SDHCI controller.
+
+Note: The mmc core bindings documentation states that if none of the core
+card-detect bindings are used, then the standard sdhci card detect mechanism
+is used. The Samsung's SDHCI controller bindings extends this as listed below.
+
+[A] The property "samsung,cd-pinmux-gpio" can be used as stated in the
+    "Optional Board Specific Properties" section below.
+
+[B] If core card-detect bindings and "samsung,cd-pinmux-gpio" property
+    is not specified, it is assumed that there is no card detection
+    mechanism used.
+
+Required SoC Specific Properties:
+- compatible: should be one of the following
+  - "samsung,s3c6410-sdhci": For controllers compatible with s3c6410 sdhci
+    controller.
+  - "samsung,exynos4210-sdhci": For controllers compatible with Exynos4 sdhci
+    controller.
+
+Required Board Specific Properties:
+- gpios: Should specify the gpios used for clock, command and data lines. The
+  gpio specifier format depends on the gpio controller.
+
+Optional Board Specific Properties:
+- samsung,cd-pinmux-gpio: Specifies the card detect line that is routed
+  through a pinmux to the card-detect pin of the card slot. This property
+  should be used only if none of the mmc core card-detect properties are
+  used.
+
+Example:
+	sdhci@12530000 {
+		compatible = "samsung,exynos4210-sdhci";
+		reg = <0x12530000 0x100>;
+		interrupts = <0 75 0>;
+		bus-width = <4>;
+		cd-gpios = <&gpk2 2 2 3 3>;
+		gpios = <&gpk2 0 2 0 3>,  /* clock line */
+			<&gpk2 1 2 0 3>,  /* command line */
+			<&gpk2 3 2 3 3>,  /* data line 0 */
+			<&gpk2 4 2 3 3>,  /* data line 1 */
+			<&gpk2 5 2 3 3>,  /* data line 2 */
+			<&gpk2 6 2 3 3>;  /* data line 3 */
+	};
+
+	Note: This example shows both SoC specific and board specific properties
+	in a single device node. The properties can be actually be seperated
+	into SoC specific node and board specific node.
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-dove.txt b/Documentation/devicetree/bindings/mmc/sdhci-dove.txt
new file mode 100644
index 0000000..ae9aab9
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/sdhci-dove.txt
@@ -0,0 +1,14 @@
+* Marvell sdhci-dove controller
+
+This file documents differences between the core properties in mmc.txt
+and the properties used by the sdhci-pxav2 and sdhci-pxav3 drivers.
+
+- compatible: Should be "marvell,dove-sdhci".
+
+Example:
+
+sdio0: sdio@92000 {
+	compatible = "marvell,dove-sdhci";
+	reg = <0x92000 0x100>;
+	interrupts = <35>;
+};
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-spear.txt b/Documentation/devicetree/bindings/mmc/sdhci-spear.txt
new file mode 100644
index 0000000..fd3643e
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/sdhci-spear.txt
@@ -0,0 +1,18 @@
+* SPEAr SDHCI Controller
+
+This file documents differences between the core properties in mmc.txt
+and the properties used by the sdhci-spear driver.
+
+Required properties:
+- compatible: "st,spear300-sdhci"
+
+Optional properties:
+- cd-gpios: card detect gpio, with zero flags.
+
+Example:
+
+	sdhci@fc000000 {
+		compatible = "st,spear300-sdhci";
+		reg = <0xfc000000 0x1000>;
+		cd-gpios = <&gpio0 6 0>;
+	};
diff --git a/Documentation/devicetree/bindings/mmc/synposis-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/synposis-dw-mshc.txt
new file mode 100644
index 0000000..06cd32d08
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/synposis-dw-mshc.txt
@@ -0,0 +1,79 @@
+* Synopsis Designware Mobile Storage Host Controller
+
+The Synopsis designware mobile storage host controller is used to interface
+a SoC with storage medium such as eMMC or SD/MMC cards. This file documents
+differences between the core mmc properties described by mmc.txt and the
+properties used by the Synopsis Designware Mobile Storage Host Controller.
+
+Required Properties:
+
+* compatible: should be
+	- snps,dw-mshc: for controllers compliant with synopsis dw-mshc.
+* #address-cells: should be 1.
+* #size-cells: should be 0.
+
+# Slots: The slot specific information are contained within child-nodes with
+  each child-node representing a supported slot. There should be atleast one
+  child node representing a card slot. The name of the child node representing
+  the slot is recommended to be slot@n where n is the unique number of the slot
+  connnected to the controller. The following are optional properties which
+  can be included in the slot child node.
+
+	* reg: specifies the physical slot number. The valid values of this
+	  property is 0 to (num-slots -1), where num-slots is the value
+	  specified by the num-slots property.
+
+	* bus-width: as documented in mmc core bindings.
+
+	* wp-gpios: specifies the write protect gpio line. The format of the
+	  gpio specifier depends on the gpio controller. If the write-protect
+	  line is not available, this property is optional.
+
+Optional properties:
+
+* num-slots: specifies the number of slots supported by the controller.
+  The number of physical slots actually used could be equal or less than the
+  value specified by num-slots. If this property is not specified, the value
+  of num-slot property is assumed to be 1.
+
+* fifo-depth: The maximum size of the tx/rx fifo's. If this property is not
+  specified, the default value of the fifo size is determined from the
+  controller registers.
+
+* card-detect-delay: Delay in milli-seconds before detecting card after card
+  insert event. The default value is 0.
+
+* supports-highspeed: Enables support for high speed cards (upto 50MHz)
+
+* broken-cd: as documented in mmc core bindings.
+
+Aliases:
+
+- All the MSHC controller nodes should be represented in the aliases node using
+  the following format 'mshc{n}' where n is a unique number for the alias.
+
+Example:
+
+The MSHC controller node can be split into two portions, SoC specific and
+board specific portions as listed below.
+
+	dwmmc0@12200000 {
+		compatible = "snps,dw-mshc";
+		reg = <0x12200000 0x1000>;
+		interrupts = <0 75 0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+
+	dwmmc0@12200000 {
+		num-slots = <1>;
+		supports-highspeed;
+		broken-cd;
+		fifo-depth = <0x80>;
+		card-detect-delay = <200>;
+
+		slot@0 {
+			reg = <0>;
+			bus-width = <8>;
+		};
+	};
diff --git a/Documentation/devicetree/bindings/mtd/atmel-nand.txt b/Documentation/devicetree/bindings/mtd/atmel-nand.txt
index a200695..d555421 100644
--- a/Documentation/devicetree/bindings/mtd/atmel-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/atmel-nand.txt
@@ -3,7 +3,9 @@
 Required properties:
 - compatible : "atmel,at91rm9200-nand".
 - reg : should specify localbus address and size used for the chip,
-	and if availlable the ECC.
+	and hardware ECC controller if available.
+	If the hardware ECC is PMECC, it should contain address and size for
+	PMECC, PMECC Error Location controller and ROM which has lookup tables.
 - atmel,nand-addr-offset : offset for the address latch.
 - atmel,nand-cmd-offset : offset for the command latch.
 - #address-cells, #size-cells : Must be present if the device has sub-nodes
@@ -16,6 +18,15 @@
 - nand-ecc-mode : String, operation mode of the NAND ecc mode, soft by default.
   Supported values are: "none", "soft", "hw", "hw_syndrome", "hw_oob_first",
   "soft_bch".
+- atmel,has-pmecc : boolean to enable Programmable Multibit ECC hardware.
+  Only supported by at91sam9x5 or later sam9 product.
+- atmel,pmecc-cap : error correct capability for Programmable Multibit ECC
+  Controller. Supported values are: 2, 4, 8, 12, 24.
+- atmel,pmecc-sector-size : sector size for ECC computation. Supported values
+  are: 512, 1024.
+- atmel,pmecc-lookup-table-offset : includes two offsets of lookup table in ROM
+  for different sector size. First one is for sector size 512, the next is for
+  sector size 1024.
 - nand-bus-width : 8 or 16 bus width if not present 8
 - nand-on-flash-bbt: boolean to enable on flash bbt option if not present false
 
@@ -39,3 +50,30 @@
 		...
 	};
 };
+
+/* for PMECC supported chips */
+nand0: nand@40000000 {
+	compatible = "atmel,at91rm9200-nand";
+	#address-cells = <1>;
+	#size-cells = <1>;
+	reg = < 0x40000000 0x10000000	/* bus addr & size */
+		0xffffe000 0x00000600	/* PMECC addr & size */
+		0xffffe600 0x00000200	/* PMECC ERRLOC addr & size */
+		0x00100000 0x00100000	/* ROM addr & size */
+		>;
+	atmel,nand-addr-offset = <21>;	/* ale */
+	atmel,nand-cmd-offset = <22>;	/* cle */
+	nand-on-flash-bbt;
+	nand-ecc-mode = "hw";
+	atmel,has-pmecc;	/* enable PMECC */
+	atmel,pmecc-cap = <2>;
+	atmel,pmecc-sector-size = <512>;
+	atmel,pmecc-lookup-table-offset = <0x8000 0x10000>;
+	gpios = <&pioD 5 0	/* rdy */
+		 &pioD 4 0	/* nce */
+		 0		/* cd */
+		>;
+	partition@0 {
+		...
+	};
+};
diff --git a/Documentation/devicetree/bindings/mtd/gpmi-nand.txt b/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
index 1a5bbd3..3fb3f901 100644
--- a/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmi-nand.txt
@@ -12,6 +12,10 @@
   - interrupt-names : The interrupt names "gpmi-dma", "bch";
   - fsl,gpmi-dma-channel : Should contain the dma channel it uses.
 
+Optional properties:
+  - nand-on-flash-bbt: boolean to enable on flash bbt option if not
+                       present false
+
 The device tree may optionally contain sub-nodes describing partitions of the
 address space. See partition.txt for more detail.
 
diff --git a/Documentation/devicetree/bindings/mtd/lpc32xx-mlc.txt b/Documentation/devicetree/bindings/mtd/lpc32xx-mlc.txt
new file mode 100644
index 0000000..d0a3725
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/lpc32xx-mlc.txt
@@ -0,0 +1,50 @@
+NXP LPC32xx SoC NAND MLC controller
+
+Required properties:
+- compatible: "nxp,lpc3220-mlc"
+- reg: Address and size of the controller
+- interrupts: The NAND interrupt specification
+- gpios: GPIO specification for NAND write protect
+
+The following required properties are very controller specific. See the LPC32xx
+User Manual 7.5.14 MLC NAND Timing Register (the values here are specified in
+Hz, to make them independent of actual clock speed and to provide for good
+accuracy:)
+- nxp,tcea_delay: TCEA_DELAY
+- nxp,busy_delay: BUSY_DELAY
+- nxp,nand_ta: NAND_TA
+- nxp,rd_high: RD_HIGH
+- nxp,rd_low: RD_LOW
+- nxp,wr_high: WR_HIGH
+- nxp,wr_low: WR_LOW
+
+Optional subnodes:
+- Partitions, see Documentation/devicetree/bindings/mtd/partition.txt
+
+Example:
+
+	mlc: flash@200A8000 {
+		compatible = "nxp,lpc3220-mlc";
+		reg = <0x200A8000 0x11000>;
+		interrupts = <11 0>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		nxp,tcea-delay = <333333333>;
+		nxp,busy-delay = <10000000>;
+		nxp,nand-ta = <18181818>;
+		nxp,rd-high = <31250000>;
+		nxp,rd-low = <45454545>;
+		nxp,wr-high = <40000000>;
+		nxp,wr-low = <83333333>;
+		gpios = <&gpio 5 19 1>; /* GPO_P3 19, active low */
+
+		mtd0@00000000 {
+			label = "boot";
+			reg = <0x00000000 0x00064000>;
+			read-only;
+		};
+
+		...
+
+	};
diff --git a/Documentation/devicetree/bindings/mtd/lpc32xx-slc.txt b/Documentation/devicetree/bindings/mtd/lpc32xx-slc.txt
new file mode 100644
index 0000000..d94edc0
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/lpc32xx-slc.txt
@@ -0,0 +1,52 @@
+NXP LPC32xx SoC NAND SLC controller
+
+Required properties:
+- compatible: "nxp,lpc3220-slc"
+- reg: Address and size of the controller
+- nand-on-flash-bbt: Use bad block table on flash
+- gpios: GPIO specification for NAND write protect
+
+The following required properties are very controller specific. See the LPC32xx
+User Manual:
+- nxp,wdr-clks: Delay before Ready signal is tested on write (W_RDY)
+- nxp,rdr-clks: Delay before Ready signal is tested on read (R_RDY)
+(The following values are specified in Hz, to make them independent of actual
+clock speed:)
+- nxp,wwidth: Write pulse width (W_WIDTH)
+- nxp,whold: Write hold time (W_HOLD)
+- nxp,wsetup: Write setup time (W_SETUP)
+- nxp,rwidth: Read pulse width (R_WIDTH)
+- nxp,rhold: Read hold time (R_HOLD)
+- nxp,rsetup: Read setup time (R_SETUP)
+
+Optional subnodes:
+- Partitions, see Documentation/devicetree/bindings/mtd/partition.txt
+
+Example:
+
+	slc: flash@20020000 {
+		compatible = "nxp,lpc3220-slc";
+		reg = <0x20020000 0x1000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		nxp,wdr-clks = <14>;
+		nxp,wwidth = <40000000>;
+		nxp,whold = <100000000>;
+		nxp,wsetup = <100000000>;
+		nxp,rdr-clks = <14>;
+		nxp,rwidth = <40000000>;
+		nxp,rhold = <66666666>;
+		nxp,rsetup = <100000000>;
+		nand-on-flash-bbt;
+		gpios = <&gpio 5 19 1>; /* GPO_P3 19, active low */
+
+		mtd0@00000000 {
+			label = "phy3250-boot";
+			reg = <0x00000000 0x00064000>;
+			read-only;
+		};
+
+		...
+
+	};
diff --git a/Documentation/devicetree/bindings/mtd/mtd-physmap.txt b/Documentation/devicetree/bindings/mtd/mtd-physmap.txt
index a63c2bd7..94de19b 100644
--- a/Documentation/devicetree/bindings/mtd/mtd-physmap.txt
+++ b/Documentation/devicetree/bindings/mtd/mtd-physmap.txt
@@ -16,6 +16,13 @@
  - #address-cells, #size-cells : Must be present if the device has
    sub-nodes representing partitions (see below).  In this case
    both #address-cells and #size-cells must be equal to 1.
+ - no-unaligned-direct-access: boolean to disable the default direct
+   mapping of the flash.
+   On some platforms (e.g. MPC5200) a direct 1:1 mapping may cause
+   problems with JFFS2 usage, as the local bus (LPB) doesn't support
+   unaligned accesses as implemented in the JFFS2 code via memcpy().
+   By defining "no-unaligned-direct-access", the flash will not be
+   exposed directly to the MTD users (e.g. JFFS2) any more.
 
 For JEDEC compatible devices, the following additional properties
 are defined:
diff --git a/Documentation/devicetree/bindings/pinctrl/lantiq,falcon-pinumx.txt b/Documentation/devicetree/bindings/pinctrl/lantiq,falcon-pinumx.txt
new file mode 100644
index 0000000..daa7689
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/lantiq,falcon-pinumx.txt
@@ -0,0 +1,83 @@
+Lantiq FALCON pinmux controller
+
+Required properties:
+- compatible: "lantiq,pinctrl-falcon"
+- reg: Should contain the physical address and length of the gpio/pinmux
+  register range
+
+Please refer to pinctrl-bindings.txt in this directory for details of the
+common pinctrl bindings used by client devices, including the meaning of the
+phrase "pin configuration node".
+
+Lantiq's pin configuration nodes act as a container for an abitrary number of
+subnodes. Each of these subnodes represents some desired configuration for a
+pin, a group, or a list of pins or groups. This configuration can include the
+mux function to select on those group(s), and two pin configuration parameters:
+pull-up and open-drain
+
+The name of each subnode is not important as long as it is unique; all subnodes
+should be enumerated and processed purely based on their content.
+
+Each subnode only affects those parameters that are explicitly listed. In
+other words, a subnode that lists a mux function but no pin configuration
+parameters implies no information about any pin configuration parameters.
+Similarly, a pin subnode that describes a pullup parameter implies no
+information about e.g. the mux function.
+
+We support 2 types of nodes.
+
+Definition of mux function groups:
+
+Required subnode-properties:
+- lantiq,groups : An array of strings. Each string contains the name of a group.
+  Valid values for these names are listed below.
+- lantiq,function: A string containing the name of the function to mux to the
+  group. Valid values for function names are listed below.
+
+Valid values for group and function names:
+
+  mux groups:
+    por, ntr, ntr8k, hrst, mdio, bootled, asc0, spi, spi cs0, spi cs1, i2c,
+    jtag, slic, pcm, asc1
+
+  functions:
+    rst, ntr, mdio, led, asc, spi, i2c, jtag, slic, pcm
+
+
+Definition of pin configurations:
+
+Required subnode-properties:
+- lantiq,pins : An array of strings. Each string contains the name of a pin.
+  Valid values for these names are listed below.
+
+Optional subnode-properties:
+- lantiq,pull: Integer, representing the pull-down/up to apply to the pin.
+    0: none, 1: down
+- lantiq,drive-current: Boolean, enables drive-current
+- lantiq,slew-rate: Boolean, enables slew-rate
+
+Example:
+	pinmux0 {
+		compatible = "lantiq,pinctrl-falcon";
+		pinctrl-names = "default";
+		pinctrl-0 = <&state_default>;
+
+		state_default: pinmux {
+			asc0 {
+				lantiq,groups = "asc0";
+				lantiq,function = "asc";
+			};
+			ntr {
+				lantiq,groups = "ntr8k";
+				lantiq,function = "ntr";
+			};
+			i2c {
+				lantiq,groups = "i2c";
+				lantiq,function = "i2c";
+			};
+			hrst {
+				lantiq,groups = "hrst";
+				lantiq,function = "rst";
+			};
+		};
+	};
diff --git a/Documentation/devicetree/bindings/pinctrl/lantiq,xway-pinumx.txt b/Documentation/devicetree/bindings/pinctrl/lantiq,xway-pinumx.txt
new file mode 100644
index 0000000..b5469db
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/lantiq,xway-pinumx.txt
@@ -0,0 +1,97 @@
+Lantiq XWAY pinmux controller
+
+Required properties:
+- compatible: "lantiq,pinctrl-xway" or "lantiq,pinctrl-xr9"
+- reg: Should contain the physical address and length of the gpio/pinmux
+  register range
+
+Please refer to pinctrl-bindings.txt in this directory for details of the
+common pinctrl bindings used by client devices, including the meaning of the
+phrase "pin configuration node".
+
+Lantiq's pin configuration nodes act as a container for an abitrary number of
+subnodes. Each of these subnodes represents some desired configuration for a
+pin, a group, or a list of pins or groups. This configuration can include the
+mux function to select on those group(s), and two pin configuration parameters:
+pull-up and open-drain
+
+The name of each subnode is not important as long as it is unique; all subnodes
+should be enumerated and processed purely based on their content.
+
+Each subnode only affects those parameters that are explicitly listed. In
+other words, a subnode that lists a mux function but no pin configuration
+parameters implies no information about any pin configuration parameters.
+Similarly, a pin subnode that describes a pullup parameter implies no
+information about e.g. the mux function.
+
+We support 2 types of nodes.
+
+Definition of mux function groups:
+
+Required subnode-properties:
+- lantiq,groups : An array of strings. Each string contains the name of a group.
+  Valid values for these names are listed below.
+- lantiq,function: A string containing the name of the function to mux to the
+  group. Valid values for function names are listed below.
+
+Valid values for group and function names:
+
+  mux groups:
+    exin0, exin1, exin2, jtag, ebu a23, ebu a24, ebu a25, ebu clk, ebu cs1,
+    ebu wait, nand ale, nand cs1, nand cle, spi, spi_cs1, spi_cs2, spi_cs3,
+    spi_cs4, spi_cs5, spi_cs6, asc0, asc0 cts rts, stp, nmi , gpt1, gpt2,
+    gpt3, clkout0, clkout1, clkout2, clkout3, gnt1, gnt2, gnt3, req1, req2,
+    req3
+
+  additional mux groups (XR9 only):
+    mdio, nand rdy, nand rd, exin3, exin4, gnt4, req4
+
+  functions:
+    spi, asc, cgu, jtag, exin, stp, gpt, nmi, pci, ebu, mdio
+
+
+
+Definition of pin configurations:
+
+Required subnode-properties:
+- lantiq,pins : An array of strings. Each string contains the name of a pin.
+  Valid values for these names are listed below.
+
+Optional subnode-properties:
+- lantiq,pull: Integer, representing the pull-down/up to apply to the pin.
+    0: none, 1: down, 2: up.
+- lantiq,open-drain: Boolean, enables open-drain on the defined pin.
+
+Valid values for XWAY pin names:
+  Pinconf pins can be referenced via the names io0-io31.
+
+Valid values for XR9 pin names:
+  Pinconf pins can be referenced via the names io0-io55.
+
+Example:
+	gpio: pinmux@E100B10 {
+		compatible = "lantiq,pinctrl-xway";
+		pinctrl-names = "default";
+		pinctrl-0 = <&state_default>;
+
+		#gpio-cells = <2>;
+		gpio-controller;
+		reg = <0xE100B10 0xA0>;
+
+		state_default: pinmux {
+			stp {
+				lantiq,groups = "stp";
+				lantiq,function = "stp";
+			};
+			pci {
+				lantiq,groups = "gnt1";
+				lantiq,function = "pci";
+			};
+			conf_out {
+				lantiq,pins = "io4", "io5", "io6"; /* stp */
+				lantiq,open-drain;
+				lantiq,pull = <0>;
+			};
+		};
+	};
+
diff --git a/Documentation/devicetree/bindings/pwm/imx-pwm.txt b/Documentation/devicetree/bindings/pwm/imx-pwm.txt
new file mode 100644
index 0000000..8522bfb
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/imx-pwm.txt
@@ -0,0 +1,17 @@
+Freescale i.MX PWM controller
+
+Required properties:
+- compatible: should be "fsl,<soc>-pwm"
+- reg: physical base address and length of the controller's registers
+- #pwm-cells: should be 2.  The first cell specifies the per-chip index
+  of the PWM to use and the second cell is the period in nanoseconds.
+- interrupts: The interrupt for the pwm controller
+
+Example:
+
+pwm1: pwm@53fb4000 {
+	#pwm-cells = <2>;
+	compatible = "fsl,imx53-pwm", "fsl,imx27-pwm";
+	reg = <0x53fb4000 0x4000>;
+	interrupts = <61>;
+};
diff --git a/Documentation/devicetree/bindings/pwm/mxs-pwm.txt b/Documentation/devicetree/bindings/pwm/mxs-pwm.txt
index 11963e4..9e3f8f1 100644
--- a/Documentation/devicetree/bindings/pwm/mxs-pwm.txt
+++ b/Documentation/devicetree/bindings/pwm/mxs-pwm.txt
@@ -4,7 +4,7 @@
 - compatible: should be "fsl,imx23-pwm"
 - reg: physical base address and length of the controller's registers
 - #pwm-cells: should be 2.  The first cell specifies the per-chip index
-  of the PWM to use and the second cell is the duty cycle in nanoseconds.
+  of the PWM to use and the second cell is the period in nanoseconds.
 - fsl,pwm-number: the number of PWM devices
 
 Example:
diff --git a/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.txt b/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.txt
index bbbeedb..01438ec 100644
--- a/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.txt
+++ b/Documentation/devicetree/bindings/pwm/nvidia,tegra20-pwm.txt
@@ -7,7 +7,7 @@
 - reg: physical base address and length of the controller's registers
 - #pwm-cells: On Tegra the number of cells used to specify a PWM is 2. The
   first cell specifies the per-chip index of the PWM to use and the second
-  cell is the duty cycle in nanoseconds.
+  cell is the period in nanoseconds.
 
 Example:
 
diff --git a/Documentation/devicetree/bindings/sound/cs4270.txt b/Documentation/devicetree/bindings/sound/cs4270.txt
new file mode 100644
index 0000000..6b222f9
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/cs4270.txt
@@ -0,0 +1,21 @@
+CS4270 audio CODEC
+
+The driver for this device currently only supports I2C.
+
+Required properties:
+
+  - compatible : "cirrus,cs4270"
+
+  - reg : the I2C address of the device for I2C
+
+Optional properties:
+
+  - reset-gpio : a GPIO spec for the reset pin. If specified, it will be
+		 deasserted before communication to the codec starts.
+
+Example:
+
+codec: cs4270@48 {
+	compatible = "cirrus,cs4270";
+	reg = <0x48>;
+};
diff --git a/Documentation/devicetree/bindings/sound/cs4271.txt b/Documentation/devicetree/bindings/sound/cs4271.txt
new file mode 100644
index 0000000..c81b5fd
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/cs4271.txt
@@ -0,0 +1,36 @@
+Cirrus Logic CS4271 DT bindings
+
+This driver supports both the I2C and the SPI bus.
+
+Required properties:
+
+ - compatible: "cirrus,cs4271"
+
+For required properties on SPI, please consult
+Documentation/devicetree/bindings/spi/spi-bus.txt
+
+Required properties on I2C:
+
+ - reg: the i2c address
+
+
+Optional properties:
+
+ - reset-gpio: 	a GPIO spec to define which pin is connected to the chip's
+		!RESET pin
+
+Examples:
+
+	codec_i2c: cs4271@10 {
+		compatible = "cirrus,cs4271";
+		reg = <0x10>;
+		reset-gpio = <&gpio 23 0>;
+	};
+
+	codec_spi: cs4271@0 {
+		compatible = "cirrus,cs4271";
+		reg = <0x0>;
+		reset-gpio = <&gpio 23 0>;
+		spi-max-frequency = <6000000>;
+	};
+
diff --git a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt
new file mode 100644
index 0000000..374e145
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt
@@ -0,0 +1,45 @@
+Texas Instruments McASP controller
+
+Required properties:
+- compatible :
+	"ti,dm646x-mcasp-audio"	: for DM646x platforms
+	"ti,da830-mcasp-audio"	: for both DA830 & DA850 platforms
+	"ti,omap2-mcasp-audio"	: for OMAP2 platforms (TI81xx, AM33xx)
+
+- reg : Should contain McASP registers offset and length
+- interrupts : Interrupt number for McASP
+- op-mode : I2S/DIT ops mode.
+- tdm-slots : Slots for TDM operation.
+- num-serializer : Serializers used by McASP.
+- serial-dir : A list of serializer pin mode. The list number should be equal
+		to "num-serializer" parameter. Each entry is a number indication
+		serializer pin direction. (0 - INACTIVE, 1 - TX, 2 - RX)
+
+
+Optional properties:
+
+- ti,hwmods : Must be "mcasp<n>", n is controller instance starting 0
+- tx-num-evt : FIFO levels.
+- rx-num-evt : FIFO levels.
+- sram-size-playback : size of sram to be allocated during playback
+- sram-size-capture  : size of sram to be allocated during capture
+
+Example:
+
+mcasp0: mcasp0@1d00000 {
+	compatible = "ti,da830-mcasp-audio";
+	#address-cells = <1>;
+	#size-cells = <0>;
+	reg = <0x100000 0x3000>;
+	interrupts = <82 83>;
+	op-mode = <0>;		/* MCASP_IIS_MODE */
+	tdm-slots = <2>;
+	num-serializer = <16>;
+	serial-dir = <
+			0 0 0 0	/* 0: INACTIVE, 1: TX, 2: RX */
+			0 0 0 0
+			0 0 0 1
+			2 0 0 0 >;
+	tx-num-evt = <1>;
+	rx-num-evt = <1>;
+};
diff --git a/Documentation/devicetree/bindings/sound/omap-abe-twl6040.txt b/Documentation/devicetree/bindings/sound/omap-abe-twl6040.txt
new file mode 100644
index 0000000..65dec87
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/omap-abe-twl6040.txt
@@ -0,0 +1,91 @@
+* Texas Instruments OMAP4+ and twl6040 based audio setups
+
+Required properties:
+- compatible: "ti,abe-twl6040"
+- ti,model: Name of the sound card ( for example "SDP4430")
+- ti,mclk-freq: MCLK frequency for HPPLL operation
+- ti,mcpdm: phandle for the McPDM node
+- ti,twl6040: phandle for the twl6040 core node
+- ti,audio-routing: List of connections between audio components.
+  Each entry is a pair of strings, the first being the connection's sink,
+  the second being the connection's source.
+
+Optional properties:
+- ti,dmic: phandle for the OMAP dmic node if the machine have it connected
+- ti,jack_detection: Need to be set to <1> if the board capable to detect jack
+  insertion, removal.
+
+Available audio endpoints for the audio-routing table:
+
+Board connectors:
+ * Headset Stereophone
+ * Earphone Spk
+ * Ext Spk
+ * Line Out
+ * Vibrator
+ * Headset Mic
+ * Main Handset Mic
+ * Sub Handset Mic
+ * Line In
+ * Digital Mic
+
+twl6040 pins:
+ * HSOL
+ * HSOR
+ * EP
+ * HFL
+ * HFR
+ * AUXL
+ * AUXR
+ * VIBRAL
+ * VIBRAR
+ * HSMIC
+ * MAINMIC
+ * SUBMIC
+ * AFML
+ * AFMR
+
+ * Headset Mic Bias
+ * Main Mic Bias
+ * Digital Mic1 Bias
+ * Digital Mic2 Bias
+
+Digital mic pins:
+ * DMic
+
+Example:
+
+sound {
+	compatible = "ti,abe-twl6040";
+	ti,model = "SDP4430";
+
+	ti,jack-detection = <1>;
+	ti,mclk-freq = <38400000>;
+
+	ti,mcpdm = <&mcpdm>;
+	ti,dmic = <&dmic>;
+
+	ti,twl6040 = <&twl6040>;
+
+	/* Audio routing */
+	ti,audio-routing =
+		"Headset Stereophone", "HSOL",
+		"Headset Stereophone", "HSOR",
+		"Earphone Spk", "EP",
+		"Ext Spk", "HFL",
+		"Ext Spk", "HFR",
+		"Line Out", "AUXL",
+		"Line Out", "AUXR",
+		"Vibrator", "VIBRAL",
+		"Vibrator", "VIBRAR",
+		"HSMIC", "Headset Mic",
+		"Headset Mic", "Headset Mic Bias",
+		"MAINMIC", "Main Handset Mic",
+		"Main Handset Mic", "Main Mic Bias",
+		"SUBMIC", "Sub Handset Mic",
+		"Sub Handset Mic", "Main Mic Bias",
+		"AFML", "Line In",
+		"AFMR", "Line In",
+		"DMic", "Digital Mic",
+		"Digital Mic", "Digital Mic1 Bias";
+};
diff --git a/Documentation/devicetree/bindings/sound/omap-mcbsp.txt b/Documentation/devicetree/bindings/sound/omap-mcbsp.txt
new file mode 100644
index 0000000..17cce44
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/omap-mcbsp.txt
@@ -0,0 +1,37 @@
+* Texas Instruments OMAP2+ McBSP module
+
+Required properties:
+- compatible: "ti,omap2420-mcbsp" for McBSP on OMAP2420
+	      "ti,omap2430-mcbsp" for McBSP on OMAP2430
+	      "ti,omap3-mcbsp" for McBSP on OMAP3
+	      "ti,omap4-mcbsp" for McBSP on OMAP4 and newer SoC
+- reg: Register location and size, for OMAP4+ as an array:
+       <MPU access base address, size>,
+       <L3 interconnect address, size>;
+- reg-names: Array of strings associated with the address space
+- interrupts: Interrupt numbers for the McBSP port, as an array in case the
+	      McBSP IP have more interrupt lines:
+	<OCP compliant irq>,
+	<TX irq>,
+	<RX irq>;
+- interrupt-names: Array of strings associated with the interrupt numbers
+- interrupt-parent: The parent interrupt controller
+- ti,buffer-size: Size of the FIFO on the port (OMAP2430 and newer SoC)
+- ti,hwmods: Name of the hwmod associated to the McBSP port
+
+Example:
+
+mcbsp2: mcbsp@49022000 {
+	compatible = "ti,omap3-mcbsp";
+	reg = <0x49022000 0xff>,
+	      <0x49028000 0xff>;
+	reg-names = "mpu", "sidetone";
+	interrupts = <0 17 0x4>, /* OCP compliant interrupt */
+		     <0 62 0x4>, /* TX interrupt */
+		     <0 63 0x4>, /* RX interrupt */
+		     <0 4 0x4>;  /* Sidetone */
+	interrupt-names = "common", "tx", "rx", "sidetone";
+	interrupt-parent = <&intc>;
+	ti,buffer-size = <1280>;
+	ti,hwmods = "mcbsp2";
+};
diff --git a/Documentation/devicetree/bindings/sound/omap-twl4030.txt b/Documentation/devicetree/bindings/sound/omap-twl4030.txt
new file mode 100644
index 0000000..6fae51c
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/omap-twl4030.txt
@@ -0,0 +1,17 @@
+* Texas Instruments SoC with twl4030 based audio setups
+
+Required properties:
+- compatible: "ti,omap-twl4030"
+- ti,model: Name of the sound card (for example "omap3beagle")
+- ti,mcbsp: phandle for the McBSP node
+- ti,codec: phandle for the twl4030 audio node
+
+Example:
+
+sound {
+	compatible = "ti,omap-twl4030";
+	ti,model = "omap3beagle";
+
+	ti,mcbsp = <&mcbsp2>;
+	ti,codec = <&twl_audio>;
+};
diff --git a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt
new file mode 100644
index 0000000..e7b98f4
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt
@@ -0,0 +1,20 @@
+Texas Instruments - tlv320aic3x Codec module
+
+The tlv320aic3x serial control bus communicates through I2C protocols
+
+Required properties:
+- compatible - "string" -  "ti,tlv320aic3x"
+- reg - <int> -  I2C slave address
+
+
+Optional properties:
+
+- gpio-reset - gpio pin number used for codec reset
+- ai3x-gpio-func - <array of 2 int> - AIC3X_GPIO1 & AIC3X_GPIO2 Functionality
+
+Example:
+
+tlv320aic3x: tlv320aic3x@1b {
+	compatible = "ti,tlv320aic3x";
+	reg = <0x1b>;
+};
diff --git a/Documentation/devicetree/bindings/spi/spi-octeon.txt b/Documentation/devicetree/bindings/spi/spi-octeon.txt
new file mode 100644
index 0000000..431add1
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/spi-octeon.txt
@@ -0,0 +1,33 @@
+Cavium, Inc. OCTEON SOC SPI master controller.
+
+Required properties:
+- compatible : "cavium,octeon-3010-spi"
+- reg : The register base for the controller.
+- interrupts : One interrupt, used by the controller.
+- #address-cells : <1>, as required by generic SPI binding.
+- #size-cells : <0>, also as required by generic SPI binding.
+
+Child nodes as per the generic SPI binding.
+
+Example:
+
+	spi@1070000001000 {
+		compatible = "cavium,octeon-3010-spi";
+		reg = <0x10700 0x00001000 0x0 0x100>;
+		interrupts = <0 58>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		eeprom@0 {
+			compatible = "st,m95256", "atmel,at25";
+			reg = <0>;
+			spi-max-frequency = <5000000>;
+			spi-cpha;
+			spi-cpol;
+
+			pagesize = <64>;
+			size = <32768>;
+			address-width = <16>;
+		};
+	};
+
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index 950856b..43cff70 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -284,3 +284,7 @@
 PINCTRL
   devm_pinctrl_get()
   devm_pinctrl_put()
+
+PWM
+  devm_pwm_get()
+  devm_pwm_put()
diff --git a/Documentation/filesystems/ext4.txt b/Documentation/filesystems/ext4.txt
index 1b7f9ac..104322b 100644
--- a/Documentation/filesystems/ext4.txt
+++ b/Documentation/filesystems/ext4.txt
@@ -375,6 +375,16 @@
 			Because of the restrictions this options comprises
 			it is off by default (e.g. dioread_lock).
 
+max_dir_size_kb=n	This limits the size of directories so that any
+			attempt to expand them beyond the specified
+			limit in kilobytes will cause an ENOSPC error.
+			This is useful in memory constrained
+			environments, where a very large directory can
+			cause severe performance problems or even
+			provoke the Out Of Memory killer.  (For example,
+			if there is only 512mb memory available, a 176mb
+			directory may seriously cramp the system's style.)
+
 i_version		Enable 64-bit inode version support. This option is
 			off by default.
 
diff --git a/Documentation/filesystems/nfs/nfs.txt b/Documentation/filesystems/nfs/nfs.txt
index f50f26c..f2571c8 100644
--- a/Documentation/filesystems/nfs/nfs.txt
+++ b/Documentation/filesystems/nfs/nfs.txt
@@ -12,9 +12,47 @@
 protocol.
 
 The purpose of this document is to provide information on some of the
-upcall interfaces that are used in order to provide the NFS client with
-some of the information that it requires in order to fully comply with
-the NFS spec.
+special features of the NFS client that can be configured by system
+administrators.
+
+
+The nfs4_unique_id parameter
+============================
+
+NFSv4 requires clients to identify themselves to servers with a unique
+string.  File open and lock state shared between one client and one server
+is associated with this identity.  To support robust NFSv4 state recovery
+and transparent state migration, this identity string must not change
+across client reboots.
+
+Without any other intervention, the Linux client uses a string that contains
+the local system's node name.  System administrators, however, often do not
+take care to ensure that node names are fully qualified and do not change
+over the lifetime of a client system.  Node names can have other
+administrative requirements that require particular behavior that does not
+work well as part of an nfs_client_id4 string.
+
+The nfs.nfs4_unique_id boot parameter specifies a unique string that can be
+used instead of a system's node name when an NFS client identifies itself to
+a server.  Thus, if the system's node name is not unique, or it changes, its
+nfs.nfs4_unique_id stays the same, preventing collision with other clients
+or loss of state during NFS reboot recovery or transparent state migration.
+
+The nfs.nfs4_unique_id string is typically a UUID, though it can contain
+anything that is believed to be unique across all NFS clients.  An
+nfs4_unique_id string should be chosen when a client system is installed,
+just as a system's root file system gets a fresh UUID in its label at
+install time.
+
+The string should remain fixed for the lifetime of the client.  It can be
+changed safely if care is taken that the client shuts down cleanly and all
+outstanding NFSv4 state has expired, to prevent loss of NFSv4 state.
+
+This string can be stored in an NFS client's grub.conf, or it can be provided
+via a net boot facility such as PXE.  It may also be specified as an nfs.ko
+module parameter.  Specifying a uniquifier string is not support for NFS
+clients running in containers.
+
 
 The DNS resolver
 ================
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index fb0a6ae..a1793d6 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -33,7 +33,7 @@
   2	Modifying System Parameters
 
   3	Per-Process Parameters
-  3.1	/proc/<pid>/oom_adj & /proc/<pid>/oom_score_adj - Adjust the oom-killer
+  3.1	/proc/<pid>/oom_score_adj - Adjust the oom-killer
 								score
   3.2	/proc/<pid>/oom_score - Display current oom-killer score
   3.3	/proc/<pid>/io - Display the IO accounting fields
@@ -1320,10 +1320,10 @@
 CHAPTER 3: PER-PROCESS PARAMETERS
 ------------------------------------------------------------------------------
 
-3.1 /proc/<pid>/oom_adj & /proc/<pid>/oom_score_adj- Adjust the oom-killer score
+3.1 /proc/<pid>/oom_score_adj- Adjust the oom-killer score
 --------------------------------------------------------------------------------
 
-These file can be used to adjust the badness heuristic used to select which
+This file can be used to adjust the badness heuristic used to select which
 process gets killed in out of memory conditions.
 
 The badness heuristic assigns a value to each candidate task ranging from 0
@@ -1361,22 +1361,10 @@
 equivalent to discounting 50% of the task's allowed memory from being considered
 as scoring against the task.
 
-For backwards compatibility with previous kernels, /proc/<pid>/oom_adj may also
-be used to tune the badness score.  Its acceptable values range from -16
-(OOM_ADJUST_MIN) to +15 (OOM_ADJUST_MAX) and a special value of -17
-(OOM_DISABLE) to disable oom killing entirely for that task.  Its value is
-scaled linearly with /proc/<pid>/oom_score_adj.
-
-Writing to /proc/<pid>/oom_score_adj or /proc/<pid>/oom_adj will change the
-other with its scaled value.
-
 The value of /proc/<pid>/oom_score_adj may be reduced no lower than the last
 value set by a CAP_SYS_RESOURCE process. To reduce the value any lower
 requires CAP_SYS_RESOURCE.
 
-NOTICE: /proc/<pid>/oom_adj is deprecated and will be removed, please see
-Documentation/feature-removal-schedule.txt.
-
 Caveat: when a parent task is selected, the oom killer will sacrifice any first
 generation children with separate address spaces instead, if possible.  This
 avoids servers and important system daemons from being killed and loses the
@@ -1387,9 +1375,7 @@
 -------------------------------------------------------------
 
 This file can be used to check the current score used by the oom-killer is for
-any given <pid>. Use it together with /proc/<pid>/oom_adj to tune which
-process should be killed in an out-of-memory situation.
-
+any given <pid>.
 
 3.3  /proc/<pid>/io - Display the IO accounting fields
 -------------------------------------------------------
diff --git a/Documentation/hwmon/da9052 b/Documentation/hwmon/da9052
index ef89855..5bc5134 100644
--- a/Documentation/hwmon/da9052
+++ b/Documentation/hwmon/da9052
@@ -56,6 +56,6 @@
 The junction temperature attribute is supported by the driver.
 
 The battery temperature is calculated:
-	Degree Celcius = 1 / (t1 + 1/298)- 273
+	Degree Celsius = 1 / (t1 + 1/298)- 273
 where t1 = (1/B)* ln(( ADCval * 2.5)/(R25*ITBAT*255))
 Default values of R25, B, ITBAT are 10e3, 3380 and 50e-6 respectively.
diff --git a/Documentation/hwmon/max1619 b/Documentation/hwmon/max1619
index d6f8d9c..e6d8739 100644
--- a/Documentation/hwmon/max1619
+++ b/Documentation/hwmon/max1619
@@ -9,7 +9,7 @@
                http://pdfserv.maxim-ic.com/en/ds/MAX1619.pdf
 
 Authors:
-        Alexey Fisher <fishor@mail.ru>,
+        Oleksij Rempel <bug-track@fisher-privat.net>,
         Jean Delvare <khali@linux-fr.org>
 
 Description
diff --git a/Documentation/hwmon/twl4030-madc-hwmon b/Documentation/hwmon/twl4030-madc-hwmon
index ef79843..c3a3a5b 100644
--- a/Documentation/hwmon/twl4030-madc-hwmon
+++ b/Documentation/hwmon/twl4030-madc-hwmon
@@ -41,5 +41,5 @@
 
 The Sysfs nodes will represent the voltage in the units of mV,
 the temperature channel shows the converted temperature in
-degree celcius. The Battery charging current channel represents
+degree Celsius. The Battery charging current channel represents
 battery charging current in mA.
diff --git a/Documentation/i2c/busses/i2c-viapro b/Documentation/i2c/busses/i2c-viapro
index 2e758b0..b88f91a 100644
--- a/Documentation/i2c/busses/i2c-viapro
+++ b/Documentation/i2c/busses/i2c-viapro
@@ -20,7 +20,10 @@
     Datasheet: available on http://linux.via.com.tw
 
   * VIA Technologies, Inc. VX855/VX875
-    Datasheet: Availability unknown
+    Datasheet: available on http://linux.via.com.tw
+
+  * VIA Technologies, Inc. VX900
+    Datasheet: available on http://linux.via.com.tw
 
 Authors:
 	Kyösti Mälkki <kmalkki@cc.hut.fi>,
@@ -57,6 +60,7 @@
  device 1106:8324   (CX700)
  device 1106:8353   (VX800/VX820)
  device 1106:8409   (VX855/VX875)
+ device 1106:8410   (VX900)
 
 If none of these show up, you should look in the BIOS for settings like
 enable ACPI / SMBus or even USB.
diff --git a/Documentation/i2c/muxes/i2c-mux-gpio b/Documentation/i2c/muxes/i2c-mux-gpio
index bd9b229..d4d91a5 100644
--- a/Documentation/i2c/muxes/i2c-mux-gpio
+++ b/Documentation/i2c/muxes/i2c-mux-gpio
@@ -63,3 +63,21 @@
 		.platform_data	= &myboard_i2cmux_data,
 	},
 };
+
+If you don't know the absolute GPIO pin numbers at registration time,
+you can instead provide a chip name (.chip_name) and relative GPIO pin
+numbers, and the i2c-gpio-mux driver will do the work for you,
+including deferred probing if the GPIO chip isn't immediately
+available.
+
+Device Registration
+-------------------
+
+When registering your i2c-gpio-mux device, you should pass the number
+of any GPIO pin it uses as the device ID. This guarantees that every
+instance has a different ID.
+
+Alternatively, if you don't need a stable device name, you can simply
+pass PLATFORM_DEVID_AUTO as the device ID, and the platform core will
+assign a dynamic ID to your device. If you do not know the absolute
+GPIO pin numbers at registration time, this is even the only option.
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index f777fa9..e2ed336 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1730,6 +1730,11 @@
 			will be autodetected by the client, and it will fall
 			back to using the idmapper.
 			To turn off this behaviour, set the value to '0'.
+	nfs.nfs4_unique_id=
+			[NFS4] Specify an additional fixed unique ident-
+			ification string that NFSv4 clients can insert into
+			their nfs_client_id4 string.  This is typically a
+			UUID that is generated at system install time.
 
 	nfs.send_implementation_id =
 			[NFSv4.1] Send client implementation identification
diff --git a/Documentation/leds/leds-lp5523.txt b/Documentation/leds/leds-lp5523.txt
index fad2feb..c2743f5 100644
--- a/Documentation/leds/leds-lp5523.txt
+++ b/Documentation/leds/leds-lp5523.txt
@@ -10,8 +10,22 @@
 Description
 -----------
 LP5523 can drive up to 9 channels. Leds can be controlled directly via
-the led class control interface. Channels have generic names:
-lp5523:channelx where x is 0...8
+the led class control interface.
+The name of each channel is configurable in the platform data - name and label.
+There are three options to make the channel name.
+
+a) Define the 'name' in the platform data
+To make specific channel name, then use 'name' platform data.
+/sys/class/leds/R1               (name: 'R1')
+/sys/class/leds/B1               (name: 'B1')
+
+b) Use the 'label' with no 'name' field
+For one device name with channel number, then use 'label'.
+/sys/class/leds/RGB:channelN     (label: 'RGB', N: 0 ~ 8)
+
+c) Default
+If both fields are NULL, 'lp5523' is used by default.
+/sys/class/leds/lp5523:channelN  (N: 0 ~ 8)
 
 The chip provides 3 engines. Each engine can control channels without
 interaction from the main CPU. Details of the micro engine code can be found
@@ -46,12 +60,13 @@
 
 static struct lp5523_led_config lp5523_led_config[] = {
         {
+		.name		= "D1",
                 .chan_nr        = 0,
                 .led_current    = 50,
 		.max_current    = 130,
         },
 ...
-        }, {
+        {
                 .chan_nr        = 8,
                 .led_current    = 50,
 		.max_current    = 130,
diff --git a/Documentation/memory.txt b/Documentation/memory.txt
deleted file mode 100644
index 802efe5..0000000
--- a/Documentation/memory.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-There are several classic problems related to memory on Linux
-systems.
-
-	1) There are some motherboards that will not cache above
-	   a certain quantity of memory.  If you have one of these
-	   motherboards, your system will be SLOWER, not faster
-	   as you add more memory.  Consider exchanging your 
-           motherboard.
-
-All of these problems can be addressed with the "mem=XXXM" boot option
-(where XXX is the size of RAM to use in megabytes).  
-It can also tell Linux to use less memory than is actually installed.
-If you use "mem=" on a machine with PCI, consider using "memmap=" to avoid
-physical address space collisions.
-
-See the documentation of your boot loader (LILO, grub, loadlin, etc.) about
-how to pass options to the kernel.
-
-There are other memory problems which Linux cannot deal with.  Random
-corruption of memory is usually a sign of serious hardware trouble.
-Try:
-
-	* Reducing memory settings in the BIOS to the most conservative 
-          timings.
-
-	* Adding a cooling fan.
-
-	* Not overclocking your CPU.
-
-	* Having the memory tested in a memory tester or exchanged
-	  with the vendor. Consider testing it with memtest86 yourself.
-	
-	* Exchanging your CPU, cache, or motherboard for one that works.
diff --git a/Documentation/percpu-rw-semaphore.txt b/Documentation/percpu-rw-semaphore.txt
new file mode 100644
index 0000000..7d3c824
--- /dev/null
+++ b/Documentation/percpu-rw-semaphore.txt
@@ -0,0 +1,27 @@
+Percpu rw semaphores
+--------------------
+
+Percpu rw semaphores is a new read-write semaphore design that is
+optimized for locking for reading.
+
+The problem with traditional read-write semaphores is that when multiple
+cores take the lock for reading, the cache line containing the semaphore
+is bouncing between L1 caches of the cores, causing performance
+degradation.
+
+Locking for reading is very fast, it uses RCU and it avoids any atomic
+instruction in the lock and unlock path. On the other hand, locking for
+writing is very expensive, it calls synchronize_rcu() that can take
+hundreds of milliseconds.
+
+The lock is declared with "struct percpu_rw_semaphore" type.
+The lock is initialized percpu_init_rwsem, it returns 0 on success and
+-ENOMEM on allocation failure.
+The lock must be freed with percpu_free_rwsem to avoid memory leak.
+
+The lock is locked for read with percpu_down_read, percpu_up_read and
+for write with percpu_down_write, percpu_up_write.
+
+The idea of using RCU for optimized rw-lock was introduced by
+Eric Dumazet <eric.dumazet@gmail.com>.
+The code was written by Mikulas Patocka <mpatocka@redhat.com>
diff --git a/Documentation/prio_tree.txt b/Documentation/prio_tree.txt
deleted file mode 100644
index 3aa68f9..0000000
--- a/Documentation/prio_tree.txt
+++ /dev/null
@@ -1,107 +0,0 @@
-The prio_tree.c code indexes vmas using 3 different indexes:
-	* heap_index  = vm_pgoff + vm_size_in_pages : end_vm_pgoff
-	* radix_index = vm_pgoff : start_vm_pgoff
-	* size_index = vm_size_in_pages
-
-A regular radix-priority-search-tree indexes vmas using only heap_index and
-radix_index. The conditions for indexing are:
-	* ->heap_index >= ->left->heap_index &&
-		->heap_index >= ->right->heap_index
-	* if (->heap_index == ->left->heap_index)
-		then ->radix_index < ->left->radix_index;
-	* if (->heap_index == ->right->heap_index)
-		then ->radix_index < ->right->radix_index;
-	* nodes are hashed to left or right subtree using radix_index
-	  similar to a pure binary radix tree.
-
-A regular radix-priority-search-tree helps to store and query
-intervals (vmas). However, a regular radix-priority-search-tree is only
-suitable for storing vmas with different radix indices (vm_pgoff).
-
-Therefore, the prio_tree.c extends the regular radix-priority-search-tree
-to handle many vmas with the same vm_pgoff. Such vmas are handled in
-2 different ways: 1) All vmas with the same radix _and_ heap indices are
-linked using vm_set.list, 2) if there are many vmas with the same radix
-index, but different heap indices and if the regular radix-priority-search
-tree cannot index them all, we build an overflow-sub-tree that indexes such
-vmas using heap and size indices instead of heap and radix indices. For
-example, in the figure below some vmas with vm_pgoff = 0 (zero) are
-indexed by regular radix-priority-search-tree whereas others are pushed
-into an overflow-subtree. Note that all vmas in an overflow-sub-tree have
-the same vm_pgoff (radix_index) and if necessary we build different
-overflow-sub-trees to handle each possible radix_index. For example,
-in figure we have 3 overflow-sub-trees corresponding to radix indices
-0, 2, and 4.
-
-In the final tree the first few (prio_tree_root->index_bits) levels
-are indexed using heap and radix indices whereas the overflow-sub-trees below
-those levels (i.e. levels prio_tree_root->index_bits + 1 and higher) are
-indexed using heap and size indices. In overflow-sub-trees the size_index
-is used for hashing the nodes to appropriate places.
-
-Now, an example prio_tree:
-
-  vmas are represented [radix_index, size_index, heap_index]
-                 i.e., [start_vm_pgoff, vm_size_in_pages, end_vm_pgoff]
-
-level  prio_tree_root->index_bits = 3
------
-												_
-  0			 				[0,7,7]					 |
-  							/     \					 |
-				      ------------------       ------------			 |     Regular
-  				     /					   \			 |  radix priority
-  1		 		[1,6,7]					  [4,3,7]		 |   search tree
-  				/     \					  /     \		 |
-			 -------       -----			    ------       -----		 |  heap-and-radix
-			/		    \			   /		      \		 |      indexed
-  2		    [0,6,6]	 	   [2,5,7]		[5,2,7]		    [6,1,7]	 |
-		    /     \		   /     \		/     \		    /     \	 |
-  3		[0,5,5]	[1,5,6]		[2,4,6]	[3,4,7]	    [4,2,6] [5,1,6]	[6,0,6]	[7,0,7]	 |
-		   /			   /		       /		   		_
-                  /		          /		      /					_
-  4	      [0,4,4]		      [2,3,5]		   [4,1,5]				 |
-  		 /			 /		      /					 |
-  5	     [0,3,3]		     [2,2,4]		  [4,0,4]				 |  Overflow-sub-trees
-  		/			/							 |
-  6	    [0,2,2]		    [2,1,3]							 |    heap-and-size
-  	       /		       /							 |       indexed
-  7	   [0,1,1]		   [2,0,2]							 |
-  	      /											 |
-  8	  [0,0,0]										 |
-  												_
-
-Note that we use prio_tree_root->index_bits to optimize the height
-of the heap-and-radix indexed tree. Since prio_tree_root->index_bits is
-set according to the maximum end_vm_pgoff mapped, we are sure that all
-bits (in vm_pgoff) above prio_tree_root->index_bits are 0 (zero). Therefore,
-we only use the first prio_tree_root->index_bits as radix_index.
-Whenever index_bits is increased in prio_tree_expand, we shuffle the tree
-to make sure that the first prio_tree_root->index_bits levels of the tree
-is indexed properly using heap and radix indices.
-
-We do not optimize the height of overflow-sub-trees using index_bits.
-The reason is: there can be many such overflow-sub-trees and all of
-them have to be suffled whenever the index_bits increases. This may involve
-walking the whole prio_tree in prio_tree_insert->prio_tree_expand code
-path which is not desirable. Hence, we do not optimize the height of the
-heap-and-size indexed overflow-sub-trees using prio_tree->index_bits.
-Instead the overflow sub-trees are indexed using full BITS_PER_LONG bits
-of size_index. This may lead to skewed sub-trees because most of the
-higher significant bits of the size_index are likely to be 0 (zero). In
-the example above, all 3 overflow-sub-trees are skewed. This may marginally
-affect the performance. However, processes rarely map many vmas with the
-same start_vm_pgoff but different end_vm_pgoffs. Therefore, we normally
-do not require overflow-sub-trees to index all vmas.
-
-From the above discussion it is clear that the maximum height of
-a prio_tree can be prio_tree_root->index_bits + BITS_PER_LONG.
-However, in most of the common cases we do not need overflow-sub-trees,
-so the tree height in the common cases will be prio_tree_root->index_bits.
-
-It is fair to mention here that the prio_tree_root->index_bits
-is increased on demand, however, the index_bits is not decreased when
-vmas are removed from the prio_tree. That's tricky to do. Hence, it's
-left as a home work problem.
-
-
diff --git a/Documentation/pwm.txt b/Documentation/pwm.txt
index 554290e..7d2b4c9 100644
--- a/Documentation/pwm.txt
+++ b/Documentation/pwm.txt
@@ -36,7 +36,8 @@
 after usage with pwm_free().
 
 New users should use the pwm_get() function and pass to it the consumer
-device or a consumer name. pwm_put() is used to free the PWM device.
+device or a consumer name. pwm_put() is used to free the PWM device. Managed
+variants of these functions, devm_pwm_get() and devm_pwm_put(), also exist.
 
 After being requested a PWM has to be configured using:
 
diff --git a/Documentation/rbtree.txt b/Documentation/rbtree.txt
index 8d32d85..61b6c48 100644
--- a/Documentation/rbtree.txt
+++ b/Documentation/rbtree.txt
@@ -193,24 +193,55 @@
 Support for Augmented rbtrees
 -----------------------------
 
-Augmented rbtree is an rbtree with "some" additional data stored in each node.
-This data can be used to augment some new functionality to rbtree.
-Augmented rbtree is an optional feature built on top of basic rbtree
-infrastructure. An rbtree user who wants this feature will have to call the
-augmentation functions with the user provided augmentation callback
-when inserting and erasing nodes.
+Augmented rbtree is an rbtree with "some" additional data stored in
+each node, where the additional data for node N must be a function of
+the contents of all nodes in the subtree rooted at N. This data can
+be used to augment some new functionality to rbtree. Augmented rbtree
+is an optional feature built on top of basic rbtree infrastructure.
+An rbtree user who wants this feature will have to call the augmentation
+functions with the user provided augmentation callback when inserting
+and erasing nodes.
 
-On insertion, the user must call rb_augment_insert() once the new node is in
-place. This will cause the augmentation function callback to be called for
-each node between the new node and the root which has been affected by the
-insertion.
+C files implementing augmented rbtree manipulation must include
+<linux/rbtree_augmented.h> instead of <linus/rbtree.h>. Note that
+linux/rbtree_augmented.h exposes some rbtree implementations details
+you are not expected to rely on; please stick to the documented APIs
+there and do not include <linux/rbtree_augmented.h> from header files
+either so as to minimize chances of your users accidentally relying on
+such implementation details.
 
-When erasing a node, the user must call rb_augment_erase_begin() first to
-retrieve the deepest node on the rebalance path. Then, after erasing the
-original node, the user must call rb_augment_erase_end() with the deepest
-node found earlier. This will cause the augmentation function to be called
-for each affected node between the deepest node and the root.
+On insertion, the user must update the augmented information on the path
+leading to the inserted node, then call rb_link_node() as usual and
+rb_augment_inserted() instead of the usual rb_insert_color() call.
+If rb_augment_inserted() rebalances the rbtree, it will callback into
+a user provided function to update the augmented information on the
+affected subtrees.
 
+When erasing a node, the user must call rb_erase_augmented() instead of
+rb_erase(). rb_erase_augmented() calls back into user provided functions
+to updated the augmented information on affected subtrees.
+
+In both cases, the callbacks are provided through struct rb_augment_callbacks.
+3 callbacks must be defined:
+
+- A propagation callback, which updates the augmented value for a given
+  node and its ancestors, up to a given stop point (or NULL to update
+  all the way to the root).
+
+- A copy callback, which copies the augmented value for a given subtree
+  to a newly assigned subtree root.
+
+- A tree rotation callback, which copies the augmented value for a given
+  subtree to a newly assigned subtree root AND recomputes the augmented
+  information for the former subtree root.
+
+The compiled code for rb_erase_augmented() may inline the propagation and
+copy callbacks, which results in a large function, so each augmented rbtree
+user should have a single rb_erase_augmented() call site in order to limit
+compiled code size.
+
+
+Sample usage:
 
 Interval tree is an example of augmented rb tree. Reference -
 "Introduction to Algorithms" by Cormen, Leiserson, Rivest and Stein.
@@ -230,26 +261,132 @@
 for lowest match (lowest start address among all possible matches)
 with something like:
 
-find_lowest_match(lo, hi, node)
+struct interval_tree_node *
+interval_tree_first_match(struct rb_root *root,
+			  unsigned long start, unsigned long last)
 {
-	lowest_match = NULL;
-	while (node) {
-		if (max_hi(node->left) > lo) {
-			// Lowest overlap if any must be on left side
-			node = node->left;
-		} else if (overlap(lo, hi, node)) {
-			lowest_match = node;
-			break;
-		} else if (lo > node->lo) {
-			// Lowest overlap if any must be on right side
-			node = node->right;
-		} else {
-			break;
+	struct interval_tree_node *node;
+
+	if (!root->rb_node)
+		return NULL;
+	node = rb_entry(root->rb_node, struct interval_tree_node, rb);
+
+	while (true) {
+		if (node->rb.rb_left) {
+			struct interval_tree_node *left =
+				rb_entry(node->rb.rb_left,
+					 struct interval_tree_node, rb);
+			if (left->__subtree_last >= start) {
+				/*
+				 * Some nodes in left subtree satisfy Cond2.
+				 * Iterate to find the leftmost such node N.
+				 * If it also satisfies Cond1, that's the match
+				 * we are looking for. Otherwise, there is no
+				 * matching interval as nodes to the right of N
+				 * can't satisfy Cond1 either.
+				 */
+				node = left;
+				continue;
+			}
 		}
+		if (node->start <= last) {		/* Cond1 */
+			if (node->last >= start)	/* Cond2 */
+				return node;	/* node is leftmost match */
+			if (node->rb.rb_right) {
+				node = rb_entry(node->rb.rb_right,
+					struct interval_tree_node, rb);
+				if (node->__subtree_last >= start)
+					continue;
+			}
+		}
+		return NULL;	/* No match */
 	}
-	return lowest_match;
 }
 
-Finding exact match will be to first find lowest match and then to follow
-successor nodes looking for exact match, until the start of a node is beyond
-the hi value we are looking for.
+Insertion/removal are defined using the following augmented callbacks:
+
+static inline unsigned long
+compute_subtree_last(struct interval_tree_node *node)
+{
+	unsigned long max = node->last, subtree_last;
+	if (node->rb.rb_left) {
+		subtree_last = rb_entry(node->rb.rb_left,
+			struct interval_tree_node, rb)->__subtree_last;
+		if (max < subtree_last)
+			max = subtree_last;
+	}
+	if (node->rb.rb_right) {
+		subtree_last = rb_entry(node->rb.rb_right,
+			struct interval_tree_node, rb)->__subtree_last;
+		if (max < subtree_last)
+			max = subtree_last;
+	}
+	return max;
+}
+
+static void augment_propagate(struct rb_node *rb, struct rb_node *stop)
+{
+	while (rb != stop) {
+		struct interval_tree_node *node =
+			rb_entry(rb, struct interval_tree_node, rb);
+		unsigned long subtree_last = compute_subtree_last(node);
+		if (node->__subtree_last == subtree_last)
+			break;
+		node->__subtree_last = subtree_last;
+		rb = rb_parent(&node->rb);
+	}
+}
+
+static void augment_copy(struct rb_node *rb_old, struct rb_node *rb_new)
+{
+	struct interval_tree_node *old =
+		rb_entry(rb_old, struct interval_tree_node, rb);
+	struct interval_tree_node *new =
+		rb_entry(rb_new, struct interval_tree_node, rb);
+
+	new->__subtree_last = old->__subtree_last;
+}
+
+static void augment_rotate(struct rb_node *rb_old, struct rb_node *rb_new)
+{
+	struct interval_tree_node *old =
+		rb_entry(rb_old, struct interval_tree_node, rb);
+	struct interval_tree_node *new =
+		rb_entry(rb_new, struct interval_tree_node, rb);
+
+	new->__subtree_last = old->__subtree_last;
+	old->__subtree_last = compute_subtree_last(old);
+}
+
+static const struct rb_augment_callbacks augment_callbacks = {
+	augment_propagate, augment_copy, augment_rotate
+};
+
+void interval_tree_insert(struct interval_tree_node *node,
+			  struct rb_root *root)
+{
+	struct rb_node **link = &root->rb_node, *rb_parent = NULL;
+	unsigned long start = node->start, last = node->last;
+	struct interval_tree_node *parent;
+
+	while (*link) {
+		rb_parent = *link;
+		parent = rb_entry(rb_parent, struct interval_tree_node, rb);
+		if (parent->__subtree_last < last)
+			parent->__subtree_last = last;
+		if (start < parent->start)
+			link = &parent->rb.rb_left;
+		else
+			link = &parent->rb.rb_right;
+	}
+
+	node->__subtree_last = last;
+	rb_link_node(&node->rb, rb_parent, link);
+	rb_insert_augmented(&node->rb, root, &augment_callbacks);
+}
+
+void interval_tree_remove(struct interval_tree_node *node,
+			  struct rb_root *root)
+{
+	rb_erase_augmented(&node->rb, root, &augment_callbacks);
+}
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 4e4d0bc..d90d8ec 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -860,8 +860,14 @@
 
     [Multiple options for each card instance]
     model	- force the model name
-    position_fix - Fix DMA pointer (0 = auto, 1 = use LPIB, 2 = POSBUF,
-    		   3 = VIACOMBO, 4 = COMBO)
+    position_fix - Fix DMA pointer
+		  -1 = system default: choose appropriate one per controller
+			hardware
+		  0 = auto: falls back to LPIB when POSBUF doesn't work
+		  1 = use LPIB
+		  2 = POSBUF: use position buffer
+		  3 = VIACOMBO: VIA-specific workaround for capture
+		  4 = COMBO: use LPIB for playback, auto for capture stream
     probe_mask  - Bitmask to probe codecs (default = -1, meaning all slots)
     		  When the bit 8 (0x100) is set, the lower 8 bits are used
 		  as the "fixed" codec slots; i.e. the driver probes the
diff --git a/Documentation/sound/alsa/Channel-Mapping-API.txt b/Documentation/sound/alsa/Channel-Mapping-API.txt
new file mode 100644
index 0000000..3c43d1a
--- /dev/null
+++ b/Documentation/sound/alsa/Channel-Mapping-API.txt
@@ -0,0 +1,153 @@
+ALSA PCM channel-mapping API
+============================
+					Takashi Iwai <tiwai@suse.de>
+
+GENERAL
+-------
+
+The channel mapping API allows user to query the possible channel maps
+and the current channel map, also optionally to modify the channel map
+of the current stream.
+
+A channel map is an array of position for each PCM channel.
+Typically, a stereo PCM stream has a channel map of
+  { front_left, front_right }
+while a 4.0 surround PCM stream has a channel map of
+  { front left, front right, rear left, rear right }.
+
+The problem, so far, was that we had no standard channel map
+explicitly, and applications had no way to know which channel
+corresponds to which (speaker) position.  Thus, applications applied
+wrong channels for 5.1 outputs, and you hear suddenly strange sound
+from rear.  Or, some devices secretly assume that center/LFE is the
+third/fourth channels while others that C/LFE as 5th/6th channels.
+
+Also, some devices such as HDMI are configurable for different speaker
+positions even with the same number of total channels.  However, there
+was no way to specify this because of lack of channel map
+specification.  These are the main motivations for the new channel
+mapping API.
+
+
+DESIGN
+------
+
+Actually, "the channel mapping API" doesn't introduce anything new in
+the kernel/user-space ABI perspective.  It uses only the existing
+control element features.
+
+As a ground design, each PCM substream may contain a control element
+providing the channel mapping information and configuration.  This
+element is specified by:
+	iface = SNDRV_CTL_ELEM_IFACE_PCM
+	name = "Playback Channel Map" or "Capture Channel Map"
+	device = the same device number for the assigned PCM substream
+	index = the same index number for the assigned PCM substream
+
+Note the name is different depending on the PCM substream direction.
+
+Each control element provides at least the TLV read operation and the
+read operation.  Optionally, the write operation can be provided to
+allow user to change the channel map dynamically.
+
+* TLV
+
+The TLV operation gives the list of available channel
+maps.  A list item of a channel map is usually a TLV of
+	type data-bytes ch0 ch1 ch2...
+where type is the TLV type value, the second argument is the total
+bytes (not the numbers) of channel values, and the rest are the
+position value for each channel.
+
+As a TLV type, either SNDRV_CTL_TLVT_CHMAP_FIXED,
+SNDRV_CTL_TLV_CHMAP_VAR or SNDRV_CTL_TLVT_CHMAP_PAIRED can be used.
+The _FIXED type is for a channel map with the fixed channel position
+while the latter two are for flexible channel positions.  _VAR type is
+for a channel map where all channels are freely swappable and _PAIRED
+type is where pair-wise channels are swappable.  For example, when you
+have {FL/FR/RL/RR} channel map, _PAIRED type would allow you to swap
+only {RL/RR/FL/FR} while _VAR type would allow even swapping FL and
+RR.
+
+These new TLV types are defined in sound/tlv.h.
+
+The available channel position values are defined in sound/asound.h,
+here is a cut:
+
+/* channel positions */
+enum {
+	SNDRV_CHMAP_UNKNOWN = 0,
+	SNDRV_CHMAP_NA,		/* N/A, silent */
+	SNDRV_CHMAP_MONO,	/* mono stream */
+	/* this follows the alsa-lib mixer channel value + 3 */
+	SNDRV_CHMAP_FL,		/* front left */
+	SNDRV_CHMAP_FR,		/* front right */
+	SNDRV_CHMAP_RL,		/* rear left */
+	SNDRV_CHMAP_RR,		/* rear right */
+	SNDRV_CHMAP_FC,		/* front center */
+	SNDRV_CHMAP_LFE,	/* LFE */
+	SNDRV_CHMAP_SL,		/* side left */
+	SNDRV_CHMAP_SR,		/* side right */
+	SNDRV_CHMAP_RC,		/* rear center */
+	/* new definitions */
+	SNDRV_CHMAP_FLC,	/* front left center */
+	SNDRV_CHMAP_FRC,	/* front right center */
+	SNDRV_CHMAP_RLC,	/* rear left center */
+	SNDRV_CHMAP_RRC,	/* rear right center */
+	SNDRV_CHMAP_FLW,	/* front left wide */
+	SNDRV_CHMAP_FRW,	/* front right wide */
+	SNDRV_CHMAP_FLH,	/* front left high */
+	SNDRV_CHMAP_FCH,	/* front center high */
+	SNDRV_CHMAP_FRH,	/* front right high */
+	SNDRV_CHMAP_TC,		/* top center */
+	SNDRV_CHMAP_TFL,	/* top front left */
+	SNDRV_CHMAP_TFR,	/* top front right */
+	SNDRV_CHMAP_TFC,	/* top front center */
+	SNDRV_CHMAP_TRL,	/* top rear left */
+	SNDRV_CHMAP_TRR,	/* top rear right */
+	SNDRV_CHMAP_TRC,	/* top rear center */
+	SNDRV_CHMAP_LAST = SNDRV_CHMAP_TRC,
+};
+
+When a PCM stream can provide more than one channel map, you can
+provide multiple channel maps in a TLV container type.  The TLV data
+to be returned will contain such as:
+	SNDRV_CTL_TLVT_CONTAINER 96
+	    SNDRV_CTL_TLVT_CHMAP_FIXED 4 SNDRV_CHMAP_FC
+	    SNDRV_CTL_TLVT_CHMAP_FIXED 8 SNDRV_CHMAP_FL SNDRV_CHMAP_FR
+	    SNDRV_CTL_TLVT_CHMAP_FIXED 16 NDRV_CHMAP_FL SNDRV_CHMAP_FR \
+		SNDRV_CHMAP_RL SNDRV_CHMAP_RR
+
+The channel position is provided in LSB 16bits.  The upper bits are
+used for bit flags.
+
+#define SNDRV_CHMAP_POSITION_MASK	0xffff
+#define SNDRV_CHMAP_PHASE_INVERSE	(0x01 << 16)
+#define SNDRV_CHMAP_DRIVER_SPEC		(0x02 << 16)
+
+SNDRV_CHMAP_PHASE_INVERSE indicates the channel is phase inverted,
+(thus summing left and right channels would result in almost silence).
+Some digital mic devices have this.
+
+When SNDRV_CHMAP_DRIVER_SPEC is set, all the channel position values
+don't follow the standard definition above but driver-specific.
+
+* READ OPERATION
+
+The control read operation is for providing the current channel map of
+the given stream.  The control element returns an integer array
+containing the position of each channel.
+
+When this is performed before the number of the channel is specified
+(i.e. hw_params is set), it should return all channels set to
+UNKNOWN.
+
+* WRITE OPERATION
+
+The control write operation is optional, and only for devices that can
+change the channel configuration on the fly, such as HDMI.  User needs
+to pass an integer value containing the valid channel positions for
+all channels of the assigned PCM substream.
+
+This operation is allowed only at PCM PREPARED state.  When called in
+other states, it shall return an error.
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt
index a92bba8..16dfe57 100644
--- a/Documentation/sound/alsa/HD-Audio-Models.txt
+++ b/Documentation/sound/alsa/HD-Audio-Models.txt
@@ -74,7 +74,8 @@
 
 AD1882 / AD1882A
 ================
-  3stack	3-stack mode (default)
+  3stack	3-stack mode
+  3stack-automute 3-stack with automute front HP (default)
   6stack	6-stack mode
 
 AD1884A / AD1883 / AD1984A / AD1984B
diff --git a/Documentation/target/tcm_mod_builder.py b/Documentation/target/tcm_mod_builder.py
index a78879b..3fe0d81 100755
--- a/Documentation/target/tcm_mod_builder.py
+++ b/Documentation/target/tcm_mod_builder.py
@@ -402,8 +402,6 @@
 	buf += "	.queue_data_in			= " + fabric_mod_name + "_queue_data_in,\n"
 	buf += "	.queue_status			= " + fabric_mod_name + "_queue_status,\n"
 	buf += "	.queue_tm_rsp			= " + fabric_mod_name + "_queue_tm_rsp,\n"
-	buf += "	.get_fabric_sense_len		= " + fabric_mod_name + "_get_fabric_sense_len,\n"
-	buf += "	.set_fabric_sense_len		= " + fabric_mod_name + "_set_fabric_sense_len,\n"
 	buf += "	.is_state_remove		= " + fabric_mod_name + "_is_state_remove,\n"
 	buf += "	/*\n"
 	buf += "	 * Setup function pointers for generic logic in target_core_fabric_configfs.c\n"
@@ -906,20 +904,6 @@
 			buf += "}\n\n"
 			bufi += "int " + fabric_mod_name + "_queue_tm_rsp(struct se_cmd *);\n"
 
-		if re.search('get_fabric_sense_len\)\(', fo):
-			buf += "u16 " + fabric_mod_name + "_get_fabric_sense_len(void)\n"
-			buf += "{\n"
-			buf += "	return 0;\n"
-			buf += "}\n\n"
-			bufi += "u16 " + fabric_mod_name + "_get_fabric_sense_len(void);\n"
-
-		if re.search('set_fabric_sense_len\)\(', fo):
-			buf += "u16 " + fabric_mod_name + "_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length)\n"
-			buf += "{\n"
-			buf += "	return 0;\n"
-			buf += "}\n\n"
-			bufi += "u16 " + fabric_mod_name + "_set_fabric_sense_len(struct se_cmd *, u32);\n"
-
 		if re.search('is_state_remove\)\(', fo):
 			buf += "int " + fabric_mod_name + "_is_state_remove(struct se_cmd *se_cmd)\n"
 			buf += "{\n"
diff --git a/Documentation/virtual/uml/UserModeLinux-HOWTO.txt b/Documentation/virtual/uml/UserModeLinux-HOWTO.txt
index 77dfecf..a5f8436 100644
--- a/Documentation/virtual/uml/UserModeLinux-HOWTO.txt
+++ b/Documentation/virtual/uml/UserModeLinux-HOWTO.txt
@@ -3591,7 +3591,7 @@
 
 
   Looking at the source shows that the fault happened during a call to
-  copy_to_user to copy the data into the kernel:
+  copy_from_user to copy the data into the kernel:
 
 
        107             count -= chars;
diff --git a/Documentation/vm/unevictable-lru.txt b/Documentation/vm/unevictable-lru.txt
index fa206cc..a68db769 100644
--- a/Documentation/vm/unevictable-lru.txt
+++ b/Documentation/vm/unevictable-lru.txt
@@ -197,12 +197,8 @@
 freeing them.
 
 page_evictable() also checks for mlocked pages by testing an additional page
-flag, PG_mlocked (as wrapped by PageMlocked()).  If the page is NOT mlocked,
-and a non-NULL VMA is supplied, page_evictable() will check whether the VMA is
-VM_LOCKED via is_mlocked_vma().  is_mlocked_vma() will SetPageMlocked() and
-update the appropriate statistics if the vma is VM_LOCKED.  This method allows
-efficient "culling" of pages in the fault path that are being faulted in to
-VM_LOCKED VMAs.
+flag, PG_mlocked (as wrapped by PageMlocked()), which is set when a page is
+faulted into a VM_LOCKED vma, or found in a vma being VM_LOCKED.
 
 
 VMSCAN'S HANDLING OF UNEVICTABLE PAGES
@@ -371,8 +367,8 @@
    mlock_fixup() will call make_pages_present() in the hugetlbfs VMA range to
    allocate the huge pages and populate the ptes.
 
-3) VMAs with VM_DONTEXPAND or VM_RESERVED are generally userspace mappings of
-   kernel pages, such as the VDSO page, relay channel pages, etc.  These pages
+3) VMAs with VM_DONTEXPAND are generally userspace mappings of kernel pages,
+   such as the VDSO page, relay channel pages, etc. These pages
    are inherently unevictable and are not managed on the LRU lists.
    mlock_fixup() treats these VMAs the same as hugetlbfs VMAs.  It calls
    make_pages_present() to populate the ptes.
@@ -651,7 +647,7 @@
 -------------------------------
 
 shrink_active_list() culls any obviously unevictable pages - i.e.
-!page_evictable(page, NULL) - diverting these to the unevictable list.
+!page_evictable(page) - diverting these to the unevictable list.
 However, shrink_active_list() only sees unevictable pages that made it onto the
 active/inactive lru lists.  Note that these pages do not have PageUnevictable
 set - otherwise they would be on the unevictable list and shrink_active_list
diff --git a/MAINTAINERS b/MAINTAINERS
index 84ee867..e73060f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1544,7 +1544,7 @@
 F:	drivers/rtc/rtc-bfin.c
 
 BLACKFIN SDH DRIVER
-M:	Cliff Cai <cliff.cai@analog.com>
+M:	Sonic Zhang <sonic.zhang@analog.com>
 L:	uclinux-dist-devel@blackfin.uclinux.org
 W:	http://blackfin.uclinux.org
 S:	Supported
@@ -1958,10 +1958,10 @@
 F:	drivers/platform/x86/classmate-laptop.c
 
 COCCINELLE/Semantic Patches (SmPL)
-M:	Julia Lawall <julia@diku.dk>
+M:	Julia Lawall <Julia.Lawall@lip6.fr>
 M:	Gilles Muller <Gilles.Muller@lip6.fr>
-M:	Nicolas Palix <npalix.work@gmail.com>
-L:	cocci@diku.dk (moderated for non-subscribers)
+M:	Nicolas Palix <nicolas.palix@imag.fr>
+L:	cocci@systeme.lip6.fr (moderated for non-subscribers)
 W:	http://coccinelle.lip6.fr/
 S:	Supported
 F:	scripts/coccinelle/
@@ -2423,11 +2423,6 @@
 F:	Documentation/hwmon/dme1737
 F:	drivers/hwmon/dme1737.c
 
-DOCBOOK FOR DOCUMENTATION
-M:	Randy Dunlap <rdunlap@xenotime.net>
-S:	Maintained
-F:	scripts/kernel-doc
-
 DOCKING STATION DRIVER
 M:	Shaohua Li <shaohua.li@intel.com>
 L:	linux-acpi@vger.kernel.org
@@ -5207,8 +5202,10 @@
 F:	drivers/mmc/host/omap.c
 
 OMAP HS MMC SUPPORT
+M:	Venkatraman S <svenkatr@ti.com>
+L:	linux-mmc@vger.kernel.org
 L:	linux-omap@vger.kernel.org
-S:	Orphan
+S:	Maintained
 F:	drivers/mmc/host/omap_hsmmc.c
 
 OMAP RANDOM NUMBER GENERATOR SUPPORT
@@ -7039,6 +7036,14 @@
 F:	Documentation/svga.txt
 F:	arch/x86/boot/video*
 
+SWIOTLB SUBSYSTEM
+M:	Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+L:	linux-kernel@vger.kernel.org
+S:	Supported
+F:	lib/swiotlb.c
+F:	arch/*/kernel/pci-swiotlb.c
+F:	include/linux/swiotlb.h
+
 SYSV FILESYSTEM
 M:	Christoph Hellwig <hch@infradead.org>
 S:	Maintained
@@ -7170,6 +7175,8 @@
 
 TENSILICA XTENSA PORT (xtensa)
 M:	Chris Zankel <chris@zankel.net>
+M:	Max Filippov <jcmvbkbc@gmail.com>
+L:	linux-xtensa@linux-xtensa.org
 S:	Maintained
 F:	arch/xtensa/
 
@@ -7457,6 +7464,12 @@
 F:	include/linux/mtd/ubi.h
 F:	include/mtd/ubi-user.h
 
+UNSORTED BLOCK IMAGES (UBI) Fastmap
+M:	Richard Weinberger <richard@nod.at>
+L:	linux-mtd@lists.infradead.org
+S:	Maintained
+F:	drivers/mtd/ubi/fastmap.c
+
 USB ACM DRIVER
 M:	Oliver Neukum <oliver@neukum.org>
 L:	linux-usb@vger.kernel.org
diff --git a/Makefile b/Makefile
index 86eb6ac..5d8e7f2 100644
--- a/Makefile
+++ b/Makefile
@@ -664,22 +664,9 @@
 endif
 
 # Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments
-# But warn user when we do so
-warn-assign = \
-$(warning "WARNING: Appending $$K$(1) ($(K$(1))) from $(origin K$(1)) to kernel $$$(1)")
-
-ifneq ($(KCPPFLAGS),)
-        $(call warn-assign,CPPFLAGS)
-        KBUILD_CPPFLAGS += $(KCPPFLAGS)
-endif
-ifneq ($(KAFLAGS),)
-        $(call warn-assign,AFLAGS)
-        KBUILD_AFLAGS += $(KAFLAGS)
-endif
-ifneq ($(KCFLAGS),)
-        $(call warn-assign,CFLAGS)
-        KBUILD_CFLAGS += $(KCFLAGS)
-endif
+KBUILD_CPPFLAGS += $(KCPPFLAGS)
+KBUILD_AFLAGS += $(KAFLAGS)
+KBUILD_CFLAGS += $(KCFLAGS)
 
 # Use --build-id when available.
 LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,\
diff --git a/README b/README
index 9beaed0..f32710a 100644
--- a/README
+++ b/README
@@ -206,6 +206,24 @@
      "make randconfig"  Create a ./.config file by setting symbol
                         values to random values.
 
+     "make localmodconfig" Create a config based on current config and
+                           loaded modules (lsmod). Disables any module
+                           option that is not needed for the loaded modules.
+
+                           To create a localmodconfig for another machine,
+                           store the lsmod of that machine into a file
+                           and pass it in as a LSMOD parameter.
+
+                   target$ lsmod > /tmp/mylsmod
+                   target$ scp /tmp/mylsmod host:/tmp
+
+                   host$ make LSMOD=/tmp/mylsmod localmodconfig
+
+                           The above also works when cross compiling.
+
+     "make localyesconfig" Similar to localmodconfig, except it will convert
+                           all module options to built in (=y) options.
+
    You can find more information on using the Linux kernel config tools
    in Documentation/kbuild/kconfig.txt.
 
diff --git a/arch/Kconfig b/arch/Kconfig
index a62965d..26a2841 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -271,6 +271,9 @@
 	select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
 	bool
 
+config GENERIC_KERNEL_THREAD
+	bool
+
 config HAVE_ARCH_SECCOMP_FILTER
 	bool
 	help
@@ -313,4 +316,7 @@
 	  Archs need to ensure they use a high enough resolution clock to
 	  support irq time accounting and then call enable_sched_clock_irqtime().
 
+config HAVE_ARCH_TRANSPARENT_HUGEPAGE
+	bool
+
 source "kernel/gcov/Kconfig"
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 9944ded..7da9124 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -20,6 +20,7 @@
 	select GENERIC_CMOS_UPDATE
 	select GENERIC_STRNCPY_FROM_USER
 	select GENERIC_STRNLEN_USER
+	select GENERIC_KERNEL_THREAD
 	help
 	  The Alpha is a 64-bit general-purpose processor designed and
 	  marketed by the Digital Equipment Corporation of blessed memory,
diff --git a/arch/alpha/include/asm/Kbuild b/arch/alpha/include/asm/Kbuild
index e423def..64ffc9e 100644
--- a/arch/alpha/include/asm/Kbuild
+++ b/arch/alpha/include/asm/Kbuild
@@ -1,5 +1,7 @@
 include include/asm-generic/Kbuild.asm
 
+generic-y += clkdev.h
+
 header-y += compiler.h
 header-y += console.h
 header-y += fpu.h
@@ -8,3 +10,4 @@
 header-y += reg.h
 header-y += regdef.h
 header-y += sysinfo.h
+generic-y += exec.h
diff --git a/arch/alpha/include/asm/exec.h b/arch/alpha/include/asm/exec.h
deleted file mode 100644
index 4a5a41f..0000000
--- a/arch/alpha/include/asm/exec.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __ALPHA_EXEC_H
-#define __ALPHA_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* __ALPHA_EXEC_H */
diff --git a/arch/alpha/include/asm/processor.h b/arch/alpha/include/asm/processor.h
index e37b887b..6cb7fe8 100644
--- a/arch/alpha/include/asm/processor.h
+++ b/arch/alpha/include/asm/processor.h
@@ -49,9 +49,6 @@
 /* Free all resources held by a thread. */
 extern void release_thread(struct task_struct *);
 
-/* Create a kernel thread without removing it from tasklists.  */
-extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
 unsigned long get_wchan(struct task_struct *p);
 
 #define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc)
diff --git a/arch/alpha/include/asm/thread_info.h b/arch/alpha/include/asm/thread_info.h
index 28335bd..4554ecb 100644
--- a/arch/alpha/include/asm/thread_info.h
+++ b/arch/alpha/include/asm/thread_info.h
@@ -84,7 +84,6 @@
 #define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
 #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
-#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
 
 /* Work to do on interrupt/exception return.  */
@@ -117,5 +116,7 @@
 		 (int __user *)(value));				\
 	})
 
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
+
 #endif /* __KERNEL__ */
 #endif /* _ALPHA_THREAD_INFO_H */
diff --git a/arch/alpha/include/asm/unistd.h b/arch/alpha/include/asm/unistd.h
index a31a78e..3cb6c11 100644
--- a/arch/alpha/include/asm/unistd.h
+++ b/arch/alpha/include/asm/unistd.h
@@ -481,6 +481,8 @@
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_SYS_EXECVE
+#define __ARCH_WANT_KERNEL_EXECVE
 
 /* "Conditional" syscalls.  What we want is
 
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
index 15fa821..89566b3 100644
--- a/arch/alpha/kernel/alpha_ksyms.c
+++ b/arch/alpha/kernel/alpha_ksyms.c
@@ -50,9 +50,6 @@
 EXPORT_SYMBOL(alpha_write_fp_reg);
 EXPORT_SYMBOL(alpha_write_fp_reg_s);
 
-/* entry.S */
-EXPORT_SYMBOL(kernel_thread);
-
 /* Networking helper routines. */
 EXPORT_SYMBOL(csum_tcpudp_magic);
 EXPORT_SYMBOL(ip_compute_csum);
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
index ec0da05..2a359c9 100644
--- a/arch/alpha/kernel/entry.S
+++ b/arch/alpha/kernel/entry.S
@@ -418,11 +418,10 @@
 strace:
 	/* set up signal stack, call syscall_trace */
 	bsr	$1, do_switch_stack
-	jsr	$26, syscall_trace
+	jsr	$26, syscall_trace_enter /* returns the syscall number */
 	bsr	$1, undo_switch_stack
 
-	/* get the system call number and the arguments back.. */
-	ldq	$0, 0($sp)
+	/* get the arguments back.. */
 	ldq	$16, SP_OFF+24($sp)
 	ldq	$17, SP_OFF+32($sp)
 	ldq	$18, SP_OFF+40($sp)
@@ -449,7 +448,7 @@
 	stq	$0, 0($sp)		/* save return value */
 
 	bsr	$1, do_switch_stack
-	jsr	$26, syscall_trace
+	jsr	$26, syscall_trace_leave
 	bsr	$1, undo_switch_stack
 	br	$31, ret_from_sys_call
 
@@ -467,7 +466,7 @@
 	bsr	$1, do_switch_stack
 	mov	$19, $9		/* save old syscall number */
 	mov	$20, $10	/* save old a3 */
-	jsr	$26, syscall_trace
+	jsr	$26, syscall_trace_leave
 	mov	$9, $19
 	mov	$10, $20
 	bsr	$1, undo_switch_stack
@@ -609,59 +608,35 @@
 .end ret_from_fork
 
 /*
- * kernel_thread(fn, arg, clone_flags)
+ * ... and new kernel threads - here
  */
 	.align 4
-	.globl	kernel_thread
-	.ent	kernel_thread
-kernel_thread:
-	/* We can be called from a module.  */
-	ldgp	$gp, 0($27)
-	.prologue 1
-	subq	$sp, SP_OFF+6*8, $sp
-	br	$1, 2f		/* load start address */
-
-	/* We've now "returned" from a fake system call.  */
-	unop
-	blt	$0, 1f		/* error?  */
-	ldi	$1, 0x3fff
-	beq	$20, 1f		/* parent or child?  */
-
-	bic	$sp, $1, $8	/* in child.  */
-	jsr	$26, ($27)
+	.globl	ret_from_kernel_thread
+	.ent	ret_from_kernel_thread
+ret_from_kernel_thread:
+	mov	$17, $16
+	jsr	$26, schedule_tail
+	mov	$9, $27
+	mov	$10, $16
+	jsr	$26, ($9)
 	ldgp	$gp, 0($26)
 	mov	$0, $16
 	mov	$31, $26
 	jmp	$31, sys_exit
+.end ret_from_kernel_thread
 
-1:	ret			/* in parent.  */
-
-	.align 4
-2:	/* Fake a system call stack frame, as we can't do system calls
-	   from kernel space.  Note that we store FN and ARG as they
-	   need to be set up in the child for the call.  Also store $8
-	   and $26 for use in the parent.  */
-	stq	$31, SP_OFF($sp)	/* ps */
-	stq	$1, SP_OFF+8($sp)	/* pc */
-	stq	$gp, SP_OFF+16($sp)	/* gp */
-	stq	$16, 136($sp)		/* $27; FN for child */
-	stq	$17, SP_OFF+24($sp)	/* $16; ARG for child */
-	stq	$8, 64($sp)		/* $8 */
-	stq	$26, 128($sp)		/* $26 */
+	.globl	ret_from_kernel_execve
+	.align	4
+	.ent	ret_from_kernel_execve
+ret_from_kernel_execve:
+	mov	$16, $sp
 	/* Avoid the HAE being gratuitously wrong, to avoid restoring it.  */
 	ldq	$2, alpha_mv+HAE_CACHE
 	stq	$2, 152($sp)		/* HAE */
+	mov	$31, $19		/* to disable syscall restarts */
+	br	$31, ret_to_user
 
-	/* Shuffle FLAGS to the front; add CLONE_VM.  */
-	ldi	$1, CLONE_VM|CLONE_UNTRACED
-	or	$18, $1, $16
-	bsr	$26, sys_clone
-
-	/* We don't actually care for a3 success widgetry in the kernel.
-	   Not for positive errno values.  */
-	stq	$0, 0($sp)		/* $0 */
-	br	ret_to_kernel
-.end kernel_thread
+.end	ret_from_kernel_execve
 
 
 /*
@@ -722,7 +697,7 @@
 	lda	$sp, -SWITCH_STACK_SIZE($sp)
 	jsr	$26, do_sigreturn
 	bne	$9, 1f
-	jsr	$26, syscall_trace
+	jsr	$26, syscall_trace_leave
 1:	br	$1, undo_switch_stack
 	br	ret_from_sys_call
 .end sys_sigreturn
@@ -739,21 +714,12 @@
 	lda	$sp, -SWITCH_STACK_SIZE($sp)
 	jsr	$26, do_rt_sigreturn
 	bne	$9, 1f
-	jsr	$26, syscall_trace
+	jsr	$26, syscall_trace_leave
 1:	br	$1, undo_switch_stack
 	br	ret_from_sys_call
 .end sys_rt_sigreturn
 
 	.align	4
-	.globl	sys_execve
-	.ent	sys_execve
-sys_execve:
-	.prologue 0
-	mov	$sp, $19
-	jmp	$31, do_sys_execve
-.end sys_execve
-
-	.align	4
 	.globl	alpha_ni_syscall
 	.ent	alpha_ni_syscall
 alpha_ni_syscall:
diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c
index 53649c7..b51f7b4 100644
--- a/arch/alpha/kernel/pci-sysfs.c
+++ b/arch/alpha/kernel/pci-sysfs.c
@@ -26,7 +26,7 @@
 		base = sparse ? hose->sparse_io_base : hose->dense_io_base;
 
 	vma->vm_pgoff += base >> PAGE_SHIFT;
-	vma->vm_flags |= (VM_IO | VM_RESERVED);
+	vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
 
 	return io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
 				  vma->vm_end - vma->vm_start,
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index 83638aa..4054e0f 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -263,33 +263,35 @@
 
 /*
  * Copy an alpha thread..
- *
- * Note the "stack_offset" stuff: when returning to kernel mode, we need
- * to have some extra stack-space for the kernel stack that still exists
- * after the "ret_from_fork".  When returning to user mode, we only want
- * the space needed by the syscall stack frame (ie "struct pt_regs").
- * Use the passed "regs" pointer to determine how much space we need
- * for a kernel fork().
  */
 
 int
 copy_thread(unsigned long clone_flags, unsigned long usp,
-	    unsigned long unused,
+	    unsigned long arg,
 	    struct task_struct * p, struct pt_regs * regs)
 {
 	extern void ret_from_fork(void);
+	extern void ret_from_kernel_thread(void);
 
 	struct thread_info *childti = task_thread_info(p);
-	struct pt_regs * childregs;
-	struct switch_stack * childstack, *stack;
-	unsigned long stack_offset, settls;
+	struct pt_regs *childregs = task_pt_regs(p);
+	struct switch_stack *childstack, *stack;
+	unsigned long settls;
 
-	stack_offset = PAGE_SIZE - sizeof(struct pt_regs);
-	if (!(regs->ps & 8))
-		stack_offset = (PAGE_SIZE-1) & (unsigned long) regs;
-	childregs = (struct pt_regs *)
-	  (stack_offset + PAGE_SIZE + task_stack_page(p));
-		
+	childstack = ((struct switch_stack *) childregs) - 1;
+	if (unlikely(!regs)) {
+		/* kernel thread */
+		memset(childstack, 0,
+			sizeof(struct switch_stack) + sizeof(struct pt_regs));
+		childstack->r26 = (unsigned long) ret_from_kernel_thread;
+		childstack->r9 = usp;	/* function */
+		childstack->r10 = arg;
+		childregs->hae = alpha_mv.hae_cache,
+		childti->pcb.usp = 0;
+		childti->pcb.ksp = (unsigned long) childstack;
+		childti->pcb.flags = 1;	/* set FEN, clear everything else */
+		return 0;
+	}
 	*childregs = *regs;
 	settls = regs->r20;
 	childregs->r0 = 0;
@@ -297,7 +299,6 @@
 	childregs->r20 = 1;	/* OSF/1 has some strange fork() semantics.  */
 	regs->r20 = 0;
 	stack = ((struct switch_stack *) regs) - 1;
-	childstack = ((struct switch_stack *) childregs) - 1;
 	*childstack = *stack;
 	childstack->r26 = (unsigned long) ret_from_fork;
 	childti->pcb.usp = usp;
@@ -386,27 +387,6 @@
 EXPORT_SYMBOL(dump_elf_task_fp);
 
 /*
- * sys_execve() executes a new program.
- */
-asmlinkage int
-do_sys_execve(const char __user *ufilename,
-	      const char __user *const __user *argv,
-	      const char __user *const __user *envp, struct pt_regs *regs)
-{
-	int error;
-	char *filename;
-
-	filename = getname(ufilename);
-	error = PTR_ERR(filename);
-	if (IS_ERR(filename))
-		goto out;
-	error = do_execve(filename, argv, envp, regs);
-	putname(filename);
-out:
-	return error;
-}
-
-/*
  * Return saved PC of a blocked thread.  This assumes the frame
  * pointer is the 6th saved long on the kernel stack and that the
  * saved return address is the first long in the frame.  This all
@@ -459,22 +439,3 @@
 	}
 	return pc;
 }
-
-int kernel_execve(const char *path, const char *const argv[], const char *const envp[])
-{
-	/* Avoid the HAE being gratuitously wrong, which would cause us
-	   to do the whole turn off interrupts thing and restore it.  */
-	struct pt_regs regs = {.hae = alpha_mv.hae_cache};
-	int err = do_execve(path, argv, envp, &regs);
-	if (!err) {
-		struct pt_regs *p = current_pt_regs();
-		/* copy regs to normal position and off to userland we go... */
-		*p = regs;
-		__asm__ __volatile__ (
-			"mov	%0, $sp;"
-			"br	$31, ret_from_sys_call"
-			: : "r"(p));
-	}
-	return err;
-}
-EXPORT_SYMBOL(kernel_execve);
diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c
index 54616f4..2a4a80f 100644
--- a/arch/alpha/kernel/ptrace.c
+++ b/arch/alpha/kernel/ptrace.c
@@ -13,6 +13,7 @@
 #include <linux/user.h>
 #include <linux/security.h>
 #include <linux/signal.h>
+#include <linux/tracehook.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -312,25 +313,18 @@
 	return ret;
 }
 
-asmlinkage void
-syscall_trace(void)
+asmlinkage unsigned long syscall_trace_enter(void)
 {
-	if (!test_thread_flag(TIF_SYSCALL_TRACE))
-		return;
-	if (!(current->ptrace & PT_PTRACED))
-		return;
-	/* The 0x80 provides a way for the tracing parent to distinguish
-	   between a syscall stop and SIGTRAP delivery */
-	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
-				 ? 0x80 : 0));
+	unsigned long ret = 0;
+	if (test_thread_flag(TIF_SYSCALL_TRACE) &&
+	    tracehook_report_syscall_entry(current_pt_regs()))
+		ret = -1UL;
+	return ret ?: current_pt_regs()->r0;
+}
 
-	/*
-	 * This isn't the same as continuing with a signal, but it will do
-	 * for normal use.  strace only continues with a signal if the
-	 * stopping signal is not SIGTRAP.  -brl
-	 */
-	if (current->exit_code) {
-		send_sig(current->exit_code, current, 1);
-		current->exit_code = 0;
-	}
+asmlinkage void
+syscall_trace_leave(void)
+{
+	if (test_thread_flag(TIF_SYSCALL_TRACE))
+		tracehook_report_syscall_exit(current_pt_regs(), 0);
 }
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f3342d4..767aae8 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -25,6 +25,7 @@
 	select HAVE_FUNCTION_GRAPH_TRACER if (!THUMB2_KERNEL)
 	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
 	select HAVE_GENERIC_DMA_COHERENT
+	select HAVE_DEBUG_KMEMLEAK
 	select HAVE_KERNEL_GZIP
 	select HAVE_KERNEL_LZO
 	select HAVE_KERNEL_LZMA
@@ -39,6 +40,7 @@
 	select HARDIRQS_SW_RESEND
 	select GENERIC_IRQ_PROBE
 	select GENERIC_IRQ_SHOW
+	select HAVE_UID16
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select HARDIRQS_SW_RESEND
 	select CPU_PM if (SUSPEND || CPU_IDLE)
@@ -50,6 +52,7 @@
 	select GENERIC_STRNCPY_FROM_USER
 	select GENERIC_STRNLEN_USER
 	select DCACHE_WORD_ACCESS if (CPU_V6 || CPU_V6K || CPU_V7) && !CPU_BIG_ENDIAN
+	select GENERIC_KERNEL_THREAD
 	help
 	  The ARM series is a line of low-power-consumption RISC chip designs
 	  licensed by ARM Ltd and targeted at embedded applications and
@@ -1767,6 +1770,7 @@
 config FORCE_MAX_ZONEORDER
 	int "Maximum zone order" if ARCH_SHMOBILE
 	range 11 64 if ARCH_SHMOBILE
+	default "12" if SOC_AM33XX
 	default "9" if SA1111
 	default "11"
 	help
diff --git a/arch/arm/boot/compressed/.gitignore b/arch/arm/boot/compressed/.gitignore
index d0d441c..f79a08e 100644
--- a/arch/arm/boot/compressed/.gitignore
+++ b/arch/arm/boot/compressed/.gitignore
@@ -1,6 +1,7 @@
 ashldi3.S
 font.c
 lib1funcs.S
+hyp-stub.S
 piggy.gzip
 piggy.lzo
 piggy.lzma
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index bb26756..a517153 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -30,6 +30,10 @@
 OBJS		+= string.o
 CFLAGS_string.o	:= -Os
 
+ifeq ($(CONFIG_ARM_VIRT_EXT),y)
+OBJS		+= hyp-stub.o
+endif
+
 #
 # Architecture dependencies
 #
@@ -126,7 +130,7 @@
 endif
 
 ccflags-y := -fpic -fno-builtin -I$(obj)
-asflags-y := -Wa,-march=all
+asflags-y := -Wa,-march=all -DZIMAGE
 
 # Supply kernel BSS size to the decompressor via a linker symbol.
 KBSS_SZ = $(shell $(CROSS_COMPILE)size $(obj)/../../../../vmlinux | \
@@ -198,3 +202,6 @@
 
 $(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile $(KCONFIG_CONFIG)
 	@sed "$(SEDFLAGS)" < $< > $@
+
+$(obj)/hyp-stub.S: $(srctree)/arch/$(SRCARCH)/kernel/hyp-stub.S
+	$(call cmd,shipped)
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index bc67cbf..90275f0 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -9,6 +9,7 @@
  * published by the Free Software Foundation.
  */
 #include <linux/linkage.h>
+#include <asm/assembler.h>
 
 /*
  * Debugging stuff
@@ -132,7 +133,12 @@
 		.word	start			@ absolute load/run zImage address
 		.word	_edata			@ zImage end address
  THUMB(		.thumb			)
-1:		mov	r7, r1			@ save architecture ID
+1:
+		mrs	r9, cpsr
+#ifdef CONFIG_ARM_VIRT_EXT
+		bl	__hyp_stub_install	@ get into SVC mode, reversibly
+#endif
+		mov	r7, r1			@ save architecture ID
 		mov	r8, r2			@ save atags pointer
 
 #ifndef __ARM_ARCH_2__
@@ -148,9 +154,9 @@
  ARM(		swi	0x123456	)	@ angel_SWI_ARM
  THUMB(		svc	0xab		)	@ angel_SWI_THUMB
 not_angel:
-		mrs	r2, cpsr		@ turn off interrupts to
-		orr	r2, r2, #0xc0		@ prevent angel from running
-		msr	cpsr_c, r2
+		safe_svcmode_maskall r0
+		msr	spsr_cxsf, r9		@ Save the CPU boot mode in
+						@ SPSR
 #else
 		teqp	pc, #0x0c000003		@ turn off interrupts
 #endif
@@ -350,6 +356,20 @@
 		adr	r5, restart
 		bic	r5, r5, #31
 
+/* Relocate the hyp vector base if necessary */
+#ifdef CONFIG_ARM_VIRT_EXT
+		mrs	r0, spsr
+		and	r0, r0, #MODE_MASK
+		cmp	r0, #HYP_MODE
+		bne	1f
+
+		bl	__hyp_get_vectors
+		sub	r0, r0, r5
+		add	r0, r0, r10
+		bl	__hyp_set_vectors
+1:
+#endif
+
 		sub	r9, r6, r5		@ size to copy
 		add	r9, r9, #31		@ rounded up to a multiple
 		bic	r9, r9, #31		@ ... of 32 bytes
@@ -458,11 +478,29 @@
 		bl	decompress_kernel
 		bl	cache_clean_flush
 		bl	cache_off
-		mov	r0, #0			@ must be zero
 		mov	r1, r7			@ restore architecture number
 		mov	r2, r8			@ restore atags pointer
- ARM(		mov	pc, r4	)		@ call kernel
- THUMB(		bx	r4	)		@ entry point is always ARM
+
+#ifdef CONFIG_ARM_VIRT_EXT
+		mrs	r0, spsr		@ Get saved CPU boot mode
+		and	r0, r0, #MODE_MASK
+		cmp	r0, #HYP_MODE		@ if not booted in HYP mode...
+		bne	__enter_kernel		@ boot kernel directly
+
+		adr	r12, .L__hyp_reentry_vectors_offset
+		ldr	r0, [r12]
+		add	r0, r0, r12
+
+		bl	__hyp_set_vectors
+		__HVC(0)			@ otherwise bounce to hyp mode
+
+		b	.			@ should never be reached
+
+		.align	2
+.L__hyp_reentry_vectors_offset:	.long	__hyp_reentry_vectors - .
+#else
+		b	__enter_kernel
+#endif
 
 		.align	2
 		.type	LC0, #object
@@ -1196,6 +1234,25 @@
 #endif
 
 		.ltorg
+
+#ifdef CONFIG_ARM_VIRT_EXT
+.align 5
+__hyp_reentry_vectors:
+		W(b)	.			@ reset
+		W(b)	.			@ undef
+		W(b)	.			@ svc
+		W(b)	.			@ pabort
+		W(b)	.			@ dabort
+		W(b)	__enter_kernel		@ hyp
+		W(b)	.			@ irq
+		W(b)	.			@ fiq
+#endif /* CONFIG_ARM_VIRT_EXT */
+
+__enter_kernel:
+		mov	r0, #0			@ must be 0
+ ARM(		mov	pc, r4	)		@ call kernel
+ THUMB(		bx	r4	)		@ entry point is always ARM
+
 reloc_code_end:
 
 		.align
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 5c5b0aa..c1ce813 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -68,7 +68,9 @@
 	omap4-pandaES.dtb \
 	omap4-var_som.dtb \
 	omap4-sdp.dtb \
-	omap5-evm.dtb
+	omap5-evm.dtb \
+	am335x-evm.dtb \
+	am335x-bone.dtb
 dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb
 dtb-$(CONFIG_ARCH_U8500) += snowball.dtb
 dtb-$(CONFIG_ARCH_SHMOBILE) += emev2-kzm9d.dtb \
diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi
index 7c95f76..d410581 100644
--- a/arch/arm/boot/dts/at91sam9260.dtsi
+++ b/arch/arm/boot/dts/at91sam9260.dtsi
@@ -28,6 +28,7 @@
 		gpio2 = &pioC;
 		tcb0 = &tcb0;
 		tcb1 = &tcb1;
+		i2c0 = &i2c0;
 	};
 	cpus {
 		cpu@0 {
@@ -202,6 +203,15 @@
 				status = "disabled";
 			};
 
+			i2c0: i2c@fffac000 {
+				compatible = "atmel,at91sam9260-i2c";
+				reg = <0xfffac000 0x100>;
+				interrupts = <11 4 6>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+			};
+
 			adc0: adc@fffe0000 {
 				compatible = "atmel,at91sam9260-adc";
 				reg = <0xfffe0000 0x100>;
diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi
index 195019b..3e6e5c1 100644
--- a/arch/arm/boot/dts/at91sam9263.dtsi
+++ b/arch/arm/boot/dts/at91sam9263.dtsi
@@ -24,6 +24,7 @@
 		gpio3 = &pioD;
 		gpio4 = &pioE;
 		tcb0 = &tcb0;
+		i2c0 = &i2c0;
 	};
 	cpus {
 		cpu@0 {
@@ -185,6 +186,15 @@
 				interrupts = <24 4 2>;
 				status = "disabled";
 			};
+
+			i2c0: i2c@fff88000 {
+				compatible = "atmel,at91sam9263-i2c";
+				reg = <0xfff88000 0x100>;
+				interrupts = <13 4 6>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+			};
 		};
 
 		nand0: nand@40000000 {
diff --git a/arch/arm/boot/dts/at91sam9g20.dtsi b/arch/arm/boot/dts/at91sam9g20.dtsi
index 2a1d1ca..75ce6e7 100644
--- a/arch/arm/boot/dts/at91sam9g20.dtsi
+++ b/arch/arm/boot/dts/at91sam9g20.dtsi
@@ -18,6 +18,10 @@
 
 	ahb {
 		apb {
+			i2c0: i2c@fffac000 {
+				compatible = "atmel,at91sam9g20-i2c";
+			};
+
 			adc0: adc@fffe0000 {
 				atmel,adc-startup-time = <40>;
 			};
diff --git a/arch/arm/boot/dts/at91sam9g25ek.dts b/arch/arm/boot/dts/at91sam9g25ek.dts
index 96514c1..877c08f 100644
--- a/arch/arm/boot/dts/at91sam9g25ek.dts
+++ b/arch/arm/boot/dts/at91sam9g25ek.dts
@@ -32,6 +32,18 @@
 				phy-mode = "rmii";
 				status = "okay";
 			};
+
+			i2c0: i2c@f8010000 {
+				status = "okay";
+			};
+
+			i2c1: i2c@f8014000 {
+				status = "okay";
+			};
+
+			i2c2: i2c@f8018000 {
+				status = "okay";
+			};
 		};
 
 		usb0: ohci@00600000 {
diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi
index 63751b1..3add030 100644
--- a/arch/arm/boot/dts/at91sam9g45.dtsi
+++ b/arch/arm/boot/dts/at91sam9g45.dtsi
@@ -29,6 +29,8 @@
 		gpio4 = &pioE;
 		tcb0 = &tcb0;
 		tcb1 = &tcb1;
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
 	};
 	cpus {
 		cpu@0 {
@@ -206,6 +208,24 @@
 				status = "disabled";
 			};
 
+			i2c0: i2c@fff84000 {
+				compatible = "atmel,at91sam9g10-i2c";
+				reg = <0xfff84000 0x100>;
+				interrupts = <12 4 6>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+			};
+
+			i2c1: i2c@fff88000 {
+				compatible = "atmel,at91sam9g10-i2c";
+				reg = <0xfff88000 0x100>;
+				interrupts = <13 4 6>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+			};
+
 			adc0: adc@fffb0000 {
 				compatible = "atmel,at91sam9260-adc";
 				reg = <0xfffb0000 0x100>;
diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts
index a3633bd..15e1dd4 100644
--- a/arch/arm/boot/dts/at91sam9m10g45ek.dts
+++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts
@@ -46,6 +46,14 @@
 				phy-mode = "rmii";
 				status = "okay";
 			};
+
+			i2c0: i2c@fff84000 {
+				status = "okay";
+			};
+
+			i2c1: i2c@fff88000 {
+				status = "okay";
+			};
 		};
 
 		nand0: nand@40000000 {
diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi
index ef9336a..82508d6 100644
--- a/arch/arm/boot/dts/at91sam9n12.dtsi
+++ b/arch/arm/boot/dts/at91sam9n12.dtsi
@@ -26,6 +26,8 @@
 		gpio3 = &pioD;
 		tcb0 = &tcb0;
 		tcb1 = &tcb1;
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
 	};
 	cpus {
 		cpu@0 {
@@ -182,6 +184,24 @@
 				atmel,use-dma-tx;
 				status = "disabled";
 			};
+
+			i2c0: i2c@f8010000 {
+				compatible = "atmel,at91sam9x5-i2c";
+				reg = <0xf8010000 0x100>;
+				interrupts = <9 4 6>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+			};
+
+			i2c1: i2c@f8014000 {
+				compatible = "atmel,at91sam9x5-i2c";
+				reg = <0xf8014000 0x100>;
+				interrupts = <10 4 6>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+			};
 		};
 
 		nand0: nand@40000000 {
diff --git a/arch/arm/boot/dts/at91sam9n12ek.dts b/arch/arm/boot/dts/at91sam9n12ek.dts
index f4e43e3..912b2c2 100644
--- a/arch/arm/boot/dts/at91sam9n12ek.dts
+++ b/arch/arm/boot/dts/at91sam9n12ek.dts
@@ -37,6 +37,14 @@
 			dbgu: serial@fffff200 {
 				status = "okay";
 			};
+
+			i2c0: i2c@f8010000 {
+				status = "okay";
+			};
+
+			i2c1: i2c@f8014000 {
+				status = "okay";
+			};
 		};
 
 		nand0: nand@40000000 {
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi
index 8a387a8..03fc136 100644
--- a/arch/arm/boot/dts/at91sam9x5.dtsi
+++ b/arch/arm/boot/dts/at91sam9x5.dtsi
@@ -27,6 +27,9 @@
 		gpio3 = &pioD;
 		tcb0 = &tcb0;
 		tcb1 = &tcb1;
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		i2c2 = &i2c2;
 	};
 	cpus {
 		cpu@0 {
@@ -196,6 +199,33 @@
 				status = "disabled";
 			};
 
+			i2c0: i2c@f8010000 {
+				compatible = "atmel,at91sam9x5-i2c";
+				reg = <0xf8010000 0x100>;
+				interrupts = <9 4 6>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+			};
+
+			i2c1: i2c@f8014000 {
+				compatible = "atmel,at91sam9x5-i2c";
+				reg = <0xf8014000 0x100>;
+				interrupts = <10 4 6>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+			};
+
+			i2c2: i2c@f8018000 {
+				compatible = "atmel,at91sam9x5-i2c";
+				reg = <0xf8018000 0x100>;
+				interrupts = <11 4 6>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+			};
+
 			adc0: adc@f804c000 {
 				compatible = "atmel,at91sam9260-adc";
 				reg = <0xf804c000 0x100>;
diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
index 59fbfba..e16d631 100644
--- a/arch/arm/boot/dts/imx28.dtsi
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -764,6 +764,7 @@
 				reg = <0x80058000 0x2000>;
 				interrupts = <111 68>;
 				clock-frequency = <100000>;
+				fsl,i2c-dma-channel = <6>;
 				status = "disabled";
 			};
 
@@ -774,6 +775,7 @@
 				reg = <0x8005a000 0x2000>;
 				interrupts = <110 69>;
 				clock-frequency = <100000>;
+				fsl,i2c-dma-channel = <7>;
 				status = "disabled";
 			};
 
diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi
index 2f71a91..75d069f 100644
--- a/arch/arm/boot/dts/imx51.dtsi
+++ b/arch/arm/boot/dts/imx51.dtsi
@@ -407,6 +407,13 @@
 				status = "disabled";
 			};
 
+			nand@83fdb000 {
+				compatible = "fsl,imx51-nand";
+				reg = <0x83fdb000 0x1000 0xcfff0000 0x10000>;
+				interrupts = <8>;
+				status = "disabled";
+			};
+
 			ssi3: ssi@83fe8000 {
 				compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
 				reg = <0x83fe8000 0x4000>;
diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi
index 221cf33..76ebb1a 100644
--- a/arch/arm/boot/dts/imx53.dtsi
+++ b/arch/arm/boot/dts/imx53.dtsi
@@ -518,6 +518,13 @@
 				status = "disabled";
 			};
 
+			nand@63fdb000 {
+				compatible = "fsl,imx53-nand";
+				reg = <0x63fdb000 0x1000 0xf7ff0000 0x10000>;
+				interrupts = <8>;
+				status = "disabled";
+			};
+
 			ssi3: ssi@63fe8000 {
 				compatible = "fsl,imx53-ssi", "fsl,imx21-ssi";
 				reg = <0x63fe8000 0x4000>;
diff --git a/arch/arm/boot/dts/omap4-panda.dts b/arch/arm/boot/dts/omap4-panda.dts
index 20b966e..e8f927c 100644
--- a/arch/arm/boot/dts/omap4-panda.dts
+++ b/arch/arm/boot/dts/omap4-panda.dts
@@ -59,6 +59,41 @@
 	};
 };
 
+&omap4_pmx_core {
+	pinctrl-names = "default";
+	pinctrl-0 = <
+			&twl6040_pins
+			&mcpdm_pins
+			&mcbsp1_pins
+	>;
+
+	twl6040_pins: pinmux_twl6040_pins {
+		pinctrl-single,pins = <
+			0xe0 0x3	/* hdq_sio.gpio_127 OUTPUT | MODE3 */
+			0x160 0x100	/* sys_nirq2.sys_nirq2 INPUT | MODE0 */
+		>;
+	};
+
+	mcpdm_pins: pinmux_mcpdm_pins {
+		pinctrl-single,pins = <
+			0xc6 0x108	/* abe_pdm_ul_data.abe_pdm_ul_data INPUT PULLDOWN | MODE0 */
+			0xc8 0x108	/* abe_pdm_dl_data.abe_pdm_dl_data INPUT PULLDOWN | MODE0 */
+			0xca 0x118	/* abe_pdm_frame.abe_pdm_frame INPUT PULLUP | MODE0 */
+			0xcc 0x108	/* abe_pdm_lb_clk.abe_pdm_lb_clk INPUT PULLDOWN | MODE0 */
+			0xce 0x108	/* abe_clks.abe_clks INPUT PULLDOWN | MODE0 */
+		>;
+	};
+
+	mcbsp1_pins: pinmux_mcbsp1_pins {
+		pinctrl-single,pins = <
+			0xbe 0x100	/* abe_mcbsp1_clkx.abe_mcbsp1_clkx INPUT | MODE0 */
+			0xc0 0x108	/* abe_mcbsp1_dr.abe_mcbsp1_dr INPUT PULLDOWN | MODE0 */
+			0xc2 0x8		/* abe_mcbsp1_dx.abe_mcbsp1_dx OUTPUT PULLDOWN | MODE0 */
+			0xc4 0x100	/* abe_mcbsp1_fsx.abe_mcbsp1_fsx INPUT | MODE0 */
+		>;
+	};
+};
+
 &i2c1 {
 	clock-frequency = <400000>;
 
@@ -137,3 +172,15 @@
 	cs1-used;
 	device-handle = <&elpida_ECB240ABACN>;
 };
+
+&mcbsp2 {
+	status = "disabled";
+};
+
+&mcbsp3 {
+	status = "disabled";
+};
+
+&dmic {
+	status = "disabled";
+};
diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts
index 94a23b3..5b7e04f 100644
--- a/arch/arm/boot/dts/omap4-sdp.dts
+++ b/arch/arm/boot/dts/omap4-sdp.dts
@@ -117,6 +117,15 @@
 };
 
 &omap4_pmx_core {
+	pinctrl-names = "default";
+	pinctrl-0 = <
+			&twl6040_pins
+			&mcpdm_pins
+			&dmic_pins
+			&mcbsp1_pins
+			&mcbsp2_pins
+	>;
+
 	uart2_pins: pinmux_uart2_pins {
 		pinctrl-single,pins = <
 			0xd8 0x118	/* uart2_cts.uart2_cts INPUT_PULLUP | MODE0 */
@@ -141,6 +150,50 @@
 			0x11e 0		/* uart4_tx.uart4_tx OUTPUT | MODE0 */
 		>;
 	};
+
+	twl6040_pins: pinmux_twl6040_pins {
+		pinctrl-single,pins = <
+			0xe0 0x3	/* hdq_sio.gpio_127 OUTPUT | MODE3 */
+			0x160 0x100	/* sys_nirq2.sys_nirq2 INPUT | MODE0 */
+		>;
+	};
+
+	mcpdm_pins: pinmux_mcpdm_pins {
+		pinctrl-single,pins = <
+			0xc6 0x108	/* abe_pdm_ul_data.abe_pdm_ul_data INPUT PULLDOWN | MODE0 */
+			0xc8 0x108	/* abe_pdm_dl_data.abe_pdm_dl_data INPUT PULLDOWN | MODE0 */
+			0xca 0x118	/* abe_pdm_frame.abe_pdm_frame INPUT PULLUP | MODE0 */
+			0xcc 0x108	/* abe_pdm_lb_clk.abe_pdm_lb_clk INPUT PULLDOWN | MODE0 */
+			0xce 0x108	/* abe_clks.abe_clks INPUT PULLDOWN | MODE0 */
+		>;
+	};
+
+	dmic_pins: pinmux_dmic_pins {
+		pinctrl-single,pins = <
+			0xd0 0		/* abe_dmic_clk1.abe_dmic_clk1 OUTPUT | MODE0 */
+			0xd2 0x100	/* abe_dmic_din1.abe_dmic_din1 INPUT | MODE0 */
+			0xd4 0x100	/* abe_dmic_din2.abe_dmic_din2 INPUT | MODE0 */
+			0xd6 0x100	/* abe_dmic_din3.abe_dmic_din3 INPUT | MODE0 */
+		>;
+	};
+
+	mcbsp1_pins: pinmux_mcbsp1_pins {
+		pinctrl-single,pins = <
+			0xbe 0x100	/* abe_mcbsp1_clkx.abe_mcbsp1_clkx INPUT | MODE0 */
+			0xc0 0x108	/* abe_mcbsp1_dr.abe_mcbsp1_dr INPUT PULLDOWN | MODE0 */
+			0xc2 0x8	/* abe_mcbsp1_dx.abe_mcbsp1_dx OUTPUT PULLDOWN | MODE0 */
+			0xc4 0x100	/* abe_mcbsp1_fsx.abe_mcbsp1_fsx INPUT | MODE0 */
+		>;
+	};
+
+	mcbsp2_pins: pinmux_mcbsp2_pins {
+		pinctrl-single,pins = <
+			0xb6 0x100	/* abe_mcbsp2_clkx.abe_mcbsp2_clkx INPUT | MODE0 */
+			0xb8 0x108	/* abe_mcbsp2_dr.abe_mcbsp2_dr INPUT PULLDOWN | MODE0 */
+			0xba 0x8	/* abe_mcbsp2_dx.abe_mcbsp2_dx OUTPUT PULLDOWN | MODE0 */
+			0xbc 0x100	/* abe_mcbsp2_fsx.abe_mcbsp2_fsx INPUT | MODE0 */
+		>;
+	};
 };
 
 &i2c1 {
@@ -349,3 +402,7 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart4_pins>;
 };
+
+&mcbsp3 {
+	status = "disabled";
+};
diff --git a/arch/arm/boot/dts/omap5-evm.dts b/arch/arm/boot/dts/omap5-evm.dts
index 9c41a3f..c663eba 100644
--- a/arch/arm/boot/dts/omap5-evm.dts
+++ b/arch/arm/boot/dts/omap5-evm.dts
@@ -27,6 +27,60 @@
 
 };
 
+&omap5_pmx_core {
+	pinctrl-names = "default";
+	pinctrl-0 = <
+			&twl6040_pins
+			&mcpdm_pins
+			&dmic_pins
+			&mcbsp1_pins
+			&mcbsp2_pins
+	>;
+
+	twl6040_pins: pinmux_twl6040_pins {
+		pinctrl-single,pins = <
+			0x18a 0x6	/* perslimbus2_clock.gpio5_145 OUTPUT | MODE6 */
+		>;
+	};
+
+	mcpdm_pins: pinmux_mcpdm_pins {
+		pinctrl-single,pins = <
+			0x142 0x108	/* abe_clks.abe_clks INPUT PULLDOWN | MODE0 */
+			0x15c 0x108	/* abemcpdm_ul_data.abemcpdm_ul_data INPUT PULLDOWN | MODE0 */
+			0x15e 0x108	/* abemcpdm_dl_data.abemcpdm_dl_data INPUT PULLDOWN | MODE0 */
+			0x160 0x118	/* abemcpdm_frame.abemcpdm_frame INPUT PULLUP | MODE0 */
+			0x162 0x108	/* abemcpdm_lb_clk.abemcpdm_lb_clk INPUT PULLDOWN | MODE0 */
+		>;
+	};
+
+	dmic_pins: pinmux_dmic_pins {
+		pinctrl-single,pins = <
+			0x144 0x100	/* abedmic_din1.abedmic_din1 INPUT | MODE0 */
+			0x146 0x100	/* abedmic_din2.abedmic_din2 INPUT | MODE0 */
+			0x148 0x100	/* abedmic_din3.abedmic_din3 INPUT | MODE0 */
+			0x14a 0		/* abedmic_clk1.abedmic_clk1 OUTPUT | MODE0 */
+		>;
+	};
+
+	mcbsp1_pins: pinmux_mcbsp1_pins {
+		pinctrl-single,pins = <
+			0x14c 0x101	/* abedmic_clk2.abemcbsp1_fsx INPUT | MODE1 */
+			0x14e 0x9	/* abedmic_clk3.abemcbsp1_dx OUTPUT PULLDOWN | MODE1 */
+			0x150 0x101	/* abeslimbus1_clock.abemcbsp1_clkx INPUT | MODE0 */
+			0x152 0x109	/* abeslimbus1_data.abemcbsp1_dr INPUT PULLDOWN | MODE1 */
+		>;
+	};
+
+	mcbsp2_pins: pinmux_mcbsp2_pins {
+		pinctrl-single,pins = <
+			0x154 0x108	/* abemcbsp2_dr.abemcbsp2_dr INPUT PULLDOWN | MODE0 */
+			0x156 0x8	/* abemcbsp2_dx.abemcbsp2_dx OUTPUT PULLDOWN | MODE0 */
+			0x158 0x100	/* abemcbsp2_fsx.abemcbsp2_fsx INPUT | MODE0 */
+			0x15a 0x100	/* abemcbsp2_clkx.abemcbsp2_clkx INPUT | MODE0 */
+		>;
+	};
+};
+
 &mmc1 {
 	vmmc-supply = <&vmmcsd_fixed>;
 	bus-width = <4>;
@@ -82,3 +136,7 @@
 			0x020700d9>;	/* SEARCH */
 	linux,input-no-autorepeat;
 };
+
+&mcbsp3 {
+	status = "disabled";
+};
diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi
index 5db33f4..42c78be 100644
--- a/arch/arm/boot/dts/omap5.dtsi
+++ b/arch/arm/boot/dts/omap5.dtsi
@@ -77,6 +77,23 @@
 		ranges;
 		ti,hwmods = "l3_main_1", "l3_main_2", "l3_main_3";
 
+		omap5_pmx_core: pinmux@4a002840 {
+			compatible = "ti,omap4-padconf", "pinctrl-single";
+			reg = <0x4a002840 0x01b6>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-single,register-width = <16>;
+			pinctrl-single,function-mask = <0x7fff>;
+		};
+		omap5_pmx_wkup: pinmux@4ae0c840 {
+			compatible = "ti,omap4-padconf", "pinctrl-single";
+			reg = <0x4ae0c840 0x0038>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-single,register-width = <16>;
+			pinctrl-single,function-mask = <0x7fff>;
+		};
+
 		gic: interrupt-controller@48211000 {
 			compatible = "arm,cortex-a15-gic";
 			interrupt-controller;
diff --git a/arch/arm/boot/dts/spear300-evb.dts b/arch/arm/boot/dts/spear300-evb.dts
index d71b8d5..1e7c7a8 100644
--- a/arch/arm/boot/dts/spear300-evb.dts
+++ b/arch/arm/boot/dts/spear300-evb.dts
@@ -80,8 +80,7 @@
 		};
 
 		sdhci@70000000 {
-			int-gpio = <&gpio1 0 0>;
-			power-gpio = <&gpio1 2 1>;
+			cd-gpios = <&gpio1 0 0>;
 			status = "okay";
 		};
 
diff --git a/arch/arm/boot/dts/spear320-evb.dts b/arch/arm/boot/dts/spear320-evb.dts
index e4e912f..082328b 100644
--- a/arch/arm/boot/dts/spear320-evb.dts
+++ b/arch/arm/boot/dts/spear320-evb.dts
@@ -103,8 +103,6 @@
 		};
 
 		sdhci@70000000 {
-			power-gpio = <&gpio0 2 1>;
-			power_always_enb;
 			status = "okay";
 		};
 
diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c
index c4110d1..001f491 100644
--- a/arch/arm/common/it8152.c
+++ b/arch/arm/common/it8152.c
@@ -284,11 +284,17 @@
 
 int __init it8152_pci_setup(int nr, struct pci_sys_data *sys)
 {
-	it8152_io.start = IT8152_IO_BASE + 0x12000;
-	it8152_io.end	= IT8152_IO_BASE + 0x12000 + 0x100000;
+	/*
+	 * FIXME: use pci_ioremap_io to remap the IO space here and
+	 * move over to the generic io.h implementation.
+	 * This requires solving the same problem for PXA PCMCIA
+	 * support.
+	 */
+	it8152_io.start = (unsigned long)IT8152_IO_BASE + 0x12000;
+	it8152_io.end	= (unsigned long)IT8152_IO_BASE + 0x12000 + 0x100000;
 
 	sys->mem_offset = 0x10000000;
-	sys->io_offset  = IT8152_IO_BASE;
+	sys->io_offset  = (unsigned long)IT8152_IO_BASE;
 
 	if (request_resource(&ioport_resource, &it8152_io)) {
 		printk(KERN_ERR "PCI: unable to allocate IO region\n");
diff --git a/arch/arm/configs/cam60_defconfig b/arch/arm/configs/cam60_defconfig
index cedc92e..1457971 100644
--- a/arch/arm/configs/cam60_defconfig
+++ b/arch/arm/configs/cam60_defconfig
@@ -49,7 +49,6 @@
 CONFIG_MTD_PLATRAM=m
 CONFIG_MTD_DATAFLASH=y
 CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
 CONFIG_MTD_NAND_ATMEL=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
diff --git a/arch/arm/configs/corgi_defconfig b/arch/arm/configs/corgi_defconfig
index e53c475..4b8a25d 100644
--- a/arch/arm/configs/corgi_defconfig
+++ b/arch/arm/configs/corgi_defconfig
@@ -97,7 +97,6 @@
 CONFIG_MTD_ROM=y
 CONFIG_MTD_COMPLEX_MAPPINGS=y
 CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
 CONFIG_MTD_NAND_SHARPSL=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_IDE=y
diff --git a/arch/arm/configs/ep93xx_defconfig b/arch/arm/configs/ep93xx_defconfig
index 8e97b2f..806005a 100644
--- a/arch/arm/configs/ep93xx_defconfig
+++ b/arch/arm/configs/ep93xx_defconfig
@@ -61,7 +61,6 @@
 CONFIG_MTD_ROM=y
 CONFIG_MTD_PHYSMAP=y
 CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
 CONFIG_BLK_DEV_NBD=y
 CONFIG_EEPROM_LEGACY=y
 CONFIG_SCSI=y
diff --git a/arch/arm/configs/mini2440_defconfig b/arch/arm/configs/mini2440_defconfig
index 082175c..00630e6 100644
--- a/arch/arm/configs/mini2440_defconfig
+++ b/arch/arm/configs/mini2440_defconfig
@@ -102,7 +102,6 @@
 CONFIG_MTD_RAM=y
 CONFIG_MTD_ROM=y
 CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
 CONFIG_MTD_NAND_S3C2410=y
 CONFIG_MTD_NAND_PLATFORM=y
 CONFIG_MTD_LPDDR=y
diff --git a/arch/arm/configs/mv78xx0_defconfig b/arch/arm/configs/mv78xx0_defconfig
index 7305ebd..1f08219 100644
--- a/arch/arm/configs/mv78xx0_defconfig
+++ b/arch/arm/configs/mv78xx0_defconfig
@@ -49,7 +49,6 @@
 CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_PHYSMAP=y
 CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
 CONFIG_MTD_NAND_ORION=y
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_SCSI_PROC_FS is not set
diff --git a/arch/arm/configs/nhk8815_defconfig b/arch/arm/configs/nhk8815_defconfig
index bf123c5..240b25e 100644
--- a/arch/arm/configs/nhk8815_defconfig
+++ b/arch/arm/configs/nhk8815_defconfig
@@ -57,7 +57,6 @@
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_ECC_SMC=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
 CONFIG_MTD_NAND_NOMADIK=y
 CONFIG_MTD_ONENAND=y
 CONFIG_MTD_ONENAND_VERIFY_WRITE=y
diff --git a/arch/arm/configs/orion5x_defconfig b/arch/arm/configs/orion5x_defconfig
index a288d70..cd5e6ba 100644
--- a/arch/arm/configs/orion5x_defconfig
+++ b/arch/arm/configs/orion5x_defconfig
@@ -72,7 +72,6 @@
 CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_PHYSMAP=y
 CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
 CONFIG_MTD_NAND_PLATFORM=y
 CONFIG_MTD_NAND_ORION=y
 CONFIG_BLK_DEV_LOOP=y
diff --git a/arch/arm/configs/pxa3xx_defconfig b/arch/arm/configs/pxa3xx_defconfig
index 1677a06..60e3138 100644
--- a/arch/arm/configs/pxa3xx_defconfig
+++ b/arch/arm/configs/pxa3xx_defconfig
@@ -36,7 +36,6 @@
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
 CONFIG_MTD_NAND_PXA3xx=y
 CONFIG_MTD_NAND_PXA3xx_BUILTIN=y
 CONFIG_MTD_ONENAND=y
diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig
index 7015827..df77931 100644
--- a/arch/arm/configs/spitz_defconfig
+++ b/arch/arm/configs/spitz_defconfig
@@ -94,7 +94,6 @@
 CONFIG_MTD_ROM=y
 CONFIG_MTD_COMPLEX_MAPPINGS=y
 CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
 CONFIG_MTD_NAND_SHARPSL=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_IDE=y
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 5c8b3bf4..2ef9581 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -22,6 +22,7 @@
 
 #include <asm/ptrace.h>
 #include <asm/domain.h>
+#include <asm/opcodes-virt.h>
 
 #define IOMEM(x)	(x)
 
@@ -240,6 +241,34 @@
 #endif
 
 /*
+ * Helper macro to enter SVC mode cleanly and mask interrupts. reg is
+ * a scratch register for the macro to overwrite.
+ *
+ * This macro is intended for forcing the CPU into SVC mode at boot time.
+ * you cannot return to the original mode.
+ *
+ * Beware, it also clobers LR.
+ */
+.macro safe_svcmode_maskall reg:req
+	mrs	\reg , cpsr
+	mov	lr , \reg
+	and	lr , lr , #MODE_MASK
+	cmp	lr , #HYP_MODE
+	orr	\reg , \reg , #PSR_I_BIT | PSR_F_BIT
+	bic	\reg , \reg , #MODE_MASK
+	orr	\reg , \reg , #SVC_MODE
+THUMB(	orr	\reg , \reg , #PSR_T_BIT	)
+	bne	1f
+	orr	\reg, \reg, #PSR_A_BIT
+	adr	lr, BSYM(2f)
+	msr	spsr_cxsf, \reg
+	__MSR_ELR_HYP(14)
+	__ERET
+1:	msr	cpsr_c, \reg
+2:
+.endm
+
+/*
  * STRT/LDRT access macros with ARM and Thumb-2 variants
  */
 #ifdef CONFIG_THUMB2_KERNEL
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index e4448e1..e1489c5 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -49,6 +49,13 @@
  *
  *		Unconditionally clean and invalidate the entire cache.
  *
+ *     flush_kern_louis()
+ *
+ *             Flush data cache levels up to the level of unification
+ *             inner shareable and invalidate the I-cache.
+ *             Only needed from v7 onwards, falls back to flush_cache_all()
+ *             for all other processor versions.
+ *
  *	flush_user_all()
  *
  *		Clean and invalidate all user space cache entries
@@ -97,6 +104,7 @@
 struct cpu_cache_fns {
 	void (*flush_icache_all)(void);
 	void (*flush_kern_all)(void);
+	void (*flush_kern_louis)(void);
 	void (*flush_user_all)(void);
 	void (*flush_user_range)(unsigned long, unsigned long, unsigned int);
 
@@ -119,6 +127,7 @@
 
 #define __cpuc_flush_icache_all		cpu_cache.flush_icache_all
 #define __cpuc_flush_kern_all		cpu_cache.flush_kern_all
+#define __cpuc_flush_kern_louis		cpu_cache.flush_kern_louis
 #define __cpuc_flush_user_all		cpu_cache.flush_user_all
 #define __cpuc_flush_user_range		cpu_cache.flush_user_range
 #define __cpuc_coherent_kern_range	cpu_cache.coherent_kern_range
@@ -139,6 +148,7 @@
 
 extern void __cpuc_flush_icache_all(void);
 extern void __cpuc_flush_kern_all(void);
+extern void __cpuc_flush_kern_louis(void);
 extern void __cpuc_flush_user_all(void);
 extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int);
 extern void __cpuc_coherent_kern_range(unsigned long, unsigned long);
@@ -204,6 +214,11 @@
 	__flush_icache_preferred();
 }
 
+/*
+ * Flush caches up to Level of Unification Inner Shareable
+ */
+#define flush_cache_louis()		__cpuc_flush_kern_louis()
+
 #define flush_cache_all()		__cpuc_flush_kern_all()
 
 static inline void vivt_flush_cache_mm(struct mm_struct *mm)
diff --git a/arch/arm/include/asm/glue-cache.h b/arch/arm/include/asm/glue-cache.h
index 4f8d2c0..cca9f15 100644
--- a/arch/arm/include/asm/glue-cache.h
+++ b/arch/arm/include/asm/glue-cache.h
@@ -132,6 +132,7 @@
 #ifndef MULTI_CACHE
 #define __cpuc_flush_icache_all		__glue(_CACHE,_flush_icache_all)
 #define __cpuc_flush_kern_all		__glue(_CACHE,_flush_kern_cache_all)
+#define __cpuc_flush_kern_louis		__glue(_CACHE,_flush_kern_cache_louis)
 #define __cpuc_flush_user_all		__glue(_CACHE,_flush_user_cache_all)
 #define __cpuc_flush_user_range		__glue(_CACHE,_flush_user_cache_range)
 #define __cpuc_coherent_kern_range	__glue(_CACHE,_coherent_kern_range)
diff --git a/arch/arm/include/asm/opcodes-virt.h b/arch/arm/include/asm/opcodes-virt.h
index b85665a..efcfdf9 100644
--- a/arch/arm/include/asm/opcodes-virt.h
+++ b/arch/arm/include/asm/opcodes-virt.h
@@ -26,4 +26,14 @@
 	0xF7E08000 | (((imm16) & 0xF000) << 4) | ((imm16) & 0x0FFF)	\
 )
 
+#define __ERET	__inst_arm_thumb32(					\
+	0xE160006E,							\
+	0xF3DE8F00							\
+)
+
+#define __MSR_ELR_HYP(regnum)	__inst_arm_thumb32(			\
+	0xE12EF300 | regnum,						\
+	0xF3808E30 | (regnum << 16)					\
+)
+
 #endif /* ! __ASM_ARM_OPCODES_VIRT_H */
diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h
index 99afa74..06e7d50 100644
--- a/arch/arm/include/asm/processor.h
+++ b/arch/arm/include/asm/processor.h
@@ -85,11 +85,6 @@
 #define cpu_relax()			barrier()
 #endif
 
-/*
- * Create a new kernel thread
- */
-extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
 #define task_pt_regs(p) \
 	((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)
 
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
index 355ece5..142d6ae 100644
--- a/arch/arm/include/asm/ptrace.h
+++ b/arch/arm/include/asm/ptrace.h
@@ -44,6 +44,7 @@
 #define IRQ_MODE	0x00000012
 #define SVC_MODE	0x00000013
 #define ABT_MODE	0x00000017
+#define HYP_MODE	0x0000001a
 #define UND_MODE	0x0000001b
 #define SYSTEM_MODE	0x0000001f
 #define MODE32_BIT	0x00000010
@@ -254,6 +255,11 @@
 	return regs->ARM_sp;
 }
 
+#define current_pt_regs(void) ({				\
+	register unsigned long sp asm ("sp");			\
+	(struct pt_regs *)((sp | (THREAD_SIZE - 1)) - 7) - 1;	\
+})
+
 #endif /* __KERNEL__ */
 
 #endif /* __ASSEMBLY__ */
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 74542c5..368165e 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -2,7 +2,6 @@
 #include <asm/barrier.h>
 #include <asm/compiler.h>
 #include <asm/cmpxchg.h>
-#include <asm/exec.h>
 #include <asm/switch_to.h>
 #include <asm/system_info.h>
 #include <asm/system_misc.h>
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index f71cdab..8477b4c 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -151,7 +151,6 @@
 #define TIF_SYSCALL_TRACE	8
 #define TIF_SYSCALL_AUDIT	9
 #define TIF_SYSCALL_TRACEPOINT	10
-#define TIF_POLLING_NRFLAG	16
 #define TIF_USING_IWMMXT	17
 #define TIF_MEMDIE		18	/* is terminating due to OOM killer */
 #define TIF_RESTORE_SIGMASK	20
@@ -164,7 +163,6 @@
 #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
 #define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
 #define _TIF_SYSCALL_TRACEPOINT	(1 << TIF_SYSCALL_TRACEPOINT)
-#define _TIF_POLLING_NRFLAG	(1 << TIF_POLLING_NRFLAG)
 #define _TIF_USING_IWMMXT	(1 << TIF_USING_IWMMXT)
 #define _TIF_SECCOMP		(1 << TIF_SECCOMP)
 
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
index d9ff5cc..f259921 100644
--- a/arch/arm/include/asm/unistd.h
+++ b/arch/arm/include/asm/unistd.h
@@ -478,6 +478,8 @@
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_SYS_SOCKETCALL
 #endif
+#define __ARCH_WANT_SYS_EXECVE
+#define __ARCH_WANT_KERNEL_EXECVE
 
 /*
  * "Conditional" syscalls
diff --git a/arch/arm/include/asm/vfpmacros.h b/arch/arm/include/asm/vfpmacros.h
index a7aadbd..6a6f1e4 100644
--- a/arch/arm/include/asm/vfpmacros.h
+++ b/arch/arm/include/asm/vfpmacros.h
@@ -28,7 +28,7 @@
 	ldr	\tmp, =elf_hwcap		    @ may not have MVFR regs
 	ldr	\tmp, [\tmp, #0]
 	tst	\tmp, #HWCAP_VFPv3D16
-	ldceq	p11, cr0, [\base],#32*4		    @ FLDMIAD \base!, {d16-d31}
+	ldceql	p11, cr0, [\base],#32*4		    @ FLDMIAD \base!, {d16-d31}
 	addne	\base, \base, #32*4		    @ step over unused register space
 #else
 	VFPFMRX	\tmp, MVFR0			    @ Media and VFP Feature Register 0
@@ -52,7 +52,7 @@
 	ldr	\tmp, =elf_hwcap		    @ may not have MVFR regs
 	ldr	\tmp, [\tmp, #0]
 	tst	\tmp, #HWCAP_VFPv3D16
-	stceq	p11, cr0, [\base],#32*4		    @ FSTMIAD \base!, {d16-d31}
+	stceql	p11, cr0, [\base],#32*4		    @ FSTMIAD \base!, {d16-d31}
 	addne	\base, \base, #32*4		    @ step over unused register space
 #else
 	VFPFMRX	\tmp, MVFR0			    @ Media and VFP Feature Register 0
diff --git a/arch/arm/include/asm/virt.h b/arch/arm/include/asm/virt.h
new file mode 100644
index 0000000..86164df
--- /dev/null
+++ b/arch/arm/include/asm/virt.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2012 Linaro Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef VIRT_H
+#define VIRT_H
+
+#include <asm/ptrace.h>
+
+/*
+ * Flag indicating that the kernel was not entered in the same mode on every
+ * CPU.  The zImage loader stashes this value in an SPSR, so we need an
+ * architecturally defined flag bit here (the N flag, as it happens)
+ */
+#define BOOT_CPU_MODE_MISMATCH (1<<31)
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_ARM_VIRT_EXT
+/*
+ * __boot_cpu_mode records what mode the primary CPU was booted in.
+ * A correctly-implemented bootloader must start all CPUs in the same mode:
+ * if it fails to do this, the flag BOOT_CPU_MODE_MISMATCH is set to indicate
+ * that some CPU(s) were booted in a different mode.
+ *
+ * This allows the kernel to flag an error when the secondaries have come up.
+ */
+extern int __boot_cpu_mode;
+
+void __hyp_set_vectors(unsigned long phys_vector_base);
+unsigned long __hyp_get_vectors(void);
+#else
+#define __boot_cpu_mode	(SVC_MODE)
+#endif
+
+#ifndef ZIMAGE
+void hyp_mode_check(void);
+
+/* Reports the availability of HYP mode */
+static inline bool is_hyp_mode_available(void)
+{
+	return ((__boot_cpu_mode & MODE_MASK) == HYP_MODE &&
+		!(__boot_cpu_mode & BOOT_CPU_MODE_MISMATCH));
+}
+
+/* Check if the bootloader has booted CPUs in different modes */
+static inline bool is_hyp_mode_mismatched(void)
+{
+	return !!(__boot_cpu_mode & BOOT_CPU_MODE_MISMATCH);
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* ! VIRT_H */
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 5dfef9d..5bbec7b 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -81,4 +81,6 @@
 obj-$(CONFIG_DEBUG_LL)	+= debug.o
 obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
 
+obj-$(CONFIG_ARM_VIRT_EXT)	+= hyp-stub.o
+
 extra-y := $(head-y) vmlinux.lds
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index e337879..831cd38 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -20,7 +20,7 @@
 		CALL(sys_creat)
 		CALL(sys_link)
 /* 10 */	CALL(sys_unlink)
-		CALL(sys_execve_wrapper)
+		CALL(sys_execve)
 		CALL(sys_chdir)
 		CALL(OBSOLETE(sys_time))	/* used by libc4 */
 		CALL(sys_mknod)
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index f459870..e340fa1 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -91,6 +91,30 @@
 	b	ret_slow_syscall
 ENDPROC(ret_from_fork)
 
+ENTRY(ret_from_kernel_thread)
+ UNWIND(.fnstart)
+ UNWIND(.cantunwind)
+	bl	schedule_tail
+	mov	r0, r4
+	adr	lr, BSYM(1f)	@ kernel threads should not exit
+	mov	pc, r5
+1:	bl	do_exit
+	nop
+ UNWIND(.fnend)
+ENDPROC(ret_from_kernel_thread)
+
+/*
+ * turn a kernel thread into userland process
+ * use: ret_from_kernel_execve(struct pt_regs *normal)
+ */
+ENTRY(ret_from_kernel_execve)
+	mov	why, #0			@ not a syscall
+	str	why, [r0, #S_R0]	@ ... and we want 0 in ->ARM_r0 as well
+	get_thread_info tsk		@ thread structure
+	mov	sp, r0			@ stack pointer just under pt_regs
+	b	ret_slow_syscall
+ENDPROC(ret_from_kernel_execve)
+
 	.equ NR_syscalls,0
 #define CALL(x) .equ NR_syscalls,NR_syscalls+1
 #include "calls.S"
@@ -517,11 +541,6 @@
 		b	sys_vfork
 ENDPROC(sys_vfork_wrapper)
 
-sys_execve_wrapper:
-		add	r3, sp, #S_OFF
-		b	sys_execve
-ENDPROC(sys_execve_wrapper)
-
 sys_clone_wrapper:
 		add	ip, sp, #S_OFF
 		str	ip, [sp, #4]
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 9874d07..4eee351 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -83,8 +83,12 @@
  THUMB(	.thumb			)	@ switch to Thumb now.
  THUMB(1:			)
 
-	setmode	PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
-						@ and irqs disabled
+#ifdef CONFIG_ARM_VIRT_EXT
+	bl	__hyp_stub_install
+#endif
+	@ ensure svc mode and all interrupts masked
+	safe_svcmode_maskall r9
+
 	mrc	p15, 0, r9, c0, c0		@ get processor id
 	bl	__lookup_processor_type		@ r5=procinfo r9=cpuid
 	movs	r10, r5				@ invalid processor (r5=0)?
@@ -326,7 +330,11 @@
 	 * the processor type - there is no need to check the machine type
 	 * as it has already been validated by the primary processor.
 	 */
-	setmode	PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9
+#ifdef CONFIG_ARM_VIRT_EXT
+	bl	__hyp_stub_install
+#endif
+	safe_svcmode_maskall r9
+
 	mrc	p15, 0, r9, c0, c0		@ get processor id
 	bl	__lookup_processor_type
 	movs	r10, r5				@ invalid processor?
diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
new file mode 100644
index 0000000..65b2417
--- /dev/null
+++ b/arch/arm/kernel/hyp-stub.S
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2012 Linaro Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/virt.h>
+
+#ifndef ZIMAGE
+/*
+ * For the kernel proper, we need to find out the CPU boot mode long after
+ * boot, so we need to store it in a writable variable.
+ *
+ * This is not in .bss, because we set it sufficiently early that the boot-time
+ * zeroing of .bss would clobber it.
+ */
+.data
+ENTRY(__boot_cpu_mode)
+	.long	0
+.text
+
+	/*
+	 * Save the primary CPU boot mode. Requires 3 scratch registers.
+	 */
+	.macro	store_primary_cpu_mode	reg1, reg2, reg3
+	mrs	\reg1, cpsr
+	and	\reg1, \reg1, #MODE_MASK
+	adr	\reg2, .L__boot_cpu_mode_offset
+	ldr	\reg3, [\reg2]
+	str	\reg1, [\reg2, \reg3]
+	.endm
+
+	/*
+	 * Compare the current mode with the one saved on the primary CPU.
+	 * If they don't match, record that fact. The Z bit indicates
+	 * if there's a match or not.
+	 * Requires 3 additionnal scratch registers.
+	 */
+	.macro	compare_cpu_mode_with_primary mode, reg1, reg2, reg3
+	adr	\reg2, .L__boot_cpu_mode_offset
+	ldr	\reg3, [\reg2]
+	ldr	\reg1, [\reg2, \reg3]
+	cmp	\mode, \reg1		@ matches primary CPU boot mode?
+	orrne	r7, r7, #BOOT_CPU_MODE_MISMATCH
+	strne	r7, [r5, r6]		@ record what happened and give up
+	.endm
+
+#else	/* ZIMAGE */
+
+	.macro	store_primary_cpu_mode	reg1:req, reg2:req, reg3:req
+	.endm
+
+/*
+ * The zImage loader only runs on one CPU, so we don't bother with mult-CPU
+ * consistency checking:
+ */
+	.macro	compare_cpu_mode_with_primary mode, reg1, reg2, reg3
+	cmp	\mode, \mode
+	.endm
+
+#endif /* ZIMAGE */
+
+/*
+ * Hypervisor stub installation functions.
+ *
+ * These must be called with the MMU and D-cache off.
+ * They are not ABI compliant and are only intended to be called from the kernel
+ * entry points in head.S.
+ */
+@ Call this from the primary CPU
+ENTRY(__hyp_stub_install)
+	store_primary_cpu_mode	r4, r5, r6
+ENDPROC(__hyp_stub_install)
+
+	@ fall through...
+
+@ Secondary CPUs should call here
+ENTRY(__hyp_stub_install_secondary)
+	mrs	r4, cpsr
+	and	r4, r4, #MODE_MASK
+
+	/*
+	 * If the secondary has booted with a different mode, give up
+	 * immediately.
+	 */
+	compare_cpu_mode_with_primary	r4, r5, r6, r7
+	bxne	lr
+
+	/*
+	 * Once we have given up on one CPU, we do not try to install the
+	 * stub hypervisor on the remaining ones: because the saved boot mode
+	 * is modified, it can't compare equal to the CPSR mode field any
+	 * more.
+	 *
+	 * Otherwise...
+	 */
+
+	cmp	r4, #HYP_MODE
+	bxne	lr			@ give up if the CPU is not in HYP mode
+
+/*
+ * Configure HSCTLR to set correct exception endianness/instruction set
+ * state etc.
+ * Turn off all traps
+ * Eventually, CPU-specific code might be needed -- assume not for now
+ *
+ * This code relies on the "eret" instruction to synchronize the
+ * various coprocessor accesses.
+ */
+	@ Now install the hypervisor stub:
+	adr	r7, __hyp_stub_vectors
+	mcr	p15, 4, r7, c12, c0, 0	@ set hypervisor vector base (HVBAR)
+
+	@ Disable all traps, so we don't get any nasty surprise
+	mov	r7, #0
+	mcr	p15, 4, r7, c1, c1, 0	@ HCR
+	mcr	p15, 4, r7, c1, c1, 2	@ HCPTR
+	mcr	p15, 4, r7, c1, c1, 3	@ HSTR
+
+THUMB(	orr	r7, #(1 << 30)	)	@ HSCTLR.TE
+#ifdef CONFIG_CPU_BIG_ENDIAN
+	orr	r7, #(1 << 9)		@ HSCTLR.EE
+#endif
+	mcr	p15, 4, r7, c1, c0, 0	@ HSCTLR
+
+	mrc	p15, 4, r7, c1, c1, 1	@ HDCR
+	and	r7, #0x1f		@ Preserve HPMN
+	mcr	p15, 4, r7, c1, c1, 1	@ HDCR
+
+#if !defined(ZIMAGE) && defined(CONFIG_ARM_ARCH_TIMER)
+	@ make CNTP_* and CNTPCT accessible from PL1
+	mrc	p15, 0, r7, c0, c1, 1	@ ID_PFR1
+	lsr	r7, #16
+	and	r7, #0xf
+	cmp	r7, #1
+	bne	1f
+	mrc	p15, 4, r7, c14, c1, 0	@ CNTHCTL
+	orr	r7, r7, #3		@ PL1PCEN | PL1PCTEN
+	mcr	p15, 4, r7, c14, c1, 0	@ CNTHCTL
+1:
+#endif
+
+	bic	r7, r4, #MODE_MASK
+	orr	r7, r7, #SVC_MODE
+THUMB(	orr	r7, r7, #PSR_T_BIT	)
+	msr	spsr_cxsf, r7		@ This is SPSR_hyp.
+
+	__MSR_ELR_HYP(14)		@ msr elr_hyp, lr
+	__ERET				@ return, switching to SVC mode
+					@ The boot CPU mode is left in r4.
+ENDPROC(__hyp_stub_install_secondary)
+
+__hyp_stub_do_trap:
+	cmp	r0, #-1
+	mrceq	p15, 4, r0, c12, c0, 0	@ get HVBAR
+	mcrne	p15, 4, r0, c12, c0, 0	@ set HVBAR
+	__ERET
+ENDPROC(__hyp_stub_do_trap)
+
+/*
+ * __hyp_set_vectors: Call this after boot to set the initial hypervisor
+ * vectors as part of hypervisor installation.  On an SMP system, this should
+ * be called on each CPU.
+ *
+ * r0 must be the physical address of the new vector table (which must lie in
+ * the bottom 4GB of physical address space.
+ *
+ * r0 must be 32-byte aligned.
+ *
+ * Before calling this, you must check that the stub hypervisor is installed
+ * everywhere, by waiting for any secondary CPUs to be brought up and then
+ * checking that BOOT_CPU_MODE_HAVE_HYP(__boot_cpu_mode) is true.
+ *
+ * If not, there is a pre-existing hypervisor, some CPUs failed to boot, or
+ * something else went wrong... in such cases, trying to install a new
+ * hypervisor is unlikely to work as desired.
+ *
+ * When you call into your shiny new hypervisor, sp_hyp will contain junk,
+ * so you will need to set that to something sensible at the new hypervisor's
+ * initialisation entry point.
+ */
+ENTRY(__hyp_get_vectors)
+	mov	r0, #-1
+ENDPROC(__hyp_get_vectors)
+	@ fall through
+ENTRY(__hyp_set_vectors)
+	__HVC(0)
+	bx	lr
+ENDPROC(__hyp_set_vectors)
+
+#ifndef ZIMAGE
+.align 2
+.L__boot_cpu_mode_offset:
+	.long	__boot_cpu_mode - .
+#endif
+
+.align 5
+__hyp_stub_vectors:
+__hyp_stub_reset:	W(b)	.
+__hyp_stub_und:		W(b)	.
+__hyp_stub_svc:		W(b)	.
+__hyp_stub_pabort:	W(b)	.
+__hyp_stub_dabort:	W(b)	.
+__hyp_stub_trap:	W(b)	__hyp_stub_do_trap
+__hyp_stub_irq:		W(b)	.
+__hyp_stub_fiq:		W(b)	.
+ENDPROC(__hyp_stub_vectors)
+
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 04eea22..f98c17f 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -373,6 +373,7 @@
 }
 
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
+asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread");
 
 int
 copy_thread(unsigned long clone_flags, unsigned long stack_start,
@@ -381,13 +382,20 @@
 	struct thread_info *thread = task_thread_info(p);
 	struct pt_regs *childregs = task_pt_regs(p);
 
-	*childregs = *regs;
-	childregs->ARM_r0 = 0;
-	childregs->ARM_sp = stack_start;
-
 	memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
+
+	if (likely(regs)) {
+		*childregs = *regs;
+		childregs->ARM_r0 = 0;
+		childregs->ARM_sp = stack_start;
+		thread->cpu_context.pc = (unsigned long)ret_from_fork;
+	} else {
+		thread->cpu_context.r4 = stk_sz;
+		thread->cpu_context.r5 = stack_start;
+		thread->cpu_context.pc = (unsigned long)ret_from_kernel_thread;
+		childregs->ARM_cpsr = SVC_MODE;
+	}
 	thread->cpu_context.sp = (unsigned long)childregs;
-	thread->cpu_context.pc = (unsigned long)ret_from_fork;
 
 	clear_ptrace_hw_breakpoint(p);
 
@@ -423,63 +431,6 @@
 }
 EXPORT_SYMBOL(dump_fpu);
 
-/*
- * Shuffle the argument into the correct register before calling the
- * thread function.  r4 is the thread argument, r5 is the pointer to
- * the thread function, and r6 points to the exit function.
- */
-extern void kernel_thread_helper(void);
-asm(	".pushsection .text\n"
-"	.align\n"
-"	.type	kernel_thread_helper, #function\n"
-"kernel_thread_helper:\n"
-#ifdef CONFIG_TRACE_IRQFLAGS
-"	bl	trace_hardirqs_on\n"
-#endif
-"	msr	cpsr_c, r7\n"
-"	mov	r0, r4\n"
-"	mov	lr, r6\n"
-"	mov	pc, r5\n"
-"	.size	kernel_thread_helper, . - kernel_thread_helper\n"
-"	.popsection");
-
-#ifdef CONFIG_ARM_UNWIND
-extern void kernel_thread_exit(long code);
-asm(	".pushsection .text\n"
-"	.align\n"
-"	.type	kernel_thread_exit, #function\n"
-"kernel_thread_exit:\n"
-"	.fnstart\n"
-"	.cantunwind\n"
-"	bl	do_exit\n"
-"	nop\n"
-"	.fnend\n"
-"	.size	kernel_thread_exit, . - kernel_thread_exit\n"
-"	.popsection");
-#else
-#define kernel_thread_exit	do_exit
-#endif
-
-/*
- * Create a kernel thread.
- */
-pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
-{
-	struct pt_regs regs;
-
-	memset(&regs, 0, sizeof(regs));
-
-	regs.ARM_r4 = (unsigned long)arg;
-	regs.ARM_r5 = (unsigned long)fn;
-	regs.ARM_r6 = (unsigned long)kernel_thread_exit;
-	regs.ARM_r7 = SVC_MODE | PSR_ENDSTATE | PSR_ISETSTATE;
-	regs.ARM_pc = (unsigned long)kernel_thread_helper;
-	regs.ARM_cpsr = regs.ARM_r7 | PSR_I_BIT;
-
-	return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
-}
-EXPORT_SYMBOL(kernel_thread);
-
 unsigned long get_wchan(struct task_struct *p)
 {
 	struct stackframe frame;
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index febafa0..da1d1aa 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -53,6 +53,7 @@
 #include <asm/traps.h>
 #include <asm/unwind.h>
 #include <asm/memblock.h>
+#include <asm/virt.h>
 
 #include "atags.h"
 #include "tcm.h"
@@ -703,6 +704,21 @@
 	return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
 }
 
+void __init hyp_mode_check(void)
+{
+#ifdef CONFIG_ARM_VIRT_EXT
+	if (is_hyp_mode_available()) {
+		pr_info("CPU: All CPU(s) started in HYP mode.\n");
+		pr_info("CPU: Virtualization extensions available.\n");
+	} else if (is_hyp_mode_mismatched()) {
+		pr_warn("CPU: WARNING: CPU(s) started in wrong/inconsistent modes (primary CPU mode 0x%x)\n",
+			__boot_cpu_mode & MODE_MASK);
+		pr_warn("CPU: This may indicate a broken bootloader or firmware.\n");
+	} else
+		pr_info("CPU: All CPU(s) started in SVC mode.\n");
+#endif
+}
+
 void __init setup_arch(char **cmdline_p)
 {
 	struct machine_desc *mdesc;
@@ -748,6 +764,10 @@
 		smp_init_cpus();
 	}
 #endif
+
+	if (!is_smp())
+		hyp_mode_check();
+
 	reserve_crashkernel();
 
 	tcm_init();
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index f27789e..56f72d2 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -10,7 +10,6 @@
 #include <linux/errno.h>
 #include <linux/signal.h>
 #include <linux/personality.h>
-#include <linux/freezer.h>
 #include <linux/uaccess.h>
 #include <linux/tracehook.h>
 
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index d100eac..8e20754d 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -43,6 +43,7 @@
 #include <asm/ptrace.h>
 #include <asm/localtimer.h>
 #include <asm/smp_plat.h>
+#include <asm/virt.h>
 #include <asm/mach/arch.h>
 
 /*
@@ -202,8 +203,11 @@
 	/*
 	 * Flush user cache and TLB mappings, and then remove this CPU
 	 * from the vm mask set of all processes.
+	 *
+	 * Caches are flushed to the Level of Unification Inner Shareable
+	 * to write-back dirty lines to unified caches shared by all CPUs.
 	 */
-	flush_cache_all();
+	flush_cache_louis();
 	local_flush_tlb_all();
 
 	clear_tasks_mm_cpumask(cpu);
@@ -355,6 +359,8 @@
 	       num_online_cpus(),
 	       bogosum / (500000/HZ),
 	       (bogosum / (5000/HZ)) % 100);
+
+	hyp_mode_check();
 }
 
 void __init smp_prepare_boot_cpu(void)
diff --git a/arch/arm/kernel/suspend.c b/arch/arm/kernel/suspend.c
index 1794cc3..358bca3 100644
--- a/arch/arm/kernel/suspend.c
+++ b/arch/arm/kernel/suspend.c
@@ -17,6 +17,8 @@
  */
 void __cpu_suspend_save(u32 *ptr, u32 ptrsz, u32 sp, u32 *save_ptr)
 {
+	u32 *ctx = ptr;
+
 	*save_ptr = virt_to_phys(ptr);
 
 	/* This must correspond to the LDM in cpu_resume() assembly */
@@ -26,7 +28,20 @@
 
 	cpu_do_suspend(ptr);
 
-	flush_cache_all();
+	flush_cache_louis();
+
+	/*
+	 * flush_cache_louis does not guarantee that
+	 * save_ptr and ptr are cleaned to main memory,
+	 * just up to the Level of Unification Inner Shareable.
+	 * Since the context pointer and context itself
+	 * are to be retrieved with the MMU off that
+	 * data must be cleaned from all cache levels
+	 * to main memory using "area" cache primitives.
+	*/
+	__cpuc_flush_dcache_area(ctx, ptrsz);
+	__cpuc_flush_dcache_area(save_ptr, sizeof(*save_ptr));
+
 	outer_clean_range(*save_ptr, *save_ptr + ptrsz);
 	outer_clean_range(virt_to_phys(save_ptr),
 			  virt_to_phys(save_ptr) + sizeof(*save_ptr));
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index 76cbb05..c2a898a 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -59,69 +59,6 @@
 	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->ARM_sp, regs, 0, NULL, NULL);
 }
 
-/* sys_execve() executes a new program.
- * This is called indirectly via a small wrapper
- */
-asmlinkage int sys_execve(const char __user *filenamei,
-			  const char __user *const __user *argv,
-			  const char __user *const __user *envp, struct pt_regs *regs)
-{
-	int error;
-	char * filename;
-
-	filename = getname(filenamei);
-	error = PTR_ERR(filename);
-	if (IS_ERR(filename))
-		goto out;
-	error = do_execve(filename, argv, envp, regs);
-	putname(filename);
-out:
-	return error;
-}
-
-int kernel_execve(const char *filename,
-		  const char *const argv[],
-		  const char *const envp[])
-{
-	struct pt_regs regs;
-	int ret;
-
-	memset(&regs, 0, sizeof(struct pt_regs));
-	ret = do_execve(filename,
-			(const char __user *const __user *)argv,
-			(const char __user *const __user *)envp, &regs);
-	if (ret < 0)
-		goto out;
-
-	/*
-	 * Save argc to the register structure for userspace.
-	 */
-	regs.ARM_r0 = ret;
-
-	/*
-	 * We were successful.  We won't be returning to our caller, but
-	 * instead to user space by manipulating the kernel stack.
-	 */
-	asm(	"add	r0, %0, %1\n\t"
-		"mov	r1, %2\n\t"
-		"mov	r2, %3\n\t"
-		"bl	memmove\n\t"	/* copy regs to top of stack */
-		"mov	r8, #0\n\t"	/* not a syscall */
-		"mov	r9, %0\n\t"	/* thread structure */
-		"mov	sp, r0\n\t"	/* reposition stack pointer */
-		"b	ret_to_user"
-		:
-		: "r" (current_thread_info()),
-		  "Ir" (THREAD_START_SP - sizeof(regs)),
-		  "r" (&regs),
-		  "Ir" (sizeof(regs))
-		: "r0", "r1", "r2", "r3", "r8", "r9", "ip", "lr", "memory");
-
- out:
-	return ret;
-}
-EXPORT_SYMBOL(kernel_execve);
-
 /*
  * Since loff_t is a 64 bit type we avoid a lot of ABI hassle
  * with a different argument ordering.
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
index 6f50c67..b4f0565 100644
--- a/arch/arm/mach-at91/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -187,6 +187,7 @@
 	CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
 	CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
 	CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk),
+	CLKDEV_CON_DEV_ID(NULL, "i2c-at91rm9200", &twi_clk),
 	/* fake hclk clock */
 	CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk),
 	CLKDEV_CON_ID("pioA", &pioA_clk),
diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c
index 9ac427a..a563189c 100644
--- a/arch/arm/mach-at91/at91rm9200_devices.c
+++ b/arch/arm/mach-at91/at91rm9200_devices.c
@@ -511,7 +511,7 @@
 };
 
 static struct platform_device at91rm9200_twi_device = {
-	.name		= "at91_i2c",
+	.name		= "i2c-at91rm9200",
 	.id		= -1,
 	.resource	= twi_resources,
 	.num_resources	= ARRAY_SIZE(twi_resources),
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index 30c7f26..ad29f93 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -211,6 +211,8 @@
 	CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk),
 	CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk),
 	CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc_clk),
+	CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260", &twi_clk),
+	CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20", &twi_clk),
 	/* more usart lookup table for DT entries */
 	CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck),
 	CLKDEV_CON_DEV_ID("usart", "fffb0000.serial", &usart0_clk),
@@ -219,6 +221,7 @@
 	CLKDEV_CON_DEV_ID("usart", "fffd0000.serial", &usart3_clk),
 	CLKDEV_CON_DEV_ID("usart", "fffd4000.serial", &usart4_clk),
 	CLKDEV_CON_DEV_ID("usart", "fffd8000.serial", &usart5_clk),
+	CLKDEV_CON_DEV_ID(NULL, "fffac000.i2c", &twi_clk),
 	/* more tc lookup table for DT entries */
 	CLKDEV_CON_DEV_ID("t0_clk", "fffa0000.timer", &tc0_clk),
 	CLKDEV_CON_DEV_ID("t1_clk", "fffa0000.timer", &tc1_clk),
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index af50ff3..a76b868 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -421,7 +421,6 @@
 };
 
 static struct platform_device at91sam9260_twi_device = {
-	.name		= "at91_i2c",
 	.id		= -1,
 	.resource	= twi_resources,
 	.num_resources	= ARRAY_SIZE(twi_resources),
@@ -429,6 +428,13 @@
 
 void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
 {
+	/* IP version is not the same on 9260 and g20 */
+	if (cpu_is_at91sam9g20()) {
+		at91sam9260_twi_device.name = "i2c-at91sam9g20";
+	} else {
+		at91sam9260_twi_device.name = "i2c-at91sam9260";
+	}
+
 	/* pins used for TWI interface */
 	at91_set_A_periph(AT91_PIN_PA23, 0);		/* TWD */
 	at91_set_multi_drive(AT91_PIN_PA23, 1);
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index f40762c..8d999eb 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -178,6 +178,8 @@
 	CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
 	CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk),
 	CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &hck0),
+	CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9261", &twi_clk),
+	CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10", &twi_clk),
 	CLKDEV_CON_ID("pioA", &pioA_clk),
 	CLKDEV_CON_ID("pioB", &pioB_clk),
 	CLKDEV_CON_ID("pioC", &pioC_clk),
diff --git a/arch/arm/mach-at91/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index 11e9fa8..9752f17 100644
--- a/arch/arm/mach-at91/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -317,7 +317,6 @@
 };
 
 static struct platform_device at91sam9261_twi_device = {
-	.name		= "at91_i2c",
 	.id		= -1,
 	.resource	= twi_resources,
 	.num_resources	= ARRAY_SIZE(twi_resources),
@@ -325,12 +324,19 @@
 
 void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
 {
+	/* IP version is not the same on 9261 and g10 */
+	if (cpu_is_at91sam9g10()) {
+		at91sam9261_twi_device.name = "i2c-at91sam9g10";
+		/* I2C PIO must not be configured as open-drain on this chip */
+	} else {
+		at91sam9261_twi_device.name = "i2c-at91sam9261";
+		at91_set_multi_drive(AT91_PIN_PA7, 1);
+		at91_set_multi_drive(AT91_PIN_PA8, 1);
+	}
+
 	/* pins used for TWI interface */
 	at91_set_A_periph(AT91_PIN_PA7, 0);		/* TWD */
-	at91_set_multi_drive(AT91_PIN_PA7, 1);
-
 	at91_set_A_periph(AT91_PIN_PA8, 0);		/* TWCK */
-	at91_set_multi_drive(AT91_PIN_PA8, 1);
 
 	i2c_register_board_info(0, devices, nr_devices);
 	platform_device_register(&at91sam9261_twi_device);
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index 144ef5d..6a01d03 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -193,6 +193,7 @@
 	CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),
 	CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
 	CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk),
+	CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260", &twi_clk),
 	/* fake hclk clock */
 	CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk),
 	CLKDEV_CON_ID("pioA", &pioA_clk),
@@ -210,6 +211,7 @@
 	CLKDEV_CON_DEV_ID("hclk", "a00000.ohci", &ohci_clk),
 	CLKDEV_CON_DEV_ID("spi_clk", "fffa4000.spi", &spi0_clk),
 	CLKDEV_CON_DEV_ID("spi_clk", "fffa8000.spi", &spi1_clk),
+	CLKDEV_CON_DEV_ID(NULL, "fff88000.i2c", &twi_clk),
 };
 
 static struct clk_lookup usart_clocks_lookups[] = {
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index 7c0898f..8dde220 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -599,7 +599,7 @@
 };
 
 static struct platform_device at91sam9263_twi_device = {
-	.name		= "at91_i2c",
+	.name		= "i2c-at91sam9260",
 	.id		= -1,
 	.resource	= twi_resources,
 	.num_resources	= ARRAY_SIZE(twi_resources),
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
index ef6cedd..84af1b5 100644
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -237,6 +237,8 @@
 	CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
 	CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb0_clk),
 	CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tcb0_clk),
+	CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10.0", &twi0_clk),
+	CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10.1", &twi1_clk),
 	CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
 	CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
 	CLKDEV_CON_DEV_ID(NULL, "atmel-trng", &trng_clk),
@@ -254,6 +256,8 @@
 	CLKDEV_CON_DEV_ID("t0_clk", "fffd4000.timer", &tcb0_clk),
 	CLKDEV_CON_DEV_ID("hclk", "700000.ohci", &uhphs_clk),
 	CLKDEV_CON_DEV_ID("ehci_clk", "800000.ehci", &uhphs_clk),
+	CLKDEV_CON_DEV_ID(NULL, "fff84000.i2c", &twi0_clk),
+	CLKDEV_CON_DEV_ID(NULL, "fff88000.i2c", &twi1_clk),
 	/* fake hclk clock */
 	CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &uhphs_clk),
 	CLKDEV_CON_ID("pioA", &pioA_clk),
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
index e4c3b37..b159607 100644
--- a/arch/arm/mach-at91/at91sam9g45_devices.c
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
@@ -653,7 +653,7 @@
 };
 
 static struct platform_device at91sam9g45_twi0_device = {
-	.name		= "at91_i2c",
+	.name		= "i2c-at91sam9g10",
 	.id		= 0,
 	.resource	= twi0_resources,
 	.num_resources	= ARRAY_SIZE(twi0_resources),
@@ -673,7 +673,7 @@
 };
 
 static struct platform_device at91sam9g45_twi1_device = {
-	.name		= "at91_i2c",
+	.name		= "i2c-at91sam9g10",
 	.id		= 1,
 	.resource	= twi1_resources,
 	.num_resources	= ARRAY_SIZE(twi1_resources),
@@ -686,18 +686,12 @@
 	/* pins used for TWI interface */
 	if (i2c_id == 0) {
 		at91_set_A_periph(AT91_PIN_PA20, 0);		/* TWD */
-		at91_set_multi_drive(AT91_PIN_PA20, 1);
-
 		at91_set_A_periph(AT91_PIN_PA21, 0);		/* TWCK */
-		at91_set_multi_drive(AT91_PIN_PA21, 1);
 
 		platform_device_register(&at91sam9g45_twi0_device);
 	} else {
 		at91_set_A_periph(AT91_PIN_PB10, 0);		/* TWD */
-		at91_set_multi_drive(AT91_PIN_PB10, 1);
-
 		at91_set_A_periph(AT91_PIN_PB11, 0);		/* TWCK */
-		at91_set_multi_drive(AT91_PIN_PB11, 1);
 
 		platform_device_register(&at91sam9g45_twi1_device);
 	}
diff --git a/arch/arm/mach-at91/at91sam9n12.c b/arch/arm/mach-at91/at91sam9n12.c
index 0849466..732d3d3 100644
--- a/arch/arm/mach-at91/at91sam9n12.c
+++ b/arch/arm/mach-at91/at91sam9n12.c
@@ -169,6 +169,8 @@
 	CLKDEV_CON_DEV_ID("t0_clk", "f8008000.timer", &tcb_clk),
 	CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb_clk),
 	CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma_clk),
+	CLKDEV_CON_DEV_ID(NULL, "f8010000.i2c", &twi0_clk),
+	CLKDEV_CON_DEV_ID(NULL, "f8014000.i2c", &twi1_clk),
 	CLKDEV_CON_ID("pioA", &pioAB_clk),
 	CLKDEV_CON_ID("pioB", &pioAB_clk),
 	CLKDEV_CON_ID("pioC", &pioCD_clk),
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c
index 72ce50a..72e9084 100644
--- a/arch/arm/mach-at91/at91sam9rl.c
+++ b/arch/arm/mach-at91/at91sam9rl.c
@@ -186,6 +186,8 @@
 	CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk),
 	CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
 	CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
+	CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.0", &twi0_clk),
+	CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.1", &twi1_clk),
 	CLKDEV_CON_ID("pioA", &pioA_clk),
 	CLKDEV_CON_ID("pioB", &pioB_clk),
 	CLKDEV_CON_ID("pioC", &pioC_clk),
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
index deafea0..d6ca054 100644
--- a/arch/arm/mach-at91/at91sam9rl_devices.c
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -346,7 +346,7 @@
 };
 
 static struct platform_device at91sam9rl_twi_device = {
-	.name		= "at91_i2c",
+	.name		= "i2c-at91sam9g20",
 	.id		= -1,
 	.resource	= twi_resources,
 	.num_resources	= ARRAY_SIZE(twi_resources),
diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c
index 477cf9d..e503538 100644
--- a/arch/arm/mach-at91/at91sam9x5.c
+++ b/arch/arm/mach-at91/at91sam9x5.c
@@ -231,6 +231,9 @@
 	CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb0_clk),
 	CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma0_clk),
 	CLKDEV_CON_DEV_ID("dma_clk", "ffffee00.dma-controller", &dma1_clk),
+	CLKDEV_CON_DEV_ID(NULL, "f8010000.i2c", &twi0_clk),
+	CLKDEV_CON_DEV_ID(NULL, "f8014000.i2c", &twi1_clk),
+	CLKDEV_CON_DEV_ID(NULL, "f8018000.i2c", &twi2_clk),
 	CLKDEV_CON_ID("pioA", &pioAB_clk),
 	CLKDEV_CON_ID("pioB", &pioAB_clk),
 	CLKDEV_CON_ID("pioC", &pioCD_clk),
diff --git a/arch/arm/mach-at91/include/mach/at91_twi.h b/arch/arm/mach-at91/include/mach/at91_twi.h
deleted file mode 100644
index bb2880f..0000000
--- a/arch/arm/mach-at91/include/mach/at91_twi.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * arch/arm/mach-at91/include/mach/at91_twi.h
- *
- * Copyright (C) 2005 Ivan Kokshaysky
- * Copyright (C) SAN People
- *
- * Two-wire Interface (TWI) registers.
- * Based on AT91RM9200 datasheet revision E.
- *
- * 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.
- */
-
-#ifndef AT91_TWI_H
-#define AT91_TWI_H
-
-#define	AT91_TWI_CR		0x00		/* Control Register */
-#define		AT91_TWI_START		(1 <<  0)	/* Send a Start Condition */
-#define		AT91_TWI_STOP		(1 <<  1)	/* Send a Stop Condition */
-#define		AT91_TWI_MSEN		(1 <<  2)	/* Master Transfer Enable */
-#define		AT91_TWI_MSDIS		(1 <<  3)	/* Master Transfer Disable */
-#define		AT91_TWI_SVEN		(1 <<  4)	/* Slave Transfer Enable [SAM9260 only] */
-#define		AT91_TWI_SVDIS		(1 <<  5)	/* Slave Transfer Disable [SAM9260 only] */
-#define		AT91_TWI_SWRST		(1 <<  7)	/* Software Reset */
-
-#define	AT91_TWI_MMR		0x04		/* Master Mode Register */
-#define		AT91_TWI_IADRSZ		(3    <<  8)	/* Internal Device Address Size */
-#define			AT91_TWI_IADRSZ_NO		(0 << 8)
-#define			AT91_TWI_IADRSZ_1		(1 << 8)
-#define			AT91_TWI_IADRSZ_2		(2 << 8)
-#define			AT91_TWI_IADRSZ_3		(3 << 8)
-#define		AT91_TWI_MREAD		(1    << 12)	/* Master Read Direction */
-#define		AT91_TWI_DADR		(0x7f << 16)	/* Device Address */
-
-#define	AT91_TWI_SMR		0x08		/* Slave Mode Register [SAM9260 only] */
-#define		AT91_TWI_SADR		(0x7f << 16)	/* Slave Address */
-
-#define	AT91_TWI_IADR		0x0c		/* Internal Address Register */
-
-#define	AT91_TWI_CWGR		0x10		/* Clock Waveform Generator Register */
-#define		AT91_TWI_CLDIV		(0xff <<  0)	/* Clock Low Divisor */
-#define		AT91_TWI_CHDIV		(0xff <<  8)	/* Clock High Divisor */
-#define		AT91_TWI_CKDIV		(7    << 16)	/* Clock Divider */
-
-#define	AT91_TWI_SR		0x20		/* Status Register */
-#define		AT91_TWI_TXCOMP		(1 <<  0)	/* Transmission Complete */
-#define		AT91_TWI_RXRDY		(1 <<  1)	/* Receive Holding Register Ready */
-#define		AT91_TWI_TXRDY		(1 <<  2)	/* Transmit Holding Register Ready */
-#define		AT91_TWI_SVREAD		(1 <<  3)	/* Slave Read [SAM9260 only] */
-#define		AT91_TWI_SVACC		(1 <<  4)	/* Slave Access [SAM9260 only] */
-#define		AT91_TWI_GACC		(1 <<  5)	/* General Call Access [SAM9260 only] */
-#define		AT91_TWI_OVRE		(1 <<  6)	/* Overrun Error [AT91RM9200 only] */
-#define		AT91_TWI_UNRE		(1 <<  7)	/* Underrun Error [AT91RM9200 only] */
-#define		AT91_TWI_NACK		(1 <<  8)	/* Not Acknowledged */
-#define		AT91_TWI_ARBLST		(1 <<  9)	/* Arbitration Lost [SAM9260 only] */
-#define		AT91_TWI_SCLWS		(1 << 10)	/* Clock Wait State [SAM9260 only] */
-#define		AT91_TWI_EOSACC		(1 << 11)	/* End of Slave Address [SAM9260 only] */
-
-#define	AT91_TWI_IER		0x24		/* Interrupt Enable Register */
-#define	AT91_TWI_IDR		0x28		/* Interrupt Disable Register */
-#define	AT91_TWI_IMR		0x2c		/* Interrupt Mask Register */
-#define	AT91_TWI_RHR		0x30		/* Receive Holding Register */
-#define	AT91_TWI_THR		0x34		/* Transmit Holding Register */
-
-#endif
-
diff --git a/arch/arm/mach-clps711x/autcpu12.c b/arch/arm/mach-clps711x/autcpu12.c
index 3fb79a1..3287191 100644
--- a/arch/arm/mach-clps711x/autcpu12.c
+++ b/arch/arm/mach-clps711x/autcpu12.c
@@ -23,6 +23,8 @@
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
 
 #include <mach/hardware.h>
 #include <asm/sizes.h>
@@ -62,9 +64,26 @@
         iotable_init(autcpu12_io_desc, ARRAY_SIZE(autcpu12_io_desc));
 }
 
+static struct resource autcpu12_nvram_resource[] __initdata = {
+	DEFINE_RES_MEM_NAMED(AUTCPU12_PHYS_NVRAM, SZ_128K, "SRAM"),
+};
+
+static struct platform_device autcpu12_nvram_pdev __initdata = {
+	.name		= "autcpu12_nvram",
+	.id		= -1,
+	.resource	= autcpu12_nvram_resource,
+	.num_resources	= ARRAY_SIZE(autcpu12_nvram_resource),
+};
+
+static void __init autcpu12_init(void)
+{
+	platform_device_register(&autcpu12_nvram_pdev);
+}
+
 MACHINE_START(AUTCPU12, "autronix autcpu12")
 	/* Maintainer: Thomas Gleixner */
 	.atag_offset	= 0x20000,
+	.init_machine	= autcpu12_init,
 	.map_io		= autcpu12_map_io,
 	.init_irq	= clps711x_init_irq,
 	.timer		= &clps711x_timer,
diff --git a/arch/arm/mach-davinci/asp.h b/arch/arm/mach-davinci/asp.h
new file mode 100644
index 0000000..d9b2acd
--- /dev/null
+++ b/arch/arm/mach-davinci/asp.h
@@ -0,0 +1,49 @@
+/*
+ * TI DaVinci Audio definitions
+ */
+#ifndef __ASM_ARCH_DAVINCI_ASP_H
+#define __ASM_ARCH_DAVINCI_ASP_H
+
+/* Bases of dm644x and dm355 register banks */
+#define DAVINCI_ASP0_BASE	0x01E02000
+#define DAVINCI_ASP1_BASE	0x01E04000
+
+/* Bases of dm365 register banks */
+#define DAVINCI_DM365_ASP0_BASE	0x01D02000
+
+/* Bases of dm646x register banks */
+#define DAVINCI_DM646X_MCASP0_REG_BASE		0x01D01000
+#define DAVINCI_DM646X_MCASP1_REG_BASE		0x01D01800
+
+/* Bases of da850/da830 McASP0  register banks */
+#define DAVINCI_DA8XX_MCASP0_REG_BASE	0x01D00000
+
+/* Bases of da830 McASP1 register banks */
+#define DAVINCI_DA830_MCASP1_REG_BASE	0x01D04000
+
+/* EDMA channels of dm644x and dm355 */
+#define DAVINCI_DMA_ASP0_TX	2
+#define DAVINCI_DMA_ASP0_RX	3
+#define DAVINCI_DMA_ASP1_TX	8
+#define DAVINCI_DMA_ASP1_RX	9
+
+/* EDMA channels of dm646x */
+#define DAVINCI_DM646X_DMA_MCASP0_AXEVT0	6
+#define DAVINCI_DM646X_DMA_MCASP0_AREVT0	9
+#define DAVINCI_DM646X_DMA_MCASP1_AXEVT1	12
+
+/* EDMA channels of da850/da830 McASP0 */
+#define DAVINCI_DA8XX_DMA_MCASP0_AREVT	0
+#define DAVINCI_DA8XX_DMA_MCASP0_AXEVT	1
+
+/* EDMA channels of da830 McASP1 */
+#define DAVINCI_DA830_DMA_MCASP1_AREVT	2
+#define DAVINCI_DA830_DMA_MCASP1_AXEVT	3
+
+/* Interrupts */
+#define DAVINCI_ASP0_RX_INT	IRQ_MBRINT
+#define DAVINCI_ASP0_TX_INT	IRQ_MBXINT
+#define DAVINCI_ASP1_RX_INT	IRQ_MBRINT
+#define DAVINCI_ASP1_TX_INT	IRQ_MBXINT
+
+#endif /* __ASM_ARCH_DAVINCI_ASP_H */
diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h
index a37fc44..12d544b 100644
--- a/arch/arm/mach-davinci/davinci.h
+++ b/arch/arm/mach-davinci/davinci.h
@@ -22,10 +22,10 @@
 #include <linux/davinci_emac.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
-
-#include <mach/asp.h>
+#include <linux/platform_data/davinci_asp.h>
 #include <linux/platform_data/keyscan-davinci.h>
 #include <mach/hardware.h>
+#include <mach/edma.h>
 
 #include <media/davinci/vpfe_capture.h>
 #include <media/davinci/vpif_types.h>
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index 783eab6..bd2f72b 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -24,6 +24,7 @@
 #include <mach/cpuidle.h>
 
 #include "clock.h"
+#include "asp.h"
 
 #define DA8XX_TPCC_BASE			0x01c00000
 #define DA8XX_TPTC0_BASE		0x01c08000
@@ -505,15 +506,8 @@
 	.resource	= da850_mcasp_resources,
 };
 
-static struct platform_device davinci_pcm_device = {
-	.name	= "davinci-pcm-audio",
-	.id	= -1,
-};
-
 void __init da8xx_register_mcasp(int id, struct snd_platform_data *pdata)
 {
-	platform_device_register(&davinci_pcm_device);
-
 	/* DA830/OMAP-L137 has 3 instances of McASP */
 	if (cpu_is_davinci_da830() && id == 1) {
 		da830_mcasp1_device.dev.platform_data = pdata;
diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c
index 3a42b6f..4c48a36 100644
--- a/arch/arm/mach-davinci/devices.c
+++ b/arch/arm/mach-davinci/devices.c
@@ -313,16 +313,6 @@
 
 /*-------------------------------------------------------------------------*/
 
-static struct platform_device davinci_pcm_device = {
-	.name		= "davinci-pcm-audio",
-	.id		= -1,
-};
-
-static void davinci_init_pcm(void)
-{
-	platform_device_register(&davinci_pcm_device);
-}
-
 /*-------------------------------------------------------------------------*/
 
 struct davinci_timer_instance davinci_timer_instance[2] = {
@@ -345,7 +335,6 @@
 	/* please keep these calls, and their implementations above,
 	 * in alphabetical order so they're easier to sort through.
 	 */
-	davinci_init_pcm();
 	davinci_init_wdt();
 
 	return 0;
diff --git a/arch/arm/mach-davinci/dm355.c b/arch/arm/mach-davinci/dm355.c
index adbde33..a255434 100644
--- a/arch/arm/mach-davinci/dm355.c
+++ b/arch/arm/mach-davinci/dm355.c
@@ -26,13 +26,13 @@
 #include <mach/time.h>
 #include <mach/serial.h>
 #include <mach/common.h>
-#include <mach/asp.h>
 #include <linux/platform_data/spi-davinci.h>
 #include <mach/gpio-davinci.h>
 
 #include "davinci.h"
 #include "clock.h"
 #include "mux.h"
+#include "asp.h"
 
 #define DM355_UART2_BASE	(IO_PHYS + 0x206000)
 
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index 719e22f..b680c83 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -29,7 +29,6 @@
 #include <mach/time.h>
 #include <mach/serial.h>
 #include <mach/common.h>
-#include <mach/asp.h>
 #include <linux/platform_data/keyscan-davinci.h>
 #include <linux/platform_data/spi-davinci.h>
 #include <mach/gpio-davinci.h>
@@ -37,6 +36,7 @@
 #include "davinci.h"
 #include "clock.h"
 #include "mux.h"
+#include "asp.h"
 
 #define DM365_REF_FREQ		24000000	/* 24 MHz on the DM365 EVM */
 
diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c
index 79d2880..cd0c8b1 100644
--- a/arch/arm/mach-davinci/dm644x.c
+++ b/arch/arm/mach-davinci/dm644x.c
@@ -23,12 +23,12 @@
 #include <mach/time.h>
 #include <mach/serial.h>
 #include <mach/common.h>
-#include <mach/asp.h>
 #include <mach/gpio-davinci.h>
 
 #include "davinci.h"
 #include "clock.h"
 #include "mux.h"
+#include "asp.h"
 
 /*
  * Device specific clocks
diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c
index 9eb87c1..97c0f8e 100644
--- a/arch/arm/mach-davinci/dm646x.c
+++ b/arch/arm/mach-davinci/dm646x.c
@@ -24,12 +24,12 @@
 #include <mach/time.h>
 #include <mach/serial.h>
 #include <mach/common.h>
-#include <mach/asp.h>
 #include <mach/gpio-davinci.h>
 
 #include "davinci.h"
 #include "clock.h"
 #include "mux.h"
+#include "asp.h"
 
 #define DAVINCI_VPIF_BASE       (0x01C12000)
 
diff --git a/arch/arm/mach-davinci/include/mach/asp.h b/arch/arm/mach-davinci/include/mach/asp.h
deleted file mode 100644
index 9aa2409..0000000
--- a/arch/arm/mach-davinci/include/mach/asp.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * <mach/asp.h> - DaVinci Audio Serial Port support
- */
-#ifndef __ASM_ARCH_DAVINCI_ASP_H
-#define __ASM_ARCH_DAVINCI_ASP_H
-
-#include <mach/irqs.h>
-#include <mach/edma.h>
-
-/* Bases of dm644x and dm355 register banks */
-#define DAVINCI_ASP0_BASE	0x01E02000
-#define DAVINCI_ASP1_BASE	0x01E04000
-
-/* Bases of dm365 register banks */
-#define DAVINCI_DM365_ASP0_BASE	0x01D02000
-
-/* Bases of dm646x register banks */
-#define	DAVINCI_DM646X_MCASP0_REG_BASE		0x01D01000
-#define DAVINCI_DM646X_MCASP1_REG_BASE		0x01D01800
-
-/* Bases of da850/da830 McASP0  register banks */
-#define DAVINCI_DA8XX_MCASP0_REG_BASE	0x01D00000
-
-/* Bases of da830 McASP1 register banks */
-#define DAVINCI_DA830_MCASP1_REG_BASE	0x01D04000
-
-/* EDMA channels of dm644x and dm355 */
-#define DAVINCI_DMA_ASP0_TX	2
-#define DAVINCI_DMA_ASP0_RX	3
-#define DAVINCI_DMA_ASP1_TX	8
-#define DAVINCI_DMA_ASP1_RX	9
-
-/* EDMA channels of dm646x */
-#define	DAVINCI_DM646X_DMA_MCASP0_AXEVT0	6
-#define	DAVINCI_DM646X_DMA_MCASP0_AREVT0	9
-#define	DAVINCI_DM646X_DMA_MCASP1_AXEVT1	12
-
-/* EDMA channels of da850/da830 McASP0 */
-#define	DAVINCI_DA8XX_DMA_MCASP0_AREVT	0
-#define	DAVINCI_DA8XX_DMA_MCASP0_AXEVT	1
-
-/* EDMA channels of da830 McASP1 */
-#define	DAVINCI_DA830_DMA_MCASP1_AREVT	2
-#define	DAVINCI_DA830_DMA_MCASP1_AXEVT	3
-
-/* Interrupts */
-#define DAVINCI_ASP0_RX_INT	IRQ_MBRINT
-#define DAVINCI_ASP0_TX_INT	IRQ_MBXINT
-#define DAVINCI_ASP1_RX_INT	IRQ_MBRINT
-#define DAVINCI_ASP1_TX_INT	IRQ_MBXINT
-
-struct snd_platform_data {
-	u32 tx_dma_offset;
-	u32 rx_dma_offset;
-	enum dma_event_q asp_chan_q;	/* event queue number for ASP channel */
-	enum dma_event_q ram_chan_q;	/* event queue number for RAM channel */
-	unsigned int codec_fmt;
-	/*
-	 * Allowing this is more efficient and eliminates left and right swaps
-	 * caused by underruns, but will swap the left and right channels
-	 * when compared to previous behavior.
-	 */
-	unsigned enable_channel_combine:1;
-	unsigned sram_size_playback;
-	unsigned sram_size_capture;
-
-	/*
-	 * If McBSP peripheral gets the clock from an external pin,
-	 * there are three chooses, that are MCBSP_CLKX, MCBSP_CLKR
-	 * and MCBSP_CLKS.
-	 * Depending on different hardware connections it is possible
-	 * to use this setting to change the behaviour of McBSP
-	 * driver. The dm365_clk_input_pin enum is available for dm365
-	 */
-	int clk_input_pin;
-
-	/*
-	 * This flag works when both clock and FS are outputs for the cpu
-	 * and makes clock more accurate (FS is not symmetrical and the
-	 * clock is very fast.
-	 * The clock becoming faster is named
-	 * i2s continuous serial clock (I2S_SCK) and it is an externally
-	 * visible bit clock.
-	 *
-	 * first line : WordSelect
-	 * second line : ContinuousSerialClock
-	 * third line: SerialData
-	 *
-	 * SYMMETRICAL APPROACH:
-	 *   _______________________          LEFT
-	 * _|         RIGHT         |______________________|
-	 *     _   _         _   _   _   _         _   _
-	 *   _| |_| |_ x16 _| |_| |_| |_| |_ x16 _| |_| |_
-	 *     _   _         _   _   _   _         _   _
-	 *   _/ \_/ \_ ... _/ \_/ \_/ \_/ \_ ... _/ \_/ \_
-	 *    \_/ \_/       \_/ \_/ \_/ \_/       \_/ \_/
-	 *
-	 * ACCURATE CLOCK APPROACH:
-	 *   ______________          LEFT
-	 * _|     RIGHT    |_______________________________|
-	 *     _         _   _         _   _   _   _   _   _
-	 *   _| |_ x16 _| |_| |_ x16 _| |_| |_| |_| |_| |_| |
-	 *     _         _   _          _      dummy cycles
-	 *   _/ \_ ... _/ \_/ \_  ... _/ \__________________
-	 *    \_/       \_/ \_/        \_/
-	 *
-	 */
-	bool i2s_accurate_sck;
-
-	/* McASP specific fields */
-	int tdm_slots;
-	u8 op_mode;
-	u8 num_serializer;
-	u8 *serial_dir;
-	u8 version;
-	u8 txnumevt;
-	u8 rxnumevt;
-};
-
-enum {
-	MCASP_VERSION_1 = 0,	/* DM646x */
-	MCASP_VERSION_2,	/* DA8xx/OMAPL1x */
-};
-
-enum dm365_clk_input_pin {
-	MCBSP_CLKR = 0,		/* DM365 */
-	MCBSP_CLKS,
-};
-
-#define INACTIVE_MODE	0
-#define TX_MODE		1
-#define RX_MODE		2
-
-#define DAVINCI_MCASP_IIS_MODE	0
-#define DAVINCI_MCASP_DIT_MODE	1
-
-#endif /* __ASM_ARCH_DAVINCI_ASP_H */
diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h
index 13d2295..aaccdc4 100644
--- a/arch/arm/mach-davinci/include/mach/da8xx.h
+++ b/arch/arm/mach-davinci/include/mach/da8xx.h
@@ -16,11 +16,11 @@
 #include <linux/platform_device.h>
 #include <linux/davinci_emac.h>
 #include <linux/spi/spi.h>
+#include <linux/platform_data/davinci_asp.h>
 #include <linux/videodev2.h>
 
 #include <mach/serial.h>
 #include <mach/edma.h>
-#include <mach/asp.h>
 #include <mach/pm.h>
 #include <linux/platform_data/i2c-davinci.h>
 #include <linux/platform_data/mmc-davinci.h>
diff --git a/arch/arm/mach-exynos/dma.c b/arch/arm/mach-exynos/dma.c
index f60b66d..21d568b 100644
--- a/arch/arm/mach-exynos/dma.c
+++ b/arch/arm/mach-exynos/dma.c
@@ -303,10 +303,12 @@
 
 	dma_cap_set(DMA_SLAVE, exynos_pdma0_pdata.cap_mask);
 	dma_cap_set(DMA_CYCLIC, exynos_pdma0_pdata.cap_mask);
+	dma_cap_set(DMA_PRIVATE, exynos_pdma0_pdata.cap_mask);
 	amba_device_register(&exynos_pdma0_device, &iomem_resource);
 
 	dma_cap_set(DMA_SLAVE, exynos_pdma1_pdata.cap_mask);
 	dma_cap_set(DMA_CYCLIC, exynos_pdma1_pdata.cap_mask);
+	dma_cap_set(DMA_PRIVATE, exynos_pdma1_pdata.cap_mask);
 	amba_device_register(&exynos_pdma1_device, &iomem_resource);
 
 	dma_cap_set(DMA_MEMCPY, exynos_mdma1_pdata.cap_mask);
diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
index d397fd2..c05d7aa 100644
--- a/arch/arm/mach-exynos/mach-nuri.c
+++ b/arch/arm/mach-exynos/mach-nuri.c
@@ -29,6 +29,7 @@
 #include <drm/exynos_drm.h>
 
 #include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
 #include <media/m5mols.h>
 #include <media/s5k6aa.h>
 #include <media/s5p_fimc.h>
@@ -39,7 +40,6 @@
 #include <asm/mach-types.h>
 
 #include <plat/adc.h>
-#include <plat/regs-fb-v4.h>
 #include <plat/regs-serial.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
index 8ff06eb..9adf491 100644
--- a/arch/arm/mach-exynos/mach-origen.c
+++ b/arch/arm/mach-exynos/mach-origen.c
@@ -30,9 +30,9 @@
 #include <asm/mach-types.h>
 
 #include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
 
 #include <plat/regs-serial.h>
-#include <plat/regs-fb-v4.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/sdhci.h>
diff --git a/arch/arm/mach-exynos/mach-smdk4x12.c b/arch/arm/mach-exynos/mach-smdk4x12.c
index 7a265d1..730f1ac 100644
--- a/arch/arm/mach-exynos/mach-smdk4x12.c
+++ b/arch/arm/mach-exynos/mach-smdk4x12.c
@@ -27,6 +27,7 @@
 #include <asm/hardware/gic.h>
 #include <asm/mach-types.h>
 
+#include <video/samsung_fimd.h>
 #include <plat/backlight.h>
 #include <plat/clock.h>
 #include <plat/cpu.h>
@@ -36,7 +37,6 @@
 #include <linux/platform_data/i2c-s3c2410.h>
 #include <plat/keypad.h>
 #include <plat/mfc.h>
-#include <plat/regs-fb.h>
 #include <plat/regs-serial.h>
 #include <plat/sdhci.h>
 
diff --git a/arch/arm/mach-exynos/mach-smdkv310.c b/arch/arm/mach-exynos/mach-smdkv310.c
index c15d223..ee4fb1a 100644
--- a/arch/arm/mach-exynos/mach-smdkv310.c
+++ b/arch/arm/mach-exynos/mach-smdkv310.c
@@ -27,9 +27,9 @@
 #include <asm/mach-types.h>
 
 #include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
 #include <plat/regs-serial.h>
 #include <plat/regs-srom.h>
-#include <plat/regs-fb-v4.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/fb.h>
diff --git a/arch/arm/mach-exynos/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c
index 6e73133..ebc9dd3 100644
--- a/arch/arm/mach-exynos/mach-universal_c210.c
+++ b/arch/arm/mach-exynos/mach-universal_c210.c
@@ -30,6 +30,7 @@
 #include <asm/hardware/gic.h>
 #include <asm/mach-types.h>
 
+#include <video/samsung_fimd.h>
 #include <plat/regs-serial.h>
 #include <plat/clock.h>
 #include <plat/cpu.h>
@@ -39,7 +40,6 @@
 #include <plat/fb.h>
 #include <plat/mfc.h>
 #include <plat/sdhci.h>
-#include <plat/regs-fb-v4.h>
 #include <plat/fimc-core.h>
 #include <plat/s5p-time.h>
 #include <plat/camport.h>
diff --git a/arch/arm/mach-exynos/setup-fimd0.c b/arch/arm/mach-exynos/setup-fimd0.c
index 07a6dbe..5665bb4 100644
--- a/arch/arm/mach-exynos/setup-fimd0.c
+++ b/arch/arm/mach-exynos/setup-fimd0.c
@@ -13,8 +13,8 @@
 #include <linux/fb.h>
 #include <linux/gpio.h>
 
+#include <video/samsung_fimd.h>
 #include <plat/gpio-cfg.h>
-#include <plat/regs-fb-v4.h>
 
 #include <mach/map.h>
 
diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c
index e5165a8..a0bf848 100644
--- a/arch/arm/mach-imx/clk-imx51-imx53.c
+++ b/arch/arm/mach-imx/clk-imx51-imx53.c
@@ -369,6 +369,7 @@
 	clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "83fcc000.ssi");
 	clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "70014000.ssi");
 	clk_register_clkdev(clk[ssi3_ipg_gate], NULL, "83fe8000.ssi");
+	clk_register_clkdev(clk[nfc_gate], NULL, "83fdb000.nand");
 
 	/* set the usboh3 parent to pll2_sw */
 	clk_set_parent(clk[usboh3_sel], clk[pll2_sw]);
@@ -461,6 +462,7 @@
 	clk_register_clkdev(clk[ssi1_ipg_gate], NULL, "63fcc000.ssi");
 	clk_register_clkdev(clk[ssi2_ipg_gate], NULL, "50014000.ssi");
 	clk_register_clkdev(clk[ssi3_ipg_gate], NULL, "63fd0000.ssi");
+	clk_register_clkdev(clk[nfc_gate], NULL, "63fdb000.nand");
 	clk_register_clkdev(clk[can1_ipg_gate], "ipg", "53fc8000.can");
 	clk_register_clkdev(clk[can1_serial_gate], "per", "53fc8000.can");
 	clk_register_clkdev(clk[can2_ipg_gate], "ipg", "53fcc000.can");
diff --git a/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c b/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
index fd3177f..98aef57 100644
--- a/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
+++ b/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
@@ -348,4 +348,5 @@
 	imx27_add_imx_keypad(&eukrea_mbimx27_keymap_data);
 
 	gpio_led_register_device(-1, &eukrea_mbimx27_gpio_led_info);
+	imx_add_platform_device("eukrea_tlv320", 0, NULL, 0, NULL, 0);
 }
diff --git a/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c b/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c
index dfd2da8..0b84666 100644
--- a/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c
+++ b/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c
@@ -306,4 +306,5 @@
 	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
 	gpio_led_register_device(-1, &eukrea_mbimxsd_led_info);
 	imx_add_gpio_keys(&eukrea_mbimxsd_button_data);
+	imx_add_platform_device("eukrea_tlv320", 0, NULL, 0, NULL, 0);
 }
diff --git a/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c b/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c
index 6e9dd12..c6532a0 100644
--- a/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c
+++ b/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c
@@ -315,4 +315,5 @@
 	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
 	gpio_led_register_device(-1, &eukrea_mbimxsd_led_info);
 	imx_add_gpio_keys(&eukrea_mbimxsd_button_data);
+	imx_add_platform_device("eukrea_tlv320", 0, NULL, 0, NULL, 0);
 }
diff --git a/arch/arm/mach-imx/eukrea_mbimxsd51-baseboard.c b/arch/arm/mach-imx/eukrea_mbimxsd51-baseboard.c
index 96a24b7..8b0de30 100644
--- a/arch/arm/mach-imx/eukrea_mbimxsd51-baseboard.c
+++ b/arch/arm/mach-imx/eukrea_mbimxsd51-baseboard.c
@@ -228,4 +228,5 @@
 
 	gpio_led_register_device(-1, &eukrea_mbimxsd51_led_info);
 	imx_add_gpio_keys(&eukrea_mbimxsd51_button_data);
+	imx_add_platform_device("eukrea_tlv320", 0, NULL, 0, NULL, 0);
 }
diff --git a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
index 821d6aa..141756f 100644
--- a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
+++ b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
@@ -32,6 +32,7 @@
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/leds.h>
+#include <linux/platform_data/asoc-mx27vis.h>
 #include <media/soc_camera.h>
 #include <sound/tlv320aic32x4.h>
 #include <asm/mach-types.h>
@@ -58,6 +59,11 @@
 #define EXPBOARD_BIT1		(GPIO_PORTD + 27)
 #define EXPBOARD_BIT0		(GPIO_PORTD + 28)
 
+#define AMP_GAIN_0		(GPIO_PORTF + 9)
+#define AMP_GAIN_1		(GPIO_PORTF + 8)
+#define AMP_MUTE_SDL		(GPIO_PORTE + 5)
+#define AMP_MUTE_SDR		(GPIO_PORTF + 7)
+
 static const int visstrim_m10_pins[] __initconst = {
 	/* UART1 (console) */
 	PE12_PF_UART1_TXD,
@@ -139,6 +145,11 @@
 	EXPBOARD_BIT2 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
 	EXPBOARD_BIT1 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
 	EXPBOARD_BIT0 | GPIO_GPIO | GPIO_IN | GPIO_PUEN,
+	/* Audio AMP control */
+	AMP_GAIN_0 | GPIO_GPIO | GPIO_OUT,
+	AMP_GAIN_1 | GPIO_GPIO | GPIO_OUT,
+	AMP_MUTE_SDL | GPIO_GPIO | GPIO_OUT,
+	AMP_MUTE_SDR | GPIO_GPIO | GPIO_OUT,
 };
 
 static struct gpio visstrim_m10_version_gpios[] = {
@@ -166,6 +177,26 @@
 		.flags = GPIOF_DIR_OUT | GPIOF_INIT_LOW,
 		.label = "usbotg_cs",
 	},
+	{
+		.gpio = AMP_GAIN_0,
+		.flags = GPIOF_DIR_OUT,
+		.label = "amp-gain-0",
+	},
+	{
+		.gpio = AMP_GAIN_1,
+		.flags = GPIOF_DIR_OUT,
+		.label = "amp-gain-1",
+	},
+	{
+		.gpio = AMP_MUTE_SDL,
+		.flags = GPIOF_DIR_OUT,
+		.label = "amp-mute-sdl",
+	},
+	{
+		.gpio = AMP_MUTE_SDR,
+		.flags = GPIOF_DIR_OUT,
+		.label = "amp-mute-sdr",
+	},
 };
 
 /* Camera */
@@ -444,6 +475,14 @@
 }
 
 
+/* Audio */
+static const struct snd_mx27vis_platform_data snd_mx27vis_pdata __initconst = {
+	.amp_gain0_gpio = AMP_GAIN_0,
+	.amp_gain1_gpio = AMP_GAIN_1,
+	.amp_mutel_gpio = AMP_MUTE_SDL,
+	.amp_muter_gpio = AMP_MUTE_SDR,
+};
+
 static void __init visstrim_m10_revision(void)
 {
 	int exp_version = 0;
@@ -502,7 +541,8 @@
 	imx27_add_fec(NULL);
 	imx_add_gpio_keys(&visstrim_gpio_keys_platform_data);
 	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
-	imx_add_platform_device("mx27vis", 0, NULL, 0, NULL, 0);
+	imx_add_platform_device("mx27vis", 0, NULL, 0, &snd_mx27vis_pdata,
+				sizeof(snd_mx27vis_pdata));
 	platform_device_register_resndata(NULL, "soc-camera-pdrv", 0, NULL, 0,
 				      &iclink_tvp5150, sizeof(iclink_tvp5150));
 	gpio_led_register_device(0, &visstrim_m10_led_data);
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index 726c02c..d3fec92 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -231,7 +231,7 @@
 
 		omap_mmc_add("mmci-omap", i, base, size, irq,
 				rx_req, tx_req, mmc_data[i]);
-	};
+	}
 }
 
 #endif
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index a88809a..3669c12 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -607,29 +607,6 @@
 			__func__, OMAP4_SFH7741_ENABLE_GPIO, error);
 }
 
-static struct gpio sdp4430_hdmi_gpios[] = {
-	{ HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" },
-	{ HDMI_GPIO_LS_OE,	GPIOF_OUT_INIT_HIGH,	"hdmi_gpio_ls_oe" },
-	{ HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" },
-};
-
-static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev)
-{
-	int status;
-
-	status = gpio_request_array(sdp4430_hdmi_gpios,
-				    ARRAY_SIZE(sdp4430_hdmi_gpios));
-	if (status)
-		pr_err("%s: Cannot request HDMI GPIOs\n", __func__);
-
-	return status;
-}
-
-static void sdp4430_panel_disable_hdmi(struct omap_dss_device *dssdev)
-{
-	gpio_free_array(sdp4430_hdmi_gpios, ARRAY_SIZE(sdp4430_hdmi_gpios));
-}
-
 static struct nokia_dsi_panel_data dsi1_panel = {
 		.name		= "taal",
 		.reset_gpio	= 102,
@@ -650,29 +627,6 @@
 	.phy.dsi		= {
 		.module		= 0,
 	},
-
-	.clocks = {
-		.dispc = {
-			.channel = {
-				/* Logic Clock = 172.8 MHz */
-				.lck_div	= 1,
-				/* Pixel Clock = 34.56 MHz */
-				.pck_div	= 5,
-				.lcd_clk_src	= OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC,
-			},
-			.dispc_fclk_src	= OMAP_DSS_CLK_SRC_FCK,
-		},
-
-		.dsi = {
-			.regn		= 16,	/* Fint = 2.4 MHz */
-			.regm		= 180,	/* DDR Clock = 216 MHz */
-			.regm_dispc	= 5,	/* PLL1_CLK1 = 172.8 MHz */
-			.regm_dsi	= 5,	/* PLL1_CLK2 = 172.8 MHz */
-
-			.lp_clk_div	= 10,	/* LP Clock = 8.64 MHz */
-			.dsi_fclk_src	= OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI,
-		},
-	},
 	.channel		= OMAP_DSS_CHANNEL_LCD,
 };
 
@@ -697,33 +651,12 @@
 
 		.module		= 1,
 	},
-
-	.clocks = {
-		.dispc = {
-			.channel = {
-				/* Logic Clock = 172.8 MHz */
-				.lck_div	= 1,
-				/* Pixel Clock = 34.56 MHz */
-				.pck_div	= 5,
-				.lcd_clk_src	= OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC,
-			},
-			.dispc_fclk_src	= OMAP_DSS_CLK_SRC_FCK,
-		},
-
-		.dsi = {
-			.regn		= 16,	/* Fint = 2.4 MHz */
-			.regm		= 180,	/* DDR Clock = 216 MHz */
-			.regm_dispc	= 5,	/* PLL1_CLK1 = 172.8 MHz */
-			.regm_dsi	= 5,	/* PLL1_CLK2 = 172.8 MHz */
-
-			.lp_clk_div	= 10,	/* LP Clock = 8.64 MHz */
-			.dsi_fclk_src	= OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI,
-		},
-	},
 	.channel		= OMAP_DSS_CHANNEL_LCD2,
 };
 
 static struct omap_dss_hdmi_data sdp4430_hdmi_data = {
+	.ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD,
+	.ls_oe_gpio = HDMI_GPIO_LS_OE,
 	.hpd_gpio = HDMI_GPIO_HPD,
 };
 
@@ -731,8 +664,6 @@
 	.name = "hdmi",
 	.driver_name = "hdmi_panel",
 	.type = OMAP_DISPLAY_TYPE_HDMI,
-	.platform_enable = sdp4430_panel_enable_hdmi,
-	.platform_disable = sdp4430_panel_disable_hdmi,
 	.channel = OMAP_DSS_CHANNEL_DIGIT,
 	.data = &sdp4430_hdmi_data,
 };
@@ -830,6 +761,32 @@
 	/* NIRQ2 for twl6040 */
 	OMAP4_MUX(SYS_NIRQ2, OMAP_MUX_MODE0 |
 		  OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE),
+	/* GPIO_127 for twl6040 */
+	OMAP4_MUX(HDQ_SIO, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT),
+	/* McPDM */
+	OMAP4_MUX(ABE_PDM_UL_DATA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+	OMAP4_MUX(ABE_PDM_DL_DATA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+	OMAP4_MUX(ABE_PDM_FRAME, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+	OMAP4_MUX(ABE_PDM_LB_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+	OMAP4_MUX(ABE_CLKS, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+	/* DMIC */
+	OMAP4_MUX(ABE_DMIC_CLK1, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT),
+	OMAP4_MUX(ABE_DMIC_DIN1, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+	OMAP4_MUX(ABE_DMIC_DIN2, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+	OMAP4_MUX(ABE_DMIC_DIN3, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+	/* McBSP1 */
+	OMAP4_MUX(ABE_MCBSP1_CLKX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+	OMAP4_MUX(ABE_MCBSP1_DR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+	OMAP4_MUX(ABE_MCBSP1_DX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT |
+		  OMAP_PULL_ENA),
+	OMAP4_MUX(ABE_MCBSP1_FSX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+	/* McBSP2 */
+	OMAP4_MUX(ABE_MCBSP2_CLKX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+	OMAP4_MUX(ABE_MCBSP2_DR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+	OMAP4_MUX(ABE_MCBSP2_DX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT |
+		  OMAP_PULL_ENA),
+	OMAP4_MUX(ABE_MCBSP2_FSX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
 	{ .reg_offset = OMAP_MUX_TERMINATOR },
 };
 
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index 0d99c91..e162897 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -263,6 +263,16 @@
 	usb_musb_init(&musb_board_data);
 }
 
+static __init void am3517_evm_mcbsp1_init(void)
+{
+	u32 devconf0;
+
+	/* McBSP1 CLKR/FSR signal to be connected to CLKX/FSX pin */
+	devconf0 = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+	devconf0 |=  OMAP2_MCBSP1_CLKR_MASK | OMAP2_MCBSP1_FSR_MASK;
+	omap_ctrl_writel(devconf0, OMAP2_CONTROL_DEVCONF0);
+}
+
 static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
 	.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
 #if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \
@@ -366,6 +376,9 @@
 	/* MUSB */
 	am3517_evm_musb_init();
 
+	/* McBSP1 */
+	am3517_evm_mcbsp1_init();
+
 	/* MMC init function */
 	omap_hsmmc_init(mmc);
 }
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index 8ffd612..376d26e 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -723,6 +723,7 @@
 	cm_t35_init_ethernet();
 	cm_t35_init_led();
 	cm_t35_init_display();
+	omap_twl4030_audio_init("cm-t3x");
 
 	usb_musb_init(NULL);
 	cm_t35_init_usbh();
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index 7bb8056..1fd161e 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -623,6 +623,7 @@
 	usbhs_init(&usbhs_bdata);
 	omap_nand_flash_init(NAND_BUSWIDTH_16, devkit8000_nand_partitions,
 			     ARRAY_SIZE(devkit8000_nand_partitions));
+	omap_twl4030_audio_init("omap3beagle");
 
 	/* Ensure SDRC pins are mux'd for self-refresh */
 	omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c
index 0cabe61..e642acf 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -218,7 +218,7 @@
 			if (onenandcs > GPMC_CS_NUM)
 				onenandcs = cs;
 			break;
-		};
+		}
 		cs++;
 	}
 
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index fb8bd83..48d5e41 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -625,6 +625,7 @@
 
 	igep_flash_init();
 	igep_leds_init();
+	omap_twl4030_audio_init("igep2");
 
 	/*
 	 * WLAN-BT combo module from MuRata which has a Marvell WLAN
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 68ff8d5..388c431 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -461,7 +461,7 @@
 		mpu_dev = omap_device_get_by_hwmod_name("mpu");
 		iva_dev = omap_device_get_by_hwmod_name("iva");
 
-		if (!mpu_dev || !iva_dev) {
+		if (IS_ERR(mpu_dev) || IS_ERR(iva_dev)) {
 			pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n",
 				__func__, mpu_dev, iva_dev);
 			return;
@@ -514,6 +514,7 @@
 	usbhs_init(&usbhs_bdata);
 	omap_nand_flash_init(NAND_BUSWIDTH_16, omap3beagle_nand_partitions,
 			     ARRAY_SIZE(omap3beagle_nand_partitions));
+	omap_twl4030_audio_init("omap3beagle");
 
 	/* Ensure msecure is mux'd to be able to set the RTC. */
 	omap_mux_init_signal("sys_drm_msecure", OMAP_PIN_OFF_OUTPUT_HIGH);
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index c64e565..b9b776b 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -88,11 +88,10 @@
 
 static u8 omap3_evm_version;
 
-u8 get_omap3_evm_rev(void)
+static u8 get_omap3_evm_rev(void)
 {
 	return omap3_evm_version;
 }
-EXPORT_SYMBOL(get_omap3_evm_rev);
 
 static void __init omap3_evm_get_revision(void)
 {
@@ -739,6 +738,7 @@
 	omap3evm_init_smsc911x();
 	omap3_evm_display_init();
 	omap3_evm_wl12xx_init();
+	omap_twl4030_audio_init("omap3evm");
 }
 
 MACHINE_START(OMAP3EVM, "OMAP3 EVM")
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index c7f3d02..731235e 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -48,11 +48,6 @@
 #include <video/omap-panel-tfp410.h>
 
 #include <linux/platform_data/spi-omap2-mcspi.h>
-#include <linux/input/matrix_keypad.h>
-#include <linux/spi/spi.h>
-#include <linux/interrupt.h>
-#include <linux/smsc911x.h>
-#include <linux/i2c/at24.h>
 
 #include "sdram-micron-mt46h32m32lf-6.h"
 #include "mux.h"
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 2b012f9..bfcd397 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -247,8 +247,7 @@
 };
 
 static struct wl12xx_platform_data omap_panda_wlan_data  __initdata = {
-	/* PANDA ref clock is 38.4 MHz */
-	.board_ref_clock = 2,
+	.board_ref_clock = WL12XX_REFCLOCK_38, /* 38.4 MHz */
 };
 
 static struct twl6040_codec_data twl6040_codec = {
@@ -388,6 +387,21 @@
 	/* NIRQ2 for twl6040 */
 	OMAP4_MUX(SYS_NIRQ2, OMAP_MUX_MODE0 |
 		  OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE),
+	/* GPIO_127 for twl6040 */
+	OMAP4_MUX(HDQ_SIO, OMAP_MUX_MODE3 | OMAP_PIN_OUTPUT),
+	/* McPDM */
+	OMAP4_MUX(ABE_PDM_UL_DATA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+	OMAP4_MUX(ABE_PDM_DL_DATA, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+	OMAP4_MUX(ABE_PDM_FRAME, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
+	OMAP4_MUX(ABE_PDM_LB_CLK, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+	OMAP4_MUX(ABE_CLKS, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+	/* McBSP1 */
+	OMAP4_MUX(ABE_MCBSP1_CLKX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+	OMAP4_MUX(ABE_MCBSP1_DR, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
+	OMAP4_MUX(ABE_MCBSP1_DX, OMAP_MUX_MODE0 | OMAP_PIN_OUTPUT |
+		  OMAP_PULL_ENA),
+	OMAP4_MUX(ABE_MCBSP1_FSX, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),
+
 	{ .reg_offset = OMAP_MUX_TERMINATOR },
 };
 
@@ -414,30 +428,9 @@
 	.channel		= OMAP_DSS_CHANNEL_LCD2,
 };
 
-static struct gpio panda_hdmi_gpios[] = {
-	{ HDMI_GPIO_CT_CP_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ct_cp_hpd" },
-	{ HDMI_GPIO_LS_OE,	GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
-	{ HDMI_GPIO_HPD, GPIOF_DIR_IN, "hdmi_gpio_hpd" },
-};
-
-static int omap4_panda_panel_enable_hdmi(struct omap_dss_device *dssdev)
-{
-	int status;
-
-	status = gpio_request_array(panda_hdmi_gpios,
-				    ARRAY_SIZE(panda_hdmi_gpios));
-	if (status)
-		pr_err("Cannot request HDMI GPIOs\n");
-
-	return status;
-}
-
-static void omap4_panda_panel_disable_hdmi(struct omap_dss_device *dssdev)
-{
-	gpio_free_array(panda_hdmi_gpios, ARRAY_SIZE(panda_hdmi_gpios));
-}
-
 static struct omap_dss_hdmi_data omap4_panda_hdmi_data = {
+	.ct_cp_hpd_gpio = HDMI_GPIO_CT_CP_HPD,
+	.ls_oe_gpio = HDMI_GPIO_LS_OE,
 	.hpd_gpio = HDMI_GPIO_HPD,
 };
 
@@ -445,8 +438,6 @@
 	.name = "hdmi",
 	.driver_name = "hdmi_panel",
 	.type = OMAP_DISPLAY_TYPE_HDMI,
-	.platform_enable = omap4_panda_panel_enable_hdmi,
-	.platform_disable = omap4_panda_panel_disable_hdmi,
 	.channel = OMAP_DSS_CHANNEL_DIGIT,
 	.data = &omap4_panda_hdmi_data,
 };
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 2e7f240..b700685 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -504,6 +504,7 @@
 	overo_display_init();
 	overo_init_led();
 	overo_init_keys();
+	omap_twl4030_audio_init("overo");
 
 	/* Ensure SDRC pins are mux'd for self-refresh */
 	omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index ed85fb8..020e03c 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -748,7 +748,7 @@
 	.subdev_board_info = &rx51_si4713_board_info,
 };
 
-static struct platform_device rx51_si4713_dev = {
+static struct platform_device rx51_si4713_dev __initdata_or_module = {
 	.name	= "radio-si4713",
 	.id	= -1,
 	.dev	= {
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index 6bcc107..c166fe1 100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -35,6 +35,7 @@
 #include "common-board-devices.h"
 
 #define OMAP_ZOOM_WLAN_PMENA_GPIO	(101)
+#define ZOOM2_HEADSET_EXTMUTE_GPIO	(153)
 #define OMAP_ZOOM_WLAN_IRQ_GPIO		(162)
 
 #define LCD_PANEL_ENABLE_GPIO		(7 + OMAP_MAX_GPIO_LINES)
@@ -194,8 +195,7 @@
 };
 
 static struct wl12xx_platform_data omap_zoom_wlan_data __initdata = {
-	/* ZOOM ref clock is 26 MHz */
-	.board_ref_clock = 1,
+	.board_ref_clock = WL12XX_REFCLOCK_26, /* 26 MHz */
 };
 
 static struct omap2_hsmmc_info mmc[] = {
@@ -245,12 +245,6 @@
 	return ret;
 }
 
-/* EXTMUTE callback function */
-static void zoom2_set_hs_extmute(int mute)
-{
-	gpio_set_value(ZOOM2_HEADSET_EXTMUTE_GPIO, mute);
-}
-
 static struct twl4030_gpio_platform_data zoom_gpio_data = {
 	.setup		= zoom_twl_gpio_setup,
 };
@@ -277,7 +271,7 @@
 
 		codec_data->ramp_delay_value = 3;	/* 161 ms */
 		codec_data->hs_extmute = 1;
-		codec_data->set_hs_extmute = zoom2_set_hs_extmute;
+		codec_data->hs_extmute_gpio = ZOOM2_HEADSET_EXTMUTE_GPIO;
 	}
 	omap_pmic_init(1, 2400, "twl5030", 7 + OMAP_INTC_START, &zoom_twldata);
 	omap_register_i2c_bus(2, 400, NULL, 0);
diff --git a/arch/arm/mach-omap2/clkt_clksel.c b/arch/arm/mach-omap2/clkt_clksel.c
index eaed390..3ff2211 100644
--- a/arch/arm/mach-omap2/clkt_clksel.c
+++ b/arch/arm/mach-omap2/clkt_clksel.c
@@ -382,7 +382,7 @@
 						  __clk_get_name(parent) :
 						 "NULL"));
 					clk_reparent(clk, clks->parent);
-				};
+				}
 				found = 1;
 			}
 		}
diff --git a/arch/arm/mach-omap2/clock33xx_data.c b/arch/arm/mach-omap2/clock33xx_data.c
index b87b88c..114ab4b 100644
--- a/arch/arm/mach-omap2/clock33xx_data.c
+++ b/arch/arm/mach-omap2/clock33xx_data.c
@@ -1035,6 +1035,8 @@
 	CLK(NULL,	"pruss_ocp_gclk",	&pruss_ocp_gclk,	CK_AM33XX),
 	CLK("davinci-mcasp.0",  NULL,           &mcasp0_fck,    CK_AM33XX),
 	CLK("davinci-mcasp.1",  NULL,           &mcasp1_fck,    CK_AM33XX),
+	CLK(NULL,	"mcasp0_fck",		&mcasp0_fck,	CK_AM33XX),
+	CLK(NULL,	"mcasp1_fck",		&mcasp1_fck,	CK_AM33XX),
 	CLK("NULL",	"mmc2_fck",		&mmc2_fck,	CK_AM33XX),
 	CLK(NULL,	"mmu_fck",		&mmu_fck,	CK_AM33XX),
 	CLK(NULL,	"smartreflex0_fck",	&smartreflex0_fck,	CK_AM33XX),
diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
index 9a7792a..70294f5 100644
--- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
@@ -183,17 +183,6 @@
 	if (!clkdm->clktrctrl_mask)
 		return 0;
 
-	/*
-	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
-	 * more details on the unpleasant problem this is working
-	 * around
-	 */
-	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
-	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
-		_enable_hwsup(clkdm);
-		return 0;
-	}
-
 	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 				clkdm->clktrctrl_mask);
 
@@ -217,17 +206,6 @@
 	if (!clkdm->clktrctrl_mask)
 		return 0;
 
-	/*
-	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
-	 * more details on the unpleasant problem this is working
-	 * around
-	 */
-	if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
-	    (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
-		omap3_clkdm_wakeup(clkdm);
-		return 0;
-	}
-
 	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 				clkdm->clktrctrl_mask);
 
@@ -269,6 +247,17 @@
 	if (!clkdm->clktrctrl_mask)
 		return 0;
 
+	/*
+	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+	 * more details on the unpleasant problem this is working
+	 * around
+	 */
+	if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) &&
+	    (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
+		omap3_clkdm_wakeup(clkdm);
+		return 0;
+	}
+
 	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 				clkdm->clktrctrl_mask);
 
@@ -292,6 +281,17 @@
 	if (!clkdm->clktrctrl_mask)
 		return 0;
 
+	/*
+	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has
+	 * more details on the unpleasant problem this is working
+	 * around
+	 */
+	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING &&
+	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
+		_enable_hwsup(clkdm);
+		return 0;
+	}
+
 	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs,
 				clkdm->clktrctrl_mask);
 
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index 7012068..1011995 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -95,7 +95,6 @@
 	{ "dss_core", "omapdss_dss", -1 },
 	{ "dss_dispc", "omapdss_dispc", -1 },
 	{ "dss_rfbi", "omapdss_rfbi", -1 },
-	{ "dss_venc", "omapdss_venc", -1 },
 	{ "dss_dsi1", "omapdss_dsi", 0 },
 	{ "dss_dsi2", "omapdss_dsi", 1 },
 	{ "dss_hdmi", "omapdss_hdmi", -1 },
@@ -221,7 +220,7 @@
 
 	ohs[0] = oh;
 	od = omap_device_alloc(pdev, ohs, 1, NULL, 0);
-	if (!od) {
+	if (IS_ERR(od)) {
 		pr_err("Could not alloc omap_device for %s\n", pdev_name);
 		r = -ENOMEM;
 		goto err;
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 8ab1e1b..5ac5cf3 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -838,7 +838,7 @@
 	return request_irq(gpmc_irq, gpmc_handle_irq, 0, "gpmc", NULL);
 }
 
-static __exit int gpmc_free_irq(void)
+static __devexit int gpmc_free_irq(void)
 {
 	int i;
 
@@ -944,7 +944,7 @@
 	return 0;
 }
 
-static __exit int gpmc_remove(struct platform_device *pdev)
+static __devexit int gpmc_remove(struct platform_device *pdev)
 {
 	gpmc_free_irq();
 	gpmc_mem_exit();
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index 03ebf47..4d3a632 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -523,7 +523,7 @@
 	dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);
 
 	od = omap_device_alloc(pdev, ohs, 1, NULL, 0);
-	if (!od) {
+	if (IS_ERR(od)) {
 		pr_err("Could not allocate od for %s\n", name);
 		goto put_pdev;
 	}
diff --git a/arch/arm/mach-omap2/include/mach/board-zoom.h b/arch/arm/mach-omap2/include/mach/board-zoom.h
index 775fdc3..2e94869 100644
--- a/arch/arm/mach-omap2/include/mach/board-zoom.h
+++ b/arch/arm/mach-omap2/include/mach/board-zoom.h
@@ -8,5 +8,3 @@
 extern int __init zoom_debugboard_init(void);
 extern void __init zoom_peripherals_init(void);
 extern void __init zoom_display_init(void);
-
-#define ZOOM2_HEADSET_EXTMUTE_GPIO	153
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
index 7d47407..37f8f94 100644
--- a/arch/arm/mach-omap2/mcbsp.c
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -15,6 +15,7 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/io.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/platform_data/asoc-ti-mcbsp.h>
@@ -23,8 +24,6 @@
 #include <plat/omap_device.h>
 #include <linux/pm_runtime.h>
 
-#include "control.h"
-
 /*
  * FIXME: Find a mechanism to enable/disable runtime the McBSP ICLK autoidle.
  * Sidetone needs non-gated ICLK and sidetone autoidle is broken.
@@ -32,112 +31,6 @@
 #include "cm2xxx_3xxx.h"
 #include "cm-regbits-34xx.h"
 
-/* McBSP1 internal signal muxing function for OMAP2/3 */
-static int omap2_mcbsp1_mux_rx_clk(struct device *dev, const char *signal,
-				   const char *src)
-{
-	u32 v;
-
-	v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
-
-	if (!strcmp(signal, "clkr")) {
-		if (!strcmp(src, "clkr"))
-			v &= ~OMAP2_MCBSP1_CLKR_MASK;
-		else if (!strcmp(src, "clkx"))
-			v |= OMAP2_MCBSP1_CLKR_MASK;
-		else
-			return -EINVAL;
-	} else if (!strcmp(signal, "fsr")) {
-		if (!strcmp(src, "fsr"))
-			v &= ~OMAP2_MCBSP1_FSR_MASK;
-		else if (!strcmp(src, "fsx"))
-			v |= OMAP2_MCBSP1_FSR_MASK;
-		else
-			return -EINVAL;
-	} else {
-		return -EINVAL;
-	}
-
-	omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
-
-	return 0;
-}
-
-/* McBSP4 internal signal muxing function for OMAP4 */
-#define OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_FSX	(1 << 31)
-#define OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_CLKX	(1 << 30)
-static int omap4_mcbsp4_mux_rx_clk(struct device *dev, const char *signal,
-				   const char *src)
-{
-	u32 v;
-
-	/*
-	 * In CONTROL_MCBSPLP register only bit 30 (CLKR mux), and bit 31 (FSR
-	 * mux) is used */
-	v = omap4_ctrl_pad_readl(OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MCBSPLP);
-
-	if (!strcmp(signal, "clkr")) {
-		if (!strcmp(src, "clkr"))
-			v &= ~OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_CLKX;
-		else if (!strcmp(src, "clkx"))
-			v |= OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_CLKX;
-		else
-			return -EINVAL;
-	} else if (!strcmp(signal, "fsr")) {
-		if (!strcmp(src, "fsr"))
-			v &= ~OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_FSX;
-		else if (!strcmp(src, "fsx"))
-			v |= OMAP4_CONTROL_MCBSPLP_ALBCTRLRX_FSX;
-		else
-			return -EINVAL;
-	} else {
-		return -EINVAL;
-	}
-
-	omap4_ctrl_pad_writel(v, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_MCBSPLP);
-
-	return 0;
-}
-
-/* McBSP CLKS source switching function */
-static int omap2_mcbsp_set_clk_src(struct device *dev, struct clk *clk,
-				   const char *src)
-{
-	struct clk *fck_src;
-	char *fck_src_name;
-	int r;
-
-	if (!strcmp(src, "clks_ext"))
-		fck_src_name = "pad_fck";
-	else if (!strcmp(src, "clks_fclk"))
-		fck_src_name = "prcm_fck";
-	else
-		return -EINVAL;
-
-	fck_src = clk_get(dev, fck_src_name);
-	if (IS_ERR_OR_NULL(fck_src)) {
-		pr_err("omap-mcbsp: %s: could not clk_get() %s\n", "clks",
-		       fck_src_name);
-		return -EINVAL;
-	}
-
-	pm_runtime_put_sync(dev);
-
-	r = clk_set_parent(clk, fck_src);
-	if (IS_ERR_VALUE(r)) {
-		pr_err("omap-mcbsp: %s: could not clk_set_parent() to %s\n",
-		       "clks", fck_src_name);
-		clk_put(fck_src);
-		return -EINVAL;
-	}
-
-	pm_runtime_get_sync(dev);
-
-	clk_put(fck_src);
-
-	return 0;
-}
-
 static int omap3_enable_st_clock(unsigned int id, bool enable)
 {
 	unsigned int w;
@@ -179,17 +72,11 @@
 		pdata->reg_size = 4;
 		pdata->has_ccr = true;
 	}
-	pdata->set_clk_src = omap2_mcbsp_set_clk_src;
 
-	/* On OMAP2/3 the McBSP1 port has 6 pin configuration */
-	if (id == 1 && oh->class->rev < MCBSP_CONFIG_TYPE4)
-		pdata->mux_signal = omap2_mcbsp1_mux_rx_clk;
-
-	/* On OMAP4 the McBSP4 port has 6 pin configuration */
-	if (id == 4 && oh->class->rev == MCBSP_CONFIG_TYPE4)
-		pdata->mux_signal = omap4_mcbsp4_mux_rx_clk;
-
-	if (oh->class->rev == MCBSP_CONFIG_TYPE3) {
+	if (oh->class->rev == MCBSP_CONFIG_TYPE2) {
+		/* The FIFO has 128 locations */
+		pdata->buffer_size = 0x80;
+	} else if (oh->class->rev == MCBSP_CONFIG_TYPE3) {
 		if (id == 2)
 			/* The FIFO has 1024 + 256 locations */
 			pdata->buffer_size = 0x500;
@@ -225,7 +112,8 @@
 
 static int __init omap2_mcbsp_init(void)
 {
-	omap_hwmod_for_each_by_class("mcbsp", omap_init_mcbsp, NULL);
+	if (!of_have_populated_dt())
+		omap_hwmod_for_each_by_class("mcbsp", omap_init_mcbsp, NULL);
 
 	return 0;
 }
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 9fe6829..701e17c 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -486,7 +486,7 @@
 		default:
 			/* Nothing to be done */
 			break;
-		};
+		}
 
 		if (val >= 0) {
 			omap_mux_write(pad->partition, val,
diff --git a/arch/arm/mach-omap2/omap-secure.c b/arch/arm/mach-omap2/omap-secure.c
index a004cb9..e089e4d 100644
--- a/arch/arm/mach-omap2/omap-secure.c
+++ b/arch/arm/mach-omap2/omap-secure.c
@@ -61,8 +61,8 @@
 {
 	u32 size = OMAP_SECURE_RAM_STORAGE;
 
-	size = ALIGN(size, SZ_1M);
-	omap_secure_memblock_base = arm_memblock_steal(size, SZ_1M);
+	size = ALIGN(size, SECTION_SIZE);
+	omap_secure_memblock_base = arm_memblock_steal(size, SECTION_SIZE);
 
 	return 0;
 }
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 299ca28..b969ab1 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1698,6 +1698,29 @@
 }
 
 /**
+ * _are_any_hardreset_lines_asserted - return true if any part of @oh is
+ * hard-reset
+ * @oh: struct omap_hwmod *
+ *
+ * If any hardreset lines associated with @oh are asserted, then
+ * return true.  Otherwise, if no hardreset lines associated with @oh
+ * are asserted, or if @oh has no hardreset lines, then return false.
+ * This function is used to avoid executing some parts of the IP block
+ * enable/disable sequence if any hardreset line is set.
+ */
+static bool _are_any_hardreset_lines_asserted(struct omap_hwmod *oh)
+{
+	int rst_cnt = 0;
+	int i;
+
+	for (i = 0; i < oh->rst_lines_cnt && rst_cnt == 0; i++)
+		if (_read_hardreset(oh, oh->rst_lines[i].name) > 0)
+			rst_cnt++;
+
+	return (rst_cnt) ? true : false;
+}
+
+/**
  * _omap4_disable_module - enable CLKCTRL modulemode on OMAP4
  * @oh: struct omap_hwmod *
  *
@@ -1715,7 +1738,7 @@
 	 * Since integration code might still be doing something, only
 	 * disable if all lines are under hardreset.
 	 */
-	if (!_are_all_hardreset_lines_asserted(oh))
+	if (_are_any_hardreset_lines_asserted(oh))
 		return 0;
 
 	pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__);
@@ -1749,12 +1772,12 @@
 
 	pr_debug("omap_hwmod: %s: %s\n", oh->name, __func__);
 
+	if (_are_any_hardreset_lines_asserted(oh))
+		return 0;
+
 	am33xx_cm_module_disable(oh->clkdm->cm_inst, oh->clkdm->clkdm_offs,
 				 oh->prcm.omap4.clkctrl_offs);
 
-	if (_are_all_hardreset_lines_asserted(oh))
-		return 0;
-
 	v = _am33xx_wait_target_disable(oh);
 	if (v)
 		pr_warn("omap_hwmod: %s: _wait_target_disable failed\n",
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
index 35dcdb6..bd9220e 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
@@ -219,7 +219,7 @@
 
 /* MPU */
 static struct omap_hwmod_irq_info omap2xxx_mpu_irqs[] = {
-	{ .name = "pmu", .irq = 3 },
+	{ .name = "pmu", .irq = 3 + OMAP_INTC_START },
 	{ .irq = -1 }
 };
 
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 2857772..f67b7ee 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -94,7 +94,7 @@
 
 /* MPU */
 static struct omap_hwmod_irq_info omap3xxx_mpu_irqs[] = {
-	{ .name = "pmu", .irq = 3 },
+	{ .name = "pmu", .irq = 3 + OMAP_INTC_START },
 	{ .irq = -1 }
 };
 
@@ -3683,6 +3683,7 @@
 	&omap3xxx_l4_core__usb_tll_hs,
 	&omap3xxx_l4_core__es3plus_mmc1,
 	&omap3xxx_l4_core__es3plus_mmc2,
+	&omap3xxx_l4_core__hdq1w,
 	&am35xx_mdio__l3,
 	&am35xx_l4_core__mdio,
 	&am35xx_emac__l3,
@@ -3737,7 +3738,7 @@
 	} else {
 		WARN(1, "OMAP3 hwmod family init: unknown chip type\n");
 		return -EINVAL;
-	};
+	}
 
 	r = omap_hwmod_register_links(h);
 	if (r < 0)
@@ -3754,7 +3755,7 @@
 		   rev == OMAP3430_REV_ES3_0 || rev == OMAP3430_REV_ES3_1 ||
 		   rev == OMAP3430_REV_ES3_1_2) {
 		h = omap3430es2plus_hwmod_ocp_ifs;
-	};
+	}
 
 	if (h) {
 		r = omap_hwmod_register_links(h);
@@ -3769,7 +3770,7 @@
 	} else if (rev == OMAP3430_REV_ES3_0 || rev == OMAP3430_REV_ES3_1 ||
 		   rev == OMAP3430_REV_ES3_1_2) {
 		h = omap3430_es3plus_hwmod_ocp_ifs;
-	};
+	}
 
 	if (h)
 		r = omap_hwmod_register_links(h);
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 8d7a935..652d028 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -5269,6 +5269,7 @@
 
 static struct omap_hwmod_addr_space omap44xx_mcpdm_addrs[] = {
 	{
+		.name		= "mpu",
 		.pa_start	= 0x40132000,
 		.pa_end		= 0x4013207f,
 		.flags		= ADDR_TYPE_RT
@@ -5287,6 +5288,7 @@
 
 static struct omap_hwmod_addr_space omap44xx_mcpdm_dma_addrs[] = {
 	{
+		.name		= "dma",
 		.pa_start	= 0x49032000,
 		.pa_end		= 0x4903207f,
 		.flags		= ADDR_TYPE_RT
diff --git a/arch/arm/mach-omap2/opp.c b/arch/arm/mach-omap2/opp.c
index 45ad7f7..58e16ae 100644
--- a/arch/arm/mach-omap2/opp.c
+++ b/arch/arm/mach-omap2/opp.c
@@ -18,6 +18,7 @@
  */
 #include <linux/module.h>
 #include <linux/opp.h>
+#include <linux/cpu.h>
 
 #include <plat/omap_device.h>
 
@@ -62,13 +63,23 @@
 				__func__, i);
 			return -EINVAL;
 		}
-		oh = omap_hwmod_lookup(opp_def->hwmod_name);
-		if (!oh || !oh->od) {
-			pr_debug("%s: no hwmod or odev for %s, [%d] cannot add OPPs.\n",
-				 __func__, opp_def->hwmod_name, i);
-			continue;
+
+		if (!strncmp(opp_def->hwmod_name, "mpu", 3)) {
+			/* 
+			 * All current OMAPs share voltage rail and
+			 * clock source, so CPU0 is used to represent
+			 * the MPU-SS.
+			 */
+			dev = get_cpu_device(0);
+		} else {
+			oh = omap_hwmod_lookup(opp_def->hwmod_name);
+			if (!oh || !oh->od) {
+				pr_debug("%s: no hwmod or odev for %s, [%d] cannot add OPPs.\n",
+					 __func__, opp_def->hwmod_name, i);
+				continue;
+			}
+			dev = &oh->od->pdev->dev;
 		}
-		dev = &oh->od->pdev->dev;
 
 		r = opp_add(dev, opp_def->freq, opp_def->u_volt);
 		if (r) {
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c
index 3e1345f..46092cd 100644
--- a/arch/arm/mach-omap2/pm-debug.c
+++ b/arch/arm/mach-omap2/pm-debug.c
@@ -168,7 +168,7 @@
 	default:
 		return single_open(file, pm_dbg_show_timers,
 			&inode->i_private);
-	};
+	}
 }
 
 static const struct file_operations debug_fops = {
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index abefbc4..ea61c329 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -16,6 +16,7 @@
 #include <linux/opp.h>
 #include <linux/export.h>
 #include <linux/suspend.h>
+#include <linux/cpu.h>
 
 #include <asm/system_misc.h>
 
@@ -169,7 +170,15 @@
 		goto exit;
 	}
 
-	dev = omap_device_get_by_hwmod_name(oh_name);
+	if (!strncmp(oh_name, "mpu", 3))
+		/* 
+		 * All current OMAPs share voltage rail and clock
+		 * source, so CPU0 is used to represent the MPU-SS.
+		 */
+		dev = get_cpu_device(0);
+	else
+		dev = omap_device_get_by_hwmod_name(oh_name);
+
 	if (IS_ERR(dev)) {
 		pr_err("%s: Unable to get dev pointer for hwmod %s\n",
 			__func__, oh_name);
@@ -177,7 +186,7 @@
 	}
 
 	voltdm = voltdm_lookup(vdd_name);
-	if (IS_ERR(voltdm)) {
+	if (!voltdm) {
 		pr_err("%s: unable to get vdd pointer for vdd_%s\n",
 			__func__, vdd_name);
 		goto exit;
diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c
index cbeae56..f8217a5 100644
--- a/arch/arm/mach-omap2/sr_device.c
+++ b/arch/arm/mach-omap2/sr_device.c
@@ -122,7 +122,7 @@
 	sr_data->senp_mod = 0x1;
 
 	sr_data->voltdm = voltdm_lookup(sr_dev_attr->sensor_voltdm_name);
-	if (IS_ERR(sr_data->voltdm)) {
+	if (!sr_data->voltdm) {
 		pr_err("%s: Unable to get voltage domain pointer for VDD %s\n",
 			__func__, sr_dev_attr->sensor_voltdm_name);
 		goto exit;
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 8847d6e..44f9aa7 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -378,7 +378,7 @@
 		return;
 	}
 	sys_clk = clk_get(NULL, "sys_clkin_ck");
-	if (!sys_clk) {
+	if (IS_ERR(sys_clk)) {
 		pr_err("%s: failed to get system clock handle\n", __func__);
 		iounmap(base);
 		return;
diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c
index 45f7741..635e109 100644
--- a/arch/arm/mach-omap2/twl-common.c
+++ b/arch/arm/mach-omap2/twl-common.c
@@ -158,7 +158,7 @@
 };
 
 static struct regulator_consumer_supply omap3_vdd1_supply[] = {
-	REGULATOR_SUPPLY("vcc", "mpu.0"),
+	REGULATOR_SUPPLY("vcc", "cpu0"),
 };
 
 static struct regulator_consumer_supply omap3_vdd2_supply[] = {
@@ -239,6 +239,10 @@
 static struct twl4030_usb_data omap4_usb_pdata = {
 };
 
+static struct regulator_consumer_supply omap4_vdda_hdmi_dac_supplies[] = {
+	REGULATOR_SUPPLY("vdda_hdmi_dac", "omapdss_hdmi"),
+};
+
 static struct regulator_init_data omap4_vdac_idata = {
 	.constraints = {
 		.min_uV			= 1800000,
@@ -248,6 +252,8 @@
 		.valid_ops_mask		= REGULATOR_CHANGE_MODE
 					| REGULATOR_CHANGE_STATUS,
 	},
+	.num_consumer_supplies	= ARRAY_SIZE(omap4_vdda_hdmi_dac_supplies),
+	.consumer_supplies	= omap4_vdda_hdmi_dac_supplies,
 	.supply_regulator	= "V2V1",
 };
 
@@ -519,3 +525,30 @@
 		pmic_data->v2v1 = &omap4_v2v1_idata;
 }
 #endif /* CONFIG_ARCH_OMAP4 */
+
+#if defined(CONFIG_SND_OMAP_SOC_OMAP_TWL4030) || \
+	defined(CONFIG_SND_OMAP_SOC_OMAP_TWL4030_MODULE)
+#include <linux/platform_data/omap-twl4030.h>
+
+static struct omap_tw4030_pdata omap_twl4030_audio_data;
+
+static struct platform_device audio_device = {
+	.name		= "omap-twl4030",
+	.id		= -1,
+	.dev = {
+		.platform_data = &omap_twl4030_audio_data,
+	},
+};
+
+void __init omap_twl4030_audio_init(char *card_name)
+{
+	omap_twl4030_audio_data.card_name = card_name;
+	platform_device_register(&audio_device);
+}
+
+#else /* SOC_OMAP_TWL4030 */
+void __init omap_twl4030_audio_init(char *card_name)
+{
+	return;
+}
+#endif /* SOC_OMAP_TWL4030 */
diff --git a/arch/arm/mach-omap2/twl-common.h b/arch/arm/mach-omap2/twl-common.h
index 2256efe..dcfbad5 100644
--- a/arch/arm/mach-omap2/twl-common.h
+++ b/arch/arm/mach-omap2/twl-common.h
@@ -60,4 +60,6 @@
 void omap4_pmic_get_config(struct twl4030_platform_data *pmic_data,
 			   u32 pdata_flags, u32 regulators_flags);
 
+void omap_twl4030_audio_init(char *card_name);
+
 #endif /* __OMAP_PMIC_COMMON__ */
diff --git a/arch/arm/mach-s3c24xx/mach-smdk2416.c b/arch/arm/mach-s3c24xx/mach-smdk2416.c
index db2787a..f30d7fc 100644
--- a/arch/arm/mach-s3c24xx/mach-smdk2416.c
+++ b/arch/arm/mach-s3c24xx/mach-smdk2416.c
@@ -29,6 +29,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
+#include <video/samsung_fimd.h>
 #include <mach/hardware.h>
 #include <asm/irq.h>
 #include <asm/mach-types.h>
@@ -52,7 +53,6 @@
 #include <linux/platform_data/usb-s3c2410_udc.h>
 #include <linux/platform_data/s3c-hsudc.h>
 
-#include <plat/regs-fb-v4.h>
 #include <plat/fb.h>
 
 #include <plat/common-smdk.h>
diff --git a/arch/arm/mach-s3c64xx/mach-anw6410.c b/arch/arm/mach-s3c64xx/mach-anw6410.c
index 15c58df..99e82ac 100644
--- a/arch/arm/mach-s3c64xx/mach-anw6410.c
+++ b/arch/arm/mach-s3c64xx/mach-anw6410.c
@@ -29,6 +29,7 @@
 #include <linux/dm9000.h>
 
 #include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
 
 #include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
@@ -44,7 +45,6 @@
 #include <plat/regs-serial.h>
 #include <linux/platform_data/i2c-s3c2410.h>
 #include <plat/fb.h>
-#include <plat/regs-fb-v4.h>
 
 #include <plat/clock.h>
 #include <plat/devs.h>
diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c
index 8b4d467..13b7eaa 100644
--- a/arch/arm/mach-s3c64xx/mach-crag6410.c
+++ b/arch/arm/mach-s3c64xx/mach-crag6410.c
@@ -46,6 +46,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 
+#include <video/samsung_fimd.h>
 #include <mach/hardware.h>
 #include <mach/map.h>
 
@@ -57,7 +58,6 @@
 #include <mach/regs-gpio-memport.h>
 
 #include <plat/regs-serial.h>
-#include <plat/regs-fb-v4.h>
 #include <plat/fb.h>
 #include <plat/sdhci.h>
 #include <plat/gpio-cfg.h>
diff --git a/arch/arm/mach-s3c64xx/mach-hmt.c b/arch/arm/mach-s3c64xx/mach-hmt.c
index 02222b3..2b14489 100644
--- a/arch/arm/mach-s3c64xx/mach-hmt.c
+++ b/arch/arm/mach-s3c64xx/mach-hmt.c
@@ -26,6 +26,7 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
+#include <video/samsung_fimd.h>
 #include <mach/hardware.h>
 #include <mach/map.h>
 
@@ -41,7 +42,6 @@
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
-#include <plat/regs-fb-v4.h>
 
 #include "common.h"
 
diff --git a/arch/arm/mach-s3c64xx/mach-mini6410.c b/arch/arm/mach-s3c64xx/mach-mini6410.c
index 09311cc..07c349c 100644
--- a/arch/arm/mach-s3c64xx/mach-mini6410.c
+++ b/arch/arm/mach-s3c64xx/mach-mini6410.c
@@ -41,9 +41,9 @@
 #include <linux/platform_data/mtd-nand-s3c2410.h>
 #include <plat/regs-serial.h>
 #include <linux/platform_data/touchscreen-s3c2410.h>
-#include <plat/regs-fb-v4.h>
 
 #include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
 
 #include "common.h"
 
diff --git a/arch/arm/mach-s3c64xx/mach-ncp.c b/arch/arm/mach-s3c64xx/mach-ncp.c
index 46ee88d..e5f9a79 100644
--- a/arch/arm/mach-s3c64xx/mach-ncp.c
+++ b/arch/arm/mach-s3c64xx/mach-ncp.c
@@ -24,6 +24,7 @@
 #include <linux/delay.h>
 
 #include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
 
 #include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
@@ -43,7 +44,6 @@
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
-#include <plat/regs-fb-v4.h>
 
 #include "common.h"
 
diff --git a/arch/arm/mach-s3c64xx/mach-real6410.c b/arch/arm/mach-s3c64xx/mach-real6410.c
index 6daca20..7476f7c 100644
--- a/arch/arm/mach-s3c64xx/mach-real6410.c
+++ b/arch/arm/mach-s3c64xx/mach-real6410.c
@@ -42,9 +42,9 @@
 #include <linux/platform_data/mtd-nand-s3c2410.h>
 #include <plat/regs-serial.h>
 #include <linux/platform_data/touchscreen-s3c2410.h>
-#include <plat/regs-fb-v4.h>
 
 #include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
 
 #include "common.h"
 
diff --git a/arch/arm/mach-s3c64xx/mach-smartq5.c b/arch/arm/mach-s3c64xx/mach-smartq5.c
index d6266d8..96d6da2 100644
--- a/arch/arm/mach-s3c64xx/mach-smartq5.c
+++ b/arch/arm/mach-s3c64xx/mach-smartq5.c
@@ -21,6 +21,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
+#include <video/samsung_fimd.h>
 #include <mach/map.h>
 #include <mach/regs-gpio.h>
 
@@ -28,7 +29,6 @@
 #include <plat/devs.h>
 #include <plat/fb.h>
 #include <plat/gpio-cfg.h>
-#include <plat/regs-fb-v4.h>
 
 #include "common.h"
 #include "mach-smartq.h"
diff --git a/arch/arm/mach-s3c64xx/mach-smartq7.c b/arch/arm/mach-s3c64xx/mach-smartq7.c
index 0957d2a..7d1167b 100644
--- a/arch/arm/mach-s3c64xx/mach-smartq7.c
+++ b/arch/arm/mach-s3c64xx/mach-smartq7.c
@@ -21,6 +21,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
+#include <video/samsung_fimd.h>
 #include <mach/map.h>
 #include <mach/regs-gpio.h>
 
@@ -28,7 +29,6 @@
 #include <plat/devs.h>
 #include <plat/fb.h>
 #include <plat/gpio-cfg.h>
-#include <plat/regs-fb-v4.h>
 
 #include "common.h"
 #include "mach-smartq.h"
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
index 2547a88..da1a771 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -43,6 +43,7 @@
 #endif
 
 #include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
 
 #include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
@@ -72,7 +73,6 @@
 #include <linux/platform_data/touchscreen-s3c2410.h>
 #include <plat/keypad.h>
 #include <plat/backlight.h>
-#include <plat/regs-fb-v4.h>
 
 #include "common.h"
 
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c
index dea78a8..96ea1fe 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6440.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c
@@ -27,6 +27,7 @@
 #include <linux/mmc/host.h>
 
 #include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
 
 #include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
@@ -52,7 +53,6 @@
 #include <plat/s5p-time.h>
 #include <plat/backlight.h>
 #include <plat/fb.h>
-#include <plat/regs-fb.h>
 #include <plat/sdhci.h>
 
 #include "common.h"
diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c
index 6f14fc7..12748b6 100644
--- a/arch/arm/mach-s5p64x0/mach-smdk6450.c
+++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c
@@ -27,6 +27,7 @@
 #include <linux/mmc/host.h>
 
 #include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
 
 #include <asm/hardware/vic.h>
 #include <asm/mach/arch.h>
@@ -52,7 +53,6 @@
 #include <plat/s5p-time.h>
 #include <plat/backlight.h>
 #include <plat/fb.h>
-#include <plat/regs-fb.h>
 #include <plat/sdhci.h>
 
 #include "common.h"
diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c
index 5d2c093..dba7384 100644
--- a/arch/arm/mach-s5pc100/mach-smdkc100.c
+++ b/arch/arm/mach-s5pc100/mach-smdkc100.c
@@ -33,6 +33,7 @@
 #include <mach/regs-gpio.h>
 
 #include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
 
 #include <asm/irq.h>
 #include <asm/mach-types.h>
@@ -51,7 +52,6 @@
 #include <linux/platform_data/touchscreen-s3c2410.h>
 #include <linux/platform_data/asoc-s3c.h>
 #include <plat/backlight.h>
-#include <plat/regs-fb-v4.h>
 
 #include "common.h"
 
diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
index 78028df..ee9fa5c 100644
--- a/arch/arm/mach-s5pv210/mach-aquila.c
+++ b/arch/arm/mach-s5pv210/mach-aquila.c
@@ -28,6 +28,7 @@
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 
+#include <video/samsung_fimd.h>
 #include <mach/map.h>
 #include <mach/regs-clock.h>
 
@@ -39,7 +40,6 @@
 #include <plat/fimc-core.h>
 #include <plat/sdhci.h>
 #include <plat/s5p-time.h>
-#include <plat/regs-fb-v4.h>
 
 #include "common.h"
 
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
index 00f1e47..55e1dba 100644
--- a/arch/arm/mach-s5pv210/mach-goni.c
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -35,6 +35,7 @@
 #include <asm/setup.h>
 #include <asm/mach-types.h>
 
+#include <video/samsung_fimd.h>
 #include <mach/map.h>
 #include <mach/regs-clock.h>
 
@@ -49,7 +50,6 @@
 #include <plat/clock.h>
 #include <plat/s5p-time.h>
 #include <plat/mfc.h>
-#include <plat/regs-fb-v4.h>
 #include <plat/camport.h>
 
 #include <media/v4l2-mediabus.h>
diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c
index 7d6fab4..4cdb5bb 100644
--- a/arch/arm/mach-s5pv210/mach-smdkv210.c
+++ b/arch/arm/mach-s5pv210/mach-smdkv210.c
@@ -28,6 +28,7 @@
 #include <asm/mach-types.h>
 
 #include <video/platform_lcd.h>
+#include <video/samsung_fimd.h>
 
 #include <mach/map.h>
 #include <mach/regs-clock.h>
@@ -46,7 +47,6 @@
 #include <plat/fb.h>
 #include <plat/s5p-time.h>
 #include <plat/backlight.h>
-#include <plat/regs-fb-v4.h>
 #include <plat/mfc.h>
 #include <plat/clock.h>
 
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c
index e106488..5633d69 100644
--- a/arch/arm/mach-spear13xx/spear13xx.c
+++ b/arch/arm/mach-spear13xx/spear13xx.c
@@ -78,6 +78,9 @@
 	.nr_channels = 8,
 	.chan_allocation_order = CHAN_ALLOCATION_DESCENDING,
 	.chan_priority = CHAN_PRIORITY_DESCENDING,
+	.block_size = 4095U,
+	.nr_masters = 2,
+	.data_width = { 3, 3, 0, 0 },
 };
 
 void __init spear13xx_l2x0_init(void)
diff --git a/arch/arm/mach-tegra/include/mach/smmu.h b/arch/arm/mach-tegra/include/mach/smmu.h
deleted file mode 100644
index dad403a..0000000
--- a/arch/arm/mach-tegra/include/mach/smmu.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * IOMMU API for SMMU in Tegra30
- *
- * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef	MACH_SMMU_H
-#define	MACH_SMMU_H
-
-enum smmu_hwgrp {
-	HWGRP_AFI,
-	HWGRP_AVPC,
-	HWGRP_DC,
-	HWGRP_DCB,
-	HWGRP_EPP,
-	HWGRP_G2,
-	HWGRP_HC,
-	HWGRP_HDA,
-	HWGRP_ISP,
-	HWGRP_MPE,
-	HWGRP_NV,
-	HWGRP_NV2,
-	HWGRP_PPCS,
-	HWGRP_SATA,
-	HWGRP_VDE,
-	HWGRP_VI,
-
-	HWGRP_COUNT,
-
-	HWGRP_END = ~0,
-};
-
-#define HWG_AFI		(1 << HWGRP_AFI)
-#define HWG_AVPC	(1 << HWGRP_AVPC)
-#define HWG_DC		(1 << HWGRP_DC)
-#define HWG_DCB		(1 << HWGRP_DCB)
-#define HWG_EPP		(1 << HWGRP_EPP)
-#define HWG_G2		(1 << HWGRP_G2)
-#define HWG_HC		(1 << HWGRP_HC)
-#define HWG_HDA		(1 << HWGRP_HDA)
-#define HWG_ISP		(1 << HWGRP_ISP)
-#define HWG_MPE		(1 << HWGRP_MPE)
-#define HWG_NV		(1 << HWGRP_NV)
-#define HWG_NV2		(1 << HWGRP_NV2)
-#define HWG_PPCS	(1 << HWGRP_PPCS)
-#define HWG_SATA	(1 << HWGRP_SATA)
-#define HWG_VDE		(1 << HWGRP_VDE)
-#define HWG_VI		(1 << HWGRP_VI)
-
-#endif	/* MACH_SMMU_H */
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 101b968..c9a4963 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -624,6 +624,23 @@
 	  Say Y here if you have a CPU with the ThumbEE extension and code to
 	  make use of it. Say N for code that can run on CPUs without ThumbEE.
 
+config ARM_VIRT_EXT
+	bool "Native support for the ARM Virtualization Extensions"
+	depends on MMU && CPU_V7
+	help
+	  Enable the kernel to make use of the ARM Virtualization
+	  Extensions to install hypervisors without run-time firmware
+	  assistance.
+
+	  A compliant bootloader is required in order to make maximum
+	  use of this feature.  Refer to Documentation/arm/Booting for
+	  details.
+
+	  It is safe to enable this option even if the kernel may not be
+	  booted in HYP mode, may not have support for the
+	  virtualization extensions, or may be booted with a
+	  non-compliant bootloader.
+
 config SWP_EMULATE
 	bool "Emulate SWP/SWPB instructions"
 	depends on !CPU_USE_DOMAINS && CPU_V7
diff --git a/arch/arm/mm/cache-fa.S b/arch/arm/mm/cache-fa.S
index 0720163..e505bef 100644
--- a/arch/arm/mm/cache-fa.S
+++ b/arch/arm/mm/cache-fa.S
@@ -240,6 +240,9 @@
 	mov	pc, lr
 ENDPROC(fa_dma_unmap_area)
 
+	.globl	fa_flush_kern_cache_louis
+	.equ	fa_flush_kern_cache_louis, fa_flush_kern_cache_all
+
 	__INITDATA
 
 	@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
diff --git a/arch/arm/mm/cache-v3.S b/arch/arm/mm/cache-v3.S
index 52e35f3..8a3fade 100644
--- a/arch/arm/mm/cache-v3.S
+++ b/arch/arm/mm/cache-v3.S
@@ -128,6 +128,9 @@
 ENDPROC(v3_dma_unmap_area)
 ENDPROC(v3_dma_map_area)
 
+	.globl	v3_flush_kern_cache_louis
+	.equ	v3_flush_kern_cache_louis, v3_flush_kern_cache_all
+
 	__INITDATA
 
 	@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
diff --git a/arch/arm/mm/cache-v4.S b/arch/arm/mm/cache-v4.S
index 022135d..43e5d77 100644
--- a/arch/arm/mm/cache-v4.S
+++ b/arch/arm/mm/cache-v4.S
@@ -140,6 +140,9 @@
 ENDPROC(v4_dma_unmap_area)
 ENDPROC(v4_dma_map_area)
 
+	.globl	v4_flush_kern_cache_louis
+	.equ	v4_flush_kern_cache_louis, v4_flush_kern_cache_all
+
 	__INITDATA
 
 	@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
diff --git a/arch/arm/mm/cache-v4wb.S b/arch/arm/mm/cache-v4wb.S
index 8f1eeae..cd49453 100644
--- a/arch/arm/mm/cache-v4wb.S
+++ b/arch/arm/mm/cache-v4wb.S
@@ -251,6 +251,9 @@
 	mov	pc, lr
 ENDPROC(v4wb_dma_unmap_area)
 
+	.globl	v4wb_flush_kern_cache_louis
+	.equ	v4wb_flush_kern_cache_louis, v4wb_flush_kern_cache_all
+
 	__INITDATA
 
 	@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
diff --git a/arch/arm/mm/cache-v4wt.S b/arch/arm/mm/cache-v4wt.S
index b34a5f9..11e5e58 100644
--- a/arch/arm/mm/cache-v4wt.S
+++ b/arch/arm/mm/cache-v4wt.S
@@ -196,6 +196,9 @@
 ENDPROC(v4wt_dma_unmap_area)
 ENDPROC(v4wt_dma_map_area)
 
+	.globl	v4wt_flush_kern_cache_louis
+	.equ	v4wt_flush_kern_cache_louis, v4wt_flush_kern_cache_all
+
 	__INITDATA
 
 	@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S
index 4b10760..d8fd4d4 100644
--- a/arch/arm/mm/cache-v6.S
+++ b/arch/arm/mm/cache-v6.S
@@ -326,6 +326,9 @@
 	mov	pc, lr
 ENDPROC(v6_dma_unmap_area)
 
+	.globl	v6_flush_kern_cache_louis
+	.equ	v6_flush_kern_cache_louis, v6_flush_kern_cache_all
+
 	__INITDATA
 
 	@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index 3b17227..cd95664 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -33,6 +33,24 @@
 	mov	pc, lr
 ENDPROC(v7_flush_icache_all)
 
+ /*
+ *     v7_flush_dcache_louis()
+ *
+ *     Flush the D-cache up to the Level of Unification Inner Shareable
+ *
+ *     Corrupted registers: r0-r7, r9-r11 (r6 only in Thumb mode)
+ */
+
+ENTRY(v7_flush_dcache_louis)
+	dmb					@ ensure ordering with previous memory accesses
+	mrc	p15, 1, r0, c0, c0, 1		@ read clidr, r0 = clidr
+	ands	r3, r0, #0xe00000		@ extract LoUIS from clidr
+	mov	r3, r3, lsr #20			@ r3 = LoUIS * 2
+	moveq	pc, lr				@ return if level == 0
+	mov	r10, #0				@ r10 (starting level) = 0
+	b	flush_levels			@ start flushing cache levels
+ENDPROC(v7_flush_dcache_louis)
+
 /*
  *	v7_flush_dcache_all()
  *
@@ -49,7 +67,7 @@
 	mov	r3, r3, lsr #23			@ left align loc bit field
 	beq	finished			@ if loc is 0, then no need to clean
 	mov	r10, #0				@ start clean at cache level 0
-loop1:
+flush_levels:
 	add	r2, r10, r10, lsr #1		@ work out 3x current cache level
 	mov	r1, r0, lsr r2			@ extract cache type bits from clidr
 	and	r1, r1, #7			@ mask of the bits for current cache only
@@ -71,9 +89,9 @@
 	clz	r5, r4				@ find bit position of way size increment
 	ldr	r7, =0x7fff
 	ands	r7, r7, r1, lsr #13		@ extract max number of the index size
-loop2:
+loop1:
 	mov	r9, r4				@ create working copy of max way size
-loop3:
+loop2:
  ARM(	orr	r11, r10, r9, lsl r5	)	@ factor way and cache number into r11
  THUMB(	lsl	r6, r9, r5		)
  THUMB(	orr	r11, r10, r6		)	@ factor way and cache number into r11
@@ -82,13 +100,13 @@
  THUMB(	orr	r11, r11, r6		)	@ factor index number into r11
 	mcr	p15, 0, r11, c7, c14, 2		@ clean & invalidate by set/way
 	subs	r9, r9, #1			@ decrement the way
-	bge	loop3
-	subs	r7, r7, #1			@ decrement the index
 	bge	loop2
+	subs	r7, r7, #1			@ decrement the index
+	bge	loop1
 skip:
 	add	r10, r10, #2			@ increment cache number
 	cmp	r3, r10
-	bgt	loop1
+	bgt	flush_levels
 finished:
 	mov	r10, #0				@ swith back to cache level 0
 	mcr	p15, 2, r10, c0, c0, 0		@ select current cache level in cssr
@@ -120,6 +138,24 @@
 	mov	pc, lr
 ENDPROC(v7_flush_kern_cache_all)
 
+ /*
+ *     v7_flush_kern_cache_louis(void)
+ *
+ *     Flush the data cache up to Level of Unification Inner Shareable.
+ *     Invalidate the I-cache to the point of unification.
+ */
+ENTRY(v7_flush_kern_cache_louis)
+ ARM(	stmfd	sp!, {r4-r5, r7, r9-r11, lr}	)
+ THUMB(	stmfd	sp!, {r4-r7, r9-r11, lr}	)
+	bl	v7_flush_dcache_louis
+	mov	r0, #0
+	ALT_SMP(mcr	p15, 0, r0, c7, c1, 0)	@ invalidate I-cache inner shareable
+	ALT_UP(mcr	p15, 0, r0, c7, c5, 0)	@ I+BTB cache invalidate
+ ARM(	ldmfd	sp!, {r4-r5, r7, r9-r11, lr}	)
+ THUMB(	ldmfd	sp!, {r4-r7, r9-r11, lr}	)
+	mov	pc, lr
+ENDPROC(v7_flush_kern_cache_louis)
+
 /*
  *	v7_flush_cache_all()
  *
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index 7599e26..2a5907b 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -134,7 +134,6 @@
 {
 	struct mm_struct *mm = vma->vm_mm;
 	struct vm_area_struct *mpnt;
-	struct prio_tree_iter iter;
 	unsigned long offset;
 	pgoff_t pgoff;
 	int aliases = 0;
@@ -147,7 +146,7 @@
 	 * cache coherency.
 	 */
 	flush_dcache_mmap_lock(mapping);
-	vma_prio_tree_foreach(mpnt, &iter, &mapping->i_mmap, pgoff, pgoff) {
+	vma_interval_tree_foreach(mpnt, &mapping->i_mmap, pgoff, pgoff) {
 		/*
 		 * If this VMA is not in our MM, we can ignore it.
 		 * Note that we intentionally mask out the VMA
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index c3bd834..5dbf13f 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -336,6 +336,7 @@
 			/* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
 			* of starvation. */
 			flags &= ~FAULT_FLAG_ALLOW_RETRY;
+			flags |= FAULT_FLAG_TRIED;
 			goto retry;
 		}
 	}
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 40ca11e..1c8f7f5 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -196,7 +196,6 @@
 {
 	struct mm_struct *mm = current->active_mm;
 	struct vm_area_struct *mpnt;
-	struct prio_tree_iter iter;
 	pgoff_t pgoff;
 
 	/*
@@ -208,7 +207,7 @@
 	pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
 
 	flush_dcache_mmap_lock(mapping);
-	vma_prio_tree_foreach(mpnt, &iter, &mapping->i_mmap, pgoff, pgoff) {
+	vma_interval_tree_foreach(mpnt, &mapping->i_mmap, pgoff, pgoff) {
 		unsigned long offset;
 
 		/*
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index 0650bb8..2bb61e7 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -368,6 +368,9 @@
 	mov	pc, lr
 ENDPROC(arm1020_dma_unmap_area)
 
+	.globl	arm1020_flush_kern_cache_louis
+	.equ	arm1020_flush_kern_cache_louis, arm1020_flush_kern_cache_all
+
 	@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
 	define_cache_functions arm1020
 
diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
index 4188478..8f96aa4 100644
--- a/arch/arm/mm/proc-arm1020e.S
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -354,6 +354,9 @@
 	mov	pc, lr
 ENDPROC(arm1020e_dma_unmap_area)
 
+	.globl	arm1020e_flush_kern_cache_louis
+	.equ	arm1020e_flush_kern_cache_louis, arm1020e_flush_kern_cache_all
+
 	@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
 	define_cache_functions arm1020e
 
diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S
index 33c6882..8ebe4a4 100644
--- a/arch/arm/mm/proc-arm1022.S
+++ b/arch/arm/mm/proc-arm1022.S
@@ -343,6 +343,9 @@
 	mov	pc, lr
 ENDPROC(arm1022_dma_unmap_area)
 
+	.globl	arm1022_flush_kern_cache_louis
+	.equ	arm1022_flush_kern_cache_louis, arm1022_flush_kern_cache_all
+
 	@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
 	define_cache_functions arm1022
 
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
index fbc1d5f..093fc7e 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -337,6 +337,9 @@
 	mov	pc, lr
 ENDPROC(arm1026_dma_unmap_area)
 
+	.globl	arm1026_flush_kern_cache_louis
+	.equ	arm1026_flush_kern_cache_louis, arm1026_flush_kern_cache_all
+
 	@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
 	define_cache_functions arm1026
 
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 1a8c138..2c3b942 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -319,6 +319,9 @@
 	mov	pc, lr
 ENDPROC(arm920_dma_unmap_area)
 
+	.globl	arm920_flush_kern_cache_louis
+	.equ	arm920_flush_kern_cache_louis, arm920_flush_kern_cache_all
+
 	@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
 	define_cache_functions arm920
 #endif
diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
index 4c44d7e..4464c49 100644
--- a/arch/arm/mm/proc-arm922.S
+++ b/arch/arm/mm/proc-arm922.S
@@ -321,6 +321,9 @@
 	mov	pc, lr
 ENDPROC(arm922_dma_unmap_area)
 
+	.globl	arm922_flush_kern_cache_louis
+	.equ	arm922_flush_kern_cache_louis, arm922_flush_kern_cache_all
+
 	@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
 	define_cache_functions arm922
 #endif
diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S
index ec5b118..281eb9b 100644
--- a/arch/arm/mm/proc-arm925.S
+++ b/arch/arm/mm/proc-arm925.S
@@ -376,6 +376,9 @@
 	mov	pc, lr
 ENDPROC(arm925_dma_unmap_area)
 
+	.globl	arm925_flush_kern_cache_louis
+	.equ	arm925_flush_kern_cache_louis, arm925_flush_kern_cache_all
+
 	@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
 	define_cache_functions arm925
 
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index c31e62c..f1803f7 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -339,6 +339,9 @@
 	mov	pc, lr
 ENDPROC(arm926_dma_unmap_area)
 
+	.globl	arm926_flush_kern_cache_louis
+	.equ	arm926_flush_kern_cache_louis, arm926_flush_kern_cache_all
+
 	@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
 	define_cache_functions arm926
 
diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S
index a613a7d..8da189d 100644
--- a/arch/arm/mm/proc-arm940.S
+++ b/arch/arm/mm/proc-arm940.S
@@ -267,6 +267,9 @@
 	mov	pc, lr
 ENDPROC(arm940_dma_unmap_area)
 
+	.globl	arm940_flush_kern_cache_louis
+	.equ	arm940_flush_kern_cache_louis, arm940_flush_kern_cache_all
+
 	@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
 	define_cache_functions arm940
 
diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S
index 9f4f299..f666cf3 100644
--- a/arch/arm/mm/proc-arm946.S
+++ b/arch/arm/mm/proc-arm946.S
@@ -310,6 +310,9 @@
 	mov	pc, lr
 ENDPROC(arm946_dma_unmap_area)
 
+	.globl	arm946_flush_kern_cache_louis
+	.equ	arm946_flush_kern_cache_louis, arm946_flush_kern_cache_all
+
 	@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
 	define_cache_functions arm946
 
diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S
index 23a8e4c..4106b09 100644
--- a/arch/arm/mm/proc-feroceon.S
+++ b/arch/arm/mm/proc-feroceon.S
@@ -415,6 +415,9 @@
 	mov	pc, lr
 ENDPROC(feroceon_dma_unmap_area)
 
+	.globl	feroceon_flush_kern_cache_louis
+	.equ	feroceon_flush_kern_cache_louis, feroceon_flush_kern_cache_all
+
 	@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
 	define_cache_functions feroceon
 
@@ -431,6 +434,7 @@
 	range_alias flush_icache_all
 	range_alias flush_user_cache_all
 	range_alias flush_kern_cache_all
+	range_alias flush_kern_cache_louis
 	range_alias flush_user_cache_range
 	range_alias coherent_kern_range
 	range_alias coherent_user_range
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index 2d8ff3a..b29a226 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -299,6 +299,7 @@
 ENTRY(\name\()_cache_fns)
 	.long	\name\()_flush_icache_all
 	.long	\name\()_flush_kern_cache_all
+	.long   \name\()_flush_kern_cache_louis
 	.long	\name\()_flush_user_cache_all
 	.long	\name\()_flush_user_cache_range
 	.long	\name\()_coherent_kern_range
diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S
index fbb2124..82f9cdc 100644
--- a/arch/arm/mm/proc-mohawk.S
+++ b/arch/arm/mm/proc-mohawk.S
@@ -303,6 +303,9 @@
 	mov	pc, lr
 ENDPROC(mohawk_dma_unmap_area)
 
+	.globl	mohawk_flush_kern_cache_louis
+	.equ	mohawk_flush_kern_cache_louis, mohawk_flush_kern_cache_all
+
 	@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
 	define_cache_functions mohawk
 
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index c2e2b66..846d279 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -172,7 +172,7 @@
 __v7_setup:
 	adr	r12, __v7_setup_stack		@ the local stack
 	stmia	r12, {r0-r5, r7, r9, r11, lr}
-	bl	v7_flush_dcache_all
+	bl      v7_flush_dcache_louis
 	ldmia	r12, {r0-r5, r7, r9, r11, lr}
 
 	mrc	p15, 0, r0, c0, c0, 0		@ read main ID register
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index b0d5786..eb93d64 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -337,6 +337,9 @@
 	mov	pc, lr
 ENDPROC(xsc3_dma_unmap_area)
 
+	.globl	xsc3_flush_kern_cache_louis
+	.equ	xsc3_flush_kern_cache_louis, xsc3_flush_kern_cache_all
+
 	@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
 	define_cache_functions xsc3
 
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index 4ffebaa..2551036 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -410,6 +410,9 @@
 	mov	pc, lr
 ENDPROC(xscale_dma_unmap_area)
 
+	.globl	xscale_flush_kern_cache_louis
+	.equ	xscale_flush_kern_cache_louis, xscale_flush_kern_cache_all
+
 	@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
 	define_cache_functions xscale
 
@@ -439,6 +442,7 @@
 	a0_alias flush_icache_all
 	a0_alias flush_user_cache_all
 	a0_alias flush_kern_cache_all
+	a0_alias flush_kern_cache_louis
 	a0_alias flush_user_cache_range
 	a0_alias coherent_kern_range
 	a0_alias coherent_user_range
diff --git a/arch/arm/plat-mxc/devices/platform-mxc_nand.c b/arch/arm/plat-mxc/devices/platform-mxc_nand.c
index 1568f39..95b75cc 100644
--- a/arch/arm/plat-mxc/devices/platform-mxc_nand.c
+++ b/arch/arm/plat-mxc/devices/platform-mxc_nand.c
@@ -63,10 +63,6 @@
 	/* AXI has to come first, that's how the mxc_nand driver expect it */
 	struct resource res[] = {
 		{
-			.start = data->axibase,
-			.end = data->axibase + SZ_16K - 1,
-			.flags = IORESOURCE_MEM,
-		}, {
 			.start = data->iobase,
 			.end = data->iobase + data->iosize - 1,
 			.flags = IORESOURCE_MEM,
@@ -74,10 +70,13 @@
 			.start = data->irq,
 			.end = data->irq,
 			.flags = IORESOURCE_IRQ,
+		}, {
+			.start = data->axibase,
+			.end = data->axibase + SZ_16K - 1,
+			.flags = IORESOURCE_MEM,
 		},
 	};
 	return imx_add_platform_device("mxc_nand", data->id,
-			res + !data->axibase,
-			ARRAY_SIZE(res) - !data->axibase,
+			res, ARRAY_SIZE(res) - !data->axibase,
 			pdata, sizeof(*pdata));
 }
diff --git a/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h b/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h
index 826de74..c08a54d 100644
--- a/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h
+++ b/arch/arm/plat-nomadik/include/plat/gpio-nomadik.h
@@ -45,6 +45,12 @@
 #define NMK_GPIO_ALT_B	2
 #define NMK_GPIO_ALT_C	(NMK_GPIO_ALT_A | NMK_GPIO_ALT_B)
 
+#define NMK_GPIO_ALT_CX_SHIFT 2
+#define NMK_GPIO_ALT_C1	((1<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
+#define NMK_GPIO_ALT_C2	((2<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
+#define NMK_GPIO_ALT_C3	((3<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
+#define NMK_GPIO_ALT_C4	((4<<NMK_GPIO_ALT_CX_SHIFT) | NMK_GPIO_ALT_C)
+
 /* Pull up/down values */
 enum nmk_gpio_pull {
 	NMK_GPIO_PULL_NONE,
diff --git a/arch/arm/plat-nomadik/include/plat/pincfg.h b/arch/arm/plat-nomadik/include/plat/pincfg.h
index 9c949c7..3b8ec60 100644
--- a/arch/arm/plat-nomadik/include/plat/pincfg.h
+++ b/arch/arm/plat-nomadik/include/plat/pincfg.h
@@ -25,6 +25,8 @@
  *	bit 19..20 - SLPM direction
  *	bit 21..22 - SLPM Value (if output)
  *	bit 23..25 - PDIS value (if input)
+ *	bit	26 - Gpio mode
+ *	bit	27 - Sleep mode
  *
  * to facilitate the definition, the following macros are provided
  *
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index ca83a76..c9d1c36 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -43,11 +43,13 @@
 
 config OMAP_DEBUG_LEDS
 	def_bool y if NEW_LEDS
+	select LEDS_CLASS
 	depends on OMAP_DEBUG_DEVICES
 
 config POWER_AVS_OMAP
 	bool "AVS(Adaptive Voltage Scaling) support for OMAP IP versions 1&2"
 	depends on POWER_AVS && (ARCH_OMAP3 || ARCH_OMAP4) && PM
+	select POWER_SUPPLY
 	help
 	  Say Y to enable AVS(Adaptive Voltage Scaling)
 	  support on OMAP containing the version 1 or
diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c
index 2e826f1..87ba8dd 100644
--- a/arch/arm/plat-omap/counter_32k.c
+++ b/arch/arm/plat-omap/counter_32k.c
@@ -52,22 +52,29 @@
  * nsecs and adds to a monotonically increasing timespec.
  */
 static struct timespec persistent_ts;
-static cycles_t cycles, last_cycles;
+static cycles_t cycles;
 static unsigned int persistent_mult, persistent_shift;
+static DEFINE_SPINLOCK(read_persistent_clock_lock);
+
 static void omap_read_persistent_clock(struct timespec *ts)
 {
 	unsigned long long nsecs;
-	cycles_t delta;
-	struct timespec *tsp = &persistent_ts;
+	cycles_t last_cycles;
+	unsigned long flags;
+
+	spin_lock_irqsave(&read_persistent_clock_lock, flags);
 
 	last_cycles = cycles;
 	cycles = sync32k_cnt_reg ? __raw_readl(sync32k_cnt_reg) : 0;
-	delta = cycles - last_cycles;
 
-	nsecs = clocksource_cyc2ns(delta, persistent_mult, persistent_shift);
+	nsecs = clocksource_cyc2ns(cycles - last_cycles,
+					persistent_mult, persistent_shift);
 
-	timespec_add_ns(tsp, nsecs);
-	*ts = *tsp;
+	timespec_add_ns(&persistent_ts, nsecs);
+
+	*ts = persistent_ts;
+
+	spin_unlock_irqrestore(&read_persistent_clock_lock, flags);
 }
 
 /**
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index 6013831..a5683a8 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -26,14 +26,12 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
-#include <linux/i2c-omap.h>
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 
 #include <mach/irqs.h>
 #include <plat/i2c.h>
-#include <plat/omap-pm.h>
 #include <plat/omap_device.h>
 
 #define OMAP_I2C_SIZE		0x3f
@@ -129,16 +127,6 @@
 
 
 #ifdef CONFIG_ARCH_OMAP2PLUS
-/*
- * XXX This function is a temporary compatibility wrapper - only
- * needed until the I2C driver can be converted to call
- * omap_pm_set_max_dev_wakeup_lat() and handle a return code.
- */
-static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t)
-{
-	omap_pm_set_max_mpu_wakeup_lat(dev, t);
-}
-
 static inline int omap2_i2c_add_bus(int bus_id)
 {
 	int l;
@@ -170,15 +158,6 @@
 	dev_attr = (struct omap_i2c_dev_attr *)oh->dev_attr;
 	pdata->flags = dev_attr->flags;
 
-	/*
-	 * When waiting for completion of a i2c transfer, we need to
-	 * set a wake up latency constraint for the MPU. This is to
-	 * ensure quick enough wakeup from idle, when transfer
-	 * completes.
-	 * Only omap3 has support for constraints
-	 */
-	if (cpu_is_omap34xx())
-		pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
 	pdev = omap_device_build(name, bus_id, oh, pdata,
 			sizeof(struct omap_i2c_bus_platform_data),
 			NULL, 0, 0);
diff --git a/arch/arm/plat-omap/omap-pm-noop.c b/arch/arm/plat-omap/omap-pm-noop.c
index 9f64133..9722f41 100644
--- a/arch/arm/plat-omap/omap-pm-noop.c
+++ b/arch/arm/plat-omap/omap-pm-noop.c
@@ -38,7 +38,7 @@
 	if (!dev || t < -1) {
 		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
 		return -EINVAL;
-	};
+	}
 
 	if (t == -1)
 		pr_debug("OMAP PM: remove max MPU wakeup latency constraint: dev %s\n",
@@ -67,7 +67,7 @@
 	    agent_id != OCP_TARGET_AGENT)) {
 		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
 		return -EINVAL;
-	};
+	}
 
 	if (r == 0)
 		pr_debug("OMAP PM: remove min bus tput constraint: dev %s for agent_id %d\n",
@@ -93,7 +93,7 @@
 	if (!req_dev || !dev || t < -1) {
 		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
 		return -EINVAL;
-	};
+	}
 
 	if (t == -1)
 		pr_debug("OMAP PM: remove max device latency constraint: dev %s\n",
@@ -123,7 +123,7 @@
 	if (!dev || t < -1) {
 		WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
 		return -EINVAL;
-	};
+	}
 
 	if (t == -1)
 		pr_debug("OMAP PM: remove max DMA latency constraint: dev %s\n",
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index cee85a5..7a7d1f2 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -725,7 +725,7 @@
 		dev_set_name(&pdev->dev, "%s", pdev->name);
 
 	od = omap_device_alloc(pdev, ohs, oh_cnt, pm_lats, pm_lats_cnt);
-	if (!od)
+	if (IS_ERR(od))
 		goto odbs_exit1;
 
 	ret = platform_device_add_data(pdev, pdata, pdata_len);
diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c
index c38d754..d088afa 100644
--- a/arch/arm/plat-samsung/dma-ops.c
+++ b/arch/arm/plat-samsung/dma-ops.c
@@ -91,7 +91,8 @@
 		break;
 	case DMA_CYCLIC:
 		desc = dmaengine_prep_dma_cyclic(chan, param->buf,
-			param->len, param->period, param->direction);
+			param->len, param->period, param->direction,
+			DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 		break;
 	default:
 		dev_err(&chan->dev->device, "unsupported format\n");
diff --git a/arch/arm/plat-samsung/include/plat/regs-fb-v4.h b/arch/arm/plat-samsung/include/plat/regs-fb-v4.h
deleted file mode 100644
index 4c3647f..0000000
--- a/arch/arm/plat-samsung/include/plat/regs-fb-v4.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/* arch/arm/plat-samsung/include/plat/regs-fb-v4.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      http://armlinux.simtec.co.uk/
- *      Ben Dooks <ben@simtec.co.uk>
- *
- * S3C64XX - new-style framebuffer register definitions
- *
- * This is the register set for the new style framebuffer interface
- * found from the S3C2443 onwards and specifically the S3C64XX series
- * S3C6400 and S3C6410.
- *
- * The file contains the cpu specific items which change between whichever
- * architecture is selected. See <plat/regs-fb.h> for the core definitions
- * that are the same.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-/* include the core definitions here, in case we really do need to
- * override them at a later date.
-*/
-
-#include <plat/regs-fb.h>
-
-#define S3C_FB_MAX_WIN (5)  /* number of hardware windows available. */
-#define VIDCON1_FSTATUS_EVEN	(1 << 15)
-
-/* Video timing controls */
-#define VIDTCON0				(0x10)
-#define VIDTCON1				(0x14)
-#define VIDTCON2				(0x18)
-
-/* Window position controls */
-
-#define WINCON(_win)				(0x20 + ((_win) * 4))
-
-/* OSD1 and OSD4 do not have register D */
-
-#define VIDOSD_BASE				(0x40)
-
-#define VIDINTCON0				(0x130)
-
-/* WINCONx */
-
-#define WINCONx_CSCWIDTH_MASK			(0x3 << 26)
-#define WINCONx_CSCWIDTH_SHIFT			(26)
-#define WINCONx_CSCWIDTH_WIDE			(0x0 << 26)
-#define WINCONx_CSCWIDTH_NARROW			(0x3 << 26)
-
-#define WINCONx_ENLOCAL				(1 << 22)
-#define WINCONx_BUFSTATUS			(1 << 21)
-#define WINCONx_BUFSEL				(1 << 20)
-#define WINCONx_BUFAUTOEN			(1 << 19)
-#define WINCONx_YCbCr				(1 << 13)
-
-#define WINCON1_LOCALSEL_CAMIF			(1 << 23)
-
-#define WINCON2_LOCALSEL_CAMIF			(1 << 23)
-#define WINCON2_BLD_PIX				(1 << 6)
-
-#define WINCON2_ALPHA_SEL			(1 << 1)
-#define WINCON2_BPPMODE_MASK			(0xf << 2)
-#define WINCON2_BPPMODE_SHIFT			(2)
-#define WINCON2_BPPMODE_1BPP			(0x0 << 2)
-#define WINCON2_BPPMODE_2BPP			(0x1 << 2)
-#define WINCON2_BPPMODE_4BPP			(0x2 << 2)
-#define WINCON2_BPPMODE_8BPP_1232		(0x4 << 2)
-#define WINCON2_BPPMODE_16BPP_565		(0x5 << 2)
-#define WINCON2_BPPMODE_16BPP_A1555		(0x6 << 2)
-#define WINCON2_BPPMODE_16BPP_I1555		(0x7 << 2)
-#define WINCON2_BPPMODE_18BPP_666		(0x8 << 2)
-#define WINCON2_BPPMODE_18BPP_A1665		(0x9 << 2)
-#define WINCON2_BPPMODE_19BPP_A1666		(0xa << 2)
-#define WINCON2_BPPMODE_24BPP_888		(0xb << 2)
-#define WINCON2_BPPMODE_24BPP_A1887		(0xc << 2)
-#define WINCON2_BPPMODE_25BPP_A1888		(0xd << 2)
-#define WINCON2_BPPMODE_28BPP_A4888		(0xd << 2)
-
-#define WINCON3_BLD_PIX				(1 << 6)
-
-#define WINCON3_ALPHA_SEL			(1 << 1)
-#define WINCON3_BPPMODE_MASK			(0xf << 2)
-#define WINCON3_BPPMODE_SHIFT			(2)
-#define WINCON3_BPPMODE_1BPP			(0x0 << 2)
-#define WINCON3_BPPMODE_2BPP			(0x1 << 2)
-#define WINCON3_BPPMODE_4BPP			(0x2 << 2)
-#define WINCON3_BPPMODE_16BPP_565		(0x5 << 2)
-#define WINCON3_BPPMODE_16BPP_A1555		(0x6 << 2)
-#define WINCON3_BPPMODE_16BPP_I1555		(0x7 << 2)
-#define WINCON3_BPPMODE_18BPP_666		(0x8 << 2)
-#define WINCON3_BPPMODE_18BPP_A1665		(0x9 << 2)
-#define WINCON3_BPPMODE_19BPP_A1666		(0xa << 2)
-#define WINCON3_BPPMODE_24BPP_888		(0xb << 2)
-#define WINCON3_BPPMODE_24BPP_A1887		(0xc << 2)
-#define WINCON3_BPPMODE_25BPP_A1888		(0xd << 2)
-#define WINCON3_BPPMODE_28BPP_A4888		(0xd << 2)
-
-#define VIDINTCON0_FIFIOSEL_WINDOW2		(0x10 << 5)
-#define VIDINTCON0_FIFIOSEL_WINDOW3		(0x20 << 5)
-#define VIDINTCON0_FIFIOSEL_WINDOW4		(0x40 << 5)
-
-#define DITHMODE				(0x170)
-#define WINxMAP(_win)				(0x180 + ((_win) * 4))
-
-
-#define DITHMODE_R_POS_MASK			(0x3 << 5)
-#define DITHMODE_R_POS_SHIFT			(5)
-#define DITHMODE_R_POS_8BIT			(0x0 << 5)
-#define DITHMODE_R_POS_6BIT			(0x1 << 5)
-#define DITHMODE_R_POS_5BIT			(0x2 << 5)
-
-#define DITHMODE_G_POS_MASK			(0x3 << 3)
-#define DITHMODE_G_POS_SHIFT			(3)
-#define DITHMODE_G_POS_8BIT			(0x0 << 3)
-#define DITHMODE_G_POS_6BIT			(0x1 << 3)
-#define DITHMODE_G_POS_5BIT			(0x2 << 3)
-
-#define DITHMODE_B_POS_MASK			(0x3 << 1)
-#define DITHMODE_B_POS_SHIFT			(1)
-#define DITHMODE_B_POS_8BIT			(0x0 << 1)
-#define DITHMODE_B_POS_6BIT			(0x1 << 1)
-#define DITHMODE_B_POS_5BIT			(0x2 << 1)
-
-#define DITHMODE_DITH_EN			(1 << 0)
-
-#define WPALCON					(0x1A0)
-
-/* Palette control */
-/* Note for S5PC100: you can still use those macros on WPALCON (aka WPALCON_L),
- * but make sure that WPALCON_H W2PAL-W4PAL entries are zeroed out */
-#define WPALCON_W4PAL_16BPP_A555		(1 << 8)
-#define WPALCON_W3PAL_16BPP_A555		(1 << 7)
-#define WPALCON_W2PAL_16BPP_A555		(1 << 6)
-
-
-/* Notes on per-window bpp settings
- *
- * Value	Win0	 Win1	  Win2	   Win3	    Win 4
- * 0000		1(P)	 1(P)	  1(P)	   1(P)	    1(P)
- * 0001		2(P)	 2(P)     2(P)	   2(P)	    2(P)
- * 0010		4(P)	 4(P)     4(P)	   4(P)     -none-
- * 0011		8(P)	 8(P)     -none-   -none-   -none-
- * 0100		-none-	 8(A232)  8(A232)  -none-   -none-
- * 0101		16(565)	 16(565)  16(565)  16(565)   16(565)
- * 0110		-none-	 16(A555) 16(A555) 16(A555)  16(A555)
- * 0111		16(I555) 16(I565) 16(I555) 16(I555)  16(I555)
- * 1000		18(666)	 18(666)  18(666)  18(666)   18(666)
- * 1001		-none-	 18(A665) 18(A665) 18(A665)  16(A665)
- * 1010		-none-	 19(A666) 19(A666) 19(A666)  19(A666)
- * 1011		24(888)	 24(888)  24(888)  24(888)   24(888)
- * 1100		-none-	 24(A887) 24(A887) 24(A887)  24(A887)
- * 1101		-none-	 25(A888) 25(A888) 25(A888)  25(A888)
- * 1110		-none-	 -none-	  -none-   -none-    -none-
- * 1111		-none-	 -none-   -none-   -none-    -none-
-*/
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 767ba56..7ff68c9 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -10,6 +10,8 @@
 	select GENERIC_TIME_VSYSCALL
 	select HARDIRQS_SW_RESEND
 	select HAVE_ARCH_TRACEHOOK
+	select HAVE_DEBUG_BUGVERBOSE
+	select HAVE_DEBUG_KMEMLEAK
 	select HAVE_DMA_API_DEBUG
 	select HAVE_DMA_ATTRS
 	select HAVE_GENERIC_DMA_COHERENT
@@ -26,6 +28,7 @@
 	select PERF_USE_VMALLOC
 	select RTC_LIB
 	select SPARSE_IRQ
+	select SYSCTL_EXCEPTION_TRACE
 	help
 	  ARM 64-bit (AArch64) Linux support.
 
@@ -193,6 +196,7 @@
 	bool "Kernel support for 32-bit EL0"
 	depends on !ARM64_64K_PAGES
 	select COMPAT_BINFMT_ELF
+	select HAVE_UID16
 	help
 	  This option enables support for a 32-bit EL0 running under a 64-bit
 	  kernel at EL1. AArch32-specific components such as system calls,
diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h
index 3ba1f1a..ba42d41 100644
--- a/arch/arm64/include/asm/unistd32.h
+++ b/arch/arm64/include/asm/unistd32.h
@@ -752,3 +752,4 @@
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_COMPAT_SYS_SENDFILE
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 38cf853..6538928 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -583,6 +583,7 @@
 	mov	x0, sp				// 'regs'
 	tst	x2, #PSR_MODE_MASK		// user mode regs?
 	b.ne	no_work_pending			// returning to kernel
+	enable_irq				// enable interrupts for do_notify_resume()
 	bl	do_notify_resume
 	b	ret_to_user
 work_resched:
diff --git a/arch/arm64/kernel/sys_compat.c b/arch/arm64/kernel/sys_compat.c
index 967e92f..93f10e2 100644
--- a/arch/arm64/kernel/sys_compat.c
+++ b/arch/arm64/kernel/sys_compat.c
@@ -84,26 +84,6 @@
 	return ret;
 }
 
-asmlinkage int compat_sys_sendfile(int out_fd, int in_fd,
-				   compat_off_t __user *offset, s32 count)
-{
-	mm_segment_t old_fs = get_fs();
-	int ret;
-	off_t of;
-
-	if (offset && get_user(of, offset))
-		return -EFAULT;
-
-	set_fs(KERNEL_DS);
-	ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *)&of : NULL,
-			   count);
-	set_fs(old_fs);
-
-	if (offset && put_user(of, offset))
-		return -EFAULT;
-	return ret;
-}
-
 static inline void
 do_compat_cache_op(unsigned long start, unsigned long end, int flags)
 {
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 5eb2444..4bd7579 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -61,12 +61,10 @@
 	.mapping_error = swiotlb_dma_mapping_error,
 };
 
-void __init swiotlb_init_with_default_size(size_t default_size, int verbose);
-
-void __init arm64_swiotlb_init(size_t max_size)
+void __init arm64_swiotlb_init(void)
 {
 	dma_ops = &arm64_swiotlb_dma_ops;
-	swiotlb_init_with_default_size(min((size_t)SZ_64M, max_size), 1);
+	swiotlb_init(1);
 }
 
 #define PREALLOC_DMA_DEBUG_ENTRIES	4096
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 5f719ba..efbf7df 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -301,10 +301,7 @@
 	unsigned long reserved_pages, free_pages;
 	struct memblock_region *reg;
 
-#if CONFIG_SWIOTLB
-	extern void __init arm64_swiotlb_init(size_t max_size);
-	arm64_swiotlb_init(max_pfn << (PAGE_SHIFT - 1));
-#endif
+	arm64_swiotlb_init();
 
 	max_mapnr   = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map;
 
diff --git a/arch/arm64/mm/mm.h b/arch/arm64/mm/mm.h
index d8d6e78..916701e 100644
--- a/arch/arm64/mm/mm.h
+++ b/arch/arm64/mm/mm.h
@@ -1,2 +1,3 @@
 extern void __flush_dcache_page(struct page *page);
 extern void __init bootmem_init(void);
+extern void __init arm64_swiotlb_init(void);
diff --git a/arch/avr32/include/asm/Kbuild b/arch/avr32/include/asm/Kbuild
index 3136628..be0433e 100644
--- a/arch/avr32/include/asm/Kbuild
+++ b/arch/avr32/include/asm/Kbuild
@@ -1,3 +1,6 @@
 include include/asm-generic/Kbuild.asm
 
+generic-y	+= clkdev.h
+generic-y	+= exec.h
+
 header-y	+= cachectl.h
diff --git a/arch/avr32/include/asm/exec.h b/arch/avr32/include/asm/exec.h
deleted file mode 100644
index f467be8..0000000
--- a/arch/avr32/include/asm/exec.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Copyright (C) 2004-2006 Atmel Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef __ASM_AVR32_EXEC_H
-#define __ASM_AVR32_EXEC_H
-
-#define arch_align_stack(x)	(x)
-
-#endif /* __ASM_AVR32_EXEC_H */
diff --git a/arch/avr32/include/asm/thread_info.h b/arch/avr32/include/asm/thread_info.h
index e5deda4..6dc62e1 100644
--- a/arch/avr32/include/asm/thread_info.h
+++ b/arch/avr32/include/asm/thread_info.h
@@ -77,8 +77,6 @@
 #define TIF_SYSCALL_TRACE       0       /* syscall trace active */
 #define TIF_SIGPENDING          1       /* signal pending */
 #define TIF_NEED_RESCHED        2       /* rescheduling necessary */
-#define TIF_POLLING_NRFLAG      3       /* true if poll_idle() is polling
-					   TIF_NEED_RESCHED */
 #define TIF_BREAKPOINT		4	/* enter monitor mode on return */
 #define TIF_SINGLE_STEP		5	/* single step in progress */
 #define TIF_MEMDIE		6	/* is terminating due to OOM killer */
@@ -91,10 +89,9 @@
 #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
-#define _TIF_POLLING_NRFLAG	(1 << TIF_POLLING_NRFLAG)
+#define _TIF_BREAKPOINT		(1 << TIF_BREAKPOINT)
 #define _TIF_SINGLE_STEP	(1 << TIF_SINGLE_STEP)
 #define _TIF_MEMDIE		(1 << TIF_MEMDIE)
-#define _TIF_RESTORE_SIGMASK	(1 << TIF_RESTORE_SIGMASK)
 #define _TIF_CPU_GOING_TO_SLEEP (1 << TIF_CPU_GOING_TO_SLEEP)
 #define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
 
@@ -102,17 +99,14 @@
 
 /* work to do on interrupt/exception return */
 #define _TIF_WORK_MASK				\
-	((1 << TIF_SIGPENDING)			\
+	(_TIF_SIGPENDING			\
 	 | _TIF_NOTIFY_RESUME			\
-	 | (1 << TIF_NEED_RESCHED)		\
-	 | (1 << TIF_POLLING_NRFLAG)		\
-	 | (1 << TIF_BREAKPOINT)		\
-	 | (1 << TIF_RESTORE_SIGMASK))
+	 | _TIF_NEED_RESCHED			\
+	 | _TIF_BREAKPOINT)
 
 /* work to do on any return to userspace */
-#define _TIF_ALLWORK_MASK	(_TIF_WORK_MASK | (1 << TIF_SYSCALL_TRACE) | \
-				 _TIF_NOTIFY_RESUME)
+#define _TIF_ALLWORK_MASK	(_TIF_WORK_MASK | _TIF_SYSCALL_TRACE)
 /* work to do on return from debug mode */
-#define _TIF_DBGWORK_MASK	(_TIF_WORK_MASK & ~(1 << TIF_BREAKPOINT))
+#define _TIF_DBGWORK_MASK	(_TIF_WORK_MASK & ~_TIF_BREAKPOINT)
 
 #endif /* __ASM_AVR32_THREAD_INFO_H */
diff --git a/arch/avr32/kernel/signal.c b/arch/avr32/kernel/signal.c
index d552a85..5e01c3a 100644
--- a/arch/avr32/kernel/signal.c
+++ b/arch/avr32/kernel/signal.c
@@ -15,7 +15,6 @@
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/unistd.h>
-#include <linux/freezer.h>
 #include <linux/tracehook.h>
 
 #include <asm/uaccess.h>
diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c
index 0445c4f..b323d8d 100644
--- a/arch/avr32/mach-at32ap/at32ap700x.c
+++ b/arch/avr32/mach-at32ap/at32ap700x.c
@@ -605,6 +605,9 @@
 
 static struct dw_dma_platform_data dw_dmac0_data = {
 	.nr_channels	= 3,
+	.block_size	= 4095U,
+	.nr_masters	= 2,
+	.data_width	= { 2, 2, 0, 0 },
 };
 
 static struct resource dw_dmac0_resource[] = {
diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c
index b92e609..b2f2d2d 100644
--- a/arch/avr32/mm/fault.c
+++ b/arch/avr32/mm/fault.c
@@ -152,6 +152,7 @@
 			tsk->min_flt++;
 		if (fault & VM_FAULT_RETRY) {
 			flags &= ~FAULT_FLAG_ALLOW_RETRY;
+			flags |= FAULT_FLAG_TRIED;
 
 			/*
 			 * No need to up_read(&mm->mmap_sem) as we would have
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index c7092e6..ccd9193 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -33,6 +33,7 @@
 	select HAVE_PERF_EVENTS
 	select ARCH_HAVE_CUSTOM_GPIO_H
 	select ARCH_WANT_OPTIONAL_GPIOLIB
+	select HAVE_UID16
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select HAVE_GENERIC_HARDIRQS
 	select GENERIC_ATOMIC64
@@ -298,7 +299,7 @@
 
 config BF_REV_0_4
 	bool "0.4"
-	depends on (BF561 || BF533 || BF532 || BF531 || BF538 || BF539)
+	depends on (BF561 || BF533 || BF532 || BF531 || BF538 || BF539 || BF54x)
 
 config BF_REV_0_5
 	bool "0.5"
diff --git a/arch/blackfin/configs/BF533-EZKIT_defconfig b/arch/blackfin/configs/BF533-EZKIT_defconfig
index 127f20d..16273a9 100644
--- a/arch/blackfin/configs/BF533-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF533-EZKIT_defconfig
@@ -52,10 +52,13 @@
 CONFIG_MTD=y
 CONFIG_MTD_CHAR=m
 CONFIG_MTD_BLOCK=y
-CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_RAM=y
-CONFIG_MTD_ROM=m
+CONFIG_MTD_ROM=y
 CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PLATRAM=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_NETDEVICES=y
 # CONFIG_NET_VENDOR_BROADCOM is not set
diff --git a/arch/blackfin/configs/BF561-ACVILON_defconfig b/arch/blackfin/configs/BF561-ACVILON_defconfig
index 0fdc4ec..9198837 100644
--- a/arch/blackfin/configs/BF561-ACVILON_defconfig
+++ b/arch/blackfin/configs/BF561-ACVILON_defconfig
@@ -57,7 +57,6 @@
 CONFIG_MTD_PHRAM=y
 CONFIG_MTD_BLOCK2MTD=y
 CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
 CONFIG_MTD_NAND_PLATFORM=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
diff --git a/arch/blackfin/configs/BF609-EZKIT_defconfig b/arch/blackfin/configs/BF609-EZKIT_defconfig
index f4b0235..13eb732 100644
--- a/arch/blackfin/configs/BF609-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF609-EZKIT_defconfig
@@ -1,5 +1,6 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
+CONFIG_HIGH_RES_TIMERS=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
@@ -24,7 +25,6 @@
 CONFIG_PINT1_ASSIGN=0x01010000
 CONFIG_PINT2_ASSIGN=0x07000101
 CONFIG_PINT3_ASSIGN=0x02020303
-CONFIG_HIGH_RES_TIMERS=y
 CONFIG_IP_CHECKSUM_L1=y
 CONFIG_SYSCALL_TAB_L1=y
 CONFIG_CPLB_SWITCH_TAB_L1=y
@@ -116,9 +116,6 @@
 # CONFIG_SND_SPI is not set
 # CONFIG_SND_USB is not set
 CONFIG_SND_SOC=m
-CONFIG_SND_BF6XX_I2S=m
-CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61=m
-CONFIG_SND_SOC_ALL_CODECS=m
 CONFIG_USB=y
 CONFIG_USB_MUSB_HDRC=y
 CONFIG_USB_MUSB_BLACKFIN=m
@@ -136,7 +133,6 @@
 CONFIG_JFFS2_FS=m
 CONFIG_UBIFS_FS=m
 CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_DEBUG_FS=y
@@ -149,9 +145,9 @@
 CONFIG_EARLY_PRINTK=y
 CONFIG_CPLB_INFO=y
 CONFIG_BFIN_PSEUDODBG_INSNS=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_MD4=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+CONFIG_CRYPTO_ARC4=m
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
-CONFIG_CRYPTO_DEV_BFIN_CRC=y
+CONFIG_CRYPTO_DEV_BFIN_CRC=m
diff --git a/arch/blackfin/include/asm/thread_info.h b/arch/blackfin/include/asm/thread_info.h
index 53ad100..3894005 100644
--- a/arch/blackfin/include/asm/thread_info.h
+++ b/arch/blackfin/include/asm/thread_info.h
@@ -96,8 +96,6 @@
 #define TIF_SYSCALL_TRACE	0	/* syscall trace active */
 #define TIF_SIGPENDING		1	/* signal pending */
 #define TIF_NEED_RESCHED	2	/* rescheduling necessary */
-#define TIF_POLLING_NRFLAG	3	/* true if poll_idle() is polling
-					   TIF_NEED_RESCHED */
 #define TIF_MEMDIE		4	/* is terminating due to OOM killer */
 #define TIF_RESTORE_SIGMASK	5	/* restore signal mask in do_signal() */
 #define TIF_IRQ_SYNC		7	/* sync pipeline stage */
@@ -108,8 +106,6 @@
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
-#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
-#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
 #define _TIF_IRQ_SYNC		(1<<TIF_IRQ_SYNC)
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
 #define _TIF_SINGLESTEP		(1<<TIF_SINGLESTEP)
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c
index 83139aa..ed978f1 100644
--- a/arch/blackfin/kernel/bfin_gpio.c
+++ b/arch/blackfin/kernel/bfin_gpio.c
@@ -1265,8 +1265,8 @@
 {
 	struct proc_dir_entry *proc_gpio;
 
-	proc_gpio = proc_create("gpio", S_IRUGO, NULL, &gpio_proc_ops);
-	return proc_gpio != NULL;
+	proc_gpio = proc_create("gpio", 0, NULL, &gpio_proc_ops);
+	return proc_gpio == NULL;
 }
 __initcall(gpio_register_proc);
 #endif
diff --git a/arch/blackfin/kernel/reboot.c b/arch/blackfin/kernel/reboot.c
index 5272e6e..c4f50a3 100644
--- a/arch/blackfin/kernel/reboot.c
+++ b/arch/blackfin/kernel/reboot.c
@@ -86,7 +86,6 @@
 void machine_restart(char *cmd)
 {
 	native_machine_restart(cmd);
-	local_irq_disable();
 	if (smp_processor_id())
 		smp_call_function((void *)bfin_reset, 0, 1);
 	else
diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c
index 6682b73..6ed20a1 100644
--- a/arch/blackfin/kernel/signal.c
+++ b/arch/blackfin/kernel/signal.c
@@ -10,7 +10,6 @@
 #include <linux/tty.h>
 #include <linux/personality.h>
 #include <linux/binfmts.h>
-#include <linux/freezer.h>
 #include <linux/uaccess.h>
 #include <linux/tracehook.h>
 
diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c
index fc179ca..29f16e5 100644
--- a/arch/blackfin/mach-bf527/boards/ezkit.c
+++ b/arch/blackfin/mach-bf527/boards/ezkit.c
@@ -587,6 +587,21 @@
 };
 #endif
 
+#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
+	        || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
+static const char * const ad1836_link[] = {
+	"bfin-tdm.0",
+	"spi0.4",
+};
+static struct platform_device bfin_ad1836_machine = {
+	.name = "bfin-snd-ad1836",
+	.id = -1,
+	.dev = {
+		.platform_data = (void *)ad1836_link,
+	},
+};
+#endif
+
 static struct spi_board_info bfin_spi_board_info[] __initdata = {
 #if defined(CONFIG_MTD_M25P80) \
 	|| defined(CONFIG_MTD_M25P80_MODULE)
@@ -1269,6 +1284,11 @@
 #if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
 	&bfin_tdm,
 #endif
+
+#if defined(CONFIG_SND_BF5XX_SOC_AD1836) || \
+	defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
+	&bfin_ad1836_machine,
+#endif
 };
 
 static int __init ezkit_init(void)
diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c
index ce88a71..6fca869 100644
--- a/arch/blackfin/mach-bf533/boards/stamp.c
+++ b/arch/blackfin/mach-bf533/boards/stamp.c
@@ -617,6 +617,21 @@
 };
 #endif
 
+#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
+	        || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
+static const char * const ad1836_link[] = {
+	"bfin-tdm.0",
+	"spi0.4",
+};
+static struct platform_device bfin_ad1836_machine = {
+	.name = "bfin-snd-ad1836",
+	.id = -1,
+	.dev = {
+		.platform_data = (void *)ad1836_link,
+	},
+};
+#endif
+
 #if defined(CONFIG_SND_BF5XX_SOC_AD73311) || \
 	defined(CONFIG_SND_BF5XX_SOC_AD73311_MODULE)
 static const unsigned ad73311_gpio[] = {
@@ -754,6 +769,11 @@
 	&bfin_ac97_pcm,
 #endif
 
+#if defined(CONFIG_SND_BF5XX_SOC_AD1836) || \
+	defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
+	&bfin_ad1836_machine,
+#endif
+
 #if defined(CONFIG_SND_BF5XX_SOC_AD73311) || \
 	defined(CONFIG_SND_BF5XX_SOC_AD73311_MODULE)
 	&bfin_ad73311_machine,
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537e.c b/arch/blackfin/mach-bf537/boards/cm_bf537e.c
index 9408ab5..85e4fc9 100644
--- a/arch/blackfin/mach-bf537/boards/cm_bf537e.c
+++ b/arch/blackfin/mach-bf537/boards/cm_bf537e.c
@@ -25,6 +25,7 @@
 #include <asm/bfin5xx_spi.h>
 #include <asm/portmux.h>
 #include <asm/dpmc.h>
+#include <asm/bfin_sport.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -143,6 +144,71 @@
 };
 #endif  /* spi master and devices */
 
+#if defined(CONFIG_SPI_BFIN_SPORT) || defined(CONFIG_SPI_BFIN_SPORT_MODULE)
+
+/* SPORT SPI controller data */
+static struct bfin5xx_spi_master bfin_sport_spi0_info = {
+	.num_chipselect = MAX_BLACKFIN_GPIOS,
+	.enable_dma = 0,  /* master don't support DMA */
+	.pin_req = {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_DRPRI,
+		P_SPORT0_RSCLK, P_SPORT0_TFS, P_SPORT0_RFS, 0},
+};
+
+static struct resource bfin_sport_spi0_resource[] = {
+	[0] = {
+		.start = SPORT0_TCR1,
+		.end   = SPORT0_TCR1 + 0xFF,
+		.flags = IORESOURCE_MEM,
+		},
+	[1] = {
+		.start = IRQ_SPORT0_ERROR,
+		.end   = IRQ_SPORT0_ERROR,
+		.flags = IORESOURCE_IRQ,
+		},
+};
+
+static struct platform_device bfin_sport_spi0_device = {
+	.name = "bfin-sport-spi",
+	.id = 1, /* Bus number */
+	.num_resources = ARRAY_SIZE(bfin_sport_spi0_resource),
+	.resource = bfin_sport_spi0_resource,
+	.dev = {
+		.platform_data = &bfin_sport_spi0_info, /* Passed to driver */
+	},
+};
+
+static struct bfin5xx_spi_master bfin_sport_spi1_info = {
+	.num_chipselect = MAX_BLACKFIN_GPIOS,
+	.enable_dma = 0,  /* master don't support DMA */
+	.pin_req = {P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_DRPRI,
+		P_SPORT1_RSCLK, P_SPORT1_TFS, P_SPORT1_RFS, 0},
+};
+
+static struct resource bfin_sport_spi1_resource[] = {
+	[0] = {
+		.start = SPORT1_TCR1,
+		.end   = SPORT1_TCR1 + 0xFF,
+		.flags = IORESOURCE_MEM,
+		},
+	[1] = {
+		.start = IRQ_SPORT1_ERROR,
+		.end   = IRQ_SPORT1_ERROR,
+		.flags = IORESOURCE_IRQ,
+		},
+};
+
+static struct platform_device bfin_sport_spi1_device = {
+	.name = "bfin-sport-spi",
+	.id = 2, /* Bus number */
+	.num_resources = ARRAY_SIZE(bfin_sport_spi1_resource),
+	.resource = bfin_sport_spi1_resource,
+	.dev = {
+		.platform_data = &bfin_sport_spi1_info, /* Passed to driver */
+	},
+};
+
+#endif  /* sport spi master and devices */
+
 #if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
 static struct platform_device rtc_device = {
 	.name = "rtc-bfin",
@@ -512,6 +578,13 @@
 };
 #endif
 
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) \
+|| defined(CONFIG_BFIN_SPORT) || defined(CONFIG_BFIN_SPORT_MODULE)
+unsigned short bfin_sport0_peripherals[] = {
+	P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+	P_SPORT0_DRPRI, P_SPORT0_RSCLK, P_SPORT0_DRSEC, P_SPORT0_DTSEC, 0
+};
+#endif
 #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
 #ifdef CONFIG_SERIAL_BFIN_SPORT0_UART
 static struct resource bfin_sport0_uart_resources[] = {
@@ -532,11 +605,6 @@
 	},
 };
 
-static unsigned short bfin_sport0_peripherals[] = {
-	P_SPORT0_TFS, P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
-	P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0
-};
-
 static struct platform_device bfin_sport0_uart_device = {
 	.name = "bfin-sport-uart",
 	.id = 0,
@@ -582,6 +650,49 @@
 };
 #endif
 #endif
+#if defined(CONFIG_BFIN_SPORT) || defined(CONFIG_BFIN_SPORT_MODULE)
+static struct resource bfin_sport0_resources[] = {
+	{
+		.start = SPORT0_TCR1,
+		.end = SPORT0_MRCS3+4,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_SPORT0_RX,
+		.end = IRQ_SPORT0_RX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT0_TX,
+		.end = IRQ_SPORT0_TX+1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_SPORT0_ERROR,
+		.end = IRQ_SPORT0_ERROR,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = CH_SPORT0_TX,
+		.end = CH_SPORT0_TX,
+		.flags = IORESOURCE_DMA,
+	},
+	{
+		.start = CH_SPORT0_RX,
+		.end = CH_SPORT0_RX,
+		.flags = IORESOURCE_DMA,
+	},
+};
+static struct platform_device bfin_sport0_device = {
+	.name = "bfin_sport_raw",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(bfin_sport0_resources),
+	.resource = bfin_sport0_resources,
+	.dev = {
+		.platform_data = &bfin_sport0_peripherals, /* Passed to driver */
+	},
+};
+#endif
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
 #include <linux/bfin_mac.h>
@@ -684,6 +795,10 @@
 
 	&bfin_dpmc,
 
+#if defined(CONFIG_BFIN_SPORT) || defined(CONFIG_BFIN_SPORT_MODULE)
+	&bfin_sport0_device,
+#endif
+
 #if defined(CONFIG_FB_HITACHI_TX09) || defined(CONFIG_FB_HITACHI_TX09_MODULE)
 	&hitachi_fb_device,
 #endif
@@ -744,6 +859,11 @@
 	&bfin_spi0_device,
 #endif
 
+#if defined(CONFIG_SPI_BFIN_SPORT) || defined(CONFIG_SPI_BFIN_SPORT_MODULE)
+	&bfin_sport_spi0_device,
+	&bfin_sport_spi1_device,
+#endif
+
 #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
 	&bfin_pata_device,
 #endif
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c
index 5ed654a..95114ed 100644
--- a/arch/blackfin/mach-bf537/boards/stamp.c
+++ b/arch/blackfin/mach-bf537/boards/stamp.c
@@ -1525,7 +1525,7 @@
 
 #if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
 static struct platform_device bfin_fb_device = {
-	.name = "bf537-lq035",
+	.name = "bf537_lq035",
 };
 #endif
 
@@ -2641,6 +2641,21 @@
 };
 #endif
 
+#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
+	        || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
+static const char * const ad1836_link[] = {
+	"bfin-tdm.0",
+	"spi0.4",
+};
+static struct platform_device bfin_ad1836_machine = {
+	.name = "bfin-snd-ad1836",
+	.id = -1,
+	.dev = {
+		.platform_data = (void *)ad1836_link,
+	},
+};
+#endif
+
 #if defined(CONFIG_SND_BF5XX_SOC_AD73311) || \
 				defined(CONFIG_SND_BF5XX_SOC_AD73311_MODULE)
 static const unsigned ad73311_gpio[] = {
@@ -2927,6 +2942,11 @@
 	&bfin_ac97_pcm,
 #endif
 
+#if defined(CONFIG_SND_BF5XX_SOC_AD1836) || \
+	defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
+	&bfin_ad1836_machine,
+#endif
+
 #if defined(CONFIG_SND_BF5XX_SOC_AD73311) || \
 		defined(CONFIG_SND_BF5XX_SOC_AD73311_MODULE)
 	&bfin_ad73311_machine,
diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c
index 7c36777..551f866 100644
--- a/arch/blackfin/mach-bf561/boards/ezkit.c
+++ b/arch/blackfin/mach-bf561/boards/ezkit.c
@@ -539,6 +539,21 @@
 };
 #endif
 
+#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
+	        || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
+static const char * const ad1836_link[] = {
+	"bfin-tdm.0",
+	"spi0.4",
+};
+static struct platform_device bfin_ad1836_machine = {
+	.name = "bfin-snd-ad1836",
+	.id = -1,
+	.dev = {
+		.platform_data = (void *)ad1836_link,
+	},
+};
+#endif
+
 static struct platform_device *ezkit_devices[] __initdata = {
 
 	&bfin_dpmc,
@@ -603,6 +618,11 @@
 #if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
 	&bfin_ac97,
 #endif
+
+#if defined(CONFIG_SND_BF5XX_SOC_AD1836) || \
+	defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
+	&bfin_ad1836_machine,
+#endif
 };
 
 static int __init net2272_init(void)
diff --git a/arch/blackfin/mach-bf609/boards/ezkit.c b/arch/blackfin/mach-bf609/boards/ezkit.c
index c2cf1ae..61c1f47 100644
--- a/arch/blackfin/mach-bf609/boards/ezkit.c
+++ b/arch/blackfin/mach-bf609/boards/ezkit.c
@@ -818,6 +818,21 @@
 };
 #endif
 
+#if defined(CONFIG_SND_BF5XX_SOC_AD1836) \
+	        || defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
+static const char * const ad1836_link[] = {
+	"bfin-tdm.0",
+	"spi0.76",
+};
+static struct platform_device bfin_ad1836_machine = {
+	.name = "bfin-snd-ad1836",
+	.id = -1,
+	.dev = {
+		.platform_data = (void *)ad1836_link,
+	},
+};
+#endif
+
 #if defined(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61) || \
 	defined(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61_MODULE)
 static struct platform_device adau1761_device = {
@@ -1557,6 +1572,10 @@
 	defined(CONFIG_SND_BF6XX_SOC_I2S_MODULE)
 	&bfin_i2s,
 #endif
+#if defined(CONFIG_SND_BF5XX_SOC_AD1836) || \
+	defined(CONFIG_SND_BF5XX_SOC_AD1836_MODULE)
+	&bfin_ad1836_machine,
+#endif
 #if defined(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61) || \
 	defined(CONFIG_SND_SOC_BFIN_EVAL_ADAU1X61_MODULE)
 	&adau1761_device,
diff --git a/arch/blackfin/mach-bf609/include/mach/defBF609.h b/arch/blackfin/mach-bf609/include/mach/defBF609.h
index 19690cc..8045ade 100644
--- a/arch/blackfin/mach-bf609/include/mach/defBF609.h
+++ b/arch/blackfin/mach-bf609/include/mach/defBF609.h
@@ -11,5 +11,276 @@
 #include "defBF60x_base.h"
 
 /* The following are the #defines needed by ADSP-BF609 that are not in the common header */
+/* =========================
+	PIXC Registers
+   ========================= */
+
+/* =========================
+	PIXC0
+   ========================= */
+#define PIXC0_CTL                   0xFFC19000         /* PIXC0 Control Register */
+#define PIXC0_PPL                   0xFFC19004         /* PIXC0 Pixels Per Line Register */
+#define PIXC0_LPF                   0xFFC19008         /* PIXC0 Line Per Frame Register */
+#define PIXC0_HSTART_A              0xFFC1900C         /* PIXC0 Overlay A Horizontal Start Register */
+#define PIXC0_HEND_A                0xFFC19010         /* PIXC0 Overlay A Horizontal End Register */
+#define PIXC0_VSTART_A              0xFFC19014         /* PIXC0 Overlay A Vertical Start Register */
+#define PIXC0_VEND_A                0xFFC19018         /* PIXC0 Overlay A Vertical End Register */
+#define PIXC0_TRANSP_A              0xFFC1901C         /* PIXC0 Overlay A Transparency Ratio Register */
+#define PIXC0_HSTART_B              0xFFC19020         /* PIXC0 Overlay B Horizontal Start Register */
+#define PIXC0_HEND_B                0xFFC19024         /* PIXC0 Overlay B Horizontal End Register */
+#define PIXC0_VSTART_B              0xFFC19028         /* PIXC0 Overlay B Vertical Start Register */
+#define PIXC0_VEND_B                0xFFC1902C         /* PIXC0 Overlay B Vertical End Register */
+#define PIXC0_TRANSP_B              0xFFC19030         /* PIXC0 Overlay B Transparency Ratio Register */
+#define PIXC0_IRQSTAT               0xFFC1903C         /* PIXC0 Interrupt Status Register */
+#define PIXC0_CONRY                 0xFFC19040         /* PIXC0 RY Conversion Component Register */
+#define PIXC0_CONGU                 0xFFC19044         /* PIXC0 GU Conversion Component Register */
+#define PIXC0_CONBV                 0xFFC19048         /* PIXC0 BV Conversion Component Register */
+#define PIXC0_CCBIAS                0xFFC1904C         /* PIXC0 Conversion Bias Register */
+#define PIXC0_TC                    0xFFC19050         /* PIXC0 Transparency Register */
+#define PIXC0_REVID                 0xFFC19054         /* PIXC0 PIXC Revision Id */
+
+/* =========================
+	PVP Registers
+   ========================= */
+
+/* =========================
+	PVP0
+   ========================= */
+#define PVP0_REVID                  0xFFC1A000         /* PVP0 Revision ID */
+#define PVP0_CTL                    0xFFC1A004         /* PVP0 Control */
+#define PVP0_IMSK0                  0xFFC1A008         /* PVP0 INTn interrupt line masks */
+#define PVP0_IMSK1                  0xFFC1A00C         /* PVP0 INTn interrupt line masks */
+#define PVP0_STAT                   0xFFC1A010         /* PVP0 Status */
+#define PVP0_ILAT                   0xFFC1A014         /* PVP0 Latched status */
+#define PVP0_IREQ0                  0xFFC1A018         /* PVP0 INT0 masked latched status */
+#define PVP0_IREQ1                  0xFFC1A01C         /* PVP0 INT0 masked latched status */
+#define PVP0_OPF0_CFG               0xFFC1A020         /* PVP0 Config */
+#define PVP0_OPF1_CFG               0xFFC1A040         /* PVP0 Config */
+#define PVP0_OPF2_CFG               0xFFC1A060         /* PVP0 Config */
+#define PVP0_OPF0_CTL               0xFFC1A024         /* PVP0 Control */
+#define PVP0_OPF1_CTL               0xFFC1A044         /* PVP0 Control */
+#define PVP0_OPF2_CTL               0xFFC1A064         /* PVP0 Control */
+#define PVP0_OPF3_CFG               0xFFC1A080         /* PVP0 Config */
+#define PVP0_OPF3_CTL               0xFFC1A084         /* PVP0 Control */
+#define PVP0_PEC_CFG                0xFFC1A0A0         /* PVP0 Config */
+#define PVP0_PEC_CTL                0xFFC1A0A4         /* PVP0 Control */
+#define PVP0_PEC_D1TH0              0xFFC1A0A8         /* PVP0 Lower Hysteresis Threshold */
+#define PVP0_PEC_D1TH1              0xFFC1A0AC         /* PVP0 Upper Hysteresis Threshold */
+#define PVP0_PEC_D2TH0              0xFFC1A0B0         /* PVP0 Weak Zero Crossing Threshold */
+#define PVP0_PEC_D2TH1              0xFFC1A0B4         /* PVP0 Strong Zero Crossing Threshold */
+#define PVP0_IIM0_CFG               0xFFC1A0C0         /* PVP0 Config */
+#define PVP0_IIM1_CFG               0xFFC1A0E0         /* PVP0 Config */
+#define PVP0_IIM0_CTL               0xFFC1A0C4         /* PVP0 Control */
+#define PVP0_IIM1_CTL               0xFFC1A0E4         /* PVP0 Control */
+#define PVP0_IIM0_SCALE             0xFFC1A0C8         /* PVP0 Scaler Values */
+#define PVP0_IIM1_SCALE             0xFFC1A0E8         /* PVP0 Scaler Values */
+#define PVP0_IIM0_SOVF_STAT         0xFFC1A0CC         /* PVP0 Signed Overflow Status */
+#define PVP0_IIM1_SOVF_STAT         0xFFC1A0EC         /* PVP0 Signed Overflow Status */
+#define PVP0_IIM0_UOVF_STAT         0xFFC1A0D0         /* PVP0 Unsigned Overflow Status */
+#define PVP0_IIM1_UOVF_STAT         0xFFC1A0F0         /* PVP0 Unsigned Overflow Status */
+#define PVP0_ACU_CFG                0xFFC1A100         /* PVP0 ACU Configuration Register */
+#define PVP0_ACU_CTL                0xFFC1A104         /* PVP0 ACU Control Register */
+#define PVP0_ACU_OFFSET             0xFFC1A108         /* PVP0 SUM constant register */
+#define PVP0_ACU_FACTOR             0xFFC1A10C         /* PVP0 PROD constant register */
+#define PVP0_ACU_SHIFT              0xFFC1A110         /* PVP0 Shift constant register */
+#define PVP0_ACU_MIN                0xFFC1A114         /* PVP0 Lower saturation threshold set to MIN */
+#define PVP0_ACU_MAX                0xFFC1A118         /* PVP0 Upper saturation threshold set to MAX */
+#define PVP0_UDS_CFG                0xFFC1A140         /* PVP0 UDS Configuration Register */
+#define PVP0_UDS_CTL                0xFFC1A144         /* PVP0 UDS Control Register */
+#define PVP0_UDS_OHCNT              0xFFC1A148         /* PVP0 UDS Output H Dimension */
+#define PVP0_UDS_OVCNT              0xFFC1A14C         /* PVP0 UDS Output V Dimension */
+#define PVP0_UDS_HAVG               0xFFC1A150         /* PVP0 UDS H Taps */
+#define PVP0_UDS_VAVG               0xFFC1A154         /* PVP0 UDS V Taps */
+#define PVP0_IPF0_CFG               0xFFC1A180         /* PVP0 Configuration */
+#define PVP0_IPF0_PIPECTL           0xFFC1A184         /* PVP0 Pipe Control */
+#define PVP0_IPF1_PIPECTL           0xFFC1A1C4         /* PVP0 Pipe Control */
+#define PVP0_IPF0_CTL               0xFFC1A188         /* PVP0 Control */
+#define PVP0_IPF1_CTL               0xFFC1A1C8         /* PVP0 Control */
+#define PVP0_IPF0_TAG               0xFFC1A18C         /* PVP0 TAG Value */
+#define PVP0_IPF1_TAG               0xFFC1A1CC         /* PVP0 TAG Value */
+#define PVP0_IPF0_FCNT              0xFFC1A190         /* PVP0 Frame Count */
+#define PVP0_IPF1_FCNT              0xFFC1A1D0         /* PVP0 Frame Count */
+#define PVP0_IPF0_HCNT              0xFFC1A194         /* PVP0 Horizontal Count */
+#define PVP0_IPF1_HCNT              0xFFC1A1D4         /* PVP0 Horizontal Count */
+#define PVP0_IPF0_VCNT              0xFFC1A198         /* PVP0 Vertical Count */
+#define PVP0_IPF1_VCNT              0xFFC1A1D8         /* PVP0 Vertical Count */
+#define PVP0_IPF0_HPOS              0xFFC1A19C         /* PVP0 Horizontal Position */
+#define PVP0_IPF0_VPOS              0xFFC1A1A0         /* PVP0 Vertical Position */
+#define PVP0_IPF0_TAG_STAT          0xFFC1A1A4         /* PVP0 TAG Status */
+#define PVP0_IPF1_TAG_STAT          0xFFC1A1E4         /* PVP0 TAG Status */
+#define PVP0_IPF1_CFG               0xFFC1A1C0         /* PVP0 Configuration */
+#define PVP0_CNV0_CFG               0xFFC1A200         /* PVP0 Configuration */
+#define PVP0_CNV1_CFG               0xFFC1A280         /* PVP0 Configuration */
+#define PVP0_CNV2_CFG               0xFFC1A300         /* PVP0 Configuration */
+#define PVP0_CNV3_CFG               0xFFC1A380         /* PVP0 Configuration */
+#define PVP0_CNV0_CTL               0xFFC1A204         /* PVP0 Control */
+#define PVP0_CNV1_CTL               0xFFC1A284         /* PVP0 Control */
+#define PVP0_CNV2_CTL               0xFFC1A304         /* PVP0 Control */
+#define PVP0_CNV3_CTL               0xFFC1A384         /* PVP0 Control */
+#define PVP0_CNV0_C00C01            0xFFC1A208         /* PVP0 Coefficients 0, 0 and 0, 1 */
+#define PVP0_CNV1_C00C01            0xFFC1A288         /* PVP0 Coefficients 0, 0 and 0, 1 */
+#define PVP0_CNV2_C00C01            0xFFC1A308         /* PVP0 Coefficients 0, 0 and 0, 1 */
+#define PVP0_CNV3_C00C01            0xFFC1A388         /* PVP0 Coefficients 0, 0 and 0, 1 */
+#define PVP0_CNV0_C02C03            0xFFC1A20C         /* PVP0 Coefficients 0, 2 and 0, 3 */
+#define PVP0_CNV1_C02C03            0xFFC1A28C         /* PVP0 Coefficients 0, 2 and 0, 3 */
+#define PVP0_CNV2_C02C03            0xFFC1A30C         /* PVP0 Coefficients 0, 2 and 0, 3 */
+#define PVP0_CNV3_C02C03            0xFFC1A38C         /* PVP0 Coefficients 0, 2 and 0, 3 */
+#define PVP0_CNV0_C04               0xFFC1A210         /* PVP0 Coefficient 0, 4 */
+#define PVP0_CNV1_C04               0xFFC1A290         /* PVP0 Coefficient 0, 4 */
+#define PVP0_CNV2_C04               0xFFC1A310         /* PVP0 Coefficient 0, 4 */
+#define PVP0_CNV3_C04               0xFFC1A390         /* PVP0 Coefficient 0, 4 */
+#define PVP0_CNV0_C10C11            0xFFC1A214         /* PVP0 Coefficients 1, 0 and 1, 1 */
+#define PVP0_CNV1_C10C11            0xFFC1A294         /* PVP0 Coefficients 1, 0 and 1, 1 */
+#define PVP0_CNV2_C10C11            0xFFC1A314         /* PVP0 Coefficients 1, 0 and 1, 1 */
+#define PVP0_CNV3_C10C11            0xFFC1A394         /* PVP0 Coefficients 1, 0 and 1, 1 */
+#define PVP0_CNV0_C12C13            0xFFC1A218         /* PVP0 Coefficients 1, 2 and 1, 3 */
+#define PVP0_CNV1_C12C13            0xFFC1A298         /* PVP0 Coefficients 1, 2 and 1, 3 */
+#define PVP0_CNV2_C12C13            0xFFC1A318         /* PVP0 Coefficients 1, 2 and 1, 3 */
+#define PVP0_CNV3_C12C13            0xFFC1A398         /* PVP0 Coefficients 1, 2 and 1, 3 */
+#define PVP0_CNV0_C14               0xFFC1A21C         /* PVP0 Coefficient 1, 4 */
+#define PVP0_CNV1_C14               0xFFC1A29C         /* PVP0 Coefficient 1, 4 */
+#define PVP0_CNV2_C14               0xFFC1A31C         /* PVP0 Coefficient 1, 4 */
+#define PVP0_CNV3_C14               0xFFC1A39C         /* PVP0 Coefficient 1, 4 */
+#define PVP0_CNV0_C20C21            0xFFC1A220         /* PVP0 Coefficients 2, 0 and 2, 1 */
+#define PVP0_CNV1_C20C21            0xFFC1A2A0         /* PVP0 Coefficients 2, 0 and 2, 1 */
+#define PVP0_CNV2_C20C21            0xFFC1A320         /* PVP0 Coefficients 2, 0 and 2, 1 */
+#define PVP0_CNV3_C20C21            0xFFC1A3A0         /* PVP0 Coefficients 2, 0 and 2, 1 */
+#define PVP0_CNV0_C22C23            0xFFC1A224         /* PVP0 Coefficients 2, 2 and 2, 3 */
+#define PVP0_CNV1_C22C23            0xFFC1A2A4         /* PVP0 Coefficients 2, 2 and 2, 3 */
+#define PVP0_CNV2_C22C23            0xFFC1A324         /* PVP0 Coefficients 2, 2 and 2, 3 */
+#define PVP0_CNV3_C22C23            0xFFC1A3A4         /* PVP0 Coefficients 2, 2 and 2, 3 */
+#define PVP0_CNV0_C24               0xFFC1A228         /* PVP0 Coefficient 2,4 */
+#define PVP0_CNV1_C24               0xFFC1A2A8         /* PVP0 Coefficient 2,4 */
+#define PVP0_CNV2_C24               0xFFC1A328         /* PVP0 Coefficient 2,4 */
+#define PVP0_CNV3_C24               0xFFC1A3A8         /* PVP0 Coefficient 2,4 */
+#define PVP0_CNV0_C30C31            0xFFC1A22C         /* PVP0 Coefficients 3, 0 and 3, 1 */
+#define PVP0_CNV1_C30C31            0xFFC1A2AC         /* PVP0 Coefficients 3, 0 and 3, 1 */
+#define PVP0_CNV2_C30C31            0xFFC1A32C         /* PVP0 Coefficients 3, 0 and 3, 1 */
+#define PVP0_CNV3_C30C31            0xFFC1A3AC         /* PVP0 Coefficients 3, 0 and 3, 1 */
+#define PVP0_CNV0_C32C33            0xFFC1A230         /* PVP0 Coefficients 3, 2 and 3, 3 */
+#define PVP0_CNV1_C32C33            0xFFC1A2B0         /* PVP0 Coefficients 3, 2 and 3, 3 */
+#define PVP0_CNV2_C32C33            0xFFC1A330         /* PVP0 Coefficients 3, 2 and 3, 3 */
+#define PVP0_CNV3_C32C33            0xFFC1A3B0         /* PVP0 Coefficients 3, 2 and 3, 3 */
+#define PVP0_CNV0_C34               0xFFC1A234         /* PVP0 Coefficient 3, 4 */
+#define PVP0_CNV1_C34               0xFFC1A2B4         /* PVP0 Coefficient 3, 4 */
+#define PVP0_CNV2_C34               0xFFC1A334         /* PVP0 Coefficient 3, 4 */
+#define PVP0_CNV3_C34               0xFFC1A3B4         /* PVP0 Coefficient 3, 4 */
+#define PVP0_CNV0_C40C41            0xFFC1A238         /* PVP0 Coefficients 4, 0 and 4, 1 */
+#define PVP0_CNV1_C40C41            0xFFC1A2B8         /* PVP0 Coefficients 4, 0 and 4, 1 */
+#define PVP0_CNV2_C40C41            0xFFC1A338         /* PVP0 Coefficients 4, 0 and 4, 1 */
+#define PVP0_CNV3_C40C41            0xFFC1A3B8         /* PVP0 Coefficients 4, 0 and 4, 1 */
+#define PVP0_CNV0_C42C43            0xFFC1A23C         /* PVP0 Coefficients 4, 2 and 4, 3 */
+#define PVP0_CNV1_C42C43            0xFFC1A2BC         /* PVP0 Coefficients 4, 2 and 4, 3 */
+#define PVP0_CNV2_C42C43            0xFFC1A33C         /* PVP0 Coefficients 4, 2 and 4, 3 */
+#define PVP0_CNV3_C42C43            0xFFC1A3BC         /* PVP0 Coefficients 4, 2 and 4, 3 */
+#define PVP0_CNV0_C44               0xFFC1A240         /* PVP0 Coefficient 4, 4 */
+#define PVP0_CNV1_C44               0xFFC1A2C0         /* PVP0 Coefficient 4, 4 */
+#define PVP0_CNV2_C44               0xFFC1A340         /* PVP0 Coefficient 4, 4 */
+#define PVP0_CNV3_C44               0xFFC1A3C0         /* PVP0 Coefficient 4, 4 */
+#define PVP0_CNV0_SCALE             0xFFC1A244         /* PVP0 Scaling factor */
+#define PVP0_CNV1_SCALE             0xFFC1A2C4         /* PVP0 Scaling factor */
+#define PVP0_CNV2_SCALE             0xFFC1A344         /* PVP0 Scaling factor */
+#define PVP0_CNV3_SCALE             0xFFC1A3C4         /* PVP0 Scaling factor */
+#define PVP0_THC0_CFG               0xFFC1A400         /* PVP0 Configuration */
+#define PVP0_THC1_CFG               0xFFC1A500         /* PVP0 Configuration */
+#define PVP0_THC0_CTL               0xFFC1A404         /* PVP0 Control */
+#define PVP0_THC1_CTL               0xFFC1A504         /* PVP0 Control */
+#define PVP0_THC0_HFCNT             0xFFC1A408         /* PVP0 Number of frames */
+#define PVP0_THC1_HFCNT             0xFFC1A508         /* PVP0 Number of frames */
+#define PVP0_THC0_RMAXREP           0xFFC1A40C         /* PVP0 Maximum number of RLE reports */
+#define PVP0_THC1_RMAXREP           0xFFC1A50C         /* PVP0 Maximum number of RLE reports */
+#define PVP0_THC0_CMINVAL           0xFFC1A410         /* PVP0 Min clip value */
+#define PVP0_THC1_CMINVAL           0xFFC1A510         /* PVP0 Min clip value */
+#define PVP0_THC0_CMINTH            0xFFC1A414         /* PVP0 Clip Min Threshold */
+#define PVP0_THC1_CMINTH            0xFFC1A514         /* PVP0 Clip Min Threshold */
+#define PVP0_THC0_CMAXTH            0xFFC1A418         /* PVP0 Clip Max Threshold */
+#define PVP0_THC1_CMAXTH            0xFFC1A518         /* PVP0 Clip Max Threshold */
+#define PVP0_THC0_CMAXVAL           0xFFC1A41C         /* PVP0 Max clip value */
+#define PVP0_THC1_CMAXVAL           0xFFC1A51C         /* PVP0 Max clip value */
+#define PVP0_THC0_TH0               0xFFC1A420         /* PVP0 Threshold Value */
+#define PVP0_THC1_TH0               0xFFC1A520         /* PVP0 Threshold Value */
+#define PVP0_THC0_TH1               0xFFC1A424         /* PVP0 Threshold Value */
+#define PVP0_THC1_TH1               0xFFC1A524         /* PVP0 Threshold Value */
+#define PVP0_THC0_TH2               0xFFC1A428         /* PVP0 Threshold Value */
+#define PVP0_THC1_TH2               0xFFC1A528         /* PVP0 Threshold Value */
+#define PVP0_THC0_TH3               0xFFC1A42C         /* PVP0 Threshold Value */
+#define PVP0_THC1_TH3               0xFFC1A52C         /* PVP0 Threshold Value */
+#define PVP0_THC0_TH4               0xFFC1A430         /* PVP0 Threshold Value */
+#define PVP0_THC1_TH4               0xFFC1A530         /* PVP0 Threshold Value */
+#define PVP0_THC0_TH5               0xFFC1A434         /* PVP0 Threshold Value */
+#define PVP0_THC1_TH5               0xFFC1A534         /* PVP0 Threshold Value */
+#define PVP0_THC0_TH6               0xFFC1A438         /* PVP0 Threshold Value */
+#define PVP0_THC1_TH6               0xFFC1A538         /* PVP0 Threshold Value */
+#define PVP0_THC0_TH7               0xFFC1A43C         /* PVP0 Threshold Value */
+#define PVP0_THC1_TH7               0xFFC1A53C         /* PVP0 Threshold Value */
+#define PVP0_THC0_TH8               0xFFC1A440         /* PVP0 Threshold Value */
+#define PVP0_THC1_TH8               0xFFC1A540         /* PVP0 Threshold Value */
+#define PVP0_THC0_TH9               0xFFC1A444         /* PVP0 Threshold Value */
+#define PVP0_THC1_TH9               0xFFC1A544         /* PVP0 Threshold Value */
+#define PVP0_THC0_TH10              0xFFC1A448         /* PVP0 Threshold Value */
+#define PVP0_THC1_TH10              0xFFC1A548         /* PVP0 Threshold Value */
+#define PVP0_THC0_TH11              0xFFC1A44C         /* PVP0 Threshold Value */
+#define PVP0_THC1_TH11              0xFFC1A54C         /* PVP0 Threshold Value */
+#define PVP0_THC0_TH12              0xFFC1A450         /* PVP0 Threshold Value */
+#define PVP0_THC1_TH12              0xFFC1A550         /* PVP0 Threshold Value */
+#define PVP0_THC0_TH13              0xFFC1A454         /* PVP0 Threshold Value */
+#define PVP0_THC1_TH13              0xFFC1A554         /* PVP0 Threshold Value */
+#define PVP0_THC0_TH14              0xFFC1A458         /* PVP0 Threshold Value */
+#define PVP0_THC1_TH14              0xFFC1A558         /* PVP0 Threshold Value */
+#define PVP0_THC0_TH15              0xFFC1A45C         /* PVP0 Threshold Value */
+#define PVP0_THC1_TH15              0xFFC1A55C         /* PVP0 Threshold Value */
+#define PVP0_THC0_HHPOS             0xFFC1A460         /* PVP0 Window start X-coordinate */
+#define PVP0_THC1_HHPOS             0xFFC1A560         /* PVP0 Window start X-coordinate */
+#define PVP0_THC0_HVPOS             0xFFC1A464         /* PVP0 Window start Y-coordinate */
+#define PVP0_THC1_HVPOS             0xFFC1A564         /* PVP0 Window start Y-coordinate */
+#define PVP0_THC0_HHCNT             0xFFC1A468         /* PVP0 Window width in X dimension */
+#define PVP0_THC1_HHCNT             0xFFC1A568         /* PVP0 Window width in X dimension */
+#define PVP0_THC0_HVCNT             0xFFC1A46C         /* PVP0 Window width in Y dimension */
+#define PVP0_THC1_HVCNT             0xFFC1A56C         /* PVP0 Window width in Y dimension */
+#define PVP0_THC0_RHPOS             0xFFC1A470         /* PVP0 Window start X-coordinate */
+#define PVP0_THC1_RHPOS             0xFFC1A570         /* PVP0 Window start X-coordinate */
+#define PVP0_THC0_RVPOS             0xFFC1A474         /* PVP0 Window start Y-coordinate */
+#define PVP0_THC1_RVPOS             0xFFC1A574         /* PVP0 Window start Y-coordinate */
+#define PVP0_THC0_RHCNT             0xFFC1A478         /* PVP0 Window width in X dimension */
+#define PVP0_THC1_RHCNT             0xFFC1A578         /* PVP0 Window width in X dimension */
+#define PVP0_THC0_RVCNT             0xFFC1A47C         /* PVP0 Window width in Y dimension */
+#define PVP0_THC1_RVCNT             0xFFC1A57C         /* PVP0 Window width in Y dimension */
+#define PVP0_THC0_HFCNT_STAT        0xFFC1A480         /* PVP0 Current Frame counter */
+#define PVP0_THC1_HFCNT_STAT        0xFFC1A580         /* PVP0 Current Frame counter */
+#define PVP0_THC0_HCNT0_STAT        0xFFC1A484         /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT0_STAT        0xFFC1A584         /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT1_STAT        0xFFC1A488         /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT1_STAT        0xFFC1A588         /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT2_STAT        0xFFC1A48C         /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT2_STAT        0xFFC1A58C         /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT3_STAT        0xFFC1A490         /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT3_STAT        0xFFC1A590         /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT4_STAT        0xFFC1A494         /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT4_STAT        0xFFC1A594         /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT5_STAT        0xFFC1A498         /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT5_STAT        0xFFC1A598         /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT6_STAT        0xFFC1A49C         /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT6_STAT        0xFFC1A59C         /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT7_STAT        0xFFC1A4A0         /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT7_STAT        0xFFC1A5A0         /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT8_STAT        0xFFC1A4A4         /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT8_STAT        0xFFC1A5A4         /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT9_STAT        0xFFC1A4A8         /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT9_STAT        0xFFC1A5A8         /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT10_STAT       0xFFC1A4AC         /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT10_STAT       0xFFC1A5AC         /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT11_STAT       0xFFC1A4B0         /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT11_STAT       0xFFC1A5B0         /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT12_STAT       0xFFC1A4B4         /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT12_STAT       0xFFC1A5B4         /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT13_STAT       0xFFC1A4B8         /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT13_STAT       0xFFC1A5B8         /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT14_STAT       0xFFC1A4BC         /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT14_STAT       0xFFC1A5BC         /* PVP0 Histogram counter value */
+#define PVP0_THC0_HCNT15_STAT       0xFFC1A4C0         /* PVP0 Histogram counter value */
+#define PVP0_THC1_HCNT15_STAT       0xFFC1A5C0         /* PVP0 Histogram counter value */
+#define PVP0_THC0_RREP_STAT         0xFFC1A4C4         /* PVP0 Number of RLE Reports */
+#define PVP0_THC1_RREP_STAT         0xFFC1A5C4         /* PVP0 Number of RLE Reports */
+#define PVP0_PMA_CFG                0xFFC1A600         /* PVP0 PMA Configuration Register */
 
 #endif /* _DEF_BF609_H */
diff --git a/arch/blackfin/mach-common/cpufreq.c b/arch/blackfin/mach-common/cpufreq.c
index c854a27..d88bd31 100644
--- a/arch/blackfin/mach-common/cpufreq.c
+++ b/arch/blackfin/mach-common/cpufreq.c
@@ -77,15 +77,14 @@
 	csel = bfin_read32(CGU0_DIV) & 0x1F;
 #endif
 
-	for (index = 0;  (cclk >> index) >= min_cclk && csel <= 3; index++, csel++) {
+	for (index = 0;  (cclk >> index) >= min_cclk && csel <= 3 && index < 3; index++, csel++) {
 		bfin_freq_table[index].frequency = cclk >> index;
 #ifndef CONFIG_BF60x
 		dpm_state_table[index].csel = csel << 4; /* Shift now into PLL_DIV bitpos */
-		dpm_state_table[index].tscale =  (TIME_SCALE / (1 << csel)) - 1;
 #else
 		dpm_state_table[index].csel = csel;
-		dpm_state_table[index].tscale =  TIME_SCALE >> index;
 #endif
+		dpm_state_table[index].tscale =  (TIME_SCALE >> index) - 1;
 
 		pr_debug("cpufreq: freq:%d csel:0x%x tscale:%d\n",
 						 bfin_freq_table[index].frequency,
@@ -135,7 +134,7 @@
 	unsigned int plldiv;
 #endif
 	unsigned int index, cpu;
-	unsigned long flags, cclk_hz;
+	unsigned long cclk_hz;
 	struct cpufreq_freqs freqs;
 	static unsigned long lpj_ref;
 	static unsigned int  lpj_ref_freq;
@@ -166,7 +165,6 @@
 
 		cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
 		if (cpu == CPUFREQ_CPU) {
-			flags = hard_local_irq_save();
 #ifndef CONFIG_BF60x
 			plldiv = (bfin_read_PLL_DIV() & SSEL) |
 						dpm_state_table[index].csel;
@@ -195,7 +193,6 @@
 				loops_per_jiffy = cpufreq_scale(lpj_ref,
 						lpj_ref_freq, freqs.new);
 			}
-			hard_local_irq_restore(flags);
 		}
 		/* TODO: just test case for cycles clock source, remove later */
 		cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c
index 7ca09ec..902bebc 100644
--- a/arch/blackfin/mach-common/ints-priority.c
+++ b/arch/blackfin/mach-common/ints-priority.c
@@ -1441,7 +1441,6 @@
 		IMASK_IVG14 | IMASK_IVG13 | IMASK_IVG12 | IMASK_IVG11 |
 		IMASK_IVG10 | IMASK_IVG9 | IMASK_IVG8 | IMASK_IVG7 | IMASK_IVGHW;
 
-	bfin_sti(bfin_irq_flags);
 
 	/* This implicitly covers ANOMALY_05000171
 	 * Boot-ROM code modifies SICA_IWRx wakeup registers
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c
index a401513..bb61ae4 100644
--- a/arch/blackfin/mach-common/smp.c
+++ b/arch/blackfin/mach-common/smp.c
@@ -146,7 +146,7 @@
 	platform_clear_ipi(cpu, IRQ_SUPPLE_1);
 
 	bfin_ipi_data = &__get_cpu_var(bfin_ipi);
-
+	smp_mb();
 	while ((pending = xchg(&bfin_ipi_data->bits, 0)) != 0) {
 		msg = 0;
 		do {
@@ -195,7 +195,7 @@
 	unsigned long flags;
 
 	local_irq_save(flags);
-
+	smp_mb();
 	for_each_cpu(cpu, cpumask) {
 		bfin_ipi_data = &per_cpu(bfin_ipi, cpu);
 		smp_mb();
diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig
index 983c859..45268b5 100644
--- a/arch/c6x/Kconfig
+++ b/arch/c6x/Kconfig
@@ -17,6 +17,7 @@
 	select OF
 	select OF_EARLY_FLATTREE
 	select GENERIC_CLOCKEVENTS
+	select GENERIC_KERNEL_THREAD
 
 config MMU
 	def_bool n
diff --git a/arch/c6x/include/asm/Kbuild b/arch/c6x/include/asm/Kbuild
index 277f1a4..4e4e98da 100644
--- a/arch/c6x/include/asm/Kbuild
+++ b/arch/c6x/include/asm/Kbuild
@@ -12,6 +12,7 @@
 generic-y += dma.h
 generic-y += emergency-restart.h
 generic-y += errno.h
+generic-y += exec.h
 generic-y += fb.h
 generic-y += fcntl.h
 generic-y += futex.h
diff --git a/arch/c6x/include/asm/exec.h b/arch/c6x/include/asm/exec.h
deleted file mode 100644
index 0fea482..0000000
--- a/arch/c6x/include/asm/exec.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ASM_C6X_EXEC_H
-#define _ASM_C6X_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _ASM_C6X_EXEC_H */
diff --git a/arch/c6x/include/asm/processor.h b/arch/c6x/include/asm/processor.h
index c50af7e..b9eb3da 100644
--- a/arch/c6x/include/asm/processor.h
+++ b/arch/c6x/include/asm/processor.h
@@ -92,8 +92,6 @@
 {
 }
 
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
 #define copy_segments(tsk, mm)		do { } while (0)
 #define release_segments(mm)		do { } while (0)
 
diff --git a/arch/c6x/include/asm/syscalls.h b/arch/c6x/include/asm/syscalls.h
index aed53da..e7b8991 100644
--- a/arch/c6x/include/asm/syscalls.h
+++ b/arch/c6x/include/asm/syscalls.h
@@ -44,11 +44,6 @@
 struct pt_regs;
 
 extern asmlinkage long sys_c6x_clone(struct pt_regs *regs);
-extern asmlinkage long sys_c6x_execve(const char __user *name,
-				      const char __user *const __user *argv,
-				      const char __user *const __user *envp,
-				      struct pt_regs *regs);
-
 
 #include <asm-generic/syscalls.h>
 
diff --git a/arch/c6x/include/asm/thread_info.h b/arch/c6x/include/asm/thread_info.h
index 1710bcb..4c8dc56 100644
--- a/arch/c6x/include/asm/thread_info.h
+++ b/arch/c6x/include/asm/thread_info.h
@@ -97,7 +97,6 @@
 #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
 #define TIF_RESTORE_SIGMASK	4	/* restore signal mask in do_signal() */
 
-#define TIF_POLLING_NRFLAG	16	/* true if polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE		17	/* OOM killer killed process */
 
 #define TIF_WORK_MASK		0x00007FFE /* work on irq/exception return */
diff --git a/arch/c6x/include/asm/unistd.h b/arch/c6x/include/asm/unistd.h
index ed22590..4ff747d1 100644
--- a/arch/c6x/include/asm/unistd.h
+++ b/arch/c6x/include/asm/unistd.h
@@ -14,6 +14,9 @@
  *   more details.
  */
 
+#define __ARCH_WANT_KERNEL_EXECVE
+#define __ARCH_WANT_SYS_EXECVE
+
 /* Use the standard ABI for syscalls. */
 #include <asm-generic/unistd.h>
 
diff --git a/arch/c6x/kernel/asm-offsets.c b/arch/c6x/kernel/asm-offsets.c
index 759ad6d..60f1e43 100644
--- a/arch/c6x/kernel/asm-offsets.c
+++ b/arch/c6x/kernel/asm-offsets.c
@@ -116,7 +116,6 @@
 	DEFINE(_TIF_NOTIFY_RESUME, (1<<TIF_NOTIFY_RESUME));
 	DEFINE(_TIF_SIGPENDING, (1<<TIF_SIGPENDING));
 	DEFINE(_TIF_NEED_RESCHED, (1<<TIF_NEED_RESCHED));
-	DEFINE(_TIF_POLLING_NRFLAG, (1<<TIF_POLLING_NRFLAG));
 
 	DEFINE(_TIF_ALLWORK_MASK, TIF_ALLWORK_MASK);
 	DEFINE(_TIF_WORK_MASK, TIF_WORK_MASK);
diff --git a/arch/c6x/kernel/entry.S b/arch/c6x/kernel/entry.S
index 30b37e5..5449c36 100644
--- a/arch/c6x/kernel/entry.S
+++ b/arch/c6x/kernel/entry.S
@@ -400,6 +400,32 @@
 	STW	.D2T2	B0,*+SP(REGS_A4+8)
 ENDPROC(ret_from_fork)
 
+ENTRY(ret_from_kernel_thread)
+#ifdef CONFIG_C6X_BIG_KERNEL
+	MVKL	.S1	schedule_tail,A0
+	MVKH	.S1	schedule_tail,A0
+	B	.S2X	A0
+#else
+	B	.S2	schedule_tail
+#endif
+	LDW	.D2T2	*+SP(REGS_A0+8),B10 /* get fn  */
+	ADDKPC	.S2	0f,B3,3
+0:
+	B	.S2	B10		   /* call fn */
+	LDW	.D2T1	*+SP(REGS_A1+8),A4 /* get arg */
+	MVKL	.S2	sys_exit,B11
+	MVKH	.S2	sys_exit,B11
+	ADDKPC	.S2	0f,B3,1
+0:
+	BNOP	.S2	B11,5	/* jump to sys_exit */
+ENDPROC(ret_from_kernel_thread)
+
+ENTRY(ret_from_kernel_execve)
+	GET_THREAD_INFO A12
+	BNOP	.S2	syscall_exit,4
+	ADD	.D2X	A4,-8,SP
+ENDPROC(ret_from_kernel_execve)
+
 	;;
 	;; These are the interrupt handlers, responsible for calling __do_IRQ()
 	;; int6 is used for syscalls (see _system_call entry)
@@ -593,13 +619,6 @@
 	NOP	4
 ENDPROC(sys_sigaltstack)
 
-	;; kernel_execve
-ENTRY(kernel_execve)
-	MVK	.S2	__NR_execve,B0
-	SWE
-	BNOP	.S2	B3,5
-ENDPROC(kernel_execve)
-
 	;;
 	;; Special system calls
 	;; return address is in B3
@@ -628,29 +647,6 @@
 #endif
 ENDPROC(sys_rt_sigreturn)
 
-ENTRY(sys_execve)
-	ADDAW	.D2	SP,2,B6		; put regs addr in 4th parameter
-					; & adjust regs stack addr
-	LDW	.D2T2	*+SP(REGS_B4+8),B4
-
-	;; c6x_execve(char *name, char **argv,
-	;;            char **envp, struct pt_regs *regs)
-#ifdef CONFIG_C6X_BIG_KERNEL
- ||	MVKL	.S1	sys_c6x_execve,A0
-	MVKH	.S1	sys_c6x_execve,A0
-	B	.S2X	A0
-#else
- ||	B	.S2	sys_c6x_execve
-#endif
-	STW	.D2T2	B3,*SP--[2]
-	ADDKPC	.S2	ret_from_c6x_execve,B3,3
-
-ret_from_c6x_execve:
-	LDW	.D2T2	*++SP[2],B3
-	NOP	4
-	BNOP	.S2	B3,5
-ENDPROC(sys_execve)
-
 ENTRY(sys_pread_c6x)
 	MV	.D2X	A8,B7
 #ifdef CONFIG_C6X_BIG_KERNEL
diff --git a/arch/c6x/kernel/process.c b/arch/c6x/kernel/process.c
index 45e924a..2770d9a 100644
--- a/arch/c6x/kernel/process.c
+++ b/arch/c6x/kernel/process.c
@@ -25,6 +25,7 @@
 void	(*c6x_halt)(void);
 
 extern asmlinkage void ret_from_fork(void);
+extern asmlinkage void ret_from_kernel_thread(void);
 
 /*
  * power off function, if any
@@ -103,37 +104,6 @@
 	halt_loop();
 }
 
-static void kernel_thread_helper(int dummy, void *arg, int (*fn)(void *))
-{
-	do_exit(fn(arg));
-}
-
-/*
- * Create a kernel thread
- */
-int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-{
-	struct pt_regs regs;
-
-	/*
-	 * copy_thread sets a4 to zero (child return from fork)
-	 * so we can't just set things up to directly return to
-	 * fn.
-	 */
-	memset(&regs, 0, sizeof(regs));
-	regs.b4 = (unsigned long) arg;
-	regs.a6 = (unsigned long) fn;
-	regs.pc = (unsigned long) kernel_thread_helper;
-	local_save_flags(regs.csr);
-	regs.csr |= 1;
-	regs.tsr = 5; /* Set GEE and GIE in TSR */
-
-	/* Ok, create the new process.. */
-	return do_fork(flags | CLONE_VM | CLONE_UNTRACED, -1, &regs,
-		       0, NULL, NULL);
-}
-EXPORT_SYMBOL(kernel_thread);
-
 void flush_thread(void)
 {
 }
@@ -191,22 +161,24 @@
 
 	childregs = task_pt_regs(p);
 
-	*childregs = *regs;
-	childregs->a4 = 0;
-
-	if (usp == -1)
+	if (!regs) {
 		/* case of  __kernel_thread: we return to supervisor space */
+		memset(childregs, 0, sizeof(struct pt_regs));
 		childregs->sp = (unsigned long)(childregs + 1);
-	else
+		p->thread.pc = (unsigned long) ret_from_kernel_thread;
+		childregs->a0 = usp;		/* function */
+		childregs->a1 = ustk_size;	/* argument */
+	} else {
 		/* Otherwise use the given stack */
+		*childregs = *regs;
 		childregs->sp = usp;
+		p->thread.pc = (unsigned long) ret_from_fork;
+	}
 
 	/* Set usp/ksp */
 	p->thread.usp = childregs->sp;
-	/* switch_to uses stack to save/restore 14 callee-saved regs */
 	thread_saved_ksp(p) = (unsigned long)childregs - 8;
-	p->thread.pc = (unsigned int) ret_from_fork;
-	p->thread.wchan	= (unsigned long) ret_from_fork;
+	p->thread.wchan	= p->thread.pc;
 #ifdef __DSBT__
 	{
 		unsigned long dp;
@@ -221,28 +193,6 @@
 	return 0;
 }
 
-/*
- * c6x_execve() executes a new program.
- */
-SYSCALL_DEFINE4(c6x_execve, const char __user *, name,
-		const char __user *const __user *, argv,
-		const char __user *const __user *, envp,
-		struct pt_regs *, regs)
-{
-	int error;
-	char *filename;
-
-	filename = getname(name);
-	error = PTR_ERR(filename);
-	if (IS_ERR(filename))
-		goto out;
-
-	error = do_execve(filename, argv, envp, regs);
-	putname(filename);
-out:
-	return error;
-}
-
 unsigned long get_wchan(struct task_struct *p)
 {
 	return p->thread.wchan;
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index 72bd5ae..a118163 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -42,6 +42,7 @@
 	select HAVE_IDE
 	select GENERIC_ATOMIC64
 	select HAVE_GENERIC_HARDIRQS
+	select HAVE_UID16
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select GENERIC_IRQ_SHOW
 	select GENERIC_IOMAP
diff --git a/arch/cris/include/asm/Kbuild b/arch/cris/include/asm/Kbuild
index 04d02a5..ff1bf7f 100644
--- a/arch/cris/include/asm/Kbuild
+++ b/arch/cris/include/asm/Kbuild
@@ -7,3 +7,6 @@
 header-y += etraxgpio.h
 header-y += rs485.h
 header-y += sync_serial.h
+
+generic-y += clkdev.h
+generic-y += exec.h
diff --git a/arch/cris/include/asm/exec.h b/arch/cris/include/asm/exec.h
deleted file mode 100644
index 9665dab..0000000
--- a/arch/cris/include/asm/exec.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __ASM_CRIS_EXEC_H
-#define __ASM_CRIS_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* __ASM_CRIS_EXEC_H */
diff --git a/arch/cris/include/asm/thread_info.h b/arch/cris/include/asm/thread_info.h
index 5b1c448..07c8c40 100644
--- a/arch/cris/include/asm/thread_info.h
+++ b/arch/cris/include/asm/thread_info.h
@@ -78,15 +78,12 @@
 #define TIF_SIGPENDING		2	/* signal pending */
 #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
 #define TIF_RESTORE_SIGMASK	9	/* restore signal mask in do_signal() */
-#define TIF_POLLING_NRFLAG	16	/* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE		17	/* is terminating due to OOM killer */
 
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
 #define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
-#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
-#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 
 #define _TIF_WORK_MASK		0x0000FFFE	/* work to do on interrupt/exception return */
 #define _TIF_ALLWORK_MASK	0x0000FFFF	/* work to do on any return to u-space */
diff --git a/arch/cris/mm/fault.c b/arch/cris/mm/fault.c
index 45fd542..73312ab 100644
--- a/arch/cris/mm/fault.c
+++ b/arch/cris/mm/fault.c
@@ -186,6 +186,7 @@
 			tsk->min_flt++;
 		if (fault & VM_FAULT_RETRY) {
 			flags &= ~FAULT_FLAG_ALLOW_RETRY;
+			flags |= FAULT_FLAG_TRIED;
 
 			/*
 			 * No need to up_read(&mm->mmap_sem) as we would
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index 971c0a1..b741250 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -5,11 +5,14 @@
 	select HAVE_ARCH_TRACEHOOK
 	select HAVE_IRQ_WORK
 	select HAVE_PERF_EVENTS
+	select HAVE_UID16
 	select HAVE_GENERIC_HARDIRQS
 	select GENERIC_IRQ_SHOW
+	select HAVE_DEBUG_BUGVERBOSE
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select GENERIC_CPU_DEVICES
 	select ARCH_WANT_IPC_PARSE_VERSION
+	select GENERIC_KERNEL_THREAD
 
 config ZONE_DMA
 	bool
diff --git a/arch/frv/include/asm/Kbuild b/arch/frv/include/asm/Kbuild
index 5be6663..251bd71 100644
--- a/arch/frv/include/asm/Kbuild
+++ b/arch/frv/include/asm/Kbuild
@@ -2,3 +2,5 @@
 
 header-y += registers.h
 header-y += termios.h
+generic-y += clkdev.h
+generic-y += exec.h
diff --git a/arch/frv/include/asm/exec.h b/arch/frv/include/asm/exec.h
deleted file mode 100644
index 65c9130..0000000
--- a/arch/frv/include/asm/exec.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* FR-V CPU executable handling
- *
- * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#ifndef _ASM_EXEC_H
-#define _ASM_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _ASM_EXEC_H */
diff --git a/arch/frv/include/asm/processor.h b/arch/frv/include/asm/processor.h
index dccb9d1..a34f309 100644
--- a/arch/frv/include/asm/processor.h
+++ b/arch/frv/include/asm/processor.h
@@ -92,14 +92,12 @@
 
 /*
  * do necessary setup to start up a newly executed thread.
- * - need to discard the frame stacked by init() invoking the execve syscall
  */
 #define start_thread(_regs, _pc, _usp)			\
 do {							\
-	__frame = __kernel_frame0_ptr;			\
-	__frame->pc	= (_pc);			\
-	__frame->psr	&= ~PSR_S;			\
-	__frame->sp	= (_usp);			\
+	_regs->pc	= (_pc);			\
+	_regs->psr	&= ~PSR_S;			\
+	_regs->sp	= (_usp);			\
 } while(0)
 
 /* Free all resources held by a thread. */
@@ -107,7 +105,6 @@
 {
 }
 
-extern asmlinkage int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 extern asmlinkage void save_user_regs(struct user_context *target);
 extern asmlinkage void *restore_user_regs(const struct user_context *target, ...);
 
diff --git a/arch/frv/include/asm/ptrace.h b/arch/frv/include/asm/ptrace.h
index ef6635c..bd534b2 100644
--- a/arch/frv/include/asm/ptrace.h
+++ b/arch/frv/include/asm/ptrace.h
@@ -76,6 +76,7 @@
 #define user_mode(regs)			(!((regs)->psr & PSR_S))
 #define instruction_pointer(regs)	((regs)->pc)
 #define user_stack_pointer(regs)	((regs)->sp)
+#define current_pt_regs()		(__frame)
 
 extern unsigned long user_stack(const struct pt_regs *);
 #define profile_pc(regs) ((regs)->pc)
diff --git a/arch/frv/include/asm/thread_info.h b/arch/frv/include/asm/thread_info.h
index 0ff03a3..bebd7ea 100644
--- a/arch/frv/include/asm/thread_info.h
+++ b/arch/frv/include/asm/thread_info.h
@@ -94,7 +94,6 @@
 #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
 #define TIF_SINGLESTEP		4	/* restore singlestep on return to user mode */
 #define TIF_RESTORE_SIGMASK	5	/* restore signal mask in do_signal() */
-#define TIF_POLLING_NRFLAG	6	/* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE		7	/* is terminating due to OOM killer */
 
 #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
@@ -102,8 +101,6 @@
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
 #define _TIF_SINGLESTEP		(1 << TIF_SINGLESTEP)
-#define _TIF_RESTORE_SIGMASK	(1 << TIF_RESTORE_SIGMASK)
-#define _TIF_POLLING_NRFLAG	(1 << TIF_POLLING_NRFLAG)
 
 /* work to do on interrupt/exception return */
 #define _TIF_WORK_MASK		\
diff --git a/arch/frv/include/asm/unistd.h b/arch/frv/include/asm/unistd.h
index 67f23a3..b6b07e5 100644
--- a/arch/frv/include/asm/unistd.h
+++ b/arch/frv/include/asm/unistd.h
@@ -372,6 +372,8 @@
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_SYS_EXECVE
+#define __ARCH_WANT_KERNEL_EXECVE
 
 /*
  * "Conditional" syscalls
diff --git a/arch/frv/kernel/Makefile b/arch/frv/kernel/Makefile
index ad4087b..3cbb329 100644
--- a/arch/frv/kernel/Makefile
+++ b/arch/frv/kernel/Makefile
@@ -7,8 +7,8 @@
 
 extra-y:= head.o vmlinux.lds
 
-obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o kernel_thread.o \
-	 kernel_execve.o process.o traps.o ptrace.o signal.o dma.o \
+obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o \
+	 process.o traps.o ptrace.o signal.o dma.o \
 	 sys_frv.o time.o setup.o frv_ksyms.o \
 	 debug-stub.o irq.o sleep.o uaccess.o
 
diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S
index 7d5e000..0027329 100644
--- a/arch/frv/kernel/entry.S
+++ b/arch/frv/kernel/entry.S
@@ -863,6 +863,19 @@
 	setlos.p	#0,gr8
 	bra		__syscall_exit
 
+	.globl		ret_from_kernel_thread
+ret_from_kernel_thread:
+	lddi.p		@(gr28,#REG_GR(8)),gr20
+	call		schedule_tail
+	or.p		gr20,gr20,gr8
+	calll		@(gr21,gr0)
+	bra		sys_exit
+
+	.globl		ret_from_kernel_execve
+ret_from_kernel_execve:
+	ori		gr28,0,sp
+	bra		__syscall_exit
+
 ###################################################################################################
 #
 # Return to user mode is not as complex as all this looks,
diff --git a/arch/frv/kernel/frv_ksyms.c b/arch/frv/kernel/frv_ksyms.c
index a89803b..86c516d 100644
--- a/arch/frv/kernel/frv_ksyms.c
+++ b/arch/frv/kernel/frv_ksyms.c
@@ -30,7 +30,6 @@
 EXPORT_SYMBOL(local_irq_count);
 EXPORT_SYMBOL(local_bh_count);
 #endif
-EXPORT_SYMBOL(kernel_thread);
 
 EXPORT_SYMBOL(__res_bus_clock_speed_HZ);
 EXPORT_SYMBOL(__page_offset);
diff --git a/arch/frv/kernel/kernel_execve.S b/arch/frv/kernel/kernel_execve.S
deleted file mode 100644
index 9b074a1..0000000
--- a/arch/frv/kernel/kernel_execve.S
+++ /dev/null
@@ -1,33 +0,0 @@
-/* in-kernel program execution
- *
- * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/linkage.h>
-#include <asm/unistd.h>
-
-###############################################################################
-#
-# Do a system call from kernel instead of calling sys_execve so we end up with
-# proper pt_regs.
-#
-# int kernel_execve(const char *filename, char *const argv[], char *const envp[])
-#
-# On entry: GR8/GR9/GR10: arguments to function
-# On return: GR8: syscall return.
-#
-###############################################################################
-	.globl		kernel_execve
-	.type		kernel_execve,@function
-kernel_execve:
-	setlos		__NR_execve,gr7
-	tira		gr0,#0
-	bralr
-
-	.size		kernel_execve,.-kernel_execve
diff --git a/arch/frv/kernel/kernel_thread.S b/arch/frv/kernel/kernel_thread.S
deleted file mode 100644
index f0e5294..0000000
--- a/arch/frv/kernel/kernel_thread.S
+++ /dev/null
@@ -1,77 +0,0 @@
-/* kernel_thread.S: kernel thread creation
- *
- * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/linkage.h>
-#include <linux/kern_levels.h>
-#include <asm/unistd.h>
-
-#define CLONE_VM	0x00000100	/* set if VM shared between processes */
-
-	.section .rodata
-kernel_thread_emsg:
-	.asciz	KERN_ERR "failed to create kernel thread: error=%d\n"
-
-	.text
-	.balign		4
-
-###############################################################################
-#
-# Create a kernel thread
-#
-# int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-#
-###############################################################################
-	.globl		kernel_thread
-	.type		kernel_thread,@function
-kernel_thread:
-	or.p		gr8,gr0,gr4
-	or		gr9,gr0,gr5
-
-	# start by forking the current process, but with shared VM
-	setlos.p	#__NR_clone,gr7		; syscall number
-	ori		gr10,#CLONE_VM,gr8	; first syscall arg	[clone_flags]
-	sethi.p		#0xe4e4,gr9		; second syscall arg	[newsp]
-	setlo		#0xe4e4,gr9
-	setlos.p	#0,gr10			; third syscall arg	[parent_tidptr]
-	setlos		#0,gr11			; fourth syscall arg	[child_tidptr]
-	tira		gr0,#0
-	setlos.p	#4095,gr7
-	andcc		gr8,gr8,gr0,icc0
-	addcc.p		gr8,gr7,gr0,icc1
-	bnelr		icc0,#2
-	bc		icc1,#0,kernel_thread_error
-
-	# now invoke the work function
-	or		gr5,gr0,gr8
-	calll		@(gr4,gr0)
-
-	# and finally exit the thread
-	setlos		#__NR_exit,gr7		; syscall number
-	tira		gr0,#0
-
-kernel_thread_error:
-	subi		sp,#8,sp
-	movsg		lr,gr4
-	sti		gr8,@(sp,#0)
-	sti.p		gr4,@(sp,#4)
-
-	or		gr8,gr0,gr9
-	sethi.p		%hi(kernel_thread_emsg),gr8
-	setlo		%lo(kernel_thread_emsg),gr8
-
-	call		printk
-
-	ldi		@(sp,#4),gr4
-	ldi		@(sp,#0),gr8
-	subi		sp,#8,sp
-	jmpl		@(gr4,gr0)
-
-	.size		kernel_thread,.-kernel_thread
diff --git a/arch/frv/kernel/process.c b/arch/frv/kernel/process.c
index 2eb7fa5..655d90d 100644
--- a/arch/frv/kernel/process.c
+++ b/arch/frv/kernel/process.c
@@ -38,6 +38,7 @@
 #include "local.h"
 
 asmlinkage void ret_from_fork(void);
+asmlinkage void ret_from_kernel_thread(void);
 
 #include <asm/pgalloc.h>
 
@@ -172,32 +173,13 @@
  * set up the kernel stack and exception frames for a new process
  */
 int copy_thread(unsigned long clone_flags,
-		unsigned long usp, unsigned long topstk,
+		unsigned long usp, unsigned long arg,
 		struct task_struct *p, struct pt_regs *regs)
 {
-	struct pt_regs *childregs0, *childregs, *regs0;
+	struct pt_regs *childregs;
 
-	regs0 = __kernel_frame0_ptr;
-	childregs0 = (struct pt_regs *)
+	childregs = (struct pt_regs *)
 		(task_stack_page(p) + THREAD_SIZE - FRV_FRAME0_SIZE);
-	childregs = childregs0;
-
-	/* set up the userspace frame (the only place that the USP is stored) */
-	*childregs0 = *regs0;
-
-	childregs0->gr8		= 0;
-	childregs0->sp		= usp;
-	childregs0->next_frame	= NULL;
-
-	/* set up the return kernel frame if called from kernel_thread() */
-	if (regs != regs0) {
-		childregs--;
-		*childregs = *regs;
-		childregs->sp = (unsigned long) childregs0;
-		childregs->next_frame = childregs0;
-		childregs->gr15 = (unsigned long) task_thread_info(p);
-		childregs->gr29 = (unsigned long) p;
-	}
 
 	p->set_child_tid = p->clear_child_tid = NULL;
 
@@ -206,8 +188,25 @@
 	p->thread.sp	 = (unsigned long) childregs;
 	p->thread.fp	 = 0;
 	p->thread.lr	 = 0;
-	p->thread.pc	 = (unsigned long) ret_from_fork;
-	p->thread.frame0 = childregs0;
+	p->thread.frame0 = childregs;
+
+	if (unlikely(!regs)) {
+		memset(childregs, 0, sizeof(struct pt_regs));
+		childregs->gr9 = usp; /* function */
+		childregs->gr8 = arg;
+		chilregs->psr = PSR_S;
+		p->thread.pc = (unsigned long) ret_from_kernel_thread;
+		save_user_regs(p->thread.user);
+		return 0;
+	}
+
+	/* set up the userspace frame (the only place that the USP is stored) */
+	*childregs = *regs;
+
+	childregs->sp		= usp;
+	childregs->next_frame	= NULL;
+
+	p->thread.pc = (unsigned long) ret_from_fork;
 
 	/* the new TLS pointer is passed in as arg #5 to sys_clone() */
 	if (clone_flags & CLONE_SETTLS)
@@ -218,25 +217,6 @@
 	return 0;
 } /* end copy_thread() */
 
-/*
- * sys_execve() executes a new program.
- */
-asmlinkage int sys_execve(const char __user *name,
-			  const char __user *const __user *argv,
-			  const char __user *const __user *envp)
-{
-	int error;
-	char * filename;
-
-	filename = getname(name);
-	error = PTR_ERR(filename);
-	if (IS_ERR(filename))
-		return error;
-	error = do_execve(filename, argv, envp, __frame);
-	putname(filename);
-	return error;
-}
-
 unsigned long get_wchan(struct task_struct *p)
 {
 	struct pt_regs *regs0;
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c
index 864c2f0..535810a 100644
--- a/arch/frv/kernel/signal.c
+++ b/arch/frv/kernel/signal.c
@@ -20,7 +20,6 @@
 #include <linux/ptrace.h>
 #include <linux/unistd.h>
 #include <linux/personality.h>
-#include <linux/freezer.h>
 #include <linux/tracehook.h>
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
@@ -298,10 +297,6 @@
 	__frame->lr   = (unsigned long) &frame->retcode;
 	__frame->gr8  = sig;
 
-	/* the tracer may want to single-step inside the handler */
-	if (test_thread_flag(TIF_SINGLESTEP))
-		ptrace_notify(SIGTRAP);
-
 #if DEBUG_SIG
 	printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
 	       sig, current->comm, current->pid, frame, __frame->pc,
@@ -400,10 +395,6 @@
 	__frame->gr8 = sig;
 	__frame->gr9 = (unsigned long) &frame->info;
 
-	/* the tracer may want to single-step inside the handler */
-	if (test_thread_flag(TIF_SINGLESTEP))
-		ptrace_notify(SIGTRAP);
-
 #if DEBUG_SIG
 	printk("SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
 	       sig, current->comm, current->pid, frame, __frame->pc,
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
index 5e8a0d9..90462eb 100644
--- a/arch/h8300/Kconfig
+++ b/arch/h8300/Kconfig
@@ -3,6 +3,7 @@
 	default y
 	select HAVE_IDE
 	select HAVE_GENERIC_HARDIRQS
+	select HAVE_UID16
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select GENERIC_IRQ_SHOW
 	select GENERIC_CPU_DEVICES
diff --git a/arch/h8300/include/asm/Kbuild b/arch/h8300/include/asm/Kbuild
index c68e168..fccd81e 100644
--- a/arch/h8300/include/asm/Kbuild
+++ b/arch/h8300/include/asm/Kbuild
@@ -1 +1,4 @@
 include include/asm-generic/Kbuild.asm
+
+generic-y += clkdev.h
+generic-y += exec.h
diff --git a/arch/h8300/include/asm/exec.h b/arch/h8300/include/asm/exec.h
deleted file mode 100644
index c01c45c..0000000
--- a/arch/h8300/include/asm/exec.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _H8300_EXEC_H
-#define _H8300_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _H8300_EXEC_H */
diff --git a/arch/h8300/include/asm/thread_info.h b/arch/h8300/include/asm/thread_info.h
index 9c126e0..ec2f777 100644
--- a/arch/h8300/include/asm/thread_info.h
+++ b/arch/h8300/include/asm/thread_info.h
@@ -85,8 +85,6 @@
 #define TIF_SYSCALL_TRACE	0	/* syscall trace active */
 #define TIF_SIGPENDING		1	/* signal pending */
 #define TIF_NEED_RESCHED	2	/* rescheduling necessary */
-#define TIF_POLLING_NRFLAG	3	/* true if poll_idle() is polling
-					   TIF_NEED_RESCHED */
 #define TIF_MEMDIE		4	/* is terminating due to OOM killer */
 #define TIF_RESTORE_SIGMASK	5	/* restore signal mask in do_signal() */
 #define TIF_NOTIFY_RESUME	6	/* callback before returning to user */
@@ -95,11 +93,10 @@
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
-#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
-#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
 #define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
 
-#define _TIF_WORK_MASK		0x0000FFFE	/* work to do on interrupt/exception return */
+#define _TIF_WORK_MASK		(_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
+				 _TIF_NOTIFY_RESUME)
 
 #endif /* __KERNEL__ */
 
diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c
index 5adaada..0e81b96 100644
--- a/arch/h8300/kernel/signal.c
+++ b/arch/h8300/kernel/signal.c
@@ -38,7 +38,6 @@
 #include <linux/personality.h>
 #include <linux/tty.h>
 #include <linux/binfmts.h>
-#include <linux/freezer.h>
 #include <linux/tracehook.h>
 
 #include <asm/setup.h>
diff --git a/arch/hexagon/include/asm/Kbuild b/arch/hexagon/include/asm/Kbuild
index 0690642..3364b696 100644
--- a/arch/hexagon/include/asm/Kbuild
+++ b/arch/hexagon/include/asm/Kbuild
@@ -7,6 +7,7 @@
 generic-y += auxvec.h
 generic-y += bug.h
 generic-y += bugs.h
+generic-y += clkdev.h
 generic-y += cputime.h
 generic-y += current.h
 generic-y += device.h
diff --git a/arch/hexagon/include/asm/thread_info.h b/arch/hexagon/include/asm/thread_info.h
index 4f936a7..e4a0aad 100644
--- a/arch/hexagon/include/asm/thread_info.h
+++ b/arch/hexagon/include/asm/thread_info.h
@@ -120,10 +120,8 @@
 #define TIF_SIGPENDING          2       /* signal pending */
 #define TIF_NEED_RESCHED        3       /* rescheduling necessary */
 #define TIF_SINGLESTEP          4       /* restore ss @ return to usr mode */
-#define TIF_IRET                5       /* return with iret */
 #define TIF_RESTORE_SIGMASK     6       /* restore sig mask in do_signal() */
 /* true if poll_idle() is polling TIF_NEED_RESCHED */
-#define TIF_POLLING_NRFLAG      16
 #define TIF_MEMDIE              17      /* OOM killer killed process */
 
 #define _TIF_SYSCALL_TRACE      (1 << TIF_SYSCALL_TRACE)
@@ -131,9 +129,6 @@
 #define _TIF_SIGPENDING         (1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED       (1 << TIF_NEED_RESCHED)
 #define _TIF_SINGLESTEP         (1 << TIF_SINGLESTEP)
-#define _TIF_IRET               (1 << TIF_IRET)
-#define _TIF_RESTORE_SIGMASK    (1 << TIF_RESTORE_SIGMASK)
-#define _TIF_POLLING_NRFLAG     (1 << TIF_POLLING_NRFLAG)
 
 /* work to do on interrupt/exception return - All but TIF_SYSCALL_TRACE */
 #define _TIF_WORK_MASK          (0x0000FFFF & ~_TIF_SYSCALL_TRACE)
diff --git a/arch/hexagon/kernel/signal.c b/arch/hexagon/kernel/signal.c
index 304b0808..1ea16be 100644
--- a/arch/hexagon/kernel/signal.c
+++ b/arch/hexagon/kernel/signal.c
@@ -20,7 +20,6 @@
 
 #include <linux/linkage.h>
 #include <linux/syscalls.h>
-#include <linux/freezer.h>
 #include <linux/tracehook.h>
 #include <asm/registers.h>
 #include <asm/thread_info.h>
diff --git a/arch/hexagon/kernel/syscall.c b/arch/hexagon/kernel/syscall.c
index 620dd18..553cd60 100644
--- a/arch/hexagon/kernel/syscall.c
+++ b/arch/hexagon/kernel/syscall.c
@@ -87,4 +87,3 @@
 
 	return retval;
 }
-EXPORT_SYMBOL(kernel_execve);
diff --git a/arch/hexagon/mm/vm_fault.c b/arch/hexagon/mm/vm_fault.c
index 06695cc..513b74c 100644
--- a/arch/hexagon/mm/vm_fault.c
+++ b/arch/hexagon/mm/vm_fault.c
@@ -113,6 +113,7 @@
 				current->min_flt++;
 			if (fault & VM_FAULT_RETRY) {
 				flags &= ~FAULT_FLAG_ALLOW_RETRY;
+				flags |= FAULT_FLAG_TRIED;
 				goto retry;
 			}
 		}
diff --git a/arch/ia64/include/asm/Kbuild b/arch/ia64/include/asm/Kbuild
index d4eb938..562f593 100644
--- a/arch/ia64/include/asm/Kbuild
+++ b/arch/ia64/include/asm/Kbuild
@@ -13,3 +13,5 @@
 header-y += rse.h
 header-y += ucontext.h
 header-y += ustack.h
+generic-y += clkdev.h
+generic-y += exec.h
diff --git a/arch/ia64/include/asm/exec.h b/arch/ia64/include/asm/exec.h
deleted file mode 100644
index b262424..0000000
--- a/arch/ia64/include/asm/exec.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Process execution defines.
- *
- * Copyright (C) 1998-2003 Hewlett-Packard Co
- *	David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
- * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
- */
-#ifndef _ASM_IA64_EXEC_H
-#define _ASM_IA64_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _ASM_IA64_EXEC_H */
diff --git a/arch/ia64/include/asm/hugetlb.h b/arch/ia64/include/asm/hugetlb.h
index da55c63..94eaa5b 100644
--- a/arch/ia64/include/asm/hugetlb.h
+++ b/arch/ia64/include/asm/hugetlb.h
@@ -77,4 +77,8 @@
 {
 }
 
+static inline void arch_clear_hugepage_flags(struct page *page)
+{
+}
+
 #endif /* _ASM_IA64_HUGETLB_H */
diff --git a/arch/ia64/include/asm/thread_info.h b/arch/ia64/include/asm/thread_info.h
index f7ee853..ff2ae41 100644
--- a/arch/ia64/include/asm/thread_info.h
+++ b/arch/ia64/include/asm/thread_info.h
@@ -106,7 +106,6 @@
 #define TIF_SYSCALL_AUDIT	3	/* syscall auditing active */
 #define TIF_SINGLESTEP		4	/* restore singlestep on return to user mode */
 #define TIF_NOTIFY_RESUME	6	/* resumption notification requested */
-#define TIF_POLLING_NRFLAG	16	/* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE		17	/* is terminating due to OOM killer */
 #define TIF_MCA_INIT		18	/* this task is processing MCA or INIT */
 #define TIF_DB_DISABLED		19	/* debug trap disabled for fsyscall */
@@ -119,7 +118,6 @@
 #define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
-#define _TIF_POLLING_NRFLAG	(1 << TIF_POLLING_NRFLAG)
 #define _TIF_MCA_INIT		(1 << TIF_MCA_INIT)
 #define _TIF_DB_DISABLED	(1 << TIF_DB_DISABLED)
 #define _TIF_RESTORE_RSE	(1 << TIF_RESTORE_RSE)
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index f388b4e..ea39eba 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -2307,7 +2307,7 @@
 	 */
 	vma->vm_mm	     = mm;
 	vma->vm_file	     = get_file(filp);
-	vma->vm_flags	     = VM_READ| VM_MAYREAD |VM_RESERVED;
+	vma->vm_flags	     = VM_READ|VM_MAYREAD|VM_DONTEXPAND|VM_DONTDUMP;
 	vma->vm_page_prot    = PAGE_READONLY; /* XXX may need to change */
 
 	/*
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index 37dd795..680b737 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -438,14 +438,6 @@
 	long errno = scr->pt.r8;
 
 	/*
-	 * In the ia64_leave_kernel code path, we want the common case to go fast, which
-	 * is why we may in certain cases get here from kernel mode. Just return without
-	 * doing anything if so.
-	 */
-	if (!user_mode(&scr->pt))
-		return;
-
-	/*
 	 * This only loops in the rare cases of handle_signal() failing, in which case we
 	 * need to push through a forced SIGSEGV.
 	 */
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
index 8443daf..6cf0341 100644
--- a/arch/ia64/mm/fault.c
+++ b/arch/ia64/mm/fault.c
@@ -184,6 +184,7 @@
 			current->min_flt++;
 		if (fault & VM_FAULT_RETRY) {
 			flags &= ~FAULT_FLAG_ALLOW_RETRY;
+			flags |= FAULT_FLAG_TRIED;
 
 			 /* No need to up_read(&mm->mmap_sem) as we would
 			 * have already released it in __lock_page_or_retry
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 0eab454..acd5b68 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -138,7 +138,8 @@
 			vma->vm_mm = current->mm;
 			vma->vm_end = PAGE_SIZE;
 			vma->vm_page_prot = __pgprot(pgprot_val(PAGE_READONLY) | _PAGE_MA_NAT);
-			vma->vm_flags = VM_READ | VM_MAYREAD | VM_IO | VM_RESERVED;
+			vma->vm_flags = VM_READ | VM_MAYREAD | VM_IO |
+					VM_DONTEXPAND | VM_DONTDUMP;
 			down_write(&current->mm->mmap_sem);
 			if (insert_vm_struct(current->mm, vma)) {
 				up_write(&current->mm->mmap_sem);
@@ -636,6 +637,7 @@
 
 	high_memory = __va(max_low_pfn * PAGE_SIZE);
 
+	reset_zone_present_pages();
 	for_each_online_pgdat(pgdat)
 		if (pgdat->bdata->node_bootmem_map)
 			totalram_pages += free_all_bootmem_node(pgdat);
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig
index 49498bb..e875fc3 100644
--- a/arch/m32r/Kconfig
+++ b/arch/m32r/Kconfig
@@ -8,6 +8,7 @@
 	select HAVE_KERNEL_BZIP2
 	select HAVE_KERNEL_LZMA
 	select ARCH_WANT_IPC_PARSE_VERSION
+	select HAVE_DEBUG_BUGVERBOSE
 	select HAVE_GENERIC_HARDIRQS
 	select GENERIC_IRQ_PROBE
 	select GENERIC_IRQ_SHOW
diff --git a/arch/m32r/include/asm/Kbuild b/arch/m32r/include/asm/Kbuild
index c68e168..fccd81e 100644
--- a/arch/m32r/include/asm/Kbuild
+++ b/arch/m32r/include/asm/Kbuild
@@ -1 +1,4 @@
 include include/asm-generic/Kbuild.asm
+
+generic-y += clkdev.h
+generic-y += exec.h
diff --git a/arch/m32r/include/asm/exec.h b/arch/m32r/include/asm/exec.h
deleted file mode 100644
index c805dbd..0000000
--- a/arch/m32r/include/asm/exec.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * 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.
- *
- * Copyright (C) 2001  Hiroyuki Kondo, Hirokazu Takata, and Hitoshi Yamamoto
- * Copyright (C) 2004, 2006  Hirokazu Takata <takata at linux-m32r.org>
- */
-#ifndef _ASM_M32R_EXEC_H
-#define _ASM_M32R_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _ASM_M32R_EXEC_H */
diff --git a/arch/m32r/include/asm/thread_info.h b/arch/m32r/include/asm/thread_info.h
index c083f60..c074f4c 100644
--- a/arch/m32r/include/asm/thread_info.h
+++ b/arch/m32r/include/asm/thread_info.h
@@ -119,25 +119,20 @@
 #define TIF_SIGPENDING		1	/* signal pending */
 #define TIF_NEED_RESCHED	2	/* rescheduling necessary */
 #define TIF_SINGLESTEP		3	/* restore singlestep on return to user mode */
-#define TIF_IRET		4	/* return with iret */
 #define TIF_NOTIFY_RESUME	5	/* callback before returning to user */
 #define TIF_RESTORE_SIGMASK	8	/* restore signal mask in do_signal() */
 #define TIF_USEDFPU		16	/* FPU was used by this task this quantum (SMP) */
-#define TIF_POLLING_NRFLAG	17	/* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE		18	/* is terminating due to OOM killer */
 
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
 #define _TIF_SINGLESTEP		(1<<TIF_SINGLESTEP)
-#define _TIF_IRET		(1<<TIF_IRET)
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
-#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
 #define _TIF_USEDFPU		(1<<TIF_USEDFPU)
-#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 
-#define _TIF_WORK_MASK		0x0000FFFE	/* work to do on interrupt/exception return */
-#define _TIF_ALLWORK_MASK	0x0000FFFF	/* work to do on any return to u-space */
+#define _TIF_WORK_MASK		(_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME)
+#define _TIF_ALLWORK_MASK	(_TIF_WORK_MASK | _TIF_SYSCALL_TRACE)
 
 /*
  * Thread-synchronous status.
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c
index d0f60b9..6e3c26a 100644
--- a/arch/m32r/kernel/signal.c
+++ b/arch/m32r/kernel/signal.c
@@ -20,7 +20,6 @@
 #include <linux/unistd.h>
 #include <linux/stddef.h>
 #include <linux/personality.h>
-#include <linux/freezer.h>
 #include <linux/tracehook.h>
 #include <asm/cacheflush.h>
 #include <asm/ucontext.h>
@@ -366,6 +365,4 @@
 		clear_thread_flag(TIF_NOTIFY_RESUME);
 		tracehook_notify_resume(regs);
 	}
-
-	clear_thread_flag(TIF_IRET);
 }
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index b22df94..76fd6e2 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -3,9 +3,11 @@
 	default y
 	select HAVE_IDE
 	select HAVE_AOUT if MMU
+	select HAVE_DEBUG_BUGVERBOSE
 	select HAVE_GENERIC_HARDIRQS
 	select GENERIC_IRQ_SHOW
 	select GENERIC_ATOMIC64
+	select HAVE_UID16
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS
 	select GENERIC_CPU_DEVICES
 	select GENERIC_STRNCPY_FROM_USER if MMU
@@ -13,6 +15,7 @@
 	select FPU if MMU
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select ARCH_USES_GETTIMEOFFSET if MMU && !COLDFIRE
+	select GENERIC_KERNEL_THREAD
 
 config RWSEM_GENERIC_SPINLOCK
 	bool
diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild
index a74e5d9..ecb5408 100644
--- a/arch/m68k/include/asm/Kbuild
+++ b/arch/m68k/include/asm/Kbuild
@@ -2,10 +2,12 @@
 header-y += cachectl.h
 
 generic-y += bitsperlong.h
+generic-y += clkdev.h
 generic-y += cputime.h
 generic-y += device.h
 generic-y += emergency-restart.h
 generic-y += errno.h
+generic-y += exec.h
 generic-y += futex.h
 generic-y += ioctl.h
 generic-y += ipcbuf.h
diff --git a/arch/m68k/include/asm/exec.h b/arch/m68k/include/asm/exec.h
deleted file mode 100644
index 0499adf..0000000
--- a/arch/m68k/include/asm/exec.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _M68K_EXEC_H
-#define _M68K_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _M68K_EXEC_H */
diff --git a/arch/m68k/include/asm/processor.h b/arch/m68k/include/asm/processor.h
index f17c42a..ae700f4 100644
--- a/arch/m68k/include/asm/processor.h
+++ b/arch/m68k/include/asm/processor.h
@@ -100,6 +100,16 @@
 	.fs	= __KERNEL_DS,						\
 }
 
+/*
+ * ColdFire stack format sbould be 0x4 for an aligned usp (will always be
+ * true on thread creation). We need to set this explicitly.
+ */
+#ifdef CONFIG_COLDFIRE
+#define setframeformat(_regs)	do { (_regs)->format = 0x4; } while(0)
+#else
+#define setframeformat(_regs)	do { } while (0)
+#endif
+
 #ifdef CONFIG_MMU
 /*
  * Do necessary setup to start up a newly executed thread.
@@ -109,6 +119,7 @@
 {
 	regs->pc = pc;
 	regs->sr &= ~0x2000;
+	setframeformat(regs);
 	wrusp(usp);
 }
 
@@ -116,21 +127,11 @@
 
 #else
 
-/*
- * Coldfire stacks need to be re-aligned on trap exit, conventional
- * 68k can handle this case cleanly.
- */
-#ifdef CONFIG_COLDFIRE
-#define reformat(_regs)		do { (_regs)->format = 0x4; } while(0)
-#else
-#define reformat(_regs)		do { } while (0)
-#endif
-
 #define start_thread(_regs, _pc, _usp)                  \
 do {                                                    \
 	(_regs)->pc = (_pc);                            \
 	((struct switch_stack *)(_regs))[-1].a6 = 0;    \
-	reformat(_regs);                                \
+	setframeformat(_regs);                          \
 	if (current->mm)                                \
 		(_regs)->d5 = current->mm->start_data;  \
 	(_regs)->sr &= ~0x2000;                         \
@@ -153,8 +154,6 @@
 {
 }
 
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
 /*
  * Free current thread data structures etc..
  */
diff --git a/arch/m68k/include/asm/ptrace.h b/arch/m68k/include/asm/ptrace.h
index 65322b17..5e08b59 100644
--- a/arch/m68k/include/asm/ptrace.h
+++ b/arch/m68k/include/asm/ptrace.h
@@ -85,6 +85,8 @@
 #define user_mode(regs) (!((regs)->sr & PS_S))
 #define instruction_pointer(regs) ((regs)->pc)
 #define profile_pc(regs) instruction_pointer(regs)
+#define current_pt_regs() \
+	(struct pt_regs *)((char *)current_thread_info() + THREAD_SIZE) - 1
 
 #define arch_has_single_step()	(1)
 
diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h
index 045cfd6..c702ad7 100644
--- a/arch/m68k/include/asm/unistd.h
+++ b/arch/m68k/include/asm/unistd.h
@@ -382,6 +382,8 @@
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_SYS_EXECVE
+#define __ARCH_WANT_KERNEL_EXECVE
 
 /*
  * "Conditional" syscalls
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
index 165ee9f..946cb01 100644
--- a/arch/m68k/kernel/entry.S
+++ b/arch/m68k/kernel/entry.S
@@ -111,6 +111,22 @@
 	addql	#4,%sp
 	jra	ret_from_exception
 
+ENTRY(ret_from_kernel_thread)
+	| a3 contains the kernel thread payload, d7 - its argument
+	movel	%d1,%sp@-
+	jsr	schedule_tail
+	GET_CURRENT(%d0)
+	movel	%d7,(%sp)
+	jsr	%a3@
+	addql	#4,%sp
+	movel	%d0,(%sp)
+	jra	sys_exit
+
+ENTRY(ret_from_kernel_execve)
+	movel	4(%sp), %sp
+	GET_CURRENT(%d0)
+	jra	ret_from_exception
+
 #if defined(CONFIG_COLDFIRE) || !defined(CONFIG_MMU)
 
 #ifdef TRAP_DBG_INTERRUPT
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
index ac2892e..c51bb17 100644
--- a/arch/m68k/kernel/process.c
+++ b/arch/m68k/kernel/process.c
@@ -35,6 +35,7 @@
 
 
 asmlinkage void ret_from_fork(void);
+asmlinkage void ret_from_kernel_thread(void);
 
 
 /*
@@ -123,51 +124,6 @@
 		printk("USP: %08lx\n", rdusp());
 }
 
-/*
- * Create a kernel thread
- */
-int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-{
-	int pid;
-	mm_segment_t fs;
-
-	fs = get_fs();
-	set_fs (KERNEL_DS);
-
-	{
-	register long retval __asm__ ("d0");
-	register long clone_arg __asm__ ("d1") = flags | CLONE_VM | CLONE_UNTRACED;
-
-	retval = __NR_clone;
-	__asm__ __volatile__
-	  ("clrl %%d2\n\t"
-	   "trap #0\n\t"		/* Linux/m68k system call */
-	   "tstl %0\n\t"		/* child or parent */
-	   "jne 1f\n\t"			/* parent - jump */
-#ifdef CONFIG_MMU
-	   "lea %%sp@(%c7),%6\n\t"	/* reload current */
-	   "movel %6@,%6\n\t"
-#endif
-	   "movel %3,%%sp@-\n\t"	/* push argument */
-	   "jsr %4@\n\t"		/* call fn */
-	   "movel %0,%%d1\n\t"		/* pass exit value */
-	   "movel %2,%%d0\n\t"		/* exit */
-	   "trap #0\n"
-	   "1:"
-	   : "+d" (retval)
-	   : "i" (__NR_clone), "i" (__NR_exit),
-	     "r" (arg), "a" (fn), "d" (clone_arg), "r" (current),
-	     "i" (-THREAD_SIZE)
-	   : "d2");
-
-	pid = retval;
-	}
-
-	set_fs (fs);
-	return pid;
-}
-EXPORT_SYMBOL(kernel_thread);
-
 void flush_thread(void)
 {
 	current->thread.fs = __USER_DS;
@@ -219,30 +175,18 @@
 }
 
 int copy_thread(unsigned long clone_flags, unsigned long usp,
-		 unsigned long unused,
+		 unsigned long arg,
 		 struct task_struct * p, struct pt_regs * regs)
 {
 	struct pt_regs * childregs;
-	struct switch_stack * childstack, *stack;
-	unsigned long *retp;
+	struct switch_stack *childstack;
 
 	childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1;
-
-	*childregs = *regs;
-	childregs->d0 = 0;
-
-	retp = ((unsigned long *) regs);
-	stack = ((struct switch_stack *) retp) - 1;
-
 	childstack = ((struct switch_stack *) childregs) - 1;
-	*childstack = *stack;
-	childstack->retpc = (unsigned long)ret_from_fork;
 
 	p->thread.usp = usp;
 	p->thread.ksp = (unsigned long)childstack;
-
-	if (clone_flags & CLONE_SETTLS)
-		task_thread_info(p)->tp_value = regs->d5;
+	p->thread.esp0 = (unsigned long)childregs;
 
 	/*
 	 * Must save the current SFC/DFC value, NOT the value when
@@ -250,6 +194,26 @@
 	 */
 	p->thread.fs = get_fs().seg;
 
+	if (unlikely(!regs)) {
+		/* kernel thread */
+		memset(childstack, 0,
+			sizeof(struct switch_stack) + sizeof(struct pt_regs));
+		childregs->sr = PS_S;
+		childstack->a3 = usp; /* function */
+		childstack->d7 = arg;
+		childstack->retpc = (unsigned long)ret_from_kernel_thread;
+		p->thread.usp = 0;
+		return 0;
+	}
+	*childregs = *regs;
+	childregs->d0 = 0;
+
+	*childstack = ((struct switch_stack *) regs)[-1];
+	childstack->retpc = (unsigned long)ret_from_fork;
+
+	if (clone_flags & CLONE_SETTLS)
+		task_thread_info(p)->tp_value = regs->d5;
+
 #ifdef CONFIG_FPU
 	if (!FPU_IS_EMU) {
 		/* Copy the current fpu state */
@@ -337,26 +301,6 @@
 EXPORT_SYMBOL(dump_fpu);
 #endif /* CONFIG_FPU */
 
-/*
- * sys_execve() executes a new program.
- */
-asmlinkage int sys_execve(const char __user *name,
-			  const char __user *const __user *argv,
-			  const char __user *const __user *envp)
-{
-	int error;
-	char * filename;
-	struct pt_regs *regs = (struct pt_regs *) &name;
-
-	filename = getname(name);
-	error = PTR_ERR(filename);
-	if (IS_ERR(filename))
-		return error;
-	error = do_execve(filename, argv, envp, regs);
-	putname(filename);
-	return error;
-}
-
 unsigned long get_wchan(struct task_struct *p)
 {
 	unsigned long fp, pc;
diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c
index 9a5932e..3a480b3 100644
--- a/arch/m68k/kernel/sys_m68k.c
+++ b/arch/m68k/kernel/sys_m68k.c
@@ -549,23 +549,6 @@
 	return PAGE_SIZE;
 }
 
-/*
- * Do a system call from kernel instead of calling sys_execve so we
- * end up with proper pt_regs.
- */
-int kernel_execve(const char *filename,
-		  const char *const argv[],
-		  const char *const envp[])
-{
-	register long __res asm ("%d0") = __NR_execve;
-	register long __a asm ("%d1") = (long)(filename);
-	register long __b asm ("%d2") = (long)(argv);
-	register long __c asm ("%d3") = (long)(envp);
-	asm volatile ("trap  #0" : "+d" (__res)
-			: "d" (__a), "d" (__b), "d" (__c));
-	return __res;
-}
-
 asmlinkage unsigned long sys_get_thread_area(void)
 {
 	return current_thread_info()->tp_value;
diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c
index aeebbb7..a563727 100644
--- a/arch/m68k/mm/fault.c
+++ b/arch/m68k/mm/fault.c
@@ -170,6 +170,7 @@
 			/* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
 			 * of starvation. */
 			flags &= ~FAULT_FLAG_ALLOW_RETRY;
+			flags |= FAULT_FLAG_TRIED;
 
 			/*
 			 * No need to up_read(&mm->mmap_sem) as we would
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index 6133bed..53fd94a 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -16,6 +16,7 @@
 	select OF
 	select OF_EARLY_FLATTREE
 	select ARCH_WANT_IPC_PARSE_VERSION
+	select HAVE_DEBUG_KMEMLEAK
 	select IRQ_DOMAIN
 	select HAVE_GENERIC_HARDIRQS
 	select GENERIC_IRQ_PROBE
diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild
index db5294c..8653072 100644
--- a/arch/microblaze/include/asm/Kbuild
+++ b/arch/microblaze/include/asm/Kbuild
@@ -1,3 +1,5 @@
 include include/asm-generic/Kbuild.asm
 
 header-y  += elf.h
+generic-y += clkdev.h
+generic-y += exec.h
diff --git a/arch/microblaze/include/asm/atomic.h b/arch/microblaze/include/asm/atomic.h
index 472d8bf..42ac382 100644
--- a/arch/microblaze/include/asm/atomic.h
+++ b/arch/microblaze/include/asm/atomic.h
@@ -22,5 +22,6 @@
 
 	return res;
 }
+#define atomic_dec_if_positive atomic_dec_if_positive
 
 #endif /* _ASM_MICROBLAZE_ATOMIC_H */
diff --git a/arch/microblaze/include/asm/exec.h b/arch/microblaze/include/asm/exec.h
deleted file mode 100644
index e750de1..0000000
--- a/arch/microblaze/include/asm/exec.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * 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.
- */
-
-#ifndef _ASM_MICROBLAZE_EXEC_H
-#define _ASM_MICROBLAZE_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _ASM_MICROBLAZE_EXEC_H */
diff --git a/arch/microblaze/include/asm/thread_info.h b/arch/microblaze/include/asm/thread_info.h
index 6c610234..008f304 100644
--- a/arch/microblaze/include/asm/thread_info.h
+++ b/arch/microblaze/include/asm/thread_info.h
@@ -121,7 +121,6 @@
 #define TIF_NEED_RESCHED	3 /* rescheduling necessary */
 /* restore singlestep on return to user mode */
 #define TIF_SINGLESTEP		4
-#define TIF_IRET		5 /* return with iret */
 #define TIF_MEMDIE		6	/* is terminating due to OOM killer */
 #define TIF_SYSCALL_AUDIT	9       /* syscall auditing active */
 #define TIF_SECCOMP		10      /* secure computing */
@@ -134,7 +133,6 @@
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
 #define _TIF_SINGLESTEP		(1 << TIF_SINGLESTEP)
-#define _TIF_IRET		(1 << TIF_IRET)
 #define _TIF_POLLING_NRFLAG	(1 << TIF_POLLING_NRFLAG)
 #define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP		(1 << TIF_SECCOMP)
@@ -184,6 +182,7 @@
 	ti->status &= ~TS_RESTORE_SIGMASK;
 	return true;
 }
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
 #endif
 
 #endif /* __KERNEL__ */
diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c
index c1220db..3847e5b 100644
--- a/arch/microblaze/kernel/signal.c
+++ b/arch/microblaze/kernel/signal.c
@@ -254,10 +254,6 @@
 
 	set_fs(USER_DS);
 
-	/* the tracer may want to single-step inside the handler */
-	if (test_thread_flag(TIF_SINGLESTEP))
-		ptrace_notify(SIGTRAP);
-
 #ifdef DEBUG_SIG
 	printk(KERN_INFO "SIG deliver (%s:%d): sp=%p pc=%08lx\n",
 		current->comm, current->pid, frame, regs->pc);
@@ -315,7 +311,8 @@
 	if (ret)
 		return;
 
-	signal_delivered(sig, info, ka, regs, 0);
+	signal_delivered(sig, info, ka, regs,
+			test_thread_flag(TIF_SINGLESTEP));
 }
 
 /*
diff --git a/arch/microblaze/mm/fault.c b/arch/microblaze/mm/fault.c
index eb365d6..714b35a 100644
--- a/arch/microblaze/mm/fault.c
+++ b/arch/microblaze/mm/fault.c
@@ -233,6 +233,7 @@
 			current->min_flt++;
 		if (fault & VM_FAULT_RETRY) {
 			flags &= ~FAULT_FLAG_ALLOW_RETRY;
+			flags |= FAULT_FLAG_TRIED;
 
 			/*
 			 * No need to up_read(&mm->mmap_sem) as we would
diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms
index d64786d..91b9d69 100644
--- a/arch/mips/Kbuild.platforms
+++ b/arch/mips/Kbuild.platforms
@@ -15,8 +15,8 @@
 platforms += lasat
 platforms += loongson
 platforms += loongson1
-platforms += mipssim
 platforms += mti-malta
+platforms += mti-sead3
 platforms += netlogic
 platforms += pmc-sierra
 platforms += pnx833x
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index faf6528..35453ea 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -17,6 +17,7 @@
 	select HAVE_FUNCTION_GRAPH_TRACER
 	select HAVE_KPROBES
 	select HAVE_KRETPROBES
+	select HAVE_DEBUG_KMEMLEAK
 	select ARCH_BINFMT_ELF_RANDOMIZE_PIE
 	select RTC_LIB if !MACH_LOONGSON
 	select GENERIC_ATOMIC64 if !64BIT
@@ -242,6 +243,8 @@
 	select HAVE_MACH_CLKDEV
 	select CLKDEV_LOOKUP
 	select USE_OF
+	select PINCTRL
+	select PINCTRL_LANTIQ
 
 config LASAT
 	bool "LASAT Networks platforms"
@@ -320,24 +323,35 @@
 	  This enables support for the MIPS Technologies Malta evaluation
 	  board.
 
-config MIPS_SIM
-	bool 'MIPS simulator (MIPSsim)'
+config MIPS_SEAD3
+	bool "MIPS SEAD3 board"
+	select BOOT_ELF32
+	select BOOT_RAW
 	select CEVT_R4K
 	select CSRC_R4K
+	select CPU_MIPSR2_IRQ_VI
+	select CPU_MIPSR2_IRQ_EI
 	select DMA_NONCOHERENT
-	select SYS_HAS_EARLY_PRINTK
 	select IRQ_CPU
-	select BOOT_RAW
+	select IRQ_GIC
+	select MIPS_BOARDS_GEN
+	select MIPS_CPU_SCACHE
+	select MIPS_MSC
 	select SYS_HAS_CPU_MIPS32_R1
 	select SYS_HAS_CPU_MIPS32_R2
+	select SYS_HAS_CPU_MIPS64_R1
 	select SYS_HAS_EARLY_PRINTK
 	select SYS_SUPPORTS_32BIT_KERNEL
+	select SYS_SUPPORTS_64BIT_KERNEL
 	select SYS_SUPPORTS_BIG_ENDIAN
-	select SYS_SUPPORTS_MULTITHREADING
 	select SYS_SUPPORTS_LITTLE_ENDIAN
+	select SYS_SUPPORTS_SMARTMIPS
+	select USB_ARCH_HAS_EHCI
+	select USB_EHCI_BIG_ENDIAN_DESC
+	select USB_EHCI_BIG_ENDIAN_MMIO
 	help
-	  This option enables support for MIPS Technologies MIPSsim software
-	  emulator.
+	  This enables support for the MIPS Technologies SEAD3 evaluation
+	  board.
 
 config NEC_MARKEINS
 	bool "NEC EMMA2RH Mark-eins board"
@@ -831,6 +845,7 @@
 	select ZONE_DMA if 64BIT
 	select SYNC_R4K
 	select SYS_HAS_EARLY_PRINTK
+	select USE_OF
 	help
 	  This board is based on Netlogic XLP Processor.
 	  Say Y here if you have a XLP based board.
@@ -1749,7 +1764,6 @@
 menu "Kernel type"
 
 choice
-
 	prompt "Kernel code model"
 	help
 	  You should only select this option if you have a workload that
@@ -1880,6 +1894,18 @@
 config CPU_HAS_PREFETCH
 	bool
 
+config CPU_GENERIC_DUMP_TLB
+	bool
+	default y if !(CPU_R3000 || CPU_R6000 || CPU_R8000 || CPU_TX39XX)
+
+config CPU_R4K_FPU
+	bool
+	default y if !(CPU_R3000 || CPU_R6000 || CPU_TX39XX || CPU_CAVIUM_OCTEON)
+
+config CPU_R4K_CACHE_TLB
+	bool
+	default y if !(CPU_R3000 || CPU_R8000 || CPU_SB1 || CPU_TX39XX || CPU_CAVIUM_OCTEON)
+
 choice
 	prompt "MIPS MT options"
 
@@ -1955,7 +1981,6 @@
 config SYS_SUPPORTS_SCHED_SMT
 	bool
 
-
 config SYS_SUPPORTS_MULTITHREADING
 	bool
 
@@ -2360,12 +2385,10 @@
 	  If unsure, say Y. Only embedded should say N here.
 
 config USE_OF
-	bool "Flattened Device Tree support"
+	bool
 	select OF
 	select OF_EARLY_FLATTREE
 	select IRQ_DOMAIN
-	help
-	  Include support for flattened device tree machine descriptions.
 
 endmenu
 
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 764e37a..654b1ad 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -225,7 +225,7 @@
 LDFLAGS			+= -m $(ld-emul)
 
 ifdef CONFIG_MIPS
-CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -xc /dev/null | \
+CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \
 	egrep -vw '__GNUC_(|MINOR_|PATCHLEVEL_)_' | \
 	sed -e "s/^\#define /-D'/" -e "s/ /'='/" -e "s/$$/'/")
 ifdef CONFIG_64BIT
diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c
index b91ad3e..579f452 100644
--- a/arch/mips/ath79/clock.c
+++ b/arch/mips/ath79/clock.c
@@ -17,6 +17,8 @@
 #include <linux/err.h>
 #include <linux/clk.h>
 
+#include <asm/div64.h>
+
 #include <asm/mach-ath79/ath79.h>
 #include <asm/mach-ath79/ar71xx_regs.h>
 #include "common.h"
@@ -166,11 +168,34 @@
 	ath79_uart_clk.rate = ath79_ref_clk.rate;
 }
 
+static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac,
+				      u32 frac, u32 out_div)
+{
+	u64 t;
+	u32 ret;
+
+	t = ath79_ref_clk.rate;
+	t *= nint;
+	do_div(t, ref_div);
+	ret = t;
+
+	t = ath79_ref_clk.rate;
+	t *= nfrac;
+	do_div(t, ref_div * frac);
+	ret += t;
+
+	ret /= (1 << out_div);
+	return ret;
+}
+
 static void __init ar934x_clocks_init(void)
 {
-	u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv;
+	u32 pll, out_div, ref_div, nint, nfrac, frac, clk_ctrl, postdiv;
 	u32 cpu_pll, ddr_pll;
 	u32 bootstrap;
+	void __iomem *dpll_base;
+
+	dpll_base = ioremap(AR934X_SRIF_BASE, AR934X_SRIF_SIZE);
 
 	bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
 	if (bootstrap &	AR934X_BOOTSTRAP_REF_CLK_40)
@@ -178,33 +203,59 @@
 	else
 		ath79_ref_clk.rate = 25 * 1000 * 1000;
 
-	pll = ath79_pll_rr(AR934X_PLL_CPU_CONFIG_REG);
-	out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
-		  AR934X_PLL_CPU_CONFIG_OUTDIV_MASK;
-	ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
-		  AR934X_PLL_CPU_CONFIG_REFDIV_MASK;
-	nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) &
-	       AR934X_PLL_CPU_CONFIG_NINT_MASK;
-	frac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) &
-	       AR934X_PLL_CPU_CONFIG_NFRAC_MASK;
+	pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL2_REG);
+	if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) {
+		out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) &
+			  AR934X_SRIF_DPLL2_OUTDIV_MASK;
+		pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL1_REG);
+		nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) &
+		       AR934X_SRIF_DPLL1_NINT_MASK;
+		nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK;
+		ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) &
+			  AR934X_SRIF_DPLL1_REFDIV_MASK;
+		frac = 1 << 18;
+	} else {
+		pll = ath79_pll_rr(AR934X_PLL_CPU_CONFIG_REG);
+		out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
+			AR934X_PLL_CPU_CONFIG_OUTDIV_MASK;
+		ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
+			  AR934X_PLL_CPU_CONFIG_REFDIV_MASK;
+		nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) &
+		       AR934X_PLL_CPU_CONFIG_NINT_MASK;
+		nfrac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) &
+			AR934X_PLL_CPU_CONFIG_NFRAC_MASK;
+		frac = 1 << 6;
+	}
 
-	cpu_pll = nint * ath79_ref_clk.rate / ref_div;
-	cpu_pll += frac * ath79_ref_clk.rate / (ref_div * (2 << 6));
-	cpu_pll /= (1 << out_div);
+	cpu_pll = ar934x_get_pll_freq(ath79_ref_clk.rate, ref_div, nint,
+				      nfrac, frac, out_div);
 
-	pll = ath79_pll_rr(AR934X_PLL_DDR_CONFIG_REG);
-	out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
-		  AR934X_PLL_DDR_CONFIG_OUTDIV_MASK;
-	ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
-		  AR934X_PLL_DDR_CONFIG_REFDIV_MASK;
-	nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) &
-	       AR934X_PLL_DDR_CONFIG_NINT_MASK;
-	frac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) &
-	       AR934X_PLL_DDR_CONFIG_NFRAC_MASK;
+	pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL2_REG);
+	if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) {
+		out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) &
+			  AR934X_SRIF_DPLL2_OUTDIV_MASK;
+		pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL1_REG);
+		nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) &
+		       AR934X_SRIF_DPLL1_NINT_MASK;
+		nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK;
+		ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) &
+			  AR934X_SRIF_DPLL1_REFDIV_MASK;
+		frac = 1 << 18;
+	} else {
+		pll = ath79_pll_rr(AR934X_PLL_DDR_CONFIG_REG);
+		out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
+			  AR934X_PLL_DDR_CONFIG_OUTDIV_MASK;
+		ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
+			   AR934X_PLL_DDR_CONFIG_REFDIV_MASK;
+		nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) &
+		       AR934X_PLL_DDR_CONFIG_NINT_MASK;
+		nfrac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) &
+			AR934X_PLL_DDR_CONFIG_NFRAC_MASK;
+		frac = 1 << 10;
+	}
 
-	ddr_pll = nint * ath79_ref_clk.rate / ref_div;
-	ddr_pll += frac * ath79_ref_clk.rate / (ref_div * (2 << 10));
-	ddr_pll /= (1 << out_div);
+	ddr_pll = ar934x_get_pll_freq(ath79_ref_clk.rate, ref_div, nint,
+				      nfrac, frac, out_div);
 
 	clk_ctrl = ath79_pll_rr(AR934X_PLL_CPU_DDR_CLK_CTRL_REG);
 
@@ -240,6 +291,8 @@
 
 	ath79_wdt_clk.rate = ath79_ref_clk.rate;
 	ath79_uart_clk.rate = ath79_ref_clk.rate;
+
+	iounmap(dpll_base);
 }
 
 void __init ath79_clocks_init(void)
diff --git a/arch/mips/ath79/dev-usb.c b/arch/mips/ath79/dev-usb.c
index b2a2311..072bb9b 100644
--- a/arch/mips/ath79/dev-usb.c
+++ b/arch/mips/ath79/dev-usb.c
@@ -25,17 +25,7 @@
 #include "common.h"
 #include "dev-usb.h"
 
-static struct resource ath79_ohci_resources[] = {
-	[0] = {
-		/* .start and .end fields are filled dynamically */
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= ATH79_MISC_IRQ_OHCI,
-		.end	= ATH79_MISC_IRQ_OHCI,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
+static struct resource ath79_ohci_resources[2];
 
 static u64 ath79_ohci_dmamask = DMA_BIT_MASK(32);
 
@@ -54,17 +44,7 @@
 	},
 };
 
-static struct resource ath79_ehci_resources[] = {
-	[0] = {
-		/* .start and .end fields are filled dynamically */
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= ATH79_CPU_IRQ_USB,
-		.end	= ATH79_CPU_IRQ_USB,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
+static struct resource ath79_ehci_resources[2];
 
 static u64 ath79_ehci_dmamask = DMA_BIT_MASK(32);
 
@@ -90,6 +70,20 @@
 	},
 };
 
+static void __init ath79_usb_init_resource(struct resource res[2],
+					   unsigned long base,
+					   unsigned long size,
+					   int irq)
+{
+	res[0].flags = IORESOURCE_MEM;
+	res[0].start = base;
+	res[0].end = base + size - 1;
+
+	res[1].flags = IORESOURCE_IRQ;
+	res[1].start = irq;
+	res[1].end = irq;
+}
+
 #define AR71XX_USB_RESET_MASK	(AR71XX_RESET_USB_HOST | \
 				 AR71XX_RESET_USB_PHY | \
 				 AR71XX_RESET_USB_OHCI_DLL)
@@ -114,12 +108,12 @@
 
 	mdelay(900);
 
-	ath79_ohci_resources[0].start = AR71XX_OHCI_BASE;
-	ath79_ohci_resources[0].end = AR71XX_OHCI_BASE + AR71XX_OHCI_SIZE - 1;
+	ath79_usb_init_resource(ath79_ohci_resources, AR71XX_OHCI_BASE,
+				AR71XX_OHCI_SIZE, ATH79_MISC_IRQ_OHCI);
 	platform_device_register(&ath79_ohci_device);
 
-	ath79_ehci_resources[0].start = AR71XX_EHCI_BASE;
-	ath79_ehci_resources[0].end = AR71XX_EHCI_BASE + AR71XX_EHCI_SIZE - 1;
+	ath79_usb_init_resource(ath79_ehci_resources, AR71XX_EHCI_BASE,
+				AR71XX_EHCI_SIZE, ATH79_CPU_IRQ_USB);
 	ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v1;
 	platform_device_register(&ath79_ehci_device);
 }
@@ -143,10 +137,8 @@
 
 	iounmap(usb_ctrl_base);
 
-	ath79_ohci_resources[0].start = AR7240_OHCI_BASE;
-	ath79_ohci_resources[0].end = AR7240_OHCI_BASE + AR7240_OHCI_SIZE - 1;
-	ath79_ohci_resources[1].start = ATH79_CPU_IRQ_USB;
-	ath79_ohci_resources[1].end = ATH79_CPU_IRQ_USB;
+	ath79_usb_init_resource(ath79_ohci_resources, AR7240_OHCI_BASE,
+				AR7240_OHCI_SIZE, ATH79_CPU_IRQ_USB);
 	platform_device_register(&ath79_ohci_device);
 }
 
@@ -161,8 +153,8 @@
 	ath79_device_reset_clear(AR724X_RESET_USB_PHY);
 	mdelay(10);
 
-	ath79_ehci_resources[0].start = AR724X_EHCI_BASE;
-	ath79_ehci_resources[0].end = AR724X_EHCI_BASE + AR724X_EHCI_SIZE - 1;
+	ath79_usb_init_resource(ath79_ehci_resources, AR724X_EHCI_BASE,
+				AR724X_EHCI_SIZE, ATH79_CPU_IRQ_USB);
 	ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2;
 	platform_device_register(&ath79_ehci_device);
 }
@@ -178,8 +170,8 @@
 	ath79_device_reset_clear(AR913X_RESET_USB_PHY);
 	mdelay(10);
 
-	ath79_ehci_resources[0].start = AR913X_EHCI_BASE;
-	ath79_ehci_resources[0].end = AR913X_EHCI_BASE + AR913X_EHCI_SIZE - 1;
+	ath79_usb_init_resource(ath79_ehci_resources, AR913X_EHCI_BASE,
+				AR913X_EHCI_SIZE, ATH79_CPU_IRQ_USB);
 	ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2;
 	platform_device_register(&ath79_ehci_device);
 }
@@ -195,8 +187,34 @@
 	ath79_device_reset_clear(AR933X_RESET_USB_PHY);
 	mdelay(10);
 
-	ath79_ehci_resources[0].start = AR933X_EHCI_BASE;
-	ath79_ehci_resources[0].end = AR933X_EHCI_BASE + AR933X_EHCI_SIZE - 1;
+	ath79_usb_init_resource(ath79_ehci_resources, AR933X_EHCI_BASE,
+				AR933X_EHCI_SIZE, ATH79_CPU_IRQ_USB);
+	ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2;
+	platform_device_register(&ath79_ehci_device);
+}
+
+static void __init ar934x_usb_setup(void)
+{
+	u32 bootstrap;
+
+	bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
+	if (bootstrap & AR934X_BOOTSTRAP_USB_MODE_DEVICE)
+		return;
+
+	ath79_device_reset_set(AR934X_RESET_USBSUS_OVERRIDE);
+	udelay(1000);
+
+	ath79_device_reset_clear(AR934X_RESET_USB_PHY);
+	udelay(1000);
+
+	ath79_device_reset_clear(AR934X_RESET_USB_PHY_ANALOG);
+	udelay(1000);
+
+	ath79_device_reset_clear(AR934X_RESET_USB_HOST);
+	udelay(1000);
+
+	ath79_usb_init_resource(ath79_ehci_resources, AR934X_EHCI_BASE,
+				AR934X_EHCI_SIZE, ATH79_CPU_IRQ_USB);
 	ath79_ehci_device.dev.platform_data = &ath79_ehci_pdata_v2;
 	platform_device_register(&ath79_ehci_device);
 }
@@ -213,6 +231,8 @@
 		ar913x_usb_setup();
 	else if (soc_is_ar933x())
 		ar933x_usb_setup();
+	else if (soc_is_ar934x())
+		ar934x_usb_setup();
 	else
 		BUG();
 }
diff --git a/arch/mips/ath79/mach-db120.c b/arch/mips/ath79/mach-db120.c
index 1983e4d..42f540a 100644
--- a/arch/mips/ath79/mach-db120.c
+++ b/arch/mips/ath79/mach-db120.c
@@ -25,6 +25,7 @@
 #include "dev-gpio-buttons.h"
 #include "dev-leds-gpio.h"
 #include "dev-spi.h"
+#include "dev-usb.h"
 #include "dev-wmac.h"
 #include "pci.h"
 
@@ -126,6 +127,7 @@
 					db120_gpio_keys);
 	ath79_register_spi(&db120_spi_data, db120_spi_info,
 			   ARRAY_SIZE(db120_spi_info));
+	ath79_register_usb();
 	ath79_register_wmac(art + DB120_WMAC_CALDATA_OFFSET);
 	db120_pci_init(art + DB120_PCIE_CALDATA_OFFSET);
 }
diff --git a/arch/mips/bcm63xx/Makefile b/arch/mips/bcm63xx/Makefile
index 833af72..9bbb30a 100644
--- a/arch/mips/bcm63xx/Makefile
+++ b/arch/mips/bcm63xx/Makefile
@@ -1,6 +1,6 @@
 obj-y		+= clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \
 		   dev-dsp.o dev-enet.o dev-flash.o dev-pcmcia.o dev-rng.o \
-		   dev-spi.o dev-uart.o dev-wdt.o
+		   dev-spi.o dev-uart.o dev-wdt.o dev-usb-usbd.o
 obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
 
 obj-y		+= boards/
diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c
index dd18e4b..1cd4d73 100644
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -24,6 +24,7 @@
 #include <bcm63xx_dev_flash.h>
 #include <bcm63xx_dev_pcmcia.h>
 #include <bcm63xx_dev_spi.h>
+#include <bcm63xx_dev_usb_usbd.h>
 #include <board_bcm963xx.h>
 
 #define PFX	"board_bcm963xx: "
@@ -42,6 +43,12 @@
 
 	.has_uart0			= 1,
 	.has_pci			= 1,
+	.has_usbd			= 0,
+
+	.usbd = {
+		.use_fullspeed		= 0,
+		.port_no		= 0,
+	},
 
 	.leds = {
 		{
@@ -713,7 +720,7 @@
  */
 static int board_get_mac_address(u8 *mac)
 {
-	u8 *p;
+	u8 *oui;
 	int count;
 
 	if (mac_addr_used >= nvram.mac_addr_count) {
@@ -722,21 +729,23 @@
 	}
 
 	memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
-	p = mac + ETH_ALEN - 1;
+	oui = mac + ETH_ALEN/2 - 1;
 	count = mac_addr_used;
 
 	while (count--) {
+		u8 *p = mac + ETH_ALEN - 1;
+
 		do {
 			(*p)++;
 			if (*p != 0)
 				break;
 			p--;
-		} while (p != mac);
-	}
+		} while (p != oui);
 
-	if (p == mac) {
-		printk(KERN_ERR PFX "unable to fetch mac address\n");
-		return -ENODEV;
+		if (p == oui) {
+			printk(KERN_ERR PFX "unable to fetch mac address\n");
+			return -ENODEV;
+		}
 	}
 
 	mac_addr_used++;
@@ -888,6 +897,9 @@
 	    !board_get_mac_address(board.enet1.mac_addr))
 		bcm63xx_enet_register(1, &board.enet1);
 
+	if (board.has_usbd)
+		bcm63xx_usbd_register(&board.usbd);
+
 	if (board.has_dsp)
 		bcm63xx_dsp_register(&board.dsp);
 
diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c
index 1db48ad..dff79ab 100644
--- a/arch/mips/bcm63xx/clk.c
+++ b/arch/mips/bcm63xx/clk.c
@@ -160,7 +160,9 @@
  */
 static void usbh_set(struct clk *clk, int enable)
 {
-	if (BCMCPU_IS_6348())
+	if (BCMCPU_IS_6328())
+		bcm_hwclock_set(CKCTL_6328_USBH_EN, enable);
+	else if (BCMCPU_IS_6348())
 		bcm_hwclock_set(CKCTL_6348_USBH_EN, enable);
 	else if (BCMCPU_IS_6368())
 		bcm_hwclock_set(CKCTL_6368_USBH_EN, enable);
@@ -171,6 +173,21 @@
 };
 
 /*
+ * USB device clock
+ */
+static void usbd_set(struct clk *clk, int enable)
+{
+	if (BCMCPU_IS_6328())
+		bcm_hwclock_set(CKCTL_6328_USBD_EN, enable);
+	else if (BCMCPU_IS_6368())
+		bcm_hwclock_set(CKCTL_6368_USBD_EN, enable);
+}
+
+static struct clk clk_usbd = {
+	.set	= usbd_set,
+};
+
+/*
  * SPI clock
  */
 static void spi_set(struct clk *clk, int enable)
@@ -284,6 +301,8 @@
 		return &clk_ephy;
 	if (!strcmp(id, "usbh"))
 		return &clk_usbh;
+	if (!strcmp(id, "usbd"))
+		return &clk_usbd;
 	if (!strcmp(id, "spi"))
 		return &clk_spi;
 	if (!strcmp(id, "xtm"))
diff --git a/arch/mips/bcm63xx/dev-usb-usbd.c b/arch/mips/bcm63xx/dev-usb-usbd.c
new file mode 100644
index 0000000..508bd9d
--- /dev/null
+++ b/arch/mips/bcm63xx/dev-usb-usbd.c
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ * Copyright (C) 2012 Kevin Cernekee <cernekee@gmail.com>
+ * Copyright (C) 2012 Broadcom Corporation
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_dev_usb_usbd.h>
+
+#define NUM_MMIO		2
+#define NUM_IRQ			7
+
+static struct resource usbd_resources[NUM_MMIO + NUM_IRQ];
+
+static u64 usbd_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device bcm63xx_usbd_device = {
+	.name		= "bcm63xx_udc",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(usbd_resources),
+	.resource	= usbd_resources,
+	.dev		= {
+		.dma_mask		= &usbd_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+};
+
+int __init bcm63xx_usbd_register(const struct bcm63xx_usbd_platform_data *pd)
+{
+	const int irq_list[NUM_IRQ] = { IRQ_USBD,
+		IRQ_USBD_RXDMA0, IRQ_USBD_TXDMA0,
+		IRQ_USBD_RXDMA1, IRQ_USBD_TXDMA1,
+		IRQ_USBD_RXDMA2, IRQ_USBD_TXDMA2 };
+	int i;
+
+	if (!BCMCPU_IS_6328() && !BCMCPU_IS_6368())
+		return 0;
+
+	usbd_resources[0].start = bcm63xx_regset_address(RSET_USBD);
+	usbd_resources[0].end = usbd_resources[0].start + RSET_USBD_SIZE - 1;
+	usbd_resources[0].flags = IORESOURCE_MEM;
+
+	usbd_resources[1].start = bcm63xx_regset_address(RSET_USBDMA);
+	usbd_resources[1].end = usbd_resources[1].start + RSET_USBDMA_SIZE - 1;
+	usbd_resources[1].flags = IORESOURCE_MEM;
+
+	for (i = 0; i < NUM_IRQ; i++) {
+		struct resource *r = &usbd_resources[NUM_MMIO + i];
+
+		r->start = r->end = bcm63xx_get_irq_number(irq_list[i]);
+		r->flags = IORESOURCE_IRQ;
+	}
+
+	platform_device_add_data(&bcm63xx_usbd_device, pd, sizeof(*pd));
+
+	return platform_device_register(&bcm63xx_usbd_device);
+}
diff --git a/arch/mips/bcm63xx/irq.c b/arch/mips/bcm63xx/irq.c
index 18e051a..da24c2b 100644
--- a/arch/mips/bcm63xx/irq.c
+++ b/arch/mips/bcm63xx/irq.c
@@ -56,8 +56,8 @@
 #define is_ext_irq_cascaded	0
 #define ext_irq_start		0
 #define ext_irq_end		0
-#define ext_irq_count		0
-#define ext_irq_cfg_reg1	0
+#define ext_irq_count		4
+#define ext_irq_cfg_reg1	PERF_EXTIRQ_CFG_REG_6345
 #define ext_irq_cfg_reg2	0
 #endif
 #ifdef CONFIG_BCM63XX_CPU_6348
@@ -143,11 +143,15 @@
 		irq_stat_addr += PERF_IRQSTAT_6338_REG;
 		irq_mask_addr += PERF_IRQMASK_6338_REG;
 		irq_bits = 32;
+		ext_irq_count = 4;
+		ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6338;
 		break;
 	case BCM6345_CPU_ID:
 		irq_stat_addr += PERF_IRQSTAT_6345_REG;
 		irq_mask_addr += PERF_IRQMASK_6345_REG;
 		irq_bits = 32;
+		ext_irq_count = 4;
+		ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6345;
 		break;
 	case BCM6348_CPU_ID:
 		irq_stat_addr += PERF_IRQSTAT_6348_REG;
@@ -434,7 +438,8 @@
 	reg = bcm_perf_readl(regaddr);
 	irq %= 4;
 
-	if (BCMCPU_IS_6348()) {
+	switch (bcm63xx_get_cpu_id()) {
+	case BCM6348_CPU_ID:
 		if (levelsense)
 			reg |= EXTIRQ_CFG_LEVELSENSE_6348(irq);
 		else
@@ -447,9 +452,13 @@
 			reg |= EXTIRQ_CFG_BOTHEDGE_6348(irq);
 		else
 			reg &= ~EXTIRQ_CFG_BOTHEDGE_6348(irq);
-	}
+		break;
 
-	if (BCMCPU_IS_6338() || BCMCPU_IS_6358() || BCMCPU_IS_6368()) {
+	case BCM6328_CPU_ID:
+	case BCM6338_CPU_ID:
+	case BCM6345_CPU_ID:
+	case BCM6358_CPU_ID:
+	case BCM6368_CPU_ID:
 		if (levelsense)
 			reg |= EXTIRQ_CFG_LEVELSENSE(irq);
 		else
@@ -462,6 +471,9 @@
 			reg |= EXTIRQ_CFG_BOTHEDGE(irq);
 		else
 			reg &= ~EXTIRQ_CFG_BOTHEDGE(irq);
+		break;
+	default:
+		BUG();
 	}
 
 	bcm_perf_writel(reg, regaddr);
diff --git a/arch/mips/bcm63xx/setup.c b/arch/mips/bcm63xx/setup.c
index 0e74a13..314231b 100644
--- a/arch/mips/bcm63xx/setup.c
+++ b/arch/mips/bcm63xx/setup.c
@@ -74,6 +74,9 @@
 	case BCM6338_CPU_ID:
 		perf_regs[0] = PERF_EXTIRQ_CFG_REG_6338;
 		break;
+	case BCM6345_CPU_ID:
+		perf_regs[0] = PERF_EXTIRQ_CFG_REG_6345;
+		break;
 	case BCM6348_CPU_ID:
 		perf_regs[0] = PERF_EXTIRQ_CFG_REG_6348;
 		break;
@@ -83,6 +86,9 @@
 	}
 
 	for (i = 0; i < 2; i++) {
+		if (!perf_regs[i])
+			break;
+
 		reg = bcm_perf_readl(perf_regs[i]);
 		if (BCMCPU_IS_6348()) {
 			reg &= ~EXTIRQ_CFG_MASK_ALL_6348;
diff --git a/arch/mips/cavium-octeon/csrc-octeon.c b/arch/mips/cavium-octeon/csrc-octeon.c
index ce6483a..0219395 100644
--- a/arch/mips/cavium-octeon/csrc-octeon.c
+++ b/arch/mips/cavium-octeon/csrc-octeon.c
@@ -4,7 +4,7 @@
  * for more details.
  *
  * Copyright (C) 2007 by Ralf Baechle
- * Copyright (C) 2009, 2010 Cavium Networks, Inc.
+ * Copyright (C) 2009, 2012 Cavium, Inc.
  */
 #include <linux/clocksource.h>
 #include <linux/export.h>
@@ -18,6 +18,33 @@
 #include <asm/octeon/cvmx-ipd-defs.h>
 #include <asm/octeon/cvmx-mio-defs.h>
 
+
+static u64 f;
+static u64 rdiv;
+static u64 sdiv;
+static u64 octeon_udelay_factor;
+static u64 octeon_ndelay_factor;
+
+void __init octeon_setup_delays(void)
+{
+	octeon_udelay_factor = octeon_get_clock_rate() / 1000000;
+	/*
+	 * For __ndelay we divide by 2^16, so the factor is multiplied
+	 * by the same amount.
+	 */
+	octeon_ndelay_factor = (octeon_udelay_factor * 0x10000ull) / 1000ull;
+
+	preset_lpj = octeon_get_clock_rate() / HZ;
+
+	if (current_cpu_type() == CPU_CAVIUM_OCTEON2) {
+		union cvmx_mio_rst_boot rst_boot;
+		rst_boot.u64 = cvmx_read_csr(CVMX_MIO_RST_BOOT);
+		rdiv = rst_boot.s.c_mul;	/* CPU clock */
+		sdiv = rst_boot.s.pnr_mul;	/* I/O clock */
+		f = (0x8000000000000000ull / sdiv) * 2;
+	}
+}
+
 /*
  * Set the current core's cvmcount counter to the value of the
  * IPD_CLK_COUNT.  We do this on all cores as they are brought
@@ -30,17 +57,6 @@
 {
 	unsigned long flags;
 	unsigned loops = 2;
-	u64 f = 0;
-	u64 rdiv = 0;
-	u64 sdiv = 0;
-	if (current_cpu_type() == CPU_CAVIUM_OCTEON2) {
-		union cvmx_mio_rst_boot rst_boot;
-		rst_boot.u64 = cvmx_read_csr(CVMX_MIO_RST_BOOT);
-		rdiv = rst_boot.s.c_mul;	/* CPU clock */
-		sdiv = rst_boot.s.pnr_mul;	/* I/O clock */
-		f = (0x8000000000000000ull / sdiv) * 2;
-	}
-
 
 	/* Clobber loops so GCC will not unroll the following while loop. */
 	asm("" : "+r" (loops));
@@ -57,9 +73,9 @@
 			if (f != 0) {
 				asm("dmultu\t%[cnt],%[f]\n\t"
 				    "mfhi\t%[cnt]"
-				    : [cnt] "+r" (ipd_clk_count),
-				      [f] "=r" (f)
-				    : : "hi", "lo");
+				    : [cnt] "+r" (ipd_clk_count)
+				    : [f] "r" (f)
+				    : "hi", "lo");
 			}
 		}
 		write_c0_cvmcount(ipd_clk_count);
@@ -109,21 +125,6 @@
 	clocksource_register_hz(&clocksource_mips, octeon_get_clock_rate());
 }
 
-static u64 octeon_udelay_factor;
-static u64 octeon_ndelay_factor;
-
-void __init octeon_setup_delays(void)
-{
-	octeon_udelay_factor = octeon_get_clock_rate() / 1000000;
-	/*
-	 * For __ndelay we divide by 2^16, so the factor is multiplied
-	 * by the same amount.
-	 */
-	octeon_ndelay_factor = (octeon_udelay_factor * 0x10000ull) / 1000ull;
-
-	preset_lpj = octeon_get_clock_rate() / HZ;
-}
-
 void __udelay(unsigned long us)
 {
 	u64 cur, end, inc;
@@ -163,3 +164,35 @@
 		cur = read_c0_cvmcount();
 }
 EXPORT_SYMBOL(__delay);
+
+
+/**
+ * octeon_io_clk_delay - wait for a given number of io clock cycles to pass.
+ *
+ * We scale the wait by the clock ratio, and then wait for the
+ * corresponding number of core clocks.
+ *
+ * @count: The number of clocks to wait.
+ */
+void octeon_io_clk_delay(unsigned long count)
+{
+	u64 cur, end;
+
+	cur = read_c0_cvmcount();
+	if (rdiv != 0) {
+		end = count * rdiv;
+		if (f != 0) {
+			asm("dmultu\t%[cnt],%[f]\n\t"
+				"mfhi\t%[cnt]"
+				: [cnt] "+r" (end)
+				: [f] "r" (f)
+				: "hi", "lo");
+		}
+		end = cur + end;
+	} else {
+		end = cur + count;
+	}
+	while (end > cur)
+		cur = read_c0_cvmcount();
+}
+EXPORT_SYMBOL(octeon_io_clk_delay);
diff --git a/arch/mips/cavium-octeon/executive/cvmx-interrupt-rsl.c b/arch/mips/cavium-octeon/executive/cvmx-interrupt-rsl.c
index bea7538..560e034 100644
--- a/arch/mips/cavium-octeon/executive/cvmx-interrupt-rsl.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-interrupt-rsl.c
@@ -130,7 +130,7 @@
 	if (num_ports) {
 		if (OCTEON_IS_MODEL(OCTEON_CN38XX)
 		    || OCTEON_IS_MODEL(OCTEON_CN58XX))
-			gmx_tx_int_en.s.ncb_nxa = 1;
+			gmx_tx_int_en.cn38xx.ncb_nxa = 1;
 		gmx_tx_int_en.s.pko_nxa = 1;
 	}
 	gmx_tx_int_en.s.undflw = (1 << num_ports) - 1;
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
index 274cd4f..02b15ee 100644
--- a/arch/mips/cavium-octeon/octeon-irq.c
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -16,12 +16,11 @@
 #include <linux/of.h>
 
 #include <asm/octeon/octeon.h>
-
-static DEFINE_RAW_SPINLOCK(octeon_irq_ciu0_lock);
-static DEFINE_RAW_SPINLOCK(octeon_irq_ciu1_lock);
+#include <asm/octeon/cvmx-ciu2-defs.h>
 
 static DEFINE_PER_CPU(unsigned long, octeon_irq_ciu0_en_mirror);
 static DEFINE_PER_CPU(unsigned long, octeon_irq_ciu1_en_mirror);
+static DEFINE_PER_CPU(raw_spinlock_t, octeon_irq_ciu_spinlock);
 
 static __read_mostly u8 octeon_irq_ciu_to_irq[8][64];
 
@@ -29,8 +28,9 @@
 	void *p;
 	unsigned long l;
 	struct {
-		unsigned int line:6;
-		unsigned int bit:6;
+		unsigned long line:6;
+		unsigned long bit:6;
+		unsigned long gpio_line:6;
 	} s;
 };
 
@@ -45,7 +45,7 @@
 
 static struct octeon_core_chip_data octeon_irq_core_chip_data[MIPS_CORE_IRQ_LINES];
 
-static void octeon_irq_set_ciu_mapping(int irq, int line, int bit,
+static void octeon_irq_set_ciu_mapping(int irq, int line, int bit, int gpio_line,
 				       struct irq_chip *chip,
 				       irq_flow_handler_t handler)
 {
@@ -56,6 +56,7 @@
 	cd.l = 0;
 	cd.s.line = line;
 	cd.s.bit = bit;
+	cd.s.gpio_line = gpio_line;
 
 	irq_set_chip_data(irq, cd.p);
 	octeon_irq_ciu_to_irq[line][bit] = irq;
@@ -231,22 +232,31 @@
 	unsigned long *pen;
 	unsigned long flags;
 	union octeon_ciu_chip_data cd;
+	raw_spinlock_t *lock = &per_cpu(octeon_irq_ciu_spinlock, cpu);
 
 	cd.p = irq_data_get_irq_chip_data(data);
 
+	raw_spin_lock_irqsave(lock, flags);
 	if (cd.s.line == 0) {
-		raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
 		pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu);
-		set_bit(cd.s.bit, pen);
+		__set_bit(cd.s.bit, pen);
+		/*
+		 * Must be visible to octeon_irq_ip{2,3}_ciu() before
+		 * enabling the irq.
+		 */
+		wmb();
 		cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen);
-		raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
 	} else {
-		raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
 		pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
-		set_bit(cd.s.bit, pen);
+		__set_bit(cd.s.bit, pen);
+		/*
+		 * Must be visible to octeon_irq_ip{2,3}_ciu() before
+		 * enabling the irq.
+		 */
+		wmb();
 		cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen);
-		raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
 	}
+	raw_spin_unlock_irqrestore(lock, flags);
 }
 
 static void octeon_irq_ciu_enable_local(struct irq_data *data)
@@ -254,22 +264,31 @@
 	unsigned long *pen;
 	unsigned long flags;
 	union octeon_ciu_chip_data cd;
+	raw_spinlock_t *lock = &__get_cpu_var(octeon_irq_ciu_spinlock);
 
 	cd.p = irq_data_get_irq_chip_data(data);
 
+	raw_spin_lock_irqsave(lock, flags);
 	if (cd.s.line == 0) {
-		raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
 		pen = &__get_cpu_var(octeon_irq_ciu0_en_mirror);
-		set_bit(cd.s.bit, pen);
+		__set_bit(cd.s.bit, pen);
+		/*
+		 * Must be visible to octeon_irq_ip{2,3}_ciu() before
+		 * enabling the irq.
+		 */
+		wmb();
 		cvmx_write_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2), *pen);
-		raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
 	} else {
-		raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
 		pen = &__get_cpu_var(octeon_irq_ciu1_en_mirror);
-		set_bit(cd.s.bit, pen);
+		__set_bit(cd.s.bit, pen);
+		/*
+		 * Must be visible to octeon_irq_ip{2,3}_ciu() before
+		 * enabling the irq.
+		 */
+		wmb();
 		cvmx_write_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1), *pen);
-		raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
 	}
+	raw_spin_unlock_irqrestore(lock, flags);
 }
 
 static void octeon_irq_ciu_disable_local(struct irq_data *data)
@@ -277,22 +296,31 @@
 	unsigned long *pen;
 	unsigned long flags;
 	union octeon_ciu_chip_data cd;
+	raw_spinlock_t *lock = &__get_cpu_var(octeon_irq_ciu_spinlock);
 
 	cd.p = irq_data_get_irq_chip_data(data);
 
+	raw_spin_lock_irqsave(lock, flags);
 	if (cd.s.line == 0) {
-		raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
 		pen = &__get_cpu_var(octeon_irq_ciu0_en_mirror);
-		clear_bit(cd.s.bit, pen);
+		__clear_bit(cd.s.bit, pen);
+		/*
+		 * Must be visible to octeon_irq_ip{2,3}_ciu() before
+		 * enabling the irq.
+		 */
+		wmb();
 		cvmx_write_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2), *pen);
-		raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
 	} else {
-		raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
 		pen = &__get_cpu_var(octeon_irq_ciu1_en_mirror);
-		clear_bit(cd.s.bit, pen);
+		__clear_bit(cd.s.bit, pen);
+		/*
+		 * Must be visible to octeon_irq_ip{2,3}_ciu() before
+		 * enabling the irq.
+		 */
+		wmb();
 		cvmx_write_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1), *pen);
-		raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
 	}
+	raw_spin_unlock_irqrestore(lock, flags);
 }
 
 static void octeon_irq_ciu_disable_all(struct irq_data *data)
@@ -301,29 +329,30 @@
 	unsigned long *pen;
 	int cpu;
 	union octeon_ciu_chip_data cd;
-
-	wmb(); /* Make sure flag changes arrive before register updates. */
+	raw_spinlock_t *lock;
 
 	cd.p = irq_data_get_irq_chip_data(data);
 
-	if (cd.s.line == 0) {
-		raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
-		for_each_online_cpu(cpu) {
-			int coreid = octeon_coreid_for_cpu(cpu);
+	for_each_online_cpu(cpu) {
+		int coreid = octeon_coreid_for_cpu(cpu);
+		lock = &per_cpu(octeon_irq_ciu_spinlock, cpu);
+		if (cd.s.line == 0)
 			pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu);
-			clear_bit(cd.s.bit, pen);
-			cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen);
-		}
-		raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
-	} else {
-		raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
-		for_each_online_cpu(cpu) {
-			int coreid = octeon_coreid_for_cpu(cpu);
+		else
 			pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
-			clear_bit(cd.s.bit, pen);
+
+		raw_spin_lock_irqsave(lock, flags);
+		__clear_bit(cd.s.bit, pen);
+		/*
+		 * Must be visible to octeon_irq_ip{2,3}_ciu() before
+		 * enabling the irq.
+		 */
+		wmb();
+		if (cd.s.line == 0)
+			cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen);
+		else
 			cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen);
-		}
-		raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
+		raw_spin_unlock_irqrestore(lock, flags);
 	}
 }
 
@@ -333,27 +362,30 @@
 	unsigned long *pen;
 	int cpu;
 	union octeon_ciu_chip_data cd;
+	raw_spinlock_t *lock;
 
 	cd.p = irq_data_get_irq_chip_data(data);
 
-	if (cd.s.line == 0) {
-		raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
-		for_each_online_cpu(cpu) {
-			int coreid = octeon_coreid_for_cpu(cpu);
+	for_each_online_cpu(cpu) {
+		int coreid = octeon_coreid_for_cpu(cpu);
+		lock = &per_cpu(octeon_irq_ciu_spinlock, cpu);
+		if (cd.s.line == 0)
 			pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu);
-			set_bit(cd.s.bit, pen);
-			cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen);
-		}
-		raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
-	} else {
-		raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
-		for_each_online_cpu(cpu) {
-			int coreid = octeon_coreid_for_cpu(cpu);
+		else
 			pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
-			set_bit(cd.s.bit, pen);
+
+		raw_spin_lock_irqsave(lock, flags);
+		__set_bit(cd.s.bit, pen);
+		/*
+		 * Must be visible to octeon_irq_ip{2,3}_ciu() before
+		 * enabling the irq.
+		 */
+		wmb();
+		if (cd.s.line == 0)
+			cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen);
+		else
 			cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen);
-		}
-		raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
+		raw_spin_unlock_irqrestore(lock, flags);
 	}
 }
 
@@ -435,7 +467,7 @@
 	u64 mask;
 	union octeon_ciu_chip_data cd;
 
-	cd.p = data->chip_data;
+	cd.p = irq_data_get_irq_chip_data(data);
 	mask = 1ull << (cd.s.bit);
 
 	if (cd.s.line == 0) {
@@ -456,9 +488,7 @@
 	u64 mask;
 	union octeon_ciu_chip_data cd;
 
-	wmb(); /* Make sure flag changes arrive before register updates. */
-
-	cd.p = data->chip_data;
+	cd.p = irq_data_get_irq_chip_data(data);
 	mask = 1ull << (cd.s.bit);
 
 	if (cd.s.line == 0) {
@@ -486,7 +516,7 @@
 	u64 mask;
 	union octeon_ciu_chip_data cd;
 
-	cd.p = data->chip_data;
+	cd.p = irq_data_get_irq_chip_data(data);
 	mask = 1ull << (cd.s.bit);
 
 	if (cd.s.line == 0) {
@@ -521,7 +551,7 @@
 	cfg.s.fil_cnt = 7;
 	cfg.s.fil_sel = 3;
 
-	cvmx_write_csr(CVMX_GPIO_BIT_CFGX(cd.s.bit - 16), cfg.u64);
+	cvmx_write_csr(CVMX_GPIO_BIT_CFGX(cd.s.gpio_line), cfg.u64);
 }
 
 static void octeon_irq_ciu_enable_gpio_v2(struct irq_data *data)
@@ -549,7 +579,7 @@
 	union octeon_ciu_chip_data cd;
 
 	cd.p = irq_data_get_irq_chip_data(data);
-	cvmx_write_csr(CVMX_GPIO_BIT_CFGX(cd.s.bit - 16), 0);
+	cvmx_write_csr(CVMX_GPIO_BIT_CFGX(cd.s.gpio_line), 0);
 
 	octeon_irq_ciu_disable_all_v2(data);
 }
@@ -559,7 +589,7 @@
 	union octeon_ciu_chip_data cd;
 
 	cd.p = irq_data_get_irq_chip_data(data);
-	cvmx_write_csr(CVMX_GPIO_BIT_CFGX(cd.s.bit - 16), 0);
+	cvmx_write_csr(CVMX_GPIO_BIT_CFGX(cd.s.gpio_line), 0);
 
 	octeon_irq_ciu_disable_all(data);
 }
@@ -570,7 +600,7 @@
 	u64 mask;
 
 	cd.p = irq_data_get_irq_chip_data(data);
-	mask = 1ull << (cd.s.bit - 16);
+	mask = 1ull << (cd.s.gpio_line);
 
 	cvmx_write_csr(CVMX_GPIO_INT_CLR, mask);
 }
@@ -615,8 +645,10 @@
 	bool enable_one = !irqd_irq_disabled(data) && !irqd_irq_masked(data);
 	unsigned long flags;
 	union octeon_ciu_chip_data cd;
+	unsigned long *pen;
+	raw_spinlock_t *lock;
 
-	cd.p = data->chip_data;
+	cd.p = irq_data_get_irq_chip_data(data);
 
 	/*
 	 * For non-v2 CIU, we will allow only single CPU affinity.
@@ -629,36 +661,36 @@
 	if (!enable_one)
 		return 0;
 
-	if (cd.s.line == 0) {
-		raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
-		for_each_online_cpu(cpu) {
-			int coreid = octeon_coreid_for_cpu(cpu);
-			unsigned long *pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu);
 
-			if (cpumask_test_cpu(cpu, dest) && enable_one) {
-				enable_one = false;
-				set_bit(cd.s.bit, pen);
-			} else {
-				clear_bit(cd.s.bit, pen);
-			}
+	for_each_online_cpu(cpu) {
+		int coreid = octeon_coreid_for_cpu(cpu);
+
+		lock = &per_cpu(octeon_irq_ciu_spinlock, cpu);
+		raw_spin_lock_irqsave(lock, flags);
+
+		if (cd.s.line == 0)
+			pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu);
+		else
+			pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
+
+		if (cpumask_test_cpu(cpu, dest) && enable_one) {
+			enable_one = 0;
+			__set_bit(cd.s.bit, pen);
+		} else {
+			__clear_bit(cd.s.bit, pen);
+		}
+		/*
+		 * Must be visible to octeon_irq_ip{2,3}_ciu() before
+		 * enabling the irq.
+		 */
+		wmb();
+
+		if (cd.s.line == 0)
 			cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen);
-		}
-		raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
-	} else {
-		raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
-		for_each_online_cpu(cpu) {
-			int coreid = octeon_coreid_for_cpu(cpu);
-			unsigned long *pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
-
-			if (cpumask_test_cpu(cpu, dest) && enable_one) {
-				enable_one = false;
-				set_bit(cd.s.bit, pen);
-			} else {
-				clear_bit(cd.s.bit, pen);
-			}
+		else
 			cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen);
-		}
-		raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
+
+		raw_spin_unlock_irqrestore(lock, flags);
 	}
 	return 0;
 }
@@ -679,7 +711,7 @@
 	if (!enable_one)
 		return 0;
 
-	cd.p = data->chip_data;
+	cd.p = irq_data_get_irq_chip_data(data);
 	mask = 1ull << cd.s.bit;
 
 	if (cd.s.line == 0) {
@@ -714,14 +746,6 @@
 #endif
 
 /*
- * The v1 CIU code already masks things, so supply a dummy version to
- * the core chip code.
- */
-static void octeon_irq_dummy_mask(struct irq_data *data)
-{
-}
-
-/*
  * Newer octeon chips have support for lockless CIU operation.
  */
 static struct irq_chip octeon_irq_chip_ciu_v2 = {
@@ -742,7 +766,8 @@
 	.irq_enable = octeon_irq_ciu_enable,
 	.irq_disable = octeon_irq_ciu_disable_all,
 	.irq_ack = octeon_irq_ciu_ack,
-	.irq_mask = octeon_irq_dummy_mask,
+	.irq_mask = octeon_irq_ciu_disable_local,
+	.irq_unmask = octeon_irq_ciu_enable,
 #ifdef CONFIG_SMP
 	.irq_set_affinity = octeon_irq_ciu_set_affinity,
 	.irq_cpu_offline = octeon_irq_cpu_offline_ciu,
@@ -766,6 +791,8 @@
 	.name = "CIU-M",
 	.irq_enable = octeon_irq_ciu_enable_all,
 	.irq_disable = octeon_irq_ciu_disable_all,
+	.irq_ack = octeon_irq_ciu_disable_local,
+	.irq_eoi = octeon_irq_ciu_enable_local,
 
 	.irq_cpu_online = octeon_irq_ciu_enable_local,
 	.irq_cpu_offline = octeon_irq_ciu_disable_local,
@@ -790,7 +817,8 @@
 	.name = "CIU-GPIO",
 	.irq_enable = octeon_irq_ciu_enable_gpio,
 	.irq_disable = octeon_irq_ciu_disable_gpio,
-	.irq_mask = octeon_irq_dummy_mask,
+	.irq_mask = octeon_irq_ciu_disable_local,
+	.irq_unmask = octeon_irq_ciu_enable,
 	.irq_ack = octeon_irq_ciu_gpio_ack,
 	.irq_set_type = octeon_irq_ciu_gpio_set_type,
 #ifdef CONFIG_SMP
@@ -809,12 +837,18 @@
 	unsigned long *pen;
 	int coreid = data->irq - OCTEON_IRQ_WDOG0;	/* Bit 0-63 of EN1 */
 	int cpu = octeon_cpu_for_coreid(coreid);
+	raw_spinlock_t *lock = &per_cpu(octeon_irq_ciu_spinlock, cpu);
 
-	raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
+	raw_spin_lock_irqsave(lock, flags);
 	pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
-	set_bit(coreid, pen);
+	__set_bit(coreid, pen);
+	/*
+	 * Must be visible to octeon_irq_ip{2,3}_ciu() before enabling
+	 * the irq.
+	 */
+	wmb();
 	cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen);
-	raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
+	raw_spin_unlock_irqrestore(lock, flags);
 }
 
 /*
@@ -843,7 +877,8 @@
 	.name = "CIU-W",
 	.irq_enable = octeon_irq_ciu_wd_enable,
 	.irq_disable = octeon_irq_ciu_disable_all,
-	.irq_mask = octeon_irq_dummy_mask,
+	.irq_mask = octeon_irq_ciu_disable_local,
+	.irq_unmask = octeon_irq_ciu_enable_local,
 };
 
 static bool octeon_irq_ciu_is_edge(unsigned int line, unsigned int bit)
@@ -976,19 +1011,20 @@
 		return -EINVAL;
 
 	if (octeon_irq_ciu_is_edge(line, bit))
-		octeon_irq_set_ciu_mapping(virq, line, bit,
+		octeon_irq_set_ciu_mapping(virq, line, bit, 0,
 					   octeon_irq_ciu_chip,
 					   handle_edge_irq);
 	else
-		octeon_irq_set_ciu_mapping(virq, line, bit,
+		octeon_irq_set_ciu_mapping(virq, line, bit, 0,
 					   octeon_irq_ciu_chip,
 					   handle_level_irq);
 
 	return 0;
 }
 
-static int octeon_irq_gpio_map(struct irq_domain *d,
-			       unsigned int virq, irq_hw_number_t hw)
+static int octeon_irq_gpio_map_common(struct irq_domain *d,
+				      unsigned int virq, irq_hw_number_t hw,
+				      int line_limit, struct irq_chip *chip)
 {
 	struct octeon_irq_gpio_domain_data *gpiod = d->host_data;
 	unsigned int line, bit;
@@ -999,15 +1035,20 @@
 	hw += gpiod->base_hwirq;
 	line = hw >> 6;
 	bit = hw & 63;
-	if (line > 1 || octeon_irq_ciu_to_irq[line][bit] != 0)
+	if (line > line_limit || octeon_irq_ciu_to_irq[line][bit] != 0)
 		return -EINVAL;
 
-	octeon_irq_set_ciu_mapping(virq, line, bit,
-				   octeon_irq_gpio_chip,
-				   octeon_irq_handle_gpio);
+	octeon_irq_set_ciu_mapping(virq, line, bit, hw,
+				   chip, octeon_irq_handle_gpio);
 	return 0;
 }
 
+static int octeon_irq_gpio_map(struct irq_domain *d,
+			       unsigned int virq, irq_hw_number_t hw)
+{
+	return octeon_irq_gpio_map_common(d, virq, hw, 1, octeon_irq_gpio_chip);
+}
+
 static struct irq_domain_ops octeon_irq_domain_ciu_ops = {
 	.map = octeon_irq_ciu_map,
 	.xlate = octeon_irq_ciu_xlat,
@@ -1018,27 +1059,7 @@
 	.xlate = octeon_irq_gpio_xlat,
 };
 
-static void octeon_irq_ip2_v1(void)
-{
-	const unsigned long core_id = cvmx_get_core_num();
-	u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INTX_SUM0(core_id * 2));
-
-	ciu_sum &= __get_cpu_var(octeon_irq_ciu0_en_mirror);
-	clear_c0_status(STATUSF_IP2);
-	if (likely(ciu_sum)) {
-		int bit = fls64(ciu_sum) - 1;
-		int irq = octeon_irq_ciu_to_irq[0][bit];
-		if (likely(irq))
-			do_IRQ(irq);
-		else
-			spurious_interrupt();
-	} else {
-		spurious_interrupt();
-	}
-	set_c0_status(STATUSF_IP2);
-}
-
-static void octeon_irq_ip2_v2(void)
+static void octeon_irq_ip2_ciu(void)
 {
 	const unsigned long core_id = cvmx_get_core_num();
 	u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INTX_SUM0(core_id * 2));
@@ -1055,12 +1076,12 @@
 		spurious_interrupt();
 	}
 }
-static void octeon_irq_ip3_v1(void)
+
+static void octeon_irq_ip3_ciu(void)
 {
 	u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INT_SUM1);
 
 	ciu_sum &= __get_cpu_var(octeon_irq_ciu1_en_mirror);
-	clear_c0_status(STATUSF_IP3);
 	if (likely(ciu_sum)) {
 		int bit = fls64(ciu_sum) - 1;
 		int irq = octeon_irq_ciu_to_irq[1][bit];
@@ -1071,24 +1092,13 @@
 	} else {
 		spurious_interrupt();
 	}
-	set_c0_status(STATUSF_IP3);
 }
 
-static void octeon_irq_ip3_v2(void)
-{
-	u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INT_SUM1);
+static bool octeon_irq_use_ip4;
 
-	ciu_sum &= __get_cpu_var(octeon_irq_ciu1_en_mirror);
-	if (likely(ciu_sum)) {
-		int bit = fls64(ciu_sum) - 1;
-		int irq = octeon_irq_ciu_to_irq[1][bit];
-		if (likely(irq))
-			do_IRQ(irq);
-		else
-			spurious_interrupt();
-	} else {
-		spurious_interrupt();
-	}
+static void __cpuinit octeon_irq_local_enable_ip4(void *arg)
+{
+	set_c0_status(STATUSF_IP4);
 }
 
 static void octeon_irq_ip4_mask(void)
@@ -1103,6 +1113,13 @@
 
 void __cpuinitdata (*octeon_irq_setup_secondary)(void);
 
+void __cpuinit octeon_irq_set_ip4_handler(octeon_irq_ip4_handler_t h)
+{
+	octeon_irq_ip4 = h;
+	octeon_irq_use_ip4 = true;
+	on_each_cpu(octeon_irq_local_enable_ip4, NULL, 1);
+}
+
 static void __cpuinit octeon_irq_percpu_enable(void)
 {
 	irq_cpu_online();
@@ -1111,6 +1128,12 @@
 static void __cpuinit octeon_irq_init_ciu_percpu(void)
 {
 	int coreid = cvmx_get_core_num();
+
+
+	__get_cpu_var(octeon_irq_ciu0_en_mirror) = 0;
+	__get_cpu_var(octeon_irq_ciu1_en_mirror) = 0;
+	wmb();
+	raw_spin_lock_init(&__get_cpu_var(octeon_irq_ciu_spinlock));
 	/*
 	 * Disable All CIU Interrupts. The ones we need will be
 	 * enabled later.  Read the SUM register so we know the write
@@ -1123,12 +1146,30 @@
 	cvmx_read_csr(CVMX_CIU_INTX_SUM0((coreid * 2)));
 }
 
+static void octeon_irq_init_ciu2_percpu(void)
+{
+	u64 regx, ipx;
+	int coreid = cvmx_get_core_num();
+	u64 base = CVMX_CIU2_EN_PPX_IP2_WRKQ(coreid);
+
+	/*
+	 * Disable All CIU2 Interrupts. The ones we need will be
+	 * enabled later.  Read the SUM register so we know the write
+	 * completed.
+	 *
+	 * There are 9 registers and 3 IPX levels with strides 0x1000
+	 * and 0x200 respectivly.  Use loops to clear them.
+	 */
+	for (regx = 0; regx <= 0x8000; regx += 0x1000) {
+		for (ipx = 0; ipx <= 0x400; ipx += 0x200)
+			cvmx_write_csr(base + regx + ipx, 0);
+	}
+
+	cvmx_read_csr(CVMX_CIU2_SUM_PPX_IP2(coreid));
+}
+
 static void __cpuinit octeon_irq_setup_secondary_ciu(void)
 {
-
-	__get_cpu_var(octeon_irq_ciu0_en_mirror) = 0;
-	__get_cpu_var(octeon_irq_ciu1_en_mirror) = 0;
-
 	octeon_irq_init_ciu_percpu();
 	octeon_irq_percpu_enable();
 
@@ -1137,6 +1178,19 @@
 	clear_c0_status(STATUSF_IP4);
 }
 
+static void octeon_irq_setup_secondary_ciu2(void)
+{
+	octeon_irq_init_ciu2_percpu();
+	octeon_irq_percpu_enable();
+
+	/* Enable the CIU lines */
+	set_c0_status(STATUSF_IP3 | STATUSF_IP2);
+	if (octeon_irq_use_ip4)
+		set_c0_status(STATUSF_IP4);
+	else
+		clear_c0_status(STATUSF_IP4);
+}
+
 static void __init octeon_irq_init_ciu(void)
 {
 	unsigned int i;
@@ -1150,19 +1204,17 @@
 	octeon_irq_init_ciu_percpu();
 	octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu;
 
+	octeon_irq_ip2 = octeon_irq_ip2_ciu;
+	octeon_irq_ip3 = octeon_irq_ip3_ciu;
 	if (OCTEON_IS_MODEL(OCTEON_CN58XX_PASS2_X) ||
 	    OCTEON_IS_MODEL(OCTEON_CN56XX_PASS2_X) ||
 	    OCTEON_IS_MODEL(OCTEON_CN52XX_PASS2_X) ||
 	    OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
-		octeon_irq_ip2 = octeon_irq_ip2_v2;
-		octeon_irq_ip3 = octeon_irq_ip3_v2;
 		chip = &octeon_irq_chip_ciu_v2;
 		chip_mbox = &octeon_irq_chip_ciu_mbox_v2;
 		chip_wd = &octeon_irq_chip_ciu_wd_v2;
 		octeon_irq_gpio_chip = &octeon_irq_chip_ciu_gpio_v2;
 	} else {
-		octeon_irq_ip2 = octeon_irq_ip2_v1;
-		octeon_irq_ip3 = octeon_irq_ip3_v1;
 		chip = &octeon_irq_chip_ciu;
 		chip_mbox = &octeon_irq_chip_ciu_mbox;
 		chip_wd = &octeon_irq_chip_ciu_wd;
@@ -1192,6 +1244,7 @@
 	ciu_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-ciu");
 	if (ciu_node) {
 		ciu_domain = irq_domain_add_tree(ciu_node, &octeon_irq_domain_ciu_ops, NULL);
+		irq_set_default_host(ciu_domain);
 		of_node_put(ciu_node);
 	} else
 		panic("Cannot find device node for cavium,octeon-3860-ciu.");
@@ -1200,8 +1253,8 @@
 	for (i = 0; i < 16; i++)
 		octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_WORKQ0, 0, i + 0);
 
-	octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq);
-	octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq);
+	octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, 0, chip_mbox, handle_percpu_irq);
+	octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, 0, chip_mbox, handle_percpu_irq);
 
 	for (i = 0; i < 4; i++)
 		octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_PCI_INT0, 0, i + 36);
@@ -1217,7 +1270,7 @@
 
 	/* CIU_1 */
 	for (i = 0; i < 16; i++)
-		octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, chip_wd, handle_level_irq);
+		octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, 0, chip_wd, handle_level_irq);
 
 	octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_USB1, 1, 17);
 
@@ -1226,6 +1279,466 @@
 	clear_c0_status(STATUSF_IP4);
 }
 
+/*
+ * Watchdog interrupts are special.  They are associated with a single
+ * core, so we hardwire the affinity to that core.
+ */
+static void octeon_irq_ciu2_wd_enable(struct irq_data *data)
+{
+	u64 mask;
+	u64 en_addr;
+	int coreid = data->irq - OCTEON_IRQ_WDOG0;
+	union octeon_ciu_chip_data cd;
+
+	cd.p = irq_data_get_irq_chip_data(data);
+	mask = 1ull << (cd.s.bit);
+
+	en_addr = CVMX_CIU2_EN_PPX_IP2_WRKQ_W1S(coreid) + (0x1000ull * cd.s.line);
+	cvmx_write_csr(en_addr, mask);
+
+}
+
+static void octeon_irq_ciu2_enable(struct irq_data *data)
+{
+	u64 mask;
+	u64 en_addr;
+	int cpu = next_cpu_for_irq(data);
+	int coreid = octeon_coreid_for_cpu(cpu);
+	union octeon_ciu_chip_data cd;
+
+	cd.p = irq_data_get_irq_chip_data(data);
+	mask = 1ull << (cd.s.bit);
+
+	en_addr = CVMX_CIU2_EN_PPX_IP2_WRKQ_W1S(coreid) + (0x1000ull * cd.s.line);
+	cvmx_write_csr(en_addr, mask);
+}
+
+static void octeon_irq_ciu2_enable_local(struct irq_data *data)
+{
+	u64 mask;
+	u64 en_addr;
+	int coreid = cvmx_get_core_num();
+	union octeon_ciu_chip_data cd;
+
+	cd.p = irq_data_get_irq_chip_data(data);
+	mask = 1ull << (cd.s.bit);
+
+	en_addr = CVMX_CIU2_EN_PPX_IP2_WRKQ_W1S(coreid) + (0x1000ull * cd.s.line);
+	cvmx_write_csr(en_addr, mask);
+
+}
+
+static void octeon_irq_ciu2_disable_local(struct irq_data *data)
+{
+	u64 mask;
+	u64 en_addr;
+	int coreid = cvmx_get_core_num();
+	union octeon_ciu_chip_data cd;
+
+	cd.p = irq_data_get_irq_chip_data(data);
+	mask = 1ull << (cd.s.bit);
+
+	en_addr = CVMX_CIU2_EN_PPX_IP2_WRKQ_W1C(coreid) + (0x1000ull * cd.s.line);
+	cvmx_write_csr(en_addr, mask);
+
+}
+
+static void octeon_irq_ciu2_ack(struct irq_data *data)
+{
+	u64 mask;
+	u64 en_addr;
+	int coreid = cvmx_get_core_num();
+	union octeon_ciu_chip_data cd;
+
+	cd.p = irq_data_get_irq_chip_data(data);
+	mask = 1ull << (cd.s.bit);
+
+	en_addr = CVMX_CIU2_RAW_PPX_IP2_WRKQ(coreid) + (0x1000ull * cd.s.line);
+	cvmx_write_csr(en_addr, mask);
+
+}
+
+static void octeon_irq_ciu2_disable_all(struct irq_data *data)
+{
+	int cpu;
+	u64 mask;
+	union octeon_ciu_chip_data cd;
+
+	cd.p = irq_data_get_irq_chip_data(data);
+	mask = 1ull << (cd.s.bit);
+
+	for_each_online_cpu(cpu) {
+		u64 en_addr = CVMX_CIU2_EN_PPX_IP2_WRKQ_W1C(octeon_coreid_for_cpu(cpu)) + (0x1000ull * cd.s.line);
+		cvmx_write_csr(en_addr, mask);
+	}
+}
+
+static void octeon_irq_ciu2_mbox_enable_all(struct irq_data *data)
+{
+	int cpu;
+	u64 mask;
+
+	mask = 1ull << (data->irq - OCTEON_IRQ_MBOX0);
+
+	for_each_online_cpu(cpu) {
+		u64 en_addr = CVMX_CIU2_EN_PPX_IP3_MBOX_W1S(octeon_coreid_for_cpu(cpu));
+		cvmx_write_csr(en_addr, mask);
+	}
+}
+
+static void octeon_irq_ciu2_mbox_disable_all(struct irq_data *data)
+{
+	int cpu;
+	u64 mask;
+
+	mask = 1ull << (data->irq - OCTEON_IRQ_MBOX0);
+
+	for_each_online_cpu(cpu) {
+		u64 en_addr = CVMX_CIU2_EN_PPX_IP3_MBOX_W1C(octeon_coreid_for_cpu(cpu));
+		cvmx_write_csr(en_addr, mask);
+	}
+}
+
+static void octeon_irq_ciu2_mbox_enable_local(struct irq_data *data)
+{
+	u64 mask;
+	u64 en_addr;
+	int coreid = cvmx_get_core_num();
+
+	mask = 1ull << (data->irq - OCTEON_IRQ_MBOX0);
+	en_addr = CVMX_CIU2_EN_PPX_IP3_MBOX_W1S(coreid);
+	cvmx_write_csr(en_addr, mask);
+}
+
+static void octeon_irq_ciu2_mbox_disable_local(struct irq_data *data)
+{
+	u64 mask;
+	u64 en_addr;
+	int coreid = cvmx_get_core_num();
+
+	mask = 1ull << (data->irq - OCTEON_IRQ_MBOX0);
+	en_addr = CVMX_CIU2_EN_PPX_IP3_MBOX_W1C(coreid);
+	cvmx_write_csr(en_addr, mask);
+}
+
+#ifdef CONFIG_SMP
+static int octeon_irq_ciu2_set_affinity(struct irq_data *data,
+					const struct cpumask *dest, bool force)
+{
+	int cpu;
+	bool enable_one = !irqd_irq_disabled(data) && !irqd_irq_masked(data);
+	u64 mask;
+	union octeon_ciu_chip_data cd;
+
+	if (!enable_one)
+		return 0;
+
+	cd.p = irq_data_get_irq_chip_data(data);
+	mask = 1ull << cd.s.bit;
+
+	for_each_online_cpu(cpu) {
+		u64 en_addr;
+		if (cpumask_test_cpu(cpu, dest) && enable_one) {
+			enable_one = false;
+			en_addr = CVMX_CIU2_EN_PPX_IP2_WRKQ_W1S(octeon_coreid_for_cpu(cpu)) + (0x1000ull * cd.s.line);
+		} else {
+			en_addr = CVMX_CIU2_EN_PPX_IP2_WRKQ_W1C(octeon_coreid_for_cpu(cpu)) + (0x1000ull * cd.s.line);
+		}
+		cvmx_write_csr(en_addr, mask);
+	}
+
+	return 0;
+}
+#endif
+
+static void octeon_irq_ciu2_enable_gpio(struct irq_data *data)
+{
+	octeon_irq_gpio_setup(data);
+	octeon_irq_ciu2_enable(data);
+}
+
+static void octeon_irq_ciu2_disable_gpio(struct irq_data *data)
+{
+	union octeon_ciu_chip_data cd;
+	cd.p = irq_data_get_irq_chip_data(data);
+
+	cvmx_write_csr(CVMX_GPIO_BIT_CFGX(cd.s.gpio_line), 0);
+
+	octeon_irq_ciu2_disable_all(data);
+}
+
+static struct irq_chip octeon_irq_chip_ciu2 = {
+	.name = "CIU2-E",
+	.irq_enable = octeon_irq_ciu2_enable,
+	.irq_disable = octeon_irq_ciu2_disable_all,
+	.irq_ack = octeon_irq_ciu2_ack,
+	.irq_mask = octeon_irq_ciu2_disable_local,
+	.irq_unmask = octeon_irq_ciu2_enable,
+#ifdef CONFIG_SMP
+	.irq_set_affinity = octeon_irq_ciu2_set_affinity,
+	.irq_cpu_offline = octeon_irq_cpu_offline_ciu,
+#endif
+};
+
+static struct irq_chip octeon_irq_chip_ciu2_mbox = {
+	.name = "CIU2-M",
+	.irq_enable = octeon_irq_ciu2_mbox_enable_all,
+	.irq_disable = octeon_irq_ciu2_mbox_disable_all,
+	.irq_ack = octeon_irq_ciu2_mbox_disable_local,
+	.irq_eoi = octeon_irq_ciu2_mbox_enable_local,
+
+	.irq_cpu_online = octeon_irq_ciu2_mbox_enable_local,
+	.irq_cpu_offline = octeon_irq_ciu2_mbox_disable_local,
+	.flags = IRQCHIP_ONOFFLINE_ENABLED,
+};
+
+static struct irq_chip octeon_irq_chip_ciu2_wd = {
+	.name = "CIU2-W",
+	.irq_enable = octeon_irq_ciu2_wd_enable,
+	.irq_disable = octeon_irq_ciu2_disable_all,
+	.irq_mask = octeon_irq_ciu2_disable_local,
+	.irq_unmask = octeon_irq_ciu2_enable_local,
+};
+
+static struct irq_chip octeon_irq_chip_ciu2_gpio = {
+	.name = "CIU-GPIO",
+	.irq_enable = octeon_irq_ciu2_enable_gpio,
+	.irq_disable = octeon_irq_ciu2_disable_gpio,
+	.irq_ack = octeon_irq_ciu_gpio_ack,
+	.irq_mask = octeon_irq_ciu2_disable_local,
+	.irq_unmask = octeon_irq_ciu2_enable,
+	.irq_set_type = octeon_irq_ciu_gpio_set_type,
+#ifdef CONFIG_SMP
+	.irq_set_affinity = octeon_irq_ciu2_set_affinity,
+	.irq_cpu_offline = octeon_irq_cpu_offline_ciu,
+#endif
+	.flags = IRQCHIP_SET_TYPE_MASKED,
+};
+
+static int octeon_irq_ciu2_xlat(struct irq_domain *d,
+				struct device_node *node,
+				const u32 *intspec,
+				unsigned int intsize,
+				unsigned long *out_hwirq,
+				unsigned int *out_type)
+{
+	unsigned int ciu, bit;
+
+	ciu = intspec[0];
+	bit = intspec[1];
+
+	/* Line 7  are the GPIO lines */
+	if (ciu > 6 || bit > 63)
+		return -EINVAL;
+
+	*out_hwirq = (ciu << 6) | bit;
+	*out_type = 0;
+
+	return 0;
+}
+
+static bool octeon_irq_ciu2_is_edge(unsigned int line, unsigned int bit)
+{
+	bool edge = false;
+
+	if (line == 3) /* MIO */
+		switch (bit) {
+		case 2:  /* IPD_DRP */
+		case 8 ... 11: /* Timers */
+		case 48: /* PTP */
+			edge = true;
+			break;
+		default:
+			break;
+		}
+	else if (line == 6) /* PKT */
+		switch (bit) {
+		case 52 ... 53: /* ILK_DRP */
+		case 8 ... 12:  /* GMX_DRP */
+			edge = true;
+			break;
+		default:
+			break;
+		}
+	return edge;
+}
+
+static int octeon_irq_ciu2_map(struct irq_domain *d,
+			       unsigned int virq, irq_hw_number_t hw)
+{
+	unsigned int line = hw >> 6;
+	unsigned int bit = hw & 63;
+
+	if (!octeon_irq_virq_in_range(virq))
+		return -EINVAL;
+
+	/* Line 7  are the GPIO lines */
+	if (line > 6 || octeon_irq_ciu_to_irq[line][bit] != 0)
+		return -EINVAL;
+
+	if (octeon_irq_ciu2_is_edge(line, bit))
+		octeon_irq_set_ciu_mapping(virq, line, bit, 0,
+					   &octeon_irq_chip_ciu2,
+					   handle_edge_irq);
+	else
+		octeon_irq_set_ciu_mapping(virq, line, bit, 0,
+					   &octeon_irq_chip_ciu2,
+					   handle_level_irq);
+
+	return 0;
+}
+static int octeon_irq_ciu2_gpio_map(struct irq_domain *d,
+				    unsigned int virq, irq_hw_number_t hw)
+{
+	return octeon_irq_gpio_map_common(d, virq, hw, 7, &octeon_irq_chip_ciu2_gpio);
+}
+
+static struct irq_domain_ops octeon_irq_domain_ciu2_ops = {
+	.map = octeon_irq_ciu2_map,
+	.xlate = octeon_irq_ciu2_xlat,
+};
+
+static struct irq_domain_ops octeon_irq_domain_ciu2_gpio_ops = {
+	.map = octeon_irq_ciu2_gpio_map,
+	.xlate = octeon_irq_gpio_xlat,
+};
+
+static void octeon_irq_ciu2(void)
+{
+	int line;
+	int bit;
+	int irq;
+	u64 src_reg, src, sum;
+	const unsigned long core_id = cvmx_get_core_num();
+
+	sum = cvmx_read_csr(CVMX_CIU2_SUM_PPX_IP2(core_id)) & 0xfful;
+
+	if (unlikely(!sum))
+		goto spurious;
+
+	line = fls64(sum) - 1;
+	src_reg = CVMX_CIU2_SRC_PPX_IP2_WRKQ(core_id) + (0x1000 * line);
+	src = cvmx_read_csr(src_reg);
+
+	if (unlikely(!src))
+		goto spurious;
+
+	bit = fls64(src) - 1;
+	irq = octeon_irq_ciu_to_irq[line][bit];
+	if (unlikely(!irq))
+		goto spurious;
+
+	do_IRQ(irq);
+	goto out;
+
+spurious:
+	spurious_interrupt();
+out:
+	/* CN68XX pass 1.x has an errata that accessing the ACK registers
+		can stop interrupts from propagating */
+	if (OCTEON_IS_MODEL(OCTEON_CN68XX))
+		cvmx_read_csr(CVMX_CIU2_INTR_CIU_READY);
+	else
+		cvmx_read_csr(CVMX_CIU2_ACK_PPX_IP2(core_id));
+	return;
+}
+
+static void octeon_irq_ciu2_mbox(void)
+{
+	int line;
+
+	const unsigned long core_id = cvmx_get_core_num();
+	u64 sum = cvmx_read_csr(CVMX_CIU2_SUM_PPX_IP3(core_id)) >> 60;
+
+	if (unlikely(!sum))
+		goto spurious;
+
+	line = fls64(sum) - 1;
+
+	do_IRQ(OCTEON_IRQ_MBOX0 + line);
+	goto out;
+
+spurious:
+	spurious_interrupt();
+out:
+	/* CN68XX pass 1.x has an errata that accessing the ACK registers
+		can stop interrupts from propagating */
+	if (OCTEON_IS_MODEL(OCTEON_CN68XX))
+		cvmx_read_csr(CVMX_CIU2_INTR_CIU_READY);
+	else
+		cvmx_read_csr(CVMX_CIU2_ACK_PPX_IP3(core_id));
+	return;
+}
+
+static void __init octeon_irq_init_ciu2(void)
+{
+	unsigned int i;
+	struct device_node *gpio_node;
+	struct device_node *ciu_node;
+	struct irq_domain *ciu_domain = NULL;
+
+	octeon_irq_init_ciu2_percpu();
+	octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu2;
+
+	octeon_irq_ip2 = octeon_irq_ciu2;
+	octeon_irq_ip3 = octeon_irq_ciu2_mbox;
+	octeon_irq_ip4 = octeon_irq_ip4_mask;
+
+	/* Mips internal */
+	octeon_irq_init_core();
+
+	gpio_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-gpio");
+	if (gpio_node) {
+		struct octeon_irq_gpio_domain_data *gpiod;
+
+		gpiod = kzalloc(sizeof(*gpiod), GFP_KERNEL);
+		if (gpiod) {
+			/* gpio domain host_data is the base hwirq number. */
+			gpiod->base_hwirq = 7 << 6;
+			irq_domain_add_linear(gpio_node, 16, &octeon_irq_domain_ciu2_gpio_ops, gpiod);
+			of_node_put(gpio_node);
+		} else
+			pr_warn("Cannot allocate memory for GPIO irq_domain.\n");
+	} else
+		pr_warn("Cannot find device node for cavium,octeon-3860-gpio.\n");
+
+	ciu_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-6880-ciu2");
+	if (ciu_node) {
+		ciu_domain = irq_domain_add_tree(ciu_node, &octeon_irq_domain_ciu2_ops, NULL);
+		irq_set_default_host(ciu_domain);
+		of_node_put(ciu_node);
+	} else
+		panic("Cannot find device node for cavium,octeon-6880-ciu2.");
+
+	/* CUI2 */
+	for (i = 0; i < 64; i++)
+		octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_WORKQ0, 0, i);
+
+	for (i = 0; i < 32; i++)
+		octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i, 0,
+					   &octeon_irq_chip_ciu2_wd, handle_level_irq);
+
+	for (i = 0; i < 4; i++)
+		octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_TIMER0, 3, i + 8);
+
+	octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_USB0, 3, 44);
+
+	for (i = 0; i < 4; i++)
+		octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_PCI_INT0, 4, i);
+
+	for (i = 0; i < 4; i++)
+		octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_PCI_MSI0, 4, i + 8);
+
+	irq_set_chip_and_handler(OCTEON_IRQ_MBOX0, &octeon_irq_chip_ciu2_mbox, handle_percpu_irq);
+	irq_set_chip_and_handler(OCTEON_IRQ_MBOX1, &octeon_irq_chip_ciu2_mbox, handle_percpu_irq);
+	irq_set_chip_and_handler(OCTEON_IRQ_MBOX2, &octeon_irq_chip_ciu2_mbox, handle_percpu_irq);
+	irq_set_chip_and_handler(OCTEON_IRQ_MBOX3, &octeon_irq_chip_ciu2_mbox, handle_percpu_irq);
+
+	/* Enable the CIU lines */
+	set_c0_status(STATUSF_IP3 | STATUSF_IP2);
+	clear_c0_status(STATUSF_IP4);
+}
+
 void __init arch_init_irq(void)
 {
 #ifdef CONFIG_SMP
@@ -1233,7 +1746,10 @@
 	cpumask_clear(irq_default_affinity);
 	cpumask_set_cpu(smp_processor_id(), irq_default_affinity);
 #endif
-	octeon_irq_init_ciu();
+	if (OCTEON_IS_MODEL(OCTEON_CN68XX))
+		octeon_irq_init_ciu2();
+	else
+		octeon_irq_init_ciu();
 }
 
 asmlinkage void plat_irq_dispatch(void)
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index 919b0fb..04dd8ff 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -548,6 +548,8 @@
 	}
 #endif
 
+	octeon_setup_delays();
+
 	/*
 	 * BIST should always be enabled when doing a soft reset. L2
 	 * Cache locking for instance is not cleared unless BIST is
@@ -611,7 +613,6 @@
 	mips_hpt_frequency = octeon_get_clock_rate();
 
 	octeon_init_cvmcount();
-	octeon_setup_delays();
 
 	_machine_restart = octeon_restart;
 	_machine_halt = octeon_halt;
diff --git a/arch/mips/configs/cavium-octeon_defconfig b/arch/mips/configs/cavium_octeon_defconfig
similarity index 100%
rename from arch/mips/configs/cavium-octeon_defconfig
rename to arch/mips/configs/cavium_octeon_defconfig
diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig
deleted file mode 100644
index b5ad738..0000000
--- a/arch/mips/configs/mipssim_defconfig
+++ /dev/null
@@ -1,64 +0,0 @@
-CONFIG_MIPS_SIM=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_HZ_100=y
-# CONFIG_SECCOMP is not set
-CONFIG_EXPERIMENTAL=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_EXPERT=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_STANDALONE is not set
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-# CONFIG_FW_LOADER is not set
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_NBD=y
-# CONFIG_MISC_DEVICES is not set
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_MIPS_SIM_NET=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_INPUT is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=1
-CONFIG_SERIAL_8250_RUNTIME_UARTS=1
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_DNOTIFY is not set
-CONFIG_TMPFS=y
-CONFIG_ROMFS_FS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_SCHED_DEBUG is not set
-CONFIG_DEBUG_INFO=y
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="nfsroot=192.168.192.169:/u1/mipsel,timeo=20 ip=dhcp"
-# CONFIG_CRC32 is not set
diff --git a/arch/mips/configs/nlm_xlp_defconfig b/arch/mips/configs/nlm_xlp_defconfig
index 84624b1..5468b1c 100644
--- a/arch/mips/configs/nlm_xlp_defconfig
+++ b/arch/mips/configs/nlm_xlp_defconfig
@@ -1,14 +1,12 @@
 CONFIG_NLM_XLP_BOARD=y
 CONFIG_64BIT=y
+CONFIG_PAGE_SIZE_16KB=y
+# CONFIG_HW_PERF_EVENTS is not set
 CONFIG_KSM=y
 CONFIG_DEFAULT_MMAP_MIN_ADDR=65536
 CONFIG_SMP=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
 # CONFIG_SECCOMP is not set
-CONFIG_USE_OF=y
 CONFIG_EXPERIMENTAL=y
-CONFIG_CROSS_COMPILE=""
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
@@ -19,13 +17,13 @@
 CONFIG_TASK_XACCT=y
 CONFIG_TASK_IO_ACCOUNTING=y
 CONFIG_AUDIT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
 CONFIG_CGROUPS=y
 CONFIG_NAMESPACES=y
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
 CONFIG_RD_BZIP2=y
 CONFIG_RD_LZMA=y
-CONFIG_INITRAMFS_COMPRESSION_LZMA=y
 CONFIG_KALLSYMS_ALL=y
 CONFIG_EMBEDDED=y
 # CONFIG_COMPAT_BRK is not set
@@ -35,6 +33,29 @@
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
 CONFIG_BLK_DEV_INTEGRITY=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ACORN_PARTITION=y
+CONFIG_ACORN_PARTITION_ICS=y
+CONFIG_ACORN_PARTITION_RISCIX=y
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_ATARI_PARTITION=y
+CONFIG_MAC_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_LDM_PARTITION=y
+CONFIG_SGI_PARTITION=y
+CONFIG_ULTRIX_PARTITION=y
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+CONFIG_SYSV68_PARTITION=y
+CONFIG_PCI=y
+CONFIG_PCI_DEBUG=y
+CONFIG_PCI_REALLOC_ENABLE_AUTO=y
+CONFIG_PCI_STUB=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_BINFMT_MISC=y
 CONFIG_MIPS32_COMPAT=y
@@ -169,7 +190,6 @@
 CONFIG_IP_NF_MATCH_TTL=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_LOG=m
 CONFIG_IP_NF_TARGET_ULOG=m
 CONFIG_NF_NAT=m
 CONFIG_IP_NF_TARGET_MASQUERADE=m
@@ -185,7 +205,6 @@
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_IP_NF_ARP_MANGLE=m
 CONFIG_NF_CONNTRACK_IPV6=m
-CONFIG_IP6_NF_QUEUE=m
 CONFIG_IP6_NF_IPTABLES=m
 CONFIG_IP6_NF_MATCH_AH=m
 CONFIG_IP6_NF_MATCH_EUI64=m
@@ -196,7 +215,6 @@
 CONFIG_IP6_NF_MATCH_MH=m
 CONFIG_IP6_NF_MATCH_RT=m
 CONFIG_IP6_NF_TARGET_HL=m
-CONFIG_IP6_NF_TARGET_LOG=m
 CONFIG_IP6_NF_FILTER=m
 CONFIG_IP6_NF_TARGET_REJECT=m
 CONFIG_IP6_NF_MANGLE=m
@@ -247,9 +265,6 @@
 CONFIG_IPDDP_DECAP=y
 CONFIG_X25=m
 CONFIG_LAPB=m
-CONFIG_ECONET=m
-CONFIG_ECONET_AUNUDP=y
-CONFIG_ECONET_NATIVE=y
 CONFIG_WAN_ROUTER=m
 CONFIG_PHONET=m
 CONFIG_IEEE802154=m
@@ -296,11 +311,21 @@
 CONFIG_NET_ACT_SKBEDIT=m
 CONFIG_DCB=y
 CONFIG_NET_PKTGEN=m
-# CONFIG_WIRELESS is not set
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_STANDALONE is not set
 CONFIG_CONNECTOR=y
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_LE_BYTE_SWAP=y
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_OF=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=m
@@ -309,7 +334,6 @@
 CONFIG_BLK_DEV_RAM_SIZE=65536
 CONFIG_CDROM_PKTCDVD=y
 CONFIG_RAID_ATTRS=m
-CONFIG_SCSI=y
 CONFIG_SCSI_TGT=m
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=m
@@ -336,6 +360,48 @@
 CONFIG_SCSI_DH_ALUA=m
 CONFIG_SCSI_OSD_INITIATOR=m
 CONFIG_SCSI_OSD_ULD=m
+CONFIG_ATA=y
+CONFIG_SATA_AHCI=y
+CONFIG_SATA_SIL24=y
+# CONFIG_ATA_SFF is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_ADAPTEC is not set
+# CONFIG_NET_VENDOR_ALTEON is not set
+# CONFIG_NET_VENDOR_AMD is not set
+# CONFIG_NET_VENDOR_ATHEROS is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_BROCADE is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_DEC is not set
+# CONFIG_NET_VENDOR_DLINK is not set
+# CONFIG_NET_VENDOR_EMULEX is not set
+# CONFIG_NET_VENDOR_EXAR is not set
+# CONFIG_NET_VENDOR_HP is not set
+CONFIG_E1000E=y
+# CONFIG_NET_VENDOR_I825XX is not set
+CONFIG_SKY2=y
+# CONFIG_NET_VENDOR_MELLANOX is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MYRI is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NVIDIA is not set
+# CONFIG_NET_VENDOR_OKI is not set
+# CONFIG_NET_PACKET_ENGINE is not set
+# CONFIG_NET_VENDOR_QLOGIC is not set
+# CONFIG_NET_VENDOR_REALTEK is not set
+# CONFIG_NET_VENDOR_RDC is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SILAN is not set
+# CONFIG_NET_VENDOR_SIS is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SUN is not set
+# CONFIG_NET_VENDOR_TEHUTI is not set
+# CONFIG_NET_VENDOR_TI is not set
+# CONFIG_NET_VENDOR_TOSHIBA is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
 # CONFIG_INPUT_MOUSEDEV is not set
 CONFIG_INPUT_EVDEV=y
 CONFIG_INPUT_EVBUG=m
@@ -359,16 +425,23 @@
 CONFIG_SERIAL_8250_MANY_PORTS=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
 CONFIG_SERIAL_8250_RSA=y
+CONFIG_SERIAL_OF_PLATFORM=y
 CONFIG_HW_RANDOM=y
 CONFIG_HW_RANDOM_TIMERIOMEM=m
 CONFIG_RAW_DRIVER=m
-# CONFIG_HWMON is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_OCORES=y
+CONFIG_SENSORS_LM90=y
+CONFIG_THERMAL=y
 # CONFIG_VGA_CONSOLE is not set
-# CONFIG_HID_SUPPORT is not set
 # CONFIG_USB_SUPPORT is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1374=y
 CONFIG_UIO=y
 CONFIG_UIO_PDRV=m
 CONFIG_UIO_PDRV_GENIRQ=m
+# CONFIG_IOMMU_SUPPORT is not set
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
@@ -380,15 +453,10 @@
 CONFIG_EXT4_FS_POSIX_ACL=y
 CONFIG_EXT4_FS_SECURITY=y
 CONFIG_GFS2_FS=m
-CONFIG_GFS2_FS_LOCKING_DLM=y
-CONFIG_OCFS2_FS=m
 CONFIG_BTRFS_FS=m
 CONFIG_BTRFS_FS_POSIX_ACL=y
 CONFIG_NILFS2_FS=m
 CONFIG_QUOTA_NETLINK_INTERFACE=y
-# CONFIG_PRINT_QUOTA_WARNING is not set
-CONFIG_QFMT_V1=m
-CONFIG_QFMT_V2=m
 CONFIG_AUTOFS4_FS=m
 CONFIG_FUSE_FS=y
 CONFIG_CUSE=m
@@ -414,6 +482,7 @@
 CONFIG_BEFS_FS=m
 CONFIG_BFS_FS=m
 CONFIG_EFS_FS=m
+CONFIG_JFFS2_FS=y
 CONFIG_CRAMFS=m
 CONFIG_SQUASHFS=m
 CONFIG_VXFS_FS=m
@@ -426,7 +495,6 @@
 CONFIG_UFS_FS=m
 CONFIG_EXOFS_FS=m
 CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
 CONFIG_NFS_V3_ACL=y
 CONFIG_NFS_V4=y
 CONFIG_NFS_FSCACHE=y
@@ -449,25 +517,6 @@
 CONFIG_NCPFS_EXTRAS=y
 CONFIG_CODA_FS=m
 CONFIG_AFS_FS=m
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_ACORN_PARTITION=y
-CONFIG_ACORN_PARTITION_ICS=y
-CONFIG_ACORN_PARTITION_RISCIX=y
-CONFIG_OSF_PARTITION=y
-CONFIG_AMIGA_PARTITION=y
-CONFIG_ATARI_PARTITION=y
-CONFIG_MAC_PARTITION=y
-CONFIG_BSD_DISKLABEL=y
-CONFIG_MINIX_SUBPARTITION=y
-CONFIG_SOLARIS_X86_PARTITION=y
-CONFIG_UNIXWARE_DISKLABEL=y
-CONFIG_LDM_PARTITION=y
-CONFIG_SGI_PARTITION=y
-CONFIG_ULTRIX_PARTITION=y
-CONFIG_SUN_PARTITION=y
-CONFIG_KARMA_PARTITION=y
-CONFIG_EFI_PARTITION=y
-CONFIG_SYSV68_PARTITION=y
 CONFIG_NLS=y
 CONFIG_NLS_DEFAULT="cp437"
 CONFIG_NLS_CODEPAGE_437=m
@@ -517,12 +566,10 @@
 CONFIG_TIMER_STATS=y
 CONFIG_DEBUG_INFO=y
 CONFIG_DEBUG_MEMORY_INIT=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_SCHED_TRACER=y
 CONFIG_BLK_DEV_IO_TRACE=y
 CONFIG_KGDB=y
 CONFIG_SECURITY=y
-CONFIG_SECURITY_NETWORK=y
 CONFIG_LSM_MMAP_MIN_ADDR=0
 CONFIG_SECURITY_SELINUX=y
 CONFIG_SECURITY_SELINUX_BOOTPARAM=y
diff --git a/arch/mips/configs/pnx8335-stb225_defconfig b/arch/mips/configs/pnx8335_stb225_defconfig
similarity index 100%
rename from arch/mips/configs/pnx8335-stb225_defconfig
rename to arch/mips/configs/pnx8335_stb225_defconfig
diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550_jbs_defconfig
similarity index 100%
rename from arch/mips/configs/pnx8550-jbs_defconfig
rename to arch/mips/configs/pnx8550_jbs_defconfig
diff --git a/arch/mips/configs/pnx8550-stb810_defconfig b/arch/mips/configs/pnx8550_stb810_defconfig
similarity index 100%
rename from arch/mips/configs/pnx8550-stb810_defconfig
rename to arch/mips/configs/pnx8550_stb810_defconfig
diff --git a/arch/mips/configs/rb532_defconfig b/arch/mips/configs/rb532_defconfig
index 55902d9..b85b121 100644
--- a/arch/mips/configs/rb532_defconfig
+++ b/arch/mips/configs/rb532_defconfig
@@ -119,7 +119,6 @@
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_BLOCK2MTD=y
 CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
 CONFIG_MTD_NAND_PLATFORM=y
 CONFIG_ATA=y
 # CONFIG_ATA_VERBOSE_ERROR is not set
diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250_swarm_defconfig
similarity index 100%
rename from arch/mips/configs/sb1250-swarm_defconfig
rename to arch/mips/configs/sb1250_swarm_defconfig
diff --git a/arch/mips/configs/sead3_defconfig b/arch/mips/configs/sead3_defconfig
new file mode 100644
index 0000000..e3eec68
--- /dev/null
+++ b/arch/mips/configs/sead3_defconfig
@@ -0,0 +1,124 @@
+CONFIG_MIPS_SEAD3=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_CPU_MIPS32_R2=y
+CONFIG_HZ_100=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=15
+CONFIG_EMBEDDED=y
+CONFIG_SLAB=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_MODULES=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_GLUEBI=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_SCSI=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_SMSC911X=y
+# CONFIG_NET_VENDOR_WIZNET is not set
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+CONFIG_VITESSE_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_ICPLUS_PHY=y
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_CONSOLE_TRANSLATIONS is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_LEGACY_PTY_COUNT=32
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_SPI=y
+CONFIG_SENSORS_ADT7475=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_STORAGE=y
+CONFIG_MMC=y
+CONFIG_MMC_DEBUG=y
+CONFIG_MMC_SPI=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_M41T80=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_XFS_FS=y
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_QUOTA=y
+# CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_UTF8=y
+# CONFIG_FTRACE is not set
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
index ca400f7..63002a2 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -95,8 +95,8 @@
 #ifndef cpu_has_smartmips
 #define cpu_has_smartmips      (cpu_data[0].ases & MIPS_ASE_SMARTMIPS)
 #endif
-#ifndef kernel_uses_smartmips_rixi
-#define kernel_uses_smartmips_rixi 0
+#ifndef cpu_has_rixi
+#define cpu_has_rixi		(cpu_data[0].options & MIPS_CPU_RIXI)
 #endif
 #ifndef cpu_has_vtag_icache
 #define cpu_has_vtag_icache	(cpu_data[0].icache.flags & MIPS_CACHE_VTAG)
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
index f21b7c0..554e2d2 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -94,6 +94,7 @@
 #define PRID_IMP_24KE		0x9600
 #define PRID_IMP_74K		0x9700
 #define PRID_IMP_1004K		0x9900
+#define PRID_IMP_1074K		0x9a00
 #define PRID_IMP_M14KC		0x9c00
 
 /*
@@ -319,6 +320,7 @@
 #define MIPS_CPU_VINT		0x00080000 /* CPU supports MIPSR2 vectored interrupts */
 #define MIPS_CPU_VEIC		0x00100000 /* CPU supports MIPSR2 external interrupt controller mode */
 #define MIPS_CPU_ULRI		0x00200000 /* CPU has ULRI feature */
+#define MIPS_CPU_RIXI		0x00400000 /* CPU has TLB Read/eXec Inhibit */
 
 /*
  * CPU ASE encodings
diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h
index 991b659..37620db 100644
--- a/arch/mips/include/asm/gic.h
+++ b/arch/mips/include/asm/gic.h
@@ -33,13 +33,13 @@
 	REG32(_gic_base + segment##_##SECTION_OFS + offset)
 
 #define GIC_ABS_REG(segment, offset) \
-       (_gic_base + segment##_##SECTION_OFS + offset##_##OFS)
+	(_gic_base + segment##_##SECTION_OFS + offset##_##OFS)
 #define GIC_REG_ABS_ADDR(segment, offset) \
-       (_gic_base + segment##_##SECTION_OFS + offset)
+	(_gic_base + segment##_##SECTION_OFS + offset)
 
 #ifdef GICISBYTELITTLEENDIAN
-#define GICREAD(reg, data)	(data) = (reg), (data) = le32_to_cpu(data)
-#define GICWRITE(reg, data)	(reg) = cpu_to_le32(data)
+#define GICREAD(reg, data)	((data) = (reg), (data) = le32_to_cpu(data))
+#define GICWRITE(reg, data)	((reg) = cpu_to_le32(data))
 #define GICBIS(reg, bits)			\
 	({unsigned int data;			\
 		GICREAD(reg, data);		\
@@ -48,9 +48,9 @@
 	})
 
 #else
-#define GICREAD(reg, data)	(data) = (reg)
-#define GICWRITE(reg, data)	(reg) = (data)
-#define GICBIS(reg, bits)	(reg) |= (bits)
+#define GICREAD(reg, data)	((data) = (reg))
+#define GICWRITE(reg, data)	((reg) = (data))
+#define GICBIS(reg, bits)	((reg) |= (bits))
 #endif
 
 
@@ -304,15 +304,15 @@
 		 GIC_SH_MAP_TO_VPE_REG_BIT(vpe))
 
 struct gic_pcpu_mask {
-       DECLARE_BITMAP(pcpu_mask, GIC_NUM_INTRS);
+	DECLARE_BITMAP(pcpu_mask, GIC_NUM_INTRS);
 };
 
 struct gic_pending_regs {
-       DECLARE_BITMAP(pending, GIC_NUM_INTRS);
+	DECLARE_BITMAP(pending, GIC_NUM_INTRS);
 };
 
 struct gic_intrmask_regs {
-       DECLARE_BITMAP(intrmask, GIC_NUM_INTRS);
+	DECLARE_BITMAP(intrmask, GIC_NUM_INTRS);
 };
 
 /*
@@ -341,15 +341,44 @@
 	unsigned int local_intr_mask;
 };
 
+/* GIC nomenclature for Core Interrupt Pins. */
+#define GIC_CPU_INT0		0 /* Core Interrupt 2 */
+#define GIC_CPU_INT1		1 /* .                */
+#define GIC_CPU_INT2		2 /* .                */
+#define GIC_CPU_INT3		3 /* .                */
+#define GIC_CPU_INT4		4 /* .                */
+#define GIC_CPU_INT5		5 /* Core Interrupt 5 */
+
+/* Local GIC interrupts. */
+#define GIC_INT_TMR		(GIC_CPU_INT5)
+#define GIC_INT_PERFCTR		(GIC_CPU_INT5)
+
+/* Add 2 to convert non-EIC hardware interrupt to EIC vector number. */
+#define GIC_CPU_TO_VEC_OFFSET	(2)
+
+/* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */
+#define GIC_PIN_TO_VEC_OFFSET	(1)
+
+extern unsigned long _gic_base;
+extern unsigned int gic_irq_base;
+extern unsigned int gic_irq_flags[];
+extern struct gic_shared_intr_map gic_shared_intr_map[];
+
 extern void gic_init(unsigned long gic_base_addr,
 	unsigned long gic_addrspace_size, struct gic_intr_map *intrmap,
 	unsigned int intrmap_size, unsigned int irqbase);
 
+extern void gic_clocksource_init(unsigned int);
 extern unsigned int gic_get_int(void);
 extern void gic_send_ipi(unsigned int intr);
 extern unsigned int plat_ipi_call_int_xlate(unsigned int);
 extern unsigned int plat_ipi_resched_int_xlate(unsigned int);
 extern void gic_bind_eic_interrupt(int irq, int set);
 extern unsigned int gic_get_timer_pending(void);
+extern void gic_enable_interrupt(int irq_vec);
+extern void gic_disable_interrupt(int irq_vec);
+extern void gic_irq_ack(struct irq_data *d);
+extern void gic_finish_irq(struct irq_data *d);
+extern void gic_platform_init(int irqs, struct irq_chip *irq_controller);
 
 #endif /* _ASM_GICREGS_H */
diff --git a/arch/mips/include/asm/hugetlb.h b/arch/mips/include/asm/hugetlb.h
index 58d3688..bd94946 100644
--- a/arch/mips/include/asm/hugetlb.h
+++ b/arch/mips/include/asm/hugetlb.h
@@ -112,4 +112,8 @@
 {
 }
 
+static inline void arch_clear_hugepage_flags(struct page *page)
+{
+}
+
 #endif /* __ASM_HUGETLB_H */
diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
index dde5044..a5e0f17 100644
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -63,6 +63,10 @@
 
 #define AR934X_WMAC_BASE	(AR71XX_APB_BASE + 0x00100000)
 #define AR934X_WMAC_SIZE	0x20000
+#define AR934X_EHCI_BASE	0x1b000000
+#define AR934X_EHCI_SIZE	0x200
+#define AR934X_SRIF_BASE	(AR71XX_APB_BASE + 0x00116000)
+#define AR934X_SRIF_SIZE	0x1000
 
 /*
  * DDR_CTRL block
@@ -288,6 +292,11 @@
 #define AR933X_RESET_USB_PHY		BIT(4)
 #define AR933X_RESET_USBSUS_OVERRIDE	BIT(3)
 
+#define AR934X_RESET_USB_PHY_ANALOG	BIT(11)
+#define AR934X_RESET_USB_HOST		BIT(5)
+#define AR934X_RESET_USB_PHY		BIT(4)
+#define AR934X_RESET_USBSUS_OVERRIDE	BIT(3)
+
 #define AR933X_BOOTSTRAP_REF_CLK_40	BIT(0)
 
 #define AR934X_BOOTSTRAP_SW_OPTION8	BIT(23)
@@ -399,4 +408,25 @@
 #define AR933X_GPIO_COUNT		30
 #define AR934X_GPIO_COUNT		23
 
+/*
+ * SRIF block
+ */
+#define AR934X_SRIF_CPU_DPLL1_REG	0x1c0
+#define AR934X_SRIF_CPU_DPLL2_REG	0x1c4
+#define AR934X_SRIF_CPU_DPLL3_REG	0x1c8
+
+#define AR934X_SRIF_DDR_DPLL1_REG	0x240
+#define AR934X_SRIF_DDR_DPLL2_REG	0x244
+#define AR934X_SRIF_DDR_DPLL3_REG	0x248
+
+#define AR934X_SRIF_DPLL1_REFDIV_SHIFT	27
+#define AR934X_SRIF_DPLL1_REFDIV_MASK	0x1f
+#define AR934X_SRIF_DPLL1_NINT_SHIFT	18
+#define AR934X_SRIF_DPLL1_NINT_MASK	0x1ff
+#define AR934X_SRIF_DPLL1_NFRAC_MASK	0x0003ffff
+
+#define AR934X_SRIF_DPLL2_LOCAL_PLL	BIT(30)
+#define AR934X_SRIF_DPLL2_OUTDIV_SHIFT	13
+#define AR934X_SRIF_DPLL2_OUTDIV_MASK	0x7
+
 #endif /* __ASM_MACH_AR71XX_REGS_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
index e104ddb..dbd5b5a 100644
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
@@ -120,6 +120,8 @@
 	RSET_OHCI0,
 	RSET_OHCI_PRIV,
 	RSET_USBH_PRIV,
+	RSET_USBD,
+	RSET_USBDMA,
 	RSET_MPI,
 	RSET_PCMCIA,
 	RSET_PCIE,
@@ -162,6 +164,8 @@
 #define RSET_UDC_SIZE			256
 #define RSET_OHCI_SIZE			256
 #define RSET_EHCI_SIZE			256
+#define RSET_USBD_SIZE			256
+#define RSET_USBDMA_SIZE		1280
 #define RSET_PCMCIA_SIZE		12
 #define RSET_M2M_SIZE			256
 #define RSET_ATM_SIZE			4096
@@ -183,10 +187,11 @@
 #define BCM_6328_GPIO_BASE		(0xb0000080)
 #define BCM_6328_SPI_BASE		(0xdeadbeef)
 #define BCM_6328_UDC0_BASE		(0xdeadbeef)
-#define BCM_6328_USBDMA_BASE		(0xdeadbeef)
-#define BCM_6328_OHCI0_BASE		(0xdeadbeef)
+#define BCM_6328_USBDMA_BASE		(0xb000c000)
+#define BCM_6328_OHCI0_BASE		(0xb0002600)
 #define BCM_6328_OHCI_PRIV_BASE		(0xdeadbeef)
-#define BCM_6328_USBH_PRIV_BASE		(0xdeadbeef)
+#define BCM_6328_USBH_PRIV_BASE		(0xb0002700)
+#define BCM_6328_USBD_BASE		(0xb0002400)
 #define BCM_6328_MPI_BASE		(0xdeadbeef)
 #define BCM_6328_PCMCIA_BASE		(0xdeadbeef)
 #define BCM_6328_PCIE_BASE		(0xb0e40000)
@@ -199,7 +204,7 @@
 #define BCM_6328_ENETDMAC_BASE		(0xb000da00)
 #define BCM_6328_ENETDMAS_BASE		(0xb000dc00)
 #define BCM_6328_ENETSW_BASE		(0xb0e00000)
-#define BCM_6328_EHCI0_BASE		(0x10002500)
+#define BCM_6328_EHCI0_BASE		(0xb0002500)
 #define BCM_6328_SDRAM_BASE		(0xdeadbeef)
 #define BCM_6328_MEMC_BASE		(0xdeadbeef)
 #define BCM_6328_DDR_BASE		(0xb0003000)
@@ -232,6 +237,7 @@
 #define BCM_6338_OHCI0_BASE		(0xdeadbeef)
 #define BCM_6338_OHCI_PRIV_BASE		(0xfffe3000)
 #define BCM_6338_USBH_PRIV_BASE		(0xdeadbeef)
+#define BCM_6338_USBD_BASE		(0xdeadbeef)
 #define BCM_6338_MPI_BASE		(0xfffe3160)
 #define BCM_6338_PCMCIA_BASE		(0xdeadbeef)
 #define BCM_6338_PCIE_BASE		(0xdeadbeef)
@@ -286,6 +292,7 @@
 #define BCM_6345_OHCI0_BASE		(0xfffe2100)
 #define BCM_6345_OHCI_PRIV_BASE		(0xfffe2200)
 #define BCM_6345_USBH_PRIV_BASE		(0xdeadbeef)
+#define BCM_6345_USBD_BASE		(0xdeadbeef)
 #define BCM_6345_SDRAM_REGS_BASE	(0xfffe2300)
 #define BCM_6345_DSL_BASE		(0xdeadbeef)
 #define BCM_6345_UBUS_BASE		(0xdeadbeef)
@@ -319,9 +326,11 @@
 #define BCM_6348_GPIO_BASE		(0xfffe0400)
 #define BCM_6348_SPI_BASE		(0xfffe0c00)
 #define BCM_6348_UDC0_BASE		(0xfffe1000)
+#define BCM_6348_USBDMA_BASE		(0xdeadbeef)
 #define BCM_6348_OHCI0_BASE		(0xfffe1b00)
 #define BCM_6348_OHCI_PRIV_BASE		(0xfffe1c00)
 #define BCM_6348_USBH_PRIV_BASE		(0xdeadbeef)
+#define BCM_6348_USBD_BASE		(0xdeadbeef)
 #define BCM_6348_MPI_BASE		(0xfffe2000)
 #define BCM_6348_PCMCIA_BASE		(0xfffe2054)
 #define BCM_6348_PCIE_BASE		(0xdeadbeef)
@@ -362,9 +371,11 @@
 #define BCM_6358_GPIO_BASE		(0xfffe0080)
 #define BCM_6358_SPI_BASE		(0xfffe0800)
 #define BCM_6358_UDC0_BASE		(0xfffe0800)
+#define BCM_6358_USBDMA_BASE		(0xdeadbeef)
 #define BCM_6358_OHCI0_BASE		(0xfffe1400)
 #define BCM_6358_OHCI_PRIV_BASE		(0xdeadbeef)
 #define BCM_6358_USBH_PRIV_BASE		(0xfffe1500)
+#define BCM_6358_USBD_BASE		(0xdeadbeef)
 #define BCM_6358_MPI_BASE		(0xfffe1000)
 #define BCM_6358_PCMCIA_BASE		(0xfffe1054)
 #define BCM_6358_PCIE_BASE		(0xdeadbeef)
@@ -406,9 +417,11 @@
 #define BCM_6368_GPIO_BASE		(0xb0000080)
 #define BCM_6368_SPI_BASE		(0xb0000800)
 #define BCM_6368_UDC0_BASE		(0xdeadbeef)
+#define BCM_6368_USBDMA_BASE		(0xb0004800)
 #define BCM_6368_OHCI0_BASE		(0xb0001600)
 #define BCM_6368_OHCI_PRIV_BASE		(0xdeadbeef)
 #define BCM_6368_USBH_PRIV_BASE		(0xb0001700)
+#define BCM_6368_USBD_BASE		(0xb0001400)
 #define BCM_6368_MPI_BASE		(0xb0001000)
 #define BCM_6368_PCMCIA_BASE		(0xb0001054)
 #define BCM_6368_PCIE_BASE		(0xdeadbeef)
@@ -458,6 +471,8 @@
 	__GEN_RSET_BASE(__cpu, OHCI0)					\
 	__GEN_RSET_BASE(__cpu, OHCI_PRIV)				\
 	__GEN_RSET_BASE(__cpu, USBH_PRIV)				\
+	__GEN_RSET_BASE(__cpu, USBD)					\
+	__GEN_RSET_BASE(__cpu, USBDMA)					\
 	__GEN_RSET_BASE(__cpu, MPI)					\
 	__GEN_RSET_BASE(__cpu, PCMCIA)					\
 	__GEN_RSET_BASE(__cpu, PCIE)					\
@@ -499,6 +514,8 @@
 	[RSET_OHCI0]		= BCM_## __cpu ##_OHCI0_BASE,		\
 	[RSET_OHCI_PRIV]	= BCM_## __cpu ##_OHCI_PRIV_BASE,	\
 	[RSET_USBH_PRIV]	= BCM_## __cpu ##_USBH_PRIV_BASE,	\
+	[RSET_USBD]		= BCM_## __cpu ##_USBD_BASE,		\
+	[RSET_USBDMA]		= BCM_## __cpu ##_USBDMA_BASE,		\
 	[RSET_MPI]		= BCM_## __cpu ##_MPI_BASE,		\
 	[RSET_PCMCIA]		= BCM_## __cpu ##_PCMCIA_BASE,		\
 	[RSET_PCIE]		= BCM_## __cpu ##_PCIE_BASE,		\
@@ -569,6 +586,13 @@
 	IRQ_ENET_PHY,
 	IRQ_OHCI0,
 	IRQ_EHCI0,
+	IRQ_USBD,
+	IRQ_USBD_RXDMA0,
+	IRQ_USBD_TXDMA0,
+	IRQ_USBD_RXDMA1,
+	IRQ_USBD_TXDMA1,
+	IRQ_USBD_RXDMA2,
+	IRQ_USBD_TXDMA2,
 	IRQ_ENET0_RXDMA,
 	IRQ_ENET0_TXDMA,
 	IRQ_ENET1_RXDMA,
@@ -602,8 +626,15 @@
 #define BCM_6328_ENET0_IRQ		0
 #define BCM_6328_ENET1_IRQ		0
 #define BCM_6328_ENET_PHY_IRQ		(IRQ_INTERNAL_BASE + 12)
-#define BCM_6328_OHCI0_IRQ		(IRQ_INTERNAL_BASE + 9)
-#define BCM_6328_EHCI0_IRQ		(IRQ_INTERNAL_BASE + 10)
+#define BCM_6328_OHCI0_IRQ		(BCM_6328_HIGH_IRQ_BASE + 9)
+#define BCM_6328_EHCI0_IRQ		(BCM_6328_HIGH_IRQ_BASE + 10)
+#define BCM_6328_USBD_IRQ		(IRQ_INTERNAL_BASE + 4)
+#define BCM_6328_USBD_RXDMA0_IRQ	(IRQ_INTERNAL_BASE + 5)
+#define BCM_6328_USBD_TXDMA0_IRQ	(IRQ_INTERNAL_BASE + 6)
+#define BCM_6328_USBD_RXDMA1_IRQ	(IRQ_INTERNAL_BASE + 7)
+#define BCM_6328_USBD_TXDMA1_IRQ	(IRQ_INTERNAL_BASE + 8)
+#define BCM_6328_USBD_RXDMA2_IRQ	(IRQ_INTERNAL_BASE + 9)
+#define BCM_6328_USBD_TXDMA2_IRQ	(IRQ_INTERNAL_BASE + 10)
 #define BCM_6328_PCMCIA_IRQ		0
 #define BCM_6328_ENET0_RXDMA_IRQ	0
 #define BCM_6328_ENET0_TXDMA_IRQ	0
@@ -615,10 +646,10 @@
 #define BCM_6328_ENETSW_RXDMA1_IRQ	(BCM_6328_HIGH_IRQ_BASE + 1)
 #define BCM_6328_ENETSW_RXDMA2_IRQ	(BCM_6328_HIGH_IRQ_BASE + 2)
 #define BCM_6328_ENETSW_RXDMA3_IRQ	(BCM_6328_HIGH_IRQ_BASE + 3)
-#define BCM_6328_ENETSW_TXDMA0_IRQ	(BCM_6328_HIGH_IRQ_BASE + 4)
-#define BCM_6328_ENETSW_TXDMA1_IRQ	(BCM_6328_HIGH_IRQ_BASE + 5)
-#define BCM_6328_ENETSW_TXDMA2_IRQ	(BCM_6328_HIGH_IRQ_BASE + 6)
-#define BCM_6328_ENETSW_TXDMA3_IRQ	(BCM_6328_HIGH_IRQ_BASE + 7)
+#define BCM_6328_ENETSW_TXDMA0_IRQ	0
+#define BCM_6328_ENETSW_TXDMA1_IRQ	0
+#define BCM_6328_ENETSW_TXDMA2_IRQ	0
+#define BCM_6328_ENETSW_TXDMA3_IRQ	0
 #define BCM_6328_XTM_IRQ		(BCM_6328_HIGH_IRQ_BASE + 31)
 #define BCM_6328_XTM_DMA0_IRQ		(BCM_6328_HIGH_IRQ_BASE + 11)
 
@@ -642,6 +673,13 @@
 #define BCM_6338_ENET_PHY_IRQ		(IRQ_INTERNAL_BASE + 9)
 #define BCM_6338_OHCI0_IRQ		0
 #define BCM_6338_EHCI0_IRQ		0
+#define BCM_6338_USBD_IRQ		0
+#define BCM_6338_USBD_RXDMA0_IRQ	0
+#define BCM_6338_USBD_TXDMA0_IRQ	0
+#define BCM_6338_USBD_RXDMA1_IRQ	0
+#define BCM_6338_USBD_TXDMA1_IRQ	0
+#define BCM_6338_USBD_RXDMA2_IRQ	0
+#define BCM_6338_USBD_TXDMA2_IRQ	0
 #define BCM_6338_ENET0_RXDMA_IRQ	(IRQ_INTERNAL_BASE + 15)
 #define BCM_6338_ENET0_TXDMA_IRQ	(IRQ_INTERNAL_BASE + 16)
 #define BCM_6338_ENET1_RXDMA_IRQ	0
@@ -673,6 +711,13 @@
 #define BCM_6345_ENET_PHY_IRQ		(IRQ_INTERNAL_BASE + 12)
 #define BCM_6345_OHCI0_IRQ		0
 #define BCM_6345_EHCI0_IRQ		0
+#define BCM_6345_USBD_IRQ		0
+#define BCM_6345_USBD_RXDMA0_IRQ	0
+#define BCM_6345_USBD_TXDMA0_IRQ	0
+#define BCM_6345_USBD_RXDMA1_IRQ	0
+#define BCM_6345_USBD_TXDMA1_IRQ	0
+#define BCM_6345_USBD_RXDMA2_IRQ	0
+#define BCM_6345_USBD_TXDMA2_IRQ	0
 #define BCM_6345_ENET0_RXDMA_IRQ	(IRQ_INTERNAL_BASE + 13 + 1)
 #define BCM_6345_ENET0_TXDMA_IRQ	(IRQ_INTERNAL_BASE + 13 + 2)
 #define BCM_6345_ENET1_RXDMA_IRQ	0
@@ -704,6 +749,13 @@
 #define BCM_6348_ENET_PHY_IRQ		(IRQ_INTERNAL_BASE + 9)
 #define BCM_6348_OHCI0_IRQ		(IRQ_INTERNAL_BASE + 12)
 #define BCM_6348_EHCI0_IRQ		0
+#define BCM_6348_USBD_IRQ		0
+#define BCM_6348_USBD_RXDMA0_IRQ	0
+#define BCM_6348_USBD_TXDMA0_IRQ	0
+#define BCM_6348_USBD_RXDMA1_IRQ	0
+#define BCM_6348_USBD_TXDMA1_IRQ	0
+#define BCM_6348_USBD_RXDMA2_IRQ	0
+#define BCM_6348_USBD_TXDMA2_IRQ	0
 #define BCM_6348_ENET0_RXDMA_IRQ	(IRQ_INTERNAL_BASE + 20)
 #define BCM_6348_ENET0_TXDMA_IRQ	(IRQ_INTERNAL_BASE + 21)
 #define BCM_6348_ENET1_RXDMA_IRQ	(IRQ_INTERNAL_BASE + 22)
@@ -735,6 +787,13 @@
 #define BCM_6358_ENET_PHY_IRQ		(IRQ_INTERNAL_BASE + 9)
 #define BCM_6358_OHCI0_IRQ		(IRQ_INTERNAL_BASE + 5)
 #define BCM_6358_EHCI0_IRQ		(IRQ_INTERNAL_BASE + 10)
+#define BCM_6358_USBD_IRQ		0
+#define BCM_6358_USBD_RXDMA0_IRQ	0
+#define BCM_6358_USBD_TXDMA0_IRQ	0
+#define BCM_6358_USBD_RXDMA1_IRQ	0
+#define BCM_6358_USBD_TXDMA1_IRQ	0
+#define BCM_6358_USBD_RXDMA2_IRQ	0
+#define BCM_6358_USBD_TXDMA2_IRQ	0
 #define BCM_6358_ENET0_RXDMA_IRQ	(IRQ_INTERNAL_BASE + 15)
 #define BCM_6358_ENET0_TXDMA_IRQ	(IRQ_INTERNAL_BASE + 16)
 #define BCM_6358_ENET1_RXDMA_IRQ	(IRQ_INTERNAL_BASE + 17)
@@ -775,6 +834,13 @@
 #define BCM_6368_ENET_PHY_IRQ		(IRQ_INTERNAL_BASE + 15)
 #define BCM_6368_OHCI0_IRQ		(IRQ_INTERNAL_BASE + 5)
 #define BCM_6368_EHCI0_IRQ		(IRQ_INTERNAL_BASE + 7)
+#define BCM_6368_USBD_IRQ		(IRQ_INTERNAL_BASE + 8)
+#define BCM_6368_USBD_RXDMA0_IRQ	(IRQ_INTERNAL_BASE + 26)
+#define BCM_6368_USBD_TXDMA0_IRQ	(IRQ_INTERNAL_BASE + 27)
+#define BCM_6368_USBD_RXDMA1_IRQ	(IRQ_INTERNAL_BASE + 28)
+#define BCM_6368_USBD_TXDMA1_IRQ	(IRQ_INTERNAL_BASE + 29)
+#define BCM_6368_USBD_RXDMA2_IRQ	(IRQ_INTERNAL_BASE + 30)
+#define BCM_6368_USBD_TXDMA2_IRQ	(IRQ_INTERNAL_BASE + 31)
 #define BCM_6368_PCMCIA_IRQ		0
 #define BCM_6368_ENET0_RXDMA_IRQ	0
 #define BCM_6368_ENET0_TXDMA_IRQ	0
@@ -815,6 +881,13 @@
 	[IRQ_ENET_PHY]		= BCM_## __cpu ##_ENET_PHY_IRQ,		\
 	[IRQ_OHCI0]		= BCM_## __cpu ##_OHCI0_IRQ,		\
 	[IRQ_EHCI0]		= BCM_## __cpu ##_EHCI0_IRQ,		\
+	[IRQ_USBD]		= BCM_## __cpu ##_USBD_IRQ,		\
+	[IRQ_USBD_RXDMA0]	= BCM_## __cpu ##_USBD_RXDMA0_IRQ,	\
+	[IRQ_USBD_TXDMA0]	= BCM_## __cpu ##_USBD_TXDMA0_IRQ,	\
+	[IRQ_USBD_RXDMA1]	= BCM_## __cpu ##_USBD_RXDMA1_IRQ,	\
+	[IRQ_USBD_TXDMA1]	= BCM_## __cpu ##_USBD_TXDMA1_IRQ,	\
+	[IRQ_USBD_RXDMA2]	= BCM_## __cpu ##_USBD_RXDMA2_IRQ,	\
+	[IRQ_USBD_TXDMA2]	= BCM_## __cpu ##_USBD_TXDMA2_IRQ,	\
 	[IRQ_ENET0_RXDMA]	= BCM_## __cpu ##_ENET0_RXDMA_IRQ,	\
 	[IRQ_ENET0_TXDMA]	= BCM_## __cpu ##_ENET0_TXDMA_IRQ,	\
 	[IRQ_ENET1_RXDMA]	= BCM_## __cpu ##_ENET1_RXDMA_IRQ,	\
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_usb_usbd.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_usb_usbd.h
new file mode 100644
index 0000000..5d6d698
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_usb_usbd.h
@@ -0,0 +1,17 @@
+#ifndef BCM63XX_DEV_USB_USBD_H_
+#define BCM63XX_DEV_USB_USBD_H_
+
+/*
+ * usb device platform data
+ */
+struct bcm63xx_usbd_platform_data {
+	/* board can only support full speed (USB 1.1) */
+	int use_fullspeed;
+
+	/* 0-based port index, for chips with >1 USB PHY */
+	int port_no;
+};
+
+int bcm63xx_usbd_register(const struct bcm63xx_usbd_platform_data *pd);
+
+#endif /* BCM63XX_DEV_USB_USBD_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_iudma.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_iudma.h
new file mode 100644
index 0000000..a5bbff3
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_iudma.h
@@ -0,0 +1,38 @@
+#ifndef BCM63XX_IUDMA_H_
+#define BCM63XX_IUDMA_H_
+
+#include <linux/types.h>
+
+/*
+ * rx/tx dma descriptor
+ */
+struct bcm_enet_desc {
+	u32 len_stat;
+	u32 address;
+};
+
+/* control */
+#define DMADESC_LENGTH_SHIFT	16
+#define DMADESC_LENGTH_MASK	(0xfff << DMADESC_LENGTH_SHIFT)
+#define DMADESC_OWNER_MASK	(1 << 15)
+#define DMADESC_EOP_MASK	(1 << 14)
+#define DMADESC_SOP_MASK	(1 << 13)
+#define DMADESC_ESOP_MASK	(DMADESC_EOP_MASK | DMADESC_SOP_MASK)
+#define DMADESC_WRAP_MASK	(1 << 12)
+#define DMADESC_USB_NOZERO_MASK	(1 << 1)
+#define DMADESC_USB_ZERO_MASK	(1 << 0)
+
+/* status */
+#define DMADESC_UNDER_MASK	(1 << 9)
+#define DMADESC_APPEND_CRC	(1 << 8)
+#define DMADESC_OVSIZE_MASK	(1 << 4)
+#define DMADESC_RXER_MASK	(1 << 2)
+#define DMADESC_CRC_MASK	(1 << 1)
+#define DMADESC_OV_MASK		(1 << 0)
+#define DMADESC_ERR_MASK	(DMADESC_UNDER_MASK | \
+				DMADESC_OVSIZE_MASK | \
+				DMADESC_RXER_MASK | \
+				DMADESC_CRC_MASK | \
+				DMADESC_OV_MASK)
+
+#endif /* ! BCM63XX_IUDMA_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
index 61f2a2a..12963d0 100644
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -161,6 +161,7 @@
 /* External Interrupt Configuration register */
 #define PERF_EXTIRQ_CFG_REG_6328	0x18
 #define PERF_EXTIRQ_CFG_REG_6338	0x14
+#define PERF_EXTIRQ_CFG_REG_6345	0x14
 #define PERF_EXTIRQ_CFG_REG_6348	0x14
 #define PERF_EXTIRQ_CFG_REG_6358	0x14
 #define PERF_EXTIRQ_CFG_REG_6368	0x18
@@ -543,6 +544,12 @@
 #define GPIO_MODE_6368_SPI_SSN5		(1 << 31)
 
 
+#define GPIO_PINMUX_OTHR_REG		0x24
+#define GPIO_PINMUX_OTHR_6328_USB_SHIFT	12
+#define GPIO_PINMUX_OTHR_6328_USB_MASK	(3 << GPIO_PINMUX_OTHR_6328_USB_SHIFT)
+#define GPIO_PINMUX_OTHR_6328_USB_HOST	(1 << GPIO_PINMUX_OTHR_6328_USB_SHIFT)
+#define GPIO_PINMUX_OTHR_6328_USB_DEV	(2 << GPIO_PINMUX_OTHR_6328_USB_SHIFT)
+
 #define GPIO_BASEMODE_6368_REG		0x38
 #define GPIO_BASEMODE_6368_UART2	0x1
 #define GPIO_BASEMODE_6368_GPIO		0x0
@@ -670,6 +677,12 @@
 #define ENETDMA_BUFALLOC_FORCE_SHIFT	31
 #define ENETDMA_BUFALLOC_FORCE_MASK	(1 << ENETDMA_BUFALLOC_FORCE_SHIFT)
 
+/* Global interrupt status */
+#define ENETDMA_GLB_IRQSTAT_REG		(0x40)
+
+/* Global interrupt mask */
+#define ENETDMA_GLB_IRQMASK_REG		(0x44)
+
 /* Channel Configuration register */
 #define ENETDMA_CHANCFG_REG(x)		(0x100 + (x) * 0x10)
 #define ENETDMA_CHANCFG_EN_SHIFT	0
@@ -709,9 +722,11 @@
 /* Channel Configuration register */
 #define ENETDMAC_CHANCFG_REG(x)		((x) * 0x10)
 #define ENETDMAC_CHANCFG_EN_SHIFT	0
-#define ENETDMAC_CHANCFG_EN_MASK	(1 << ENETDMA_CHANCFG_EN_SHIFT)
+#define ENETDMAC_CHANCFG_EN_MASK	(1 << ENETDMAC_CHANCFG_EN_SHIFT)
 #define ENETDMAC_CHANCFG_PKTHALT_SHIFT	1
-#define ENETDMAC_CHANCFG_PKTHALT_MASK	(1 << ENETDMA_CHANCFG_PKTHALT_SHIFT)
+#define ENETDMAC_CHANCFG_PKTHALT_MASK	(1 << ENETDMAC_CHANCFG_PKTHALT_SHIFT)
+#define ENETDMAC_CHANCFG_BUFHALT_SHIFT	2
+#define ENETDMAC_CHANCFG_BUFHALT_MASK	(1 << ENETDMAC_CHANCFG_BUFHALT_SHIFT)
 
 /* Interrupt Control/Status register */
 #define ENETDMAC_IR_REG(x)		(0x4 + (x) * 0x10)
@@ -770,6 +785,8 @@
 #define USBH_PRIV_SWAP_6358_REG		0x0
 #define USBH_PRIV_SWAP_6368_REG		0x1c
 
+#define USBH_PRIV_SWAP_USBD_SHIFT	6
+#define USBH_PRIV_SWAP_USBD_MASK	(1 << USBH_PRIV_SWAP_USBD_SHIFT)
 #define USBH_PRIV_SWAP_EHCI_ENDN_SHIFT	4
 #define USBH_PRIV_SWAP_EHCI_ENDN_MASK	(1 << USBH_PRIV_SWAP_EHCI_ENDN_SHIFT)
 #define USBH_PRIV_SWAP_EHCI_DATA_SHIFT	3
@@ -779,6 +796,12 @@
 #define USBH_PRIV_SWAP_OHCI_DATA_SHIFT	0
 #define USBH_PRIV_SWAP_OHCI_DATA_MASK	(1 << USBH_PRIV_SWAP_OHCI_DATA_SHIFT)
 
+#define USBH_PRIV_UTMI_CTL_6368_REG	0x10
+#define USBH_PRIV_UTMI_CTL_NODRIV_SHIFT	12
+#define USBH_PRIV_UTMI_CTL_NODRIV_MASK	(0xf << USBH_PRIV_UTMI_CTL_NODRIV_SHIFT)
+#define USBH_PRIV_UTMI_CTL_HOSTB_SHIFT	0
+#define USBH_PRIV_UTMI_CTL_HOSTB_MASK	(0xf << USBH_PRIV_UTMI_CTL_HOSTB_SHIFT)
+
 #define USBH_PRIV_TEST_6358_REG		0x24
 #define USBH_PRIV_TEST_6368_REG		0x14
 
@@ -787,6 +810,147 @@
 #define USBH_PRIV_SETUP_IOC_MASK	(1 << USBH_PRIV_SETUP_IOC_SHIFT)
 
 
+/*************************************************************************
+ * _REG relative to RSET_USBD
+ *************************************************************************/
+
+/* General control */
+#define USBD_CONTROL_REG		0x00
+#define USBD_CONTROL_TXZLENINS_SHIFT	14
+#define USBD_CONTROL_TXZLENINS_MASK	(1 << USBD_CONTROL_TXZLENINS_SHIFT)
+#define USBD_CONTROL_AUTO_CSRS_SHIFT	13
+#define USBD_CONTROL_AUTO_CSRS_MASK	(1 << USBD_CONTROL_AUTO_CSRS_SHIFT)
+#define USBD_CONTROL_RXZSCFG_SHIFT	12
+#define USBD_CONTROL_RXZSCFG_MASK	(1 << USBD_CONTROL_RXZSCFG_SHIFT)
+#define USBD_CONTROL_INIT_SEL_SHIFT	8
+#define USBD_CONTROL_INIT_SEL_MASK	(0xf << USBD_CONTROL_INIT_SEL_SHIFT)
+#define USBD_CONTROL_FIFO_RESET_SHIFT	6
+#define USBD_CONTROL_FIFO_RESET_MASK	(3 << USBD_CONTROL_FIFO_RESET_SHIFT)
+#define USBD_CONTROL_SETUPERRLOCK_SHIFT	5
+#define USBD_CONTROL_SETUPERRLOCK_MASK	(1 << USBD_CONTROL_SETUPERRLOCK_SHIFT)
+#define USBD_CONTROL_DONE_CSRS_SHIFT	0
+#define USBD_CONTROL_DONE_CSRS_MASK	(1 << USBD_CONTROL_DONE_CSRS_SHIFT)
+
+/* Strap options */
+#define USBD_STRAPS_REG			0x04
+#define USBD_STRAPS_APP_SELF_PWR_SHIFT	10
+#define USBD_STRAPS_APP_SELF_PWR_MASK	(1 << USBD_STRAPS_APP_SELF_PWR_SHIFT)
+#define USBD_STRAPS_APP_DISCON_SHIFT	9
+#define USBD_STRAPS_APP_DISCON_MASK	(1 << USBD_STRAPS_APP_DISCON_SHIFT)
+#define USBD_STRAPS_APP_CSRPRGSUP_SHIFT	8
+#define USBD_STRAPS_APP_CSRPRGSUP_MASK	(1 << USBD_STRAPS_APP_CSRPRGSUP_SHIFT)
+#define USBD_STRAPS_APP_RMTWKUP_SHIFT	6
+#define USBD_STRAPS_APP_RMTWKUP_MASK	(1 << USBD_STRAPS_APP_RMTWKUP_SHIFT)
+#define USBD_STRAPS_APP_RAM_IF_SHIFT	7
+#define USBD_STRAPS_APP_RAM_IF_MASK	(1 << USBD_STRAPS_APP_RAM_IF_SHIFT)
+#define USBD_STRAPS_APP_8BITPHY_SHIFT	2
+#define USBD_STRAPS_APP_8BITPHY_MASK	(1 << USBD_STRAPS_APP_8BITPHY_SHIFT)
+#define USBD_STRAPS_SPEED_SHIFT		0
+#define USBD_STRAPS_SPEED_MASK		(3 << USBD_STRAPS_SPEED_SHIFT)
+
+/* Stall control */
+#define USBD_STALL_REG			0x08
+#define USBD_STALL_UPDATE_SHIFT		7
+#define USBD_STALL_UPDATE_MASK		(1 << USBD_STALL_UPDATE_SHIFT)
+#define USBD_STALL_ENABLE_SHIFT		6
+#define USBD_STALL_ENABLE_MASK		(1 << USBD_STALL_ENABLE_SHIFT)
+#define USBD_STALL_EPNUM_SHIFT		0
+#define USBD_STALL_EPNUM_MASK		(0xf << USBD_STALL_EPNUM_SHIFT)
+
+/* General status */
+#define USBD_STATUS_REG			0x0c
+#define USBD_STATUS_SOF_SHIFT		16
+#define USBD_STATUS_SOF_MASK		(0x7ff << USBD_STATUS_SOF_SHIFT)
+#define USBD_STATUS_SPD_SHIFT		12
+#define USBD_STATUS_SPD_MASK		(3 << USBD_STATUS_SPD_SHIFT)
+#define USBD_STATUS_ALTINTF_SHIFT	8
+#define USBD_STATUS_ALTINTF_MASK	(0xf << USBD_STATUS_ALTINTF_SHIFT)
+#define USBD_STATUS_INTF_SHIFT		4
+#define USBD_STATUS_INTF_MASK		(0xf << USBD_STATUS_INTF_SHIFT)
+#define USBD_STATUS_CFG_SHIFT		0
+#define USBD_STATUS_CFG_MASK		(0xf << USBD_STATUS_CFG_SHIFT)
+
+/* Other events */
+#define USBD_EVENTS_REG			0x10
+#define USBD_EVENTS_USB_LINK_SHIFT	10
+#define USBD_EVENTS_USB_LINK_MASK	(1 << USBD_EVENTS_USB_LINK_SHIFT)
+
+/* IRQ status */
+#define USBD_EVENT_IRQ_STATUS_REG	0x14
+
+/* IRQ level (2 bits per IRQ event) */
+#define USBD_EVENT_IRQ_CFG_HI_REG	0x18
+
+#define USBD_EVENT_IRQ_CFG_LO_REG	0x1c
+
+#define USBD_EVENT_IRQ_CFG_SHIFT(x)	((x & 0xf) << 1)
+#define USBD_EVENT_IRQ_CFG_MASK(x)	(3 << USBD_EVENT_IRQ_CFG_SHIFT(x))
+#define USBD_EVENT_IRQ_CFG_RISING(x)	(0 << USBD_EVENT_IRQ_CFG_SHIFT(x))
+#define USBD_EVENT_IRQ_CFG_FALLING(x)	(1 << USBD_EVENT_IRQ_CFG_SHIFT(x))
+
+/* IRQ mask (1=unmasked) */
+#define USBD_EVENT_IRQ_MASK_REG		0x20
+
+/* IRQ bits */
+#define USBD_EVENT_IRQ_USB_LINK		10
+#define USBD_EVENT_IRQ_SETCFG		9
+#define USBD_EVENT_IRQ_SETINTF		8
+#define USBD_EVENT_IRQ_ERRATIC_ERR	7
+#define USBD_EVENT_IRQ_SET_CSRS		6
+#define USBD_EVENT_IRQ_SUSPEND		5
+#define USBD_EVENT_IRQ_EARLY_SUSPEND	4
+#define USBD_EVENT_IRQ_SOF		3
+#define USBD_EVENT_IRQ_ENUM_ON		2
+#define USBD_EVENT_IRQ_SETUP		1
+#define USBD_EVENT_IRQ_USB_RESET	0
+
+/* TX FIFO partitioning */
+#define USBD_TXFIFO_CONFIG_REG		0x40
+#define USBD_TXFIFO_CONFIG_END_SHIFT	16
+#define USBD_TXFIFO_CONFIG_END_MASK	(0xff << USBD_TXFIFO_CONFIG_END_SHIFT)
+#define USBD_TXFIFO_CONFIG_START_SHIFT	0
+#define USBD_TXFIFO_CONFIG_START_MASK	(0xff << USBD_TXFIFO_CONFIG_START_SHIFT)
+
+/* RX FIFO partitioning */
+#define USBD_RXFIFO_CONFIG_REG		0x44
+#define USBD_RXFIFO_CONFIG_END_SHIFT	16
+#define USBD_RXFIFO_CONFIG_END_MASK	(0xff << USBD_TXFIFO_CONFIG_END_SHIFT)
+#define USBD_RXFIFO_CONFIG_START_SHIFT	0
+#define USBD_RXFIFO_CONFIG_START_MASK	(0xff << USBD_TXFIFO_CONFIG_START_SHIFT)
+
+/* TX FIFO/endpoint configuration */
+#define USBD_TXFIFO_EPSIZE_REG		0x48
+
+/* RX FIFO/endpoint configuration */
+#define USBD_RXFIFO_EPSIZE_REG		0x4c
+
+/* Endpoint<->DMA mappings */
+#define USBD_EPNUM_TYPEMAP_REG		0x50
+#define USBD_EPNUM_TYPEMAP_TYPE_SHIFT	8
+#define USBD_EPNUM_TYPEMAP_TYPE_MASK	(0x3 << USBD_EPNUM_TYPEMAP_TYPE_SHIFT)
+#define USBD_EPNUM_TYPEMAP_DMA_CH_SHIFT	0
+#define USBD_EPNUM_TYPEMAP_DMA_CH_MASK	(0xf << USBD_EPNUM_TYPEMAP_DMACH_SHIFT)
+
+/* Misc per-endpoint settings */
+#define USBD_CSR_SETUPADDR_REG		0x80
+#define USBD_CSR_SETUPADDR_DEF		0xb550
+
+#define USBD_CSR_EP_REG(x)		(0x84 + (x) * 4)
+#define USBD_CSR_EP_MAXPKT_SHIFT	19
+#define USBD_CSR_EP_MAXPKT_MASK		(0x7ff << USBD_CSR_EP_MAXPKT_SHIFT)
+#define USBD_CSR_EP_ALTIFACE_SHIFT	15
+#define USBD_CSR_EP_ALTIFACE_MASK	(0xf << USBD_CSR_EP_ALTIFACE_SHIFT)
+#define USBD_CSR_EP_IFACE_SHIFT		11
+#define USBD_CSR_EP_IFACE_MASK		(0xf << USBD_CSR_EP_IFACE_SHIFT)
+#define USBD_CSR_EP_CFG_SHIFT		7
+#define USBD_CSR_EP_CFG_MASK		(0xf << USBD_CSR_EP_CFG_SHIFT)
+#define USBD_CSR_EP_TYPE_SHIFT		5
+#define USBD_CSR_EP_TYPE_MASK		(3 << USBD_CSR_EP_TYPE_SHIFT)
+#define USBD_CSR_EP_DIR_SHIFT		4
+#define USBD_CSR_EP_DIR_MASK		(1 << USBD_CSR_EP_DIR_SHIFT)
+#define USBD_CSR_EP_LOG_SHIFT		0
+#define USBD_CSR_EP_LOG_MASK		(0xf << USBD_CSR_EP_LOG_SHIFT)
+
 
 /*************************************************************************
  * _REG relative to RSET_MPI
diff --git a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
index 474daaa..b0dd4bb 100644
--- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
+++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
@@ -5,6 +5,7 @@
 #include <linux/gpio.h>
 #include <linux/leds.h>
 #include <bcm63xx_dev_enet.h>
+#include <bcm63xx_dev_usb_usbd.h>
 #include <bcm63xx_dev_dsp.h>
 
 /*
@@ -44,6 +45,7 @@
 	unsigned int	has_pccard:1;
 	unsigned int	has_ohci0:1;
 	unsigned int	has_ehci0:1;
+	unsigned int	has_usbd:1;
 	unsigned int	has_dsp:1;
 	unsigned int	has_uart0:1;
 	unsigned int	has_uart1:1;
@@ -52,6 +54,9 @@
 	struct bcm63xx_enet_platform_data enet0;
 	struct bcm63xx_enet_platform_data enet1;
 
+	/* USB config */
+	struct bcm63xx_usbd_platform_data usbd;
+
 	/* DSP config */
 	struct bcm63xx_dsp_platform_data dsp;
 
diff --git a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
index a58addb..375ad0c 100644
--- a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
@@ -58,7 +58,7 @@
 #define cpu_has_veic		0
 #define cpu_hwrena_impl_bits	0xc0000000
 
-#define kernel_uses_smartmips_rixi (cpu_data[0].cputype != CPU_CAVIUM_OCTEON)
+#define cpu_has_rixi		(cpu_data[0].cputype != CPU_CAVIUM_OCTEON)
 
 #define ARCH_HAS_IRQ_PER_CPU	1
 #define ARCH_HAS_SPINLOCK_PREFETCH 1
diff --git a/arch/mips/include/asm/mach-cavium-octeon/irq.h b/arch/mips/include/asm/mach-cavium-octeon/irq.h
index c22a307..ff0d490 100644
--- a/arch/mips/include/asm/mach-cavium-octeon/irq.h
+++ b/arch/mips/include/asm/mach-cavium-octeon/irq.h
@@ -21,10 +21,11 @@
 	OCTEON_IRQ_TIMER,
 /* sources in CIU_INTX_EN0 */
 	OCTEON_IRQ_WORKQ0,
-	OCTEON_IRQ_WDOG0 = OCTEON_IRQ_WORKQ0 + 16,
-	OCTEON_IRQ_WDOG15 = OCTEON_IRQ_WDOG0 + 15,
-	OCTEON_IRQ_MBOX0 = OCTEON_IRQ_WDOG0 + 16,
+	OCTEON_IRQ_WDOG0 = OCTEON_IRQ_WORKQ0 + 64,
+	OCTEON_IRQ_MBOX0 = OCTEON_IRQ_WDOG0 + 32,
 	OCTEON_IRQ_MBOX1,
+	OCTEON_IRQ_MBOX2,
+	OCTEON_IRQ_MBOX3,
 	OCTEON_IRQ_PCI_INT0,
 	OCTEON_IRQ_PCI_INT1,
 	OCTEON_IRQ_PCI_INT2,
diff --git a/arch/mips/include/asm/mach-jz4740/platform.h b/arch/mips/include/asm/mach-jz4740/platform.h
index 564ab81..163e81d 100644
--- a/arch/mips/include/asm/mach-jz4740/platform.h
+++ b/arch/mips/include/asm/mach-jz4740/platform.h
@@ -31,6 +31,7 @@
 extern struct platform_device jz4740_codec_device;
 extern struct platform_device jz4740_adc_device;
 extern struct platform_device jz4740_wdt_device;
+extern struct platform_device jz4740_pwm_device;
 
 void jz4740_serial_device_register(void);
 
diff --git a/arch/mips/include/asm/mach-jz4740/timer.h b/arch/mips/include/asm/mach-jz4740/timer.h
index 9baa03c..a7759fb 100644
--- a/arch/mips/include/asm/mach-jz4740/timer.h
+++ b/arch/mips/include/asm/mach-jz4740/timer.h
@@ -16,7 +16,120 @@
 #ifndef __ASM_MACH_JZ4740_TIMER
 #define __ASM_MACH_JZ4740_TIMER
 
+#define JZ_REG_TIMER_STOP		0x0C
+#define JZ_REG_TIMER_STOP_SET		0x1C
+#define JZ_REG_TIMER_STOP_CLEAR		0x2C
+#define JZ_REG_TIMER_ENABLE		0x00
+#define JZ_REG_TIMER_ENABLE_SET		0x04
+#define JZ_REG_TIMER_ENABLE_CLEAR	0x08
+#define JZ_REG_TIMER_FLAG		0x10
+#define JZ_REG_TIMER_FLAG_SET		0x14
+#define JZ_REG_TIMER_FLAG_CLEAR		0x18
+#define JZ_REG_TIMER_MASK		0x20
+#define JZ_REG_TIMER_MASK_SET		0x24
+#define JZ_REG_TIMER_MASK_CLEAR		0x28
+
+#define JZ_REG_TIMER_DFR(x) (((x) * 0x10) + 0x30)
+#define JZ_REG_TIMER_DHR(x) (((x) * 0x10) + 0x34)
+#define JZ_REG_TIMER_CNT(x) (((x) * 0x10) + 0x38)
+#define JZ_REG_TIMER_CTRL(x) (((x) * 0x10) + 0x3C)
+
+#define JZ_TIMER_IRQ_HALF(x) BIT((x) + 0x10)
+#define JZ_TIMER_IRQ_FULL(x) BIT(x)
+
+#define JZ_TIMER_CTRL_PWM_ABBRUPT_SHUTDOWN	BIT(9)
+#define JZ_TIMER_CTRL_PWM_ACTIVE_LOW		BIT(8)
+#define JZ_TIMER_CTRL_PWM_ENABLE		BIT(7)
+#define JZ_TIMER_CTRL_PRESCALE_MASK		0x1c
+#define JZ_TIMER_CTRL_PRESCALE_OFFSET		0x3
+#define JZ_TIMER_CTRL_PRESCALE_1		(0 << 3)
+#define JZ_TIMER_CTRL_PRESCALE_4		(1 << 3)
+#define JZ_TIMER_CTRL_PRESCALE_16		(2 << 3)
+#define JZ_TIMER_CTRL_PRESCALE_64		(3 << 3)
+#define JZ_TIMER_CTRL_PRESCALE_256		(4 << 3)
+#define JZ_TIMER_CTRL_PRESCALE_1024		(5 << 3)
+
+#define JZ_TIMER_CTRL_PRESCALER(x) ((x) << JZ_TIMER_CTRL_PRESCALE_OFFSET)
+
+#define JZ_TIMER_CTRL_SRC_EXT		BIT(2)
+#define JZ_TIMER_CTRL_SRC_RTC		BIT(1)
+#define JZ_TIMER_CTRL_SRC_PCLK		BIT(0)
+
+extern void __iomem *jz4740_timer_base;
+void __init jz4740_timer_init(void);
+
 void jz4740_timer_enable_watchdog(void);
 void jz4740_timer_disable_watchdog(void);
 
+static inline void jz4740_timer_stop(unsigned int timer)
+{
+	writel(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_STOP_SET);
+}
+
+static inline void jz4740_timer_start(unsigned int timer)
+{
+	writel(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_STOP_CLEAR);
+}
+
+static inline bool jz4740_timer_is_enabled(unsigned int timer)
+{
+	return readb(jz4740_timer_base + JZ_REG_TIMER_ENABLE) & BIT(timer);
+}
+
+static inline void jz4740_timer_enable(unsigned int timer)
+{
+	writeb(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_ENABLE_SET);
+}
+
+static inline void jz4740_timer_disable(unsigned int timer)
+{
+	writeb(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_ENABLE_CLEAR);
+}
+
+static inline void jz4740_timer_set_period(unsigned int timer, uint16_t period)
+{
+	writew(period, jz4740_timer_base + JZ_REG_TIMER_DFR(timer));
+}
+
+static inline void jz4740_timer_set_duty(unsigned int timer, uint16_t duty)
+{
+	writew(duty, jz4740_timer_base + JZ_REG_TIMER_DHR(timer));
+}
+
+static inline void jz4740_timer_set_count(unsigned int timer, uint16_t count)
+{
+	writew(count, jz4740_timer_base + JZ_REG_TIMER_CNT(timer));
+}
+
+static inline uint16_t jz4740_timer_get_count(unsigned int timer)
+{
+	return readw(jz4740_timer_base + JZ_REG_TIMER_CNT(timer));
+}
+
+static inline void jz4740_timer_ack_full(unsigned int timer)
+{
+	writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_FLAG_CLEAR);
+}
+
+static inline void jz4740_timer_irq_full_enable(unsigned int timer)
+{
+	writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_FLAG_CLEAR);
+	writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_CLEAR);
+}
+
+static inline void jz4740_timer_irq_full_disable(unsigned int timer)
+{
+	writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_SET);
+}
+
+static inline void jz4740_timer_set_ctrl(unsigned int timer, uint16_t ctrl)
+{
+	writew(ctrl, jz4740_timer_base + JZ_REG_TIMER_CTRL(timer));
+}
+
+static inline uint16_t jz4740_timer_get_ctrl(unsigned int timer)
+{
+	return readw(jz4740_timer_base + JZ_REG_TIMER_CTRL(timer));
+}
+
 #endif
diff --git a/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h b/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h
index 318f982..c6b63a4 100644
--- a/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h
+++ b/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h
@@ -20,4 +20,6 @@
 
 #define MIPS_CPU_TIMER_IRQ			7
 
+#define MAX_IM			5
+
 #endif /* _FALCON_IRQ__ */
diff --git a/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
index b385252..fccac35 100644
--- a/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
+++ b/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h
@@ -57,6 +57,10 @@
 #define ltq_sys1_w32_mask(clear, set, reg)   \
 	ltq_sys1_w32((ltq_sys1_r32(reg) & ~(clear)) | (set), reg)
 
+/* allow the gpio and pinctrl drivers to talk to eachother */
+extern int pinctrl_falcon_get_range_size(int id);
+extern void pinctrl_falcon_add_gpio_range(struct pinctrl_gpio_range *range);
+
 /*
  * to keep the irq code generic we need to define this to 0 as falcon
  * has no EIU/EBU
diff --git a/arch/mips/include/asm/mach-lantiq/gpio.h b/arch/mips/include/asm/mach-lantiq/gpio.h
index f79505b..9ba1cae 100644
--- a/arch/mips/include/asm/mach-lantiq/gpio.h
+++ b/arch/mips/include/asm/mach-lantiq/gpio.h
@@ -1,10 +1,7 @@
 #ifndef __ASM_MIPS_MACH_LANTIQ_GPIO_H
 #define __ASM_MIPS_MACH_LANTIQ_GPIO_H
 
-static inline int gpio_to_irq(unsigned int gpio)
-{
-	return -1;
-}
+#define gpio_to_irq __gpio_to_irq
 
 #define gpio_get_value __gpio_get_value
 #define gpio_set_value __gpio_set_value
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
index aa0b3b8..5eadfe5 100644
--- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
@@ -21,4 +21,6 @@
 
 #define MIPS_CPU_TIMER_IRQ	7
 
+#define MAX_IM			5
+
 #endif
diff --git a/arch/mips/include/asm/mach-mipssim/cpu-feature-overrides.h b/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h
similarity index 83%
rename from arch/mips/include/asm/mach-mipssim/cpu-feature-overrides.h
rename to arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h
index 27aaaa5..7f3e3f9 100644
--- a/arch/mips/include/asm/mach-mipssim/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h
@@ -4,9 +4,10 @@
  * for more details.
  *
  * Copyright (C) 2003, 2004 Chris Dearman
+ * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
  */
-#ifndef __ASM_MACH_SIM_CPU_FEATURE_OVERRIDES_H
-#define __ASM_MACH_SIM_CPU_FEATURE_OVERRIDES_H
+#ifndef __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H
 
 
 /*
@@ -16,7 +17,7 @@
 #define cpu_has_tlb		1
 #define cpu_has_4kex		1
 #define cpu_has_4k_cache	1
-#define cpu_has_fpu		0
+/* #define cpu_has_fpu		? */
 /* #define cpu_has_32fpr	? */
 #define cpu_has_counter		1
 /* #define cpu_has_watch	? */
@@ -27,15 +28,19 @@
 /* #define cpu_has_prefetch	? */
 #define cpu_has_mcheck		1
 /* #define cpu_has_ejtag	? */
+#ifdef CONFIG_CPU_HAS_LLSC
 #define cpu_has_llsc		1
+#else
+#define cpu_has_llsc		0
+#endif
 /* #define cpu_has_vtag_icache	? */
 /* #define cpu_has_dc_aliases	? */
 /* #define cpu_has_ic_fills_f_dc ? */
-#define cpu_has_clo_clz		1
 #define cpu_has_nofpuex		0
 /* #define cpu_has_64bits	? */
 /* #define cpu_has_64bit_zero_reg ? */
 /* #define cpu_has_inclusive_pcaches ? */
+#define cpu_icache_snoops_remote_store 1
 #endif
 
 #ifdef CONFIG_CPU_MIPS64
@@ -57,11 +62,11 @@
 /* #define cpu_has_vtag_icache	? */
 /* #define cpu_has_dc_aliases	? */
 /* #define cpu_has_ic_fills_f_dc ? */
-#define cpu_has_clo_clz		1
 #define cpu_has_nofpuex		0
 /* #define cpu_has_64bits	? */
 /* #define cpu_has_64bit_zero_reg ? */
 /* #define cpu_has_inclusive_pcaches ? */
+#define cpu_icache_snoops_remote_store 1
 #endif
 
 #endif /* __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-sead3/irq.h b/arch/mips/include/asm/mach-sead3/irq.h
new file mode 100644
index 0000000..652ea4c
--- /dev/null
+++ b/arch/mips/include/asm/mach-sead3/irq.h
@@ -0,0 +1,9 @@
+#ifndef __ASM_MACH_MIPS_IRQ_H
+#define __ASM_MACH_MIPS_IRQ_H
+
+#define NR_IRQS	256
+
+
+#include_next <irq.h>
+
+#endif /* __ASM_MACH_MIPS_IRQ_H */
diff --git a/arch/mips/include/asm/mach-sead3/kernel-entry-init.h b/arch/mips/include/asm/mach-sead3/kernel-entry-init.h
new file mode 100644
index 0000000..3dfbd8e
--- /dev/null
+++ b/arch/mips/include/asm/mach-sead3/kernel-entry-init.h
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ *
+ * Chris Dearman (chris@mips.com)
+ * Copyright (C) 2007 Mips Technologies, Inc.
+ */
+#ifndef __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H
+#define __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H
+
+	.macro	kernel_entry_setup
+#ifdef CONFIG_MIPS_MT_SMTC
+	mfc0	t0, CP0_CONFIG
+	bgez	t0, 9f
+	mfc0	t0, CP0_CONFIG, 1
+	bgez	t0, 9f
+	mfc0	t0, CP0_CONFIG, 2
+	bgez	t0, 9f
+	mfc0	t0, CP0_CONFIG, 3
+	and	t0, 1<<2
+	bnez	t0, 0f
+9 :
+	/* Assume we came from YAMON... */
+	PTR_LA	v0, 0x9fc00534	/* YAMON print */
+	lw	v0, (v0)
+	move	a0, zero
+	PTR_LA	a1, nonmt_processor
+	jal	v0
+
+	PTR_LA	v0, 0x9fc00520	/* YAMON exit */
+	lw	v0, (v0)
+	li	a0, 1
+	jal	v0
+
+1 :	b	1b
+
+	__INITDATA
+nonmt_processor :
+	.asciz	"SMTC kernel requires the MT ASE to run\n"
+	__FINIT
+0 :
+#endif
+	.endm
+
+/*
+ * Do SMP slave processor setup necessary before we can safely execute C code.
+ */
+	.macro	smp_slave_setup
+	.endm
+
+#endif /* __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H */
diff --git a/arch/mips/include/asm/mach-mipssim/war.h b/arch/mips/include/asm/mach-sead3/war.h
similarity index 72%
rename from arch/mips/include/asm/mach-mipssim/war.h
rename to arch/mips/include/asm/mach-sead3/war.h
index c8a74a3..7c6931d 100644
--- a/arch/mips/include/asm/mach-mipssim/war.h
+++ b/arch/mips/include/asm/mach-sead3/war.h
@@ -5,8 +5,8 @@
  *
  * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
  */
-#ifndef __ASM_MIPS_MACH_MIPSSIM_WAR_H
-#define __ASM_MIPS_MACH_MIPSSIM_WAR_H
+#ifndef __ASM_MIPS_MACH_MIPS_WAR_H
+#define __ASM_MIPS_MACH_MIPS_WAR_H
 
 #define R4600_V1_INDEX_ICACHEOP_WAR	0
 #define R4600_V1_HIT_CACHEOP_WAR	0
@@ -14,12 +14,12 @@
 #define R5432_CP0_INTERRUPT_WAR		0
 #define BCM1250_M3_WAR			0
 #define SIBYTE_1956_WAR			0
-#define MIPS4K_ICACHE_REFILL_WAR	0
-#define MIPS_CACHE_SYNC_WAR		0
+#define MIPS4K_ICACHE_REFILL_WAR	1
+#define MIPS_CACHE_SYNC_WAR		1
 #define TX49XX_ICACHE_INDEX_INV_WAR	0
 #define RM9000_CDEX_SMP_WAR		0
-#define ICACHE_REFILLS_WORKAROUND_WAR	0
+#define ICACHE_REFILLS_WORKAROUND_WAR	1
 #define R10000_LLSC_WAR			0
 #define MIPS34K_MISSED_ITLB_WAR		0
 
-#endif /* __ASM_MIPS_MACH_MIPSSIM_WAR_H */
+#endif /* __ASM_MIPS_MACH_MIPS_WAR_H */
diff --git a/arch/mips/include/asm/mips-boards/maltaint.h b/arch/mips/include/asm/mips-boards/maltaint.h
index 5447d9f..6692448 100644
--- a/arch/mips/include/asm/mips-boards/maltaint.h
+++ b/arch/mips/include/asm/mips-boards/maltaint.h
@@ -1,31 +1,16 @@
 /*
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ * 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.
  *
- * ########################################################################
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- * Defines for the Malta interrupt controller.
- *
+ * Copyright (C) 2000,2012 MIPS Technologies, Inc.  All rights reserved.
+ *      Carsten Langgaard <carstenl@mips.com>
+ *      Steven J. Hill <sjhill@mips.com>
  */
 #ifndef _MIPS_MALTAINT_H
 #define _MIPS_MALTAINT_H
 
-#include <irq.h>
+#define MIPS_GIC_IRQ_BASE	(MIPS_CPU_IRQ_BASE + 8)
 
 /*
  * Interrupts 0..15 are used for Malta ISA compatible interrupts
@@ -78,26 +63,6 @@
 #define MSC01E_INT_PERFCTR	10
 #define MSC01E_INT_CPUCTR	11
 
-/* GIC's Nomenclature for Core Interrupt Pins on the Malta */
-#define GIC_CPU_INT0		0 /* Core Interrupt 2 	*/
-#define GIC_CPU_INT1		1 /* .			*/
-#define GIC_CPU_INT2		2 /* .			*/
-#define GIC_CPU_INT3		3 /* .			*/
-#define GIC_CPU_INT4		4 /* .			*/
-#define GIC_CPU_INT5		5 /* Core Interrupt 5   */
-
-/* MALTA GIC local interrupts */
-#define GIC_INT_TMR             (GIC_CPU_INT5)
-#define GIC_INT_PERFCTR         (GIC_CPU_INT5)
-
-/* GIC constants */
-/* Add 2 to convert non-eic hw int # to eic vector # */
-#define GIC_CPU_TO_VEC_OFFSET   (2)
-/* If we map an intr to pin X, GIC will actually generate vector X+1 */
-#define GIC_PIN_TO_VEC_OFFSET   (1)
-
-#define GIC_EXT_INTR(x)		x
-
 /* External Interrupts used for IPI */
 #define GIC_IPI_EXT_INTR_RESCHED_VPE0	16
 #define GIC_IPI_EXT_INTR_CALLFNC_VPE0	17
@@ -108,10 +73,4 @@
 #define GIC_IPI_EXT_INTR_RESCHED_VPE3	22
 #define GIC_IPI_EXT_INTR_CALLFNC_VPE3	23
 
-#define MIPS_GIC_IRQ_BASE	(MIPS_CPU_IRQ_BASE + 8)
-
-#ifndef __ASSEMBLY__
-extern void maltaint_init(void);
-#endif
-
 #endif /* !(_MIPS_MALTAINT_H) */
diff --git a/arch/mips/include/asm/mips-boards/sead3int.h b/arch/mips/include/asm/mips-boards/sead3int.h
new file mode 100644
index 0000000..d634d9a
--- /dev/null
+++ b/arch/mips/include/asm/mips-boards/sead3int.h
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2000,2012 MIPS Technologies, Inc.  All rights reserved.
+ *      Douglas Leung <douglas@mips.com>
+ *      Steven J. Hill <sjhill@mips.com>
+ */
+#ifndef _MIPS_SEAD3INT_H
+#define _MIPS_SEAD3INT_H
+
+/* SEAD-3 GIC address space definitions. */
+#define GIC_BASE_ADDR		0x1b1c0000
+#define GIC_ADDRSPACE_SZ	(128 * 1024)
+
+#define MIPS_GIC_IRQ_BASE	(MIPS_CPU_IRQ_BASE + 0)
+
+#endif /* !(_MIPS_SEAD3INT_H) */
diff --git a/arch/mips/include/asm/mips-boards/simint.h b/arch/mips/include/asm/mips-boards/simint.h
deleted file mode 100644
index 8ef6db7..0000000
--- a/arch/mips/include/asm/mips-boards/simint.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2005 MIPS Technologies, Inc.  All rights reserved.
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-#ifndef _MIPS_SIMINT_H
-#define _MIPS_SIMINT_H
-
-#include <irq.h>
-
-#define SIM_INT_BASE		0
-#define MIPSCPU_INT_MB0		2
-#define MIPS_CPU_TIMER_IRQ	7
-
-
-#define MSC01E_INT_BASE		64
-
-#define MSC01E_INT_CPUCTR	11
-
-#endif
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 7f87d82..528fda1 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -590,12 +590,15 @@
 #define MIPS_CONF3_VEIC		(_ULCAST_(1) <<  6)
 #define MIPS_CONF3_LPA		(_ULCAST_(1) <<  7)
 #define MIPS_CONF3_DSP		(_ULCAST_(1) << 10)
+#define MIPS_CONF3_RXI		(_ULCAST_(1) << 12)
 #define MIPS_CONF3_ULRI		(_ULCAST_(1) << 13)
 
 #define MIPS_CONF4_MMUSIZEEXT	(_ULCAST_(255) << 0)
 #define MIPS_CONF4_MMUEXTDEF	(_ULCAST_(3) << 14)
 #define MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT (_ULCAST_(1) << 14)
 
+#define MIPS_CONF6_SYND		(_ULCAST_(1) << 13)
+
 #define MIPS_CONF7_WII		(_ULCAST_(1) << 31)
 
 #define MIPS_CONF7_RPS		(_ULCAST_(1) << 2)
diff --git a/arch/mips/include/asm/octeon/cvmx-agl-defs.h b/arch/mips/include/asm/octeon/cvmx-agl-defs.h
index 30d68f2..542ee09 100644
--- a/arch/mips/include/asm/octeon/cvmx-agl-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-agl-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -106,6 +106,7 @@
 union cvmx_agl_gmx_bad_reg {
 	uint64_t u64;
 	struct cvmx_agl_gmx_bad_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_38_63:26;
 		uint64_t txpsh1:1;
 		uint64_t txpop1:1;
@@ -120,8 +121,25 @@
 		uint64_t reserved_4_21:18;
 		uint64_t out_ovr:2;
 		uint64_t reserved_0_1:2;
+#else
+		uint64_t reserved_0_1:2;
+		uint64_t out_ovr:2;
+		uint64_t reserved_4_21:18;
+		uint64_t loststat:2;
+		uint64_t reserved_24_25:2;
+		uint64_t statovr:1;
+		uint64_t reserved_27_31:5;
+		uint64_t ovrflw:1;
+		uint64_t txpop:1;
+		uint64_t txpsh:1;
+		uint64_t ovrflw1:1;
+		uint64_t txpop1:1;
+		uint64_t txpsh1:1;
+		uint64_t reserved_38_63:26;
+#endif
 	} s;
 	struct cvmx_agl_gmx_bad_reg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_38_63:26;
 		uint64_t txpsh1:1;
 		uint64_t txpop1:1;
@@ -136,9 +154,26 @@
 		uint64_t reserved_4_21:18;
 		uint64_t out_ovr:2;
 		uint64_t reserved_0_1:2;
+#else
+		uint64_t reserved_0_1:2;
+		uint64_t out_ovr:2;
+		uint64_t reserved_4_21:18;
+		uint64_t loststat:1;
+		uint64_t reserved_23_25:3;
+		uint64_t statovr:1;
+		uint64_t reserved_27_31:5;
+		uint64_t ovrflw:1;
+		uint64_t txpop:1;
+		uint64_t txpsh:1;
+		uint64_t ovrflw1:1;
+		uint64_t txpop1:1;
+		uint64_t txpsh1:1;
+		uint64_t reserved_38_63:26;
+#endif
 	} cn52xx;
 	struct cvmx_agl_gmx_bad_reg_cn52xx cn52xxp1;
 	struct cvmx_agl_gmx_bad_reg_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_35_63:29;
 		uint64_t txpsh:1;
 		uint64_t txpop:1;
@@ -150,32 +185,64 @@
 		uint64_t reserved_3_21:19;
 		uint64_t out_ovr:1;
 		uint64_t reserved_0_1:2;
+#else
+		uint64_t reserved_0_1:2;
+		uint64_t out_ovr:1;
+		uint64_t reserved_3_21:19;
+		uint64_t loststat:1;
+		uint64_t reserved_23_25:3;
+		uint64_t statovr:1;
+		uint64_t reserved_27_31:5;
+		uint64_t ovrflw:1;
+		uint64_t txpop:1;
+		uint64_t txpsh:1;
+		uint64_t reserved_35_63:29;
+#endif
 	} cn56xx;
 	struct cvmx_agl_gmx_bad_reg_cn56xx cn56xxp1;
+	struct cvmx_agl_gmx_bad_reg_s cn61xx;
 	struct cvmx_agl_gmx_bad_reg_s cn63xx;
 	struct cvmx_agl_gmx_bad_reg_s cn63xxp1;
+	struct cvmx_agl_gmx_bad_reg_s cn66xx;
+	struct cvmx_agl_gmx_bad_reg_s cn68xx;
+	struct cvmx_agl_gmx_bad_reg_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_bist {
 	uint64_t u64;
 	struct cvmx_agl_gmx_bist_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_25_63:39;
 		uint64_t status:25;
+#else
+		uint64_t status:25;
+		uint64_t reserved_25_63:39;
+#endif
 	} s;
 	struct cvmx_agl_gmx_bist_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t status:10;
+#else
+		uint64_t status:10;
+		uint64_t reserved_10_63:54;
+#endif
 	} cn52xx;
 	struct cvmx_agl_gmx_bist_cn52xx cn52xxp1;
 	struct cvmx_agl_gmx_bist_cn52xx cn56xx;
 	struct cvmx_agl_gmx_bist_cn52xx cn56xxp1;
+	struct cvmx_agl_gmx_bist_s cn61xx;
 	struct cvmx_agl_gmx_bist_s cn63xx;
 	struct cvmx_agl_gmx_bist_s cn63xxp1;
+	struct cvmx_agl_gmx_bist_s cn66xx;
+	struct cvmx_agl_gmx_bist_s cn68xx;
+	struct cvmx_agl_gmx_bist_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_drv_ctl {
 	uint64_t u64;
 	struct cvmx_agl_gmx_drv_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_49_63:15;
 		uint64_t byp_en1:1;
 		uint64_t reserved_45_47:3;
@@ -188,16 +255,39 @@
 		uint64_t pctl:5;
 		uint64_t reserved_5_7:3;
 		uint64_t nctl:5;
+#else
+		uint64_t nctl:5;
+		uint64_t reserved_5_7:3;
+		uint64_t pctl:5;
+		uint64_t reserved_13_15:3;
+		uint64_t byp_en:1;
+		uint64_t reserved_17_31:15;
+		uint64_t nctl1:5;
+		uint64_t reserved_37_39:3;
+		uint64_t pctl1:5;
+		uint64_t reserved_45_47:3;
+		uint64_t byp_en1:1;
+		uint64_t reserved_49_63:15;
+#endif
 	} s;
 	struct cvmx_agl_gmx_drv_ctl_s cn52xx;
 	struct cvmx_agl_gmx_drv_ctl_s cn52xxp1;
 	struct cvmx_agl_gmx_drv_ctl_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_17_63:47;
 		uint64_t byp_en:1;
 		uint64_t reserved_13_15:3;
 		uint64_t pctl:5;
 		uint64_t reserved_5_7:3;
 		uint64_t nctl:5;
+#else
+		uint64_t nctl:5;
+		uint64_t reserved_5_7:3;
+		uint64_t pctl:5;
+		uint64_t reserved_13_15:3;
+		uint64_t byp_en:1;
+		uint64_t reserved_17_63:47;
+#endif
 	} cn56xx;
 	struct cvmx_agl_gmx_drv_ctl_cn56xx cn56xxp1;
 };
@@ -205,9 +295,15 @@
 union cvmx_agl_gmx_inf_mode {
 	uint64_t u64;
 	struct cvmx_agl_gmx_inf_mode_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t en:1;
 		uint64_t reserved_0_0:1;
+#else
+		uint64_t reserved_0_0:1;
+		uint64_t en:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_agl_gmx_inf_mode_s cn52xx;
 	struct cvmx_agl_gmx_inf_mode_s cn52xxp1;
@@ -218,6 +314,7 @@
 union cvmx_agl_gmx_prtx_cfg {
 	uint64_t u64;
 	struct cvmx_agl_gmx_prtx_cfg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_14_63:50;
 		uint64_t tx_idle:1;
 		uint64_t rx_idle:1;
@@ -231,8 +328,24 @@
 		uint64_t duplex:1;
 		uint64_t speed:1;
 		uint64_t en:1;
+#else
+		uint64_t en:1;
+		uint64_t speed:1;
+		uint64_t duplex:1;
+		uint64_t slottime:1;
+		uint64_t rx_en:1;
+		uint64_t tx_en:1;
+		uint64_t burst:1;
+		uint64_t reserved_7_7:1;
+		uint64_t speed_msb:1;
+		uint64_t reserved_9_11:3;
+		uint64_t rx_idle:1;
+		uint64_t tx_idle:1;
+		uint64_t reserved_14_63:50;
+#endif
 	} s;
 	struct cvmx_agl_gmx_prtx_cfg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t tx_en:1;
 		uint64_t rx_en:1;
@@ -240,139 +353,230 @@
 		uint64_t duplex:1;
 		uint64_t speed:1;
 		uint64_t en:1;
+#else
+		uint64_t en:1;
+		uint64_t speed:1;
+		uint64_t duplex:1;
+		uint64_t slottime:1;
+		uint64_t rx_en:1;
+		uint64_t tx_en:1;
+		uint64_t reserved_6_63:58;
+#endif
 	} cn52xx;
 	struct cvmx_agl_gmx_prtx_cfg_cn52xx cn52xxp1;
 	struct cvmx_agl_gmx_prtx_cfg_cn52xx cn56xx;
 	struct cvmx_agl_gmx_prtx_cfg_cn52xx cn56xxp1;
+	struct cvmx_agl_gmx_prtx_cfg_s cn61xx;
 	struct cvmx_agl_gmx_prtx_cfg_s cn63xx;
 	struct cvmx_agl_gmx_prtx_cfg_s cn63xxp1;
+	struct cvmx_agl_gmx_prtx_cfg_s cn66xx;
+	struct cvmx_agl_gmx_prtx_cfg_s cn68xx;
+	struct cvmx_agl_gmx_prtx_cfg_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_adr_cam0 {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_adr_cam0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t adr:64;
+#else
+		uint64_t adr:64;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_adr_cam0_s cn52xx;
 	struct cvmx_agl_gmx_rxx_adr_cam0_s cn52xxp1;
 	struct cvmx_agl_gmx_rxx_adr_cam0_s cn56xx;
 	struct cvmx_agl_gmx_rxx_adr_cam0_s cn56xxp1;
+	struct cvmx_agl_gmx_rxx_adr_cam0_s cn61xx;
 	struct cvmx_agl_gmx_rxx_adr_cam0_s cn63xx;
 	struct cvmx_agl_gmx_rxx_adr_cam0_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_adr_cam0_s cn66xx;
+	struct cvmx_agl_gmx_rxx_adr_cam0_s cn68xx;
+	struct cvmx_agl_gmx_rxx_adr_cam0_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_adr_cam1 {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_adr_cam1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t adr:64;
+#else
+		uint64_t adr:64;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_adr_cam1_s cn52xx;
 	struct cvmx_agl_gmx_rxx_adr_cam1_s cn52xxp1;
 	struct cvmx_agl_gmx_rxx_adr_cam1_s cn56xx;
 	struct cvmx_agl_gmx_rxx_adr_cam1_s cn56xxp1;
+	struct cvmx_agl_gmx_rxx_adr_cam1_s cn61xx;
 	struct cvmx_agl_gmx_rxx_adr_cam1_s cn63xx;
 	struct cvmx_agl_gmx_rxx_adr_cam1_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_adr_cam1_s cn66xx;
+	struct cvmx_agl_gmx_rxx_adr_cam1_s cn68xx;
+	struct cvmx_agl_gmx_rxx_adr_cam1_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_adr_cam2 {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_adr_cam2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t adr:64;
+#else
+		uint64_t adr:64;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_adr_cam2_s cn52xx;
 	struct cvmx_agl_gmx_rxx_adr_cam2_s cn52xxp1;
 	struct cvmx_agl_gmx_rxx_adr_cam2_s cn56xx;
 	struct cvmx_agl_gmx_rxx_adr_cam2_s cn56xxp1;
+	struct cvmx_agl_gmx_rxx_adr_cam2_s cn61xx;
 	struct cvmx_agl_gmx_rxx_adr_cam2_s cn63xx;
 	struct cvmx_agl_gmx_rxx_adr_cam2_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_adr_cam2_s cn66xx;
+	struct cvmx_agl_gmx_rxx_adr_cam2_s cn68xx;
+	struct cvmx_agl_gmx_rxx_adr_cam2_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_adr_cam3 {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_adr_cam3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t adr:64;
+#else
+		uint64_t adr:64;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_adr_cam3_s cn52xx;
 	struct cvmx_agl_gmx_rxx_adr_cam3_s cn52xxp1;
 	struct cvmx_agl_gmx_rxx_adr_cam3_s cn56xx;
 	struct cvmx_agl_gmx_rxx_adr_cam3_s cn56xxp1;
+	struct cvmx_agl_gmx_rxx_adr_cam3_s cn61xx;
 	struct cvmx_agl_gmx_rxx_adr_cam3_s cn63xx;
 	struct cvmx_agl_gmx_rxx_adr_cam3_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_adr_cam3_s cn66xx;
+	struct cvmx_agl_gmx_rxx_adr_cam3_s cn68xx;
+	struct cvmx_agl_gmx_rxx_adr_cam3_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_adr_cam4 {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_adr_cam4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t adr:64;
+#else
+		uint64_t adr:64;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_adr_cam4_s cn52xx;
 	struct cvmx_agl_gmx_rxx_adr_cam4_s cn52xxp1;
 	struct cvmx_agl_gmx_rxx_adr_cam4_s cn56xx;
 	struct cvmx_agl_gmx_rxx_adr_cam4_s cn56xxp1;
+	struct cvmx_agl_gmx_rxx_adr_cam4_s cn61xx;
 	struct cvmx_agl_gmx_rxx_adr_cam4_s cn63xx;
 	struct cvmx_agl_gmx_rxx_adr_cam4_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_adr_cam4_s cn66xx;
+	struct cvmx_agl_gmx_rxx_adr_cam4_s cn68xx;
+	struct cvmx_agl_gmx_rxx_adr_cam4_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_adr_cam5 {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_adr_cam5_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t adr:64;
+#else
+		uint64_t adr:64;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_adr_cam5_s cn52xx;
 	struct cvmx_agl_gmx_rxx_adr_cam5_s cn52xxp1;
 	struct cvmx_agl_gmx_rxx_adr_cam5_s cn56xx;
 	struct cvmx_agl_gmx_rxx_adr_cam5_s cn56xxp1;
+	struct cvmx_agl_gmx_rxx_adr_cam5_s cn61xx;
 	struct cvmx_agl_gmx_rxx_adr_cam5_s cn63xx;
 	struct cvmx_agl_gmx_rxx_adr_cam5_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_adr_cam5_s cn66xx;
+	struct cvmx_agl_gmx_rxx_adr_cam5_s cn68xx;
+	struct cvmx_agl_gmx_rxx_adr_cam5_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_adr_cam_en {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_adr_cam_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t en:8;
+#else
+		uint64_t en:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_adr_cam_en_s cn52xx;
 	struct cvmx_agl_gmx_rxx_adr_cam_en_s cn52xxp1;
 	struct cvmx_agl_gmx_rxx_adr_cam_en_s cn56xx;
 	struct cvmx_agl_gmx_rxx_adr_cam_en_s cn56xxp1;
+	struct cvmx_agl_gmx_rxx_adr_cam_en_s cn61xx;
 	struct cvmx_agl_gmx_rxx_adr_cam_en_s cn63xx;
 	struct cvmx_agl_gmx_rxx_adr_cam_en_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_adr_cam_en_s cn66xx;
+	struct cvmx_agl_gmx_rxx_adr_cam_en_s cn68xx;
+	struct cvmx_agl_gmx_rxx_adr_cam_en_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_adr_ctl {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_adr_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t cam_mode:1;
 		uint64_t mcst:2;
 		uint64_t bcst:1;
+#else
+		uint64_t bcst:1;
+		uint64_t mcst:2;
+		uint64_t cam_mode:1;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_adr_ctl_s cn52xx;
 	struct cvmx_agl_gmx_rxx_adr_ctl_s cn52xxp1;
 	struct cvmx_agl_gmx_rxx_adr_ctl_s cn56xx;
 	struct cvmx_agl_gmx_rxx_adr_ctl_s cn56xxp1;
+	struct cvmx_agl_gmx_rxx_adr_ctl_s cn61xx;
 	struct cvmx_agl_gmx_rxx_adr_ctl_s cn63xx;
 	struct cvmx_agl_gmx_rxx_adr_ctl_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_adr_ctl_s cn66xx;
+	struct cvmx_agl_gmx_rxx_adr_ctl_s cn68xx;
+	struct cvmx_agl_gmx_rxx_adr_ctl_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_decision {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_decision_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t cnt:5;
+#else
+		uint64_t cnt:5;
+		uint64_t reserved_5_63:59;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_decision_s cn52xx;
 	struct cvmx_agl_gmx_rxx_decision_s cn52xxp1;
 	struct cvmx_agl_gmx_rxx_decision_s cn56xx;
 	struct cvmx_agl_gmx_rxx_decision_s cn56xxp1;
+	struct cvmx_agl_gmx_rxx_decision_s cn61xx;
 	struct cvmx_agl_gmx_rxx_decision_s cn63xx;
 	struct cvmx_agl_gmx_rxx_decision_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_decision_s cn66xx;
+	struct cvmx_agl_gmx_rxx_decision_s cn68xx;
+	struct cvmx_agl_gmx_rxx_decision_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_frm_chk {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_frm_chk_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t niberr:1;
 		uint64_t skperr:1;
@@ -384,8 +588,22 @@
 		uint64_t maxerr:1;
 		uint64_t carext:1;
 		uint64_t minerr:1;
+#else
+		uint64_t minerr:1;
+		uint64_t carext:1;
+		uint64_t maxerr:1;
+		uint64_t jabber:1;
+		uint64_t fcserr:1;
+		uint64_t alnerr:1;
+		uint64_t lenerr:1;
+		uint64_t rcverr:1;
+		uint64_t skperr:1;
+		uint64_t niberr:1;
+		uint64_t reserved_10_63:54;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_frm_chk_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t skperr:1;
 		uint64_t rcverr:1;
@@ -396,17 +614,34 @@
 		uint64_t maxerr:1;
 		uint64_t reserved_1_1:1;
 		uint64_t minerr:1;
+#else
+		uint64_t minerr:1;
+		uint64_t reserved_1_1:1;
+		uint64_t maxerr:1;
+		uint64_t jabber:1;
+		uint64_t fcserr:1;
+		uint64_t alnerr:1;
+		uint64_t lenerr:1;
+		uint64_t rcverr:1;
+		uint64_t skperr:1;
+		uint64_t reserved_9_63:55;
+#endif
 	} cn52xx;
 	struct cvmx_agl_gmx_rxx_frm_chk_cn52xx cn52xxp1;
 	struct cvmx_agl_gmx_rxx_frm_chk_cn52xx cn56xx;
 	struct cvmx_agl_gmx_rxx_frm_chk_cn52xx cn56xxp1;
+	struct cvmx_agl_gmx_rxx_frm_chk_s cn61xx;
 	struct cvmx_agl_gmx_rxx_frm_chk_s cn63xx;
 	struct cvmx_agl_gmx_rxx_frm_chk_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_frm_chk_s cn66xx;
+	struct cvmx_agl_gmx_rxx_frm_chk_s cn68xx;
+	struct cvmx_agl_gmx_rxx_frm_chk_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_frm_ctl {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_frm_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_13_63:51;
 		uint64_t ptp_mode:1;
 		uint64_t reserved_11_11:1;
@@ -421,8 +656,25 @@
 		uint64_t ctl_drp:1;
 		uint64_t pre_strp:1;
 		uint64_t pre_chk:1;
+#else
+		uint64_t pre_chk:1;
+		uint64_t pre_strp:1;
+		uint64_t ctl_drp:1;
+		uint64_t ctl_bck:1;
+		uint64_t ctl_mcst:1;
+		uint64_t ctl_smac:1;
+		uint64_t pre_free:1;
+		uint64_t vlan_len:1;
+		uint64_t pad_len:1;
+		uint64_t pre_align:1;
+		uint64_t null_dis:1;
+		uint64_t reserved_11_11:1;
+		uint64_t ptp_mode:1;
+		uint64_t reserved_13_63:51;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_frm_ctl_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t pre_align:1;
 		uint64_t pad_len:1;
@@ -434,59 +686,104 @@
 		uint64_t ctl_drp:1;
 		uint64_t pre_strp:1;
 		uint64_t pre_chk:1;
+#else
+		uint64_t pre_chk:1;
+		uint64_t pre_strp:1;
+		uint64_t ctl_drp:1;
+		uint64_t ctl_bck:1;
+		uint64_t ctl_mcst:1;
+		uint64_t ctl_smac:1;
+		uint64_t pre_free:1;
+		uint64_t vlan_len:1;
+		uint64_t pad_len:1;
+		uint64_t pre_align:1;
+		uint64_t reserved_10_63:54;
+#endif
 	} cn52xx;
 	struct cvmx_agl_gmx_rxx_frm_ctl_cn52xx cn52xxp1;
 	struct cvmx_agl_gmx_rxx_frm_ctl_cn52xx cn56xx;
 	struct cvmx_agl_gmx_rxx_frm_ctl_cn52xx cn56xxp1;
+	struct cvmx_agl_gmx_rxx_frm_ctl_s cn61xx;
 	struct cvmx_agl_gmx_rxx_frm_ctl_s cn63xx;
 	struct cvmx_agl_gmx_rxx_frm_ctl_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_frm_ctl_s cn66xx;
+	struct cvmx_agl_gmx_rxx_frm_ctl_s cn68xx;
+	struct cvmx_agl_gmx_rxx_frm_ctl_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_frm_max {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_frm_max_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t len:16;
+#else
+		uint64_t len:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_frm_max_s cn52xx;
 	struct cvmx_agl_gmx_rxx_frm_max_s cn52xxp1;
 	struct cvmx_agl_gmx_rxx_frm_max_s cn56xx;
 	struct cvmx_agl_gmx_rxx_frm_max_s cn56xxp1;
+	struct cvmx_agl_gmx_rxx_frm_max_s cn61xx;
 	struct cvmx_agl_gmx_rxx_frm_max_s cn63xx;
 	struct cvmx_agl_gmx_rxx_frm_max_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_frm_max_s cn66xx;
+	struct cvmx_agl_gmx_rxx_frm_max_s cn68xx;
+	struct cvmx_agl_gmx_rxx_frm_max_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_frm_min {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_frm_min_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t len:16;
+#else
+		uint64_t len:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_frm_min_s cn52xx;
 	struct cvmx_agl_gmx_rxx_frm_min_s cn52xxp1;
 	struct cvmx_agl_gmx_rxx_frm_min_s cn56xx;
 	struct cvmx_agl_gmx_rxx_frm_min_s cn56xxp1;
+	struct cvmx_agl_gmx_rxx_frm_min_s cn61xx;
 	struct cvmx_agl_gmx_rxx_frm_min_s cn63xx;
 	struct cvmx_agl_gmx_rxx_frm_min_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_frm_min_s cn66xx;
+	struct cvmx_agl_gmx_rxx_frm_min_s cn68xx;
+	struct cvmx_agl_gmx_rxx_frm_min_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_ifg {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_ifg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t ifg:4;
+#else
+		uint64_t ifg:4;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_ifg_s cn52xx;
 	struct cvmx_agl_gmx_rxx_ifg_s cn52xxp1;
 	struct cvmx_agl_gmx_rxx_ifg_s cn56xx;
 	struct cvmx_agl_gmx_rxx_ifg_s cn56xxp1;
+	struct cvmx_agl_gmx_rxx_ifg_s cn61xx;
 	struct cvmx_agl_gmx_rxx_ifg_s cn63xx;
 	struct cvmx_agl_gmx_rxx_ifg_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_ifg_s cn66xx;
+	struct cvmx_agl_gmx_rxx_ifg_s cn68xx;
+	struct cvmx_agl_gmx_rxx_ifg_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_int_en {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_int_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t pause_drp:1;
 		uint64_t phy_dupx:1;
@@ -508,8 +805,32 @@
 		uint64_t maxerr:1;
 		uint64_t carext:1;
 		uint64_t minerr:1;
+#else
+		uint64_t minerr:1;
+		uint64_t carext:1;
+		uint64_t maxerr:1;
+		uint64_t jabber:1;
+		uint64_t fcserr:1;
+		uint64_t alnerr:1;
+		uint64_t lenerr:1;
+		uint64_t rcverr:1;
+		uint64_t skperr:1;
+		uint64_t niberr:1;
+		uint64_t ovrerr:1;
+		uint64_t pcterr:1;
+		uint64_t rsverr:1;
+		uint64_t falerr:1;
+		uint64_t coldet:1;
+		uint64_t ifgerr:1;
+		uint64_t phy_link:1;
+		uint64_t phy_spd:1;
+		uint64_t phy_dupx:1;
+		uint64_t pause_drp:1;
+		uint64_t reserved_20_63:44;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_int_en_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t pause_drp:1;
 		uint64_t reserved_16_18:3;
@@ -529,17 +850,43 @@
 		uint64_t maxerr:1;
 		uint64_t reserved_1_1:1;
 		uint64_t minerr:1;
+#else
+		uint64_t minerr:1;
+		uint64_t reserved_1_1:1;
+		uint64_t maxerr:1;
+		uint64_t jabber:1;
+		uint64_t fcserr:1;
+		uint64_t alnerr:1;
+		uint64_t lenerr:1;
+		uint64_t rcverr:1;
+		uint64_t skperr:1;
+		uint64_t reserved_9_9:1;
+		uint64_t ovrerr:1;
+		uint64_t pcterr:1;
+		uint64_t rsverr:1;
+		uint64_t falerr:1;
+		uint64_t coldet:1;
+		uint64_t ifgerr:1;
+		uint64_t reserved_16_18:3;
+		uint64_t pause_drp:1;
+		uint64_t reserved_20_63:44;
+#endif
 	} cn52xx;
 	struct cvmx_agl_gmx_rxx_int_en_cn52xx cn52xxp1;
 	struct cvmx_agl_gmx_rxx_int_en_cn52xx cn56xx;
 	struct cvmx_agl_gmx_rxx_int_en_cn52xx cn56xxp1;
+	struct cvmx_agl_gmx_rxx_int_en_s cn61xx;
 	struct cvmx_agl_gmx_rxx_int_en_s cn63xx;
 	struct cvmx_agl_gmx_rxx_int_en_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_int_en_s cn66xx;
+	struct cvmx_agl_gmx_rxx_int_en_s cn68xx;
+	struct cvmx_agl_gmx_rxx_int_en_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_int_reg {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_int_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t pause_drp:1;
 		uint64_t phy_dupx:1;
@@ -561,8 +908,32 @@
 		uint64_t maxerr:1;
 		uint64_t carext:1;
 		uint64_t minerr:1;
+#else
+		uint64_t minerr:1;
+		uint64_t carext:1;
+		uint64_t maxerr:1;
+		uint64_t jabber:1;
+		uint64_t fcserr:1;
+		uint64_t alnerr:1;
+		uint64_t lenerr:1;
+		uint64_t rcverr:1;
+		uint64_t skperr:1;
+		uint64_t niberr:1;
+		uint64_t ovrerr:1;
+		uint64_t pcterr:1;
+		uint64_t rsverr:1;
+		uint64_t falerr:1;
+		uint64_t coldet:1;
+		uint64_t ifgerr:1;
+		uint64_t phy_link:1;
+		uint64_t phy_spd:1;
+		uint64_t phy_dupx:1;
+		uint64_t pause_drp:1;
+		uint64_t reserved_20_63:44;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_int_reg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t pause_drp:1;
 		uint64_t reserved_16_18:3;
@@ -582,666 +953,1130 @@
 		uint64_t maxerr:1;
 		uint64_t reserved_1_1:1;
 		uint64_t minerr:1;
+#else
+		uint64_t minerr:1;
+		uint64_t reserved_1_1:1;
+		uint64_t maxerr:1;
+		uint64_t jabber:1;
+		uint64_t fcserr:1;
+		uint64_t alnerr:1;
+		uint64_t lenerr:1;
+		uint64_t rcverr:1;
+		uint64_t skperr:1;
+		uint64_t reserved_9_9:1;
+		uint64_t ovrerr:1;
+		uint64_t pcterr:1;
+		uint64_t rsverr:1;
+		uint64_t falerr:1;
+		uint64_t coldet:1;
+		uint64_t ifgerr:1;
+		uint64_t reserved_16_18:3;
+		uint64_t pause_drp:1;
+		uint64_t reserved_20_63:44;
+#endif
 	} cn52xx;
 	struct cvmx_agl_gmx_rxx_int_reg_cn52xx cn52xxp1;
 	struct cvmx_agl_gmx_rxx_int_reg_cn52xx cn56xx;
 	struct cvmx_agl_gmx_rxx_int_reg_cn52xx cn56xxp1;
+	struct cvmx_agl_gmx_rxx_int_reg_s cn61xx;
 	struct cvmx_agl_gmx_rxx_int_reg_s cn63xx;
 	struct cvmx_agl_gmx_rxx_int_reg_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_int_reg_s cn66xx;
+	struct cvmx_agl_gmx_rxx_int_reg_s cn68xx;
+	struct cvmx_agl_gmx_rxx_int_reg_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_jabber {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_jabber_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t cnt:16;
+#else
+		uint64_t cnt:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_jabber_s cn52xx;
 	struct cvmx_agl_gmx_rxx_jabber_s cn52xxp1;
 	struct cvmx_agl_gmx_rxx_jabber_s cn56xx;
 	struct cvmx_agl_gmx_rxx_jabber_s cn56xxp1;
+	struct cvmx_agl_gmx_rxx_jabber_s cn61xx;
 	struct cvmx_agl_gmx_rxx_jabber_s cn63xx;
 	struct cvmx_agl_gmx_rxx_jabber_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_jabber_s cn66xx;
+	struct cvmx_agl_gmx_rxx_jabber_s cn68xx;
+	struct cvmx_agl_gmx_rxx_jabber_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_pause_drop_time {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_pause_drop_time_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t status:16;
+#else
+		uint64_t status:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_pause_drop_time_s cn52xx;
 	struct cvmx_agl_gmx_rxx_pause_drop_time_s cn52xxp1;
 	struct cvmx_agl_gmx_rxx_pause_drop_time_s cn56xx;
 	struct cvmx_agl_gmx_rxx_pause_drop_time_s cn56xxp1;
+	struct cvmx_agl_gmx_rxx_pause_drop_time_s cn61xx;
 	struct cvmx_agl_gmx_rxx_pause_drop_time_s cn63xx;
 	struct cvmx_agl_gmx_rxx_pause_drop_time_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_pause_drop_time_s cn66xx;
+	struct cvmx_agl_gmx_rxx_pause_drop_time_s cn68xx;
+	struct cvmx_agl_gmx_rxx_pause_drop_time_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_rx_inbnd {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_rx_inbnd_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t duplex:1;
 		uint64_t speed:2;
 		uint64_t status:1;
+#else
+		uint64_t status:1;
+		uint64_t speed:2;
+		uint64_t duplex:1;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
+	struct cvmx_agl_gmx_rxx_rx_inbnd_s cn61xx;
 	struct cvmx_agl_gmx_rxx_rx_inbnd_s cn63xx;
 	struct cvmx_agl_gmx_rxx_rx_inbnd_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_rx_inbnd_s cn66xx;
+	struct cvmx_agl_gmx_rxx_rx_inbnd_s cn68xx;
+	struct cvmx_agl_gmx_rxx_rx_inbnd_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_stats_ctl {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_stats_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t rd_clr:1;
+#else
+		uint64_t rd_clr:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_stats_ctl_s cn52xx;
 	struct cvmx_agl_gmx_rxx_stats_ctl_s cn52xxp1;
 	struct cvmx_agl_gmx_rxx_stats_ctl_s cn56xx;
 	struct cvmx_agl_gmx_rxx_stats_ctl_s cn56xxp1;
+	struct cvmx_agl_gmx_rxx_stats_ctl_s cn61xx;
 	struct cvmx_agl_gmx_rxx_stats_ctl_s cn63xx;
 	struct cvmx_agl_gmx_rxx_stats_ctl_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_stats_ctl_s cn66xx;
+	struct cvmx_agl_gmx_rxx_stats_ctl_s cn68xx;
+	struct cvmx_agl_gmx_rxx_stats_ctl_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_stats_octs {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_stats_octs_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t cnt:48;
+#else
+		uint64_t cnt:48;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_stats_octs_s cn52xx;
 	struct cvmx_agl_gmx_rxx_stats_octs_s cn52xxp1;
 	struct cvmx_agl_gmx_rxx_stats_octs_s cn56xx;
 	struct cvmx_agl_gmx_rxx_stats_octs_s cn56xxp1;
+	struct cvmx_agl_gmx_rxx_stats_octs_s cn61xx;
 	struct cvmx_agl_gmx_rxx_stats_octs_s cn63xx;
 	struct cvmx_agl_gmx_rxx_stats_octs_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_stats_octs_s cn66xx;
+	struct cvmx_agl_gmx_rxx_stats_octs_s cn68xx;
+	struct cvmx_agl_gmx_rxx_stats_octs_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_stats_octs_ctl {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_stats_octs_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t cnt:48;
+#else
+		uint64_t cnt:48;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn52xx;
 	struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn52xxp1;
 	struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn56xx;
 	struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn56xxp1;
+	struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn61xx;
 	struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn63xx;
 	struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn66xx;
+	struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn68xx;
+	struct cvmx_agl_gmx_rxx_stats_octs_ctl_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_stats_octs_dmac {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_stats_octs_dmac_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t cnt:48;
+#else
+		uint64_t cnt:48;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn52xx;
 	struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn52xxp1;
 	struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn56xx;
 	struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn56xxp1;
+	struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn61xx;
 	struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn63xx;
 	struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn66xx;
+	struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn68xx;
+	struct cvmx_agl_gmx_rxx_stats_octs_dmac_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_stats_octs_drp {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_stats_octs_drp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t cnt:48;
+#else
+		uint64_t cnt:48;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn52xx;
 	struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn52xxp1;
 	struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn56xx;
 	struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn56xxp1;
+	struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn61xx;
 	struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn63xx;
 	struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn66xx;
+	struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn68xx;
+	struct cvmx_agl_gmx_rxx_stats_octs_drp_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_stats_pkts {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_stats_pkts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_stats_pkts_s cn52xx;
 	struct cvmx_agl_gmx_rxx_stats_pkts_s cn52xxp1;
 	struct cvmx_agl_gmx_rxx_stats_pkts_s cn56xx;
 	struct cvmx_agl_gmx_rxx_stats_pkts_s cn56xxp1;
+	struct cvmx_agl_gmx_rxx_stats_pkts_s cn61xx;
 	struct cvmx_agl_gmx_rxx_stats_pkts_s cn63xx;
 	struct cvmx_agl_gmx_rxx_stats_pkts_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_stats_pkts_s cn66xx;
+	struct cvmx_agl_gmx_rxx_stats_pkts_s cn68xx;
+	struct cvmx_agl_gmx_rxx_stats_pkts_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_stats_pkts_bad {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_stats_pkts_bad_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn52xx;
 	struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn52xxp1;
 	struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn56xx;
 	struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn56xxp1;
+	struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn61xx;
 	struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn63xx;
 	struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn66xx;
+	struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn68xx;
+	struct cvmx_agl_gmx_rxx_stats_pkts_bad_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_stats_pkts_ctl {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn52xx;
 	struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn52xxp1;
 	struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn56xx;
 	struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn56xxp1;
+	struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn61xx;
 	struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn63xx;
 	struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn66xx;
+	struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn68xx;
+	struct cvmx_agl_gmx_rxx_stats_pkts_ctl_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_stats_pkts_dmac {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn52xx;
 	struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn52xxp1;
 	struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn56xx;
 	struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn56xxp1;
+	struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn61xx;
 	struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn63xx;
 	struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn66xx;
+	struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn68xx;
+	struct cvmx_agl_gmx_rxx_stats_pkts_dmac_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_stats_pkts_drp {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_stats_pkts_drp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn52xx;
 	struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn52xxp1;
 	struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn56xx;
 	struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn56xxp1;
+	struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn61xx;
 	struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn63xx;
 	struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn66xx;
+	struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn68xx;
+	struct cvmx_agl_gmx_rxx_stats_pkts_drp_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rxx_udd_skp {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rxx_udd_skp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t fcssel:1;
 		uint64_t reserved_7_7:1;
 		uint64_t len:7;
+#else
+		uint64_t len:7;
+		uint64_t reserved_7_7:1;
+		uint64_t fcssel:1;
+		uint64_t reserved_9_63:55;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rxx_udd_skp_s cn52xx;
 	struct cvmx_agl_gmx_rxx_udd_skp_s cn52xxp1;
 	struct cvmx_agl_gmx_rxx_udd_skp_s cn56xx;
 	struct cvmx_agl_gmx_rxx_udd_skp_s cn56xxp1;
+	struct cvmx_agl_gmx_rxx_udd_skp_s cn61xx;
 	struct cvmx_agl_gmx_rxx_udd_skp_s cn63xx;
 	struct cvmx_agl_gmx_rxx_udd_skp_s cn63xxp1;
+	struct cvmx_agl_gmx_rxx_udd_skp_s cn66xx;
+	struct cvmx_agl_gmx_rxx_udd_skp_s cn68xx;
+	struct cvmx_agl_gmx_rxx_udd_skp_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rx_bp_dropx {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rx_bp_dropx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t mark:6;
+#else
+		uint64_t mark:6;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rx_bp_dropx_s cn52xx;
 	struct cvmx_agl_gmx_rx_bp_dropx_s cn52xxp1;
 	struct cvmx_agl_gmx_rx_bp_dropx_s cn56xx;
 	struct cvmx_agl_gmx_rx_bp_dropx_s cn56xxp1;
+	struct cvmx_agl_gmx_rx_bp_dropx_s cn61xx;
 	struct cvmx_agl_gmx_rx_bp_dropx_s cn63xx;
 	struct cvmx_agl_gmx_rx_bp_dropx_s cn63xxp1;
+	struct cvmx_agl_gmx_rx_bp_dropx_s cn66xx;
+	struct cvmx_agl_gmx_rx_bp_dropx_s cn68xx;
+	struct cvmx_agl_gmx_rx_bp_dropx_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rx_bp_offx {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rx_bp_offx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t mark:6;
+#else
+		uint64_t mark:6;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rx_bp_offx_s cn52xx;
 	struct cvmx_agl_gmx_rx_bp_offx_s cn52xxp1;
 	struct cvmx_agl_gmx_rx_bp_offx_s cn56xx;
 	struct cvmx_agl_gmx_rx_bp_offx_s cn56xxp1;
+	struct cvmx_agl_gmx_rx_bp_offx_s cn61xx;
 	struct cvmx_agl_gmx_rx_bp_offx_s cn63xx;
 	struct cvmx_agl_gmx_rx_bp_offx_s cn63xxp1;
+	struct cvmx_agl_gmx_rx_bp_offx_s cn66xx;
+	struct cvmx_agl_gmx_rx_bp_offx_s cn68xx;
+	struct cvmx_agl_gmx_rx_bp_offx_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rx_bp_onx {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rx_bp_onx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t mark:9;
+#else
+		uint64_t mark:9;
+		uint64_t reserved_9_63:55;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rx_bp_onx_s cn52xx;
 	struct cvmx_agl_gmx_rx_bp_onx_s cn52xxp1;
 	struct cvmx_agl_gmx_rx_bp_onx_s cn56xx;
 	struct cvmx_agl_gmx_rx_bp_onx_s cn56xxp1;
+	struct cvmx_agl_gmx_rx_bp_onx_s cn61xx;
 	struct cvmx_agl_gmx_rx_bp_onx_s cn63xx;
 	struct cvmx_agl_gmx_rx_bp_onx_s cn63xxp1;
+	struct cvmx_agl_gmx_rx_bp_onx_s cn66xx;
+	struct cvmx_agl_gmx_rx_bp_onx_s cn68xx;
+	struct cvmx_agl_gmx_rx_bp_onx_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rx_prt_info {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rx_prt_info_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_18_63:46;
 		uint64_t drop:2;
 		uint64_t reserved_2_15:14;
 		uint64_t commit:2;
+#else
+		uint64_t commit:2;
+		uint64_t reserved_2_15:14;
+		uint64_t drop:2;
+		uint64_t reserved_18_63:46;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rx_prt_info_s cn52xx;
 	struct cvmx_agl_gmx_rx_prt_info_s cn52xxp1;
 	struct cvmx_agl_gmx_rx_prt_info_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_17_63:47;
 		uint64_t drop:1;
 		uint64_t reserved_1_15:15;
 		uint64_t commit:1;
+#else
+		uint64_t commit:1;
+		uint64_t reserved_1_15:15;
+		uint64_t drop:1;
+		uint64_t reserved_17_63:47;
+#endif
 	} cn56xx;
 	struct cvmx_agl_gmx_rx_prt_info_cn56xx cn56xxp1;
+	struct cvmx_agl_gmx_rx_prt_info_s cn61xx;
 	struct cvmx_agl_gmx_rx_prt_info_s cn63xx;
 	struct cvmx_agl_gmx_rx_prt_info_s cn63xxp1;
+	struct cvmx_agl_gmx_rx_prt_info_s cn66xx;
+	struct cvmx_agl_gmx_rx_prt_info_s cn68xx;
+	struct cvmx_agl_gmx_rx_prt_info_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_rx_tx_status {
 	uint64_t u64;
 	struct cvmx_agl_gmx_rx_tx_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t tx:2;
 		uint64_t reserved_2_3:2;
 		uint64_t rx:2;
+#else
+		uint64_t rx:2;
+		uint64_t reserved_2_3:2;
+		uint64_t tx:2;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
 	struct cvmx_agl_gmx_rx_tx_status_s cn52xx;
 	struct cvmx_agl_gmx_rx_tx_status_s cn52xxp1;
 	struct cvmx_agl_gmx_rx_tx_status_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t tx:1;
 		uint64_t reserved_1_3:3;
 		uint64_t rx:1;
+#else
+		uint64_t rx:1;
+		uint64_t reserved_1_3:3;
+		uint64_t tx:1;
+		uint64_t reserved_5_63:59;
+#endif
 	} cn56xx;
 	struct cvmx_agl_gmx_rx_tx_status_cn56xx cn56xxp1;
+	struct cvmx_agl_gmx_rx_tx_status_s cn61xx;
 	struct cvmx_agl_gmx_rx_tx_status_s cn63xx;
 	struct cvmx_agl_gmx_rx_tx_status_s cn63xxp1;
+	struct cvmx_agl_gmx_rx_tx_status_s cn66xx;
+	struct cvmx_agl_gmx_rx_tx_status_s cn68xx;
+	struct cvmx_agl_gmx_rx_tx_status_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_smacx {
 	uint64_t u64;
 	struct cvmx_agl_gmx_smacx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t smac:48;
+#else
+		uint64_t smac:48;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_agl_gmx_smacx_s cn52xx;
 	struct cvmx_agl_gmx_smacx_s cn52xxp1;
 	struct cvmx_agl_gmx_smacx_s cn56xx;
 	struct cvmx_agl_gmx_smacx_s cn56xxp1;
+	struct cvmx_agl_gmx_smacx_s cn61xx;
 	struct cvmx_agl_gmx_smacx_s cn63xx;
 	struct cvmx_agl_gmx_smacx_s cn63xxp1;
+	struct cvmx_agl_gmx_smacx_s cn66xx;
+	struct cvmx_agl_gmx_smacx_s cn68xx;
+	struct cvmx_agl_gmx_smacx_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_stat_bp {
 	uint64_t u64;
 	struct cvmx_agl_gmx_stat_bp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_17_63:47;
 		uint64_t bp:1;
 		uint64_t cnt:16;
+#else
+		uint64_t cnt:16;
+		uint64_t bp:1;
+		uint64_t reserved_17_63:47;
+#endif
 	} s;
 	struct cvmx_agl_gmx_stat_bp_s cn52xx;
 	struct cvmx_agl_gmx_stat_bp_s cn52xxp1;
 	struct cvmx_agl_gmx_stat_bp_s cn56xx;
 	struct cvmx_agl_gmx_stat_bp_s cn56xxp1;
+	struct cvmx_agl_gmx_stat_bp_s cn61xx;
 	struct cvmx_agl_gmx_stat_bp_s cn63xx;
 	struct cvmx_agl_gmx_stat_bp_s cn63xxp1;
+	struct cvmx_agl_gmx_stat_bp_s cn66xx;
+	struct cvmx_agl_gmx_stat_bp_s cn68xx;
+	struct cvmx_agl_gmx_stat_bp_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_txx_append {
 	uint64_t u64;
 	struct cvmx_agl_gmx_txx_append_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t force_fcs:1;
 		uint64_t fcs:1;
 		uint64_t pad:1;
 		uint64_t preamble:1;
+#else
+		uint64_t preamble:1;
+		uint64_t pad:1;
+		uint64_t fcs:1;
+		uint64_t force_fcs:1;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_agl_gmx_txx_append_s cn52xx;
 	struct cvmx_agl_gmx_txx_append_s cn52xxp1;
 	struct cvmx_agl_gmx_txx_append_s cn56xx;
 	struct cvmx_agl_gmx_txx_append_s cn56xxp1;
+	struct cvmx_agl_gmx_txx_append_s cn61xx;
 	struct cvmx_agl_gmx_txx_append_s cn63xx;
 	struct cvmx_agl_gmx_txx_append_s cn63xxp1;
+	struct cvmx_agl_gmx_txx_append_s cn66xx;
+	struct cvmx_agl_gmx_txx_append_s cn68xx;
+	struct cvmx_agl_gmx_txx_append_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_txx_clk {
 	uint64_t u64;
 	struct cvmx_agl_gmx_txx_clk_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t clk_cnt:6;
+#else
+		uint64_t clk_cnt:6;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
+	struct cvmx_agl_gmx_txx_clk_s cn61xx;
 	struct cvmx_agl_gmx_txx_clk_s cn63xx;
 	struct cvmx_agl_gmx_txx_clk_s cn63xxp1;
+	struct cvmx_agl_gmx_txx_clk_s cn66xx;
+	struct cvmx_agl_gmx_txx_clk_s cn68xx;
+	struct cvmx_agl_gmx_txx_clk_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_txx_ctl {
 	uint64_t u64;
 	struct cvmx_agl_gmx_txx_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t xsdef_en:1;
 		uint64_t xscol_en:1;
+#else
+		uint64_t xscol_en:1;
+		uint64_t xsdef_en:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_agl_gmx_txx_ctl_s cn52xx;
 	struct cvmx_agl_gmx_txx_ctl_s cn52xxp1;
 	struct cvmx_agl_gmx_txx_ctl_s cn56xx;
 	struct cvmx_agl_gmx_txx_ctl_s cn56xxp1;
+	struct cvmx_agl_gmx_txx_ctl_s cn61xx;
 	struct cvmx_agl_gmx_txx_ctl_s cn63xx;
 	struct cvmx_agl_gmx_txx_ctl_s cn63xxp1;
+	struct cvmx_agl_gmx_txx_ctl_s cn66xx;
+	struct cvmx_agl_gmx_txx_ctl_s cn68xx;
+	struct cvmx_agl_gmx_txx_ctl_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_txx_min_pkt {
 	uint64_t u64;
 	struct cvmx_agl_gmx_txx_min_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t min_size:8;
+#else
+		uint64_t min_size:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_agl_gmx_txx_min_pkt_s cn52xx;
 	struct cvmx_agl_gmx_txx_min_pkt_s cn52xxp1;
 	struct cvmx_agl_gmx_txx_min_pkt_s cn56xx;
 	struct cvmx_agl_gmx_txx_min_pkt_s cn56xxp1;
+	struct cvmx_agl_gmx_txx_min_pkt_s cn61xx;
 	struct cvmx_agl_gmx_txx_min_pkt_s cn63xx;
 	struct cvmx_agl_gmx_txx_min_pkt_s cn63xxp1;
+	struct cvmx_agl_gmx_txx_min_pkt_s cn66xx;
+	struct cvmx_agl_gmx_txx_min_pkt_s cn68xx;
+	struct cvmx_agl_gmx_txx_min_pkt_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_txx_pause_pkt_interval {
 	uint64_t u64;
 	struct cvmx_agl_gmx_txx_pause_pkt_interval_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t interval:16;
+#else
+		uint64_t interval:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn52xx;
 	struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn52xxp1;
 	struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn56xx;
 	struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn56xxp1;
+	struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn61xx;
 	struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn63xx;
 	struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn63xxp1;
+	struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn66xx;
+	struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn68xx;
+	struct cvmx_agl_gmx_txx_pause_pkt_interval_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_txx_pause_pkt_time {
 	uint64_t u64;
 	struct cvmx_agl_gmx_txx_pause_pkt_time_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t time:16;
+#else
+		uint64_t time:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_agl_gmx_txx_pause_pkt_time_s cn52xx;
 	struct cvmx_agl_gmx_txx_pause_pkt_time_s cn52xxp1;
 	struct cvmx_agl_gmx_txx_pause_pkt_time_s cn56xx;
 	struct cvmx_agl_gmx_txx_pause_pkt_time_s cn56xxp1;
+	struct cvmx_agl_gmx_txx_pause_pkt_time_s cn61xx;
 	struct cvmx_agl_gmx_txx_pause_pkt_time_s cn63xx;
 	struct cvmx_agl_gmx_txx_pause_pkt_time_s cn63xxp1;
+	struct cvmx_agl_gmx_txx_pause_pkt_time_s cn66xx;
+	struct cvmx_agl_gmx_txx_pause_pkt_time_s cn68xx;
+	struct cvmx_agl_gmx_txx_pause_pkt_time_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_txx_pause_togo {
 	uint64_t u64;
 	struct cvmx_agl_gmx_txx_pause_togo_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t time:16;
+#else
+		uint64_t time:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_agl_gmx_txx_pause_togo_s cn52xx;
 	struct cvmx_agl_gmx_txx_pause_togo_s cn52xxp1;
 	struct cvmx_agl_gmx_txx_pause_togo_s cn56xx;
 	struct cvmx_agl_gmx_txx_pause_togo_s cn56xxp1;
+	struct cvmx_agl_gmx_txx_pause_togo_s cn61xx;
 	struct cvmx_agl_gmx_txx_pause_togo_s cn63xx;
 	struct cvmx_agl_gmx_txx_pause_togo_s cn63xxp1;
+	struct cvmx_agl_gmx_txx_pause_togo_s cn66xx;
+	struct cvmx_agl_gmx_txx_pause_togo_s cn68xx;
+	struct cvmx_agl_gmx_txx_pause_togo_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_txx_pause_zero {
 	uint64_t u64;
 	struct cvmx_agl_gmx_txx_pause_zero_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t send:1;
+#else
+		uint64_t send:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_agl_gmx_txx_pause_zero_s cn52xx;
 	struct cvmx_agl_gmx_txx_pause_zero_s cn52xxp1;
 	struct cvmx_agl_gmx_txx_pause_zero_s cn56xx;
 	struct cvmx_agl_gmx_txx_pause_zero_s cn56xxp1;
+	struct cvmx_agl_gmx_txx_pause_zero_s cn61xx;
 	struct cvmx_agl_gmx_txx_pause_zero_s cn63xx;
 	struct cvmx_agl_gmx_txx_pause_zero_s cn63xxp1;
+	struct cvmx_agl_gmx_txx_pause_zero_s cn66xx;
+	struct cvmx_agl_gmx_txx_pause_zero_s cn68xx;
+	struct cvmx_agl_gmx_txx_pause_zero_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_txx_soft_pause {
 	uint64_t u64;
 	struct cvmx_agl_gmx_txx_soft_pause_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t time:16;
+#else
+		uint64_t time:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_agl_gmx_txx_soft_pause_s cn52xx;
 	struct cvmx_agl_gmx_txx_soft_pause_s cn52xxp1;
 	struct cvmx_agl_gmx_txx_soft_pause_s cn56xx;
 	struct cvmx_agl_gmx_txx_soft_pause_s cn56xxp1;
+	struct cvmx_agl_gmx_txx_soft_pause_s cn61xx;
 	struct cvmx_agl_gmx_txx_soft_pause_s cn63xx;
 	struct cvmx_agl_gmx_txx_soft_pause_s cn63xxp1;
+	struct cvmx_agl_gmx_txx_soft_pause_s cn66xx;
+	struct cvmx_agl_gmx_txx_soft_pause_s cn68xx;
+	struct cvmx_agl_gmx_txx_soft_pause_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_txx_stat0 {
 	uint64_t u64;
 	struct cvmx_agl_gmx_txx_stat0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t xsdef:32;
 		uint64_t xscol:32;
+#else
+		uint64_t xscol:32;
+		uint64_t xsdef:32;
+#endif
 	} s;
 	struct cvmx_agl_gmx_txx_stat0_s cn52xx;
 	struct cvmx_agl_gmx_txx_stat0_s cn52xxp1;
 	struct cvmx_agl_gmx_txx_stat0_s cn56xx;
 	struct cvmx_agl_gmx_txx_stat0_s cn56xxp1;
+	struct cvmx_agl_gmx_txx_stat0_s cn61xx;
 	struct cvmx_agl_gmx_txx_stat0_s cn63xx;
 	struct cvmx_agl_gmx_txx_stat0_s cn63xxp1;
+	struct cvmx_agl_gmx_txx_stat0_s cn66xx;
+	struct cvmx_agl_gmx_txx_stat0_s cn68xx;
+	struct cvmx_agl_gmx_txx_stat0_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_txx_stat1 {
 	uint64_t u64;
 	struct cvmx_agl_gmx_txx_stat1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t scol:32;
 		uint64_t mcol:32;
+#else
+		uint64_t mcol:32;
+		uint64_t scol:32;
+#endif
 	} s;
 	struct cvmx_agl_gmx_txx_stat1_s cn52xx;
 	struct cvmx_agl_gmx_txx_stat1_s cn52xxp1;
 	struct cvmx_agl_gmx_txx_stat1_s cn56xx;
 	struct cvmx_agl_gmx_txx_stat1_s cn56xxp1;
+	struct cvmx_agl_gmx_txx_stat1_s cn61xx;
 	struct cvmx_agl_gmx_txx_stat1_s cn63xx;
 	struct cvmx_agl_gmx_txx_stat1_s cn63xxp1;
+	struct cvmx_agl_gmx_txx_stat1_s cn66xx;
+	struct cvmx_agl_gmx_txx_stat1_s cn68xx;
+	struct cvmx_agl_gmx_txx_stat1_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_txx_stat2 {
 	uint64_t u64;
 	struct cvmx_agl_gmx_txx_stat2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t octs:48;
+#else
+		uint64_t octs:48;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_agl_gmx_txx_stat2_s cn52xx;
 	struct cvmx_agl_gmx_txx_stat2_s cn52xxp1;
 	struct cvmx_agl_gmx_txx_stat2_s cn56xx;
 	struct cvmx_agl_gmx_txx_stat2_s cn56xxp1;
+	struct cvmx_agl_gmx_txx_stat2_s cn61xx;
 	struct cvmx_agl_gmx_txx_stat2_s cn63xx;
 	struct cvmx_agl_gmx_txx_stat2_s cn63xxp1;
+	struct cvmx_agl_gmx_txx_stat2_s cn66xx;
+	struct cvmx_agl_gmx_txx_stat2_s cn68xx;
+	struct cvmx_agl_gmx_txx_stat2_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_txx_stat3 {
 	uint64_t u64;
 	struct cvmx_agl_gmx_txx_stat3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t pkts:32;
+#else
+		uint64_t pkts:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_agl_gmx_txx_stat3_s cn52xx;
 	struct cvmx_agl_gmx_txx_stat3_s cn52xxp1;
 	struct cvmx_agl_gmx_txx_stat3_s cn56xx;
 	struct cvmx_agl_gmx_txx_stat3_s cn56xxp1;
+	struct cvmx_agl_gmx_txx_stat3_s cn61xx;
 	struct cvmx_agl_gmx_txx_stat3_s cn63xx;
 	struct cvmx_agl_gmx_txx_stat3_s cn63xxp1;
+	struct cvmx_agl_gmx_txx_stat3_s cn66xx;
+	struct cvmx_agl_gmx_txx_stat3_s cn68xx;
+	struct cvmx_agl_gmx_txx_stat3_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_txx_stat4 {
 	uint64_t u64;
 	struct cvmx_agl_gmx_txx_stat4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t hist1:32;
 		uint64_t hist0:32;
+#else
+		uint64_t hist0:32;
+		uint64_t hist1:32;
+#endif
 	} s;
 	struct cvmx_agl_gmx_txx_stat4_s cn52xx;
 	struct cvmx_agl_gmx_txx_stat4_s cn52xxp1;
 	struct cvmx_agl_gmx_txx_stat4_s cn56xx;
 	struct cvmx_agl_gmx_txx_stat4_s cn56xxp1;
+	struct cvmx_agl_gmx_txx_stat4_s cn61xx;
 	struct cvmx_agl_gmx_txx_stat4_s cn63xx;
 	struct cvmx_agl_gmx_txx_stat4_s cn63xxp1;
+	struct cvmx_agl_gmx_txx_stat4_s cn66xx;
+	struct cvmx_agl_gmx_txx_stat4_s cn68xx;
+	struct cvmx_agl_gmx_txx_stat4_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_txx_stat5 {
 	uint64_t u64;
 	struct cvmx_agl_gmx_txx_stat5_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t hist3:32;
 		uint64_t hist2:32;
+#else
+		uint64_t hist2:32;
+		uint64_t hist3:32;
+#endif
 	} s;
 	struct cvmx_agl_gmx_txx_stat5_s cn52xx;
 	struct cvmx_agl_gmx_txx_stat5_s cn52xxp1;
 	struct cvmx_agl_gmx_txx_stat5_s cn56xx;
 	struct cvmx_agl_gmx_txx_stat5_s cn56xxp1;
+	struct cvmx_agl_gmx_txx_stat5_s cn61xx;
 	struct cvmx_agl_gmx_txx_stat5_s cn63xx;
 	struct cvmx_agl_gmx_txx_stat5_s cn63xxp1;
+	struct cvmx_agl_gmx_txx_stat5_s cn66xx;
+	struct cvmx_agl_gmx_txx_stat5_s cn68xx;
+	struct cvmx_agl_gmx_txx_stat5_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_txx_stat6 {
 	uint64_t u64;
 	struct cvmx_agl_gmx_txx_stat6_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t hist5:32;
 		uint64_t hist4:32;
+#else
+		uint64_t hist4:32;
+		uint64_t hist5:32;
+#endif
 	} s;
 	struct cvmx_agl_gmx_txx_stat6_s cn52xx;
 	struct cvmx_agl_gmx_txx_stat6_s cn52xxp1;
 	struct cvmx_agl_gmx_txx_stat6_s cn56xx;
 	struct cvmx_agl_gmx_txx_stat6_s cn56xxp1;
+	struct cvmx_agl_gmx_txx_stat6_s cn61xx;
 	struct cvmx_agl_gmx_txx_stat6_s cn63xx;
 	struct cvmx_agl_gmx_txx_stat6_s cn63xxp1;
+	struct cvmx_agl_gmx_txx_stat6_s cn66xx;
+	struct cvmx_agl_gmx_txx_stat6_s cn68xx;
+	struct cvmx_agl_gmx_txx_stat6_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_txx_stat7 {
 	uint64_t u64;
 	struct cvmx_agl_gmx_txx_stat7_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t hist7:32;
 		uint64_t hist6:32;
+#else
+		uint64_t hist6:32;
+		uint64_t hist7:32;
+#endif
 	} s;
 	struct cvmx_agl_gmx_txx_stat7_s cn52xx;
 	struct cvmx_agl_gmx_txx_stat7_s cn52xxp1;
 	struct cvmx_agl_gmx_txx_stat7_s cn56xx;
 	struct cvmx_agl_gmx_txx_stat7_s cn56xxp1;
+	struct cvmx_agl_gmx_txx_stat7_s cn61xx;
 	struct cvmx_agl_gmx_txx_stat7_s cn63xx;
 	struct cvmx_agl_gmx_txx_stat7_s cn63xxp1;
+	struct cvmx_agl_gmx_txx_stat7_s cn66xx;
+	struct cvmx_agl_gmx_txx_stat7_s cn68xx;
+	struct cvmx_agl_gmx_txx_stat7_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_txx_stat8 {
 	uint64_t u64;
 	struct cvmx_agl_gmx_txx_stat8_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t mcst:32;
 		uint64_t bcst:32;
+#else
+		uint64_t bcst:32;
+		uint64_t mcst:32;
+#endif
 	} s;
 	struct cvmx_agl_gmx_txx_stat8_s cn52xx;
 	struct cvmx_agl_gmx_txx_stat8_s cn52xxp1;
 	struct cvmx_agl_gmx_txx_stat8_s cn56xx;
 	struct cvmx_agl_gmx_txx_stat8_s cn56xxp1;
+	struct cvmx_agl_gmx_txx_stat8_s cn61xx;
 	struct cvmx_agl_gmx_txx_stat8_s cn63xx;
 	struct cvmx_agl_gmx_txx_stat8_s cn63xxp1;
+	struct cvmx_agl_gmx_txx_stat8_s cn66xx;
+	struct cvmx_agl_gmx_txx_stat8_s cn68xx;
+	struct cvmx_agl_gmx_txx_stat8_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_txx_stat9 {
 	uint64_t u64;
 	struct cvmx_agl_gmx_txx_stat9_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t undflw:32;
 		uint64_t ctl:32;
+#else
+		uint64_t ctl:32;
+		uint64_t undflw:32;
+#endif
 	} s;
 	struct cvmx_agl_gmx_txx_stat9_s cn52xx;
 	struct cvmx_agl_gmx_txx_stat9_s cn52xxp1;
 	struct cvmx_agl_gmx_txx_stat9_s cn56xx;
 	struct cvmx_agl_gmx_txx_stat9_s cn56xxp1;
+	struct cvmx_agl_gmx_txx_stat9_s cn61xx;
 	struct cvmx_agl_gmx_txx_stat9_s cn63xx;
 	struct cvmx_agl_gmx_txx_stat9_s cn63xxp1;
+	struct cvmx_agl_gmx_txx_stat9_s cn66xx;
+	struct cvmx_agl_gmx_txx_stat9_s cn68xx;
+	struct cvmx_agl_gmx_txx_stat9_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_txx_stats_ctl {
 	uint64_t u64;
 	struct cvmx_agl_gmx_txx_stats_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t rd_clr:1;
+#else
+		uint64_t rd_clr:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_agl_gmx_txx_stats_ctl_s cn52xx;
 	struct cvmx_agl_gmx_txx_stats_ctl_s cn52xxp1;
 	struct cvmx_agl_gmx_txx_stats_ctl_s cn56xx;
 	struct cvmx_agl_gmx_txx_stats_ctl_s cn56xxp1;
+	struct cvmx_agl_gmx_txx_stats_ctl_s cn61xx;
 	struct cvmx_agl_gmx_txx_stats_ctl_s cn63xx;
 	struct cvmx_agl_gmx_txx_stats_ctl_s cn63xxp1;
+	struct cvmx_agl_gmx_txx_stats_ctl_s cn66xx;
+	struct cvmx_agl_gmx_txx_stats_ctl_s cn68xx;
+	struct cvmx_agl_gmx_txx_stats_ctl_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_txx_thresh {
 	uint64_t u64;
 	struct cvmx_agl_gmx_txx_thresh_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t cnt:6;
+#else
+		uint64_t cnt:6;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
 	struct cvmx_agl_gmx_txx_thresh_s cn52xx;
 	struct cvmx_agl_gmx_txx_thresh_s cn52xxp1;
 	struct cvmx_agl_gmx_txx_thresh_s cn56xx;
 	struct cvmx_agl_gmx_txx_thresh_s cn56xxp1;
+	struct cvmx_agl_gmx_txx_thresh_s cn61xx;
 	struct cvmx_agl_gmx_txx_thresh_s cn63xx;
 	struct cvmx_agl_gmx_txx_thresh_s cn63xxp1;
+	struct cvmx_agl_gmx_txx_thresh_s cn66xx;
+	struct cvmx_agl_gmx_txx_thresh_s cn68xx;
+	struct cvmx_agl_gmx_txx_thresh_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_tx_bp {
 	uint64_t u64;
 	struct cvmx_agl_gmx_tx_bp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t bp:2;
+#else
+		uint64_t bp:2;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_agl_gmx_tx_bp_s cn52xx;
 	struct cvmx_agl_gmx_tx_bp_s cn52xxp1;
 	struct cvmx_agl_gmx_tx_bp_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t bp:1;
+#else
+		uint64_t bp:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} cn56xx;
 	struct cvmx_agl_gmx_tx_bp_cn56xx cn56xxp1;
+	struct cvmx_agl_gmx_tx_bp_s cn61xx;
 	struct cvmx_agl_gmx_tx_bp_s cn63xx;
 	struct cvmx_agl_gmx_tx_bp_s cn63xxp1;
+	struct cvmx_agl_gmx_tx_bp_s cn66xx;
+	struct cvmx_agl_gmx_tx_bp_s cn68xx;
+	struct cvmx_agl_gmx_tx_bp_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_tx_col_attempt {
 	uint64_t u64;
 	struct cvmx_agl_gmx_tx_col_attempt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t limit:5;
+#else
+		uint64_t limit:5;
+		uint64_t reserved_5_63:59;
+#endif
 	} s;
 	struct cvmx_agl_gmx_tx_col_attempt_s cn52xx;
 	struct cvmx_agl_gmx_tx_col_attempt_s cn52xxp1;
 	struct cvmx_agl_gmx_tx_col_attempt_s cn56xx;
 	struct cvmx_agl_gmx_tx_col_attempt_s cn56xxp1;
+	struct cvmx_agl_gmx_tx_col_attempt_s cn61xx;
 	struct cvmx_agl_gmx_tx_col_attempt_s cn63xx;
 	struct cvmx_agl_gmx_tx_col_attempt_s cn63xxp1;
+	struct cvmx_agl_gmx_tx_col_attempt_s cn66xx;
+	struct cvmx_agl_gmx_tx_col_attempt_s cn68xx;
+	struct cvmx_agl_gmx_tx_col_attempt_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_tx_ifg {
 	uint64_t u64;
 	struct cvmx_agl_gmx_tx_ifg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t ifg2:4;
 		uint64_t ifg1:4;
+#else
+		uint64_t ifg1:4;
+		uint64_t ifg2:4;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_agl_gmx_tx_ifg_s cn52xx;
 	struct cvmx_agl_gmx_tx_ifg_s cn52xxp1;
 	struct cvmx_agl_gmx_tx_ifg_s cn56xx;
 	struct cvmx_agl_gmx_tx_ifg_s cn56xxp1;
+	struct cvmx_agl_gmx_tx_ifg_s cn61xx;
 	struct cvmx_agl_gmx_tx_ifg_s cn63xx;
 	struct cvmx_agl_gmx_tx_ifg_s cn63xxp1;
+	struct cvmx_agl_gmx_tx_ifg_s cn66xx;
+	struct cvmx_agl_gmx_tx_ifg_s cn68xx;
+	struct cvmx_agl_gmx_tx_ifg_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_tx_int_en {
 	uint64_t u64;
 	struct cvmx_agl_gmx_tx_int_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_22_63:42;
 		uint64_t ptp_lost:2;
 		uint64_t reserved_18_19:2;
@@ -1254,8 +2089,23 @@
 		uint64_t undflw:2;
 		uint64_t reserved_1_1:1;
 		uint64_t pko_nxa:1;
+#else
+		uint64_t pko_nxa:1;
+		uint64_t reserved_1_1:1;
+		uint64_t undflw:2;
+		uint64_t reserved_4_7:4;
+		uint64_t xscol:2;
+		uint64_t reserved_10_11:2;
+		uint64_t xsdef:2;
+		uint64_t reserved_14_15:2;
+		uint64_t late_col:2;
+		uint64_t reserved_18_19:2;
+		uint64_t ptp_lost:2;
+		uint64_t reserved_22_63:42;
+#endif
 	} s;
 	struct cvmx_agl_gmx_tx_int_en_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_18_63:46;
 		uint64_t late_col:2;
 		uint64_t reserved_14_15:2;
@@ -1266,9 +2116,22 @@
 		uint64_t undflw:2;
 		uint64_t reserved_1_1:1;
 		uint64_t pko_nxa:1;
+#else
+		uint64_t pko_nxa:1;
+		uint64_t reserved_1_1:1;
+		uint64_t undflw:2;
+		uint64_t reserved_4_7:4;
+		uint64_t xscol:2;
+		uint64_t reserved_10_11:2;
+		uint64_t xsdef:2;
+		uint64_t reserved_14_15:2;
+		uint64_t late_col:2;
+		uint64_t reserved_18_63:46;
+#endif
 	} cn52xx;
 	struct cvmx_agl_gmx_tx_int_en_cn52xx cn52xxp1;
 	struct cvmx_agl_gmx_tx_int_en_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_17_63:47;
 		uint64_t late_col:1;
 		uint64_t reserved_13_15:3;
@@ -1279,15 +2142,32 @@
 		uint64_t undflw:1;
 		uint64_t reserved_1_1:1;
 		uint64_t pko_nxa:1;
+#else
+		uint64_t pko_nxa:1;
+		uint64_t reserved_1_1:1;
+		uint64_t undflw:1;
+		uint64_t reserved_3_7:5;
+		uint64_t xscol:1;
+		uint64_t reserved_9_11:3;
+		uint64_t xsdef:1;
+		uint64_t reserved_13_15:3;
+		uint64_t late_col:1;
+		uint64_t reserved_17_63:47;
+#endif
 	} cn56xx;
 	struct cvmx_agl_gmx_tx_int_en_cn56xx cn56xxp1;
+	struct cvmx_agl_gmx_tx_int_en_s cn61xx;
 	struct cvmx_agl_gmx_tx_int_en_s cn63xx;
 	struct cvmx_agl_gmx_tx_int_en_s cn63xxp1;
+	struct cvmx_agl_gmx_tx_int_en_s cn66xx;
+	struct cvmx_agl_gmx_tx_int_en_s cn68xx;
+	struct cvmx_agl_gmx_tx_int_en_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_tx_int_reg {
 	uint64_t u64;
 	struct cvmx_agl_gmx_tx_int_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_22_63:42;
 		uint64_t ptp_lost:2;
 		uint64_t reserved_18_19:2;
@@ -1300,8 +2180,23 @@
 		uint64_t undflw:2;
 		uint64_t reserved_1_1:1;
 		uint64_t pko_nxa:1;
+#else
+		uint64_t pko_nxa:1;
+		uint64_t reserved_1_1:1;
+		uint64_t undflw:2;
+		uint64_t reserved_4_7:4;
+		uint64_t xscol:2;
+		uint64_t reserved_10_11:2;
+		uint64_t xsdef:2;
+		uint64_t reserved_14_15:2;
+		uint64_t late_col:2;
+		uint64_t reserved_18_19:2;
+		uint64_t ptp_lost:2;
+		uint64_t reserved_22_63:42;
+#endif
 	} s;
 	struct cvmx_agl_gmx_tx_int_reg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_18_63:46;
 		uint64_t late_col:2;
 		uint64_t reserved_14_15:2;
@@ -1312,9 +2207,22 @@
 		uint64_t undflw:2;
 		uint64_t reserved_1_1:1;
 		uint64_t pko_nxa:1;
+#else
+		uint64_t pko_nxa:1;
+		uint64_t reserved_1_1:1;
+		uint64_t undflw:2;
+		uint64_t reserved_4_7:4;
+		uint64_t xscol:2;
+		uint64_t reserved_10_11:2;
+		uint64_t xsdef:2;
+		uint64_t reserved_14_15:2;
+		uint64_t late_col:2;
+		uint64_t reserved_18_63:46;
+#endif
 	} cn52xx;
 	struct cvmx_agl_gmx_tx_int_reg_cn52xx cn52xxp1;
 	struct cvmx_agl_gmx_tx_int_reg_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_17_63:47;
 		uint64_t late_col:1;
 		uint64_t reserved_13_15:3;
@@ -1325,96 +2233,171 @@
 		uint64_t undflw:1;
 		uint64_t reserved_1_1:1;
 		uint64_t pko_nxa:1;
+#else
+		uint64_t pko_nxa:1;
+		uint64_t reserved_1_1:1;
+		uint64_t undflw:1;
+		uint64_t reserved_3_7:5;
+		uint64_t xscol:1;
+		uint64_t reserved_9_11:3;
+		uint64_t xsdef:1;
+		uint64_t reserved_13_15:3;
+		uint64_t late_col:1;
+		uint64_t reserved_17_63:47;
+#endif
 	} cn56xx;
 	struct cvmx_agl_gmx_tx_int_reg_cn56xx cn56xxp1;
+	struct cvmx_agl_gmx_tx_int_reg_s cn61xx;
 	struct cvmx_agl_gmx_tx_int_reg_s cn63xx;
 	struct cvmx_agl_gmx_tx_int_reg_s cn63xxp1;
+	struct cvmx_agl_gmx_tx_int_reg_s cn66xx;
+	struct cvmx_agl_gmx_tx_int_reg_s cn68xx;
+	struct cvmx_agl_gmx_tx_int_reg_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_tx_jam {
 	uint64_t u64;
 	struct cvmx_agl_gmx_tx_jam_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t jam:8;
+#else
+		uint64_t jam:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_agl_gmx_tx_jam_s cn52xx;
 	struct cvmx_agl_gmx_tx_jam_s cn52xxp1;
 	struct cvmx_agl_gmx_tx_jam_s cn56xx;
 	struct cvmx_agl_gmx_tx_jam_s cn56xxp1;
+	struct cvmx_agl_gmx_tx_jam_s cn61xx;
 	struct cvmx_agl_gmx_tx_jam_s cn63xx;
 	struct cvmx_agl_gmx_tx_jam_s cn63xxp1;
+	struct cvmx_agl_gmx_tx_jam_s cn66xx;
+	struct cvmx_agl_gmx_tx_jam_s cn68xx;
+	struct cvmx_agl_gmx_tx_jam_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_tx_lfsr {
 	uint64_t u64;
 	struct cvmx_agl_gmx_tx_lfsr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t lfsr:16;
+#else
+		uint64_t lfsr:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_agl_gmx_tx_lfsr_s cn52xx;
 	struct cvmx_agl_gmx_tx_lfsr_s cn52xxp1;
 	struct cvmx_agl_gmx_tx_lfsr_s cn56xx;
 	struct cvmx_agl_gmx_tx_lfsr_s cn56xxp1;
+	struct cvmx_agl_gmx_tx_lfsr_s cn61xx;
 	struct cvmx_agl_gmx_tx_lfsr_s cn63xx;
 	struct cvmx_agl_gmx_tx_lfsr_s cn63xxp1;
+	struct cvmx_agl_gmx_tx_lfsr_s cn66xx;
+	struct cvmx_agl_gmx_tx_lfsr_s cn68xx;
+	struct cvmx_agl_gmx_tx_lfsr_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_tx_ovr_bp {
 	uint64_t u64;
 	struct cvmx_agl_gmx_tx_ovr_bp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t en:2;
 		uint64_t reserved_6_7:2;
 		uint64_t bp:2;
 		uint64_t reserved_2_3:2;
 		uint64_t ign_full:2;
+#else
+		uint64_t ign_full:2;
+		uint64_t reserved_2_3:2;
+		uint64_t bp:2;
+		uint64_t reserved_6_7:2;
+		uint64_t en:2;
+		uint64_t reserved_10_63:54;
+#endif
 	} s;
 	struct cvmx_agl_gmx_tx_ovr_bp_s cn52xx;
 	struct cvmx_agl_gmx_tx_ovr_bp_s cn52xxp1;
 	struct cvmx_agl_gmx_tx_ovr_bp_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t en:1;
 		uint64_t reserved_5_7:3;
 		uint64_t bp:1;
 		uint64_t reserved_1_3:3;
 		uint64_t ign_full:1;
+#else
+		uint64_t ign_full:1;
+		uint64_t reserved_1_3:3;
+		uint64_t bp:1;
+		uint64_t reserved_5_7:3;
+		uint64_t en:1;
+		uint64_t reserved_9_63:55;
+#endif
 	} cn56xx;
 	struct cvmx_agl_gmx_tx_ovr_bp_cn56xx cn56xxp1;
+	struct cvmx_agl_gmx_tx_ovr_bp_s cn61xx;
 	struct cvmx_agl_gmx_tx_ovr_bp_s cn63xx;
 	struct cvmx_agl_gmx_tx_ovr_bp_s cn63xxp1;
+	struct cvmx_agl_gmx_tx_ovr_bp_s cn66xx;
+	struct cvmx_agl_gmx_tx_ovr_bp_s cn68xx;
+	struct cvmx_agl_gmx_tx_ovr_bp_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_tx_pause_pkt_dmac {
 	uint64_t u64;
 	struct cvmx_agl_gmx_tx_pause_pkt_dmac_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t dmac:48;
+#else
+		uint64_t dmac:48;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn52xx;
 	struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn52xxp1;
 	struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn56xx;
 	struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn56xxp1;
+	struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn61xx;
 	struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn63xx;
 	struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn63xxp1;
+	struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn66xx;
+	struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn68xx;
+	struct cvmx_agl_gmx_tx_pause_pkt_dmac_s cn68xxp1;
 };
 
 union cvmx_agl_gmx_tx_pause_pkt_type {
 	uint64_t u64;
 	struct cvmx_agl_gmx_tx_pause_pkt_type_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t type:16;
+#else
+		uint64_t type:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_agl_gmx_tx_pause_pkt_type_s cn52xx;
 	struct cvmx_agl_gmx_tx_pause_pkt_type_s cn52xxp1;
 	struct cvmx_agl_gmx_tx_pause_pkt_type_s cn56xx;
 	struct cvmx_agl_gmx_tx_pause_pkt_type_s cn56xxp1;
+	struct cvmx_agl_gmx_tx_pause_pkt_type_s cn61xx;
 	struct cvmx_agl_gmx_tx_pause_pkt_type_s cn63xx;
 	struct cvmx_agl_gmx_tx_pause_pkt_type_s cn63xxp1;
+	struct cvmx_agl_gmx_tx_pause_pkt_type_s cn66xx;
+	struct cvmx_agl_gmx_tx_pause_pkt_type_s cn68xx;
+	struct cvmx_agl_gmx_tx_pause_pkt_type_s cn68xxp1;
 };
 
 union cvmx_agl_prtx_ctl {
 	uint64_t u64;
 	struct cvmx_agl_prtx_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t drv_byp:1;
 		uint64_t reserved_62_62:1;
 		uint64_t cmp_pctl:6;
@@ -1438,9 +2421,38 @@
 		uint64_t enable:1;
 		uint64_t clkrst:1;
 		uint64_t mode:1;
+#else
+		uint64_t mode:1;
+		uint64_t clkrst:1;
+		uint64_t enable:1;
+		uint64_t comp:1;
+		uint64_t dllrst:1;
+		uint64_t reserved_5_7:3;
+		uint64_t clktx_set:5;
+		uint64_t reserved_13_14:2;
+		uint64_t clktx_byp:1;
+		uint64_t clkrx_set:5;
+		uint64_t reserved_21_22:2;
+		uint64_t clkrx_byp:1;
+		uint64_t clk_set:5;
+		uint64_t reserved_29_31:3;
+		uint64_t drv_nctl:6;
+		uint64_t reserved_38_39:2;
+		uint64_t drv_pctl:6;
+		uint64_t reserved_46_47:2;
+		uint64_t cmp_nctl:6;
+		uint64_t reserved_54_55:2;
+		uint64_t cmp_pctl:6;
+		uint64_t reserved_62_62:1;
+		uint64_t drv_byp:1;
+#endif
 	} s;
+	struct cvmx_agl_prtx_ctl_s cn61xx;
 	struct cvmx_agl_prtx_ctl_s cn63xx;
 	struct cvmx_agl_prtx_ctl_s cn63xxp1;
+	struct cvmx_agl_prtx_ctl_s cn66xx;
+	struct cvmx_agl_prtx_ctl_s cn68xx;
+	struct cvmx_agl_prtx_ctl_s cn68xxp1;
 };
 
 #endif
diff --git a/arch/mips/include/asm/octeon/cvmx-asxx-defs.h b/arch/mips/include/asm/octeon/cvmx-asxx-defs.h
index 91415a8..a1e21a3 100644
--- a/arch/mips/include/asm/octeon/cvmx-asxx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-asxx-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -28,64 +28,43 @@
 #ifndef __CVMX_ASXX_DEFS_H__
 #define __CVMX_ASXX_DEFS_H__
 
-#define CVMX_ASXX_GMII_RX_CLK_SET(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000180ull + (((block_id) & 0) * 0x8000000ull))
-#define CVMX_ASXX_GMII_RX_DAT_SET(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000188ull + (((block_id) & 0) * 0x8000000ull))
-#define CVMX_ASXX_INT_EN(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000018ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_INT_REG(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000010ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_MII_RX_DAT_SET(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000190ull + (((block_id) & 0) * 0x8000000ull))
-#define CVMX_ASXX_PRT_LOOP(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000040ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RLD_BYPASS(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000248ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RLD_BYPASS_SETTING(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000250ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RLD_COMP(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000220ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RLD_DATA_DRV(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000218ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RLD_FCRAM_MODE(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000210ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RLD_NCTL_STRONG(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000230ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RLD_NCTL_WEAK(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000240ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RLD_PCTL_STRONG(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000228ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RLD_PCTL_WEAK(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000238ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RLD_SETTING(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000258ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RX_CLK_SETX(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000020ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RX_PRT_EN(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000000ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RX_WOL(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000100ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RX_WOL_MSK(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000108ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RX_WOL_POWOK(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000118ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_RX_WOL_SIG(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000110ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_TX_CLK_SETX(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000048ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_TX_COMP_BYP(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000068ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_TX_HI_WATERX(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000080ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_ASXX_TX_PRT_EN(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000008ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_ASXX_GMII_RX_CLK_SET(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000180ull))
+#define CVMX_ASXX_GMII_RX_DAT_SET(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000188ull))
+#define CVMX_ASXX_INT_EN(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000018ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_INT_REG(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000010ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_MII_RX_DAT_SET(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000190ull))
+#define CVMX_ASXX_PRT_LOOP(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000040ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RLD_BYPASS(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000248ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RLD_BYPASS_SETTING(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000250ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RLD_COMP(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000220ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RLD_DATA_DRV(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000218ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RLD_FCRAM_MODE(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000210ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RLD_NCTL_STRONG(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000230ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RLD_NCTL_WEAK(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000240ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RLD_PCTL_STRONG(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000228ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RLD_PCTL_WEAK(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000238ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RLD_SETTING(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000258ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RX_CLK_SETX(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800B0000020ull) + (((offset) & 3) + ((block_id) & 1) * 0x1000000ull) * 8)
+#define CVMX_ASXX_RX_PRT_EN(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000000ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RX_WOL(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000100ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RX_WOL_MSK(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000108ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RX_WOL_POWOK(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000118ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_RX_WOL_SIG(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000110ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_TX_CLK_SETX(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800B0000048ull) + (((offset) & 3) + ((block_id) & 1) * 0x1000000ull) * 8)
+#define CVMX_ASXX_TX_COMP_BYP(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000068ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_ASXX_TX_HI_WATERX(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800B0000080ull) + (((offset) & 3) + ((block_id) & 1) * 0x1000000ull) * 8)
+#define CVMX_ASXX_TX_PRT_EN(block_id) (CVMX_ADD_IO_SEG(0x00011800B0000008ull) + ((block_id) & 1) * 0x8000000ull)
 
 union cvmx_asxx_gmii_rx_clk_set {
 	uint64_t u64;
 	struct cvmx_asxx_gmii_rx_clk_set_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t setting:5;
+#else
+		uint64_t setting:5;
+		uint64_t reserved_5_63:59;
+#endif
 	} s;
 	struct cvmx_asxx_gmii_rx_clk_set_s cn30xx;
 	struct cvmx_asxx_gmii_rx_clk_set_s cn31xx;
@@ -95,8 +74,13 @@
 union cvmx_asxx_gmii_rx_dat_set {
 	uint64_t u64;
 	struct cvmx_asxx_gmii_rx_dat_set_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t setting:5;
+#else
+		uint64_t setting:5;
+		uint64_t reserved_5_63:59;
+#endif
 	} s;
 	struct cvmx_asxx_gmii_rx_dat_set_s cn30xx;
 	struct cvmx_asxx_gmii_rx_dat_set_s cn31xx;
@@ -106,18 +90,34 @@
 union cvmx_asxx_int_en {
 	uint64_t u64;
 	struct cvmx_asxx_int_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t txpsh:4;
 		uint64_t txpop:4;
 		uint64_t ovrflw:4;
+#else
+		uint64_t ovrflw:4;
+		uint64_t txpop:4;
+		uint64_t txpsh:4;
+		uint64_t reserved_12_63:52;
+#endif
 	} s;
 	struct cvmx_asxx_int_en_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_11_63:53;
 		uint64_t txpsh:3;
 		uint64_t reserved_7_7:1;
 		uint64_t txpop:3;
 		uint64_t reserved_3_3:1;
 		uint64_t ovrflw:3;
+#else
+		uint64_t ovrflw:3;
+		uint64_t reserved_3_3:1;
+		uint64_t txpop:3;
+		uint64_t reserved_7_7:1;
+		uint64_t txpsh:3;
+		uint64_t reserved_11_63:53;
+#endif
 	} cn30xx;
 	struct cvmx_asxx_int_en_cn30xx cn31xx;
 	struct cvmx_asxx_int_en_s cn38xx;
@@ -130,18 +130,34 @@
 union cvmx_asxx_int_reg {
 	uint64_t u64;
 	struct cvmx_asxx_int_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t txpsh:4;
 		uint64_t txpop:4;
 		uint64_t ovrflw:4;
+#else
+		uint64_t ovrflw:4;
+		uint64_t txpop:4;
+		uint64_t txpsh:4;
+		uint64_t reserved_12_63:52;
+#endif
 	} s;
 	struct cvmx_asxx_int_reg_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_11_63:53;
 		uint64_t txpsh:3;
 		uint64_t reserved_7_7:1;
 		uint64_t txpop:3;
 		uint64_t reserved_3_3:1;
 		uint64_t ovrflw:3;
+#else
+		uint64_t ovrflw:3;
+		uint64_t reserved_3_3:1;
+		uint64_t txpop:3;
+		uint64_t reserved_7_7:1;
+		uint64_t txpsh:3;
+		uint64_t reserved_11_63:53;
+#endif
 	} cn30xx;
 	struct cvmx_asxx_int_reg_cn30xx cn31xx;
 	struct cvmx_asxx_int_reg_s cn38xx;
@@ -154,8 +170,13 @@
 union cvmx_asxx_mii_rx_dat_set {
 	uint64_t u64;
 	struct cvmx_asxx_mii_rx_dat_set_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t setting:5;
+#else
+		uint64_t setting:5;
+		uint64_t reserved_5_63:59;
+#endif
 	} s;
 	struct cvmx_asxx_mii_rx_dat_set_s cn30xx;
 	struct cvmx_asxx_mii_rx_dat_set_s cn50xx;
@@ -164,15 +185,28 @@
 union cvmx_asxx_prt_loop {
 	uint64_t u64;
 	struct cvmx_asxx_prt_loop_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t ext_loop:4;
 		uint64_t int_loop:4;
+#else
+		uint64_t int_loop:4;
+		uint64_t ext_loop:4;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_asxx_prt_loop_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_7_63:57;
 		uint64_t ext_loop:3;
 		uint64_t reserved_3_3:1;
 		uint64_t int_loop:3;
+#else
+		uint64_t int_loop:3;
+		uint64_t reserved_3_3:1;
+		uint64_t ext_loop:3;
+		uint64_t reserved_7_63:57;
+#endif
 	} cn30xx;
 	struct cvmx_asxx_prt_loop_cn30xx cn31xx;
 	struct cvmx_asxx_prt_loop_s cn38xx;
@@ -185,8 +219,13 @@
 union cvmx_asxx_rld_bypass {
 	uint64_t u64;
 	struct cvmx_asxx_rld_bypass_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t bypass:1;
+#else
+		uint64_t bypass:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_asxx_rld_bypass_s cn38xx;
 	struct cvmx_asxx_rld_bypass_s cn38xxp2;
@@ -197,8 +236,13 @@
 union cvmx_asxx_rld_bypass_setting {
 	uint64_t u64;
 	struct cvmx_asxx_rld_bypass_setting_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t setting:5;
+#else
+		uint64_t setting:5;
+		uint64_t reserved_5_63:59;
+#endif
 	} s;
 	struct cvmx_asxx_rld_bypass_setting_s cn38xx;
 	struct cvmx_asxx_rld_bypass_setting_s cn38xxp2;
@@ -209,14 +253,26 @@
 union cvmx_asxx_rld_comp {
 	uint64_t u64;
 	struct cvmx_asxx_rld_comp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t pctl:5;
 		uint64_t nctl:4;
+#else
+		uint64_t nctl:4;
+		uint64_t pctl:5;
+		uint64_t reserved_9_63:55;
+#endif
 	} s;
 	struct cvmx_asxx_rld_comp_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t pctl:4;
 		uint64_t nctl:4;
+#else
+		uint64_t nctl:4;
+		uint64_t pctl:4;
+		uint64_t reserved_8_63:56;
+#endif
 	} cn38xx;
 	struct cvmx_asxx_rld_comp_cn38xx cn38xxp2;
 	struct cvmx_asxx_rld_comp_s cn58xx;
@@ -226,9 +282,15 @@
 union cvmx_asxx_rld_data_drv {
 	uint64_t u64;
 	struct cvmx_asxx_rld_data_drv_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t pctl:4;
 		uint64_t nctl:4;
+#else
+		uint64_t nctl:4;
+		uint64_t pctl:4;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_asxx_rld_data_drv_s cn38xx;
 	struct cvmx_asxx_rld_data_drv_s cn38xxp2;
@@ -239,8 +301,13 @@
 union cvmx_asxx_rld_fcram_mode {
 	uint64_t u64;
 	struct cvmx_asxx_rld_fcram_mode_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t mode:1;
+#else
+		uint64_t mode:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_asxx_rld_fcram_mode_s cn38xx;
 	struct cvmx_asxx_rld_fcram_mode_s cn38xxp2;
@@ -249,8 +316,13 @@
 union cvmx_asxx_rld_nctl_strong {
 	uint64_t u64;
 	struct cvmx_asxx_rld_nctl_strong_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t nctl:5;
+#else
+		uint64_t nctl:5;
+		uint64_t reserved_5_63:59;
+#endif
 	} s;
 	struct cvmx_asxx_rld_nctl_strong_s cn38xx;
 	struct cvmx_asxx_rld_nctl_strong_s cn38xxp2;
@@ -261,8 +333,13 @@
 union cvmx_asxx_rld_nctl_weak {
 	uint64_t u64;
 	struct cvmx_asxx_rld_nctl_weak_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t nctl:5;
+#else
+		uint64_t nctl:5;
+		uint64_t reserved_5_63:59;
+#endif
 	} s;
 	struct cvmx_asxx_rld_nctl_weak_s cn38xx;
 	struct cvmx_asxx_rld_nctl_weak_s cn38xxp2;
@@ -273,8 +350,13 @@
 union cvmx_asxx_rld_pctl_strong {
 	uint64_t u64;
 	struct cvmx_asxx_rld_pctl_strong_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t pctl:5;
+#else
+		uint64_t pctl:5;
+		uint64_t reserved_5_63:59;
+#endif
 	} s;
 	struct cvmx_asxx_rld_pctl_strong_s cn38xx;
 	struct cvmx_asxx_rld_pctl_strong_s cn38xxp2;
@@ -285,8 +367,13 @@
 union cvmx_asxx_rld_pctl_weak {
 	uint64_t u64;
 	struct cvmx_asxx_rld_pctl_weak_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t pctl:5;
+#else
+		uint64_t pctl:5;
+		uint64_t reserved_5_63:59;
+#endif
 	} s;
 	struct cvmx_asxx_rld_pctl_weak_s cn38xx;
 	struct cvmx_asxx_rld_pctl_weak_s cn38xxp2;
@@ -297,16 +384,30 @@
 union cvmx_asxx_rld_setting {
 	uint64_t u64;
 	struct cvmx_asxx_rld_setting_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_13_63:51;
 		uint64_t dfaset:5;
 		uint64_t dfalag:1;
 		uint64_t dfalead:1;
 		uint64_t dfalock:1;
 		uint64_t setting:5;
+#else
+		uint64_t setting:5;
+		uint64_t dfalock:1;
+		uint64_t dfalead:1;
+		uint64_t dfalag:1;
+		uint64_t dfaset:5;
+		uint64_t reserved_13_63:51;
+#endif
 	} s;
 	struct cvmx_asxx_rld_setting_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t setting:5;
+#else
+		uint64_t setting:5;
+		uint64_t reserved_5_63:59;
+#endif
 	} cn38xx;
 	struct cvmx_asxx_rld_setting_cn38xx cn38xxp2;
 	struct cvmx_asxx_rld_setting_s cn58xx;
@@ -316,8 +417,13 @@
 union cvmx_asxx_rx_clk_setx {
 	uint64_t u64;
 	struct cvmx_asxx_rx_clk_setx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t setting:5;
+#else
+		uint64_t setting:5;
+		uint64_t reserved_5_63:59;
+#endif
 	} s;
 	struct cvmx_asxx_rx_clk_setx_s cn30xx;
 	struct cvmx_asxx_rx_clk_setx_s cn31xx;
@@ -331,12 +437,22 @@
 union cvmx_asxx_rx_prt_en {
 	uint64_t u64;
 	struct cvmx_asxx_rx_prt_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t prt_en:4;
+#else
+		uint64_t prt_en:4;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_asxx_rx_prt_en_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_3_63:61;
 		uint64_t prt_en:3;
+#else
+		uint64_t prt_en:3;
+		uint64_t reserved_3_63:61;
+#endif
 	} cn30xx;
 	struct cvmx_asxx_rx_prt_en_cn30xx cn31xx;
 	struct cvmx_asxx_rx_prt_en_s cn38xx;
@@ -349,9 +465,15 @@
 union cvmx_asxx_rx_wol {
 	uint64_t u64;
 	struct cvmx_asxx_rx_wol_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t status:1;
 		uint64_t enable:1;
+#else
+		uint64_t enable:1;
+		uint64_t status:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_asxx_rx_wol_s cn38xx;
 	struct cvmx_asxx_rx_wol_s cn38xxp2;
@@ -360,7 +482,11 @@
 union cvmx_asxx_rx_wol_msk {
 	uint64_t u64;
 	struct cvmx_asxx_rx_wol_msk_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t msk:64;
+#else
+		uint64_t msk:64;
+#endif
 	} s;
 	struct cvmx_asxx_rx_wol_msk_s cn38xx;
 	struct cvmx_asxx_rx_wol_msk_s cn38xxp2;
@@ -369,8 +495,13 @@
 union cvmx_asxx_rx_wol_powok {
 	uint64_t u64;
 	struct cvmx_asxx_rx_wol_powok_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t powerok:1;
+#else
+		uint64_t powerok:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_asxx_rx_wol_powok_s cn38xx;
 	struct cvmx_asxx_rx_wol_powok_s cn38xxp2;
@@ -379,8 +510,13 @@
 union cvmx_asxx_rx_wol_sig {
 	uint64_t u64;
 	struct cvmx_asxx_rx_wol_sig_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t sig:32;
+#else
+		uint64_t sig:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_asxx_rx_wol_sig_s cn38xx;
 	struct cvmx_asxx_rx_wol_sig_s cn38xxp2;
@@ -389,8 +525,13 @@
 union cvmx_asxx_tx_clk_setx {
 	uint64_t u64;
 	struct cvmx_asxx_tx_clk_setx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t setting:5;
+#else
+		uint64_t setting:5;
+		uint64_t reserved_5_63:59;
+#endif
 	} s;
 	struct cvmx_asxx_tx_clk_setx_s cn30xx;
 	struct cvmx_asxx_tx_clk_setx_s cn31xx;
@@ -404,34 +545,67 @@
 union cvmx_asxx_tx_comp_byp {
 	uint64_t u64;
 	struct cvmx_asxx_tx_comp_byp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_0_63:64;
+#else
+		uint64_t reserved_0_63:64;
+#endif
 	} s;
 	struct cvmx_asxx_tx_comp_byp_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t bypass:1;
 		uint64_t pctl:4;
 		uint64_t nctl:4;
+#else
+		uint64_t nctl:4;
+		uint64_t pctl:4;
+		uint64_t bypass:1;
+		uint64_t reserved_9_63:55;
+#endif
 	} cn30xx;
 	struct cvmx_asxx_tx_comp_byp_cn30xx cn31xx;
 	struct cvmx_asxx_tx_comp_byp_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t pctl:4;
 		uint64_t nctl:4;
+#else
+		uint64_t nctl:4;
+		uint64_t pctl:4;
+		uint64_t reserved_8_63:56;
+#endif
 	} cn38xx;
 	struct cvmx_asxx_tx_comp_byp_cn38xx cn38xxp2;
 	struct cvmx_asxx_tx_comp_byp_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_17_63:47;
 		uint64_t bypass:1;
 		uint64_t reserved_13_15:3;
 		uint64_t pctl:5;
 		uint64_t reserved_5_7:3;
 		uint64_t nctl:5;
+#else
+		uint64_t nctl:5;
+		uint64_t reserved_5_7:3;
+		uint64_t pctl:5;
+		uint64_t reserved_13_15:3;
+		uint64_t bypass:1;
+		uint64_t reserved_17_63:47;
+#endif
 	} cn50xx;
 	struct cvmx_asxx_tx_comp_byp_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_13_63:51;
 		uint64_t pctl:5;
 		uint64_t reserved_5_7:3;
 		uint64_t nctl:5;
+#else
+		uint64_t nctl:5;
+		uint64_t reserved_5_7:3;
+		uint64_t pctl:5;
+		uint64_t reserved_13_63:51;
+#endif
 	} cn58xx;
 	struct cvmx_asxx_tx_comp_byp_cn58xx cn58xxp1;
 };
@@ -439,12 +613,22 @@
 union cvmx_asxx_tx_hi_waterx {
 	uint64_t u64;
 	struct cvmx_asxx_tx_hi_waterx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t mark:4;
+#else
+		uint64_t mark:4;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_asxx_tx_hi_waterx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_3_63:61;
 		uint64_t mark:3;
+#else
+		uint64_t mark:3;
+		uint64_t reserved_3_63:61;
+#endif
 	} cn30xx;
 	struct cvmx_asxx_tx_hi_waterx_cn30xx cn31xx;
 	struct cvmx_asxx_tx_hi_waterx_s cn38xx;
@@ -457,12 +641,22 @@
 union cvmx_asxx_tx_prt_en {
 	uint64_t u64;
 	struct cvmx_asxx_tx_prt_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t prt_en:4;
+#else
+		uint64_t prt_en:4;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_asxx_tx_prt_en_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_3_63:61;
 		uint64_t prt_en:3;
+#else
+		uint64_t prt_en:3;
+		uint64_t reserved_3_63:61;
+#endif
 	} cn30xx;
 	struct cvmx_asxx_tx_prt_en_cn30xx cn31xx;
 	struct cvmx_asxx_tx_prt_en_s cn38xx;
diff --git a/arch/mips/include/asm/octeon/cvmx-ciu-defs.h b/arch/mips/include/asm/octeon/cvmx-ciu-defs.h
index 27cead3..0dd0e40 100644
--- a/arch/mips/include/asm/octeon/cvmx-ciu-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-ciu-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -31,6 +31,18 @@
 #define CVMX_CIU_BIST (CVMX_ADD_IO_SEG(0x0001070000000730ull))
 #define CVMX_CIU_BLOCK_INT (CVMX_ADD_IO_SEG(0x00010700000007C0ull))
 #define CVMX_CIU_DINT (CVMX_ADD_IO_SEG(0x0001070000000720ull))
+#define CVMX_CIU_EN2_IOX_INT(offset) (CVMX_ADD_IO_SEG(0x000107000000A600ull) + ((offset) & 1) * 8)
+#define CVMX_CIU_EN2_IOX_INT_W1C(offset) (CVMX_ADD_IO_SEG(0x000107000000CE00ull) + ((offset) & 1) * 8)
+#define CVMX_CIU_EN2_IOX_INT_W1S(offset) (CVMX_ADD_IO_SEG(0x000107000000AE00ull) + ((offset) & 1) * 8)
+#define CVMX_CIU_EN2_PPX_IP2(offset) (CVMX_ADD_IO_SEG(0x000107000000A000ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_EN2_PPX_IP2_W1C(offset) (CVMX_ADD_IO_SEG(0x000107000000C800ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_EN2_PPX_IP2_W1S(offset) (CVMX_ADD_IO_SEG(0x000107000000A800ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_EN2_PPX_IP3(offset) (CVMX_ADD_IO_SEG(0x000107000000A200ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_EN2_PPX_IP3_W1C(offset) (CVMX_ADD_IO_SEG(0x000107000000CA00ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_EN2_PPX_IP3_W1S(offset) (CVMX_ADD_IO_SEG(0x000107000000AA00ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_EN2_PPX_IP4(offset) (CVMX_ADD_IO_SEG(0x000107000000A400ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_EN2_PPX_IP4_W1C(offset) (CVMX_ADD_IO_SEG(0x000107000000CC00ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_EN2_PPX_IP4_W1S(offset) (CVMX_ADD_IO_SEG(0x000107000000AC00ull) + ((offset) & 15) * 8)
 #define CVMX_CIU_FUSE (CVMX_ADD_IO_SEG(0x0001070000000728ull))
 #define CVMX_CIU_GSTOP (CVMX_ADD_IO_SEG(0x0001070000000710ull))
 #define CVMX_CIU_INT33_SUM0 (CVMX_ADD_IO_SEG(0x0001070000000110ull))
@@ -50,59 +62,378 @@
 #define CVMX_CIU_INTX_SUM4(offset) (CVMX_ADD_IO_SEG(0x0001070000000C00ull) + ((offset) & 15) * 8)
 #define CVMX_CIU_INT_DBG_SEL (CVMX_ADD_IO_SEG(0x00010700000007D0ull))
 #define CVMX_CIU_INT_SUM1 (CVMX_ADD_IO_SEG(0x0001070000000108ull))
-#define CVMX_CIU_MBOX_CLRX(offset) (CVMX_ADD_IO_SEG(0x0001070000000680ull) + ((offset) & 15) * 8)
-#define CVMX_CIU_MBOX_SETX(offset) (CVMX_ADD_IO_SEG(0x0001070000000600ull) + ((offset) & 15) * 8)
+static inline uint64_t CVMX_CIU_MBOX_CLRX(unsigned long offset)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000680ull) + (offset) * 8;
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000680ull) + (offset) * 8;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000680ull) + (offset) * 8;
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000680ull) + (offset) * 8;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000680ull) + (offset) * 8;
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000680ull) + (offset) * 8;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000680ull) + (offset) * 8;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070100100600ull) + (offset) * 8;
+	}
+	return CVMX_ADD_IO_SEG(0x0001070000000680ull) + (offset) * 8;
+}
+
+static inline uint64_t CVMX_CIU_MBOX_SETX(unsigned long offset)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000600ull) + (offset) * 8;
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000600ull) + (offset) * 8;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000600ull) + (offset) * 8;
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000600ull) + (offset) * 8;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000600ull) + (offset) * 8;
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000600ull) + (offset) * 8;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000600ull) + (offset) * 8;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070100100400ull) + (offset) * 8;
+	}
+	return CVMX_ADD_IO_SEG(0x0001070000000600ull) + (offset) * 8;
+}
+
 #define CVMX_CIU_NMI (CVMX_ADD_IO_SEG(0x0001070000000718ull))
 #define CVMX_CIU_PCI_INTA (CVMX_ADD_IO_SEG(0x0001070000000750ull))
+#define CVMX_CIU_PP_BIST_STAT (CVMX_ADD_IO_SEG(0x00010700000007E0ull))
 #define CVMX_CIU_PP_DBG (CVMX_ADD_IO_SEG(0x0001070000000708ull))
-#define CVMX_CIU_PP_POKEX(offset) (CVMX_ADD_IO_SEG(0x0001070000000580ull) + ((offset) & 15) * 8)
+static inline uint64_t CVMX_CIU_PP_POKEX(unsigned long offset)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8;
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8;
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8;
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070100100200ull) + (offset) * 8;
+	}
+	return CVMX_ADD_IO_SEG(0x0001070000000580ull) + (offset) * 8;
+}
+
 #define CVMX_CIU_PP_RST (CVMX_ADD_IO_SEG(0x0001070000000700ull))
 #define CVMX_CIU_QLM0 (CVMX_ADD_IO_SEG(0x0001070000000780ull))
 #define CVMX_CIU_QLM1 (CVMX_ADD_IO_SEG(0x0001070000000788ull))
 #define CVMX_CIU_QLM2 (CVMX_ADD_IO_SEG(0x0001070000000790ull))
+#define CVMX_CIU_QLM3 (CVMX_ADD_IO_SEG(0x0001070000000798ull))
+#define CVMX_CIU_QLM4 (CVMX_ADD_IO_SEG(0x00010700000007A0ull))
 #define CVMX_CIU_QLM_DCOK (CVMX_ADD_IO_SEG(0x0001070000000760ull))
 #define CVMX_CIU_QLM_JTGC (CVMX_ADD_IO_SEG(0x0001070000000768ull))
 #define CVMX_CIU_QLM_JTGD (CVMX_ADD_IO_SEG(0x0001070000000770ull))
 #define CVMX_CIU_SOFT_BIST (CVMX_ADD_IO_SEG(0x0001070000000738ull))
 #define CVMX_CIU_SOFT_PRST (CVMX_ADD_IO_SEG(0x0001070000000748ull))
 #define CVMX_CIU_SOFT_PRST1 (CVMX_ADD_IO_SEG(0x0001070000000758ull))
+#define CVMX_CIU_SOFT_PRST2 (CVMX_ADD_IO_SEG(0x00010700000007D8ull))
+#define CVMX_CIU_SOFT_PRST3 (CVMX_ADD_IO_SEG(0x00010700000007E0ull))
 #define CVMX_CIU_SOFT_RST (CVMX_ADD_IO_SEG(0x0001070000000740ull))
-#define CVMX_CIU_TIMX(offset) (CVMX_ADD_IO_SEG(0x0001070000000480ull) + ((offset) & 3) * 8)
-#define CVMX_CIU_WDOGX(offset) (CVMX_ADD_IO_SEG(0x0001070000000500ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_SUM1_IOX_INT(offset) (CVMX_ADD_IO_SEG(0x0001070000008600ull) + ((offset) & 1) * 8)
+#define CVMX_CIU_SUM1_PPX_IP2(offset) (CVMX_ADD_IO_SEG(0x0001070000008000ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_SUM1_PPX_IP3(offset) (CVMX_ADD_IO_SEG(0x0001070000008200ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_SUM1_PPX_IP4(offset) (CVMX_ADD_IO_SEG(0x0001070000008400ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_SUM2_IOX_INT(offset) (CVMX_ADD_IO_SEG(0x0001070000008E00ull) + ((offset) & 1) * 8)
+#define CVMX_CIU_SUM2_PPX_IP2(offset) (CVMX_ADD_IO_SEG(0x0001070000008800ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_SUM2_PPX_IP3(offset) (CVMX_ADD_IO_SEG(0x0001070000008A00ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_SUM2_PPX_IP4(offset) (CVMX_ADD_IO_SEG(0x0001070000008C00ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_TIMX(offset) (CVMX_ADD_IO_SEG(0x0001070000000480ull) + ((offset) & 15) * 8)
+#define CVMX_CIU_TIM_MULTI_CAST (CVMX_ADD_IO_SEG(0x000107000000C200ull))
+static inline uint64_t CVMX_CIU_WDOGX(unsigned long offset)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8;
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8;
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8;
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001070100100000ull) + (offset) * 8;
+	}
+	return CVMX_ADD_IO_SEG(0x0001070000000500ull) + (offset) * 8;
+}
 
 union cvmx_ciu_bist {
 	uint64_t u64;
 	struct cvmx_ciu_bist_s {
-		uint64_t reserved_5_63:59;
-		uint64_t bist:5;
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_7_63:57;
+		uint64_t bist:7;
+#else
+		uint64_t bist:7;
+		uint64_t reserved_7_63:57;
+#endif
 	} s;
 	struct cvmx_ciu_bist_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t bist:4;
+#else
+		uint64_t bist:4;
+		uint64_t reserved_4_63:60;
+#endif
 	} cn30xx;
 	struct cvmx_ciu_bist_cn30xx cn31xx;
 	struct cvmx_ciu_bist_cn30xx cn38xx;
 	struct cvmx_ciu_bist_cn30xx cn38xxp2;
 	struct cvmx_ciu_bist_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t bist:2;
+#else
+		uint64_t bist:2;
+		uint64_t reserved_2_63:62;
+#endif
 	} cn50xx;
 	struct cvmx_ciu_bist_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_3_63:61;
 		uint64_t bist:3;
+#else
+		uint64_t bist:3;
+		uint64_t reserved_3_63:61;
+#endif
 	} cn52xx;
 	struct cvmx_ciu_bist_cn52xx cn52xxp1;
 	struct cvmx_ciu_bist_cn30xx cn56xx;
 	struct cvmx_ciu_bist_cn30xx cn56xxp1;
 	struct cvmx_ciu_bist_cn30xx cn58xx;
 	struct cvmx_ciu_bist_cn30xx cn58xxp1;
-	struct cvmx_ciu_bist_s cn63xx;
-	struct cvmx_ciu_bist_s cn63xxp1;
+	struct cvmx_ciu_bist_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_6_63:58;
+		uint64_t bist:6;
+#else
+		uint64_t bist:6;
+		uint64_t reserved_6_63:58;
+#endif
+	} cn61xx;
+	struct cvmx_ciu_bist_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_5_63:59;
+		uint64_t bist:5;
+#else
+		uint64_t bist:5;
+		uint64_t reserved_5_63:59;
+#endif
+	} cn63xx;
+	struct cvmx_ciu_bist_cn63xx cn63xxp1;
+	struct cvmx_ciu_bist_cn61xx cn66xx;
+	struct cvmx_ciu_bist_s cn68xx;
+	struct cvmx_ciu_bist_s cn68xxp1;
+	struct cvmx_ciu_bist_cn61xx cnf71xx;
 };
 
 union cvmx_ciu_block_int {
 	uint64_t u64;
 	struct cvmx_ciu_block_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_62_63:2;
+		uint64_t srio3:1;
+		uint64_t srio2:1;
+		uint64_t reserved_43_59:17;
+		uint64_t ptp:1;
+		uint64_t dpi:1;
+		uint64_t dfm:1;
+		uint64_t reserved_34_39:6;
+		uint64_t srio1:1;
+		uint64_t srio0:1;
+		uint64_t reserved_31_31:1;
+		uint64_t iob:1;
+		uint64_t reserved_29_29:1;
+		uint64_t agl:1;
+		uint64_t reserved_27_27:1;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t reserved_24_24:1;
+		uint64_t asxpcs1:1;
+		uint64_t asxpcs0:1;
+		uint64_t reserved_21_21:1;
+		uint64_t pip:1;
+		uint64_t reserved_18_19:2;
+		uint64_t lmc0:1;
+		uint64_t l2c:1;
+		uint64_t reserved_15_15:1;
+		uint64_t rad:1;
+		uint64_t usb:1;
+		uint64_t pow:1;
+		uint64_t tim:1;
+		uint64_t pko:1;
+		uint64_t ipd:1;
+		uint64_t reserved_8_8:1;
+		uint64_t zip:1;
+		uint64_t dfa:1;
+		uint64_t fpa:1;
+		uint64_t key:1;
+		uint64_t sli:1;
+		uint64_t gmx1:1;
+		uint64_t gmx0:1;
+		uint64_t mio:1;
+#else
+		uint64_t mio:1;
+		uint64_t gmx0:1;
+		uint64_t gmx1:1;
+		uint64_t sli:1;
+		uint64_t key:1;
+		uint64_t fpa:1;
+		uint64_t dfa:1;
+		uint64_t zip:1;
+		uint64_t reserved_8_8:1;
+		uint64_t ipd:1;
+		uint64_t pko:1;
+		uint64_t tim:1;
+		uint64_t pow:1;
+		uint64_t usb:1;
+		uint64_t rad:1;
+		uint64_t reserved_15_15:1;
+		uint64_t l2c:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_18_19:2;
+		uint64_t pip:1;
+		uint64_t reserved_21_21:1;
+		uint64_t asxpcs0:1;
+		uint64_t asxpcs1:1;
+		uint64_t reserved_24_24:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t reserved_27_27:1;
+		uint64_t agl:1;
+		uint64_t reserved_29_29:1;
+		uint64_t iob:1;
+		uint64_t reserved_31_31:1;
+		uint64_t srio0:1;
+		uint64_t srio1:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dfm:1;
+		uint64_t dpi:1;
+		uint64_t ptp:1;
+		uint64_t reserved_43_59:17;
+		uint64_t srio2:1;
+		uint64_t srio3:1;
+		uint64_t reserved_62_63:2;
+#endif
+	} s;
+	struct cvmx_ciu_block_int_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_43_63:21;
+		uint64_t ptp:1;
+		uint64_t dpi:1;
+		uint64_t reserved_31_40:10;
+		uint64_t iob:1;
+		uint64_t reserved_29_29:1;
+		uint64_t agl:1;
+		uint64_t reserved_27_27:1;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t reserved_24_24:1;
+		uint64_t asxpcs1:1;
+		uint64_t asxpcs0:1;
+		uint64_t reserved_21_21:1;
+		uint64_t pip:1;
+		uint64_t reserved_18_19:2;
+		uint64_t lmc0:1;
+		uint64_t l2c:1;
+		uint64_t reserved_15_15:1;
+		uint64_t rad:1;
+		uint64_t usb:1;
+		uint64_t pow:1;
+		uint64_t tim:1;
+		uint64_t pko:1;
+		uint64_t ipd:1;
+		uint64_t reserved_8_8:1;
+		uint64_t zip:1;
+		uint64_t dfa:1;
+		uint64_t fpa:1;
+		uint64_t key:1;
+		uint64_t sli:1;
+		uint64_t gmx1:1;
+		uint64_t gmx0:1;
+		uint64_t mio:1;
+#else
+		uint64_t mio:1;
+		uint64_t gmx0:1;
+		uint64_t gmx1:1;
+		uint64_t sli:1;
+		uint64_t key:1;
+		uint64_t fpa:1;
+		uint64_t dfa:1;
+		uint64_t zip:1;
+		uint64_t reserved_8_8:1;
+		uint64_t ipd:1;
+		uint64_t pko:1;
+		uint64_t tim:1;
+		uint64_t pow:1;
+		uint64_t usb:1;
+		uint64_t rad:1;
+		uint64_t reserved_15_15:1;
+		uint64_t l2c:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_18_19:2;
+		uint64_t pip:1;
+		uint64_t reserved_21_21:1;
+		uint64_t asxpcs0:1;
+		uint64_t asxpcs1:1;
+		uint64_t reserved_24_24:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t reserved_27_27:1;
+		uint64_t agl:1;
+		uint64_t reserved_29_29:1;
+		uint64_t iob:1;
+		uint64_t reserved_31_40:10;
+		uint64_t dpi:1;
+		uint64_t ptp:1;
+		uint64_t reserved_43_63:21;
+#endif
+	} cn61xx;
+	struct cvmx_ciu_block_int_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_43_63:21;
 		uint64_t ptp:1;
 		uint64_t dpi:1;
@@ -140,88 +471,789 @@
 		uint64_t reserved_2_2:1;
 		uint64_t gmx0:1;
 		uint64_t mio:1;
-	} s;
-	struct cvmx_ciu_block_int_s cn63xx;
-	struct cvmx_ciu_block_int_s cn63xxp1;
+#else
+		uint64_t mio:1;
+		uint64_t gmx0:1;
+		uint64_t reserved_2_2:1;
+		uint64_t sli:1;
+		uint64_t key:1;
+		uint64_t fpa:1;
+		uint64_t dfa:1;
+		uint64_t zip:1;
+		uint64_t reserved_8_8:1;
+		uint64_t ipd:1;
+		uint64_t pko:1;
+		uint64_t tim:1;
+		uint64_t pow:1;
+		uint64_t usb:1;
+		uint64_t rad:1;
+		uint64_t reserved_15_15:1;
+		uint64_t l2c:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_18_19:2;
+		uint64_t pip:1;
+		uint64_t reserved_21_21:1;
+		uint64_t asxpcs0:1;
+		uint64_t reserved_23_24:2;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t reserved_27_27:1;
+		uint64_t agl:1;
+		uint64_t reserved_29_29:1;
+		uint64_t iob:1;
+		uint64_t reserved_31_31:1;
+		uint64_t srio0:1;
+		uint64_t srio1:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dfm:1;
+		uint64_t dpi:1;
+		uint64_t ptp:1;
+		uint64_t reserved_43_63:21;
+#endif
+	} cn63xx;
+	struct cvmx_ciu_block_int_cn63xx cn63xxp1;
+	struct cvmx_ciu_block_int_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_62_63:2;
+		uint64_t srio3:1;
+		uint64_t srio2:1;
+		uint64_t reserved_43_59:17;
+		uint64_t ptp:1;
+		uint64_t dpi:1;
+		uint64_t dfm:1;
+		uint64_t reserved_33_39:7;
+		uint64_t srio0:1;
+		uint64_t reserved_31_31:1;
+		uint64_t iob:1;
+		uint64_t reserved_29_29:1;
+		uint64_t agl:1;
+		uint64_t reserved_27_27:1;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t reserved_24_24:1;
+		uint64_t asxpcs1:1;
+		uint64_t asxpcs0:1;
+		uint64_t reserved_21_21:1;
+		uint64_t pip:1;
+		uint64_t reserved_18_19:2;
+		uint64_t lmc0:1;
+		uint64_t l2c:1;
+		uint64_t reserved_15_15:1;
+		uint64_t rad:1;
+		uint64_t usb:1;
+		uint64_t pow:1;
+		uint64_t tim:1;
+		uint64_t pko:1;
+		uint64_t ipd:1;
+		uint64_t reserved_8_8:1;
+		uint64_t zip:1;
+		uint64_t dfa:1;
+		uint64_t fpa:1;
+		uint64_t key:1;
+		uint64_t sli:1;
+		uint64_t gmx1:1;
+		uint64_t gmx0:1;
+		uint64_t mio:1;
+#else
+		uint64_t mio:1;
+		uint64_t gmx0:1;
+		uint64_t gmx1:1;
+		uint64_t sli:1;
+		uint64_t key:1;
+		uint64_t fpa:1;
+		uint64_t dfa:1;
+		uint64_t zip:1;
+		uint64_t reserved_8_8:1;
+		uint64_t ipd:1;
+		uint64_t pko:1;
+		uint64_t tim:1;
+		uint64_t pow:1;
+		uint64_t usb:1;
+		uint64_t rad:1;
+		uint64_t reserved_15_15:1;
+		uint64_t l2c:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_18_19:2;
+		uint64_t pip:1;
+		uint64_t reserved_21_21:1;
+		uint64_t asxpcs0:1;
+		uint64_t asxpcs1:1;
+		uint64_t reserved_24_24:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t reserved_27_27:1;
+		uint64_t agl:1;
+		uint64_t reserved_29_29:1;
+		uint64_t iob:1;
+		uint64_t reserved_31_31:1;
+		uint64_t srio0:1;
+		uint64_t reserved_33_39:7;
+		uint64_t dfm:1;
+		uint64_t dpi:1;
+		uint64_t ptp:1;
+		uint64_t reserved_43_59:17;
+		uint64_t srio2:1;
+		uint64_t srio3:1;
+		uint64_t reserved_62_63:2;
+#endif
+	} cn66xx;
+	struct cvmx_ciu_block_int_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_43_63:21;
+		uint64_t ptp:1;
+		uint64_t dpi:1;
+		uint64_t reserved_31_40:10;
+		uint64_t iob:1;
+		uint64_t reserved_27_29:3;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t reserved_23_24:2;
+		uint64_t asxpcs0:1;
+		uint64_t reserved_21_21:1;
+		uint64_t pip:1;
+		uint64_t reserved_18_19:2;
+		uint64_t lmc0:1;
+		uint64_t l2c:1;
+		uint64_t reserved_15_15:1;
+		uint64_t rad:1;
+		uint64_t usb:1;
+		uint64_t pow:1;
+		uint64_t tim:1;
+		uint64_t pko:1;
+		uint64_t ipd:1;
+		uint64_t reserved_6_8:3;
+		uint64_t fpa:1;
+		uint64_t key:1;
+		uint64_t sli:1;
+		uint64_t reserved_2_2:1;
+		uint64_t gmx0:1;
+		uint64_t mio:1;
+#else
+		uint64_t mio:1;
+		uint64_t gmx0:1;
+		uint64_t reserved_2_2:1;
+		uint64_t sli:1;
+		uint64_t key:1;
+		uint64_t fpa:1;
+		uint64_t reserved_6_8:3;
+		uint64_t ipd:1;
+		uint64_t pko:1;
+		uint64_t tim:1;
+		uint64_t pow:1;
+		uint64_t usb:1;
+		uint64_t rad:1;
+		uint64_t reserved_15_15:1;
+		uint64_t l2c:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_18_19:2;
+		uint64_t pip:1;
+		uint64_t reserved_21_21:1;
+		uint64_t asxpcs0:1;
+		uint64_t reserved_23_24:2;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t reserved_27_29:3;
+		uint64_t iob:1;
+		uint64_t reserved_31_40:10;
+		uint64_t dpi:1;
+		uint64_t ptp:1;
+		uint64_t reserved_43_63:21;
+#endif
+	} cnf71xx;
 };
 
 union cvmx_ciu_dint {
 	uint64_t u64;
 	struct cvmx_ciu_dint_s {
-		uint64_t reserved_16_63:48;
-		uint64_t dint:16;
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t dint:32;
+#else
+		uint64_t dint:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_ciu_dint_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t dint:1;
+#else
+		uint64_t dint:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} cn30xx;
 	struct cvmx_ciu_dint_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t dint:2;
+#else
+		uint64_t dint:2;
+		uint64_t reserved_2_63:62;
+#endif
 	} cn31xx;
-	struct cvmx_ciu_dint_s cn38xx;
-	struct cvmx_ciu_dint_s cn38xxp2;
+	struct cvmx_ciu_dint_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t dint:16;
+#else
+		uint64_t dint:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} cn38xx;
+	struct cvmx_ciu_dint_cn38xx cn38xxp2;
 	struct cvmx_ciu_dint_cn31xx cn50xx;
 	struct cvmx_ciu_dint_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t dint:4;
+#else
+		uint64_t dint:4;
+		uint64_t reserved_4_63:60;
+#endif
 	} cn52xx;
 	struct cvmx_ciu_dint_cn52xx cn52xxp1;
 	struct cvmx_ciu_dint_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t dint:12;
+#else
+		uint64_t dint:12;
+		uint64_t reserved_12_63:52;
+#endif
 	} cn56xx;
 	struct cvmx_ciu_dint_cn56xx cn56xxp1;
-	struct cvmx_ciu_dint_s cn58xx;
-	struct cvmx_ciu_dint_s cn58xxp1;
+	struct cvmx_ciu_dint_cn38xx cn58xx;
+	struct cvmx_ciu_dint_cn38xx cn58xxp1;
+	struct cvmx_ciu_dint_cn52xx cn61xx;
 	struct cvmx_ciu_dint_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t dint:6;
+#else
+		uint64_t dint:6;
+		uint64_t reserved_6_63:58;
+#endif
 	} cn63xx;
 	struct cvmx_ciu_dint_cn63xx cn63xxp1;
+	struct cvmx_ciu_dint_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t dint:10;
+#else
+		uint64_t dint:10;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn66xx;
+	struct cvmx_ciu_dint_s cn68xx;
+	struct cvmx_ciu_dint_s cn68xxp1;
+	struct cvmx_ciu_dint_cn52xx cnf71xx;
+};
+
+union cvmx_ciu_en2_iox_int {
+	uint64_t u64;
+	struct cvmx_ciu_en2_iox_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_15_63:49;
+		uint64_t endor:2;
+		uint64_t eoi:1;
+		uint64_t reserved_10_11:2;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_11:2;
+		uint64_t eoi:1;
+		uint64_t endor:2;
+		uint64_t reserved_15_63:49;
+#endif
+	} s;
+	struct cvmx_ciu_en2_iox_int_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn61xx;
+	struct cvmx_ciu_en2_iox_int_cn61xx cn66xx;
+	struct cvmx_ciu_en2_iox_int_s cnf71xx;
+};
+
+union cvmx_ciu_en2_iox_int_w1c {
+	uint64_t u64;
+	struct cvmx_ciu_en2_iox_int_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_15_63:49;
+		uint64_t endor:2;
+		uint64_t eoi:1;
+		uint64_t reserved_10_11:2;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_11:2;
+		uint64_t eoi:1;
+		uint64_t endor:2;
+		uint64_t reserved_15_63:49;
+#endif
+	} s;
+	struct cvmx_ciu_en2_iox_int_w1c_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn61xx;
+	struct cvmx_ciu_en2_iox_int_w1c_cn61xx cn66xx;
+	struct cvmx_ciu_en2_iox_int_w1c_s cnf71xx;
+};
+
+union cvmx_ciu_en2_iox_int_w1s {
+	uint64_t u64;
+	struct cvmx_ciu_en2_iox_int_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_15_63:49;
+		uint64_t endor:2;
+		uint64_t eoi:1;
+		uint64_t reserved_10_11:2;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_11:2;
+		uint64_t eoi:1;
+		uint64_t endor:2;
+		uint64_t reserved_15_63:49;
+#endif
+	} s;
+	struct cvmx_ciu_en2_iox_int_w1s_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn61xx;
+	struct cvmx_ciu_en2_iox_int_w1s_cn61xx cn66xx;
+	struct cvmx_ciu_en2_iox_int_w1s_s cnf71xx;
+};
+
+union cvmx_ciu_en2_ppx_ip2 {
+	uint64_t u64;
+	struct cvmx_ciu_en2_ppx_ip2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_15_63:49;
+		uint64_t endor:2;
+		uint64_t eoi:1;
+		uint64_t reserved_10_11:2;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_11:2;
+		uint64_t eoi:1;
+		uint64_t endor:2;
+		uint64_t reserved_15_63:49;
+#endif
+	} s;
+	struct cvmx_ciu_en2_ppx_ip2_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn61xx;
+	struct cvmx_ciu_en2_ppx_ip2_cn61xx cn66xx;
+	struct cvmx_ciu_en2_ppx_ip2_s cnf71xx;
+};
+
+union cvmx_ciu_en2_ppx_ip2_w1c {
+	uint64_t u64;
+	struct cvmx_ciu_en2_ppx_ip2_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_15_63:49;
+		uint64_t endor:2;
+		uint64_t eoi:1;
+		uint64_t reserved_10_11:2;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_11:2;
+		uint64_t eoi:1;
+		uint64_t endor:2;
+		uint64_t reserved_15_63:49;
+#endif
+	} s;
+	struct cvmx_ciu_en2_ppx_ip2_w1c_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn61xx;
+	struct cvmx_ciu_en2_ppx_ip2_w1c_cn61xx cn66xx;
+	struct cvmx_ciu_en2_ppx_ip2_w1c_s cnf71xx;
+};
+
+union cvmx_ciu_en2_ppx_ip2_w1s {
+	uint64_t u64;
+	struct cvmx_ciu_en2_ppx_ip2_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_15_63:49;
+		uint64_t endor:2;
+		uint64_t eoi:1;
+		uint64_t reserved_10_11:2;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_11:2;
+		uint64_t eoi:1;
+		uint64_t endor:2;
+		uint64_t reserved_15_63:49;
+#endif
+	} s;
+	struct cvmx_ciu_en2_ppx_ip2_w1s_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn61xx;
+	struct cvmx_ciu_en2_ppx_ip2_w1s_cn61xx cn66xx;
+	struct cvmx_ciu_en2_ppx_ip2_w1s_s cnf71xx;
+};
+
+union cvmx_ciu_en2_ppx_ip3 {
+	uint64_t u64;
+	struct cvmx_ciu_en2_ppx_ip3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_15_63:49;
+		uint64_t endor:2;
+		uint64_t eoi:1;
+		uint64_t reserved_10_11:2;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_11:2;
+		uint64_t eoi:1;
+		uint64_t endor:2;
+		uint64_t reserved_15_63:49;
+#endif
+	} s;
+	struct cvmx_ciu_en2_ppx_ip3_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn61xx;
+	struct cvmx_ciu_en2_ppx_ip3_cn61xx cn66xx;
+	struct cvmx_ciu_en2_ppx_ip3_s cnf71xx;
+};
+
+union cvmx_ciu_en2_ppx_ip3_w1c {
+	uint64_t u64;
+	struct cvmx_ciu_en2_ppx_ip3_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_15_63:49;
+		uint64_t endor:2;
+		uint64_t eoi:1;
+		uint64_t reserved_10_11:2;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_11:2;
+		uint64_t eoi:1;
+		uint64_t endor:2;
+		uint64_t reserved_15_63:49;
+#endif
+	} s;
+	struct cvmx_ciu_en2_ppx_ip3_w1c_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn61xx;
+	struct cvmx_ciu_en2_ppx_ip3_w1c_cn61xx cn66xx;
+	struct cvmx_ciu_en2_ppx_ip3_w1c_s cnf71xx;
+};
+
+union cvmx_ciu_en2_ppx_ip3_w1s {
+	uint64_t u64;
+	struct cvmx_ciu_en2_ppx_ip3_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_15_63:49;
+		uint64_t endor:2;
+		uint64_t eoi:1;
+		uint64_t reserved_10_11:2;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_11:2;
+		uint64_t eoi:1;
+		uint64_t endor:2;
+		uint64_t reserved_15_63:49;
+#endif
+	} s;
+	struct cvmx_ciu_en2_ppx_ip3_w1s_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn61xx;
+	struct cvmx_ciu_en2_ppx_ip3_w1s_cn61xx cn66xx;
+	struct cvmx_ciu_en2_ppx_ip3_w1s_s cnf71xx;
+};
+
+union cvmx_ciu_en2_ppx_ip4 {
+	uint64_t u64;
+	struct cvmx_ciu_en2_ppx_ip4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_15_63:49;
+		uint64_t endor:2;
+		uint64_t eoi:1;
+		uint64_t reserved_10_11:2;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_11:2;
+		uint64_t eoi:1;
+		uint64_t endor:2;
+		uint64_t reserved_15_63:49;
+#endif
+	} s;
+	struct cvmx_ciu_en2_ppx_ip4_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn61xx;
+	struct cvmx_ciu_en2_ppx_ip4_cn61xx cn66xx;
+	struct cvmx_ciu_en2_ppx_ip4_s cnf71xx;
+};
+
+union cvmx_ciu_en2_ppx_ip4_w1c {
+	uint64_t u64;
+	struct cvmx_ciu_en2_ppx_ip4_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_15_63:49;
+		uint64_t endor:2;
+		uint64_t eoi:1;
+		uint64_t reserved_10_11:2;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_11:2;
+		uint64_t eoi:1;
+		uint64_t endor:2;
+		uint64_t reserved_15_63:49;
+#endif
+	} s;
+	struct cvmx_ciu_en2_ppx_ip4_w1c_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn61xx;
+	struct cvmx_ciu_en2_ppx_ip4_w1c_cn61xx cn66xx;
+	struct cvmx_ciu_en2_ppx_ip4_w1c_s cnf71xx;
+};
+
+union cvmx_ciu_en2_ppx_ip4_w1s {
+	uint64_t u64;
+	struct cvmx_ciu_en2_ppx_ip4_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_15_63:49;
+		uint64_t endor:2;
+		uint64_t eoi:1;
+		uint64_t reserved_10_11:2;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_11:2;
+		uint64_t eoi:1;
+		uint64_t endor:2;
+		uint64_t reserved_15_63:49;
+#endif
+	} s;
+	struct cvmx_ciu_en2_ppx_ip4_w1s_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn61xx;
+	struct cvmx_ciu_en2_ppx_ip4_w1s_cn61xx cn66xx;
+	struct cvmx_ciu_en2_ppx_ip4_w1s_s cnf71xx;
 };
 
 union cvmx_ciu_fuse {
 	uint64_t u64;
 	struct cvmx_ciu_fuse_s {
-		uint64_t reserved_16_63:48;
-		uint64_t fuse:16;
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t fuse:32;
+#else
+		uint64_t fuse:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_ciu_fuse_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t fuse:1;
+#else
+		uint64_t fuse:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} cn30xx;
 	struct cvmx_ciu_fuse_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t fuse:2;
+#else
+		uint64_t fuse:2;
+		uint64_t reserved_2_63:62;
+#endif
 	} cn31xx;
-	struct cvmx_ciu_fuse_s cn38xx;
-	struct cvmx_ciu_fuse_s cn38xxp2;
+	struct cvmx_ciu_fuse_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t fuse:16;
+#else
+		uint64_t fuse:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} cn38xx;
+	struct cvmx_ciu_fuse_cn38xx cn38xxp2;
 	struct cvmx_ciu_fuse_cn31xx cn50xx;
 	struct cvmx_ciu_fuse_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t fuse:4;
+#else
+		uint64_t fuse:4;
+		uint64_t reserved_4_63:60;
+#endif
 	} cn52xx;
 	struct cvmx_ciu_fuse_cn52xx cn52xxp1;
 	struct cvmx_ciu_fuse_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t fuse:12;
+#else
+		uint64_t fuse:12;
+		uint64_t reserved_12_63:52;
+#endif
 	} cn56xx;
 	struct cvmx_ciu_fuse_cn56xx cn56xxp1;
-	struct cvmx_ciu_fuse_s cn58xx;
-	struct cvmx_ciu_fuse_s cn58xxp1;
+	struct cvmx_ciu_fuse_cn38xx cn58xx;
+	struct cvmx_ciu_fuse_cn38xx cn58xxp1;
+	struct cvmx_ciu_fuse_cn52xx cn61xx;
 	struct cvmx_ciu_fuse_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t fuse:6;
+#else
+		uint64_t fuse:6;
+		uint64_t reserved_6_63:58;
+#endif
 	} cn63xx;
 	struct cvmx_ciu_fuse_cn63xx cn63xxp1;
+	struct cvmx_ciu_fuse_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t fuse:10;
+#else
+		uint64_t fuse:10;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn66xx;
+	struct cvmx_ciu_fuse_s cn68xx;
+	struct cvmx_ciu_fuse_s cn68xxp1;
+	struct cvmx_ciu_fuse_cn52xx cnf71xx;
 };
 
 union cvmx_ciu_gstop {
 	uint64_t u64;
 	struct cvmx_ciu_gstop_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t gstop:1;
+#else
+		uint64_t gstop:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_ciu_gstop_s cn30xx;
 	struct cvmx_ciu_gstop_s cn31xx;
@@ -234,13 +1266,19 @@
 	struct cvmx_ciu_gstop_s cn56xxp1;
 	struct cvmx_ciu_gstop_s cn58xx;
 	struct cvmx_ciu_gstop_s cn58xxp1;
+	struct cvmx_ciu_gstop_s cn61xx;
 	struct cvmx_ciu_gstop_s cn63xx;
 	struct cvmx_ciu_gstop_s cn63xxp1;
+	struct cvmx_ciu_gstop_s cn66xx;
+	struct cvmx_ciu_gstop_s cn68xx;
+	struct cvmx_ciu_gstop_s cn68xxp1;
+	struct cvmx_ciu_gstop_s cnf71xx;
 };
 
 union cvmx_ciu_intx_en0 {
 	uint64_t u64;
 	struct cvmx_ciu_intx_en0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t bootdma:1;
 		uint64_t mii:1;
 		uint64_t ipdppthr:1;
@@ -263,8 +1301,33 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t key_zero:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
 	} s;
 	struct cvmx_ciu_intx_en0_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_59_63:5;
 		uint64_t mpi:1;
 		uint64_t pcm:1;
@@ -284,8 +1347,30 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t reserved_47_47:1;
+		uint64_t gmx_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t reserved_59_63:5;
+#endif
 	} cn30xx;
 	struct cvmx_ciu_intx_en0_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_59_63:5;
 		uint64_t mpi:1;
 		uint64_t pcm:1;
@@ -305,8 +1390,30 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t reserved_59_63:5;
+#endif
 	} cn31xx;
 	struct cvmx_ciu_intx_en0_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_56_63:8;
 		uint64_t timer:4;
 		uint64_t key_zero:1;
@@ -322,10 +1429,28 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t key_zero:1;
+		uint64_t timer:4;
+		uint64_t reserved_56_63:8;
+#endif
 	} cn38xx;
 	struct cvmx_ciu_intx_en0_cn38xx cn38xxp2;
 	struct cvmx_ciu_intx_en0_cn30xx cn50xx;
 	struct cvmx_ciu_intx_en0_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t bootdma:1;
 		uint64_t mii:1;
 		uint64_t ipdppthr:1;
@@ -348,9 +1473,34 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t reserved_57_58:2;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
 	} cn52xx;
 	struct cvmx_ciu_intx_en0_cn52xx cn52xxp1;
 	struct cvmx_ciu_intx_en0_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t bootdma:1;
 		uint64_t mii:1;
 		uint64_t ipdppthr:1;
@@ -372,23 +1522,197 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t key_zero:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t reserved_57_58:2;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
 	} cn56xx;
 	struct cvmx_ciu_intx_en0_cn56xx cn56xxp1;
 	struct cvmx_ciu_intx_en0_cn38xx cn58xx;
 	struct cvmx_ciu_intx_en0_cn38xx cn58xxp1;
+	struct cvmx_ciu_intx_en0_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t mii:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t mpi:1;
+		uint64_t pcm:1;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t reserved_51_51:1;
+		uint64_t ipd_drp:1;
+		uint64_t gmx_drp:2;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t reserved_44_44:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
+	} cn61xx;
 	struct cvmx_ciu_intx_en0_cn52xx cn63xx;
 	struct cvmx_ciu_intx_en0_cn52xx cn63xxp1;
+	struct cvmx_ciu_intx_en0_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t mii:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t mpi:1;
+		uint64_t reserved_57_57:1;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t reserved_51_51:1;
+		uint64_t ipd_drp:1;
+		uint64_t gmx_drp:2;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t reserved_44_44:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t reserved_57_57:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
+	} cn66xx;
+	struct cvmx_ciu_intx_en0_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t reserved_62_62:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t mpi:1;
+		uint64_t pcm:1;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t reserved_51_51:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t gmx_drp:1;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t reserved_44_44:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t reserved_62_62:1;
+		uint64_t bootdma:1;
+#endif
+	} cnf71xx;
 };
 
 union cvmx_ciu_intx_en0_w1c {
 	uint64_t u64;
 	struct cvmx_ciu_intx_en0_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t bootdma:1;
 		uint64_t mii:1;
 		uint64_t ipdppthr:1;
 		uint64_t powiq:1;
 		uint64_t twsi2:1;
-		uint64_t reserved_57_58:2;
+		uint64_t mpi:1;
+		uint64_t pcm:1;
 		uint64_t usb:1;
 		uint64_t timer:4;
 		uint64_t key_zero:1;
@@ -404,8 +1728,33 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t key_zero:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
 	} s;
 	struct cvmx_ciu_intx_en0_w1c_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t bootdma:1;
 		uint64_t mii:1;
 		uint64_t ipdppthr:1;
@@ -428,9 +1777,80 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t reserved_57_58:2;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
 	} cn52xx;
-	struct cvmx_ciu_intx_en0_w1c_s cn56xx;
+	struct cvmx_ciu_intx_en0_w1c_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t mii:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t reserved_57_58:2;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t key_zero:1;
+		uint64_t ipd_drp:1;
+		uint64_t gmx_drp:2;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t reserved_44_44:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t key_zero:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t reserved_57_58:2;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
+	} cn56xx;
 	struct cvmx_ciu_intx_en0_w1c_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_56_63:8;
 		uint64_t timer:4;
 		uint64_t key_zero:1;
@@ -446,20 +1866,188 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t key_zero:1;
+		uint64_t timer:4;
+		uint64_t reserved_56_63:8;
+#endif
 	} cn58xx;
+	struct cvmx_ciu_intx_en0_w1c_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t mii:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t mpi:1;
+		uint64_t pcm:1;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t reserved_51_51:1;
+		uint64_t ipd_drp:1;
+		uint64_t gmx_drp:2;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t reserved_44_44:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
+	} cn61xx;
 	struct cvmx_ciu_intx_en0_w1c_cn52xx cn63xx;
 	struct cvmx_ciu_intx_en0_w1c_cn52xx cn63xxp1;
+	struct cvmx_ciu_intx_en0_w1c_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t mii:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t mpi:1;
+		uint64_t reserved_57_57:1;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t reserved_51_51:1;
+		uint64_t ipd_drp:1;
+		uint64_t gmx_drp:2;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t reserved_44_44:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t reserved_57_57:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
+	} cn66xx;
+	struct cvmx_ciu_intx_en0_w1c_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t reserved_62_62:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t mpi:1;
+		uint64_t pcm:1;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t reserved_51_51:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t gmx_drp:1;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t reserved_44_44:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t reserved_62_62:1;
+		uint64_t bootdma:1;
+#endif
+	} cnf71xx;
 };
 
 union cvmx_ciu_intx_en0_w1s {
 	uint64_t u64;
 	struct cvmx_ciu_intx_en0_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t bootdma:1;
 		uint64_t mii:1;
 		uint64_t ipdppthr:1;
 		uint64_t powiq:1;
 		uint64_t twsi2:1;
-		uint64_t reserved_57_58:2;
+		uint64_t mpi:1;
+		uint64_t pcm:1;
 		uint64_t usb:1;
 		uint64_t timer:4;
 		uint64_t key_zero:1;
@@ -475,8 +2063,33 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t key_zero:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
 	} s;
 	struct cvmx_ciu_intx_en0_w1s_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t bootdma:1;
 		uint64_t mii:1;
 		uint64_t ipdppthr:1;
@@ -499,9 +2112,80 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t reserved_57_58:2;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
 	} cn52xx;
-	struct cvmx_ciu_intx_en0_w1s_s cn56xx;
+	struct cvmx_ciu_intx_en0_w1s_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t mii:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t reserved_57_58:2;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t key_zero:1;
+		uint64_t ipd_drp:1;
+		uint64_t gmx_drp:2;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t reserved_44_44:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t key_zero:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t reserved_57_58:2;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
+	} cn56xx;
 	struct cvmx_ciu_intx_en0_w1s_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_56_63:8;
 		uint64_t timer:4;
 		uint64_t key_zero:1;
@@ -517,16 +2201,186 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t key_zero:1;
+		uint64_t timer:4;
+		uint64_t reserved_56_63:8;
+#endif
 	} cn58xx;
+	struct cvmx_ciu_intx_en0_w1s_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t mii:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t mpi:1;
+		uint64_t pcm:1;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t reserved_51_51:1;
+		uint64_t ipd_drp:1;
+		uint64_t gmx_drp:2;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t reserved_44_44:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
+	} cn61xx;
 	struct cvmx_ciu_intx_en0_w1s_cn52xx cn63xx;
 	struct cvmx_ciu_intx_en0_w1s_cn52xx cn63xxp1;
+	struct cvmx_ciu_intx_en0_w1s_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t mii:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t mpi:1;
+		uint64_t reserved_57_57:1;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t reserved_51_51:1;
+		uint64_t ipd_drp:1;
+		uint64_t gmx_drp:2;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t reserved_44_44:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t reserved_57_57:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
+	} cn66xx;
+	struct cvmx_ciu_intx_en0_w1s_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t reserved_62_62:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t mpi:1;
+		uint64_t pcm:1;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t reserved_51_51:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t gmx_drp:1;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t reserved_44_44:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t reserved_62_62:1;
+		uint64_t bootdma:1;
+#endif
+	} cnf71xx;
 };
 
 union cvmx_ciu_intx_en1 {
 	uint64_t u64;
 	struct cvmx_ciu_intx_en1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t rst:1;
-		uint64_t reserved_57_62:6;
+		uint64_t reserved_62_62:1;
+		uint64_t srio3:1;
+		uint64_t srio2:1;
+		uint64_t reserved_57_59:3;
 		uint64_t dfm:1;
 		uint64_t reserved_53_55:3;
 		uint64_t lmc0:1;
@@ -536,7 +2390,10 @@
 		uint64_t pem0:1;
 		uint64_t ptp:1;
 		uint64_t agl:1;
-		uint64_t reserved_37_45:9;
+		uint64_t reserved_41_45:5;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_38_39:2;
+		uint64_t agx1:1;
 		uint64_t agx0:1;
 		uint64_t dpi:1;
 		uint64_t sli:1;
@@ -559,22 +2416,80 @@
 		uint64_t usb1:1;
 		uint64_t uart2:1;
 		uint64_t wdog:16;
+#else
+		uint64_t wdog:16;
+		uint64_t uart2:1;
+		uint64_t usb1:1;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_39:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_45:5;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t srio1:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_59:3;
+		uint64_t srio2:1;
+		uint64_t srio3:1;
+		uint64_t reserved_62_62:1;
+		uint64_t rst:1;
+#endif
 	} s;
 	struct cvmx_ciu_intx_en1_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t wdog:1;
+#else
+		uint64_t wdog:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} cn30xx;
 	struct cvmx_ciu_intx_en1_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t wdog:2;
+#else
+		uint64_t wdog:2;
+		uint64_t reserved_2_63:62;
+#endif
 	} cn31xx;
 	struct cvmx_ciu_intx_en1_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t wdog:16;
+#else
+		uint64_t wdog:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} cn38xx;
 	struct cvmx_ciu_intx_en1_cn38xx cn38xxp2;
 	struct cvmx_ciu_intx_en1_cn31xx cn50xx;
 	struct cvmx_ciu_intx_en1_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t nand:1;
 		uint64_t mii1:1;
@@ -582,23 +2497,118 @@
 		uint64_t uart2:1;
 		uint64_t reserved_4_15:12;
 		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_15:12;
+		uint64_t uart2:1;
+		uint64_t usb1:1;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t reserved_20_63:44;
+#endif
 	} cn52xx;
 	struct cvmx_ciu_intx_en1_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_19_63:45;
 		uint64_t mii1:1;
 		uint64_t usb1:1;
 		uint64_t uart2:1;
 		uint64_t reserved_4_15:12;
 		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_15:12;
+		uint64_t uart2:1;
+		uint64_t usb1:1;
+		uint64_t mii1:1;
+		uint64_t reserved_19_63:45;
+#endif
 	} cn52xxp1;
 	struct cvmx_ciu_intx_en1_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t wdog:12;
+#else
+		uint64_t wdog:12;
+		uint64_t reserved_12_63:52;
+#endif
 	} cn56xx;
 	struct cvmx_ciu_intx_en1_cn56xx cn56xxp1;
 	struct cvmx_ciu_intx_en1_cn38xx cn58xx;
 	struct cvmx_ciu_intx_en1_cn38xx cn58xxp1;
+	struct cvmx_ciu_intx_en1_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_53_62:10;
+		uint64_t lmc0:1;
+		uint64_t reserved_50_51:2;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t agl:1;
+		uint64_t reserved_41_45:5;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_38_39:2;
+		uint64_t agx1:1;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t dfa:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t zip:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t mii1:1;
+		uint64_t reserved_4_17:14;
+		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_17:14;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_39:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_45:5;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t reserved_50_51:2;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_62:10;
+		uint64_t rst:1;
+#endif
+	} cn61xx;
 	struct cvmx_ciu_intx_en1_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t rst:1;
 		uint64_t reserved_57_62:6;
 		uint64_t dfm:1;
@@ -632,15 +2642,198 @@
 		uint64_t mii1:1;
 		uint64_t reserved_6_17:12;
 		uint64_t wdog:6;
+#else
+		uint64_t wdog:6;
+		uint64_t reserved_6_17:12;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t reserved_37_45:9;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t srio1:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_62:6;
+		uint64_t rst:1;
+#endif
 	} cn63xx;
 	struct cvmx_ciu_intx_en1_cn63xx cn63xxp1;
+	struct cvmx_ciu_intx_en1_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_62_62:1;
+		uint64_t srio3:1;
+		uint64_t srio2:1;
+		uint64_t reserved_57_59:3;
+		uint64_t dfm:1;
+		uint64_t reserved_53_55:3;
+		uint64_t lmc0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t srio0:1;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t agl:1;
+		uint64_t reserved_38_45:8;
+		uint64_t agx1:1;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t dfa:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t zip:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t mii1:1;
+		uint64_t reserved_10_17:8;
+		uint64_t wdog:10;
+#else
+		uint64_t wdog:10;
+		uint64_t reserved_10_17:8;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_45:8;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_59:3;
+		uint64_t srio2:1;
+		uint64_t srio3:1;
+		uint64_t reserved_62_62:1;
+		uint64_t rst:1;
+#endif
+	} cn66xx;
+	struct cvmx_ciu_intx_en1_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_53_62:10;
+		uint64_t lmc0:1;
+		uint64_t reserved_50_51:2;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t reserved_41_46:6;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t reserved_32_32:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_28_28:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_4_18:15;
+		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_18:15;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_28_28:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_32_32:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_46:6;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t reserved_50_51:2;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_62:10;
+		uint64_t rst:1;
+#endif
+	} cnf71xx;
 };
 
 union cvmx_ciu_intx_en1_w1c {
 	uint64_t u64;
 	struct cvmx_ciu_intx_en1_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t rst:1;
-		uint64_t reserved_57_62:6;
+		uint64_t reserved_62_62:1;
+		uint64_t srio3:1;
+		uint64_t srio2:1;
+		uint64_t reserved_57_59:3;
 		uint64_t dfm:1;
 		uint64_t reserved_53_55:3;
 		uint64_t lmc0:1;
@@ -650,7 +2843,10 @@
 		uint64_t pem0:1;
 		uint64_t ptp:1;
 		uint64_t agl:1;
-		uint64_t reserved_37_45:9;
+		uint64_t reserved_41_45:5;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_38_39:2;
+		uint64_t agx1:1;
 		uint64_t agx0:1;
 		uint64_t dpi:1;
 		uint64_t sli:1;
@@ -673,8 +2869,51 @@
 		uint64_t usb1:1;
 		uint64_t uart2:1;
 		uint64_t wdog:16;
+#else
+		uint64_t wdog:16;
+		uint64_t uart2:1;
+		uint64_t usb1:1;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_39:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_45:5;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t srio1:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_59:3;
+		uint64_t srio2:1;
+		uint64_t srio3:1;
+		uint64_t reserved_62_62:1;
+		uint64_t rst:1;
+#endif
 	} s;
 	struct cvmx_ciu_intx_en1_w1c_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t nand:1;
 		uint64_t mii1:1;
@@ -682,16 +2921,107 @@
 		uint64_t uart2:1;
 		uint64_t reserved_4_15:12;
 		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_15:12;
+		uint64_t uart2:1;
+		uint64_t usb1:1;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t reserved_20_63:44;
+#endif
 	} cn52xx;
 	struct cvmx_ciu_intx_en1_w1c_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t wdog:12;
+#else
+		uint64_t wdog:12;
+		uint64_t reserved_12_63:52;
+#endif
 	} cn56xx;
 	struct cvmx_ciu_intx_en1_w1c_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t wdog:16;
+#else
+		uint64_t wdog:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} cn58xx;
+	struct cvmx_ciu_intx_en1_w1c_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_53_62:10;
+		uint64_t lmc0:1;
+		uint64_t reserved_50_51:2;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t agl:1;
+		uint64_t reserved_41_45:5;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_38_39:2;
+		uint64_t agx1:1;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t dfa:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t zip:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t mii1:1;
+		uint64_t reserved_4_17:14;
+		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_17:14;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_39:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_45:5;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t reserved_50_51:2;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_62:10;
+		uint64_t rst:1;
+#endif
+	} cn61xx;
 	struct cvmx_ciu_intx_en1_w1c_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t rst:1;
 		uint64_t reserved_57_62:6;
 		uint64_t dfm:1;
@@ -725,15 +3055,198 @@
 		uint64_t mii1:1;
 		uint64_t reserved_6_17:12;
 		uint64_t wdog:6;
+#else
+		uint64_t wdog:6;
+		uint64_t reserved_6_17:12;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t reserved_37_45:9;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t srio1:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_62:6;
+		uint64_t rst:1;
+#endif
 	} cn63xx;
 	struct cvmx_ciu_intx_en1_w1c_cn63xx cn63xxp1;
+	struct cvmx_ciu_intx_en1_w1c_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_62_62:1;
+		uint64_t srio3:1;
+		uint64_t srio2:1;
+		uint64_t reserved_57_59:3;
+		uint64_t dfm:1;
+		uint64_t reserved_53_55:3;
+		uint64_t lmc0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t srio0:1;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t agl:1;
+		uint64_t reserved_38_45:8;
+		uint64_t agx1:1;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t dfa:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t zip:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t mii1:1;
+		uint64_t reserved_10_17:8;
+		uint64_t wdog:10;
+#else
+		uint64_t wdog:10;
+		uint64_t reserved_10_17:8;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_45:8;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_59:3;
+		uint64_t srio2:1;
+		uint64_t srio3:1;
+		uint64_t reserved_62_62:1;
+		uint64_t rst:1;
+#endif
+	} cn66xx;
+	struct cvmx_ciu_intx_en1_w1c_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_53_62:10;
+		uint64_t lmc0:1;
+		uint64_t reserved_50_51:2;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t reserved_41_46:6;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t reserved_32_32:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_28_28:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_4_18:15;
+		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_18:15;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_28_28:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_32_32:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_46:6;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t reserved_50_51:2;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_62:10;
+		uint64_t rst:1;
+#endif
+	} cnf71xx;
 };
 
 union cvmx_ciu_intx_en1_w1s {
 	uint64_t u64;
 	struct cvmx_ciu_intx_en1_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t rst:1;
-		uint64_t reserved_57_62:6;
+		uint64_t reserved_62_62:1;
+		uint64_t srio3:1;
+		uint64_t srio2:1;
+		uint64_t reserved_57_59:3;
 		uint64_t dfm:1;
 		uint64_t reserved_53_55:3;
 		uint64_t lmc0:1;
@@ -743,7 +3256,10 @@
 		uint64_t pem0:1;
 		uint64_t ptp:1;
 		uint64_t agl:1;
-		uint64_t reserved_37_45:9;
+		uint64_t reserved_41_45:5;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_38_39:2;
+		uint64_t agx1:1;
 		uint64_t agx0:1;
 		uint64_t dpi:1;
 		uint64_t sli:1;
@@ -766,8 +3282,51 @@
 		uint64_t usb1:1;
 		uint64_t uart2:1;
 		uint64_t wdog:16;
+#else
+		uint64_t wdog:16;
+		uint64_t uart2:1;
+		uint64_t usb1:1;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_39:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_45:5;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t srio1:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_59:3;
+		uint64_t srio2:1;
+		uint64_t srio3:1;
+		uint64_t reserved_62_62:1;
+		uint64_t rst:1;
+#endif
 	} s;
 	struct cvmx_ciu_intx_en1_w1s_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t nand:1;
 		uint64_t mii1:1;
@@ -775,16 +3334,107 @@
 		uint64_t uart2:1;
 		uint64_t reserved_4_15:12;
 		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_15:12;
+		uint64_t uart2:1;
+		uint64_t usb1:1;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t reserved_20_63:44;
+#endif
 	} cn52xx;
 	struct cvmx_ciu_intx_en1_w1s_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t wdog:12;
+#else
+		uint64_t wdog:12;
+		uint64_t reserved_12_63:52;
+#endif
 	} cn56xx;
 	struct cvmx_ciu_intx_en1_w1s_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t wdog:16;
+#else
+		uint64_t wdog:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} cn58xx;
+	struct cvmx_ciu_intx_en1_w1s_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_53_62:10;
+		uint64_t lmc0:1;
+		uint64_t reserved_50_51:2;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t agl:1;
+		uint64_t reserved_41_45:5;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_38_39:2;
+		uint64_t agx1:1;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t dfa:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t zip:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t mii1:1;
+		uint64_t reserved_4_17:14;
+		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_17:14;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_39:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_45:5;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t reserved_50_51:2;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_62:10;
+		uint64_t rst:1;
+#endif
+	} cn61xx;
 	struct cvmx_ciu_intx_en1_w1s_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t rst:1;
 		uint64_t reserved_57_62:6;
 		uint64_t dfm:1;
@@ -818,13 +3468,193 @@
 		uint64_t mii1:1;
 		uint64_t reserved_6_17:12;
 		uint64_t wdog:6;
+#else
+		uint64_t wdog:6;
+		uint64_t reserved_6_17:12;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t reserved_37_45:9;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t srio1:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_62:6;
+		uint64_t rst:1;
+#endif
 	} cn63xx;
 	struct cvmx_ciu_intx_en1_w1s_cn63xx cn63xxp1;
+	struct cvmx_ciu_intx_en1_w1s_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_62_62:1;
+		uint64_t srio3:1;
+		uint64_t srio2:1;
+		uint64_t reserved_57_59:3;
+		uint64_t dfm:1;
+		uint64_t reserved_53_55:3;
+		uint64_t lmc0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t srio0:1;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t agl:1;
+		uint64_t reserved_38_45:8;
+		uint64_t agx1:1;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t dfa:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t zip:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t mii1:1;
+		uint64_t reserved_10_17:8;
+		uint64_t wdog:10;
+#else
+		uint64_t wdog:10;
+		uint64_t reserved_10_17:8;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_45:8;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_59:3;
+		uint64_t srio2:1;
+		uint64_t srio3:1;
+		uint64_t reserved_62_62:1;
+		uint64_t rst:1;
+#endif
+	} cn66xx;
+	struct cvmx_ciu_intx_en1_w1s_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_53_62:10;
+		uint64_t lmc0:1;
+		uint64_t reserved_50_51:2;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t reserved_41_46:6;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t reserved_32_32:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_28_28:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_4_18:15;
+		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_18:15;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_28_28:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_32_32:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_46:6;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t reserved_50_51:2;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_62:10;
+		uint64_t rst:1;
+#endif
+	} cnf71xx;
 };
 
 union cvmx_ciu_intx_en4_0 {
 	uint64_t u64;
 	struct cvmx_ciu_intx_en4_0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t bootdma:1;
 		uint64_t mii:1;
 		uint64_t ipdppthr:1;
@@ -847,8 +3677,33 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t key_zero:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
 	} s;
 	struct cvmx_ciu_intx_en4_0_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_59_63:5;
 		uint64_t mpi:1;
 		uint64_t pcm:1;
@@ -868,8 +3723,30 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t reserved_47_47:1;
+		uint64_t gmx_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t reserved_59_63:5;
+#endif
 	} cn50xx;
 	struct cvmx_ciu_intx_en4_0_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t bootdma:1;
 		uint64_t mii:1;
 		uint64_t ipdppthr:1;
@@ -892,9 +3769,34 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t reserved_57_58:2;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
 	} cn52xx;
 	struct cvmx_ciu_intx_en4_0_cn52xx cn52xxp1;
 	struct cvmx_ciu_intx_en4_0_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t bootdma:1;
 		uint64_t mii:1;
 		uint64_t ipdppthr:1;
@@ -916,9 +3818,33 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t key_zero:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t reserved_57_58:2;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
 	} cn56xx;
 	struct cvmx_ciu_intx_en4_0_cn56xx cn56xxp1;
 	struct cvmx_ciu_intx_en4_0_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_56_63:8;
 		uint64_t timer:4;
 		uint64_t key_zero:1;
@@ -934,21 +3860,189 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t key_zero:1;
+		uint64_t timer:4;
+		uint64_t reserved_56_63:8;
+#endif
 	} cn58xx;
 	struct cvmx_ciu_intx_en4_0_cn58xx cn58xxp1;
+	struct cvmx_ciu_intx_en4_0_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t mii:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t mpi:1;
+		uint64_t pcm:1;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t reserved_51_51:1;
+		uint64_t ipd_drp:1;
+		uint64_t gmx_drp:2;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t reserved_44_44:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
+	} cn61xx;
 	struct cvmx_ciu_intx_en4_0_cn52xx cn63xx;
 	struct cvmx_ciu_intx_en4_0_cn52xx cn63xxp1;
+	struct cvmx_ciu_intx_en4_0_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t mii:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t mpi:1;
+		uint64_t reserved_57_57:1;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t reserved_51_51:1;
+		uint64_t ipd_drp:1;
+		uint64_t gmx_drp:2;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t reserved_44_44:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t reserved_57_57:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
+	} cn66xx;
+	struct cvmx_ciu_intx_en4_0_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t reserved_62_62:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t mpi:1;
+		uint64_t pcm:1;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t reserved_51_51:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t gmx_drp:1;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t reserved_44_44:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t reserved_62_62:1;
+		uint64_t bootdma:1;
+#endif
+	} cnf71xx;
 };
 
 union cvmx_ciu_intx_en4_0_w1c {
 	uint64_t u64;
 	struct cvmx_ciu_intx_en4_0_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t bootdma:1;
 		uint64_t mii:1;
 		uint64_t ipdppthr:1;
 		uint64_t powiq:1;
 		uint64_t twsi2:1;
-		uint64_t reserved_57_58:2;
+		uint64_t mpi:1;
+		uint64_t pcm:1;
 		uint64_t usb:1;
 		uint64_t timer:4;
 		uint64_t key_zero:1;
@@ -964,8 +4058,33 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t key_zero:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
 	} s;
 	struct cvmx_ciu_intx_en4_0_w1c_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t bootdma:1;
 		uint64_t mii:1;
 		uint64_t ipdppthr:1;
@@ -988,9 +4107,80 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t reserved_57_58:2;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
 	} cn52xx;
-	struct cvmx_ciu_intx_en4_0_w1c_s cn56xx;
+	struct cvmx_ciu_intx_en4_0_w1c_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t mii:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t reserved_57_58:2;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t key_zero:1;
+		uint64_t ipd_drp:1;
+		uint64_t gmx_drp:2;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t reserved_44_44:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t key_zero:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t reserved_57_58:2;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
+	} cn56xx;
 	struct cvmx_ciu_intx_en4_0_w1c_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_56_63:8;
 		uint64_t timer:4;
 		uint64_t key_zero:1;
@@ -1006,20 +4196,188 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t key_zero:1;
+		uint64_t timer:4;
+		uint64_t reserved_56_63:8;
+#endif
 	} cn58xx;
+	struct cvmx_ciu_intx_en4_0_w1c_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t mii:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t mpi:1;
+		uint64_t pcm:1;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t reserved_51_51:1;
+		uint64_t ipd_drp:1;
+		uint64_t gmx_drp:2;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t reserved_44_44:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
+	} cn61xx;
 	struct cvmx_ciu_intx_en4_0_w1c_cn52xx cn63xx;
 	struct cvmx_ciu_intx_en4_0_w1c_cn52xx cn63xxp1;
+	struct cvmx_ciu_intx_en4_0_w1c_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t mii:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t mpi:1;
+		uint64_t reserved_57_57:1;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t reserved_51_51:1;
+		uint64_t ipd_drp:1;
+		uint64_t gmx_drp:2;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t reserved_44_44:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t reserved_57_57:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
+	} cn66xx;
+	struct cvmx_ciu_intx_en4_0_w1c_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t reserved_62_62:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t mpi:1;
+		uint64_t pcm:1;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t reserved_51_51:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t gmx_drp:1;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t reserved_44_44:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t reserved_62_62:1;
+		uint64_t bootdma:1;
+#endif
+	} cnf71xx;
 };
 
 union cvmx_ciu_intx_en4_0_w1s {
 	uint64_t u64;
 	struct cvmx_ciu_intx_en4_0_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t bootdma:1;
 		uint64_t mii:1;
 		uint64_t ipdppthr:1;
 		uint64_t powiq:1;
 		uint64_t twsi2:1;
-		uint64_t reserved_57_58:2;
+		uint64_t mpi:1;
+		uint64_t pcm:1;
 		uint64_t usb:1;
 		uint64_t timer:4;
 		uint64_t key_zero:1;
@@ -1035,8 +4393,33 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t key_zero:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
 	} s;
 	struct cvmx_ciu_intx_en4_0_w1s_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t bootdma:1;
 		uint64_t mii:1;
 		uint64_t ipdppthr:1;
@@ -1059,9 +4442,80 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t reserved_57_58:2;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
 	} cn52xx;
-	struct cvmx_ciu_intx_en4_0_w1s_s cn56xx;
+	struct cvmx_ciu_intx_en4_0_w1s_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t mii:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t reserved_57_58:2;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t key_zero:1;
+		uint64_t ipd_drp:1;
+		uint64_t gmx_drp:2;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t reserved_44_44:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t key_zero:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t reserved_57_58:2;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
+	} cn56xx;
 	struct cvmx_ciu_intx_en4_0_w1s_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_56_63:8;
 		uint64_t timer:4;
 		uint64_t key_zero:1;
@@ -1077,16 +4531,186 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t key_zero:1;
+		uint64_t timer:4;
+		uint64_t reserved_56_63:8;
+#endif
 	} cn58xx;
+	struct cvmx_ciu_intx_en4_0_w1s_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t mii:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t mpi:1;
+		uint64_t pcm:1;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t reserved_51_51:1;
+		uint64_t ipd_drp:1;
+		uint64_t gmx_drp:2;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t reserved_44_44:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
+	} cn61xx;
 	struct cvmx_ciu_intx_en4_0_w1s_cn52xx cn63xx;
 	struct cvmx_ciu_intx_en4_0_w1s_cn52xx cn63xxp1;
+	struct cvmx_ciu_intx_en4_0_w1s_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t mii:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t mpi:1;
+		uint64_t reserved_57_57:1;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t reserved_51_51:1;
+		uint64_t ipd_drp:1;
+		uint64_t gmx_drp:2;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t reserved_44_44:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t reserved_57_57:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
+	} cn66xx;
+	struct cvmx_ciu_intx_en4_0_w1s_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t reserved_62_62:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t mpi:1;
+		uint64_t pcm:1;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t reserved_51_51:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t gmx_drp:1;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t reserved_44_44:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t reserved_44_44:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t reserved_62_62:1;
+		uint64_t bootdma:1;
+#endif
+	} cnf71xx;
 };
 
 union cvmx_ciu_intx_en4_1 {
 	uint64_t u64;
 	struct cvmx_ciu_intx_en4_1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t rst:1;
-		uint64_t reserved_57_62:6;
+		uint64_t reserved_62_62:1;
+		uint64_t srio3:1;
+		uint64_t srio2:1;
+		uint64_t reserved_57_59:3;
 		uint64_t dfm:1;
 		uint64_t reserved_53_55:3;
 		uint64_t lmc0:1;
@@ -1096,7 +4720,10 @@
 		uint64_t pem0:1;
 		uint64_t ptp:1;
 		uint64_t agl:1;
-		uint64_t reserved_37_45:9;
+		uint64_t reserved_41_45:5;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_38_39:2;
+		uint64_t agx1:1;
 		uint64_t agx0:1;
 		uint64_t dpi:1;
 		uint64_t sli:1;
@@ -1119,12 +4746,60 @@
 		uint64_t usb1:1;
 		uint64_t uart2:1;
 		uint64_t wdog:16;
+#else
+		uint64_t wdog:16;
+		uint64_t uart2:1;
+		uint64_t usb1:1;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_39:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_45:5;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t srio1:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_59:3;
+		uint64_t srio2:1;
+		uint64_t srio3:1;
+		uint64_t reserved_62_62:1;
+		uint64_t rst:1;
+#endif
 	} s;
 	struct cvmx_ciu_intx_en4_1_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t wdog:2;
+#else
+		uint64_t wdog:2;
+		uint64_t reserved_2_63:62;
+#endif
 	} cn50xx;
 	struct cvmx_ciu_intx_en4_1_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t nand:1;
 		uint64_t mii1:1;
@@ -1132,26 +4807,126 @@
 		uint64_t uart2:1;
 		uint64_t reserved_4_15:12;
 		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_15:12;
+		uint64_t uart2:1;
+		uint64_t usb1:1;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t reserved_20_63:44;
+#endif
 	} cn52xx;
 	struct cvmx_ciu_intx_en4_1_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_19_63:45;
 		uint64_t mii1:1;
 		uint64_t usb1:1;
 		uint64_t uart2:1;
 		uint64_t reserved_4_15:12;
 		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_15:12;
+		uint64_t uart2:1;
+		uint64_t usb1:1;
+		uint64_t mii1:1;
+		uint64_t reserved_19_63:45;
+#endif
 	} cn52xxp1;
 	struct cvmx_ciu_intx_en4_1_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t wdog:12;
+#else
+		uint64_t wdog:12;
+		uint64_t reserved_12_63:52;
+#endif
 	} cn56xx;
 	struct cvmx_ciu_intx_en4_1_cn56xx cn56xxp1;
 	struct cvmx_ciu_intx_en4_1_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t wdog:16;
+#else
+		uint64_t wdog:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} cn58xx;
 	struct cvmx_ciu_intx_en4_1_cn58xx cn58xxp1;
+	struct cvmx_ciu_intx_en4_1_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_53_62:10;
+		uint64_t lmc0:1;
+		uint64_t reserved_50_51:2;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t agl:1;
+		uint64_t reserved_41_45:5;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_38_39:2;
+		uint64_t agx1:1;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t dfa:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t zip:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t mii1:1;
+		uint64_t reserved_4_17:14;
+		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_17:14;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_39:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_45:5;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t reserved_50_51:2;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_62:10;
+		uint64_t rst:1;
+#endif
+	} cn61xx;
 	struct cvmx_ciu_intx_en4_1_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t rst:1;
 		uint64_t reserved_57_62:6;
 		uint64_t dfm:1;
@@ -1185,15 +4960,198 @@
 		uint64_t mii1:1;
 		uint64_t reserved_6_17:12;
 		uint64_t wdog:6;
+#else
+		uint64_t wdog:6;
+		uint64_t reserved_6_17:12;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t reserved_37_45:9;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t srio1:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_62:6;
+		uint64_t rst:1;
+#endif
 	} cn63xx;
 	struct cvmx_ciu_intx_en4_1_cn63xx cn63xxp1;
+	struct cvmx_ciu_intx_en4_1_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_62_62:1;
+		uint64_t srio3:1;
+		uint64_t srio2:1;
+		uint64_t reserved_57_59:3;
+		uint64_t dfm:1;
+		uint64_t reserved_53_55:3;
+		uint64_t lmc0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t srio0:1;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t agl:1;
+		uint64_t reserved_38_45:8;
+		uint64_t agx1:1;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t dfa:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t zip:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t mii1:1;
+		uint64_t reserved_10_17:8;
+		uint64_t wdog:10;
+#else
+		uint64_t wdog:10;
+		uint64_t reserved_10_17:8;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_45:8;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_59:3;
+		uint64_t srio2:1;
+		uint64_t srio3:1;
+		uint64_t reserved_62_62:1;
+		uint64_t rst:1;
+#endif
+	} cn66xx;
+	struct cvmx_ciu_intx_en4_1_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_53_62:10;
+		uint64_t lmc0:1;
+		uint64_t reserved_50_51:2;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t reserved_41_46:6;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t reserved_32_32:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_28_28:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_4_18:15;
+		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_18:15;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_28_28:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_32_32:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_46:6;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t reserved_50_51:2;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_62:10;
+		uint64_t rst:1;
+#endif
+	} cnf71xx;
 };
 
 union cvmx_ciu_intx_en4_1_w1c {
 	uint64_t u64;
 	struct cvmx_ciu_intx_en4_1_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t rst:1;
-		uint64_t reserved_57_62:6;
+		uint64_t reserved_62_62:1;
+		uint64_t srio3:1;
+		uint64_t srio2:1;
+		uint64_t reserved_57_59:3;
 		uint64_t dfm:1;
 		uint64_t reserved_53_55:3;
 		uint64_t lmc0:1;
@@ -1203,7 +5161,10 @@
 		uint64_t pem0:1;
 		uint64_t ptp:1;
 		uint64_t agl:1;
-		uint64_t reserved_37_45:9;
+		uint64_t reserved_41_45:5;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_38_39:2;
+		uint64_t agx1:1;
 		uint64_t agx0:1;
 		uint64_t dpi:1;
 		uint64_t sli:1;
@@ -1226,8 +5187,51 @@
 		uint64_t usb1:1;
 		uint64_t uart2:1;
 		uint64_t wdog:16;
+#else
+		uint64_t wdog:16;
+		uint64_t uart2:1;
+		uint64_t usb1:1;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_39:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_45:5;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t srio1:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_59:3;
+		uint64_t srio2:1;
+		uint64_t srio3:1;
+		uint64_t reserved_62_62:1;
+		uint64_t rst:1;
+#endif
 	} s;
 	struct cvmx_ciu_intx_en4_1_w1c_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t nand:1;
 		uint64_t mii1:1;
@@ -1235,16 +5239,107 @@
 		uint64_t uart2:1;
 		uint64_t reserved_4_15:12;
 		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_15:12;
+		uint64_t uart2:1;
+		uint64_t usb1:1;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t reserved_20_63:44;
+#endif
 	} cn52xx;
 	struct cvmx_ciu_intx_en4_1_w1c_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t wdog:12;
+#else
+		uint64_t wdog:12;
+		uint64_t reserved_12_63:52;
+#endif
 	} cn56xx;
 	struct cvmx_ciu_intx_en4_1_w1c_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t wdog:16;
+#else
+		uint64_t wdog:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} cn58xx;
+	struct cvmx_ciu_intx_en4_1_w1c_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_53_62:10;
+		uint64_t lmc0:1;
+		uint64_t reserved_50_51:2;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t agl:1;
+		uint64_t reserved_41_45:5;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_38_39:2;
+		uint64_t agx1:1;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t dfa:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t zip:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t mii1:1;
+		uint64_t reserved_4_17:14;
+		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_17:14;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_39:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_45:5;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t reserved_50_51:2;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_62:10;
+		uint64_t rst:1;
+#endif
+	} cn61xx;
 	struct cvmx_ciu_intx_en4_1_w1c_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t rst:1;
 		uint64_t reserved_57_62:6;
 		uint64_t dfm:1;
@@ -1278,15 +5373,198 @@
 		uint64_t mii1:1;
 		uint64_t reserved_6_17:12;
 		uint64_t wdog:6;
+#else
+		uint64_t wdog:6;
+		uint64_t reserved_6_17:12;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t reserved_37_45:9;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t srio1:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_62:6;
+		uint64_t rst:1;
+#endif
 	} cn63xx;
 	struct cvmx_ciu_intx_en4_1_w1c_cn63xx cn63xxp1;
+	struct cvmx_ciu_intx_en4_1_w1c_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_62_62:1;
+		uint64_t srio3:1;
+		uint64_t srio2:1;
+		uint64_t reserved_57_59:3;
+		uint64_t dfm:1;
+		uint64_t reserved_53_55:3;
+		uint64_t lmc0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t srio0:1;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t agl:1;
+		uint64_t reserved_38_45:8;
+		uint64_t agx1:1;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t dfa:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t zip:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t mii1:1;
+		uint64_t reserved_10_17:8;
+		uint64_t wdog:10;
+#else
+		uint64_t wdog:10;
+		uint64_t reserved_10_17:8;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_45:8;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_59:3;
+		uint64_t srio2:1;
+		uint64_t srio3:1;
+		uint64_t reserved_62_62:1;
+		uint64_t rst:1;
+#endif
+	} cn66xx;
+	struct cvmx_ciu_intx_en4_1_w1c_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_53_62:10;
+		uint64_t lmc0:1;
+		uint64_t reserved_50_51:2;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t reserved_41_46:6;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t reserved_32_32:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_28_28:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_4_18:15;
+		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_18:15;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_28_28:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_32_32:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_46:6;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t reserved_50_51:2;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_62:10;
+		uint64_t rst:1;
+#endif
+	} cnf71xx;
 };
 
 union cvmx_ciu_intx_en4_1_w1s {
 	uint64_t u64;
 	struct cvmx_ciu_intx_en4_1_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t rst:1;
-		uint64_t reserved_57_62:6;
+		uint64_t reserved_62_62:1;
+		uint64_t srio3:1;
+		uint64_t srio2:1;
+		uint64_t reserved_57_59:3;
 		uint64_t dfm:1;
 		uint64_t reserved_53_55:3;
 		uint64_t lmc0:1;
@@ -1296,7 +5574,10 @@
 		uint64_t pem0:1;
 		uint64_t ptp:1;
 		uint64_t agl:1;
-		uint64_t reserved_37_45:9;
+		uint64_t reserved_41_45:5;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_38_39:2;
+		uint64_t agx1:1;
 		uint64_t agx0:1;
 		uint64_t dpi:1;
 		uint64_t sli:1;
@@ -1319,8 +5600,51 @@
 		uint64_t usb1:1;
 		uint64_t uart2:1;
 		uint64_t wdog:16;
+#else
+		uint64_t wdog:16;
+		uint64_t uart2:1;
+		uint64_t usb1:1;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_39:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_45:5;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t srio1:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_59:3;
+		uint64_t srio2:1;
+		uint64_t srio3:1;
+		uint64_t reserved_62_62:1;
+		uint64_t rst:1;
+#endif
 	} s;
 	struct cvmx_ciu_intx_en4_1_w1s_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t nand:1;
 		uint64_t mii1:1;
@@ -1328,16 +5652,107 @@
 		uint64_t uart2:1;
 		uint64_t reserved_4_15:12;
 		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_15:12;
+		uint64_t uart2:1;
+		uint64_t usb1:1;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t reserved_20_63:44;
+#endif
 	} cn52xx;
 	struct cvmx_ciu_intx_en4_1_w1s_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t wdog:12;
+#else
+		uint64_t wdog:12;
+		uint64_t reserved_12_63:52;
+#endif
 	} cn56xx;
 	struct cvmx_ciu_intx_en4_1_w1s_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t wdog:16;
+#else
+		uint64_t wdog:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} cn58xx;
+	struct cvmx_ciu_intx_en4_1_w1s_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_53_62:10;
+		uint64_t lmc0:1;
+		uint64_t reserved_50_51:2;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t agl:1;
+		uint64_t reserved_41_45:5;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_38_39:2;
+		uint64_t agx1:1;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t dfa:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t zip:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t mii1:1;
+		uint64_t reserved_4_17:14;
+		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_17:14;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_39:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_45:5;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t reserved_50_51:2;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_62:10;
+		uint64_t rst:1;
+#endif
+	} cn61xx;
 	struct cvmx_ciu_intx_en4_1_w1s_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t rst:1;
 		uint64_t reserved_57_62:6;
 		uint64_t dfm:1;
@@ -1371,13 +5786,193 @@
 		uint64_t mii1:1;
 		uint64_t reserved_6_17:12;
 		uint64_t wdog:6;
+#else
+		uint64_t wdog:6;
+		uint64_t reserved_6_17:12;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t reserved_37_45:9;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t srio1:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_62:6;
+		uint64_t rst:1;
+#endif
 	} cn63xx;
 	struct cvmx_ciu_intx_en4_1_w1s_cn63xx cn63xxp1;
+	struct cvmx_ciu_intx_en4_1_w1s_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_62_62:1;
+		uint64_t srio3:1;
+		uint64_t srio2:1;
+		uint64_t reserved_57_59:3;
+		uint64_t dfm:1;
+		uint64_t reserved_53_55:3;
+		uint64_t lmc0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t srio0:1;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t agl:1;
+		uint64_t reserved_38_45:8;
+		uint64_t agx1:1;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t dfa:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t zip:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t mii1:1;
+		uint64_t reserved_10_17:8;
+		uint64_t wdog:10;
+#else
+		uint64_t wdog:10;
+		uint64_t reserved_10_17:8;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_45:8;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_59:3;
+		uint64_t srio2:1;
+		uint64_t srio3:1;
+		uint64_t reserved_62_62:1;
+		uint64_t rst:1;
+#endif
+	} cn66xx;
+	struct cvmx_ciu_intx_en4_1_w1s_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_53_62:10;
+		uint64_t lmc0:1;
+		uint64_t reserved_50_51:2;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t reserved_41_46:6;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t reserved_32_32:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_28_28:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_4_18:15;
+		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_18:15;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_28_28:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_32_32:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_46:6;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t reserved_50_51:2;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_62:10;
+		uint64_t rst:1;
+#endif
+	} cnf71xx;
 };
 
 union cvmx_ciu_intx_sum0 {
 	uint64_t u64;
 	struct cvmx_ciu_intx_sum0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t bootdma:1;
 		uint64_t mii:1;
 		uint64_t ipdppthr:1;
@@ -1387,7 +5982,7 @@
 		uint64_t pcm:1;
 		uint64_t usb:1;
 		uint64_t timer:4;
-		uint64_t key_zero:1;
+		uint64_t reserved_51_51:1;
 		uint64_t ipd_drp:1;
 		uint64_t gmx_drp:2;
 		uint64_t trace:1;
@@ -1400,8 +5995,33 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t wdog_sum:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
 	} s;
 	struct cvmx_ciu_intx_sum0_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_59_63:5;
 		uint64_t mpi:1;
 		uint64_t pcm:1;
@@ -1421,8 +6041,30 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t wdog_sum:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t reserved_47_47:1;
+		uint64_t gmx_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t reserved_59_63:5;
+#endif
 	} cn30xx;
 	struct cvmx_ciu_intx_sum0_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_59_63:5;
 		uint64_t mpi:1;
 		uint64_t pcm:1;
@@ -1442,8 +6084,30 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t wdog_sum:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t reserved_59_63:5;
+#endif
 	} cn31xx;
 	struct cvmx_ciu_intx_sum0_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_56_63:8;
 		uint64_t timer:4;
 		uint64_t key_zero:1;
@@ -1459,10 +6123,28 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t wdog_sum:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t key_zero:1;
+		uint64_t timer:4;
+		uint64_t reserved_56_63:8;
+#endif
 	} cn38xx;
 	struct cvmx_ciu_intx_sum0_cn38xx cn38xxp2;
 	struct cvmx_ciu_intx_sum0_cn30xx cn50xx;
 	struct cvmx_ciu_intx_sum0_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t bootdma:1;
 		uint64_t mii:1;
 		uint64_t ipdppthr:1;
@@ -1485,9 +6167,34 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t wdog_sum:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t reserved_57_58:2;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
 	} cn52xx;
 	struct cvmx_ciu_intx_sum0_cn52xx cn52xxp1;
 	struct cvmx_ciu_intx_sum0_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t bootdma:1;
 		uint64_t mii:1;
 		uint64_t ipdppthr:1;
@@ -1509,17 +6216,190 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t wdog_sum:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t key_zero:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t reserved_57_58:2;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
 	} cn56xx;
 	struct cvmx_ciu_intx_sum0_cn56xx cn56xxp1;
 	struct cvmx_ciu_intx_sum0_cn38xx cn58xx;
 	struct cvmx_ciu_intx_sum0_cn38xx cn58xxp1;
+	struct cvmx_ciu_intx_sum0_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t mii:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t mpi:1;
+		uint64_t pcm:1;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t sum2:1;
+		uint64_t ipd_drp:1;
+		uint64_t gmx_drp:2;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t wdog_sum:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t wdog_sum:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t sum2:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
+	} cn61xx;
 	struct cvmx_ciu_intx_sum0_cn52xx cn63xx;
 	struct cvmx_ciu_intx_sum0_cn52xx cn63xxp1;
+	struct cvmx_ciu_intx_sum0_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t mii:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t mpi:1;
+		uint64_t reserved_57_57:1;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t sum2:1;
+		uint64_t ipd_drp:1;
+		uint64_t gmx_drp:2;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t wdog_sum:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t wdog_sum:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t sum2:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t reserved_57_57:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
+	} cn66xx;
+	struct cvmx_ciu_intx_sum0_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t reserved_62_62:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t mpi:1;
+		uint64_t pcm:1;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t sum2:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t gmx_drp:1;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t wdog_sum:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t wdog_sum:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t ipd_drp:1;
+		uint64_t sum2:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t reserved_62_62:1;
+		uint64_t bootdma:1;
+#endif
+	} cnf71xx;
 };
 
 union cvmx_ciu_intx_sum4 {
 	uint64_t u64;
 	struct cvmx_ciu_intx_sum4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t bootdma:1;
 		uint64_t mii:1;
 		uint64_t ipdppthr:1;
@@ -1529,7 +6409,7 @@
 		uint64_t pcm:1;
 		uint64_t usb:1;
 		uint64_t timer:4;
-		uint64_t key_zero:1;
+		uint64_t reserved_51_51:1;
 		uint64_t ipd_drp:1;
 		uint64_t gmx_drp:2;
 		uint64_t trace:1;
@@ -1542,8 +6422,33 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t wdog_sum:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
 	} s;
 	struct cvmx_ciu_intx_sum4_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_59_63:5;
 		uint64_t mpi:1;
 		uint64_t pcm:1;
@@ -1563,8 +6468,30 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t wdog_sum:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t reserved_47_47:1;
+		uint64_t gmx_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t reserved_59_63:5;
+#endif
 	} cn50xx;
 	struct cvmx_ciu_intx_sum4_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t bootdma:1;
 		uint64_t mii:1;
 		uint64_t ipdppthr:1;
@@ -1587,9 +6514,34 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t wdog_sum:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t reserved_57_58:2;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
 	} cn52xx;
 	struct cvmx_ciu_intx_sum4_cn52xx cn52xxp1;
 	struct cvmx_ciu_intx_sum4_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t bootdma:1;
 		uint64_t mii:1;
 		uint64_t ipdppthr:1;
@@ -1611,9 +6563,33 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t wdog_sum:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t key_zero:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t reserved_57_58:2;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
 	} cn56xx;
 	struct cvmx_ciu_intx_sum4_cn56xx cn56xxp1;
 	struct cvmx_ciu_intx_sum4_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_56_63:8;
 		uint64_t timer:4;
 		uint64_t key_zero:1;
@@ -1629,15 +6605,232 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t wdog_sum:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t key_zero:1;
+		uint64_t timer:4;
+		uint64_t reserved_56_63:8;
+#endif
 	} cn58xx;
 	struct cvmx_ciu_intx_sum4_cn58xx cn58xxp1;
+	struct cvmx_ciu_intx_sum4_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t mii:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t mpi:1;
+		uint64_t pcm:1;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t sum2:1;
+		uint64_t ipd_drp:1;
+		uint64_t gmx_drp:2;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t wdog_sum:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t wdog_sum:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t sum2:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
+	} cn61xx;
 	struct cvmx_ciu_intx_sum4_cn52xx cn63xx;
 	struct cvmx_ciu_intx_sum4_cn52xx cn63xxp1;
+	struct cvmx_ciu_intx_sum4_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t mii:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t mpi:1;
+		uint64_t reserved_57_57:1;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t sum2:1;
+		uint64_t ipd_drp:1;
+		uint64_t gmx_drp:2;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t wdog_sum:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t wdog_sum:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t sum2:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t reserved_57_57:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
+	} cn66xx;
+	struct cvmx_ciu_intx_sum4_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t reserved_62_62:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t mpi:1;
+		uint64_t pcm:1;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t sum2:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t gmx_drp:1;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t wdog_sum:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t wdog_sum:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t ipd_drp:1;
+		uint64_t sum2:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t reserved_62_62:1;
+		uint64_t bootdma:1;
+#endif
+	} cnf71xx;
 };
 
 union cvmx_ciu_int33_sum0 {
 	uint64_t u64;
 	struct cvmx_ciu_int33_sum0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t mii:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t mpi:1;
+		uint64_t pcm:1;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t sum2:1;
+		uint64_t ipd_drp:1;
+		uint64_t gmx_drp:2;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t wdog_sum:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t wdog_sum:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t sum2:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
+	} s;
+	struct cvmx_ciu_int33_sum0_s cn61xx;
+	struct cvmx_ciu_int33_sum0_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t bootdma:1;
 		uint64_t mii:1;
 		uint64_t ipdppthr:1;
@@ -1660,29 +6853,202 @@
 		uint64_t mbox:2;
 		uint64_t gpio:16;
 		uint64_t workq:16;
-	} s;
-	struct cvmx_ciu_int33_sum0_s cn63xx;
-	struct cvmx_ciu_int33_sum0_s cn63xxp1;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t wdog_sum:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_51_51:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t reserved_57_58:2;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
+	} cn63xx;
+	struct cvmx_ciu_int33_sum0_cn63xx cn63xxp1;
+	struct cvmx_ciu_int33_sum0_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t mii:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t mpi:1;
+		uint64_t reserved_57_57:1;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t sum2:1;
+		uint64_t ipd_drp:1;
+		uint64_t gmx_drp:2;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t wdog_sum:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t wdog_sum:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:2;
+		uint64_t ipd_drp:1;
+		uint64_t sum2:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t reserved_57_57:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t mii:1;
+		uint64_t bootdma:1;
+#endif
+	} cn66xx;
+	struct cvmx_ciu_int33_sum0_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bootdma:1;
+		uint64_t reserved_62_62:1;
+		uint64_t ipdppthr:1;
+		uint64_t powiq:1;
+		uint64_t twsi2:1;
+		uint64_t mpi:1;
+		uint64_t pcm:1;
+		uint64_t usb:1;
+		uint64_t timer:4;
+		uint64_t sum2:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t gmx_drp:1;
+		uint64_t trace:1;
+		uint64_t rml:1;
+		uint64_t twsi:1;
+		uint64_t wdog_sum:1;
+		uint64_t pci_msi:4;
+		uint64_t pci_int:4;
+		uint64_t uart:2;
+		uint64_t mbox:2;
+		uint64_t gpio:16;
+		uint64_t workq:16;
+#else
+		uint64_t workq:16;
+		uint64_t gpio:16;
+		uint64_t mbox:2;
+		uint64_t uart:2;
+		uint64_t pci_int:4;
+		uint64_t pci_msi:4;
+		uint64_t wdog_sum:1;
+		uint64_t twsi:1;
+		uint64_t rml:1;
+		uint64_t trace:1;
+		uint64_t gmx_drp:1;
+		uint64_t reserved_49_49:1;
+		uint64_t ipd_drp:1;
+		uint64_t sum2:1;
+		uint64_t timer:4;
+		uint64_t usb:1;
+		uint64_t pcm:1;
+		uint64_t mpi:1;
+		uint64_t twsi2:1;
+		uint64_t powiq:1;
+		uint64_t ipdppthr:1;
+		uint64_t reserved_62_62:1;
+		uint64_t bootdma:1;
+#endif
+	} cnf71xx;
 };
 
 union cvmx_ciu_int_dbg_sel {
 	uint64_t u64;
 	struct cvmx_ciu_int_dbg_sel_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_19_63:45;
+		uint64_t sel:3;
+		uint64_t reserved_10_15:6;
+		uint64_t irq:2;
+		uint64_t reserved_5_7:3;
+		uint64_t pp:5;
+#else
+		uint64_t pp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t irq:2;
+		uint64_t reserved_10_15:6;
+		uint64_t sel:3;
+		uint64_t reserved_19_63:45;
+#endif
+	} s;
+	struct cvmx_ciu_int_dbg_sel_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_19_63:45;
+		uint64_t sel:3;
+		uint64_t reserved_10_15:6;
+		uint64_t irq:2;
+		uint64_t reserved_4_7:4;
+		uint64_t pp:4;
+#else
+		uint64_t pp:4;
+		uint64_t reserved_4_7:4;
+		uint64_t irq:2;
+		uint64_t reserved_10_15:6;
+		uint64_t sel:3;
+		uint64_t reserved_19_63:45;
+#endif
+	} cn61xx;
+	struct cvmx_ciu_int_dbg_sel_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_19_63:45;
 		uint64_t sel:3;
 		uint64_t reserved_10_15:6;
 		uint64_t irq:2;
 		uint64_t reserved_3_7:5;
 		uint64_t pp:3;
-	} s;
-	struct cvmx_ciu_int_dbg_sel_s cn63xx;
+#else
+		uint64_t pp:3;
+		uint64_t reserved_3_7:5;
+		uint64_t irq:2;
+		uint64_t reserved_10_15:6;
+		uint64_t sel:3;
+		uint64_t reserved_19_63:45;
+#endif
+	} cn63xx;
+	struct cvmx_ciu_int_dbg_sel_cn61xx cn66xx;
+	struct cvmx_ciu_int_dbg_sel_s cn68xx;
+	struct cvmx_ciu_int_dbg_sel_s cn68xxp1;
+	struct cvmx_ciu_int_dbg_sel_cn61xx cnf71xx;
 };
 
 union cvmx_ciu_int_sum1 {
 	uint64_t u64;
 	struct cvmx_ciu_int_sum1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t rst:1;
-		uint64_t reserved_57_62:6;
+		uint64_t reserved_62_62:1;
+		uint64_t srio3:1;
+		uint64_t srio2:1;
+		uint64_t reserved_57_59:3;
 		uint64_t dfm:1;
 		uint64_t reserved_53_55:3;
 		uint64_t lmc0:1;
@@ -1692,7 +7058,8 @@
 		uint64_t pem0:1;
 		uint64_t ptp:1;
 		uint64_t agl:1;
-		uint64_t reserved_37_45:9;
+		uint64_t reserved_38_45:8;
+		uint64_t agx1:1;
 		uint64_t agx0:1;
 		uint64_t dpi:1;
 		uint64_t sli:1;
@@ -1715,22 +7082,78 @@
 		uint64_t usb1:1;
 		uint64_t uart2:1;
 		uint64_t wdog:16;
+#else
+		uint64_t wdog:16;
+		uint64_t uart2:1;
+		uint64_t usb1:1;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_45:8;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t srio1:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_59:3;
+		uint64_t srio2:1;
+		uint64_t srio3:1;
+		uint64_t reserved_62_62:1;
+		uint64_t rst:1;
+#endif
 	} s;
 	struct cvmx_ciu_int_sum1_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t wdog:1;
+#else
+		uint64_t wdog:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} cn30xx;
 	struct cvmx_ciu_int_sum1_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t wdog:2;
+#else
+		uint64_t wdog:2;
+		uint64_t reserved_2_63:62;
+#endif
 	} cn31xx;
 	struct cvmx_ciu_int_sum1_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t wdog:16;
+#else
+		uint64_t wdog:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} cn38xx;
 	struct cvmx_ciu_int_sum1_cn38xx cn38xxp2;
 	struct cvmx_ciu_int_sum1_cn31xx cn50xx;
 	struct cvmx_ciu_int_sum1_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t nand:1;
 		uint64_t mii1:1;
@@ -1738,23 +7161,114 @@
 		uint64_t uart2:1;
 		uint64_t reserved_4_15:12;
 		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_15:12;
+		uint64_t uart2:1;
+		uint64_t usb1:1;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t reserved_20_63:44;
+#endif
 	} cn52xx;
 	struct cvmx_ciu_int_sum1_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_19_63:45;
 		uint64_t mii1:1;
 		uint64_t usb1:1;
 		uint64_t uart2:1;
 		uint64_t reserved_4_15:12;
 		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_15:12;
+		uint64_t uart2:1;
+		uint64_t usb1:1;
+		uint64_t mii1:1;
+		uint64_t reserved_19_63:45;
+#endif
 	} cn52xxp1;
 	struct cvmx_ciu_int_sum1_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t wdog:12;
+#else
+		uint64_t wdog:12;
+		uint64_t reserved_12_63:52;
+#endif
 	} cn56xx;
 	struct cvmx_ciu_int_sum1_cn56xx cn56xxp1;
 	struct cvmx_ciu_int_sum1_cn38xx cn58xx;
 	struct cvmx_ciu_int_sum1_cn38xx cn58xxp1;
+	struct cvmx_ciu_int_sum1_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_53_62:10;
+		uint64_t lmc0:1;
+		uint64_t reserved_50_51:2;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t agl:1;
+		uint64_t reserved_38_45:8;
+		uint64_t agx1:1;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t dfa:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t zip:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t mii1:1;
+		uint64_t reserved_4_17:14;
+		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_17:14;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_45:8;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t reserved_50_51:2;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_62:10;
+		uint64_t rst:1;
+#endif
+	} cn61xx;
 	struct cvmx_ciu_int_sum1_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t rst:1;
 		uint64_t reserved_57_62:6;
 		uint64_t dfm:1;
@@ -1788,15 +7302,195 @@
 		uint64_t mii1:1;
 		uint64_t reserved_6_17:12;
 		uint64_t wdog:6;
+#else
+		uint64_t wdog:6;
+		uint64_t reserved_6_17:12;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t reserved_37_45:9;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t srio1:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_62:6;
+		uint64_t rst:1;
+#endif
 	} cn63xx;
 	struct cvmx_ciu_int_sum1_cn63xx cn63xxp1;
+	struct cvmx_ciu_int_sum1_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_62_62:1;
+		uint64_t srio3:1;
+		uint64_t srio2:1;
+		uint64_t reserved_57_59:3;
+		uint64_t dfm:1;
+		uint64_t reserved_53_55:3;
+		uint64_t lmc0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t srio0:1;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t agl:1;
+		uint64_t reserved_38_45:8;
+		uint64_t agx1:1;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t dfa:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t zip:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t mii1:1;
+		uint64_t reserved_10_17:8;
+		uint64_t wdog:10;
+#else
+		uint64_t wdog:10;
+		uint64_t reserved_10_17:8;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_45:8;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_59:3;
+		uint64_t srio2:1;
+		uint64_t srio3:1;
+		uint64_t reserved_62_62:1;
+		uint64_t rst:1;
+#endif
+	} cn66xx;
+	struct cvmx_ciu_int_sum1_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_53_62:10;
+		uint64_t lmc0:1;
+		uint64_t reserved_50_51:2;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t reserved_37_46:10;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t reserved_32_32:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_28_28:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_4_18:15;
+		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_18:15;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_28_28:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_32_32:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t reserved_37_46:10;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t reserved_50_51:2;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_62:10;
+		uint64_t rst:1;
+#endif
+	} cnf71xx;
 };
 
 union cvmx_ciu_mbox_clrx {
 	uint64_t u64;
 	struct cvmx_ciu_mbox_clrx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t bits:32;
+#else
+		uint64_t bits:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_ciu_mbox_clrx_s cn30xx;
 	struct cvmx_ciu_mbox_clrx_s cn31xx;
@@ -1809,15 +7503,25 @@
 	struct cvmx_ciu_mbox_clrx_s cn56xxp1;
 	struct cvmx_ciu_mbox_clrx_s cn58xx;
 	struct cvmx_ciu_mbox_clrx_s cn58xxp1;
+	struct cvmx_ciu_mbox_clrx_s cn61xx;
 	struct cvmx_ciu_mbox_clrx_s cn63xx;
 	struct cvmx_ciu_mbox_clrx_s cn63xxp1;
+	struct cvmx_ciu_mbox_clrx_s cn66xx;
+	struct cvmx_ciu_mbox_clrx_s cn68xx;
+	struct cvmx_ciu_mbox_clrx_s cn68xxp1;
+	struct cvmx_ciu_mbox_clrx_s cnf71xx;
 };
 
 union cvmx_ciu_mbox_setx {
 	uint64_t u64;
 	struct cvmx_ciu_mbox_setx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t bits:32;
+#else
+		uint64_t bits:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_ciu_mbox_setx_s cn30xx;
 	struct cvmx_ciu_mbox_setx_s cn31xx;
@@ -1830,51 +7534,112 @@
 	struct cvmx_ciu_mbox_setx_s cn56xxp1;
 	struct cvmx_ciu_mbox_setx_s cn58xx;
 	struct cvmx_ciu_mbox_setx_s cn58xxp1;
+	struct cvmx_ciu_mbox_setx_s cn61xx;
 	struct cvmx_ciu_mbox_setx_s cn63xx;
 	struct cvmx_ciu_mbox_setx_s cn63xxp1;
+	struct cvmx_ciu_mbox_setx_s cn66xx;
+	struct cvmx_ciu_mbox_setx_s cn68xx;
+	struct cvmx_ciu_mbox_setx_s cn68xxp1;
+	struct cvmx_ciu_mbox_setx_s cnf71xx;
 };
 
 union cvmx_ciu_nmi {
 	uint64_t u64;
 	struct cvmx_ciu_nmi_s {
-		uint64_t reserved_16_63:48;
-		uint64_t nmi:16;
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t nmi:32;
+#else
+		uint64_t nmi:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_ciu_nmi_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t nmi:1;
+#else
+		uint64_t nmi:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} cn30xx;
 	struct cvmx_ciu_nmi_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t nmi:2;
+#else
+		uint64_t nmi:2;
+		uint64_t reserved_2_63:62;
+#endif
 	} cn31xx;
-	struct cvmx_ciu_nmi_s cn38xx;
-	struct cvmx_ciu_nmi_s cn38xxp2;
+	struct cvmx_ciu_nmi_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t nmi:16;
+#else
+		uint64_t nmi:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} cn38xx;
+	struct cvmx_ciu_nmi_cn38xx cn38xxp2;
 	struct cvmx_ciu_nmi_cn31xx cn50xx;
 	struct cvmx_ciu_nmi_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t nmi:4;
+#else
+		uint64_t nmi:4;
+		uint64_t reserved_4_63:60;
+#endif
 	} cn52xx;
 	struct cvmx_ciu_nmi_cn52xx cn52xxp1;
 	struct cvmx_ciu_nmi_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t nmi:12;
+#else
+		uint64_t nmi:12;
+		uint64_t reserved_12_63:52;
+#endif
 	} cn56xx;
 	struct cvmx_ciu_nmi_cn56xx cn56xxp1;
-	struct cvmx_ciu_nmi_s cn58xx;
-	struct cvmx_ciu_nmi_s cn58xxp1;
+	struct cvmx_ciu_nmi_cn38xx cn58xx;
+	struct cvmx_ciu_nmi_cn38xx cn58xxp1;
+	struct cvmx_ciu_nmi_cn52xx cn61xx;
 	struct cvmx_ciu_nmi_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t nmi:6;
+#else
+		uint64_t nmi:6;
+		uint64_t reserved_6_63:58;
+#endif
 	} cn63xx;
 	struct cvmx_ciu_nmi_cn63xx cn63xxp1;
+	struct cvmx_ciu_nmi_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t nmi:10;
+#else
+		uint64_t nmi:10;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn66xx;
+	struct cvmx_ciu_nmi_s cn68xx;
+	struct cvmx_ciu_nmi_s cn68xxp1;
+	struct cvmx_ciu_nmi_cn52xx cnf71xx;
 };
 
 union cvmx_ciu_pci_inta {
 	uint64_t u64;
 	struct cvmx_ciu_pci_inta_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t intr:2;
+#else
+		uint64_t intr:2;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_ciu_pci_inta_s cn30xx;
 	struct cvmx_ciu_pci_inta_s cn31xx;
@@ -1887,50 +7652,125 @@
 	struct cvmx_ciu_pci_inta_s cn56xxp1;
 	struct cvmx_ciu_pci_inta_s cn58xx;
 	struct cvmx_ciu_pci_inta_s cn58xxp1;
+	struct cvmx_ciu_pci_inta_s cn61xx;
 	struct cvmx_ciu_pci_inta_s cn63xx;
 	struct cvmx_ciu_pci_inta_s cn63xxp1;
+	struct cvmx_ciu_pci_inta_s cn66xx;
+	struct cvmx_ciu_pci_inta_s cn68xx;
+	struct cvmx_ciu_pci_inta_s cn68xxp1;
+	struct cvmx_ciu_pci_inta_s cnf71xx;
+};
+
+union cvmx_ciu_pp_bist_stat {
+	uint64_t u64;
+	struct cvmx_ciu_pp_bist_stat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t pp_bist:32;
+#else
+		uint64_t pp_bist:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_ciu_pp_bist_stat_s cn68xx;
+	struct cvmx_ciu_pp_bist_stat_s cn68xxp1;
 };
 
 union cvmx_ciu_pp_dbg {
 	uint64_t u64;
 	struct cvmx_ciu_pp_dbg_s {
-		uint64_t reserved_16_63:48;
-		uint64_t ppdbg:16;
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t ppdbg:32;
+#else
+		uint64_t ppdbg:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_ciu_pp_dbg_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t ppdbg:1;
+#else
+		uint64_t ppdbg:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} cn30xx;
 	struct cvmx_ciu_pp_dbg_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t ppdbg:2;
+#else
+		uint64_t ppdbg:2;
+		uint64_t reserved_2_63:62;
+#endif
 	} cn31xx;
-	struct cvmx_ciu_pp_dbg_s cn38xx;
-	struct cvmx_ciu_pp_dbg_s cn38xxp2;
+	struct cvmx_ciu_pp_dbg_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t ppdbg:16;
+#else
+		uint64_t ppdbg:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} cn38xx;
+	struct cvmx_ciu_pp_dbg_cn38xx cn38xxp2;
 	struct cvmx_ciu_pp_dbg_cn31xx cn50xx;
 	struct cvmx_ciu_pp_dbg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t ppdbg:4;
+#else
+		uint64_t ppdbg:4;
+		uint64_t reserved_4_63:60;
+#endif
 	} cn52xx;
 	struct cvmx_ciu_pp_dbg_cn52xx cn52xxp1;
 	struct cvmx_ciu_pp_dbg_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t ppdbg:12;
+#else
+		uint64_t ppdbg:12;
+		uint64_t reserved_12_63:52;
+#endif
 	} cn56xx;
 	struct cvmx_ciu_pp_dbg_cn56xx cn56xxp1;
-	struct cvmx_ciu_pp_dbg_s cn58xx;
-	struct cvmx_ciu_pp_dbg_s cn58xxp1;
+	struct cvmx_ciu_pp_dbg_cn38xx cn58xx;
+	struct cvmx_ciu_pp_dbg_cn38xx cn58xxp1;
+	struct cvmx_ciu_pp_dbg_cn52xx cn61xx;
 	struct cvmx_ciu_pp_dbg_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t ppdbg:6;
+#else
+		uint64_t ppdbg:6;
+		uint64_t reserved_6_63:58;
+#endif
 	} cn63xx;
 	struct cvmx_ciu_pp_dbg_cn63xx cn63xxp1;
+	struct cvmx_ciu_pp_dbg_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t ppdbg:10;
+#else
+		uint64_t ppdbg:10;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn66xx;
+	struct cvmx_ciu_pp_dbg_s cn68xx;
+	struct cvmx_ciu_pp_dbg_s cn68xxp1;
+	struct cvmx_ciu_pp_dbg_cn52xx cnf71xx;
 };
 
 union cvmx_ciu_pp_pokex {
 	uint64_t u64;
 	struct cvmx_ciu_pp_pokex_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t poke:64;
+#else
+		uint64_t poke:64;
+#endif
 	} s;
 	struct cvmx_ciu_pp_pokex_s cn30xx;
 	struct cvmx_ciu_pp_pokex_s cn31xx;
@@ -1943,54 +7783,120 @@
 	struct cvmx_ciu_pp_pokex_s cn56xxp1;
 	struct cvmx_ciu_pp_pokex_s cn58xx;
 	struct cvmx_ciu_pp_pokex_s cn58xxp1;
+	struct cvmx_ciu_pp_pokex_s cn61xx;
 	struct cvmx_ciu_pp_pokex_s cn63xx;
 	struct cvmx_ciu_pp_pokex_s cn63xxp1;
+	struct cvmx_ciu_pp_pokex_s cn66xx;
+	struct cvmx_ciu_pp_pokex_s cn68xx;
+	struct cvmx_ciu_pp_pokex_s cn68xxp1;
+	struct cvmx_ciu_pp_pokex_s cnf71xx;
 };
 
 union cvmx_ciu_pp_rst {
 	uint64_t u64;
 	struct cvmx_ciu_pp_rst_s {
-		uint64_t reserved_16_63:48;
-		uint64_t rst:15;
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t rst:31;
 		uint64_t rst0:1;
+#else
+		uint64_t rst0:1;
+		uint64_t rst:31;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_ciu_pp_rst_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t rst0:1;
+#else
+		uint64_t rst0:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} cn30xx;
 	struct cvmx_ciu_pp_rst_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t rst:1;
 		uint64_t rst0:1;
+#else
+		uint64_t rst0:1;
+		uint64_t rst:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} cn31xx;
-	struct cvmx_ciu_pp_rst_s cn38xx;
-	struct cvmx_ciu_pp_rst_s cn38xxp2;
+	struct cvmx_ciu_pp_rst_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t rst:15;
+		uint64_t rst0:1;
+#else
+		uint64_t rst0:1;
+		uint64_t rst:15;
+		uint64_t reserved_16_63:48;
+#endif
+	} cn38xx;
+	struct cvmx_ciu_pp_rst_cn38xx cn38xxp2;
 	struct cvmx_ciu_pp_rst_cn31xx cn50xx;
 	struct cvmx_ciu_pp_rst_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t rst:3;
 		uint64_t rst0:1;
+#else
+		uint64_t rst0:1;
+		uint64_t rst:3;
+		uint64_t reserved_4_63:60;
+#endif
 	} cn52xx;
 	struct cvmx_ciu_pp_rst_cn52xx cn52xxp1;
 	struct cvmx_ciu_pp_rst_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t rst:11;
 		uint64_t rst0:1;
+#else
+		uint64_t rst0:1;
+		uint64_t rst:11;
+		uint64_t reserved_12_63:52;
+#endif
 	} cn56xx;
 	struct cvmx_ciu_pp_rst_cn56xx cn56xxp1;
-	struct cvmx_ciu_pp_rst_s cn58xx;
-	struct cvmx_ciu_pp_rst_s cn58xxp1;
+	struct cvmx_ciu_pp_rst_cn38xx cn58xx;
+	struct cvmx_ciu_pp_rst_cn38xx cn58xxp1;
+	struct cvmx_ciu_pp_rst_cn52xx cn61xx;
 	struct cvmx_ciu_pp_rst_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t rst:5;
 		uint64_t rst0:1;
+#else
+		uint64_t rst0:1;
+		uint64_t rst:5;
+		uint64_t reserved_6_63:58;
+#endif
 	} cn63xx;
 	struct cvmx_ciu_pp_rst_cn63xx cn63xxp1;
+	struct cvmx_ciu_pp_rst_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t rst:9;
+		uint64_t rst0:1;
+#else
+		uint64_t rst0:1;
+		uint64_t rst:9;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn66xx;
+	struct cvmx_ciu_pp_rst_s cn68xx;
+	struct cvmx_ciu_pp_rst_s cn68xxp1;
+	struct cvmx_ciu_pp_rst_cn52xx cnf71xx;
 };
 
 union cvmx_ciu_qlm0 {
 	uint64_t u64;
 	struct cvmx_ciu_qlm0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t g2bypass:1;
 		uint64_t reserved_53_62:10;
 		uint64_t g2deemph:5;
@@ -2004,9 +7910,26 @@
 		uint64_t txmargin:5;
 		uint64_t reserved_4_7:4;
 		uint64_t lane_en:4;
+#else
+		uint64_t lane_en:4;
+		uint64_t reserved_4_7:4;
+		uint64_t txmargin:5;
+		uint64_t reserved_13_15:3;
+		uint64_t txdeemph:5;
+		uint64_t reserved_21_30:10;
+		uint64_t txbypass:1;
+		uint64_t reserved_32_39:8;
+		uint64_t g2margin:5;
+		uint64_t reserved_45_47:3;
+		uint64_t g2deemph:5;
+		uint64_t reserved_53_62:10;
+		uint64_t g2bypass:1;
+#endif
 	} s;
+	struct cvmx_ciu_qlm0_s cn61xx;
 	struct cvmx_ciu_qlm0_s cn63xx;
 	struct cvmx_ciu_qlm0_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t txbypass:1;
 		uint64_t reserved_20_30:11;
@@ -2015,12 +7938,47 @@
 		uint64_t txmargin:5;
 		uint64_t reserved_4_7:4;
 		uint64_t lane_en:4;
+#else
+		uint64_t lane_en:4;
+		uint64_t reserved_4_7:4;
+		uint64_t txmargin:5;
+		uint64_t reserved_13_15:3;
+		uint64_t txdeemph:4;
+		uint64_t reserved_20_30:11;
+		uint64_t txbypass:1;
+		uint64_t reserved_32_63:32;
+#endif
 	} cn63xxp1;
+	struct cvmx_ciu_qlm0_s cn66xx;
+	struct cvmx_ciu_qlm0_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t txbypass:1;
+		uint64_t reserved_21_30:10;
+		uint64_t txdeemph:5;
+		uint64_t reserved_13_15:3;
+		uint64_t txmargin:5;
+		uint64_t reserved_4_7:4;
+		uint64_t lane_en:4;
+#else
+		uint64_t lane_en:4;
+		uint64_t reserved_4_7:4;
+		uint64_t txmargin:5;
+		uint64_t reserved_13_15:3;
+		uint64_t txdeemph:5;
+		uint64_t reserved_21_30:10;
+		uint64_t txbypass:1;
+		uint64_t reserved_32_63:32;
+#endif
+	} cn68xx;
+	struct cvmx_ciu_qlm0_cn68xx cn68xxp1;
+	struct cvmx_ciu_qlm0_s cnf71xx;
 };
 
 union cvmx_ciu_qlm1 {
 	uint64_t u64;
 	struct cvmx_ciu_qlm1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t g2bypass:1;
 		uint64_t reserved_53_62:10;
 		uint64_t g2deemph:5;
@@ -2034,9 +7992,26 @@
 		uint64_t txmargin:5;
 		uint64_t reserved_4_7:4;
 		uint64_t lane_en:4;
+#else
+		uint64_t lane_en:4;
+		uint64_t reserved_4_7:4;
+		uint64_t txmargin:5;
+		uint64_t reserved_13_15:3;
+		uint64_t txdeemph:5;
+		uint64_t reserved_21_30:10;
+		uint64_t txbypass:1;
+		uint64_t reserved_32_39:8;
+		uint64_t g2margin:5;
+		uint64_t reserved_45_47:3;
+		uint64_t g2deemph:5;
+		uint64_t reserved_53_62:10;
+		uint64_t g2bypass:1;
+#endif
 	} s;
+	struct cvmx_ciu_qlm1_s cn61xx;
 	struct cvmx_ciu_qlm1_s cn63xx;
 	struct cvmx_ciu_qlm1_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t txbypass:1;
 		uint64_t reserved_20_30:11;
@@ -2045,12 +8020,58 @@
 		uint64_t txmargin:5;
 		uint64_t reserved_4_7:4;
 		uint64_t lane_en:4;
+#else
+		uint64_t lane_en:4;
+		uint64_t reserved_4_7:4;
+		uint64_t txmargin:5;
+		uint64_t reserved_13_15:3;
+		uint64_t txdeemph:4;
+		uint64_t reserved_20_30:11;
+		uint64_t txbypass:1;
+		uint64_t reserved_32_63:32;
+#endif
 	} cn63xxp1;
+	struct cvmx_ciu_qlm1_s cn66xx;
+	struct cvmx_ciu_qlm1_s cn68xx;
+	struct cvmx_ciu_qlm1_s cn68xxp1;
+	struct cvmx_ciu_qlm1_s cnf71xx;
 };
 
 union cvmx_ciu_qlm2 {
 	uint64_t u64;
 	struct cvmx_ciu_qlm2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t g2bypass:1;
+		uint64_t reserved_53_62:10;
+		uint64_t g2deemph:5;
+		uint64_t reserved_45_47:3;
+		uint64_t g2margin:5;
+		uint64_t reserved_32_39:8;
+		uint64_t txbypass:1;
+		uint64_t reserved_21_30:10;
+		uint64_t txdeemph:5;
+		uint64_t reserved_13_15:3;
+		uint64_t txmargin:5;
+		uint64_t reserved_4_7:4;
+		uint64_t lane_en:4;
+#else
+		uint64_t lane_en:4;
+		uint64_t reserved_4_7:4;
+		uint64_t txmargin:5;
+		uint64_t reserved_13_15:3;
+		uint64_t txdeemph:5;
+		uint64_t reserved_21_30:10;
+		uint64_t txbypass:1;
+		uint64_t reserved_32_39:8;
+		uint64_t g2margin:5;
+		uint64_t reserved_45_47:3;
+		uint64_t g2deemph:5;
+		uint64_t reserved_53_62:10;
+		uint64_t g2bypass:1;
+#endif
+	} s;
+	struct cvmx_ciu_qlm2_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t txbypass:1;
 		uint64_t reserved_21_30:10;
@@ -2059,9 +8080,20 @@
 		uint64_t txmargin:5;
 		uint64_t reserved_4_7:4;
 		uint64_t lane_en:4;
-	} s;
-	struct cvmx_ciu_qlm2_s cn63xx;
+#else
+		uint64_t lane_en:4;
+		uint64_t reserved_4_7:4;
+		uint64_t txmargin:5;
+		uint64_t reserved_13_15:3;
+		uint64_t txdeemph:5;
+		uint64_t reserved_21_30:10;
+		uint64_t txbypass:1;
+		uint64_t reserved_32_63:32;
+#endif
+	} cn61xx;
+	struct cvmx_ciu_qlm2_cn61xx cn63xx;
 	struct cvmx_ciu_qlm2_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t txbypass:1;
 		uint64_t reserved_20_30:11;
@@ -2070,18 +8102,116 @@
 		uint64_t txmargin:5;
 		uint64_t reserved_4_7:4;
 		uint64_t lane_en:4;
+#else
+		uint64_t lane_en:4;
+		uint64_t reserved_4_7:4;
+		uint64_t txmargin:5;
+		uint64_t reserved_13_15:3;
+		uint64_t txdeemph:4;
+		uint64_t reserved_20_30:11;
+		uint64_t txbypass:1;
+		uint64_t reserved_32_63:32;
+#endif
 	} cn63xxp1;
+	struct cvmx_ciu_qlm2_cn61xx cn66xx;
+	struct cvmx_ciu_qlm2_s cn68xx;
+	struct cvmx_ciu_qlm2_s cn68xxp1;
+	struct cvmx_ciu_qlm2_cn61xx cnf71xx;
+};
+
+union cvmx_ciu_qlm3 {
+	uint64_t u64;
+	struct cvmx_ciu_qlm3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t g2bypass:1;
+		uint64_t reserved_53_62:10;
+		uint64_t g2deemph:5;
+		uint64_t reserved_45_47:3;
+		uint64_t g2margin:5;
+		uint64_t reserved_32_39:8;
+		uint64_t txbypass:1;
+		uint64_t reserved_21_30:10;
+		uint64_t txdeemph:5;
+		uint64_t reserved_13_15:3;
+		uint64_t txmargin:5;
+		uint64_t reserved_4_7:4;
+		uint64_t lane_en:4;
+#else
+		uint64_t lane_en:4;
+		uint64_t reserved_4_7:4;
+		uint64_t txmargin:5;
+		uint64_t reserved_13_15:3;
+		uint64_t txdeemph:5;
+		uint64_t reserved_21_30:10;
+		uint64_t txbypass:1;
+		uint64_t reserved_32_39:8;
+		uint64_t g2margin:5;
+		uint64_t reserved_45_47:3;
+		uint64_t g2deemph:5;
+		uint64_t reserved_53_62:10;
+		uint64_t g2bypass:1;
+#endif
+	} s;
+	struct cvmx_ciu_qlm3_s cn68xx;
+	struct cvmx_ciu_qlm3_s cn68xxp1;
+};
+
+union cvmx_ciu_qlm4 {
+	uint64_t u64;
+	struct cvmx_ciu_qlm4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t g2bypass:1;
+		uint64_t reserved_53_62:10;
+		uint64_t g2deemph:5;
+		uint64_t reserved_45_47:3;
+		uint64_t g2margin:5;
+		uint64_t reserved_32_39:8;
+		uint64_t txbypass:1;
+		uint64_t reserved_21_30:10;
+		uint64_t txdeemph:5;
+		uint64_t reserved_13_15:3;
+		uint64_t txmargin:5;
+		uint64_t reserved_4_7:4;
+		uint64_t lane_en:4;
+#else
+		uint64_t lane_en:4;
+		uint64_t reserved_4_7:4;
+		uint64_t txmargin:5;
+		uint64_t reserved_13_15:3;
+		uint64_t txdeemph:5;
+		uint64_t reserved_21_30:10;
+		uint64_t txbypass:1;
+		uint64_t reserved_32_39:8;
+		uint64_t g2margin:5;
+		uint64_t reserved_45_47:3;
+		uint64_t g2deemph:5;
+		uint64_t reserved_53_62:10;
+		uint64_t g2bypass:1;
+#endif
+	} s;
+	struct cvmx_ciu_qlm4_s cn68xx;
+	struct cvmx_ciu_qlm4_s cn68xxp1;
 };
 
 union cvmx_ciu_qlm_dcok {
 	uint64_t u64;
 	struct cvmx_ciu_qlm_dcok_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t qlm_dcok:4;
+#else
+		uint64_t qlm_dcok:4;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_ciu_qlm_dcok_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t qlm_dcok:2;
+#else
+		uint64_t qlm_dcok:2;
+		uint64_t reserved_2_63:62;
+#endif
 	} cn52xx;
 	struct cvmx_ciu_qlm_dcok_cn52xx cn52xxp1;
 	struct cvmx_ciu_qlm_dcok_s cn56xx;
@@ -2091,47 +8221,108 @@
 union cvmx_ciu_qlm_jtgc {
 	uint64_t u64;
 	struct cvmx_ciu_qlm_jtgc_s {
-		uint64_t reserved_11_63:53;
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_17_63:47;
+		uint64_t bypass_ext:1;
+		uint64_t reserved_11_15:5;
 		uint64_t clk_div:3;
-		uint64_t reserved_6_7:2;
-		uint64_t mux_sel:2;
+		uint64_t reserved_7_7:1;
+		uint64_t mux_sel:3;
 		uint64_t bypass:4;
+#else
+		uint64_t bypass:4;
+		uint64_t mux_sel:3;
+		uint64_t reserved_7_7:1;
+		uint64_t clk_div:3;
+		uint64_t reserved_11_15:5;
+		uint64_t bypass_ext:1;
+		uint64_t reserved_17_63:47;
+#endif
 	} s;
 	struct cvmx_ciu_qlm_jtgc_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_11_63:53;
 		uint64_t clk_div:3;
 		uint64_t reserved_5_7:3;
 		uint64_t mux_sel:1;
 		uint64_t reserved_2_3:2;
 		uint64_t bypass:2;
+#else
+		uint64_t bypass:2;
+		uint64_t reserved_2_3:2;
+		uint64_t mux_sel:1;
+		uint64_t reserved_5_7:3;
+		uint64_t clk_div:3;
+		uint64_t reserved_11_63:53;
+#endif
 	} cn52xx;
 	struct cvmx_ciu_qlm_jtgc_cn52xx cn52xxp1;
-	struct cvmx_ciu_qlm_jtgc_s cn56xx;
-	struct cvmx_ciu_qlm_jtgc_s cn56xxp1;
-	struct cvmx_ciu_qlm_jtgc_cn63xx {
+	struct cvmx_ciu_qlm_jtgc_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_11_63:53;
+		uint64_t clk_div:3;
+		uint64_t reserved_6_7:2;
+		uint64_t mux_sel:2;
+		uint64_t bypass:4;
+#else
+		uint64_t bypass:4;
+		uint64_t mux_sel:2;
+		uint64_t reserved_6_7:2;
+		uint64_t clk_div:3;
+		uint64_t reserved_11_63:53;
+#endif
+	} cn56xx;
+	struct cvmx_ciu_qlm_jtgc_cn56xx cn56xxp1;
+	struct cvmx_ciu_qlm_jtgc_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_11_63:53;
 		uint64_t clk_div:3;
 		uint64_t reserved_6_7:2;
 		uint64_t mux_sel:2;
 		uint64_t reserved_3_3:1;
 		uint64_t bypass:3;
-	} cn63xx;
-	struct cvmx_ciu_qlm_jtgc_cn63xx cn63xxp1;
+#else
+		uint64_t bypass:3;
+		uint64_t reserved_3_3:1;
+		uint64_t mux_sel:2;
+		uint64_t reserved_6_7:2;
+		uint64_t clk_div:3;
+		uint64_t reserved_11_63:53;
+#endif
+	} cn61xx;
+	struct cvmx_ciu_qlm_jtgc_cn61xx cn63xx;
+	struct cvmx_ciu_qlm_jtgc_cn61xx cn63xxp1;
+	struct cvmx_ciu_qlm_jtgc_cn61xx cn66xx;
+	struct cvmx_ciu_qlm_jtgc_s cn68xx;
+	struct cvmx_ciu_qlm_jtgc_s cn68xxp1;
+	struct cvmx_ciu_qlm_jtgc_cn61xx cnf71xx;
 };
 
 union cvmx_ciu_qlm_jtgd {
 	uint64_t u64;
 	struct cvmx_ciu_qlm_jtgd_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t capture:1;
 		uint64_t shift:1;
 		uint64_t update:1;
-		uint64_t reserved_44_60:17;
-		uint64_t select:4;
+		uint64_t reserved_45_60:16;
+		uint64_t select:5;
 		uint64_t reserved_37_39:3;
 		uint64_t shft_cnt:5;
 		uint64_t shft_reg:32;
+#else
+		uint64_t shft_reg:32;
+		uint64_t shft_cnt:5;
+		uint64_t reserved_37_39:3;
+		uint64_t select:5;
+		uint64_t reserved_45_60:16;
+		uint64_t update:1;
+		uint64_t shift:1;
+		uint64_t capture:1;
+#endif
 	} s;
 	struct cvmx_ciu_qlm_jtgd_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t capture:1;
 		uint64_t shift:1;
 		uint64_t update:1;
@@ -2140,18 +8331,58 @@
 		uint64_t reserved_37_39:3;
 		uint64_t shft_cnt:5;
 		uint64_t shft_reg:32;
+#else
+		uint64_t shft_reg:32;
+		uint64_t shft_cnt:5;
+		uint64_t reserved_37_39:3;
+		uint64_t select:2;
+		uint64_t reserved_42_60:19;
+		uint64_t update:1;
+		uint64_t shift:1;
+		uint64_t capture:1;
+#endif
 	} cn52xx;
 	struct cvmx_ciu_qlm_jtgd_cn52xx cn52xxp1;
-	struct cvmx_ciu_qlm_jtgd_s cn56xx;
+	struct cvmx_ciu_qlm_jtgd_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t capture:1;
+		uint64_t shift:1;
+		uint64_t update:1;
+		uint64_t reserved_44_60:17;
+		uint64_t select:4;
+		uint64_t reserved_37_39:3;
+		uint64_t shft_cnt:5;
+		uint64_t shft_reg:32;
+#else
+		uint64_t shft_reg:32;
+		uint64_t shft_cnt:5;
+		uint64_t reserved_37_39:3;
+		uint64_t select:4;
+		uint64_t reserved_44_60:17;
+		uint64_t update:1;
+		uint64_t shift:1;
+		uint64_t capture:1;
+#endif
+	} cn56xx;
 	struct cvmx_ciu_qlm_jtgd_cn56xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t capture:1;
 		uint64_t shift:1;
 		uint64_t update:1;
 		uint64_t reserved_37_60:24;
 		uint64_t shft_cnt:5;
 		uint64_t shft_reg:32;
+#else
+		uint64_t shft_reg:32;
+		uint64_t shft_cnt:5;
+		uint64_t reserved_37_60:24;
+		uint64_t update:1;
+		uint64_t shift:1;
+		uint64_t capture:1;
+#endif
 	} cn56xxp1;
-	struct cvmx_ciu_qlm_jtgd_cn63xx {
+	struct cvmx_ciu_qlm_jtgd_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t capture:1;
 		uint64_t shift:1;
 		uint64_t update:1;
@@ -2160,15 +8391,35 @@
 		uint64_t reserved_37_39:3;
 		uint64_t shft_cnt:5;
 		uint64_t shft_reg:32;
-	} cn63xx;
-	struct cvmx_ciu_qlm_jtgd_cn63xx cn63xxp1;
+#else
+		uint64_t shft_reg:32;
+		uint64_t shft_cnt:5;
+		uint64_t reserved_37_39:3;
+		uint64_t select:3;
+		uint64_t reserved_43_60:18;
+		uint64_t update:1;
+		uint64_t shift:1;
+		uint64_t capture:1;
+#endif
+	} cn61xx;
+	struct cvmx_ciu_qlm_jtgd_cn61xx cn63xx;
+	struct cvmx_ciu_qlm_jtgd_cn61xx cn63xxp1;
+	struct cvmx_ciu_qlm_jtgd_cn61xx cn66xx;
+	struct cvmx_ciu_qlm_jtgd_s cn68xx;
+	struct cvmx_ciu_qlm_jtgd_s cn68xxp1;
+	struct cvmx_ciu_qlm_jtgd_cn61xx cnf71xx;
 };
 
 union cvmx_ciu_soft_bist {
 	uint64_t u64;
 	struct cvmx_ciu_soft_bist_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t soft_bist:1;
+#else
+		uint64_t soft_bist:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_ciu_soft_bist_s cn30xx;
 	struct cvmx_ciu_soft_bist_s cn31xx;
@@ -2181,17 +8432,29 @@
 	struct cvmx_ciu_soft_bist_s cn56xxp1;
 	struct cvmx_ciu_soft_bist_s cn58xx;
 	struct cvmx_ciu_soft_bist_s cn58xxp1;
+	struct cvmx_ciu_soft_bist_s cn61xx;
 	struct cvmx_ciu_soft_bist_s cn63xx;
 	struct cvmx_ciu_soft_bist_s cn63xxp1;
+	struct cvmx_ciu_soft_bist_s cn66xx;
+	struct cvmx_ciu_soft_bist_s cn68xx;
+	struct cvmx_ciu_soft_bist_s cn68xxp1;
+	struct cvmx_ciu_soft_bist_s cnf71xx;
 };
 
 union cvmx_ciu_soft_prst {
 	uint64_t u64;
 	struct cvmx_ciu_soft_prst_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_3_63:61;
 		uint64_t host64:1;
 		uint64_t npi:1;
 		uint64_t soft_prst:1;
+#else
+		uint64_t soft_prst:1;
+		uint64_t npi:1;
+		uint64_t host64:1;
+		uint64_t reserved_3_63:61;
+#endif
 	} s;
 	struct cvmx_ciu_soft_prst_s cn30xx;
 	struct cvmx_ciu_soft_prst_s cn31xx;
@@ -2199,37 +8462,90 @@
 	struct cvmx_ciu_soft_prst_s cn38xxp2;
 	struct cvmx_ciu_soft_prst_s cn50xx;
 	struct cvmx_ciu_soft_prst_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t soft_prst:1;
+#else
+		uint64_t soft_prst:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} cn52xx;
 	struct cvmx_ciu_soft_prst_cn52xx cn52xxp1;
 	struct cvmx_ciu_soft_prst_cn52xx cn56xx;
 	struct cvmx_ciu_soft_prst_cn52xx cn56xxp1;
 	struct cvmx_ciu_soft_prst_s cn58xx;
 	struct cvmx_ciu_soft_prst_s cn58xxp1;
+	struct cvmx_ciu_soft_prst_cn52xx cn61xx;
 	struct cvmx_ciu_soft_prst_cn52xx cn63xx;
 	struct cvmx_ciu_soft_prst_cn52xx cn63xxp1;
+	struct cvmx_ciu_soft_prst_cn52xx cn66xx;
+	struct cvmx_ciu_soft_prst_cn52xx cn68xx;
+	struct cvmx_ciu_soft_prst_cn52xx cn68xxp1;
+	struct cvmx_ciu_soft_prst_cn52xx cnf71xx;
 };
 
 union cvmx_ciu_soft_prst1 {
 	uint64_t u64;
 	struct cvmx_ciu_soft_prst1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t soft_prst:1;
+#else
+		uint64_t soft_prst:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_ciu_soft_prst1_s cn52xx;
 	struct cvmx_ciu_soft_prst1_s cn52xxp1;
 	struct cvmx_ciu_soft_prst1_s cn56xx;
 	struct cvmx_ciu_soft_prst1_s cn56xxp1;
+	struct cvmx_ciu_soft_prst1_s cn61xx;
 	struct cvmx_ciu_soft_prst1_s cn63xx;
 	struct cvmx_ciu_soft_prst1_s cn63xxp1;
+	struct cvmx_ciu_soft_prst1_s cn66xx;
+	struct cvmx_ciu_soft_prst1_s cn68xx;
+	struct cvmx_ciu_soft_prst1_s cn68xxp1;
+	struct cvmx_ciu_soft_prst1_s cnf71xx;
+};
+
+union cvmx_ciu_soft_prst2 {
+	uint64_t u64;
+	struct cvmx_ciu_soft_prst2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_1_63:63;
+		uint64_t soft_prst:1;
+#else
+		uint64_t soft_prst:1;
+		uint64_t reserved_1_63:63;
+#endif
+	} s;
+	struct cvmx_ciu_soft_prst2_s cn66xx;
+};
+
+union cvmx_ciu_soft_prst3 {
+	uint64_t u64;
+	struct cvmx_ciu_soft_prst3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_1_63:63;
+		uint64_t soft_prst:1;
+#else
+		uint64_t soft_prst:1;
+		uint64_t reserved_1_63:63;
+#endif
+	} s;
+	struct cvmx_ciu_soft_prst3_s cn66xx;
 };
 
 union cvmx_ciu_soft_rst {
 	uint64_t u64;
 	struct cvmx_ciu_soft_rst_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t soft_rst:1;
+#else
+		uint64_t soft_rst:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_ciu_soft_rst_s cn30xx;
 	struct cvmx_ciu_soft_rst_s cn31xx;
@@ -2242,16 +8558,1371 @@
 	struct cvmx_ciu_soft_rst_s cn56xxp1;
 	struct cvmx_ciu_soft_rst_s cn58xx;
 	struct cvmx_ciu_soft_rst_s cn58xxp1;
+	struct cvmx_ciu_soft_rst_s cn61xx;
 	struct cvmx_ciu_soft_rst_s cn63xx;
 	struct cvmx_ciu_soft_rst_s cn63xxp1;
+	struct cvmx_ciu_soft_rst_s cn66xx;
+	struct cvmx_ciu_soft_rst_s cn68xx;
+	struct cvmx_ciu_soft_rst_s cn68xxp1;
+	struct cvmx_ciu_soft_rst_s cnf71xx;
+};
+
+union cvmx_ciu_sum1_iox_int {
+	uint64_t u64;
+	struct cvmx_ciu_sum1_iox_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_62_62:1;
+		uint64_t srio3:1;
+		uint64_t srio2:1;
+		uint64_t reserved_57_59:3;
+		uint64_t dfm:1;
+		uint64_t reserved_53_55:3;
+		uint64_t lmc0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t srio0:1;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t agl:1;
+		uint64_t reserved_41_45:5;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_38_39:2;
+		uint64_t agx1:1;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t dfa:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t zip:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t mii1:1;
+		uint64_t reserved_10_17:8;
+		uint64_t wdog:10;
+#else
+		uint64_t wdog:10;
+		uint64_t reserved_10_17:8;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_39:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_45:5;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_59:3;
+		uint64_t srio2:1;
+		uint64_t srio3:1;
+		uint64_t reserved_62_62:1;
+		uint64_t rst:1;
+#endif
+	} s;
+	struct cvmx_ciu_sum1_iox_int_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_53_62:10;
+		uint64_t lmc0:1;
+		uint64_t reserved_50_51:2;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t agl:1;
+		uint64_t reserved_41_45:5;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_38_39:2;
+		uint64_t agx1:1;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t dfa:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t zip:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t mii1:1;
+		uint64_t reserved_4_17:14;
+		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_17:14;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_39:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_45:5;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t reserved_50_51:2;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_62:10;
+		uint64_t rst:1;
+#endif
+	} cn61xx;
+	struct cvmx_ciu_sum1_iox_int_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_62_62:1;
+		uint64_t srio3:1;
+		uint64_t srio2:1;
+		uint64_t reserved_57_59:3;
+		uint64_t dfm:1;
+		uint64_t reserved_53_55:3;
+		uint64_t lmc0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t srio0:1;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t agl:1;
+		uint64_t reserved_38_45:8;
+		uint64_t agx1:1;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t dfa:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t zip:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t mii1:1;
+		uint64_t reserved_10_17:8;
+		uint64_t wdog:10;
+#else
+		uint64_t wdog:10;
+		uint64_t reserved_10_17:8;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_45:8;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_59:3;
+		uint64_t srio2:1;
+		uint64_t srio3:1;
+		uint64_t reserved_62_62:1;
+		uint64_t rst:1;
+#endif
+	} cn66xx;
+	struct cvmx_ciu_sum1_iox_int_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_53_62:10;
+		uint64_t lmc0:1;
+		uint64_t reserved_50_51:2;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t reserved_41_46:6;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t reserved_32_32:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_28_28:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_4_18:15;
+		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_18:15;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_28_28:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_32_32:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_46:6;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t reserved_50_51:2;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_62:10;
+		uint64_t rst:1;
+#endif
+	} cnf71xx;
+};
+
+union cvmx_ciu_sum1_ppx_ip2 {
+	uint64_t u64;
+	struct cvmx_ciu_sum1_ppx_ip2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_62_62:1;
+		uint64_t srio3:1;
+		uint64_t srio2:1;
+		uint64_t reserved_57_59:3;
+		uint64_t dfm:1;
+		uint64_t reserved_53_55:3;
+		uint64_t lmc0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t srio0:1;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t agl:1;
+		uint64_t reserved_41_45:5;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_38_39:2;
+		uint64_t agx1:1;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t dfa:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t zip:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t mii1:1;
+		uint64_t reserved_10_17:8;
+		uint64_t wdog:10;
+#else
+		uint64_t wdog:10;
+		uint64_t reserved_10_17:8;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_39:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_45:5;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_59:3;
+		uint64_t srio2:1;
+		uint64_t srio3:1;
+		uint64_t reserved_62_62:1;
+		uint64_t rst:1;
+#endif
+	} s;
+	struct cvmx_ciu_sum1_ppx_ip2_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_53_62:10;
+		uint64_t lmc0:1;
+		uint64_t reserved_50_51:2;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t agl:1;
+		uint64_t reserved_41_45:5;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_38_39:2;
+		uint64_t agx1:1;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t dfa:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t zip:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t mii1:1;
+		uint64_t reserved_4_17:14;
+		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_17:14;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_39:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_45:5;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t reserved_50_51:2;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_62:10;
+		uint64_t rst:1;
+#endif
+	} cn61xx;
+	struct cvmx_ciu_sum1_ppx_ip2_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_62_62:1;
+		uint64_t srio3:1;
+		uint64_t srio2:1;
+		uint64_t reserved_57_59:3;
+		uint64_t dfm:1;
+		uint64_t reserved_53_55:3;
+		uint64_t lmc0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t srio0:1;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t agl:1;
+		uint64_t reserved_38_45:8;
+		uint64_t agx1:1;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t dfa:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t zip:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t mii1:1;
+		uint64_t reserved_10_17:8;
+		uint64_t wdog:10;
+#else
+		uint64_t wdog:10;
+		uint64_t reserved_10_17:8;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_45:8;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_59:3;
+		uint64_t srio2:1;
+		uint64_t srio3:1;
+		uint64_t reserved_62_62:1;
+		uint64_t rst:1;
+#endif
+	} cn66xx;
+	struct cvmx_ciu_sum1_ppx_ip2_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_53_62:10;
+		uint64_t lmc0:1;
+		uint64_t reserved_50_51:2;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t reserved_41_46:6;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t reserved_32_32:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_28_28:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_4_18:15;
+		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_18:15;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_28_28:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_32_32:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_46:6;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t reserved_50_51:2;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_62:10;
+		uint64_t rst:1;
+#endif
+	} cnf71xx;
+};
+
+union cvmx_ciu_sum1_ppx_ip3 {
+	uint64_t u64;
+	struct cvmx_ciu_sum1_ppx_ip3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_62_62:1;
+		uint64_t srio3:1;
+		uint64_t srio2:1;
+		uint64_t reserved_57_59:3;
+		uint64_t dfm:1;
+		uint64_t reserved_53_55:3;
+		uint64_t lmc0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t srio0:1;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t agl:1;
+		uint64_t reserved_41_45:5;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_38_39:2;
+		uint64_t agx1:1;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t dfa:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t zip:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t mii1:1;
+		uint64_t reserved_10_17:8;
+		uint64_t wdog:10;
+#else
+		uint64_t wdog:10;
+		uint64_t reserved_10_17:8;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_39:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_45:5;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_59:3;
+		uint64_t srio2:1;
+		uint64_t srio3:1;
+		uint64_t reserved_62_62:1;
+		uint64_t rst:1;
+#endif
+	} s;
+	struct cvmx_ciu_sum1_ppx_ip3_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_53_62:10;
+		uint64_t lmc0:1;
+		uint64_t reserved_50_51:2;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t agl:1;
+		uint64_t reserved_41_45:5;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_38_39:2;
+		uint64_t agx1:1;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t dfa:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t zip:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t mii1:1;
+		uint64_t reserved_4_17:14;
+		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_17:14;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_39:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_45:5;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t reserved_50_51:2;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_62:10;
+		uint64_t rst:1;
+#endif
+	} cn61xx;
+	struct cvmx_ciu_sum1_ppx_ip3_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_62_62:1;
+		uint64_t srio3:1;
+		uint64_t srio2:1;
+		uint64_t reserved_57_59:3;
+		uint64_t dfm:1;
+		uint64_t reserved_53_55:3;
+		uint64_t lmc0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t srio0:1;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t agl:1;
+		uint64_t reserved_38_45:8;
+		uint64_t agx1:1;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t dfa:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t zip:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t mii1:1;
+		uint64_t reserved_10_17:8;
+		uint64_t wdog:10;
+#else
+		uint64_t wdog:10;
+		uint64_t reserved_10_17:8;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_45:8;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_59:3;
+		uint64_t srio2:1;
+		uint64_t srio3:1;
+		uint64_t reserved_62_62:1;
+		uint64_t rst:1;
+#endif
+	} cn66xx;
+	struct cvmx_ciu_sum1_ppx_ip3_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_53_62:10;
+		uint64_t lmc0:1;
+		uint64_t reserved_50_51:2;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t reserved_41_46:6;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t reserved_32_32:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_28_28:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_4_18:15;
+		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_18:15;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_28_28:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_32_32:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_46:6;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t reserved_50_51:2;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_62:10;
+		uint64_t rst:1;
+#endif
+	} cnf71xx;
+};
+
+union cvmx_ciu_sum1_ppx_ip4 {
+	uint64_t u64;
+	struct cvmx_ciu_sum1_ppx_ip4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_62_62:1;
+		uint64_t srio3:1;
+		uint64_t srio2:1;
+		uint64_t reserved_57_59:3;
+		uint64_t dfm:1;
+		uint64_t reserved_53_55:3;
+		uint64_t lmc0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t srio0:1;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t agl:1;
+		uint64_t reserved_41_45:5;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_38_39:2;
+		uint64_t agx1:1;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t dfa:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t zip:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t mii1:1;
+		uint64_t reserved_10_17:8;
+		uint64_t wdog:10;
+#else
+		uint64_t wdog:10;
+		uint64_t reserved_10_17:8;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_39:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_45:5;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_59:3;
+		uint64_t srio2:1;
+		uint64_t srio3:1;
+		uint64_t reserved_62_62:1;
+		uint64_t rst:1;
+#endif
+	} s;
+	struct cvmx_ciu_sum1_ppx_ip4_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_53_62:10;
+		uint64_t lmc0:1;
+		uint64_t reserved_50_51:2;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t agl:1;
+		uint64_t reserved_41_45:5;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_38_39:2;
+		uint64_t agx1:1;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t dfa:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t zip:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t mii1:1;
+		uint64_t reserved_4_17:14;
+		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_17:14;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_39:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_45:5;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t reserved_50_51:2;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_62:10;
+		uint64_t rst:1;
+#endif
+	} cn61xx;
+	struct cvmx_ciu_sum1_ppx_ip4_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_62_62:1;
+		uint64_t srio3:1;
+		uint64_t srio2:1;
+		uint64_t reserved_57_59:3;
+		uint64_t dfm:1;
+		uint64_t reserved_53_55:3;
+		uint64_t lmc0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t srio0:1;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t agl:1;
+		uint64_t reserved_38_45:8;
+		uint64_t agx1:1;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t dfa:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t zip:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t mii1:1;
+		uint64_t reserved_10_17:8;
+		uint64_t wdog:10;
+#else
+		uint64_t wdog:10;
+		uint64_t reserved_10_17:8;
+		uint64_t mii1:1;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t zip:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t dfa:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t agx1:1;
+		uint64_t reserved_38_45:8;
+		uint64_t agl:1;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t srio0:1;
+		uint64_t reserved_51_51:1;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_55:3;
+		uint64_t dfm:1;
+		uint64_t reserved_57_59:3;
+		uint64_t srio2:1;
+		uint64_t srio3:1;
+		uint64_t reserved_62_62:1;
+		uint64_t rst:1;
+#endif
+	} cn66xx;
+	struct cvmx_ciu_sum1_ppx_ip4_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_53_62:10;
+		uint64_t lmc0:1;
+		uint64_t reserved_50_51:2;
+		uint64_t pem1:1;
+		uint64_t pem0:1;
+		uint64_t ptp:1;
+		uint64_t reserved_41_46:6;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t agx0:1;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t usb:1;
+		uint64_t reserved_32_32:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_28_28:1;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t l2c:1;
+		uint64_t pow:1;
+		uint64_t fpa:1;
+		uint64_t iob:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_4_18:15;
+		uint64_t wdog:4;
+#else
+		uint64_t wdog:4;
+		uint64_t reserved_4_18:15;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t iob:1;
+		uint64_t fpa:1;
+		uint64_t pow:1;
+		uint64_t l2c:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_28_28:1;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_32_32:1;
+		uint64_t usb:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t agx0:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_41_46:6;
+		uint64_t ptp:1;
+		uint64_t pem0:1;
+		uint64_t pem1:1;
+		uint64_t reserved_50_51:2;
+		uint64_t lmc0:1;
+		uint64_t reserved_53_62:10;
+		uint64_t rst:1;
+#endif
+	} cnf71xx;
+};
+
+union cvmx_ciu_sum2_iox_int {
+	uint64_t u64;
+	struct cvmx_ciu_sum2_iox_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_15_63:49;
+		uint64_t endor:2;
+		uint64_t eoi:1;
+		uint64_t reserved_10_11:2;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_11:2;
+		uint64_t eoi:1;
+		uint64_t endor:2;
+		uint64_t reserved_15_63:49;
+#endif
+	} s;
+	struct cvmx_ciu_sum2_iox_int_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn61xx;
+	struct cvmx_ciu_sum2_iox_int_cn61xx cn66xx;
+	struct cvmx_ciu_sum2_iox_int_s cnf71xx;
+};
+
+union cvmx_ciu_sum2_ppx_ip2 {
+	uint64_t u64;
+	struct cvmx_ciu_sum2_ppx_ip2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_15_63:49;
+		uint64_t endor:2;
+		uint64_t eoi:1;
+		uint64_t reserved_10_11:2;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_11:2;
+		uint64_t eoi:1;
+		uint64_t endor:2;
+		uint64_t reserved_15_63:49;
+#endif
+	} s;
+	struct cvmx_ciu_sum2_ppx_ip2_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn61xx;
+	struct cvmx_ciu_sum2_ppx_ip2_cn61xx cn66xx;
+	struct cvmx_ciu_sum2_ppx_ip2_s cnf71xx;
+};
+
+union cvmx_ciu_sum2_ppx_ip3 {
+	uint64_t u64;
+	struct cvmx_ciu_sum2_ppx_ip3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_15_63:49;
+		uint64_t endor:2;
+		uint64_t eoi:1;
+		uint64_t reserved_10_11:2;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_11:2;
+		uint64_t eoi:1;
+		uint64_t endor:2;
+		uint64_t reserved_15_63:49;
+#endif
+	} s;
+	struct cvmx_ciu_sum2_ppx_ip3_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn61xx;
+	struct cvmx_ciu_sum2_ppx_ip3_cn61xx cn66xx;
+	struct cvmx_ciu_sum2_ppx_ip3_s cnf71xx;
+};
+
+union cvmx_ciu_sum2_ppx_ip4 {
+	uint64_t u64;
+	struct cvmx_ciu_sum2_ppx_ip4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_15_63:49;
+		uint64_t endor:2;
+		uint64_t eoi:1;
+		uint64_t reserved_10_11:2;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_11:2;
+		uint64_t eoi:1;
+		uint64_t endor:2;
+		uint64_t reserved_15_63:49;
+#endif
+	} s;
+	struct cvmx_ciu_sum2_ppx_ip4_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t timer:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t timer:6;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn61xx;
+	struct cvmx_ciu_sum2_ppx_ip4_cn61xx cn66xx;
+	struct cvmx_ciu_sum2_ppx_ip4_s cnf71xx;
 };
 
 union cvmx_ciu_timx {
 	uint64_t u64;
 	struct cvmx_ciu_timx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_37_63:27;
 		uint64_t one_shot:1;
 		uint64_t len:36;
+#else
+		uint64_t len:36;
+		uint64_t one_shot:1;
+		uint64_t reserved_37_63:27;
+#endif
 	} s;
 	struct cvmx_ciu_timx_s cn30xx;
 	struct cvmx_ciu_timx_s cn31xx;
@@ -2264,13 +9935,35 @@
 	struct cvmx_ciu_timx_s cn56xxp1;
 	struct cvmx_ciu_timx_s cn58xx;
 	struct cvmx_ciu_timx_s cn58xxp1;
+	struct cvmx_ciu_timx_s cn61xx;
 	struct cvmx_ciu_timx_s cn63xx;
 	struct cvmx_ciu_timx_s cn63xxp1;
+	struct cvmx_ciu_timx_s cn66xx;
+	struct cvmx_ciu_timx_s cn68xx;
+	struct cvmx_ciu_timx_s cn68xxp1;
+	struct cvmx_ciu_timx_s cnf71xx;
+};
+
+union cvmx_ciu_tim_multi_cast {
+	uint64_t u64;
+	struct cvmx_ciu_tim_multi_cast_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_1_63:63;
+		uint64_t en:1;
+#else
+		uint64_t en:1;
+		uint64_t reserved_1_63:63;
+#endif
+	} s;
+	struct cvmx_ciu_tim_multi_cast_s cn61xx;
+	struct cvmx_ciu_tim_multi_cast_s cn66xx;
+	struct cvmx_ciu_tim_multi_cast_s cnf71xx;
 };
 
 union cvmx_ciu_wdogx {
 	uint64_t u64;
 	struct cvmx_ciu_wdogx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_46_63:18;
 		uint64_t gstopen:1;
 		uint64_t dstop:1;
@@ -2278,6 +9971,15 @@
 		uint64_t len:16;
 		uint64_t state:2;
 		uint64_t mode:2;
+#else
+		uint64_t mode:2;
+		uint64_t state:2;
+		uint64_t len:16;
+		uint64_t cnt:24;
+		uint64_t dstop:1;
+		uint64_t gstopen:1;
+		uint64_t reserved_46_63:18;
+#endif
 	} s;
 	struct cvmx_ciu_wdogx_s cn30xx;
 	struct cvmx_ciu_wdogx_s cn31xx;
@@ -2290,8 +9992,13 @@
 	struct cvmx_ciu_wdogx_s cn56xxp1;
 	struct cvmx_ciu_wdogx_s cn58xx;
 	struct cvmx_ciu_wdogx_s cn58xxp1;
+	struct cvmx_ciu_wdogx_s cn61xx;
 	struct cvmx_ciu_wdogx_s cn63xx;
 	struct cvmx_ciu_wdogx_s cn63xxp1;
+	struct cvmx_ciu_wdogx_s cn66xx;
+	struct cvmx_ciu_wdogx_s cn68xx;
+	struct cvmx_ciu_wdogx_s cn68xxp1;
+	struct cvmx_ciu_wdogx_s cnf71xx;
 };
 
 #endif
diff --git a/arch/mips/include/asm/octeon/cvmx-ciu2-defs.h b/arch/mips/include/asm/octeon/cvmx-ciu2-defs.h
new file mode 100644
index 0000000..148bc9a
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-ciu2-defs.h
@@ -0,0 +1,7108 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2012 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_CIU2_DEFS_H__
+#define __CVMX_CIU2_DEFS_H__
+
+#define CVMX_CIU2_ACK_IOX_INT(block_id) (CVMX_ADD_IO_SEG(0x00010701080C0800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_ACK_PPX_IP2(block_id) (CVMX_ADD_IO_SEG(0x00010701000C0000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_ACK_PPX_IP3(block_id) (CVMX_ADD_IO_SEG(0x00010701000C0200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_ACK_PPX_IP4(block_id) (CVMX_ADD_IO_SEG(0x00010701000C0400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_GPIO(block_id) (CVMX_ADD_IO_SEG(0x0001070108097800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_GPIO_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701080B7800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_GPIO_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701080A7800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_IO(block_id) (CVMX_ADD_IO_SEG(0x0001070108094800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_IO_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701080B4800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_IO_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701080A4800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_MBOX(block_id) (CVMX_ADD_IO_SEG(0x0001070108098800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_MBOX_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701080B8800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_MBOX_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701080A8800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_MEM(block_id) (CVMX_ADD_IO_SEG(0x0001070108095800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_MEM_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701080B5800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_MEM_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701080A5800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_MIO(block_id) (CVMX_ADD_IO_SEG(0x0001070108093800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_MIO_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701080B3800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_MIO_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701080A3800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_PKT(block_id) (CVMX_ADD_IO_SEG(0x0001070108096800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_PKT_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701080B6800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_PKT_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701080A6800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_RML(block_id) (CVMX_ADD_IO_SEG(0x0001070108092800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_RML_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701080B2800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_RML_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701080A2800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_WDOG(block_id) (CVMX_ADD_IO_SEG(0x0001070108091800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_WDOG_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701080B1800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_WDOG_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701080A1800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_WRKQ(block_id) (CVMX_ADD_IO_SEG(0x0001070108090800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_WRKQ_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701080B0800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_IOX_INT_WRKQ_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701080A0800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_GPIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100097000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_GPIO_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B7000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_GPIO_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A7000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_IO(block_id) (CVMX_ADD_IO_SEG(0x0001070100094000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_IO_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B4000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_IO_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A4000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_MBOX(block_id) (CVMX_ADD_IO_SEG(0x0001070100098000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_MBOX_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B8000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_MBOX_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A8000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_MEM(block_id) (CVMX_ADD_IO_SEG(0x0001070100095000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_MEM_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B5000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_MEM_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A5000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_MIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100093000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_MIO_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B3000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_MIO_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A3000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_PKT(block_id) (CVMX_ADD_IO_SEG(0x0001070100096000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_PKT_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B6000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_PKT_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A6000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_RML(block_id) (CVMX_ADD_IO_SEG(0x0001070100092000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_RML_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B2000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_RML_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A2000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_WDOG(block_id) (CVMX_ADD_IO_SEG(0x0001070100091000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_WDOG_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B1000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_WDOG_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A1000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_WRKQ(block_id) (CVMX_ADD_IO_SEG(0x0001070100090000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_WRKQ_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B0000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP2_WRKQ_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A0000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_GPIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100097200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_GPIO_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B7200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_GPIO_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A7200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_IO(block_id) (CVMX_ADD_IO_SEG(0x0001070100094200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_IO_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B4200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_IO_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A4200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_MBOX(block_id) (CVMX_ADD_IO_SEG(0x0001070100098200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_MBOX_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B8200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_MBOX_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A8200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_MEM(block_id) (CVMX_ADD_IO_SEG(0x0001070100095200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_MEM_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B5200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_MEM_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A5200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_MIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100093200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_MIO_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B3200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_MIO_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A3200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_PKT(block_id) (CVMX_ADD_IO_SEG(0x0001070100096200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_PKT_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B6200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_PKT_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A6200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_RML(block_id) (CVMX_ADD_IO_SEG(0x0001070100092200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_RML_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B2200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_RML_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A2200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_WDOG(block_id) (CVMX_ADD_IO_SEG(0x0001070100091200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_WDOG_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B1200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_WDOG_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A1200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_WRKQ(block_id) (CVMX_ADD_IO_SEG(0x0001070100090200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_WRKQ_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B0200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP3_WRKQ_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A0200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_GPIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100097400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_GPIO_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B7400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_GPIO_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A7400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_IO(block_id) (CVMX_ADD_IO_SEG(0x0001070100094400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_IO_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B4400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_IO_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A4400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_MBOX(block_id) (CVMX_ADD_IO_SEG(0x0001070100098400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_MBOX_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B8400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_MBOX_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A8400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_MEM(block_id) (CVMX_ADD_IO_SEG(0x0001070100095400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_MEM_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B5400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_MEM_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A5400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_MIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100093400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_MIO_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B3400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_MIO_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A3400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_PKT(block_id) (CVMX_ADD_IO_SEG(0x0001070100096400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_PKT_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B6400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_PKT_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A6400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_RML(block_id) (CVMX_ADD_IO_SEG(0x0001070100092400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_RML_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B2400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_RML_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A2400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_WDOG(block_id) (CVMX_ADD_IO_SEG(0x0001070100091400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_WDOG_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B1400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_WDOG_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A1400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_WRKQ(block_id) (CVMX_ADD_IO_SEG(0x0001070100090400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_WRKQ_W1C(block_id) (CVMX_ADD_IO_SEG(0x00010701000B0400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_EN_PPX_IP4_WRKQ_W1S(block_id) (CVMX_ADD_IO_SEG(0x00010701000A0400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_INTR_CIU_READY (CVMX_ADD_IO_SEG(0x0001070100102008ull))
+#define CVMX_CIU2_INTR_RAM_ECC_CTL (CVMX_ADD_IO_SEG(0x0001070100102010ull))
+#define CVMX_CIU2_INTR_RAM_ECC_ST (CVMX_ADD_IO_SEG(0x0001070100102018ull))
+#define CVMX_CIU2_INTR_SLOWDOWN (CVMX_ADD_IO_SEG(0x0001070100102000ull))
+#define CVMX_CIU2_MSIRED_PPX_IP2(block_id) (CVMX_ADD_IO_SEG(0x00010701000C1000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_MSIRED_PPX_IP3(block_id) (CVMX_ADD_IO_SEG(0x00010701000C1200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_MSIRED_PPX_IP4(block_id) (CVMX_ADD_IO_SEG(0x00010701000C1400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_MSI_RCVX(offset) (CVMX_ADD_IO_SEG(0x00010701000C2000ull) + ((offset) & 255) * 8)
+#define CVMX_CIU2_MSI_SELX(offset) (CVMX_ADD_IO_SEG(0x00010701000C3000ull) + ((offset) & 255) * 8)
+#define CVMX_CIU2_RAW_IOX_INT_GPIO(block_id) (CVMX_ADD_IO_SEG(0x0001070108047800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_RAW_IOX_INT_IO(block_id) (CVMX_ADD_IO_SEG(0x0001070108044800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_RAW_IOX_INT_MEM(block_id) (CVMX_ADD_IO_SEG(0x0001070108045800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_RAW_IOX_INT_MIO(block_id) (CVMX_ADD_IO_SEG(0x0001070108043800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_RAW_IOX_INT_PKT(block_id) (CVMX_ADD_IO_SEG(0x0001070108046800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_RAW_IOX_INT_RML(block_id) (CVMX_ADD_IO_SEG(0x0001070108042800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_RAW_IOX_INT_WDOG(block_id) (CVMX_ADD_IO_SEG(0x0001070108041800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_RAW_IOX_INT_WRKQ(block_id) (CVMX_ADD_IO_SEG(0x0001070108040800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP2_GPIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100047000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP2_IO(block_id) (CVMX_ADD_IO_SEG(0x0001070100044000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP2_MEM(block_id) (CVMX_ADD_IO_SEG(0x0001070100045000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP2_MIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100043000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP2_PKT(block_id) (CVMX_ADD_IO_SEG(0x0001070100046000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP2_RML(block_id) (CVMX_ADD_IO_SEG(0x0001070100042000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP2_WDOG(block_id) (CVMX_ADD_IO_SEG(0x0001070100041000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP2_WRKQ(block_id) (CVMX_ADD_IO_SEG(0x0001070100040000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP3_GPIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100047200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP3_IO(block_id) (CVMX_ADD_IO_SEG(0x0001070100044200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP3_MEM(block_id) (CVMX_ADD_IO_SEG(0x0001070100045200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP3_MIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100043200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP3_PKT(block_id) (CVMX_ADD_IO_SEG(0x0001070100046200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP3_RML(block_id) (CVMX_ADD_IO_SEG(0x0001070100042200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP3_WDOG(block_id) (CVMX_ADD_IO_SEG(0x0001070100041200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP3_WRKQ(block_id) (CVMX_ADD_IO_SEG(0x0001070100040200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP4_GPIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100047400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP4_IO(block_id) (CVMX_ADD_IO_SEG(0x0001070100044400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP4_MEM(block_id) (CVMX_ADD_IO_SEG(0x0001070100045400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP4_MIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100043400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP4_PKT(block_id) (CVMX_ADD_IO_SEG(0x0001070100046400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP4_RML(block_id) (CVMX_ADD_IO_SEG(0x0001070100042400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP4_WDOG(block_id) (CVMX_ADD_IO_SEG(0x0001070100041400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_RAW_PPX_IP4_WRKQ(block_id) (CVMX_ADD_IO_SEG(0x0001070100040400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_IOX_INT_GPIO(block_id) (CVMX_ADD_IO_SEG(0x0001070108087800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_SRC_IOX_INT_IO(block_id) (CVMX_ADD_IO_SEG(0x0001070108084800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_SRC_IOX_INT_MBOX(block_id) (CVMX_ADD_IO_SEG(0x0001070108088800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_SRC_IOX_INT_MEM(block_id) (CVMX_ADD_IO_SEG(0x0001070108085800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_SRC_IOX_INT_MIO(block_id) (CVMX_ADD_IO_SEG(0x0001070108083800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_SRC_IOX_INT_PKT(block_id) (CVMX_ADD_IO_SEG(0x0001070108086800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_SRC_IOX_INT_RML(block_id) (CVMX_ADD_IO_SEG(0x0001070108082800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_SRC_IOX_INT_WDOG(block_id) (CVMX_ADD_IO_SEG(0x0001070108081800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_SRC_IOX_INT_WRKQ(block_id) (CVMX_ADD_IO_SEG(0x0001070108080800ull) + ((block_id) & 1) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP2_GPIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100087000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP2_IO(block_id) (CVMX_ADD_IO_SEG(0x0001070100084000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP2_MBOX(block_id) (CVMX_ADD_IO_SEG(0x0001070100088000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP2_MEM(block_id) (CVMX_ADD_IO_SEG(0x0001070100085000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP2_MIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100083000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP2_PKT(block_id) (CVMX_ADD_IO_SEG(0x0001070100086000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP2_RML(block_id) (CVMX_ADD_IO_SEG(0x0001070100082000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP2_WDOG(block_id) (CVMX_ADD_IO_SEG(0x0001070100081000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP2_WRKQ(block_id) (CVMX_ADD_IO_SEG(0x0001070100080000ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP3_GPIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100087200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP3_IO(block_id) (CVMX_ADD_IO_SEG(0x0001070100084200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP3_MBOX(block_id) (CVMX_ADD_IO_SEG(0x0001070100088200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP3_MEM(block_id) (CVMX_ADD_IO_SEG(0x0001070100085200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP3_MIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100083200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP3_PKT(block_id) (CVMX_ADD_IO_SEG(0x0001070100086200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP3_RML(block_id) (CVMX_ADD_IO_SEG(0x0001070100082200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP3_WDOG(block_id) (CVMX_ADD_IO_SEG(0x0001070100081200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP3_WRKQ(block_id) (CVMX_ADD_IO_SEG(0x0001070100080200ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP4_GPIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100087400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP4_IO(block_id) (CVMX_ADD_IO_SEG(0x0001070100084400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP4_MBOX(block_id) (CVMX_ADD_IO_SEG(0x0001070100088400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP4_MEM(block_id) (CVMX_ADD_IO_SEG(0x0001070100085400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP4_MIO(block_id) (CVMX_ADD_IO_SEG(0x0001070100083400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP4_PKT(block_id) (CVMX_ADD_IO_SEG(0x0001070100086400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP4_RML(block_id) (CVMX_ADD_IO_SEG(0x0001070100082400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP4_WDOG(block_id) (CVMX_ADD_IO_SEG(0x0001070100081400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SRC_PPX_IP4_WRKQ(block_id) (CVMX_ADD_IO_SEG(0x0001070100080400ull) + ((block_id) & 31) * 0x200000ull)
+#define CVMX_CIU2_SUM_IOX_INT(offset) (CVMX_ADD_IO_SEG(0x0001070100000800ull) + ((offset) & 1) * 8)
+#define CVMX_CIU2_SUM_PPX_IP2(offset) (CVMX_ADD_IO_SEG(0x0001070100000000ull) + ((offset) & 31) * 8)
+#define CVMX_CIU2_SUM_PPX_IP3(offset) (CVMX_ADD_IO_SEG(0x0001070100000200ull) + ((offset) & 31) * 8)
+#define CVMX_CIU2_SUM_PPX_IP4(offset) (CVMX_ADD_IO_SEG(0x0001070100000400ull) + ((offset) & 31) * 8)
+
+union cvmx_ciu2_ack_iox_int {
+	uint64_t u64;
+	struct cvmx_ciu2_ack_iox_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_1_63:63;
+		uint64_t ack:1;
+#else
+		uint64_t ack:1;
+		uint64_t reserved_1_63:63;
+#endif
+	} s;
+	struct cvmx_ciu2_ack_iox_int_s cn68xx;
+	struct cvmx_ciu2_ack_iox_int_s cn68xxp1;
+};
+
+union cvmx_ciu2_ack_ppx_ip2 {
+	uint64_t u64;
+	struct cvmx_ciu2_ack_ppx_ip2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_1_63:63;
+		uint64_t ack:1;
+#else
+		uint64_t ack:1;
+		uint64_t reserved_1_63:63;
+#endif
+	} s;
+	struct cvmx_ciu2_ack_ppx_ip2_s cn68xx;
+	struct cvmx_ciu2_ack_ppx_ip2_s cn68xxp1;
+};
+
+union cvmx_ciu2_ack_ppx_ip3 {
+	uint64_t u64;
+	struct cvmx_ciu2_ack_ppx_ip3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_1_63:63;
+		uint64_t ack:1;
+#else
+		uint64_t ack:1;
+		uint64_t reserved_1_63:63;
+#endif
+	} s;
+	struct cvmx_ciu2_ack_ppx_ip3_s cn68xx;
+	struct cvmx_ciu2_ack_ppx_ip3_s cn68xxp1;
+};
+
+union cvmx_ciu2_ack_ppx_ip4 {
+	uint64_t u64;
+	struct cvmx_ciu2_ack_ppx_ip4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_1_63:63;
+		uint64_t ack:1;
+#else
+		uint64_t ack:1;
+		uint64_t reserved_1_63:63;
+#endif
+	} s;
+	struct cvmx_ciu2_ack_ppx_ip4_s cn68xx;
+	struct cvmx_ciu2_ack_ppx_ip4_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_gpio {
+	uint64_t u64;
+	struct cvmx_ciu2_en_iox_int_gpio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t gpio:16;
+#else
+		uint64_t gpio:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} s;
+	struct cvmx_ciu2_en_iox_int_gpio_s cn68xx;
+	struct cvmx_ciu2_en_iox_int_gpio_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_gpio_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_iox_int_gpio_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t gpio:16;
+#else
+		uint64_t gpio:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} s;
+	struct cvmx_ciu2_en_iox_int_gpio_w1c_s cn68xx;
+	struct cvmx_ciu2_en_iox_int_gpio_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_gpio_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_iox_int_gpio_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t gpio:16;
+#else
+		uint64_t gpio:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} s;
+	struct cvmx_ciu2_en_iox_int_gpio_w1s_s cn68xx;
+	struct cvmx_ciu2_en_iox_int_gpio_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_io {
+	uint64_t u64;
+	struct cvmx_ciu2_en_iox_int_io_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_34_63:30;
+		uint64_t pem:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pci_inta:2;
+		uint64_t reserved_13_15:3;
+		uint64_t msired:1;
+		uint64_t pci_msi:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_intr:4;
+#else
+		uint64_t pci_intr:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_msi:4;
+		uint64_t msired:1;
+		uint64_t reserved_13_15:3;
+		uint64_t pci_inta:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pem:2;
+		uint64_t reserved_34_63:30;
+#endif
+	} s;
+	struct cvmx_ciu2_en_iox_int_io_s cn68xx;
+	struct cvmx_ciu2_en_iox_int_io_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_io_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_iox_int_io_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_34_63:30;
+		uint64_t pem:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pci_inta:2;
+		uint64_t reserved_13_15:3;
+		uint64_t msired:1;
+		uint64_t pci_msi:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_intr:4;
+#else
+		uint64_t pci_intr:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_msi:4;
+		uint64_t msired:1;
+		uint64_t reserved_13_15:3;
+		uint64_t pci_inta:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pem:2;
+		uint64_t reserved_34_63:30;
+#endif
+	} s;
+	struct cvmx_ciu2_en_iox_int_io_w1c_s cn68xx;
+	struct cvmx_ciu2_en_iox_int_io_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_io_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_iox_int_io_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_34_63:30;
+		uint64_t pem:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pci_inta:2;
+		uint64_t reserved_13_15:3;
+		uint64_t msired:1;
+		uint64_t pci_msi:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_intr:4;
+#else
+		uint64_t pci_intr:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_msi:4;
+		uint64_t msired:1;
+		uint64_t reserved_13_15:3;
+		uint64_t pci_inta:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pem:2;
+		uint64_t reserved_34_63:30;
+#endif
+	} s;
+	struct cvmx_ciu2_en_iox_int_io_w1s_s cn68xx;
+	struct cvmx_ciu2_en_iox_int_io_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_mbox {
+	uint64_t u64;
+	struct cvmx_ciu2_en_iox_int_mbox_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t mbox:4;
+#else
+		uint64_t mbox:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_en_iox_int_mbox_s cn68xx;
+	struct cvmx_ciu2_en_iox_int_mbox_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_mbox_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_iox_int_mbox_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t mbox:4;
+#else
+		uint64_t mbox:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_en_iox_int_mbox_w1c_s cn68xx;
+	struct cvmx_ciu2_en_iox_int_mbox_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_mbox_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_iox_int_mbox_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t mbox:4;
+#else
+		uint64_t mbox:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_en_iox_int_mbox_w1s_s cn68xx;
+	struct cvmx_ciu2_en_iox_int_mbox_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_mem {
+	uint64_t u64;
+	struct cvmx_ciu2_en_iox_int_mem_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t lmc:4;
+#else
+		uint64_t lmc:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_en_iox_int_mem_s cn68xx;
+	struct cvmx_ciu2_en_iox_int_mem_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_mem_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_iox_int_mem_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t lmc:4;
+#else
+		uint64_t lmc:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_en_iox_int_mem_w1c_s cn68xx;
+	struct cvmx_ciu2_en_iox_int_mem_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_mem_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_iox_int_mem_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t lmc:4;
+#else
+		uint64_t lmc:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_en_iox_int_mem_w1s_s cn68xx;
+	struct cvmx_ciu2_en_iox_int_mem_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_mio {
+	uint64_t u64;
+	struct cvmx_ciu2_en_iox_int_mio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_49_62:14;
+		uint64_t ptp:1;
+		uint64_t reserved_45_47:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_38_39:2;
+		uint64_t uart:2;
+		uint64_t reserved_34_35:2;
+		uint64_t twsi:2;
+		uint64_t reserved_19_31:13;
+		uint64_t bootdma:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_12_15:4;
+		uint64_t timer:4;
+		uint64_t reserved_3_7:5;
+		uint64_t ipd_drp:1;
+		uint64_t ssoiq:1;
+		uint64_t ipdppthr:1;
+#else
+		uint64_t ipdppthr:1;
+		uint64_t ssoiq:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_3_7:5;
+		uint64_t timer:4;
+		uint64_t reserved_12_15:4;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t bootdma:1;
+		uint64_t reserved_19_31:13;
+		uint64_t twsi:2;
+		uint64_t reserved_34_35:2;
+		uint64_t uart:2;
+		uint64_t reserved_38_39:2;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_45_47:3;
+		uint64_t ptp:1;
+		uint64_t reserved_49_62:14;
+		uint64_t rst:1;
+#endif
+	} s;
+	struct cvmx_ciu2_en_iox_int_mio_s cn68xx;
+	struct cvmx_ciu2_en_iox_int_mio_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_mio_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_iox_int_mio_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_49_62:14;
+		uint64_t ptp:1;
+		uint64_t reserved_45_47:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_38_39:2;
+		uint64_t uart:2;
+		uint64_t reserved_34_35:2;
+		uint64_t twsi:2;
+		uint64_t reserved_19_31:13;
+		uint64_t bootdma:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_12_15:4;
+		uint64_t timer:4;
+		uint64_t reserved_3_7:5;
+		uint64_t ipd_drp:1;
+		uint64_t ssoiq:1;
+		uint64_t ipdppthr:1;
+#else
+		uint64_t ipdppthr:1;
+		uint64_t ssoiq:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_3_7:5;
+		uint64_t timer:4;
+		uint64_t reserved_12_15:4;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t bootdma:1;
+		uint64_t reserved_19_31:13;
+		uint64_t twsi:2;
+		uint64_t reserved_34_35:2;
+		uint64_t uart:2;
+		uint64_t reserved_38_39:2;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_45_47:3;
+		uint64_t ptp:1;
+		uint64_t reserved_49_62:14;
+		uint64_t rst:1;
+#endif
+	} s;
+	struct cvmx_ciu2_en_iox_int_mio_w1c_s cn68xx;
+	struct cvmx_ciu2_en_iox_int_mio_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_mio_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_iox_int_mio_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_49_62:14;
+		uint64_t ptp:1;
+		uint64_t reserved_45_47:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_38_39:2;
+		uint64_t uart:2;
+		uint64_t reserved_34_35:2;
+		uint64_t twsi:2;
+		uint64_t reserved_19_31:13;
+		uint64_t bootdma:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_12_15:4;
+		uint64_t timer:4;
+		uint64_t reserved_3_7:5;
+		uint64_t ipd_drp:1;
+		uint64_t ssoiq:1;
+		uint64_t ipdppthr:1;
+#else
+		uint64_t ipdppthr:1;
+		uint64_t ssoiq:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_3_7:5;
+		uint64_t timer:4;
+		uint64_t reserved_12_15:4;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t bootdma:1;
+		uint64_t reserved_19_31:13;
+		uint64_t twsi:2;
+		uint64_t reserved_34_35:2;
+		uint64_t uart:2;
+		uint64_t reserved_38_39:2;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_45_47:3;
+		uint64_t ptp:1;
+		uint64_t reserved_49_62:14;
+		uint64_t rst:1;
+#endif
+	} s;
+	struct cvmx_ciu2_en_iox_int_mio_w1s_s cn68xx;
+	struct cvmx_ciu2_en_iox_int_mio_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_pkt {
+	uint64_t u64;
+	struct cvmx_ciu2_en_iox_int_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_54_63:10;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_54_63:10;
+#endif
+	} s;
+	struct cvmx_ciu2_en_iox_int_pkt_s cn68xx;
+	struct cvmx_ciu2_en_iox_int_pkt_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_49_63:15;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_63:15;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_pkt_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_iox_int_pkt_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_54_63:10;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_54_63:10;
+#endif
+	} s;
+	struct cvmx_ciu2_en_iox_int_pkt_w1c_s cn68xx;
+	struct cvmx_ciu2_en_iox_int_pkt_w1c_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_49_63:15;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_63:15;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_pkt_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_iox_int_pkt_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_54_63:10;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_54_63:10;
+#endif
+	} s;
+	struct cvmx_ciu2_en_iox_int_pkt_w1s_s cn68xx;
+	struct cvmx_ciu2_en_iox_int_pkt_w1s_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_49_63:15;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_63:15;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_rml {
+	uint64_t u64;
+	struct cvmx_ciu2_en_iox_int_rml_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} s;
+	struct cvmx_ciu2_en_iox_int_rml_s cn68xx;
+	struct cvmx_ciu2_en_iox_int_rml_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_rml_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_iox_int_rml_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} s;
+	struct cvmx_ciu2_en_iox_int_rml_w1c_s cn68xx;
+	struct cvmx_ciu2_en_iox_int_rml_w1c_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_rml_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_iox_int_rml_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} s;
+	struct cvmx_ciu2_en_iox_int_rml_w1s_s cn68xx;
+	struct cvmx_ciu2_en_iox_int_rml_w1s_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_wdog {
+	uint64_t u64;
+	struct cvmx_ciu2_en_iox_int_wdog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t wdog:32;
+#else
+		uint64_t wdog:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_ciu2_en_iox_int_wdog_s cn68xx;
+	struct cvmx_ciu2_en_iox_int_wdog_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_wdog_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_iox_int_wdog_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t wdog:32;
+#else
+		uint64_t wdog:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_ciu2_en_iox_int_wdog_w1c_s cn68xx;
+	struct cvmx_ciu2_en_iox_int_wdog_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_wdog_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_iox_int_wdog_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t wdog:32;
+#else
+		uint64_t wdog:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_ciu2_en_iox_int_wdog_w1s_s cn68xx;
+	struct cvmx_ciu2_en_iox_int_wdog_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_wrkq {
+	uint64_t u64;
+	struct cvmx_ciu2_en_iox_int_wrkq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t workq:64;
+#else
+		uint64_t workq:64;
+#endif
+	} s;
+	struct cvmx_ciu2_en_iox_int_wrkq_s cn68xx;
+	struct cvmx_ciu2_en_iox_int_wrkq_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_wrkq_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_iox_int_wrkq_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t workq:64;
+#else
+		uint64_t workq:64;
+#endif
+	} s;
+	struct cvmx_ciu2_en_iox_int_wrkq_w1c_s cn68xx;
+	struct cvmx_ciu2_en_iox_int_wrkq_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_iox_int_wrkq_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_iox_int_wrkq_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t workq:64;
+#else
+		uint64_t workq:64;
+#endif
+	} s;
+	struct cvmx_ciu2_en_iox_int_wrkq_w1s_s cn68xx;
+	struct cvmx_ciu2_en_iox_int_wrkq_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_gpio {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip2_gpio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t gpio:16;
+#else
+		uint64_t gpio:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip2_gpio_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip2_gpio_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_gpio_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip2_gpio_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t gpio:16;
+#else
+		uint64_t gpio:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip2_gpio_w1c_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip2_gpio_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_gpio_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip2_gpio_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t gpio:16;
+#else
+		uint64_t gpio:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip2_gpio_w1s_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip2_gpio_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_io {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip2_io_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_34_63:30;
+		uint64_t pem:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pci_inta:2;
+		uint64_t reserved_13_15:3;
+		uint64_t msired:1;
+		uint64_t pci_msi:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_intr:4;
+#else
+		uint64_t pci_intr:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_msi:4;
+		uint64_t msired:1;
+		uint64_t reserved_13_15:3;
+		uint64_t pci_inta:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pem:2;
+		uint64_t reserved_34_63:30;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip2_io_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip2_io_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_io_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip2_io_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_34_63:30;
+		uint64_t pem:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pci_inta:2;
+		uint64_t reserved_13_15:3;
+		uint64_t msired:1;
+		uint64_t pci_msi:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_intr:4;
+#else
+		uint64_t pci_intr:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_msi:4;
+		uint64_t msired:1;
+		uint64_t reserved_13_15:3;
+		uint64_t pci_inta:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pem:2;
+		uint64_t reserved_34_63:30;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip2_io_w1c_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip2_io_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_io_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip2_io_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_34_63:30;
+		uint64_t pem:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pci_inta:2;
+		uint64_t reserved_13_15:3;
+		uint64_t msired:1;
+		uint64_t pci_msi:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_intr:4;
+#else
+		uint64_t pci_intr:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_msi:4;
+		uint64_t msired:1;
+		uint64_t reserved_13_15:3;
+		uint64_t pci_inta:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pem:2;
+		uint64_t reserved_34_63:30;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip2_io_w1s_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip2_io_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_mbox {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip2_mbox_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t mbox:4;
+#else
+		uint64_t mbox:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip2_mbox_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip2_mbox_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_mbox_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip2_mbox_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t mbox:4;
+#else
+		uint64_t mbox:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip2_mbox_w1c_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip2_mbox_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_mbox_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip2_mbox_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t mbox:4;
+#else
+		uint64_t mbox:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip2_mbox_w1s_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip2_mbox_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_mem {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip2_mem_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t lmc:4;
+#else
+		uint64_t lmc:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip2_mem_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip2_mem_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_mem_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip2_mem_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t lmc:4;
+#else
+		uint64_t lmc:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip2_mem_w1c_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip2_mem_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_mem_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip2_mem_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t lmc:4;
+#else
+		uint64_t lmc:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip2_mem_w1s_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip2_mem_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_mio {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip2_mio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_49_62:14;
+		uint64_t ptp:1;
+		uint64_t reserved_45_47:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_38_39:2;
+		uint64_t uart:2;
+		uint64_t reserved_34_35:2;
+		uint64_t twsi:2;
+		uint64_t reserved_19_31:13;
+		uint64_t bootdma:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_12_15:4;
+		uint64_t timer:4;
+		uint64_t reserved_3_7:5;
+		uint64_t ipd_drp:1;
+		uint64_t ssoiq:1;
+		uint64_t ipdppthr:1;
+#else
+		uint64_t ipdppthr:1;
+		uint64_t ssoiq:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_3_7:5;
+		uint64_t timer:4;
+		uint64_t reserved_12_15:4;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t bootdma:1;
+		uint64_t reserved_19_31:13;
+		uint64_t twsi:2;
+		uint64_t reserved_34_35:2;
+		uint64_t uart:2;
+		uint64_t reserved_38_39:2;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_45_47:3;
+		uint64_t ptp:1;
+		uint64_t reserved_49_62:14;
+		uint64_t rst:1;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip2_mio_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip2_mio_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_mio_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip2_mio_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_49_62:14;
+		uint64_t ptp:1;
+		uint64_t reserved_45_47:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_38_39:2;
+		uint64_t uart:2;
+		uint64_t reserved_34_35:2;
+		uint64_t twsi:2;
+		uint64_t reserved_19_31:13;
+		uint64_t bootdma:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_12_15:4;
+		uint64_t timer:4;
+		uint64_t reserved_3_7:5;
+		uint64_t ipd_drp:1;
+		uint64_t ssoiq:1;
+		uint64_t ipdppthr:1;
+#else
+		uint64_t ipdppthr:1;
+		uint64_t ssoiq:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_3_7:5;
+		uint64_t timer:4;
+		uint64_t reserved_12_15:4;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t bootdma:1;
+		uint64_t reserved_19_31:13;
+		uint64_t twsi:2;
+		uint64_t reserved_34_35:2;
+		uint64_t uart:2;
+		uint64_t reserved_38_39:2;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_45_47:3;
+		uint64_t ptp:1;
+		uint64_t reserved_49_62:14;
+		uint64_t rst:1;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip2_mio_w1c_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip2_mio_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_mio_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip2_mio_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_49_62:14;
+		uint64_t ptp:1;
+		uint64_t reserved_45_47:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_38_39:2;
+		uint64_t uart:2;
+		uint64_t reserved_34_35:2;
+		uint64_t twsi:2;
+		uint64_t reserved_19_31:13;
+		uint64_t bootdma:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_12_15:4;
+		uint64_t timer:4;
+		uint64_t reserved_3_7:5;
+		uint64_t ipd_drp:1;
+		uint64_t ssoiq:1;
+		uint64_t ipdppthr:1;
+#else
+		uint64_t ipdppthr:1;
+		uint64_t ssoiq:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_3_7:5;
+		uint64_t timer:4;
+		uint64_t reserved_12_15:4;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t bootdma:1;
+		uint64_t reserved_19_31:13;
+		uint64_t twsi:2;
+		uint64_t reserved_34_35:2;
+		uint64_t uart:2;
+		uint64_t reserved_38_39:2;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_45_47:3;
+		uint64_t ptp:1;
+		uint64_t reserved_49_62:14;
+		uint64_t rst:1;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip2_mio_w1s_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip2_mio_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_pkt {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip2_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_54_63:10;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_54_63:10;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip2_pkt_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip2_pkt_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_49_63:15;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_63:15;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_pkt_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip2_pkt_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_54_63:10;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_54_63:10;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip2_pkt_w1c_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip2_pkt_w1c_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_49_63:15;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_63:15;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_pkt_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip2_pkt_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_54_63:10;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_54_63:10;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip2_pkt_w1s_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip2_pkt_w1s_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_49_63:15;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_63:15;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_rml {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip2_rml_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip2_rml_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip2_rml_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_rml_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip2_rml_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip2_rml_w1c_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip2_rml_w1c_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_rml_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip2_rml_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip2_rml_w1s_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip2_rml_w1s_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_wdog {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip2_wdog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t wdog:32;
+#else
+		uint64_t wdog:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip2_wdog_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip2_wdog_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_wdog_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip2_wdog_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t wdog:32;
+#else
+		uint64_t wdog:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip2_wdog_w1c_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip2_wdog_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_wdog_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip2_wdog_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t wdog:32;
+#else
+		uint64_t wdog:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip2_wdog_w1s_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip2_wdog_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_wrkq {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip2_wrkq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t workq:64;
+#else
+		uint64_t workq:64;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip2_wrkq_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip2_wrkq_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_wrkq_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip2_wrkq_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t workq:64;
+#else
+		uint64_t workq:64;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip2_wrkq_w1c_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip2_wrkq_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip2_wrkq_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip2_wrkq_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t workq:64;
+#else
+		uint64_t workq:64;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip2_wrkq_w1s_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip2_wrkq_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_gpio {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip3_gpio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t gpio:16;
+#else
+		uint64_t gpio:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip3_gpio_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip3_gpio_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_gpio_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip3_gpio_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t gpio:16;
+#else
+		uint64_t gpio:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip3_gpio_w1c_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip3_gpio_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_gpio_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip3_gpio_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t gpio:16;
+#else
+		uint64_t gpio:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip3_gpio_w1s_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip3_gpio_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_io {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip3_io_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_34_63:30;
+		uint64_t pem:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pci_inta:2;
+		uint64_t reserved_13_15:3;
+		uint64_t msired:1;
+		uint64_t pci_msi:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_intr:4;
+#else
+		uint64_t pci_intr:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_msi:4;
+		uint64_t msired:1;
+		uint64_t reserved_13_15:3;
+		uint64_t pci_inta:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pem:2;
+		uint64_t reserved_34_63:30;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip3_io_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip3_io_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_io_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip3_io_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_34_63:30;
+		uint64_t pem:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pci_inta:2;
+		uint64_t reserved_13_15:3;
+		uint64_t msired:1;
+		uint64_t pci_msi:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_intr:4;
+#else
+		uint64_t pci_intr:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_msi:4;
+		uint64_t msired:1;
+		uint64_t reserved_13_15:3;
+		uint64_t pci_inta:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pem:2;
+		uint64_t reserved_34_63:30;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip3_io_w1c_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip3_io_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_io_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip3_io_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_34_63:30;
+		uint64_t pem:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pci_inta:2;
+		uint64_t reserved_13_15:3;
+		uint64_t msired:1;
+		uint64_t pci_msi:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_intr:4;
+#else
+		uint64_t pci_intr:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_msi:4;
+		uint64_t msired:1;
+		uint64_t reserved_13_15:3;
+		uint64_t pci_inta:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pem:2;
+		uint64_t reserved_34_63:30;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip3_io_w1s_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip3_io_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_mbox {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip3_mbox_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t mbox:4;
+#else
+		uint64_t mbox:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip3_mbox_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip3_mbox_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_mbox_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip3_mbox_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t mbox:4;
+#else
+		uint64_t mbox:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip3_mbox_w1c_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip3_mbox_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_mbox_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip3_mbox_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t mbox:4;
+#else
+		uint64_t mbox:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip3_mbox_w1s_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip3_mbox_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_mem {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip3_mem_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t lmc:4;
+#else
+		uint64_t lmc:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip3_mem_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip3_mem_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_mem_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip3_mem_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t lmc:4;
+#else
+		uint64_t lmc:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip3_mem_w1c_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip3_mem_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_mem_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip3_mem_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t lmc:4;
+#else
+		uint64_t lmc:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip3_mem_w1s_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip3_mem_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_mio {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip3_mio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_49_62:14;
+		uint64_t ptp:1;
+		uint64_t reserved_45_47:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_38_39:2;
+		uint64_t uart:2;
+		uint64_t reserved_34_35:2;
+		uint64_t twsi:2;
+		uint64_t reserved_19_31:13;
+		uint64_t bootdma:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_12_15:4;
+		uint64_t timer:4;
+		uint64_t reserved_3_7:5;
+		uint64_t ipd_drp:1;
+		uint64_t ssoiq:1;
+		uint64_t ipdppthr:1;
+#else
+		uint64_t ipdppthr:1;
+		uint64_t ssoiq:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_3_7:5;
+		uint64_t timer:4;
+		uint64_t reserved_12_15:4;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t bootdma:1;
+		uint64_t reserved_19_31:13;
+		uint64_t twsi:2;
+		uint64_t reserved_34_35:2;
+		uint64_t uart:2;
+		uint64_t reserved_38_39:2;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_45_47:3;
+		uint64_t ptp:1;
+		uint64_t reserved_49_62:14;
+		uint64_t rst:1;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip3_mio_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip3_mio_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_mio_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip3_mio_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_49_62:14;
+		uint64_t ptp:1;
+		uint64_t reserved_45_47:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_38_39:2;
+		uint64_t uart:2;
+		uint64_t reserved_34_35:2;
+		uint64_t twsi:2;
+		uint64_t reserved_19_31:13;
+		uint64_t bootdma:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_12_15:4;
+		uint64_t timer:4;
+		uint64_t reserved_3_7:5;
+		uint64_t ipd_drp:1;
+		uint64_t ssoiq:1;
+		uint64_t ipdppthr:1;
+#else
+		uint64_t ipdppthr:1;
+		uint64_t ssoiq:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_3_7:5;
+		uint64_t timer:4;
+		uint64_t reserved_12_15:4;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t bootdma:1;
+		uint64_t reserved_19_31:13;
+		uint64_t twsi:2;
+		uint64_t reserved_34_35:2;
+		uint64_t uart:2;
+		uint64_t reserved_38_39:2;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_45_47:3;
+		uint64_t ptp:1;
+		uint64_t reserved_49_62:14;
+		uint64_t rst:1;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip3_mio_w1c_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip3_mio_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_mio_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip3_mio_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_49_62:14;
+		uint64_t ptp:1;
+		uint64_t reserved_45_47:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_38_39:2;
+		uint64_t uart:2;
+		uint64_t reserved_34_35:2;
+		uint64_t twsi:2;
+		uint64_t reserved_19_31:13;
+		uint64_t bootdma:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_12_15:4;
+		uint64_t timer:4;
+		uint64_t reserved_3_7:5;
+		uint64_t ipd_drp:1;
+		uint64_t ssoiq:1;
+		uint64_t ipdppthr:1;
+#else
+		uint64_t ipdppthr:1;
+		uint64_t ssoiq:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_3_7:5;
+		uint64_t timer:4;
+		uint64_t reserved_12_15:4;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t bootdma:1;
+		uint64_t reserved_19_31:13;
+		uint64_t twsi:2;
+		uint64_t reserved_34_35:2;
+		uint64_t uart:2;
+		uint64_t reserved_38_39:2;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_45_47:3;
+		uint64_t ptp:1;
+		uint64_t reserved_49_62:14;
+		uint64_t rst:1;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip3_mio_w1s_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip3_mio_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_pkt {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip3_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_54_63:10;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_54_63:10;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip3_pkt_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip3_pkt_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_49_63:15;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_63:15;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_pkt_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip3_pkt_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_54_63:10;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_54_63:10;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip3_pkt_w1c_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip3_pkt_w1c_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_49_63:15;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_63:15;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_pkt_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip3_pkt_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_54_63:10;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_54_63:10;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip3_pkt_w1s_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip3_pkt_w1s_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_49_63:15;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_63:15;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_rml {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip3_rml_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip3_rml_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip3_rml_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_rml_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip3_rml_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip3_rml_w1c_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip3_rml_w1c_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_rml_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip3_rml_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip3_rml_w1s_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip3_rml_w1s_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_wdog {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip3_wdog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t wdog:32;
+#else
+		uint64_t wdog:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip3_wdog_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip3_wdog_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_wdog_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip3_wdog_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t wdog:32;
+#else
+		uint64_t wdog:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip3_wdog_w1c_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip3_wdog_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_wdog_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip3_wdog_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t wdog:32;
+#else
+		uint64_t wdog:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip3_wdog_w1s_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip3_wdog_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_wrkq {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip3_wrkq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t workq:64;
+#else
+		uint64_t workq:64;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip3_wrkq_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip3_wrkq_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_wrkq_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip3_wrkq_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t workq:64;
+#else
+		uint64_t workq:64;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip3_wrkq_w1c_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip3_wrkq_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip3_wrkq_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip3_wrkq_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t workq:64;
+#else
+		uint64_t workq:64;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip3_wrkq_w1s_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip3_wrkq_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_gpio {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip4_gpio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t gpio:16;
+#else
+		uint64_t gpio:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip4_gpio_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip4_gpio_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_gpio_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip4_gpio_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t gpio:16;
+#else
+		uint64_t gpio:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip4_gpio_w1c_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip4_gpio_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_gpio_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip4_gpio_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t gpio:16;
+#else
+		uint64_t gpio:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip4_gpio_w1s_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip4_gpio_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_io {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip4_io_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_34_63:30;
+		uint64_t pem:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pci_inta:2;
+		uint64_t reserved_13_15:3;
+		uint64_t msired:1;
+		uint64_t pci_msi:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_intr:4;
+#else
+		uint64_t pci_intr:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_msi:4;
+		uint64_t msired:1;
+		uint64_t reserved_13_15:3;
+		uint64_t pci_inta:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pem:2;
+		uint64_t reserved_34_63:30;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip4_io_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip4_io_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_io_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip4_io_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_34_63:30;
+		uint64_t pem:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pci_inta:2;
+		uint64_t reserved_13_15:3;
+		uint64_t msired:1;
+		uint64_t pci_msi:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_intr:4;
+#else
+		uint64_t pci_intr:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_msi:4;
+		uint64_t msired:1;
+		uint64_t reserved_13_15:3;
+		uint64_t pci_inta:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pem:2;
+		uint64_t reserved_34_63:30;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip4_io_w1c_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip4_io_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_io_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip4_io_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_34_63:30;
+		uint64_t pem:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pci_inta:2;
+		uint64_t reserved_13_15:3;
+		uint64_t msired:1;
+		uint64_t pci_msi:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_intr:4;
+#else
+		uint64_t pci_intr:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_msi:4;
+		uint64_t msired:1;
+		uint64_t reserved_13_15:3;
+		uint64_t pci_inta:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pem:2;
+		uint64_t reserved_34_63:30;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip4_io_w1s_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip4_io_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_mbox {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip4_mbox_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t mbox:4;
+#else
+		uint64_t mbox:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip4_mbox_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip4_mbox_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_mbox_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip4_mbox_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t mbox:4;
+#else
+		uint64_t mbox:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip4_mbox_w1c_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip4_mbox_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_mbox_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip4_mbox_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t mbox:4;
+#else
+		uint64_t mbox:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip4_mbox_w1s_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip4_mbox_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_mem {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip4_mem_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t lmc:4;
+#else
+		uint64_t lmc:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip4_mem_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip4_mem_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_mem_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip4_mem_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t lmc:4;
+#else
+		uint64_t lmc:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip4_mem_w1c_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip4_mem_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_mem_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip4_mem_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t lmc:4;
+#else
+		uint64_t lmc:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip4_mem_w1s_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip4_mem_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_mio {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip4_mio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_49_62:14;
+		uint64_t ptp:1;
+		uint64_t reserved_45_47:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_38_39:2;
+		uint64_t uart:2;
+		uint64_t reserved_34_35:2;
+		uint64_t twsi:2;
+		uint64_t reserved_19_31:13;
+		uint64_t bootdma:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_12_15:4;
+		uint64_t timer:4;
+		uint64_t reserved_3_7:5;
+		uint64_t ipd_drp:1;
+		uint64_t ssoiq:1;
+		uint64_t ipdppthr:1;
+#else
+		uint64_t ipdppthr:1;
+		uint64_t ssoiq:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_3_7:5;
+		uint64_t timer:4;
+		uint64_t reserved_12_15:4;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t bootdma:1;
+		uint64_t reserved_19_31:13;
+		uint64_t twsi:2;
+		uint64_t reserved_34_35:2;
+		uint64_t uart:2;
+		uint64_t reserved_38_39:2;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_45_47:3;
+		uint64_t ptp:1;
+		uint64_t reserved_49_62:14;
+		uint64_t rst:1;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip4_mio_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip4_mio_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_mio_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip4_mio_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_49_62:14;
+		uint64_t ptp:1;
+		uint64_t reserved_45_47:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_38_39:2;
+		uint64_t uart:2;
+		uint64_t reserved_34_35:2;
+		uint64_t twsi:2;
+		uint64_t reserved_19_31:13;
+		uint64_t bootdma:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_12_15:4;
+		uint64_t timer:4;
+		uint64_t reserved_3_7:5;
+		uint64_t ipd_drp:1;
+		uint64_t ssoiq:1;
+		uint64_t ipdppthr:1;
+#else
+		uint64_t ipdppthr:1;
+		uint64_t ssoiq:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_3_7:5;
+		uint64_t timer:4;
+		uint64_t reserved_12_15:4;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t bootdma:1;
+		uint64_t reserved_19_31:13;
+		uint64_t twsi:2;
+		uint64_t reserved_34_35:2;
+		uint64_t uart:2;
+		uint64_t reserved_38_39:2;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_45_47:3;
+		uint64_t ptp:1;
+		uint64_t reserved_49_62:14;
+		uint64_t rst:1;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip4_mio_w1c_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip4_mio_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_mio_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip4_mio_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_49_62:14;
+		uint64_t ptp:1;
+		uint64_t reserved_45_47:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_38_39:2;
+		uint64_t uart:2;
+		uint64_t reserved_34_35:2;
+		uint64_t twsi:2;
+		uint64_t reserved_19_31:13;
+		uint64_t bootdma:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_12_15:4;
+		uint64_t timer:4;
+		uint64_t reserved_3_7:5;
+		uint64_t ipd_drp:1;
+		uint64_t ssoiq:1;
+		uint64_t ipdppthr:1;
+#else
+		uint64_t ipdppthr:1;
+		uint64_t ssoiq:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_3_7:5;
+		uint64_t timer:4;
+		uint64_t reserved_12_15:4;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t bootdma:1;
+		uint64_t reserved_19_31:13;
+		uint64_t twsi:2;
+		uint64_t reserved_34_35:2;
+		uint64_t uart:2;
+		uint64_t reserved_38_39:2;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_45_47:3;
+		uint64_t ptp:1;
+		uint64_t reserved_49_62:14;
+		uint64_t rst:1;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip4_mio_w1s_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip4_mio_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_pkt {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip4_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_54_63:10;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_54_63:10;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip4_pkt_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip4_pkt_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_49_63:15;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_63:15;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_pkt_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip4_pkt_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_54_63:10;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_54_63:10;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip4_pkt_w1c_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip4_pkt_w1c_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_49_63:15;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_63:15;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_pkt_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip4_pkt_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_54_63:10;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_54_63:10;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip4_pkt_w1s_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip4_pkt_w1s_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_49_63:15;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_63:15;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_rml {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip4_rml_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip4_rml_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip4_rml_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_rml_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip4_rml_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip4_rml_w1c_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip4_rml_w1c_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_rml_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip4_rml_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip4_rml_w1s_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip4_rml_w1s_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_wdog {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip4_wdog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t wdog:32;
+#else
+		uint64_t wdog:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip4_wdog_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip4_wdog_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_wdog_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip4_wdog_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t wdog:32;
+#else
+		uint64_t wdog:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip4_wdog_w1c_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip4_wdog_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_wdog_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip4_wdog_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t wdog:32;
+#else
+		uint64_t wdog:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip4_wdog_w1s_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip4_wdog_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_wrkq {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip4_wrkq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t workq:64;
+#else
+		uint64_t workq:64;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip4_wrkq_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip4_wrkq_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_wrkq_w1c {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip4_wrkq_w1c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t workq:64;
+#else
+		uint64_t workq:64;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip4_wrkq_w1c_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip4_wrkq_w1c_s cn68xxp1;
+};
+
+union cvmx_ciu2_en_ppx_ip4_wrkq_w1s {
+	uint64_t u64;
+	struct cvmx_ciu2_en_ppx_ip4_wrkq_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t workq:64;
+#else
+		uint64_t workq:64;
+#endif
+	} s;
+	struct cvmx_ciu2_en_ppx_ip4_wrkq_w1s_s cn68xx;
+	struct cvmx_ciu2_en_ppx_ip4_wrkq_w1s_s cn68xxp1;
+};
+
+union cvmx_ciu2_intr_ciu_ready {
+	uint64_t u64;
+	struct cvmx_ciu2_intr_ciu_ready_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_1_63:63;
+		uint64_t ready:1;
+#else
+		uint64_t ready:1;
+		uint64_t reserved_1_63:63;
+#endif
+	} s;
+	struct cvmx_ciu2_intr_ciu_ready_s cn68xx;
+	struct cvmx_ciu2_intr_ciu_ready_s cn68xxp1;
+};
+
+union cvmx_ciu2_intr_ram_ecc_ctl {
+	uint64_t u64;
+	struct cvmx_ciu2_intr_ram_ecc_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_3_63:61;
+		uint64_t flip_synd:2;
+		uint64_t ecc_ena:1;
+#else
+		uint64_t ecc_ena:1;
+		uint64_t flip_synd:2;
+		uint64_t reserved_3_63:61;
+#endif
+	} s;
+	struct cvmx_ciu2_intr_ram_ecc_ctl_s cn68xx;
+	struct cvmx_ciu2_intr_ram_ecc_ctl_s cn68xxp1;
+};
+
+union cvmx_ciu2_intr_ram_ecc_st {
+	uint64_t u64;
+	struct cvmx_ciu2_intr_ram_ecc_st_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_23_63:41;
+		uint64_t addr:7;
+		uint64_t reserved_13_15:3;
+		uint64_t syndrom:9;
+		uint64_t reserved_2_3:2;
+		uint64_t dbe:1;
+		uint64_t sbe:1;
+#else
+		uint64_t sbe:1;
+		uint64_t dbe:1;
+		uint64_t reserved_2_3:2;
+		uint64_t syndrom:9;
+		uint64_t reserved_13_15:3;
+		uint64_t addr:7;
+		uint64_t reserved_23_63:41;
+#endif
+	} s;
+	struct cvmx_ciu2_intr_ram_ecc_st_s cn68xx;
+	struct cvmx_ciu2_intr_ram_ecc_st_s cn68xxp1;
+};
+
+union cvmx_ciu2_intr_slowdown {
+	uint64_t u64;
+	struct cvmx_ciu2_intr_slowdown_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_3_63:61;
+		uint64_t ctl:3;
+#else
+		uint64_t ctl:3;
+		uint64_t reserved_3_63:61;
+#endif
+	} s;
+	struct cvmx_ciu2_intr_slowdown_s cn68xx;
+	struct cvmx_ciu2_intr_slowdown_s cn68xxp1;
+};
+
+union cvmx_ciu2_msi_rcvx {
+	uint64_t u64;
+	struct cvmx_ciu2_msi_rcvx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_1_63:63;
+		uint64_t msi_rcv:1;
+#else
+		uint64_t msi_rcv:1;
+		uint64_t reserved_1_63:63;
+#endif
+	} s;
+	struct cvmx_ciu2_msi_rcvx_s cn68xx;
+	struct cvmx_ciu2_msi_rcvx_s cn68xxp1;
+};
+
+union cvmx_ciu2_msi_selx {
+	uint64_t u64;
+	struct cvmx_ciu2_msi_selx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_13_63:51;
+		uint64_t pp_num:5;
+		uint64_t reserved_6_7:2;
+		uint64_t ip_num:2;
+		uint64_t reserved_1_3:3;
+		uint64_t en:1;
+#else
+		uint64_t en:1;
+		uint64_t reserved_1_3:3;
+		uint64_t ip_num:2;
+		uint64_t reserved_6_7:2;
+		uint64_t pp_num:5;
+		uint64_t reserved_13_63:51;
+#endif
+	} s;
+	struct cvmx_ciu2_msi_selx_s cn68xx;
+	struct cvmx_ciu2_msi_selx_s cn68xxp1;
+};
+
+union cvmx_ciu2_msired_ppx_ip2 {
+	uint64_t u64;
+	struct cvmx_ciu2_msired_ppx_ip2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_21_63:43;
+		uint64_t intr:1;
+		uint64_t reserved_17_19:3;
+		uint64_t newint:1;
+		uint64_t reserved_8_15:8;
+		uint64_t msi_num:8;
+#else
+		uint64_t msi_num:8;
+		uint64_t reserved_8_15:8;
+		uint64_t newint:1;
+		uint64_t reserved_17_19:3;
+		uint64_t intr:1;
+		uint64_t reserved_21_63:43;
+#endif
+	} s;
+	struct cvmx_ciu2_msired_ppx_ip2_s cn68xx;
+	struct cvmx_ciu2_msired_ppx_ip2_s cn68xxp1;
+};
+
+union cvmx_ciu2_msired_ppx_ip3 {
+	uint64_t u64;
+	struct cvmx_ciu2_msired_ppx_ip3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_21_63:43;
+		uint64_t intr:1;
+		uint64_t reserved_17_19:3;
+		uint64_t newint:1;
+		uint64_t reserved_8_15:8;
+		uint64_t msi_num:8;
+#else
+		uint64_t msi_num:8;
+		uint64_t reserved_8_15:8;
+		uint64_t newint:1;
+		uint64_t reserved_17_19:3;
+		uint64_t intr:1;
+		uint64_t reserved_21_63:43;
+#endif
+	} s;
+	struct cvmx_ciu2_msired_ppx_ip3_s cn68xx;
+	struct cvmx_ciu2_msired_ppx_ip3_s cn68xxp1;
+};
+
+union cvmx_ciu2_msired_ppx_ip4 {
+	uint64_t u64;
+	struct cvmx_ciu2_msired_ppx_ip4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_21_63:43;
+		uint64_t intr:1;
+		uint64_t reserved_17_19:3;
+		uint64_t newint:1;
+		uint64_t reserved_8_15:8;
+		uint64_t msi_num:8;
+#else
+		uint64_t msi_num:8;
+		uint64_t reserved_8_15:8;
+		uint64_t newint:1;
+		uint64_t reserved_17_19:3;
+		uint64_t intr:1;
+		uint64_t reserved_21_63:43;
+#endif
+	} s;
+	struct cvmx_ciu2_msired_ppx_ip4_s cn68xx;
+	struct cvmx_ciu2_msired_ppx_ip4_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_iox_int_gpio {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_iox_int_gpio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t gpio:16;
+#else
+		uint64_t gpio:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_iox_int_gpio_s cn68xx;
+	struct cvmx_ciu2_raw_iox_int_gpio_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_iox_int_io {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_iox_int_io_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_34_63:30;
+		uint64_t pem:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pci_inta:2;
+		uint64_t reserved_13_15:3;
+		uint64_t msired:1;
+		uint64_t pci_msi:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_intr:4;
+#else
+		uint64_t pci_intr:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_msi:4;
+		uint64_t msired:1;
+		uint64_t reserved_13_15:3;
+		uint64_t pci_inta:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pem:2;
+		uint64_t reserved_34_63:30;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_iox_int_io_s cn68xx;
+	struct cvmx_ciu2_raw_iox_int_io_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_iox_int_mem {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_iox_int_mem_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t lmc:4;
+#else
+		uint64_t lmc:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_iox_int_mem_s cn68xx;
+	struct cvmx_ciu2_raw_iox_int_mem_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_iox_int_mio {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_iox_int_mio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_49_62:14;
+		uint64_t ptp:1;
+		uint64_t reserved_45_47:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_38_39:2;
+		uint64_t uart:2;
+		uint64_t reserved_34_35:2;
+		uint64_t twsi:2;
+		uint64_t reserved_19_31:13;
+		uint64_t bootdma:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_12_15:4;
+		uint64_t timer:4;
+		uint64_t reserved_3_7:5;
+		uint64_t ipd_drp:1;
+		uint64_t ssoiq:1;
+		uint64_t ipdppthr:1;
+#else
+		uint64_t ipdppthr:1;
+		uint64_t ssoiq:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_3_7:5;
+		uint64_t timer:4;
+		uint64_t reserved_12_15:4;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t bootdma:1;
+		uint64_t reserved_19_31:13;
+		uint64_t twsi:2;
+		uint64_t reserved_34_35:2;
+		uint64_t uart:2;
+		uint64_t reserved_38_39:2;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_45_47:3;
+		uint64_t ptp:1;
+		uint64_t reserved_49_62:14;
+		uint64_t rst:1;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_iox_int_mio_s cn68xx;
+	struct cvmx_ciu2_raw_iox_int_mio_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_iox_int_pkt {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_iox_int_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_54_63:10;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_54_63:10;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_iox_int_pkt_s cn68xx;
+	struct cvmx_ciu2_raw_iox_int_pkt_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_49_63:15;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_63:15;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_raw_iox_int_rml {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_iox_int_rml_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_iox_int_rml_s cn68xx;
+	struct cvmx_ciu2_raw_iox_int_rml_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_raw_iox_int_wdog {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_iox_int_wdog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t wdog:32;
+#else
+		uint64_t wdog:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_iox_int_wdog_s cn68xx;
+	struct cvmx_ciu2_raw_iox_int_wdog_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_iox_int_wrkq {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_iox_int_wrkq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t workq:64;
+#else
+		uint64_t workq:64;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_iox_int_wrkq_s cn68xx;
+	struct cvmx_ciu2_raw_iox_int_wrkq_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip2_gpio {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_ppx_ip2_gpio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t gpio:16;
+#else
+		uint64_t gpio:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_ppx_ip2_gpio_s cn68xx;
+	struct cvmx_ciu2_raw_ppx_ip2_gpio_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip2_io {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_ppx_ip2_io_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_34_63:30;
+		uint64_t pem:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pci_inta:2;
+		uint64_t reserved_13_15:3;
+		uint64_t msired:1;
+		uint64_t pci_msi:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_intr:4;
+#else
+		uint64_t pci_intr:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_msi:4;
+		uint64_t msired:1;
+		uint64_t reserved_13_15:3;
+		uint64_t pci_inta:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pem:2;
+		uint64_t reserved_34_63:30;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_ppx_ip2_io_s cn68xx;
+	struct cvmx_ciu2_raw_ppx_ip2_io_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip2_mem {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_ppx_ip2_mem_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t lmc:4;
+#else
+		uint64_t lmc:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_ppx_ip2_mem_s cn68xx;
+	struct cvmx_ciu2_raw_ppx_ip2_mem_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip2_mio {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_ppx_ip2_mio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_49_62:14;
+		uint64_t ptp:1;
+		uint64_t reserved_45_47:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_38_39:2;
+		uint64_t uart:2;
+		uint64_t reserved_34_35:2;
+		uint64_t twsi:2;
+		uint64_t reserved_19_31:13;
+		uint64_t bootdma:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_12_15:4;
+		uint64_t timer:4;
+		uint64_t reserved_3_7:5;
+		uint64_t ipd_drp:1;
+		uint64_t ssoiq:1;
+		uint64_t ipdppthr:1;
+#else
+		uint64_t ipdppthr:1;
+		uint64_t ssoiq:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_3_7:5;
+		uint64_t timer:4;
+		uint64_t reserved_12_15:4;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t bootdma:1;
+		uint64_t reserved_19_31:13;
+		uint64_t twsi:2;
+		uint64_t reserved_34_35:2;
+		uint64_t uart:2;
+		uint64_t reserved_38_39:2;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_45_47:3;
+		uint64_t ptp:1;
+		uint64_t reserved_49_62:14;
+		uint64_t rst:1;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_ppx_ip2_mio_s cn68xx;
+	struct cvmx_ciu2_raw_ppx_ip2_mio_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip2_pkt {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_ppx_ip2_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_54_63:10;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_54_63:10;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_ppx_ip2_pkt_s cn68xx;
+	struct cvmx_ciu2_raw_ppx_ip2_pkt_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_49_63:15;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_63:15;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip2_rml {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_ppx_ip2_rml_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_ppx_ip2_rml_s cn68xx;
+	struct cvmx_ciu2_raw_ppx_ip2_rml_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip2_wdog {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_ppx_ip2_wdog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t wdog:32;
+#else
+		uint64_t wdog:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_ppx_ip2_wdog_s cn68xx;
+	struct cvmx_ciu2_raw_ppx_ip2_wdog_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip2_wrkq {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_ppx_ip2_wrkq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t workq:64;
+#else
+		uint64_t workq:64;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_ppx_ip2_wrkq_s cn68xx;
+	struct cvmx_ciu2_raw_ppx_ip2_wrkq_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip3_gpio {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_ppx_ip3_gpio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t gpio:16;
+#else
+		uint64_t gpio:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_ppx_ip3_gpio_s cn68xx;
+	struct cvmx_ciu2_raw_ppx_ip3_gpio_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip3_io {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_ppx_ip3_io_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_34_63:30;
+		uint64_t pem:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pci_inta:2;
+		uint64_t reserved_13_15:3;
+		uint64_t msired:1;
+		uint64_t pci_msi:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_intr:4;
+#else
+		uint64_t pci_intr:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_msi:4;
+		uint64_t msired:1;
+		uint64_t reserved_13_15:3;
+		uint64_t pci_inta:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pem:2;
+		uint64_t reserved_34_63:30;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_ppx_ip3_io_s cn68xx;
+	struct cvmx_ciu2_raw_ppx_ip3_io_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip3_mem {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_ppx_ip3_mem_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t lmc:4;
+#else
+		uint64_t lmc:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_ppx_ip3_mem_s cn68xx;
+	struct cvmx_ciu2_raw_ppx_ip3_mem_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip3_mio {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_ppx_ip3_mio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_49_62:14;
+		uint64_t ptp:1;
+		uint64_t reserved_45_47:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_38_39:2;
+		uint64_t uart:2;
+		uint64_t reserved_34_35:2;
+		uint64_t twsi:2;
+		uint64_t reserved_19_31:13;
+		uint64_t bootdma:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_12_15:4;
+		uint64_t timer:4;
+		uint64_t reserved_3_7:5;
+		uint64_t ipd_drp:1;
+		uint64_t ssoiq:1;
+		uint64_t ipdppthr:1;
+#else
+		uint64_t ipdppthr:1;
+		uint64_t ssoiq:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_3_7:5;
+		uint64_t timer:4;
+		uint64_t reserved_12_15:4;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t bootdma:1;
+		uint64_t reserved_19_31:13;
+		uint64_t twsi:2;
+		uint64_t reserved_34_35:2;
+		uint64_t uart:2;
+		uint64_t reserved_38_39:2;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_45_47:3;
+		uint64_t ptp:1;
+		uint64_t reserved_49_62:14;
+		uint64_t rst:1;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_ppx_ip3_mio_s cn68xx;
+	struct cvmx_ciu2_raw_ppx_ip3_mio_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip3_pkt {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_ppx_ip3_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_54_63:10;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_54_63:10;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_ppx_ip3_pkt_s cn68xx;
+	struct cvmx_ciu2_raw_ppx_ip3_pkt_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_49_63:15;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_63:15;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip3_rml {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_ppx_ip3_rml_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_ppx_ip3_rml_s cn68xx;
+	struct cvmx_ciu2_raw_ppx_ip3_rml_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip3_wdog {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_ppx_ip3_wdog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t wdog:32;
+#else
+		uint64_t wdog:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_ppx_ip3_wdog_s cn68xx;
+	struct cvmx_ciu2_raw_ppx_ip3_wdog_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip3_wrkq {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_ppx_ip3_wrkq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t workq:64;
+#else
+		uint64_t workq:64;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_ppx_ip3_wrkq_s cn68xx;
+	struct cvmx_ciu2_raw_ppx_ip3_wrkq_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip4_gpio {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_ppx_ip4_gpio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t gpio:16;
+#else
+		uint64_t gpio:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_ppx_ip4_gpio_s cn68xx;
+	struct cvmx_ciu2_raw_ppx_ip4_gpio_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip4_io {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_ppx_ip4_io_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_34_63:30;
+		uint64_t pem:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pci_inta:2;
+		uint64_t reserved_13_15:3;
+		uint64_t msired:1;
+		uint64_t pci_msi:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_intr:4;
+#else
+		uint64_t pci_intr:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_msi:4;
+		uint64_t msired:1;
+		uint64_t reserved_13_15:3;
+		uint64_t pci_inta:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pem:2;
+		uint64_t reserved_34_63:30;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_ppx_ip4_io_s cn68xx;
+	struct cvmx_ciu2_raw_ppx_ip4_io_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip4_mem {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_ppx_ip4_mem_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t lmc:4;
+#else
+		uint64_t lmc:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_ppx_ip4_mem_s cn68xx;
+	struct cvmx_ciu2_raw_ppx_ip4_mem_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip4_mio {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_ppx_ip4_mio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_49_62:14;
+		uint64_t ptp:1;
+		uint64_t reserved_45_47:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_38_39:2;
+		uint64_t uart:2;
+		uint64_t reserved_34_35:2;
+		uint64_t twsi:2;
+		uint64_t reserved_19_31:13;
+		uint64_t bootdma:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_12_15:4;
+		uint64_t timer:4;
+		uint64_t reserved_3_7:5;
+		uint64_t ipd_drp:1;
+		uint64_t ssoiq:1;
+		uint64_t ipdppthr:1;
+#else
+		uint64_t ipdppthr:1;
+		uint64_t ssoiq:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_3_7:5;
+		uint64_t timer:4;
+		uint64_t reserved_12_15:4;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t bootdma:1;
+		uint64_t reserved_19_31:13;
+		uint64_t twsi:2;
+		uint64_t reserved_34_35:2;
+		uint64_t uart:2;
+		uint64_t reserved_38_39:2;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_45_47:3;
+		uint64_t ptp:1;
+		uint64_t reserved_49_62:14;
+		uint64_t rst:1;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_ppx_ip4_mio_s cn68xx;
+	struct cvmx_ciu2_raw_ppx_ip4_mio_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip4_pkt {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_ppx_ip4_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_54_63:10;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_54_63:10;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_ppx_ip4_pkt_s cn68xx;
+	struct cvmx_ciu2_raw_ppx_ip4_pkt_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_49_63:15;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_63:15;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip4_rml {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_ppx_ip4_rml_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_ppx_ip4_rml_s cn68xx;
+	struct cvmx_ciu2_raw_ppx_ip4_rml_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip4_wdog {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_ppx_ip4_wdog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t wdog:32;
+#else
+		uint64_t wdog:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_ppx_ip4_wdog_s cn68xx;
+	struct cvmx_ciu2_raw_ppx_ip4_wdog_s cn68xxp1;
+};
+
+union cvmx_ciu2_raw_ppx_ip4_wrkq {
+	uint64_t u64;
+	struct cvmx_ciu2_raw_ppx_ip4_wrkq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t workq:64;
+#else
+		uint64_t workq:64;
+#endif
+	} s;
+	struct cvmx_ciu2_raw_ppx_ip4_wrkq_s cn68xx;
+	struct cvmx_ciu2_raw_ppx_ip4_wrkq_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_iox_int_gpio {
+	uint64_t u64;
+	struct cvmx_ciu2_src_iox_int_gpio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t gpio:16;
+#else
+		uint64_t gpio:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} s;
+	struct cvmx_ciu2_src_iox_int_gpio_s cn68xx;
+	struct cvmx_ciu2_src_iox_int_gpio_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_iox_int_io {
+	uint64_t u64;
+	struct cvmx_ciu2_src_iox_int_io_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_34_63:30;
+		uint64_t pem:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pci_inta:2;
+		uint64_t reserved_13_15:3;
+		uint64_t msired:1;
+		uint64_t pci_msi:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_intr:4;
+#else
+		uint64_t pci_intr:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_msi:4;
+		uint64_t msired:1;
+		uint64_t reserved_13_15:3;
+		uint64_t pci_inta:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pem:2;
+		uint64_t reserved_34_63:30;
+#endif
+	} s;
+	struct cvmx_ciu2_src_iox_int_io_s cn68xx;
+	struct cvmx_ciu2_src_iox_int_io_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_iox_int_mbox {
+	uint64_t u64;
+	struct cvmx_ciu2_src_iox_int_mbox_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t mbox:4;
+#else
+		uint64_t mbox:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_src_iox_int_mbox_s cn68xx;
+	struct cvmx_ciu2_src_iox_int_mbox_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_iox_int_mem {
+	uint64_t u64;
+	struct cvmx_ciu2_src_iox_int_mem_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t lmc:4;
+#else
+		uint64_t lmc:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_src_iox_int_mem_s cn68xx;
+	struct cvmx_ciu2_src_iox_int_mem_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_iox_int_mio {
+	uint64_t u64;
+	struct cvmx_ciu2_src_iox_int_mio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_49_62:14;
+		uint64_t ptp:1;
+		uint64_t reserved_45_47:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_38_39:2;
+		uint64_t uart:2;
+		uint64_t reserved_34_35:2;
+		uint64_t twsi:2;
+		uint64_t reserved_19_31:13;
+		uint64_t bootdma:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_12_15:4;
+		uint64_t timer:4;
+		uint64_t reserved_3_7:5;
+		uint64_t ipd_drp:1;
+		uint64_t ssoiq:1;
+		uint64_t ipdppthr:1;
+#else
+		uint64_t ipdppthr:1;
+		uint64_t ssoiq:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_3_7:5;
+		uint64_t timer:4;
+		uint64_t reserved_12_15:4;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t bootdma:1;
+		uint64_t reserved_19_31:13;
+		uint64_t twsi:2;
+		uint64_t reserved_34_35:2;
+		uint64_t uart:2;
+		uint64_t reserved_38_39:2;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_45_47:3;
+		uint64_t ptp:1;
+		uint64_t reserved_49_62:14;
+		uint64_t rst:1;
+#endif
+	} s;
+	struct cvmx_ciu2_src_iox_int_mio_s cn68xx;
+	struct cvmx_ciu2_src_iox_int_mio_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_iox_int_pkt {
+	uint64_t u64;
+	struct cvmx_ciu2_src_iox_int_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_54_63:10;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_54_63:10;
+#endif
+	} s;
+	struct cvmx_ciu2_src_iox_int_pkt_s cn68xx;
+	struct cvmx_ciu2_src_iox_int_pkt_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_49_63:15;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_63:15;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_src_iox_int_rml {
+	uint64_t u64;
+	struct cvmx_ciu2_src_iox_int_rml_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} s;
+	struct cvmx_ciu2_src_iox_int_rml_s cn68xx;
+	struct cvmx_ciu2_src_iox_int_rml_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_src_iox_int_wdog {
+	uint64_t u64;
+	struct cvmx_ciu2_src_iox_int_wdog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t wdog:32;
+#else
+		uint64_t wdog:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_ciu2_src_iox_int_wdog_s cn68xx;
+	struct cvmx_ciu2_src_iox_int_wdog_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_iox_int_wrkq {
+	uint64_t u64;
+	struct cvmx_ciu2_src_iox_int_wrkq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t workq:64;
+#else
+		uint64_t workq:64;
+#endif
+	} s;
+	struct cvmx_ciu2_src_iox_int_wrkq_s cn68xx;
+	struct cvmx_ciu2_src_iox_int_wrkq_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip2_gpio {
+	uint64_t u64;
+	struct cvmx_ciu2_src_ppx_ip2_gpio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t gpio:16;
+#else
+		uint64_t gpio:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} s;
+	struct cvmx_ciu2_src_ppx_ip2_gpio_s cn68xx;
+	struct cvmx_ciu2_src_ppx_ip2_gpio_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip2_io {
+	uint64_t u64;
+	struct cvmx_ciu2_src_ppx_ip2_io_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_34_63:30;
+		uint64_t pem:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pci_inta:2;
+		uint64_t reserved_13_15:3;
+		uint64_t msired:1;
+		uint64_t pci_msi:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_intr:4;
+#else
+		uint64_t pci_intr:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_msi:4;
+		uint64_t msired:1;
+		uint64_t reserved_13_15:3;
+		uint64_t pci_inta:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pem:2;
+		uint64_t reserved_34_63:30;
+#endif
+	} s;
+	struct cvmx_ciu2_src_ppx_ip2_io_s cn68xx;
+	struct cvmx_ciu2_src_ppx_ip2_io_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip2_mbox {
+	uint64_t u64;
+	struct cvmx_ciu2_src_ppx_ip2_mbox_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t mbox:4;
+#else
+		uint64_t mbox:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_src_ppx_ip2_mbox_s cn68xx;
+	struct cvmx_ciu2_src_ppx_ip2_mbox_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip2_mem {
+	uint64_t u64;
+	struct cvmx_ciu2_src_ppx_ip2_mem_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t lmc:4;
+#else
+		uint64_t lmc:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_src_ppx_ip2_mem_s cn68xx;
+	struct cvmx_ciu2_src_ppx_ip2_mem_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip2_mio {
+	uint64_t u64;
+	struct cvmx_ciu2_src_ppx_ip2_mio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_49_62:14;
+		uint64_t ptp:1;
+		uint64_t reserved_45_47:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_38_39:2;
+		uint64_t uart:2;
+		uint64_t reserved_34_35:2;
+		uint64_t twsi:2;
+		uint64_t reserved_19_31:13;
+		uint64_t bootdma:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_12_15:4;
+		uint64_t timer:4;
+		uint64_t reserved_3_7:5;
+		uint64_t ipd_drp:1;
+		uint64_t ssoiq:1;
+		uint64_t ipdppthr:1;
+#else
+		uint64_t ipdppthr:1;
+		uint64_t ssoiq:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_3_7:5;
+		uint64_t timer:4;
+		uint64_t reserved_12_15:4;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t bootdma:1;
+		uint64_t reserved_19_31:13;
+		uint64_t twsi:2;
+		uint64_t reserved_34_35:2;
+		uint64_t uart:2;
+		uint64_t reserved_38_39:2;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_45_47:3;
+		uint64_t ptp:1;
+		uint64_t reserved_49_62:14;
+		uint64_t rst:1;
+#endif
+	} s;
+	struct cvmx_ciu2_src_ppx_ip2_mio_s cn68xx;
+	struct cvmx_ciu2_src_ppx_ip2_mio_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip2_pkt {
+	uint64_t u64;
+	struct cvmx_ciu2_src_ppx_ip2_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_54_63:10;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_54_63:10;
+#endif
+	} s;
+	struct cvmx_ciu2_src_ppx_ip2_pkt_s cn68xx;
+	struct cvmx_ciu2_src_ppx_ip2_pkt_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_49_63:15;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_63:15;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip2_rml {
+	uint64_t u64;
+	struct cvmx_ciu2_src_ppx_ip2_rml_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} s;
+	struct cvmx_ciu2_src_ppx_ip2_rml_s cn68xx;
+	struct cvmx_ciu2_src_ppx_ip2_rml_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip2_wdog {
+	uint64_t u64;
+	struct cvmx_ciu2_src_ppx_ip2_wdog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t wdog:32;
+#else
+		uint64_t wdog:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_ciu2_src_ppx_ip2_wdog_s cn68xx;
+	struct cvmx_ciu2_src_ppx_ip2_wdog_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip2_wrkq {
+	uint64_t u64;
+	struct cvmx_ciu2_src_ppx_ip2_wrkq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t workq:64;
+#else
+		uint64_t workq:64;
+#endif
+	} s;
+	struct cvmx_ciu2_src_ppx_ip2_wrkq_s cn68xx;
+	struct cvmx_ciu2_src_ppx_ip2_wrkq_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip3_gpio {
+	uint64_t u64;
+	struct cvmx_ciu2_src_ppx_ip3_gpio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t gpio:16;
+#else
+		uint64_t gpio:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} s;
+	struct cvmx_ciu2_src_ppx_ip3_gpio_s cn68xx;
+	struct cvmx_ciu2_src_ppx_ip3_gpio_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip3_io {
+	uint64_t u64;
+	struct cvmx_ciu2_src_ppx_ip3_io_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_34_63:30;
+		uint64_t pem:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pci_inta:2;
+		uint64_t reserved_13_15:3;
+		uint64_t msired:1;
+		uint64_t pci_msi:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_intr:4;
+#else
+		uint64_t pci_intr:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_msi:4;
+		uint64_t msired:1;
+		uint64_t reserved_13_15:3;
+		uint64_t pci_inta:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pem:2;
+		uint64_t reserved_34_63:30;
+#endif
+	} s;
+	struct cvmx_ciu2_src_ppx_ip3_io_s cn68xx;
+	struct cvmx_ciu2_src_ppx_ip3_io_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip3_mbox {
+	uint64_t u64;
+	struct cvmx_ciu2_src_ppx_ip3_mbox_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t mbox:4;
+#else
+		uint64_t mbox:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_src_ppx_ip3_mbox_s cn68xx;
+	struct cvmx_ciu2_src_ppx_ip3_mbox_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip3_mem {
+	uint64_t u64;
+	struct cvmx_ciu2_src_ppx_ip3_mem_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t lmc:4;
+#else
+		uint64_t lmc:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_src_ppx_ip3_mem_s cn68xx;
+	struct cvmx_ciu2_src_ppx_ip3_mem_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip3_mio {
+	uint64_t u64;
+	struct cvmx_ciu2_src_ppx_ip3_mio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_49_62:14;
+		uint64_t ptp:1;
+		uint64_t reserved_45_47:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_38_39:2;
+		uint64_t uart:2;
+		uint64_t reserved_34_35:2;
+		uint64_t twsi:2;
+		uint64_t reserved_19_31:13;
+		uint64_t bootdma:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_12_15:4;
+		uint64_t timer:4;
+		uint64_t reserved_3_7:5;
+		uint64_t ipd_drp:1;
+		uint64_t ssoiq:1;
+		uint64_t ipdppthr:1;
+#else
+		uint64_t ipdppthr:1;
+		uint64_t ssoiq:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_3_7:5;
+		uint64_t timer:4;
+		uint64_t reserved_12_15:4;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t bootdma:1;
+		uint64_t reserved_19_31:13;
+		uint64_t twsi:2;
+		uint64_t reserved_34_35:2;
+		uint64_t uart:2;
+		uint64_t reserved_38_39:2;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_45_47:3;
+		uint64_t ptp:1;
+		uint64_t reserved_49_62:14;
+		uint64_t rst:1;
+#endif
+	} s;
+	struct cvmx_ciu2_src_ppx_ip3_mio_s cn68xx;
+	struct cvmx_ciu2_src_ppx_ip3_mio_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip3_pkt {
+	uint64_t u64;
+	struct cvmx_ciu2_src_ppx_ip3_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_54_63:10;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_54_63:10;
+#endif
+	} s;
+	struct cvmx_ciu2_src_ppx_ip3_pkt_s cn68xx;
+	struct cvmx_ciu2_src_ppx_ip3_pkt_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_49_63:15;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_63:15;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip3_rml {
+	uint64_t u64;
+	struct cvmx_ciu2_src_ppx_ip3_rml_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} s;
+	struct cvmx_ciu2_src_ppx_ip3_rml_s cn68xx;
+	struct cvmx_ciu2_src_ppx_ip3_rml_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip3_wdog {
+	uint64_t u64;
+	struct cvmx_ciu2_src_ppx_ip3_wdog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t wdog:32;
+#else
+		uint64_t wdog:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_ciu2_src_ppx_ip3_wdog_s cn68xx;
+	struct cvmx_ciu2_src_ppx_ip3_wdog_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip3_wrkq {
+	uint64_t u64;
+	struct cvmx_ciu2_src_ppx_ip3_wrkq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t workq:64;
+#else
+		uint64_t workq:64;
+#endif
+	} s;
+	struct cvmx_ciu2_src_ppx_ip3_wrkq_s cn68xx;
+	struct cvmx_ciu2_src_ppx_ip3_wrkq_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip4_gpio {
+	uint64_t u64;
+	struct cvmx_ciu2_src_ppx_ip4_gpio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t gpio:16;
+#else
+		uint64_t gpio:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} s;
+	struct cvmx_ciu2_src_ppx_ip4_gpio_s cn68xx;
+	struct cvmx_ciu2_src_ppx_ip4_gpio_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip4_io {
+	uint64_t u64;
+	struct cvmx_ciu2_src_ppx_ip4_io_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_34_63:30;
+		uint64_t pem:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pci_inta:2;
+		uint64_t reserved_13_15:3;
+		uint64_t msired:1;
+		uint64_t pci_msi:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_intr:4;
+#else
+		uint64_t pci_intr:4;
+		uint64_t reserved_4_7:4;
+		uint64_t pci_msi:4;
+		uint64_t msired:1;
+		uint64_t reserved_13_15:3;
+		uint64_t pci_inta:2;
+		uint64_t reserved_18_31:14;
+		uint64_t pem:2;
+		uint64_t reserved_34_63:30;
+#endif
+	} s;
+	struct cvmx_ciu2_src_ppx_ip4_io_s cn68xx;
+	struct cvmx_ciu2_src_ppx_ip4_io_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip4_mbox {
+	uint64_t u64;
+	struct cvmx_ciu2_src_ppx_ip4_mbox_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t mbox:4;
+#else
+		uint64_t mbox:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_src_ppx_ip4_mbox_s cn68xx;
+	struct cvmx_ciu2_src_ppx_ip4_mbox_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip4_mem {
+	uint64_t u64;
+	struct cvmx_ciu2_src_ppx_ip4_mem_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t lmc:4;
+#else
+		uint64_t lmc:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_ciu2_src_ppx_ip4_mem_s cn68xx;
+	struct cvmx_ciu2_src_ppx_ip4_mem_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip4_mio {
+	uint64_t u64;
+	struct cvmx_ciu2_src_ppx_ip4_mio_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t rst:1;
+		uint64_t reserved_49_62:14;
+		uint64_t ptp:1;
+		uint64_t reserved_45_47:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_38_39:2;
+		uint64_t uart:2;
+		uint64_t reserved_34_35:2;
+		uint64_t twsi:2;
+		uint64_t reserved_19_31:13;
+		uint64_t bootdma:1;
+		uint64_t mio:1;
+		uint64_t nand:1;
+		uint64_t reserved_12_15:4;
+		uint64_t timer:4;
+		uint64_t reserved_3_7:5;
+		uint64_t ipd_drp:1;
+		uint64_t ssoiq:1;
+		uint64_t ipdppthr:1;
+#else
+		uint64_t ipdppthr:1;
+		uint64_t ssoiq:1;
+		uint64_t ipd_drp:1;
+		uint64_t reserved_3_7:5;
+		uint64_t timer:4;
+		uint64_t reserved_12_15:4;
+		uint64_t nand:1;
+		uint64_t mio:1;
+		uint64_t bootdma:1;
+		uint64_t reserved_19_31:13;
+		uint64_t twsi:2;
+		uint64_t reserved_34_35:2;
+		uint64_t uart:2;
+		uint64_t reserved_38_39:2;
+		uint64_t usb_uctl:1;
+		uint64_t reserved_41_43:3;
+		uint64_t usb_hci:1;
+		uint64_t reserved_45_47:3;
+		uint64_t ptp:1;
+		uint64_t reserved_49_62:14;
+		uint64_t rst:1;
+#endif
+	} s;
+	struct cvmx_ciu2_src_ppx_ip4_mio_s cn68xx;
+	struct cvmx_ciu2_src_ppx_ip4_mio_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip4_pkt {
+	uint64_t u64;
+	struct cvmx_ciu2_src_ppx_ip4_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_54_63:10;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_51:3;
+		uint64_t ilk_drp:2;
+		uint64_t reserved_54_63:10;
+#endif
+	} s;
+	struct cvmx_ciu2_src_ppx_ip4_pkt_s cn68xx;
+	struct cvmx_ciu2_src_ppx_ip4_pkt_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_49_63:15;
+		uint64_t ilk:1;
+		uint64_t reserved_41_47:7;
+		uint64_t mii:1;
+		uint64_t reserved_33_39:7;
+		uint64_t agl:1;
+		uint64_t reserved_13_31:19;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_5_7:3;
+		uint64_t agx:5;
+#else
+		uint64_t agx:5;
+		uint64_t reserved_5_7:3;
+		uint64_t gmx_drp:5;
+		uint64_t reserved_13_31:19;
+		uint64_t agl:1;
+		uint64_t reserved_33_39:7;
+		uint64_t mii:1;
+		uint64_t reserved_41_47:7;
+		uint64_t ilk:1;
+		uint64_t reserved_49_63:15;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip4_rml {
+	uint64_t u64;
+	struct cvmx_ciu2_src_ppx_ip4_rml_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_35:2;
+		uint64_t dpi_dma:1;
+		uint64_t reserved_37_39:3;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} s;
+	struct cvmx_ciu2_src_ppx_ip4_rml_s cn68xx;
+	struct cvmx_ciu2_src_ppx_ip4_rml_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t trace:4;
+		uint64_t reserved_49_51:3;
+		uint64_t l2c:1;
+		uint64_t reserved_41_47:7;
+		uint64_t dfa:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dpi:1;
+		uint64_t sli:1;
+		uint64_t reserved_31_31:1;
+		uint64_t key:1;
+		uint64_t rad:1;
+		uint64_t tim:1;
+		uint64_t reserved_25_27:3;
+		uint64_t zip:1;
+		uint64_t reserved_17_23:7;
+		uint64_t sso:1;
+		uint64_t reserved_8_15:8;
+		uint64_t pko:1;
+		uint64_t pip:1;
+		uint64_t ipd:1;
+		uint64_t fpa:1;
+		uint64_t reserved_1_3:3;
+		uint64_t iob:1;
+#else
+		uint64_t iob:1;
+		uint64_t reserved_1_3:3;
+		uint64_t fpa:1;
+		uint64_t ipd:1;
+		uint64_t pip:1;
+		uint64_t pko:1;
+		uint64_t reserved_8_15:8;
+		uint64_t sso:1;
+		uint64_t reserved_17_23:7;
+		uint64_t zip:1;
+		uint64_t reserved_25_27:3;
+		uint64_t tim:1;
+		uint64_t rad:1;
+		uint64_t key:1;
+		uint64_t reserved_31_31:1;
+		uint64_t sli:1;
+		uint64_t dpi:1;
+		uint64_t reserved_34_39:6;
+		uint64_t dfa:1;
+		uint64_t reserved_41_47:7;
+		uint64_t l2c:1;
+		uint64_t reserved_49_51:3;
+		uint64_t trace:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip4_wdog {
+	uint64_t u64;
+	struct cvmx_ciu2_src_ppx_ip4_wdog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t wdog:32;
+#else
+		uint64_t wdog:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_ciu2_src_ppx_ip4_wdog_s cn68xx;
+	struct cvmx_ciu2_src_ppx_ip4_wdog_s cn68xxp1;
+};
+
+union cvmx_ciu2_src_ppx_ip4_wrkq {
+	uint64_t u64;
+	struct cvmx_ciu2_src_ppx_ip4_wrkq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t workq:64;
+#else
+		uint64_t workq:64;
+#endif
+	} s;
+	struct cvmx_ciu2_src_ppx_ip4_wrkq_s cn68xx;
+	struct cvmx_ciu2_src_ppx_ip4_wrkq_s cn68xxp1;
+};
+
+union cvmx_ciu2_sum_iox_int {
+	uint64_t u64;
+	struct cvmx_ciu2_sum_iox_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t mbox:4;
+		uint64_t reserved_8_59:52;
+		uint64_t gpio:1;
+		uint64_t pkt:1;
+		uint64_t mem:1;
+		uint64_t io:1;
+		uint64_t mio:1;
+		uint64_t rml:1;
+		uint64_t wdog:1;
+		uint64_t workq:1;
+#else
+		uint64_t workq:1;
+		uint64_t wdog:1;
+		uint64_t rml:1;
+		uint64_t mio:1;
+		uint64_t io:1;
+		uint64_t mem:1;
+		uint64_t pkt:1;
+		uint64_t gpio:1;
+		uint64_t reserved_8_59:52;
+		uint64_t mbox:4;
+#endif
+	} s;
+	struct cvmx_ciu2_sum_iox_int_s cn68xx;
+	struct cvmx_ciu2_sum_iox_int_s cn68xxp1;
+};
+
+union cvmx_ciu2_sum_ppx_ip2 {
+	uint64_t u64;
+	struct cvmx_ciu2_sum_ppx_ip2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t mbox:4;
+		uint64_t reserved_8_59:52;
+		uint64_t gpio:1;
+		uint64_t pkt:1;
+		uint64_t mem:1;
+		uint64_t io:1;
+		uint64_t mio:1;
+		uint64_t rml:1;
+		uint64_t wdog:1;
+		uint64_t workq:1;
+#else
+		uint64_t workq:1;
+		uint64_t wdog:1;
+		uint64_t rml:1;
+		uint64_t mio:1;
+		uint64_t io:1;
+		uint64_t mem:1;
+		uint64_t pkt:1;
+		uint64_t gpio:1;
+		uint64_t reserved_8_59:52;
+		uint64_t mbox:4;
+#endif
+	} s;
+	struct cvmx_ciu2_sum_ppx_ip2_s cn68xx;
+	struct cvmx_ciu2_sum_ppx_ip2_s cn68xxp1;
+};
+
+union cvmx_ciu2_sum_ppx_ip3 {
+	uint64_t u64;
+	struct cvmx_ciu2_sum_ppx_ip3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t mbox:4;
+		uint64_t reserved_8_59:52;
+		uint64_t gpio:1;
+		uint64_t pkt:1;
+		uint64_t mem:1;
+		uint64_t io:1;
+		uint64_t mio:1;
+		uint64_t rml:1;
+		uint64_t wdog:1;
+		uint64_t workq:1;
+#else
+		uint64_t workq:1;
+		uint64_t wdog:1;
+		uint64_t rml:1;
+		uint64_t mio:1;
+		uint64_t io:1;
+		uint64_t mem:1;
+		uint64_t pkt:1;
+		uint64_t gpio:1;
+		uint64_t reserved_8_59:52;
+		uint64_t mbox:4;
+#endif
+	} s;
+	struct cvmx_ciu2_sum_ppx_ip3_s cn68xx;
+	struct cvmx_ciu2_sum_ppx_ip3_s cn68xxp1;
+};
+
+union cvmx_ciu2_sum_ppx_ip4 {
+	uint64_t u64;
+	struct cvmx_ciu2_sum_ppx_ip4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t mbox:4;
+		uint64_t reserved_8_59:52;
+		uint64_t gpio:1;
+		uint64_t pkt:1;
+		uint64_t mem:1;
+		uint64_t io:1;
+		uint64_t mio:1;
+		uint64_t rml:1;
+		uint64_t wdog:1;
+		uint64_t workq:1;
+#else
+		uint64_t workq:1;
+		uint64_t wdog:1;
+		uint64_t rml:1;
+		uint64_t mio:1;
+		uint64_t io:1;
+		uint64_t mem:1;
+		uint64_t pkt:1;
+		uint64_t gpio:1;
+		uint64_t reserved_8_59:52;
+		uint64_t mbox:4;
+#endif
+	} s;
+	struct cvmx_ciu2_sum_ppx_ip4_s cn68xx;
+	struct cvmx_ciu2_sum_ppx_ip4_s cn68xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-dbg-defs.h b/arch/mips/include/asm/octeon/cvmx-dbg-defs.h
index abbf42d..40799cd 100644
--- a/arch/mips/include/asm/octeon/cvmx-dbg-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-dbg-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -28,27 +28,43 @@
 #ifndef __CVMX_DBG_DEFS_H__
 #define __CVMX_DBG_DEFS_H__
 
-#define CVMX_DBG_DATA \
-	 CVMX_ADD_IO_SEG(0x00011F00000001E8ull)
+#define CVMX_DBG_DATA (CVMX_ADD_IO_SEG(0x00011F00000001E8ull))
 
 union cvmx_dbg_data {
 	uint64_t u64;
 	struct cvmx_dbg_data_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_23_63:41;
 		uint64_t c_mul:5;
 		uint64_t dsel_ext:1;
 		uint64_t data:17;
+#else
+		uint64_t data:17;
+		uint64_t dsel_ext:1;
+		uint64_t c_mul:5;
+		uint64_t reserved_23_63:41;
+#endif
 	} s;
 	struct cvmx_dbg_data_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_31_63:33;
 		uint64_t pll_mul:3;
 		uint64_t reserved_23_27:5;
 		uint64_t c_mul:5;
 		uint64_t dsel_ext:1;
 		uint64_t data:17;
+#else
+		uint64_t data:17;
+		uint64_t dsel_ext:1;
+		uint64_t c_mul:5;
+		uint64_t reserved_23_27:5;
+		uint64_t pll_mul:3;
+		uint64_t reserved_31_63:33;
+#endif
 	} cn30xx;
 	struct cvmx_dbg_data_cn30xx cn31xx;
 	struct cvmx_dbg_data_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_29_63:35;
 		uint64_t d_mul:4;
 		uint64_t dclk_mul2:1;
@@ -56,15 +72,32 @@
 		uint64_t c_mul:5;
 		uint64_t dsel_ext:1;
 		uint64_t data:17;
+#else
+		uint64_t data:17;
+		uint64_t dsel_ext:1;
+		uint64_t c_mul:5;
+		uint64_t cclk_div2:1;
+		uint64_t dclk_mul2:1;
+		uint64_t d_mul:4;
+		uint64_t reserved_29_63:35;
+#endif
 	} cn38xx;
 	struct cvmx_dbg_data_cn38xx cn38xxp2;
 	struct cvmx_dbg_data_cn30xx cn50xx;
 	struct cvmx_dbg_data_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_29_63:35;
 		uint64_t rem:6;
 		uint64_t c_mul:5;
 		uint64_t dsel_ext:1;
 		uint64_t data:17;
+#else
+		uint64_t data:17;
+		uint64_t dsel_ext:1;
+		uint64_t c_mul:5;
+		uint64_t rem:6;
+		uint64_t reserved_29_63:35;
+#endif
 	} cn58xx;
 	struct cvmx_dbg_data_cn58xx cn58xxp1;
 };
diff --git a/arch/mips/include/asm/octeon/cvmx-dpi-defs.h b/arch/mips/include/asm/octeon/cvmx-dpi-defs.h
index c34ad04..dd5b042 100644
--- a/arch/mips/include/asm/octeon/cvmx-dpi-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-dpi-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2011 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -55,52 +55,107 @@
 #define CVMX_DPI_REQ_ERR_SKIP_COMP (CVMX_ADD_IO_SEG(0x0001DF0000000838ull))
 #define CVMX_DPI_REQ_GBL_EN (CVMX_ADD_IO_SEG(0x0001DF0000000050ull))
 #define CVMX_DPI_SLI_PRTX_CFG(offset) (CVMX_ADD_IO_SEG(0x0001DF0000000900ull) + ((offset) & 3) * 8)
+static inline uint64_t CVMX_DPI_SLI_PRTX_ERR(unsigned long offset)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001DF0000000920ull) + (offset) * 8;
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+
+		if (OCTEON_IS_MODEL(OCTEON_CN68XX_PASS1))
+			return CVMX_ADD_IO_SEG(0x0001DF0000000928ull) + (offset) * 8;
+
+		if (OCTEON_IS_MODEL(OCTEON_CN68XX_PASS2))
+			return CVMX_ADD_IO_SEG(0x0001DF0000000920ull) + (offset) * 8;
+		return CVMX_ADD_IO_SEG(0x0001DF0000000920ull) + (offset) * 8;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001DF0000000928ull) + (offset) * 8;
+	}
+	return CVMX_ADD_IO_SEG(0x0001DF0000000920ull) + (offset) * 8;
+}
+
 #define CVMX_DPI_SLI_PRTX_ERR_INFO(offset) (CVMX_ADD_IO_SEG(0x0001DF0000000940ull) + ((offset) & 3) * 8)
 
 union cvmx_dpi_bist_status {
 	uint64_t u64;
 	struct cvmx_dpi_bist_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_47_63:17;
 		uint64_t bist:47;
+#else
+		uint64_t bist:47;
+		uint64_t reserved_47_63:17;
+#endif
 	} s;
 	struct cvmx_dpi_bist_status_s cn61xx;
 	struct cvmx_dpi_bist_status_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_45_63:19;
 		uint64_t bist:45;
+#else
+		uint64_t bist:45;
+		uint64_t reserved_45_63:19;
+#endif
 	} cn63xx;
 	struct cvmx_dpi_bist_status_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_37_63:27;
 		uint64_t bist:37;
+#else
+		uint64_t bist:37;
+		uint64_t reserved_37_63:27;
+#endif
 	} cn63xxp1;
 	struct cvmx_dpi_bist_status_s cn66xx;
 	struct cvmx_dpi_bist_status_cn63xx cn68xx;
 	struct cvmx_dpi_bist_status_cn63xx cn68xxp1;
+	struct cvmx_dpi_bist_status_s cnf71xx;
 };
 
 union cvmx_dpi_ctl {
 	uint64_t u64;
 	struct cvmx_dpi_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t clk:1;
 		uint64_t en:1;
+#else
+		uint64_t en:1;
+		uint64_t clk:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_dpi_ctl_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t en:1;
+#else
+		uint64_t en:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} cn61xx;
 	struct cvmx_dpi_ctl_s cn63xx;
 	struct cvmx_dpi_ctl_s cn63xxp1;
 	struct cvmx_dpi_ctl_s cn66xx;
 	struct cvmx_dpi_ctl_s cn68xx;
 	struct cvmx_dpi_ctl_s cn68xxp1;
+	struct cvmx_dpi_ctl_cn61xx cnf71xx;
 };
 
 union cvmx_dpi_dmax_counts {
 	uint64_t u64;
 	struct cvmx_dpi_dmax_counts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_39_63:25;
 		uint64_t fcnt:7;
 		uint64_t dbell:32;
+#else
+		uint64_t dbell:32;
+		uint64_t fcnt:7;
+		uint64_t reserved_39_63:25;
+#endif
 	} s;
 	struct cvmx_dpi_dmax_counts_s cn61xx;
 	struct cvmx_dpi_dmax_counts_s cn63xx;
@@ -108,13 +163,19 @@
 	struct cvmx_dpi_dmax_counts_s cn66xx;
 	struct cvmx_dpi_dmax_counts_s cn68xx;
 	struct cvmx_dpi_dmax_counts_s cn68xxp1;
+	struct cvmx_dpi_dmax_counts_s cnf71xx;
 };
 
 union cvmx_dpi_dmax_dbell {
 	uint64_t u64;
 	struct cvmx_dpi_dmax_dbell_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t dbell:16;
+#else
+		uint64_t dbell:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_dpi_dmax_dbell_s cn61xx;
 	struct cvmx_dpi_dmax_dbell_s cn63xx;
@@ -122,31 +183,48 @@
 	struct cvmx_dpi_dmax_dbell_s cn66xx;
 	struct cvmx_dpi_dmax_dbell_s cn68xx;
 	struct cvmx_dpi_dmax_dbell_s cn68xxp1;
+	struct cvmx_dpi_dmax_dbell_s cnf71xx;
 };
 
 union cvmx_dpi_dmax_err_rsp_status {
 	uint64_t u64;
 	struct cvmx_dpi_dmax_err_rsp_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t status:6;
+#else
+		uint64_t status:6;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
 	struct cvmx_dpi_dmax_err_rsp_status_s cn61xx;
 	struct cvmx_dpi_dmax_err_rsp_status_s cn66xx;
 	struct cvmx_dpi_dmax_err_rsp_status_s cn68xx;
 	struct cvmx_dpi_dmax_err_rsp_status_s cn68xxp1;
+	struct cvmx_dpi_dmax_err_rsp_status_s cnf71xx;
 };
 
 union cvmx_dpi_dmax_ibuff_saddr {
 	uint64_t u64;
 	struct cvmx_dpi_dmax_ibuff_saddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_62_63:2;
 		uint64_t csize:14;
 		uint64_t reserved_41_47:7;
 		uint64_t idle:1;
 		uint64_t saddr:33;
 		uint64_t reserved_0_6:7;
+#else
+		uint64_t reserved_0_6:7;
+		uint64_t saddr:33;
+		uint64_t idle:1;
+		uint64_t reserved_41_47:7;
+		uint64_t csize:14;
+		uint64_t reserved_62_63:2;
+#endif
 	} s;
 	struct cvmx_dpi_dmax_ibuff_saddr_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_62_63:2;
 		uint64_t csize:14;
 		uint64_t reserved_41_47:7;
@@ -154,47 +232,78 @@
 		uint64_t reserved_36_39:4;
 		uint64_t saddr:29;
 		uint64_t reserved_0_6:7;
+#else
+		uint64_t reserved_0_6:7;
+		uint64_t saddr:29;
+		uint64_t reserved_36_39:4;
+		uint64_t idle:1;
+		uint64_t reserved_41_47:7;
+		uint64_t csize:14;
+		uint64_t reserved_62_63:2;
+#endif
 	} cn61xx;
 	struct cvmx_dpi_dmax_ibuff_saddr_cn61xx cn63xx;
 	struct cvmx_dpi_dmax_ibuff_saddr_cn61xx cn63xxp1;
 	struct cvmx_dpi_dmax_ibuff_saddr_cn61xx cn66xx;
 	struct cvmx_dpi_dmax_ibuff_saddr_s cn68xx;
 	struct cvmx_dpi_dmax_ibuff_saddr_s cn68xxp1;
+	struct cvmx_dpi_dmax_ibuff_saddr_cn61xx cnf71xx;
 };
 
 union cvmx_dpi_dmax_iflight {
 	uint64_t u64;
 	struct cvmx_dpi_dmax_iflight_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_3_63:61;
 		uint64_t cnt:3;
+#else
+		uint64_t cnt:3;
+		uint64_t reserved_3_63:61;
+#endif
 	} s;
 	struct cvmx_dpi_dmax_iflight_s cn61xx;
 	struct cvmx_dpi_dmax_iflight_s cn66xx;
 	struct cvmx_dpi_dmax_iflight_s cn68xx;
 	struct cvmx_dpi_dmax_iflight_s cn68xxp1;
+	struct cvmx_dpi_dmax_iflight_s cnf71xx;
 };
 
 union cvmx_dpi_dmax_naddr {
 	uint64_t u64;
 	struct cvmx_dpi_dmax_naddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_40_63:24;
 		uint64_t addr:40;
+#else
+		uint64_t addr:40;
+		uint64_t reserved_40_63:24;
+#endif
 	} s;
 	struct cvmx_dpi_dmax_naddr_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_36_63:28;
 		uint64_t addr:36;
+#else
+		uint64_t addr:36;
+		uint64_t reserved_36_63:28;
+#endif
 	} cn61xx;
 	struct cvmx_dpi_dmax_naddr_cn61xx cn63xx;
 	struct cvmx_dpi_dmax_naddr_cn61xx cn63xxp1;
 	struct cvmx_dpi_dmax_naddr_cn61xx cn66xx;
 	struct cvmx_dpi_dmax_naddr_s cn68xx;
 	struct cvmx_dpi_dmax_naddr_s cn68xxp1;
+	struct cvmx_dpi_dmax_naddr_cn61xx cnf71xx;
 };
 
 union cvmx_dpi_dmax_reqbnk0 {
 	uint64_t u64;
 	struct cvmx_dpi_dmax_reqbnk0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t state:64;
+#else
+		uint64_t state:64;
+#endif
 	} s;
 	struct cvmx_dpi_dmax_reqbnk0_s cn61xx;
 	struct cvmx_dpi_dmax_reqbnk0_s cn63xx;
@@ -202,12 +311,17 @@
 	struct cvmx_dpi_dmax_reqbnk0_s cn66xx;
 	struct cvmx_dpi_dmax_reqbnk0_s cn68xx;
 	struct cvmx_dpi_dmax_reqbnk0_s cn68xxp1;
+	struct cvmx_dpi_dmax_reqbnk0_s cnf71xx;
 };
 
 union cvmx_dpi_dmax_reqbnk1 {
 	uint64_t u64;
 	struct cvmx_dpi_dmax_reqbnk1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t state:64;
+#else
+		uint64_t state:64;
+#endif
 	} s;
 	struct cvmx_dpi_dmax_reqbnk1_s cn61xx;
 	struct cvmx_dpi_dmax_reqbnk1_s cn63xx;
@@ -215,11 +329,13 @@
 	struct cvmx_dpi_dmax_reqbnk1_s cn66xx;
 	struct cvmx_dpi_dmax_reqbnk1_s cn68xx;
 	struct cvmx_dpi_dmax_reqbnk1_s cn68xxp1;
+	struct cvmx_dpi_dmax_reqbnk1_s cnf71xx;
 };
 
 union cvmx_dpi_dma_control {
 	uint64_t u64;
 	struct cvmx_dpi_dma_control_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_62_63:2;
 		uint64_t dici_mode:1;
 		uint64_t pkt_en1:1;
@@ -240,9 +356,32 @@
 		uint64_t o_es:2;
 		uint64_t o_mode:1;
 		uint64_t reserved_0_13:14;
+#else
+		uint64_t reserved_0_13:14;
+		uint64_t o_mode:1;
+		uint64_t o_es:2;
+		uint64_t o_ns:1;
+		uint64_t o_ro:1;
+		uint64_t o_add1:1;
+		uint64_t fpa_que:3;
+		uint64_t dwb_ichk:9;
+		uint64_t dwb_denb:1;
+		uint64_t b0_lend:1;
+		uint64_t reserved_34_47:14;
+		uint64_t dma_enb:6;
+		uint64_t reserved_54_55:2;
+		uint64_t pkt_en:1;
+		uint64_t pkt_hp:1;
+		uint64_t commit_mode:1;
+		uint64_t ffp_dis:1;
+		uint64_t pkt_en1:1;
+		uint64_t dici_mode:1;
+		uint64_t reserved_62_63:2;
+#endif
 	} s;
 	struct cvmx_dpi_dma_control_s cn61xx;
 	struct cvmx_dpi_dma_control_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_61_63:3;
 		uint64_t pkt_en1:1;
 		uint64_t ffp_dis:1;
@@ -262,8 +401,30 @@
 		uint64_t o_es:2;
 		uint64_t o_mode:1;
 		uint64_t reserved_0_13:14;
+#else
+		uint64_t reserved_0_13:14;
+		uint64_t o_mode:1;
+		uint64_t o_es:2;
+		uint64_t o_ns:1;
+		uint64_t o_ro:1;
+		uint64_t o_add1:1;
+		uint64_t fpa_que:3;
+		uint64_t dwb_ichk:9;
+		uint64_t dwb_denb:1;
+		uint64_t b0_lend:1;
+		uint64_t reserved_34_47:14;
+		uint64_t dma_enb:6;
+		uint64_t reserved_54_55:2;
+		uint64_t pkt_en:1;
+		uint64_t pkt_hp:1;
+		uint64_t commit_mode:1;
+		uint64_t ffp_dis:1;
+		uint64_t pkt_en1:1;
+		uint64_t reserved_61_63:3;
+#endif
 	} cn63xx;
 	struct cvmx_dpi_dma_control_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_59_63:5;
 		uint64_t commit_mode:1;
 		uint64_t pkt_hp:1;
@@ -281,17 +442,42 @@
 		uint64_t o_es:2;
 		uint64_t o_mode:1;
 		uint64_t reserved_0_13:14;
+#else
+		uint64_t reserved_0_13:14;
+		uint64_t o_mode:1;
+		uint64_t o_es:2;
+		uint64_t o_ns:1;
+		uint64_t o_ro:1;
+		uint64_t o_add1:1;
+		uint64_t fpa_que:3;
+		uint64_t dwb_ichk:9;
+		uint64_t dwb_denb:1;
+		uint64_t b0_lend:1;
+		uint64_t reserved_34_47:14;
+		uint64_t dma_enb:6;
+		uint64_t reserved_54_55:2;
+		uint64_t pkt_en:1;
+		uint64_t pkt_hp:1;
+		uint64_t commit_mode:1;
+		uint64_t reserved_59_63:5;
+#endif
 	} cn63xxp1;
 	struct cvmx_dpi_dma_control_cn63xx cn66xx;
 	struct cvmx_dpi_dma_control_s cn68xx;
 	struct cvmx_dpi_dma_control_cn63xx cn68xxp1;
+	struct cvmx_dpi_dma_control_s cnf71xx;
 };
 
 union cvmx_dpi_dma_engx_en {
 	uint64_t u64;
 	struct cvmx_dpi_dma_engx_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t qen:8;
+#else
+		uint64_t qen:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_dpi_dma_engx_en_s cn61xx;
 	struct cvmx_dpi_dma_engx_en_s cn63xx;
@@ -299,63 +485,101 @@
 	struct cvmx_dpi_dma_engx_en_s cn66xx;
 	struct cvmx_dpi_dma_engx_en_s cn68xx;
 	struct cvmx_dpi_dma_engx_en_s cn68xxp1;
+	struct cvmx_dpi_dma_engx_en_s cnf71xx;
 };
 
 union cvmx_dpi_dma_ppx_cnt {
 	uint64_t u64;
 	struct cvmx_dpi_dma_ppx_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t cnt:16;
+#else
+		uint64_t cnt:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_dpi_dma_ppx_cnt_s cn61xx;
 	struct cvmx_dpi_dma_ppx_cnt_s cn68xx;
+	struct cvmx_dpi_dma_ppx_cnt_s cnf71xx;
 };
 
 union cvmx_dpi_engx_buf {
 	uint64_t u64;
 	struct cvmx_dpi_engx_buf_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_37_63:27;
 		uint64_t compblks:5;
 		uint64_t reserved_9_31:23;
 		uint64_t base:5;
 		uint64_t blks:4;
+#else
+		uint64_t blks:4;
+		uint64_t base:5;
+		uint64_t reserved_9_31:23;
+		uint64_t compblks:5;
+		uint64_t reserved_37_63:27;
+#endif
 	} s;
 	struct cvmx_dpi_engx_buf_s cn61xx;
 	struct cvmx_dpi_engx_buf_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t base:4;
 		uint64_t blks:4;
+#else
+		uint64_t blks:4;
+		uint64_t base:4;
+		uint64_t reserved_8_63:56;
+#endif
 	} cn63xx;
 	struct cvmx_dpi_engx_buf_cn63xx cn63xxp1;
 	struct cvmx_dpi_engx_buf_s cn66xx;
 	struct cvmx_dpi_engx_buf_s cn68xx;
 	struct cvmx_dpi_engx_buf_s cn68xxp1;
+	struct cvmx_dpi_engx_buf_s cnf71xx;
 };
 
 union cvmx_dpi_info_reg {
 	uint64_t u64;
 	struct cvmx_dpi_info_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t ffp:4;
 		uint64_t reserved_2_3:2;
 		uint64_t ncb:1;
 		uint64_t rsl:1;
+#else
+		uint64_t rsl:1;
+		uint64_t ncb:1;
+		uint64_t reserved_2_3:2;
+		uint64_t ffp:4;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_dpi_info_reg_s cn61xx;
 	struct cvmx_dpi_info_reg_s cn63xx;
 	struct cvmx_dpi_info_reg_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t ncb:1;
 		uint64_t rsl:1;
+#else
+		uint64_t rsl:1;
+		uint64_t ncb:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} cn63xxp1;
 	struct cvmx_dpi_info_reg_s cn66xx;
 	struct cvmx_dpi_info_reg_s cn68xx;
 	struct cvmx_dpi_info_reg_s cn68xxp1;
+	struct cvmx_dpi_info_reg_s cnf71xx;
 };
 
 union cvmx_dpi_int_en {
 	uint64_t u64;
 	struct cvmx_dpi_int_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_28_63:36;
 		uint64_t sprt3_rst:1;
 		uint64_t sprt2_rst:1;
@@ -373,9 +597,29 @@
 		uint64_t reserved_2_7:6;
 		uint64_t nfovr:1;
 		uint64_t nderr:1;
+#else
+		uint64_t nderr:1;
+		uint64_t nfovr:1;
+		uint64_t reserved_2_7:6;
+		uint64_t dmadbo:8;
+		uint64_t req_badadr:1;
+		uint64_t req_badlen:1;
+		uint64_t req_ovrflw:1;
+		uint64_t req_undflw:1;
+		uint64_t req_anull:1;
+		uint64_t req_inull:1;
+		uint64_t req_badfil:1;
+		uint64_t reserved_23_23:1;
+		uint64_t sprt0_rst:1;
+		uint64_t sprt1_rst:1;
+		uint64_t sprt2_rst:1;
+		uint64_t sprt3_rst:1;
+		uint64_t reserved_28_63:36;
+#endif
 	} s;
 	struct cvmx_dpi_int_en_s cn61xx;
 	struct cvmx_dpi_int_en_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_26_63:38;
 		uint64_t sprt1_rst:1;
 		uint64_t sprt0_rst:1;
@@ -391,16 +635,35 @@
 		uint64_t reserved_2_7:6;
 		uint64_t nfovr:1;
 		uint64_t nderr:1;
+#else
+		uint64_t nderr:1;
+		uint64_t nfovr:1;
+		uint64_t reserved_2_7:6;
+		uint64_t dmadbo:8;
+		uint64_t req_badadr:1;
+		uint64_t req_badlen:1;
+		uint64_t req_ovrflw:1;
+		uint64_t req_undflw:1;
+		uint64_t req_anull:1;
+		uint64_t req_inull:1;
+		uint64_t req_badfil:1;
+		uint64_t reserved_23_23:1;
+		uint64_t sprt0_rst:1;
+		uint64_t sprt1_rst:1;
+		uint64_t reserved_26_63:38;
+#endif
 	} cn63xx;
 	struct cvmx_dpi_int_en_cn63xx cn63xxp1;
 	struct cvmx_dpi_int_en_s cn66xx;
 	struct cvmx_dpi_int_en_cn63xx cn68xx;
 	struct cvmx_dpi_int_en_cn63xx cn68xxp1;
+	struct cvmx_dpi_int_en_s cnf71xx;
 };
 
 union cvmx_dpi_int_reg {
 	uint64_t u64;
 	struct cvmx_dpi_int_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_28_63:36;
 		uint64_t sprt3_rst:1;
 		uint64_t sprt2_rst:1;
@@ -418,9 +681,29 @@
 		uint64_t reserved_2_7:6;
 		uint64_t nfovr:1;
 		uint64_t nderr:1;
+#else
+		uint64_t nderr:1;
+		uint64_t nfovr:1;
+		uint64_t reserved_2_7:6;
+		uint64_t dmadbo:8;
+		uint64_t req_badadr:1;
+		uint64_t req_badlen:1;
+		uint64_t req_ovrflw:1;
+		uint64_t req_undflw:1;
+		uint64_t req_anull:1;
+		uint64_t req_inull:1;
+		uint64_t req_badfil:1;
+		uint64_t reserved_23_23:1;
+		uint64_t sprt0_rst:1;
+		uint64_t sprt1_rst:1;
+		uint64_t sprt2_rst:1;
+		uint64_t sprt3_rst:1;
+		uint64_t reserved_28_63:36;
+#endif
 	} s;
 	struct cvmx_dpi_int_reg_s cn61xx;
 	struct cvmx_dpi_int_reg_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_26_63:38;
 		uint64_t sprt1_rst:1;
 		uint64_t sprt0_rst:1;
@@ -436,31 +719,62 @@
 		uint64_t reserved_2_7:6;
 		uint64_t nfovr:1;
 		uint64_t nderr:1;
+#else
+		uint64_t nderr:1;
+		uint64_t nfovr:1;
+		uint64_t reserved_2_7:6;
+		uint64_t dmadbo:8;
+		uint64_t req_badadr:1;
+		uint64_t req_badlen:1;
+		uint64_t req_ovrflw:1;
+		uint64_t req_undflw:1;
+		uint64_t req_anull:1;
+		uint64_t req_inull:1;
+		uint64_t req_badfil:1;
+		uint64_t reserved_23_23:1;
+		uint64_t sprt0_rst:1;
+		uint64_t sprt1_rst:1;
+		uint64_t reserved_26_63:38;
+#endif
 	} cn63xx;
 	struct cvmx_dpi_int_reg_cn63xx cn63xxp1;
 	struct cvmx_dpi_int_reg_s cn66xx;
 	struct cvmx_dpi_int_reg_cn63xx cn68xx;
 	struct cvmx_dpi_int_reg_cn63xx cn68xxp1;
+	struct cvmx_dpi_int_reg_s cnf71xx;
 };
 
 union cvmx_dpi_ncbx_cfg {
 	uint64_t u64;
 	struct cvmx_dpi_ncbx_cfg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t molr:6;
+#else
+		uint64_t molr:6;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
 	struct cvmx_dpi_ncbx_cfg_s cn61xx;
 	struct cvmx_dpi_ncbx_cfg_s cn66xx;
 	struct cvmx_dpi_ncbx_cfg_s cn68xx;
+	struct cvmx_dpi_ncbx_cfg_s cnf71xx;
 };
 
 union cvmx_dpi_pint_info {
 	uint64_t u64;
 	struct cvmx_dpi_pint_info_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_14_63:50;
 		uint64_t iinfo:6;
 		uint64_t reserved_6_7:2;
 		uint64_t sinfo:6;
+#else
+		uint64_t sinfo:6;
+		uint64_t reserved_6_7:2;
+		uint64_t iinfo:6;
+		uint64_t reserved_14_63:50;
+#endif
 	} s;
 	struct cvmx_dpi_pint_info_s cn61xx;
 	struct cvmx_dpi_pint_info_s cn63xx;
@@ -468,13 +782,19 @@
 	struct cvmx_dpi_pint_info_s cn66xx;
 	struct cvmx_dpi_pint_info_s cn68xx;
 	struct cvmx_dpi_pint_info_s cn68xxp1;
+	struct cvmx_dpi_pint_info_s cnf71xx;
 };
 
 union cvmx_dpi_pkt_err_rsp {
 	uint64_t u64;
 	struct cvmx_dpi_pkt_err_rsp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t pkterr:1;
+#else
+		uint64_t pkterr:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_dpi_pkt_err_rsp_s cn61xx;
 	struct cvmx_dpi_pkt_err_rsp_s cn63xx;
@@ -482,13 +802,19 @@
 	struct cvmx_dpi_pkt_err_rsp_s cn66xx;
 	struct cvmx_dpi_pkt_err_rsp_s cn68xx;
 	struct cvmx_dpi_pkt_err_rsp_s cn68xxp1;
+	struct cvmx_dpi_pkt_err_rsp_s cnf71xx;
 };
 
 union cvmx_dpi_req_err_rsp {
 	uint64_t u64;
 	struct cvmx_dpi_req_err_rsp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t qerr:8;
+#else
+		uint64_t qerr:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_dpi_req_err_rsp_s cn61xx;
 	struct cvmx_dpi_req_err_rsp_s cn63xx;
@@ -496,13 +822,19 @@
 	struct cvmx_dpi_req_err_rsp_s cn66xx;
 	struct cvmx_dpi_req_err_rsp_s cn68xx;
 	struct cvmx_dpi_req_err_rsp_s cn68xxp1;
+	struct cvmx_dpi_req_err_rsp_s cnf71xx;
 };
 
 union cvmx_dpi_req_err_rsp_en {
 	uint64_t u64;
 	struct cvmx_dpi_req_err_rsp_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t en:8;
+#else
+		uint64_t en:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_dpi_req_err_rsp_en_s cn61xx;
 	struct cvmx_dpi_req_err_rsp_en_s cn63xx;
@@ -510,13 +842,19 @@
 	struct cvmx_dpi_req_err_rsp_en_s cn66xx;
 	struct cvmx_dpi_req_err_rsp_en_s cn68xx;
 	struct cvmx_dpi_req_err_rsp_en_s cn68xxp1;
+	struct cvmx_dpi_req_err_rsp_en_s cnf71xx;
 };
 
 union cvmx_dpi_req_err_rst {
 	uint64_t u64;
 	struct cvmx_dpi_req_err_rst_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t qerr:8;
+#else
+		uint64_t qerr:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_dpi_req_err_rst_s cn61xx;
 	struct cvmx_dpi_req_err_rst_s cn63xx;
@@ -524,13 +862,19 @@
 	struct cvmx_dpi_req_err_rst_s cn66xx;
 	struct cvmx_dpi_req_err_rst_s cn68xx;
 	struct cvmx_dpi_req_err_rst_s cn68xxp1;
+	struct cvmx_dpi_req_err_rst_s cnf71xx;
 };
 
 union cvmx_dpi_req_err_rst_en {
 	uint64_t u64;
 	struct cvmx_dpi_req_err_rst_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t en:8;
+#else
+		uint64_t en:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_dpi_req_err_rst_en_s cn61xx;
 	struct cvmx_dpi_req_err_rst_en_s cn63xx;
@@ -538,27 +882,41 @@
 	struct cvmx_dpi_req_err_rst_en_s cn66xx;
 	struct cvmx_dpi_req_err_rst_en_s cn68xx;
 	struct cvmx_dpi_req_err_rst_en_s cn68xxp1;
+	struct cvmx_dpi_req_err_rst_en_s cnf71xx;
 };
 
 union cvmx_dpi_req_err_skip_comp {
 	uint64_t u64;
 	struct cvmx_dpi_req_err_skip_comp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_24_63:40;
 		uint64_t en_rst:8;
 		uint64_t reserved_8_15:8;
 		uint64_t en_rsp:8;
+#else
+		uint64_t en_rsp:8;
+		uint64_t reserved_8_15:8;
+		uint64_t en_rst:8;
+		uint64_t reserved_24_63:40;
+#endif
 	} s;
 	struct cvmx_dpi_req_err_skip_comp_s cn61xx;
 	struct cvmx_dpi_req_err_skip_comp_s cn66xx;
 	struct cvmx_dpi_req_err_skip_comp_s cn68xx;
 	struct cvmx_dpi_req_err_skip_comp_s cn68xxp1;
+	struct cvmx_dpi_req_err_skip_comp_s cnf71xx;
 };
 
 union cvmx_dpi_req_gbl_en {
 	uint64_t u64;
 	struct cvmx_dpi_req_gbl_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t qen:8;
+#else
+		uint64_t qen:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_dpi_req_gbl_en_s cn61xx;
 	struct cvmx_dpi_req_gbl_en_s cn63xx;
@@ -566,11 +924,13 @@
 	struct cvmx_dpi_req_gbl_en_s cn66xx;
 	struct cvmx_dpi_req_gbl_en_s cn68xx;
 	struct cvmx_dpi_req_gbl_en_s cn68xxp1;
+	struct cvmx_dpi_req_gbl_en_s cnf71xx;
 };
 
 union cvmx_dpi_sli_prtx_cfg {
 	uint64_t u64;
 	struct cvmx_dpi_sli_prtx_cfg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_25_63:39;
 		uint64_t halt:1;
 		uint64_t qlm_cfg:4;
@@ -584,9 +944,25 @@
 		uint64_t mrrs_lim:1;
 		uint64_t reserved_2_2:1;
 		uint64_t mrrs:2;
+#else
+		uint64_t mrrs:2;
+		uint64_t reserved_2_2:1;
+		uint64_t mrrs_lim:1;
+		uint64_t mps:1;
+		uint64_t reserved_5_6:2;
+		uint64_t mps_lim:1;
+		uint64_t molr:6;
+		uint64_t reserved_14_15:2;
+		uint64_t rd_mode:1;
+		uint64_t reserved_17_19:3;
+		uint64_t qlm_cfg:4;
+		uint64_t halt:1;
+		uint64_t reserved_25_63:39;
+#endif
 	} s;
 	struct cvmx_dpi_sli_prtx_cfg_s cn61xx;
 	struct cvmx_dpi_sli_prtx_cfg_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_25_63:39;
 		uint64_t halt:1;
 		uint64_t reserved_21_23:3;
@@ -601,18 +977,40 @@
 		uint64_t mrrs_lim:1;
 		uint64_t reserved_2_2:1;
 		uint64_t mrrs:2;
+#else
+		uint64_t mrrs:2;
+		uint64_t reserved_2_2:1;
+		uint64_t mrrs_lim:1;
+		uint64_t mps:1;
+		uint64_t reserved_5_6:2;
+		uint64_t mps_lim:1;
+		uint64_t molr:6;
+		uint64_t reserved_14_15:2;
+		uint64_t rd_mode:1;
+		uint64_t reserved_17_19:3;
+		uint64_t qlm_cfg:1;
+		uint64_t reserved_21_23:3;
+		uint64_t halt:1;
+		uint64_t reserved_25_63:39;
+#endif
 	} cn63xx;
 	struct cvmx_dpi_sli_prtx_cfg_cn63xx cn63xxp1;
 	struct cvmx_dpi_sli_prtx_cfg_s cn66xx;
 	struct cvmx_dpi_sli_prtx_cfg_cn63xx cn68xx;
 	struct cvmx_dpi_sli_prtx_cfg_cn63xx cn68xxp1;
+	struct cvmx_dpi_sli_prtx_cfg_s cnf71xx;
 };
 
 union cvmx_dpi_sli_prtx_err {
 	uint64_t u64;
 	struct cvmx_dpi_sli_prtx_err_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t addr:61;
 		uint64_t reserved_0_2:3;
+#else
+		uint64_t reserved_0_2:3;
+		uint64_t addr:61;
+#endif
 	} s;
 	struct cvmx_dpi_sli_prtx_err_s cn61xx;
 	struct cvmx_dpi_sli_prtx_err_s cn63xx;
@@ -620,17 +1018,27 @@
 	struct cvmx_dpi_sli_prtx_err_s cn66xx;
 	struct cvmx_dpi_sli_prtx_err_s cn68xx;
 	struct cvmx_dpi_sli_prtx_err_s cn68xxp1;
+	struct cvmx_dpi_sli_prtx_err_s cnf71xx;
 };
 
 union cvmx_dpi_sli_prtx_err_info {
 	uint64_t u64;
 	struct cvmx_dpi_sli_prtx_err_info_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t lock:1;
 		uint64_t reserved_5_7:3;
 		uint64_t type:1;
 		uint64_t reserved_3_3:1;
 		uint64_t reqq:3;
+#else
+		uint64_t reqq:3;
+		uint64_t reserved_3_3:1;
+		uint64_t type:1;
+		uint64_t reserved_5_7:3;
+		uint64_t lock:1;
+		uint64_t reserved_9_63:55;
+#endif
 	} s;
 	struct cvmx_dpi_sli_prtx_err_info_s cn61xx;
 	struct cvmx_dpi_sli_prtx_err_info_s cn63xx;
@@ -638,6 +1046,7 @@
 	struct cvmx_dpi_sli_prtx_err_info_s cn66xx;
 	struct cvmx_dpi_sli_prtx_err_info_s cn68xx;
 	struct cvmx_dpi_sli_prtx_err_info_s cn68xxp1;
+	struct cvmx_dpi_sli_prtx_err_info_s cnf71xx;
 };
 
 #endif
diff --git a/arch/mips/include/asm/octeon/cvmx-fpa-defs.h b/arch/mips/include/asm/octeon/cvmx-fpa-defs.h
index bf5546b..1d79e3c 100644
--- a/arch/mips/include/asm/octeon/cvmx-fpa-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-fpa-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -28,74 +28,83 @@
 #ifndef __CVMX_FPA_DEFS_H__
 #define __CVMX_FPA_DEFS_H__
 
-#define CVMX_FPA_BIST_STATUS \
-	 CVMX_ADD_IO_SEG(0x00011800280000E8ull)
-#define CVMX_FPA_CTL_STATUS \
-	 CVMX_ADD_IO_SEG(0x0001180028000050ull)
-#define CVMX_FPA_FPF0_MARKS \
-	 CVMX_ADD_IO_SEG(0x0001180028000000ull)
-#define CVMX_FPA_FPF0_SIZE \
-	 CVMX_ADD_IO_SEG(0x0001180028000058ull)
-#define CVMX_FPA_FPF1_MARKS \
-	 CVMX_ADD_IO_SEG(0x0001180028000008ull)
-#define CVMX_FPA_FPF2_MARKS \
-	 CVMX_ADD_IO_SEG(0x0001180028000010ull)
-#define CVMX_FPA_FPF3_MARKS \
-	 CVMX_ADD_IO_SEG(0x0001180028000018ull)
-#define CVMX_FPA_FPF4_MARKS \
-	 CVMX_ADD_IO_SEG(0x0001180028000020ull)
-#define CVMX_FPA_FPF5_MARKS \
-	 CVMX_ADD_IO_SEG(0x0001180028000028ull)
-#define CVMX_FPA_FPF6_MARKS \
-	 CVMX_ADD_IO_SEG(0x0001180028000030ull)
-#define CVMX_FPA_FPF7_MARKS \
-	 CVMX_ADD_IO_SEG(0x0001180028000038ull)
-#define CVMX_FPA_FPFX_MARKS(offset) \
-	 CVMX_ADD_IO_SEG(0x0001180028000008ull + (((offset) & 7) * 8) - 8 * 1)
-#define CVMX_FPA_FPFX_SIZE(offset) \
-	 CVMX_ADD_IO_SEG(0x0001180028000060ull + (((offset) & 7) * 8) - 8 * 1)
-#define CVMX_FPA_INT_ENB \
-	 CVMX_ADD_IO_SEG(0x0001180028000048ull)
-#define CVMX_FPA_INT_SUM \
-	 CVMX_ADD_IO_SEG(0x0001180028000040ull)
-#define CVMX_FPA_QUE0_PAGE_INDEX \
-	 CVMX_ADD_IO_SEG(0x00011800280000F0ull)
-#define CVMX_FPA_QUE1_PAGE_INDEX \
-	 CVMX_ADD_IO_SEG(0x00011800280000F8ull)
-#define CVMX_FPA_QUE2_PAGE_INDEX \
-	 CVMX_ADD_IO_SEG(0x0001180028000100ull)
-#define CVMX_FPA_QUE3_PAGE_INDEX \
-	 CVMX_ADD_IO_SEG(0x0001180028000108ull)
-#define CVMX_FPA_QUE4_PAGE_INDEX \
-	 CVMX_ADD_IO_SEG(0x0001180028000110ull)
-#define CVMX_FPA_QUE5_PAGE_INDEX \
-	 CVMX_ADD_IO_SEG(0x0001180028000118ull)
-#define CVMX_FPA_QUE6_PAGE_INDEX \
-	 CVMX_ADD_IO_SEG(0x0001180028000120ull)
-#define CVMX_FPA_QUE7_PAGE_INDEX \
-	 CVMX_ADD_IO_SEG(0x0001180028000128ull)
-#define CVMX_FPA_QUEX_AVAILABLE(offset) \
-	 CVMX_ADD_IO_SEG(0x0001180028000098ull + (((offset) & 7) * 8))
-#define CVMX_FPA_QUEX_PAGE_INDEX(offset) \
-	 CVMX_ADD_IO_SEG(0x00011800280000F0ull + (((offset) & 7) * 8))
-#define CVMX_FPA_QUE_ACT \
-	 CVMX_ADD_IO_SEG(0x0001180028000138ull)
-#define CVMX_FPA_QUE_EXP \
-	 CVMX_ADD_IO_SEG(0x0001180028000130ull)
-#define CVMX_FPA_WART_CTL \
-	 CVMX_ADD_IO_SEG(0x00011800280000D8ull)
-#define CVMX_FPA_WART_STATUS \
-	 CVMX_ADD_IO_SEG(0x00011800280000E0ull)
+#define CVMX_FPA_ADDR_RANGE_ERROR (CVMX_ADD_IO_SEG(0x0001180028000458ull))
+#define CVMX_FPA_BIST_STATUS (CVMX_ADD_IO_SEG(0x00011800280000E8ull))
+#define CVMX_FPA_CTL_STATUS (CVMX_ADD_IO_SEG(0x0001180028000050ull))
+#define CVMX_FPA_FPF0_MARKS (CVMX_ADD_IO_SEG(0x0001180028000000ull))
+#define CVMX_FPA_FPF0_SIZE (CVMX_ADD_IO_SEG(0x0001180028000058ull))
+#define CVMX_FPA_FPF1_MARKS CVMX_FPA_FPFX_MARKS(1)
+#define CVMX_FPA_FPF2_MARKS CVMX_FPA_FPFX_MARKS(2)
+#define CVMX_FPA_FPF3_MARKS CVMX_FPA_FPFX_MARKS(3)
+#define CVMX_FPA_FPF4_MARKS CVMX_FPA_FPFX_MARKS(4)
+#define CVMX_FPA_FPF5_MARKS CVMX_FPA_FPFX_MARKS(5)
+#define CVMX_FPA_FPF6_MARKS CVMX_FPA_FPFX_MARKS(6)
+#define CVMX_FPA_FPF7_MARKS CVMX_FPA_FPFX_MARKS(7)
+#define CVMX_FPA_FPF8_MARKS (CVMX_ADD_IO_SEG(0x0001180028000240ull))
+#define CVMX_FPA_FPF8_SIZE (CVMX_ADD_IO_SEG(0x0001180028000248ull))
+#define CVMX_FPA_FPFX_MARKS(offset) (CVMX_ADD_IO_SEG(0x0001180028000008ull) + ((offset) & 7) * 8 - 8*1)
+#define CVMX_FPA_FPFX_SIZE(offset) (CVMX_ADD_IO_SEG(0x0001180028000060ull) + ((offset) & 7) * 8 - 8*1)
+#define CVMX_FPA_INT_ENB (CVMX_ADD_IO_SEG(0x0001180028000048ull))
+#define CVMX_FPA_INT_SUM (CVMX_ADD_IO_SEG(0x0001180028000040ull))
+#define CVMX_FPA_PACKET_THRESHOLD (CVMX_ADD_IO_SEG(0x0001180028000460ull))
+#define CVMX_FPA_POOLX_END_ADDR(offset) (CVMX_ADD_IO_SEG(0x0001180028000358ull) + ((offset) & 15) * 8)
+#define CVMX_FPA_POOLX_START_ADDR(offset) (CVMX_ADD_IO_SEG(0x0001180028000258ull) + ((offset) & 15) * 8)
+#define CVMX_FPA_POOLX_THRESHOLD(offset) (CVMX_ADD_IO_SEG(0x0001180028000140ull) + ((offset) & 15) * 8)
+#define CVMX_FPA_QUE0_PAGE_INDEX CVMX_FPA_QUEX_PAGE_INDEX(0)
+#define CVMX_FPA_QUE1_PAGE_INDEX CVMX_FPA_QUEX_PAGE_INDEX(1)
+#define CVMX_FPA_QUE2_PAGE_INDEX CVMX_FPA_QUEX_PAGE_INDEX(2)
+#define CVMX_FPA_QUE3_PAGE_INDEX CVMX_FPA_QUEX_PAGE_INDEX(3)
+#define CVMX_FPA_QUE4_PAGE_INDEX CVMX_FPA_QUEX_PAGE_INDEX(4)
+#define CVMX_FPA_QUE5_PAGE_INDEX CVMX_FPA_QUEX_PAGE_INDEX(5)
+#define CVMX_FPA_QUE6_PAGE_INDEX CVMX_FPA_QUEX_PAGE_INDEX(6)
+#define CVMX_FPA_QUE7_PAGE_INDEX CVMX_FPA_QUEX_PAGE_INDEX(7)
+#define CVMX_FPA_QUE8_PAGE_INDEX (CVMX_ADD_IO_SEG(0x0001180028000250ull))
+#define CVMX_FPA_QUEX_AVAILABLE(offset) (CVMX_ADD_IO_SEG(0x0001180028000098ull) + ((offset) & 15) * 8)
+#define CVMX_FPA_QUEX_PAGE_INDEX(offset) (CVMX_ADD_IO_SEG(0x00011800280000F0ull) + ((offset) & 7) * 8)
+#define CVMX_FPA_QUE_ACT (CVMX_ADD_IO_SEG(0x0001180028000138ull))
+#define CVMX_FPA_QUE_EXP (CVMX_ADD_IO_SEG(0x0001180028000130ull))
+#define CVMX_FPA_WART_CTL (CVMX_ADD_IO_SEG(0x00011800280000D8ull))
+#define CVMX_FPA_WART_STATUS (CVMX_ADD_IO_SEG(0x00011800280000E0ull))
+#define CVMX_FPA_WQE_THRESHOLD (CVMX_ADD_IO_SEG(0x0001180028000468ull))
+
+union cvmx_fpa_addr_range_error {
+	uint64_t u64;
+	struct cvmx_fpa_addr_range_error_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_38_63:26;
+		uint64_t pool:5;
+		uint64_t addr:33;
+#else
+		uint64_t addr:33;
+		uint64_t pool:5;
+		uint64_t reserved_38_63:26;
+#endif
+	} s;
+	struct cvmx_fpa_addr_range_error_s cn61xx;
+	struct cvmx_fpa_addr_range_error_s cn66xx;
+	struct cvmx_fpa_addr_range_error_s cn68xx;
+	struct cvmx_fpa_addr_range_error_s cn68xxp1;
+	struct cvmx_fpa_addr_range_error_s cnf71xx;
+};
 
 union cvmx_fpa_bist_status {
 	uint64_t u64;
 	struct cvmx_fpa_bist_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t frd:1;
 		uint64_t fpf0:1;
 		uint64_t fpf1:1;
 		uint64_t ffr:1;
 		uint64_t fdr:1;
+#else
+		uint64_t fdr:1;
+		uint64_t ffr:1;
+		uint64_t fpf1:1;
+		uint64_t fpf0:1;
+		uint64_t frd:1;
+		uint64_t reserved_5_63:59;
+#endif
 	} s;
 	struct cvmx_fpa_bist_status_s cn30xx;
 	struct cvmx_fpa_bist_status_s cn31xx;
@@ -108,11 +117,44 @@
 	struct cvmx_fpa_bist_status_s cn56xxp1;
 	struct cvmx_fpa_bist_status_s cn58xx;
 	struct cvmx_fpa_bist_status_s cn58xxp1;
+	struct cvmx_fpa_bist_status_s cn61xx;
+	struct cvmx_fpa_bist_status_s cn63xx;
+	struct cvmx_fpa_bist_status_s cn63xxp1;
+	struct cvmx_fpa_bist_status_s cn66xx;
+	struct cvmx_fpa_bist_status_s cn68xx;
+	struct cvmx_fpa_bist_status_s cn68xxp1;
+	struct cvmx_fpa_bist_status_s cnf71xx;
 };
 
 union cvmx_fpa_ctl_status {
 	uint64_t u64;
 	struct cvmx_fpa_ctl_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_21_63:43;
+		uint64_t free_en:1;
+		uint64_t ret_off:1;
+		uint64_t req_off:1;
+		uint64_t reset:1;
+		uint64_t use_ldt:1;
+		uint64_t use_stt:1;
+		uint64_t enb:1;
+		uint64_t mem1_err:7;
+		uint64_t mem0_err:7;
+#else
+		uint64_t mem0_err:7;
+		uint64_t mem1_err:7;
+		uint64_t enb:1;
+		uint64_t use_stt:1;
+		uint64_t use_ldt:1;
+		uint64_t reset:1;
+		uint64_t req_off:1;
+		uint64_t ret_off:1;
+		uint64_t free_en:1;
+		uint64_t reserved_21_63:43;
+#endif
+	} s;
+	struct cvmx_fpa_ctl_status_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_18_63:46;
 		uint64_t reset:1;
 		uint64_t use_ldt:1;
@@ -120,26 +162,47 @@
 		uint64_t enb:1;
 		uint64_t mem1_err:7;
 		uint64_t mem0_err:7;
-	} s;
-	struct cvmx_fpa_ctl_status_s cn30xx;
-	struct cvmx_fpa_ctl_status_s cn31xx;
-	struct cvmx_fpa_ctl_status_s cn38xx;
-	struct cvmx_fpa_ctl_status_s cn38xxp2;
-	struct cvmx_fpa_ctl_status_s cn50xx;
-	struct cvmx_fpa_ctl_status_s cn52xx;
-	struct cvmx_fpa_ctl_status_s cn52xxp1;
-	struct cvmx_fpa_ctl_status_s cn56xx;
-	struct cvmx_fpa_ctl_status_s cn56xxp1;
-	struct cvmx_fpa_ctl_status_s cn58xx;
-	struct cvmx_fpa_ctl_status_s cn58xxp1;
+#else
+		uint64_t mem0_err:7;
+		uint64_t mem1_err:7;
+		uint64_t enb:1;
+		uint64_t use_stt:1;
+		uint64_t use_ldt:1;
+		uint64_t reset:1;
+		uint64_t reserved_18_63:46;
+#endif
+	} cn30xx;
+	struct cvmx_fpa_ctl_status_cn30xx cn31xx;
+	struct cvmx_fpa_ctl_status_cn30xx cn38xx;
+	struct cvmx_fpa_ctl_status_cn30xx cn38xxp2;
+	struct cvmx_fpa_ctl_status_cn30xx cn50xx;
+	struct cvmx_fpa_ctl_status_cn30xx cn52xx;
+	struct cvmx_fpa_ctl_status_cn30xx cn52xxp1;
+	struct cvmx_fpa_ctl_status_cn30xx cn56xx;
+	struct cvmx_fpa_ctl_status_cn30xx cn56xxp1;
+	struct cvmx_fpa_ctl_status_cn30xx cn58xx;
+	struct cvmx_fpa_ctl_status_cn30xx cn58xxp1;
+	struct cvmx_fpa_ctl_status_s cn61xx;
+	struct cvmx_fpa_ctl_status_s cn63xx;
+	struct cvmx_fpa_ctl_status_cn30xx cn63xxp1;
+	struct cvmx_fpa_ctl_status_s cn66xx;
+	struct cvmx_fpa_ctl_status_s cn68xx;
+	struct cvmx_fpa_ctl_status_s cn68xxp1;
+	struct cvmx_fpa_ctl_status_s cnf71xx;
 };
 
 union cvmx_fpa_fpfx_marks {
 	uint64_t u64;
 	struct cvmx_fpa_fpfx_marks_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_22_63:42;
 		uint64_t fpf_wr:11;
 		uint64_t fpf_rd:11;
+#else
+		uint64_t fpf_rd:11;
+		uint64_t fpf_wr:11;
+		uint64_t reserved_22_63:42;
+#endif
 	} s;
 	struct cvmx_fpa_fpfx_marks_s cn38xx;
 	struct cvmx_fpa_fpfx_marks_s cn38xxp2;
@@ -147,13 +210,25 @@
 	struct cvmx_fpa_fpfx_marks_s cn56xxp1;
 	struct cvmx_fpa_fpfx_marks_s cn58xx;
 	struct cvmx_fpa_fpfx_marks_s cn58xxp1;
+	struct cvmx_fpa_fpfx_marks_s cn61xx;
+	struct cvmx_fpa_fpfx_marks_s cn63xx;
+	struct cvmx_fpa_fpfx_marks_s cn63xxp1;
+	struct cvmx_fpa_fpfx_marks_s cn66xx;
+	struct cvmx_fpa_fpfx_marks_s cn68xx;
+	struct cvmx_fpa_fpfx_marks_s cn68xxp1;
+	struct cvmx_fpa_fpfx_marks_s cnf71xx;
 };
 
 union cvmx_fpa_fpfx_size {
 	uint64_t u64;
 	struct cvmx_fpa_fpfx_size_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_11_63:53;
 		uint64_t fpf_siz:11;
+#else
+		uint64_t fpf_siz:11;
+		uint64_t reserved_11_63:53;
+#endif
 	} s;
 	struct cvmx_fpa_fpfx_size_s cn38xx;
 	struct cvmx_fpa_fpfx_size_s cn38xxp2;
@@ -161,14 +236,27 @@
 	struct cvmx_fpa_fpfx_size_s cn56xxp1;
 	struct cvmx_fpa_fpfx_size_s cn58xx;
 	struct cvmx_fpa_fpfx_size_s cn58xxp1;
+	struct cvmx_fpa_fpfx_size_s cn61xx;
+	struct cvmx_fpa_fpfx_size_s cn63xx;
+	struct cvmx_fpa_fpfx_size_s cn63xxp1;
+	struct cvmx_fpa_fpfx_size_s cn66xx;
+	struct cvmx_fpa_fpfx_size_s cn68xx;
+	struct cvmx_fpa_fpfx_size_s cn68xxp1;
+	struct cvmx_fpa_fpfx_size_s cnf71xx;
 };
 
 union cvmx_fpa_fpf0_marks {
 	uint64_t u64;
 	struct cvmx_fpa_fpf0_marks_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_24_63:40;
 		uint64_t fpf_wr:12;
 		uint64_t fpf_rd:12;
+#else
+		uint64_t fpf_rd:12;
+		uint64_t fpf_wr:12;
+		uint64_t reserved_24_63:40;
+#endif
 	} s;
 	struct cvmx_fpa_fpf0_marks_s cn38xx;
 	struct cvmx_fpa_fpf0_marks_s cn38xxp2;
@@ -176,13 +264,25 @@
 	struct cvmx_fpa_fpf0_marks_s cn56xxp1;
 	struct cvmx_fpa_fpf0_marks_s cn58xx;
 	struct cvmx_fpa_fpf0_marks_s cn58xxp1;
+	struct cvmx_fpa_fpf0_marks_s cn61xx;
+	struct cvmx_fpa_fpf0_marks_s cn63xx;
+	struct cvmx_fpa_fpf0_marks_s cn63xxp1;
+	struct cvmx_fpa_fpf0_marks_s cn66xx;
+	struct cvmx_fpa_fpf0_marks_s cn68xx;
+	struct cvmx_fpa_fpf0_marks_s cn68xxp1;
+	struct cvmx_fpa_fpf0_marks_s cnf71xx;
 };
 
 union cvmx_fpa_fpf0_size {
 	uint64_t u64;
 	struct cvmx_fpa_fpf0_size_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t fpf_siz:12;
+#else
+		uint64_t fpf_siz:12;
+		uint64_t reserved_12_63:52;
+#endif
 	} s;
 	struct cvmx_fpa_fpf0_size_s cn38xx;
 	struct cvmx_fpa_fpf0_size_s cn38xxp2;
@@ -190,11 +290,150 @@
 	struct cvmx_fpa_fpf0_size_s cn56xxp1;
 	struct cvmx_fpa_fpf0_size_s cn58xx;
 	struct cvmx_fpa_fpf0_size_s cn58xxp1;
+	struct cvmx_fpa_fpf0_size_s cn61xx;
+	struct cvmx_fpa_fpf0_size_s cn63xx;
+	struct cvmx_fpa_fpf0_size_s cn63xxp1;
+	struct cvmx_fpa_fpf0_size_s cn66xx;
+	struct cvmx_fpa_fpf0_size_s cn68xx;
+	struct cvmx_fpa_fpf0_size_s cn68xxp1;
+	struct cvmx_fpa_fpf0_size_s cnf71xx;
+};
+
+union cvmx_fpa_fpf8_marks {
+	uint64_t u64;
+	struct cvmx_fpa_fpf8_marks_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_22_63:42;
+		uint64_t fpf_wr:11;
+		uint64_t fpf_rd:11;
+#else
+		uint64_t fpf_rd:11;
+		uint64_t fpf_wr:11;
+		uint64_t reserved_22_63:42;
+#endif
+	} s;
+	struct cvmx_fpa_fpf8_marks_s cn68xx;
+	struct cvmx_fpa_fpf8_marks_s cn68xxp1;
+};
+
+union cvmx_fpa_fpf8_size {
+	uint64_t u64;
+	struct cvmx_fpa_fpf8_size_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_12_63:52;
+		uint64_t fpf_siz:12;
+#else
+		uint64_t fpf_siz:12;
+		uint64_t reserved_12_63:52;
+#endif
+	} s;
+	struct cvmx_fpa_fpf8_size_s cn68xx;
+	struct cvmx_fpa_fpf8_size_s cn68xxp1;
 };
 
 union cvmx_fpa_int_enb {
 	uint64_t u64;
 	struct cvmx_fpa_int_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_50_63:14;
+		uint64_t paddr_e:1;
+		uint64_t reserved_44_48:5;
+		uint64_t free7:1;
+		uint64_t free6:1;
+		uint64_t free5:1;
+		uint64_t free4:1;
+		uint64_t free3:1;
+		uint64_t free2:1;
+		uint64_t free1:1;
+		uint64_t free0:1;
+		uint64_t pool7th:1;
+		uint64_t pool6th:1;
+		uint64_t pool5th:1;
+		uint64_t pool4th:1;
+		uint64_t pool3th:1;
+		uint64_t pool2th:1;
+		uint64_t pool1th:1;
+		uint64_t pool0th:1;
+		uint64_t q7_perr:1;
+		uint64_t q7_coff:1;
+		uint64_t q7_und:1;
+		uint64_t q6_perr:1;
+		uint64_t q6_coff:1;
+		uint64_t q6_und:1;
+		uint64_t q5_perr:1;
+		uint64_t q5_coff:1;
+		uint64_t q5_und:1;
+		uint64_t q4_perr:1;
+		uint64_t q4_coff:1;
+		uint64_t q4_und:1;
+		uint64_t q3_perr:1;
+		uint64_t q3_coff:1;
+		uint64_t q3_und:1;
+		uint64_t q2_perr:1;
+		uint64_t q2_coff:1;
+		uint64_t q2_und:1;
+		uint64_t q1_perr:1;
+		uint64_t q1_coff:1;
+		uint64_t q1_und:1;
+		uint64_t q0_perr:1;
+		uint64_t q0_coff:1;
+		uint64_t q0_und:1;
+		uint64_t fed1_dbe:1;
+		uint64_t fed1_sbe:1;
+		uint64_t fed0_dbe:1;
+		uint64_t fed0_sbe:1;
+#else
+		uint64_t fed0_sbe:1;
+		uint64_t fed0_dbe:1;
+		uint64_t fed1_sbe:1;
+		uint64_t fed1_dbe:1;
+		uint64_t q0_und:1;
+		uint64_t q0_coff:1;
+		uint64_t q0_perr:1;
+		uint64_t q1_und:1;
+		uint64_t q1_coff:1;
+		uint64_t q1_perr:1;
+		uint64_t q2_und:1;
+		uint64_t q2_coff:1;
+		uint64_t q2_perr:1;
+		uint64_t q3_und:1;
+		uint64_t q3_coff:1;
+		uint64_t q3_perr:1;
+		uint64_t q4_und:1;
+		uint64_t q4_coff:1;
+		uint64_t q4_perr:1;
+		uint64_t q5_und:1;
+		uint64_t q5_coff:1;
+		uint64_t q5_perr:1;
+		uint64_t q6_und:1;
+		uint64_t q6_coff:1;
+		uint64_t q6_perr:1;
+		uint64_t q7_und:1;
+		uint64_t q7_coff:1;
+		uint64_t q7_perr:1;
+		uint64_t pool0th:1;
+		uint64_t pool1th:1;
+		uint64_t pool2th:1;
+		uint64_t pool3th:1;
+		uint64_t pool4th:1;
+		uint64_t pool5th:1;
+		uint64_t pool6th:1;
+		uint64_t pool7th:1;
+		uint64_t free0:1;
+		uint64_t free1:1;
+		uint64_t free2:1;
+		uint64_t free3:1;
+		uint64_t free4:1;
+		uint64_t free5:1;
+		uint64_t free6:1;
+		uint64_t free7:1;
+		uint64_t reserved_44_48:5;
+		uint64_t paddr_e:1;
+		uint64_t reserved_50_63:14;
+#endif
+	} s;
+	struct cvmx_fpa_int_enb_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_28_63:36;
 		uint64_t q7_perr:1;
 		uint64_t q7_coff:1;
@@ -224,23 +463,466 @@
 		uint64_t fed1_sbe:1;
 		uint64_t fed0_dbe:1;
 		uint64_t fed0_sbe:1;
-	} s;
-	struct cvmx_fpa_int_enb_s cn30xx;
-	struct cvmx_fpa_int_enb_s cn31xx;
-	struct cvmx_fpa_int_enb_s cn38xx;
-	struct cvmx_fpa_int_enb_s cn38xxp2;
-	struct cvmx_fpa_int_enb_s cn50xx;
-	struct cvmx_fpa_int_enb_s cn52xx;
-	struct cvmx_fpa_int_enb_s cn52xxp1;
-	struct cvmx_fpa_int_enb_s cn56xx;
-	struct cvmx_fpa_int_enb_s cn56xxp1;
-	struct cvmx_fpa_int_enb_s cn58xx;
-	struct cvmx_fpa_int_enb_s cn58xxp1;
+#else
+		uint64_t fed0_sbe:1;
+		uint64_t fed0_dbe:1;
+		uint64_t fed1_sbe:1;
+		uint64_t fed1_dbe:1;
+		uint64_t q0_und:1;
+		uint64_t q0_coff:1;
+		uint64_t q0_perr:1;
+		uint64_t q1_und:1;
+		uint64_t q1_coff:1;
+		uint64_t q1_perr:1;
+		uint64_t q2_und:1;
+		uint64_t q2_coff:1;
+		uint64_t q2_perr:1;
+		uint64_t q3_und:1;
+		uint64_t q3_coff:1;
+		uint64_t q3_perr:1;
+		uint64_t q4_und:1;
+		uint64_t q4_coff:1;
+		uint64_t q4_perr:1;
+		uint64_t q5_und:1;
+		uint64_t q5_coff:1;
+		uint64_t q5_perr:1;
+		uint64_t q6_und:1;
+		uint64_t q6_coff:1;
+		uint64_t q6_perr:1;
+		uint64_t q7_und:1;
+		uint64_t q7_coff:1;
+		uint64_t q7_perr:1;
+		uint64_t reserved_28_63:36;
+#endif
+	} cn30xx;
+	struct cvmx_fpa_int_enb_cn30xx cn31xx;
+	struct cvmx_fpa_int_enb_cn30xx cn38xx;
+	struct cvmx_fpa_int_enb_cn30xx cn38xxp2;
+	struct cvmx_fpa_int_enb_cn30xx cn50xx;
+	struct cvmx_fpa_int_enb_cn30xx cn52xx;
+	struct cvmx_fpa_int_enb_cn30xx cn52xxp1;
+	struct cvmx_fpa_int_enb_cn30xx cn56xx;
+	struct cvmx_fpa_int_enb_cn30xx cn56xxp1;
+	struct cvmx_fpa_int_enb_cn30xx cn58xx;
+	struct cvmx_fpa_int_enb_cn30xx cn58xxp1;
+	struct cvmx_fpa_int_enb_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_50_63:14;
+		uint64_t paddr_e:1;
+		uint64_t res_44:5;
+		uint64_t free7:1;
+		uint64_t free6:1;
+		uint64_t free5:1;
+		uint64_t free4:1;
+		uint64_t free3:1;
+		uint64_t free2:1;
+		uint64_t free1:1;
+		uint64_t free0:1;
+		uint64_t pool7th:1;
+		uint64_t pool6th:1;
+		uint64_t pool5th:1;
+		uint64_t pool4th:1;
+		uint64_t pool3th:1;
+		uint64_t pool2th:1;
+		uint64_t pool1th:1;
+		uint64_t pool0th:1;
+		uint64_t q7_perr:1;
+		uint64_t q7_coff:1;
+		uint64_t q7_und:1;
+		uint64_t q6_perr:1;
+		uint64_t q6_coff:1;
+		uint64_t q6_und:1;
+		uint64_t q5_perr:1;
+		uint64_t q5_coff:1;
+		uint64_t q5_und:1;
+		uint64_t q4_perr:1;
+		uint64_t q4_coff:1;
+		uint64_t q4_und:1;
+		uint64_t q3_perr:1;
+		uint64_t q3_coff:1;
+		uint64_t q3_und:1;
+		uint64_t q2_perr:1;
+		uint64_t q2_coff:1;
+		uint64_t q2_und:1;
+		uint64_t q1_perr:1;
+		uint64_t q1_coff:1;
+		uint64_t q1_und:1;
+		uint64_t q0_perr:1;
+		uint64_t q0_coff:1;
+		uint64_t q0_und:1;
+		uint64_t fed1_dbe:1;
+		uint64_t fed1_sbe:1;
+		uint64_t fed0_dbe:1;
+		uint64_t fed0_sbe:1;
+#else
+		uint64_t fed0_sbe:1;
+		uint64_t fed0_dbe:1;
+		uint64_t fed1_sbe:1;
+		uint64_t fed1_dbe:1;
+		uint64_t q0_und:1;
+		uint64_t q0_coff:1;
+		uint64_t q0_perr:1;
+		uint64_t q1_und:1;
+		uint64_t q1_coff:1;
+		uint64_t q1_perr:1;
+		uint64_t q2_und:1;
+		uint64_t q2_coff:1;
+		uint64_t q2_perr:1;
+		uint64_t q3_und:1;
+		uint64_t q3_coff:1;
+		uint64_t q3_perr:1;
+		uint64_t q4_und:1;
+		uint64_t q4_coff:1;
+		uint64_t q4_perr:1;
+		uint64_t q5_und:1;
+		uint64_t q5_coff:1;
+		uint64_t q5_perr:1;
+		uint64_t q6_und:1;
+		uint64_t q6_coff:1;
+		uint64_t q6_perr:1;
+		uint64_t q7_und:1;
+		uint64_t q7_coff:1;
+		uint64_t q7_perr:1;
+		uint64_t pool0th:1;
+		uint64_t pool1th:1;
+		uint64_t pool2th:1;
+		uint64_t pool3th:1;
+		uint64_t pool4th:1;
+		uint64_t pool5th:1;
+		uint64_t pool6th:1;
+		uint64_t pool7th:1;
+		uint64_t free0:1;
+		uint64_t free1:1;
+		uint64_t free2:1;
+		uint64_t free3:1;
+		uint64_t free4:1;
+		uint64_t free5:1;
+		uint64_t free6:1;
+		uint64_t free7:1;
+		uint64_t res_44:5;
+		uint64_t paddr_e:1;
+		uint64_t reserved_50_63:14;
+#endif
+	} cn61xx;
+	struct cvmx_fpa_int_enb_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_44_63:20;
+		uint64_t free7:1;
+		uint64_t free6:1;
+		uint64_t free5:1;
+		uint64_t free4:1;
+		uint64_t free3:1;
+		uint64_t free2:1;
+		uint64_t free1:1;
+		uint64_t free0:1;
+		uint64_t pool7th:1;
+		uint64_t pool6th:1;
+		uint64_t pool5th:1;
+		uint64_t pool4th:1;
+		uint64_t pool3th:1;
+		uint64_t pool2th:1;
+		uint64_t pool1th:1;
+		uint64_t pool0th:1;
+		uint64_t q7_perr:1;
+		uint64_t q7_coff:1;
+		uint64_t q7_und:1;
+		uint64_t q6_perr:1;
+		uint64_t q6_coff:1;
+		uint64_t q6_und:1;
+		uint64_t q5_perr:1;
+		uint64_t q5_coff:1;
+		uint64_t q5_und:1;
+		uint64_t q4_perr:1;
+		uint64_t q4_coff:1;
+		uint64_t q4_und:1;
+		uint64_t q3_perr:1;
+		uint64_t q3_coff:1;
+		uint64_t q3_und:1;
+		uint64_t q2_perr:1;
+		uint64_t q2_coff:1;
+		uint64_t q2_und:1;
+		uint64_t q1_perr:1;
+		uint64_t q1_coff:1;
+		uint64_t q1_und:1;
+		uint64_t q0_perr:1;
+		uint64_t q0_coff:1;
+		uint64_t q0_und:1;
+		uint64_t fed1_dbe:1;
+		uint64_t fed1_sbe:1;
+		uint64_t fed0_dbe:1;
+		uint64_t fed0_sbe:1;
+#else
+		uint64_t fed0_sbe:1;
+		uint64_t fed0_dbe:1;
+		uint64_t fed1_sbe:1;
+		uint64_t fed1_dbe:1;
+		uint64_t q0_und:1;
+		uint64_t q0_coff:1;
+		uint64_t q0_perr:1;
+		uint64_t q1_und:1;
+		uint64_t q1_coff:1;
+		uint64_t q1_perr:1;
+		uint64_t q2_und:1;
+		uint64_t q2_coff:1;
+		uint64_t q2_perr:1;
+		uint64_t q3_und:1;
+		uint64_t q3_coff:1;
+		uint64_t q3_perr:1;
+		uint64_t q4_und:1;
+		uint64_t q4_coff:1;
+		uint64_t q4_perr:1;
+		uint64_t q5_und:1;
+		uint64_t q5_coff:1;
+		uint64_t q5_perr:1;
+		uint64_t q6_und:1;
+		uint64_t q6_coff:1;
+		uint64_t q6_perr:1;
+		uint64_t q7_und:1;
+		uint64_t q7_coff:1;
+		uint64_t q7_perr:1;
+		uint64_t pool0th:1;
+		uint64_t pool1th:1;
+		uint64_t pool2th:1;
+		uint64_t pool3th:1;
+		uint64_t pool4th:1;
+		uint64_t pool5th:1;
+		uint64_t pool6th:1;
+		uint64_t pool7th:1;
+		uint64_t free0:1;
+		uint64_t free1:1;
+		uint64_t free2:1;
+		uint64_t free3:1;
+		uint64_t free4:1;
+		uint64_t free5:1;
+		uint64_t free6:1;
+		uint64_t free7:1;
+		uint64_t reserved_44_63:20;
+#endif
+	} cn63xx;
+	struct cvmx_fpa_int_enb_cn30xx cn63xxp1;
+	struct cvmx_fpa_int_enb_cn61xx cn66xx;
+	struct cvmx_fpa_int_enb_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_50_63:14;
+		uint64_t paddr_e:1;
+		uint64_t pool8th:1;
+		uint64_t q8_perr:1;
+		uint64_t q8_coff:1;
+		uint64_t q8_und:1;
+		uint64_t free8:1;
+		uint64_t free7:1;
+		uint64_t free6:1;
+		uint64_t free5:1;
+		uint64_t free4:1;
+		uint64_t free3:1;
+		uint64_t free2:1;
+		uint64_t free1:1;
+		uint64_t free0:1;
+		uint64_t pool7th:1;
+		uint64_t pool6th:1;
+		uint64_t pool5th:1;
+		uint64_t pool4th:1;
+		uint64_t pool3th:1;
+		uint64_t pool2th:1;
+		uint64_t pool1th:1;
+		uint64_t pool0th:1;
+		uint64_t q7_perr:1;
+		uint64_t q7_coff:1;
+		uint64_t q7_und:1;
+		uint64_t q6_perr:1;
+		uint64_t q6_coff:1;
+		uint64_t q6_und:1;
+		uint64_t q5_perr:1;
+		uint64_t q5_coff:1;
+		uint64_t q5_und:1;
+		uint64_t q4_perr:1;
+		uint64_t q4_coff:1;
+		uint64_t q4_und:1;
+		uint64_t q3_perr:1;
+		uint64_t q3_coff:1;
+		uint64_t q3_und:1;
+		uint64_t q2_perr:1;
+		uint64_t q2_coff:1;
+		uint64_t q2_und:1;
+		uint64_t q1_perr:1;
+		uint64_t q1_coff:1;
+		uint64_t q1_und:1;
+		uint64_t q0_perr:1;
+		uint64_t q0_coff:1;
+		uint64_t q0_und:1;
+		uint64_t fed1_dbe:1;
+		uint64_t fed1_sbe:1;
+		uint64_t fed0_dbe:1;
+		uint64_t fed0_sbe:1;
+#else
+		uint64_t fed0_sbe:1;
+		uint64_t fed0_dbe:1;
+		uint64_t fed1_sbe:1;
+		uint64_t fed1_dbe:1;
+		uint64_t q0_und:1;
+		uint64_t q0_coff:1;
+		uint64_t q0_perr:1;
+		uint64_t q1_und:1;
+		uint64_t q1_coff:1;
+		uint64_t q1_perr:1;
+		uint64_t q2_und:1;
+		uint64_t q2_coff:1;
+		uint64_t q2_perr:1;
+		uint64_t q3_und:1;
+		uint64_t q3_coff:1;
+		uint64_t q3_perr:1;
+		uint64_t q4_und:1;
+		uint64_t q4_coff:1;
+		uint64_t q4_perr:1;
+		uint64_t q5_und:1;
+		uint64_t q5_coff:1;
+		uint64_t q5_perr:1;
+		uint64_t q6_und:1;
+		uint64_t q6_coff:1;
+		uint64_t q6_perr:1;
+		uint64_t q7_und:1;
+		uint64_t q7_coff:1;
+		uint64_t q7_perr:1;
+		uint64_t pool0th:1;
+		uint64_t pool1th:1;
+		uint64_t pool2th:1;
+		uint64_t pool3th:1;
+		uint64_t pool4th:1;
+		uint64_t pool5th:1;
+		uint64_t pool6th:1;
+		uint64_t pool7th:1;
+		uint64_t free0:1;
+		uint64_t free1:1;
+		uint64_t free2:1;
+		uint64_t free3:1;
+		uint64_t free4:1;
+		uint64_t free5:1;
+		uint64_t free6:1;
+		uint64_t free7:1;
+		uint64_t free8:1;
+		uint64_t q8_und:1;
+		uint64_t q8_coff:1;
+		uint64_t q8_perr:1;
+		uint64_t pool8th:1;
+		uint64_t paddr_e:1;
+		uint64_t reserved_50_63:14;
+#endif
+	} cn68xx;
+	struct cvmx_fpa_int_enb_cn68xx cn68xxp1;
+	struct cvmx_fpa_int_enb_cn61xx cnf71xx;
 };
 
 union cvmx_fpa_int_sum {
 	uint64_t u64;
 	struct cvmx_fpa_int_sum_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_50_63:14;
+		uint64_t paddr_e:1;
+		uint64_t pool8th:1;
+		uint64_t q8_perr:1;
+		uint64_t q8_coff:1;
+		uint64_t q8_und:1;
+		uint64_t free8:1;
+		uint64_t free7:1;
+		uint64_t free6:1;
+		uint64_t free5:1;
+		uint64_t free4:1;
+		uint64_t free3:1;
+		uint64_t free2:1;
+		uint64_t free1:1;
+		uint64_t free0:1;
+		uint64_t pool7th:1;
+		uint64_t pool6th:1;
+		uint64_t pool5th:1;
+		uint64_t pool4th:1;
+		uint64_t pool3th:1;
+		uint64_t pool2th:1;
+		uint64_t pool1th:1;
+		uint64_t pool0th:1;
+		uint64_t q7_perr:1;
+		uint64_t q7_coff:1;
+		uint64_t q7_und:1;
+		uint64_t q6_perr:1;
+		uint64_t q6_coff:1;
+		uint64_t q6_und:1;
+		uint64_t q5_perr:1;
+		uint64_t q5_coff:1;
+		uint64_t q5_und:1;
+		uint64_t q4_perr:1;
+		uint64_t q4_coff:1;
+		uint64_t q4_und:1;
+		uint64_t q3_perr:1;
+		uint64_t q3_coff:1;
+		uint64_t q3_und:1;
+		uint64_t q2_perr:1;
+		uint64_t q2_coff:1;
+		uint64_t q2_und:1;
+		uint64_t q1_perr:1;
+		uint64_t q1_coff:1;
+		uint64_t q1_und:1;
+		uint64_t q0_perr:1;
+		uint64_t q0_coff:1;
+		uint64_t q0_und:1;
+		uint64_t fed1_dbe:1;
+		uint64_t fed1_sbe:1;
+		uint64_t fed0_dbe:1;
+		uint64_t fed0_sbe:1;
+#else
+		uint64_t fed0_sbe:1;
+		uint64_t fed0_dbe:1;
+		uint64_t fed1_sbe:1;
+		uint64_t fed1_dbe:1;
+		uint64_t q0_und:1;
+		uint64_t q0_coff:1;
+		uint64_t q0_perr:1;
+		uint64_t q1_und:1;
+		uint64_t q1_coff:1;
+		uint64_t q1_perr:1;
+		uint64_t q2_und:1;
+		uint64_t q2_coff:1;
+		uint64_t q2_perr:1;
+		uint64_t q3_und:1;
+		uint64_t q3_coff:1;
+		uint64_t q3_perr:1;
+		uint64_t q4_und:1;
+		uint64_t q4_coff:1;
+		uint64_t q4_perr:1;
+		uint64_t q5_und:1;
+		uint64_t q5_coff:1;
+		uint64_t q5_perr:1;
+		uint64_t q6_und:1;
+		uint64_t q6_coff:1;
+		uint64_t q6_perr:1;
+		uint64_t q7_und:1;
+		uint64_t q7_coff:1;
+		uint64_t q7_perr:1;
+		uint64_t pool0th:1;
+		uint64_t pool1th:1;
+		uint64_t pool2th:1;
+		uint64_t pool3th:1;
+		uint64_t pool4th:1;
+		uint64_t pool5th:1;
+		uint64_t pool6th:1;
+		uint64_t pool7th:1;
+		uint64_t free0:1;
+		uint64_t free1:1;
+		uint64_t free2:1;
+		uint64_t free3:1;
+		uint64_t free4:1;
+		uint64_t free5:1;
+		uint64_t free6:1;
+		uint64_t free7:1;
+		uint64_t free8:1;
+		uint64_t q8_und:1;
+		uint64_t q8_coff:1;
+		uint64_t q8_perr:1;
+		uint64_t pool8th:1;
+		uint64_t paddr_e:1;
+		uint64_t reserved_50_63:14;
+#endif
+	} s;
+	struct cvmx_fpa_int_sum_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_28_63:36;
 		uint64_t q7_perr:1;
 		uint64_t q7_coff:1;
@@ -270,44 +952,380 @@
 		uint64_t fed1_sbe:1;
 		uint64_t fed0_dbe:1;
 		uint64_t fed0_sbe:1;
+#else
+		uint64_t fed0_sbe:1;
+		uint64_t fed0_dbe:1;
+		uint64_t fed1_sbe:1;
+		uint64_t fed1_dbe:1;
+		uint64_t q0_und:1;
+		uint64_t q0_coff:1;
+		uint64_t q0_perr:1;
+		uint64_t q1_und:1;
+		uint64_t q1_coff:1;
+		uint64_t q1_perr:1;
+		uint64_t q2_und:1;
+		uint64_t q2_coff:1;
+		uint64_t q2_perr:1;
+		uint64_t q3_und:1;
+		uint64_t q3_coff:1;
+		uint64_t q3_perr:1;
+		uint64_t q4_und:1;
+		uint64_t q4_coff:1;
+		uint64_t q4_perr:1;
+		uint64_t q5_und:1;
+		uint64_t q5_coff:1;
+		uint64_t q5_perr:1;
+		uint64_t q6_und:1;
+		uint64_t q6_coff:1;
+		uint64_t q6_perr:1;
+		uint64_t q7_und:1;
+		uint64_t q7_coff:1;
+		uint64_t q7_perr:1;
+		uint64_t reserved_28_63:36;
+#endif
+	} cn30xx;
+	struct cvmx_fpa_int_sum_cn30xx cn31xx;
+	struct cvmx_fpa_int_sum_cn30xx cn38xx;
+	struct cvmx_fpa_int_sum_cn30xx cn38xxp2;
+	struct cvmx_fpa_int_sum_cn30xx cn50xx;
+	struct cvmx_fpa_int_sum_cn30xx cn52xx;
+	struct cvmx_fpa_int_sum_cn30xx cn52xxp1;
+	struct cvmx_fpa_int_sum_cn30xx cn56xx;
+	struct cvmx_fpa_int_sum_cn30xx cn56xxp1;
+	struct cvmx_fpa_int_sum_cn30xx cn58xx;
+	struct cvmx_fpa_int_sum_cn30xx cn58xxp1;
+	struct cvmx_fpa_int_sum_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_50_63:14;
+		uint64_t paddr_e:1;
+		uint64_t reserved_44_48:5;
+		uint64_t free7:1;
+		uint64_t free6:1;
+		uint64_t free5:1;
+		uint64_t free4:1;
+		uint64_t free3:1;
+		uint64_t free2:1;
+		uint64_t free1:1;
+		uint64_t free0:1;
+		uint64_t pool7th:1;
+		uint64_t pool6th:1;
+		uint64_t pool5th:1;
+		uint64_t pool4th:1;
+		uint64_t pool3th:1;
+		uint64_t pool2th:1;
+		uint64_t pool1th:1;
+		uint64_t pool0th:1;
+		uint64_t q7_perr:1;
+		uint64_t q7_coff:1;
+		uint64_t q7_und:1;
+		uint64_t q6_perr:1;
+		uint64_t q6_coff:1;
+		uint64_t q6_und:1;
+		uint64_t q5_perr:1;
+		uint64_t q5_coff:1;
+		uint64_t q5_und:1;
+		uint64_t q4_perr:1;
+		uint64_t q4_coff:1;
+		uint64_t q4_und:1;
+		uint64_t q3_perr:1;
+		uint64_t q3_coff:1;
+		uint64_t q3_und:1;
+		uint64_t q2_perr:1;
+		uint64_t q2_coff:1;
+		uint64_t q2_und:1;
+		uint64_t q1_perr:1;
+		uint64_t q1_coff:1;
+		uint64_t q1_und:1;
+		uint64_t q0_perr:1;
+		uint64_t q0_coff:1;
+		uint64_t q0_und:1;
+		uint64_t fed1_dbe:1;
+		uint64_t fed1_sbe:1;
+		uint64_t fed0_dbe:1;
+		uint64_t fed0_sbe:1;
+#else
+		uint64_t fed0_sbe:1;
+		uint64_t fed0_dbe:1;
+		uint64_t fed1_sbe:1;
+		uint64_t fed1_dbe:1;
+		uint64_t q0_und:1;
+		uint64_t q0_coff:1;
+		uint64_t q0_perr:1;
+		uint64_t q1_und:1;
+		uint64_t q1_coff:1;
+		uint64_t q1_perr:1;
+		uint64_t q2_und:1;
+		uint64_t q2_coff:1;
+		uint64_t q2_perr:1;
+		uint64_t q3_und:1;
+		uint64_t q3_coff:1;
+		uint64_t q3_perr:1;
+		uint64_t q4_und:1;
+		uint64_t q4_coff:1;
+		uint64_t q4_perr:1;
+		uint64_t q5_und:1;
+		uint64_t q5_coff:1;
+		uint64_t q5_perr:1;
+		uint64_t q6_und:1;
+		uint64_t q6_coff:1;
+		uint64_t q6_perr:1;
+		uint64_t q7_und:1;
+		uint64_t q7_coff:1;
+		uint64_t q7_perr:1;
+		uint64_t pool0th:1;
+		uint64_t pool1th:1;
+		uint64_t pool2th:1;
+		uint64_t pool3th:1;
+		uint64_t pool4th:1;
+		uint64_t pool5th:1;
+		uint64_t pool6th:1;
+		uint64_t pool7th:1;
+		uint64_t free0:1;
+		uint64_t free1:1;
+		uint64_t free2:1;
+		uint64_t free3:1;
+		uint64_t free4:1;
+		uint64_t free5:1;
+		uint64_t free6:1;
+		uint64_t free7:1;
+		uint64_t reserved_44_48:5;
+		uint64_t paddr_e:1;
+		uint64_t reserved_50_63:14;
+#endif
+	} cn61xx;
+	struct cvmx_fpa_int_sum_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_44_63:20;
+		uint64_t free7:1;
+		uint64_t free6:1;
+		uint64_t free5:1;
+		uint64_t free4:1;
+		uint64_t free3:1;
+		uint64_t free2:1;
+		uint64_t free1:1;
+		uint64_t free0:1;
+		uint64_t pool7th:1;
+		uint64_t pool6th:1;
+		uint64_t pool5th:1;
+		uint64_t pool4th:1;
+		uint64_t pool3th:1;
+		uint64_t pool2th:1;
+		uint64_t pool1th:1;
+		uint64_t pool0th:1;
+		uint64_t q7_perr:1;
+		uint64_t q7_coff:1;
+		uint64_t q7_und:1;
+		uint64_t q6_perr:1;
+		uint64_t q6_coff:1;
+		uint64_t q6_und:1;
+		uint64_t q5_perr:1;
+		uint64_t q5_coff:1;
+		uint64_t q5_und:1;
+		uint64_t q4_perr:1;
+		uint64_t q4_coff:1;
+		uint64_t q4_und:1;
+		uint64_t q3_perr:1;
+		uint64_t q3_coff:1;
+		uint64_t q3_und:1;
+		uint64_t q2_perr:1;
+		uint64_t q2_coff:1;
+		uint64_t q2_und:1;
+		uint64_t q1_perr:1;
+		uint64_t q1_coff:1;
+		uint64_t q1_und:1;
+		uint64_t q0_perr:1;
+		uint64_t q0_coff:1;
+		uint64_t q0_und:1;
+		uint64_t fed1_dbe:1;
+		uint64_t fed1_sbe:1;
+		uint64_t fed0_dbe:1;
+		uint64_t fed0_sbe:1;
+#else
+		uint64_t fed0_sbe:1;
+		uint64_t fed0_dbe:1;
+		uint64_t fed1_sbe:1;
+		uint64_t fed1_dbe:1;
+		uint64_t q0_und:1;
+		uint64_t q0_coff:1;
+		uint64_t q0_perr:1;
+		uint64_t q1_und:1;
+		uint64_t q1_coff:1;
+		uint64_t q1_perr:1;
+		uint64_t q2_und:1;
+		uint64_t q2_coff:1;
+		uint64_t q2_perr:1;
+		uint64_t q3_und:1;
+		uint64_t q3_coff:1;
+		uint64_t q3_perr:1;
+		uint64_t q4_und:1;
+		uint64_t q4_coff:1;
+		uint64_t q4_perr:1;
+		uint64_t q5_und:1;
+		uint64_t q5_coff:1;
+		uint64_t q5_perr:1;
+		uint64_t q6_und:1;
+		uint64_t q6_coff:1;
+		uint64_t q6_perr:1;
+		uint64_t q7_und:1;
+		uint64_t q7_coff:1;
+		uint64_t q7_perr:1;
+		uint64_t pool0th:1;
+		uint64_t pool1th:1;
+		uint64_t pool2th:1;
+		uint64_t pool3th:1;
+		uint64_t pool4th:1;
+		uint64_t pool5th:1;
+		uint64_t pool6th:1;
+		uint64_t pool7th:1;
+		uint64_t free0:1;
+		uint64_t free1:1;
+		uint64_t free2:1;
+		uint64_t free3:1;
+		uint64_t free4:1;
+		uint64_t free5:1;
+		uint64_t free6:1;
+		uint64_t free7:1;
+		uint64_t reserved_44_63:20;
+#endif
+	} cn63xx;
+	struct cvmx_fpa_int_sum_cn30xx cn63xxp1;
+	struct cvmx_fpa_int_sum_cn61xx cn66xx;
+	struct cvmx_fpa_int_sum_s cn68xx;
+	struct cvmx_fpa_int_sum_s cn68xxp1;
+	struct cvmx_fpa_int_sum_cn61xx cnf71xx;
+};
+
+union cvmx_fpa_packet_threshold {
+	uint64_t u64;
+	struct cvmx_fpa_packet_threshold_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t thresh:32;
+#else
+		uint64_t thresh:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
-	struct cvmx_fpa_int_sum_s cn30xx;
-	struct cvmx_fpa_int_sum_s cn31xx;
-	struct cvmx_fpa_int_sum_s cn38xx;
-	struct cvmx_fpa_int_sum_s cn38xxp2;
-	struct cvmx_fpa_int_sum_s cn50xx;
-	struct cvmx_fpa_int_sum_s cn52xx;
-	struct cvmx_fpa_int_sum_s cn52xxp1;
-	struct cvmx_fpa_int_sum_s cn56xx;
-	struct cvmx_fpa_int_sum_s cn56xxp1;
-	struct cvmx_fpa_int_sum_s cn58xx;
-	struct cvmx_fpa_int_sum_s cn58xxp1;
+	struct cvmx_fpa_packet_threshold_s cn61xx;
+	struct cvmx_fpa_packet_threshold_s cn63xx;
+	struct cvmx_fpa_packet_threshold_s cn66xx;
+	struct cvmx_fpa_packet_threshold_s cn68xx;
+	struct cvmx_fpa_packet_threshold_s cn68xxp1;
+	struct cvmx_fpa_packet_threshold_s cnf71xx;
+};
+
+union cvmx_fpa_poolx_end_addr {
+	uint64_t u64;
+	struct cvmx_fpa_poolx_end_addr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_33_63:31;
+		uint64_t addr:33;
+#else
+		uint64_t addr:33;
+		uint64_t reserved_33_63:31;
+#endif
+	} s;
+	struct cvmx_fpa_poolx_end_addr_s cn61xx;
+	struct cvmx_fpa_poolx_end_addr_s cn66xx;
+	struct cvmx_fpa_poolx_end_addr_s cn68xx;
+	struct cvmx_fpa_poolx_end_addr_s cn68xxp1;
+	struct cvmx_fpa_poolx_end_addr_s cnf71xx;
+};
+
+union cvmx_fpa_poolx_start_addr {
+	uint64_t u64;
+	struct cvmx_fpa_poolx_start_addr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_33_63:31;
+		uint64_t addr:33;
+#else
+		uint64_t addr:33;
+		uint64_t reserved_33_63:31;
+#endif
+	} s;
+	struct cvmx_fpa_poolx_start_addr_s cn61xx;
+	struct cvmx_fpa_poolx_start_addr_s cn66xx;
+	struct cvmx_fpa_poolx_start_addr_s cn68xx;
+	struct cvmx_fpa_poolx_start_addr_s cn68xxp1;
+	struct cvmx_fpa_poolx_start_addr_s cnf71xx;
+};
+
+union cvmx_fpa_poolx_threshold {
+	uint64_t u64;
+	struct cvmx_fpa_poolx_threshold_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t thresh:32;
+#else
+		uint64_t thresh:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_fpa_poolx_threshold_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_29_63:35;
+		uint64_t thresh:29;
+#else
+		uint64_t thresh:29;
+		uint64_t reserved_29_63:35;
+#endif
+	} cn61xx;
+	struct cvmx_fpa_poolx_threshold_cn61xx cn63xx;
+	struct cvmx_fpa_poolx_threshold_cn61xx cn66xx;
+	struct cvmx_fpa_poolx_threshold_s cn68xx;
+	struct cvmx_fpa_poolx_threshold_s cn68xxp1;
+	struct cvmx_fpa_poolx_threshold_cn61xx cnf71xx;
 };
 
 union cvmx_fpa_quex_available {
 	uint64_t u64;
 	struct cvmx_fpa_quex_available_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t que_siz:32;
+#else
+		uint64_t que_siz:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_fpa_quex_available_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_29_63:35;
 		uint64_t que_siz:29;
-	} s;
-	struct cvmx_fpa_quex_available_s cn30xx;
-	struct cvmx_fpa_quex_available_s cn31xx;
-	struct cvmx_fpa_quex_available_s cn38xx;
-	struct cvmx_fpa_quex_available_s cn38xxp2;
-	struct cvmx_fpa_quex_available_s cn50xx;
-	struct cvmx_fpa_quex_available_s cn52xx;
-	struct cvmx_fpa_quex_available_s cn52xxp1;
-	struct cvmx_fpa_quex_available_s cn56xx;
-	struct cvmx_fpa_quex_available_s cn56xxp1;
-	struct cvmx_fpa_quex_available_s cn58xx;
-	struct cvmx_fpa_quex_available_s cn58xxp1;
+#else
+		uint64_t que_siz:29;
+		uint64_t reserved_29_63:35;
+#endif
+	} cn30xx;
+	struct cvmx_fpa_quex_available_cn30xx cn31xx;
+	struct cvmx_fpa_quex_available_cn30xx cn38xx;
+	struct cvmx_fpa_quex_available_cn30xx cn38xxp2;
+	struct cvmx_fpa_quex_available_cn30xx cn50xx;
+	struct cvmx_fpa_quex_available_cn30xx cn52xx;
+	struct cvmx_fpa_quex_available_cn30xx cn52xxp1;
+	struct cvmx_fpa_quex_available_cn30xx cn56xx;
+	struct cvmx_fpa_quex_available_cn30xx cn56xxp1;
+	struct cvmx_fpa_quex_available_cn30xx cn58xx;
+	struct cvmx_fpa_quex_available_cn30xx cn58xxp1;
+	struct cvmx_fpa_quex_available_cn30xx cn61xx;
+	struct cvmx_fpa_quex_available_cn30xx cn63xx;
+	struct cvmx_fpa_quex_available_cn30xx cn63xxp1;
+	struct cvmx_fpa_quex_available_cn30xx cn66xx;
+	struct cvmx_fpa_quex_available_s cn68xx;
+	struct cvmx_fpa_quex_available_s cn68xxp1;
+	struct cvmx_fpa_quex_available_cn30xx cnf71xx;
 };
 
 union cvmx_fpa_quex_page_index {
 	uint64_t u64;
 	struct cvmx_fpa_quex_page_index_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_25_63:39;
 		uint64_t pg_num:25;
+#else
+		uint64_t pg_num:25;
+		uint64_t reserved_25_63:39;
+#endif
 	} s;
 	struct cvmx_fpa_quex_page_index_s cn30xx;
 	struct cvmx_fpa_quex_page_index_s cn31xx;
@@ -320,14 +1338,42 @@
 	struct cvmx_fpa_quex_page_index_s cn56xxp1;
 	struct cvmx_fpa_quex_page_index_s cn58xx;
 	struct cvmx_fpa_quex_page_index_s cn58xxp1;
+	struct cvmx_fpa_quex_page_index_s cn61xx;
+	struct cvmx_fpa_quex_page_index_s cn63xx;
+	struct cvmx_fpa_quex_page_index_s cn63xxp1;
+	struct cvmx_fpa_quex_page_index_s cn66xx;
+	struct cvmx_fpa_quex_page_index_s cn68xx;
+	struct cvmx_fpa_quex_page_index_s cn68xxp1;
+	struct cvmx_fpa_quex_page_index_s cnf71xx;
+};
+
+union cvmx_fpa_que8_page_index {
+	uint64_t u64;
+	struct cvmx_fpa_que8_page_index_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_25_63:39;
+		uint64_t pg_num:25;
+#else
+		uint64_t pg_num:25;
+		uint64_t reserved_25_63:39;
+#endif
+	} s;
+	struct cvmx_fpa_que8_page_index_s cn68xx;
+	struct cvmx_fpa_que8_page_index_s cn68xxp1;
 };
 
 union cvmx_fpa_que_act {
 	uint64_t u64;
 	struct cvmx_fpa_que_act_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_29_63:35;
 		uint64_t act_que:3;
 		uint64_t act_indx:26;
+#else
+		uint64_t act_indx:26;
+		uint64_t act_que:3;
+		uint64_t reserved_29_63:35;
+#endif
 	} s;
 	struct cvmx_fpa_que_act_s cn30xx;
 	struct cvmx_fpa_que_act_s cn31xx;
@@ -340,14 +1386,27 @@
 	struct cvmx_fpa_que_act_s cn56xxp1;
 	struct cvmx_fpa_que_act_s cn58xx;
 	struct cvmx_fpa_que_act_s cn58xxp1;
+	struct cvmx_fpa_que_act_s cn61xx;
+	struct cvmx_fpa_que_act_s cn63xx;
+	struct cvmx_fpa_que_act_s cn63xxp1;
+	struct cvmx_fpa_que_act_s cn66xx;
+	struct cvmx_fpa_que_act_s cn68xx;
+	struct cvmx_fpa_que_act_s cn68xxp1;
+	struct cvmx_fpa_que_act_s cnf71xx;
 };
 
 union cvmx_fpa_que_exp {
 	uint64_t u64;
 	struct cvmx_fpa_que_exp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_29_63:35;
 		uint64_t exp_que:3;
 		uint64_t exp_indx:26;
+#else
+		uint64_t exp_indx:26;
+		uint64_t exp_que:3;
+		uint64_t reserved_29_63:35;
+#endif
 	} s;
 	struct cvmx_fpa_que_exp_s cn30xx;
 	struct cvmx_fpa_que_exp_s cn31xx;
@@ -360,13 +1419,25 @@
 	struct cvmx_fpa_que_exp_s cn56xxp1;
 	struct cvmx_fpa_que_exp_s cn58xx;
 	struct cvmx_fpa_que_exp_s cn58xxp1;
+	struct cvmx_fpa_que_exp_s cn61xx;
+	struct cvmx_fpa_que_exp_s cn63xx;
+	struct cvmx_fpa_que_exp_s cn63xxp1;
+	struct cvmx_fpa_que_exp_s cn66xx;
+	struct cvmx_fpa_que_exp_s cn68xx;
+	struct cvmx_fpa_que_exp_s cn68xxp1;
+	struct cvmx_fpa_que_exp_s cnf71xx;
 };
 
 union cvmx_fpa_wart_ctl {
 	uint64_t u64;
 	struct cvmx_fpa_wart_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t ctl:16;
+#else
+		uint64_t ctl:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_fpa_wart_ctl_s cn30xx;
 	struct cvmx_fpa_wart_ctl_s cn31xx;
@@ -384,8 +1455,13 @@
 union cvmx_fpa_wart_status {
 	uint64_t u64;
 	struct cvmx_fpa_wart_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t status:32;
+#else
+		uint64_t status:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_fpa_wart_status_s cn30xx;
 	struct cvmx_fpa_wart_status_s cn31xx;
@@ -400,4 +1476,23 @@
 	struct cvmx_fpa_wart_status_s cn58xxp1;
 };
 
+union cvmx_fpa_wqe_threshold {
+	uint64_t u64;
+	struct cvmx_fpa_wqe_threshold_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t thresh:32;
+#else
+		uint64_t thresh:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_fpa_wqe_threshold_s cn61xx;
+	struct cvmx_fpa_wqe_threshold_s cn63xx;
+	struct cvmx_fpa_wqe_threshold_s cn66xx;
+	struct cvmx_fpa_wqe_threshold_s cn68xx;
+	struct cvmx_fpa_wqe_threshold_s cn68xxp1;
+	struct cvmx_fpa_wqe_threshold_s cnf71xx;
+};
+
 #endif
diff --git a/arch/mips/include/asm/octeon/cvmx-gmxx-defs.h b/arch/mips/include/asm/octeon/cvmx-gmxx-defs.h
index 946a43a..e347496 100644
--- a/arch/mips/include/asm/octeon/cvmx-gmxx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-gmxx-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -28,208 +28,2052 @@
 #ifndef __CVMX_GMXX_DEFS_H__
 #define __CVMX_GMXX_DEFS_H__
 
-#define CVMX_GMXX_BAD_REG(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000518ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_BIST(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000400ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_CLK_EN(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080007F0ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_HG2_CONTROL(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000550ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_INF_MODE(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080007F8ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_NXA_ADR(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000510ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_PRTX_CBFC_CTL(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000580ull + (((offset) & 0) * 8) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_PRTX_CFG(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000010ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_ADR_CAM0(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000180ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_ADR_CAM1(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000188ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_ADR_CAM2(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000190ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_ADR_CAM3(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000198ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_ADR_CAM4(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080001A0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_ADR_CAM5(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080001A8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_ADR_CAM_EN(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000108ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_ADR_CTL(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000100ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_DECISION(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000040ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_FRM_CHK(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000020ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_FRM_CTL(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000018ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_FRM_MAX(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000030ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_FRM_MIN(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000028ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_IFG(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000058ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_INT_EN(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000008ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_INT_REG(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000000ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_JABBER(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000038ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_PAUSE_DROP_TIME(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000068ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_RX_INBND(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000060ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_STATS_CTL(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000050ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_STATS_OCTS(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000088ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_STATS_OCTS_CTL(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000098ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_STATS_OCTS_DMAC(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080000A8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_STATS_OCTS_DRP(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080000B8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_STATS_PKTS(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000080ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_STATS_PKTS_BAD(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080000C0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_STATS_PKTS_CTL(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000090ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_STATS_PKTS_DMAC(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080000A0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_STATS_PKTS_DRP(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080000B0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RXX_UDD_SKP(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000048ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RX_BP_DROPX(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000420ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RX_BP_OFFX(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000460ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RX_BP_ONX(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000440ull + (((offset) & 3) * 8) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RX_HG2_STATUS(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000548ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RX_PASS_EN(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080005F8ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RX_PASS_MAPX(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000600ull + (((offset) & 15) * 8) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RX_PRTS(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000410ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RX_PRT_INFO(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080004E8ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RX_TX_STATUS(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080007E8ull + (((block_id) & 0) * 0x8000000ull))
-#define CVMX_GMXX_RX_XAUI_BAD_COL(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000538ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_RX_XAUI_CTL(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000530ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_SMACX(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000230ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_STAT_BP(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000520ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_APPEND(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000218ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_BURST(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000228ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_CBFC_XOFF(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080005A0ull + (((offset) & 0) * 8) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_CBFC_XON(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080005C0ull + (((offset) & 0) * 8) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_CLK(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000208ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_CTL(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000270ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_MIN_PKT(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000240ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_PAUSE_PKT_INTERVAL(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000248ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_PAUSE_PKT_TIME(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000238ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_PAUSE_TOGO(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000258ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_PAUSE_ZERO(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000260ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_SGMII_CTL(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000300ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_SLOT(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000220ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_SOFT_PAUSE(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000250ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_STAT0(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000280ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_STAT1(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000288ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_STAT2(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000290ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_STAT3(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000298ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_STAT4(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080002A0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_STAT5(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080002A8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_STAT6(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080002B0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_STAT7(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080002B8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_STAT8(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080002C0ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_STAT9(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080002C8ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_STATS_CTL(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000268ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TXX_THRESH(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000210ull + (((offset) & 3) * 2048) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_BP(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080004D0ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_CLK_MSKX(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000780ull + (((offset) & 1) * 8) + (((block_id) & 0) * 0x0ull))
-#define CVMX_GMXX_TX_COL_ATTEMPT(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000498ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_CORRUPT(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080004D8ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_HG2_REG1(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000558ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_HG2_REG2(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000560ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_IFG(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000488ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_INT_EN(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000508ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_INT_REG(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000500ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_JAM(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000490ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_LFSR(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080004F8ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_OVR_BP(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080004C8ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_PAUSE_PKT_DMAC(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080004A0ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_PAUSE_PKT_TYPE(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080004A8ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_PRTS(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000480ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_SPI_CTL(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080004C0ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_SPI_DRAIN(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080004E0ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_SPI_MAX(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080004B0ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_SPI_ROUNDX(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000680ull + (((offset) & 31) * 8) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_SPI_THRESH(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800080004B8ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_TX_XAUI_CTL(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000528ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_GMXX_XAUI_EXT_LOOPBACK(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180008000540ull + (((block_id) & 1) * 0x8000000ull))
+static inline uint64_t CVMX_GMXX_BAD_REG(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000518ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000518ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000518ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000518ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_BIST(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000400ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000400ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000400ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000400ull) + (block_id) * 0x8000000ull;
+}
+
+#define CVMX_GMXX_BPID_MAPX(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180008000680ull) + (((offset) & 15) + ((block_id) & 7) * 0x200000ull) * 8)
+#define CVMX_GMXX_BPID_MSK(block_id) (CVMX_ADD_IO_SEG(0x0001180008000700ull) + ((block_id) & 7) * 0x1000000ull)
+static inline uint64_t CVMX_GMXX_CLK_EN(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080007F0ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080007F0ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080007F0ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800080007F0ull) + (block_id) * 0x8000000ull;
+}
+
+#define CVMX_GMXX_EBP_DIS(block_id) (CVMX_ADD_IO_SEG(0x0001180008000608ull) + ((block_id) & 7) * 0x1000000ull)
+#define CVMX_GMXX_EBP_MSK(block_id) (CVMX_ADD_IO_SEG(0x0001180008000600ull) + ((block_id) & 7) * 0x1000000ull)
+static inline uint64_t CVMX_GMXX_HG2_CONTROL(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000550ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000550ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000550ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000550ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_INF_MODE(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080007F8ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080007F8ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080007F8ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800080007F8ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_NXA_ADR(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000510ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000510ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000510ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000510ull) + (block_id) * 0x8000000ull;
+}
+
+#define CVMX_GMXX_PIPE_STATUS(block_id) (CVMX_ADD_IO_SEG(0x0001180008000760ull) + ((block_id) & 7) * 0x1000000ull)
+static inline uint64_t CVMX_GMXX_PRTX_CBFC_CTL(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000580ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000580ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000580ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000580ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_PRTX_CFG(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000010ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000010ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000010ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000010ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000010ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000010ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000010ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+#define CVMX_GMXX_RXAUI_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180008000740ull) + ((block_id) & 7) * 0x1000000ull)
+static inline uint64_t CVMX_GMXX_RXX_ADR_CAM0(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000180ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000180ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000180ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000180ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000180ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000180ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_ADR_CAM1(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000188ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000188ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000188ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000188ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000188ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000188ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_ADR_CAM2(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000190ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000190ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000190ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000190ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000190ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000190ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_ADR_CAM3(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000198ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000198ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000198ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000198ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000198ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000198ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_ADR_CAM4(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080001A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080001A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080001A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080001A0ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080001A0ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800080001A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_ADR_CAM5(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080001A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080001A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080001A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080001A8ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080001A8ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800080001A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_ADR_CAM_ALL_EN(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000110ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000110ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000110ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000110ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_ADR_CAM_EN(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000108ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000108ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000108ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000108ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000108ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000108ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000108ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_ADR_CTL(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000100ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000100ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000100ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000100ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000100ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000100ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000100ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_DECISION(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000040ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000040ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000040ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000040ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000040ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000040ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000040ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_FRM_CHK(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000020ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000020ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000020ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000020ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000020ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000020ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000020ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_FRM_CTL(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000018ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000018ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000018ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000018ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000018ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000018ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000018ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+#define CVMX_GMXX_RXX_FRM_MAX(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180008000030ull) + (((offset) & 3) + ((block_id) & 1) * 0x10000ull) * 2048)
+#define CVMX_GMXX_RXX_FRM_MIN(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180008000028ull) + (((offset) & 3) + ((block_id) & 1) * 0x10000ull) * 2048)
+static inline uint64_t CVMX_GMXX_RXX_IFG(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000058ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000058ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000058ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000058ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000058ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000058ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000058ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_INT_EN(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000008ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000008ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000008ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000008ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000008ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000008ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000008ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_INT_REG(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000000ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000000ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000000ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000000ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000000ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000000ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000000ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_JABBER(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000038ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000038ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000038ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000038ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000038ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000038ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000038ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_PAUSE_DROP_TIME(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000068ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000068ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000068ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000068ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000068ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000068ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000068ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+#define CVMX_GMXX_RXX_RX_INBND(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180008000060ull) + (((offset) & 3) + ((block_id) & 1) * 0x10000ull) * 2048)
+static inline uint64_t CVMX_GMXX_RXX_STATS_CTL(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000050ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000050ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000050ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000050ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000050ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000050ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000050ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_STATS_OCTS(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000088ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000088ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000088ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000088ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000088ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000088ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000088ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_STATS_OCTS_CTL(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000098ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000098ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000098ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000098ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000098ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000098ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000098ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_STATS_OCTS_DMAC(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000A8ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000A8ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800080000A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_STATS_OCTS_DRP(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000B8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000B8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000B8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000B8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000B8ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000B8ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800080000B8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_STATS_PKTS(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000080ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000080ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000080ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000080ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000080ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000080ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000080ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_STATS_PKTS_BAD(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000C0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000C0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000C0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000C0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000C0ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000C0ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800080000C0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_STATS_PKTS_CTL(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000090ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000090ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000090ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000090ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000090ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000090ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000090ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_STATS_PKTS_DMAC(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000A0ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000A0ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800080000A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_STATS_PKTS_DRP(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000B0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000B0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000B0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000B0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000B0ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080000B0ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800080000B0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RXX_UDD_SKP(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000048ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000048ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000048ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000048ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000048ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000048ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000048ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_RX_BP_DROPX(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000420ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000420ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000420ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000420ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000420ull) + ((offset) + (block_id) * 0x0ull) * 8;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000420ull) + ((offset) + (block_id) * 0x200000ull) * 8;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000420ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+}
+
+static inline uint64_t CVMX_GMXX_RX_BP_OFFX(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000460ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000460ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000460ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000460ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000460ull) + ((offset) + (block_id) * 0x0ull) * 8;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000460ull) + ((offset) + (block_id) * 0x200000ull) * 8;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000460ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+}
+
+static inline uint64_t CVMX_GMXX_RX_BP_ONX(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000440ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000440ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000440ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000440ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000440ull) + ((offset) + (block_id) * 0x0ull) * 8;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000440ull) + ((offset) + (block_id) * 0x200000ull) * 8;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000440ull) + ((offset) + (block_id) * 0x1000000ull) * 8;
+}
+
+static inline uint64_t CVMX_GMXX_RX_HG2_STATUS(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000548ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000548ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000548ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000548ull) + (block_id) * 0x8000000ull;
+}
+
+#define CVMX_GMXX_RX_PASS_EN(block_id) (CVMX_ADD_IO_SEG(0x00011800080005F8ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_GMXX_RX_PASS_MAPX(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180008000600ull) + (((offset) & 15) + ((block_id) & 1) * 0x1000000ull) * 8)
+static inline uint64_t CVMX_GMXX_RX_PRTS(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000410ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000410ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000410ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000410ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_RX_PRT_INFO(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080004E8ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080004E8ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080004E8ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800080004E8ull) + (block_id) * 0x8000000ull;
+}
+
+#define CVMX_GMXX_RX_TX_STATUS(block_id) (CVMX_ADD_IO_SEG(0x00011800080007E8ull))
+static inline uint64_t CVMX_GMXX_RX_XAUI_BAD_COL(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000538ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000538ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000538ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000538ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_RX_XAUI_CTL(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000530ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000530ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000530ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000530ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_SMACX(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000230ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000230ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000230ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000230ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000230ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000230ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000230ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_SOFT_BIST(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080007E8ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080007E8ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080007E8ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800080007E8ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_STAT_BP(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000520ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000520ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000520ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000520ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TB_REG(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080007E0ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080007E0ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080007E0ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800080007E0ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_APPEND(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000218ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000218ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000218ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000218ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000218ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000218ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000218ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_BURST(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000228ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000228ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000228ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000228ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000228ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000228ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000228ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_CBFC_XOFF(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080005A0ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080005A0ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080005A0ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800080005A0ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_CBFC_XON(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080005C0ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080005C0ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080005C0ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800080005C0ull) + (block_id) * 0x8000000ull;
+}
+
+#define CVMX_GMXX_TXX_CLK(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180008000208ull) + (((offset) & 3) + ((block_id) & 1) * 0x10000ull) * 2048)
+static inline uint64_t CVMX_GMXX_TXX_CTL(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000270ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000270ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000270ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000270ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000270ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000270ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000270ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_MIN_PKT(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000240ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000240ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000240ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000240ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000240ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000240ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000240ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_PAUSE_PKT_INTERVAL(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000248ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000248ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000248ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000248ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000248ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000248ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000248ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_PAUSE_PKT_TIME(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000238ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000238ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000238ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000238ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000238ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000238ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000238ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_PAUSE_TOGO(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000258ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000258ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000258ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000258ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000258ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000258ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000258ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_PAUSE_ZERO(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000260ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000260ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000260ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000260ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000260ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000260ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000260ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+#define CVMX_GMXX_TXX_PIPE(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180008000310ull) + (((offset) & 3) + ((block_id) & 7) * 0x2000ull) * 2048)
+static inline uint64_t CVMX_GMXX_TXX_SGMII_CTL(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000300ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000300ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000300ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000300ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000300ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_SLOT(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000220ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000220ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000220ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000220ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000220ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000220ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000220ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_SOFT_PAUSE(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000250ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000250ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000250ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000250ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000250ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000250ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000250ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_STAT0(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000280ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000280ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000280ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000280ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000280ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000280ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000280ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_STAT1(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000288ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000288ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000288ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000288ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000288ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000288ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000288ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_STAT2(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000290ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000290ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000290ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000290ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000290ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000290ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000290ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_STAT3(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000298ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000298ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000298ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000298ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000298ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000298ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000298ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_STAT4(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002A0ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002A0ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800080002A0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_STAT5(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002A8ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002A8ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800080002A8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_STAT6(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002B0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002B0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002B0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002B0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002B0ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002B0ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800080002B0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_STAT7(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002B8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002B8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002B8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002B8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002B8ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002B8ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800080002B8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_STAT8(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002C0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002C0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002C0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002C0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002C0ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002C0ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800080002C0ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_STAT9(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002C8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002C8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002C8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002C8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002C8ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080002C8ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800080002C8ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_STATS_CTL(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000268ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000268ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000268ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000268ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000268ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000268ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000268ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TXX_THRESH(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000210ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000210ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000210ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000210ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000210ull) + ((offset) + (block_id) * 0x0ull) * 2048;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000210ull) + ((offset) + (block_id) * 0x2000ull) * 2048;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000210ull) + ((offset) + (block_id) * 0x10000ull) * 2048;
+}
+
+static inline uint64_t CVMX_GMXX_TX_BP(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080004D0ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080004D0ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080004D0ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800080004D0ull) + (block_id) * 0x8000000ull;
+}
+
+#define CVMX_GMXX_TX_CLK_MSKX(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180008000780ull) + (((offset) & 1) + ((block_id) & 0) * 0x0ull) * 8)
+static inline uint64_t CVMX_GMXX_TX_COL_ATTEMPT(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000498ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000498ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000498ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000498ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TX_CORRUPT(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080004D8ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080004D8ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080004D8ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800080004D8ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TX_HG2_REG1(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000558ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000558ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000558ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000558ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TX_HG2_REG2(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000560ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000560ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000560ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000560ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TX_IFG(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000488ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000488ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000488ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000488ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TX_INT_EN(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000508ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000508ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000508ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000508ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TX_INT_REG(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000500ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000500ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000500ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000500ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TX_JAM(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000490ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000490ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000490ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000490ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TX_LFSR(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080004F8ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080004F8ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080004F8ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800080004F8ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TX_OVR_BP(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080004C8ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080004C8ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080004C8ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800080004C8ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TX_PAUSE_PKT_DMAC(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080004A0ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080004A0ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080004A0ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800080004A0ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TX_PAUSE_PKT_TYPE(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080004A8ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080004A8ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800080004A8ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800080004A8ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_TX_PRTS(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000480ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000480ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000480ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000480ull) + (block_id) * 0x8000000ull;
+}
+
+#define CVMX_GMXX_TX_SPI_CTL(block_id) (CVMX_ADD_IO_SEG(0x00011800080004C0ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_GMXX_TX_SPI_DRAIN(block_id) (CVMX_ADD_IO_SEG(0x00011800080004E0ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_GMXX_TX_SPI_MAX(block_id) (CVMX_ADD_IO_SEG(0x00011800080004B0ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_GMXX_TX_SPI_ROUNDX(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180008000680ull) + (((offset) & 31) + ((block_id) & 1) * 0x1000000ull) * 8)
+#define CVMX_GMXX_TX_SPI_THRESH(block_id) (CVMX_ADD_IO_SEG(0x00011800080004B8ull) + ((block_id) & 1) * 0x8000000ull)
+static inline uint64_t CVMX_GMXX_TX_XAUI_CTL(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000528ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000528ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000528ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000528ull) + (block_id) * 0x8000000ull;
+}
+
+static inline uint64_t CVMX_GMXX_XAUI_EXT_LOOPBACK(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000540ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000540ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180008000540ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180008000540ull) + (block_id) * 0x8000000ull;
+}
 
 union cvmx_gmxx_bad_reg {
 	uint64_t u64;
 	struct cvmx_gmxx_bad_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_31_63:33;
 		uint64_t inb_nxa:4;
 		uint64_t statovr:1;
@@ -238,8 +2082,19 @@
 		uint64_t out_ovr:16;
 		uint64_t ncb_ovr:1;
 		uint64_t out_col:1;
+#else
+		uint64_t out_col:1;
+		uint64_t ncb_ovr:1;
+		uint64_t out_ovr:16;
+		uint64_t reserved_18_21:4;
+		uint64_t loststat:4;
+		uint64_t statovr:1;
+		uint64_t inb_nxa:4;
+		uint64_t reserved_31_63:33;
+#endif
 	} s;
 	struct cvmx_gmxx_bad_reg_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_31_63:33;
 		uint64_t inb_nxa:4;
 		uint64_t statovr:1;
@@ -248,12 +2103,23 @@
 		uint64_t reserved_5_21:17;
 		uint64_t out_ovr:3;
 		uint64_t reserved_0_1:2;
+#else
+		uint64_t reserved_0_1:2;
+		uint64_t out_ovr:3;
+		uint64_t reserved_5_21:17;
+		uint64_t loststat:3;
+		uint64_t reserved_25_25:1;
+		uint64_t statovr:1;
+		uint64_t inb_nxa:4;
+		uint64_t reserved_31_63:33;
+#endif
 	} cn30xx;
 	struct cvmx_gmxx_bad_reg_cn30xx cn31xx;
 	struct cvmx_gmxx_bad_reg_s cn38xx;
 	struct cvmx_gmxx_bad_reg_s cn38xxp2;
 	struct cvmx_gmxx_bad_reg_cn30xx cn50xx;
 	struct cvmx_gmxx_bad_reg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_31_63:33;
 		uint64_t inb_nxa:4;
 		uint64_t statovr:1;
@@ -261,95 +2127,274 @@
 		uint64_t reserved_6_21:16;
 		uint64_t out_ovr:4;
 		uint64_t reserved_0_1:2;
+#else
+		uint64_t reserved_0_1:2;
+		uint64_t out_ovr:4;
+		uint64_t reserved_6_21:16;
+		uint64_t loststat:4;
+		uint64_t statovr:1;
+		uint64_t inb_nxa:4;
+		uint64_t reserved_31_63:33;
+#endif
 	} cn52xx;
 	struct cvmx_gmxx_bad_reg_cn52xx cn52xxp1;
 	struct cvmx_gmxx_bad_reg_cn52xx cn56xx;
 	struct cvmx_gmxx_bad_reg_cn52xx cn56xxp1;
 	struct cvmx_gmxx_bad_reg_s cn58xx;
 	struct cvmx_gmxx_bad_reg_s cn58xxp1;
+	struct cvmx_gmxx_bad_reg_cn52xx cn61xx;
+	struct cvmx_gmxx_bad_reg_cn52xx cn63xx;
+	struct cvmx_gmxx_bad_reg_cn52xx cn63xxp1;
+	struct cvmx_gmxx_bad_reg_cn52xx cn66xx;
+	struct cvmx_gmxx_bad_reg_cn52xx cn68xx;
+	struct cvmx_gmxx_bad_reg_cn52xx cn68xxp1;
+	struct cvmx_gmxx_bad_reg_cn52xx cnf71xx;
 };
 
 union cvmx_gmxx_bist {
 	uint64_t u64;
 	struct cvmx_gmxx_bist_s {
-		uint64_t reserved_17_63:47;
-		uint64_t status:17;
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_25_63:39;
+		uint64_t status:25;
+#else
+		uint64_t status:25;
+		uint64_t reserved_25_63:39;
+#endif
 	} s;
 	struct cvmx_gmxx_bist_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t status:10;
+#else
+		uint64_t status:10;
+		uint64_t reserved_10_63:54;
+#endif
 	} cn30xx;
 	struct cvmx_gmxx_bist_cn30xx cn31xx;
 	struct cvmx_gmxx_bist_cn30xx cn38xx;
 	struct cvmx_gmxx_bist_cn30xx cn38xxp2;
 	struct cvmx_gmxx_bist_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t status:12;
+#else
+		uint64_t status:12;
+		uint64_t reserved_12_63:52;
+#endif
 	} cn50xx;
 	struct cvmx_gmxx_bist_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t status:16;
+#else
+		uint64_t status:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} cn52xx;
 	struct cvmx_gmxx_bist_cn52xx cn52xxp1;
 	struct cvmx_gmxx_bist_cn52xx cn56xx;
 	struct cvmx_gmxx_bist_cn52xx cn56xxp1;
-	struct cvmx_gmxx_bist_s cn58xx;
-	struct cvmx_gmxx_bist_s cn58xxp1;
+	struct cvmx_gmxx_bist_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_17_63:47;
+		uint64_t status:17;
+#else
+		uint64_t status:17;
+		uint64_t reserved_17_63:47;
+#endif
+	} cn58xx;
+	struct cvmx_gmxx_bist_cn58xx cn58xxp1;
+	struct cvmx_gmxx_bist_s cn61xx;
+	struct cvmx_gmxx_bist_s cn63xx;
+	struct cvmx_gmxx_bist_s cn63xxp1;
+	struct cvmx_gmxx_bist_s cn66xx;
+	struct cvmx_gmxx_bist_s cn68xx;
+	struct cvmx_gmxx_bist_s cn68xxp1;
+	struct cvmx_gmxx_bist_s cnf71xx;
+};
+
+union cvmx_gmxx_bpid_mapx {
+	uint64_t u64;
+	struct cvmx_gmxx_bpid_mapx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_17_63:47;
+		uint64_t status:1;
+		uint64_t reserved_9_15:7;
+		uint64_t val:1;
+		uint64_t reserved_6_7:2;
+		uint64_t bpid:6;
+#else
+		uint64_t bpid:6;
+		uint64_t reserved_6_7:2;
+		uint64_t val:1;
+		uint64_t reserved_9_15:7;
+		uint64_t status:1;
+		uint64_t reserved_17_63:47;
+#endif
+	} s;
+	struct cvmx_gmxx_bpid_mapx_s cn68xx;
+	struct cvmx_gmxx_bpid_mapx_s cn68xxp1;
+};
+
+union cvmx_gmxx_bpid_msk {
+	uint64_t u64;
+	struct cvmx_gmxx_bpid_msk_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_48_63:16;
+		uint64_t msk_or:16;
+		uint64_t reserved_16_31:16;
+		uint64_t msk_and:16;
+#else
+		uint64_t msk_and:16;
+		uint64_t reserved_16_31:16;
+		uint64_t msk_or:16;
+		uint64_t reserved_48_63:16;
+#endif
+	} s;
+	struct cvmx_gmxx_bpid_msk_s cn68xx;
+	struct cvmx_gmxx_bpid_msk_s cn68xxp1;
 };
 
 union cvmx_gmxx_clk_en {
 	uint64_t u64;
 	struct cvmx_gmxx_clk_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t clk_en:1;
+#else
+		uint64_t clk_en:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_gmxx_clk_en_s cn52xx;
 	struct cvmx_gmxx_clk_en_s cn52xxp1;
 	struct cvmx_gmxx_clk_en_s cn56xx;
 	struct cvmx_gmxx_clk_en_s cn56xxp1;
+	struct cvmx_gmxx_clk_en_s cn61xx;
+	struct cvmx_gmxx_clk_en_s cn63xx;
+	struct cvmx_gmxx_clk_en_s cn63xxp1;
+	struct cvmx_gmxx_clk_en_s cn66xx;
+	struct cvmx_gmxx_clk_en_s cn68xx;
+	struct cvmx_gmxx_clk_en_s cn68xxp1;
+	struct cvmx_gmxx_clk_en_s cnf71xx;
+};
+
+union cvmx_gmxx_ebp_dis {
+	uint64_t u64;
+	struct cvmx_gmxx_ebp_dis_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t dis:16;
+#else
+		uint64_t dis:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} s;
+	struct cvmx_gmxx_ebp_dis_s cn68xx;
+	struct cvmx_gmxx_ebp_dis_s cn68xxp1;
+};
+
+union cvmx_gmxx_ebp_msk {
+	uint64_t u64;
+	struct cvmx_gmxx_ebp_msk_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t msk:16;
+#else
+		uint64_t msk:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} s;
+	struct cvmx_gmxx_ebp_msk_s cn68xx;
+	struct cvmx_gmxx_ebp_msk_s cn68xxp1;
 };
 
 union cvmx_gmxx_hg2_control {
 	uint64_t u64;
 	struct cvmx_gmxx_hg2_control_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_19_63:45;
 		uint64_t hg2tx_en:1;
 		uint64_t hg2rx_en:1;
 		uint64_t phys_en:1;
 		uint64_t logl_en:16;
+#else
+		uint64_t logl_en:16;
+		uint64_t phys_en:1;
+		uint64_t hg2rx_en:1;
+		uint64_t hg2tx_en:1;
+		uint64_t reserved_19_63:45;
+#endif
 	} s;
 	struct cvmx_gmxx_hg2_control_s cn52xx;
 	struct cvmx_gmxx_hg2_control_s cn52xxp1;
 	struct cvmx_gmxx_hg2_control_s cn56xx;
+	struct cvmx_gmxx_hg2_control_s cn61xx;
+	struct cvmx_gmxx_hg2_control_s cn63xx;
+	struct cvmx_gmxx_hg2_control_s cn63xxp1;
+	struct cvmx_gmxx_hg2_control_s cn66xx;
+	struct cvmx_gmxx_hg2_control_s cn68xx;
+	struct cvmx_gmxx_hg2_control_s cn68xxp1;
+	struct cvmx_gmxx_hg2_control_s cnf71xx;
 };
 
 union cvmx_gmxx_inf_mode {
 	uint64_t u64;
 	struct cvmx_gmxx_inf_mode_s {
-		uint64_t reserved_10_63:54;
-		uint64_t speed:2;
-		uint64_t reserved_6_7:2;
-		uint64_t mode:2;
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_20_63:44;
+		uint64_t rate:4;
+		uint64_t reserved_12_15:4;
+		uint64_t speed:4;
+		uint64_t reserved_7_7:1;
+		uint64_t mode:3;
 		uint64_t reserved_3_3:1;
 		uint64_t p0mii:1;
 		uint64_t en:1;
 		uint64_t type:1;
+#else
+		uint64_t type:1;
+		uint64_t en:1;
+		uint64_t p0mii:1;
+		uint64_t reserved_3_3:1;
+		uint64_t mode:3;
+		uint64_t reserved_7_7:1;
+		uint64_t speed:4;
+		uint64_t reserved_12_15:4;
+		uint64_t rate:4;
+		uint64_t reserved_20_63:44;
+#endif
 	} s;
 	struct cvmx_gmxx_inf_mode_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_3_63:61;
 		uint64_t p0mii:1;
 		uint64_t en:1;
 		uint64_t type:1;
+#else
+		uint64_t type:1;
+		uint64_t en:1;
+		uint64_t p0mii:1;
+		uint64_t reserved_3_63:61;
+#endif
 	} cn30xx;
 	struct cvmx_gmxx_inf_mode_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t en:1;
 		uint64_t type:1;
+#else
+		uint64_t type:1;
+		uint64_t en:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} cn31xx;
 	struct cvmx_gmxx_inf_mode_cn31xx cn38xx;
 	struct cvmx_gmxx_inf_mode_cn31xx cn38xxp2;
 	struct cvmx_gmxx_inf_mode_cn30xx cn50xx;
 	struct cvmx_gmxx_inf_mode_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t speed:2;
 		uint64_t reserved_6_7:2;
@@ -357,36 +2402,158 @@
 		uint64_t reserved_2_3:2;
 		uint64_t en:1;
 		uint64_t type:1;
+#else
+		uint64_t type:1;
+		uint64_t en:1;
+		uint64_t reserved_2_3:2;
+		uint64_t mode:2;
+		uint64_t reserved_6_7:2;
+		uint64_t speed:2;
+		uint64_t reserved_10_63:54;
+#endif
 	} cn52xx;
 	struct cvmx_gmxx_inf_mode_cn52xx cn52xxp1;
 	struct cvmx_gmxx_inf_mode_cn52xx cn56xx;
 	struct cvmx_gmxx_inf_mode_cn52xx cn56xxp1;
 	struct cvmx_gmxx_inf_mode_cn31xx cn58xx;
 	struct cvmx_gmxx_inf_mode_cn31xx cn58xxp1;
+	struct cvmx_gmxx_inf_mode_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_12_63:52;
+		uint64_t speed:4;
+		uint64_t reserved_5_7:3;
+		uint64_t mode:1;
+		uint64_t reserved_2_3:2;
+		uint64_t en:1;
+		uint64_t type:1;
+#else
+		uint64_t type:1;
+		uint64_t en:1;
+		uint64_t reserved_2_3:2;
+		uint64_t mode:1;
+		uint64_t reserved_5_7:3;
+		uint64_t speed:4;
+		uint64_t reserved_12_63:52;
+#endif
+	} cn61xx;
+	struct cvmx_gmxx_inf_mode_cn61xx cn63xx;
+	struct cvmx_gmxx_inf_mode_cn61xx cn63xxp1;
+	struct cvmx_gmxx_inf_mode_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_20_63:44;
+		uint64_t rate:4;
+		uint64_t reserved_12_15:4;
+		uint64_t speed:4;
+		uint64_t reserved_5_7:3;
+		uint64_t mode:1;
+		uint64_t reserved_2_3:2;
+		uint64_t en:1;
+		uint64_t type:1;
+#else
+		uint64_t type:1;
+		uint64_t en:1;
+		uint64_t reserved_2_3:2;
+		uint64_t mode:1;
+		uint64_t reserved_5_7:3;
+		uint64_t speed:4;
+		uint64_t reserved_12_15:4;
+		uint64_t rate:4;
+		uint64_t reserved_20_63:44;
+#endif
+	} cn66xx;
+	struct cvmx_gmxx_inf_mode_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_12_63:52;
+		uint64_t speed:4;
+		uint64_t reserved_7_7:1;
+		uint64_t mode:3;
+		uint64_t reserved_2_3:2;
+		uint64_t en:1;
+		uint64_t type:1;
+#else
+		uint64_t type:1;
+		uint64_t en:1;
+		uint64_t reserved_2_3:2;
+		uint64_t mode:3;
+		uint64_t reserved_7_7:1;
+		uint64_t speed:4;
+		uint64_t reserved_12_63:52;
+#endif
+	} cn68xx;
+	struct cvmx_gmxx_inf_mode_cn68xx cn68xxp1;
+	struct cvmx_gmxx_inf_mode_cn61xx cnf71xx;
 };
 
 union cvmx_gmxx_nxa_adr {
 	uint64_t u64;
 	struct cvmx_gmxx_nxa_adr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_23_63:41;
+		uint64_t pipe:7;
+		uint64_t reserved_6_15:10;
+		uint64_t prt:6;
+#else
+		uint64_t prt:6;
+		uint64_t reserved_6_15:10;
+		uint64_t pipe:7;
+		uint64_t reserved_23_63:41;
+#endif
+	} s;
+	struct cvmx_gmxx_nxa_adr_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t prt:6;
+#else
+		uint64_t prt:6;
+		uint64_t reserved_6_63:58;
+#endif
+	} cn30xx;
+	struct cvmx_gmxx_nxa_adr_cn30xx cn31xx;
+	struct cvmx_gmxx_nxa_adr_cn30xx cn38xx;
+	struct cvmx_gmxx_nxa_adr_cn30xx cn38xxp2;
+	struct cvmx_gmxx_nxa_adr_cn30xx cn50xx;
+	struct cvmx_gmxx_nxa_adr_cn30xx cn52xx;
+	struct cvmx_gmxx_nxa_adr_cn30xx cn52xxp1;
+	struct cvmx_gmxx_nxa_adr_cn30xx cn56xx;
+	struct cvmx_gmxx_nxa_adr_cn30xx cn56xxp1;
+	struct cvmx_gmxx_nxa_adr_cn30xx cn58xx;
+	struct cvmx_gmxx_nxa_adr_cn30xx cn58xxp1;
+	struct cvmx_gmxx_nxa_adr_cn30xx cn61xx;
+	struct cvmx_gmxx_nxa_adr_cn30xx cn63xx;
+	struct cvmx_gmxx_nxa_adr_cn30xx cn63xxp1;
+	struct cvmx_gmxx_nxa_adr_cn30xx cn66xx;
+	struct cvmx_gmxx_nxa_adr_s cn68xx;
+	struct cvmx_gmxx_nxa_adr_s cn68xxp1;
+	struct cvmx_gmxx_nxa_adr_cn30xx cnf71xx;
+};
+
+union cvmx_gmxx_pipe_status {
+	uint64_t u64;
+	struct cvmx_gmxx_pipe_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_20_63:44;
+		uint64_t ovr:4;
+		uint64_t reserved_12_15:4;
+		uint64_t bp:4;
+		uint64_t reserved_4_7:4;
+		uint64_t stop:4;
+#else
+		uint64_t stop:4;
+		uint64_t reserved_4_7:4;
+		uint64_t bp:4;
+		uint64_t reserved_12_15:4;
+		uint64_t ovr:4;
+		uint64_t reserved_20_63:44;
+#endif
 	} s;
-	struct cvmx_gmxx_nxa_adr_s cn30xx;
-	struct cvmx_gmxx_nxa_adr_s cn31xx;
-	struct cvmx_gmxx_nxa_adr_s cn38xx;
-	struct cvmx_gmxx_nxa_adr_s cn38xxp2;
-	struct cvmx_gmxx_nxa_adr_s cn50xx;
-	struct cvmx_gmxx_nxa_adr_s cn52xx;
-	struct cvmx_gmxx_nxa_adr_s cn52xxp1;
-	struct cvmx_gmxx_nxa_adr_s cn56xx;
-	struct cvmx_gmxx_nxa_adr_s cn56xxp1;
-	struct cvmx_gmxx_nxa_adr_s cn58xx;
-	struct cvmx_gmxx_nxa_adr_s cn58xxp1;
+	struct cvmx_gmxx_pipe_status_s cn68xx;
+	struct cvmx_gmxx_pipe_status_s cn68xxp1;
 };
 
 union cvmx_gmxx_prtx_cbfc_ctl {
 	uint64_t u64;
 	struct cvmx_gmxx_prtx_cbfc_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t phys_en:16;
 		uint64_t logl_en:16;
 		uint64_t phys_bp:16;
@@ -395,14 +2562,80 @@
 		uint64_t drp_en:1;
 		uint64_t tx_en:1;
 		uint64_t rx_en:1;
+#else
+		uint64_t rx_en:1;
+		uint64_t tx_en:1;
+		uint64_t drp_en:1;
+		uint64_t bck_en:1;
+		uint64_t reserved_4_15:12;
+		uint64_t phys_bp:16;
+		uint64_t logl_en:16;
+		uint64_t phys_en:16;
+#endif
 	} s;
 	struct cvmx_gmxx_prtx_cbfc_ctl_s cn52xx;
 	struct cvmx_gmxx_prtx_cbfc_ctl_s cn56xx;
+	struct cvmx_gmxx_prtx_cbfc_ctl_s cn61xx;
+	struct cvmx_gmxx_prtx_cbfc_ctl_s cn63xx;
+	struct cvmx_gmxx_prtx_cbfc_ctl_s cn63xxp1;
+	struct cvmx_gmxx_prtx_cbfc_ctl_s cn66xx;
+	struct cvmx_gmxx_prtx_cbfc_ctl_s cn68xx;
+	struct cvmx_gmxx_prtx_cbfc_ctl_s cn68xxp1;
+	struct cvmx_gmxx_prtx_cbfc_ctl_s cnf71xx;
 };
 
 union cvmx_gmxx_prtx_cfg {
 	uint64_t u64;
 	struct cvmx_gmxx_prtx_cfg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_22_63:42;
+		uint64_t pknd:6;
+		uint64_t reserved_14_15:2;
+		uint64_t tx_idle:1;
+		uint64_t rx_idle:1;
+		uint64_t reserved_9_11:3;
+		uint64_t speed_msb:1;
+		uint64_t reserved_4_7:4;
+		uint64_t slottime:1;
+		uint64_t duplex:1;
+		uint64_t speed:1;
+		uint64_t en:1;
+#else
+		uint64_t en:1;
+		uint64_t speed:1;
+		uint64_t duplex:1;
+		uint64_t slottime:1;
+		uint64_t reserved_4_7:4;
+		uint64_t speed_msb:1;
+		uint64_t reserved_9_11:3;
+		uint64_t rx_idle:1;
+		uint64_t tx_idle:1;
+		uint64_t reserved_14_15:2;
+		uint64_t pknd:6;
+		uint64_t reserved_22_63:42;
+#endif
+	} s;
+	struct cvmx_gmxx_prtx_cfg_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t slottime:1;
+		uint64_t duplex:1;
+		uint64_t speed:1;
+		uint64_t en:1;
+#else
+		uint64_t en:1;
+		uint64_t speed:1;
+		uint64_t duplex:1;
+		uint64_t slottime:1;
+		uint64_t reserved_4_63:60;
+#endif
+	} cn30xx;
+	struct cvmx_gmxx_prtx_cfg_cn30xx cn31xx;
+	struct cvmx_gmxx_prtx_cfg_cn30xx cn38xx;
+	struct cvmx_gmxx_prtx_cfg_cn30xx cn38xxp2;
+	struct cvmx_gmxx_prtx_cfg_cn30xx cn50xx;
+	struct cvmx_gmxx_prtx_cfg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_14_63:50;
 		uint64_t tx_idle:1;
 		uint64_t rx_idle:1;
@@ -413,30 +2646,41 @@
 		uint64_t duplex:1;
 		uint64_t speed:1;
 		uint64_t en:1;
-	} s;
-	struct cvmx_gmxx_prtx_cfg_cn30xx {
-		uint64_t reserved_4_63:60;
-		uint64_t slottime:1;
-		uint64_t duplex:1;
-		uint64_t speed:1;
+#else
 		uint64_t en:1;
-	} cn30xx;
-	struct cvmx_gmxx_prtx_cfg_cn30xx cn31xx;
-	struct cvmx_gmxx_prtx_cfg_cn30xx cn38xx;
-	struct cvmx_gmxx_prtx_cfg_cn30xx cn38xxp2;
-	struct cvmx_gmxx_prtx_cfg_cn30xx cn50xx;
-	struct cvmx_gmxx_prtx_cfg_s cn52xx;
-	struct cvmx_gmxx_prtx_cfg_s cn52xxp1;
-	struct cvmx_gmxx_prtx_cfg_s cn56xx;
-	struct cvmx_gmxx_prtx_cfg_s cn56xxp1;
+		uint64_t speed:1;
+		uint64_t duplex:1;
+		uint64_t slottime:1;
+		uint64_t reserved_4_7:4;
+		uint64_t speed_msb:1;
+		uint64_t reserved_9_11:3;
+		uint64_t rx_idle:1;
+		uint64_t tx_idle:1;
+		uint64_t reserved_14_63:50;
+#endif
+	} cn52xx;
+	struct cvmx_gmxx_prtx_cfg_cn52xx cn52xxp1;
+	struct cvmx_gmxx_prtx_cfg_cn52xx cn56xx;
+	struct cvmx_gmxx_prtx_cfg_cn52xx cn56xxp1;
 	struct cvmx_gmxx_prtx_cfg_cn30xx cn58xx;
 	struct cvmx_gmxx_prtx_cfg_cn30xx cn58xxp1;
+	struct cvmx_gmxx_prtx_cfg_cn52xx cn61xx;
+	struct cvmx_gmxx_prtx_cfg_cn52xx cn63xx;
+	struct cvmx_gmxx_prtx_cfg_cn52xx cn63xxp1;
+	struct cvmx_gmxx_prtx_cfg_cn52xx cn66xx;
+	struct cvmx_gmxx_prtx_cfg_s cn68xx;
+	struct cvmx_gmxx_prtx_cfg_s cn68xxp1;
+	struct cvmx_gmxx_prtx_cfg_cn52xx cnf71xx;
 };
 
 union cvmx_gmxx_rxx_adr_cam0 {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_adr_cam0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t adr:64;
+#else
+		uint64_t adr:64;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_adr_cam0_s cn30xx;
 	struct cvmx_gmxx_rxx_adr_cam0_s cn31xx;
@@ -449,12 +2693,23 @@
 	struct cvmx_gmxx_rxx_adr_cam0_s cn56xxp1;
 	struct cvmx_gmxx_rxx_adr_cam0_s cn58xx;
 	struct cvmx_gmxx_rxx_adr_cam0_s cn58xxp1;
+	struct cvmx_gmxx_rxx_adr_cam0_s cn61xx;
+	struct cvmx_gmxx_rxx_adr_cam0_s cn63xx;
+	struct cvmx_gmxx_rxx_adr_cam0_s cn63xxp1;
+	struct cvmx_gmxx_rxx_adr_cam0_s cn66xx;
+	struct cvmx_gmxx_rxx_adr_cam0_s cn68xx;
+	struct cvmx_gmxx_rxx_adr_cam0_s cn68xxp1;
+	struct cvmx_gmxx_rxx_adr_cam0_s cnf71xx;
 };
 
 union cvmx_gmxx_rxx_adr_cam1 {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_adr_cam1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t adr:64;
+#else
+		uint64_t adr:64;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_adr_cam1_s cn30xx;
 	struct cvmx_gmxx_rxx_adr_cam1_s cn31xx;
@@ -467,12 +2722,23 @@
 	struct cvmx_gmxx_rxx_adr_cam1_s cn56xxp1;
 	struct cvmx_gmxx_rxx_adr_cam1_s cn58xx;
 	struct cvmx_gmxx_rxx_adr_cam1_s cn58xxp1;
+	struct cvmx_gmxx_rxx_adr_cam1_s cn61xx;
+	struct cvmx_gmxx_rxx_adr_cam1_s cn63xx;
+	struct cvmx_gmxx_rxx_adr_cam1_s cn63xxp1;
+	struct cvmx_gmxx_rxx_adr_cam1_s cn66xx;
+	struct cvmx_gmxx_rxx_adr_cam1_s cn68xx;
+	struct cvmx_gmxx_rxx_adr_cam1_s cn68xxp1;
+	struct cvmx_gmxx_rxx_adr_cam1_s cnf71xx;
 };
 
 union cvmx_gmxx_rxx_adr_cam2 {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_adr_cam2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t adr:64;
+#else
+		uint64_t adr:64;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_adr_cam2_s cn30xx;
 	struct cvmx_gmxx_rxx_adr_cam2_s cn31xx;
@@ -485,12 +2751,23 @@
 	struct cvmx_gmxx_rxx_adr_cam2_s cn56xxp1;
 	struct cvmx_gmxx_rxx_adr_cam2_s cn58xx;
 	struct cvmx_gmxx_rxx_adr_cam2_s cn58xxp1;
+	struct cvmx_gmxx_rxx_adr_cam2_s cn61xx;
+	struct cvmx_gmxx_rxx_adr_cam2_s cn63xx;
+	struct cvmx_gmxx_rxx_adr_cam2_s cn63xxp1;
+	struct cvmx_gmxx_rxx_adr_cam2_s cn66xx;
+	struct cvmx_gmxx_rxx_adr_cam2_s cn68xx;
+	struct cvmx_gmxx_rxx_adr_cam2_s cn68xxp1;
+	struct cvmx_gmxx_rxx_adr_cam2_s cnf71xx;
 };
 
 union cvmx_gmxx_rxx_adr_cam3 {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_adr_cam3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t adr:64;
+#else
+		uint64_t adr:64;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_adr_cam3_s cn30xx;
 	struct cvmx_gmxx_rxx_adr_cam3_s cn31xx;
@@ -503,12 +2780,23 @@
 	struct cvmx_gmxx_rxx_adr_cam3_s cn56xxp1;
 	struct cvmx_gmxx_rxx_adr_cam3_s cn58xx;
 	struct cvmx_gmxx_rxx_adr_cam3_s cn58xxp1;
+	struct cvmx_gmxx_rxx_adr_cam3_s cn61xx;
+	struct cvmx_gmxx_rxx_adr_cam3_s cn63xx;
+	struct cvmx_gmxx_rxx_adr_cam3_s cn63xxp1;
+	struct cvmx_gmxx_rxx_adr_cam3_s cn66xx;
+	struct cvmx_gmxx_rxx_adr_cam3_s cn68xx;
+	struct cvmx_gmxx_rxx_adr_cam3_s cn68xxp1;
+	struct cvmx_gmxx_rxx_adr_cam3_s cnf71xx;
 };
 
 union cvmx_gmxx_rxx_adr_cam4 {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_adr_cam4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t adr:64;
+#else
+		uint64_t adr:64;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_adr_cam4_s cn30xx;
 	struct cvmx_gmxx_rxx_adr_cam4_s cn31xx;
@@ -521,12 +2809,23 @@
 	struct cvmx_gmxx_rxx_adr_cam4_s cn56xxp1;
 	struct cvmx_gmxx_rxx_adr_cam4_s cn58xx;
 	struct cvmx_gmxx_rxx_adr_cam4_s cn58xxp1;
+	struct cvmx_gmxx_rxx_adr_cam4_s cn61xx;
+	struct cvmx_gmxx_rxx_adr_cam4_s cn63xx;
+	struct cvmx_gmxx_rxx_adr_cam4_s cn63xxp1;
+	struct cvmx_gmxx_rxx_adr_cam4_s cn66xx;
+	struct cvmx_gmxx_rxx_adr_cam4_s cn68xx;
+	struct cvmx_gmxx_rxx_adr_cam4_s cn68xxp1;
+	struct cvmx_gmxx_rxx_adr_cam4_s cnf71xx;
 };
 
 union cvmx_gmxx_rxx_adr_cam5 {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_adr_cam5_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t adr:64;
+#else
+		uint64_t adr:64;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_adr_cam5_s cn30xx;
 	struct cvmx_gmxx_rxx_adr_cam5_s cn31xx;
@@ -539,13 +2838,42 @@
 	struct cvmx_gmxx_rxx_adr_cam5_s cn56xxp1;
 	struct cvmx_gmxx_rxx_adr_cam5_s cn58xx;
 	struct cvmx_gmxx_rxx_adr_cam5_s cn58xxp1;
+	struct cvmx_gmxx_rxx_adr_cam5_s cn61xx;
+	struct cvmx_gmxx_rxx_adr_cam5_s cn63xx;
+	struct cvmx_gmxx_rxx_adr_cam5_s cn63xxp1;
+	struct cvmx_gmxx_rxx_adr_cam5_s cn66xx;
+	struct cvmx_gmxx_rxx_adr_cam5_s cn68xx;
+	struct cvmx_gmxx_rxx_adr_cam5_s cn68xxp1;
+	struct cvmx_gmxx_rxx_adr_cam5_s cnf71xx;
+};
+
+union cvmx_gmxx_rxx_adr_cam_all_en {
+	uint64_t u64;
+	struct cvmx_gmxx_rxx_adr_cam_all_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t en:32;
+#else
+		uint64_t en:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_gmxx_rxx_adr_cam_all_en_s cn61xx;
+	struct cvmx_gmxx_rxx_adr_cam_all_en_s cn66xx;
+	struct cvmx_gmxx_rxx_adr_cam_all_en_s cn68xx;
+	struct cvmx_gmxx_rxx_adr_cam_all_en_s cnf71xx;
 };
 
 union cvmx_gmxx_rxx_adr_cam_en {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_adr_cam_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t en:8;
+#else
+		uint64_t en:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_adr_cam_en_s cn30xx;
 	struct cvmx_gmxx_rxx_adr_cam_en_s cn31xx;
@@ -558,15 +2886,29 @@
 	struct cvmx_gmxx_rxx_adr_cam_en_s cn56xxp1;
 	struct cvmx_gmxx_rxx_adr_cam_en_s cn58xx;
 	struct cvmx_gmxx_rxx_adr_cam_en_s cn58xxp1;
+	struct cvmx_gmxx_rxx_adr_cam_en_s cn61xx;
+	struct cvmx_gmxx_rxx_adr_cam_en_s cn63xx;
+	struct cvmx_gmxx_rxx_adr_cam_en_s cn63xxp1;
+	struct cvmx_gmxx_rxx_adr_cam_en_s cn66xx;
+	struct cvmx_gmxx_rxx_adr_cam_en_s cn68xx;
+	struct cvmx_gmxx_rxx_adr_cam_en_s cn68xxp1;
+	struct cvmx_gmxx_rxx_adr_cam_en_s cnf71xx;
 };
 
 union cvmx_gmxx_rxx_adr_ctl {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_adr_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t cam_mode:1;
 		uint64_t mcst:2;
 		uint64_t bcst:1;
+#else
+		uint64_t bcst:1;
+		uint64_t mcst:2;
+		uint64_t cam_mode:1;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_adr_ctl_s cn30xx;
 	struct cvmx_gmxx_rxx_adr_ctl_s cn31xx;
@@ -579,13 +2921,25 @@
 	struct cvmx_gmxx_rxx_adr_ctl_s cn56xxp1;
 	struct cvmx_gmxx_rxx_adr_ctl_s cn58xx;
 	struct cvmx_gmxx_rxx_adr_ctl_s cn58xxp1;
+	struct cvmx_gmxx_rxx_adr_ctl_s cn61xx;
+	struct cvmx_gmxx_rxx_adr_ctl_s cn63xx;
+	struct cvmx_gmxx_rxx_adr_ctl_s cn63xxp1;
+	struct cvmx_gmxx_rxx_adr_ctl_s cn66xx;
+	struct cvmx_gmxx_rxx_adr_ctl_s cn68xx;
+	struct cvmx_gmxx_rxx_adr_ctl_s cn68xxp1;
+	struct cvmx_gmxx_rxx_adr_ctl_s cnf71xx;
 };
 
 union cvmx_gmxx_rxx_decision {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_decision_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t cnt:5;
+#else
+		uint64_t cnt:5;
+		uint64_t reserved_5_63:59;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_decision_s cn30xx;
 	struct cvmx_gmxx_rxx_decision_s cn31xx;
@@ -598,11 +2952,19 @@
 	struct cvmx_gmxx_rxx_decision_s cn56xxp1;
 	struct cvmx_gmxx_rxx_decision_s cn58xx;
 	struct cvmx_gmxx_rxx_decision_s cn58xxp1;
+	struct cvmx_gmxx_rxx_decision_s cn61xx;
+	struct cvmx_gmxx_rxx_decision_s cn63xx;
+	struct cvmx_gmxx_rxx_decision_s cn63xxp1;
+	struct cvmx_gmxx_rxx_decision_s cn66xx;
+	struct cvmx_gmxx_rxx_decision_s cn68xx;
+	struct cvmx_gmxx_rxx_decision_s cn68xxp1;
+	struct cvmx_gmxx_rxx_decision_s cnf71xx;
 };
 
 union cvmx_gmxx_rxx_frm_chk {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_frm_chk_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t niberr:1;
 		uint64_t skperr:1;
@@ -614,12 +2976,26 @@
 		uint64_t maxerr:1;
 		uint64_t carext:1;
 		uint64_t minerr:1;
+#else
+		uint64_t minerr:1;
+		uint64_t carext:1;
+		uint64_t maxerr:1;
+		uint64_t jabber:1;
+		uint64_t fcserr:1;
+		uint64_t alnerr:1;
+		uint64_t lenerr:1;
+		uint64_t rcverr:1;
+		uint64_t skperr:1;
+		uint64_t niberr:1;
+		uint64_t reserved_10_63:54;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_frm_chk_s cn30xx;
 	struct cvmx_gmxx_rxx_frm_chk_s cn31xx;
 	struct cvmx_gmxx_rxx_frm_chk_s cn38xx;
 	struct cvmx_gmxx_rxx_frm_chk_s cn38xxp2;
 	struct cvmx_gmxx_rxx_frm_chk_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t niberr:1;
 		uint64_t skperr:1;
@@ -631,8 +3007,22 @@
 		uint64_t reserved_2_2:1;
 		uint64_t carext:1;
 		uint64_t reserved_0_0:1;
+#else
+		uint64_t reserved_0_0:1;
+		uint64_t carext:1;
+		uint64_t reserved_2_2:1;
+		uint64_t jabber:1;
+		uint64_t fcserr:1;
+		uint64_t alnerr:1;
+		uint64_t reserved_6_6:1;
+		uint64_t rcverr:1;
+		uint64_t skperr:1;
+		uint64_t niberr:1;
+		uint64_t reserved_10_63:54;
+#endif
 	} cn50xx;
 	struct cvmx_gmxx_rxx_frm_chk_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t skperr:1;
 		uint64_t rcverr:1;
@@ -642,18 +3032,61 @@
 		uint64_t reserved_2_2:1;
 		uint64_t carext:1;
 		uint64_t reserved_0_0:1;
+#else
+		uint64_t reserved_0_0:1;
+		uint64_t carext:1;
+		uint64_t reserved_2_2:1;
+		uint64_t jabber:1;
+		uint64_t fcserr:1;
+		uint64_t reserved_5_6:2;
+		uint64_t rcverr:1;
+		uint64_t skperr:1;
+		uint64_t reserved_9_63:55;
+#endif
 	} cn52xx;
 	struct cvmx_gmxx_rxx_frm_chk_cn52xx cn52xxp1;
 	struct cvmx_gmxx_rxx_frm_chk_cn52xx cn56xx;
 	struct cvmx_gmxx_rxx_frm_chk_cn52xx cn56xxp1;
 	struct cvmx_gmxx_rxx_frm_chk_s cn58xx;
 	struct cvmx_gmxx_rxx_frm_chk_s cn58xxp1;
+	struct cvmx_gmxx_rxx_frm_chk_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_9_63:55;
+		uint64_t skperr:1;
+		uint64_t rcverr:1;
+		uint64_t reserved_5_6:2;
+		uint64_t fcserr:1;
+		uint64_t jabber:1;
+		uint64_t reserved_2_2:1;
+		uint64_t carext:1;
+		uint64_t minerr:1;
+#else
+		uint64_t minerr:1;
+		uint64_t carext:1;
+		uint64_t reserved_2_2:1;
+		uint64_t jabber:1;
+		uint64_t fcserr:1;
+		uint64_t reserved_5_6:2;
+		uint64_t rcverr:1;
+		uint64_t skperr:1;
+		uint64_t reserved_9_63:55;
+#endif
+	} cn61xx;
+	struct cvmx_gmxx_rxx_frm_chk_cn61xx cn63xx;
+	struct cvmx_gmxx_rxx_frm_chk_cn61xx cn63xxp1;
+	struct cvmx_gmxx_rxx_frm_chk_cn61xx cn66xx;
+	struct cvmx_gmxx_rxx_frm_chk_cn61xx cn68xx;
+	struct cvmx_gmxx_rxx_frm_chk_cn61xx cn68xxp1;
+	struct cvmx_gmxx_rxx_frm_chk_cn61xx cnf71xx;
 };
 
 union cvmx_gmxx_rxx_frm_ctl {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_frm_ctl_s {
-		uint64_t reserved_11_63:53;
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_13_63:51;
+		uint64_t ptp_mode:1;
+		uint64_t reserved_11_11:1;
 		uint64_t null_dis:1;
 		uint64_t pre_align:1;
 		uint64_t pad_len:1;
@@ -665,8 +3098,25 @@
 		uint64_t ctl_drp:1;
 		uint64_t pre_strp:1;
 		uint64_t pre_chk:1;
+#else
+		uint64_t pre_chk:1;
+		uint64_t pre_strp:1;
+		uint64_t ctl_drp:1;
+		uint64_t ctl_bck:1;
+		uint64_t ctl_mcst:1;
+		uint64_t ctl_smac:1;
+		uint64_t pre_free:1;
+		uint64_t vlan_len:1;
+		uint64_t pad_len:1;
+		uint64_t pre_align:1;
+		uint64_t null_dis:1;
+		uint64_t reserved_11_11:1;
+		uint64_t ptp_mode:1;
+		uint64_t reserved_13_63:51;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_frm_ctl_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t pad_len:1;
 		uint64_t vlan_len:1;
@@ -677,8 +3127,21 @@
 		uint64_t ctl_drp:1;
 		uint64_t pre_strp:1;
 		uint64_t pre_chk:1;
+#else
+		uint64_t pre_chk:1;
+		uint64_t pre_strp:1;
+		uint64_t ctl_drp:1;
+		uint64_t ctl_bck:1;
+		uint64_t ctl_mcst:1;
+		uint64_t ctl_smac:1;
+		uint64_t pre_free:1;
+		uint64_t vlan_len:1;
+		uint64_t pad_len:1;
+		uint64_t reserved_9_63:55;
+#endif
 	} cn30xx;
 	struct cvmx_gmxx_rxx_frm_ctl_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t vlan_len:1;
 		uint64_t pre_free:1;
@@ -688,10 +3151,22 @@
 		uint64_t ctl_drp:1;
 		uint64_t pre_strp:1;
 		uint64_t pre_chk:1;
+#else
+		uint64_t pre_chk:1;
+		uint64_t pre_strp:1;
+		uint64_t ctl_drp:1;
+		uint64_t ctl_bck:1;
+		uint64_t ctl_mcst:1;
+		uint64_t ctl_smac:1;
+		uint64_t pre_free:1;
+		uint64_t vlan_len:1;
+		uint64_t reserved_8_63:56;
+#endif
 	} cn31xx;
 	struct cvmx_gmxx_rxx_frm_ctl_cn30xx cn38xx;
 	struct cvmx_gmxx_rxx_frm_ctl_cn31xx cn38xxp2;
 	struct cvmx_gmxx_rxx_frm_ctl_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_11_63:53;
 		uint64_t null_dis:1;
 		uint64_t pre_align:1;
@@ -703,11 +3178,25 @@
 		uint64_t ctl_drp:1;
 		uint64_t pre_strp:1;
 		uint64_t pre_chk:1;
+#else
+		uint64_t pre_chk:1;
+		uint64_t pre_strp:1;
+		uint64_t ctl_drp:1;
+		uint64_t ctl_bck:1;
+		uint64_t ctl_mcst:1;
+		uint64_t ctl_smac:1;
+		uint64_t pre_free:1;
+		uint64_t reserved_7_8:2;
+		uint64_t pre_align:1;
+		uint64_t null_dis:1;
+		uint64_t reserved_11_63:53;
+#endif
 	} cn50xx;
 	struct cvmx_gmxx_rxx_frm_ctl_cn50xx cn52xx;
 	struct cvmx_gmxx_rxx_frm_ctl_cn50xx cn52xxp1;
 	struct cvmx_gmxx_rxx_frm_ctl_cn50xx cn56xx;
 	struct cvmx_gmxx_rxx_frm_ctl_cn56xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t pre_align:1;
 		uint64_t reserved_7_8:2;
@@ -718,16 +3207,98 @@
 		uint64_t ctl_drp:1;
 		uint64_t pre_strp:1;
 		uint64_t pre_chk:1;
+#else
+		uint64_t pre_chk:1;
+		uint64_t pre_strp:1;
+		uint64_t ctl_drp:1;
+		uint64_t ctl_bck:1;
+		uint64_t ctl_mcst:1;
+		uint64_t ctl_smac:1;
+		uint64_t pre_free:1;
+		uint64_t reserved_7_8:2;
+		uint64_t pre_align:1;
+		uint64_t reserved_10_63:54;
+#endif
 	} cn56xxp1;
-	struct cvmx_gmxx_rxx_frm_ctl_s cn58xx;
+	struct cvmx_gmxx_rxx_frm_ctl_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_11_63:53;
+		uint64_t null_dis:1;
+		uint64_t pre_align:1;
+		uint64_t pad_len:1;
+		uint64_t vlan_len:1;
+		uint64_t pre_free:1;
+		uint64_t ctl_smac:1;
+		uint64_t ctl_mcst:1;
+		uint64_t ctl_bck:1;
+		uint64_t ctl_drp:1;
+		uint64_t pre_strp:1;
+		uint64_t pre_chk:1;
+#else
+		uint64_t pre_chk:1;
+		uint64_t pre_strp:1;
+		uint64_t ctl_drp:1;
+		uint64_t ctl_bck:1;
+		uint64_t ctl_mcst:1;
+		uint64_t ctl_smac:1;
+		uint64_t pre_free:1;
+		uint64_t vlan_len:1;
+		uint64_t pad_len:1;
+		uint64_t pre_align:1;
+		uint64_t null_dis:1;
+		uint64_t reserved_11_63:53;
+#endif
+	} cn58xx;
 	struct cvmx_gmxx_rxx_frm_ctl_cn30xx cn58xxp1;
+	struct cvmx_gmxx_rxx_frm_ctl_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_13_63:51;
+		uint64_t ptp_mode:1;
+		uint64_t reserved_11_11:1;
+		uint64_t null_dis:1;
+		uint64_t pre_align:1;
+		uint64_t reserved_7_8:2;
+		uint64_t pre_free:1;
+		uint64_t ctl_smac:1;
+		uint64_t ctl_mcst:1;
+		uint64_t ctl_bck:1;
+		uint64_t ctl_drp:1;
+		uint64_t pre_strp:1;
+		uint64_t pre_chk:1;
+#else
+		uint64_t pre_chk:1;
+		uint64_t pre_strp:1;
+		uint64_t ctl_drp:1;
+		uint64_t ctl_bck:1;
+		uint64_t ctl_mcst:1;
+		uint64_t ctl_smac:1;
+		uint64_t pre_free:1;
+		uint64_t reserved_7_8:2;
+		uint64_t pre_align:1;
+		uint64_t null_dis:1;
+		uint64_t reserved_11_11:1;
+		uint64_t ptp_mode:1;
+		uint64_t reserved_13_63:51;
+#endif
+	} cn61xx;
+	struct cvmx_gmxx_rxx_frm_ctl_cn61xx cn63xx;
+	struct cvmx_gmxx_rxx_frm_ctl_cn61xx cn63xxp1;
+	struct cvmx_gmxx_rxx_frm_ctl_cn61xx cn66xx;
+	struct cvmx_gmxx_rxx_frm_ctl_cn61xx cn68xx;
+	struct cvmx_gmxx_rxx_frm_ctl_cn61xx cn68xxp1;
+	struct cvmx_gmxx_rxx_frm_ctl_cn61xx cnf71xx;
 };
 
 union cvmx_gmxx_rxx_frm_max {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_frm_max_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t len:16;
+#else
+		uint64_t len:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_frm_max_s cn30xx;
 	struct cvmx_gmxx_rxx_frm_max_s cn31xx;
@@ -740,8 +3311,13 @@
 union cvmx_gmxx_rxx_frm_min {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_frm_min_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t len:16;
+#else
+		uint64_t len:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_frm_min_s cn30xx;
 	struct cvmx_gmxx_rxx_frm_min_s cn31xx;
@@ -754,8 +3330,13 @@
 union cvmx_gmxx_rxx_ifg {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_ifg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t ifg:4;
+#else
+		uint64_t ifg:4;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_ifg_s cn30xx;
 	struct cvmx_gmxx_rxx_ifg_s cn31xx;
@@ -768,11 +3349,19 @@
 	struct cvmx_gmxx_rxx_ifg_s cn56xxp1;
 	struct cvmx_gmxx_rxx_ifg_s cn58xx;
 	struct cvmx_gmxx_rxx_ifg_s cn58xxp1;
+	struct cvmx_gmxx_rxx_ifg_s cn61xx;
+	struct cvmx_gmxx_rxx_ifg_s cn63xx;
+	struct cvmx_gmxx_rxx_ifg_s cn63xxp1;
+	struct cvmx_gmxx_rxx_ifg_s cn66xx;
+	struct cvmx_gmxx_rxx_ifg_s cn68xx;
+	struct cvmx_gmxx_rxx_ifg_s cn68xxp1;
+	struct cvmx_gmxx_rxx_ifg_s cnf71xx;
 };
 
 union cvmx_gmxx_rxx_int_en {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_int_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_29_63:35;
 		uint64_t hg2cc:1;
 		uint64_t hg2fld:1;
@@ -803,8 +3392,41 @@
 		uint64_t maxerr:1;
 		uint64_t carext:1;
 		uint64_t minerr:1;
+#else
+		uint64_t minerr:1;
+		uint64_t carext:1;
+		uint64_t maxerr:1;
+		uint64_t jabber:1;
+		uint64_t fcserr:1;
+		uint64_t alnerr:1;
+		uint64_t lenerr:1;
+		uint64_t rcverr:1;
+		uint64_t skperr:1;
+		uint64_t niberr:1;
+		uint64_t ovrerr:1;
+		uint64_t pcterr:1;
+		uint64_t rsverr:1;
+		uint64_t falerr:1;
+		uint64_t coldet:1;
+		uint64_t ifgerr:1;
+		uint64_t phy_link:1;
+		uint64_t phy_spd:1;
+		uint64_t phy_dupx:1;
+		uint64_t pause_drp:1;
+		uint64_t loc_fault:1;
+		uint64_t rem_fault:1;
+		uint64_t bad_seq:1;
+		uint64_t bad_term:1;
+		uint64_t unsop:1;
+		uint64_t uneop:1;
+		uint64_t undat:1;
+		uint64_t hg2fld:1;
+		uint64_t hg2cc:1;
+		uint64_t reserved_29_63:35;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_int_en_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_19_63:45;
 		uint64_t phy_dupx:1;
 		uint64_t phy_spd:1;
@@ -825,11 +3447,34 @@
 		uint64_t maxerr:1;
 		uint64_t carext:1;
 		uint64_t minerr:1;
+#else
+		uint64_t minerr:1;
+		uint64_t carext:1;
+		uint64_t maxerr:1;
+		uint64_t jabber:1;
+		uint64_t fcserr:1;
+		uint64_t alnerr:1;
+		uint64_t lenerr:1;
+		uint64_t rcverr:1;
+		uint64_t skperr:1;
+		uint64_t niberr:1;
+		uint64_t ovrerr:1;
+		uint64_t pcterr:1;
+		uint64_t rsverr:1;
+		uint64_t falerr:1;
+		uint64_t coldet:1;
+		uint64_t ifgerr:1;
+		uint64_t phy_link:1;
+		uint64_t phy_spd:1;
+		uint64_t phy_dupx:1;
+		uint64_t reserved_19_63:45;
+#endif
 	} cn30xx;
 	struct cvmx_gmxx_rxx_int_en_cn30xx cn31xx;
 	struct cvmx_gmxx_rxx_int_en_cn30xx cn38xx;
 	struct cvmx_gmxx_rxx_int_en_cn30xx cn38xxp2;
 	struct cvmx_gmxx_rxx_int_en_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t pause_drp:1;
 		uint64_t phy_dupx:1;
@@ -851,8 +3496,32 @@
 		uint64_t reserved_2_2:1;
 		uint64_t carext:1;
 		uint64_t reserved_0_0:1;
+#else
+		uint64_t reserved_0_0:1;
+		uint64_t carext:1;
+		uint64_t reserved_2_2:1;
+		uint64_t jabber:1;
+		uint64_t fcserr:1;
+		uint64_t alnerr:1;
+		uint64_t reserved_6_6:1;
+		uint64_t rcverr:1;
+		uint64_t skperr:1;
+		uint64_t niberr:1;
+		uint64_t ovrerr:1;
+		uint64_t pcterr:1;
+		uint64_t rsverr:1;
+		uint64_t falerr:1;
+		uint64_t coldet:1;
+		uint64_t ifgerr:1;
+		uint64_t phy_link:1;
+		uint64_t phy_spd:1;
+		uint64_t phy_dupx:1;
+		uint64_t pause_drp:1;
+		uint64_t reserved_20_63:44;
+#endif
 	} cn50xx;
 	struct cvmx_gmxx_rxx_int_en_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_29_63:35;
 		uint64_t hg2cc:1;
 		uint64_t hg2fld:1;
@@ -880,10 +3549,40 @@
 		uint64_t reserved_2_2:1;
 		uint64_t carext:1;
 		uint64_t reserved_0_0:1;
+#else
+		uint64_t reserved_0_0:1;
+		uint64_t carext:1;
+		uint64_t reserved_2_2:1;
+		uint64_t jabber:1;
+		uint64_t fcserr:1;
+		uint64_t reserved_5_6:2;
+		uint64_t rcverr:1;
+		uint64_t skperr:1;
+		uint64_t reserved_9_9:1;
+		uint64_t ovrerr:1;
+		uint64_t pcterr:1;
+		uint64_t rsverr:1;
+		uint64_t falerr:1;
+		uint64_t coldet:1;
+		uint64_t ifgerr:1;
+		uint64_t reserved_16_18:3;
+		uint64_t pause_drp:1;
+		uint64_t loc_fault:1;
+		uint64_t rem_fault:1;
+		uint64_t bad_seq:1;
+		uint64_t bad_term:1;
+		uint64_t unsop:1;
+		uint64_t uneop:1;
+		uint64_t undat:1;
+		uint64_t hg2fld:1;
+		uint64_t hg2cc:1;
+		uint64_t reserved_29_63:35;
+#endif
 	} cn52xx;
 	struct cvmx_gmxx_rxx_int_en_cn52xx cn52xxp1;
 	struct cvmx_gmxx_rxx_int_en_cn52xx cn56xx;
 	struct cvmx_gmxx_rxx_int_en_cn56xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_27_63:37;
 		uint64_t undat:1;
 		uint64_t uneop:1;
@@ -909,8 +3608,36 @@
 		uint64_t reserved_2_2:1;
 		uint64_t carext:1;
 		uint64_t reserved_0_0:1;
+#else
+		uint64_t reserved_0_0:1;
+		uint64_t carext:1;
+		uint64_t reserved_2_2:1;
+		uint64_t jabber:1;
+		uint64_t fcserr:1;
+		uint64_t reserved_5_6:2;
+		uint64_t rcverr:1;
+		uint64_t skperr:1;
+		uint64_t reserved_9_9:1;
+		uint64_t ovrerr:1;
+		uint64_t pcterr:1;
+		uint64_t rsverr:1;
+		uint64_t falerr:1;
+		uint64_t coldet:1;
+		uint64_t ifgerr:1;
+		uint64_t reserved_16_18:3;
+		uint64_t pause_drp:1;
+		uint64_t loc_fault:1;
+		uint64_t rem_fault:1;
+		uint64_t bad_seq:1;
+		uint64_t bad_term:1;
+		uint64_t unsop:1;
+		uint64_t uneop:1;
+		uint64_t undat:1;
+		uint64_t reserved_27_63:37;
+#endif
 	} cn56xxp1;
 	struct cvmx_gmxx_rxx_int_en_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t pause_drp:1;
 		uint64_t phy_dupx:1;
@@ -932,13 +3659,102 @@
 		uint64_t maxerr:1;
 		uint64_t carext:1;
 		uint64_t minerr:1;
+#else
+		uint64_t minerr:1;
+		uint64_t carext:1;
+		uint64_t maxerr:1;
+		uint64_t jabber:1;
+		uint64_t fcserr:1;
+		uint64_t alnerr:1;
+		uint64_t lenerr:1;
+		uint64_t rcverr:1;
+		uint64_t skperr:1;
+		uint64_t niberr:1;
+		uint64_t ovrerr:1;
+		uint64_t pcterr:1;
+		uint64_t rsverr:1;
+		uint64_t falerr:1;
+		uint64_t coldet:1;
+		uint64_t ifgerr:1;
+		uint64_t phy_link:1;
+		uint64_t phy_spd:1;
+		uint64_t phy_dupx:1;
+		uint64_t pause_drp:1;
+		uint64_t reserved_20_63:44;
+#endif
 	} cn58xx;
 	struct cvmx_gmxx_rxx_int_en_cn58xx cn58xxp1;
+	struct cvmx_gmxx_rxx_int_en_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_29_63:35;
+		uint64_t hg2cc:1;
+		uint64_t hg2fld:1;
+		uint64_t undat:1;
+		uint64_t uneop:1;
+		uint64_t unsop:1;
+		uint64_t bad_term:1;
+		uint64_t bad_seq:1;
+		uint64_t rem_fault:1;
+		uint64_t loc_fault:1;
+		uint64_t pause_drp:1;
+		uint64_t reserved_16_18:3;
+		uint64_t ifgerr:1;
+		uint64_t coldet:1;
+		uint64_t falerr:1;
+		uint64_t rsverr:1;
+		uint64_t pcterr:1;
+		uint64_t ovrerr:1;
+		uint64_t reserved_9_9:1;
+		uint64_t skperr:1;
+		uint64_t rcverr:1;
+		uint64_t reserved_5_6:2;
+		uint64_t fcserr:1;
+		uint64_t jabber:1;
+		uint64_t reserved_2_2:1;
+		uint64_t carext:1;
+		uint64_t minerr:1;
+#else
+		uint64_t minerr:1;
+		uint64_t carext:1;
+		uint64_t reserved_2_2:1;
+		uint64_t jabber:1;
+		uint64_t fcserr:1;
+		uint64_t reserved_5_6:2;
+		uint64_t rcverr:1;
+		uint64_t skperr:1;
+		uint64_t reserved_9_9:1;
+		uint64_t ovrerr:1;
+		uint64_t pcterr:1;
+		uint64_t rsverr:1;
+		uint64_t falerr:1;
+		uint64_t coldet:1;
+		uint64_t ifgerr:1;
+		uint64_t reserved_16_18:3;
+		uint64_t pause_drp:1;
+		uint64_t loc_fault:1;
+		uint64_t rem_fault:1;
+		uint64_t bad_seq:1;
+		uint64_t bad_term:1;
+		uint64_t unsop:1;
+		uint64_t uneop:1;
+		uint64_t undat:1;
+		uint64_t hg2fld:1;
+		uint64_t hg2cc:1;
+		uint64_t reserved_29_63:35;
+#endif
+	} cn61xx;
+	struct cvmx_gmxx_rxx_int_en_cn61xx cn63xx;
+	struct cvmx_gmxx_rxx_int_en_cn61xx cn63xxp1;
+	struct cvmx_gmxx_rxx_int_en_cn61xx cn66xx;
+	struct cvmx_gmxx_rxx_int_en_cn61xx cn68xx;
+	struct cvmx_gmxx_rxx_int_en_cn61xx cn68xxp1;
+	struct cvmx_gmxx_rxx_int_en_cn61xx cnf71xx;
 };
 
 union cvmx_gmxx_rxx_int_reg {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_int_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_29_63:35;
 		uint64_t hg2cc:1;
 		uint64_t hg2fld:1;
@@ -969,8 +3785,41 @@
 		uint64_t maxerr:1;
 		uint64_t carext:1;
 		uint64_t minerr:1;
+#else
+		uint64_t minerr:1;
+		uint64_t carext:1;
+		uint64_t maxerr:1;
+		uint64_t jabber:1;
+		uint64_t fcserr:1;
+		uint64_t alnerr:1;
+		uint64_t lenerr:1;
+		uint64_t rcverr:1;
+		uint64_t skperr:1;
+		uint64_t niberr:1;
+		uint64_t ovrerr:1;
+		uint64_t pcterr:1;
+		uint64_t rsverr:1;
+		uint64_t falerr:1;
+		uint64_t coldet:1;
+		uint64_t ifgerr:1;
+		uint64_t phy_link:1;
+		uint64_t phy_spd:1;
+		uint64_t phy_dupx:1;
+		uint64_t pause_drp:1;
+		uint64_t loc_fault:1;
+		uint64_t rem_fault:1;
+		uint64_t bad_seq:1;
+		uint64_t bad_term:1;
+		uint64_t unsop:1;
+		uint64_t uneop:1;
+		uint64_t undat:1;
+		uint64_t hg2fld:1;
+		uint64_t hg2cc:1;
+		uint64_t reserved_29_63:35;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_int_reg_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_19_63:45;
 		uint64_t phy_dupx:1;
 		uint64_t phy_spd:1;
@@ -991,11 +3840,34 @@
 		uint64_t maxerr:1;
 		uint64_t carext:1;
 		uint64_t minerr:1;
+#else
+		uint64_t minerr:1;
+		uint64_t carext:1;
+		uint64_t maxerr:1;
+		uint64_t jabber:1;
+		uint64_t fcserr:1;
+		uint64_t alnerr:1;
+		uint64_t lenerr:1;
+		uint64_t rcverr:1;
+		uint64_t skperr:1;
+		uint64_t niberr:1;
+		uint64_t ovrerr:1;
+		uint64_t pcterr:1;
+		uint64_t rsverr:1;
+		uint64_t falerr:1;
+		uint64_t coldet:1;
+		uint64_t ifgerr:1;
+		uint64_t phy_link:1;
+		uint64_t phy_spd:1;
+		uint64_t phy_dupx:1;
+		uint64_t reserved_19_63:45;
+#endif
 	} cn30xx;
 	struct cvmx_gmxx_rxx_int_reg_cn30xx cn31xx;
 	struct cvmx_gmxx_rxx_int_reg_cn30xx cn38xx;
 	struct cvmx_gmxx_rxx_int_reg_cn30xx cn38xxp2;
 	struct cvmx_gmxx_rxx_int_reg_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t pause_drp:1;
 		uint64_t phy_dupx:1;
@@ -1017,8 +3889,32 @@
 		uint64_t reserved_2_2:1;
 		uint64_t carext:1;
 		uint64_t reserved_0_0:1;
+#else
+		uint64_t reserved_0_0:1;
+		uint64_t carext:1;
+		uint64_t reserved_2_2:1;
+		uint64_t jabber:1;
+		uint64_t fcserr:1;
+		uint64_t alnerr:1;
+		uint64_t reserved_6_6:1;
+		uint64_t rcverr:1;
+		uint64_t skperr:1;
+		uint64_t niberr:1;
+		uint64_t ovrerr:1;
+		uint64_t pcterr:1;
+		uint64_t rsverr:1;
+		uint64_t falerr:1;
+		uint64_t coldet:1;
+		uint64_t ifgerr:1;
+		uint64_t phy_link:1;
+		uint64_t phy_spd:1;
+		uint64_t phy_dupx:1;
+		uint64_t pause_drp:1;
+		uint64_t reserved_20_63:44;
+#endif
 	} cn50xx;
 	struct cvmx_gmxx_rxx_int_reg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_29_63:35;
 		uint64_t hg2cc:1;
 		uint64_t hg2fld:1;
@@ -1046,10 +3942,40 @@
 		uint64_t reserved_2_2:1;
 		uint64_t carext:1;
 		uint64_t reserved_0_0:1;
+#else
+		uint64_t reserved_0_0:1;
+		uint64_t carext:1;
+		uint64_t reserved_2_2:1;
+		uint64_t jabber:1;
+		uint64_t fcserr:1;
+		uint64_t reserved_5_6:2;
+		uint64_t rcverr:1;
+		uint64_t skperr:1;
+		uint64_t reserved_9_9:1;
+		uint64_t ovrerr:1;
+		uint64_t pcterr:1;
+		uint64_t rsverr:1;
+		uint64_t falerr:1;
+		uint64_t coldet:1;
+		uint64_t ifgerr:1;
+		uint64_t reserved_16_18:3;
+		uint64_t pause_drp:1;
+		uint64_t loc_fault:1;
+		uint64_t rem_fault:1;
+		uint64_t bad_seq:1;
+		uint64_t bad_term:1;
+		uint64_t unsop:1;
+		uint64_t uneop:1;
+		uint64_t undat:1;
+		uint64_t hg2fld:1;
+		uint64_t hg2cc:1;
+		uint64_t reserved_29_63:35;
+#endif
 	} cn52xx;
 	struct cvmx_gmxx_rxx_int_reg_cn52xx cn52xxp1;
 	struct cvmx_gmxx_rxx_int_reg_cn52xx cn56xx;
 	struct cvmx_gmxx_rxx_int_reg_cn56xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_27_63:37;
 		uint64_t undat:1;
 		uint64_t uneop:1;
@@ -1075,8 +4001,36 @@
 		uint64_t reserved_2_2:1;
 		uint64_t carext:1;
 		uint64_t reserved_0_0:1;
+#else
+		uint64_t reserved_0_0:1;
+		uint64_t carext:1;
+		uint64_t reserved_2_2:1;
+		uint64_t jabber:1;
+		uint64_t fcserr:1;
+		uint64_t reserved_5_6:2;
+		uint64_t rcverr:1;
+		uint64_t skperr:1;
+		uint64_t reserved_9_9:1;
+		uint64_t ovrerr:1;
+		uint64_t pcterr:1;
+		uint64_t rsverr:1;
+		uint64_t falerr:1;
+		uint64_t coldet:1;
+		uint64_t ifgerr:1;
+		uint64_t reserved_16_18:3;
+		uint64_t pause_drp:1;
+		uint64_t loc_fault:1;
+		uint64_t rem_fault:1;
+		uint64_t bad_seq:1;
+		uint64_t bad_term:1;
+		uint64_t unsop:1;
+		uint64_t uneop:1;
+		uint64_t undat:1;
+		uint64_t reserved_27_63:37;
+#endif
 	} cn56xxp1;
 	struct cvmx_gmxx_rxx_int_reg_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t pause_drp:1;
 		uint64_t phy_dupx:1;
@@ -1098,15 +4052,108 @@
 		uint64_t maxerr:1;
 		uint64_t carext:1;
 		uint64_t minerr:1;
+#else
+		uint64_t minerr:1;
+		uint64_t carext:1;
+		uint64_t maxerr:1;
+		uint64_t jabber:1;
+		uint64_t fcserr:1;
+		uint64_t alnerr:1;
+		uint64_t lenerr:1;
+		uint64_t rcverr:1;
+		uint64_t skperr:1;
+		uint64_t niberr:1;
+		uint64_t ovrerr:1;
+		uint64_t pcterr:1;
+		uint64_t rsverr:1;
+		uint64_t falerr:1;
+		uint64_t coldet:1;
+		uint64_t ifgerr:1;
+		uint64_t phy_link:1;
+		uint64_t phy_spd:1;
+		uint64_t phy_dupx:1;
+		uint64_t pause_drp:1;
+		uint64_t reserved_20_63:44;
+#endif
 	} cn58xx;
 	struct cvmx_gmxx_rxx_int_reg_cn58xx cn58xxp1;
+	struct cvmx_gmxx_rxx_int_reg_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_29_63:35;
+		uint64_t hg2cc:1;
+		uint64_t hg2fld:1;
+		uint64_t undat:1;
+		uint64_t uneop:1;
+		uint64_t unsop:1;
+		uint64_t bad_term:1;
+		uint64_t bad_seq:1;
+		uint64_t rem_fault:1;
+		uint64_t loc_fault:1;
+		uint64_t pause_drp:1;
+		uint64_t reserved_16_18:3;
+		uint64_t ifgerr:1;
+		uint64_t coldet:1;
+		uint64_t falerr:1;
+		uint64_t rsverr:1;
+		uint64_t pcterr:1;
+		uint64_t ovrerr:1;
+		uint64_t reserved_9_9:1;
+		uint64_t skperr:1;
+		uint64_t rcverr:1;
+		uint64_t reserved_5_6:2;
+		uint64_t fcserr:1;
+		uint64_t jabber:1;
+		uint64_t reserved_2_2:1;
+		uint64_t carext:1;
+		uint64_t minerr:1;
+#else
+		uint64_t minerr:1;
+		uint64_t carext:1;
+		uint64_t reserved_2_2:1;
+		uint64_t jabber:1;
+		uint64_t fcserr:1;
+		uint64_t reserved_5_6:2;
+		uint64_t rcverr:1;
+		uint64_t skperr:1;
+		uint64_t reserved_9_9:1;
+		uint64_t ovrerr:1;
+		uint64_t pcterr:1;
+		uint64_t rsverr:1;
+		uint64_t falerr:1;
+		uint64_t coldet:1;
+		uint64_t ifgerr:1;
+		uint64_t reserved_16_18:3;
+		uint64_t pause_drp:1;
+		uint64_t loc_fault:1;
+		uint64_t rem_fault:1;
+		uint64_t bad_seq:1;
+		uint64_t bad_term:1;
+		uint64_t unsop:1;
+		uint64_t uneop:1;
+		uint64_t undat:1;
+		uint64_t hg2fld:1;
+		uint64_t hg2cc:1;
+		uint64_t reserved_29_63:35;
+#endif
+	} cn61xx;
+	struct cvmx_gmxx_rxx_int_reg_cn61xx cn63xx;
+	struct cvmx_gmxx_rxx_int_reg_cn61xx cn63xxp1;
+	struct cvmx_gmxx_rxx_int_reg_cn61xx cn66xx;
+	struct cvmx_gmxx_rxx_int_reg_cn61xx cn68xx;
+	struct cvmx_gmxx_rxx_int_reg_cn61xx cn68xxp1;
+	struct cvmx_gmxx_rxx_int_reg_cn61xx cnf71xx;
 };
 
 union cvmx_gmxx_rxx_jabber {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_jabber_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t cnt:16;
+#else
+		uint64_t cnt:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_jabber_s cn30xx;
 	struct cvmx_gmxx_rxx_jabber_s cn31xx;
@@ -1119,13 +4166,25 @@
 	struct cvmx_gmxx_rxx_jabber_s cn56xxp1;
 	struct cvmx_gmxx_rxx_jabber_s cn58xx;
 	struct cvmx_gmxx_rxx_jabber_s cn58xxp1;
+	struct cvmx_gmxx_rxx_jabber_s cn61xx;
+	struct cvmx_gmxx_rxx_jabber_s cn63xx;
+	struct cvmx_gmxx_rxx_jabber_s cn63xxp1;
+	struct cvmx_gmxx_rxx_jabber_s cn66xx;
+	struct cvmx_gmxx_rxx_jabber_s cn68xx;
+	struct cvmx_gmxx_rxx_jabber_s cn68xxp1;
+	struct cvmx_gmxx_rxx_jabber_s cnf71xx;
 };
 
 union cvmx_gmxx_rxx_pause_drop_time {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_pause_drop_time_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t status:16;
+#else
+		uint64_t status:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_pause_drop_time_s cn50xx;
 	struct cvmx_gmxx_rxx_pause_drop_time_s cn52xx;
@@ -1134,15 +4193,29 @@
 	struct cvmx_gmxx_rxx_pause_drop_time_s cn56xxp1;
 	struct cvmx_gmxx_rxx_pause_drop_time_s cn58xx;
 	struct cvmx_gmxx_rxx_pause_drop_time_s cn58xxp1;
+	struct cvmx_gmxx_rxx_pause_drop_time_s cn61xx;
+	struct cvmx_gmxx_rxx_pause_drop_time_s cn63xx;
+	struct cvmx_gmxx_rxx_pause_drop_time_s cn63xxp1;
+	struct cvmx_gmxx_rxx_pause_drop_time_s cn66xx;
+	struct cvmx_gmxx_rxx_pause_drop_time_s cn68xx;
+	struct cvmx_gmxx_rxx_pause_drop_time_s cn68xxp1;
+	struct cvmx_gmxx_rxx_pause_drop_time_s cnf71xx;
 };
 
 union cvmx_gmxx_rxx_rx_inbnd {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_rx_inbnd_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t duplex:1;
 		uint64_t speed:2;
 		uint64_t status:1;
+#else
+		uint64_t status:1;
+		uint64_t speed:2;
+		uint64_t duplex:1;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_rx_inbnd_s cn30xx;
 	struct cvmx_gmxx_rxx_rx_inbnd_s cn31xx;
@@ -1156,8 +4229,13 @@
 union cvmx_gmxx_rxx_stats_ctl {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_stats_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t rd_clr:1;
+#else
+		uint64_t rd_clr:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_stats_ctl_s cn30xx;
 	struct cvmx_gmxx_rxx_stats_ctl_s cn31xx;
@@ -1170,13 +4248,25 @@
 	struct cvmx_gmxx_rxx_stats_ctl_s cn56xxp1;
 	struct cvmx_gmxx_rxx_stats_ctl_s cn58xx;
 	struct cvmx_gmxx_rxx_stats_ctl_s cn58xxp1;
+	struct cvmx_gmxx_rxx_stats_ctl_s cn61xx;
+	struct cvmx_gmxx_rxx_stats_ctl_s cn63xx;
+	struct cvmx_gmxx_rxx_stats_ctl_s cn63xxp1;
+	struct cvmx_gmxx_rxx_stats_ctl_s cn66xx;
+	struct cvmx_gmxx_rxx_stats_ctl_s cn68xx;
+	struct cvmx_gmxx_rxx_stats_ctl_s cn68xxp1;
+	struct cvmx_gmxx_rxx_stats_ctl_s cnf71xx;
 };
 
 union cvmx_gmxx_rxx_stats_octs {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_stats_octs_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t cnt:48;
+#else
+		uint64_t cnt:48;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_stats_octs_s cn30xx;
 	struct cvmx_gmxx_rxx_stats_octs_s cn31xx;
@@ -1189,13 +4279,25 @@
 	struct cvmx_gmxx_rxx_stats_octs_s cn56xxp1;
 	struct cvmx_gmxx_rxx_stats_octs_s cn58xx;
 	struct cvmx_gmxx_rxx_stats_octs_s cn58xxp1;
+	struct cvmx_gmxx_rxx_stats_octs_s cn61xx;
+	struct cvmx_gmxx_rxx_stats_octs_s cn63xx;
+	struct cvmx_gmxx_rxx_stats_octs_s cn63xxp1;
+	struct cvmx_gmxx_rxx_stats_octs_s cn66xx;
+	struct cvmx_gmxx_rxx_stats_octs_s cn68xx;
+	struct cvmx_gmxx_rxx_stats_octs_s cn68xxp1;
+	struct cvmx_gmxx_rxx_stats_octs_s cnf71xx;
 };
 
 union cvmx_gmxx_rxx_stats_octs_ctl {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_stats_octs_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t cnt:48;
+#else
+		uint64_t cnt:48;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_stats_octs_ctl_s cn30xx;
 	struct cvmx_gmxx_rxx_stats_octs_ctl_s cn31xx;
@@ -1208,13 +4310,25 @@
 	struct cvmx_gmxx_rxx_stats_octs_ctl_s cn56xxp1;
 	struct cvmx_gmxx_rxx_stats_octs_ctl_s cn58xx;
 	struct cvmx_gmxx_rxx_stats_octs_ctl_s cn58xxp1;
+	struct cvmx_gmxx_rxx_stats_octs_ctl_s cn61xx;
+	struct cvmx_gmxx_rxx_stats_octs_ctl_s cn63xx;
+	struct cvmx_gmxx_rxx_stats_octs_ctl_s cn63xxp1;
+	struct cvmx_gmxx_rxx_stats_octs_ctl_s cn66xx;
+	struct cvmx_gmxx_rxx_stats_octs_ctl_s cn68xx;
+	struct cvmx_gmxx_rxx_stats_octs_ctl_s cn68xxp1;
+	struct cvmx_gmxx_rxx_stats_octs_ctl_s cnf71xx;
 };
 
 union cvmx_gmxx_rxx_stats_octs_dmac {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_stats_octs_dmac_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t cnt:48;
+#else
+		uint64_t cnt:48;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_stats_octs_dmac_s cn30xx;
 	struct cvmx_gmxx_rxx_stats_octs_dmac_s cn31xx;
@@ -1227,13 +4341,25 @@
 	struct cvmx_gmxx_rxx_stats_octs_dmac_s cn56xxp1;
 	struct cvmx_gmxx_rxx_stats_octs_dmac_s cn58xx;
 	struct cvmx_gmxx_rxx_stats_octs_dmac_s cn58xxp1;
+	struct cvmx_gmxx_rxx_stats_octs_dmac_s cn61xx;
+	struct cvmx_gmxx_rxx_stats_octs_dmac_s cn63xx;
+	struct cvmx_gmxx_rxx_stats_octs_dmac_s cn63xxp1;
+	struct cvmx_gmxx_rxx_stats_octs_dmac_s cn66xx;
+	struct cvmx_gmxx_rxx_stats_octs_dmac_s cn68xx;
+	struct cvmx_gmxx_rxx_stats_octs_dmac_s cn68xxp1;
+	struct cvmx_gmxx_rxx_stats_octs_dmac_s cnf71xx;
 };
 
 union cvmx_gmxx_rxx_stats_octs_drp {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_stats_octs_drp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t cnt:48;
+#else
+		uint64_t cnt:48;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_stats_octs_drp_s cn30xx;
 	struct cvmx_gmxx_rxx_stats_octs_drp_s cn31xx;
@@ -1246,13 +4372,25 @@
 	struct cvmx_gmxx_rxx_stats_octs_drp_s cn56xxp1;
 	struct cvmx_gmxx_rxx_stats_octs_drp_s cn58xx;
 	struct cvmx_gmxx_rxx_stats_octs_drp_s cn58xxp1;
+	struct cvmx_gmxx_rxx_stats_octs_drp_s cn61xx;
+	struct cvmx_gmxx_rxx_stats_octs_drp_s cn63xx;
+	struct cvmx_gmxx_rxx_stats_octs_drp_s cn63xxp1;
+	struct cvmx_gmxx_rxx_stats_octs_drp_s cn66xx;
+	struct cvmx_gmxx_rxx_stats_octs_drp_s cn68xx;
+	struct cvmx_gmxx_rxx_stats_octs_drp_s cn68xxp1;
+	struct cvmx_gmxx_rxx_stats_octs_drp_s cnf71xx;
 };
 
 union cvmx_gmxx_rxx_stats_pkts {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_stats_pkts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_stats_pkts_s cn30xx;
 	struct cvmx_gmxx_rxx_stats_pkts_s cn31xx;
@@ -1265,13 +4403,25 @@
 	struct cvmx_gmxx_rxx_stats_pkts_s cn56xxp1;
 	struct cvmx_gmxx_rxx_stats_pkts_s cn58xx;
 	struct cvmx_gmxx_rxx_stats_pkts_s cn58xxp1;
+	struct cvmx_gmxx_rxx_stats_pkts_s cn61xx;
+	struct cvmx_gmxx_rxx_stats_pkts_s cn63xx;
+	struct cvmx_gmxx_rxx_stats_pkts_s cn63xxp1;
+	struct cvmx_gmxx_rxx_stats_pkts_s cn66xx;
+	struct cvmx_gmxx_rxx_stats_pkts_s cn68xx;
+	struct cvmx_gmxx_rxx_stats_pkts_s cn68xxp1;
+	struct cvmx_gmxx_rxx_stats_pkts_s cnf71xx;
 };
 
 union cvmx_gmxx_rxx_stats_pkts_bad {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_stats_pkts_bad_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_stats_pkts_bad_s cn30xx;
 	struct cvmx_gmxx_rxx_stats_pkts_bad_s cn31xx;
@@ -1284,13 +4434,25 @@
 	struct cvmx_gmxx_rxx_stats_pkts_bad_s cn56xxp1;
 	struct cvmx_gmxx_rxx_stats_pkts_bad_s cn58xx;
 	struct cvmx_gmxx_rxx_stats_pkts_bad_s cn58xxp1;
+	struct cvmx_gmxx_rxx_stats_pkts_bad_s cn61xx;
+	struct cvmx_gmxx_rxx_stats_pkts_bad_s cn63xx;
+	struct cvmx_gmxx_rxx_stats_pkts_bad_s cn63xxp1;
+	struct cvmx_gmxx_rxx_stats_pkts_bad_s cn66xx;
+	struct cvmx_gmxx_rxx_stats_pkts_bad_s cn68xx;
+	struct cvmx_gmxx_rxx_stats_pkts_bad_s cn68xxp1;
+	struct cvmx_gmxx_rxx_stats_pkts_bad_s cnf71xx;
 };
 
 union cvmx_gmxx_rxx_stats_pkts_ctl {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_stats_pkts_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn30xx;
 	struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn31xx;
@@ -1303,13 +4465,25 @@
 	struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn56xxp1;
 	struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn58xx;
 	struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn58xxp1;
+	struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn61xx;
+	struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn63xx;
+	struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn63xxp1;
+	struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn66xx;
+	struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn68xx;
+	struct cvmx_gmxx_rxx_stats_pkts_ctl_s cn68xxp1;
+	struct cvmx_gmxx_rxx_stats_pkts_ctl_s cnf71xx;
 };
 
 union cvmx_gmxx_rxx_stats_pkts_dmac {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_stats_pkts_dmac_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn30xx;
 	struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn31xx;
@@ -1322,13 +4496,25 @@
 	struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn56xxp1;
 	struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn58xx;
 	struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn58xxp1;
+	struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn61xx;
+	struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn63xx;
+	struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn63xxp1;
+	struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn66xx;
+	struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn68xx;
+	struct cvmx_gmxx_rxx_stats_pkts_dmac_s cn68xxp1;
+	struct cvmx_gmxx_rxx_stats_pkts_dmac_s cnf71xx;
 };
 
 union cvmx_gmxx_rxx_stats_pkts_drp {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_stats_pkts_drp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_stats_pkts_drp_s cn30xx;
 	struct cvmx_gmxx_rxx_stats_pkts_drp_s cn31xx;
@@ -1341,15 +4527,29 @@
 	struct cvmx_gmxx_rxx_stats_pkts_drp_s cn56xxp1;
 	struct cvmx_gmxx_rxx_stats_pkts_drp_s cn58xx;
 	struct cvmx_gmxx_rxx_stats_pkts_drp_s cn58xxp1;
+	struct cvmx_gmxx_rxx_stats_pkts_drp_s cn61xx;
+	struct cvmx_gmxx_rxx_stats_pkts_drp_s cn63xx;
+	struct cvmx_gmxx_rxx_stats_pkts_drp_s cn63xxp1;
+	struct cvmx_gmxx_rxx_stats_pkts_drp_s cn66xx;
+	struct cvmx_gmxx_rxx_stats_pkts_drp_s cn68xx;
+	struct cvmx_gmxx_rxx_stats_pkts_drp_s cn68xxp1;
+	struct cvmx_gmxx_rxx_stats_pkts_drp_s cnf71xx;
 };
 
 union cvmx_gmxx_rxx_udd_skp {
 	uint64_t u64;
 	struct cvmx_gmxx_rxx_udd_skp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t fcssel:1;
 		uint64_t reserved_7_7:1;
 		uint64_t len:7;
+#else
+		uint64_t len:7;
+		uint64_t reserved_7_7:1;
+		uint64_t fcssel:1;
+		uint64_t reserved_9_63:55;
+#endif
 	} s;
 	struct cvmx_gmxx_rxx_udd_skp_s cn30xx;
 	struct cvmx_gmxx_rxx_udd_skp_s cn31xx;
@@ -1362,13 +4562,25 @@
 	struct cvmx_gmxx_rxx_udd_skp_s cn56xxp1;
 	struct cvmx_gmxx_rxx_udd_skp_s cn58xx;
 	struct cvmx_gmxx_rxx_udd_skp_s cn58xxp1;
+	struct cvmx_gmxx_rxx_udd_skp_s cn61xx;
+	struct cvmx_gmxx_rxx_udd_skp_s cn63xx;
+	struct cvmx_gmxx_rxx_udd_skp_s cn63xxp1;
+	struct cvmx_gmxx_rxx_udd_skp_s cn66xx;
+	struct cvmx_gmxx_rxx_udd_skp_s cn68xx;
+	struct cvmx_gmxx_rxx_udd_skp_s cn68xxp1;
+	struct cvmx_gmxx_rxx_udd_skp_s cnf71xx;
 };
 
 union cvmx_gmxx_rx_bp_dropx {
 	uint64_t u64;
 	struct cvmx_gmxx_rx_bp_dropx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t mark:6;
+#else
+		uint64_t mark:6;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
 	struct cvmx_gmxx_rx_bp_dropx_s cn30xx;
 	struct cvmx_gmxx_rx_bp_dropx_s cn31xx;
@@ -1381,13 +4593,25 @@
 	struct cvmx_gmxx_rx_bp_dropx_s cn56xxp1;
 	struct cvmx_gmxx_rx_bp_dropx_s cn58xx;
 	struct cvmx_gmxx_rx_bp_dropx_s cn58xxp1;
+	struct cvmx_gmxx_rx_bp_dropx_s cn61xx;
+	struct cvmx_gmxx_rx_bp_dropx_s cn63xx;
+	struct cvmx_gmxx_rx_bp_dropx_s cn63xxp1;
+	struct cvmx_gmxx_rx_bp_dropx_s cn66xx;
+	struct cvmx_gmxx_rx_bp_dropx_s cn68xx;
+	struct cvmx_gmxx_rx_bp_dropx_s cn68xxp1;
+	struct cvmx_gmxx_rx_bp_dropx_s cnf71xx;
 };
 
 union cvmx_gmxx_rx_bp_offx {
 	uint64_t u64;
 	struct cvmx_gmxx_rx_bp_offx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t mark:6;
+#else
+		uint64_t mark:6;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
 	struct cvmx_gmxx_rx_bp_offx_s cn30xx;
 	struct cvmx_gmxx_rx_bp_offx_s cn31xx;
@@ -1400,45 +4624,91 @@
 	struct cvmx_gmxx_rx_bp_offx_s cn56xxp1;
 	struct cvmx_gmxx_rx_bp_offx_s cn58xx;
 	struct cvmx_gmxx_rx_bp_offx_s cn58xxp1;
+	struct cvmx_gmxx_rx_bp_offx_s cn61xx;
+	struct cvmx_gmxx_rx_bp_offx_s cn63xx;
+	struct cvmx_gmxx_rx_bp_offx_s cn63xxp1;
+	struct cvmx_gmxx_rx_bp_offx_s cn66xx;
+	struct cvmx_gmxx_rx_bp_offx_s cn68xx;
+	struct cvmx_gmxx_rx_bp_offx_s cn68xxp1;
+	struct cvmx_gmxx_rx_bp_offx_s cnf71xx;
 };
 
 union cvmx_gmxx_rx_bp_onx {
 	uint64_t u64;
 	struct cvmx_gmxx_rx_bp_onx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_11_63:53;
+		uint64_t mark:11;
+#else
+		uint64_t mark:11;
+		uint64_t reserved_11_63:53;
+#endif
+	} s;
+	struct cvmx_gmxx_rx_bp_onx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t mark:9;
-	} s;
-	struct cvmx_gmxx_rx_bp_onx_s cn30xx;
-	struct cvmx_gmxx_rx_bp_onx_s cn31xx;
-	struct cvmx_gmxx_rx_bp_onx_s cn38xx;
-	struct cvmx_gmxx_rx_bp_onx_s cn38xxp2;
-	struct cvmx_gmxx_rx_bp_onx_s cn50xx;
-	struct cvmx_gmxx_rx_bp_onx_s cn52xx;
-	struct cvmx_gmxx_rx_bp_onx_s cn52xxp1;
-	struct cvmx_gmxx_rx_bp_onx_s cn56xx;
-	struct cvmx_gmxx_rx_bp_onx_s cn56xxp1;
-	struct cvmx_gmxx_rx_bp_onx_s cn58xx;
-	struct cvmx_gmxx_rx_bp_onx_s cn58xxp1;
+#else
+		uint64_t mark:9;
+		uint64_t reserved_9_63:55;
+#endif
+	} cn30xx;
+	struct cvmx_gmxx_rx_bp_onx_cn30xx cn31xx;
+	struct cvmx_gmxx_rx_bp_onx_cn30xx cn38xx;
+	struct cvmx_gmxx_rx_bp_onx_cn30xx cn38xxp2;
+	struct cvmx_gmxx_rx_bp_onx_cn30xx cn50xx;
+	struct cvmx_gmxx_rx_bp_onx_cn30xx cn52xx;
+	struct cvmx_gmxx_rx_bp_onx_cn30xx cn52xxp1;
+	struct cvmx_gmxx_rx_bp_onx_cn30xx cn56xx;
+	struct cvmx_gmxx_rx_bp_onx_cn30xx cn56xxp1;
+	struct cvmx_gmxx_rx_bp_onx_cn30xx cn58xx;
+	struct cvmx_gmxx_rx_bp_onx_cn30xx cn58xxp1;
+	struct cvmx_gmxx_rx_bp_onx_cn30xx cn61xx;
+	struct cvmx_gmxx_rx_bp_onx_cn30xx cn63xx;
+	struct cvmx_gmxx_rx_bp_onx_cn30xx cn63xxp1;
+	struct cvmx_gmxx_rx_bp_onx_cn30xx cn66xx;
+	struct cvmx_gmxx_rx_bp_onx_s cn68xx;
+	struct cvmx_gmxx_rx_bp_onx_s cn68xxp1;
+	struct cvmx_gmxx_rx_bp_onx_cn30xx cnf71xx;
 };
 
 union cvmx_gmxx_rx_hg2_status {
 	uint64_t u64;
 	struct cvmx_gmxx_rx_hg2_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t phtim2go:16;
 		uint64_t xof:16;
 		uint64_t lgtim2go:16;
+#else
+		uint64_t lgtim2go:16;
+		uint64_t xof:16;
+		uint64_t phtim2go:16;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_gmxx_rx_hg2_status_s cn52xx;
 	struct cvmx_gmxx_rx_hg2_status_s cn52xxp1;
 	struct cvmx_gmxx_rx_hg2_status_s cn56xx;
+	struct cvmx_gmxx_rx_hg2_status_s cn61xx;
+	struct cvmx_gmxx_rx_hg2_status_s cn63xx;
+	struct cvmx_gmxx_rx_hg2_status_s cn63xxp1;
+	struct cvmx_gmxx_rx_hg2_status_s cn66xx;
+	struct cvmx_gmxx_rx_hg2_status_s cn68xx;
+	struct cvmx_gmxx_rx_hg2_status_s cn68xxp1;
+	struct cvmx_gmxx_rx_hg2_status_s cnf71xx;
 };
 
 union cvmx_gmxx_rx_pass_en {
 	uint64_t u64;
 	struct cvmx_gmxx_rx_pass_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t en:16;
+#else
+		uint64_t en:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_gmxx_rx_pass_en_s cn38xx;
 	struct cvmx_gmxx_rx_pass_en_s cn38xxp2;
@@ -1449,8 +4719,13 @@
 union cvmx_gmxx_rx_pass_mapx {
 	uint64_t u64;
 	struct cvmx_gmxx_rx_pass_mapx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t dprt:4;
+#else
+		uint64_t dprt:4;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_gmxx_rx_pass_mapx_s cn38xx;
 	struct cvmx_gmxx_rx_pass_mapx_s cn38xxp2;
@@ -1461,37 +4736,81 @@
 union cvmx_gmxx_rx_prt_info {
 	uint64_t u64;
 	struct cvmx_gmxx_rx_prt_info_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t drop:16;
 		uint64_t commit:16;
+#else
+		uint64_t commit:16;
+		uint64_t drop:16;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_gmxx_rx_prt_info_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_19_63:45;
 		uint64_t drop:3;
 		uint64_t reserved_3_15:13;
 		uint64_t commit:3;
+#else
+		uint64_t commit:3;
+		uint64_t reserved_3_15:13;
+		uint64_t drop:3;
+		uint64_t reserved_19_63:45;
+#endif
 	} cn30xx;
 	struct cvmx_gmxx_rx_prt_info_cn30xx cn31xx;
 	struct cvmx_gmxx_rx_prt_info_s cn38xx;
 	struct cvmx_gmxx_rx_prt_info_cn30xx cn50xx;
 	struct cvmx_gmxx_rx_prt_info_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t drop:4;
 		uint64_t reserved_4_15:12;
 		uint64_t commit:4;
+#else
+		uint64_t commit:4;
+		uint64_t reserved_4_15:12;
+		uint64_t drop:4;
+		uint64_t reserved_20_63:44;
+#endif
 	} cn52xx;
 	struct cvmx_gmxx_rx_prt_info_cn52xx cn52xxp1;
 	struct cvmx_gmxx_rx_prt_info_cn52xx cn56xx;
 	struct cvmx_gmxx_rx_prt_info_cn52xx cn56xxp1;
 	struct cvmx_gmxx_rx_prt_info_s cn58xx;
 	struct cvmx_gmxx_rx_prt_info_s cn58xxp1;
+	struct cvmx_gmxx_rx_prt_info_cn52xx cn61xx;
+	struct cvmx_gmxx_rx_prt_info_cn52xx cn63xx;
+	struct cvmx_gmxx_rx_prt_info_cn52xx cn63xxp1;
+	struct cvmx_gmxx_rx_prt_info_cn52xx cn66xx;
+	struct cvmx_gmxx_rx_prt_info_cn52xx cn68xx;
+	struct cvmx_gmxx_rx_prt_info_cn52xx cn68xxp1;
+	struct cvmx_gmxx_rx_prt_info_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_18_63:46;
+		uint64_t drop:2;
+		uint64_t reserved_2_15:14;
+		uint64_t commit:2;
+#else
+		uint64_t commit:2;
+		uint64_t reserved_2_15:14;
+		uint64_t drop:2;
+		uint64_t reserved_18_63:46;
+#endif
+	} cnf71xx;
 };
 
 union cvmx_gmxx_rx_prts {
 	uint64_t u64;
 	struct cvmx_gmxx_rx_prts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_3_63:61;
 		uint64_t prts:3;
+#else
+		uint64_t prts:3;
+		uint64_t reserved_3_63:61;
+#endif
 	} s;
 	struct cvmx_gmxx_rx_prts_s cn30xx;
 	struct cvmx_gmxx_rx_prts_s cn31xx;
@@ -1504,15 +4823,29 @@
 	struct cvmx_gmxx_rx_prts_s cn56xxp1;
 	struct cvmx_gmxx_rx_prts_s cn58xx;
 	struct cvmx_gmxx_rx_prts_s cn58xxp1;
+	struct cvmx_gmxx_rx_prts_s cn61xx;
+	struct cvmx_gmxx_rx_prts_s cn63xx;
+	struct cvmx_gmxx_rx_prts_s cn63xxp1;
+	struct cvmx_gmxx_rx_prts_s cn66xx;
+	struct cvmx_gmxx_rx_prts_s cn68xx;
+	struct cvmx_gmxx_rx_prts_s cn68xxp1;
+	struct cvmx_gmxx_rx_prts_s cnf71xx;
 };
 
 union cvmx_gmxx_rx_tx_status {
 	uint64_t u64;
 	struct cvmx_gmxx_rx_tx_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_7_63:57;
 		uint64_t tx:3;
 		uint64_t reserved_3_3:1;
 		uint64_t rx:3;
+#else
+		uint64_t rx:3;
+		uint64_t reserved_3_3:1;
+		uint64_t tx:3;
+		uint64_t reserved_7_63:57;
+#endif
 	} s;
 	struct cvmx_gmxx_rx_tx_status_s cn30xx;
 	struct cvmx_gmxx_rx_tx_status_s cn31xx;
@@ -1522,35 +4855,82 @@
 union cvmx_gmxx_rx_xaui_bad_col {
 	uint64_t u64;
 	struct cvmx_gmxx_rx_xaui_bad_col_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_40_63:24;
 		uint64_t val:1;
 		uint64_t state:3;
 		uint64_t lane_rxc:4;
 		uint64_t lane_rxd:32;
+#else
+		uint64_t lane_rxd:32;
+		uint64_t lane_rxc:4;
+		uint64_t state:3;
+		uint64_t val:1;
+		uint64_t reserved_40_63:24;
+#endif
 	} s;
 	struct cvmx_gmxx_rx_xaui_bad_col_s cn52xx;
 	struct cvmx_gmxx_rx_xaui_bad_col_s cn52xxp1;
 	struct cvmx_gmxx_rx_xaui_bad_col_s cn56xx;
 	struct cvmx_gmxx_rx_xaui_bad_col_s cn56xxp1;
+	struct cvmx_gmxx_rx_xaui_bad_col_s cn61xx;
+	struct cvmx_gmxx_rx_xaui_bad_col_s cn63xx;
+	struct cvmx_gmxx_rx_xaui_bad_col_s cn63xxp1;
+	struct cvmx_gmxx_rx_xaui_bad_col_s cn66xx;
+	struct cvmx_gmxx_rx_xaui_bad_col_s cn68xx;
+	struct cvmx_gmxx_rx_xaui_bad_col_s cn68xxp1;
+	struct cvmx_gmxx_rx_xaui_bad_col_s cnf71xx;
 };
 
 union cvmx_gmxx_rx_xaui_ctl {
 	uint64_t u64;
 	struct cvmx_gmxx_rx_xaui_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t status:2;
+#else
+		uint64_t status:2;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_gmxx_rx_xaui_ctl_s cn52xx;
 	struct cvmx_gmxx_rx_xaui_ctl_s cn52xxp1;
 	struct cvmx_gmxx_rx_xaui_ctl_s cn56xx;
 	struct cvmx_gmxx_rx_xaui_ctl_s cn56xxp1;
+	struct cvmx_gmxx_rx_xaui_ctl_s cn61xx;
+	struct cvmx_gmxx_rx_xaui_ctl_s cn63xx;
+	struct cvmx_gmxx_rx_xaui_ctl_s cn63xxp1;
+	struct cvmx_gmxx_rx_xaui_ctl_s cn66xx;
+	struct cvmx_gmxx_rx_xaui_ctl_s cn68xx;
+	struct cvmx_gmxx_rx_xaui_ctl_s cn68xxp1;
+	struct cvmx_gmxx_rx_xaui_ctl_s cnf71xx;
+};
+
+union cvmx_gmxx_rxaui_ctl {
+	uint64_t u64;
+	struct cvmx_gmxx_rxaui_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_1_63:63;
+		uint64_t disparity:1;
+#else
+		uint64_t disparity:1;
+		uint64_t reserved_1_63:63;
+#endif
+	} s;
+	struct cvmx_gmxx_rxaui_ctl_s cn68xx;
+	struct cvmx_gmxx_rxaui_ctl_s cn68xxp1;
 };
 
 union cvmx_gmxx_smacx {
 	uint64_t u64;
 	struct cvmx_gmxx_smacx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t smac:48;
+#else
+		uint64_t smac:48;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_gmxx_smacx_s cn30xx;
 	struct cvmx_gmxx_smacx_s cn31xx;
@@ -1563,14 +4943,47 @@
 	struct cvmx_gmxx_smacx_s cn56xxp1;
 	struct cvmx_gmxx_smacx_s cn58xx;
 	struct cvmx_gmxx_smacx_s cn58xxp1;
+	struct cvmx_gmxx_smacx_s cn61xx;
+	struct cvmx_gmxx_smacx_s cn63xx;
+	struct cvmx_gmxx_smacx_s cn63xxp1;
+	struct cvmx_gmxx_smacx_s cn66xx;
+	struct cvmx_gmxx_smacx_s cn68xx;
+	struct cvmx_gmxx_smacx_s cn68xxp1;
+	struct cvmx_gmxx_smacx_s cnf71xx;
+};
+
+union cvmx_gmxx_soft_bist {
+	uint64_t u64;
+	struct cvmx_gmxx_soft_bist_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_2_63:62;
+		uint64_t start_bist:1;
+		uint64_t clear_bist:1;
+#else
+		uint64_t clear_bist:1;
+		uint64_t start_bist:1;
+		uint64_t reserved_2_63:62;
+#endif
+	} s;
+	struct cvmx_gmxx_soft_bist_s cn63xx;
+	struct cvmx_gmxx_soft_bist_s cn63xxp1;
+	struct cvmx_gmxx_soft_bist_s cn66xx;
+	struct cvmx_gmxx_soft_bist_s cn68xx;
+	struct cvmx_gmxx_soft_bist_s cn68xxp1;
 };
 
 union cvmx_gmxx_stat_bp {
 	uint64_t u64;
 	struct cvmx_gmxx_stat_bp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_17_63:47;
 		uint64_t bp:1;
 		uint64_t cnt:16;
+#else
+		uint64_t cnt:16;
+		uint64_t bp:1;
+		uint64_t reserved_17_63:47;
+#endif
 	} s;
 	struct cvmx_gmxx_stat_bp_s cn30xx;
 	struct cvmx_gmxx_stat_bp_s cn31xx;
@@ -1583,16 +4996,48 @@
 	struct cvmx_gmxx_stat_bp_s cn56xxp1;
 	struct cvmx_gmxx_stat_bp_s cn58xx;
 	struct cvmx_gmxx_stat_bp_s cn58xxp1;
+	struct cvmx_gmxx_stat_bp_s cn61xx;
+	struct cvmx_gmxx_stat_bp_s cn63xx;
+	struct cvmx_gmxx_stat_bp_s cn63xxp1;
+	struct cvmx_gmxx_stat_bp_s cn66xx;
+	struct cvmx_gmxx_stat_bp_s cn68xx;
+	struct cvmx_gmxx_stat_bp_s cn68xxp1;
+	struct cvmx_gmxx_stat_bp_s cnf71xx;
+};
+
+union cvmx_gmxx_tb_reg {
+	uint64_t u64;
+	struct cvmx_gmxx_tb_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_1_63:63;
+		uint64_t wr_magic:1;
+#else
+		uint64_t wr_magic:1;
+		uint64_t reserved_1_63:63;
+#endif
+	} s;
+	struct cvmx_gmxx_tb_reg_s cn61xx;
+	struct cvmx_gmxx_tb_reg_s cn66xx;
+	struct cvmx_gmxx_tb_reg_s cn68xx;
+	struct cvmx_gmxx_tb_reg_s cnf71xx;
 };
 
 union cvmx_gmxx_txx_append {
 	uint64_t u64;
 	struct cvmx_gmxx_txx_append_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t force_fcs:1;
 		uint64_t fcs:1;
 		uint64_t pad:1;
 		uint64_t preamble:1;
+#else
+		uint64_t preamble:1;
+		uint64_t pad:1;
+		uint64_t fcs:1;
+		uint64_t force_fcs:1;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_gmxx_txx_append_s cn30xx;
 	struct cvmx_gmxx_txx_append_s cn31xx;
@@ -1605,13 +5050,25 @@
 	struct cvmx_gmxx_txx_append_s cn56xxp1;
 	struct cvmx_gmxx_txx_append_s cn58xx;
 	struct cvmx_gmxx_txx_append_s cn58xxp1;
+	struct cvmx_gmxx_txx_append_s cn61xx;
+	struct cvmx_gmxx_txx_append_s cn63xx;
+	struct cvmx_gmxx_txx_append_s cn63xxp1;
+	struct cvmx_gmxx_txx_append_s cn66xx;
+	struct cvmx_gmxx_txx_append_s cn68xx;
+	struct cvmx_gmxx_txx_append_s cn68xxp1;
+	struct cvmx_gmxx_txx_append_s cnf71xx;
 };
 
 union cvmx_gmxx_txx_burst {
 	uint64_t u64;
 	struct cvmx_gmxx_txx_burst_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t burst:16;
+#else
+		uint64_t burst:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_gmxx_txx_burst_s cn30xx;
 	struct cvmx_gmxx_txx_burst_s cn31xx;
@@ -1624,33 +5081,69 @@
 	struct cvmx_gmxx_txx_burst_s cn56xxp1;
 	struct cvmx_gmxx_txx_burst_s cn58xx;
 	struct cvmx_gmxx_txx_burst_s cn58xxp1;
+	struct cvmx_gmxx_txx_burst_s cn61xx;
+	struct cvmx_gmxx_txx_burst_s cn63xx;
+	struct cvmx_gmxx_txx_burst_s cn63xxp1;
+	struct cvmx_gmxx_txx_burst_s cn66xx;
+	struct cvmx_gmxx_txx_burst_s cn68xx;
+	struct cvmx_gmxx_txx_burst_s cn68xxp1;
+	struct cvmx_gmxx_txx_burst_s cnf71xx;
 };
 
 union cvmx_gmxx_txx_cbfc_xoff {
 	uint64_t u64;
 	struct cvmx_gmxx_txx_cbfc_xoff_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t xoff:16;
+#else
+		uint64_t xoff:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_gmxx_txx_cbfc_xoff_s cn52xx;
 	struct cvmx_gmxx_txx_cbfc_xoff_s cn56xx;
+	struct cvmx_gmxx_txx_cbfc_xoff_s cn61xx;
+	struct cvmx_gmxx_txx_cbfc_xoff_s cn63xx;
+	struct cvmx_gmxx_txx_cbfc_xoff_s cn63xxp1;
+	struct cvmx_gmxx_txx_cbfc_xoff_s cn66xx;
+	struct cvmx_gmxx_txx_cbfc_xoff_s cn68xx;
+	struct cvmx_gmxx_txx_cbfc_xoff_s cn68xxp1;
+	struct cvmx_gmxx_txx_cbfc_xoff_s cnf71xx;
 };
 
 union cvmx_gmxx_txx_cbfc_xon {
 	uint64_t u64;
 	struct cvmx_gmxx_txx_cbfc_xon_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t xon:16;
+#else
+		uint64_t xon:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_gmxx_txx_cbfc_xon_s cn52xx;
 	struct cvmx_gmxx_txx_cbfc_xon_s cn56xx;
+	struct cvmx_gmxx_txx_cbfc_xon_s cn61xx;
+	struct cvmx_gmxx_txx_cbfc_xon_s cn63xx;
+	struct cvmx_gmxx_txx_cbfc_xon_s cn63xxp1;
+	struct cvmx_gmxx_txx_cbfc_xon_s cn66xx;
+	struct cvmx_gmxx_txx_cbfc_xon_s cn68xx;
+	struct cvmx_gmxx_txx_cbfc_xon_s cn68xxp1;
+	struct cvmx_gmxx_txx_cbfc_xon_s cnf71xx;
 };
 
 union cvmx_gmxx_txx_clk {
 	uint64_t u64;
 	struct cvmx_gmxx_txx_clk_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t clk_cnt:6;
+#else
+		uint64_t clk_cnt:6;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
 	struct cvmx_gmxx_txx_clk_s cn30xx;
 	struct cvmx_gmxx_txx_clk_s cn31xx;
@@ -1664,9 +5157,15 @@
 union cvmx_gmxx_txx_ctl {
 	uint64_t u64;
 	struct cvmx_gmxx_txx_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t xsdef_en:1;
 		uint64_t xscol_en:1;
+#else
+		uint64_t xscol_en:1;
+		uint64_t xsdef_en:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_gmxx_txx_ctl_s cn30xx;
 	struct cvmx_gmxx_txx_ctl_s cn31xx;
@@ -1679,13 +5178,25 @@
 	struct cvmx_gmxx_txx_ctl_s cn56xxp1;
 	struct cvmx_gmxx_txx_ctl_s cn58xx;
 	struct cvmx_gmxx_txx_ctl_s cn58xxp1;
+	struct cvmx_gmxx_txx_ctl_s cn61xx;
+	struct cvmx_gmxx_txx_ctl_s cn63xx;
+	struct cvmx_gmxx_txx_ctl_s cn63xxp1;
+	struct cvmx_gmxx_txx_ctl_s cn66xx;
+	struct cvmx_gmxx_txx_ctl_s cn68xx;
+	struct cvmx_gmxx_txx_ctl_s cn68xxp1;
+	struct cvmx_gmxx_txx_ctl_s cnf71xx;
 };
 
 union cvmx_gmxx_txx_min_pkt {
 	uint64_t u64;
 	struct cvmx_gmxx_txx_min_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t min_size:8;
+#else
+		uint64_t min_size:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_gmxx_txx_min_pkt_s cn30xx;
 	struct cvmx_gmxx_txx_min_pkt_s cn31xx;
@@ -1698,13 +5209,25 @@
 	struct cvmx_gmxx_txx_min_pkt_s cn56xxp1;
 	struct cvmx_gmxx_txx_min_pkt_s cn58xx;
 	struct cvmx_gmxx_txx_min_pkt_s cn58xxp1;
+	struct cvmx_gmxx_txx_min_pkt_s cn61xx;
+	struct cvmx_gmxx_txx_min_pkt_s cn63xx;
+	struct cvmx_gmxx_txx_min_pkt_s cn63xxp1;
+	struct cvmx_gmxx_txx_min_pkt_s cn66xx;
+	struct cvmx_gmxx_txx_min_pkt_s cn68xx;
+	struct cvmx_gmxx_txx_min_pkt_s cn68xxp1;
+	struct cvmx_gmxx_txx_min_pkt_s cnf71xx;
 };
 
 union cvmx_gmxx_txx_pause_pkt_interval {
 	uint64_t u64;
 	struct cvmx_gmxx_txx_pause_pkt_interval_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t interval:16;
+#else
+		uint64_t interval:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_gmxx_txx_pause_pkt_interval_s cn30xx;
 	struct cvmx_gmxx_txx_pause_pkt_interval_s cn31xx;
@@ -1717,13 +5240,25 @@
 	struct cvmx_gmxx_txx_pause_pkt_interval_s cn56xxp1;
 	struct cvmx_gmxx_txx_pause_pkt_interval_s cn58xx;
 	struct cvmx_gmxx_txx_pause_pkt_interval_s cn58xxp1;
+	struct cvmx_gmxx_txx_pause_pkt_interval_s cn61xx;
+	struct cvmx_gmxx_txx_pause_pkt_interval_s cn63xx;
+	struct cvmx_gmxx_txx_pause_pkt_interval_s cn63xxp1;
+	struct cvmx_gmxx_txx_pause_pkt_interval_s cn66xx;
+	struct cvmx_gmxx_txx_pause_pkt_interval_s cn68xx;
+	struct cvmx_gmxx_txx_pause_pkt_interval_s cn68xxp1;
+	struct cvmx_gmxx_txx_pause_pkt_interval_s cnf71xx;
 };
 
 union cvmx_gmxx_txx_pause_pkt_time {
 	uint64_t u64;
 	struct cvmx_gmxx_txx_pause_pkt_time_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t time:16;
+#else
+		uint64_t time:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_gmxx_txx_pause_pkt_time_s cn30xx;
 	struct cvmx_gmxx_txx_pause_pkt_time_s cn31xx;
@@ -1736,18 +5271,36 @@
 	struct cvmx_gmxx_txx_pause_pkt_time_s cn56xxp1;
 	struct cvmx_gmxx_txx_pause_pkt_time_s cn58xx;
 	struct cvmx_gmxx_txx_pause_pkt_time_s cn58xxp1;
+	struct cvmx_gmxx_txx_pause_pkt_time_s cn61xx;
+	struct cvmx_gmxx_txx_pause_pkt_time_s cn63xx;
+	struct cvmx_gmxx_txx_pause_pkt_time_s cn63xxp1;
+	struct cvmx_gmxx_txx_pause_pkt_time_s cn66xx;
+	struct cvmx_gmxx_txx_pause_pkt_time_s cn68xx;
+	struct cvmx_gmxx_txx_pause_pkt_time_s cn68xxp1;
+	struct cvmx_gmxx_txx_pause_pkt_time_s cnf71xx;
 };
 
 union cvmx_gmxx_txx_pause_togo {
 	uint64_t u64;
 	struct cvmx_gmxx_txx_pause_togo_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t msg_time:16;
 		uint64_t time:16;
+#else
+		uint64_t time:16;
+		uint64_t msg_time:16;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_gmxx_txx_pause_togo_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t time:16;
+#else
+		uint64_t time:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} cn30xx;
 	struct cvmx_gmxx_txx_pause_togo_cn30xx cn31xx;
 	struct cvmx_gmxx_txx_pause_togo_cn30xx cn38xx;
@@ -1759,13 +5312,25 @@
 	struct cvmx_gmxx_txx_pause_togo_cn30xx cn56xxp1;
 	struct cvmx_gmxx_txx_pause_togo_cn30xx cn58xx;
 	struct cvmx_gmxx_txx_pause_togo_cn30xx cn58xxp1;
+	struct cvmx_gmxx_txx_pause_togo_s cn61xx;
+	struct cvmx_gmxx_txx_pause_togo_s cn63xx;
+	struct cvmx_gmxx_txx_pause_togo_s cn63xxp1;
+	struct cvmx_gmxx_txx_pause_togo_s cn66xx;
+	struct cvmx_gmxx_txx_pause_togo_s cn68xx;
+	struct cvmx_gmxx_txx_pause_togo_s cn68xxp1;
+	struct cvmx_gmxx_txx_pause_togo_s cnf71xx;
 };
 
 union cvmx_gmxx_txx_pause_zero {
 	uint64_t u64;
 	struct cvmx_gmxx_txx_pause_zero_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t send:1;
+#else
+		uint64_t send:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_gmxx_txx_pause_zero_s cn30xx;
 	struct cvmx_gmxx_txx_pause_zero_s cn31xx;
@@ -1778,25 +5343,72 @@
 	struct cvmx_gmxx_txx_pause_zero_s cn56xxp1;
 	struct cvmx_gmxx_txx_pause_zero_s cn58xx;
 	struct cvmx_gmxx_txx_pause_zero_s cn58xxp1;
+	struct cvmx_gmxx_txx_pause_zero_s cn61xx;
+	struct cvmx_gmxx_txx_pause_zero_s cn63xx;
+	struct cvmx_gmxx_txx_pause_zero_s cn63xxp1;
+	struct cvmx_gmxx_txx_pause_zero_s cn66xx;
+	struct cvmx_gmxx_txx_pause_zero_s cn68xx;
+	struct cvmx_gmxx_txx_pause_zero_s cn68xxp1;
+	struct cvmx_gmxx_txx_pause_zero_s cnf71xx;
+};
+
+union cvmx_gmxx_txx_pipe {
+	uint64_t u64;
+	struct cvmx_gmxx_txx_pipe_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_33_63:31;
+		uint64_t ign_bp:1;
+		uint64_t reserved_21_31:11;
+		uint64_t nump:5;
+		uint64_t reserved_7_15:9;
+		uint64_t base:7;
+#else
+		uint64_t base:7;
+		uint64_t reserved_7_15:9;
+		uint64_t nump:5;
+		uint64_t reserved_21_31:11;
+		uint64_t ign_bp:1;
+		uint64_t reserved_33_63:31;
+#endif
+	} s;
+	struct cvmx_gmxx_txx_pipe_s cn68xx;
+	struct cvmx_gmxx_txx_pipe_s cn68xxp1;
 };
 
 union cvmx_gmxx_txx_sgmii_ctl {
 	uint64_t u64;
 	struct cvmx_gmxx_txx_sgmii_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t align:1;
+#else
+		uint64_t align:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_gmxx_txx_sgmii_ctl_s cn52xx;
 	struct cvmx_gmxx_txx_sgmii_ctl_s cn52xxp1;
 	struct cvmx_gmxx_txx_sgmii_ctl_s cn56xx;
 	struct cvmx_gmxx_txx_sgmii_ctl_s cn56xxp1;
+	struct cvmx_gmxx_txx_sgmii_ctl_s cn61xx;
+	struct cvmx_gmxx_txx_sgmii_ctl_s cn63xx;
+	struct cvmx_gmxx_txx_sgmii_ctl_s cn63xxp1;
+	struct cvmx_gmxx_txx_sgmii_ctl_s cn66xx;
+	struct cvmx_gmxx_txx_sgmii_ctl_s cn68xx;
+	struct cvmx_gmxx_txx_sgmii_ctl_s cn68xxp1;
+	struct cvmx_gmxx_txx_sgmii_ctl_s cnf71xx;
 };
 
 union cvmx_gmxx_txx_slot {
 	uint64_t u64;
 	struct cvmx_gmxx_txx_slot_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t slot:10;
+#else
+		uint64_t slot:10;
+		uint64_t reserved_10_63:54;
+#endif
 	} s;
 	struct cvmx_gmxx_txx_slot_s cn30xx;
 	struct cvmx_gmxx_txx_slot_s cn31xx;
@@ -1809,13 +5421,25 @@
 	struct cvmx_gmxx_txx_slot_s cn56xxp1;
 	struct cvmx_gmxx_txx_slot_s cn58xx;
 	struct cvmx_gmxx_txx_slot_s cn58xxp1;
+	struct cvmx_gmxx_txx_slot_s cn61xx;
+	struct cvmx_gmxx_txx_slot_s cn63xx;
+	struct cvmx_gmxx_txx_slot_s cn63xxp1;
+	struct cvmx_gmxx_txx_slot_s cn66xx;
+	struct cvmx_gmxx_txx_slot_s cn68xx;
+	struct cvmx_gmxx_txx_slot_s cn68xxp1;
+	struct cvmx_gmxx_txx_slot_s cnf71xx;
 };
 
 union cvmx_gmxx_txx_soft_pause {
 	uint64_t u64;
 	struct cvmx_gmxx_txx_soft_pause_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t time:16;
+#else
+		uint64_t time:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_gmxx_txx_soft_pause_s cn30xx;
 	struct cvmx_gmxx_txx_soft_pause_s cn31xx;
@@ -1828,13 +5452,25 @@
 	struct cvmx_gmxx_txx_soft_pause_s cn56xxp1;
 	struct cvmx_gmxx_txx_soft_pause_s cn58xx;
 	struct cvmx_gmxx_txx_soft_pause_s cn58xxp1;
+	struct cvmx_gmxx_txx_soft_pause_s cn61xx;
+	struct cvmx_gmxx_txx_soft_pause_s cn63xx;
+	struct cvmx_gmxx_txx_soft_pause_s cn63xxp1;
+	struct cvmx_gmxx_txx_soft_pause_s cn66xx;
+	struct cvmx_gmxx_txx_soft_pause_s cn68xx;
+	struct cvmx_gmxx_txx_soft_pause_s cn68xxp1;
+	struct cvmx_gmxx_txx_soft_pause_s cnf71xx;
 };
 
 union cvmx_gmxx_txx_stat0 {
 	uint64_t u64;
 	struct cvmx_gmxx_txx_stat0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t xsdef:32;
 		uint64_t xscol:32;
+#else
+		uint64_t xscol:32;
+		uint64_t xsdef:32;
+#endif
 	} s;
 	struct cvmx_gmxx_txx_stat0_s cn30xx;
 	struct cvmx_gmxx_txx_stat0_s cn31xx;
@@ -1847,13 +5483,25 @@
 	struct cvmx_gmxx_txx_stat0_s cn56xxp1;
 	struct cvmx_gmxx_txx_stat0_s cn58xx;
 	struct cvmx_gmxx_txx_stat0_s cn58xxp1;
+	struct cvmx_gmxx_txx_stat0_s cn61xx;
+	struct cvmx_gmxx_txx_stat0_s cn63xx;
+	struct cvmx_gmxx_txx_stat0_s cn63xxp1;
+	struct cvmx_gmxx_txx_stat0_s cn66xx;
+	struct cvmx_gmxx_txx_stat0_s cn68xx;
+	struct cvmx_gmxx_txx_stat0_s cn68xxp1;
+	struct cvmx_gmxx_txx_stat0_s cnf71xx;
 };
 
 union cvmx_gmxx_txx_stat1 {
 	uint64_t u64;
 	struct cvmx_gmxx_txx_stat1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t scol:32;
 		uint64_t mcol:32;
+#else
+		uint64_t mcol:32;
+		uint64_t scol:32;
+#endif
 	} s;
 	struct cvmx_gmxx_txx_stat1_s cn30xx;
 	struct cvmx_gmxx_txx_stat1_s cn31xx;
@@ -1866,13 +5514,25 @@
 	struct cvmx_gmxx_txx_stat1_s cn56xxp1;
 	struct cvmx_gmxx_txx_stat1_s cn58xx;
 	struct cvmx_gmxx_txx_stat1_s cn58xxp1;
+	struct cvmx_gmxx_txx_stat1_s cn61xx;
+	struct cvmx_gmxx_txx_stat1_s cn63xx;
+	struct cvmx_gmxx_txx_stat1_s cn63xxp1;
+	struct cvmx_gmxx_txx_stat1_s cn66xx;
+	struct cvmx_gmxx_txx_stat1_s cn68xx;
+	struct cvmx_gmxx_txx_stat1_s cn68xxp1;
+	struct cvmx_gmxx_txx_stat1_s cnf71xx;
 };
 
 union cvmx_gmxx_txx_stat2 {
 	uint64_t u64;
 	struct cvmx_gmxx_txx_stat2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t octs:48;
+#else
+		uint64_t octs:48;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_gmxx_txx_stat2_s cn30xx;
 	struct cvmx_gmxx_txx_stat2_s cn31xx;
@@ -1885,13 +5545,25 @@
 	struct cvmx_gmxx_txx_stat2_s cn56xxp1;
 	struct cvmx_gmxx_txx_stat2_s cn58xx;
 	struct cvmx_gmxx_txx_stat2_s cn58xxp1;
+	struct cvmx_gmxx_txx_stat2_s cn61xx;
+	struct cvmx_gmxx_txx_stat2_s cn63xx;
+	struct cvmx_gmxx_txx_stat2_s cn63xxp1;
+	struct cvmx_gmxx_txx_stat2_s cn66xx;
+	struct cvmx_gmxx_txx_stat2_s cn68xx;
+	struct cvmx_gmxx_txx_stat2_s cn68xxp1;
+	struct cvmx_gmxx_txx_stat2_s cnf71xx;
 };
 
 union cvmx_gmxx_txx_stat3 {
 	uint64_t u64;
 	struct cvmx_gmxx_txx_stat3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t pkts:32;
+#else
+		uint64_t pkts:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_gmxx_txx_stat3_s cn30xx;
 	struct cvmx_gmxx_txx_stat3_s cn31xx;
@@ -1904,13 +5576,25 @@
 	struct cvmx_gmxx_txx_stat3_s cn56xxp1;
 	struct cvmx_gmxx_txx_stat3_s cn58xx;
 	struct cvmx_gmxx_txx_stat3_s cn58xxp1;
+	struct cvmx_gmxx_txx_stat3_s cn61xx;
+	struct cvmx_gmxx_txx_stat3_s cn63xx;
+	struct cvmx_gmxx_txx_stat3_s cn63xxp1;
+	struct cvmx_gmxx_txx_stat3_s cn66xx;
+	struct cvmx_gmxx_txx_stat3_s cn68xx;
+	struct cvmx_gmxx_txx_stat3_s cn68xxp1;
+	struct cvmx_gmxx_txx_stat3_s cnf71xx;
 };
 
 union cvmx_gmxx_txx_stat4 {
 	uint64_t u64;
 	struct cvmx_gmxx_txx_stat4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t hist1:32;
 		uint64_t hist0:32;
+#else
+		uint64_t hist0:32;
+		uint64_t hist1:32;
+#endif
 	} s;
 	struct cvmx_gmxx_txx_stat4_s cn30xx;
 	struct cvmx_gmxx_txx_stat4_s cn31xx;
@@ -1923,13 +5607,25 @@
 	struct cvmx_gmxx_txx_stat4_s cn56xxp1;
 	struct cvmx_gmxx_txx_stat4_s cn58xx;
 	struct cvmx_gmxx_txx_stat4_s cn58xxp1;
+	struct cvmx_gmxx_txx_stat4_s cn61xx;
+	struct cvmx_gmxx_txx_stat4_s cn63xx;
+	struct cvmx_gmxx_txx_stat4_s cn63xxp1;
+	struct cvmx_gmxx_txx_stat4_s cn66xx;
+	struct cvmx_gmxx_txx_stat4_s cn68xx;
+	struct cvmx_gmxx_txx_stat4_s cn68xxp1;
+	struct cvmx_gmxx_txx_stat4_s cnf71xx;
 };
 
 union cvmx_gmxx_txx_stat5 {
 	uint64_t u64;
 	struct cvmx_gmxx_txx_stat5_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t hist3:32;
 		uint64_t hist2:32;
+#else
+		uint64_t hist2:32;
+		uint64_t hist3:32;
+#endif
 	} s;
 	struct cvmx_gmxx_txx_stat5_s cn30xx;
 	struct cvmx_gmxx_txx_stat5_s cn31xx;
@@ -1942,13 +5638,25 @@
 	struct cvmx_gmxx_txx_stat5_s cn56xxp1;
 	struct cvmx_gmxx_txx_stat5_s cn58xx;
 	struct cvmx_gmxx_txx_stat5_s cn58xxp1;
+	struct cvmx_gmxx_txx_stat5_s cn61xx;
+	struct cvmx_gmxx_txx_stat5_s cn63xx;
+	struct cvmx_gmxx_txx_stat5_s cn63xxp1;
+	struct cvmx_gmxx_txx_stat5_s cn66xx;
+	struct cvmx_gmxx_txx_stat5_s cn68xx;
+	struct cvmx_gmxx_txx_stat5_s cn68xxp1;
+	struct cvmx_gmxx_txx_stat5_s cnf71xx;
 };
 
 union cvmx_gmxx_txx_stat6 {
 	uint64_t u64;
 	struct cvmx_gmxx_txx_stat6_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t hist5:32;
 		uint64_t hist4:32;
+#else
+		uint64_t hist4:32;
+		uint64_t hist5:32;
+#endif
 	} s;
 	struct cvmx_gmxx_txx_stat6_s cn30xx;
 	struct cvmx_gmxx_txx_stat6_s cn31xx;
@@ -1961,13 +5669,25 @@
 	struct cvmx_gmxx_txx_stat6_s cn56xxp1;
 	struct cvmx_gmxx_txx_stat6_s cn58xx;
 	struct cvmx_gmxx_txx_stat6_s cn58xxp1;
+	struct cvmx_gmxx_txx_stat6_s cn61xx;
+	struct cvmx_gmxx_txx_stat6_s cn63xx;
+	struct cvmx_gmxx_txx_stat6_s cn63xxp1;
+	struct cvmx_gmxx_txx_stat6_s cn66xx;
+	struct cvmx_gmxx_txx_stat6_s cn68xx;
+	struct cvmx_gmxx_txx_stat6_s cn68xxp1;
+	struct cvmx_gmxx_txx_stat6_s cnf71xx;
 };
 
 union cvmx_gmxx_txx_stat7 {
 	uint64_t u64;
 	struct cvmx_gmxx_txx_stat7_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t hist7:32;
 		uint64_t hist6:32;
+#else
+		uint64_t hist6:32;
+		uint64_t hist7:32;
+#endif
 	} s;
 	struct cvmx_gmxx_txx_stat7_s cn30xx;
 	struct cvmx_gmxx_txx_stat7_s cn31xx;
@@ -1980,13 +5700,25 @@
 	struct cvmx_gmxx_txx_stat7_s cn56xxp1;
 	struct cvmx_gmxx_txx_stat7_s cn58xx;
 	struct cvmx_gmxx_txx_stat7_s cn58xxp1;
+	struct cvmx_gmxx_txx_stat7_s cn61xx;
+	struct cvmx_gmxx_txx_stat7_s cn63xx;
+	struct cvmx_gmxx_txx_stat7_s cn63xxp1;
+	struct cvmx_gmxx_txx_stat7_s cn66xx;
+	struct cvmx_gmxx_txx_stat7_s cn68xx;
+	struct cvmx_gmxx_txx_stat7_s cn68xxp1;
+	struct cvmx_gmxx_txx_stat7_s cnf71xx;
 };
 
 union cvmx_gmxx_txx_stat8 {
 	uint64_t u64;
 	struct cvmx_gmxx_txx_stat8_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t mcst:32;
 		uint64_t bcst:32;
+#else
+		uint64_t bcst:32;
+		uint64_t mcst:32;
+#endif
 	} s;
 	struct cvmx_gmxx_txx_stat8_s cn30xx;
 	struct cvmx_gmxx_txx_stat8_s cn31xx;
@@ -1999,13 +5731,25 @@
 	struct cvmx_gmxx_txx_stat8_s cn56xxp1;
 	struct cvmx_gmxx_txx_stat8_s cn58xx;
 	struct cvmx_gmxx_txx_stat8_s cn58xxp1;
+	struct cvmx_gmxx_txx_stat8_s cn61xx;
+	struct cvmx_gmxx_txx_stat8_s cn63xx;
+	struct cvmx_gmxx_txx_stat8_s cn63xxp1;
+	struct cvmx_gmxx_txx_stat8_s cn66xx;
+	struct cvmx_gmxx_txx_stat8_s cn68xx;
+	struct cvmx_gmxx_txx_stat8_s cn68xxp1;
+	struct cvmx_gmxx_txx_stat8_s cnf71xx;
 };
 
 union cvmx_gmxx_txx_stat9 {
 	uint64_t u64;
 	struct cvmx_gmxx_txx_stat9_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t undflw:32;
 		uint64_t ctl:32;
+#else
+		uint64_t ctl:32;
+		uint64_t undflw:32;
+#endif
 	} s;
 	struct cvmx_gmxx_txx_stat9_s cn30xx;
 	struct cvmx_gmxx_txx_stat9_s cn31xx;
@@ -2018,13 +5762,25 @@
 	struct cvmx_gmxx_txx_stat9_s cn56xxp1;
 	struct cvmx_gmxx_txx_stat9_s cn58xx;
 	struct cvmx_gmxx_txx_stat9_s cn58xxp1;
+	struct cvmx_gmxx_txx_stat9_s cn61xx;
+	struct cvmx_gmxx_txx_stat9_s cn63xx;
+	struct cvmx_gmxx_txx_stat9_s cn63xxp1;
+	struct cvmx_gmxx_txx_stat9_s cn66xx;
+	struct cvmx_gmxx_txx_stat9_s cn68xx;
+	struct cvmx_gmxx_txx_stat9_s cn68xxp1;
+	struct cvmx_gmxx_txx_stat9_s cnf71xx;
 };
 
 union cvmx_gmxx_txx_stats_ctl {
 	uint64_t u64;
 	struct cvmx_gmxx_txx_stats_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t rd_clr:1;
+#else
+		uint64_t rd_clr:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_gmxx_txx_stats_ctl_s cn30xx;
 	struct cvmx_gmxx_txx_stats_ctl_s cn31xx;
@@ -2037,39 +5793,81 @@
 	struct cvmx_gmxx_txx_stats_ctl_s cn56xxp1;
 	struct cvmx_gmxx_txx_stats_ctl_s cn58xx;
 	struct cvmx_gmxx_txx_stats_ctl_s cn58xxp1;
+	struct cvmx_gmxx_txx_stats_ctl_s cn61xx;
+	struct cvmx_gmxx_txx_stats_ctl_s cn63xx;
+	struct cvmx_gmxx_txx_stats_ctl_s cn63xxp1;
+	struct cvmx_gmxx_txx_stats_ctl_s cn66xx;
+	struct cvmx_gmxx_txx_stats_ctl_s cn68xx;
+	struct cvmx_gmxx_txx_stats_ctl_s cn68xxp1;
+	struct cvmx_gmxx_txx_stats_ctl_s cnf71xx;
 };
 
 union cvmx_gmxx_txx_thresh {
 	uint64_t u64;
 	struct cvmx_gmxx_txx_thresh_s {
-		uint64_t reserved_9_63:55;
-		uint64_t cnt:9;
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t cnt:10;
+#else
+		uint64_t cnt:10;
+		uint64_t reserved_10_63:54;
+#endif
 	} s;
 	struct cvmx_gmxx_txx_thresh_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_7_63:57;
 		uint64_t cnt:7;
+#else
+		uint64_t cnt:7;
+		uint64_t reserved_7_63:57;
+#endif
 	} cn30xx;
 	struct cvmx_gmxx_txx_thresh_cn30xx cn31xx;
-	struct cvmx_gmxx_txx_thresh_s cn38xx;
-	struct cvmx_gmxx_txx_thresh_s cn38xxp2;
+	struct cvmx_gmxx_txx_thresh_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_9_63:55;
+		uint64_t cnt:9;
+#else
+		uint64_t cnt:9;
+		uint64_t reserved_9_63:55;
+#endif
+	} cn38xx;
+	struct cvmx_gmxx_txx_thresh_cn38xx cn38xxp2;
 	struct cvmx_gmxx_txx_thresh_cn30xx cn50xx;
-	struct cvmx_gmxx_txx_thresh_s cn52xx;
-	struct cvmx_gmxx_txx_thresh_s cn52xxp1;
-	struct cvmx_gmxx_txx_thresh_s cn56xx;
-	struct cvmx_gmxx_txx_thresh_s cn56xxp1;
-	struct cvmx_gmxx_txx_thresh_s cn58xx;
-	struct cvmx_gmxx_txx_thresh_s cn58xxp1;
+	struct cvmx_gmxx_txx_thresh_cn38xx cn52xx;
+	struct cvmx_gmxx_txx_thresh_cn38xx cn52xxp1;
+	struct cvmx_gmxx_txx_thresh_cn38xx cn56xx;
+	struct cvmx_gmxx_txx_thresh_cn38xx cn56xxp1;
+	struct cvmx_gmxx_txx_thresh_cn38xx cn58xx;
+	struct cvmx_gmxx_txx_thresh_cn38xx cn58xxp1;
+	struct cvmx_gmxx_txx_thresh_cn38xx cn61xx;
+	struct cvmx_gmxx_txx_thresh_cn38xx cn63xx;
+	struct cvmx_gmxx_txx_thresh_cn38xx cn63xxp1;
+	struct cvmx_gmxx_txx_thresh_cn38xx cn66xx;
+	struct cvmx_gmxx_txx_thresh_s cn68xx;
+	struct cvmx_gmxx_txx_thresh_s cn68xxp1;
+	struct cvmx_gmxx_txx_thresh_cn38xx cnf71xx;
 };
 
 union cvmx_gmxx_tx_bp {
 	uint64_t u64;
 	struct cvmx_gmxx_tx_bp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t bp:4;
+#else
+		uint64_t bp:4;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_gmxx_tx_bp_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_3_63:61;
 		uint64_t bp:3;
+#else
+		uint64_t bp:3;
+		uint64_t reserved_3_63:61;
+#endif
 	} cn30xx;
 	struct cvmx_gmxx_tx_bp_cn30xx cn31xx;
 	struct cvmx_gmxx_tx_bp_s cn38xx;
@@ -2081,13 +5879,33 @@
 	struct cvmx_gmxx_tx_bp_s cn56xxp1;
 	struct cvmx_gmxx_tx_bp_s cn58xx;
 	struct cvmx_gmxx_tx_bp_s cn58xxp1;
+	struct cvmx_gmxx_tx_bp_s cn61xx;
+	struct cvmx_gmxx_tx_bp_s cn63xx;
+	struct cvmx_gmxx_tx_bp_s cn63xxp1;
+	struct cvmx_gmxx_tx_bp_s cn66xx;
+	struct cvmx_gmxx_tx_bp_s cn68xx;
+	struct cvmx_gmxx_tx_bp_s cn68xxp1;
+	struct cvmx_gmxx_tx_bp_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_2_63:62;
+		uint64_t bp:2;
+#else
+		uint64_t bp:2;
+		uint64_t reserved_2_63:62;
+#endif
+	} cnf71xx;
 };
 
 union cvmx_gmxx_tx_clk_mskx {
 	uint64_t u64;
 	struct cvmx_gmxx_tx_clk_mskx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t msk:1;
+#else
+		uint64_t msk:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_gmxx_tx_clk_mskx_s cn30xx;
 	struct cvmx_gmxx_tx_clk_mskx_s cn50xx;
@@ -2096,8 +5914,13 @@
 union cvmx_gmxx_tx_col_attempt {
 	uint64_t u64;
 	struct cvmx_gmxx_tx_col_attempt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t limit:5;
+#else
+		uint64_t limit:5;
+		uint64_t reserved_5_63:59;
+#endif
 	} s;
 	struct cvmx_gmxx_tx_col_attempt_s cn30xx;
 	struct cvmx_gmxx_tx_col_attempt_s cn31xx;
@@ -2110,17 +5933,34 @@
 	struct cvmx_gmxx_tx_col_attempt_s cn56xxp1;
 	struct cvmx_gmxx_tx_col_attempt_s cn58xx;
 	struct cvmx_gmxx_tx_col_attempt_s cn58xxp1;
+	struct cvmx_gmxx_tx_col_attempt_s cn61xx;
+	struct cvmx_gmxx_tx_col_attempt_s cn63xx;
+	struct cvmx_gmxx_tx_col_attempt_s cn63xxp1;
+	struct cvmx_gmxx_tx_col_attempt_s cn66xx;
+	struct cvmx_gmxx_tx_col_attempt_s cn68xx;
+	struct cvmx_gmxx_tx_col_attempt_s cn68xxp1;
+	struct cvmx_gmxx_tx_col_attempt_s cnf71xx;
 };
 
 union cvmx_gmxx_tx_corrupt {
 	uint64_t u64;
 	struct cvmx_gmxx_tx_corrupt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t corrupt:4;
+#else
+		uint64_t corrupt:4;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_gmxx_tx_corrupt_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_3_63:61;
 		uint64_t corrupt:3;
+#else
+		uint64_t corrupt:3;
+		uint64_t reserved_3_63:61;
+#endif
 	} cn30xx;
 	struct cvmx_gmxx_tx_corrupt_cn30xx cn31xx;
 	struct cvmx_gmxx_tx_corrupt_s cn38xx;
@@ -2132,36 +5972,81 @@
 	struct cvmx_gmxx_tx_corrupt_s cn56xxp1;
 	struct cvmx_gmxx_tx_corrupt_s cn58xx;
 	struct cvmx_gmxx_tx_corrupt_s cn58xxp1;
+	struct cvmx_gmxx_tx_corrupt_s cn61xx;
+	struct cvmx_gmxx_tx_corrupt_s cn63xx;
+	struct cvmx_gmxx_tx_corrupt_s cn63xxp1;
+	struct cvmx_gmxx_tx_corrupt_s cn66xx;
+	struct cvmx_gmxx_tx_corrupt_s cn68xx;
+	struct cvmx_gmxx_tx_corrupt_s cn68xxp1;
+	struct cvmx_gmxx_tx_corrupt_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_2_63:62;
+		uint64_t corrupt:2;
+#else
+		uint64_t corrupt:2;
+		uint64_t reserved_2_63:62;
+#endif
+	} cnf71xx;
 };
 
 union cvmx_gmxx_tx_hg2_reg1 {
 	uint64_t u64;
 	struct cvmx_gmxx_tx_hg2_reg1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t tx_xof:16;
+#else
+		uint64_t tx_xof:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_gmxx_tx_hg2_reg1_s cn52xx;
 	struct cvmx_gmxx_tx_hg2_reg1_s cn52xxp1;
 	struct cvmx_gmxx_tx_hg2_reg1_s cn56xx;
+	struct cvmx_gmxx_tx_hg2_reg1_s cn61xx;
+	struct cvmx_gmxx_tx_hg2_reg1_s cn63xx;
+	struct cvmx_gmxx_tx_hg2_reg1_s cn63xxp1;
+	struct cvmx_gmxx_tx_hg2_reg1_s cn66xx;
+	struct cvmx_gmxx_tx_hg2_reg1_s cn68xx;
+	struct cvmx_gmxx_tx_hg2_reg1_s cn68xxp1;
+	struct cvmx_gmxx_tx_hg2_reg1_s cnf71xx;
 };
 
 union cvmx_gmxx_tx_hg2_reg2 {
 	uint64_t u64;
 	struct cvmx_gmxx_tx_hg2_reg2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t tx_xon:16;
+#else
+		uint64_t tx_xon:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_gmxx_tx_hg2_reg2_s cn52xx;
 	struct cvmx_gmxx_tx_hg2_reg2_s cn52xxp1;
 	struct cvmx_gmxx_tx_hg2_reg2_s cn56xx;
+	struct cvmx_gmxx_tx_hg2_reg2_s cn61xx;
+	struct cvmx_gmxx_tx_hg2_reg2_s cn63xx;
+	struct cvmx_gmxx_tx_hg2_reg2_s cn63xxp1;
+	struct cvmx_gmxx_tx_hg2_reg2_s cn66xx;
+	struct cvmx_gmxx_tx_hg2_reg2_s cn68xx;
+	struct cvmx_gmxx_tx_hg2_reg2_s cn68xxp1;
+	struct cvmx_gmxx_tx_hg2_reg2_s cnf71xx;
 };
 
 union cvmx_gmxx_tx_ifg {
 	uint64_t u64;
 	struct cvmx_gmxx_tx_ifg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t ifg2:4;
 		uint64_t ifg1:4;
+#else
+		uint64_t ifg1:4;
+		uint64_t ifg2:4;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_gmxx_tx_ifg_s cn30xx;
 	struct cvmx_gmxx_tx_ifg_s cn31xx;
@@ -2174,21 +6059,44 @@
 	struct cvmx_gmxx_tx_ifg_s cn56xxp1;
 	struct cvmx_gmxx_tx_ifg_s cn58xx;
 	struct cvmx_gmxx_tx_ifg_s cn58xxp1;
+	struct cvmx_gmxx_tx_ifg_s cn61xx;
+	struct cvmx_gmxx_tx_ifg_s cn63xx;
+	struct cvmx_gmxx_tx_ifg_s cn63xxp1;
+	struct cvmx_gmxx_tx_ifg_s cn66xx;
+	struct cvmx_gmxx_tx_ifg_s cn68xx;
+	struct cvmx_gmxx_tx_ifg_s cn68xxp1;
+	struct cvmx_gmxx_tx_ifg_s cnf71xx;
 };
 
 union cvmx_gmxx_tx_int_en {
 	uint64_t u64;
 	struct cvmx_gmxx_tx_int_en_s {
-		uint64_t reserved_20_63:44;
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_25_63:39;
+		uint64_t xchange:1;
+		uint64_t ptp_lost:4;
 		uint64_t late_col:4;
 		uint64_t xsdef:4;
 		uint64_t xscol:4;
 		uint64_t reserved_6_7:2;
 		uint64_t undflw:4;
-		uint64_t ncb_nxa:1;
+		uint64_t reserved_1_1:1;
 		uint64_t pko_nxa:1;
+#else
+		uint64_t pko_nxa:1;
+		uint64_t reserved_1_1:1;
+		uint64_t undflw:4;
+		uint64_t reserved_6_7:2;
+		uint64_t xscol:4;
+		uint64_t xsdef:4;
+		uint64_t late_col:4;
+		uint64_t ptp_lost:4;
+		uint64_t xchange:1;
+		uint64_t reserved_25_63:39;
+#endif
 	} s;
 	struct cvmx_gmxx_tx_int_en_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_19_63:45;
 		uint64_t late_col:3;
 		uint64_t reserved_15_15:1;
@@ -2199,8 +6107,21 @@
 		uint64_t undflw:3;
 		uint64_t reserved_1_1:1;
 		uint64_t pko_nxa:1;
+#else
+		uint64_t pko_nxa:1;
+		uint64_t reserved_1_1:1;
+		uint64_t undflw:3;
+		uint64_t reserved_5_7:3;
+		uint64_t xscol:3;
+		uint64_t reserved_11_11:1;
+		uint64_t xsdef:3;
+		uint64_t reserved_15_15:1;
+		uint64_t late_col:3;
+		uint64_t reserved_19_63:45;
+#endif
 	} cn30xx;
 	struct cvmx_gmxx_tx_int_en_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_15_63:49;
 		uint64_t xsdef:3;
 		uint64_t reserved_11_11:1;
@@ -2209,9 +6130,40 @@
 		uint64_t undflw:3;
 		uint64_t reserved_1_1:1;
 		uint64_t pko_nxa:1;
+#else
+		uint64_t pko_nxa:1;
+		uint64_t reserved_1_1:1;
+		uint64_t undflw:3;
+		uint64_t reserved_5_7:3;
+		uint64_t xscol:3;
+		uint64_t reserved_11_11:1;
+		uint64_t xsdef:3;
+		uint64_t reserved_15_63:49;
+#endif
 	} cn31xx;
-	struct cvmx_gmxx_tx_int_en_s cn38xx;
+	struct cvmx_gmxx_tx_int_en_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_20_63:44;
+		uint64_t late_col:4;
+		uint64_t xsdef:4;
+		uint64_t xscol:4;
+		uint64_t reserved_6_7:2;
+		uint64_t undflw:4;
+		uint64_t ncb_nxa:1;
+		uint64_t pko_nxa:1;
+#else
+		uint64_t pko_nxa:1;
+		uint64_t ncb_nxa:1;
+		uint64_t undflw:4;
+		uint64_t reserved_6_7:2;
+		uint64_t xscol:4;
+		uint64_t xsdef:4;
+		uint64_t late_col:4;
+		uint64_t reserved_20_63:44;
+#endif
+	} cn38xx;
 	struct cvmx_gmxx_tx_int_en_cn38xxp2 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t xsdef:4;
 		uint64_t xscol:4;
@@ -2219,9 +6171,19 @@
 		uint64_t undflw:4;
 		uint64_t ncb_nxa:1;
 		uint64_t pko_nxa:1;
+#else
+		uint64_t pko_nxa:1;
+		uint64_t ncb_nxa:1;
+		uint64_t undflw:4;
+		uint64_t reserved_6_7:2;
+		uint64_t xscol:4;
+		uint64_t xsdef:4;
+		uint64_t reserved_16_63:48;
+#endif
 	} cn38xxp2;
 	struct cvmx_gmxx_tx_int_en_cn30xx cn50xx;
 	struct cvmx_gmxx_tx_int_en_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t late_col:4;
 		uint64_t xsdef:4;
@@ -2230,27 +6192,138 @@
 		uint64_t undflw:4;
 		uint64_t reserved_1_1:1;
 		uint64_t pko_nxa:1;
+#else
+		uint64_t pko_nxa:1;
+		uint64_t reserved_1_1:1;
+		uint64_t undflw:4;
+		uint64_t reserved_6_7:2;
+		uint64_t xscol:4;
+		uint64_t xsdef:4;
+		uint64_t late_col:4;
+		uint64_t reserved_20_63:44;
+#endif
 	} cn52xx;
 	struct cvmx_gmxx_tx_int_en_cn52xx cn52xxp1;
 	struct cvmx_gmxx_tx_int_en_cn52xx cn56xx;
 	struct cvmx_gmxx_tx_int_en_cn52xx cn56xxp1;
-	struct cvmx_gmxx_tx_int_en_s cn58xx;
-	struct cvmx_gmxx_tx_int_en_s cn58xxp1;
+	struct cvmx_gmxx_tx_int_en_cn38xx cn58xx;
+	struct cvmx_gmxx_tx_int_en_cn38xx cn58xxp1;
+	struct cvmx_gmxx_tx_int_en_s cn61xx;
+	struct cvmx_gmxx_tx_int_en_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_24_63:40;
+		uint64_t ptp_lost:4;
+		uint64_t late_col:4;
+		uint64_t xsdef:4;
+		uint64_t xscol:4;
+		uint64_t reserved_6_7:2;
+		uint64_t undflw:4;
+		uint64_t reserved_1_1:1;
+		uint64_t pko_nxa:1;
+#else
+		uint64_t pko_nxa:1;
+		uint64_t reserved_1_1:1;
+		uint64_t undflw:4;
+		uint64_t reserved_6_7:2;
+		uint64_t xscol:4;
+		uint64_t xsdef:4;
+		uint64_t late_col:4;
+		uint64_t ptp_lost:4;
+		uint64_t reserved_24_63:40;
+#endif
+	} cn63xx;
+	struct cvmx_gmxx_tx_int_en_cn63xx cn63xxp1;
+	struct cvmx_gmxx_tx_int_en_s cn66xx;
+	struct cvmx_gmxx_tx_int_en_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_25_63:39;
+		uint64_t xchange:1;
+		uint64_t ptp_lost:4;
+		uint64_t late_col:4;
+		uint64_t xsdef:4;
+		uint64_t xscol:4;
+		uint64_t reserved_6_7:2;
+		uint64_t undflw:4;
+		uint64_t pko_nxp:1;
+		uint64_t pko_nxa:1;
+#else
+		uint64_t pko_nxa:1;
+		uint64_t pko_nxp:1;
+		uint64_t undflw:4;
+		uint64_t reserved_6_7:2;
+		uint64_t xscol:4;
+		uint64_t xsdef:4;
+		uint64_t late_col:4;
+		uint64_t ptp_lost:4;
+		uint64_t xchange:1;
+		uint64_t reserved_25_63:39;
+#endif
+	} cn68xx;
+	struct cvmx_gmxx_tx_int_en_cn68xx cn68xxp1;
+	struct cvmx_gmxx_tx_int_en_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_25_63:39;
+		uint64_t xchange:1;
+		uint64_t reserved_22_23:2;
+		uint64_t ptp_lost:2;
+		uint64_t reserved_18_19:2;
+		uint64_t late_col:2;
+		uint64_t reserved_14_15:2;
+		uint64_t xsdef:2;
+		uint64_t reserved_10_11:2;
+		uint64_t xscol:2;
+		uint64_t reserved_4_7:4;
+		uint64_t undflw:2;
+		uint64_t reserved_1_1:1;
+		uint64_t pko_nxa:1;
+#else
+		uint64_t pko_nxa:1;
+		uint64_t reserved_1_1:1;
+		uint64_t undflw:2;
+		uint64_t reserved_4_7:4;
+		uint64_t xscol:2;
+		uint64_t reserved_10_11:2;
+		uint64_t xsdef:2;
+		uint64_t reserved_14_15:2;
+		uint64_t late_col:2;
+		uint64_t reserved_18_19:2;
+		uint64_t ptp_lost:2;
+		uint64_t reserved_22_23:2;
+		uint64_t xchange:1;
+		uint64_t reserved_25_63:39;
+#endif
+	} cnf71xx;
 };
 
 union cvmx_gmxx_tx_int_reg {
 	uint64_t u64;
 	struct cvmx_gmxx_tx_int_reg_s {
-		uint64_t reserved_20_63:44;
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_25_63:39;
+		uint64_t xchange:1;
+		uint64_t ptp_lost:4;
 		uint64_t late_col:4;
 		uint64_t xsdef:4;
 		uint64_t xscol:4;
 		uint64_t reserved_6_7:2;
 		uint64_t undflw:4;
-		uint64_t ncb_nxa:1;
+		uint64_t reserved_1_1:1;
 		uint64_t pko_nxa:1;
+#else
+		uint64_t pko_nxa:1;
+		uint64_t reserved_1_1:1;
+		uint64_t undflw:4;
+		uint64_t reserved_6_7:2;
+		uint64_t xscol:4;
+		uint64_t xsdef:4;
+		uint64_t late_col:4;
+		uint64_t ptp_lost:4;
+		uint64_t xchange:1;
+		uint64_t reserved_25_63:39;
+#endif
 	} s;
 	struct cvmx_gmxx_tx_int_reg_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_19_63:45;
 		uint64_t late_col:3;
 		uint64_t reserved_15_15:1;
@@ -2261,8 +6334,21 @@
 		uint64_t undflw:3;
 		uint64_t reserved_1_1:1;
 		uint64_t pko_nxa:1;
+#else
+		uint64_t pko_nxa:1;
+		uint64_t reserved_1_1:1;
+		uint64_t undflw:3;
+		uint64_t reserved_5_7:3;
+		uint64_t xscol:3;
+		uint64_t reserved_11_11:1;
+		uint64_t xsdef:3;
+		uint64_t reserved_15_15:1;
+		uint64_t late_col:3;
+		uint64_t reserved_19_63:45;
+#endif
 	} cn30xx;
 	struct cvmx_gmxx_tx_int_reg_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_15_63:49;
 		uint64_t xsdef:3;
 		uint64_t reserved_11_11:1;
@@ -2271,9 +6357,40 @@
 		uint64_t undflw:3;
 		uint64_t reserved_1_1:1;
 		uint64_t pko_nxa:1;
+#else
+		uint64_t pko_nxa:1;
+		uint64_t reserved_1_1:1;
+		uint64_t undflw:3;
+		uint64_t reserved_5_7:3;
+		uint64_t xscol:3;
+		uint64_t reserved_11_11:1;
+		uint64_t xsdef:3;
+		uint64_t reserved_15_63:49;
+#endif
 	} cn31xx;
-	struct cvmx_gmxx_tx_int_reg_s cn38xx;
+	struct cvmx_gmxx_tx_int_reg_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_20_63:44;
+		uint64_t late_col:4;
+		uint64_t xsdef:4;
+		uint64_t xscol:4;
+		uint64_t reserved_6_7:2;
+		uint64_t undflw:4;
+		uint64_t ncb_nxa:1;
+		uint64_t pko_nxa:1;
+#else
+		uint64_t pko_nxa:1;
+		uint64_t ncb_nxa:1;
+		uint64_t undflw:4;
+		uint64_t reserved_6_7:2;
+		uint64_t xscol:4;
+		uint64_t xsdef:4;
+		uint64_t late_col:4;
+		uint64_t reserved_20_63:44;
+#endif
+	} cn38xx;
 	struct cvmx_gmxx_tx_int_reg_cn38xxp2 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t xsdef:4;
 		uint64_t xscol:4;
@@ -2281,9 +6398,19 @@
 		uint64_t undflw:4;
 		uint64_t ncb_nxa:1;
 		uint64_t pko_nxa:1;
+#else
+		uint64_t pko_nxa:1;
+		uint64_t ncb_nxa:1;
+		uint64_t undflw:4;
+		uint64_t reserved_6_7:2;
+		uint64_t xscol:4;
+		uint64_t xsdef:4;
+		uint64_t reserved_16_63:48;
+#endif
 	} cn38xxp2;
 	struct cvmx_gmxx_tx_int_reg_cn30xx cn50xx;
 	struct cvmx_gmxx_tx_int_reg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t late_col:4;
 		uint64_t xsdef:4;
@@ -2292,19 +6419,119 @@
 		uint64_t undflw:4;
 		uint64_t reserved_1_1:1;
 		uint64_t pko_nxa:1;
+#else
+		uint64_t pko_nxa:1;
+		uint64_t reserved_1_1:1;
+		uint64_t undflw:4;
+		uint64_t reserved_6_7:2;
+		uint64_t xscol:4;
+		uint64_t xsdef:4;
+		uint64_t late_col:4;
+		uint64_t reserved_20_63:44;
+#endif
 	} cn52xx;
 	struct cvmx_gmxx_tx_int_reg_cn52xx cn52xxp1;
 	struct cvmx_gmxx_tx_int_reg_cn52xx cn56xx;
 	struct cvmx_gmxx_tx_int_reg_cn52xx cn56xxp1;
-	struct cvmx_gmxx_tx_int_reg_s cn58xx;
-	struct cvmx_gmxx_tx_int_reg_s cn58xxp1;
+	struct cvmx_gmxx_tx_int_reg_cn38xx cn58xx;
+	struct cvmx_gmxx_tx_int_reg_cn38xx cn58xxp1;
+	struct cvmx_gmxx_tx_int_reg_s cn61xx;
+	struct cvmx_gmxx_tx_int_reg_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_24_63:40;
+		uint64_t ptp_lost:4;
+		uint64_t late_col:4;
+		uint64_t xsdef:4;
+		uint64_t xscol:4;
+		uint64_t reserved_6_7:2;
+		uint64_t undflw:4;
+		uint64_t reserved_1_1:1;
+		uint64_t pko_nxa:1;
+#else
+		uint64_t pko_nxa:1;
+		uint64_t reserved_1_1:1;
+		uint64_t undflw:4;
+		uint64_t reserved_6_7:2;
+		uint64_t xscol:4;
+		uint64_t xsdef:4;
+		uint64_t late_col:4;
+		uint64_t ptp_lost:4;
+		uint64_t reserved_24_63:40;
+#endif
+	} cn63xx;
+	struct cvmx_gmxx_tx_int_reg_cn63xx cn63xxp1;
+	struct cvmx_gmxx_tx_int_reg_s cn66xx;
+	struct cvmx_gmxx_tx_int_reg_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_25_63:39;
+		uint64_t xchange:1;
+		uint64_t ptp_lost:4;
+		uint64_t late_col:4;
+		uint64_t xsdef:4;
+		uint64_t xscol:4;
+		uint64_t reserved_6_7:2;
+		uint64_t undflw:4;
+		uint64_t pko_nxp:1;
+		uint64_t pko_nxa:1;
+#else
+		uint64_t pko_nxa:1;
+		uint64_t pko_nxp:1;
+		uint64_t undflw:4;
+		uint64_t reserved_6_7:2;
+		uint64_t xscol:4;
+		uint64_t xsdef:4;
+		uint64_t late_col:4;
+		uint64_t ptp_lost:4;
+		uint64_t xchange:1;
+		uint64_t reserved_25_63:39;
+#endif
+	} cn68xx;
+	struct cvmx_gmxx_tx_int_reg_cn68xx cn68xxp1;
+	struct cvmx_gmxx_tx_int_reg_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_25_63:39;
+		uint64_t xchange:1;
+		uint64_t reserved_22_23:2;
+		uint64_t ptp_lost:2;
+		uint64_t reserved_18_19:2;
+		uint64_t late_col:2;
+		uint64_t reserved_14_15:2;
+		uint64_t xsdef:2;
+		uint64_t reserved_10_11:2;
+		uint64_t xscol:2;
+		uint64_t reserved_4_7:4;
+		uint64_t undflw:2;
+		uint64_t reserved_1_1:1;
+		uint64_t pko_nxa:1;
+#else
+		uint64_t pko_nxa:1;
+		uint64_t reserved_1_1:1;
+		uint64_t undflw:2;
+		uint64_t reserved_4_7:4;
+		uint64_t xscol:2;
+		uint64_t reserved_10_11:2;
+		uint64_t xsdef:2;
+		uint64_t reserved_14_15:2;
+		uint64_t late_col:2;
+		uint64_t reserved_18_19:2;
+		uint64_t ptp_lost:2;
+		uint64_t reserved_22_23:2;
+		uint64_t xchange:1;
+		uint64_t reserved_25_63:39;
+#endif
+	} cnf71xx;
 };
 
 union cvmx_gmxx_tx_jam {
 	uint64_t u64;
 	struct cvmx_gmxx_tx_jam_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t jam:8;
+#else
+		uint64_t jam:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_gmxx_tx_jam_s cn30xx;
 	struct cvmx_gmxx_tx_jam_s cn31xx;
@@ -2317,13 +6544,25 @@
 	struct cvmx_gmxx_tx_jam_s cn56xxp1;
 	struct cvmx_gmxx_tx_jam_s cn58xx;
 	struct cvmx_gmxx_tx_jam_s cn58xxp1;
+	struct cvmx_gmxx_tx_jam_s cn61xx;
+	struct cvmx_gmxx_tx_jam_s cn63xx;
+	struct cvmx_gmxx_tx_jam_s cn63xxp1;
+	struct cvmx_gmxx_tx_jam_s cn66xx;
+	struct cvmx_gmxx_tx_jam_s cn68xx;
+	struct cvmx_gmxx_tx_jam_s cn68xxp1;
+	struct cvmx_gmxx_tx_jam_s cnf71xx;
 };
 
 union cvmx_gmxx_tx_lfsr {
 	uint64_t u64;
 	struct cvmx_gmxx_tx_lfsr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t lfsr:16;
+#else
+		uint64_t lfsr:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_gmxx_tx_lfsr_s cn30xx;
 	struct cvmx_gmxx_tx_lfsr_s cn31xx;
@@ -2336,32 +6575,64 @@
 	struct cvmx_gmxx_tx_lfsr_s cn56xxp1;
 	struct cvmx_gmxx_tx_lfsr_s cn58xx;
 	struct cvmx_gmxx_tx_lfsr_s cn58xxp1;
+	struct cvmx_gmxx_tx_lfsr_s cn61xx;
+	struct cvmx_gmxx_tx_lfsr_s cn63xx;
+	struct cvmx_gmxx_tx_lfsr_s cn63xxp1;
+	struct cvmx_gmxx_tx_lfsr_s cn66xx;
+	struct cvmx_gmxx_tx_lfsr_s cn68xx;
+	struct cvmx_gmxx_tx_lfsr_s cn68xxp1;
+	struct cvmx_gmxx_tx_lfsr_s cnf71xx;
 };
 
 union cvmx_gmxx_tx_ovr_bp {
 	uint64_t u64;
 	struct cvmx_gmxx_tx_ovr_bp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t tx_prt_bp:16;
 		uint64_t reserved_12_31:20;
 		uint64_t en:4;
 		uint64_t bp:4;
 		uint64_t ign_full:4;
+#else
+		uint64_t ign_full:4;
+		uint64_t bp:4;
+		uint64_t en:4;
+		uint64_t reserved_12_31:20;
+		uint64_t tx_prt_bp:16;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_gmxx_tx_ovr_bp_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_11_63:53;
 		uint64_t en:3;
 		uint64_t reserved_7_7:1;
 		uint64_t bp:3;
 		uint64_t reserved_3_3:1;
 		uint64_t ign_full:3;
+#else
+		uint64_t ign_full:3;
+		uint64_t reserved_3_3:1;
+		uint64_t bp:3;
+		uint64_t reserved_7_7:1;
+		uint64_t en:3;
+		uint64_t reserved_11_63:53;
+#endif
 	} cn30xx;
 	struct cvmx_gmxx_tx_ovr_bp_cn30xx cn31xx;
 	struct cvmx_gmxx_tx_ovr_bp_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t en:4;
 		uint64_t bp:4;
 		uint64_t ign_full:4;
+#else
+		uint64_t ign_full:4;
+		uint64_t bp:4;
+		uint64_t en:4;
+		uint64_t reserved_12_63:52;
+#endif
 	} cn38xx;
 	struct cvmx_gmxx_tx_ovr_bp_cn38xx cn38xxp2;
 	struct cvmx_gmxx_tx_ovr_bp_cn30xx cn50xx;
@@ -2371,13 +6642,45 @@
 	struct cvmx_gmxx_tx_ovr_bp_s cn56xxp1;
 	struct cvmx_gmxx_tx_ovr_bp_cn38xx cn58xx;
 	struct cvmx_gmxx_tx_ovr_bp_cn38xx cn58xxp1;
+	struct cvmx_gmxx_tx_ovr_bp_s cn61xx;
+	struct cvmx_gmxx_tx_ovr_bp_s cn63xx;
+	struct cvmx_gmxx_tx_ovr_bp_s cn63xxp1;
+	struct cvmx_gmxx_tx_ovr_bp_s cn66xx;
+	struct cvmx_gmxx_tx_ovr_bp_s cn68xx;
+	struct cvmx_gmxx_tx_ovr_bp_s cn68xxp1;
+	struct cvmx_gmxx_tx_ovr_bp_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_48_63:16;
+		uint64_t tx_prt_bp:16;
+		uint64_t reserved_10_31:22;
+		uint64_t en:2;
+		uint64_t reserved_6_7:2;
+		uint64_t bp:2;
+		uint64_t reserved_2_3:2;
+		uint64_t ign_full:2;
+#else
+		uint64_t ign_full:2;
+		uint64_t reserved_2_3:2;
+		uint64_t bp:2;
+		uint64_t reserved_6_7:2;
+		uint64_t en:2;
+		uint64_t reserved_10_31:22;
+		uint64_t tx_prt_bp:16;
+		uint64_t reserved_48_63:16;
+#endif
+	} cnf71xx;
 };
 
 union cvmx_gmxx_tx_pause_pkt_dmac {
 	uint64_t u64;
 	struct cvmx_gmxx_tx_pause_pkt_dmac_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t dmac:48;
+#else
+		uint64_t dmac:48;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_gmxx_tx_pause_pkt_dmac_s cn30xx;
 	struct cvmx_gmxx_tx_pause_pkt_dmac_s cn31xx;
@@ -2390,13 +6693,25 @@
 	struct cvmx_gmxx_tx_pause_pkt_dmac_s cn56xxp1;
 	struct cvmx_gmxx_tx_pause_pkt_dmac_s cn58xx;
 	struct cvmx_gmxx_tx_pause_pkt_dmac_s cn58xxp1;
+	struct cvmx_gmxx_tx_pause_pkt_dmac_s cn61xx;
+	struct cvmx_gmxx_tx_pause_pkt_dmac_s cn63xx;
+	struct cvmx_gmxx_tx_pause_pkt_dmac_s cn63xxp1;
+	struct cvmx_gmxx_tx_pause_pkt_dmac_s cn66xx;
+	struct cvmx_gmxx_tx_pause_pkt_dmac_s cn68xx;
+	struct cvmx_gmxx_tx_pause_pkt_dmac_s cn68xxp1;
+	struct cvmx_gmxx_tx_pause_pkt_dmac_s cnf71xx;
 };
 
 union cvmx_gmxx_tx_pause_pkt_type {
 	uint64_t u64;
 	struct cvmx_gmxx_tx_pause_pkt_type_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t type:16;
+#else
+		uint64_t type:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_gmxx_tx_pause_pkt_type_s cn30xx;
 	struct cvmx_gmxx_tx_pause_pkt_type_s cn31xx;
@@ -2409,13 +6724,25 @@
 	struct cvmx_gmxx_tx_pause_pkt_type_s cn56xxp1;
 	struct cvmx_gmxx_tx_pause_pkt_type_s cn58xx;
 	struct cvmx_gmxx_tx_pause_pkt_type_s cn58xxp1;
+	struct cvmx_gmxx_tx_pause_pkt_type_s cn61xx;
+	struct cvmx_gmxx_tx_pause_pkt_type_s cn63xx;
+	struct cvmx_gmxx_tx_pause_pkt_type_s cn63xxp1;
+	struct cvmx_gmxx_tx_pause_pkt_type_s cn66xx;
+	struct cvmx_gmxx_tx_pause_pkt_type_s cn68xx;
+	struct cvmx_gmxx_tx_pause_pkt_type_s cn68xxp1;
+	struct cvmx_gmxx_tx_pause_pkt_type_s cnf71xx;
 };
 
 union cvmx_gmxx_tx_prts {
 	uint64_t u64;
 	struct cvmx_gmxx_tx_prts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t prts:5;
+#else
+		uint64_t prts:5;
+		uint64_t reserved_5_63:59;
+#endif
 	} s;
 	struct cvmx_gmxx_tx_prts_s cn30xx;
 	struct cvmx_gmxx_tx_prts_s cn31xx;
@@ -2428,14 +6755,27 @@
 	struct cvmx_gmxx_tx_prts_s cn56xxp1;
 	struct cvmx_gmxx_tx_prts_s cn58xx;
 	struct cvmx_gmxx_tx_prts_s cn58xxp1;
+	struct cvmx_gmxx_tx_prts_s cn61xx;
+	struct cvmx_gmxx_tx_prts_s cn63xx;
+	struct cvmx_gmxx_tx_prts_s cn63xxp1;
+	struct cvmx_gmxx_tx_prts_s cn66xx;
+	struct cvmx_gmxx_tx_prts_s cn68xx;
+	struct cvmx_gmxx_tx_prts_s cn68xxp1;
+	struct cvmx_gmxx_tx_prts_s cnf71xx;
 };
 
 union cvmx_gmxx_tx_spi_ctl {
 	uint64_t u64;
 	struct cvmx_gmxx_tx_spi_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t tpa_clr:1;
 		uint64_t cont_pkt:1;
+#else
+		uint64_t cont_pkt:1;
+		uint64_t tpa_clr:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_gmxx_tx_spi_ctl_s cn38xx;
 	struct cvmx_gmxx_tx_spi_ctl_s cn38xxp2;
@@ -2446,8 +6786,13 @@
 union cvmx_gmxx_tx_spi_drain {
 	uint64_t u64;
 	struct cvmx_gmxx_tx_spi_drain_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t drain:16;
+#else
+		uint64_t drain:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_gmxx_tx_spi_drain_s cn38xx;
 	struct cvmx_gmxx_tx_spi_drain_s cn58xx;
@@ -2457,15 +6802,28 @@
 union cvmx_gmxx_tx_spi_max {
 	uint64_t u64;
 	struct cvmx_gmxx_tx_spi_max_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_23_63:41;
 		uint64_t slice:7;
 		uint64_t max2:8;
 		uint64_t max1:8;
+#else
+		uint64_t max1:8;
+		uint64_t max2:8;
+		uint64_t slice:7;
+		uint64_t reserved_23_63:41;
+#endif
 	} s;
 	struct cvmx_gmxx_tx_spi_max_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t max2:8;
 		uint64_t max1:8;
+#else
+		uint64_t max1:8;
+		uint64_t max2:8;
+		uint64_t reserved_16_63:48;
+#endif
 	} cn38xx;
 	struct cvmx_gmxx_tx_spi_max_cn38xx cn38xxp2;
 	struct cvmx_gmxx_tx_spi_max_s cn58xx;
@@ -2475,8 +6833,13 @@
 union cvmx_gmxx_tx_spi_roundx {
 	uint64_t u64;
 	struct cvmx_gmxx_tx_spi_roundx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t round:16;
+#else
+		uint64_t round:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_gmxx_tx_spi_roundx_s cn58xx;
 	struct cvmx_gmxx_tx_spi_roundx_s cn58xxp1;
@@ -2485,8 +6848,13 @@
 union cvmx_gmxx_tx_spi_thresh {
 	uint64_t u64;
 	struct cvmx_gmxx_tx_spi_thresh_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t thresh:6;
+#else
+		uint64_t thresh:6;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
 	struct cvmx_gmxx_tx_spi_thresh_s cn38xx;
 	struct cvmx_gmxx_tx_spi_thresh_s cn38xxp2;
@@ -2497,6 +6865,7 @@
 union cvmx_gmxx_tx_xaui_ctl {
 	uint64_t u64;
 	struct cvmx_gmxx_tx_xaui_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_11_63:53;
 		uint64_t hg_pause_hgi:2;
 		uint64_t hg_en:1;
@@ -2506,24 +6875,55 @@
 		uint64_t reserved_2_3:2;
 		uint64_t uni_en:1;
 		uint64_t dic_en:1;
+#else
+		uint64_t dic_en:1;
+		uint64_t uni_en:1;
+		uint64_t reserved_2_3:2;
+		uint64_t ls:2;
+		uint64_t ls_byp:1;
+		uint64_t reserved_7_7:1;
+		uint64_t hg_en:1;
+		uint64_t hg_pause_hgi:2;
+		uint64_t reserved_11_63:53;
+#endif
 	} s;
 	struct cvmx_gmxx_tx_xaui_ctl_s cn52xx;
 	struct cvmx_gmxx_tx_xaui_ctl_s cn52xxp1;
 	struct cvmx_gmxx_tx_xaui_ctl_s cn56xx;
 	struct cvmx_gmxx_tx_xaui_ctl_s cn56xxp1;
+	struct cvmx_gmxx_tx_xaui_ctl_s cn61xx;
+	struct cvmx_gmxx_tx_xaui_ctl_s cn63xx;
+	struct cvmx_gmxx_tx_xaui_ctl_s cn63xxp1;
+	struct cvmx_gmxx_tx_xaui_ctl_s cn66xx;
+	struct cvmx_gmxx_tx_xaui_ctl_s cn68xx;
+	struct cvmx_gmxx_tx_xaui_ctl_s cn68xxp1;
+	struct cvmx_gmxx_tx_xaui_ctl_s cnf71xx;
 };
 
 union cvmx_gmxx_xaui_ext_loopback {
 	uint64_t u64;
 	struct cvmx_gmxx_xaui_ext_loopback_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t en:1;
 		uint64_t thresh:4;
+#else
+		uint64_t thresh:4;
+		uint64_t en:1;
+		uint64_t reserved_5_63:59;
+#endif
 	} s;
 	struct cvmx_gmxx_xaui_ext_loopback_s cn52xx;
 	struct cvmx_gmxx_xaui_ext_loopback_s cn52xxp1;
 	struct cvmx_gmxx_xaui_ext_loopback_s cn56xx;
 	struct cvmx_gmxx_xaui_ext_loopback_s cn56xxp1;
+	struct cvmx_gmxx_xaui_ext_loopback_s cn61xx;
+	struct cvmx_gmxx_xaui_ext_loopback_s cn63xx;
+	struct cvmx_gmxx_xaui_ext_loopback_s cn63xxp1;
+	struct cvmx_gmxx_xaui_ext_loopback_s cn66xx;
+	struct cvmx_gmxx_xaui_ext_loopback_s cn68xx;
+	struct cvmx_gmxx_xaui_ext_loopback_s cn68xxp1;
+	struct cvmx_gmxx_xaui_ext_loopback_s cnf71xx;
 };
 
 #endif
diff --git a/arch/mips/include/asm/octeon/cvmx-gpio-defs.h b/arch/mips/include/asm/octeon/cvmx-gpio-defs.h
index 395564e..4719fcf 100644
--- a/arch/mips/include/asm/octeon/cvmx-gpio-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-gpio-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -34,7 +34,10 @@
 #define CVMX_GPIO_CLK_QLMX(offset) (CVMX_ADD_IO_SEG(0x00010700000008E0ull) + ((offset) & 1) * 8)
 #define CVMX_GPIO_DBG_ENA (CVMX_ADD_IO_SEG(0x00010700000008A0ull))
 #define CVMX_GPIO_INT_CLR (CVMX_ADD_IO_SEG(0x0001070000000898ull))
+#define CVMX_GPIO_MULTI_CAST (CVMX_ADD_IO_SEG(0x00010700000008B0ull))
+#define CVMX_GPIO_PIN_ENA (CVMX_ADD_IO_SEG(0x00010700000008B8ull))
 #define CVMX_GPIO_RX_DAT (CVMX_ADD_IO_SEG(0x0001070000000880ull))
+#define CVMX_GPIO_TIM_CTL (CVMX_ADD_IO_SEG(0x00010700000008A0ull))
 #define CVMX_GPIO_TX_CLR (CVMX_ADD_IO_SEG(0x0001070000000890ull))
 #define CVMX_GPIO_TX_SET (CVMX_ADD_IO_SEG(0x0001070000000888ull))
 #define CVMX_GPIO_XBIT_CFGX(offset) (CVMX_ADD_IO_SEG(0x0001070000000900ull) + ((offset) & 31) * 8 - 8*16)
@@ -42,6 +45,7 @@
 union cvmx_gpio_bit_cfgx {
 	uint64_t u64;
 	struct cvmx_gpio_bit_cfgx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_17_63:47;
 		uint64_t synce_sel:2;
 		uint64_t clk_gen:1;
@@ -52,8 +56,21 @@
 		uint64_t int_en:1;
 		uint64_t rx_xor:1;
 		uint64_t tx_oe:1;
+#else
+		uint64_t tx_oe:1;
+		uint64_t rx_xor:1;
+		uint64_t int_en:1;
+		uint64_t int_type:1;
+		uint64_t fil_cnt:4;
+		uint64_t fil_sel:4;
+		uint64_t clk_sel:2;
+		uint64_t clk_gen:1;
+		uint64_t synce_sel:2;
+		uint64_t reserved_17_63:47;
+#endif
 	} s;
 	struct cvmx_gpio_bit_cfgx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t fil_sel:4;
 		uint64_t fil_cnt:4;
@@ -61,12 +78,22 @@
 		uint64_t int_en:1;
 		uint64_t rx_xor:1;
 		uint64_t tx_oe:1;
+#else
+		uint64_t tx_oe:1;
+		uint64_t rx_xor:1;
+		uint64_t int_en:1;
+		uint64_t int_type:1;
+		uint64_t fil_cnt:4;
+		uint64_t fil_sel:4;
+		uint64_t reserved_12_63:52;
+#endif
 	} cn30xx;
 	struct cvmx_gpio_bit_cfgx_cn30xx cn31xx;
 	struct cvmx_gpio_bit_cfgx_cn30xx cn38xx;
 	struct cvmx_gpio_bit_cfgx_cn30xx cn38xxp2;
 	struct cvmx_gpio_bit_cfgx_cn30xx cn50xx;
 	struct cvmx_gpio_bit_cfgx_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_15_63:49;
 		uint64_t clk_gen:1;
 		uint64_t clk_sel:2;
@@ -76,22 +103,44 @@
 		uint64_t int_en:1;
 		uint64_t rx_xor:1;
 		uint64_t tx_oe:1;
+#else
+		uint64_t tx_oe:1;
+		uint64_t rx_xor:1;
+		uint64_t int_en:1;
+		uint64_t int_type:1;
+		uint64_t fil_cnt:4;
+		uint64_t fil_sel:4;
+		uint64_t clk_sel:2;
+		uint64_t clk_gen:1;
+		uint64_t reserved_15_63:49;
+#endif
 	} cn52xx;
 	struct cvmx_gpio_bit_cfgx_cn52xx cn52xxp1;
 	struct cvmx_gpio_bit_cfgx_cn52xx cn56xx;
 	struct cvmx_gpio_bit_cfgx_cn52xx cn56xxp1;
 	struct cvmx_gpio_bit_cfgx_cn30xx cn58xx;
 	struct cvmx_gpio_bit_cfgx_cn30xx cn58xxp1;
+	struct cvmx_gpio_bit_cfgx_s cn61xx;
 	struct cvmx_gpio_bit_cfgx_s cn63xx;
 	struct cvmx_gpio_bit_cfgx_s cn63xxp1;
+	struct cvmx_gpio_bit_cfgx_s cn66xx;
+	struct cvmx_gpio_bit_cfgx_s cn68xx;
+	struct cvmx_gpio_bit_cfgx_s cn68xxp1;
+	struct cvmx_gpio_bit_cfgx_s cnf71xx;
 };
 
 union cvmx_gpio_boot_ena {
 	uint64_t u64;
 	struct cvmx_gpio_boot_ena_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t boot_ena:4;
 		uint64_t reserved_0_7:8;
+#else
+		uint64_t reserved_0_7:8;
+		uint64_t boot_ena:4;
+		uint64_t reserved_12_63:52;
+#endif
 	} s;
 	struct cvmx_gpio_boot_ena_s cn30xx;
 	struct cvmx_gpio_boot_ena_s cn31xx;
@@ -101,33 +150,87 @@
 union cvmx_gpio_clk_genx {
 	uint64_t u64;
 	struct cvmx_gpio_clk_genx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t n:32;
+#else
+		uint64_t n:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_gpio_clk_genx_s cn52xx;
 	struct cvmx_gpio_clk_genx_s cn52xxp1;
 	struct cvmx_gpio_clk_genx_s cn56xx;
 	struct cvmx_gpio_clk_genx_s cn56xxp1;
+	struct cvmx_gpio_clk_genx_s cn61xx;
 	struct cvmx_gpio_clk_genx_s cn63xx;
 	struct cvmx_gpio_clk_genx_s cn63xxp1;
+	struct cvmx_gpio_clk_genx_s cn66xx;
+	struct cvmx_gpio_clk_genx_s cn68xx;
+	struct cvmx_gpio_clk_genx_s cn68xxp1;
+	struct cvmx_gpio_clk_genx_s cnf71xx;
 };
 
 union cvmx_gpio_clk_qlmx {
 	uint64_t u64;
 	struct cvmx_gpio_clk_qlmx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_11_63:53;
+		uint64_t qlm_sel:3;
+		uint64_t reserved_3_7:5;
+		uint64_t div:1;
+		uint64_t lane_sel:2;
+#else
+		uint64_t lane_sel:2;
+		uint64_t div:1;
+		uint64_t reserved_3_7:5;
+		uint64_t qlm_sel:3;
+		uint64_t reserved_11_63:53;
+#endif
+	} s;
+	struct cvmx_gpio_clk_qlmx_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t qlm_sel:2;
+		uint64_t reserved_3_7:5;
+		uint64_t div:1;
+		uint64_t lane_sel:2;
+#else
+		uint64_t lane_sel:2;
+		uint64_t div:1;
+		uint64_t reserved_3_7:5;
+		uint64_t qlm_sel:2;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn61xx;
+	struct cvmx_gpio_clk_qlmx_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_3_63:61;
 		uint64_t div:1;
 		uint64_t lane_sel:2;
-	} s;
-	struct cvmx_gpio_clk_qlmx_s cn63xx;
-	struct cvmx_gpio_clk_qlmx_s cn63xxp1;
+#else
+		uint64_t lane_sel:2;
+		uint64_t div:1;
+		uint64_t reserved_3_63:61;
+#endif
+	} cn63xx;
+	struct cvmx_gpio_clk_qlmx_cn63xx cn63xxp1;
+	struct cvmx_gpio_clk_qlmx_cn61xx cn66xx;
+	struct cvmx_gpio_clk_qlmx_s cn68xx;
+	struct cvmx_gpio_clk_qlmx_s cn68xxp1;
+	struct cvmx_gpio_clk_qlmx_cn61xx cnf71xx;
 };
 
 union cvmx_gpio_dbg_ena {
 	uint64_t u64;
 	struct cvmx_gpio_dbg_ena_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_21_63:43;
 		uint64_t dbg_ena:21;
+#else
+		uint64_t dbg_ena:21;
+		uint64_t reserved_21_63:43;
+#endif
 	} s;
 	struct cvmx_gpio_dbg_ena_s cn30xx;
 	struct cvmx_gpio_dbg_ena_s cn31xx;
@@ -137,8 +240,13 @@
 union cvmx_gpio_int_clr {
 	uint64_t u64;
 	struct cvmx_gpio_int_clr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t type:16;
+#else
+		uint64_t type:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_gpio_int_clr_s cn30xx;
 	struct cvmx_gpio_int_clr_s cn31xx;
@@ -151,21 +259,69 @@
 	struct cvmx_gpio_int_clr_s cn56xxp1;
 	struct cvmx_gpio_int_clr_s cn58xx;
 	struct cvmx_gpio_int_clr_s cn58xxp1;
+	struct cvmx_gpio_int_clr_s cn61xx;
 	struct cvmx_gpio_int_clr_s cn63xx;
 	struct cvmx_gpio_int_clr_s cn63xxp1;
+	struct cvmx_gpio_int_clr_s cn66xx;
+	struct cvmx_gpio_int_clr_s cn68xx;
+	struct cvmx_gpio_int_clr_s cn68xxp1;
+	struct cvmx_gpio_int_clr_s cnf71xx;
+};
+
+union cvmx_gpio_multi_cast {
+	uint64_t u64;
+	struct cvmx_gpio_multi_cast_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_1_63:63;
+		uint64_t en:1;
+#else
+		uint64_t en:1;
+		uint64_t reserved_1_63:63;
+#endif
+	} s;
+	struct cvmx_gpio_multi_cast_s cn61xx;
+	struct cvmx_gpio_multi_cast_s cnf71xx;
+};
+
+union cvmx_gpio_pin_ena {
+	uint64_t u64;
+	struct cvmx_gpio_pin_ena_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_20_63:44;
+		uint64_t ena19:1;
+		uint64_t ena18:1;
+		uint64_t reserved_0_17:18;
+#else
+		uint64_t reserved_0_17:18;
+		uint64_t ena18:1;
+		uint64_t ena19:1;
+		uint64_t reserved_20_63:44;
+#endif
+	} s;
+	struct cvmx_gpio_pin_ena_s cn66xx;
 };
 
 union cvmx_gpio_rx_dat {
 	uint64_t u64;
 	struct cvmx_gpio_rx_dat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_24_63:40;
 		uint64_t dat:24;
+#else
+		uint64_t dat:24;
+		uint64_t reserved_24_63:40;
+#endif
 	} s;
 	struct cvmx_gpio_rx_dat_s cn30xx;
 	struct cvmx_gpio_rx_dat_s cn31xx;
 	struct cvmx_gpio_rx_dat_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t dat:16;
+#else
+		uint64_t dat:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} cn38xx;
 	struct cvmx_gpio_rx_dat_cn38xx cn38xxp2;
 	struct cvmx_gpio_rx_dat_s cn50xx;
@@ -175,21 +331,59 @@
 	struct cvmx_gpio_rx_dat_cn38xx cn56xxp1;
 	struct cvmx_gpio_rx_dat_cn38xx cn58xx;
 	struct cvmx_gpio_rx_dat_cn38xx cn58xxp1;
+	struct cvmx_gpio_rx_dat_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_20_63:44;
+		uint64_t dat:20;
+#else
+		uint64_t dat:20;
+		uint64_t reserved_20_63:44;
+#endif
+	} cn61xx;
 	struct cvmx_gpio_rx_dat_cn38xx cn63xx;
 	struct cvmx_gpio_rx_dat_cn38xx cn63xxp1;
+	struct cvmx_gpio_rx_dat_cn61xx cn66xx;
+	struct cvmx_gpio_rx_dat_cn38xx cn68xx;
+	struct cvmx_gpio_rx_dat_cn38xx cn68xxp1;
+	struct cvmx_gpio_rx_dat_cn61xx cnf71xx;
+};
+
+union cvmx_gpio_tim_ctl {
+	uint64_t u64;
+	struct cvmx_gpio_tim_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t sel:4;
+#else
+		uint64_t sel:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_gpio_tim_ctl_s cn68xx;
+	struct cvmx_gpio_tim_ctl_s cn68xxp1;
 };
 
 union cvmx_gpio_tx_clr {
 	uint64_t u64;
 	struct cvmx_gpio_tx_clr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_24_63:40;
 		uint64_t clr:24;
+#else
+		uint64_t clr:24;
+		uint64_t reserved_24_63:40;
+#endif
 	} s;
 	struct cvmx_gpio_tx_clr_s cn30xx;
 	struct cvmx_gpio_tx_clr_s cn31xx;
 	struct cvmx_gpio_tx_clr_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t clr:16;
+#else
+		uint64_t clr:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} cn38xx;
 	struct cvmx_gpio_tx_clr_cn38xx cn38xxp2;
 	struct cvmx_gpio_tx_clr_s cn50xx;
@@ -199,21 +393,44 @@
 	struct cvmx_gpio_tx_clr_cn38xx cn56xxp1;
 	struct cvmx_gpio_tx_clr_cn38xx cn58xx;
 	struct cvmx_gpio_tx_clr_cn38xx cn58xxp1;
+	struct cvmx_gpio_tx_clr_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_20_63:44;
+		uint64_t clr:20;
+#else
+		uint64_t clr:20;
+		uint64_t reserved_20_63:44;
+#endif
+	} cn61xx;
 	struct cvmx_gpio_tx_clr_cn38xx cn63xx;
 	struct cvmx_gpio_tx_clr_cn38xx cn63xxp1;
+	struct cvmx_gpio_tx_clr_cn61xx cn66xx;
+	struct cvmx_gpio_tx_clr_cn38xx cn68xx;
+	struct cvmx_gpio_tx_clr_cn38xx cn68xxp1;
+	struct cvmx_gpio_tx_clr_cn61xx cnf71xx;
 };
 
 union cvmx_gpio_tx_set {
 	uint64_t u64;
 	struct cvmx_gpio_tx_set_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_24_63:40;
 		uint64_t set:24;
+#else
+		uint64_t set:24;
+		uint64_t reserved_24_63:40;
+#endif
 	} s;
 	struct cvmx_gpio_tx_set_s cn30xx;
 	struct cvmx_gpio_tx_set_s cn31xx;
 	struct cvmx_gpio_tx_set_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t set:16;
+#else
+		uint64_t set:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} cn38xx;
 	struct cvmx_gpio_tx_set_cn38xx cn38xxp2;
 	struct cvmx_gpio_tx_set_s cn50xx;
@@ -223,23 +440,72 @@
 	struct cvmx_gpio_tx_set_cn38xx cn56xxp1;
 	struct cvmx_gpio_tx_set_cn38xx cn58xx;
 	struct cvmx_gpio_tx_set_cn38xx cn58xxp1;
+	struct cvmx_gpio_tx_set_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_20_63:44;
+		uint64_t set:20;
+#else
+		uint64_t set:20;
+		uint64_t reserved_20_63:44;
+#endif
+	} cn61xx;
 	struct cvmx_gpio_tx_set_cn38xx cn63xx;
 	struct cvmx_gpio_tx_set_cn38xx cn63xxp1;
+	struct cvmx_gpio_tx_set_cn61xx cn66xx;
+	struct cvmx_gpio_tx_set_cn38xx cn68xx;
+	struct cvmx_gpio_tx_set_cn38xx cn68xxp1;
+	struct cvmx_gpio_tx_set_cn61xx cnf71xx;
 };
 
 union cvmx_gpio_xbit_cfgx {
 	uint64_t u64;
 	struct cvmx_gpio_xbit_cfgx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_17_63:47;
+		uint64_t synce_sel:2;
+		uint64_t clk_gen:1;
+		uint64_t clk_sel:2;
+		uint64_t fil_sel:4;
+		uint64_t fil_cnt:4;
+		uint64_t int_type:1;
+		uint64_t int_en:1;
+		uint64_t rx_xor:1;
+		uint64_t tx_oe:1;
+#else
+		uint64_t tx_oe:1;
+		uint64_t rx_xor:1;
+		uint64_t int_en:1;
+		uint64_t int_type:1;
+		uint64_t fil_cnt:4;
+		uint64_t fil_sel:4;
+		uint64_t clk_sel:2;
+		uint64_t clk_gen:1;
+		uint64_t synce_sel:2;
+		uint64_t reserved_17_63:47;
+#endif
+	} s;
+	struct cvmx_gpio_xbit_cfgx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t fil_sel:4;
 		uint64_t fil_cnt:4;
 		uint64_t reserved_2_3:2;
 		uint64_t rx_xor:1;
 		uint64_t tx_oe:1;
-	} s;
-	struct cvmx_gpio_xbit_cfgx_s cn30xx;
-	struct cvmx_gpio_xbit_cfgx_s cn31xx;
-	struct cvmx_gpio_xbit_cfgx_s cn50xx;
+#else
+		uint64_t tx_oe:1;
+		uint64_t rx_xor:1;
+		uint64_t reserved_2_3:2;
+		uint64_t fil_cnt:4;
+		uint64_t fil_sel:4;
+		uint64_t reserved_12_63:52;
+#endif
+	} cn30xx;
+	struct cvmx_gpio_xbit_cfgx_cn30xx cn31xx;
+	struct cvmx_gpio_xbit_cfgx_cn30xx cn50xx;
+	struct cvmx_gpio_xbit_cfgx_s cn61xx;
+	struct cvmx_gpio_xbit_cfgx_s cn66xx;
+	struct cvmx_gpio_xbit_cfgx_s cnf71xx;
 };
 
 #endif
diff --git a/arch/mips/include/asm/octeon/cvmx-iob-defs.h b/arch/mips/include/asm/octeon/cvmx-iob-defs.h
index d7d856c..7936f81 100644
--- a/arch/mips/include/asm/octeon/cvmx-iob-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-iob-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -51,10 +51,86 @@
 #define CVMX_IOB_P2C_REQ_PRI_CNT (CVMX_ADD_IO_SEG(0x00011800F0000018ull))
 #define CVMX_IOB_PKT_ERR (CVMX_ADD_IO_SEG(0x00011800F0000068ull))
 #define CVMX_IOB_TO_CMB_CREDITS (CVMX_ADD_IO_SEG(0x00011800F00000B0ull))
+#define CVMX_IOB_TO_NCB_DID_00_CREDITS (CVMX_ADD_IO_SEG(0x00011800F0000800ull))
+#define CVMX_IOB_TO_NCB_DID_111_CREDITS (CVMX_ADD_IO_SEG(0x00011800F0000B78ull))
+#define CVMX_IOB_TO_NCB_DID_223_CREDITS (CVMX_ADD_IO_SEG(0x00011800F0000EF8ull))
+#define CVMX_IOB_TO_NCB_DID_24_CREDITS (CVMX_ADD_IO_SEG(0x00011800F00008C0ull))
+#define CVMX_IOB_TO_NCB_DID_32_CREDITS (CVMX_ADD_IO_SEG(0x00011800F0000900ull))
+#define CVMX_IOB_TO_NCB_DID_40_CREDITS (CVMX_ADD_IO_SEG(0x00011800F0000940ull))
+#define CVMX_IOB_TO_NCB_DID_55_CREDITS (CVMX_ADD_IO_SEG(0x00011800F00009B8ull))
+#define CVMX_IOB_TO_NCB_DID_64_CREDITS (CVMX_ADD_IO_SEG(0x00011800F0000A00ull))
+#define CVMX_IOB_TO_NCB_DID_79_CREDITS (CVMX_ADD_IO_SEG(0x00011800F0000A78ull))
+#define CVMX_IOB_TO_NCB_DID_96_CREDITS (CVMX_ADD_IO_SEG(0x00011800F0000B00ull))
+#define CVMX_IOB_TO_NCB_DID_98_CREDITS (CVMX_ADD_IO_SEG(0x00011800F0000B10ull))
 
 union cvmx_iob_bist_status {
 	uint64_t u64;
 	struct cvmx_iob_bist_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_2_63:62;
+		uint64_t ibd:1;
+		uint64_t icd:1;
+#else
+		uint64_t icd:1;
+		uint64_t ibd:1;
+		uint64_t reserved_2_63:62;
+#endif
+	} s;
+	struct cvmx_iob_bist_status_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_18_63:46;
+		uint64_t icnrcb:1;
+		uint64_t icr0:1;
+		uint64_t icr1:1;
+		uint64_t icnr1:1;
+		uint64_t icnr0:1;
+		uint64_t ibdr0:1;
+		uint64_t ibdr1:1;
+		uint64_t ibr0:1;
+		uint64_t ibr1:1;
+		uint64_t icnrt:1;
+		uint64_t ibrq0:1;
+		uint64_t ibrq1:1;
+		uint64_t icrn0:1;
+		uint64_t icrn1:1;
+		uint64_t icrp0:1;
+		uint64_t icrp1:1;
+		uint64_t ibd:1;
+		uint64_t icd:1;
+#else
+		uint64_t icd:1;
+		uint64_t ibd:1;
+		uint64_t icrp1:1;
+		uint64_t icrp0:1;
+		uint64_t icrn1:1;
+		uint64_t icrn0:1;
+		uint64_t ibrq1:1;
+		uint64_t ibrq0:1;
+		uint64_t icnrt:1;
+		uint64_t ibr1:1;
+		uint64_t ibr0:1;
+		uint64_t ibdr1:1;
+		uint64_t ibdr0:1;
+		uint64_t icnr0:1;
+		uint64_t icnr1:1;
+		uint64_t icr1:1;
+		uint64_t icr0:1;
+		uint64_t icnrcb:1;
+		uint64_t reserved_18_63:46;
+#endif
+	} cn30xx;
+	struct cvmx_iob_bist_status_cn30xx cn31xx;
+	struct cvmx_iob_bist_status_cn30xx cn38xx;
+	struct cvmx_iob_bist_status_cn30xx cn38xxp2;
+	struct cvmx_iob_bist_status_cn30xx cn50xx;
+	struct cvmx_iob_bist_status_cn30xx cn52xx;
+	struct cvmx_iob_bist_status_cn30xx cn52xxp1;
+	struct cvmx_iob_bist_status_cn30xx cn56xx;
+	struct cvmx_iob_bist_status_cn30xx cn56xxp1;
+	struct cvmx_iob_bist_status_cn30xx cn58xx;
+	struct cvmx_iob_bist_status_cn30xx cn58xxp1;
+	struct cvmx_iob_bist_status_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_23_63:41;
 		uint64_t xmdfif:1;
 		uint64_t xmcfif:1;
@@ -79,16 +155,48 @@
 		uint64_t icrp1:1;
 		uint64_t ibd:1;
 		uint64_t icd:1;
-	} s;
-	struct cvmx_iob_bist_status_cn30xx {
+#else
+		uint64_t icd:1;
+		uint64_t ibd:1;
+		uint64_t icrp1:1;
+		uint64_t icrp0:1;
+		uint64_t icrn1:1;
+		uint64_t icrn0:1;
+		uint64_t ibrq1:1;
+		uint64_t ibrq0:1;
+		uint64_t icnrt:1;
+		uint64_t ibr1:1;
+		uint64_t ibr0:1;
+		uint64_t ibdr1:1;
+		uint64_t ibdr0:1;
+		uint64_t icnr0:1;
+		uint64_t icnr1:1;
+		uint64_t icr1:1;
+		uint64_t icr0:1;
+		uint64_t icnrcb:1;
+		uint64_t iocfif:1;
+		uint64_t rsdfif:1;
+		uint64_t iorfif:1;
+		uint64_t xmcfif:1;
+		uint64_t xmdfif:1;
+		uint64_t reserved_23_63:41;
+#endif
+	} cn61xx;
+	struct cvmx_iob_bist_status_cn61xx cn63xx;
+	struct cvmx_iob_bist_status_cn61xx cn63xxp1;
+	struct cvmx_iob_bist_status_cn61xx cn66xx;
+	struct cvmx_iob_bist_status_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_18_63:46;
+		uint64_t xmdfif:1;
+		uint64_t xmcfif:1;
+		uint64_t iorfif:1;
+		uint64_t rsdfif:1;
+		uint64_t iocfif:1;
 		uint64_t icnrcb:1;
 		uint64_t icr0:1;
 		uint64_t icr1:1;
-		uint64_t icnr1:1;
 		uint64_t icnr0:1;
-		uint64_t ibdr0:1;
-		uint64_t ibdr1:1;
 		uint64_t ibr0:1;
 		uint64_t ibr1:1;
 		uint64_t icnrt:1;
@@ -96,28 +204,129 @@
 		uint64_t ibrq1:1;
 		uint64_t icrn0:1;
 		uint64_t icrn1:1;
-		uint64_t icrp0:1;
-		uint64_t icrp1:1;
 		uint64_t ibd:1;
 		uint64_t icd:1;
-	} cn30xx;
-	struct cvmx_iob_bist_status_cn30xx cn31xx;
-	struct cvmx_iob_bist_status_cn30xx cn38xx;
-	struct cvmx_iob_bist_status_cn30xx cn38xxp2;
-	struct cvmx_iob_bist_status_cn30xx cn50xx;
-	struct cvmx_iob_bist_status_cn30xx cn52xx;
-	struct cvmx_iob_bist_status_cn30xx cn52xxp1;
-	struct cvmx_iob_bist_status_cn30xx cn56xx;
-	struct cvmx_iob_bist_status_cn30xx cn56xxp1;
-	struct cvmx_iob_bist_status_cn30xx cn58xx;
-	struct cvmx_iob_bist_status_cn30xx cn58xxp1;
-	struct cvmx_iob_bist_status_s cn63xx;
-	struct cvmx_iob_bist_status_s cn63xxp1;
+#else
+		uint64_t icd:1;
+		uint64_t ibd:1;
+		uint64_t icrn1:1;
+		uint64_t icrn0:1;
+		uint64_t ibrq1:1;
+		uint64_t ibrq0:1;
+		uint64_t icnrt:1;
+		uint64_t ibr1:1;
+		uint64_t ibr0:1;
+		uint64_t icnr0:1;
+		uint64_t icr1:1;
+		uint64_t icr0:1;
+		uint64_t icnrcb:1;
+		uint64_t iocfif:1;
+		uint64_t rsdfif:1;
+		uint64_t iorfif:1;
+		uint64_t xmcfif:1;
+		uint64_t xmdfif:1;
+		uint64_t reserved_18_63:46;
+#endif
+	} cn68xx;
+	struct cvmx_iob_bist_status_cn68xx cn68xxp1;
+	struct cvmx_iob_bist_status_cn61xx cnf71xx;
 };
 
 union cvmx_iob_ctl_status {
 	uint64_t u64;
 	struct cvmx_iob_ctl_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_11_63:53;
+		uint64_t fif_dly:1;
+		uint64_t xmc_per:4;
+		uint64_t reserved_5_5:1;
+		uint64_t outb_mat:1;
+		uint64_t inb_mat:1;
+		uint64_t pko_enb:1;
+		uint64_t dwb_enb:1;
+		uint64_t fau_end:1;
+#else
+		uint64_t fau_end:1;
+		uint64_t dwb_enb:1;
+		uint64_t pko_enb:1;
+		uint64_t inb_mat:1;
+		uint64_t outb_mat:1;
+		uint64_t reserved_5_5:1;
+		uint64_t xmc_per:4;
+		uint64_t fif_dly:1;
+		uint64_t reserved_11_63:53;
+#endif
+	} s;
+	struct cvmx_iob_ctl_status_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_5_63:59;
+		uint64_t outb_mat:1;
+		uint64_t inb_mat:1;
+		uint64_t pko_enb:1;
+		uint64_t dwb_enb:1;
+		uint64_t fau_end:1;
+#else
+		uint64_t fau_end:1;
+		uint64_t dwb_enb:1;
+		uint64_t pko_enb:1;
+		uint64_t inb_mat:1;
+		uint64_t outb_mat:1;
+		uint64_t reserved_5_63:59;
+#endif
+	} cn30xx;
+	struct cvmx_iob_ctl_status_cn30xx cn31xx;
+	struct cvmx_iob_ctl_status_cn30xx cn38xx;
+	struct cvmx_iob_ctl_status_cn30xx cn38xxp2;
+	struct cvmx_iob_ctl_status_cn30xx cn50xx;
+	struct cvmx_iob_ctl_status_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_6_63:58;
+		uint64_t rr_mode:1;
+		uint64_t outb_mat:1;
+		uint64_t inb_mat:1;
+		uint64_t pko_enb:1;
+		uint64_t dwb_enb:1;
+		uint64_t fau_end:1;
+#else
+		uint64_t fau_end:1;
+		uint64_t dwb_enb:1;
+		uint64_t pko_enb:1;
+		uint64_t inb_mat:1;
+		uint64_t outb_mat:1;
+		uint64_t rr_mode:1;
+		uint64_t reserved_6_63:58;
+#endif
+	} cn52xx;
+	struct cvmx_iob_ctl_status_cn30xx cn52xxp1;
+	struct cvmx_iob_ctl_status_cn30xx cn56xx;
+	struct cvmx_iob_ctl_status_cn30xx cn56xxp1;
+	struct cvmx_iob_ctl_status_cn30xx cn58xx;
+	struct cvmx_iob_ctl_status_cn30xx cn58xxp1;
+	struct cvmx_iob_ctl_status_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_11_63:53;
+		uint64_t fif_dly:1;
+		uint64_t xmc_per:4;
+		uint64_t rr_mode:1;
+		uint64_t outb_mat:1;
+		uint64_t inb_mat:1;
+		uint64_t pko_enb:1;
+		uint64_t dwb_enb:1;
+		uint64_t fau_end:1;
+#else
+		uint64_t fau_end:1;
+		uint64_t dwb_enb:1;
+		uint64_t pko_enb:1;
+		uint64_t inb_mat:1;
+		uint64_t outb_mat:1;
+		uint64_t rr_mode:1;
+		uint64_t xmc_per:4;
+		uint64_t fif_dly:1;
+		uint64_t reserved_11_63:53;
+#endif
+	} cn61xx;
+	struct cvmx_iob_ctl_status_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t xmc_per:4;
 		uint64_t rr_mode:1;
@@ -126,43 +335,58 @@
 		uint64_t pko_enb:1;
 		uint64_t dwb_enb:1;
 		uint64_t fau_end:1;
-	} s;
-	struct cvmx_iob_ctl_status_cn30xx {
-		uint64_t reserved_5_63:59;
-		uint64_t outb_mat:1;
-		uint64_t inb_mat:1;
-		uint64_t pko_enb:1;
-		uint64_t dwb_enb:1;
+#else
 		uint64_t fau_end:1;
-	} cn30xx;
-	struct cvmx_iob_ctl_status_cn30xx cn31xx;
-	struct cvmx_iob_ctl_status_cn30xx cn38xx;
-	struct cvmx_iob_ctl_status_cn30xx cn38xxp2;
-	struct cvmx_iob_ctl_status_cn30xx cn50xx;
-	struct cvmx_iob_ctl_status_cn52xx {
-		uint64_t reserved_6_63:58;
+		uint64_t dwb_enb:1;
+		uint64_t pko_enb:1;
+		uint64_t inb_mat:1;
+		uint64_t outb_mat:1;
 		uint64_t rr_mode:1;
+		uint64_t xmc_per:4;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn63xx;
+	struct cvmx_iob_ctl_status_cn63xx cn63xxp1;
+	struct cvmx_iob_ctl_status_cn61xx cn66xx;
+	struct cvmx_iob_ctl_status_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_11_63:53;
+		uint64_t fif_dly:1;
+		uint64_t xmc_per:4;
+		uint64_t rsvr5:1;
 		uint64_t outb_mat:1;
 		uint64_t inb_mat:1;
 		uint64_t pko_enb:1;
 		uint64_t dwb_enb:1;
 		uint64_t fau_end:1;
-	} cn52xx;
-	struct cvmx_iob_ctl_status_cn30xx cn52xxp1;
-	struct cvmx_iob_ctl_status_cn30xx cn56xx;
-	struct cvmx_iob_ctl_status_cn30xx cn56xxp1;
-	struct cvmx_iob_ctl_status_cn30xx cn58xx;
-	struct cvmx_iob_ctl_status_cn30xx cn58xxp1;
-	struct cvmx_iob_ctl_status_s cn63xx;
-	struct cvmx_iob_ctl_status_s cn63xxp1;
+#else
+		uint64_t fau_end:1;
+		uint64_t dwb_enb:1;
+		uint64_t pko_enb:1;
+		uint64_t inb_mat:1;
+		uint64_t outb_mat:1;
+		uint64_t rsvr5:1;
+		uint64_t xmc_per:4;
+		uint64_t fif_dly:1;
+		uint64_t reserved_11_63:53;
+#endif
+	} cn68xx;
+	struct cvmx_iob_ctl_status_cn68xx cn68xxp1;
+	struct cvmx_iob_ctl_status_cn61xx cnf71xx;
 };
 
 union cvmx_iob_dwb_pri_cnt {
 	uint64_t u64;
 	struct cvmx_iob_dwb_pri_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t cnt_enb:1;
 		uint64_t cnt_val:15;
+#else
+		uint64_t cnt_val:15;
+		uint64_t cnt_enb:1;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_iob_dwb_pri_cnt_s cn38xx;
 	struct cvmx_iob_dwb_pri_cnt_s cn38xxp2;
@@ -172,16 +396,25 @@
 	struct cvmx_iob_dwb_pri_cnt_s cn56xxp1;
 	struct cvmx_iob_dwb_pri_cnt_s cn58xx;
 	struct cvmx_iob_dwb_pri_cnt_s cn58xxp1;
+	struct cvmx_iob_dwb_pri_cnt_s cn61xx;
 	struct cvmx_iob_dwb_pri_cnt_s cn63xx;
 	struct cvmx_iob_dwb_pri_cnt_s cn63xxp1;
+	struct cvmx_iob_dwb_pri_cnt_s cn66xx;
+	struct cvmx_iob_dwb_pri_cnt_s cnf71xx;
 };
 
 union cvmx_iob_fau_timeout {
 	uint64_t u64;
 	struct cvmx_iob_fau_timeout_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_13_63:51;
 		uint64_t tout_enb:1;
 		uint64_t tout_val:12;
+#else
+		uint64_t tout_val:12;
+		uint64_t tout_enb:1;
+		uint64_t reserved_13_63:51;
+#endif
 	} s;
 	struct cvmx_iob_fau_timeout_s cn30xx;
 	struct cvmx_iob_fau_timeout_s cn31xx;
@@ -194,16 +427,27 @@
 	struct cvmx_iob_fau_timeout_s cn56xxp1;
 	struct cvmx_iob_fau_timeout_s cn58xx;
 	struct cvmx_iob_fau_timeout_s cn58xxp1;
+	struct cvmx_iob_fau_timeout_s cn61xx;
 	struct cvmx_iob_fau_timeout_s cn63xx;
 	struct cvmx_iob_fau_timeout_s cn63xxp1;
+	struct cvmx_iob_fau_timeout_s cn66xx;
+	struct cvmx_iob_fau_timeout_s cn68xx;
+	struct cvmx_iob_fau_timeout_s cn68xxp1;
+	struct cvmx_iob_fau_timeout_s cnf71xx;
 };
 
 union cvmx_iob_i2c_pri_cnt {
 	uint64_t u64;
 	struct cvmx_iob_i2c_pri_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t cnt_enb:1;
 		uint64_t cnt_val:15;
+#else
+		uint64_t cnt_val:15;
+		uint64_t cnt_enb:1;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_iob_i2c_pri_cnt_s cn38xx;
 	struct cvmx_iob_i2c_pri_cnt_s cn38xxp2;
@@ -213,18 +457,29 @@
 	struct cvmx_iob_i2c_pri_cnt_s cn56xxp1;
 	struct cvmx_iob_i2c_pri_cnt_s cn58xx;
 	struct cvmx_iob_i2c_pri_cnt_s cn58xxp1;
+	struct cvmx_iob_i2c_pri_cnt_s cn61xx;
 	struct cvmx_iob_i2c_pri_cnt_s cn63xx;
 	struct cvmx_iob_i2c_pri_cnt_s cn63xxp1;
+	struct cvmx_iob_i2c_pri_cnt_s cn66xx;
+	struct cvmx_iob_i2c_pri_cnt_s cnf71xx;
 };
 
 union cvmx_iob_inb_control_match {
 	uint64_t u64;
 	struct cvmx_iob_inb_control_match_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_29_63:35;
 		uint64_t mask:8;
 		uint64_t opc:4;
 		uint64_t dst:9;
 		uint64_t src:8;
+#else
+		uint64_t src:8;
+		uint64_t dst:9;
+		uint64_t opc:4;
+		uint64_t mask:8;
+		uint64_t reserved_29_63:35;
+#endif
 	} s;
 	struct cvmx_iob_inb_control_match_s cn30xx;
 	struct cvmx_iob_inb_control_match_s cn31xx;
@@ -237,18 +492,31 @@
 	struct cvmx_iob_inb_control_match_s cn56xxp1;
 	struct cvmx_iob_inb_control_match_s cn58xx;
 	struct cvmx_iob_inb_control_match_s cn58xxp1;
+	struct cvmx_iob_inb_control_match_s cn61xx;
 	struct cvmx_iob_inb_control_match_s cn63xx;
 	struct cvmx_iob_inb_control_match_s cn63xxp1;
+	struct cvmx_iob_inb_control_match_s cn66xx;
+	struct cvmx_iob_inb_control_match_s cn68xx;
+	struct cvmx_iob_inb_control_match_s cn68xxp1;
+	struct cvmx_iob_inb_control_match_s cnf71xx;
 };
 
 union cvmx_iob_inb_control_match_enb {
 	uint64_t u64;
 	struct cvmx_iob_inb_control_match_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_29_63:35;
 		uint64_t mask:8;
 		uint64_t opc:4;
 		uint64_t dst:9;
 		uint64_t src:8;
+#else
+		uint64_t src:8;
+		uint64_t dst:9;
+		uint64_t opc:4;
+		uint64_t mask:8;
+		uint64_t reserved_29_63:35;
+#endif
 	} s;
 	struct cvmx_iob_inb_control_match_enb_s cn30xx;
 	struct cvmx_iob_inb_control_match_enb_s cn31xx;
@@ -261,14 +529,23 @@
 	struct cvmx_iob_inb_control_match_enb_s cn56xxp1;
 	struct cvmx_iob_inb_control_match_enb_s cn58xx;
 	struct cvmx_iob_inb_control_match_enb_s cn58xxp1;
+	struct cvmx_iob_inb_control_match_enb_s cn61xx;
 	struct cvmx_iob_inb_control_match_enb_s cn63xx;
 	struct cvmx_iob_inb_control_match_enb_s cn63xxp1;
+	struct cvmx_iob_inb_control_match_enb_s cn66xx;
+	struct cvmx_iob_inb_control_match_enb_s cn68xx;
+	struct cvmx_iob_inb_control_match_enb_s cn68xxp1;
+	struct cvmx_iob_inb_control_match_enb_s cnf71xx;
 };
 
 union cvmx_iob_inb_data_match {
 	uint64_t u64;
 	struct cvmx_iob_inb_data_match_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t data:64;
+#else
+		uint64_t data:64;
+#endif
 	} s;
 	struct cvmx_iob_inb_data_match_s cn30xx;
 	struct cvmx_iob_inb_data_match_s cn31xx;
@@ -281,14 +558,23 @@
 	struct cvmx_iob_inb_data_match_s cn56xxp1;
 	struct cvmx_iob_inb_data_match_s cn58xx;
 	struct cvmx_iob_inb_data_match_s cn58xxp1;
+	struct cvmx_iob_inb_data_match_s cn61xx;
 	struct cvmx_iob_inb_data_match_s cn63xx;
 	struct cvmx_iob_inb_data_match_s cn63xxp1;
+	struct cvmx_iob_inb_data_match_s cn66xx;
+	struct cvmx_iob_inb_data_match_s cn68xx;
+	struct cvmx_iob_inb_data_match_s cn68xxp1;
+	struct cvmx_iob_inb_data_match_s cnf71xx;
 };
 
 union cvmx_iob_inb_data_match_enb {
 	uint64_t u64;
 	struct cvmx_iob_inb_data_match_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t data:64;
+#else
+		uint64_t data:64;
+#endif
 	} s;
 	struct cvmx_iob_inb_data_match_enb_s cn30xx;
 	struct cvmx_iob_inb_data_match_enb_s cn31xx;
@@ -301,13 +587,19 @@
 	struct cvmx_iob_inb_data_match_enb_s cn56xxp1;
 	struct cvmx_iob_inb_data_match_enb_s cn58xx;
 	struct cvmx_iob_inb_data_match_enb_s cn58xxp1;
+	struct cvmx_iob_inb_data_match_enb_s cn61xx;
 	struct cvmx_iob_inb_data_match_enb_s cn63xx;
 	struct cvmx_iob_inb_data_match_enb_s cn63xxp1;
+	struct cvmx_iob_inb_data_match_enb_s cn66xx;
+	struct cvmx_iob_inb_data_match_enb_s cn68xx;
+	struct cvmx_iob_inb_data_match_enb_s cn68xxp1;
+	struct cvmx_iob_inb_data_match_enb_s cnf71xx;
 };
 
 union cvmx_iob_int_enb {
 	uint64_t u64;
 	struct cvmx_iob_int_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t p_dat:1;
 		uint64_t np_dat:1;
@@ -315,13 +607,30 @@
 		uint64_t p_sop:1;
 		uint64_t np_eop:1;
 		uint64_t np_sop:1;
+#else
+		uint64_t np_sop:1;
+		uint64_t np_eop:1;
+		uint64_t p_sop:1;
+		uint64_t p_eop:1;
+		uint64_t np_dat:1;
+		uint64_t p_dat:1;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
 	struct cvmx_iob_int_enb_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t p_eop:1;
 		uint64_t p_sop:1;
 		uint64_t np_eop:1;
 		uint64_t np_sop:1;
+#else
+		uint64_t np_sop:1;
+		uint64_t np_eop:1;
+		uint64_t p_sop:1;
+		uint64_t p_eop:1;
+		uint64_t reserved_4_63:60;
+#endif
 	} cn30xx;
 	struct cvmx_iob_int_enb_cn30xx cn31xx;
 	struct cvmx_iob_int_enb_cn30xx cn38xx;
@@ -333,13 +642,25 @@
 	struct cvmx_iob_int_enb_s cn56xxp1;
 	struct cvmx_iob_int_enb_s cn58xx;
 	struct cvmx_iob_int_enb_s cn58xxp1;
+	struct cvmx_iob_int_enb_s cn61xx;
 	struct cvmx_iob_int_enb_s cn63xx;
 	struct cvmx_iob_int_enb_s cn63xxp1;
+	struct cvmx_iob_int_enb_s cn66xx;
+	struct cvmx_iob_int_enb_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_0_63:64;
+#else
+		uint64_t reserved_0_63:64;
+#endif
+	} cn68xx;
+	struct cvmx_iob_int_enb_cn68xx cn68xxp1;
+	struct cvmx_iob_int_enb_s cnf71xx;
 };
 
 union cvmx_iob_int_sum {
 	uint64_t u64;
 	struct cvmx_iob_int_sum_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t p_dat:1;
 		uint64_t np_dat:1;
@@ -347,13 +668,30 @@
 		uint64_t p_sop:1;
 		uint64_t np_eop:1;
 		uint64_t np_sop:1;
+#else
+		uint64_t np_sop:1;
+		uint64_t np_eop:1;
+		uint64_t p_sop:1;
+		uint64_t p_eop:1;
+		uint64_t np_dat:1;
+		uint64_t p_dat:1;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
 	struct cvmx_iob_int_sum_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t p_eop:1;
 		uint64_t p_sop:1;
 		uint64_t np_eop:1;
 		uint64_t np_sop:1;
+#else
+		uint64_t np_sop:1;
+		uint64_t np_eop:1;
+		uint64_t p_sop:1;
+		uint64_t p_eop:1;
+		uint64_t reserved_4_63:60;
+#endif
 	} cn30xx;
 	struct cvmx_iob_int_sum_cn30xx cn31xx;
 	struct cvmx_iob_int_sum_cn30xx cn38xx;
@@ -365,16 +703,33 @@
 	struct cvmx_iob_int_sum_s cn56xxp1;
 	struct cvmx_iob_int_sum_s cn58xx;
 	struct cvmx_iob_int_sum_s cn58xxp1;
+	struct cvmx_iob_int_sum_s cn61xx;
 	struct cvmx_iob_int_sum_s cn63xx;
 	struct cvmx_iob_int_sum_s cn63xxp1;
+	struct cvmx_iob_int_sum_s cn66xx;
+	struct cvmx_iob_int_sum_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_0_63:64;
+#else
+		uint64_t reserved_0_63:64;
+#endif
+	} cn68xx;
+	struct cvmx_iob_int_sum_cn68xx cn68xxp1;
+	struct cvmx_iob_int_sum_s cnf71xx;
 };
 
 union cvmx_iob_n2c_l2c_pri_cnt {
 	uint64_t u64;
 	struct cvmx_iob_n2c_l2c_pri_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t cnt_enb:1;
 		uint64_t cnt_val:15;
+#else
+		uint64_t cnt_val:15;
+		uint64_t cnt_enb:1;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_iob_n2c_l2c_pri_cnt_s cn38xx;
 	struct cvmx_iob_n2c_l2c_pri_cnt_s cn38xxp2;
@@ -384,16 +739,25 @@
 	struct cvmx_iob_n2c_l2c_pri_cnt_s cn56xxp1;
 	struct cvmx_iob_n2c_l2c_pri_cnt_s cn58xx;
 	struct cvmx_iob_n2c_l2c_pri_cnt_s cn58xxp1;
+	struct cvmx_iob_n2c_l2c_pri_cnt_s cn61xx;
 	struct cvmx_iob_n2c_l2c_pri_cnt_s cn63xx;
 	struct cvmx_iob_n2c_l2c_pri_cnt_s cn63xxp1;
+	struct cvmx_iob_n2c_l2c_pri_cnt_s cn66xx;
+	struct cvmx_iob_n2c_l2c_pri_cnt_s cnf71xx;
 };
 
 union cvmx_iob_n2c_rsp_pri_cnt {
 	uint64_t u64;
 	struct cvmx_iob_n2c_rsp_pri_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t cnt_enb:1;
 		uint64_t cnt_val:15;
+#else
+		uint64_t cnt_val:15;
+		uint64_t cnt_enb:1;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_iob_n2c_rsp_pri_cnt_s cn38xx;
 	struct cvmx_iob_n2c_rsp_pri_cnt_s cn38xxp2;
@@ -403,16 +767,25 @@
 	struct cvmx_iob_n2c_rsp_pri_cnt_s cn56xxp1;
 	struct cvmx_iob_n2c_rsp_pri_cnt_s cn58xx;
 	struct cvmx_iob_n2c_rsp_pri_cnt_s cn58xxp1;
+	struct cvmx_iob_n2c_rsp_pri_cnt_s cn61xx;
 	struct cvmx_iob_n2c_rsp_pri_cnt_s cn63xx;
 	struct cvmx_iob_n2c_rsp_pri_cnt_s cn63xxp1;
+	struct cvmx_iob_n2c_rsp_pri_cnt_s cn66xx;
+	struct cvmx_iob_n2c_rsp_pri_cnt_s cnf71xx;
 };
 
 union cvmx_iob_outb_com_pri_cnt {
 	uint64_t u64;
 	struct cvmx_iob_outb_com_pri_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t cnt_enb:1;
 		uint64_t cnt_val:15;
+#else
+		uint64_t cnt_val:15;
+		uint64_t cnt_enb:1;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_iob_outb_com_pri_cnt_s cn38xx;
 	struct cvmx_iob_outb_com_pri_cnt_s cn38xxp2;
@@ -422,18 +795,31 @@
 	struct cvmx_iob_outb_com_pri_cnt_s cn56xxp1;
 	struct cvmx_iob_outb_com_pri_cnt_s cn58xx;
 	struct cvmx_iob_outb_com_pri_cnt_s cn58xxp1;
+	struct cvmx_iob_outb_com_pri_cnt_s cn61xx;
 	struct cvmx_iob_outb_com_pri_cnt_s cn63xx;
 	struct cvmx_iob_outb_com_pri_cnt_s cn63xxp1;
+	struct cvmx_iob_outb_com_pri_cnt_s cn66xx;
+	struct cvmx_iob_outb_com_pri_cnt_s cn68xx;
+	struct cvmx_iob_outb_com_pri_cnt_s cn68xxp1;
+	struct cvmx_iob_outb_com_pri_cnt_s cnf71xx;
 };
 
 union cvmx_iob_outb_control_match {
 	uint64_t u64;
 	struct cvmx_iob_outb_control_match_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_26_63:38;
 		uint64_t mask:8;
 		uint64_t eot:1;
 		uint64_t dst:8;
 		uint64_t src:9;
+#else
+		uint64_t src:9;
+		uint64_t dst:8;
+		uint64_t eot:1;
+		uint64_t mask:8;
+		uint64_t reserved_26_63:38;
+#endif
 	} s;
 	struct cvmx_iob_outb_control_match_s cn30xx;
 	struct cvmx_iob_outb_control_match_s cn31xx;
@@ -446,18 +832,31 @@
 	struct cvmx_iob_outb_control_match_s cn56xxp1;
 	struct cvmx_iob_outb_control_match_s cn58xx;
 	struct cvmx_iob_outb_control_match_s cn58xxp1;
+	struct cvmx_iob_outb_control_match_s cn61xx;
 	struct cvmx_iob_outb_control_match_s cn63xx;
 	struct cvmx_iob_outb_control_match_s cn63xxp1;
+	struct cvmx_iob_outb_control_match_s cn66xx;
+	struct cvmx_iob_outb_control_match_s cn68xx;
+	struct cvmx_iob_outb_control_match_s cn68xxp1;
+	struct cvmx_iob_outb_control_match_s cnf71xx;
 };
 
 union cvmx_iob_outb_control_match_enb {
 	uint64_t u64;
 	struct cvmx_iob_outb_control_match_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_26_63:38;
 		uint64_t mask:8;
 		uint64_t eot:1;
 		uint64_t dst:8;
 		uint64_t src:9;
+#else
+		uint64_t src:9;
+		uint64_t dst:8;
+		uint64_t eot:1;
+		uint64_t mask:8;
+		uint64_t reserved_26_63:38;
+#endif
 	} s;
 	struct cvmx_iob_outb_control_match_enb_s cn30xx;
 	struct cvmx_iob_outb_control_match_enb_s cn31xx;
@@ -470,14 +869,23 @@
 	struct cvmx_iob_outb_control_match_enb_s cn56xxp1;
 	struct cvmx_iob_outb_control_match_enb_s cn58xx;
 	struct cvmx_iob_outb_control_match_enb_s cn58xxp1;
+	struct cvmx_iob_outb_control_match_enb_s cn61xx;
 	struct cvmx_iob_outb_control_match_enb_s cn63xx;
 	struct cvmx_iob_outb_control_match_enb_s cn63xxp1;
+	struct cvmx_iob_outb_control_match_enb_s cn66xx;
+	struct cvmx_iob_outb_control_match_enb_s cn68xx;
+	struct cvmx_iob_outb_control_match_enb_s cn68xxp1;
+	struct cvmx_iob_outb_control_match_enb_s cnf71xx;
 };
 
 union cvmx_iob_outb_data_match {
 	uint64_t u64;
 	struct cvmx_iob_outb_data_match_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t data:64;
+#else
+		uint64_t data:64;
+#endif
 	} s;
 	struct cvmx_iob_outb_data_match_s cn30xx;
 	struct cvmx_iob_outb_data_match_s cn31xx;
@@ -490,14 +898,23 @@
 	struct cvmx_iob_outb_data_match_s cn56xxp1;
 	struct cvmx_iob_outb_data_match_s cn58xx;
 	struct cvmx_iob_outb_data_match_s cn58xxp1;
+	struct cvmx_iob_outb_data_match_s cn61xx;
 	struct cvmx_iob_outb_data_match_s cn63xx;
 	struct cvmx_iob_outb_data_match_s cn63xxp1;
+	struct cvmx_iob_outb_data_match_s cn66xx;
+	struct cvmx_iob_outb_data_match_s cn68xx;
+	struct cvmx_iob_outb_data_match_s cn68xxp1;
+	struct cvmx_iob_outb_data_match_s cnf71xx;
 };
 
 union cvmx_iob_outb_data_match_enb {
 	uint64_t u64;
 	struct cvmx_iob_outb_data_match_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t data:64;
+#else
+		uint64_t data:64;
+#endif
 	} s;
 	struct cvmx_iob_outb_data_match_enb_s cn30xx;
 	struct cvmx_iob_outb_data_match_enb_s cn31xx;
@@ -510,16 +927,27 @@
 	struct cvmx_iob_outb_data_match_enb_s cn56xxp1;
 	struct cvmx_iob_outb_data_match_enb_s cn58xx;
 	struct cvmx_iob_outb_data_match_enb_s cn58xxp1;
+	struct cvmx_iob_outb_data_match_enb_s cn61xx;
 	struct cvmx_iob_outb_data_match_enb_s cn63xx;
 	struct cvmx_iob_outb_data_match_enb_s cn63xxp1;
+	struct cvmx_iob_outb_data_match_enb_s cn66xx;
+	struct cvmx_iob_outb_data_match_enb_s cn68xx;
+	struct cvmx_iob_outb_data_match_enb_s cn68xxp1;
+	struct cvmx_iob_outb_data_match_enb_s cnf71xx;
 };
 
 union cvmx_iob_outb_fpa_pri_cnt {
 	uint64_t u64;
 	struct cvmx_iob_outb_fpa_pri_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t cnt_enb:1;
 		uint64_t cnt_val:15;
+#else
+		uint64_t cnt_val:15;
+		uint64_t cnt_enb:1;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_iob_outb_fpa_pri_cnt_s cn38xx;
 	struct cvmx_iob_outb_fpa_pri_cnt_s cn38xxp2;
@@ -529,16 +957,27 @@
 	struct cvmx_iob_outb_fpa_pri_cnt_s cn56xxp1;
 	struct cvmx_iob_outb_fpa_pri_cnt_s cn58xx;
 	struct cvmx_iob_outb_fpa_pri_cnt_s cn58xxp1;
+	struct cvmx_iob_outb_fpa_pri_cnt_s cn61xx;
 	struct cvmx_iob_outb_fpa_pri_cnt_s cn63xx;
 	struct cvmx_iob_outb_fpa_pri_cnt_s cn63xxp1;
+	struct cvmx_iob_outb_fpa_pri_cnt_s cn66xx;
+	struct cvmx_iob_outb_fpa_pri_cnt_s cn68xx;
+	struct cvmx_iob_outb_fpa_pri_cnt_s cn68xxp1;
+	struct cvmx_iob_outb_fpa_pri_cnt_s cnf71xx;
 };
 
 union cvmx_iob_outb_req_pri_cnt {
 	uint64_t u64;
 	struct cvmx_iob_outb_req_pri_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t cnt_enb:1;
 		uint64_t cnt_val:15;
+#else
+		uint64_t cnt_val:15;
+		uint64_t cnt_enb:1;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_iob_outb_req_pri_cnt_s cn38xx;
 	struct cvmx_iob_outb_req_pri_cnt_s cn38xxp2;
@@ -548,16 +987,27 @@
 	struct cvmx_iob_outb_req_pri_cnt_s cn56xxp1;
 	struct cvmx_iob_outb_req_pri_cnt_s cn58xx;
 	struct cvmx_iob_outb_req_pri_cnt_s cn58xxp1;
+	struct cvmx_iob_outb_req_pri_cnt_s cn61xx;
 	struct cvmx_iob_outb_req_pri_cnt_s cn63xx;
 	struct cvmx_iob_outb_req_pri_cnt_s cn63xxp1;
+	struct cvmx_iob_outb_req_pri_cnt_s cn66xx;
+	struct cvmx_iob_outb_req_pri_cnt_s cn68xx;
+	struct cvmx_iob_outb_req_pri_cnt_s cn68xxp1;
+	struct cvmx_iob_outb_req_pri_cnt_s cnf71xx;
 };
 
 union cvmx_iob_p2c_req_pri_cnt {
 	uint64_t u64;
 	struct cvmx_iob_p2c_req_pri_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t cnt_enb:1;
 		uint64_t cnt_val:15;
+#else
+		uint64_t cnt_val:15;
+		uint64_t cnt_enb:1;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_iob_p2c_req_pri_cnt_s cn38xx;
 	struct cvmx_iob_p2c_req_pri_cnt_s cn38xxp2;
@@ -567,20 +1017,34 @@
 	struct cvmx_iob_p2c_req_pri_cnt_s cn56xxp1;
 	struct cvmx_iob_p2c_req_pri_cnt_s cn58xx;
 	struct cvmx_iob_p2c_req_pri_cnt_s cn58xxp1;
+	struct cvmx_iob_p2c_req_pri_cnt_s cn61xx;
 	struct cvmx_iob_p2c_req_pri_cnt_s cn63xx;
 	struct cvmx_iob_p2c_req_pri_cnt_s cn63xxp1;
+	struct cvmx_iob_p2c_req_pri_cnt_s cn66xx;
+	struct cvmx_iob_p2c_req_pri_cnt_s cnf71xx;
 };
 
 union cvmx_iob_pkt_err {
 	uint64_t u64;
 	struct cvmx_iob_pkt_err_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t vport:6;
 		uint64_t port:6;
+#else
+		uint64_t port:6;
+		uint64_t vport:6;
+		uint64_t reserved_12_63:52;
+#endif
 	} s;
 	struct cvmx_iob_pkt_err_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t port:6;
+#else
+		uint64_t port:6;
+		uint64_t reserved_6_63:58;
+#endif
 	} cn30xx;
 	struct cvmx_iob_pkt_err_cn30xx cn31xx;
 	struct cvmx_iob_pkt_err_cn30xx cn38xx;
@@ -592,21 +1056,223 @@
 	struct cvmx_iob_pkt_err_cn30xx cn56xxp1;
 	struct cvmx_iob_pkt_err_cn30xx cn58xx;
 	struct cvmx_iob_pkt_err_cn30xx cn58xxp1;
+	struct cvmx_iob_pkt_err_s cn61xx;
 	struct cvmx_iob_pkt_err_s cn63xx;
 	struct cvmx_iob_pkt_err_s cn63xxp1;
+	struct cvmx_iob_pkt_err_s cn66xx;
+	struct cvmx_iob_pkt_err_s cnf71xx;
 };
 
 union cvmx_iob_to_cmb_credits {
 	uint64_t u64;
 	struct cvmx_iob_to_cmb_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_6_63:58;
+		uint64_t ncb_rd:3;
+		uint64_t ncb_wr:3;
+#else
+		uint64_t ncb_wr:3;
+		uint64_t ncb_rd:3;
+		uint64_t reserved_6_63:58;
+#endif
+	} s;
+	struct cvmx_iob_to_cmb_credits_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t pko_rd:3;
 		uint64_t ncb_rd:3;
 		uint64_t ncb_wr:3;
+#else
+		uint64_t ncb_wr:3;
+		uint64_t ncb_rd:3;
+		uint64_t pko_rd:3;
+		uint64_t reserved_9_63:55;
+#endif
+	} cn52xx;
+	struct cvmx_iob_to_cmb_credits_cn52xx cn61xx;
+	struct cvmx_iob_to_cmb_credits_cn52xx cn63xx;
+	struct cvmx_iob_to_cmb_credits_cn52xx cn63xxp1;
+	struct cvmx_iob_to_cmb_credits_cn52xx cn66xx;
+	struct cvmx_iob_to_cmb_credits_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_9_63:55;
+		uint64_t dwb:3;
+		uint64_t ncb_rd:3;
+		uint64_t ncb_wr:3;
+#else
+		uint64_t ncb_wr:3;
+		uint64_t ncb_rd:3;
+		uint64_t dwb:3;
+		uint64_t reserved_9_63:55;
+#endif
+	} cn68xx;
+	struct cvmx_iob_to_cmb_credits_cn68xx cn68xxp1;
+	struct cvmx_iob_to_cmb_credits_cn52xx cnf71xx;
+};
+
+union cvmx_iob_to_ncb_did_00_credits {
+	uint64_t u64;
+	struct cvmx_iob_to_ncb_did_00_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_7_63:57;
+		uint64_t crd:7;
+#else
+		uint64_t crd:7;
+		uint64_t reserved_7_63:57;
+#endif
 	} s;
-	struct cvmx_iob_to_cmb_credits_s cn52xx;
-	struct cvmx_iob_to_cmb_credits_s cn63xx;
-	struct cvmx_iob_to_cmb_credits_s cn63xxp1;
+	struct cvmx_iob_to_ncb_did_00_credits_s cn68xx;
+	struct cvmx_iob_to_ncb_did_00_credits_s cn68xxp1;
+};
+
+union cvmx_iob_to_ncb_did_111_credits {
+	uint64_t u64;
+	struct cvmx_iob_to_ncb_did_111_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_7_63:57;
+		uint64_t crd:7;
+#else
+		uint64_t crd:7;
+		uint64_t reserved_7_63:57;
+#endif
+	} s;
+	struct cvmx_iob_to_ncb_did_111_credits_s cn68xx;
+	struct cvmx_iob_to_ncb_did_111_credits_s cn68xxp1;
+};
+
+union cvmx_iob_to_ncb_did_223_credits {
+	uint64_t u64;
+	struct cvmx_iob_to_ncb_did_223_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_7_63:57;
+		uint64_t crd:7;
+#else
+		uint64_t crd:7;
+		uint64_t reserved_7_63:57;
+#endif
+	} s;
+	struct cvmx_iob_to_ncb_did_223_credits_s cn68xx;
+	struct cvmx_iob_to_ncb_did_223_credits_s cn68xxp1;
+};
+
+union cvmx_iob_to_ncb_did_24_credits {
+	uint64_t u64;
+	struct cvmx_iob_to_ncb_did_24_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_7_63:57;
+		uint64_t crd:7;
+#else
+		uint64_t crd:7;
+		uint64_t reserved_7_63:57;
+#endif
+	} s;
+	struct cvmx_iob_to_ncb_did_24_credits_s cn68xx;
+	struct cvmx_iob_to_ncb_did_24_credits_s cn68xxp1;
+};
+
+union cvmx_iob_to_ncb_did_32_credits {
+	uint64_t u64;
+	struct cvmx_iob_to_ncb_did_32_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_7_63:57;
+		uint64_t crd:7;
+#else
+		uint64_t crd:7;
+		uint64_t reserved_7_63:57;
+#endif
+	} s;
+	struct cvmx_iob_to_ncb_did_32_credits_s cn68xx;
+	struct cvmx_iob_to_ncb_did_32_credits_s cn68xxp1;
+};
+
+union cvmx_iob_to_ncb_did_40_credits {
+	uint64_t u64;
+	struct cvmx_iob_to_ncb_did_40_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_7_63:57;
+		uint64_t crd:7;
+#else
+		uint64_t crd:7;
+		uint64_t reserved_7_63:57;
+#endif
+	} s;
+	struct cvmx_iob_to_ncb_did_40_credits_s cn68xx;
+	struct cvmx_iob_to_ncb_did_40_credits_s cn68xxp1;
+};
+
+union cvmx_iob_to_ncb_did_55_credits {
+	uint64_t u64;
+	struct cvmx_iob_to_ncb_did_55_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_7_63:57;
+		uint64_t crd:7;
+#else
+		uint64_t crd:7;
+		uint64_t reserved_7_63:57;
+#endif
+	} s;
+	struct cvmx_iob_to_ncb_did_55_credits_s cn68xx;
+	struct cvmx_iob_to_ncb_did_55_credits_s cn68xxp1;
+};
+
+union cvmx_iob_to_ncb_did_64_credits {
+	uint64_t u64;
+	struct cvmx_iob_to_ncb_did_64_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_7_63:57;
+		uint64_t crd:7;
+#else
+		uint64_t crd:7;
+		uint64_t reserved_7_63:57;
+#endif
+	} s;
+	struct cvmx_iob_to_ncb_did_64_credits_s cn68xx;
+	struct cvmx_iob_to_ncb_did_64_credits_s cn68xxp1;
+};
+
+union cvmx_iob_to_ncb_did_79_credits {
+	uint64_t u64;
+	struct cvmx_iob_to_ncb_did_79_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_7_63:57;
+		uint64_t crd:7;
+#else
+		uint64_t crd:7;
+		uint64_t reserved_7_63:57;
+#endif
+	} s;
+	struct cvmx_iob_to_ncb_did_79_credits_s cn68xx;
+	struct cvmx_iob_to_ncb_did_79_credits_s cn68xxp1;
+};
+
+union cvmx_iob_to_ncb_did_96_credits {
+	uint64_t u64;
+	struct cvmx_iob_to_ncb_did_96_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_7_63:57;
+		uint64_t crd:7;
+#else
+		uint64_t crd:7;
+		uint64_t reserved_7_63:57;
+#endif
+	} s;
+	struct cvmx_iob_to_ncb_did_96_credits_s cn68xx;
+	struct cvmx_iob_to_ncb_did_96_credits_s cn68xxp1;
+};
+
+union cvmx_iob_to_ncb_did_98_credits {
+	uint64_t u64;
+	struct cvmx_iob_to_ncb_did_98_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_7_63:57;
+		uint64_t crd:7;
+#else
+		uint64_t crd:7;
+		uint64_t reserved_7_63:57;
+#endif
+	} s;
+	struct cvmx_iob_to_ncb_did_98_credits_s cn68xx;
+	struct cvmx_iob_to_ncb_did_98_credits_s cn68xxp1;
 };
 
 #endif
diff --git a/arch/mips/include/asm/octeon/cvmx-ipd-defs.h b/arch/mips/include/asm/octeon/cvmx-ipd-defs.h
index e0a5bfe..1193f73 100644
--- a/arch/mips/include/asm/octeon/cvmx-ipd-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-ipd-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -32,23 +32,37 @@
 #define CVMX_IPD_1st_NEXT_PTR_BACK (CVMX_ADD_IO_SEG(0x00014F0000000150ull))
 #define CVMX_IPD_2nd_NEXT_PTR_BACK (CVMX_ADD_IO_SEG(0x00014F0000000158ull))
 #define CVMX_IPD_BIST_STATUS (CVMX_ADD_IO_SEG(0x00014F00000007F8ull))
+#define CVMX_IPD_BPIDX_MBUF_TH(offset) (CVMX_ADD_IO_SEG(0x00014F0000002000ull) + ((offset) & 63) * 8)
+#define CVMX_IPD_BPID_BP_COUNTERX(offset) (CVMX_ADD_IO_SEG(0x00014F0000003000ull) + ((offset) & 63) * 8)
 #define CVMX_IPD_BP_PRT_RED_END (CVMX_ADD_IO_SEG(0x00014F0000000328ull))
 #define CVMX_IPD_CLK_COUNT (CVMX_ADD_IO_SEG(0x00014F0000000338ull))
+#define CVMX_IPD_CREDITS (CVMX_ADD_IO_SEG(0x00014F0000004410ull))
 #define CVMX_IPD_CTL_STATUS (CVMX_ADD_IO_SEG(0x00014F0000000018ull))
+#define CVMX_IPD_ECC_CTL (CVMX_ADD_IO_SEG(0x00014F0000004408ull))
+#define CVMX_IPD_FREE_PTR_FIFO_CTL (CVMX_ADD_IO_SEG(0x00014F0000000780ull))
+#define CVMX_IPD_FREE_PTR_VALUE (CVMX_ADD_IO_SEG(0x00014F0000000788ull))
+#define CVMX_IPD_HOLD_PTR_FIFO_CTL (CVMX_ADD_IO_SEG(0x00014F0000000790ull))
 #define CVMX_IPD_INT_ENB (CVMX_ADD_IO_SEG(0x00014F0000000160ull))
 #define CVMX_IPD_INT_SUM (CVMX_ADD_IO_SEG(0x00014F0000000168ull))
+#define CVMX_IPD_NEXT_PKT_PTR (CVMX_ADD_IO_SEG(0x00014F00000007A0ull))
+#define CVMX_IPD_NEXT_WQE_PTR (CVMX_ADD_IO_SEG(0x00014F00000007A8ull))
 #define CVMX_IPD_NOT_1ST_MBUFF_SKIP (CVMX_ADD_IO_SEG(0x00014F0000000008ull))
+#define CVMX_IPD_ON_BP_DROP_PKTX(block_id) (CVMX_ADD_IO_SEG(0x00014F0000004100ull))
 #define CVMX_IPD_PACKET_MBUFF_SIZE (CVMX_ADD_IO_SEG(0x00014F0000000010ull))
+#define CVMX_IPD_PKT_ERR (CVMX_ADD_IO_SEG(0x00014F00000003F0ull))
 #define CVMX_IPD_PKT_PTR_VALID (CVMX_ADD_IO_SEG(0x00014F0000000358ull))
 #define CVMX_IPD_PORTX_BP_PAGE_CNT(offset) (CVMX_ADD_IO_SEG(0x00014F0000000028ull) + ((offset) & 63) * 8)
 #define CVMX_IPD_PORTX_BP_PAGE_CNT2(offset) (CVMX_ADD_IO_SEG(0x00014F0000000368ull) + ((offset) & 63) * 8 - 8*36)
 #define CVMX_IPD_PORTX_BP_PAGE_CNT3(offset) (CVMX_ADD_IO_SEG(0x00014F00000003D0ull) + ((offset) & 63) * 8 - 8*40)
 #define CVMX_IPD_PORT_BP_COUNTERS2_PAIRX(offset) (CVMX_ADD_IO_SEG(0x00014F0000000388ull) + ((offset) & 63) * 8 - 8*36)
 #define CVMX_IPD_PORT_BP_COUNTERS3_PAIRX(offset) (CVMX_ADD_IO_SEG(0x00014F00000003B0ull) + ((offset) & 63) * 8 - 8*40)
+#define CVMX_IPD_PORT_BP_COUNTERS4_PAIRX(offset) (CVMX_ADD_IO_SEG(0x00014F0000000410ull) + ((offset) & 63) * 8 - 8*44)
 #define CVMX_IPD_PORT_BP_COUNTERS_PAIRX(offset) (CVMX_ADD_IO_SEG(0x00014F00000001B8ull) + ((offset) & 63) * 8)
+#define CVMX_IPD_PORT_PTR_FIFO_CTL (CVMX_ADD_IO_SEG(0x00014F0000000798ull))
 #define CVMX_IPD_PORT_QOS_INTX(offset) (CVMX_ADD_IO_SEG(0x00014F0000000808ull) + ((offset) & 7) * 8)
 #define CVMX_IPD_PORT_QOS_INT_ENBX(offset) (CVMX_ADD_IO_SEG(0x00014F0000000848ull) + ((offset) & 7) * 8)
 #define CVMX_IPD_PORT_QOS_X_CNT(offset) (CVMX_ADD_IO_SEG(0x00014F0000000888ull) + ((offset) & 511) * 8)
+#define CVMX_IPD_PORT_SOPX(block_id) (CVMX_ADD_IO_SEG(0x00014F0000004400ull))
 #define CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL (CVMX_ADD_IO_SEG(0x00014F0000000348ull))
 #define CVMX_IPD_PRC_PORT_PTR_FIFO_CTL (CVMX_ADD_IO_SEG(0x00014F0000000350ull))
 #define CVMX_IPD_PTR_COUNT (CVMX_ADD_IO_SEG(0x00014F0000000320ull))
@@ -63,6 +77,8 @@
 #define CVMX_IPD_QOS7_RED_MARKS CVMX_IPD_QOSX_RED_MARKS(7)
 #define CVMX_IPD_QOSX_RED_MARKS(offset) (CVMX_ADD_IO_SEG(0x00014F0000000178ull) + ((offset) & 7) * 8)
 #define CVMX_IPD_QUE0_FREE_PAGE_CNT (CVMX_ADD_IO_SEG(0x00014F0000000330ull))
+#define CVMX_IPD_RED_BPID_ENABLEX(block_id) (CVMX_ADD_IO_SEG(0x00014F0000004200ull))
+#define CVMX_IPD_RED_DELAY (CVMX_ADD_IO_SEG(0x00014F0000004300ull))
 #define CVMX_IPD_RED_PORT_ENABLE (CVMX_ADD_IO_SEG(0x00014F00000002D8ull))
 #define CVMX_IPD_RED_PORT_ENABLE2 (CVMX_ADD_IO_SEG(0x00014F00000003A8ull))
 #define CVMX_IPD_RED_QUE0_PARAM CVMX_IPD_RED_QUEX_PARAM(0)
@@ -74,6 +90,7 @@
 #define CVMX_IPD_RED_QUE6_PARAM CVMX_IPD_RED_QUEX_PARAM(6)
 #define CVMX_IPD_RED_QUE7_PARAM CVMX_IPD_RED_QUEX_PARAM(7)
 #define CVMX_IPD_RED_QUEX_PARAM(offset) (CVMX_ADD_IO_SEG(0x00014F00000002E0ull) + ((offset) & 7) * 8)
+#define CVMX_IPD_REQ_WGT (CVMX_ADD_IO_SEG(0x00014F0000004418ull))
 #define CVMX_IPD_SUB_PORT_BP_PAGE_CNT (CVMX_ADD_IO_SEG(0x00014F0000000148ull))
 #define CVMX_IPD_SUB_PORT_FCS (CVMX_ADD_IO_SEG(0x00014F0000000170ull))
 #define CVMX_IPD_SUB_PORT_QOS_CNT (CVMX_ADD_IO_SEG(0x00014F0000000800ull))
@@ -83,8 +100,13 @@
 union cvmx_ipd_1st_mbuff_skip {
 	uint64_t u64;
 	struct cvmx_ipd_1st_mbuff_skip_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t skip_sz:6;
+#else
+		uint64_t skip_sz:6;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
 	struct cvmx_ipd_1st_mbuff_skip_s cn30xx;
 	struct cvmx_ipd_1st_mbuff_skip_s cn31xx;
@@ -97,15 +119,25 @@
 	struct cvmx_ipd_1st_mbuff_skip_s cn56xxp1;
 	struct cvmx_ipd_1st_mbuff_skip_s cn58xx;
 	struct cvmx_ipd_1st_mbuff_skip_s cn58xxp1;
+	struct cvmx_ipd_1st_mbuff_skip_s cn61xx;
 	struct cvmx_ipd_1st_mbuff_skip_s cn63xx;
 	struct cvmx_ipd_1st_mbuff_skip_s cn63xxp1;
+	struct cvmx_ipd_1st_mbuff_skip_s cn66xx;
+	struct cvmx_ipd_1st_mbuff_skip_s cn68xx;
+	struct cvmx_ipd_1st_mbuff_skip_s cn68xxp1;
+	struct cvmx_ipd_1st_mbuff_skip_s cnf71xx;
 };
 
 union cvmx_ipd_1st_next_ptr_back {
 	uint64_t u64;
 	struct cvmx_ipd_1st_next_ptr_back_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t back:4;
+#else
+		uint64_t back:4;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_ipd_1st_next_ptr_back_s cn30xx;
 	struct cvmx_ipd_1st_next_ptr_back_s cn31xx;
@@ -118,15 +150,25 @@
 	struct cvmx_ipd_1st_next_ptr_back_s cn56xxp1;
 	struct cvmx_ipd_1st_next_ptr_back_s cn58xx;
 	struct cvmx_ipd_1st_next_ptr_back_s cn58xxp1;
+	struct cvmx_ipd_1st_next_ptr_back_s cn61xx;
 	struct cvmx_ipd_1st_next_ptr_back_s cn63xx;
 	struct cvmx_ipd_1st_next_ptr_back_s cn63xxp1;
+	struct cvmx_ipd_1st_next_ptr_back_s cn66xx;
+	struct cvmx_ipd_1st_next_ptr_back_s cn68xx;
+	struct cvmx_ipd_1st_next_ptr_back_s cn68xxp1;
+	struct cvmx_ipd_1st_next_ptr_back_s cnf71xx;
 };
 
 union cvmx_ipd_2nd_next_ptr_back {
 	uint64_t u64;
 	struct cvmx_ipd_2nd_next_ptr_back_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t back:4;
+#else
+		uint64_t back:4;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_ipd_2nd_next_ptr_back_s cn30xx;
 	struct cvmx_ipd_2nd_next_ptr_back_s cn31xx;
@@ -139,13 +181,115 @@
 	struct cvmx_ipd_2nd_next_ptr_back_s cn56xxp1;
 	struct cvmx_ipd_2nd_next_ptr_back_s cn58xx;
 	struct cvmx_ipd_2nd_next_ptr_back_s cn58xxp1;
+	struct cvmx_ipd_2nd_next_ptr_back_s cn61xx;
 	struct cvmx_ipd_2nd_next_ptr_back_s cn63xx;
 	struct cvmx_ipd_2nd_next_ptr_back_s cn63xxp1;
+	struct cvmx_ipd_2nd_next_ptr_back_s cn66xx;
+	struct cvmx_ipd_2nd_next_ptr_back_s cn68xx;
+	struct cvmx_ipd_2nd_next_ptr_back_s cn68xxp1;
+	struct cvmx_ipd_2nd_next_ptr_back_s cnf71xx;
 };
 
 union cvmx_ipd_bist_status {
 	uint64_t u64;
 	struct cvmx_ipd_bist_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_23_63:41;
+		uint64_t iiwo1:1;
+		uint64_t iiwo0:1;
+		uint64_t iio1:1;
+		uint64_t iio0:1;
+		uint64_t pbm4:1;
+		uint64_t csr_mem:1;
+		uint64_t csr_ncmd:1;
+		uint64_t pwq_wqed:1;
+		uint64_t pwq_wp1:1;
+		uint64_t pwq_pow:1;
+		uint64_t ipq_pbe1:1;
+		uint64_t ipq_pbe0:1;
+		uint64_t pbm3:1;
+		uint64_t pbm2:1;
+		uint64_t pbm1:1;
+		uint64_t pbm0:1;
+		uint64_t pbm_word:1;
+		uint64_t pwq1:1;
+		uint64_t pwq0:1;
+		uint64_t prc_off:1;
+		uint64_t ipd_old:1;
+		uint64_t ipd_new:1;
+		uint64_t pwp:1;
+#else
+		uint64_t pwp:1;
+		uint64_t ipd_new:1;
+		uint64_t ipd_old:1;
+		uint64_t prc_off:1;
+		uint64_t pwq0:1;
+		uint64_t pwq1:1;
+		uint64_t pbm_word:1;
+		uint64_t pbm0:1;
+		uint64_t pbm1:1;
+		uint64_t pbm2:1;
+		uint64_t pbm3:1;
+		uint64_t ipq_pbe0:1;
+		uint64_t ipq_pbe1:1;
+		uint64_t pwq_pow:1;
+		uint64_t pwq_wp1:1;
+		uint64_t pwq_wqed:1;
+		uint64_t csr_ncmd:1;
+		uint64_t csr_mem:1;
+		uint64_t pbm4:1;
+		uint64_t iio0:1;
+		uint64_t iio1:1;
+		uint64_t iiwo0:1;
+		uint64_t iiwo1:1;
+		uint64_t reserved_23_63:41;
+#endif
+	} s;
+	struct cvmx_ipd_bist_status_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t pwq_wqed:1;
+		uint64_t pwq_wp1:1;
+		uint64_t pwq_pow:1;
+		uint64_t ipq_pbe1:1;
+		uint64_t ipq_pbe0:1;
+		uint64_t pbm3:1;
+		uint64_t pbm2:1;
+		uint64_t pbm1:1;
+		uint64_t pbm0:1;
+		uint64_t pbm_word:1;
+		uint64_t pwq1:1;
+		uint64_t pwq0:1;
+		uint64_t prc_off:1;
+		uint64_t ipd_old:1;
+		uint64_t ipd_new:1;
+		uint64_t pwp:1;
+#else
+		uint64_t pwp:1;
+		uint64_t ipd_new:1;
+		uint64_t ipd_old:1;
+		uint64_t prc_off:1;
+		uint64_t pwq0:1;
+		uint64_t pwq1:1;
+		uint64_t pbm_word:1;
+		uint64_t pbm0:1;
+		uint64_t pbm1:1;
+		uint64_t pbm2:1;
+		uint64_t pbm3:1;
+		uint64_t ipq_pbe0:1;
+		uint64_t ipq_pbe1:1;
+		uint64_t pwq_pow:1;
+		uint64_t pwq_wp1:1;
+		uint64_t pwq_wqed:1;
+		uint64_t reserved_16_63:48;
+#endif
+	} cn30xx;
+	struct cvmx_ipd_bist_status_cn30xx cn31xx;
+	struct cvmx_ipd_bist_status_cn30xx cn38xx;
+	struct cvmx_ipd_bist_status_cn30xx cn38xxp2;
+	struct cvmx_ipd_bist_status_cn30xx cn50xx;
+	struct cvmx_ipd_bist_status_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_18_63:46;
 		uint64_t csr_mem:1;
 		uint64_t csr_ncmd:1;
@@ -165,71 +309,135 @@
 		uint64_t ipd_old:1;
 		uint64_t ipd_new:1;
 		uint64_t pwp:1;
-	} s;
-	struct cvmx_ipd_bist_status_cn30xx {
-		uint64_t reserved_16_63:48;
-		uint64_t pwq_wqed:1;
-		uint64_t pwq_wp1:1;
-		uint64_t pwq_pow:1;
-		uint64_t ipq_pbe1:1;
-		uint64_t ipq_pbe0:1;
-		uint64_t pbm3:1;
-		uint64_t pbm2:1;
-		uint64_t pbm1:1;
-		uint64_t pbm0:1;
-		uint64_t pbm_word:1;
-		uint64_t pwq1:1;
-		uint64_t pwq0:1;
-		uint64_t prc_off:1;
-		uint64_t ipd_old:1;
-		uint64_t ipd_new:1;
+#else
 		uint64_t pwp:1;
-	} cn30xx;
-	struct cvmx_ipd_bist_status_cn30xx cn31xx;
-	struct cvmx_ipd_bist_status_cn30xx cn38xx;
-	struct cvmx_ipd_bist_status_cn30xx cn38xxp2;
-	struct cvmx_ipd_bist_status_cn30xx cn50xx;
-	struct cvmx_ipd_bist_status_s cn52xx;
-	struct cvmx_ipd_bist_status_s cn52xxp1;
-	struct cvmx_ipd_bist_status_s cn56xx;
-	struct cvmx_ipd_bist_status_s cn56xxp1;
+		uint64_t ipd_new:1;
+		uint64_t ipd_old:1;
+		uint64_t prc_off:1;
+		uint64_t pwq0:1;
+		uint64_t pwq1:1;
+		uint64_t pbm_word:1;
+		uint64_t pbm0:1;
+		uint64_t pbm1:1;
+		uint64_t pbm2:1;
+		uint64_t pbm3:1;
+		uint64_t ipq_pbe0:1;
+		uint64_t ipq_pbe1:1;
+		uint64_t pwq_pow:1;
+		uint64_t pwq_wp1:1;
+		uint64_t pwq_wqed:1;
+		uint64_t csr_ncmd:1;
+		uint64_t csr_mem:1;
+		uint64_t reserved_18_63:46;
+#endif
+	} cn52xx;
+	struct cvmx_ipd_bist_status_cn52xx cn52xxp1;
+	struct cvmx_ipd_bist_status_cn52xx cn56xx;
+	struct cvmx_ipd_bist_status_cn52xx cn56xxp1;
 	struct cvmx_ipd_bist_status_cn30xx cn58xx;
 	struct cvmx_ipd_bist_status_cn30xx cn58xxp1;
-	struct cvmx_ipd_bist_status_s cn63xx;
-	struct cvmx_ipd_bist_status_s cn63xxp1;
+	struct cvmx_ipd_bist_status_cn52xx cn61xx;
+	struct cvmx_ipd_bist_status_cn52xx cn63xx;
+	struct cvmx_ipd_bist_status_cn52xx cn63xxp1;
+	struct cvmx_ipd_bist_status_cn52xx cn66xx;
+	struct cvmx_ipd_bist_status_s cn68xx;
+	struct cvmx_ipd_bist_status_s cn68xxp1;
+	struct cvmx_ipd_bist_status_cn52xx cnf71xx;
 };
 
 union cvmx_ipd_bp_prt_red_end {
 	uint64_t u64;
 	struct cvmx_ipd_bp_prt_red_end_s {
-		uint64_t reserved_44_63:20;
-		uint64_t prt_enb:44;
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_48_63:16;
+		uint64_t prt_enb:48;
+#else
+		uint64_t prt_enb:48;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_ipd_bp_prt_red_end_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_36_63:28;
 		uint64_t prt_enb:36;
+#else
+		uint64_t prt_enb:36;
+		uint64_t reserved_36_63:28;
+#endif
 	} cn30xx;
 	struct cvmx_ipd_bp_prt_red_end_cn30xx cn31xx;
 	struct cvmx_ipd_bp_prt_red_end_cn30xx cn38xx;
 	struct cvmx_ipd_bp_prt_red_end_cn30xx cn38xxp2;
 	struct cvmx_ipd_bp_prt_red_end_cn30xx cn50xx;
 	struct cvmx_ipd_bp_prt_red_end_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_40_63:24;
 		uint64_t prt_enb:40;
+#else
+		uint64_t prt_enb:40;
+		uint64_t reserved_40_63:24;
+#endif
 	} cn52xx;
 	struct cvmx_ipd_bp_prt_red_end_cn52xx cn52xxp1;
 	struct cvmx_ipd_bp_prt_red_end_cn52xx cn56xx;
 	struct cvmx_ipd_bp_prt_red_end_cn52xx cn56xxp1;
 	struct cvmx_ipd_bp_prt_red_end_cn30xx cn58xx;
 	struct cvmx_ipd_bp_prt_red_end_cn30xx cn58xxp1;
-	struct cvmx_ipd_bp_prt_red_end_s cn63xx;
-	struct cvmx_ipd_bp_prt_red_end_s cn63xxp1;
+	struct cvmx_ipd_bp_prt_red_end_s cn61xx;
+	struct cvmx_ipd_bp_prt_red_end_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_44_63:20;
+		uint64_t prt_enb:44;
+#else
+		uint64_t prt_enb:44;
+		uint64_t reserved_44_63:20;
+#endif
+	} cn63xx;
+	struct cvmx_ipd_bp_prt_red_end_cn63xx cn63xxp1;
+	struct cvmx_ipd_bp_prt_red_end_s cn66xx;
+	struct cvmx_ipd_bp_prt_red_end_s cnf71xx;
+};
+
+union cvmx_ipd_bpidx_mbuf_th {
+	uint64_t u64;
+	struct cvmx_ipd_bpidx_mbuf_th_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_18_63:46;
+		uint64_t bp_enb:1;
+		uint64_t page_cnt:17;
+#else
+		uint64_t page_cnt:17;
+		uint64_t bp_enb:1;
+		uint64_t reserved_18_63:46;
+#endif
+	} s;
+	struct cvmx_ipd_bpidx_mbuf_th_s cn68xx;
+	struct cvmx_ipd_bpidx_mbuf_th_s cn68xxp1;
+};
+
+union cvmx_ipd_bpid_bp_counterx {
+	uint64_t u64;
+	struct cvmx_ipd_bpid_bp_counterx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_25_63:39;
+		uint64_t cnt_val:25;
+#else
+		uint64_t cnt_val:25;
+		uint64_t reserved_25_63:39;
+#endif
+	} s;
+	struct cvmx_ipd_bpid_bp_counterx_s cn68xx;
+	struct cvmx_ipd_bpid_bp_counterx_s cn68xxp1;
 };
 
 union cvmx_ipd_clk_count {
 	uint64_t u64;
 	struct cvmx_ipd_clk_count_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t clk_cnt:64;
+#else
+		uint64_t clk_cnt:64;
+#endif
 	} s;
 	struct cvmx_ipd_clk_count_s cn30xx;
 	struct cvmx_ipd_clk_count_s cn31xx;
@@ -242,13 +450,36 @@
 	struct cvmx_ipd_clk_count_s cn56xxp1;
 	struct cvmx_ipd_clk_count_s cn58xx;
 	struct cvmx_ipd_clk_count_s cn58xxp1;
+	struct cvmx_ipd_clk_count_s cn61xx;
 	struct cvmx_ipd_clk_count_s cn63xx;
 	struct cvmx_ipd_clk_count_s cn63xxp1;
+	struct cvmx_ipd_clk_count_s cn66xx;
+	struct cvmx_ipd_clk_count_s cn68xx;
+	struct cvmx_ipd_clk_count_s cn68xxp1;
+	struct cvmx_ipd_clk_count_s cnf71xx;
+};
+
+union cvmx_ipd_credits {
+	uint64_t u64;
+	struct cvmx_ipd_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t iob_wrc:8;
+		uint64_t iob_wr:8;
+#else
+		uint64_t iob_wr:8;
+		uint64_t iob_wrc:8;
+		uint64_t reserved_16_63:48;
+#endif
+	} s;
+	struct cvmx_ipd_credits_s cn68xx;
+	struct cvmx_ipd_credits_s cn68xxp1;
 };
 
 union cvmx_ipd_ctl_status {
 	uint64_t u64;
 	struct cvmx_ipd_ctl_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_18_63:46;
 		uint64_t use_sop:1;
 		uint64_t rst_done:1;
@@ -267,8 +498,29 @@
 		uint64_t pbp_en:1;
 		uint64_t opc_mode:2;
 		uint64_t ipd_en:1;
+#else
+		uint64_t ipd_en:1;
+		uint64_t opc_mode:2;
+		uint64_t pbp_en:1;
+		uint64_t wqe_lend:1;
+		uint64_t pkt_lend:1;
+		uint64_t naddbuf:1;
+		uint64_t addpkt:1;
+		uint64_t reset:1;
+		uint64_t len_m8:1;
+		uint64_t pkt_off:1;
+		uint64_t ipd_full:1;
+		uint64_t pq_nabuf:1;
+		uint64_t pq_apkt:1;
+		uint64_t no_wptr:1;
+		uint64_t clken:1;
+		uint64_t rst_done:1;
+		uint64_t use_sop:1;
+		uint64_t reserved_18_63:46;
+#endif
 	} s;
 	struct cvmx_ipd_ctl_status_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t len_m8:1;
 		uint64_t reset:1;
@@ -279,10 +531,23 @@
 		uint64_t pbp_en:1;
 		uint64_t opc_mode:2;
 		uint64_t ipd_en:1;
+#else
+		uint64_t ipd_en:1;
+		uint64_t opc_mode:2;
+		uint64_t pbp_en:1;
+		uint64_t wqe_lend:1;
+		uint64_t pkt_lend:1;
+		uint64_t naddbuf:1;
+		uint64_t addpkt:1;
+		uint64_t reset:1;
+		uint64_t len_m8:1;
+		uint64_t reserved_10_63:54;
+#endif
 	} cn30xx;
 	struct cvmx_ipd_ctl_status_cn30xx cn31xx;
 	struct cvmx_ipd_ctl_status_cn30xx cn38xx;
 	struct cvmx_ipd_ctl_status_cn38xxp2 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t reset:1;
 		uint64_t addpkt:1;
@@ -292,8 +557,20 @@
 		uint64_t pbp_en:1;
 		uint64_t opc_mode:2;
 		uint64_t ipd_en:1;
+#else
+		uint64_t ipd_en:1;
+		uint64_t opc_mode:2;
+		uint64_t pbp_en:1;
+		uint64_t wqe_lend:1;
+		uint64_t pkt_lend:1;
+		uint64_t naddbuf:1;
+		uint64_t addpkt:1;
+		uint64_t reset:1;
+		uint64_t reserved_9_63:55;
+#endif
 	} cn38xxp2;
 	struct cvmx_ipd_ctl_status_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_15_63:49;
 		uint64_t no_wptr:1;
 		uint64_t pq_apkt:1;
@@ -309,12 +586,30 @@
 		uint64_t pbp_en:1;
 		uint64_t opc_mode:2;
 		uint64_t ipd_en:1;
+#else
+		uint64_t ipd_en:1;
+		uint64_t opc_mode:2;
+		uint64_t pbp_en:1;
+		uint64_t wqe_lend:1;
+		uint64_t pkt_lend:1;
+		uint64_t naddbuf:1;
+		uint64_t addpkt:1;
+		uint64_t reset:1;
+		uint64_t len_m8:1;
+		uint64_t pkt_off:1;
+		uint64_t ipd_full:1;
+		uint64_t pq_nabuf:1;
+		uint64_t pq_apkt:1;
+		uint64_t no_wptr:1;
+		uint64_t reserved_15_63:49;
+#endif
 	} cn50xx;
 	struct cvmx_ipd_ctl_status_cn50xx cn52xx;
 	struct cvmx_ipd_ctl_status_cn50xx cn52xxp1;
 	struct cvmx_ipd_ctl_status_cn50xx cn56xx;
 	struct cvmx_ipd_ctl_status_cn50xx cn56xxp1;
 	struct cvmx_ipd_ctl_status_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t ipd_full:1;
 		uint64_t pkt_off:1;
@@ -327,10 +622,26 @@
 		uint64_t pbp_en:1;
 		uint64_t opc_mode:2;
 		uint64_t ipd_en:1;
+#else
+		uint64_t ipd_en:1;
+		uint64_t opc_mode:2;
+		uint64_t pbp_en:1;
+		uint64_t wqe_lend:1;
+		uint64_t pkt_lend:1;
+		uint64_t naddbuf:1;
+		uint64_t addpkt:1;
+		uint64_t reset:1;
+		uint64_t len_m8:1;
+		uint64_t pkt_off:1;
+		uint64_t ipd_full:1;
+		uint64_t reserved_12_63:52;
+#endif
 	} cn58xx;
 	struct cvmx_ipd_ctl_status_cn58xx cn58xxp1;
+	struct cvmx_ipd_ctl_status_s cn61xx;
 	struct cvmx_ipd_ctl_status_s cn63xx;
 	struct cvmx_ipd_ctl_status_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t clken:1;
 		uint64_t no_wptr:1;
@@ -347,12 +658,217 @@
 		uint64_t pbp_en:1;
 		uint64_t opc_mode:2;
 		uint64_t ipd_en:1;
+#else
+		uint64_t ipd_en:1;
+		uint64_t opc_mode:2;
+		uint64_t pbp_en:1;
+		uint64_t wqe_lend:1;
+		uint64_t pkt_lend:1;
+		uint64_t naddbuf:1;
+		uint64_t addpkt:1;
+		uint64_t reset:1;
+		uint64_t len_m8:1;
+		uint64_t pkt_off:1;
+		uint64_t ipd_full:1;
+		uint64_t pq_nabuf:1;
+		uint64_t pq_apkt:1;
+		uint64_t no_wptr:1;
+		uint64_t clken:1;
+		uint64_t reserved_16_63:48;
+#endif
 	} cn63xxp1;
+	struct cvmx_ipd_ctl_status_s cn66xx;
+	struct cvmx_ipd_ctl_status_s cn68xx;
+	struct cvmx_ipd_ctl_status_s cn68xxp1;
+	struct cvmx_ipd_ctl_status_s cnf71xx;
+};
+
+union cvmx_ipd_ecc_ctl {
+	uint64_t u64;
+	struct cvmx_ipd_ecc_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_8_63:56;
+		uint64_t pm3_syn:2;
+		uint64_t pm2_syn:2;
+		uint64_t pm1_syn:2;
+		uint64_t pm0_syn:2;
+#else
+		uint64_t pm0_syn:2;
+		uint64_t pm1_syn:2;
+		uint64_t pm2_syn:2;
+		uint64_t pm3_syn:2;
+		uint64_t reserved_8_63:56;
+#endif
+	} s;
+	struct cvmx_ipd_ecc_ctl_s cn68xx;
+	struct cvmx_ipd_ecc_ctl_s cn68xxp1;
+};
+
+union cvmx_ipd_free_ptr_fifo_ctl {
+	uint64_t u64;
+	struct cvmx_ipd_free_ptr_fifo_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t max_cnts:7;
+		uint64_t wraddr:8;
+		uint64_t praddr:8;
+		uint64_t cena:1;
+		uint64_t raddr:8;
+#else
+		uint64_t raddr:8;
+		uint64_t cena:1;
+		uint64_t praddr:8;
+		uint64_t wraddr:8;
+		uint64_t max_cnts:7;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_ipd_free_ptr_fifo_ctl_s cn68xx;
+	struct cvmx_ipd_free_ptr_fifo_ctl_s cn68xxp1;
+};
+
+union cvmx_ipd_free_ptr_value {
+	uint64_t u64;
+	struct cvmx_ipd_free_ptr_value_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_33_63:31;
+		uint64_t ptr:33;
+#else
+		uint64_t ptr:33;
+		uint64_t reserved_33_63:31;
+#endif
+	} s;
+	struct cvmx_ipd_free_ptr_value_s cn68xx;
+	struct cvmx_ipd_free_ptr_value_s cn68xxp1;
+};
+
+union cvmx_ipd_hold_ptr_fifo_ctl {
+	uint64_t u64;
+	struct cvmx_ipd_hold_ptr_fifo_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_43_63:21;
+		uint64_t ptr:33;
+		uint64_t max_pkt:3;
+		uint64_t praddr:3;
+		uint64_t cena:1;
+		uint64_t raddr:3;
+#else
+		uint64_t raddr:3;
+		uint64_t cena:1;
+		uint64_t praddr:3;
+		uint64_t max_pkt:3;
+		uint64_t ptr:33;
+		uint64_t reserved_43_63:21;
+#endif
+	} s;
+	struct cvmx_ipd_hold_ptr_fifo_ctl_s cn68xx;
+	struct cvmx_ipd_hold_ptr_fifo_ctl_s cn68xxp1;
 };
 
 union cvmx_ipd_int_enb {
 	uint64_t u64;
 	struct cvmx_ipd_int_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_23_63:41;
+		uint64_t pw3_dbe:1;
+		uint64_t pw3_sbe:1;
+		uint64_t pw2_dbe:1;
+		uint64_t pw2_sbe:1;
+		uint64_t pw1_dbe:1;
+		uint64_t pw1_sbe:1;
+		uint64_t pw0_dbe:1;
+		uint64_t pw0_sbe:1;
+		uint64_t dat:1;
+		uint64_t eop:1;
+		uint64_t sop:1;
+		uint64_t pq_sub:1;
+		uint64_t pq_add:1;
+		uint64_t bc_ovr:1;
+		uint64_t d_coll:1;
+		uint64_t c_coll:1;
+		uint64_t cc_ovr:1;
+		uint64_t dc_ovr:1;
+		uint64_t bp_sub:1;
+		uint64_t prc_par3:1;
+		uint64_t prc_par2:1;
+		uint64_t prc_par1:1;
+		uint64_t prc_par0:1;
+#else
+		uint64_t prc_par0:1;
+		uint64_t prc_par1:1;
+		uint64_t prc_par2:1;
+		uint64_t prc_par3:1;
+		uint64_t bp_sub:1;
+		uint64_t dc_ovr:1;
+		uint64_t cc_ovr:1;
+		uint64_t c_coll:1;
+		uint64_t d_coll:1;
+		uint64_t bc_ovr:1;
+		uint64_t pq_add:1;
+		uint64_t pq_sub:1;
+		uint64_t sop:1;
+		uint64_t eop:1;
+		uint64_t dat:1;
+		uint64_t pw0_sbe:1;
+		uint64_t pw0_dbe:1;
+		uint64_t pw1_sbe:1;
+		uint64_t pw1_dbe:1;
+		uint64_t pw2_sbe:1;
+		uint64_t pw2_dbe:1;
+		uint64_t pw3_sbe:1;
+		uint64_t pw3_dbe:1;
+		uint64_t reserved_23_63:41;
+#endif
+	} s;
+	struct cvmx_ipd_int_enb_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_5_63:59;
+		uint64_t bp_sub:1;
+		uint64_t prc_par3:1;
+		uint64_t prc_par2:1;
+		uint64_t prc_par1:1;
+		uint64_t prc_par0:1;
+#else
+		uint64_t prc_par0:1;
+		uint64_t prc_par1:1;
+		uint64_t prc_par2:1;
+		uint64_t prc_par3:1;
+		uint64_t bp_sub:1;
+		uint64_t reserved_5_63:59;
+#endif
+	} cn30xx;
+	struct cvmx_ipd_int_enb_cn30xx cn31xx;
+	struct cvmx_ipd_int_enb_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t bc_ovr:1;
+		uint64_t d_coll:1;
+		uint64_t c_coll:1;
+		uint64_t cc_ovr:1;
+		uint64_t dc_ovr:1;
+		uint64_t bp_sub:1;
+		uint64_t prc_par3:1;
+		uint64_t prc_par2:1;
+		uint64_t prc_par1:1;
+		uint64_t prc_par0:1;
+#else
+		uint64_t prc_par0:1;
+		uint64_t prc_par1:1;
+		uint64_t prc_par2:1;
+		uint64_t prc_par3:1;
+		uint64_t bp_sub:1;
+		uint64_t dc_ovr:1;
+		uint64_t cc_ovr:1;
+		uint64_t c_coll:1;
+		uint64_t d_coll:1;
+		uint64_t bc_ovr:1;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn38xx;
+	struct cvmx_ipd_int_enb_cn30xx cn38xxp2;
+	struct cvmx_ipd_int_enb_cn38xx cn50xx;
+	struct cvmx_ipd_int_enb_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t pq_sub:1;
 		uint64_t pq_add:1;
@@ -366,44 +882,140 @@
 		uint64_t prc_par2:1;
 		uint64_t prc_par1:1;
 		uint64_t prc_par0:1;
-	} s;
-	struct cvmx_ipd_int_enb_cn30xx {
-		uint64_t reserved_5_63:59;
-		uint64_t bp_sub:1;
-		uint64_t prc_par3:1;
-		uint64_t prc_par2:1;
-		uint64_t prc_par1:1;
+#else
 		uint64_t prc_par0:1;
-	} cn30xx;
-	struct cvmx_ipd_int_enb_cn30xx cn31xx;
-	struct cvmx_ipd_int_enb_cn38xx {
-		uint64_t reserved_10_63:54;
-		uint64_t bc_ovr:1;
-		uint64_t d_coll:1;
-		uint64_t c_coll:1;
-		uint64_t cc_ovr:1;
+		uint64_t prc_par1:1;
+		uint64_t prc_par2:1;
+		uint64_t prc_par3:1;
+		uint64_t bp_sub:1;
 		uint64_t dc_ovr:1;
-		uint64_t bp_sub:1;
-		uint64_t prc_par3:1;
-		uint64_t prc_par2:1;
-		uint64_t prc_par1:1;
-		uint64_t prc_par0:1;
-	} cn38xx;
-	struct cvmx_ipd_int_enb_cn30xx cn38xxp2;
-	struct cvmx_ipd_int_enb_cn38xx cn50xx;
-	struct cvmx_ipd_int_enb_s cn52xx;
-	struct cvmx_ipd_int_enb_s cn52xxp1;
-	struct cvmx_ipd_int_enb_s cn56xx;
-	struct cvmx_ipd_int_enb_s cn56xxp1;
+		uint64_t cc_ovr:1;
+		uint64_t c_coll:1;
+		uint64_t d_coll:1;
+		uint64_t bc_ovr:1;
+		uint64_t pq_add:1;
+		uint64_t pq_sub:1;
+		uint64_t reserved_12_63:52;
+#endif
+	} cn52xx;
+	struct cvmx_ipd_int_enb_cn52xx cn52xxp1;
+	struct cvmx_ipd_int_enb_cn52xx cn56xx;
+	struct cvmx_ipd_int_enb_cn52xx cn56xxp1;
 	struct cvmx_ipd_int_enb_cn38xx cn58xx;
 	struct cvmx_ipd_int_enb_cn38xx cn58xxp1;
-	struct cvmx_ipd_int_enb_s cn63xx;
-	struct cvmx_ipd_int_enb_s cn63xxp1;
+	struct cvmx_ipd_int_enb_cn52xx cn61xx;
+	struct cvmx_ipd_int_enb_cn52xx cn63xx;
+	struct cvmx_ipd_int_enb_cn52xx cn63xxp1;
+	struct cvmx_ipd_int_enb_cn52xx cn66xx;
+	struct cvmx_ipd_int_enb_s cn68xx;
+	struct cvmx_ipd_int_enb_s cn68xxp1;
+	struct cvmx_ipd_int_enb_cn52xx cnf71xx;
 };
 
 union cvmx_ipd_int_sum {
 	uint64_t u64;
 	struct cvmx_ipd_int_sum_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_23_63:41;
+		uint64_t pw3_dbe:1;
+		uint64_t pw3_sbe:1;
+		uint64_t pw2_dbe:1;
+		uint64_t pw2_sbe:1;
+		uint64_t pw1_dbe:1;
+		uint64_t pw1_sbe:1;
+		uint64_t pw0_dbe:1;
+		uint64_t pw0_sbe:1;
+		uint64_t dat:1;
+		uint64_t eop:1;
+		uint64_t sop:1;
+		uint64_t pq_sub:1;
+		uint64_t pq_add:1;
+		uint64_t bc_ovr:1;
+		uint64_t d_coll:1;
+		uint64_t c_coll:1;
+		uint64_t cc_ovr:1;
+		uint64_t dc_ovr:1;
+		uint64_t bp_sub:1;
+		uint64_t prc_par3:1;
+		uint64_t prc_par2:1;
+		uint64_t prc_par1:1;
+		uint64_t prc_par0:1;
+#else
+		uint64_t prc_par0:1;
+		uint64_t prc_par1:1;
+		uint64_t prc_par2:1;
+		uint64_t prc_par3:1;
+		uint64_t bp_sub:1;
+		uint64_t dc_ovr:1;
+		uint64_t cc_ovr:1;
+		uint64_t c_coll:1;
+		uint64_t d_coll:1;
+		uint64_t bc_ovr:1;
+		uint64_t pq_add:1;
+		uint64_t pq_sub:1;
+		uint64_t sop:1;
+		uint64_t eop:1;
+		uint64_t dat:1;
+		uint64_t pw0_sbe:1;
+		uint64_t pw0_dbe:1;
+		uint64_t pw1_sbe:1;
+		uint64_t pw1_dbe:1;
+		uint64_t pw2_sbe:1;
+		uint64_t pw2_dbe:1;
+		uint64_t pw3_sbe:1;
+		uint64_t pw3_dbe:1;
+		uint64_t reserved_23_63:41;
+#endif
+	} s;
+	struct cvmx_ipd_int_sum_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_5_63:59;
+		uint64_t bp_sub:1;
+		uint64_t prc_par3:1;
+		uint64_t prc_par2:1;
+		uint64_t prc_par1:1;
+		uint64_t prc_par0:1;
+#else
+		uint64_t prc_par0:1;
+		uint64_t prc_par1:1;
+		uint64_t prc_par2:1;
+		uint64_t prc_par3:1;
+		uint64_t bp_sub:1;
+		uint64_t reserved_5_63:59;
+#endif
+	} cn30xx;
+	struct cvmx_ipd_int_sum_cn30xx cn31xx;
+	struct cvmx_ipd_int_sum_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t bc_ovr:1;
+		uint64_t d_coll:1;
+		uint64_t c_coll:1;
+		uint64_t cc_ovr:1;
+		uint64_t dc_ovr:1;
+		uint64_t bp_sub:1;
+		uint64_t prc_par3:1;
+		uint64_t prc_par2:1;
+		uint64_t prc_par1:1;
+		uint64_t prc_par0:1;
+#else
+		uint64_t prc_par0:1;
+		uint64_t prc_par1:1;
+		uint64_t prc_par2:1;
+		uint64_t prc_par3:1;
+		uint64_t bp_sub:1;
+		uint64_t dc_ovr:1;
+		uint64_t cc_ovr:1;
+		uint64_t c_coll:1;
+		uint64_t d_coll:1;
+		uint64_t bc_ovr:1;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn38xx;
+	struct cvmx_ipd_int_sum_cn30xx cn38xxp2;
+	struct cvmx_ipd_int_sum_cn38xx cn50xx;
+	struct cvmx_ipd_int_sum_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t pq_sub:1;
 		uint64_t pq_add:1;
@@ -417,46 +1029,76 @@
 		uint64_t prc_par2:1;
 		uint64_t prc_par1:1;
 		uint64_t prc_par0:1;
-	} s;
-	struct cvmx_ipd_int_sum_cn30xx {
-		uint64_t reserved_5_63:59;
-		uint64_t bp_sub:1;
-		uint64_t prc_par3:1;
-		uint64_t prc_par2:1;
-		uint64_t prc_par1:1;
+#else
 		uint64_t prc_par0:1;
-	} cn30xx;
-	struct cvmx_ipd_int_sum_cn30xx cn31xx;
-	struct cvmx_ipd_int_sum_cn38xx {
-		uint64_t reserved_10_63:54;
-		uint64_t bc_ovr:1;
-		uint64_t d_coll:1;
-		uint64_t c_coll:1;
-		uint64_t cc_ovr:1;
+		uint64_t prc_par1:1;
+		uint64_t prc_par2:1;
+		uint64_t prc_par3:1;
+		uint64_t bp_sub:1;
 		uint64_t dc_ovr:1;
-		uint64_t bp_sub:1;
-		uint64_t prc_par3:1;
-		uint64_t prc_par2:1;
-		uint64_t prc_par1:1;
-		uint64_t prc_par0:1;
-	} cn38xx;
-	struct cvmx_ipd_int_sum_cn30xx cn38xxp2;
-	struct cvmx_ipd_int_sum_cn38xx cn50xx;
-	struct cvmx_ipd_int_sum_s cn52xx;
-	struct cvmx_ipd_int_sum_s cn52xxp1;
-	struct cvmx_ipd_int_sum_s cn56xx;
-	struct cvmx_ipd_int_sum_s cn56xxp1;
+		uint64_t cc_ovr:1;
+		uint64_t c_coll:1;
+		uint64_t d_coll:1;
+		uint64_t bc_ovr:1;
+		uint64_t pq_add:1;
+		uint64_t pq_sub:1;
+		uint64_t reserved_12_63:52;
+#endif
+	} cn52xx;
+	struct cvmx_ipd_int_sum_cn52xx cn52xxp1;
+	struct cvmx_ipd_int_sum_cn52xx cn56xx;
+	struct cvmx_ipd_int_sum_cn52xx cn56xxp1;
 	struct cvmx_ipd_int_sum_cn38xx cn58xx;
 	struct cvmx_ipd_int_sum_cn38xx cn58xxp1;
-	struct cvmx_ipd_int_sum_s cn63xx;
-	struct cvmx_ipd_int_sum_s cn63xxp1;
+	struct cvmx_ipd_int_sum_cn52xx cn61xx;
+	struct cvmx_ipd_int_sum_cn52xx cn63xx;
+	struct cvmx_ipd_int_sum_cn52xx cn63xxp1;
+	struct cvmx_ipd_int_sum_cn52xx cn66xx;
+	struct cvmx_ipd_int_sum_s cn68xx;
+	struct cvmx_ipd_int_sum_s cn68xxp1;
+	struct cvmx_ipd_int_sum_cn52xx cnf71xx;
+};
+
+union cvmx_ipd_next_pkt_ptr {
+	uint64_t u64;
+	struct cvmx_ipd_next_pkt_ptr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_33_63:31;
+		uint64_t ptr:33;
+#else
+		uint64_t ptr:33;
+		uint64_t reserved_33_63:31;
+#endif
+	} s;
+	struct cvmx_ipd_next_pkt_ptr_s cn68xx;
+	struct cvmx_ipd_next_pkt_ptr_s cn68xxp1;
+};
+
+union cvmx_ipd_next_wqe_ptr {
+	uint64_t u64;
+	struct cvmx_ipd_next_wqe_ptr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_33_63:31;
+		uint64_t ptr:33;
+#else
+		uint64_t ptr:33;
+		uint64_t reserved_33_63:31;
+#endif
+	} s;
+	struct cvmx_ipd_next_wqe_ptr_s cn68xx;
+	struct cvmx_ipd_next_wqe_ptr_s cn68xxp1;
 };
 
 union cvmx_ipd_not_1st_mbuff_skip {
 	uint64_t u64;
 	struct cvmx_ipd_not_1st_mbuff_skip_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t skip_sz:6;
+#else
+		uint64_t skip_sz:6;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
 	struct cvmx_ipd_not_1st_mbuff_skip_s cn30xx;
 	struct cvmx_ipd_not_1st_mbuff_skip_s cn31xx;
@@ -469,15 +1111,38 @@
 	struct cvmx_ipd_not_1st_mbuff_skip_s cn56xxp1;
 	struct cvmx_ipd_not_1st_mbuff_skip_s cn58xx;
 	struct cvmx_ipd_not_1st_mbuff_skip_s cn58xxp1;
+	struct cvmx_ipd_not_1st_mbuff_skip_s cn61xx;
 	struct cvmx_ipd_not_1st_mbuff_skip_s cn63xx;
 	struct cvmx_ipd_not_1st_mbuff_skip_s cn63xxp1;
+	struct cvmx_ipd_not_1st_mbuff_skip_s cn66xx;
+	struct cvmx_ipd_not_1st_mbuff_skip_s cn68xx;
+	struct cvmx_ipd_not_1st_mbuff_skip_s cn68xxp1;
+	struct cvmx_ipd_not_1st_mbuff_skip_s cnf71xx;
+};
+
+union cvmx_ipd_on_bp_drop_pktx {
+	uint64_t u64;
+	struct cvmx_ipd_on_bp_drop_pktx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t prt_enb:64;
+#else
+		uint64_t prt_enb:64;
+#endif
+	} s;
+	struct cvmx_ipd_on_bp_drop_pktx_s cn68xx;
+	struct cvmx_ipd_on_bp_drop_pktx_s cn68xxp1;
 };
 
 union cvmx_ipd_packet_mbuff_size {
 	uint64_t u64;
 	struct cvmx_ipd_packet_mbuff_size_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t mb_size:12;
+#else
+		uint64_t mb_size:12;
+		uint64_t reserved_12_63:52;
+#endif
 	} s;
 	struct cvmx_ipd_packet_mbuff_size_s cn30xx;
 	struct cvmx_ipd_packet_mbuff_size_s cn31xx;
@@ -490,15 +1155,40 @@
 	struct cvmx_ipd_packet_mbuff_size_s cn56xxp1;
 	struct cvmx_ipd_packet_mbuff_size_s cn58xx;
 	struct cvmx_ipd_packet_mbuff_size_s cn58xxp1;
+	struct cvmx_ipd_packet_mbuff_size_s cn61xx;
 	struct cvmx_ipd_packet_mbuff_size_s cn63xx;
 	struct cvmx_ipd_packet_mbuff_size_s cn63xxp1;
+	struct cvmx_ipd_packet_mbuff_size_s cn66xx;
+	struct cvmx_ipd_packet_mbuff_size_s cn68xx;
+	struct cvmx_ipd_packet_mbuff_size_s cn68xxp1;
+	struct cvmx_ipd_packet_mbuff_size_s cnf71xx;
+};
+
+union cvmx_ipd_pkt_err {
+	uint64_t u64;
+	struct cvmx_ipd_pkt_err_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_6_63:58;
+		uint64_t reasm:6;
+#else
+		uint64_t reasm:6;
+		uint64_t reserved_6_63:58;
+#endif
+	} s;
+	struct cvmx_ipd_pkt_err_s cn68xx;
+	struct cvmx_ipd_pkt_err_s cn68xxp1;
 };
 
 union cvmx_ipd_pkt_ptr_valid {
 	uint64_t u64;
 	struct cvmx_ipd_pkt_ptr_valid_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_29_63:35;
 		uint64_t ptr:29;
+#else
+		uint64_t ptr:29;
+		uint64_t reserved_29_63:35;
+#endif
 	} s;
 	struct cvmx_ipd_pkt_ptr_valid_s cn30xx;
 	struct cvmx_ipd_pkt_ptr_valid_s cn31xx;
@@ -510,16 +1200,25 @@
 	struct cvmx_ipd_pkt_ptr_valid_s cn56xxp1;
 	struct cvmx_ipd_pkt_ptr_valid_s cn58xx;
 	struct cvmx_ipd_pkt_ptr_valid_s cn58xxp1;
+	struct cvmx_ipd_pkt_ptr_valid_s cn61xx;
 	struct cvmx_ipd_pkt_ptr_valid_s cn63xx;
 	struct cvmx_ipd_pkt_ptr_valid_s cn63xxp1;
+	struct cvmx_ipd_pkt_ptr_valid_s cn66xx;
+	struct cvmx_ipd_pkt_ptr_valid_s cnf71xx;
 };
 
 union cvmx_ipd_portx_bp_page_cnt {
 	uint64_t u64;
 	struct cvmx_ipd_portx_bp_page_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_18_63:46;
 		uint64_t bp_enb:1;
 		uint64_t page_cnt:17;
+#else
+		uint64_t page_cnt:17;
+		uint64_t bp_enb:1;
+		uint64_t reserved_18_63:46;
+#endif
 	} s;
 	struct cvmx_ipd_portx_bp_page_cnt_s cn30xx;
 	struct cvmx_ipd_portx_bp_page_cnt_s cn31xx;
@@ -532,65 +1231,123 @@
 	struct cvmx_ipd_portx_bp_page_cnt_s cn56xxp1;
 	struct cvmx_ipd_portx_bp_page_cnt_s cn58xx;
 	struct cvmx_ipd_portx_bp_page_cnt_s cn58xxp1;
+	struct cvmx_ipd_portx_bp_page_cnt_s cn61xx;
 	struct cvmx_ipd_portx_bp_page_cnt_s cn63xx;
 	struct cvmx_ipd_portx_bp_page_cnt_s cn63xxp1;
+	struct cvmx_ipd_portx_bp_page_cnt_s cn66xx;
+	struct cvmx_ipd_portx_bp_page_cnt_s cnf71xx;
 };
 
 union cvmx_ipd_portx_bp_page_cnt2 {
 	uint64_t u64;
 	struct cvmx_ipd_portx_bp_page_cnt2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_18_63:46;
 		uint64_t bp_enb:1;
 		uint64_t page_cnt:17;
+#else
+		uint64_t page_cnt:17;
+		uint64_t bp_enb:1;
+		uint64_t reserved_18_63:46;
+#endif
 	} s;
 	struct cvmx_ipd_portx_bp_page_cnt2_s cn52xx;
 	struct cvmx_ipd_portx_bp_page_cnt2_s cn52xxp1;
 	struct cvmx_ipd_portx_bp_page_cnt2_s cn56xx;
 	struct cvmx_ipd_portx_bp_page_cnt2_s cn56xxp1;
+	struct cvmx_ipd_portx_bp_page_cnt2_s cn61xx;
 	struct cvmx_ipd_portx_bp_page_cnt2_s cn63xx;
 	struct cvmx_ipd_portx_bp_page_cnt2_s cn63xxp1;
+	struct cvmx_ipd_portx_bp_page_cnt2_s cn66xx;
+	struct cvmx_ipd_portx_bp_page_cnt2_s cnf71xx;
 };
 
 union cvmx_ipd_portx_bp_page_cnt3 {
 	uint64_t u64;
 	struct cvmx_ipd_portx_bp_page_cnt3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_18_63:46;
 		uint64_t bp_enb:1;
 		uint64_t page_cnt:17;
+#else
+		uint64_t page_cnt:17;
+		uint64_t bp_enb:1;
+		uint64_t reserved_18_63:46;
+#endif
 	} s;
+	struct cvmx_ipd_portx_bp_page_cnt3_s cn61xx;
 	struct cvmx_ipd_portx_bp_page_cnt3_s cn63xx;
 	struct cvmx_ipd_portx_bp_page_cnt3_s cn63xxp1;
+	struct cvmx_ipd_portx_bp_page_cnt3_s cn66xx;
+	struct cvmx_ipd_portx_bp_page_cnt3_s cnf71xx;
 };
 
 union cvmx_ipd_port_bp_counters2_pairx {
 	uint64_t u64;
 	struct cvmx_ipd_port_bp_counters2_pairx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_25_63:39;
 		uint64_t cnt_val:25;
+#else
+		uint64_t cnt_val:25;
+		uint64_t reserved_25_63:39;
+#endif
 	} s;
 	struct cvmx_ipd_port_bp_counters2_pairx_s cn52xx;
 	struct cvmx_ipd_port_bp_counters2_pairx_s cn52xxp1;
 	struct cvmx_ipd_port_bp_counters2_pairx_s cn56xx;
 	struct cvmx_ipd_port_bp_counters2_pairx_s cn56xxp1;
+	struct cvmx_ipd_port_bp_counters2_pairx_s cn61xx;
 	struct cvmx_ipd_port_bp_counters2_pairx_s cn63xx;
 	struct cvmx_ipd_port_bp_counters2_pairx_s cn63xxp1;
+	struct cvmx_ipd_port_bp_counters2_pairx_s cn66xx;
+	struct cvmx_ipd_port_bp_counters2_pairx_s cnf71xx;
 };
 
 union cvmx_ipd_port_bp_counters3_pairx {
 	uint64_t u64;
 	struct cvmx_ipd_port_bp_counters3_pairx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_25_63:39;
 		uint64_t cnt_val:25;
+#else
+		uint64_t cnt_val:25;
+		uint64_t reserved_25_63:39;
+#endif
 	} s;
+	struct cvmx_ipd_port_bp_counters3_pairx_s cn61xx;
 	struct cvmx_ipd_port_bp_counters3_pairx_s cn63xx;
 	struct cvmx_ipd_port_bp_counters3_pairx_s cn63xxp1;
+	struct cvmx_ipd_port_bp_counters3_pairx_s cn66xx;
+	struct cvmx_ipd_port_bp_counters3_pairx_s cnf71xx;
+};
+
+union cvmx_ipd_port_bp_counters4_pairx {
+	uint64_t u64;
+	struct cvmx_ipd_port_bp_counters4_pairx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_25_63:39;
+		uint64_t cnt_val:25;
+#else
+		uint64_t cnt_val:25;
+		uint64_t reserved_25_63:39;
+#endif
+	} s;
+	struct cvmx_ipd_port_bp_counters4_pairx_s cn61xx;
+	struct cvmx_ipd_port_bp_counters4_pairx_s cn66xx;
+	struct cvmx_ipd_port_bp_counters4_pairx_s cnf71xx;
 };
 
 union cvmx_ipd_port_bp_counters_pairx {
 	uint64_t u64;
 	struct cvmx_ipd_port_bp_counters_pairx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_25_63:39;
 		uint64_t cnt_val:25;
+#else
+		uint64_t cnt_val:25;
+		uint64_t reserved_25_63:39;
+#endif
 	} s;
 	struct cvmx_ipd_port_bp_counters_pairx_s cn30xx;
 	struct cvmx_ipd_port_bp_counters_pairx_s cn31xx;
@@ -603,59 +1360,133 @@
 	struct cvmx_ipd_port_bp_counters_pairx_s cn56xxp1;
 	struct cvmx_ipd_port_bp_counters_pairx_s cn58xx;
 	struct cvmx_ipd_port_bp_counters_pairx_s cn58xxp1;
+	struct cvmx_ipd_port_bp_counters_pairx_s cn61xx;
 	struct cvmx_ipd_port_bp_counters_pairx_s cn63xx;
 	struct cvmx_ipd_port_bp_counters_pairx_s cn63xxp1;
+	struct cvmx_ipd_port_bp_counters_pairx_s cn66xx;
+	struct cvmx_ipd_port_bp_counters_pairx_s cnf71xx;
+};
+
+union cvmx_ipd_port_ptr_fifo_ctl {
+	uint64_t u64;
+	struct cvmx_ipd_port_ptr_fifo_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_48_63:16;
+		uint64_t ptr:33;
+		uint64_t max_pkt:7;
+		uint64_t cena:1;
+		uint64_t raddr:7;
+#else
+		uint64_t raddr:7;
+		uint64_t cena:1;
+		uint64_t max_pkt:7;
+		uint64_t ptr:33;
+		uint64_t reserved_48_63:16;
+#endif
+	} s;
+	struct cvmx_ipd_port_ptr_fifo_ctl_s cn68xx;
+	struct cvmx_ipd_port_ptr_fifo_ctl_s cn68xxp1;
 };
 
 union cvmx_ipd_port_qos_x_cnt {
 	uint64_t u64;
 	struct cvmx_ipd_port_qos_x_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t wmark:32;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t wmark:32;
+#endif
 	} s;
 	struct cvmx_ipd_port_qos_x_cnt_s cn52xx;
 	struct cvmx_ipd_port_qos_x_cnt_s cn52xxp1;
 	struct cvmx_ipd_port_qos_x_cnt_s cn56xx;
 	struct cvmx_ipd_port_qos_x_cnt_s cn56xxp1;
+	struct cvmx_ipd_port_qos_x_cnt_s cn61xx;
 	struct cvmx_ipd_port_qos_x_cnt_s cn63xx;
 	struct cvmx_ipd_port_qos_x_cnt_s cn63xxp1;
+	struct cvmx_ipd_port_qos_x_cnt_s cn66xx;
+	struct cvmx_ipd_port_qos_x_cnt_s cn68xx;
+	struct cvmx_ipd_port_qos_x_cnt_s cn68xxp1;
+	struct cvmx_ipd_port_qos_x_cnt_s cnf71xx;
 };
 
 union cvmx_ipd_port_qos_intx {
 	uint64_t u64;
 	struct cvmx_ipd_port_qos_intx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t intr:64;
+#else
+		uint64_t intr:64;
+#endif
 	} s;
 	struct cvmx_ipd_port_qos_intx_s cn52xx;
 	struct cvmx_ipd_port_qos_intx_s cn52xxp1;
 	struct cvmx_ipd_port_qos_intx_s cn56xx;
 	struct cvmx_ipd_port_qos_intx_s cn56xxp1;
+	struct cvmx_ipd_port_qos_intx_s cn61xx;
 	struct cvmx_ipd_port_qos_intx_s cn63xx;
 	struct cvmx_ipd_port_qos_intx_s cn63xxp1;
+	struct cvmx_ipd_port_qos_intx_s cn66xx;
+	struct cvmx_ipd_port_qos_intx_s cn68xx;
+	struct cvmx_ipd_port_qos_intx_s cn68xxp1;
+	struct cvmx_ipd_port_qos_intx_s cnf71xx;
 };
 
 union cvmx_ipd_port_qos_int_enbx {
 	uint64_t u64;
 	struct cvmx_ipd_port_qos_int_enbx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t enb:64;
+#else
+		uint64_t enb:64;
+#endif
 	} s;
 	struct cvmx_ipd_port_qos_int_enbx_s cn52xx;
 	struct cvmx_ipd_port_qos_int_enbx_s cn52xxp1;
 	struct cvmx_ipd_port_qos_int_enbx_s cn56xx;
 	struct cvmx_ipd_port_qos_int_enbx_s cn56xxp1;
+	struct cvmx_ipd_port_qos_int_enbx_s cn61xx;
 	struct cvmx_ipd_port_qos_int_enbx_s cn63xx;
 	struct cvmx_ipd_port_qos_int_enbx_s cn63xxp1;
+	struct cvmx_ipd_port_qos_int_enbx_s cn66xx;
+	struct cvmx_ipd_port_qos_int_enbx_s cn68xx;
+	struct cvmx_ipd_port_qos_int_enbx_s cn68xxp1;
+	struct cvmx_ipd_port_qos_int_enbx_s cnf71xx;
+};
+
+union cvmx_ipd_port_sopx {
+	uint64_t u64;
+	struct cvmx_ipd_port_sopx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t sop:64;
+#else
+		uint64_t sop:64;
+#endif
+	} s;
+	struct cvmx_ipd_port_sopx_s cn68xx;
+	struct cvmx_ipd_port_sopx_s cn68xxp1;
 };
 
 union cvmx_ipd_prc_hold_ptr_fifo_ctl {
 	uint64_t u64;
 	struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_39_63:25;
 		uint64_t max_pkt:3;
 		uint64_t praddr:3;
 		uint64_t ptr:29;
 		uint64_t cena:1;
 		uint64_t raddr:3;
+#else
+		uint64_t raddr:3;
+		uint64_t cena:1;
+		uint64_t ptr:29;
+		uint64_t praddr:3;
+		uint64_t max_pkt:3;
+		uint64_t reserved_39_63:25;
+#endif
 	} s;
 	struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn30xx;
 	struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn31xx;
@@ -667,18 +1498,29 @@
 	struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn56xxp1;
 	struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn58xx;
 	struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn58xxp1;
+	struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn61xx;
 	struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn63xx;
 	struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn63xxp1;
+	struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn66xx;
+	struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cnf71xx;
 };
 
 union cvmx_ipd_prc_port_ptr_fifo_ctl {
 	uint64_t u64;
 	struct cvmx_ipd_prc_port_ptr_fifo_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_44_63:20;
 		uint64_t max_pkt:7;
 		uint64_t ptr:29;
 		uint64_t cena:1;
 		uint64_t raddr:7;
+#else
+		uint64_t raddr:7;
+		uint64_t cena:1;
+		uint64_t ptr:29;
+		uint64_t max_pkt:7;
+		uint64_t reserved_44_63:20;
+#endif
 	} s;
 	struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn30xx;
 	struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn31xx;
@@ -690,19 +1532,31 @@
 	struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn56xxp1;
 	struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn58xx;
 	struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn58xxp1;
+	struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn61xx;
 	struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn63xx;
 	struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn63xxp1;
+	struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn66xx;
+	struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cnf71xx;
 };
 
 union cvmx_ipd_ptr_count {
 	uint64_t u64;
 	struct cvmx_ipd_ptr_count_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_19_63:45;
 		uint64_t pktv_cnt:1;
 		uint64_t wqev_cnt:1;
 		uint64_t pfif_cnt:3;
 		uint64_t pkt_pcnt:7;
 		uint64_t wqe_pcnt:7;
+#else
+		uint64_t wqe_pcnt:7;
+		uint64_t pkt_pcnt:7;
+		uint64_t pfif_cnt:3;
+		uint64_t wqev_cnt:1;
+		uint64_t pktv_cnt:1;
+		uint64_t reserved_19_63:45;
+#endif
 	} s;
 	struct cvmx_ipd_ptr_count_s cn30xx;
 	struct cvmx_ipd_ptr_count_s cn31xx;
@@ -715,13 +1569,19 @@
 	struct cvmx_ipd_ptr_count_s cn56xxp1;
 	struct cvmx_ipd_ptr_count_s cn58xx;
 	struct cvmx_ipd_ptr_count_s cn58xxp1;
+	struct cvmx_ipd_ptr_count_s cn61xx;
 	struct cvmx_ipd_ptr_count_s cn63xx;
 	struct cvmx_ipd_ptr_count_s cn63xxp1;
+	struct cvmx_ipd_ptr_count_s cn66xx;
+	struct cvmx_ipd_ptr_count_s cn68xx;
+	struct cvmx_ipd_ptr_count_s cn68xxp1;
+	struct cvmx_ipd_ptr_count_s cnf71xx;
 };
 
 union cvmx_ipd_pwp_ptr_fifo_ctl {
 	uint64_t u64;
 	struct cvmx_ipd_pwp_ptr_fifo_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_61_63:3;
 		uint64_t max_cnts:7;
 		uint64_t wraddr:8;
@@ -729,6 +1589,15 @@
 		uint64_t ptr:29;
 		uint64_t cena:1;
 		uint64_t raddr:8;
+#else
+		uint64_t raddr:8;
+		uint64_t cena:1;
+		uint64_t ptr:29;
+		uint64_t praddr:8;
+		uint64_t wraddr:8;
+		uint64_t max_cnts:7;
+		uint64_t reserved_61_63:3;
+#endif
 	} s;
 	struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn30xx;
 	struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn31xx;
@@ -740,15 +1609,23 @@
 	struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn56xxp1;
 	struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn58xx;
 	struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn58xxp1;
+	struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn61xx;
 	struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn63xx;
 	struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn63xxp1;
+	struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn66xx;
+	struct cvmx_ipd_pwp_ptr_fifo_ctl_s cnf71xx;
 };
 
 union cvmx_ipd_qosx_red_marks {
 	uint64_t u64;
 	struct cvmx_ipd_qosx_red_marks_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t drop:32;
 		uint64_t pass:32;
+#else
+		uint64_t pass:32;
+		uint64_t drop:32;
+#endif
 	} s;
 	struct cvmx_ipd_qosx_red_marks_s cn30xx;
 	struct cvmx_ipd_qosx_red_marks_s cn31xx;
@@ -761,15 +1638,25 @@
 	struct cvmx_ipd_qosx_red_marks_s cn56xxp1;
 	struct cvmx_ipd_qosx_red_marks_s cn58xx;
 	struct cvmx_ipd_qosx_red_marks_s cn58xxp1;
+	struct cvmx_ipd_qosx_red_marks_s cn61xx;
 	struct cvmx_ipd_qosx_red_marks_s cn63xx;
 	struct cvmx_ipd_qosx_red_marks_s cn63xxp1;
+	struct cvmx_ipd_qosx_red_marks_s cn66xx;
+	struct cvmx_ipd_qosx_red_marks_s cn68xx;
+	struct cvmx_ipd_qosx_red_marks_s cn68xxp1;
+	struct cvmx_ipd_qosx_red_marks_s cnf71xx;
 };
 
 union cvmx_ipd_que0_free_page_cnt {
 	uint64_t u64;
 	struct cvmx_ipd_que0_free_page_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t q0_pcnt:32;
+#else
+		uint64_t q0_pcnt:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_ipd_que0_free_page_cnt_s cn30xx;
 	struct cvmx_ipd_que0_free_page_cnt_s cn31xx;
@@ -782,16 +1669,57 @@
 	struct cvmx_ipd_que0_free_page_cnt_s cn56xxp1;
 	struct cvmx_ipd_que0_free_page_cnt_s cn58xx;
 	struct cvmx_ipd_que0_free_page_cnt_s cn58xxp1;
+	struct cvmx_ipd_que0_free_page_cnt_s cn61xx;
 	struct cvmx_ipd_que0_free_page_cnt_s cn63xx;
 	struct cvmx_ipd_que0_free_page_cnt_s cn63xxp1;
+	struct cvmx_ipd_que0_free_page_cnt_s cn66xx;
+	struct cvmx_ipd_que0_free_page_cnt_s cn68xx;
+	struct cvmx_ipd_que0_free_page_cnt_s cn68xxp1;
+	struct cvmx_ipd_que0_free_page_cnt_s cnf71xx;
+};
+
+union cvmx_ipd_red_bpid_enablex {
+	uint64_t u64;
+	struct cvmx_ipd_red_bpid_enablex_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t prt_enb:64;
+#else
+		uint64_t prt_enb:64;
+#endif
+	} s;
+	struct cvmx_ipd_red_bpid_enablex_s cn68xx;
+	struct cvmx_ipd_red_bpid_enablex_s cn68xxp1;
+};
+
+union cvmx_ipd_red_delay {
+	uint64_t u64;
+	struct cvmx_ipd_red_delay_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_28_63:36;
+		uint64_t prb_dly:14;
+		uint64_t avg_dly:14;
+#else
+		uint64_t avg_dly:14;
+		uint64_t prb_dly:14;
+		uint64_t reserved_28_63:36;
+#endif
+	} s;
+	struct cvmx_ipd_red_delay_s cn68xx;
+	struct cvmx_ipd_red_delay_s cn68xxp1;
 };
 
 union cvmx_ipd_red_port_enable {
 	uint64_t u64;
 	struct cvmx_ipd_red_port_enable_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t prb_dly:14;
 		uint64_t avg_dly:14;
 		uint64_t prt_enb:36;
+#else
+		uint64_t prt_enb:36;
+		uint64_t avg_dly:14;
+		uint64_t prb_dly:14;
+#endif
 	} s;
 	struct cvmx_ipd_red_port_enable_s cn30xx;
 	struct cvmx_ipd_red_port_enable_s cn31xx;
@@ -804,35 +1732,67 @@
 	struct cvmx_ipd_red_port_enable_s cn56xxp1;
 	struct cvmx_ipd_red_port_enable_s cn58xx;
 	struct cvmx_ipd_red_port_enable_s cn58xxp1;
+	struct cvmx_ipd_red_port_enable_s cn61xx;
 	struct cvmx_ipd_red_port_enable_s cn63xx;
 	struct cvmx_ipd_red_port_enable_s cn63xxp1;
+	struct cvmx_ipd_red_port_enable_s cn66xx;
+	struct cvmx_ipd_red_port_enable_s cnf71xx;
 };
 
 union cvmx_ipd_red_port_enable2 {
 	uint64_t u64;
 	struct cvmx_ipd_red_port_enable2_s {
-		uint64_t reserved_8_63:56;
-		uint64_t prt_enb:8;
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_12_63:52;
+		uint64_t prt_enb:12;
+#else
+		uint64_t prt_enb:12;
+		uint64_t reserved_12_63:52;
+#endif
 	} s;
 	struct cvmx_ipd_red_port_enable2_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t prt_enb:4;
+#else
+		uint64_t prt_enb:4;
+		uint64_t reserved_4_63:60;
+#endif
 	} cn52xx;
 	struct cvmx_ipd_red_port_enable2_cn52xx cn52xxp1;
 	struct cvmx_ipd_red_port_enable2_cn52xx cn56xx;
 	struct cvmx_ipd_red_port_enable2_cn52xx cn56xxp1;
-	struct cvmx_ipd_red_port_enable2_s cn63xx;
-	struct cvmx_ipd_red_port_enable2_s cn63xxp1;
+	struct cvmx_ipd_red_port_enable2_s cn61xx;
+	struct cvmx_ipd_red_port_enable2_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_8_63:56;
+		uint64_t prt_enb:8;
+#else
+		uint64_t prt_enb:8;
+		uint64_t reserved_8_63:56;
+#endif
+	} cn63xx;
+	struct cvmx_ipd_red_port_enable2_cn63xx cn63xxp1;
+	struct cvmx_ipd_red_port_enable2_s cn66xx;
+	struct cvmx_ipd_red_port_enable2_s cnf71xx;
 };
 
 union cvmx_ipd_red_quex_param {
 	uint64_t u64;
 	struct cvmx_ipd_red_quex_param_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_49_63:15;
 		uint64_t use_pcnt:1;
 		uint64_t new_con:8;
 		uint64_t avg_con:8;
 		uint64_t prb_con:32;
+#else
+		uint64_t prb_con:32;
+		uint64_t avg_con:8;
+		uint64_t new_con:8;
+		uint64_t use_pcnt:1;
+		uint64_t reserved_49_63:15;
+#endif
 	} s;
 	struct cvmx_ipd_red_quex_param_s cn30xx;
 	struct cvmx_ipd_red_quex_param_s cn31xx;
@@ -845,16 +1805,53 @@
 	struct cvmx_ipd_red_quex_param_s cn56xxp1;
 	struct cvmx_ipd_red_quex_param_s cn58xx;
 	struct cvmx_ipd_red_quex_param_s cn58xxp1;
+	struct cvmx_ipd_red_quex_param_s cn61xx;
 	struct cvmx_ipd_red_quex_param_s cn63xx;
 	struct cvmx_ipd_red_quex_param_s cn63xxp1;
+	struct cvmx_ipd_red_quex_param_s cn66xx;
+	struct cvmx_ipd_red_quex_param_s cn68xx;
+	struct cvmx_ipd_red_quex_param_s cn68xxp1;
+	struct cvmx_ipd_red_quex_param_s cnf71xx;
+};
+
+union cvmx_ipd_req_wgt {
+	uint64_t u64;
+	struct cvmx_ipd_req_wgt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t wgt7:8;
+		uint64_t wgt6:8;
+		uint64_t wgt5:8;
+		uint64_t wgt4:8;
+		uint64_t wgt3:8;
+		uint64_t wgt2:8;
+		uint64_t wgt1:8;
+		uint64_t wgt0:8;
+#else
+		uint64_t wgt0:8;
+		uint64_t wgt1:8;
+		uint64_t wgt2:8;
+		uint64_t wgt3:8;
+		uint64_t wgt4:8;
+		uint64_t wgt5:8;
+		uint64_t wgt6:8;
+		uint64_t wgt7:8;
+#endif
+	} s;
+	struct cvmx_ipd_req_wgt_s cn68xx;
 };
 
 union cvmx_ipd_sub_port_bp_page_cnt {
 	uint64_t u64;
 	struct cvmx_ipd_sub_port_bp_page_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_31_63:33;
 		uint64_t port:6;
 		uint64_t page_cnt:25;
+#else
+		uint64_t page_cnt:25;
+		uint64_t port:6;
+		uint64_t reserved_31_63:33;
+#endif
 	} s;
 	struct cvmx_ipd_sub_port_bp_page_cnt_s cn30xx;
 	struct cvmx_ipd_sub_port_bp_page_cnt_s cn31xx;
@@ -867,26 +1864,48 @@
 	struct cvmx_ipd_sub_port_bp_page_cnt_s cn56xxp1;
 	struct cvmx_ipd_sub_port_bp_page_cnt_s cn58xx;
 	struct cvmx_ipd_sub_port_bp_page_cnt_s cn58xxp1;
+	struct cvmx_ipd_sub_port_bp_page_cnt_s cn61xx;
 	struct cvmx_ipd_sub_port_bp_page_cnt_s cn63xx;
 	struct cvmx_ipd_sub_port_bp_page_cnt_s cn63xxp1;
+	struct cvmx_ipd_sub_port_bp_page_cnt_s cn66xx;
+	struct cvmx_ipd_sub_port_bp_page_cnt_s cn68xx;
+	struct cvmx_ipd_sub_port_bp_page_cnt_s cn68xxp1;
+	struct cvmx_ipd_sub_port_bp_page_cnt_s cnf71xx;
 };
 
 union cvmx_ipd_sub_port_fcs {
 	uint64_t u64;
 	struct cvmx_ipd_sub_port_fcs_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_40_63:24;
 		uint64_t port_bit2:4;
 		uint64_t reserved_32_35:4;
 		uint64_t port_bit:32;
+#else
+		uint64_t port_bit:32;
+		uint64_t reserved_32_35:4;
+		uint64_t port_bit2:4;
+		uint64_t reserved_40_63:24;
+#endif
 	} s;
 	struct cvmx_ipd_sub_port_fcs_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_3_63:61;
 		uint64_t port_bit:3;
+#else
+		uint64_t port_bit:3;
+		uint64_t reserved_3_63:61;
+#endif
 	} cn30xx;
 	struct cvmx_ipd_sub_port_fcs_cn30xx cn31xx;
 	struct cvmx_ipd_sub_port_fcs_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t port_bit:32;
+#else
+		uint64_t port_bit:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} cn38xx;
 	struct cvmx_ipd_sub_port_fcs_cn38xx cn38xxp2;
 	struct cvmx_ipd_sub_port_fcs_cn30xx cn50xx;
@@ -896,30 +1915,49 @@
 	struct cvmx_ipd_sub_port_fcs_s cn56xxp1;
 	struct cvmx_ipd_sub_port_fcs_cn38xx cn58xx;
 	struct cvmx_ipd_sub_port_fcs_cn38xx cn58xxp1;
+	struct cvmx_ipd_sub_port_fcs_s cn61xx;
 	struct cvmx_ipd_sub_port_fcs_s cn63xx;
 	struct cvmx_ipd_sub_port_fcs_s cn63xxp1;
+	struct cvmx_ipd_sub_port_fcs_s cn66xx;
+	struct cvmx_ipd_sub_port_fcs_s cnf71xx;
 };
 
 union cvmx_ipd_sub_port_qos_cnt {
 	uint64_t u64;
 	struct cvmx_ipd_sub_port_qos_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_41_63:23;
 		uint64_t port_qos:9;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t port_qos:9;
+		uint64_t reserved_41_63:23;
+#endif
 	} s;
 	struct cvmx_ipd_sub_port_qos_cnt_s cn52xx;
 	struct cvmx_ipd_sub_port_qos_cnt_s cn52xxp1;
 	struct cvmx_ipd_sub_port_qos_cnt_s cn56xx;
 	struct cvmx_ipd_sub_port_qos_cnt_s cn56xxp1;
+	struct cvmx_ipd_sub_port_qos_cnt_s cn61xx;
 	struct cvmx_ipd_sub_port_qos_cnt_s cn63xx;
 	struct cvmx_ipd_sub_port_qos_cnt_s cn63xxp1;
+	struct cvmx_ipd_sub_port_qos_cnt_s cn66xx;
+	struct cvmx_ipd_sub_port_qos_cnt_s cn68xx;
+	struct cvmx_ipd_sub_port_qos_cnt_s cn68xxp1;
+	struct cvmx_ipd_sub_port_qos_cnt_s cnf71xx;
 };
 
 union cvmx_ipd_wqe_fpa_queue {
 	uint64_t u64;
 	struct cvmx_ipd_wqe_fpa_queue_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_3_63:61;
 		uint64_t wqe_pool:3;
+#else
+		uint64_t wqe_pool:3;
+		uint64_t reserved_3_63:61;
+#endif
 	} s;
 	struct cvmx_ipd_wqe_fpa_queue_s cn30xx;
 	struct cvmx_ipd_wqe_fpa_queue_s cn31xx;
@@ -932,15 +1970,25 @@
 	struct cvmx_ipd_wqe_fpa_queue_s cn56xxp1;
 	struct cvmx_ipd_wqe_fpa_queue_s cn58xx;
 	struct cvmx_ipd_wqe_fpa_queue_s cn58xxp1;
+	struct cvmx_ipd_wqe_fpa_queue_s cn61xx;
 	struct cvmx_ipd_wqe_fpa_queue_s cn63xx;
 	struct cvmx_ipd_wqe_fpa_queue_s cn63xxp1;
+	struct cvmx_ipd_wqe_fpa_queue_s cn66xx;
+	struct cvmx_ipd_wqe_fpa_queue_s cn68xx;
+	struct cvmx_ipd_wqe_fpa_queue_s cn68xxp1;
+	struct cvmx_ipd_wqe_fpa_queue_s cnf71xx;
 };
 
 union cvmx_ipd_wqe_ptr_valid {
 	uint64_t u64;
 	struct cvmx_ipd_wqe_ptr_valid_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_29_63:35;
 		uint64_t ptr:29;
+#else
+		uint64_t ptr:29;
+		uint64_t reserved_29_63:35;
+#endif
 	} s;
 	struct cvmx_ipd_wqe_ptr_valid_s cn30xx;
 	struct cvmx_ipd_wqe_ptr_valid_s cn31xx;
@@ -952,8 +2000,11 @@
 	struct cvmx_ipd_wqe_ptr_valid_s cn56xxp1;
 	struct cvmx_ipd_wqe_ptr_valid_s cn58xx;
 	struct cvmx_ipd_wqe_ptr_valid_s cn58xxp1;
+	struct cvmx_ipd_wqe_ptr_valid_s cn61xx;
 	struct cvmx_ipd_wqe_ptr_valid_s cn63xx;
 	struct cvmx_ipd_wqe_ptr_valid_s cn63xxp1;
+	struct cvmx_ipd_wqe_ptr_valid_s cn66xx;
+	struct cvmx_ipd_wqe_ptr_valid_s cnf71xx;
 };
 
 #endif
diff --git a/arch/mips/include/asm/octeon/cvmx-l2c-defs.h b/arch/mips/include/asm/octeon/cvmx-l2c-defs.h
index 7a50a0b..10262cb 100644
--- a/arch/mips/include/asm/octeon/cvmx-l2c-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-l2c-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -33,18 +33,18 @@
 #define CVMX_L2C_BST0 (CVMX_ADD_IO_SEG(0x00011800800007F8ull))
 #define CVMX_L2C_BST1 (CVMX_ADD_IO_SEG(0x00011800800007F0ull))
 #define CVMX_L2C_BST2 (CVMX_ADD_IO_SEG(0x00011800800007E8ull))
-#define CVMX_L2C_BST_MEMX(block_id) (CVMX_ADD_IO_SEG(0x0001180080C007F8ull))
-#define CVMX_L2C_BST_TDTX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007F0ull))
-#define CVMX_L2C_BST_TTGX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007F8ull))
+#define CVMX_L2C_BST_MEMX(block_id) (CVMX_ADD_IO_SEG(0x0001180080C007F8ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_BST_TDTX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007F0ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_BST_TTGX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007F8ull) + ((block_id) & 3) * 0x40000ull)
 #define CVMX_L2C_CFG (CVMX_ADD_IO_SEG(0x0001180080000000ull))
 #define CVMX_L2C_COP0_MAPX(offset) (CVMX_ADD_IO_SEG(0x0001180080940000ull) + ((offset) & 16383) * 8)
 #define CVMX_L2C_CTL (CVMX_ADD_IO_SEG(0x0001180080800000ull))
 #define CVMX_L2C_DBG (CVMX_ADD_IO_SEG(0x0001180080000030ull))
 #define CVMX_L2C_DUT (CVMX_ADD_IO_SEG(0x0001180080000050ull))
-#define CVMX_L2C_DUT_MAPX(offset) (CVMX_ADD_IO_SEG(0x0001180080E00000ull) + ((offset) & 2047) * 8)
-#define CVMX_L2C_ERR_TDTX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007E0ull))
-#define CVMX_L2C_ERR_TTGX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007E8ull))
-#define CVMX_L2C_ERR_VBFX(block_id) (CVMX_ADD_IO_SEG(0x0001180080C007F0ull))
+#define CVMX_L2C_DUT_MAPX(offset) (CVMX_ADD_IO_SEG(0x0001180080E00000ull) + ((offset) & 8191) * 8)
+#define CVMX_L2C_ERR_TDTX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007E0ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_ERR_TTGX(block_id) (CVMX_ADD_IO_SEG(0x0001180080A007E8ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_ERR_VBFX(block_id) (CVMX_ADD_IO_SEG(0x0001180080C007F0ull) + ((block_id) & 3) * 0x40000ull)
 #define CVMX_L2C_ERR_XMC (CVMX_ADD_IO_SEG(0x00011800808007D8ull))
 #define CVMX_L2C_GRPWRR0 (CVMX_ADD_IO_SEG(0x00011800800000C8ull))
 #define CVMX_L2C_GRPWRR1 (CVMX_ADD_IO_SEG(0x00011800800000D0ull))
@@ -71,54 +71,119 @@
 #define CVMX_L2C_PFCTL (CVMX_ADD_IO_SEG(0x0001180080000090ull))
 #define CVMX_L2C_PFCX(offset) (CVMX_ADD_IO_SEG(0x0001180080000098ull) + ((offset) & 3) * 8)
 #define CVMX_L2C_PPGRP (CVMX_ADD_IO_SEG(0x00011800800000C0ull))
-#define CVMX_L2C_QOS_IOBX(block_id) (CVMX_ADD_IO_SEG(0x0001180080880200ull))
-#define CVMX_L2C_QOS_PPX(offset) (CVMX_ADD_IO_SEG(0x0001180080880000ull) + ((offset) & 7) * 8)
+#define CVMX_L2C_QOS_IOBX(offset) (CVMX_ADD_IO_SEG(0x0001180080880200ull) + ((offset) & 1) * 8)
+#define CVMX_L2C_QOS_PPX(offset) (CVMX_ADD_IO_SEG(0x0001180080880000ull) + ((offset) & 31) * 8)
 #define CVMX_L2C_QOS_WGT (CVMX_ADD_IO_SEG(0x0001180080800008ull))
-#define CVMX_L2C_RSCX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800410ull))
-#define CVMX_L2C_RSDX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800418ull))
+#define CVMX_L2C_RSCX_PFC(offset) (CVMX_ADD_IO_SEG(0x0001180080800410ull) + ((offset) & 3) * 64)
+#define CVMX_L2C_RSDX_PFC(offset) (CVMX_ADD_IO_SEG(0x0001180080800418ull) + ((offset) & 3) * 64)
 #define CVMX_L2C_SPAR0 (CVMX_ADD_IO_SEG(0x0001180080000068ull))
 #define CVMX_L2C_SPAR1 (CVMX_ADD_IO_SEG(0x0001180080000070ull))
 #define CVMX_L2C_SPAR2 (CVMX_ADD_IO_SEG(0x0001180080000078ull))
 #define CVMX_L2C_SPAR3 (CVMX_ADD_IO_SEG(0x0001180080000080ull))
 #define CVMX_L2C_SPAR4 (CVMX_ADD_IO_SEG(0x0001180080000088ull))
-#define CVMX_L2C_TADX_ECC0(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00018ull))
-#define CVMX_L2C_TADX_ECC1(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00020ull))
-#define CVMX_L2C_TADX_IEN(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00000ull))
-#define CVMX_L2C_TADX_INT(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00028ull))
-#define CVMX_L2C_TADX_PFC0(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00400ull))
-#define CVMX_L2C_TADX_PFC1(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00408ull))
-#define CVMX_L2C_TADX_PFC2(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00410ull))
-#define CVMX_L2C_TADX_PFC3(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00418ull))
-#define CVMX_L2C_TADX_PRF(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00008ull))
-#define CVMX_L2C_TADX_TAG(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00010ull))
+#define CVMX_L2C_TADX_ECC0(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00018ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_TADX_ECC1(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00020ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_TADX_IEN(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00000ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_TADX_INT(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00028ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_TADX_PFC0(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00400ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_TADX_PFC1(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00408ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_TADX_PFC2(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00410ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_TADX_PFC3(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00418ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_TADX_PRF(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00008ull) + ((block_id) & 3) * 0x40000ull)
+#define CVMX_L2C_TADX_TAG(block_id) (CVMX_ADD_IO_SEG(0x0001180080A00010ull) + ((block_id) & 3) * 0x40000ull)
 #define CVMX_L2C_VER_ID (CVMX_ADD_IO_SEG(0x00011800808007E0ull))
 #define CVMX_L2C_VER_IOB (CVMX_ADD_IO_SEG(0x00011800808007F0ull))
 #define CVMX_L2C_VER_MSC (CVMX_ADD_IO_SEG(0x00011800808007D0ull))
 #define CVMX_L2C_VER_PP (CVMX_ADD_IO_SEG(0x00011800808007E8ull))
-#define CVMX_L2C_VIRTID_IOBX(block_id) (CVMX_ADD_IO_SEG(0x00011800808C0200ull))
-#define CVMX_L2C_VIRTID_PPX(offset) (CVMX_ADD_IO_SEG(0x00011800808C0000ull) + ((offset) & 7) * 8)
+#define CVMX_L2C_VIRTID_IOBX(offset) (CVMX_ADD_IO_SEG(0x00011800808C0200ull) + ((offset) & 1) * 8)
+#define CVMX_L2C_VIRTID_PPX(offset) (CVMX_ADD_IO_SEG(0x00011800808C0000ull) + ((offset) & 31) * 8)
 #define CVMX_L2C_VRT_CTL (CVMX_ADD_IO_SEG(0x0001180080800010ull))
 #define CVMX_L2C_VRT_MEMX(offset) (CVMX_ADD_IO_SEG(0x0001180080900000ull) + ((offset) & 1023) * 8)
-#define CVMX_L2C_WPAR_IOBX(block_id) (CVMX_ADD_IO_SEG(0x0001180080840200ull))
-#define CVMX_L2C_WPAR_PPX(offset) (CVMX_ADD_IO_SEG(0x0001180080840000ull) + ((offset) & 7) * 8)
-#define CVMX_L2C_XMCX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800400ull))
+#define CVMX_L2C_WPAR_IOBX(offset) (CVMX_ADD_IO_SEG(0x0001180080840200ull) + ((offset) & 1) * 8)
+#define CVMX_L2C_WPAR_PPX(offset) (CVMX_ADD_IO_SEG(0x0001180080840000ull) + ((offset) & 31) * 8)
+#define CVMX_L2C_XMCX_PFC(offset) (CVMX_ADD_IO_SEG(0x0001180080800400ull) + ((offset) & 3) * 64)
 #define CVMX_L2C_XMC_CMD (CVMX_ADD_IO_SEG(0x0001180080800028ull))
-#define CVMX_L2C_XMDX_PFC(block_id) (CVMX_ADD_IO_SEG(0x0001180080800408ull))
+#define CVMX_L2C_XMDX_PFC(offset) (CVMX_ADD_IO_SEG(0x0001180080800408ull) + ((offset) & 3) * 64)
 
 union cvmx_l2c_big_ctl {
 	uint64_t u64;
 	struct cvmx_l2c_big_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t maxdram:4;
 		uint64_t reserved_1_3:3;
 		uint64_t disable:1;
+#else
+		uint64_t disable:1;
+		uint64_t reserved_1_3:3;
+		uint64_t maxdram:4;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
+	struct cvmx_l2c_big_ctl_s cn61xx;
 	struct cvmx_l2c_big_ctl_s cn63xx;
+	struct cvmx_l2c_big_ctl_s cn66xx;
+	struct cvmx_l2c_big_ctl_s cn68xx;
+	struct cvmx_l2c_big_ctl_s cn68xxp1;
+	struct cvmx_l2c_big_ctl_s cnf71xx;
 };
 
 union cvmx_l2c_bst {
 	uint64_t u64;
 	struct cvmx_l2c_bst_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t dutfl:32;
+		uint64_t rbffl:4;
+		uint64_t xbffl:4;
+		uint64_t tdpfl:4;
+		uint64_t ioccmdfl:4;
+		uint64_t iocdatfl:4;
+		uint64_t dutresfl:4;
+		uint64_t vrtfl:4;
+		uint64_t tdffl:4;
+#else
+		uint64_t tdffl:4;
+		uint64_t vrtfl:4;
+		uint64_t dutresfl:4;
+		uint64_t iocdatfl:4;
+		uint64_t ioccmdfl:4;
+		uint64_t tdpfl:4;
+		uint64_t xbffl:4;
+		uint64_t rbffl:4;
+		uint64_t dutfl:32;
+#endif
+	} s;
+	struct cvmx_l2c_bst_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_36_63:28;
+		uint64_t dutfl:4;
+		uint64_t reserved_17_31:15;
+		uint64_t ioccmdfl:1;
+		uint64_t reserved_13_15:3;
+		uint64_t iocdatfl:1;
+		uint64_t reserved_9_11:3;
+		uint64_t dutresfl:1;
+		uint64_t reserved_5_7:3;
+		uint64_t vrtfl:1;
+		uint64_t reserved_1_3:3;
+		uint64_t tdffl:1;
+#else
+		uint64_t tdffl:1;
+		uint64_t reserved_1_3:3;
+		uint64_t vrtfl:1;
+		uint64_t reserved_5_7:3;
+		uint64_t dutresfl:1;
+		uint64_t reserved_9_11:3;
+		uint64_t iocdatfl:1;
+		uint64_t reserved_13_15:3;
+		uint64_t ioccmdfl:1;
+		uint64_t reserved_17_31:15;
+		uint64_t dutfl:4;
+		uint64_t reserved_36_63:28;
+#endif
+	} cn61xx;
+	struct cvmx_l2c_bst_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_38_63:26;
 		uint64_t dutfl:6;
 		uint64_t reserved_17_31:15;
@@ -131,14 +196,60 @@
 		uint64_t vrtfl:1;
 		uint64_t reserved_1_3:3;
 		uint64_t tdffl:1;
-	} s;
-	struct cvmx_l2c_bst_s cn63xx;
-	struct cvmx_l2c_bst_s cn63xxp1;
+#else
+		uint64_t tdffl:1;
+		uint64_t reserved_1_3:3;
+		uint64_t vrtfl:1;
+		uint64_t reserved_5_7:3;
+		uint64_t dutresfl:1;
+		uint64_t reserved_9_11:3;
+		uint64_t iocdatfl:1;
+		uint64_t reserved_13_15:3;
+		uint64_t ioccmdfl:1;
+		uint64_t reserved_17_31:15;
+		uint64_t dutfl:6;
+		uint64_t reserved_38_63:26;
+#endif
+	} cn63xx;
+	struct cvmx_l2c_bst_cn63xx cn63xxp1;
+	struct cvmx_l2c_bst_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_42_63:22;
+		uint64_t dutfl:10;
+		uint64_t reserved_17_31:15;
+		uint64_t ioccmdfl:1;
+		uint64_t reserved_13_15:3;
+		uint64_t iocdatfl:1;
+		uint64_t reserved_9_11:3;
+		uint64_t dutresfl:1;
+		uint64_t reserved_5_7:3;
+		uint64_t vrtfl:1;
+		uint64_t reserved_1_3:3;
+		uint64_t tdffl:1;
+#else
+		uint64_t tdffl:1;
+		uint64_t reserved_1_3:3;
+		uint64_t vrtfl:1;
+		uint64_t reserved_5_7:3;
+		uint64_t dutresfl:1;
+		uint64_t reserved_9_11:3;
+		uint64_t iocdatfl:1;
+		uint64_t reserved_13_15:3;
+		uint64_t ioccmdfl:1;
+		uint64_t reserved_17_31:15;
+		uint64_t dutfl:10;
+		uint64_t reserved_42_63:22;
+#endif
+	} cn66xx;
+	struct cvmx_l2c_bst_s cn68xx;
+	struct cvmx_l2c_bst_s cn68xxp1;
+	struct cvmx_l2c_bst_cn61xx cnf71xx;
 };
 
 union cvmx_l2c_bst0 {
 	uint64_t u64;
 	struct cvmx_l2c_bst0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_24_63:40;
 		uint64_t dtbnk:1;
 		uint64_t wlb_msk:4;
@@ -146,8 +257,18 @@
 		uint64_t dt:1;
 		uint64_t stin_msk:1;
 		uint64_t wlb_dat:4;
+#else
+		uint64_t wlb_dat:4;
+		uint64_t stin_msk:1;
+		uint64_t dt:1;
+		uint64_t dtcnt:13;
+		uint64_t wlb_msk:4;
+		uint64_t dtbnk:1;
+		uint64_t reserved_24_63:40;
+#endif
 	} s;
 	struct cvmx_l2c_bst0_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_23_63:41;
 		uint64_t wlb_msk:4;
 		uint64_t reserved_15_18:4;
@@ -155,8 +276,18 @@
 		uint64_t dt:1;
 		uint64_t reserved_4_4:1;
 		uint64_t wlb_dat:4;
+#else
+		uint64_t wlb_dat:4;
+		uint64_t reserved_4_4:1;
+		uint64_t dt:1;
+		uint64_t dtcnt:9;
+		uint64_t reserved_15_18:4;
+		uint64_t wlb_msk:4;
+		uint64_t reserved_23_63:41;
+#endif
 	} cn30xx;
 	struct cvmx_l2c_bst0_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_23_63:41;
 		uint64_t wlb_msk:4;
 		uint64_t reserved_16_18:3;
@@ -164,16 +295,34 @@
 		uint64_t dt:1;
 		uint64_t stin_msk:1;
 		uint64_t wlb_dat:4;
+#else
+		uint64_t wlb_dat:4;
+		uint64_t stin_msk:1;
+		uint64_t dt:1;
+		uint64_t dtcnt:10;
+		uint64_t reserved_16_18:3;
+		uint64_t wlb_msk:4;
+		uint64_t reserved_23_63:41;
+#endif
 	} cn31xx;
 	struct cvmx_l2c_bst0_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_19_63:45;
 		uint64_t dtcnt:13;
 		uint64_t dt:1;
 		uint64_t stin_msk:1;
 		uint64_t wlb_dat:4;
+#else
+		uint64_t wlb_dat:4;
+		uint64_t stin_msk:1;
+		uint64_t dt:1;
+		uint64_t dtcnt:13;
+		uint64_t reserved_19_63:45;
+#endif
 	} cn38xx;
 	struct cvmx_l2c_bst0_cn38xx cn38xxp2;
 	struct cvmx_l2c_bst0_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_24_63:40;
 		uint64_t dtbnk:1;
 		uint64_t wlb_msk:4;
@@ -182,6 +331,16 @@
 		uint64_t dt:1;
 		uint64_t stin_msk:1;
 		uint64_t wlb_dat:4;
+#else
+		uint64_t wlb_dat:4;
+		uint64_t stin_msk:1;
+		uint64_t dt:1;
+		uint64_t dtcnt:10;
+		uint64_t reserved_16_18:3;
+		uint64_t wlb_msk:4;
+		uint64_t dtbnk:1;
+		uint64_t reserved_24_63:40;
+#endif
 	} cn50xx;
 	struct cvmx_l2c_bst0_cn50xx cn52xx;
 	struct cvmx_l2c_bst0_cn50xx cn52xxp1;
@@ -194,28 +353,51 @@
 union cvmx_l2c_bst1 {
 	uint64_t u64;
 	struct cvmx_l2c_bst1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t l2t:9;
+#else
+		uint64_t l2t:9;
+		uint64_t reserved_9_63:55;
+#endif
 	} s;
 	struct cvmx_l2c_bst1_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t vwdf:4;
 		uint64_t lrf:2;
 		uint64_t vab_vwcf:1;
 		uint64_t reserved_5_8:4;
 		uint64_t l2t:5;
+#else
+		uint64_t l2t:5;
+		uint64_t reserved_5_8:4;
+		uint64_t vab_vwcf:1;
+		uint64_t lrf:2;
+		uint64_t vwdf:4;
+		uint64_t reserved_16_63:48;
+#endif
 	} cn30xx;
 	struct cvmx_l2c_bst1_cn30xx cn31xx;
 	struct cvmx_l2c_bst1_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t vwdf:4;
 		uint64_t lrf:2;
 		uint64_t vab_vwcf:1;
 		uint64_t l2t:9;
+#else
+		uint64_t l2t:9;
+		uint64_t vab_vwcf:1;
+		uint64_t lrf:2;
+		uint64_t vwdf:4;
+		uint64_t reserved_16_63:48;
+#endif
 	} cn38xx;
 	struct cvmx_l2c_bst1_cn38xx cn38xxp2;
 	struct cvmx_l2c_bst1_cn38xx cn50xx;
 	struct cvmx_l2c_bst1_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_19_63:45;
 		uint64_t plc2:1;
 		uint64_t plc1:1;
@@ -225,9 +407,21 @@
 		uint64_t ilc:1;
 		uint64_t vab_vwcf:1;
 		uint64_t l2t:9;
+#else
+		uint64_t l2t:9;
+		uint64_t vab_vwcf:1;
+		uint64_t ilc:1;
+		uint64_t reserved_11_11:1;
+		uint64_t vwdf:4;
+		uint64_t plc0:1;
+		uint64_t plc1:1;
+		uint64_t plc2:1;
+		uint64_t reserved_19_63:45;
+#endif
 	} cn52xx;
 	struct cvmx_l2c_bst1_cn52xx cn52xxp1;
 	struct cvmx_l2c_bst1_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_24_63:40;
 		uint64_t plc2:1;
 		uint64_t plc1:1;
@@ -239,6 +433,19 @@
 		uint64_t reserved_10_10:1;
 		uint64_t vab_vwcf0:1;
 		uint64_t l2t:9;
+#else
+		uint64_t l2t:9;
+		uint64_t vab_vwcf0:1;
+		uint64_t reserved_10_10:1;
+		uint64_t vab_vwcf1:1;
+		uint64_t vwdf0:4;
+		uint64_t vwdf1:4;
+		uint64_t ilc:1;
+		uint64_t plc0:1;
+		uint64_t plc1:1;
+		uint64_t plc2:1;
+		uint64_t reserved_24_63:40;
+#endif
 	} cn56xx;
 	struct cvmx_l2c_bst1_cn56xx cn56xxp1;
 	struct cvmx_l2c_bst1_cn38xx cn58xx;
@@ -248,6 +455,7 @@
 union cvmx_l2c_bst2 {
 	uint64_t u64;
 	struct cvmx_l2c_bst2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t mrb:4;
 		uint64_t reserved_4_11:8;
@@ -255,8 +463,18 @@
 		uint64_t picbst:1;
 		uint64_t xrdmsk:1;
 		uint64_t xrddat:1;
+#else
+		uint64_t xrddat:1;
+		uint64_t xrdmsk:1;
+		uint64_t picbst:1;
+		uint64_t ipcbst:1;
+		uint64_t reserved_4_11:8;
+		uint64_t mrb:4;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_l2c_bst2_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t mrb:4;
 		uint64_t rmdf:4;
@@ -265,9 +483,20 @@
 		uint64_t reserved_2_2:1;
 		uint64_t xrdmsk:1;
 		uint64_t xrddat:1;
+#else
+		uint64_t xrddat:1;
+		uint64_t xrdmsk:1;
+		uint64_t reserved_2_2:1;
+		uint64_t ipcbst:1;
+		uint64_t reserved_4_7:4;
+		uint64_t rmdf:4;
+		uint64_t mrb:4;
+		uint64_t reserved_16_63:48;
+#endif
 	} cn30xx;
 	struct cvmx_l2c_bst2_cn30xx cn31xx;
 	struct cvmx_l2c_bst2_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t mrb:4;
 		uint64_t rmdf:4;
@@ -276,12 +505,23 @@
 		uint64_t picbst:1;
 		uint64_t xrdmsk:1;
 		uint64_t xrddat:1;
+#else
+		uint64_t xrddat:1;
+		uint64_t xrdmsk:1;
+		uint64_t picbst:1;
+		uint64_t ipcbst:1;
+		uint64_t rhdf:4;
+		uint64_t rmdf:4;
+		uint64_t mrb:4;
+		uint64_t reserved_16_63:48;
+#endif
 	} cn38xx;
 	struct cvmx_l2c_bst2_cn38xx cn38xxp2;
 	struct cvmx_l2c_bst2_cn30xx cn50xx;
 	struct cvmx_l2c_bst2_cn30xx cn52xx;
 	struct cvmx_l2c_bst2_cn30xx cn52xxp1;
 	struct cvmx_l2c_bst2_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t mrb:4;
 		uint64_t rmdb:4;
@@ -290,6 +530,16 @@
 		uint64_t picbst:1;
 		uint64_t xrdmsk:1;
 		uint64_t xrddat:1;
+#else
+		uint64_t xrddat:1;
+		uint64_t xrdmsk:1;
+		uint64_t picbst:1;
+		uint64_t ipcbst:1;
+		uint64_t rhdb:4;
+		uint64_t rmdb:4;
+		uint64_t mrb:4;
+		uint64_t reserved_16_63:48;
+#endif
 	} cn56xx;
 	struct cvmx_l2c_bst2_cn56xx cn56xxp1;
 	struct cvmx_l2c_bst2_cn56xx cn58xx;
@@ -299,48 +549,93 @@
 union cvmx_l2c_bst_memx {
 	uint64_t u64;
 	struct cvmx_l2c_bst_memx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t start_bist:1;
 		uint64_t clear_bist:1;
 		uint64_t reserved_5_61:57;
 		uint64_t rdffl:1;
 		uint64_t vbffl:4;
+#else
+		uint64_t vbffl:4;
+		uint64_t rdffl:1;
+		uint64_t reserved_5_61:57;
+		uint64_t clear_bist:1;
+		uint64_t start_bist:1;
+#endif
 	} s;
+	struct cvmx_l2c_bst_memx_s cn61xx;
 	struct cvmx_l2c_bst_memx_s cn63xx;
 	struct cvmx_l2c_bst_memx_s cn63xxp1;
+	struct cvmx_l2c_bst_memx_s cn66xx;
+	struct cvmx_l2c_bst_memx_s cn68xx;
+	struct cvmx_l2c_bst_memx_s cn68xxp1;
+	struct cvmx_l2c_bst_memx_s cnf71xx;
 };
 
 union cvmx_l2c_bst_tdtx {
 	uint64_t u64;
 	struct cvmx_l2c_bst_tdtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t fbfrspfl:8;
 		uint64_t sbffl:8;
 		uint64_t fbffl:8;
 		uint64_t l2dfl:8;
+#else
+		uint64_t l2dfl:8;
+		uint64_t fbffl:8;
+		uint64_t sbffl:8;
+		uint64_t fbfrspfl:8;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
+	struct cvmx_l2c_bst_tdtx_s cn61xx;
 	struct cvmx_l2c_bst_tdtx_s cn63xx;
 	struct cvmx_l2c_bst_tdtx_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_24_63:40;
 		uint64_t sbffl:8;
 		uint64_t fbffl:8;
 		uint64_t l2dfl:8;
+#else
+		uint64_t l2dfl:8;
+		uint64_t fbffl:8;
+		uint64_t sbffl:8;
+		uint64_t reserved_24_63:40;
+#endif
 	} cn63xxp1;
+	struct cvmx_l2c_bst_tdtx_s cn66xx;
+	struct cvmx_l2c_bst_tdtx_s cn68xx;
+	struct cvmx_l2c_bst_tdtx_s cn68xxp1;
+	struct cvmx_l2c_bst_tdtx_s cnf71xx;
 };
 
 union cvmx_l2c_bst_ttgx {
 	uint64_t u64;
 	struct cvmx_l2c_bst_ttgx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_17_63:47;
 		uint64_t lrufl:1;
 		uint64_t tagfl:16;
+#else
+		uint64_t tagfl:16;
+		uint64_t lrufl:1;
+		uint64_t reserved_17_63:47;
+#endif
 	} s;
+	struct cvmx_l2c_bst_ttgx_s cn61xx;
 	struct cvmx_l2c_bst_ttgx_s cn63xx;
 	struct cvmx_l2c_bst_ttgx_s cn63xxp1;
+	struct cvmx_l2c_bst_ttgx_s cn66xx;
+	struct cvmx_l2c_bst_ttgx_s cn68xx;
+	struct cvmx_l2c_bst_ttgx_s cn68xxp1;
+	struct cvmx_l2c_bst_ttgx_s cnf71xx;
 };
 
 union cvmx_l2c_cfg {
 	uint64_t u64;
 	struct cvmx_l2c_cfg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t bstrun:1;
 		uint64_t lbist:1;
@@ -356,8 +651,26 @@
 		uint64_t rsp_arb_mode:1;
 		uint64_t rfb_arb_mode:1;
 		uint64_t lrf_arb_mode:1;
+#else
+		uint64_t lrf_arb_mode:1;
+		uint64_t rfb_arb_mode:1;
+		uint64_t rsp_arb_mode:1;
+		uint64_t mwf_crd:4;
+		uint64_t idxalias:1;
+		uint64_t fpen:1;
+		uint64_t fpempty:1;
+		uint64_t fpexp:4;
+		uint64_t dfill_dis:1;
+		uint64_t dpres0:1;
+		uint64_t dpres1:1;
+		uint64_t xor_bank:1;
+		uint64_t lbist:1;
+		uint64_t bstrun:1;
+		uint64_t reserved_20_63:44;
+#endif
 	} s;
 	struct cvmx_l2c_cfg_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_14_63:50;
 		uint64_t fpexp:4;
 		uint64_t fpempty:1;
@@ -367,11 +680,23 @@
 		uint64_t rsp_arb_mode:1;
 		uint64_t rfb_arb_mode:1;
 		uint64_t lrf_arb_mode:1;
+#else
+		uint64_t lrf_arb_mode:1;
+		uint64_t rfb_arb_mode:1;
+		uint64_t rsp_arb_mode:1;
+		uint64_t mwf_crd:4;
+		uint64_t idxalias:1;
+		uint64_t fpen:1;
+		uint64_t fpempty:1;
+		uint64_t fpexp:4;
+		uint64_t reserved_14_63:50;
+#endif
 	} cn30xx;
 	struct cvmx_l2c_cfg_cn30xx cn31xx;
 	struct cvmx_l2c_cfg_cn30xx cn38xx;
 	struct cvmx_l2c_cfg_cn30xx cn38xxp2;
 	struct cvmx_l2c_cfg_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t bstrun:1;
 		uint64_t lbist:1;
@@ -384,12 +709,27 @@
 		uint64_t rsp_arb_mode:1;
 		uint64_t rfb_arb_mode:1;
 		uint64_t lrf_arb_mode:1;
+#else
+		uint64_t lrf_arb_mode:1;
+		uint64_t rfb_arb_mode:1;
+		uint64_t rsp_arb_mode:1;
+		uint64_t mwf_crd:4;
+		uint64_t idxalias:1;
+		uint64_t fpen:1;
+		uint64_t fpempty:1;
+		uint64_t fpexp:4;
+		uint64_t reserved_14_17:4;
+		uint64_t lbist:1;
+		uint64_t bstrun:1;
+		uint64_t reserved_20_63:44;
+#endif
 	} cn50xx;
 	struct cvmx_l2c_cfg_cn50xx cn52xx;
 	struct cvmx_l2c_cfg_cn50xx cn52xxp1;
 	struct cvmx_l2c_cfg_s cn56xx;
 	struct cvmx_l2c_cfg_s cn56xxp1;
 	struct cvmx_l2c_cfg_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t bstrun:1;
 		uint64_t lbist:1;
@@ -403,8 +743,24 @@
 		uint64_t rsp_arb_mode:1;
 		uint64_t rfb_arb_mode:1;
 		uint64_t lrf_arb_mode:1;
+#else
+		uint64_t lrf_arb_mode:1;
+		uint64_t rfb_arb_mode:1;
+		uint64_t rsp_arb_mode:1;
+		uint64_t mwf_crd:4;
+		uint64_t idxalias:1;
+		uint64_t fpen:1;
+		uint64_t fpempty:1;
+		uint64_t fpexp:4;
+		uint64_t dfill_dis:1;
+		uint64_t reserved_15_17:3;
+		uint64_t lbist:1;
+		uint64_t bstrun:1;
+		uint64_t reserved_20_63:44;
+#endif
 	} cn58xx;
 	struct cvmx_l2c_cfg_cn58xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_15_63:49;
 		uint64_t dfill_dis:1;
 		uint64_t fpexp:4;
@@ -415,21 +771,115 @@
 		uint64_t rsp_arb_mode:1;
 		uint64_t rfb_arb_mode:1;
 		uint64_t lrf_arb_mode:1;
+#else
+		uint64_t lrf_arb_mode:1;
+		uint64_t rfb_arb_mode:1;
+		uint64_t rsp_arb_mode:1;
+		uint64_t mwf_crd:4;
+		uint64_t idxalias:1;
+		uint64_t fpen:1;
+		uint64_t fpempty:1;
+		uint64_t fpexp:4;
+		uint64_t dfill_dis:1;
+		uint64_t reserved_15_63:49;
+#endif
 	} cn58xxp1;
 };
 
 union cvmx_l2c_cop0_mapx {
 	uint64_t u64;
 	struct cvmx_l2c_cop0_mapx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t data:64;
+#else
+		uint64_t data:64;
+#endif
 	} s;
+	struct cvmx_l2c_cop0_mapx_s cn61xx;
 	struct cvmx_l2c_cop0_mapx_s cn63xx;
 	struct cvmx_l2c_cop0_mapx_s cn63xxp1;
+	struct cvmx_l2c_cop0_mapx_s cn66xx;
+	struct cvmx_l2c_cop0_mapx_s cn68xx;
+	struct cvmx_l2c_cop0_mapx_s cn68xxp1;
+	struct cvmx_l2c_cop0_mapx_s cnf71xx;
 };
 
 union cvmx_l2c_ctl {
 	uint64_t u64;
 	struct cvmx_l2c_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_30_63:34;
+		uint64_t sepcmt:1;
+		uint64_t rdf_fast:1;
+		uint64_t disstgl2i:1;
+		uint64_t l2dfsbe:1;
+		uint64_t l2dfdbe:1;
+		uint64_t discclk:1;
+		uint64_t maxvab:4;
+		uint64_t maxlfb:4;
+		uint64_t rsp_arb_mode:1;
+		uint64_t xmc_arb_mode:1;
+		uint64_t ef_ena:1;
+		uint64_t ef_cnt:7;
+		uint64_t vab_thresh:4;
+		uint64_t disecc:1;
+		uint64_t disidxalias:1;
+#else
+		uint64_t disidxalias:1;
+		uint64_t disecc:1;
+		uint64_t vab_thresh:4;
+		uint64_t ef_cnt:7;
+		uint64_t ef_ena:1;
+		uint64_t xmc_arb_mode:1;
+		uint64_t rsp_arb_mode:1;
+		uint64_t maxlfb:4;
+		uint64_t maxvab:4;
+		uint64_t discclk:1;
+		uint64_t l2dfdbe:1;
+		uint64_t l2dfsbe:1;
+		uint64_t disstgl2i:1;
+		uint64_t rdf_fast:1;
+		uint64_t sepcmt:1;
+		uint64_t reserved_30_63:34;
+#endif
+	} s;
+	struct cvmx_l2c_ctl_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_29_63:35;
+		uint64_t rdf_fast:1;
+		uint64_t disstgl2i:1;
+		uint64_t l2dfsbe:1;
+		uint64_t l2dfdbe:1;
+		uint64_t discclk:1;
+		uint64_t maxvab:4;
+		uint64_t maxlfb:4;
+		uint64_t rsp_arb_mode:1;
+		uint64_t xmc_arb_mode:1;
+		uint64_t ef_ena:1;
+		uint64_t ef_cnt:7;
+		uint64_t vab_thresh:4;
+		uint64_t disecc:1;
+		uint64_t disidxalias:1;
+#else
+		uint64_t disidxalias:1;
+		uint64_t disecc:1;
+		uint64_t vab_thresh:4;
+		uint64_t ef_cnt:7;
+		uint64_t ef_ena:1;
+		uint64_t xmc_arb_mode:1;
+		uint64_t rsp_arb_mode:1;
+		uint64_t maxlfb:4;
+		uint64_t maxvab:4;
+		uint64_t discclk:1;
+		uint64_t l2dfdbe:1;
+		uint64_t l2dfsbe:1;
+		uint64_t disstgl2i:1;
+		uint64_t rdf_fast:1;
+		uint64_t reserved_29_63:35;
+#endif
+	} cn61xx;
+	struct cvmx_l2c_ctl_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_28_63:36;
 		uint64_t disstgl2i:1;
 		uint64_t l2dfsbe:1;
@@ -444,9 +894,25 @@
 		uint64_t vab_thresh:4;
 		uint64_t disecc:1;
 		uint64_t disidxalias:1;
-	} s;
-	struct cvmx_l2c_ctl_s cn63xx;
+#else
+		uint64_t disidxalias:1;
+		uint64_t disecc:1;
+		uint64_t vab_thresh:4;
+		uint64_t ef_cnt:7;
+		uint64_t ef_ena:1;
+		uint64_t xmc_arb_mode:1;
+		uint64_t rsp_arb_mode:1;
+		uint64_t maxlfb:4;
+		uint64_t maxvab:4;
+		uint64_t discclk:1;
+		uint64_t l2dfdbe:1;
+		uint64_t l2dfsbe:1;
+		uint64_t disstgl2i:1;
+		uint64_t reserved_28_63:36;
+#endif
+	} cn63xx;
 	struct cvmx_l2c_ctl_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_25_63:39;
 		uint64_t discclk:1;
 		uint64_t maxvab:4;
@@ -458,12 +924,30 @@
 		uint64_t vab_thresh:4;
 		uint64_t disecc:1;
 		uint64_t disidxalias:1;
+#else
+		uint64_t disidxalias:1;
+		uint64_t disecc:1;
+		uint64_t vab_thresh:4;
+		uint64_t ef_cnt:7;
+		uint64_t ef_ena:1;
+		uint64_t xmc_arb_mode:1;
+		uint64_t rsp_arb_mode:1;
+		uint64_t maxlfb:4;
+		uint64_t maxvab:4;
+		uint64_t discclk:1;
+		uint64_t reserved_25_63:39;
+#endif
 	} cn63xxp1;
+	struct cvmx_l2c_ctl_cn61xx cn66xx;
+	struct cvmx_l2c_ctl_s cn68xx;
+	struct cvmx_l2c_ctl_cn63xx cn68xxp1;
+	struct cvmx_l2c_ctl_cn61xx cnf71xx;
 };
 
 union cvmx_l2c_dbg {
 	uint64_t u64;
 	struct cvmx_l2c_dbg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_15_63:49;
 		uint64_t lfb_enum:4;
 		uint64_t lfb_dmp:1;
@@ -472,8 +956,19 @@
 		uint64_t finv:1;
 		uint64_t l2d:1;
 		uint64_t l2t:1;
+#else
+		uint64_t l2t:1;
+		uint64_t l2d:1;
+		uint64_t finv:1;
+		uint64_t set:3;
+		uint64_t ppnum:4;
+		uint64_t lfb_dmp:1;
+		uint64_t lfb_enum:4;
+		uint64_t reserved_15_63:49;
+#endif
 	} s;
 	struct cvmx_l2c_dbg_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_13_63:51;
 		uint64_t lfb_enum:2;
 		uint64_t lfb_dmp:1;
@@ -484,8 +979,21 @@
 		uint64_t finv:1;
 		uint64_t l2d:1;
 		uint64_t l2t:1;
+#else
+		uint64_t l2t:1;
+		uint64_t l2d:1;
+		uint64_t finv:1;
+		uint64_t set:2;
+		uint64_t reserved_5_5:1;
+		uint64_t ppnum:1;
+		uint64_t reserved_7_9:3;
+		uint64_t lfb_dmp:1;
+		uint64_t lfb_enum:2;
+		uint64_t reserved_13_63:51;
+#endif
 	} cn30xx;
 	struct cvmx_l2c_dbg_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_14_63:50;
 		uint64_t lfb_enum:3;
 		uint64_t lfb_dmp:1;
@@ -496,10 +1004,23 @@
 		uint64_t finv:1;
 		uint64_t l2d:1;
 		uint64_t l2t:1;
+#else
+		uint64_t l2t:1;
+		uint64_t l2d:1;
+		uint64_t finv:1;
+		uint64_t set:2;
+		uint64_t reserved_5_5:1;
+		uint64_t ppnum:1;
+		uint64_t reserved_7_9:3;
+		uint64_t lfb_dmp:1;
+		uint64_t lfb_enum:3;
+		uint64_t reserved_14_63:50;
+#endif
 	} cn31xx;
 	struct cvmx_l2c_dbg_s cn38xx;
 	struct cvmx_l2c_dbg_s cn38xxp2;
 	struct cvmx_l2c_dbg_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_14_63:50;
 		uint64_t lfb_enum:3;
 		uint64_t lfb_dmp:1;
@@ -509,8 +1030,20 @@
 		uint64_t finv:1;
 		uint64_t l2d:1;
 		uint64_t l2t:1;
+#else
+		uint64_t l2t:1;
+		uint64_t l2d:1;
+		uint64_t finv:1;
+		uint64_t set:3;
+		uint64_t ppnum:1;
+		uint64_t reserved_7_9:3;
+		uint64_t lfb_dmp:1;
+		uint64_t lfb_enum:3;
+		uint64_t reserved_14_63:50;
+#endif
 	} cn50xx;
 	struct cvmx_l2c_dbg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_14_63:50;
 		uint64_t lfb_enum:3;
 		uint64_t lfb_dmp:1;
@@ -520,6 +1053,17 @@
 		uint64_t finv:1;
 		uint64_t l2d:1;
 		uint64_t l2t:1;
+#else
+		uint64_t l2t:1;
+		uint64_t l2d:1;
+		uint64_t finv:1;
+		uint64_t set:3;
+		uint64_t ppnum:2;
+		uint64_t reserved_8_9:2;
+		uint64_t lfb_dmp:1;
+		uint64_t lfb_enum:3;
+		uint64_t reserved_14_63:50;
+#endif
 	} cn52xx;
 	struct cvmx_l2c_dbg_cn52xx cn52xxp1;
 	struct cvmx_l2c_dbg_s cn56xx;
@@ -531,11 +1075,19 @@
 union cvmx_l2c_dut {
 	uint64_t u64;
 	struct cvmx_l2c_dut_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t dtena:1;
 		uint64_t reserved_30_30:1;
 		uint64_t dt_vld:1;
 		uint64_t dt_tag:29;
+#else
+		uint64_t dt_tag:29;
+		uint64_t dt_vld:1;
+		uint64_t reserved_30_30:1;
+		uint64_t dtena:1;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_l2c_dut_s cn30xx;
 	struct cvmx_l2c_dut_s cn31xx;
@@ -553,18 +1105,77 @@
 union cvmx_l2c_dut_mapx {
 	uint64_t u64;
 	struct cvmx_l2c_dut_mapx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_38_63:26;
 		uint64_t tag:28;
 		uint64_t reserved_1_9:9;
 		uint64_t valid:1;
+#else
+		uint64_t valid:1;
+		uint64_t reserved_1_9:9;
+		uint64_t tag:28;
+		uint64_t reserved_38_63:26;
+#endif
 	} s;
+	struct cvmx_l2c_dut_mapx_s cn61xx;
 	struct cvmx_l2c_dut_mapx_s cn63xx;
 	struct cvmx_l2c_dut_mapx_s cn63xxp1;
+	struct cvmx_l2c_dut_mapx_s cn66xx;
+	struct cvmx_l2c_dut_mapx_s cn68xx;
+	struct cvmx_l2c_dut_mapx_s cn68xxp1;
+	struct cvmx_l2c_dut_mapx_s cnf71xx;
 };
 
 union cvmx_l2c_err_tdtx {
 	uint64_t u64;
 	struct cvmx_l2c_err_tdtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t dbe:1;
+		uint64_t sbe:1;
+		uint64_t vdbe:1;
+		uint64_t vsbe:1;
+		uint64_t syn:10;
+		uint64_t reserved_22_49:28;
+		uint64_t wayidx:18;
+		uint64_t reserved_2_3:2;
+		uint64_t type:2;
+#else
+		uint64_t type:2;
+		uint64_t reserved_2_3:2;
+		uint64_t wayidx:18;
+		uint64_t reserved_22_49:28;
+		uint64_t syn:10;
+		uint64_t vsbe:1;
+		uint64_t vdbe:1;
+		uint64_t sbe:1;
+		uint64_t dbe:1;
+#endif
+	} s;
+	struct cvmx_l2c_err_tdtx_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t dbe:1;
+		uint64_t sbe:1;
+		uint64_t vdbe:1;
+		uint64_t vsbe:1;
+		uint64_t syn:10;
+		uint64_t reserved_20_49:30;
+		uint64_t wayidx:16;
+		uint64_t reserved_2_3:2;
+		uint64_t type:2;
+#else
+		uint64_t type:2;
+		uint64_t reserved_2_3:2;
+		uint64_t wayidx:16;
+		uint64_t reserved_20_49:30;
+		uint64_t syn:10;
+		uint64_t vsbe:1;
+		uint64_t vdbe:1;
+		uint64_t sbe:1;
+		uint64_t dbe:1;
+#endif
+	} cn61xx;
+	struct cvmx_l2c_err_tdtx_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t dbe:1;
 		uint64_t sbe:1;
 		uint64_t vdbe:1;
@@ -574,14 +1185,75 @@
 		uint64_t wayidx:17;
 		uint64_t reserved_2_3:2;
 		uint64_t type:2;
-	} s;
-	struct cvmx_l2c_err_tdtx_s cn63xx;
-	struct cvmx_l2c_err_tdtx_s cn63xxp1;
+#else
+		uint64_t type:2;
+		uint64_t reserved_2_3:2;
+		uint64_t wayidx:17;
+		uint64_t reserved_21_49:29;
+		uint64_t syn:10;
+		uint64_t vsbe:1;
+		uint64_t vdbe:1;
+		uint64_t sbe:1;
+		uint64_t dbe:1;
+#endif
+	} cn63xx;
+	struct cvmx_l2c_err_tdtx_cn63xx cn63xxp1;
+	struct cvmx_l2c_err_tdtx_cn63xx cn66xx;
+	struct cvmx_l2c_err_tdtx_s cn68xx;
+	struct cvmx_l2c_err_tdtx_s cn68xxp1;
+	struct cvmx_l2c_err_tdtx_cn61xx cnf71xx;
 };
 
 union cvmx_l2c_err_ttgx {
 	uint64_t u64;
 	struct cvmx_l2c_err_ttgx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t dbe:1;
+		uint64_t sbe:1;
+		uint64_t noway:1;
+		uint64_t reserved_56_60:5;
+		uint64_t syn:6;
+		uint64_t reserved_22_49:28;
+		uint64_t wayidx:15;
+		uint64_t reserved_2_6:5;
+		uint64_t type:2;
+#else
+		uint64_t type:2;
+		uint64_t reserved_2_6:5;
+		uint64_t wayidx:15;
+		uint64_t reserved_22_49:28;
+		uint64_t syn:6;
+		uint64_t reserved_56_60:5;
+		uint64_t noway:1;
+		uint64_t sbe:1;
+		uint64_t dbe:1;
+#endif
+	} s;
+	struct cvmx_l2c_err_ttgx_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t dbe:1;
+		uint64_t sbe:1;
+		uint64_t noway:1;
+		uint64_t reserved_56_60:5;
+		uint64_t syn:6;
+		uint64_t reserved_20_49:30;
+		uint64_t wayidx:13;
+		uint64_t reserved_2_6:5;
+		uint64_t type:2;
+#else
+		uint64_t type:2;
+		uint64_t reserved_2_6:5;
+		uint64_t wayidx:13;
+		uint64_t reserved_20_49:30;
+		uint64_t syn:6;
+		uint64_t reserved_56_60:5;
+		uint64_t noway:1;
+		uint64_t sbe:1;
+		uint64_t dbe:1;
+#endif
+	} cn61xx;
+	struct cvmx_l2c_err_ttgx_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t dbe:1;
 		uint64_t sbe:1;
 		uint64_t noway:1;
@@ -591,43 +1263,117 @@
 		uint64_t wayidx:14;
 		uint64_t reserved_2_6:5;
 		uint64_t type:2;
-	} s;
-	struct cvmx_l2c_err_ttgx_s cn63xx;
-	struct cvmx_l2c_err_ttgx_s cn63xxp1;
+#else
+		uint64_t type:2;
+		uint64_t reserved_2_6:5;
+		uint64_t wayidx:14;
+		uint64_t reserved_21_49:29;
+		uint64_t syn:6;
+		uint64_t reserved_56_60:5;
+		uint64_t noway:1;
+		uint64_t sbe:1;
+		uint64_t dbe:1;
+#endif
+	} cn63xx;
+	struct cvmx_l2c_err_ttgx_cn63xx cn63xxp1;
+	struct cvmx_l2c_err_ttgx_cn63xx cn66xx;
+	struct cvmx_l2c_err_ttgx_s cn68xx;
+	struct cvmx_l2c_err_ttgx_s cn68xxp1;
+	struct cvmx_l2c_err_ttgx_cn61xx cnf71xx;
 };
 
 union cvmx_l2c_err_vbfx {
 	uint64_t u64;
 	struct cvmx_l2c_err_vbfx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_62_63:2;
 		uint64_t vdbe:1;
 		uint64_t vsbe:1;
 		uint64_t vsyn:10;
 		uint64_t reserved_2_49:48;
 		uint64_t type:2;
+#else
+		uint64_t type:2;
+		uint64_t reserved_2_49:48;
+		uint64_t vsyn:10;
+		uint64_t vsbe:1;
+		uint64_t vdbe:1;
+		uint64_t reserved_62_63:2;
+#endif
 	} s;
+	struct cvmx_l2c_err_vbfx_s cn61xx;
 	struct cvmx_l2c_err_vbfx_s cn63xx;
 	struct cvmx_l2c_err_vbfx_s cn63xxp1;
+	struct cvmx_l2c_err_vbfx_s cn66xx;
+	struct cvmx_l2c_err_vbfx_s cn68xx;
+	struct cvmx_l2c_err_vbfx_s cn68xxp1;
+	struct cvmx_l2c_err_vbfx_s cnf71xx;
 };
 
 union cvmx_l2c_err_xmc {
 	uint64_t u64;
 	struct cvmx_l2c_err_xmc_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t cmd:6;
+		uint64_t reserved_54_57:4;
+		uint64_t sid:6;
+		uint64_t reserved_38_47:10;
+		uint64_t addr:38;
+#else
+		uint64_t addr:38;
+		uint64_t reserved_38_47:10;
+		uint64_t sid:6;
+		uint64_t reserved_54_57:4;
+		uint64_t cmd:6;
+#endif
+	} s;
+	struct cvmx_l2c_err_xmc_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t cmd:6;
 		uint64_t reserved_52_57:6;
 		uint64_t sid:4;
 		uint64_t reserved_38_47:10;
 		uint64_t addr:38;
-	} s;
-	struct cvmx_l2c_err_xmc_s cn63xx;
-	struct cvmx_l2c_err_xmc_s cn63xxp1;
+#else
+		uint64_t addr:38;
+		uint64_t reserved_38_47:10;
+		uint64_t sid:4;
+		uint64_t reserved_52_57:6;
+		uint64_t cmd:6;
+#endif
+	} cn61xx;
+	struct cvmx_l2c_err_xmc_cn61xx cn63xx;
+	struct cvmx_l2c_err_xmc_cn61xx cn63xxp1;
+	struct cvmx_l2c_err_xmc_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t cmd:6;
+		uint64_t reserved_53_57:5;
+		uint64_t sid:5;
+		uint64_t reserved_38_47:10;
+		uint64_t addr:38;
+#else
+		uint64_t addr:38;
+		uint64_t reserved_38_47:10;
+		uint64_t sid:5;
+		uint64_t reserved_53_57:5;
+		uint64_t cmd:6;
+#endif
+	} cn66xx;
+	struct cvmx_l2c_err_xmc_s cn68xx;
+	struct cvmx_l2c_err_xmc_s cn68xxp1;
+	struct cvmx_l2c_err_xmc_cn61xx cnf71xx;
 };
 
 union cvmx_l2c_grpwrr0 {
 	uint64_t u64;
 	struct cvmx_l2c_grpwrr0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t plc1rmsk:32;
 		uint64_t plc0rmsk:32;
+#else
+		uint64_t plc0rmsk:32;
+		uint64_t plc1rmsk:32;
+#endif
 	} s;
 	struct cvmx_l2c_grpwrr0_s cn52xx;
 	struct cvmx_l2c_grpwrr0_s cn52xxp1;
@@ -638,8 +1384,13 @@
 union cvmx_l2c_grpwrr1 {
 	uint64_t u64;
 	struct cvmx_l2c_grpwrr1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t ilcrmsk:32;
 		uint64_t plc2rmsk:32;
+#else
+		uint64_t plc2rmsk:32;
+		uint64_t ilcrmsk:32;
+#endif
 	} s;
 	struct cvmx_l2c_grpwrr1_s cn52xx;
 	struct cvmx_l2c_grpwrr1_s cn52xxp1;
@@ -650,6 +1401,7 @@
 union cvmx_l2c_int_en {
 	uint64_t u64;
 	struct cvmx_l2c_int_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t lck2ena:1;
 		uint64_t lckena:1;
@@ -660,6 +1412,18 @@
 		uint64_t oob3en:1;
 		uint64_t oob2en:1;
 		uint64_t oob1en:1;
+#else
+		uint64_t oob1en:1;
+		uint64_t oob2en:1;
+		uint64_t oob3en:1;
+		uint64_t l2tsecen:1;
+		uint64_t l2tdeden:1;
+		uint64_t l2dsecen:1;
+		uint64_t l2ddeden:1;
+		uint64_t lckena:1;
+		uint64_t lck2ena:1;
+		uint64_t reserved_9_63:55;
+#endif
 	} s;
 	struct cvmx_l2c_int_en_s cn52xx;
 	struct cvmx_l2c_int_en_s cn52xxp1;
@@ -670,6 +1434,7 @@
 union cvmx_l2c_int_ena {
 	uint64_t u64;
 	struct cvmx_l2c_int_ena_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t bigrd:1;
 		uint64_t bigwr:1;
@@ -679,9 +1444,22 @@
 		uint64_t vrtwr:1;
 		uint64_t holewr:1;
 		uint64_t holerd:1;
+#else
+		uint64_t holerd:1;
+		uint64_t holewr:1;
+		uint64_t vrtwr:1;
+		uint64_t vrtidrng:1;
+		uint64_t vrtadrng:1;
+		uint64_t vrtpe:1;
+		uint64_t bigwr:1;
+		uint64_t bigrd:1;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
+	struct cvmx_l2c_int_ena_s cn61xx;
 	struct cvmx_l2c_int_ena_s cn63xx;
 	struct cvmx_l2c_int_ena_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t vrtpe:1;
 		uint64_t vrtadrng:1;
@@ -689,12 +1467,59 @@
 		uint64_t vrtwr:1;
 		uint64_t holewr:1;
 		uint64_t holerd:1;
+#else
+		uint64_t holerd:1;
+		uint64_t holewr:1;
+		uint64_t vrtwr:1;
+		uint64_t vrtidrng:1;
+		uint64_t vrtadrng:1;
+		uint64_t vrtpe:1;
+		uint64_t reserved_6_63:58;
+#endif
 	} cn63xxp1;
+	struct cvmx_l2c_int_ena_s cn66xx;
+	struct cvmx_l2c_int_ena_s cn68xx;
+	struct cvmx_l2c_int_ena_s cn68xxp1;
+	struct cvmx_l2c_int_ena_s cnf71xx;
 };
 
 union cvmx_l2c_int_reg {
 	uint64_t u64;
 	struct cvmx_l2c_int_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_20_63:44;
+		uint64_t tad3:1;
+		uint64_t tad2:1;
+		uint64_t tad1:1;
+		uint64_t tad0:1;
+		uint64_t reserved_8_15:8;
+		uint64_t bigrd:1;
+		uint64_t bigwr:1;
+		uint64_t vrtpe:1;
+		uint64_t vrtadrng:1;
+		uint64_t vrtidrng:1;
+		uint64_t vrtwr:1;
+		uint64_t holewr:1;
+		uint64_t holerd:1;
+#else
+		uint64_t holerd:1;
+		uint64_t holewr:1;
+		uint64_t vrtwr:1;
+		uint64_t vrtidrng:1;
+		uint64_t vrtadrng:1;
+		uint64_t vrtpe:1;
+		uint64_t bigwr:1;
+		uint64_t bigrd:1;
+		uint64_t reserved_8_15:8;
+		uint64_t tad0:1;
+		uint64_t tad1:1;
+		uint64_t tad2:1;
+		uint64_t tad3:1;
+		uint64_t reserved_20_63:44;
+#endif
+	} s;
+	struct cvmx_l2c_int_reg_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_17_63:47;
 		uint64_t tad0:1;
 		uint64_t reserved_8_15:8;
@@ -706,9 +1531,23 @@
 		uint64_t vrtwr:1;
 		uint64_t holewr:1;
 		uint64_t holerd:1;
-	} s;
-	struct cvmx_l2c_int_reg_s cn63xx;
+#else
+		uint64_t holerd:1;
+		uint64_t holewr:1;
+		uint64_t vrtwr:1;
+		uint64_t vrtidrng:1;
+		uint64_t vrtadrng:1;
+		uint64_t vrtpe:1;
+		uint64_t bigwr:1;
+		uint64_t bigrd:1;
+		uint64_t reserved_8_15:8;
+		uint64_t tad0:1;
+		uint64_t reserved_17_63:47;
+#endif
+	} cn61xx;
+	struct cvmx_l2c_int_reg_cn61xx cn63xx;
 	struct cvmx_l2c_int_reg_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_17_63:47;
 		uint64_t tad0:1;
 		uint64_t reserved_6_15:10;
@@ -718,12 +1557,28 @@
 		uint64_t vrtwr:1;
 		uint64_t holewr:1;
 		uint64_t holerd:1;
+#else
+		uint64_t holerd:1;
+		uint64_t holewr:1;
+		uint64_t vrtwr:1;
+		uint64_t vrtidrng:1;
+		uint64_t vrtadrng:1;
+		uint64_t vrtpe:1;
+		uint64_t reserved_6_15:10;
+		uint64_t tad0:1;
+		uint64_t reserved_17_63:47;
+#endif
 	} cn63xxp1;
+	struct cvmx_l2c_int_reg_cn61xx cn66xx;
+	struct cvmx_l2c_int_reg_s cn68xx;
+	struct cvmx_l2c_int_reg_s cn68xxp1;
+	struct cvmx_l2c_int_reg_cn61xx cnf71xx;
 };
 
 union cvmx_l2c_int_stat {
 	uint64_t u64;
 	struct cvmx_l2c_int_stat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t lck2:1;
 		uint64_t lck:1;
@@ -734,6 +1589,18 @@
 		uint64_t oob3:1;
 		uint64_t oob2:1;
 		uint64_t oob1:1;
+#else
+		uint64_t oob1:1;
+		uint64_t oob2:1;
+		uint64_t oob3:1;
+		uint64_t l2tsec:1;
+		uint64_t l2tded:1;
+		uint64_t l2dsec:1;
+		uint64_t l2dded:1;
+		uint64_t lck:1;
+		uint64_t lck2:1;
+		uint64_t reserved_9_63:55;
+#endif
 	} s;
 	struct cvmx_l2c_int_stat_s cn52xx;
 	struct cvmx_l2c_int_stat_s cn52xxp1;
@@ -744,28 +1611,53 @@
 union cvmx_l2c_iocx_pfc {
 	uint64_t u64;
 	struct cvmx_l2c_iocx_pfc_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t count:64;
+#else
+		uint64_t count:64;
+#endif
 	} s;
+	struct cvmx_l2c_iocx_pfc_s cn61xx;
 	struct cvmx_l2c_iocx_pfc_s cn63xx;
 	struct cvmx_l2c_iocx_pfc_s cn63xxp1;
+	struct cvmx_l2c_iocx_pfc_s cn66xx;
+	struct cvmx_l2c_iocx_pfc_s cn68xx;
+	struct cvmx_l2c_iocx_pfc_s cn68xxp1;
+	struct cvmx_l2c_iocx_pfc_s cnf71xx;
 };
 
 union cvmx_l2c_iorx_pfc {
 	uint64_t u64;
 	struct cvmx_l2c_iorx_pfc_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t count:64;
+#else
+		uint64_t count:64;
+#endif
 	} s;
+	struct cvmx_l2c_iorx_pfc_s cn61xx;
 	struct cvmx_l2c_iorx_pfc_s cn63xx;
 	struct cvmx_l2c_iorx_pfc_s cn63xxp1;
+	struct cvmx_l2c_iorx_pfc_s cn66xx;
+	struct cvmx_l2c_iorx_pfc_s cn68xx;
+	struct cvmx_l2c_iorx_pfc_s cn68xxp1;
+	struct cvmx_l2c_iorx_pfc_s cnf71xx;
 };
 
 union cvmx_l2c_lckbase {
 	uint64_t u64;
 	struct cvmx_l2c_lckbase_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_31_63:33;
 		uint64_t lck_base:27;
 		uint64_t reserved_1_3:3;
 		uint64_t lck_ena:1;
+#else
+		uint64_t lck_ena:1;
+		uint64_t reserved_1_3:3;
+		uint64_t lck_base:27;
+		uint64_t reserved_31_63:33;
+#endif
 	} s;
 	struct cvmx_l2c_lckbase_s cn30xx;
 	struct cvmx_l2c_lckbase_s cn31xx;
@@ -783,8 +1675,13 @@
 union cvmx_l2c_lckoff {
 	uint64_t u64;
 	struct cvmx_l2c_lckoff_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t lck_offset:10;
+#else
+		uint64_t lck_offset:10;
+		uint64_t reserved_10_63:54;
+#endif
 	} s;
 	struct cvmx_l2c_lckoff_s cn30xx;
 	struct cvmx_l2c_lckoff_s cn31xx;
@@ -802,6 +1699,7 @@
 union cvmx_l2c_lfb0 {
 	uint64_t u64;
 	struct cvmx_l2c_lfb0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t stcpnd:1;
 		uint64_t stpnd:1;
@@ -816,8 +1714,25 @@
 		uint64_t sid:9;
 		uint64_t cmd:4;
 		uint64_t vld:1;
+#else
+		uint64_t vld:1;
+		uint64_t cmd:4;
+		uint64_t sid:9;
+		uint64_t vabnum:4;
+		uint64_t set:3;
+		uint64_t ihd:1;
+		uint64_t itl:1;
+		uint64_t inxt:4;
+		uint64_t vam:1;
+		uint64_t stcfl:1;
+		uint64_t stinv:1;
+		uint64_t stpnd:1;
+		uint64_t stcpnd:1;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_l2c_lfb0_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t stcpnd:1;
 		uint64_t stpnd:1;
@@ -835,8 +1750,28 @@
 		uint64_t sid:9;
 		uint64_t cmd:4;
 		uint64_t vld:1;
+#else
+		uint64_t vld:1;
+		uint64_t cmd:4;
+		uint64_t sid:9;
+		uint64_t vabnum:2;
+		uint64_t reserved_16_17:2;
+		uint64_t set:2;
+		uint64_t reserved_20_20:1;
+		uint64_t ihd:1;
+		uint64_t itl:1;
+		uint64_t inxt:2;
+		uint64_t reserved_25_26:2;
+		uint64_t vam:1;
+		uint64_t stcfl:1;
+		uint64_t stinv:1;
+		uint64_t stpnd:1;
+		uint64_t stcpnd:1;
+		uint64_t reserved_32_63:32;
+#endif
 	} cn30xx;
 	struct cvmx_l2c_lfb0_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t stcpnd:1;
 		uint64_t stpnd:1;
@@ -854,10 +1789,30 @@
 		uint64_t sid:9;
 		uint64_t cmd:4;
 		uint64_t vld:1;
+#else
+		uint64_t vld:1;
+		uint64_t cmd:4;
+		uint64_t sid:9;
+		uint64_t vabnum:3;
+		uint64_t reserved_17_17:1;
+		uint64_t set:2;
+		uint64_t reserved_20_20:1;
+		uint64_t ihd:1;
+		uint64_t itl:1;
+		uint64_t inxt:3;
+		uint64_t reserved_26_26:1;
+		uint64_t vam:1;
+		uint64_t stcfl:1;
+		uint64_t stinv:1;
+		uint64_t stpnd:1;
+		uint64_t stcpnd:1;
+		uint64_t reserved_32_63:32;
+#endif
 	} cn31xx;
 	struct cvmx_l2c_lfb0_s cn38xx;
 	struct cvmx_l2c_lfb0_s cn38xxp2;
 	struct cvmx_l2c_lfb0_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t stcpnd:1;
 		uint64_t stpnd:1;
@@ -874,6 +1829,24 @@
 		uint64_t sid:9;
 		uint64_t cmd:4;
 		uint64_t vld:1;
+#else
+		uint64_t vld:1;
+		uint64_t cmd:4;
+		uint64_t sid:9;
+		uint64_t vabnum:3;
+		uint64_t reserved_17_17:1;
+		uint64_t set:3;
+		uint64_t ihd:1;
+		uint64_t itl:1;
+		uint64_t inxt:3;
+		uint64_t reserved_26_26:1;
+		uint64_t vam:1;
+		uint64_t stcfl:1;
+		uint64_t stinv:1;
+		uint64_t stpnd:1;
+		uint64_t stcpnd:1;
+		uint64_t reserved_32_63:32;
+#endif
 	} cn50xx;
 	struct cvmx_l2c_lfb0_cn50xx cn52xx;
 	struct cvmx_l2c_lfb0_cn50xx cn52xxp1;
@@ -886,6 +1859,7 @@
 union cvmx_l2c_lfb1 {
 	uint64_t u64;
 	struct cvmx_l2c_lfb1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_19_63:45;
 		uint64_t dsgoing:1;
 		uint64_t bid:2;
@@ -905,6 +1879,27 @@
 		uint64_t prbrty:1;
 		uint64_t wtprb:1;
 		uint64_t vld:1;
+#else
+		uint64_t vld:1;
+		uint64_t wtprb:1;
+		uint64_t prbrty:1;
+		uint64_t wtmfl:1;
+		uint64_t wtvtm:1;
+		uint64_t wtstrsc:1;
+		uint64_t wtstrsp:1;
+		uint64_t wtstdt:1;
+		uint64_t wtrda:1;
+		uint64_t wtstm:1;
+		uint64_t wtwrm:1;
+		uint64_t wtwhf:1;
+		uint64_t wtwhp:1;
+		uint64_t wtdq:1;
+		uint64_t wtdw:1;
+		uint64_t wtrsp:1;
+		uint64_t bid:2;
+		uint64_t dsgoing:1;
+		uint64_t reserved_19_63:45;
+#endif
 	} s;
 	struct cvmx_l2c_lfb1_s cn30xx;
 	struct cvmx_l2c_lfb1_s cn31xx;
@@ -922,35 +1917,69 @@
 union cvmx_l2c_lfb2 {
 	uint64_t u64;
 	struct cvmx_l2c_lfb2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_0_63:64;
+#else
+		uint64_t reserved_0_63:64;
+#endif
 	} s;
 	struct cvmx_l2c_lfb2_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_27_63:37;
 		uint64_t lfb_tag:19;
 		uint64_t lfb_idx:8;
+#else
+		uint64_t lfb_idx:8;
+		uint64_t lfb_tag:19;
+		uint64_t reserved_27_63:37;
+#endif
 	} cn30xx;
 	struct cvmx_l2c_lfb2_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_27_63:37;
 		uint64_t lfb_tag:17;
 		uint64_t lfb_idx:10;
+#else
+		uint64_t lfb_idx:10;
+		uint64_t lfb_tag:17;
+		uint64_t reserved_27_63:37;
+#endif
 	} cn31xx;
 	struct cvmx_l2c_lfb2_cn31xx cn38xx;
 	struct cvmx_l2c_lfb2_cn31xx cn38xxp2;
 	struct cvmx_l2c_lfb2_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_27_63:37;
 		uint64_t lfb_tag:20;
 		uint64_t lfb_idx:7;
+#else
+		uint64_t lfb_idx:7;
+		uint64_t lfb_tag:20;
+		uint64_t reserved_27_63:37;
+#endif
 	} cn50xx;
 	struct cvmx_l2c_lfb2_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_27_63:37;
 		uint64_t lfb_tag:18;
 		uint64_t lfb_idx:9;
+#else
+		uint64_t lfb_idx:9;
+		uint64_t lfb_tag:18;
+		uint64_t reserved_27_63:37;
+#endif
 	} cn52xx;
 	struct cvmx_l2c_lfb2_cn52xx cn52xxp1;
 	struct cvmx_l2c_lfb2_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_27_63:37;
 		uint64_t lfb_tag:16;
 		uint64_t lfb_idx:11;
+#else
+		uint64_t lfb_idx:11;
+		uint64_t lfb_tag:16;
+		uint64_t reserved_27_63:37;
+#endif
 	} cn56xx;
 	struct cvmx_l2c_lfb2_cn56xx cn56xxp1;
 	struct cvmx_l2c_lfb2_cn56xx cn58xx;
@@ -960,21 +1989,41 @@
 union cvmx_l2c_lfb3 {
 	uint64_t u64;
 	struct cvmx_l2c_lfb3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t stpartdis:1;
 		uint64_t lfb_hwm:4;
+#else
+		uint64_t lfb_hwm:4;
+		uint64_t stpartdis:1;
+		uint64_t reserved_5_63:59;
+#endif
 	} s;
 	struct cvmx_l2c_lfb3_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t stpartdis:1;
 		uint64_t reserved_2_3:2;
 		uint64_t lfb_hwm:2;
+#else
+		uint64_t lfb_hwm:2;
+		uint64_t reserved_2_3:2;
+		uint64_t stpartdis:1;
+		uint64_t reserved_5_63:59;
+#endif
 	} cn30xx;
 	struct cvmx_l2c_lfb3_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t stpartdis:1;
 		uint64_t reserved_3_3:1;
 		uint64_t lfb_hwm:3;
+#else
+		uint64_t lfb_hwm:3;
+		uint64_t reserved_3_3:1;
+		uint64_t stpartdis:1;
+		uint64_t reserved_5_63:59;
+#endif
 	} cn31xx;
 	struct cvmx_l2c_lfb3_s cn38xx;
 	struct cvmx_l2c_lfb3_s cn38xxp2;
@@ -990,9 +2039,15 @@
 union cvmx_l2c_oob {
 	uint64_t u64;
 	struct cvmx_l2c_oob_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t dwbena:1;
 		uint64_t stena:1;
+#else
+		uint64_t stena:1;
+		uint64_t dwbena:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_l2c_oob_s cn52xx;
 	struct cvmx_l2c_oob_s cn52xxp1;
@@ -1003,12 +2058,21 @@
 union cvmx_l2c_oob1 {
 	uint64_t u64;
 	struct cvmx_l2c_oob1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t fadr:27;
 		uint64_t fsrc:1;
 		uint64_t reserved_34_35:2;
 		uint64_t sadr:14;
 		uint64_t reserved_14_19:6;
 		uint64_t size:14;
+#else
+		uint64_t size:14;
+		uint64_t reserved_14_19:6;
+		uint64_t sadr:14;
+		uint64_t reserved_34_35:2;
+		uint64_t fsrc:1;
+		uint64_t fadr:27;
+#endif
 	} s;
 	struct cvmx_l2c_oob1_s cn52xx;
 	struct cvmx_l2c_oob1_s cn52xxp1;
@@ -1019,12 +2083,21 @@
 union cvmx_l2c_oob2 {
 	uint64_t u64;
 	struct cvmx_l2c_oob2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t fadr:27;
 		uint64_t fsrc:1;
 		uint64_t reserved_34_35:2;
 		uint64_t sadr:14;
 		uint64_t reserved_14_19:6;
 		uint64_t size:14;
+#else
+		uint64_t size:14;
+		uint64_t reserved_14_19:6;
+		uint64_t sadr:14;
+		uint64_t reserved_34_35:2;
+		uint64_t fsrc:1;
+		uint64_t fadr:27;
+#endif
 	} s;
 	struct cvmx_l2c_oob2_s cn52xx;
 	struct cvmx_l2c_oob2_s cn52xxp1;
@@ -1035,12 +2108,21 @@
 union cvmx_l2c_oob3 {
 	uint64_t u64;
 	struct cvmx_l2c_oob3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t fadr:27;
 		uint64_t fsrc:1;
 		uint64_t reserved_34_35:2;
 		uint64_t sadr:14;
 		uint64_t reserved_14_19:6;
 		uint64_t size:14;
+#else
+		uint64_t size:14;
+		uint64_t reserved_14_19:6;
+		uint64_t sadr:14;
+		uint64_t reserved_34_35:2;
+		uint64_t fsrc:1;
+		uint64_t fadr:27;
+#endif
 	} s;
 	struct cvmx_l2c_oob3_s cn52xx;
 	struct cvmx_l2c_oob3_s cn52xxp1;
@@ -1051,8 +2133,13 @@
 union cvmx_l2c_pfcx {
 	uint64_t u64;
 	struct cvmx_l2c_pfcx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_36_63:28;
 		uint64_t pfcnt0:36;
+#else
+		uint64_t pfcnt0:36;
+		uint64_t reserved_36_63:28;
+#endif
 	} s;
 	struct cvmx_l2c_pfcx_s cn30xx;
 	struct cvmx_l2c_pfcx_s cn31xx;
@@ -1070,6 +2157,7 @@
 union cvmx_l2c_pfctl {
 	uint64_t u64;
 	struct cvmx_l2c_pfctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_36_63:28;
 		uint64_t cnt3rdclr:1;
 		uint64_t cnt2rdclr:1;
@@ -1087,6 +2175,25 @@
 		uint64_t cnt0ena:1;
 		uint64_t cnt0clr:1;
 		uint64_t cnt0sel:6;
+#else
+		uint64_t cnt0sel:6;
+		uint64_t cnt0clr:1;
+		uint64_t cnt0ena:1;
+		uint64_t cnt1sel:6;
+		uint64_t cnt1clr:1;
+		uint64_t cnt1ena:1;
+		uint64_t cnt2sel:6;
+		uint64_t cnt2clr:1;
+		uint64_t cnt2ena:1;
+		uint64_t cnt3sel:6;
+		uint64_t cnt3clr:1;
+		uint64_t cnt3ena:1;
+		uint64_t cnt0rdclr:1;
+		uint64_t cnt1rdclr:1;
+		uint64_t cnt2rdclr:1;
+		uint64_t cnt3rdclr:1;
+		uint64_t reserved_36_63:28;
+#endif
 	} s;
 	struct cvmx_l2c_pfctl_s cn30xx;
 	struct cvmx_l2c_pfctl_s cn31xx;
@@ -1104,6 +2211,7 @@
 union cvmx_l2c_ppgrp {
 	uint64_t u64;
 	struct cvmx_l2c_ppgrp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_24_63:40;
 		uint64_t pp11grp:2;
 		uint64_t pp10grp:2;
@@ -1117,13 +2225,36 @@
 		uint64_t pp2grp:2;
 		uint64_t pp1grp:2;
 		uint64_t pp0grp:2;
+#else
+		uint64_t pp0grp:2;
+		uint64_t pp1grp:2;
+		uint64_t pp2grp:2;
+		uint64_t pp3grp:2;
+		uint64_t pp4grp:2;
+		uint64_t pp5grp:2;
+		uint64_t pp6grp:2;
+		uint64_t pp7grp:2;
+		uint64_t pp8grp:2;
+		uint64_t pp9grp:2;
+		uint64_t pp10grp:2;
+		uint64_t pp11grp:2;
+		uint64_t reserved_24_63:40;
+#endif
 	} s;
 	struct cvmx_l2c_ppgrp_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t pp3grp:2;
 		uint64_t pp2grp:2;
 		uint64_t pp1grp:2;
 		uint64_t pp0grp:2;
+#else
+		uint64_t pp0grp:2;
+		uint64_t pp1grp:2;
+		uint64_t pp2grp:2;
+		uint64_t pp3grp:2;
+		uint64_t reserved_8_63:56;
+#endif
 	} cn52xx;
 	struct cvmx_l2c_ppgrp_cn52xx cn52xxp1;
 	struct cvmx_l2c_ppgrp_s cn56xx;
@@ -1133,81 +2264,200 @@
 union cvmx_l2c_qos_iobx {
 	uint64_t u64;
 	struct cvmx_l2c_qos_iobx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_7_63:57;
+		uint64_t dwblvl:3;
+		uint64_t reserved_3_3:1;
+		uint64_t lvl:3;
+#else
+		uint64_t lvl:3;
+		uint64_t reserved_3_3:1;
+		uint64_t dwblvl:3;
+		uint64_t reserved_7_63:57;
+#endif
+	} s;
+	struct cvmx_l2c_qos_iobx_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t dwblvl:2;
 		uint64_t reserved_2_3:2;
 		uint64_t lvl:2;
-	} s;
-	struct cvmx_l2c_qos_iobx_s cn63xx;
-	struct cvmx_l2c_qos_iobx_s cn63xxp1;
+#else
+		uint64_t lvl:2;
+		uint64_t reserved_2_3:2;
+		uint64_t dwblvl:2;
+		uint64_t reserved_6_63:58;
+#endif
+	} cn61xx;
+	struct cvmx_l2c_qos_iobx_cn61xx cn63xx;
+	struct cvmx_l2c_qos_iobx_cn61xx cn63xxp1;
+	struct cvmx_l2c_qos_iobx_cn61xx cn66xx;
+	struct cvmx_l2c_qos_iobx_s cn68xx;
+	struct cvmx_l2c_qos_iobx_s cn68xxp1;
+	struct cvmx_l2c_qos_iobx_cn61xx cnf71xx;
 };
 
 union cvmx_l2c_qos_ppx {
 	uint64_t u64;
 	struct cvmx_l2c_qos_ppx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_3_63:61;
+		uint64_t lvl:3;
+#else
+		uint64_t lvl:3;
+		uint64_t reserved_3_63:61;
+#endif
+	} s;
+	struct cvmx_l2c_qos_ppx_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t lvl:2;
-	} s;
-	struct cvmx_l2c_qos_ppx_s cn63xx;
-	struct cvmx_l2c_qos_ppx_s cn63xxp1;
+#else
+		uint64_t lvl:2;
+		uint64_t reserved_2_63:62;
+#endif
+	} cn61xx;
+	struct cvmx_l2c_qos_ppx_cn61xx cn63xx;
+	struct cvmx_l2c_qos_ppx_cn61xx cn63xxp1;
+	struct cvmx_l2c_qos_ppx_cn61xx cn66xx;
+	struct cvmx_l2c_qos_ppx_s cn68xx;
+	struct cvmx_l2c_qos_ppx_s cn68xxp1;
+	struct cvmx_l2c_qos_ppx_cn61xx cnf71xx;
 };
 
 union cvmx_l2c_qos_wgt {
 	uint64_t u64;
 	struct cvmx_l2c_qos_wgt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t wgt7:8;
+		uint64_t wgt6:8;
+		uint64_t wgt5:8;
+		uint64_t wgt4:8;
+		uint64_t wgt3:8;
+		uint64_t wgt2:8;
+		uint64_t wgt1:8;
+		uint64_t wgt0:8;
+#else
+		uint64_t wgt0:8;
+		uint64_t wgt1:8;
+		uint64_t wgt2:8;
+		uint64_t wgt3:8;
+		uint64_t wgt4:8;
+		uint64_t wgt5:8;
+		uint64_t wgt6:8;
+		uint64_t wgt7:8;
+#endif
+	} s;
+	struct cvmx_l2c_qos_wgt_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t wgt3:8;
 		uint64_t wgt2:8;
 		uint64_t wgt1:8;
 		uint64_t wgt0:8;
-	} s;
-	struct cvmx_l2c_qos_wgt_s cn63xx;
-	struct cvmx_l2c_qos_wgt_s cn63xxp1;
+#else
+		uint64_t wgt0:8;
+		uint64_t wgt1:8;
+		uint64_t wgt2:8;
+		uint64_t wgt3:8;
+		uint64_t reserved_32_63:32;
+#endif
+	} cn61xx;
+	struct cvmx_l2c_qos_wgt_cn61xx cn63xx;
+	struct cvmx_l2c_qos_wgt_cn61xx cn63xxp1;
+	struct cvmx_l2c_qos_wgt_cn61xx cn66xx;
+	struct cvmx_l2c_qos_wgt_s cn68xx;
+	struct cvmx_l2c_qos_wgt_s cn68xxp1;
+	struct cvmx_l2c_qos_wgt_cn61xx cnf71xx;
 };
 
 union cvmx_l2c_rscx_pfc {
 	uint64_t u64;
 	struct cvmx_l2c_rscx_pfc_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t count:64;
+#else
+		uint64_t count:64;
+#endif
 	} s;
+	struct cvmx_l2c_rscx_pfc_s cn61xx;
 	struct cvmx_l2c_rscx_pfc_s cn63xx;
 	struct cvmx_l2c_rscx_pfc_s cn63xxp1;
+	struct cvmx_l2c_rscx_pfc_s cn66xx;
+	struct cvmx_l2c_rscx_pfc_s cn68xx;
+	struct cvmx_l2c_rscx_pfc_s cn68xxp1;
+	struct cvmx_l2c_rscx_pfc_s cnf71xx;
 };
 
 union cvmx_l2c_rsdx_pfc {
 	uint64_t u64;
 	struct cvmx_l2c_rsdx_pfc_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t count:64;
+#else
+		uint64_t count:64;
+#endif
 	} s;
+	struct cvmx_l2c_rsdx_pfc_s cn61xx;
 	struct cvmx_l2c_rsdx_pfc_s cn63xx;
 	struct cvmx_l2c_rsdx_pfc_s cn63xxp1;
+	struct cvmx_l2c_rsdx_pfc_s cn66xx;
+	struct cvmx_l2c_rsdx_pfc_s cn68xx;
+	struct cvmx_l2c_rsdx_pfc_s cn68xxp1;
+	struct cvmx_l2c_rsdx_pfc_s cnf71xx;
 };
 
 union cvmx_l2c_spar0 {
 	uint64_t u64;
 	struct cvmx_l2c_spar0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t umsk3:8;
 		uint64_t umsk2:8;
 		uint64_t umsk1:8;
 		uint64_t umsk0:8;
+#else
+		uint64_t umsk0:8;
+		uint64_t umsk1:8;
+		uint64_t umsk2:8;
+		uint64_t umsk3:8;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_l2c_spar0_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t umsk0:4;
+#else
+		uint64_t umsk0:4;
+		uint64_t reserved_4_63:60;
+#endif
 	} cn30xx;
 	struct cvmx_l2c_spar0_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t umsk1:4;
 		uint64_t reserved_4_7:4;
 		uint64_t umsk0:4;
+#else
+		uint64_t umsk0:4;
+		uint64_t reserved_4_7:4;
+		uint64_t umsk1:4;
+		uint64_t reserved_12_63:52;
+#endif
 	} cn31xx;
 	struct cvmx_l2c_spar0_s cn38xx;
 	struct cvmx_l2c_spar0_s cn38xxp2;
 	struct cvmx_l2c_spar0_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t umsk1:8;
 		uint64_t umsk0:8;
+#else
+		uint64_t umsk0:8;
+		uint64_t umsk1:8;
+		uint64_t reserved_16_63:48;
+#endif
 	} cn50xx;
 	struct cvmx_l2c_spar0_s cn52xx;
 	struct cvmx_l2c_spar0_s cn52xxp1;
@@ -1220,11 +2470,19 @@
 union cvmx_l2c_spar1 {
 	uint64_t u64;
 	struct cvmx_l2c_spar1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t umsk7:8;
 		uint64_t umsk6:8;
 		uint64_t umsk5:8;
 		uint64_t umsk4:8;
+#else
+		uint64_t umsk4:8;
+		uint64_t umsk5:8;
+		uint64_t umsk6:8;
+		uint64_t umsk7:8;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_l2c_spar1_s cn38xx;
 	struct cvmx_l2c_spar1_s cn38xxp2;
@@ -1237,11 +2495,19 @@
 union cvmx_l2c_spar2 {
 	uint64_t u64;
 	struct cvmx_l2c_spar2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t umsk11:8;
 		uint64_t umsk10:8;
 		uint64_t umsk9:8;
 		uint64_t umsk8:8;
+#else
+		uint64_t umsk8:8;
+		uint64_t umsk9:8;
+		uint64_t umsk10:8;
+		uint64_t umsk11:8;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_l2c_spar2_s cn38xx;
 	struct cvmx_l2c_spar2_s cn38xxp2;
@@ -1254,11 +2520,19 @@
 union cvmx_l2c_spar3 {
 	uint64_t u64;
 	struct cvmx_l2c_spar3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t umsk15:8;
 		uint64_t umsk14:8;
 		uint64_t umsk13:8;
 		uint64_t umsk12:8;
+#else
+		uint64_t umsk12:8;
+		uint64_t umsk13:8;
+		uint64_t umsk14:8;
+		uint64_t umsk15:8;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_l2c_spar3_s cn38xx;
 	struct cvmx_l2c_spar3_s cn38xxp2;
@@ -1269,12 +2543,22 @@
 union cvmx_l2c_spar4 {
 	uint64_t u64;
 	struct cvmx_l2c_spar4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t umskiob:8;
+#else
+		uint64_t umskiob:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_l2c_spar4_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t umskiob:4;
+#else
+		uint64_t umskiob:4;
+		uint64_t reserved_4_63:60;
+#endif
 	} cn30xx;
 	struct cvmx_l2c_spar4_cn30xx cn31xx;
 	struct cvmx_l2c_spar4_s cn38xx;
@@ -1291,6 +2575,7 @@
 union cvmx_l2c_tadx_ecc0 {
 	uint64_t u64;
 	struct cvmx_l2c_tadx_ecc0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_58_63:6;
 		uint64_t ow3ecc:10;
 		uint64_t reserved_42_47:6;
@@ -1299,14 +2584,30 @@
 		uint64_t ow1ecc:10;
 		uint64_t reserved_10_15:6;
 		uint64_t ow0ecc:10;
+#else
+		uint64_t ow0ecc:10;
+		uint64_t reserved_10_15:6;
+		uint64_t ow1ecc:10;
+		uint64_t reserved_26_31:6;
+		uint64_t ow2ecc:10;
+		uint64_t reserved_42_47:6;
+		uint64_t ow3ecc:10;
+		uint64_t reserved_58_63:6;
+#endif
 	} s;
+	struct cvmx_l2c_tadx_ecc0_s cn61xx;
 	struct cvmx_l2c_tadx_ecc0_s cn63xx;
 	struct cvmx_l2c_tadx_ecc0_s cn63xxp1;
+	struct cvmx_l2c_tadx_ecc0_s cn66xx;
+	struct cvmx_l2c_tadx_ecc0_s cn68xx;
+	struct cvmx_l2c_tadx_ecc0_s cn68xxp1;
+	struct cvmx_l2c_tadx_ecc0_s cnf71xx;
 };
 
 union cvmx_l2c_tadx_ecc1 {
 	uint64_t u64;
 	struct cvmx_l2c_tadx_ecc1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_58_63:6;
 		uint64_t ow7ecc:10;
 		uint64_t reserved_42_47:6;
@@ -1315,14 +2616,30 @@
 		uint64_t ow5ecc:10;
 		uint64_t reserved_10_15:6;
 		uint64_t ow4ecc:10;
+#else
+		uint64_t ow4ecc:10;
+		uint64_t reserved_10_15:6;
+		uint64_t ow5ecc:10;
+		uint64_t reserved_26_31:6;
+		uint64_t ow6ecc:10;
+		uint64_t reserved_42_47:6;
+		uint64_t ow7ecc:10;
+		uint64_t reserved_58_63:6;
+#endif
 	} s;
+	struct cvmx_l2c_tadx_ecc1_s cn61xx;
 	struct cvmx_l2c_tadx_ecc1_s cn63xx;
 	struct cvmx_l2c_tadx_ecc1_s cn63xxp1;
+	struct cvmx_l2c_tadx_ecc1_s cn66xx;
+	struct cvmx_l2c_tadx_ecc1_s cn68xx;
+	struct cvmx_l2c_tadx_ecc1_s cn68xxp1;
+	struct cvmx_l2c_tadx_ecc1_s cnf71xx;
 };
 
 union cvmx_l2c_tadx_ien {
 	uint64_t u64;
 	struct cvmx_l2c_tadx_ien_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t wrdislmc:1;
 		uint64_t rddislmc:1;
@@ -1333,9 +2650,23 @@
 		uint64_t tagsbe:1;
 		uint64_t l2ddbe:1;
 		uint64_t l2dsbe:1;
+#else
+		uint64_t l2dsbe:1;
+		uint64_t l2ddbe:1;
+		uint64_t tagsbe:1;
+		uint64_t tagdbe:1;
+		uint64_t vbfsbe:1;
+		uint64_t vbfdbe:1;
+		uint64_t noway:1;
+		uint64_t rddislmc:1;
+		uint64_t wrdislmc:1;
+		uint64_t reserved_9_63:55;
+#endif
 	} s;
+	struct cvmx_l2c_tadx_ien_s cn61xx;
 	struct cvmx_l2c_tadx_ien_s cn63xx;
 	struct cvmx_l2c_tadx_ien_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_7_63:57;
 		uint64_t noway:1;
 		uint64_t vbfdbe:1;
@@ -1344,12 +2675,27 @@
 		uint64_t tagsbe:1;
 		uint64_t l2ddbe:1;
 		uint64_t l2dsbe:1;
+#else
+		uint64_t l2dsbe:1;
+		uint64_t l2ddbe:1;
+		uint64_t tagsbe:1;
+		uint64_t tagdbe:1;
+		uint64_t vbfsbe:1;
+		uint64_t vbfdbe:1;
+		uint64_t noway:1;
+		uint64_t reserved_7_63:57;
+#endif
 	} cn63xxp1;
+	struct cvmx_l2c_tadx_ien_s cn66xx;
+	struct cvmx_l2c_tadx_ien_s cn68xx;
+	struct cvmx_l2c_tadx_ien_s cn68xxp1;
+	struct cvmx_l2c_tadx_ien_s cnf71xx;
 };
 
 union cvmx_l2c_tadx_int {
 	uint64_t u64;
 	struct cvmx_l2c_tadx_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t wrdislmc:1;
 		uint64_t rddislmc:1;
@@ -1360,62 +2706,129 @@
 		uint64_t tagsbe:1;
 		uint64_t l2ddbe:1;
 		uint64_t l2dsbe:1;
+#else
+		uint64_t l2dsbe:1;
+		uint64_t l2ddbe:1;
+		uint64_t tagsbe:1;
+		uint64_t tagdbe:1;
+		uint64_t vbfsbe:1;
+		uint64_t vbfdbe:1;
+		uint64_t noway:1;
+		uint64_t rddislmc:1;
+		uint64_t wrdislmc:1;
+		uint64_t reserved_9_63:55;
+#endif
 	} s;
+	struct cvmx_l2c_tadx_int_s cn61xx;
 	struct cvmx_l2c_tadx_int_s cn63xx;
+	struct cvmx_l2c_tadx_int_s cn66xx;
+	struct cvmx_l2c_tadx_int_s cn68xx;
+	struct cvmx_l2c_tadx_int_s cn68xxp1;
+	struct cvmx_l2c_tadx_int_s cnf71xx;
 };
 
 union cvmx_l2c_tadx_pfc0 {
 	uint64_t u64;
 	struct cvmx_l2c_tadx_pfc0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t count:64;
+#else
+		uint64_t count:64;
+#endif
 	} s;
+	struct cvmx_l2c_tadx_pfc0_s cn61xx;
 	struct cvmx_l2c_tadx_pfc0_s cn63xx;
 	struct cvmx_l2c_tadx_pfc0_s cn63xxp1;
+	struct cvmx_l2c_tadx_pfc0_s cn66xx;
+	struct cvmx_l2c_tadx_pfc0_s cn68xx;
+	struct cvmx_l2c_tadx_pfc0_s cn68xxp1;
+	struct cvmx_l2c_tadx_pfc0_s cnf71xx;
 };
 
 union cvmx_l2c_tadx_pfc1 {
 	uint64_t u64;
 	struct cvmx_l2c_tadx_pfc1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t count:64;
+#else
+		uint64_t count:64;
+#endif
 	} s;
+	struct cvmx_l2c_tadx_pfc1_s cn61xx;
 	struct cvmx_l2c_tadx_pfc1_s cn63xx;
 	struct cvmx_l2c_tadx_pfc1_s cn63xxp1;
+	struct cvmx_l2c_tadx_pfc1_s cn66xx;
+	struct cvmx_l2c_tadx_pfc1_s cn68xx;
+	struct cvmx_l2c_tadx_pfc1_s cn68xxp1;
+	struct cvmx_l2c_tadx_pfc1_s cnf71xx;
 };
 
 union cvmx_l2c_tadx_pfc2 {
 	uint64_t u64;
 	struct cvmx_l2c_tadx_pfc2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t count:64;
+#else
+		uint64_t count:64;
+#endif
 	} s;
+	struct cvmx_l2c_tadx_pfc2_s cn61xx;
 	struct cvmx_l2c_tadx_pfc2_s cn63xx;
 	struct cvmx_l2c_tadx_pfc2_s cn63xxp1;
+	struct cvmx_l2c_tadx_pfc2_s cn66xx;
+	struct cvmx_l2c_tadx_pfc2_s cn68xx;
+	struct cvmx_l2c_tadx_pfc2_s cn68xxp1;
+	struct cvmx_l2c_tadx_pfc2_s cnf71xx;
 };
 
 union cvmx_l2c_tadx_pfc3 {
 	uint64_t u64;
 	struct cvmx_l2c_tadx_pfc3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t count:64;
+#else
+		uint64_t count:64;
+#endif
 	} s;
+	struct cvmx_l2c_tadx_pfc3_s cn61xx;
 	struct cvmx_l2c_tadx_pfc3_s cn63xx;
 	struct cvmx_l2c_tadx_pfc3_s cn63xxp1;
+	struct cvmx_l2c_tadx_pfc3_s cn66xx;
+	struct cvmx_l2c_tadx_pfc3_s cn68xx;
+	struct cvmx_l2c_tadx_pfc3_s cn68xxp1;
+	struct cvmx_l2c_tadx_pfc3_s cnf71xx;
 };
 
 union cvmx_l2c_tadx_prf {
 	uint64_t u64;
 	struct cvmx_l2c_tadx_prf_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t cnt3sel:8;
 		uint64_t cnt2sel:8;
 		uint64_t cnt1sel:8;
 		uint64_t cnt0sel:8;
+#else
+		uint64_t cnt0sel:8;
+		uint64_t cnt1sel:8;
+		uint64_t cnt2sel:8;
+		uint64_t cnt3sel:8;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
+	struct cvmx_l2c_tadx_prf_s cn61xx;
 	struct cvmx_l2c_tadx_prf_s cn63xx;
 	struct cvmx_l2c_tadx_prf_s cn63xxp1;
+	struct cvmx_l2c_tadx_prf_s cn66xx;
+	struct cvmx_l2c_tadx_prf_s cn68xx;
+	struct cvmx_l2c_tadx_prf_s cn68xxp1;
+	struct cvmx_l2c_tadx_prf_s cnf71xx;
 };
 
 union cvmx_l2c_tadx_tag {
 	uint64_t u64;
 	struct cvmx_l2c_tadx_tag_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_46_63:18;
 		uint64_t ecc:6;
 		uint64_t reserved_36_39:4;
@@ -1425,145 +2838,330 @@
 		uint64_t valid:1;
 		uint64_t dirty:1;
 		uint64_t lock:1;
+#else
+		uint64_t lock:1;
+		uint64_t dirty:1;
+		uint64_t valid:1;
+		uint64_t use:1;
+		uint64_t reserved_4_16:13;
+		uint64_t tag:19;
+		uint64_t reserved_36_39:4;
+		uint64_t ecc:6;
+		uint64_t reserved_46_63:18;
+#endif
 	} s;
+	struct cvmx_l2c_tadx_tag_s cn61xx;
 	struct cvmx_l2c_tadx_tag_s cn63xx;
 	struct cvmx_l2c_tadx_tag_s cn63xxp1;
+	struct cvmx_l2c_tadx_tag_s cn66xx;
+	struct cvmx_l2c_tadx_tag_s cn68xx;
+	struct cvmx_l2c_tadx_tag_s cn68xxp1;
+	struct cvmx_l2c_tadx_tag_s cnf71xx;
 };
 
 union cvmx_l2c_ver_id {
 	uint64_t u64;
 	struct cvmx_l2c_ver_id_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t mask:64;
+#else
+		uint64_t mask:64;
+#endif
 	} s;
+	struct cvmx_l2c_ver_id_s cn61xx;
 	struct cvmx_l2c_ver_id_s cn63xx;
 	struct cvmx_l2c_ver_id_s cn63xxp1;
+	struct cvmx_l2c_ver_id_s cn66xx;
+	struct cvmx_l2c_ver_id_s cn68xx;
+	struct cvmx_l2c_ver_id_s cn68xxp1;
+	struct cvmx_l2c_ver_id_s cnf71xx;
 };
 
 union cvmx_l2c_ver_iob {
 	uint64_t u64;
 	struct cvmx_l2c_ver_iob_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_2_63:62;
+		uint64_t mask:2;
+#else
+		uint64_t mask:2;
+		uint64_t reserved_2_63:62;
+#endif
+	} s;
+	struct cvmx_l2c_ver_iob_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t mask:1;
-	} s;
-	struct cvmx_l2c_ver_iob_s cn63xx;
-	struct cvmx_l2c_ver_iob_s cn63xxp1;
+#else
+		uint64_t mask:1;
+		uint64_t reserved_1_63:63;
+#endif
+	} cn61xx;
+	struct cvmx_l2c_ver_iob_cn61xx cn63xx;
+	struct cvmx_l2c_ver_iob_cn61xx cn63xxp1;
+	struct cvmx_l2c_ver_iob_cn61xx cn66xx;
+	struct cvmx_l2c_ver_iob_s cn68xx;
+	struct cvmx_l2c_ver_iob_s cn68xxp1;
+	struct cvmx_l2c_ver_iob_cn61xx cnf71xx;
 };
 
 union cvmx_l2c_ver_msc {
 	uint64_t u64;
 	struct cvmx_l2c_ver_msc_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t invl2:1;
 		uint64_t dwb:1;
+#else
+		uint64_t dwb:1;
+		uint64_t invl2:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
+	struct cvmx_l2c_ver_msc_s cn61xx;
 	struct cvmx_l2c_ver_msc_s cn63xx;
+	struct cvmx_l2c_ver_msc_s cn66xx;
+	struct cvmx_l2c_ver_msc_s cn68xx;
+	struct cvmx_l2c_ver_msc_s cn68xxp1;
+	struct cvmx_l2c_ver_msc_s cnf71xx;
 };
 
 union cvmx_l2c_ver_pp {
 	uint64_t u64;
 	struct cvmx_l2c_ver_pp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t mask:32;
+#else
+		uint64_t mask:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_l2c_ver_pp_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t mask:4;
+#else
+		uint64_t mask:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} cn61xx;
+	struct cvmx_l2c_ver_pp_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t mask:6;
-	} s;
-	struct cvmx_l2c_ver_pp_s cn63xx;
-	struct cvmx_l2c_ver_pp_s cn63xxp1;
+#else
+		uint64_t mask:6;
+		uint64_t reserved_6_63:58;
+#endif
+	} cn63xx;
+	struct cvmx_l2c_ver_pp_cn63xx cn63xxp1;
+	struct cvmx_l2c_ver_pp_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_10_63:54;
+		uint64_t mask:10;
+#else
+		uint64_t mask:10;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn66xx;
+	struct cvmx_l2c_ver_pp_s cn68xx;
+	struct cvmx_l2c_ver_pp_s cn68xxp1;
+	struct cvmx_l2c_ver_pp_cn61xx cnf71xx;
 };
 
 union cvmx_l2c_virtid_iobx {
 	uint64_t u64;
 	struct cvmx_l2c_virtid_iobx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_14_63:50;
 		uint64_t dwbid:6;
 		uint64_t reserved_6_7:2;
 		uint64_t id:6;
+#else
+		uint64_t id:6;
+		uint64_t reserved_6_7:2;
+		uint64_t dwbid:6;
+		uint64_t reserved_14_63:50;
+#endif
 	} s;
+	struct cvmx_l2c_virtid_iobx_s cn61xx;
 	struct cvmx_l2c_virtid_iobx_s cn63xx;
 	struct cvmx_l2c_virtid_iobx_s cn63xxp1;
+	struct cvmx_l2c_virtid_iobx_s cn66xx;
+	struct cvmx_l2c_virtid_iobx_s cn68xx;
+	struct cvmx_l2c_virtid_iobx_s cn68xxp1;
+	struct cvmx_l2c_virtid_iobx_s cnf71xx;
 };
 
 union cvmx_l2c_virtid_ppx {
 	uint64_t u64;
 	struct cvmx_l2c_virtid_ppx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t id:6;
+#else
+		uint64_t id:6;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
+	struct cvmx_l2c_virtid_ppx_s cn61xx;
 	struct cvmx_l2c_virtid_ppx_s cn63xx;
 	struct cvmx_l2c_virtid_ppx_s cn63xxp1;
+	struct cvmx_l2c_virtid_ppx_s cn66xx;
+	struct cvmx_l2c_virtid_ppx_s cn68xx;
+	struct cvmx_l2c_virtid_ppx_s cn68xxp1;
+	struct cvmx_l2c_virtid_ppx_s cnf71xx;
 };
 
 union cvmx_l2c_vrt_ctl {
 	uint64_t u64;
 	struct cvmx_l2c_vrt_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t ooberr:1;
 		uint64_t reserved_7_7:1;
 		uint64_t memsz:3;
 		uint64_t numid:3;
 		uint64_t enable:1;
+#else
+		uint64_t enable:1;
+		uint64_t numid:3;
+		uint64_t memsz:3;
+		uint64_t reserved_7_7:1;
+		uint64_t ooberr:1;
+		uint64_t reserved_9_63:55;
+#endif
 	} s;
+	struct cvmx_l2c_vrt_ctl_s cn61xx;
 	struct cvmx_l2c_vrt_ctl_s cn63xx;
 	struct cvmx_l2c_vrt_ctl_s cn63xxp1;
+	struct cvmx_l2c_vrt_ctl_s cn66xx;
+	struct cvmx_l2c_vrt_ctl_s cn68xx;
+	struct cvmx_l2c_vrt_ctl_s cn68xxp1;
+	struct cvmx_l2c_vrt_ctl_s cnf71xx;
 };
 
 union cvmx_l2c_vrt_memx {
 	uint64_t u64;
 	struct cvmx_l2c_vrt_memx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_36_63:28;
 		uint64_t parity:4;
 		uint64_t data:32;
+#else
+		uint64_t data:32;
+		uint64_t parity:4;
+		uint64_t reserved_36_63:28;
+#endif
 	} s;
+	struct cvmx_l2c_vrt_memx_s cn61xx;
 	struct cvmx_l2c_vrt_memx_s cn63xx;
 	struct cvmx_l2c_vrt_memx_s cn63xxp1;
+	struct cvmx_l2c_vrt_memx_s cn66xx;
+	struct cvmx_l2c_vrt_memx_s cn68xx;
+	struct cvmx_l2c_vrt_memx_s cn68xxp1;
+	struct cvmx_l2c_vrt_memx_s cnf71xx;
 };
 
 union cvmx_l2c_wpar_iobx {
 	uint64_t u64;
 	struct cvmx_l2c_wpar_iobx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t mask:16;
+#else
+		uint64_t mask:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
+	struct cvmx_l2c_wpar_iobx_s cn61xx;
 	struct cvmx_l2c_wpar_iobx_s cn63xx;
 	struct cvmx_l2c_wpar_iobx_s cn63xxp1;
+	struct cvmx_l2c_wpar_iobx_s cn66xx;
+	struct cvmx_l2c_wpar_iobx_s cn68xx;
+	struct cvmx_l2c_wpar_iobx_s cn68xxp1;
+	struct cvmx_l2c_wpar_iobx_s cnf71xx;
 };
 
 union cvmx_l2c_wpar_ppx {
 	uint64_t u64;
 	struct cvmx_l2c_wpar_ppx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t mask:16;
+#else
+		uint64_t mask:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
+	struct cvmx_l2c_wpar_ppx_s cn61xx;
 	struct cvmx_l2c_wpar_ppx_s cn63xx;
 	struct cvmx_l2c_wpar_ppx_s cn63xxp1;
+	struct cvmx_l2c_wpar_ppx_s cn66xx;
+	struct cvmx_l2c_wpar_ppx_s cn68xx;
+	struct cvmx_l2c_wpar_ppx_s cn68xxp1;
+	struct cvmx_l2c_wpar_ppx_s cnf71xx;
 };
 
 union cvmx_l2c_xmcx_pfc {
 	uint64_t u64;
 	struct cvmx_l2c_xmcx_pfc_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t count:64;
+#else
+		uint64_t count:64;
+#endif
 	} s;
+	struct cvmx_l2c_xmcx_pfc_s cn61xx;
 	struct cvmx_l2c_xmcx_pfc_s cn63xx;
 	struct cvmx_l2c_xmcx_pfc_s cn63xxp1;
+	struct cvmx_l2c_xmcx_pfc_s cn66xx;
+	struct cvmx_l2c_xmcx_pfc_s cn68xx;
+	struct cvmx_l2c_xmcx_pfc_s cn68xxp1;
+	struct cvmx_l2c_xmcx_pfc_s cnf71xx;
 };
 
 union cvmx_l2c_xmc_cmd {
 	uint64_t u64;
 	struct cvmx_l2c_xmc_cmd_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t inuse:1;
 		uint64_t cmd:6;
 		uint64_t reserved_38_56:19;
 		uint64_t addr:38;
+#else
+		uint64_t addr:38;
+		uint64_t reserved_38_56:19;
+		uint64_t cmd:6;
+		uint64_t inuse:1;
+#endif
 	} s;
+	struct cvmx_l2c_xmc_cmd_s cn61xx;
 	struct cvmx_l2c_xmc_cmd_s cn63xx;
 	struct cvmx_l2c_xmc_cmd_s cn63xxp1;
+	struct cvmx_l2c_xmc_cmd_s cn66xx;
+	struct cvmx_l2c_xmc_cmd_s cn68xx;
+	struct cvmx_l2c_xmc_cmd_s cn68xxp1;
+	struct cvmx_l2c_xmc_cmd_s cnf71xx;
 };
 
 union cvmx_l2c_xmdx_pfc {
 	uint64_t u64;
 	struct cvmx_l2c_xmdx_pfc_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t count:64;
+#else
+		uint64_t count:64;
+#endif
 	} s;
+	struct cvmx_l2c_xmdx_pfc_s cn61xx;
 	struct cvmx_l2c_xmdx_pfc_s cn63xx;
 	struct cvmx_l2c_xmdx_pfc_s cn63xxp1;
+	struct cvmx_l2c_xmdx_pfc_s cn66xx;
+	struct cvmx_l2c_xmdx_pfc_s cn68xx;
+	struct cvmx_l2c_xmdx_pfc_s cn68xxp1;
+	struct cvmx_l2c_xmdx_pfc_s cnf71xx;
 };
 
 #endif
diff --git a/arch/mips/include/asm/octeon/cvmx-l2d-defs.h b/arch/mips/include/asm/octeon/cvmx-l2d-defs.h
index 60543e0..11a4562 100644
--- a/arch/mips/include/asm/octeon/cvmx-l2d-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-l2d-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -44,9 +44,15 @@
 union cvmx_l2d_bst0 {
 	uint64_t u64;
 	struct cvmx_l2d_bst0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_35_63:29;
 		uint64_t ftl:1;
 		uint64_t q0stat:34;
+#else
+		uint64_t q0stat:34;
+		uint64_t ftl:1;
+		uint64_t reserved_35_63:29;
+#endif
 	} s;
 	struct cvmx_l2d_bst0_s cn30xx;
 	struct cvmx_l2d_bst0_s cn31xx;
@@ -64,8 +70,13 @@
 union cvmx_l2d_bst1 {
 	uint64_t u64;
 	struct cvmx_l2d_bst1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_34_63:30;
 		uint64_t q1stat:34;
+#else
+		uint64_t q1stat:34;
+		uint64_t reserved_34_63:30;
+#endif
 	} s;
 	struct cvmx_l2d_bst1_s cn30xx;
 	struct cvmx_l2d_bst1_s cn31xx;
@@ -83,8 +94,13 @@
 union cvmx_l2d_bst2 {
 	uint64_t u64;
 	struct cvmx_l2d_bst2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_34_63:30;
 		uint64_t q2stat:34;
+#else
+		uint64_t q2stat:34;
+		uint64_t reserved_34_63:30;
+#endif
 	} s;
 	struct cvmx_l2d_bst2_s cn30xx;
 	struct cvmx_l2d_bst2_s cn31xx;
@@ -102,8 +118,13 @@
 union cvmx_l2d_bst3 {
 	uint64_t u64;
 	struct cvmx_l2d_bst3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_34_63:30;
 		uint64_t q3stat:34;
+#else
+		uint64_t q3stat:34;
+		uint64_t reserved_34_63:30;
+#endif
 	} s;
 	struct cvmx_l2d_bst3_s cn30xx;
 	struct cvmx_l2d_bst3_s cn31xx;
@@ -121,6 +142,7 @@
 union cvmx_l2d_err {
 	uint64_t u64;
 	struct cvmx_l2d_err_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t bmhclsel:1;
 		uint64_t ded_err:1;
@@ -128,6 +150,15 @@
 		uint64_t ded_intena:1;
 		uint64_t sec_intena:1;
 		uint64_t ecc_ena:1;
+#else
+		uint64_t ecc_ena:1;
+		uint64_t sec_intena:1;
+		uint64_t ded_intena:1;
+		uint64_t sec_err:1;
+		uint64_t ded_err:1;
+		uint64_t bmhclsel:1;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
 	struct cvmx_l2d_err_s cn30xx;
 	struct cvmx_l2d_err_s cn31xx;
@@ -145,48 +176,97 @@
 union cvmx_l2d_fadr {
 	uint64_t u64;
 	struct cvmx_l2d_fadr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_19_63:45;
 		uint64_t fadru:1;
 		uint64_t fowmsk:4;
 		uint64_t fset:3;
 		uint64_t fadr:11;
+#else
+		uint64_t fadr:11;
+		uint64_t fset:3;
+		uint64_t fowmsk:4;
+		uint64_t fadru:1;
+		uint64_t reserved_19_63:45;
+#endif
 	} s;
 	struct cvmx_l2d_fadr_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_18_63:46;
 		uint64_t fowmsk:4;
 		uint64_t reserved_13_13:1;
 		uint64_t fset:2;
 		uint64_t reserved_9_10:2;
 		uint64_t fadr:9;
+#else
+		uint64_t fadr:9;
+		uint64_t reserved_9_10:2;
+		uint64_t fset:2;
+		uint64_t reserved_13_13:1;
+		uint64_t fowmsk:4;
+		uint64_t reserved_18_63:46;
+#endif
 	} cn30xx;
 	struct cvmx_l2d_fadr_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_18_63:46;
 		uint64_t fowmsk:4;
 		uint64_t reserved_13_13:1;
 		uint64_t fset:2;
 		uint64_t reserved_10_10:1;
 		uint64_t fadr:10;
+#else
+		uint64_t fadr:10;
+		uint64_t reserved_10_10:1;
+		uint64_t fset:2;
+		uint64_t reserved_13_13:1;
+		uint64_t fowmsk:4;
+		uint64_t reserved_18_63:46;
+#endif
 	} cn31xx;
 	struct cvmx_l2d_fadr_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_18_63:46;
 		uint64_t fowmsk:4;
 		uint64_t fset:3;
 		uint64_t fadr:11;
+#else
+		uint64_t fadr:11;
+		uint64_t fset:3;
+		uint64_t fowmsk:4;
+		uint64_t reserved_18_63:46;
+#endif
 	} cn38xx;
 	struct cvmx_l2d_fadr_cn38xx cn38xxp2;
 	struct cvmx_l2d_fadr_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_18_63:46;
 		uint64_t fowmsk:4;
 		uint64_t fset:3;
 		uint64_t reserved_8_10:3;
 		uint64_t fadr:8;
+#else
+		uint64_t fadr:8;
+		uint64_t reserved_8_10:3;
+		uint64_t fset:3;
+		uint64_t fowmsk:4;
+		uint64_t reserved_18_63:46;
+#endif
 	} cn50xx;
 	struct cvmx_l2d_fadr_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_18_63:46;
 		uint64_t fowmsk:4;
 		uint64_t fset:3;
 		uint64_t reserved_10_10:1;
 		uint64_t fadr:10;
+#else
+		uint64_t fadr:10;
+		uint64_t reserved_10_10:1;
+		uint64_t fset:3;
+		uint64_t fowmsk:4;
+		uint64_t reserved_18_63:46;
+#endif
 	} cn52xx;
 	struct cvmx_l2d_fadr_cn52xx cn52xxp1;
 	struct cvmx_l2d_fadr_s cn56xx;
@@ -198,9 +278,15 @@
 union cvmx_l2d_fsyn0 {
 	uint64_t u64;
 	struct cvmx_l2d_fsyn0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t fsyn_ow1:10;
 		uint64_t fsyn_ow0:10;
+#else
+		uint64_t fsyn_ow0:10;
+		uint64_t fsyn_ow1:10;
+		uint64_t reserved_20_63:44;
+#endif
 	} s;
 	struct cvmx_l2d_fsyn0_s cn30xx;
 	struct cvmx_l2d_fsyn0_s cn31xx;
@@ -218,9 +304,15 @@
 union cvmx_l2d_fsyn1 {
 	uint64_t u64;
 	struct cvmx_l2d_fsyn1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t fsyn_ow3:10;
 		uint64_t fsyn_ow2:10;
+#else
+		uint64_t fsyn_ow2:10;
+		uint64_t fsyn_ow3:10;
+		uint64_t reserved_20_63:44;
+#endif
 	} s;
 	struct cvmx_l2d_fsyn1_s cn30xx;
 	struct cvmx_l2d_fsyn1_s cn31xx;
@@ -238,8 +330,13 @@
 union cvmx_l2d_fus0 {
 	uint64_t u64;
 	struct cvmx_l2d_fus0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_34_63:30;
 		uint64_t q0fus:34;
+#else
+		uint64_t q0fus:34;
+		uint64_t reserved_34_63:30;
+#endif
 	} s;
 	struct cvmx_l2d_fus0_s cn30xx;
 	struct cvmx_l2d_fus0_s cn31xx;
@@ -257,8 +354,13 @@
 union cvmx_l2d_fus1 {
 	uint64_t u64;
 	struct cvmx_l2d_fus1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_34_63:30;
 		uint64_t q1fus:34;
+#else
+		uint64_t q1fus:34;
+		uint64_t reserved_34_63:30;
+#endif
 	} s;
 	struct cvmx_l2d_fus1_s cn30xx;
 	struct cvmx_l2d_fus1_s cn31xx;
@@ -276,8 +378,13 @@
 union cvmx_l2d_fus2 {
 	uint64_t u64;
 	struct cvmx_l2d_fus2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_34_63:30;
 		uint64_t q2fus:34;
+#else
+		uint64_t q2fus:34;
+		uint64_t reserved_34_63:30;
+#endif
 	} s;
 	struct cvmx_l2d_fus2_s cn30xx;
 	struct cvmx_l2d_fus2_s cn31xx;
@@ -295,61 +402,123 @@
 union cvmx_l2d_fus3 {
 	uint64_t u64;
 	struct cvmx_l2d_fus3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_40_63:24;
 		uint64_t ema_ctl:3;
 		uint64_t reserved_34_36:3;
 		uint64_t q3fus:34;
+#else
+		uint64_t q3fus:34;
+		uint64_t reserved_34_36:3;
+		uint64_t ema_ctl:3;
+		uint64_t reserved_40_63:24;
+#endif
 	} s;
 	struct cvmx_l2d_fus3_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_35_63:29;
 		uint64_t crip_64k:1;
 		uint64_t q3fus:34;
+#else
+		uint64_t q3fus:34;
+		uint64_t crip_64k:1;
+		uint64_t reserved_35_63:29;
+#endif
 	} cn30xx;
 	struct cvmx_l2d_fus3_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_35_63:29;
 		uint64_t crip_128k:1;
 		uint64_t q3fus:34;
+#else
+		uint64_t q3fus:34;
+		uint64_t crip_128k:1;
+		uint64_t reserved_35_63:29;
+#endif
 	} cn31xx;
 	struct cvmx_l2d_fus3_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_36_63:28;
 		uint64_t crip_256k:1;
 		uint64_t crip_512k:1;
 		uint64_t q3fus:34;
+#else
+		uint64_t q3fus:34;
+		uint64_t crip_512k:1;
+		uint64_t crip_256k:1;
+		uint64_t reserved_36_63:28;
+#endif
 	} cn38xx;
 	struct cvmx_l2d_fus3_cn38xx cn38xxp2;
 	struct cvmx_l2d_fus3_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_40_63:24;
 		uint64_t ema_ctl:3;
 		uint64_t reserved_36_36:1;
 		uint64_t crip_32k:1;
 		uint64_t crip_64k:1;
 		uint64_t q3fus:34;
+#else
+		uint64_t q3fus:34;
+		uint64_t crip_64k:1;
+		uint64_t crip_32k:1;
+		uint64_t reserved_36_36:1;
+		uint64_t ema_ctl:3;
+		uint64_t reserved_40_63:24;
+#endif
 	} cn50xx;
 	struct cvmx_l2d_fus3_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_40_63:24;
 		uint64_t ema_ctl:3;
 		uint64_t reserved_36_36:1;
 		uint64_t crip_128k:1;
 		uint64_t crip_256k:1;
 		uint64_t q3fus:34;
+#else
+		uint64_t q3fus:34;
+		uint64_t crip_256k:1;
+		uint64_t crip_128k:1;
+		uint64_t reserved_36_36:1;
+		uint64_t ema_ctl:3;
+		uint64_t reserved_40_63:24;
+#endif
 	} cn52xx;
 	struct cvmx_l2d_fus3_cn52xx cn52xxp1;
 	struct cvmx_l2d_fus3_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_40_63:24;
 		uint64_t ema_ctl:3;
 		uint64_t reserved_36_36:1;
 		uint64_t crip_512k:1;
 		uint64_t crip_1024k:1;
 		uint64_t q3fus:34;
+#else
+		uint64_t q3fus:34;
+		uint64_t crip_1024k:1;
+		uint64_t crip_512k:1;
+		uint64_t reserved_36_36:1;
+		uint64_t ema_ctl:3;
+		uint64_t reserved_40_63:24;
+#endif
 	} cn56xx;
 	struct cvmx_l2d_fus3_cn56xx cn56xxp1;
 	struct cvmx_l2d_fus3_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_39_63:25;
 		uint64_t ema_ctl:2;
 		uint64_t reserved_36_36:1;
 		uint64_t crip_512k:1;
 		uint64_t crip_1024k:1;
 		uint64_t q3fus:34;
+#else
+		uint64_t q3fus:34;
+		uint64_t crip_1024k:1;
+		uint64_t crip_512k:1;
+		uint64_t reserved_36_36:1;
+		uint64_t ema_ctl:2;
+		uint64_t reserved_39_63:25;
+#endif
 	} cn58xx;
 	struct cvmx_l2d_fus3_cn58xx cn58xxp1;
 };
diff --git a/arch/mips/include/asm/octeon/cvmx-l2t-defs.h b/arch/mips/include/asm/octeon/cvmx-l2t-defs.h
index 873968f..83ce22c 100644
--- a/arch/mips/include/asm/octeon/cvmx-l2t-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-l2t-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -33,6 +33,7 @@
 union cvmx_l2t_err {
 	uint64_t u64;
 	struct cvmx_l2t_err_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_29_63:35;
 		uint64_t fadru:1;
 		uint64_t lck_intena2:1;
@@ -47,8 +48,25 @@
 		uint64_t ded_intena:1;
 		uint64_t sec_intena:1;
 		uint64_t ecc_ena:1;
+#else
+		uint64_t ecc_ena:1;
+		uint64_t sec_intena:1;
+		uint64_t ded_intena:1;
+		uint64_t sec_err:1;
+		uint64_t ded_err:1;
+		uint64_t fsyn:6;
+		uint64_t fadr:10;
+		uint64_t fset:3;
+		uint64_t lckerr:1;
+		uint64_t lck_intena:1;
+		uint64_t lckerr2:1;
+		uint64_t lck_intena2:1;
+		uint64_t fadru:1;
+		uint64_t reserved_29_63:35;
+#endif
 	} s;
 	struct cvmx_l2t_err_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_28_63:36;
 		uint64_t lck_intena2:1;
 		uint64_t lckerr2:1;
@@ -64,8 +82,26 @@
 		uint64_t ded_intena:1;
 		uint64_t sec_intena:1;
 		uint64_t ecc_ena:1;
+#else
+		uint64_t ecc_ena:1;
+		uint64_t sec_intena:1;
+		uint64_t ded_intena:1;
+		uint64_t sec_err:1;
+		uint64_t ded_err:1;
+		uint64_t fsyn:6;
+		uint64_t fadr:8;
+		uint64_t reserved_19_20:2;
+		uint64_t fset:2;
+		uint64_t reserved_23_23:1;
+		uint64_t lckerr:1;
+		uint64_t lck_intena:1;
+		uint64_t lckerr2:1;
+		uint64_t lck_intena2:1;
+		uint64_t reserved_28_63:36;
+#endif
 	} cn30xx;
 	struct cvmx_l2t_err_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_28_63:36;
 		uint64_t lck_intena2:1;
 		uint64_t lckerr2:1;
@@ -81,8 +117,26 @@
 		uint64_t ded_intena:1;
 		uint64_t sec_intena:1;
 		uint64_t ecc_ena:1;
+#else
+		uint64_t ecc_ena:1;
+		uint64_t sec_intena:1;
+		uint64_t ded_intena:1;
+		uint64_t sec_err:1;
+		uint64_t ded_err:1;
+		uint64_t fsyn:6;
+		uint64_t fadr:9;
+		uint64_t reserved_20_20:1;
+		uint64_t fset:2;
+		uint64_t reserved_23_23:1;
+		uint64_t lckerr:1;
+		uint64_t lck_intena:1;
+		uint64_t lckerr2:1;
+		uint64_t lck_intena2:1;
+		uint64_t reserved_28_63:36;
+#endif
 	} cn31xx;
 	struct cvmx_l2t_err_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_28_63:36;
 		uint64_t lck_intena2:1;
 		uint64_t lckerr2:1;
@@ -96,9 +150,25 @@
 		uint64_t ded_intena:1;
 		uint64_t sec_intena:1;
 		uint64_t ecc_ena:1;
+#else
+		uint64_t ecc_ena:1;
+		uint64_t sec_intena:1;
+		uint64_t ded_intena:1;
+		uint64_t sec_err:1;
+		uint64_t ded_err:1;
+		uint64_t fsyn:6;
+		uint64_t fadr:10;
+		uint64_t fset:3;
+		uint64_t lckerr:1;
+		uint64_t lck_intena:1;
+		uint64_t lckerr2:1;
+		uint64_t lck_intena2:1;
+		uint64_t reserved_28_63:36;
+#endif
 	} cn38xx;
 	struct cvmx_l2t_err_cn38xx cn38xxp2;
 	struct cvmx_l2t_err_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_28_63:36;
 		uint64_t lck_intena2:1;
 		uint64_t lckerr2:1;
@@ -113,8 +183,25 @@
 		uint64_t ded_intena:1;
 		uint64_t sec_intena:1;
 		uint64_t ecc_ena:1;
+#else
+		uint64_t ecc_ena:1;
+		uint64_t sec_intena:1;
+		uint64_t ded_intena:1;
+		uint64_t sec_err:1;
+		uint64_t ded_err:1;
+		uint64_t fsyn:6;
+		uint64_t fadr:7;
+		uint64_t reserved_18_20:3;
+		uint64_t fset:3;
+		uint64_t lckerr:1;
+		uint64_t lck_intena:1;
+		uint64_t lckerr2:1;
+		uint64_t lck_intena2:1;
+		uint64_t reserved_28_63:36;
+#endif
 	} cn50xx;
 	struct cvmx_l2t_err_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_28_63:36;
 		uint64_t lck_intena2:1;
 		uint64_t lckerr2:1;
@@ -129,6 +216,22 @@
 		uint64_t ded_intena:1;
 		uint64_t sec_intena:1;
 		uint64_t ecc_ena:1;
+#else
+		uint64_t ecc_ena:1;
+		uint64_t sec_intena:1;
+		uint64_t ded_intena:1;
+		uint64_t sec_err:1;
+		uint64_t ded_err:1;
+		uint64_t fsyn:6;
+		uint64_t fadr:9;
+		uint64_t reserved_20_20:1;
+		uint64_t fset:3;
+		uint64_t lckerr:1;
+		uint64_t lck_intena:1;
+		uint64_t lckerr2:1;
+		uint64_t lck_intena2:1;
+		uint64_t reserved_28_63:36;
+#endif
 	} cn52xx;
 	struct cvmx_l2t_err_cn52xx cn52xxp1;
 	struct cvmx_l2t_err_s cn56xx;
diff --git a/arch/mips/include/asm/octeon/cvmx-led-defs.h b/arch/mips/include/asm/octeon/cvmx-led-defs.h
index e25173b..d36d42b 100644
--- a/arch/mips/include/asm/octeon/cvmx-led-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-led-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -45,8 +45,13 @@
 union cvmx_led_blink {
 	uint64_t u64;
 	struct cvmx_led_blink_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t rate:8;
+#else
+		uint64_t rate:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_led_blink_s cn38xx;
 	struct cvmx_led_blink_s cn38xxp2;
@@ -59,8 +64,13 @@
 union cvmx_led_clk_phase {
 	uint64_t u64;
 	struct cvmx_led_clk_phase_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_7_63:57;
 		uint64_t phase:7;
+#else
+		uint64_t phase:7;
+		uint64_t reserved_7_63:57;
+#endif
 	} s;
 	struct cvmx_led_clk_phase_s cn38xx;
 	struct cvmx_led_clk_phase_s cn38xxp2;
@@ -73,8 +83,13 @@
 union cvmx_led_cylon {
 	uint64_t u64;
 	struct cvmx_led_cylon_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t rate:16;
+#else
+		uint64_t rate:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_led_cylon_s cn38xx;
 	struct cvmx_led_cylon_s cn38xxp2;
@@ -87,8 +102,13 @@
 union cvmx_led_dbg {
 	uint64_t u64;
 	struct cvmx_led_dbg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t dbg_en:1;
+#else
+		uint64_t dbg_en:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_led_dbg_s cn38xx;
 	struct cvmx_led_dbg_s cn38xxp2;
@@ -101,8 +121,13 @@
 union cvmx_led_en {
 	uint64_t u64;
 	struct cvmx_led_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t en:1;
+#else
+		uint64_t en:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_led_en_s cn38xx;
 	struct cvmx_led_en_s cn38xxp2;
@@ -115,8 +140,13 @@
 union cvmx_led_polarity {
 	uint64_t u64;
 	struct cvmx_led_polarity_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t polarity:1;
+#else
+		uint64_t polarity:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_led_polarity_s cn38xx;
 	struct cvmx_led_polarity_s cn38xxp2;
@@ -129,8 +159,13 @@
 union cvmx_led_prt {
 	uint64_t u64;
 	struct cvmx_led_prt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t prt_en:8;
+#else
+		uint64_t prt_en:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_led_prt_s cn38xx;
 	struct cvmx_led_prt_s cn38xxp2;
@@ -143,8 +178,13 @@
 union cvmx_led_prt_fmt {
 	uint64_t u64;
 	struct cvmx_led_prt_fmt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t format:4;
+#else
+		uint64_t format:4;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_led_prt_fmt_s cn38xx;
 	struct cvmx_led_prt_fmt_s cn38xxp2;
@@ -157,8 +197,13 @@
 union cvmx_led_prt_statusx {
 	uint64_t u64;
 	struct cvmx_led_prt_statusx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t status:6;
+#else
+		uint64_t status:6;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
 	struct cvmx_led_prt_statusx_s cn38xx;
 	struct cvmx_led_prt_statusx_s cn38xxp2;
@@ -171,8 +216,13 @@
 union cvmx_led_udd_cntx {
 	uint64_t u64;
 	struct cvmx_led_udd_cntx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t cnt:6;
+#else
+		uint64_t cnt:6;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
 	struct cvmx_led_udd_cntx_s cn38xx;
 	struct cvmx_led_udd_cntx_s cn38xxp2;
@@ -185,8 +235,13 @@
 union cvmx_led_udd_datx {
 	uint64_t u64;
 	struct cvmx_led_udd_datx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t dat:32;
+#else
+		uint64_t dat:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_led_udd_datx_s cn38xx;
 	struct cvmx_led_udd_datx_s cn38xxp2;
@@ -199,8 +254,13 @@
 union cvmx_led_udd_dat_clrx {
 	uint64_t u64;
 	struct cvmx_led_udd_dat_clrx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t clr:32;
+#else
+		uint64_t clr:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_led_udd_dat_clrx_s cn38xx;
 	struct cvmx_led_udd_dat_clrx_s cn38xxp2;
@@ -213,8 +273,13 @@
 union cvmx_led_udd_dat_setx {
 	uint64_t u64;
 	struct cvmx_led_udd_dat_setx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t set:32;
+#else
+		uint64_t set:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_led_udd_dat_setx_s cn38xx;
 	struct cvmx_led_udd_dat_setx_s cn38xxp2;
diff --git a/arch/mips/include/asm/octeon/cvmx-mio-defs.h b/arch/mips/include/asm/octeon/cvmx-mio-defs.h
index b177412..bb0ae33 100644
--- a/arch/mips/include/asm/octeon/cvmx-mio-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-mio-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -94,6 +94,7 @@
 #define CVMX_MIO_PTP_CLOCK_HI (CVMX_ADD_IO_SEG(0x0001070000000F10ull))
 #define CVMX_MIO_PTP_CLOCK_LO (CVMX_ADD_IO_SEG(0x0001070000000F08ull))
 #define CVMX_MIO_PTP_EVT_CNT (CVMX_ADD_IO_SEG(0x0001070000000F28ull))
+#define CVMX_MIO_PTP_PHY_1PPS_IN (CVMX_ADD_IO_SEG(0x0001070000000F70ull))
 #define CVMX_MIO_PTP_PPS_HI_INCR (CVMX_ADD_IO_SEG(0x0001070000000F60ull))
 #define CVMX_MIO_PTP_PPS_LO_INCR (CVMX_ADD_IO_SEG(0x0001070000000F68ull))
 #define CVMX_MIO_PTP_PPS_THRESH_HI (CVMX_ADD_IO_SEG(0x0001070000000F58ull))
@@ -166,24 +167,44 @@
 union cvmx_mio_boot_bist_stat {
 	uint64_t u64;
 	struct cvmx_mio_boot_bist_stat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_0_63:64;
+#else
+		uint64_t reserved_0_63:64;
+#endif
 	} s;
 	struct cvmx_mio_boot_bist_stat_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t ncbo_1:1;
 		uint64_t ncbo_0:1;
 		uint64_t loc:1;
 		uint64_t ncbi:1;
+#else
+		uint64_t ncbi:1;
+		uint64_t loc:1;
+		uint64_t ncbo_0:1;
+		uint64_t ncbo_1:1;
+		uint64_t reserved_4_63:60;
+#endif
 	} cn30xx;
 	struct cvmx_mio_boot_bist_stat_cn30xx cn31xx;
 	struct cvmx_mio_boot_bist_stat_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_3_63:61;
 		uint64_t ncbo_0:1;
 		uint64_t loc:1;
 		uint64_t ncbi:1;
+#else
+		uint64_t ncbi:1;
+		uint64_t loc:1;
+		uint64_t ncbo_0:1;
+		uint64_t reserved_3_63:61;
+#endif
 	} cn38xx;
 	struct cvmx_mio_boot_bist_stat_cn38xx cn38xxp2;
 	struct cvmx_mio_boot_bist_stat_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t pcm_1:1;
 		uint64_t pcm_0:1;
@@ -191,72 +212,132 @@
 		uint64_t ncbo_0:1;
 		uint64_t loc:1;
 		uint64_t ncbi:1;
+#else
+		uint64_t ncbi:1;
+		uint64_t loc:1;
+		uint64_t ncbo_0:1;
+		uint64_t ncbo_1:1;
+		uint64_t pcm_0:1;
+		uint64_t pcm_1:1;
+		uint64_t reserved_6_63:58;
+#endif
 	} cn50xx;
 	struct cvmx_mio_boot_bist_stat_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t ndf:2;
 		uint64_t ncbo_0:1;
 		uint64_t dma:1;
 		uint64_t loc:1;
 		uint64_t ncbi:1;
+#else
+		uint64_t ncbi:1;
+		uint64_t loc:1;
+		uint64_t dma:1;
+		uint64_t ncbo_0:1;
+		uint64_t ndf:2;
+		uint64_t reserved_6_63:58;
+#endif
 	} cn52xx;
 	struct cvmx_mio_boot_bist_stat_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t ncbo_0:1;
 		uint64_t dma:1;
 		uint64_t loc:1;
 		uint64_t ncbi:1;
+#else
+		uint64_t ncbi:1;
+		uint64_t loc:1;
+		uint64_t dma:1;
+		uint64_t ncbo_0:1;
+		uint64_t reserved_4_63:60;
+#endif
 	} cn52xxp1;
 	struct cvmx_mio_boot_bist_stat_cn52xxp1 cn56xx;
 	struct cvmx_mio_boot_bist_stat_cn52xxp1 cn56xxp1;
 	struct cvmx_mio_boot_bist_stat_cn38xx cn58xx;
 	struct cvmx_mio_boot_bist_stat_cn38xx cn58xxp1;
 	struct cvmx_mio_boot_bist_stat_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t stat:12;
+#else
+		uint64_t stat:12;
+		uint64_t reserved_12_63:52;
+#endif
 	} cn61xx;
 	struct cvmx_mio_boot_bist_stat_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t stat:9;
+#else
+		uint64_t stat:9;
+		uint64_t reserved_9_63:55;
+#endif
 	} cn63xx;
 	struct cvmx_mio_boot_bist_stat_cn63xx cn63xxp1;
 	struct cvmx_mio_boot_bist_stat_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t stat:10;
+#else
+		uint64_t stat:10;
+		uint64_t reserved_10_63:54;
+#endif
 	} cn66xx;
 	struct cvmx_mio_boot_bist_stat_cn66xx cn68xx;
 	struct cvmx_mio_boot_bist_stat_cn66xx cn68xxp1;
+	struct cvmx_mio_boot_bist_stat_cn61xx cnf71xx;
 };
 
 union cvmx_mio_boot_comp {
 	uint64_t u64;
 	struct cvmx_mio_boot_comp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_0_63:64;
+#else
+		uint64_t reserved_0_63:64;
+#endif
 	} s;
 	struct cvmx_mio_boot_comp_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t pctl:5;
 		uint64_t nctl:5;
+#else
+		uint64_t nctl:5;
+		uint64_t pctl:5;
+		uint64_t reserved_10_63:54;
+#endif
 	} cn50xx;
 	struct cvmx_mio_boot_comp_cn50xx cn52xx;
 	struct cvmx_mio_boot_comp_cn50xx cn52xxp1;
 	struct cvmx_mio_boot_comp_cn50xx cn56xx;
 	struct cvmx_mio_boot_comp_cn50xx cn56xxp1;
 	struct cvmx_mio_boot_comp_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t pctl:6;
 		uint64_t nctl:6;
+#else
+		uint64_t nctl:6;
+		uint64_t pctl:6;
+		uint64_t reserved_12_63:52;
+#endif
 	} cn61xx;
 	struct cvmx_mio_boot_comp_cn61xx cn63xx;
 	struct cvmx_mio_boot_comp_cn61xx cn63xxp1;
 	struct cvmx_mio_boot_comp_cn61xx cn66xx;
 	struct cvmx_mio_boot_comp_cn61xx cn68xx;
 	struct cvmx_mio_boot_comp_cn61xx cn68xxp1;
+	struct cvmx_mio_boot_comp_cn61xx cnf71xx;
 };
 
 union cvmx_mio_boot_dma_cfgx {
 	uint64_t u64;
 	struct cvmx_mio_boot_dma_cfgx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t en:1;
 		uint64_t rw:1;
 		uint64_t clr:1;
@@ -267,6 +348,18 @@
 		uint64_t endian:1;
 		uint64_t size:20;
 		uint64_t adr:36;
+#else
+		uint64_t adr:36;
+		uint64_t size:20;
+		uint64_t endian:1;
+		uint64_t swap8:1;
+		uint64_t swap16:1;
+		uint64_t swap32:1;
+		uint64_t reserved_60_60:1;
+		uint64_t clr:1;
+		uint64_t rw:1;
+		uint64_t en:1;
+#endif
 	} s;
 	struct cvmx_mio_boot_dma_cfgx_s cn52xx;
 	struct cvmx_mio_boot_dma_cfgx_s cn52xxp1;
@@ -278,14 +371,21 @@
 	struct cvmx_mio_boot_dma_cfgx_s cn66xx;
 	struct cvmx_mio_boot_dma_cfgx_s cn68xx;
 	struct cvmx_mio_boot_dma_cfgx_s cn68xxp1;
+	struct cvmx_mio_boot_dma_cfgx_s cnf71xx;
 };
 
 union cvmx_mio_boot_dma_intx {
 	uint64_t u64;
 	struct cvmx_mio_boot_dma_intx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t dmarq:1;
 		uint64_t done:1;
+#else
+		uint64_t done:1;
+		uint64_t dmarq:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_mio_boot_dma_intx_s cn52xx;
 	struct cvmx_mio_boot_dma_intx_s cn52xxp1;
@@ -297,14 +397,21 @@
 	struct cvmx_mio_boot_dma_intx_s cn66xx;
 	struct cvmx_mio_boot_dma_intx_s cn68xx;
 	struct cvmx_mio_boot_dma_intx_s cn68xxp1;
+	struct cvmx_mio_boot_dma_intx_s cnf71xx;
 };
 
 union cvmx_mio_boot_dma_int_enx {
 	uint64_t u64;
 	struct cvmx_mio_boot_dma_int_enx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t dmarq:1;
 		uint64_t done:1;
+#else
+		uint64_t done:1;
+		uint64_t dmarq:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_mio_boot_dma_int_enx_s cn52xx;
 	struct cvmx_mio_boot_dma_int_enx_s cn52xxp1;
@@ -316,11 +423,13 @@
 	struct cvmx_mio_boot_dma_int_enx_s cn66xx;
 	struct cvmx_mio_boot_dma_int_enx_s cn68xx;
 	struct cvmx_mio_boot_dma_int_enx_s cn68xxp1;
+	struct cvmx_mio_boot_dma_int_enx_s cnf71xx;
 };
 
 union cvmx_mio_boot_dma_timx {
 	uint64_t u64;
 	struct cvmx_mio_boot_dma_timx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t dmack_pi:1;
 		uint64_t dmarq_pi:1;
 		uint64_t tim_mult:2;
@@ -336,6 +445,23 @@
 		uint64_t oe_a:6;
 		uint64_t dmack_s:6;
 		uint64_t dmarq:6;
+#else
+		uint64_t dmarq:6;
+		uint64_t dmack_s:6;
+		uint64_t oe_a:6;
+		uint64_t oe_n:6;
+		uint64_t we_a:6;
+		uint64_t we_n:6;
+		uint64_t dmack_h:6;
+		uint64_t pause:6;
+		uint64_t reserved_48_54:7;
+		uint64_t width:1;
+		uint64_t ddr:1;
+		uint64_t rd_dly:3;
+		uint64_t tim_mult:2;
+		uint64_t dmarq_pi:1;
+		uint64_t dmack_pi:1;
+#endif
 	} s;
 	struct cvmx_mio_boot_dma_timx_s cn52xx;
 	struct cvmx_mio_boot_dma_timx_s cn52xxp1;
@@ -347,14 +473,21 @@
 	struct cvmx_mio_boot_dma_timx_s cn66xx;
 	struct cvmx_mio_boot_dma_timx_s cn68xx;
 	struct cvmx_mio_boot_dma_timx_s cn68xxp1;
+	struct cvmx_mio_boot_dma_timx_s cnf71xx;
 };
 
 union cvmx_mio_boot_err {
 	uint64_t u64;
 	struct cvmx_mio_boot_err_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t wait_err:1;
 		uint64_t adr_err:1;
+#else
+		uint64_t adr_err:1;
+		uint64_t wait_err:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_mio_boot_err_s cn30xx;
 	struct cvmx_mio_boot_err_s cn31xx;
@@ -373,14 +506,21 @@
 	struct cvmx_mio_boot_err_s cn66xx;
 	struct cvmx_mio_boot_err_s cn68xx;
 	struct cvmx_mio_boot_err_s cn68xxp1;
+	struct cvmx_mio_boot_err_s cnf71xx;
 };
 
 union cvmx_mio_boot_int {
 	uint64_t u64;
 	struct cvmx_mio_boot_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t wait_int:1;
 		uint64_t adr_int:1;
+#else
+		uint64_t adr_int:1;
+		uint64_t wait_int:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_mio_boot_int_s cn30xx;
 	struct cvmx_mio_boot_int_s cn31xx;
@@ -399,14 +539,21 @@
 	struct cvmx_mio_boot_int_s cn66xx;
 	struct cvmx_mio_boot_int_s cn68xx;
 	struct cvmx_mio_boot_int_s cn68xxp1;
+	struct cvmx_mio_boot_int_s cnf71xx;
 };
 
 union cvmx_mio_boot_loc_adr {
 	uint64_t u64;
 	struct cvmx_mio_boot_loc_adr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t adr:5;
 		uint64_t reserved_0_2:3;
+#else
+		uint64_t reserved_0_2:3;
+		uint64_t adr:5;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_mio_boot_loc_adr_s cn30xx;
 	struct cvmx_mio_boot_loc_adr_s cn31xx;
@@ -425,16 +572,25 @@
 	struct cvmx_mio_boot_loc_adr_s cn66xx;
 	struct cvmx_mio_boot_loc_adr_s cn68xx;
 	struct cvmx_mio_boot_loc_adr_s cn68xxp1;
+	struct cvmx_mio_boot_loc_adr_s cnf71xx;
 };
 
 union cvmx_mio_boot_loc_cfgx {
 	uint64_t u64;
 	struct cvmx_mio_boot_loc_cfgx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t en:1;
 		uint64_t reserved_28_30:3;
 		uint64_t base:25;
 		uint64_t reserved_0_2:3;
+#else
+		uint64_t reserved_0_2:3;
+		uint64_t base:25;
+		uint64_t reserved_28_30:3;
+		uint64_t en:1;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_mio_boot_loc_cfgx_s cn30xx;
 	struct cvmx_mio_boot_loc_cfgx_s cn31xx;
@@ -453,12 +609,17 @@
 	struct cvmx_mio_boot_loc_cfgx_s cn66xx;
 	struct cvmx_mio_boot_loc_cfgx_s cn68xx;
 	struct cvmx_mio_boot_loc_cfgx_s cn68xxp1;
+	struct cvmx_mio_boot_loc_cfgx_s cnf71xx;
 };
 
 union cvmx_mio_boot_loc_dat {
 	uint64_t u64;
 	struct cvmx_mio_boot_loc_dat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t data:64;
+#else
+		uint64_t data:64;
+#endif
 	} s;
 	struct cvmx_mio_boot_loc_dat_s cn30xx;
 	struct cvmx_mio_boot_loc_dat_s cn31xx;
@@ -477,11 +638,13 @@
 	struct cvmx_mio_boot_loc_dat_s cn66xx;
 	struct cvmx_mio_boot_loc_dat_s cn68xx;
 	struct cvmx_mio_boot_loc_dat_s cn68xxp1;
+	struct cvmx_mio_boot_loc_dat_s cnf71xx;
 };
 
 union cvmx_mio_boot_pin_defs {
 	uint64_t u64;
 	struct cvmx_mio_boot_pin_defs_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t user1:16;
 		uint64_t ale:1;
@@ -492,8 +655,21 @@
 		uint64_t term:2;
 		uint64_t nand:1;
 		uint64_t user0:8;
+#else
+		uint64_t user0:8;
+		uint64_t nand:1;
+		uint64_t term:2;
+		uint64_t dmack_p0:1;
+		uint64_t dmack_p1:1;
+		uint64_t dmack_p2:1;
+		uint64_t width:1;
+		uint64_t ale:1;
+		uint64_t user1:16;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_mio_boot_pin_defs_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t ale:1;
 		uint64_t width:1;
@@ -503,8 +679,20 @@
 		uint64_t term:2;
 		uint64_t nand:1;
 		uint64_t reserved_0_7:8;
+#else
+		uint64_t reserved_0_7:8;
+		uint64_t nand:1;
+		uint64_t term:2;
+		uint64_t dmack_p0:1;
+		uint64_t dmack_p1:1;
+		uint64_t reserved_13_13:1;
+		uint64_t width:1;
+		uint64_t ale:1;
+		uint64_t reserved_16_63:48;
+#endif
 	} cn52xx;
 	struct cvmx_mio_boot_pin_defs_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t ale:1;
 		uint64_t width:1;
@@ -513,8 +701,19 @@
 		uint64_t dmack_p0:1;
 		uint64_t term:2;
 		uint64_t reserved_0_8:9;
+#else
+		uint64_t reserved_0_8:9;
+		uint64_t term:2;
+		uint64_t dmack_p0:1;
+		uint64_t dmack_p1:1;
+		uint64_t dmack_p2:1;
+		uint64_t width:1;
+		uint64_t ale:1;
+		uint64_t reserved_16_63:48;
+#endif
 	} cn56xx;
 	struct cvmx_mio_boot_pin_defs_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t user1:16;
 		uint64_t ale:1;
@@ -525,17 +724,31 @@
 		uint64_t term:2;
 		uint64_t nand:1;
 		uint64_t user0:8;
+#else
+		uint64_t user0:8;
+		uint64_t nand:1;
+		uint64_t term:2;
+		uint64_t dmack_p0:1;
+		uint64_t dmack_p1:1;
+		uint64_t reserved_13_13:1;
+		uint64_t width:1;
+		uint64_t ale:1;
+		uint64_t user1:16;
+		uint64_t reserved_32_63:32;
+#endif
 	} cn61xx;
 	struct cvmx_mio_boot_pin_defs_cn52xx cn63xx;
 	struct cvmx_mio_boot_pin_defs_cn52xx cn63xxp1;
 	struct cvmx_mio_boot_pin_defs_cn52xx cn66xx;
 	struct cvmx_mio_boot_pin_defs_cn52xx cn68xx;
 	struct cvmx_mio_boot_pin_defs_cn52xx cn68xxp1;
+	struct cvmx_mio_boot_pin_defs_cn61xx cnf71xx;
 };
 
 union cvmx_mio_boot_reg_cfgx {
 	uint64_t u64;
 	struct cvmx_mio_boot_reg_cfgx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_44_63:20;
 		uint64_t dmack:2;
 		uint64_t tim_mult:2;
@@ -549,8 +762,24 @@
 		uint64_t width:1;
 		uint64_t size:12;
 		uint64_t base:16;
+#else
+		uint64_t base:16;
+		uint64_t size:12;
+		uint64_t width:1;
+		uint64_t ale:1;
+		uint64_t orbit:1;
+		uint64_t en:1;
+		uint64_t oe_ext:2;
+		uint64_t we_ext:2;
+		uint64_t sam:1;
+		uint64_t rd_dly:3;
+		uint64_t tim_mult:2;
+		uint64_t dmack:2;
+		uint64_t reserved_44_63:20;
+#endif
 	} s;
 	struct cvmx_mio_boot_reg_cfgx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_37_63:27;
 		uint64_t sam:1;
 		uint64_t we_ext:2;
@@ -561,18 +790,40 @@
 		uint64_t width:1;
 		uint64_t size:12;
 		uint64_t base:16;
+#else
+		uint64_t base:16;
+		uint64_t size:12;
+		uint64_t width:1;
+		uint64_t ale:1;
+		uint64_t orbit:1;
+		uint64_t en:1;
+		uint64_t oe_ext:2;
+		uint64_t we_ext:2;
+		uint64_t sam:1;
+		uint64_t reserved_37_63:27;
+#endif
 	} cn30xx;
 	struct cvmx_mio_boot_reg_cfgx_cn30xx cn31xx;
 	struct cvmx_mio_boot_reg_cfgx_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t en:1;
 		uint64_t orbit:1;
 		uint64_t reserved_28_29:2;
 		uint64_t size:12;
 		uint64_t base:16;
+#else
+		uint64_t base:16;
+		uint64_t size:12;
+		uint64_t reserved_28_29:2;
+		uint64_t orbit:1;
+		uint64_t en:1;
+		uint64_t reserved_32_63:32;
+#endif
 	} cn38xx;
 	struct cvmx_mio_boot_reg_cfgx_cn38xx cn38xxp2;
 	struct cvmx_mio_boot_reg_cfgx_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_42_63:22;
 		uint64_t tim_mult:2;
 		uint64_t rd_dly:3;
@@ -585,6 +836,20 @@
 		uint64_t width:1;
 		uint64_t size:12;
 		uint64_t base:16;
+#else
+		uint64_t base:16;
+		uint64_t size:12;
+		uint64_t width:1;
+		uint64_t ale:1;
+		uint64_t orbit:1;
+		uint64_t en:1;
+		uint64_t oe_ext:2;
+		uint64_t we_ext:2;
+		uint64_t sam:1;
+		uint64_t rd_dly:3;
+		uint64_t tim_mult:2;
+		uint64_t reserved_42_63:22;
+#endif
 	} cn50xx;
 	struct cvmx_mio_boot_reg_cfgx_s cn52xx;
 	struct cvmx_mio_boot_reg_cfgx_s cn52xxp1;
@@ -598,11 +863,13 @@
 	struct cvmx_mio_boot_reg_cfgx_s cn66xx;
 	struct cvmx_mio_boot_reg_cfgx_s cn68xx;
 	struct cvmx_mio_boot_reg_cfgx_s cn68xxp1;
+	struct cvmx_mio_boot_reg_cfgx_s cnf71xx;
 };
 
 union cvmx_mio_boot_reg_timx {
 	uint64_t u64;
 	struct cvmx_mio_boot_reg_timx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t pagem:1;
 		uint64_t waitm:1;
 		uint64_t pages:2;
@@ -616,10 +883,26 @@
 		uint64_t oe:6;
 		uint64_t ce:6;
 		uint64_t adr:6;
+#else
+		uint64_t adr:6;
+		uint64_t ce:6;
+		uint64_t oe:6;
+		uint64_t we:6;
+		uint64_t rd_hld:6;
+		uint64_t wr_hld:6;
+		uint64_t pause:6;
+		uint64_t wait:6;
+		uint64_t page:6;
+		uint64_t ale:6;
+		uint64_t pages:2;
+		uint64_t waitm:1;
+		uint64_t pagem:1;
+#endif
 	} s;
 	struct cvmx_mio_boot_reg_timx_s cn30xx;
 	struct cvmx_mio_boot_reg_timx_s cn31xx;
 	struct cvmx_mio_boot_reg_timx_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t pagem:1;
 		uint64_t waitm:1;
 		uint64_t pages:2;
@@ -633,6 +916,21 @@
 		uint64_t oe:6;
 		uint64_t ce:6;
 		uint64_t adr:6;
+#else
+		uint64_t adr:6;
+		uint64_t ce:6;
+		uint64_t oe:6;
+		uint64_t we:6;
+		uint64_t rd_hld:6;
+		uint64_t wr_hld:6;
+		uint64_t pause:6;
+		uint64_t wait:6;
+		uint64_t page:6;
+		uint64_t reserved_54_59:6;
+		uint64_t pages:2;
+		uint64_t waitm:1;
+		uint64_t pagem:1;
+#endif
 	} cn38xx;
 	struct cvmx_mio_boot_reg_timx_cn38xx cn38xxp2;
 	struct cvmx_mio_boot_reg_timx_s cn50xx;
@@ -648,23 +946,40 @@
 	struct cvmx_mio_boot_reg_timx_s cn66xx;
 	struct cvmx_mio_boot_reg_timx_s cn68xx;
 	struct cvmx_mio_boot_reg_timx_s cn68xxp1;
+	struct cvmx_mio_boot_reg_timx_s cnf71xx;
 };
 
 union cvmx_mio_boot_thr {
 	uint64_t u64;
 	struct cvmx_mio_boot_thr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_22_63:42;
 		uint64_t dma_thr:6;
 		uint64_t reserved_14_15:2;
 		uint64_t fif_cnt:6;
 		uint64_t reserved_6_7:2;
 		uint64_t fif_thr:6;
+#else
+		uint64_t fif_thr:6;
+		uint64_t reserved_6_7:2;
+		uint64_t fif_cnt:6;
+		uint64_t reserved_14_15:2;
+		uint64_t dma_thr:6;
+		uint64_t reserved_22_63:42;
+#endif
 	} s;
 	struct cvmx_mio_boot_thr_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_14_63:50;
 		uint64_t fif_cnt:6;
 		uint64_t reserved_6_7:2;
 		uint64_t fif_thr:6;
+#else
+		uint64_t fif_thr:6;
+		uint64_t reserved_6_7:2;
+		uint64_t fif_cnt:6;
+		uint64_t reserved_14_63:50;
+#endif
 	} cn30xx;
 	struct cvmx_mio_boot_thr_cn30xx cn31xx;
 	struct cvmx_mio_boot_thr_cn30xx cn38xx;
@@ -682,42 +997,66 @@
 	struct cvmx_mio_boot_thr_s cn66xx;
 	struct cvmx_mio_boot_thr_s cn68xx;
 	struct cvmx_mio_boot_thr_s cn68xxp1;
+	struct cvmx_mio_boot_thr_s cnf71xx;
 };
 
 union cvmx_mio_emm_buf_dat {
 	uint64_t u64;
 	struct cvmx_mio_emm_buf_dat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t dat:64;
+#else
+		uint64_t dat:64;
+#endif
 	} s;
 	struct cvmx_mio_emm_buf_dat_s cn61xx;
+	struct cvmx_mio_emm_buf_dat_s cnf71xx;
 };
 
 union cvmx_mio_emm_buf_idx {
 	uint64_t u64;
 	struct cvmx_mio_emm_buf_idx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_17_63:47;
 		uint64_t inc:1;
 		uint64_t reserved_7_15:9;
 		uint64_t buf_num:1;
 		uint64_t offset:6;
+#else
+		uint64_t offset:6;
+		uint64_t buf_num:1;
+		uint64_t reserved_7_15:9;
+		uint64_t inc:1;
+		uint64_t reserved_17_63:47;
+#endif
 	} s;
 	struct cvmx_mio_emm_buf_idx_s cn61xx;
+	struct cvmx_mio_emm_buf_idx_s cnf71xx;
 };
 
 union cvmx_mio_emm_cfg {
 	uint64_t u64;
 	struct cvmx_mio_emm_cfg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_17_63:47;
 		uint64_t boot_fail:1;
 		uint64_t reserved_4_15:12;
 		uint64_t bus_ena:4;
+#else
+		uint64_t bus_ena:4;
+		uint64_t reserved_4_15:12;
+		uint64_t boot_fail:1;
+		uint64_t reserved_17_63:47;
+#endif
 	} s;
 	struct cvmx_mio_emm_cfg_s cn61xx;
+	struct cvmx_mio_emm_cfg_s cnf71xx;
 };
 
 union cvmx_mio_emm_cmd {
 	uint64_t u64;
 	struct cvmx_mio_emm_cmd_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_62_63:2;
 		uint64_t bus_id:2;
 		uint64_t cmd_val:1;
@@ -729,13 +1068,28 @@
 		uint64_t rtype_xor:3;
 		uint64_t cmd_idx:6;
 		uint64_t arg:32;
+#else
+		uint64_t arg:32;
+		uint64_t cmd_idx:6;
+		uint64_t rtype_xor:3;
+		uint64_t ctype_xor:2;
+		uint64_t reserved_43_48:6;
+		uint64_t offset:6;
+		uint64_t dbuf:1;
+		uint64_t reserved_56_58:3;
+		uint64_t cmd_val:1;
+		uint64_t bus_id:2;
+		uint64_t reserved_62_63:2;
+#endif
 	} s;
 	struct cvmx_mio_emm_cmd_s cn61xx;
+	struct cvmx_mio_emm_cmd_s cnf71xx;
 };
 
 union cvmx_mio_emm_dma {
 	uint64_t u64;
 	struct cvmx_mio_emm_dma_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_62_63:2;
 		uint64_t bus_id:2;
 		uint64_t dma_val:1;
@@ -747,13 +1101,28 @@
 		uint64_t multi:1;
 		uint64_t block_cnt:16;
 		uint64_t card_addr:32;
+#else
+		uint64_t card_addr:32;
+		uint64_t block_cnt:16;
+		uint64_t multi:1;
+		uint64_t rw:1;
+		uint64_t rel_wr:1;
+		uint64_t thres:6;
+		uint64_t dat_null:1;
+		uint64_t sector:1;
+		uint64_t dma_val:1;
+		uint64_t bus_id:2;
+		uint64_t reserved_62_63:2;
+#endif
 	} s;
 	struct cvmx_mio_emm_dma_s cn61xx;
+	struct cvmx_mio_emm_dma_s cnf71xx;
 };
 
 union cvmx_mio_emm_int {
 	uint64_t u64;
 	struct cvmx_mio_emm_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_7_63:57;
 		uint64_t switch_err:1;
 		uint64_t switch_done:1;
@@ -762,13 +1131,25 @@
 		uint64_t dma_done:1;
 		uint64_t cmd_done:1;
 		uint64_t buf_done:1;
+#else
+		uint64_t buf_done:1;
+		uint64_t cmd_done:1;
+		uint64_t dma_done:1;
+		uint64_t cmd_err:1;
+		uint64_t dma_err:1;
+		uint64_t switch_done:1;
+		uint64_t switch_err:1;
+		uint64_t reserved_7_63:57;
+#endif
 	} s;
 	struct cvmx_mio_emm_int_s cn61xx;
+	struct cvmx_mio_emm_int_s cnf71xx;
 };
 
 union cvmx_mio_emm_int_en {
 	uint64_t u64;
 	struct cvmx_mio_emm_int_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_7_63:57;
 		uint64_t switch_err:1;
 		uint64_t switch_done:1;
@@ -777,13 +1158,25 @@
 		uint64_t dma_done:1;
 		uint64_t cmd_done:1;
 		uint64_t buf_done:1;
+#else
+		uint64_t buf_done:1;
+		uint64_t cmd_done:1;
+		uint64_t dma_done:1;
+		uint64_t cmd_err:1;
+		uint64_t dma_err:1;
+		uint64_t switch_done:1;
+		uint64_t switch_err:1;
+		uint64_t reserved_7_63:57;
+#endif
 	} s;
 	struct cvmx_mio_emm_int_en_s cn61xx;
+	struct cvmx_mio_emm_int_en_s cnf71xx;
 };
 
 union cvmx_mio_emm_modex {
 	uint64_t u64;
 	struct cvmx_mio_emm_modex_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_49_63:15;
 		uint64_t hs_timing:1;
 		uint64_t reserved_43_47:5;
@@ -792,38 +1185,66 @@
 		uint64_t power_class:4;
 		uint64_t clk_hi:16;
 		uint64_t clk_lo:16;
+#else
+		uint64_t clk_lo:16;
+		uint64_t clk_hi:16;
+		uint64_t power_class:4;
+		uint64_t reserved_36_39:4;
+		uint64_t bus_width:3;
+		uint64_t reserved_43_47:5;
+		uint64_t hs_timing:1;
+		uint64_t reserved_49_63:15;
+#endif
 	} s;
 	struct cvmx_mio_emm_modex_s cn61xx;
+	struct cvmx_mio_emm_modex_s cnf71xx;
 };
 
 union cvmx_mio_emm_rca {
 	uint64_t u64;
 	struct cvmx_mio_emm_rca_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t card_rca:16;
+#else
+		uint64_t card_rca:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_mio_emm_rca_s cn61xx;
+	struct cvmx_mio_emm_rca_s cnf71xx;
 };
 
 union cvmx_mio_emm_rsp_hi {
 	uint64_t u64;
 	struct cvmx_mio_emm_rsp_hi_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t dat:64;
+#else
+		uint64_t dat:64;
+#endif
 	} s;
 	struct cvmx_mio_emm_rsp_hi_s cn61xx;
+	struct cvmx_mio_emm_rsp_hi_s cnf71xx;
 };
 
 union cvmx_mio_emm_rsp_lo {
 	uint64_t u64;
 	struct cvmx_mio_emm_rsp_lo_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t dat:64;
+#else
+		uint64_t dat:64;
+#endif
 	} s;
 	struct cvmx_mio_emm_rsp_lo_s cn61xx;
+	struct cvmx_mio_emm_rsp_lo_s cnf71xx;
 };
 
 union cvmx_mio_emm_rsp_sts {
 	uint64_t u64;
 	struct cvmx_mio_emm_rsp_sts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_62_63:2;
 		uint64_t bus_id:2;
 		uint64_t cmd_val:1;
@@ -849,33 +1270,76 @@
 		uint64_t cmd_type:2;
 		uint64_t cmd_idx:6;
 		uint64_t cmd_done:1;
+#else
+		uint64_t cmd_done:1;
+		uint64_t cmd_idx:6;
+		uint64_t cmd_type:2;
+		uint64_t rsp_type:3;
+		uint64_t rsp_val:1;
+		uint64_t rsp_bad_sts:1;
+		uint64_t rsp_crc_err:1;
+		uint64_t rsp_timeout:1;
+		uint64_t stp_val:1;
+		uint64_t stp_bad_sts:1;
+		uint64_t stp_crc_err:1;
+		uint64_t stp_timeout:1;
+		uint64_t rsp_busybit:1;
+		uint64_t blk_crc_err:1;
+		uint64_t blk_timeout:1;
+		uint64_t dbuf:1;
+		uint64_t reserved_24_27:4;
+		uint64_t dbuf_err:1;
+		uint64_t reserved_29_55:27;
+		uint64_t dma_pend:1;
+		uint64_t dma_val:1;
+		uint64_t switch_val:1;
+		uint64_t cmd_val:1;
+		uint64_t bus_id:2;
+		uint64_t reserved_62_63:2;
+#endif
 	} s;
 	struct cvmx_mio_emm_rsp_sts_s cn61xx;
+	struct cvmx_mio_emm_rsp_sts_s cnf71xx;
 };
 
 union cvmx_mio_emm_sample {
 	uint64_t u64;
 	struct cvmx_mio_emm_sample_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_26_63:38;
 		uint64_t cmd_cnt:10;
 		uint64_t reserved_10_15:6;
 		uint64_t dat_cnt:10;
+#else
+		uint64_t dat_cnt:10;
+		uint64_t reserved_10_15:6;
+		uint64_t cmd_cnt:10;
+		uint64_t reserved_26_63:38;
+#endif
 	} s;
 	struct cvmx_mio_emm_sample_s cn61xx;
+	struct cvmx_mio_emm_sample_s cnf71xx;
 };
 
 union cvmx_mio_emm_sts_mask {
 	uint64_t u64;
 	struct cvmx_mio_emm_sts_mask_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t sts_msk:32;
+#else
+		uint64_t sts_msk:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_mio_emm_sts_mask_s cn61xx;
+	struct cvmx_mio_emm_sts_mask_s cnf71xx;
 };
 
 union cvmx_mio_emm_switch {
 	uint64_t u64;
 	struct cvmx_mio_emm_switch_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_62_63:2;
 		uint64_t bus_id:2;
 		uint64_t switch_exe:1;
@@ -890,23 +1354,50 @@
 		uint64_t power_class:4;
 		uint64_t clk_hi:16;
 		uint64_t clk_lo:16;
+#else
+		uint64_t clk_lo:16;
+		uint64_t clk_hi:16;
+		uint64_t power_class:4;
+		uint64_t reserved_36_39:4;
+		uint64_t bus_width:3;
+		uint64_t reserved_43_47:5;
+		uint64_t hs_timing:1;
+		uint64_t reserved_49_55:7;
+		uint64_t switch_err2:1;
+		uint64_t switch_err1:1;
+		uint64_t switch_err0:1;
+		uint64_t switch_exe:1;
+		uint64_t bus_id:2;
+		uint64_t reserved_62_63:2;
+#endif
 	} s;
 	struct cvmx_mio_emm_switch_s cn61xx;
+	struct cvmx_mio_emm_switch_s cnf71xx;
 };
 
 union cvmx_mio_emm_wdog {
 	uint64_t u64;
 	struct cvmx_mio_emm_wdog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_26_63:38;
 		uint64_t clk_cnt:26;
+#else
+		uint64_t clk_cnt:26;
+		uint64_t reserved_26_63:38;
+#endif
 	} s;
 	struct cvmx_mio_emm_wdog_s cn61xx;
+	struct cvmx_mio_emm_wdog_s cnf71xx;
 };
 
 union cvmx_mio_fus_bnk_datx {
 	uint64_t u64;
 	struct cvmx_mio_fus_bnk_datx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t dat:64;
+#else
+		uint64_t dat:64;
+#endif
 	} s;
 	struct cvmx_mio_fus_bnk_datx_s cn50xx;
 	struct cvmx_mio_fus_bnk_datx_s cn52xx;
@@ -921,13 +1412,19 @@
 	struct cvmx_mio_fus_bnk_datx_s cn66xx;
 	struct cvmx_mio_fus_bnk_datx_s cn68xx;
 	struct cvmx_mio_fus_bnk_datx_s cn68xxp1;
+	struct cvmx_mio_fus_bnk_datx_s cnf71xx;
 };
 
 union cvmx_mio_fus_dat0 {
 	uint64_t u64;
 	struct cvmx_mio_fus_dat0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t man_info:32;
+#else
+		uint64_t man_info:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_mio_fus_dat0_s cn30xx;
 	struct cvmx_mio_fus_dat0_s cn31xx;
@@ -946,13 +1443,19 @@
 	struct cvmx_mio_fus_dat0_s cn66xx;
 	struct cvmx_mio_fus_dat0_s cn68xx;
 	struct cvmx_mio_fus_dat0_s cn68xxp1;
+	struct cvmx_mio_fus_dat0_s cnf71xx;
 };
 
 union cvmx_mio_fus_dat1 {
 	uint64_t u64;
 	struct cvmx_mio_fus_dat1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t man_info:32;
+#else
+		uint64_t man_info:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_mio_fus_dat1_s cn30xx;
 	struct cvmx_mio_fus_dat1_s cn31xx;
@@ -971,11 +1474,13 @@
 	struct cvmx_mio_fus_dat1_s cn66xx;
 	struct cvmx_mio_fus_dat1_s cn68xx;
 	struct cvmx_mio_fus_dat1_s cn68xxp1;
+	struct cvmx_mio_fus_dat1_s cnf71xx;
 };
 
 union cvmx_mio_fus_dat2 {
 	uint64_t u64;
 	struct cvmx_mio_fus_dat2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t fus118:1;
 		uint64_t rom_info:10;
@@ -992,8 +1497,27 @@
 		uint64_t bist_dis:1;
 		uint64_t chip_id:8;
 		uint64_t reserved_0_15:16;
+#else
+		uint64_t reserved_0_15:16;
+		uint64_t chip_id:8;
+		uint64_t bist_dis:1;
+		uint64_t rst_sht:1;
+		uint64_t nocrypto:1;
+		uint64_t nomul:1;
+		uint64_t nodfa_cp2:1;
+		uint64_t nokasu:1;
+		uint64_t reserved_30_31:2;
+		uint64_t raid_en:1;
+		uint64_t fus318:1;
+		uint64_t dorm_crypto:1;
+		uint64_t power_limit:2;
+		uint64_t rom_info:10;
+		uint64_t fus118:1;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_mio_fus_dat2_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_29_63:35;
 		uint64_t nodfa_cp2:1;
 		uint64_t nomul:1;
@@ -1004,8 +1528,21 @@
 		uint64_t pll_off:4;
 		uint64_t reserved_1_11:11;
 		uint64_t pp_dis:1;
+#else
+		uint64_t pp_dis:1;
+		uint64_t reserved_1_11:11;
+		uint64_t pll_off:4;
+		uint64_t chip_id:8;
+		uint64_t bist_dis:1;
+		uint64_t rst_sht:1;
+		uint64_t nocrypto:1;
+		uint64_t nomul:1;
+		uint64_t nodfa_cp2:1;
+		uint64_t reserved_29_63:35;
+#endif
 	} cn30xx;
 	struct cvmx_mio_fus_dat2_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_29_63:35;
 		uint64_t nodfa_cp2:1;
 		uint64_t nomul:1;
@@ -1016,8 +1553,21 @@
 		uint64_t pll_off:4;
 		uint64_t reserved_2_11:10;
 		uint64_t pp_dis:2;
+#else
+		uint64_t pp_dis:2;
+		uint64_t reserved_2_11:10;
+		uint64_t pll_off:4;
+		uint64_t chip_id:8;
+		uint64_t bist_dis:1;
+		uint64_t rst_sht:1;
+		uint64_t nocrypto:1;
+		uint64_t nomul:1;
+		uint64_t nodfa_cp2:1;
+		uint64_t reserved_29_63:35;
+#endif
 	} cn31xx;
 	struct cvmx_mio_fus_dat2_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_29_63:35;
 		uint64_t nodfa_cp2:1;
 		uint64_t nomul:1;
@@ -1026,9 +1576,20 @@
 		uint64_t bist_dis:1;
 		uint64_t chip_id:8;
 		uint64_t pp_dis:16;
+#else
+		uint64_t pp_dis:16;
+		uint64_t chip_id:8;
+		uint64_t bist_dis:1;
+		uint64_t rst_sht:1;
+		uint64_t nocrypto:1;
+		uint64_t nomul:1;
+		uint64_t nodfa_cp2:1;
+		uint64_t reserved_29_63:35;
+#endif
 	} cn38xx;
 	struct cvmx_mio_fus_dat2_cn38xx cn38xxp2;
 	struct cvmx_mio_fus_dat2_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_34_63:30;
 		uint64_t fus318:1;
 		uint64_t raid_en:1;
@@ -1042,8 +1603,24 @@
 		uint64_t chip_id:8;
 		uint64_t reserved_2_15:14;
 		uint64_t pp_dis:2;
+#else
+		uint64_t pp_dis:2;
+		uint64_t reserved_2_15:14;
+		uint64_t chip_id:8;
+		uint64_t bist_dis:1;
+		uint64_t rst_sht:1;
+		uint64_t nocrypto:1;
+		uint64_t nomul:1;
+		uint64_t nodfa_cp2:1;
+		uint64_t nokasu:1;
+		uint64_t reserved_30_31:2;
+		uint64_t raid_en:1;
+		uint64_t fus318:1;
+		uint64_t reserved_34_63:30;
+#endif
 	} cn50xx;
 	struct cvmx_mio_fus_dat2_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_34_63:30;
 		uint64_t fus318:1;
 		uint64_t raid_en:1;
@@ -1057,9 +1634,25 @@
 		uint64_t chip_id:8;
 		uint64_t reserved_4_15:12;
 		uint64_t pp_dis:4;
+#else
+		uint64_t pp_dis:4;
+		uint64_t reserved_4_15:12;
+		uint64_t chip_id:8;
+		uint64_t bist_dis:1;
+		uint64_t rst_sht:1;
+		uint64_t nocrypto:1;
+		uint64_t nomul:1;
+		uint64_t nodfa_cp2:1;
+		uint64_t nokasu:1;
+		uint64_t reserved_30_31:2;
+		uint64_t raid_en:1;
+		uint64_t fus318:1;
+		uint64_t reserved_34_63:30;
+#endif
 	} cn52xx;
 	struct cvmx_mio_fus_dat2_cn52xx cn52xxp1;
 	struct cvmx_mio_fus_dat2_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_34_63:30;
 		uint64_t fus318:1;
 		uint64_t raid_en:1;
@@ -1073,9 +1666,25 @@
 		uint64_t chip_id:8;
 		uint64_t reserved_12_15:4;
 		uint64_t pp_dis:12;
+#else
+		uint64_t pp_dis:12;
+		uint64_t reserved_12_15:4;
+		uint64_t chip_id:8;
+		uint64_t bist_dis:1;
+		uint64_t rst_sht:1;
+		uint64_t nocrypto:1;
+		uint64_t nomul:1;
+		uint64_t nodfa_cp2:1;
+		uint64_t nokasu:1;
+		uint64_t reserved_30_31:2;
+		uint64_t raid_en:1;
+		uint64_t fus318:1;
+		uint64_t reserved_34_63:30;
+#endif
 	} cn56xx;
 	struct cvmx_mio_fus_dat2_cn56xx cn56xxp1;
 	struct cvmx_mio_fus_dat2_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_30_63:34;
 		uint64_t nokasu:1;
 		uint64_t nodfa_cp2:1;
@@ -1085,9 +1694,21 @@
 		uint64_t bist_dis:1;
 		uint64_t chip_id:8;
 		uint64_t pp_dis:16;
+#else
+		uint64_t pp_dis:16;
+		uint64_t chip_id:8;
+		uint64_t bist_dis:1;
+		uint64_t rst_sht:1;
+		uint64_t nocrypto:1;
+		uint64_t nomul:1;
+		uint64_t nodfa_cp2:1;
+		uint64_t nokasu:1;
+		uint64_t reserved_30_63:34;
+#endif
 	} cn58xx;
 	struct cvmx_mio_fus_dat2_cn58xx cn58xxp1;
 	struct cvmx_mio_fus_dat2_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t fus118:1;
 		uint64_t rom_info:10;
@@ -1103,8 +1724,26 @@
 		uint64_t chip_id:8;
 		uint64_t reserved_4_15:12;
 		uint64_t pp_dis:4;
+#else
+		uint64_t pp_dis:4;
+		uint64_t reserved_4_15:12;
+		uint64_t chip_id:8;
+		uint64_t reserved_24_25:2;
+		uint64_t nocrypto:1;
+		uint64_t nomul:1;
+		uint64_t nodfa_cp2:1;
+		uint64_t reserved_29_31:3;
+		uint64_t raid_en:1;
+		uint64_t fus318:1;
+		uint64_t dorm_crypto:1;
+		uint64_t power_limit:2;
+		uint64_t rom_info:10;
+		uint64_t fus118:1;
+		uint64_t reserved_48_63:16;
+#endif
 	} cn61xx;
 	struct cvmx_mio_fus_dat2_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_35_63:29;
 		uint64_t dorm_crypto:1;
 		uint64_t fus318:1;
@@ -1117,9 +1756,24 @@
 		uint64_t chip_id:8;
 		uint64_t reserved_6_15:10;
 		uint64_t pp_dis:6;
+#else
+		uint64_t pp_dis:6;
+		uint64_t reserved_6_15:10;
+		uint64_t chip_id:8;
+		uint64_t reserved_24_25:2;
+		uint64_t nocrypto:1;
+		uint64_t nomul:1;
+		uint64_t nodfa_cp2:1;
+		uint64_t reserved_29_31:3;
+		uint64_t raid_en:1;
+		uint64_t fus318:1;
+		uint64_t dorm_crypto:1;
+		uint64_t reserved_35_63:29;
+#endif
 	} cn63xx;
 	struct cvmx_mio_fus_dat2_cn63xx cn63xxp1;
 	struct cvmx_mio_fus_dat2_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t fus118:1;
 		uint64_t rom_info:10;
@@ -1135,8 +1789,26 @@
 		uint64_t chip_id:8;
 		uint64_t reserved_10_15:6;
 		uint64_t pp_dis:10;
+#else
+		uint64_t pp_dis:10;
+		uint64_t reserved_10_15:6;
+		uint64_t chip_id:8;
+		uint64_t reserved_24_25:2;
+		uint64_t nocrypto:1;
+		uint64_t nomul:1;
+		uint64_t nodfa_cp2:1;
+		uint64_t reserved_29_31:3;
+		uint64_t raid_en:1;
+		uint64_t fus318:1;
+		uint64_t dorm_crypto:1;
+		uint64_t power_limit:2;
+		uint64_t rom_info:10;
+		uint64_t fus118:1;
+		uint64_t reserved_48_63:16;
+#endif
 	} cn66xx;
 	struct cvmx_mio_fus_dat2_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_37_63:27;
 		uint64_t power_limit:2;
 		uint64_t dorm_crypto:1;
@@ -1149,13 +1821,29 @@
 		uint64_t reserved_24_25:2;
 		uint64_t chip_id:8;
 		uint64_t reserved_0_15:16;
+#else
+		uint64_t reserved_0_15:16;
+		uint64_t chip_id:8;
+		uint64_t reserved_24_25:2;
+		uint64_t nocrypto:1;
+		uint64_t nomul:1;
+		uint64_t nodfa_cp2:1;
+		uint64_t reserved_29_31:3;
+		uint64_t raid_en:1;
+		uint64_t fus318:1;
+		uint64_t dorm_crypto:1;
+		uint64_t power_limit:2;
+		uint64_t reserved_37_63:27;
+#endif
 	} cn68xx;
 	struct cvmx_mio_fus_dat2_cn68xx cn68xxp1;
+	struct cvmx_mio_fus_dat2_cn61xx cnf71xx;
 };
 
 union cvmx_mio_fus_dat3 {
 	uint64_t u64;
 	struct cvmx_mio_fus_dat3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_58_63:6;
 		uint64_t pll_ctl:10;
 		uint64_t dfa_info_dte:3;
@@ -1174,8 +1862,29 @@
 		uint64_t nozip:1;
 		uint64_t nodfa_dte:1;
 		uint64_t icache:24;
+#else
+		uint64_t icache:24;
+		uint64_t nodfa_dte:1;
+		uint64_t nozip:1;
+		uint64_t efus_ign:1;
+		uint64_t efus_lck:1;
+		uint64_t bar2_en:1;
+		uint64_t reserved_29_30:2;
+		uint64_t pll_div4:1;
+		uint64_t l2c_crip:3;
+		uint64_t pll_half_dis:1;
+		uint64_t efus_lck_man:1;
+		uint64_t efus_lck_rsv:1;
+		uint64_t ema:2;
+		uint64_t reserved_40_40:1;
+		uint64_t dfa_info_clm:4;
+		uint64_t dfa_info_dte:3;
+		uint64_t pll_ctl:10;
+		uint64_t reserved_58_63:6;
+#endif
 	} s;
 	struct cvmx_mio_fus_dat3_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t pll_div4:1;
 		uint64_t reserved_29_30:2;
@@ -1185,8 +1894,20 @@
 		uint64_t nozip:1;
 		uint64_t nodfa_dte:1;
 		uint64_t icache:24;
+#else
+		uint64_t icache:24;
+		uint64_t nodfa_dte:1;
+		uint64_t nozip:1;
+		uint64_t efus_ign:1;
+		uint64_t efus_lck:1;
+		uint64_t bar2_en:1;
+		uint64_t reserved_29_30:2;
+		uint64_t pll_div4:1;
+		uint64_t reserved_32_63:32;
+#endif
 	} cn30xx;
 	struct cvmx_mio_fus_dat3_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t pll_div4:1;
 		uint64_t zip_crip:2;
@@ -1196,8 +1917,20 @@
 		uint64_t nozip:1;
 		uint64_t nodfa_dte:1;
 		uint64_t icache:24;
+#else
+		uint64_t icache:24;
+		uint64_t nodfa_dte:1;
+		uint64_t nozip:1;
+		uint64_t efus_ign:1;
+		uint64_t efus_lck:1;
+		uint64_t bar2_en:1;
+		uint64_t zip_crip:2;
+		uint64_t pll_div4:1;
+		uint64_t reserved_32_63:32;
+#endif
 	} cn31xx;
 	struct cvmx_mio_fus_dat3_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_31_63:33;
 		uint64_t zip_crip:2;
 		uint64_t bar2_en:1;
@@ -1206,8 +1939,19 @@
 		uint64_t nozip:1;
 		uint64_t nodfa_dte:1;
 		uint64_t icache:24;
+#else
+		uint64_t icache:24;
+		uint64_t nodfa_dte:1;
+		uint64_t nozip:1;
+		uint64_t efus_ign:1;
+		uint64_t efus_lck:1;
+		uint64_t bar2_en:1;
+		uint64_t zip_crip:2;
+		uint64_t reserved_31_63:33;
+#endif
 	} cn38xx;
 	struct cvmx_mio_fus_dat3_cn38xxp2 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_29_63:35;
 		uint64_t bar2_en:1;
 		uint64_t efus_lck:1;
@@ -1215,6 +1959,15 @@
 		uint64_t nozip:1;
 		uint64_t nodfa_dte:1;
 		uint64_t icache:24;
+#else
+		uint64_t icache:24;
+		uint64_t nodfa_dte:1;
+		uint64_t nozip:1;
+		uint64_t efus_ign:1;
+		uint64_t efus_lck:1;
+		uint64_t bar2_en:1;
+		uint64_t reserved_29_63:35;
+#endif
 	} cn38xxp2;
 	struct cvmx_mio_fus_dat3_cn38xx cn50xx;
 	struct cvmx_mio_fus_dat3_cn38xx cn52xx;
@@ -1224,6 +1977,7 @@
 	struct cvmx_mio_fus_dat3_cn38xx cn58xx;
 	struct cvmx_mio_fus_dat3_cn38xx cn58xxp1;
 	struct cvmx_mio_fus_dat3_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_58_63:6;
 		uint64_t pll_ctl:10;
 		uint64_t dfa_info_dte:3;
@@ -1242,21 +1996,49 @@
 		uint64_t nozip:1;
 		uint64_t nodfa_dte:1;
 		uint64_t reserved_0_23:24;
+#else
+		uint64_t reserved_0_23:24;
+		uint64_t nodfa_dte:1;
+		uint64_t nozip:1;
+		uint64_t efus_ign:1;
+		uint64_t efus_lck:1;
+		uint64_t bar2_en:1;
+		uint64_t zip_info:2;
+		uint64_t reserved_31_31:1;
+		uint64_t l2c_crip:3;
+		uint64_t pll_half_dis:1;
+		uint64_t efus_lck_man:1;
+		uint64_t efus_lck_rsv:1;
+		uint64_t ema:2;
+		uint64_t reserved_40_40:1;
+		uint64_t dfa_info_clm:4;
+		uint64_t dfa_info_dte:3;
+		uint64_t pll_ctl:10;
+		uint64_t reserved_58_63:6;
+#endif
 	} cn61xx;
 	struct cvmx_mio_fus_dat3_cn61xx cn63xx;
 	struct cvmx_mio_fus_dat3_cn61xx cn63xxp1;
 	struct cvmx_mio_fus_dat3_cn61xx cn66xx;
 	struct cvmx_mio_fus_dat3_cn61xx cn68xx;
 	struct cvmx_mio_fus_dat3_cn61xx cn68xxp1;
+	struct cvmx_mio_fus_dat3_cn61xx cnf71xx;
 };
 
 union cvmx_mio_fus_ema {
 	uint64_t u64;
 	struct cvmx_mio_fus_ema_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_7_63:57;
 		uint64_t eff_ema:3;
 		uint64_t reserved_3_3:1;
 		uint64_t ema:3;
+#else
+		uint64_t ema:3;
+		uint64_t reserved_3_3:1;
+		uint64_t eff_ema:3;
+		uint64_t reserved_7_63:57;
+#endif
 	} s;
 	struct cvmx_mio_fus_ema_s cn50xx;
 	struct cvmx_mio_fus_ema_s cn52xx;
@@ -1264,8 +2046,13 @@
 	struct cvmx_mio_fus_ema_s cn56xx;
 	struct cvmx_mio_fus_ema_s cn56xxp1;
 	struct cvmx_mio_fus_ema_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t ema:2;
+#else
+		uint64_t ema:2;
+		uint64_t reserved_2_63:62;
+#endif
 	} cn58xx;
 	struct cvmx_mio_fus_ema_cn58xx cn58xxp1;
 	struct cvmx_mio_fus_ema_s cn61xx;
@@ -1274,12 +2061,17 @@
 	struct cvmx_mio_fus_ema_s cn66xx;
 	struct cvmx_mio_fus_ema_s cn68xx;
 	struct cvmx_mio_fus_ema_s cn68xxp1;
+	struct cvmx_mio_fus_ema_s cnf71xx;
 };
 
 union cvmx_mio_fus_pdf {
 	uint64_t u64;
 	struct cvmx_mio_fus_pdf_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t pdf:64;
+#else
+		uint64_t pdf:64;
+#endif
 	} s;
 	struct cvmx_mio_fus_pdf_s cn50xx;
 	struct cvmx_mio_fus_pdf_s cn52xx;
@@ -1293,11 +2085,13 @@
 	struct cvmx_mio_fus_pdf_s cn66xx;
 	struct cvmx_mio_fus_pdf_s cn68xx;
 	struct cvmx_mio_fus_pdf_s cn68xxp1;
+	struct cvmx_mio_fus_pdf_s cnf71xx;
 };
 
 union cvmx_mio_fus_pll {
 	uint64_t u64;
 	struct cvmx_mio_fus_pll_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t rclk_align_r:8;
 		uint64_t rclk_align_l:8;
@@ -1308,11 +2102,29 @@
 		uint64_t pnr_cout_sel:2;
 		uint64_t rfslip:1;
 		uint64_t fbslip:1;
+#else
+		uint64_t fbslip:1;
+		uint64_t rfslip:1;
+		uint64_t pnr_cout_sel:2;
+		uint64_t pnr_cout_rst:1;
+		uint64_t c_cout_sel:2;
+		uint64_t c_cout_rst:1;
+		uint64_t reserved_8_31:24;
+		uint64_t rclk_align_l:8;
+		uint64_t rclk_align_r:8;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_mio_fus_pll_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t rfslip:1;
 		uint64_t fbslip:1;
+#else
+		uint64_t fbslip:1;
+		uint64_t rfslip:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} cn50xx;
 	struct cvmx_mio_fus_pll_cn50xx cn52xx;
 	struct cvmx_mio_fus_pll_cn50xx cn52xxp1;
@@ -1321,6 +2133,7 @@
 	struct cvmx_mio_fus_pll_cn50xx cn58xx;
 	struct cvmx_mio_fus_pll_cn50xx cn58xxp1;
 	struct cvmx_mio_fus_pll_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t c_cout_rst:1;
 		uint64_t c_cout_sel:2;
@@ -1328,24 +2141,45 @@
 		uint64_t pnr_cout_sel:2;
 		uint64_t rfslip:1;
 		uint64_t fbslip:1;
+#else
+		uint64_t fbslip:1;
+		uint64_t rfslip:1;
+		uint64_t pnr_cout_sel:2;
+		uint64_t pnr_cout_rst:1;
+		uint64_t c_cout_sel:2;
+		uint64_t c_cout_rst:1;
+		uint64_t reserved_8_63:56;
+#endif
 	} cn61xx;
 	struct cvmx_mio_fus_pll_cn61xx cn63xx;
 	struct cvmx_mio_fus_pll_cn61xx cn63xxp1;
 	struct cvmx_mio_fus_pll_cn61xx cn66xx;
 	struct cvmx_mio_fus_pll_s cn68xx;
 	struct cvmx_mio_fus_pll_s cn68xxp1;
+	struct cvmx_mio_fus_pll_cn61xx cnf71xx;
 };
 
 union cvmx_mio_fus_prog {
 	uint64_t u64;
 	struct cvmx_mio_fus_prog_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t soft:1;
 		uint64_t prog:1;
+#else
+		uint64_t prog:1;
+		uint64_t soft:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_mio_fus_prog_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t prog:1;
+#else
+		uint64_t prog:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} cn30xx;
 	struct cvmx_mio_fus_prog_cn30xx cn31xx;
 	struct cvmx_mio_fus_prog_cn30xx cn38xx;
@@ -1363,25 +2197,44 @@
 	struct cvmx_mio_fus_prog_s cn66xx;
 	struct cvmx_mio_fus_prog_s cn68xx;
 	struct cvmx_mio_fus_prog_s cn68xxp1;
+	struct cvmx_mio_fus_prog_s cnf71xx;
 };
 
 union cvmx_mio_fus_prog_times {
 	uint64_t u64;
 	struct cvmx_mio_fus_prog_times_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_35_63:29;
 		uint64_t vgate_pin:1;
 		uint64_t fsrc_pin:1;
 		uint64_t prog_pin:1;
 		uint64_t reserved_6_31:26;
 		uint64_t setup:6;
+#else
+		uint64_t setup:6;
+		uint64_t reserved_6_31:26;
+		uint64_t prog_pin:1;
+		uint64_t fsrc_pin:1;
+		uint64_t vgate_pin:1;
+		uint64_t reserved_35_63:29;
+#endif
 	} s;
 	struct cvmx_mio_fus_prog_times_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_33_63:31;
 		uint64_t prog_pin:1;
 		uint64_t out:8;
 		uint64_t sclk_lo:4;
 		uint64_t sclk_hi:12;
 		uint64_t setup:8;
+#else
+		uint64_t setup:8;
+		uint64_t sclk_hi:12;
+		uint64_t sclk_lo:4;
+		uint64_t out:8;
+		uint64_t prog_pin:1;
+		uint64_t reserved_33_63:31;
+#endif
 	} cn50xx;
 	struct cvmx_mio_fus_prog_times_cn50xx cn52xx;
 	struct cvmx_mio_fus_prog_times_cn50xx cn52xxp1;
@@ -1390,6 +2243,7 @@
 	struct cvmx_mio_fus_prog_times_cn50xx cn58xx;
 	struct cvmx_mio_fus_prog_times_cn50xx cn58xxp1;
 	struct cvmx_mio_fus_prog_times_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_35_63:29;
 		uint64_t vgate_pin:1;
 		uint64_t fsrc_pin:1;
@@ -1398,17 +2252,29 @@
 		uint64_t sclk_lo:4;
 		uint64_t sclk_hi:15;
 		uint64_t setup:6;
+#else
+		uint64_t setup:6;
+		uint64_t sclk_hi:15;
+		uint64_t sclk_lo:4;
+		uint64_t out:7;
+		uint64_t prog_pin:1;
+		uint64_t fsrc_pin:1;
+		uint64_t vgate_pin:1;
+		uint64_t reserved_35_63:29;
+#endif
 	} cn61xx;
 	struct cvmx_mio_fus_prog_times_cn61xx cn63xx;
 	struct cvmx_mio_fus_prog_times_cn61xx cn63xxp1;
 	struct cvmx_mio_fus_prog_times_cn61xx cn66xx;
 	struct cvmx_mio_fus_prog_times_cn61xx cn68xx;
 	struct cvmx_mio_fus_prog_times_cn61xx cn68xxp1;
+	struct cvmx_mio_fus_prog_times_cn61xx cnf71xx;
 };
 
 union cvmx_mio_fus_rcmd {
 	uint64_t u64;
 	struct cvmx_mio_fus_rcmd_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_24_63:40;
 		uint64_t dat:8;
 		uint64_t reserved_13_15:3;
@@ -1416,8 +2282,18 @@
 		uint64_t reserved_9_11:3;
 		uint64_t efuse:1;
 		uint64_t addr:8;
+#else
+		uint64_t addr:8;
+		uint64_t efuse:1;
+		uint64_t reserved_9_11:3;
+		uint64_t pend:1;
+		uint64_t reserved_13_15:3;
+		uint64_t dat:8;
+		uint64_t reserved_24_63:40;
+#endif
 	} s;
 	struct cvmx_mio_fus_rcmd_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_24_63:40;
 		uint64_t dat:8;
 		uint64_t reserved_13_15:3;
@@ -1426,6 +2302,16 @@
 		uint64_t efuse:1;
 		uint64_t reserved_7_7:1;
 		uint64_t addr:7;
+#else
+		uint64_t addr:7;
+		uint64_t reserved_7_7:1;
+		uint64_t efuse:1;
+		uint64_t reserved_9_11:3;
+		uint64_t pend:1;
+		uint64_t reserved_13_15:3;
+		uint64_t dat:8;
+		uint64_t reserved_24_63:40;
+#endif
 	} cn30xx;
 	struct cvmx_mio_fus_rcmd_cn30xx cn31xx;
 	struct cvmx_mio_fus_rcmd_cn30xx cn38xx;
@@ -1443,17 +2329,27 @@
 	struct cvmx_mio_fus_rcmd_s cn66xx;
 	struct cvmx_mio_fus_rcmd_s cn68xx;
 	struct cvmx_mio_fus_rcmd_s cn68xxp1;
+	struct cvmx_mio_fus_rcmd_s cnf71xx;
 };
 
 union cvmx_mio_fus_read_times {
 	uint64_t u64;
 	struct cvmx_mio_fus_read_times_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_26_63:38;
 		uint64_t sch:4;
 		uint64_t fsh:4;
 		uint64_t prh:4;
 		uint64_t sdh:4;
 		uint64_t setup:10;
+#else
+		uint64_t setup:10;
+		uint64_t sdh:4;
+		uint64_t prh:4;
+		uint64_t fsh:4;
+		uint64_t sch:4;
+		uint64_t reserved_26_63:38;
+#endif
 	} s;
 	struct cvmx_mio_fus_read_times_s cn61xx;
 	struct cvmx_mio_fus_read_times_s cn63xx;
@@ -1461,16 +2357,25 @@
 	struct cvmx_mio_fus_read_times_s cn66xx;
 	struct cvmx_mio_fus_read_times_s cn68xx;
 	struct cvmx_mio_fus_read_times_s cn68xxp1;
+	struct cvmx_mio_fus_read_times_s cnf71xx;
 };
 
 union cvmx_mio_fus_repair_res0 {
 	uint64_t u64;
 	struct cvmx_mio_fus_repair_res0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_55_63:9;
 		uint64_t too_many:1;
 		uint64_t repair2:18;
 		uint64_t repair1:18;
 		uint64_t repair0:18;
+#else
+		uint64_t repair0:18;
+		uint64_t repair1:18;
+		uint64_t repair2:18;
+		uint64_t too_many:1;
+		uint64_t reserved_55_63:9;
+#endif
 	} s;
 	struct cvmx_mio_fus_repair_res0_s cn61xx;
 	struct cvmx_mio_fus_repair_res0_s cn63xx;
@@ -1478,15 +2383,23 @@
 	struct cvmx_mio_fus_repair_res0_s cn66xx;
 	struct cvmx_mio_fus_repair_res0_s cn68xx;
 	struct cvmx_mio_fus_repair_res0_s cn68xxp1;
+	struct cvmx_mio_fus_repair_res0_s cnf71xx;
 };
 
 union cvmx_mio_fus_repair_res1 {
 	uint64_t u64;
 	struct cvmx_mio_fus_repair_res1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_54_63:10;
 		uint64_t repair5:18;
 		uint64_t repair4:18;
 		uint64_t repair3:18;
+#else
+		uint64_t repair3:18;
+		uint64_t repair4:18;
+		uint64_t repair5:18;
+		uint64_t reserved_54_63:10;
+#endif
 	} s;
 	struct cvmx_mio_fus_repair_res1_s cn61xx;
 	struct cvmx_mio_fus_repair_res1_s cn63xx;
@@ -1494,13 +2407,19 @@
 	struct cvmx_mio_fus_repair_res1_s cn66xx;
 	struct cvmx_mio_fus_repair_res1_s cn68xx;
 	struct cvmx_mio_fus_repair_res1_s cn68xxp1;
+	struct cvmx_mio_fus_repair_res1_s cnf71xx;
 };
 
 union cvmx_mio_fus_repair_res2 {
 	uint64_t u64;
 	struct cvmx_mio_fus_repair_res2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_18_63:46;
 		uint64_t repair6:18;
+#else
+		uint64_t repair6:18;
+		uint64_t reserved_18_63:46;
+#endif
 	} s;
 	struct cvmx_mio_fus_repair_res2_s cn61xx;
 	struct cvmx_mio_fus_repair_res2_s cn63xx;
@@ -1508,15 +2427,23 @@
 	struct cvmx_mio_fus_repair_res2_s cn66xx;
 	struct cvmx_mio_fus_repair_res2_s cn68xx;
 	struct cvmx_mio_fus_repair_res2_s cn68xxp1;
+	struct cvmx_mio_fus_repair_res2_s cnf71xx;
 };
 
 union cvmx_mio_fus_spr_repair_res {
 	uint64_t u64;
 	struct cvmx_mio_fus_spr_repair_res_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_42_63:22;
 		uint64_t repair2:14;
 		uint64_t repair1:14;
 		uint64_t repair0:14;
+#else
+		uint64_t repair0:14;
+		uint64_t repair1:14;
+		uint64_t repair2:14;
+		uint64_t reserved_42_63:22;
+#endif
 	} s;
 	struct cvmx_mio_fus_spr_repair_res_s cn30xx;
 	struct cvmx_mio_fus_spr_repair_res_s cn31xx;
@@ -1534,13 +2461,19 @@
 	struct cvmx_mio_fus_spr_repair_res_s cn66xx;
 	struct cvmx_mio_fus_spr_repair_res_s cn68xx;
 	struct cvmx_mio_fus_spr_repair_res_s cn68xxp1;
+	struct cvmx_mio_fus_spr_repair_res_s cnf71xx;
 };
 
 union cvmx_mio_fus_spr_repair_sum {
 	uint64_t u64;
 	struct cvmx_mio_fus_spr_repair_sum_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t too_many:1;
+#else
+		uint64_t too_many:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_mio_fus_spr_repair_sum_s cn30xx;
 	struct cvmx_mio_fus_spr_repair_sum_s cn31xx;
@@ -1558,23 +2491,35 @@
 	struct cvmx_mio_fus_spr_repair_sum_s cn66xx;
 	struct cvmx_mio_fus_spr_repair_sum_s cn68xx;
 	struct cvmx_mio_fus_spr_repair_sum_s cn68xxp1;
+	struct cvmx_mio_fus_spr_repair_sum_s cnf71xx;
 };
 
 union cvmx_mio_fus_tgg {
 	uint64_t u64;
 	struct cvmx_mio_fus_tgg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t val:1;
 		uint64_t dat:63;
+#else
+		uint64_t dat:63;
+		uint64_t val:1;
+#endif
 	} s;
 	struct cvmx_mio_fus_tgg_s cn61xx;
 	struct cvmx_mio_fus_tgg_s cn66xx;
+	struct cvmx_mio_fus_tgg_s cnf71xx;
 };
 
 union cvmx_mio_fus_unlock {
 	uint64_t u64;
 	struct cvmx_mio_fus_unlock_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_24_63:40;
 		uint64_t key:24;
+#else
+		uint64_t key:24;
+		uint64_t reserved_24_63:40;
+#endif
 	} s;
 	struct cvmx_mio_fus_unlock_s cn30xx;
 	struct cvmx_mio_fus_unlock_s cn31xx;
@@ -1583,20 +2528,35 @@
 union cvmx_mio_fus_wadr {
 	uint64_t u64;
 	struct cvmx_mio_fus_wadr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t addr:10;
+#else
+		uint64_t addr:10;
+		uint64_t reserved_10_63:54;
+#endif
 	} s;
 	struct cvmx_mio_fus_wadr_s cn30xx;
 	struct cvmx_mio_fus_wadr_s cn31xx;
 	struct cvmx_mio_fus_wadr_s cn38xx;
 	struct cvmx_mio_fus_wadr_s cn38xxp2;
 	struct cvmx_mio_fus_wadr_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t addr:2;
+#else
+		uint64_t addr:2;
+		uint64_t reserved_2_63:62;
+#endif
 	} cn50xx;
 	struct cvmx_mio_fus_wadr_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_3_63:61;
 		uint64_t addr:3;
+#else
+		uint64_t addr:3;
+		uint64_t reserved_3_63:61;
+#endif
 	} cn52xx;
 	struct cvmx_mio_fus_wadr_cn52xx cn52xxp1;
 	struct cvmx_mio_fus_wadr_cn52xx cn56xx;
@@ -1604,22 +2564,34 @@
 	struct cvmx_mio_fus_wadr_cn50xx cn58xx;
 	struct cvmx_mio_fus_wadr_cn50xx cn58xxp1;
 	struct cvmx_mio_fus_wadr_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t addr:4;
+#else
+		uint64_t addr:4;
+		uint64_t reserved_4_63:60;
+#endif
 	} cn61xx;
 	struct cvmx_mio_fus_wadr_cn61xx cn63xx;
 	struct cvmx_mio_fus_wadr_cn61xx cn63xxp1;
 	struct cvmx_mio_fus_wadr_cn61xx cn66xx;
 	struct cvmx_mio_fus_wadr_cn61xx cn68xx;
 	struct cvmx_mio_fus_wadr_cn61xx cn68xxp1;
+	struct cvmx_mio_fus_wadr_cn61xx cnf71xx;
 };
 
 union cvmx_mio_gpio_comp {
 	uint64_t u64;
 	struct cvmx_mio_gpio_comp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t pctl:6;
 		uint64_t nctl:6;
+#else
+		uint64_t nctl:6;
+		uint64_t pctl:6;
+		uint64_t reserved_12_63:52;
+#endif
 	} s;
 	struct cvmx_mio_gpio_comp_s cn61xx;
 	struct cvmx_mio_gpio_comp_s cn63xx;
@@ -1627,11 +2599,13 @@
 	struct cvmx_mio_gpio_comp_s cn66xx;
 	struct cvmx_mio_gpio_comp_s cn68xx;
 	struct cvmx_mio_gpio_comp_s cn68xxp1;
+	struct cvmx_mio_gpio_comp_s cnf71xx;
 };
 
 union cvmx_mio_ndf_dma_cfg {
 	uint64_t u64;
 	struct cvmx_mio_ndf_dma_cfg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t en:1;
 		uint64_t rw:1;
 		uint64_t clr:1;
@@ -1642,6 +2616,18 @@
 		uint64_t endian:1;
 		uint64_t size:20;
 		uint64_t adr:36;
+#else
+		uint64_t adr:36;
+		uint64_t size:20;
+		uint64_t endian:1;
+		uint64_t swap8:1;
+		uint64_t swap16:1;
+		uint64_t swap32:1;
+		uint64_t reserved_60_60:1;
+		uint64_t clr:1;
+		uint64_t rw:1;
+		uint64_t en:1;
+#endif
 	} s;
 	struct cvmx_mio_ndf_dma_cfg_s cn52xx;
 	struct cvmx_mio_ndf_dma_cfg_s cn61xx;
@@ -1650,13 +2636,19 @@
 	struct cvmx_mio_ndf_dma_cfg_s cn66xx;
 	struct cvmx_mio_ndf_dma_cfg_s cn68xx;
 	struct cvmx_mio_ndf_dma_cfg_s cn68xxp1;
+	struct cvmx_mio_ndf_dma_cfg_s cnf71xx;
 };
 
 union cvmx_mio_ndf_dma_int {
 	uint64_t u64;
 	struct cvmx_mio_ndf_dma_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t done:1;
+#else
+		uint64_t done:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_mio_ndf_dma_int_s cn52xx;
 	struct cvmx_mio_ndf_dma_int_s cn61xx;
@@ -1665,13 +2657,19 @@
 	struct cvmx_mio_ndf_dma_int_s cn66xx;
 	struct cvmx_mio_ndf_dma_int_s cn68xx;
 	struct cvmx_mio_ndf_dma_int_s cn68xxp1;
+	struct cvmx_mio_ndf_dma_int_s cnf71xx;
 };
 
 union cvmx_mio_ndf_dma_int_en {
 	uint64_t u64;
 	struct cvmx_mio_ndf_dma_int_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t done:1;
+#else
+		uint64_t done:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_mio_ndf_dma_int_en_s cn52xx;
 	struct cvmx_mio_ndf_dma_int_en_s cn61xx;
@@ -1680,13 +2678,19 @@
 	struct cvmx_mio_ndf_dma_int_en_s cn66xx;
 	struct cvmx_mio_ndf_dma_int_en_s cn68xx;
 	struct cvmx_mio_ndf_dma_int_en_s cn68xxp1;
+	struct cvmx_mio_ndf_dma_int_en_s cnf71xx;
 };
 
 union cvmx_mio_pll_ctl {
 	uint64_t u64;
 	struct cvmx_mio_pll_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t bw_ctl:5;
+#else
+		uint64_t bw_ctl:5;
+		uint64_t reserved_5_63:59;
+#endif
 	} s;
 	struct cvmx_mio_pll_ctl_s cn30xx;
 	struct cvmx_mio_pll_ctl_s cn31xx;
@@ -1695,8 +2699,13 @@
 union cvmx_mio_pll_setting {
 	uint64_t u64;
 	struct cvmx_mio_pll_setting_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_17_63:47;
 		uint64_t setting:17;
+#else
+		uint64_t setting:17;
+		uint64_t reserved_17_63:47;
+#endif
 	} s;
 	struct cvmx_mio_pll_setting_s cn30xx;
 	struct cvmx_mio_pll_setting_s cn31xx;
@@ -1705,49 +2714,73 @@
 union cvmx_mio_ptp_ckout_hi_incr {
 	uint64_t u64;
 	struct cvmx_mio_ptp_ckout_hi_incr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t nanosec:32;
 		uint64_t frnanosec:32;
+#else
+		uint64_t frnanosec:32;
+		uint64_t nanosec:32;
+#endif
 	} s;
 	struct cvmx_mio_ptp_ckout_hi_incr_s cn61xx;
 	struct cvmx_mio_ptp_ckout_hi_incr_s cn66xx;
 	struct cvmx_mio_ptp_ckout_hi_incr_s cn68xx;
+	struct cvmx_mio_ptp_ckout_hi_incr_s cnf71xx;
 };
 
 union cvmx_mio_ptp_ckout_lo_incr {
 	uint64_t u64;
 	struct cvmx_mio_ptp_ckout_lo_incr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t nanosec:32;
 		uint64_t frnanosec:32;
+#else
+		uint64_t frnanosec:32;
+		uint64_t nanosec:32;
+#endif
 	} s;
 	struct cvmx_mio_ptp_ckout_lo_incr_s cn61xx;
 	struct cvmx_mio_ptp_ckout_lo_incr_s cn66xx;
 	struct cvmx_mio_ptp_ckout_lo_incr_s cn68xx;
+	struct cvmx_mio_ptp_ckout_lo_incr_s cnf71xx;
 };
 
 union cvmx_mio_ptp_ckout_thresh_hi {
 	uint64_t u64;
 	struct cvmx_mio_ptp_ckout_thresh_hi_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t nanosec:64;
+#else
+		uint64_t nanosec:64;
+#endif
 	} s;
 	struct cvmx_mio_ptp_ckout_thresh_hi_s cn61xx;
 	struct cvmx_mio_ptp_ckout_thresh_hi_s cn66xx;
 	struct cvmx_mio_ptp_ckout_thresh_hi_s cn68xx;
+	struct cvmx_mio_ptp_ckout_thresh_hi_s cnf71xx;
 };
 
 union cvmx_mio_ptp_ckout_thresh_lo {
 	uint64_t u64;
 	struct cvmx_mio_ptp_ckout_thresh_lo_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t frnanosec:32;
+#else
+		uint64_t frnanosec:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_mio_ptp_ckout_thresh_lo_s cn61xx;
 	struct cvmx_mio_ptp_ckout_thresh_lo_s cn66xx;
 	struct cvmx_mio_ptp_ckout_thresh_lo_s cn68xx;
+	struct cvmx_mio_ptp_ckout_thresh_lo_s cnf71xx;
 };
 
 union cvmx_mio_ptp_clock_cfg {
 	uint64_t u64;
 	struct cvmx_mio_ptp_clock_cfg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_42_63:22;
 		uint64_t pps:1;
 		uint64_t ckout:1;
@@ -1768,9 +2801,32 @@
 		uint64_t ext_clk_in:6;
 		uint64_t ext_clk_en:1;
 		uint64_t ptp_en:1;
+#else
+		uint64_t ptp_en:1;
+		uint64_t ext_clk_en:1;
+		uint64_t ext_clk_in:6;
+		uint64_t tstmp_en:1;
+		uint64_t tstmp_edge:1;
+		uint64_t tstmp_in:6;
+		uint64_t evcnt_en:1;
+		uint64_t evcnt_edge:1;
+		uint64_t evcnt_in:6;
+		uint64_t ckout_en:1;
+		uint64_t ckout_inv:1;
+		uint64_t ckout_out:4;
+		uint64_t pps_en:1;
+		uint64_t pps_inv:1;
+		uint64_t pps_out:5;
+		uint64_t ckout_out4:1;
+		uint64_t ext_clk_edge:2;
+		uint64_t ckout:1;
+		uint64_t pps:1;
+		uint64_t reserved_42_63:22;
+#endif
 	} s;
 	struct cvmx_mio_ptp_clock_cfg_s cn61xx;
 	struct cvmx_mio_ptp_clock_cfg_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_24_63:40;
 		uint64_t evcnt_in:6;
 		uint64_t evcnt_edge:1;
@@ -1781,9 +2837,22 @@
 		uint64_t ext_clk_in:6;
 		uint64_t ext_clk_en:1;
 		uint64_t ptp_en:1;
+#else
+		uint64_t ptp_en:1;
+		uint64_t ext_clk_en:1;
+		uint64_t ext_clk_in:6;
+		uint64_t tstmp_en:1;
+		uint64_t tstmp_edge:1;
+		uint64_t tstmp_in:6;
+		uint64_t evcnt_en:1;
+		uint64_t evcnt_edge:1;
+		uint64_t evcnt_in:6;
+		uint64_t reserved_24_63:40;
+#endif
 	} cn63xx;
 	struct cvmx_mio_ptp_clock_cfg_cn63xx cn63xxp1;
 	struct cvmx_mio_ptp_clock_cfg_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_40_63:24;
 		uint64_t ext_clk_edge:2;
 		uint64_t ckout_out4:1;
@@ -1802,16 +2871,42 @@
 		uint64_t ext_clk_in:6;
 		uint64_t ext_clk_en:1;
 		uint64_t ptp_en:1;
+#else
+		uint64_t ptp_en:1;
+		uint64_t ext_clk_en:1;
+		uint64_t ext_clk_in:6;
+		uint64_t tstmp_en:1;
+		uint64_t tstmp_edge:1;
+		uint64_t tstmp_in:6;
+		uint64_t evcnt_en:1;
+		uint64_t evcnt_edge:1;
+		uint64_t evcnt_in:6;
+		uint64_t ckout_en:1;
+		uint64_t ckout_inv:1;
+		uint64_t ckout_out:4;
+		uint64_t pps_en:1;
+		uint64_t pps_inv:1;
+		uint64_t pps_out:5;
+		uint64_t ckout_out4:1;
+		uint64_t ext_clk_edge:2;
+		uint64_t reserved_40_63:24;
+#endif
 	} cn66xx;
 	struct cvmx_mio_ptp_clock_cfg_s cn68xx;
 	struct cvmx_mio_ptp_clock_cfg_cn63xx cn68xxp1;
+	struct cvmx_mio_ptp_clock_cfg_s cnf71xx;
 };
 
 union cvmx_mio_ptp_clock_comp {
 	uint64_t u64;
 	struct cvmx_mio_ptp_clock_comp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t nanosec:32;
 		uint64_t frnanosec:32;
+#else
+		uint64_t frnanosec:32;
+		uint64_t nanosec:32;
+#endif
 	} s;
 	struct cvmx_mio_ptp_clock_comp_s cn61xx;
 	struct cvmx_mio_ptp_clock_comp_s cn63xx;
@@ -1819,12 +2914,17 @@
 	struct cvmx_mio_ptp_clock_comp_s cn66xx;
 	struct cvmx_mio_ptp_clock_comp_s cn68xx;
 	struct cvmx_mio_ptp_clock_comp_s cn68xxp1;
+	struct cvmx_mio_ptp_clock_comp_s cnf71xx;
 };
 
 union cvmx_mio_ptp_clock_hi {
 	uint64_t u64;
 	struct cvmx_mio_ptp_clock_hi_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t nanosec:64;
+#else
+		uint64_t nanosec:64;
+#endif
 	} s;
 	struct cvmx_mio_ptp_clock_hi_s cn61xx;
 	struct cvmx_mio_ptp_clock_hi_s cn63xx;
@@ -1832,13 +2932,19 @@
 	struct cvmx_mio_ptp_clock_hi_s cn66xx;
 	struct cvmx_mio_ptp_clock_hi_s cn68xx;
 	struct cvmx_mio_ptp_clock_hi_s cn68xxp1;
+	struct cvmx_mio_ptp_clock_hi_s cnf71xx;
 };
 
 union cvmx_mio_ptp_clock_lo {
 	uint64_t u64;
 	struct cvmx_mio_ptp_clock_lo_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t frnanosec:32;
+#else
+		uint64_t frnanosec:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_mio_ptp_clock_lo_s cn61xx;
 	struct cvmx_mio_ptp_clock_lo_s cn63xx;
@@ -1846,12 +2952,17 @@
 	struct cvmx_mio_ptp_clock_lo_s cn66xx;
 	struct cvmx_mio_ptp_clock_lo_s cn68xx;
 	struct cvmx_mio_ptp_clock_lo_s cn68xxp1;
+	struct cvmx_mio_ptp_clock_lo_s cnf71xx;
 };
 
 union cvmx_mio_ptp_evt_cnt {
 	uint64_t u64;
 	struct cvmx_mio_ptp_evt_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t cntr:64;
+#else
+		uint64_t cntr:64;
+#endif
 	} s;
 	struct cvmx_mio_ptp_evt_cnt_s cn61xx;
 	struct cvmx_mio_ptp_evt_cnt_s cn63xx;
@@ -1859,55 +2970,97 @@
 	struct cvmx_mio_ptp_evt_cnt_s cn66xx;
 	struct cvmx_mio_ptp_evt_cnt_s cn68xx;
 	struct cvmx_mio_ptp_evt_cnt_s cn68xxp1;
+	struct cvmx_mio_ptp_evt_cnt_s cnf71xx;
+};
+
+union cvmx_mio_ptp_phy_1pps_in {
+	uint64_t u64;
+	struct cvmx_mio_ptp_phy_1pps_in_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_5_63:59;
+		uint64_t sel:5;
+#else
+		uint64_t sel:5;
+		uint64_t reserved_5_63:59;
+#endif
+	} s;
+	struct cvmx_mio_ptp_phy_1pps_in_s cnf71xx;
 };
 
 union cvmx_mio_ptp_pps_hi_incr {
 	uint64_t u64;
 	struct cvmx_mio_ptp_pps_hi_incr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t nanosec:32;
 		uint64_t frnanosec:32;
+#else
+		uint64_t frnanosec:32;
+		uint64_t nanosec:32;
+#endif
 	} s;
 	struct cvmx_mio_ptp_pps_hi_incr_s cn61xx;
 	struct cvmx_mio_ptp_pps_hi_incr_s cn66xx;
 	struct cvmx_mio_ptp_pps_hi_incr_s cn68xx;
+	struct cvmx_mio_ptp_pps_hi_incr_s cnf71xx;
 };
 
 union cvmx_mio_ptp_pps_lo_incr {
 	uint64_t u64;
 	struct cvmx_mio_ptp_pps_lo_incr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t nanosec:32;
 		uint64_t frnanosec:32;
+#else
+		uint64_t frnanosec:32;
+		uint64_t nanosec:32;
+#endif
 	} s;
 	struct cvmx_mio_ptp_pps_lo_incr_s cn61xx;
 	struct cvmx_mio_ptp_pps_lo_incr_s cn66xx;
 	struct cvmx_mio_ptp_pps_lo_incr_s cn68xx;
+	struct cvmx_mio_ptp_pps_lo_incr_s cnf71xx;
 };
 
 union cvmx_mio_ptp_pps_thresh_hi {
 	uint64_t u64;
 	struct cvmx_mio_ptp_pps_thresh_hi_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t nanosec:64;
+#else
+		uint64_t nanosec:64;
+#endif
 	} s;
 	struct cvmx_mio_ptp_pps_thresh_hi_s cn61xx;
 	struct cvmx_mio_ptp_pps_thresh_hi_s cn66xx;
 	struct cvmx_mio_ptp_pps_thresh_hi_s cn68xx;
+	struct cvmx_mio_ptp_pps_thresh_hi_s cnf71xx;
 };
 
 union cvmx_mio_ptp_pps_thresh_lo {
 	uint64_t u64;
 	struct cvmx_mio_ptp_pps_thresh_lo_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t frnanosec:32;
+#else
+		uint64_t frnanosec:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_mio_ptp_pps_thresh_lo_s cn61xx;
 	struct cvmx_mio_ptp_pps_thresh_lo_s cn66xx;
 	struct cvmx_mio_ptp_pps_thresh_lo_s cn68xx;
+	struct cvmx_mio_ptp_pps_thresh_lo_s cnf71xx;
 };
 
 union cvmx_mio_ptp_timestamp {
 	uint64_t u64;
 	struct cvmx_mio_ptp_timestamp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t nanosec:64;
+#else
+		uint64_t nanosec:64;
+#endif
 	} s;
 	struct cvmx_mio_ptp_timestamp_s cn61xx;
 	struct cvmx_mio_ptp_timestamp_s cn63xx;
@@ -1915,35 +3068,79 @@
 	struct cvmx_mio_ptp_timestamp_s cn66xx;
 	struct cvmx_mio_ptp_timestamp_s cn68xx;
 	struct cvmx_mio_ptp_timestamp_s cn68xxp1;
+	struct cvmx_mio_ptp_timestamp_s cnf71xx;
 };
 
 union cvmx_mio_qlmx_cfg {
 	uint64_t u64;
 	struct cvmx_mio_qlmx_cfg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_15_63:49;
+		uint64_t prtmode:1;
+		uint64_t reserved_12_13:2;
+		uint64_t qlm_spd:4;
+		uint64_t reserved_4_7:4;
+		uint64_t qlm_cfg:4;
+#else
+		uint64_t qlm_cfg:4;
+		uint64_t reserved_4_7:4;
+		uint64_t qlm_spd:4;
+		uint64_t reserved_12_13:2;
+		uint64_t prtmode:1;
+		uint64_t reserved_15_63:49;
+#endif
+	} s;
+	struct cvmx_mio_qlmx_cfg_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_15_63:49;
+		uint64_t prtmode:1;
+		uint64_t reserved_12_13:2;
+		uint64_t qlm_spd:4;
+		uint64_t reserved_2_7:6;
+		uint64_t qlm_cfg:2;
+#else
+		uint64_t qlm_cfg:2;
+		uint64_t reserved_2_7:6;
+		uint64_t qlm_spd:4;
+		uint64_t reserved_12_13:2;
+		uint64_t prtmode:1;
+		uint64_t reserved_15_63:49;
+#endif
+	} cn61xx;
+	struct cvmx_mio_qlmx_cfg_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t qlm_spd:4;
 		uint64_t reserved_4_7:4;
 		uint64_t qlm_cfg:4;
-	} s;
-	struct cvmx_mio_qlmx_cfg_cn61xx {
-		uint64_t reserved_12_63:52;
+#else
+		uint64_t qlm_cfg:4;
+		uint64_t reserved_4_7:4;
 		uint64_t qlm_spd:4;
-		uint64_t reserved_2_7:6;
-		uint64_t qlm_cfg:2;
-	} cn61xx;
-	struct cvmx_mio_qlmx_cfg_s cn66xx;
+		uint64_t reserved_12_63:52;
+#endif
+	} cn66xx;
 	struct cvmx_mio_qlmx_cfg_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t qlm_spd:4;
 		uint64_t reserved_3_7:5;
 		uint64_t qlm_cfg:3;
+#else
+		uint64_t qlm_cfg:3;
+		uint64_t reserved_3_7:5;
+		uint64_t qlm_spd:4;
+		uint64_t reserved_12_63:52;
+#endif
 	} cn68xx;
 	struct cvmx_mio_qlmx_cfg_cn68xx cn68xxp1;
+	struct cvmx_mio_qlmx_cfg_cn61xx cnf71xx;
 };
 
 union cvmx_mio_rst_boot {
 	uint64_t u64;
 	struct cvmx_mio_rst_boot_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t chipkill:1;
 		uint64_t jtcsrdis:1;
 		uint64_t ejtagdis:1;
@@ -1963,8 +3160,30 @@
 		uint64_t lboot:10;
 		uint64_t rboot:1;
 		uint64_t rboot_pin:1;
+#else
+		uint64_t rboot_pin:1;
+		uint64_t rboot:1;
+		uint64_t lboot:10;
+		uint64_t qlm0_spd:4;
+		uint64_t qlm1_spd:4;
+		uint64_t qlm2_spd:4;
+		uint64_t pnr_mul:6;
+		uint64_t c_mul:6;
+		uint64_t qlm3_spd:4;
+		uint64_t qlm4_spd:4;
+		uint64_t reserved_44_47:4;
+		uint64_t lboot_ext:2;
+		uint64_t reserved_50_57:8;
+		uint64_t jt_tstmode:1;
+		uint64_t ckill_ppdis:1;
+		uint64_t romen:1;
+		uint64_t ejtagdis:1;
+		uint64_t jtcsrdis:1;
+		uint64_t chipkill:1;
+#endif
 	} s;
 	struct cvmx_mio_rst_boot_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t chipkill:1;
 		uint64_t jtcsrdis:1;
 		uint64_t ejtagdis:1;
@@ -1982,8 +3201,28 @@
 		uint64_t lboot:10;
 		uint64_t rboot:1;
 		uint64_t rboot_pin:1;
+#else
+		uint64_t rboot_pin:1;
+		uint64_t rboot:1;
+		uint64_t lboot:10;
+		uint64_t qlm0_spd:4;
+		uint64_t qlm1_spd:4;
+		uint64_t qlm2_spd:4;
+		uint64_t pnr_mul:6;
+		uint64_t c_mul:6;
+		uint64_t reserved_36_47:12;
+		uint64_t lboot_ext:2;
+		uint64_t reserved_50_57:8;
+		uint64_t jt_tstmode:1;
+		uint64_t ckill_ppdis:1;
+		uint64_t romen:1;
+		uint64_t ejtagdis:1;
+		uint64_t jtcsrdis:1;
+		uint64_t chipkill:1;
+#endif
 	} cn61xx;
 	struct cvmx_mio_rst_boot_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_36_63:28;
 		uint64_t c_mul:6;
 		uint64_t pnr_mul:6;
@@ -1993,9 +3232,21 @@
 		uint64_t lboot:10;
 		uint64_t rboot:1;
 		uint64_t rboot_pin:1;
+#else
+		uint64_t rboot_pin:1;
+		uint64_t rboot:1;
+		uint64_t lboot:10;
+		uint64_t qlm0_spd:4;
+		uint64_t qlm1_spd:4;
+		uint64_t qlm2_spd:4;
+		uint64_t pnr_mul:6;
+		uint64_t c_mul:6;
+		uint64_t reserved_36_63:28;
+#endif
 	} cn63xx;
 	struct cvmx_mio_rst_boot_cn63xx cn63xxp1;
 	struct cvmx_mio_rst_boot_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t chipkill:1;
 		uint64_t jtcsrdis:1;
 		uint64_t ejtagdis:1;
@@ -2012,8 +3263,27 @@
 		uint64_t lboot:10;
 		uint64_t rboot:1;
 		uint64_t rboot_pin:1;
+#else
+		uint64_t rboot_pin:1;
+		uint64_t rboot:1;
+		uint64_t lboot:10;
+		uint64_t qlm0_spd:4;
+		uint64_t qlm1_spd:4;
+		uint64_t qlm2_spd:4;
+		uint64_t pnr_mul:6;
+		uint64_t c_mul:6;
+		uint64_t reserved_36_47:12;
+		uint64_t lboot_ext:2;
+		uint64_t reserved_50_58:9;
+		uint64_t ckill_ppdis:1;
+		uint64_t romen:1;
+		uint64_t ejtagdis:1;
+		uint64_t jtcsrdis:1;
+		uint64_t chipkill:1;
+#endif
 	} cn66xx;
 	struct cvmx_mio_rst_boot_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_59_63:5;
 		uint64_t jt_tstmode:1;
 		uint64_t reserved_44_57:14;
@@ -2027,8 +3297,24 @@
 		uint64_t lboot:10;
 		uint64_t rboot:1;
 		uint64_t rboot_pin:1;
+#else
+		uint64_t rboot_pin:1;
+		uint64_t rboot:1;
+		uint64_t lboot:10;
+		uint64_t qlm0_spd:4;
+		uint64_t qlm1_spd:4;
+		uint64_t qlm2_spd:4;
+		uint64_t pnr_mul:6;
+		uint64_t c_mul:6;
+		uint64_t qlm3_spd:4;
+		uint64_t qlm4_spd:4;
+		uint64_t reserved_44_57:14;
+		uint64_t jt_tstmode:1;
+		uint64_t reserved_59_63:5;
+#endif
 	} cn68xx;
 	struct cvmx_mio_rst_boot_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_44_63:20;
 		uint64_t qlm4_spd:4;
 		uint64_t qlm3_spd:4;
@@ -2040,55 +3326,107 @@
 		uint64_t lboot:10;
 		uint64_t rboot:1;
 		uint64_t rboot_pin:1;
+#else
+		uint64_t rboot_pin:1;
+		uint64_t rboot:1;
+		uint64_t lboot:10;
+		uint64_t qlm0_spd:4;
+		uint64_t qlm1_spd:4;
+		uint64_t qlm2_spd:4;
+		uint64_t pnr_mul:6;
+		uint64_t c_mul:6;
+		uint64_t qlm3_spd:4;
+		uint64_t qlm4_spd:4;
+		uint64_t reserved_44_63:20;
+#endif
 	} cn68xxp1;
+	struct cvmx_mio_rst_boot_cn61xx cnf71xx;
 };
 
 union cvmx_mio_rst_cfg {
 	uint64_t u64;
 	struct cvmx_mio_rst_cfg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_3_63:61;
 		uint64_t cntl_clr_bist:1;
 		uint64_t warm_clr_bist:1;
 		uint64_t soft_clr_bist:1;
+#else
+		uint64_t soft_clr_bist:1;
+		uint64_t warm_clr_bist:1;
+		uint64_t cntl_clr_bist:1;
+		uint64_t reserved_3_63:61;
+#endif
 	} s;
 	struct cvmx_mio_rst_cfg_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t bist_delay:58;
 		uint64_t reserved_3_5:3;
 		uint64_t cntl_clr_bist:1;
 		uint64_t warm_clr_bist:1;
 		uint64_t soft_clr_bist:1;
+#else
+		uint64_t soft_clr_bist:1;
+		uint64_t warm_clr_bist:1;
+		uint64_t cntl_clr_bist:1;
+		uint64_t reserved_3_5:3;
+		uint64_t bist_delay:58;
+#endif
 	} cn61xx;
 	struct cvmx_mio_rst_cfg_cn61xx cn63xx;
 	struct cvmx_mio_rst_cfg_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t bist_delay:58;
 		uint64_t reserved_2_5:4;
 		uint64_t warm_clr_bist:1;
 		uint64_t soft_clr_bist:1;
+#else
+		uint64_t soft_clr_bist:1;
+		uint64_t warm_clr_bist:1;
+		uint64_t reserved_2_5:4;
+		uint64_t bist_delay:58;
+#endif
 	} cn63xxp1;
 	struct cvmx_mio_rst_cfg_cn61xx cn66xx;
 	struct cvmx_mio_rst_cfg_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t bist_delay:56;
 		uint64_t reserved_3_7:5;
 		uint64_t cntl_clr_bist:1;
 		uint64_t warm_clr_bist:1;
 		uint64_t soft_clr_bist:1;
+#else
+		uint64_t soft_clr_bist:1;
+		uint64_t warm_clr_bist:1;
+		uint64_t cntl_clr_bist:1;
+		uint64_t reserved_3_7:5;
+		uint64_t bist_delay:56;
+#endif
 	} cn68xx;
 	struct cvmx_mio_rst_cfg_cn68xx cn68xxp1;
+	struct cvmx_mio_rst_cfg_cn61xx cnf71xx;
 };
 
 union cvmx_mio_rst_ckill {
 	uint64_t u64;
 	struct cvmx_mio_rst_ckill_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_47_63:17;
 		uint64_t timer:47;
+#else
+		uint64_t timer:47;
+		uint64_t reserved_47_63:17;
+#endif
 	} s;
 	struct cvmx_mio_rst_ckill_s cn61xx;
 	struct cvmx_mio_rst_ckill_s cn66xx;
+	struct cvmx_mio_rst_ckill_s cnf71xx;
 };
 
 union cvmx_mio_rst_cntlx {
 	uint64_t u64;
 	struct cvmx_mio_rst_cntlx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_13_63:51;
 		uint64_t in_rev_ln:1;
 		uint64_t rev_lanes:1;
@@ -2102,9 +3440,25 @@
 		uint64_t rst_rcv:1;
 		uint64_t rst_chip:1;
 		uint64_t rst_val:1;
+#else
+		uint64_t rst_val:1;
+		uint64_t rst_chip:1;
+		uint64_t rst_rcv:1;
+		uint64_t rst_drv:1;
+		uint64_t prtmode:2;
+		uint64_t host_mode:1;
+		uint64_t rst_link:1;
+		uint64_t rst_done:1;
+		uint64_t prst_link:1;
+		uint64_t gen1_only:1;
+		uint64_t rev_lanes:1;
+		uint64_t in_rev_ln:1;
+		uint64_t reserved_13_63:51;
+#endif
 	} s;
 	struct cvmx_mio_rst_cntlx_s cn61xx;
 	struct cvmx_mio_rst_cntlx_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t prst_link:1;
 		uint64_t rst_done:1;
@@ -2115,13 +3469,27 @@
 		uint64_t rst_rcv:1;
 		uint64_t rst_chip:1;
 		uint64_t rst_val:1;
+#else
+		uint64_t rst_val:1;
+		uint64_t rst_chip:1;
+		uint64_t rst_rcv:1;
+		uint64_t rst_drv:1;
+		uint64_t prtmode:2;
+		uint64_t host_mode:1;
+		uint64_t rst_link:1;
+		uint64_t rst_done:1;
+		uint64_t prst_link:1;
+		uint64_t reserved_10_63:54;
+#endif
 	} cn66xx;
 	struct cvmx_mio_rst_cntlx_cn66xx cn68xx;
+	struct cvmx_mio_rst_cntlx_s cnf71xx;
 };
 
 union cvmx_mio_rst_ctlx {
 	uint64_t u64;
 	struct cvmx_mio_rst_ctlx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_13_63:51;
 		uint64_t in_rev_ln:1;
 		uint64_t rev_lanes:1;
@@ -2135,9 +3503,25 @@
 		uint64_t rst_rcv:1;
 		uint64_t rst_chip:1;
 		uint64_t rst_val:1;
+#else
+		uint64_t rst_val:1;
+		uint64_t rst_chip:1;
+		uint64_t rst_rcv:1;
+		uint64_t rst_drv:1;
+		uint64_t prtmode:2;
+		uint64_t host_mode:1;
+		uint64_t rst_link:1;
+		uint64_t rst_done:1;
+		uint64_t prst_link:1;
+		uint64_t gen1_only:1;
+		uint64_t rev_lanes:1;
+		uint64_t in_rev_ln:1;
+		uint64_t reserved_13_63:51;
+#endif
 	} s;
 	struct cvmx_mio_rst_ctlx_s cn61xx;
 	struct cvmx_mio_rst_ctlx_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t prst_link:1;
 		uint64_t rst_done:1;
@@ -2148,8 +3532,21 @@
 		uint64_t rst_rcv:1;
 		uint64_t rst_chip:1;
 		uint64_t rst_val:1;
+#else
+		uint64_t rst_val:1;
+		uint64_t rst_chip:1;
+		uint64_t rst_rcv:1;
+		uint64_t rst_drv:1;
+		uint64_t prtmode:2;
+		uint64_t host_mode:1;
+		uint64_t rst_link:1;
+		uint64_t rst_done:1;
+		uint64_t prst_link:1;
+		uint64_t reserved_10_63:54;
+#endif
 	} cn63xx;
 	struct cvmx_mio_rst_ctlx_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t rst_done:1;
 		uint64_t rst_link:1;
@@ -2159,18 +3556,36 @@
 		uint64_t rst_rcv:1;
 		uint64_t rst_chip:1;
 		uint64_t rst_val:1;
+#else
+		uint64_t rst_val:1;
+		uint64_t rst_chip:1;
+		uint64_t rst_rcv:1;
+		uint64_t rst_drv:1;
+		uint64_t prtmode:2;
+		uint64_t host_mode:1;
+		uint64_t rst_link:1;
+		uint64_t rst_done:1;
+		uint64_t reserved_9_63:55;
+#endif
 	} cn63xxp1;
 	struct cvmx_mio_rst_ctlx_cn63xx cn66xx;
 	struct cvmx_mio_rst_ctlx_cn63xx cn68xx;
 	struct cvmx_mio_rst_ctlx_cn63xx cn68xxp1;
+	struct cvmx_mio_rst_ctlx_s cnf71xx;
 };
 
 union cvmx_mio_rst_delay {
 	uint64_t u64;
 	struct cvmx_mio_rst_delay_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t warm_rst_dly:16;
 		uint64_t soft_rst_dly:16;
+#else
+		uint64_t soft_rst_dly:16;
+		uint64_t warm_rst_dly:16;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_mio_rst_delay_s cn61xx;
 	struct cvmx_mio_rst_delay_s cn63xx;
@@ -2178,11 +3593,13 @@
 	struct cvmx_mio_rst_delay_s cn66xx;
 	struct cvmx_mio_rst_delay_s cn68xx;
 	struct cvmx_mio_rst_delay_s cn68xxp1;
+	struct cvmx_mio_rst_delay_s cnf71xx;
 };
 
 union cvmx_mio_rst_int {
 	uint64_t u64;
 	struct cvmx_mio_rst_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t perst1:1;
 		uint64_t perst0:1;
@@ -2191,25 +3608,46 @@
 		uint64_t rst_link2:1;
 		uint64_t rst_link1:1;
 		uint64_t rst_link0:1;
+#else
+		uint64_t rst_link0:1;
+		uint64_t rst_link1:1;
+		uint64_t rst_link2:1;
+		uint64_t rst_link3:1;
+		uint64_t reserved_4_7:4;
+		uint64_t perst0:1;
+		uint64_t perst1:1;
+		uint64_t reserved_10_63:54;
+#endif
 	} s;
 	struct cvmx_mio_rst_int_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t perst1:1;
 		uint64_t perst0:1;
 		uint64_t reserved_2_7:6;
 		uint64_t rst_link1:1;
 		uint64_t rst_link0:1;
+#else
+		uint64_t rst_link0:1;
+		uint64_t rst_link1:1;
+		uint64_t reserved_2_7:6;
+		uint64_t perst0:1;
+		uint64_t perst1:1;
+		uint64_t reserved_10_63:54;
+#endif
 	} cn61xx;
 	struct cvmx_mio_rst_int_cn61xx cn63xx;
 	struct cvmx_mio_rst_int_cn61xx cn63xxp1;
 	struct cvmx_mio_rst_int_s cn66xx;
 	struct cvmx_mio_rst_int_cn61xx cn68xx;
 	struct cvmx_mio_rst_int_cn61xx cn68xxp1;
+	struct cvmx_mio_rst_int_cn61xx cnf71xx;
 };
 
 union cvmx_mio_rst_int_en {
 	uint64_t u64;
 	struct cvmx_mio_rst_int_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t perst1:1;
 		uint64_t perst0:1;
@@ -2218,25 +3656,46 @@
 		uint64_t rst_link2:1;
 		uint64_t rst_link1:1;
 		uint64_t rst_link0:1;
+#else
+		uint64_t rst_link0:1;
+		uint64_t rst_link1:1;
+		uint64_t rst_link2:1;
+		uint64_t rst_link3:1;
+		uint64_t reserved_4_7:4;
+		uint64_t perst0:1;
+		uint64_t perst1:1;
+		uint64_t reserved_10_63:54;
+#endif
 	} s;
 	struct cvmx_mio_rst_int_en_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t perst1:1;
 		uint64_t perst0:1;
 		uint64_t reserved_2_7:6;
 		uint64_t rst_link1:1;
 		uint64_t rst_link0:1;
+#else
+		uint64_t rst_link0:1;
+		uint64_t rst_link1:1;
+		uint64_t reserved_2_7:6;
+		uint64_t perst0:1;
+		uint64_t perst1:1;
+		uint64_t reserved_10_63:54;
+#endif
 	} cn61xx;
 	struct cvmx_mio_rst_int_en_cn61xx cn63xx;
 	struct cvmx_mio_rst_int_en_cn61xx cn63xxp1;
 	struct cvmx_mio_rst_int_en_s cn66xx;
 	struct cvmx_mio_rst_int_en_cn61xx cn68xx;
 	struct cvmx_mio_rst_int_en_cn61xx cn68xxp1;
+	struct cvmx_mio_rst_int_en_cn61xx cnf71xx;
 };
 
 union cvmx_mio_twsx_int {
 	uint64_t u64;
 	struct cvmx_mio_twsx_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t scl:1;
 		uint64_t sda:1;
@@ -2250,11 +3709,27 @@
 		uint64_t core_int:1;
 		uint64_t ts_int:1;
 		uint64_t st_int:1;
+#else
+		uint64_t st_int:1;
+		uint64_t ts_int:1;
+		uint64_t core_int:1;
+		uint64_t reserved_3_3:1;
+		uint64_t st_en:1;
+		uint64_t ts_en:1;
+		uint64_t core_en:1;
+		uint64_t reserved_7_7:1;
+		uint64_t sda_ovr:1;
+		uint64_t scl_ovr:1;
+		uint64_t sda:1;
+		uint64_t scl:1;
+		uint64_t reserved_12_63:52;
+#endif
 	} s;
 	struct cvmx_mio_twsx_int_s cn30xx;
 	struct cvmx_mio_twsx_int_s cn31xx;
 	struct cvmx_mio_twsx_int_s cn38xx;
 	struct cvmx_mio_twsx_int_cn38xxp2 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_7_63:57;
 		uint64_t core_en:1;
 		uint64_t ts_en:1;
@@ -2263,6 +3738,16 @@
 		uint64_t core_int:1;
 		uint64_t ts_int:1;
 		uint64_t st_int:1;
+#else
+		uint64_t st_int:1;
+		uint64_t ts_int:1;
+		uint64_t core_int:1;
+		uint64_t reserved_3_3:1;
+		uint64_t st_en:1;
+		uint64_t ts_en:1;
+		uint64_t core_en:1;
+		uint64_t reserved_7_63:57;
+#endif
 	} cn38xxp2;
 	struct cvmx_mio_twsx_int_s cn50xx;
 	struct cvmx_mio_twsx_int_s cn52xx;
@@ -2277,11 +3762,13 @@
 	struct cvmx_mio_twsx_int_s cn66xx;
 	struct cvmx_mio_twsx_int_s cn68xx;
 	struct cvmx_mio_twsx_int_s cn68xxp1;
+	struct cvmx_mio_twsx_int_s cnf71xx;
 };
 
 union cvmx_mio_twsx_sw_twsi {
 	uint64_t u64;
 	struct cvmx_mio_twsx_sw_twsi_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t v:1;
 		uint64_t slonly:1;
 		uint64_t eia:1;
@@ -2294,6 +3781,20 @@
 		uint64_t ia:5;
 		uint64_t eop_ia:3;
 		uint64_t d:32;
+#else
+		uint64_t d:32;
+		uint64_t eop_ia:3;
+		uint64_t ia:5;
+		uint64_t a:10;
+		uint64_t scr:2;
+		uint64_t size:3;
+		uint64_t sovr:1;
+		uint64_t r:1;
+		uint64_t op:4;
+		uint64_t eia:1;
+		uint64_t slonly:1;
+		uint64_t v:1;
+#endif
 	} s;
 	struct cvmx_mio_twsx_sw_twsi_s cn30xx;
 	struct cvmx_mio_twsx_sw_twsi_s cn31xx;
@@ -2312,14 +3813,21 @@
 	struct cvmx_mio_twsx_sw_twsi_s cn66xx;
 	struct cvmx_mio_twsx_sw_twsi_s cn68xx;
 	struct cvmx_mio_twsx_sw_twsi_s cn68xxp1;
+	struct cvmx_mio_twsx_sw_twsi_s cnf71xx;
 };
 
 union cvmx_mio_twsx_sw_twsi_ext {
 	uint64_t u64;
 	struct cvmx_mio_twsx_sw_twsi_ext_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_40_63:24;
 		uint64_t ia:8;
 		uint64_t d:32;
+#else
+		uint64_t d:32;
+		uint64_t ia:8;
+		uint64_t reserved_40_63:24;
+#endif
 	} s;
 	struct cvmx_mio_twsx_sw_twsi_ext_s cn30xx;
 	struct cvmx_mio_twsx_sw_twsi_ext_s cn31xx;
@@ -2338,14 +3846,21 @@
 	struct cvmx_mio_twsx_sw_twsi_ext_s cn66xx;
 	struct cvmx_mio_twsx_sw_twsi_ext_s cn68xx;
 	struct cvmx_mio_twsx_sw_twsi_ext_s cn68xxp1;
+	struct cvmx_mio_twsx_sw_twsi_ext_s cnf71xx;
 };
 
 union cvmx_mio_twsx_twsi_sw {
 	uint64_t u64;
 	struct cvmx_mio_twsx_twsi_sw_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t v:2;
 		uint64_t reserved_32_61:30;
 		uint64_t d:32;
+#else
+		uint64_t d:32;
+		uint64_t reserved_32_61:30;
+		uint64_t v:2;
+#endif
 	} s;
 	struct cvmx_mio_twsx_twsi_sw_s cn30xx;
 	struct cvmx_mio_twsx_twsi_sw_s cn31xx;
@@ -2364,13 +3879,19 @@
 	struct cvmx_mio_twsx_twsi_sw_s cn66xx;
 	struct cvmx_mio_twsx_twsi_sw_s cn68xx;
 	struct cvmx_mio_twsx_twsi_sw_s cn68xxp1;
+	struct cvmx_mio_twsx_twsi_sw_s cnf71xx;
 };
 
 union cvmx_mio_uartx_dlh {
 	uint64_t u64;
 	struct cvmx_mio_uartx_dlh_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t dlh:8;
+#else
+		uint64_t dlh:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_mio_uartx_dlh_s cn30xx;
 	struct cvmx_mio_uartx_dlh_s cn31xx;
@@ -2389,13 +3910,19 @@
 	struct cvmx_mio_uartx_dlh_s cn66xx;
 	struct cvmx_mio_uartx_dlh_s cn68xx;
 	struct cvmx_mio_uartx_dlh_s cn68xxp1;
+	struct cvmx_mio_uartx_dlh_s cnf71xx;
 };
 
 union cvmx_mio_uartx_dll {
 	uint64_t u64;
 	struct cvmx_mio_uartx_dll_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t dll:8;
+#else
+		uint64_t dll:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_mio_uartx_dll_s cn30xx;
 	struct cvmx_mio_uartx_dll_s cn31xx;
@@ -2414,13 +3941,19 @@
 	struct cvmx_mio_uartx_dll_s cn66xx;
 	struct cvmx_mio_uartx_dll_s cn68xx;
 	struct cvmx_mio_uartx_dll_s cn68xxp1;
+	struct cvmx_mio_uartx_dll_s cnf71xx;
 };
 
 union cvmx_mio_uartx_far {
 	uint64_t u64;
 	struct cvmx_mio_uartx_far_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t far:1;
+#else
+		uint64_t far:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_mio_uartx_far_s cn30xx;
 	struct cvmx_mio_uartx_far_s cn31xx;
@@ -2439,11 +3972,13 @@
 	struct cvmx_mio_uartx_far_s cn66xx;
 	struct cvmx_mio_uartx_far_s cn68xx;
 	struct cvmx_mio_uartx_far_s cn68xxp1;
+	struct cvmx_mio_uartx_far_s cnf71xx;
 };
 
 union cvmx_mio_uartx_fcr {
 	uint64_t u64;
 	struct cvmx_mio_uartx_fcr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t rxtrig:2;
 		uint64_t txtrig:2;
@@ -2451,6 +3986,15 @@
 		uint64_t txfr:1;
 		uint64_t rxfr:1;
 		uint64_t en:1;
+#else
+		uint64_t en:1;
+		uint64_t rxfr:1;
+		uint64_t txfr:1;
+		uint64_t reserved_3_3:1;
+		uint64_t txtrig:2;
+		uint64_t rxtrig:2;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_mio_uartx_fcr_s cn30xx;
 	struct cvmx_mio_uartx_fcr_s cn31xx;
@@ -2469,13 +4013,19 @@
 	struct cvmx_mio_uartx_fcr_s cn66xx;
 	struct cvmx_mio_uartx_fcr_s cn68xx;
 	struct cvmx_mio_uartx_fcr_s cn68xxp1;
+	struct cvmx_mio_uartx_fcr_s cnf71xx;
 };
 
 union cvmx_mio_uartx_htx {
 	uint64_t u64;
 	struct cvmx_mio_uartx_htx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t htx:1;
+#else
+		uint64_t htx:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_mio_uartx_htx_s cn30xx;
 	struct cvmx_mio_uartx_htx_s cn31xx;
@@ -2494,11 +4044,13 @@
 	struct cvmx_mio_uartx_htx_s cn66xx;
 	struct cvmx_mio_uartx_htx_s cn68xx;
 	struct cvmx_mio_uartx_htx_s cn68xxp1;
+	struct cvmx_mio_uartx_htx_s cnf71xx;
 };
 
 union cvmx_mio_uartx_ier {
 	uint64_t u64;
 	struct cvmx_mio_uartx_ier_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t ptime:1;
 		uint64_t reserved_4_6:3;
@@ -2506,6 +4058,15 @@
 		uint64_t elsi:1;
 		uint64_t etbei:1;
 		uint64_t erbfi:1;
+#else
+		uint64_t erbfi:1;
+		uint64_t etbei:1;
+		uint64_t elsi:1;
+		uint64_t edssi:1;
+		uint64_t reserved_4_6:3;
+		uint64_t ptime:1;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_mio_uartx_ier_s cn30xx;
 	struct cvmx_mio_uartx_ier_s cn31xx;
@@ -2524,15 +4085,23 @@
 	struct cvmx_mio_uartx_ier_s cn66xx;
 	struct cvmx_mio_uartx_ier_s cn68xx;
 	struct cvmx_mio_uartx_ier_s cn68xxp1;
+	struct cvmx_mio_uartx_ier_s cnf71xx;
 };
 
 union cvmx_mio_uartx_iir {
 	uint64_t u64;
 	struct cvmx_mio_uartx_iir_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t fen:2;
 		uint64_t reserved_4_5:2;
 		uint64_t iid:4;
+#else
+		uint64_t iid:4;
+		uint64_t reserved_4_5:2;
+		uint64_t fen:2;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_mio_uartx_iir_s cn30xx;
 	struct cvmx_mio_uartx_iir_s cn31xx;
@@ -2551,11 +4120,13 @@
 	struct cvmx_mio_uartx_iir_s cn66xx;
 	struct cvmx_mio_uartx_iir_s cn68xx;
 	struct cvmx_mio_uartx_iir_s cn68xxp1;
+	struct cvmx_mio_uartx_iir_s cnf71xx;
 };
 
 union cvmx_mio_uartx_lcr {
 	uint64_t u64;
 	struct cvmx_mio_uartx_lcr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t dlab:1;
 		uint64_t brk:1;
@@ -2564,6 +4135,16 @@
 		uint64_t pen:1;
 		uint64_t stop:1;
 		uint64_t cls:2;
+#else
+		uint64_t cls:2;
+		uint64_t stop:1;
+		uint64_t pen:1;
+		uint64_t eps:1;
+		uint64_t reserved_5_5:1;
+		uint64_t brk:1;
+		uint64_t dlab:1;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_mio_uartx_lcr_s cn30xx;
 	struct cvmx_mio_uartx_lcr_s cn31xx;
@@ -2582,11 +4163,13 @@
 	struct cvmx_mio_uartx_lcr_s cn66xx;
 	struct cvmx_mio_uartx_lcr_s cn68xx;
 	struct cvmx_mio_uartx_lcr_s cn68xxp1;
+	struct cvmx_mio_uartx_lcr_s cnf71xx;
 };
 
 union cvmx_mio_uartx_lsr {
 	uint64_t u64;
 	struct cvmx_mio_uartx_lsr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t ferr:1;
 		uint64_t temt:1;
@@ -2596,6 +4179,17 @@
 		uint64_t pe:1;
 		uint64_t oe:1;
 		uint64_t dr:1;
+#else
+		uint64_t dr:1;
+		uint64_t oe:1;
+		uint64_t pe:1;
+		uint64_t fe:1;
+		uint64_t bi:1;
+		uint64_t thre:1;
+		uint64_t temt:1;
+		uint64_t ferr:1;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_mio_uartx_lsr_s cn30xx;
 	struct cvmx_mio_uartx_lsr_s cn31xx;
@@ -2614,11 +4208,13 @@
 	struct cvmx_mio_uartx_lsr_s cn66xx;
 	struct cvmx_mio_uartx_lsr_s cn68xx;
 	struct cvmx_mio_uartx_lsr_s cn68xxp1;
+	struct cvmx_mio_uartx_lsr_s cnf71xx;
 };
 
 union cvmx_mio_uartx_mcr {
 	uint64_t u64;
 	struct cvmx_mio_uartx_mcr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t afce:1;
 		uint64_t loop:1;
@@ -2626,6 +4222,15 @@
 		uint64_t out1:1;
 		uint64_t rts:1;
 		uint64_t dtr:1;
+#else
+		uint64_t dtr:1;
+		uint64_t rts:1;
+		uint64_t out1:1;
+		uint64_t out2:1;
+		uint64_t loop:1;
+		uint64_t afce:1;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
 	struct cvmx_mio_uartx_mcr_s cn30xx;
 	struct cvmx_mio_uartx_mcr_s cn31xx;
@@ -2644,11 +4249,13 @@
 	struct cvmx_mio_uartx_mcr_s cn66xx;
 	struct cvmx_mio_uartx_mcr_s cn68xx;
 	struct cvmx_mio_uartx_mcr_s cn68xxp1;
+	struct cvmx_mio_uartx_mcr_s cnf71xx;
 };
 
 union cvmx_mio_uartx_msr {
 	uint64_t u64;
 	struct cvmx_mio_uartx_msr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t dcd:1;
 		uint64_t ri:1;
@@ -2658,6 +4265,17 @@
 		uint64_t teri:1;
 		uint64_t ddsr:1;
 		uint64_t dcts:1;
+#else
+		uint64_t dcts:1;
+		uint64_t ddsr:1;
+		uint64_t teri:1;
+		uint64_t ddcd:1;
+		uint64_t cts:1;
+		uint64_t dsr:1;
+		uint64_t ri:1;
+		uint64_t dcd:1;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_mio_uartx_msr_s cn30xx;
 	struct cvmx_mio_uartx_msr_s cn31xx;
@@ -2676,13 +4294,19 @@
 	struct cvmx_mio_uartx_msr_s cn66xx;
 	struct cvmx_mio_uartx_msr_s cn68xx;
 	struct cvmx_mio_uartx_msr_s cn68xxp1;
+	struct cvmx_mio_uartx_msr_s cnf71xx;
 };
 
 union cvmx_mio_uartx_rbr {
 	uint64_t u64;
 	struct cvmx_mio_uartx_rbr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t rbr:8;
+#else
+		uint64_t rbr:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_mio_uartx_rbr_s cn30xx;
 	struct cvmx_mio_uartx_rbr_s cn31xx;
@@ -2701,13 +4325,19 @@
 	struct cvmx_mio_uartx_rbr_s cn66xx;
 	struct cvmx_mio_uartx_rbr_s cn68xx;
 	struct cvmx_mio_uartx_rbr_s cn68xxp1;
+	struct cvmx_mio_uartx_rbr_s cnf71xx;
 };
 
 union cvmx_mio_uartx_rfl {
 	uint64_t u64;
 	struct cvmx_mio_uartx_rfl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_7_63:57;
 		uint64_t rfl:7;
+#else
+		uint64_t rfl:7;
+		uint64_t reserved_7_63:57;
+#endif
 	} s;
 	struct cvmx_mio_uartx_rfl_s cn30xx;
 	struct cvmx_mio_uartx_rfl_s cn31xx;
@@ -2726,15 +4356,23 @@
 	struct cvmx_mio_uartx_rfl_s cn66xx;
 	struct cvmx_mio_uartx_rfl_s cn68xx;
 	struct cvmx_mio_uartx_rfl_s cn68xxp1;
+	struct cvmx_mio_uartx_rfl_s cnf71xx;
 };
 
 union cvmx_mio_uartx_rfw {
 	uint64_t u64;
 	struct cvmx_mio_uartx_rfw_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t rffe:1;
 		uint64_t rfpe:1;
 		uint64_t rfwd:8;
+#else
+		uint64_t rfwd:8;
+		uint64_t rfpe:1;
+		uint64_t rffe:1;
+		uint64_t reserved_10_63:54;
+#endif
 	} s;
 	struct cvmx_mio_uartx_rfw_s cn30xx;
 	struct cvmx_mio_uartx_rfw_s cn31xx;
@@ -2753,13 +4391,19 @@
 	struct cvmx_mio_uartx_rfw_s cn66xx;
 	struct cvmx_mio_uartx_rfw_s cn68xx;
 	struct cvmx_mio_uartx_rfw_s cn68xxp1;
+	struct cvmx_mio_uartx_rfw_s cnf71xx;
 };
 
 union cvmx_mio_uartx_sbcr {
 	uint64_t u64;
 	struct cvmx_mio_uartx_sbcr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t sbcr:1;
+#else
+		uint64_t sbcr:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_mio_uartx_sbcr_s cn30xx;
 	struct cvmx_mio_uartx_sbcr_s cn31xx;
@@ -2778,13 +4422,19 @@
 	struct cvmx_mio_uartx_sbcr_s cn66xx;
 	struct cvmx_mio_uartx_sbcr_s cn68xx;
 	struct cvmx_mio_uartx_sbcr_s cn68xxp1;
+	struct cvmx_mio_uartx_sbcr_s cnf71xx;
 };
 
 union cvmx_mio_uartx_scr {
 	uint64_t u64;
 	struct cvmx_mio_uartx_scr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t scr:8;
+#else
+		uint64_t scr:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_mio_uartx_scr_s cn30xx;
 	struct cvmx_mio_uartx_scr_s cn31xx;
@@ -2803,13 +4453,19 @@
 	struct cvmx_mio_uartx_scr_s cn66xx;
 	struct cvmx_mio_uartx_scr_s cn68xx;
 	struct cvmx_mio_uartx_scr_s cn68xxp1;
+	struct cvmx_mio_uartx_scr_s cnf71xx;
 };
 
 union cvmx_mio_uartx_sfe {
 	uint64_t u64;
 	struct cvmx_mio_uartx_sfe_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t sfe:1;
+#else
+		uint64_t sfe:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_mio_uartx_sfe_s cn30xx;
 	struct cvmx_mio_uartx_sfe_s cn31xx;
@@ -2828,15 +4484,23 @@
 	struct cvmx_mio_uartx_sfe_s cn66xx;
 	struct cvmx_mio_uartx_sfe_s cn68xx;
 	struct cvmx_mio_uartx_sfe_s cn68xxp1;
+	struct cvmx_mio_uartx_sfe_s cnf71xx;
 };
 
 union cvmx_mio_uartx_srr {
 	uint64_t u64;
 	struct cvmx_mio_uartx_srr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_3_63:61;
 		uint64_t stfr:1;
 		uint64_t srfr:1;
 		uint64_t usr:1;
+#else
+		uint64_t usr:1;
+		uint64_t srfr:1;
+		uint64_t stfr:1;
+		uint64_t reserved_3_63:61;
+#endif
 	} s;
 	struct cvmx_mio_uartx_srr_s cn30xx;
 	struct cvmx_mio_uartx_srr_s cn31xx;
@@ -2855,13 +4519,19 @@
 	struct cvmx_mio_uartx_srr_s cn66xx;
 	struct cvmx_mio_uartx_srr_s cn68xx;
 	struct cvmx_mio_uartx_srr_s cn68xxp1;
+	struct cvmx_mio_uartx_srr_s cnf71xx;
 };
 
 union cvmx_mio_uartx_srt {
 	uint64_t u64;
 	struct cvmx_mio_uartx_srt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t srt:2;
+#else
+		uint64_t srt:2;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_mio_uartx_srt_s cn30xx;
 	struct cvmx_mio_uartx_srt_s cn31xx;
@@ -2880,13 +4550,19 @@
 	struct cvmx_mio_uartx_srt_s cn66xx;
 	struct cvmx_mio_uartx_srt_s cn68xx;
 	struct cvmx_mio_uartx_srt_s cn68xxp1;
+	struct cvmx_mio_uartx_srt_s cnf71xx;
 };
 
 union cvmx_mio_uartx_srts {
 	uint64_t u64;
 	struct cvmx_mio_uartx_srts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t srts:1;
+#else
+		uint64_t srts:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_mio_uartx_srts_s cn30xx;
 	struct cvmx_mio_uartx_srts_s cn31xx;
@@ -2905,13 +4581,19 @@
 	struct cvmx_mio_uartx_srts_s cn66xx;
 	struct cvmx_mio_uartx_srts_s cn68xx;
 	struct cvmx_mio_uartx_srts_s cn68xxp1;
+	struct cvmx_mio_uartx_srts_s cnf71xx;
 };
 
 union cvmx_mio_uartx_stt {
 	uint64_t u64;
 	struct cvmx_mio_uartx_stt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t stt:2;
+#else
+		uint64_t stt:2;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_mio_uartx_stt_s cn30xx;
 	struct cvmx_mio_uartx_stt_s cn31xx;
@@ -2930,13 +4612,19 @@
 	struct cvmx_mio_uartx_stt_s cn66xx;
 	struct cvmx_mio_uartx_stt_s cn68xx;
 	struct cvmx_mio_uartx_stt_s cn68xxp1;
+	struct cvmx_mio_uartx_stt_s cnf71xx;
 };
 
 union cvmx_mio_uartx_tfl {
 	uint64_t u64;
 	struct cvmx_mio_uartx_tfl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_7_63:57;
 		uint64_t tfl:7;
+#else
+		uint64_t tfl:7;
+		uint64_t reserved_7_63:57;
+#endif
 	} s;
 	struct cvmx_mio_uartx_tfl_s cn30xx;
 	struct cvmx_mio_uartx_tfl_s cn31xx;
@@ -2955,13 +4643,19 @@
 	struct cvmx_mio_uartx_tfl_s cn66xx;
 	struct cvmx_mio_uartx_tfl_s cn68xx;
 	struct cvmx_mio_uartx_tfl_s cn68xxp1;
+	struct cvmx_mio_uartx_tfl_s cnf71xx;
 };
 
 union cvmx_mio_uartx_tfr {
 	uint64_t u64;
 	struct cvmx_mio_uartx_tfr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t tfr:8;
+#else
+		uint64_t tfr:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_mio_uartx_tfr_s cn30xx;
 	struct cvmx_mio_uartx_tfr_s cn31xx;
@@ -2980,13 +4674,19 @@
 	struct cvmx_mio_uartx_tfr_s cn66xx;
 	struct cvmx_mio_uartx_tfr_s cn68xx;
 	struct cvmx_mio_uartx_tfr_s cn68xxp1;
+	struct cvmx_mio_uartx_tfr_s cnf71xx;
 };
 
 union cvmx_mio_uartx_thr {
 	uint64_t u64;
 	struct cvmx_mio_uartx_thr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t thr:8;
+#else
+		uint64_t thr:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_mio_uartx_thr_s cn30xx;
 	struct cvmx_mio_uartx_thr_s cn31xx;
@@ -3005,17 +4705,27 @@
 	struct cvmx_mio_uartx_thr_s cn66xx;
 	struct cvmx_mio_uartx_thr_s cn68xx;
 	struct cvmx_mio_uartx_thr_s cn68xxp1;
+	struct cvmx_mio_uartx_thr_s cnf71xx;
 };
 
 union cvmx_mio_uartx_usr {
 	uint64_t u64;
 	struct cvmx_mio_uartx_usr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t rff:1;
 		uint64_t rfne:1;
 		uint64_t tfe:1;
 		uint64_t tfnf:1;
 		uint64_t busy:1;
+#else
+		uint64_t busy:1;
+		uint64_t tfnf:1;
+		uint64_t tfe:1;
+		uint64_t rfne:1;
+		uint64_t rff:1;
+		uint64_t reserved_5_63:59;
+#endif
 	} s;
 	struct cvmx_mio_uartx_usr_s cn30xx;
 	struct cvmx_mio_uartx_usr_s cn31xx;
@@ -3034,13 +4744,19 @@
 	struct cvmx_mio_uartx_usr_s cn66xx;
 	struct cvmx_mio_uartx_usr_s cn68xx;
 	struct cvmx_mio_uartx_usr_s cn68xxp1;
+	struct cvmx_mio_uartx_usr_s cnf71xx;
 };
 
 union cvmx_mio_uart2_dlh {
 	uint64_t u64;
 	struct cvmx_mio_uart2_dlh_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t dlh:8;
+#else
+		uint64_t dlh:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_mio_uart2_dlh_s cn52xx;
 	struct cvmx_mio_uart2_dlh_s cn52xxp1;
@@ -3049,8 +4765,13 @@
 union cvmx_mio_uart2_dll {
 	uint64_t u64;
 	struct cvmx_mio_uart2_dll_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t dll:8;
+#else
+		uint64_t dll:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_mio_uart2_dll_s cn52xx;
 	struct cvmx_mio_uart2_dll_s cn52xxp1;
@@ -3059,8 +4780,13 @@
 union cvmx_mio_uart2_far {
 	uint64_t u64;
 	struct cvmx_mio_uart2_far_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t far:1;
+#else
+		uint64_t far:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_mio_uart2_far_s cn52xx;
 	struct cvmx_mio_uart2_far_s cn52xxp1;
@@ -3069,6 +4795,7 @@
 union cvmx_mio_uart2_fcr {
 	uint64_t u64;
 	struct cvmx_mio_uart2_fcr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t rxtrig:2;
 		uint64_t txtrig:2;
@@ -3076,6 +4803,15 @@
 		uint64_t txfr:1;
 		uint64_t rxfr:1;
 		uint64_t en:1;
+#else
+		uint64_t en:1;
+		uint64_t rxfr:1;
+		uint64_t txfr:1;
+		uint64_t reserved_3_3:1;
+		uint64_t txtrig:2;
+		uint64_t rxtrig:2;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_mio_uart2_fcr_s cn52xx;
 	struct cvmx_mio_uart2_fcr_s cn52xxp1;
@@ -3084,8 +4820,13 @@
 union cvmx_mio_uart2_htx {
 	uint64_t u64;
 	struct cvmx_mio_uart2_htx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t htx:1;
+#else
+		uint64_t htx:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_mio_uart2_htx_s cn52xx;
 	struct cvmx_mio_uart2_htx_s cn52xxp1;
@@ -3094,6 +4835,7 @@
 union cvmx_mio_uart2_ier {
 	uint64_t u64;
 	struct cvmx_mio_uart2_ier_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t ptime:1;
 		uint64_t reserved_4_6:3;
@@ -3101,6 +4843,15 @@
 		uint64_t elsi:1;
 		uint64_t etbei:1;
 		uint64_t erbfi:1;
+#else
+		uint64_t erbfi:1;
+		uint64_t etbei:1;
+		uint64_t elsi:1;
+		uint64_t edssi:1;
+		uint64_t reserved_4_6:3;
+		uint64_t ptime:1;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_mio_uart2_ier_s cn52xx;
 	struct cvmx_mio_uart2_ier_s cn52xxp1;
@@ -3109,10 +4860,17 @@
 union cvmx_mio_uart2_iir {
 	uint64_t u64;
 	struct cvmx_mio_uart2_iir_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t fen:2;
 		uint64_t reserved_4_5:2;
 		uint64_t iid:4;
+#else
+		uint64_t iid:4;
+		uint64_t reserved_4_5:2;
+		uint64_t fen:2;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_mio_uart2_iir_s cn52xx;
 	struct cvmx_mio_uart2_iir_s cn52xxp1;
@@ -3121,6 +4879,7 @@
 union cvmx_mio_uart2_lcr {
 	uint64_t u64;
 	struct cvmx_mio_uart2_lcr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t dlab:1;
 		uint64_t brk:1;
@@ -3129,6 +4888,16 @@
 		uint64_t pen:1;
 		uint64_t stop:1;
 		uint64_t cls:2;
+#else
+		uint64_t cls:2;
+		uint64_t stop:1;
+		uint64_t pen:1;
+		uint64_t eps:1;
+		uint64_t reserved_5_5:1;
+		uint64_t brk:1;
+		uint64_t dlab:1;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_mio_uart2_lcr_s cn52xx;
 	struct cvmx_mio_uart2_lcr_s cn52xxp1;
@@ -3137,6 +4906,7 @@
 union cvmx_mio_uart2_lsr {
 	uint64_t u64;
 	struct cvmx_mio_uart2_lsr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t ferr:1;
 		uint64_t temt:1;
@@ -3146,6 +4916,17 @@
 		uint64_t pe:1;
 		uint64_t oe:1;
 		uint64_t dr:1;
+#else
+		uint64_t dr:1;
+		uint64_t oe:1;
+		uint64_t pe:1;
+		uint64_t fe:1;
+		uint64_t bi:1;
+		uint64_t thre:1;
+		uint64_t temt:1;
+		uint64_t ferr:1;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_mio_uart2_lsr_s cn52xx;
 	struct cvmx_mio_uart2_lsr_s cn52xxp1;
@@ -3154,6 +4935,7 @@
 union cvmx_mio_uart2_mcr {
 	uint64_t u64;
 	struct cvmx_mio_uart2_mcr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t afce:1;
 		uint64_t loop:1;
@@ -3161,6 +4943,15 @@
 		uint64_t out1:1;
 		uint64_t rts:1;
 		uint64_t dtr:1;
+#else
+		uint64_t dtr:1;
+		uint64_t rts:1;
+		uint64_t out1:1;
+		uint64_t out2:1;
+		uint64_t loop:1;
+		uint64_t afce:1;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
 	struct cvmx_mio_uart2_mcr_s cn52xx;
 	struct cvmx_mio_uart2_mcr_s cn52xxp1;
@@ -3169,6 +4960,7 @@
 union cvmx_mio_uart2_msr {
 	uint64_t u64;
 	struct cvmx_mio_uart2_msr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t dcd:1;
 		uint64_t ri:1;
@@ -3178,6 +4970,17 @@
 		uint64_t teri:1;
 		uint64_t ddsr:1;
 		uint64_t dcts:1;
+#else
+		uint64_t dcts:1;
+		uint64_t ddsr:1;
+		uint64_t teri:1;
+		uint64_t ddcd:1;
+		uint64_t cts:1;
+		uint64_t dsr:1;
+		uint64_t ri:1;
+		uint64_t dcd:1;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_mio_uart2_msr_s cn52xx;
 	struct cvmx_mio_uart2_msr_s cn52xxp1;
@@ -3186,8 +4989,13 @@
 union cvmx_mio_uart2_rbr {
 	uint64_t u64;
 	struct cvmx_mio_uart2_rbr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t rbr:8;
+#else
+		uint64_t rbr:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_mio_uart2_rbr_s cn52xx;
 	struct cvmx_mio_uart2_rbr_s cn52xxp1;
@@ -3196,8 +5004,13 @@
 union cvmx_mio_uart2_rfl {
 	uint64_t u64;
 	struct cvmx_mio_uart2_rfl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_7_63:57;
 		uint64_t rfl:7;
+#else
+		uint64_t rfl:7;
+		uint64_t reserved_7_63:57;
+#endif
 	} s;
 	struct cvmx_mio_uart2_rfl_s cn52xx;
 	struct cvmx_mio_uart2_rfl_s cn52xxp1;
@@ -3206,10 +5019,17 @@
 union cvmx_mio_uart2_rfw {
 	uint64_t u64;
 	struct cvmx_mio_uart2_rfw_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t rffe:1;
 		uint64_t rfpe:1;
 		uint64_t rfwd:8;
+#else
+		uint64_t rfwd:8;
+		uint64_t rfpe:1;
+		uint64_t rffe:1;
+		uint64_t reserved_10_63:54;
+#endif
 	} s;
 	struct cvmx_mio_uart2_rfw_s cn52xx;
 	struct cvmx_mio_uart2_rfw_s cn52xxp1;
@@ -3218,8 +5038,13 @@
 union cvmx_mio_uart2_sbcr {
 	uint64_t u64;
 	struct cvmx_mio_uart2_sbcr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t sbcr:1;
+#else
+		uint64_t sbcr:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_mio_uart2_sbcr_s cn52xx;
 	struct cvmx_mio_uart2_sbcr_s cn52xxp1;
@@ -3228,8 +5053,13 @@
 union cvmx_mio_uart2_scr {
 	uint64_t u64;
 	struct cvmx_mio_uart2_scr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t scr:8;
+#else
+		uint64_t scr:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_mio_uart2_scr_s cn52xx;
 	struct cvmx_mio_uart2_scr_s cn52xxp1;
@@ -3238,8 +5068,13 @@
 union cvmx_mio_uart2_sfe {
 	uint64_t u64;
 	struct cvmx_mio_uart2_sfe_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t sfe:1;
+#else
+		uint64_t sfe:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_mio_uart2_sfe_s cn52xx;
 	struct cvmx_mio_uart2_sfe_s cn52xxp1;
@@ -3248,10 +5083,17 @@
 union cvmx_mio_uart2_srr {
 	uint64_t u64;
 	struct cvmx_mio_uart2_srr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_3_63:61;
 		uint64_t stfr:1;
 		uint64_t srfr:1;
 		uint64_t usr:1;
+#else
+		uint64_t usr:1;
+		uint64_t srfr:1;
+		uint64_t stfr:1;
+		uint64_t reserved_3_63:61;
+#endif
 	} s;
 	struct cvmx_mio_uart2_srr_s cn52xx;
 	struct cvmx_mio_uart2_srr_s cn52xxp1;
@@ -3260,8 +5102,13 @@
 union cvmx_mio_uart2_srt {
 	uint64_t u64;
 	struct cvmx_mio_uart2_srt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t srt:2;
+#else
+		uint64_t srt:2;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_mio_uart2_srt_s cn52xx;
 	struct cvmx_mio_uart2_srt_s cn52xxp1;
@@ -3270,8 +5117,13 @@
 union cvmx_mio_uart2_srts {
 	uint64_t u64;
 	struct cvmx_mio_uart2_srts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t srts:1;
+#else
+		uint64_t srts:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_mio_uart2_srts_s cn52xx;
 	struct cvmx_mio_uart2_srts_s cn52xxp1;
@@ -3280,8 +5132,13 @@
 union cvmx_mio_uart2_stt {
 	uint64_t u64;
 	struct cvmx_mio_uart2_stt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t stt:2;
+#else
+		uint64_t stt:2;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_mio_uart2_stt_s cn52xx;
 	struct cvmx_mio_uart2_stt_s cn52xxp1;
@@ -3290,8 +5147,13 @@
 union cvmx_mio_uart2_tfl {
 	uint64_t u64;
 	struct cvmx_mio_uart2_tfl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_7_63:57;
 		uint64_t tfl:7;
+#else
+		uint64_t tfl:7;
+		uint64_t reserved_7_63:57;
+#endif
 	} s;
 	struct cvmx_mio_uart2_tfl_s cn52xx;
 	struct cvmx_mio_uart2_tfl_s cn52xxp1;
@@ -3300,8 +5162,13 @@
 union cvmx_mio_uart2_tfr {
 	uint64_t u64;
 	struct cvmx_mio_uart2_tfr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t tfr:8;
+#else
+		uint64_t tfr:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_mio_uart2_tfr_s cn52xx;
 	struct cvmx_mio_uart2_tfr_s cn52xxp1;
@@ -3310,8 +5177,13 @@
 union cvmx_mio_uart2_thr {
 	uint64_t u64;
 	struct cvmx_mio_uart2_thr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t thr:8;
+#else
+		uint64_t thr:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_mio_uart2_thr_s cn52xx;
 	struct cvmx_mio_uart2_thr_s cn52xxp1;
@@ -3320,12 +5192,21 @@
 union cvmx_mio_uart2_usr {
 	uint64_t u64;
 	struct cvmx_mio_uart2_usr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t rff:1;
 		uint64_t rfne:1;
 		uint64_t tfe:1;
 		uint64_t tfnf:1;
 		uint64_t busy:1;
+#else
+		uint64_t busy:1;
+		uint64_t tfnf:1;
+		uint64_t tfe:1;
+		uint64_t rfne:1;
+		uint64_t rff:1;
+		uint64_t reserved_5_63:59;
+#endif
 	} s;
 	struct cvmx_mio_uart2_usr_s cn52xx;
 	struct cvmx_mio_uart2_usr_s cn52xxp1;
diff --git a/arch/mips/include/asm/octeon/cvmx-mixx-defs.h b/arch/mips/include/asm/octeon/cvmx-mixx-defs.h
index 7057c44..3155e60 100644
--- a/arch/mips/include/asm/octeon/cvmx-mixx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-mixx-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -47,6 +47,7 @@
 union cvmx_mixx_bist {
 	uint64_t u64;
 	struct cvmx_mixx_bist_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t opfdat:1;
 		uint64_t mrgdat:1;
@@ -54,24 +55,46 @@
 		uint64_t ipfdat:1;
 		uint64_t irfdat:1;
 		uint64_t orfdat:1;
+#else
+		uint64_t orfdat:1;
+		uint64_t irfdat:1;
+		uint64_t ipfdat:1;
+		uint64_t mrqdat:1;
+		uint64_t mrgdat:1;
+		uint64_t opfdat:1;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
 	struct cvmx_mixx_bist_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t mrqdat:1;
 		uint64_t ipfdat:1;
 		uint64_t irfdat:1;
 		uint64_t orfdat:1;
+#else
+		uint64_t orfdat:1;
+		uint64_t irfdat:1;
+		uint64_t ipfdat:1;
+		uint64_t mrqdat:1;
+		uint64_t reserved_4_63:60;
+#endif
 	} cn52xx;
 	struct cvmx_mixx_bist_cn52xx cn52xxp1;
 	struct cvmx_mixx_bist_cn52xx cn56xx;
 	struct cvmx_mixx_bist_cn52xx cn56xxp1;
+	struct cvmx_mixx_bist_s cn61xx;
 	struct cvmx_mixx_bist_s cn63xx;
 	struct cvmx_mixx_bist_s cn63xxp1;
+	struct cvmx_mixx_bist_s cn66xx;
+	struct cvmx_mixx_bist_s cn68xx;
+	struct cvmx_mixx_bist_s cn68xxp1;
 };
 
 union cvmx_mixx_ctl {
 	uint64_t u64;
 	struct cvmx_mixx_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t ts_thresh:4;
 		uint64_t crc_strip:1;
@@ -81,8 +104,20 @@
 		uint64_t lendian:1;
 		uint64_t nbtarb:1;
 		uint64_t mrq_hwm:2;
+#else
+		uint64_t mrq_hwm:2;
+		uint64_t nbtarb:1;
+		uint64_t lendian:1;
+		uint64_t reset:1;
+		uint64_t en:1;
+		uint64_t busy:1;
+		uint64_t crc_strip:1;
+		uint64_t ts_thresh:4;
+		uint64_t reserved_12_63:52;
+#endif
 	} s;
 	struct cvmx_mixx_ctl_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t crc_strip:1;
 		uint64_t busy:1;
@@ -91,17 +126,32 @@
 		uint64_t lendian:1;
 		uint64_t nbtarb:1;
 		uint64_t mrq_hwm:2;
+#else
+		uint64_t mrq_hwm:2;
+		uint64_t nbtarb:1;
+		uint64_t lendian:1;
+		uint64_t reset:1;
+		uint64_t en:1;
+		uint64_t busy:1;
+		uint64_t crc_strip:1;
+		uint64_t reserved_8_63:56;
+#endif
 	} cn52xx;
 	struct cvmx_mixx_ctl_cn52xx cn52xxp1;
 	struct cvmx_mixx_ctl_cn52xx cn56xx;
 	struct cvmx_mixx_ctl_cn52xx cn56xxp1;
+	struct cvmx_mixx_ctl_s cn61xx;
 	struct cvmx_mixx_ctl_s cn63xx;
 	struct cvmx_mixx_ctl_s cn63xxp1;
+	struct cvmx_mixx_ctl_s cn66xx;
+	struct cvmx_mixx_ctl_s cn68xx;
+	struct cvmx_mixx_ctl_s cn68xxp1;
 };
 
 union cvmx_mixx_intena {
 	uint64_t u64;
 	struct cvmx_mixx_intena_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t tsena:1;
 		uint64_t orunena:1;
@@ -111,8 +161,20 @@
 		uint64_t othena:1;
 		uint64_t ivfena:1;
 		uint64_t ovfena:1;
+#else
+		uint64_t ovfena:1;
+		uint64_t ivfena:1;
+		uint64_t othena:1;
+		uint64_t ithena:1;
+		uint64_t data_drpena:1;
+		uint64_t irunena:1;
+		uint64_t orunena:1;
+		uint64_t tsena:1;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_mixx_intena_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_7_63:57;
 		uint64_t orunena:1;
 		uint64_t irunena:1;
@@ -121,84 +183,148 @@
 		uint64_t othena:1;
 		uint64_t ivfena:1;
 		uint64_t ovfena:1;
+#else
+		uint64_t ovfena:1;
+		uint64_t ivfena:1;
+		uint64_t othena:1;
+		uint64_t ithena:1;
+		uint64_t data_drpena:1;
+		uint64_t irunena:1;
+		uint64_t orunena:1;
+		uint64_t reserved_7_63:57;
+#endif
 	} cn52xx;
 	struct cvmx_mixx_intena_cn52xx cn52xxp1;
 	struct cvmx_mixx_intena_cn52xx cn56xx;
 	struct cvmx_mixx_intena_cn52xx cn56xxp1;
+	struct cvmx_mixx_intena_s cn61xx;
 	struct cvmx_mixx_intena_s cn63xx;
 	struct cvmx_mixx_intena_s cn63xxp1;
+	struct cvmx_mixx_intena_s cn66xx;
+	struct cvmx_mixx_intena_s cn68xx;
+	struct cvmx_mixx_intena_s cn68xxp1;
 };
 
 union cvmx_mixx_ircnt {
 	uint64_t u64;
 	struct cvmx_mixx_ircnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t ircnt:20;
+#else
+		uint64_t ircnt:20;
+		uint64_t reserved_20_63:44;
+#endif
 	} s;
 	struct cvmx_mixx_ircnt_s cn52xx;
 	struct cvmx_mixx_ircnt_s cn52xxp1;
 	struct cvmx_mixx_ircnt_s cn56xx;
 	struct cvmx_mixx_ircnt_s cn56xxp1;
+	struct cvmx_mixx_ircnt_s cn61xx;
 	struct cvmx_mixx_ircnt_s cn63xx;
 	struct cvmx_mixx_ircnt_s cn63xxp1;
+	struct cvmx_mixx_ircnt_s cn66xx;
+	struct cvmx_mixx_ircnt_s cn68xx;
+	struct cvmx_mixx_ircnt_s cn68xxp1;
 };
 
 union cvmx_mixx_irhwm {
 	uint64_t u64;
 	struct cvmx_mixx_irhwm_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_40_63:24;
 		uint64_t ibplwm:20;
 		uint64_t irhwm:20;
+#else
+		uint64_t irhwm:20;
+		uint64_t ibplwm:20;
+		uint64_t reserved_40_63:24;
+#endif
 	} s;
 	struct cvmx_mixx_irhwm_s cn52xx;
 	struct cvmx_mixx_irhwm_s cn52xxp1;
 	struct cvmx_mixx_irhwm_s cn56xx;
 	struct cvmx_mixx_irhwm_s cn56xxp1;
+	struct cvmx_mixx_irhwm_s cn61xx;
 	struct cvmx_mixx_irhwm_s cn63xx;
 	struct cvmx_mixx_irhwm_s cn63xxp1;
+	struct cvmx_mixx_irhwm_s cn66xx;
+	struct cvmx_mixx_irhwm_s cn68xx;
+	struct cvmx_mixx_irhwm_s cn68xxp1;
 };
 
 union cvmx_mixx_iring1 {
 	uint64_t u64;
 	struct cvmx_mixx_iring1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_60_63:4;
 		uint64_t isize:20;
 		uint64_t ibase:37;
 		uint64_t reserved_0_2:3;
+#else
+		uint64_t reserved_0_2:3;
+		uint64_t ibase:37;
+		uint64_t isize:20;
+		uint64_t reserved_60_63:4;
+#endif
 	} s;
 	struct cvmx_mixx_iring1_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_60_63:4;
 		uint64_t isize:20;
 		uint64_t reserved_36_39:4;
 		uint64_t ibase:33;
 		uint64_t reserved_0_2:3;
+#else
+		uint64_t reserved_0_2:3;
+		uint64_t ibase:33;
+		uint64_t reserved_36_39:4;
+		uint64_t isize:20;
+		uint64_t reserved_60_63:4;
+#endif
 	} cn52xx;
 	struct cvmx_mixx_iring1_cn52xx cn52xxp1;
 	struct cvmx_mixx_iring1_cn52xx cn56xx;
 	struct cvmx_mixx_iring1_cn52xx cn56xxp1;
+	struct cvmx_mixx_iring1_s cn61xx;
 	struct cvmx_mixx_iring1_s cn63xx;
 	struct cvmx_mixx_iring1_s cn63xxp1;
+	struct cvmx_mixx_iring1_s cn66xx;
+	struct cvmx_mixx_iring1_s cn68xx;
+	struct cvmx_mixx_iring1_s cn68xxp1;
 };
 
 union cvmx_mixx_iring2 {
 	uint64_t u64;
 	struct cvmx_mixx_iring2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_52_63:12;
 		uint64_t itlptr:20;
 		uint64_t reserved_20_31:12;
 		uint64_t idbell:20;
+#else
+		uint64_t idbell:20;
+		uint64_t reserved_20_31:12;
+		uint64_t itlptr:20;
+		uint64_t reserved_52_63:12;
+#endif
 	} s;
 	struct cvmx_mixx_iring2_s cn52xx;
 	struct cvmx_mixx_iring2_s cn52xxp1;
 	struct cvmx_mixx_iring2_s cn56xx;
 	struct cvmx_mixx_iring2_s cn56xxp1;
+	struct cvmx_mixx_iring2_s cn61xx;
 	struct cvmx_mixx_iring2_s cn63xx;
 	struct cvmx_mixx_iring2_s cn63xxp1;
+	struct cvmx_mixx_iring2_s cn66xx;
+	struct cvmx_mixx_iring2_s cn68xx;
+	struct cvmx_mixx_iring2_s cn68xxp1;
 };
 
 union cvmx_mixx_isr {
 	uint64_t u64;
 	struct cvmx_mixx_isr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t ts:1;
 		uint64_t orun:1;
@@ -208,8 +334,20 @@
 		uint64_t orthresh:1;
 		uint64_t idblovf:1;
 		uint64_t odblovf:1;
+#else
+		uint64_t odblovf:1;
+		uint64_t idblovf:1;
+		uint64_t orthresh:1;
+		uint64_t irthresh:1;
+		uint64_t data_drp:1;
+		uint64_t irun:1;
+		uint64_t orun:1;
+		uint64_t ts:1;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_mixx_isr_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_7_63:57;
 		uint64_t orun:1;
 		uint64_t irun:1;
@@ -218,117 +356,211 @@
 		uint64_t orthresh:1;
 		uint64_t idblovf:1;
 		uint64_t odblovf:1;
+#else
+		uint64_t odblovf:1;
+		uint64_t idblovf:1;
+		uint64_t orthresh:1;
+		uint64_t irthresh:1;
+		uint64_t data_drp:1;
+		uint64_t irun:1;
+		uint64_t orun:1;
+		uint64_t reserved_7_63:57;
+#endif
 	} cn52xx;
 	struct cvmx_mixx_isr_cn52xx cn52xxp1;
 	struct cvmx_mixx_isr_cn52xx cn56xx;
 	struct cvmx_mixx_isr_cn52xx cn56xxp1;
+	struct cvmx_mixx_isr_s cn61xx;
 	struct cvmx_mixx_isr_s cn63xx;
 	struct cvmx_mixx_isr_s cn63xxp1;
+	struct cvmx_mixx_isr_s cn66xx;
+	struct cvmx_mixx_isr_s cn68xx;
+	struct cvmx_mixx_isr_s cn68xxp1;
 };
 
 union cvmx_mixx_orcnt {
 	uint64_t u64;
 	struct cvmx_mixx_orcnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t orcnt:20;
+#else
+		uint64_t orcnt:20;
+		uint64_t reserved_20_63:44;
+#endif
 	} s;
 	struct cvmx_mixx_orcnt_s cn52xx;
 	struct cvmx_mixx_orcnt_s cn52xxp1;
 	struct cvmx_mixx_orcnt_s cn56xx;
 	struct cvmx_mixx_orcnt_s cn56xxp1;
+	struct cvmx_mixx_orcnt_s cn61xx;
 	struct cvmx_mixx_orcnt_s cn63xx;
 	struct cvmx_mixx_orcnt_s cn63xxp1;
+	struct cvmx_mixx_orcnt_s cn66xx;
+	struct cvmx_mixx_orcnt_s cn68xx;
+	struct cvmx_mixx_orcnt_s cn68xxp1;
 };
 
 union cvmx_mixx_orhwm {
 	uint64_t u64;
 	struct cvmx_mixx_orhwm_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t orhwm:20;
+#else
+		uint64_t orhwm:20;
+		uint64_t reserved_20_63:44;
+#endif
 	} s;
 	struct cvmx_mixx_orhwm_s cn52xx;
 	struct cvmx_mixx_orhwm_s cn52xxp1;
 	struct cvmx_mixx_orhwm_s cn56xx;
 	struct cvmx_mixx_orhwm_s cn56xxp1;
+	struct cvmx_mixx_orhwm_s cn61xx;
 	struct cvmx_mixx_orhwm_s cn63xx;
 	struct cvmx_mixx_orhwm_s cn63xxp1;
+	struct cvmx_mixx_orhwm_s cn66xx;
+	struct cvmx_mixx_orhwm_s cn68xx;
+	struct cvmx_mixx_orhwm_s cn68xxp1;
 };
 
 union cvmx_mixx_oring1 {
 	uint64_t u64;
 	struct cvmx_mixx_oring1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_60_63:4;
 		uint64_t osize:20;
 		uint64_t obase:37;
 		uint64_t reserved_0_2:3;
+#else
+		uint64_t reserved_0_2:3;
+		uint64_t obase:37;
+		uint64_t osize:20;
+		uint64_t reserved_60_63:4;
+#endif
 	} s;
 	struct cvmx_mixx_oring1_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_60_63:4;
 		uint64_t osize:20;
 		uint64_t reserved_36_39:4;
 		uint64_t obase:33;
 		uint64_t reserved_0_2:3;
+#else
+		uint64_t reserved_0_2:3;
+		uint64_t obase:33;
+		uint64_t reserved_36_39:4;
+		uint64_t osize:20;
+		uint64_t reserved_60_63:4;
+#endif
 	} cn52xx;
 	struct cvmx_mixx_oring1_cn52xx cn52xxp1;
 	struct cvmx_mixx_oring1_cn52xx cn56xx;
 	struct cvmx_mixx_oring1_cn52xx cn56xxp1;
+	struct cvmx_mixx_oring1_s cn61xx;
 	struct cvmx_mixx_oring1_s cn63xx;
 	struct cvmx_mixx_oring1_s cn63xxp1;
+	struct cvmx_mixx_oring1_s cn66xx;
+	struct cvmx_mixx_oring1_s cn68xx;
+	struct cvmx_mixx_oring1_s cn68xxp1;
 };
 
 union cvmx_mixx_oring2 {
 	uint64_t u64;
 	struct cvmx_mixx_oring2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_52_63:12;
 		uint64_t otlptr:20;
 		uint64_t reserved_20_31:12;
 		uint64_t odbell:20;
+#else
+		uint64_t odbell:20;
+		uint64_t reserved_20_31:12;
+		uint64_t otlptr:20;
+		uint64_t reserved_52_63:12;
+#endif
 	} s;
 	struct cvmx_mixx_oring2_s cn52xx;
 	struct cvmx_mixx_oring2_s cn52xxp1;
 	struct cvmx_mixx_oring2_s cn56xx;
 	struct cvmx_mixx_oring2_s cn56xxp1;
+	struct cvmx_mixx_oring2_s cn61xx;
 	struct cvmx_mixx_oring2_s cn63xx;
 	struct cvmx_mixx_oring2_s cn63xxp1;
+	struct cvmx_mixx_oring2_s cn66xx;
+	struct cvmx_mixx_oring2_s cn68xx;
+	struct cvmx_mixx_oring2_s cn68xxp1;
 };
 
 union cvmx_mixx_remcnt {
 	uint64_t u64;
 	struct cvmx_mixx_remcnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_52_63:12;
 		uint64_t iremcnt:20;
 		uint64_t reserved_20_31:12;
 		uint64_t oremcnt:20;
+#else
+		uint64_t oremcnt:20;
+		uint64_t reserved_20_31:12;
+		uint64_t iremcnt:20;
+		uint64_t reserved_52_63:12;
+#endif
 	} s;
 	struct cvmx_mixx_remcnt_s cn52xx;
 	struct cvmx_mixx_remcnt_s cn52xxp1;
 	struct cvmx_mixx_remcnt_s cn56xx;
 	struct cvmx_mixx_remcnt_s cn56xxp1;
+	struct cvmx_mixx_remcnt_s cn61xx;
 	struct cvmx_mixx_remcnt_s cn63xx;
 	struct cvmx_mixx_remcnt_s cn63xxp1;
+	struct cvmx_mixx_remcnt_s cn66xx;
+	struct cvmx_mixx_remcnt_s cn68xx;
+	struct cvmx_mixx_remcnt_s cn68xxp1;
 };
 
 union cvmx_mixx_tsctl {
 	uint64_t u64;
 	struct cvmx_mixx_tsctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_21_63:43;
 		uint64_t tsavl:5;
 		uint64_t reserved_13_15:3;
 		uint64_t tstot:5;
 		uint64_t reserved_5_7:3;
 		uint64_t tscnt:5;
+#else
+		uint64_t tscnt:5;
+		uint64_t reserved_5_7:3;
+		uint64_t tstot:5;
+		uint64_t reserved_13_15:3;
+		uint64_t tsavl:5;
+		uint64_t reserved_21_63:43;
+#endif
 	} s;
+	struct cvmx_mixx_tsctl_s cn61xx;
 	struct cvmx_mixx_tsctl_s cn63xx;
 	struct cvmx_mixx_tsctl_s cn63xxp1;
+	struct cvmx_mixx_tsctl_s cn66xx;
+	struct cvmx_mixx_tsctl_s cn68xx;
+	struct cvmx_mixx_tsctl_s cn68xxp1;
 };
 
 union cvmx_mixx_tstamp {
 	uint64_t u64;
 	struct cvmx_mixx_tstamp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t tstamp:64;
+#else
+		uint64_t tstamp:64;
+#endif
 	} s;
+	struct cvmx_mixx_tstamp_s cn61xx;
 	struct cvmx_mixx_tstamp_s cn63xx;
 	struct cvmx_mixx_tstamp_s cn63xxp1;
+	struct cvmx_mixx_tstamp_s cn66xx;
+	struct cvmx_mixx_tstamp_s cn68xx;
+	struct cvmx_mixx_tstamp_s cn68xxp1;
 };
 
 #endif
diff --git a/arch/mips/include/asm/octeon/cvmx-mpi-defs.h b/arch/mips/include/asm/octeon/cvmx-mpi-defs.h
new file mode 100644
index 0000000..4615b10
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-mpi-defs.h
@@ -0,0 +1,328 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2012 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_MPI_DEFS_H__
+#define __CVMX_MPI_DEFS_H__
+
+#define CVMX_MPI_CFG (CVMX_ADD_IO_SEG(0x0001070000001000ull))
+#define CVMX_MPI_DATX(offset) (CVMX_ADD_IO_SEG(0x0001070000001080ull) + ((offset) & 15) * 8)
+#define CVMX_MPI_STS (CVMX_ADD_IO_SEG(0x0001070000001008ull))
+#define CVMX_MPI_TX (CVMX_ADD_IO_SEG(0x0001070000001010ull))
+
+union cvmx_mpi_cfg {
+	uint64_t u64;
+	struct cvmx_mpi_cfg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_29_63:35;
+		uint64_t clkdiv:13;
+		uint64_t csena3:1;
+		uint64_t csena2:1;
+		uint64_t csena1:1;
+		uint64_t csena0:1;
+		uint64_t cslate:1;
+		uint64_t tritx:1;
+		uint64_t idleclks:2;
+		uint64_t cshi:1;
+		uint64_t csena:1;
+		uint64_t int_ena:1;
+		uint64_t lsbfirst:1;
+		uint64_t wireor:1;
+		uint64_t clk_cont:1;
+		uint64_t idlelo:1;
+		uint64_t enable:1;
+#else
+		uint64_t enable:1;
+		uint64_t idlelo:1;
+		uint64_t clk_cont:1;
+		uint64_t wireor:1;
+		uint64_t lsbfirst:1;
+		uint64_t int_ena:1;
+		uint64_t csena:1;
+		uint64_t cshi:1;
+		uint64_t idleclks:2;
+		uint64_t tritx:1;
+		uint64_t cslate:1;
+		uint64_t csena0:1;
+		uint64_t csena1:1;
+		uint64_t csena2:1;
+		uint64_t csena3:1;
+		uint64_t clkdiv:13;
+		uint64_t reserved_29_63:35;
+#endif
+	} s;
+	struct cvmx_mpi_cfg_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_29_63:35;
+		uint64_t clkdiv:13;
+		uint64_t reserved_12_15:4;
+		uint64_t cslate:1;
+		uint64_t tritx:1;
+		uint64_t idleclks:2;
+		uint64_t cshi:1;
+		uint64_t csena:1;
+		uint64_t int_ena:1;
+		uint64_t lsbfirst:1;
+		uint64_t wireor:1;
+		uint64_t clk_cont:1;
+		uint64_t idlelo:1;
+		uint64_t enable:1;
+#else
+		uint64_t enable:1;
+		uint64_t idlelo:1;
+		uint64_t clk_cont:1;
+		uint64_t wireor:1;
+		uint64_t lsbfirst:1;
+		uint64_t int_ena:1;
+		uint64_t csena:1;
+		uint64_t cshi:1;
+		uint64_t idleclks:2;
+		uint64_t tritx:1;
+		uint64_t cslate:1;
+		uint64_t reserved_12_15:4;
+		uint64_t clkdiv:13;
+		uint64_t reserved_29_63:35;
+#endif
+	} cn30xx;
+	struct cvmx_mpi_cfg_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_29_63:35;
+		uint64_t clkdiv:13;
+		uint64_t reserved_11_15:5;
+		uint64_t tritx:1;
+		uint64_t idleclks:2;
+		uint64_t cshi:1;
+		uint64_t csena:1;
+		uint64_t int_ena:1;
+		uint64_t lsbfirst:1;
+		uint64_t wireor:1;
+		uint64_t clk_cont:1;
+		uint64_t idlelo:1;
+		uint64_t enable:1;
+#else
+		uint64_t enable:1;
+		uint64_t idlelo:1;
+		uint64_t clk_cont:1;
+		uint64_t wireor:1;
+		uint64_t lsbfirst:1;
+		uint64_t int_ena:1;
+		uint64_t csena:1;
+		uint64_t cshi:1;
+		uint64_t idleclks:2;
+		uint64_t tritx:1;
+		uint64_t reserved_11_15:5;
+		uint64_t clkdiv:13;
+		uint64_t reserved_29_63:35;
+#endif
+	} cn31xx;
+	struct cvmx_mpi_cfg_cn30xx cn50xx;
+	struct cvmx_mpi_cfg_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_29_63:35;
+		uint64_t clkdiv:13;
+		uint64_t reserved_14_15:2;
+		uint64_t csena1:1;
+		uint64_t csena0:1;
+		uint64_t cslate:1;
+		uint64_t tritx:1;
+		uint64_t idleclks:2;
+		uint64_t cshi:1;
+		uint64_t reserved_6_6:1;
+		uint64_t int_ena:1;
+		uint64_t lsbfirst:1;
+		uint64_t wireor:1;
+		uint64_t clk_cont:1;
+		uint64_t idlelo:1;
+		uint64_t enable:1;
+#else
+		uint64_t enable:1;
+		uint64_t idlelo:1;
+		uint64_t clk_cont:1;
+		uint64_t wireor:1;
+		uint64_t lsbfirst:1;
+		uint64_t int_ena:1;
+		uint64_t reserved_6_6:1;
+		uint64_t cshi:1;
+		uint64_t idleclks:2;
+		uint64_t tritx:1;
+		uint64_t cslate:1;
+		uint64_t csena0:1;
+		uint64_t csena1:1;
+		uint64_t reserved_14_15:2;
+		uint64_t clkdiv:13;
+		uint64_t reserved_29_63:35;
+#endif
+	} cn61xx;
+	struct cvmx_mpi_cfg_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_29_63:35;
+		uint64_t clkdiv:13;
+		uint64_t csena3:1;
+		uint64_t csena2:1;
+		uint64_t reserved_12_13:2;
+		uint64_t cslate:1;
+		uint64_t tritx:1;
+		uint64_t idleclks:2;
+		uint64_t cshi:1;
+		uint64_t reserved_6_6:1;
+		uint64_t int_ena:1;
+		uint64_t lsbfirst:1;
+		uint64_t wireor:1;
+		uint64_t clk_cont:1;
+		uint64_t idlelo:1;
+		uint64_t enable:1;
+#else
+		uint64_t enable:1;
+		uint64_t idlelo:1;
+		uint64_t clk_cont:1;
+		uint64_t wireor:1;
+		uint64_t lsbfirst:1;
+		uint64_t int_ena:1;
+		uint64_t reserved_6_6:1;
+		uint64_t cshi:1;
+		uint64_t idleclks:2;
+		uint64_t tritx:1;
+		uint64_t cslate:1;
+		uint64_t reserved_12_13:2;
+		uint64_t csena2:1;
+		uint64_t csena3:1;
+		uint64_t clkdiv:13;
+		uint64_t reserved_29_63:35;
+#endif
+	} cn66xx;
+	struct cvmx_mpi_cfg_cn61xx cnf71xx;
+};
+
+union cvmx_mpi_datx {
+	uint64_t u64;
+	struct cvmx_mpi_datx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_8_63:56;
+		uint64_t data:8;
+#else
+		uint64_t data:8;
+		uint64_t reserved_8_63:56;
+#endif
+	} s;
+	struct cvmx_mpi_datx_s cn30xx;
+	struct cvmx_mpi_datx_s cn31xx;
+	struct cvmx_mpi_datx_s cn50xx;
+	struct cvmx_mpi_datx_s cn61xx;
+	struct cvmx_mpi_datx_s cn66xx;
+	struct cvmx_mpi_datx_s cnf71xx;
+};
+
+union cvmx_mpi_sts {
+	uint64_t u64;
+	struct cvmx_mpi_sts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_13_63:51;
+		uint64_t rxnum:5;
+		uint64_t reserved_1_7:7;
+		uint64_t busy:1;
+#else
+		uint64_t busy:1;
+		uint64_t reserved_1_7:7;
+		uint64_t rxnum:5;
+		uint64_t reserved_13_63:51;
+#endif
+	} s;
+	struct cvmx_mpi_sts_s cn30xx;
+	struct cvmx_mpi_sts_s cn31xx;
+	struct cvmx_mpi_sts_s cn50xx;
+	struct cvmx_mpi_sts_s cn61xx;
+	struct cvmx_mpi_sts_s cn66xx;
+	struct cvmx_mpi_sts_s cnf71xx;
+};
+
+union cvmx_mpi_tx {
+	uint64_t u64;
+	struct cvmx_mpi_tx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_22_63:42;
+		uint64_t csid:2;
+		uint64_t reserved_17_19:3;
+		uint64_t leavecs:1;
+		uint64_t reserved_13_15:3;
+		uint64_t txnum:5;
+		uint64_t reserved_5_7:3;
+		uint64_t totnum:5;
+#else
+		uint64_t totnum:5;
+		uint64_t reserved_5_7:3;
+		uint64_t txnum:5;
+		uint64_t reserved_13_15:3;
+		uint64_t leavecs:1;
+		uint64_t reserved_17_19:3;
+		uint64_t csid:2;
+		uint64_t reserved_22_63:42;
+#endif
+	} s;
+	struct cvmx_mpi_tx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_17_63:47;
+		uint64_t leavecs:1;
+		uint64_t reserved_13_15:3;
+		uint64_t txnum:5;
+		uint64_t reserved_5_7:3;
+		uint64_t totnum:5;
+#else
+		uint64_t totnum:5;
+		uint64_t reserved_5_7:3;
+		uint64_t txnum:5;
+		uint64_t reserved_13_15:3;
+		uint64_t leavecs:1;
+		uint64_t reserved_17_63:47;
+#endif
+	} cn30xx;
+	struct cvmx_mpi_tx_cn30xx cn31xx;
+	struct cvmx_mpi_tx_cn30xx cn50xx;
+	struct cvmx_mpi_tx_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_21_63:43;
+		uint64_t csid:1;
+		uint64_t reserved_17_19:3;
+		uint64_t leavecs:1;
+		uint64_t reserved_13_15:3;
+		uint64_t txnum:5;
+		uint64_t reserved_5_7:3;
+		uint64_t totnum:5;
+#else
+		uint64_t totnum:5;
+		uint64_t reserved_5_7:3;
+		uint64_t txnum:5;
+		uint64_t reserved_13_15:3;
+		uint64_t leavecs:1;
+		uint64_t reserved_17_19:3;
+		uint64_t csid:1;
+		uint64_t reserved_21_63:43;
+#endif
+	} cn61xx;
+	struct cvmx_mpi_tx_s cn66xx;
+	struct cvmx_mpi_tx_cn61xx cnf71xx;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-npei-defs.h b/arch/mips/include/asm/octeon/cvmx-npei-defs.h
index a3075f7..58114d4 100644
--- a/arch/mips/include/asm/octeon/cvmx-npei-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-npei-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2011 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -140,11 +140,19 @@
 union cvmx_npei_bar1_indexx {
 	uint32_t u32;
 	struct cvmx_npei_bar1_indexx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_18_31:14;
 		uint32_t addr_idx:14;
 		uint32_t ca:1;
 		uint32_t end_swp:2;
 		uint32_t addr_v:1;
+#else
+		uint32_t addr_v:1;
+		uint32_t end_swp:2;
+		uint32_t ca:1;
+		uint32_t addr_idx:14;
+		uint32_t reserved_18_31:14;
+#endif
 	} s;
 	struct cvmx_npei_bar1_indexx_s cn52xx;
 	struct cvmx_npei_bar1_indexx_s cn52xxp1;
@@ -155,6 +163,7 @@
 union cvmx_npei_bist_status {
 	uint64_t u64;
 	struct cvmx_npei_bist_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t pkt_rdf:1;
 		uint64_t reserved_60_62:3;
 		uint64_t pcr_gim:1;
@@ -204,8 +213,60 @@
 		uint64_t reserved_2_2:1;
 		uint64_t msi:1;
 		uint64_t ncb_cmd:1;
+#else
+		uint64_t ncb_cmd:1;
+		uint64_t msi:1;
+		uint64_t reserved_2_2:1;
+		uint64_t dif3:1;
+		uint64_t dif2:1;
+		uint64_t dif1:1;
+		uint64_t dif0:1;
+		uint64_t csm1:1;
+		uint64_t csm0:1;
+		uint64_t p2n1_p1:1;
+		uint64_t p2n1_p0:1;
+		uint64_t p2n1_n:1;
+		uint64_t p2n1_c1:1;
+		uint64_t p2n1_c0:1;
+		uint64_t p2n0_p1:1;
+		uint64_t p2n0_p0:1;
+		uint64_t p2n0_n:1;
+		uint64_t p2n0_c1:1;
+		uint64_t p2n0_c0:1;
+		uint64_t p2n0_co:1;
+		uint64_t p2n0_no:1;
+		uint64_t p2n0_po:1;
+		uint64_t p2n1_co:1;
+		uint64_t p2n1_no:1;
+		uint64_t p2n1_po:1;
+		uint64_t cpl_p1:1;
+		uint64_t cpl_p0:1;
+		uint64_t n2p1_o:1;
+		uint64_t n2p1_c:1;
+		uint64_t n2p0_o:1;
+		uint64_t n2p0_c:1;
+		uint64_t reserved_31_31:1;
+		uint64_t d3_pst:1;
+		uint64_t d2_pst:1;
+		uint64_t d1_pst:1;
+		uint64_t d0_pst:1;
+		uint64_t reserved_36_47:12;
+		uint64_t pkt_slm:1;
+		uint64_t pkt_ind:1;
+		uint64_t reserved_50_52:3;
+		uint64_t pcsr_sl:1;
+		uint64_t pcsr_id:1;
+		uint64_t pcsr_cnt:1;
+		uint64_t pcsr_im:1;
+		uint64_t pcsr_int:1;
+		uint64_t pkt_pif:1;
+		uint64_t pcr_gim:1;
+		uint64_t reserved_60_62:3;
+		uint64_t pkt_rdf:1;
+#endif
 	} s;
 	struct cvmx_npei_bist_status_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t pkt_rdf:1;
 		uint64_t reserved_60_62:3;
 		uint64_t pcr_gim:1;
@@ -264,8 +325,69 @@
 		uint64_t dif4:1;
 		uint64_t msi:1;
 		uint64_t ncb_cmd:1;
+#else
+		uint64_t ncb_cmd:1;
+		uint64_t msi:1;
+		uint64_t dif4:1;
+		uint64_t dif3:1;
+		uint64_t dif2:1;
+		uint64_t dif1:1;
+		uint64_t dif0:1;
+		uint64_t csm1:1;
+		uint64_t csm0:1;
+		uint64_t p2n1_p1:1;
+		uint64_t p2n1_p0:1;
+		uint64_t p2n1_n:1;
+		uint64_t p2n1_c1:1;
+		uint64_t p2n1_c0:1;
+		uint64_t p2n0_p1:1;
+		uint64_t p2n0_p0:1;
+		uint64_t p2n0_n:1;
+		uint64_t p2n0_c1:1;
+		uint64_t p2n0_c0:1;
+		uint64_t p2n0_co:1;
+		uint64_t p2n0_no:1;
+		uint64_t p2n0_po:1;
+		uint64_t p2n1_co:1;
+		uint64_t p2n1_no:1;
+		uint64_t p2n1_po:1;
+		uint64_t cpl_p1:1;
+		uint64_t cpl_p0:1;
+		uint64_t n2p1_o:1;
+		uint64_t n2p1_c:1;
+		uint64_t n2p0_o:1;
+		uint64_t n2p0_c:1;
+		uint64_t d4_pst:1;
+		uint64_t d3_pst:1;
+		uint64_t d2_pst:1;
+		uint64_t d1_pst:1;
+		uint64_t d0_pst:1;
+		uint64_t reserved_36_39:4;
+		uint64_t ds_mem:1;
+		uint64_t d4_mem:1;
+		uint64_t d3_mem:1;
+		uint64_t d2_mem:1;
+		uint64_t d1_mem:1;
+		uint64_t d0_mem:1;
+		uint64_t pkt_pop1:1;
+		uint64_t pkt_pop0:1;
+		uint64_t reserved_48_49:2;
+		uint64_t pkt_pof:1;
+		uint64_t pkt_pfm:1;
+		uint64_t pkt_imem:1;
+		uint64_t pcsr_sl:1;
+		uint64_t pcsr_id:1;
+		uint64_t pcsr_cnt:1;
+		uint64_t pcsr_im:1;
+		uint64_t pcsr_int:1;
+		uint64_t pkt_pif:1;
+		uint64_t pcr_gim:1;
+		uint64_t reserved_60_62:3;
+		uint64_t pkt_rdf:1;
+#endif
 	} cn52xx;
 	struct cvmx_npei_bist_status_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_46_63:18;
 		uint64_t d0_mem0:1;
 		uint64_t d1_mem1:1;
@@ -313,9 +435,59 @@
 		uint64_t dr3_mem:1;
 		uint64_t msi:1;
 		uint64_t ncb_cmd:1;
+#else
+		uint64_t ncb_cmd:1;
+		uint64_t msi:1;
+		uint64_t dr3_mem:1;
+		uint64_t dif3:1;
+		uint64_t dif2:1;
+		uint64_t dif1:1;
+		uint64_t dif0:1;
+		uint64_t csm1:1;
+		uint64_t csm0:1;
+		uint64_t p2n1_p1:1;
+		uint64_t p2n1_p0:1;
+		uint64_t p2n1_n:1;
+		uint64_t p2n1_c1:1;
+		uint64_t p2n1_c0:1;
+		uint64_t p2n0_p1:1;
+		uint64_t p2n0_p0:1;
+		uint64_t p2n0_n:1;
+		uint64_t p2n0_c1:1;
+		uint64_t p2n0_c0:1;
+		uint64_t p2n0_co:1;
+		uint64_t p2n0_no:1;
+		uint64_t p2n0_po:1;
+		uint64_t p2n1_co:1;
+		uint64_t p2n1_no:1;
+		uint64_t p2n1_po:1;
+		uint64_t cpl_p1:1;
+		uint64_t cpl_p0:1;
+		uint64_t n2p1_o:1;
+		uint64_t n2p1_c:1;
+		uint64_t n2p0_o:1;
+		uint64_t n2p0_c:1;
+		uint64_t dr2_mem:1;
+		uint64_t d3_pst:1;
+		uint64_t d2_pst:1;
+		uint64_t d1_pst:1;
+		uint64_t d0_pst:1;
+		uint64_t dr1_mem:1;
+		uint64_t d3_mem:1;
+		uint64_t d2_mem:1;
+		uint64_t d1_mem:1;
+		uint64_t d0_mem:1;
+		uint64_t dr0_mem:1;
+		uint64_t d3_mem3:1;
+		uint64_t d2_mem2:1;
+		uint64_t d1_mem1:1;
+		uint64_t d0_mem0:1;
+		uint64_t reserved_46_63:18;
+#endif
 	} cn52xxp1;
 	struct cvmx_npei_bist_status_cn52xx cn56xx;
 	struct cvmx_npei_bist_status_cn56xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_58_63:6;
 		uint64_t pcsr_int:1;
 		uint64_t pcsr_im:1;
@@ -375,12 +547,74 @@
 		uint64_t dif4:1;
 		uint64_t msi:1;
 		uint64_t ncb_cmd:1;
+#else
+		uint64_t ncb_cmd:1;
+		uint64_t msi:1;
+		uint64_t dif4:1;
+		uint64_t dif3:1;
+		uint64_t dif2:1;
+		uint64_t dif1:1;
+		uint64_t dif0:1;
+		uint64_t csm1:1;
+		uint64_t csm0:1;
+		uint64_t p2n1_p1:1;
+		uint64_t p2n1_p0:1;
+		uint64_t p2n1_n:1;
+		uint64_t p2n1_c1:1;
+		uint64_t p2n1_c0:1;
+		uint64_t p2n0_p1:1;
+		uint64_t p2n0_p0:1;
+		uint64_t p2n0_n:1;
+		uint64_t p2n0_c1:1;
+		uint64_t p2n0_c0:1;
+		uint64_t p2n0_co:1;
+		uint64_t p2n0_no:1;
+		uint64_t p2n0_po:1;
+		uint64_t p2n1_co:1;
+		uint64_t p2n1_no:1;
+		uint64_t p2n1_po:1;
+		uint64_t cpl_p1:1;
+		uint64_t cpl_p0:1;
+		uint64_t n2p1_o:1;
+		uint64_t n2p1_c:1;
+		uint64_t n2p0_o:1;
+		uint64_t n2p0_c:1;
+		uint64_t d4_pst:1;
+		uint64_t d3_pst:1;
+		uint64_t d2_pst:1;
+		uint64_t d1_pst:1;
+		uint64_t d0_pst:1;
+		uint64_t d4_mem:1;
+		uint64_t d3_mem:1;
+		uint64_t d2_mem:1;
+		uint64_t d1_mem:1;
+		uint64_t d0_mem:1;
+		uint64_t pkt_s1:1;
+		uint64_t pkt_s0:1;
+		uint64_t pkt_i1:1;
+		uint64_t pkt_i0:1;
+		uint64_t pkt_out:1;
+		uint64_t pkt_oif:1;
+		uint64_t pkt_odf:1;
+		uint64_t pkt_slm:1;
+		uint64_t pkt_ind:1;
+		uint64_t pkt_cntm:1;
+		uint64_t pkt_imem:1;
+		uint64_t pkt_pout:1;
+		uint64_t pcsr_sl:1;
+		uint64_t pcsr_id:1;
+		uint64_t pcsr_cnt:1;
+		uint64_t pcsr_im:1;
+		uint64_t pcsr_int:1;
+		uint64_t reserved_58_63:6;
+#endif
 	} cn56xxp1;
 };
 
 union cvmx_npei_bist_status2 {
 	uint64_t u64;
 	struct cvmx_npei_bist_status2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_14_63:50;
 		uint64_t prd_tag:1;
 		uint64_t prd_st0:1;
@@ -396,6 +630,23 @@
 		uint64_t pkt_gd:1;
 		uint64_t pkt_gl:1;
 		uint64_t pkt_blk:1;
+#else
+		uint64_t pkt_blk:1;
+		uint64_t pkt_gl:1;
+		uint64_t pkt_gd:1;
+		uint64_t psc_p1:1;
+		uint64_t psc_p0:1;
+		uint64_t pkt_rd:1;
+		uint64_t nwe_wr1:1;
+		uint64_t nwe_wr0:1;
+		uint64_t nwe_st:1;
+		uint64_t nrd_st:1;
+		uint64_t prd_err:1;
+		uint64_t prd_st1:1;
+		uint64_t prd_st0:1;
+		uint64_t prd_tag:1;
+		uint64_t reserved_14_63:50;
+#endif
 	} s;
 	struct cvmx_npei_bist_status2_s cn52xx;
 	struct cvmx_npei_bist_status2_s cn56xx;
@@ -404,6 +655,7 @@
 union cvmx_npei_ctl_port0 {
 	uint64_t u64;
 	struct cvmx_npei_ctl_port0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_21_63:43;
 		uint64_t waitl_com:1;
 		uint64_t intd:1;
@@ -421,6 +673,25 @@
 		uint64_t bar2_esx:2;
 		uint64_t bar2_cax:1;
 		uint64_t wait_com:1;
+#else
+		uint64_t wait_com:1;
+		uint64_t bar2_cax:1;
+		uint64_t bar2_esx:2;
+		uint64_t bar2_enb:1;
+		uint64_t ptlp_ro:1;
+		uint64_t reserved_6_6:1;
+		uint64_t ctlp_ro:1;
+		uint64_t inta_map:2;
+		uint64_t intb_map:2;
+		uint64_t intc_map:2;
+		uint64_t intd_map:2;
+		uint64_t inta:1;
+		uint64_t intb:1;
+		uint64_t intc:1;
+		uint64_t intd:1;
+		uint64_t waitl_com:1;
+		uint64_t reserved_21_63:43;
+#endif
 	} s;
 	struct cvmx_npei_ctl_port0_s cn52xx;
 	struct cvmx_npei_ctl_port0_s cn52xxp1;
@@ -431,6 +702,7 @@
 union cvmx_npei_ctl_port1 {
 	uint64_t u64;
 	struct cvmx_npei_ctl_port1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_21_63:43;
 		uint64_t waitl_com:1;
 		uint64_t intd:1;
@@ -448,6 +720,25 @@
 		uint64_t bar2_esx:2;
 		uint64_t bar2_cax:1;
 		uint64_t wait_com:1;
+#else
+		uint64_t wait_com:1;
+		uint64_t bar2_cax:1;
+		uint64_t bar2_esx:2;
+		uint64_t bar2_enb:1;
+		uint64_t ptlp_ro:1;
+		uint64_t reserved_6_6:1;
+		uint64_t ctlp_ro:1;
+		uint64_t inta_map:2;
+		uint64_t intb_map:2;
+		uint64_t intc_map:2;
+		uint64_t intd_map:2;
+		uint64_t inta:1;
+		uint64_t intb:1;
+		uint64_t intc:1;
+		uint64_t intd:1;
+		uint64_t waitl_com:1;
+		uint64_t reserved_21_63:43;
+#endif
 	} s;
 	struct cvmx_npei_ctl_port1_s cn52xx;
 	struct cvmx_npei_ctl_port1_s cn52xxp1;
@@ -458,6 +749,7 @@
 union cvmx_npei_ctl_status {
 	uint64_t u64;
 	struct cvmx_npei_ctl_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_44_63:20;
 		uint64_t p1_ntags:6;
 		uint64_t p0_ntags:6;
@@ -468,9 +760,22 @@
 		uint64_t pkt_bp:4;
 		uint64_t host_mode:1;
 		uint64_t chip_rev:8;
+#else
+		uint64_t chip_rev:8;
+		uint64_t host_mode:1;
+		uint64_t pkt_bp:4;
+		uint64_t arb:1;
+		uint64_t lnk_rst:1;
+		uint64_t ring_en:1;
+		uint64_t cfg_rtry:16;
+		uint64_t p0_ntags:6;
+		uint64_t p1_ntags:6;
+		uint64_t reserved_44_63:20;
+#endif
 	} s;
 	struct cvmx_npei_ctl_status_s cn52xx;
 	struct cvmx_npei_ctl_status_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_44_63:20;
 		uint64_t p1_ntags:6;
 		uint64_t p0_ntags:6;
@@ -481,21 +786,43 @@
 		uint64_t reserved_9_12:4;
 		uint64_t host_mode:1;
 		uint64_t chip_rev:8;
+#else
+		uint64_t chip_rev:8;
+		uint64_t host_mode:1;
+		uint64_t reserved_9_12:4;
+		uint64_t arb:1;
+		uint64_t lnk_rst:1;
+		uint64_t reserved_15_15:1;
+		uint64_t cfg_rtry:16;
+		uint64_t p0_ntags:6;
+		uint64_t p1_ntags:6;
+		uint64_t reserved_44_63:20;
+#endif
 	} cn52xxp1;
 	struct cvmx_npei_ctl_status_s cn56xx;
 	struct cvmx_npei_ctl_status_cn56xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_15_63:49;
 		uint64_t lnk_rst:1;
 		uint64_t arb:1;
 		uint64_t pkt_bp:4;
 		uint64_t host_mode:1;
 		uint64_t chip_rev:8;
+#else
+		uint64_t chip_rev:8;
+		uint64_t host_mode:1;
+		uint64_t pkt_bp:4;
+		uint64_t arb:1;
+		uint64_t lnk_rst:1;
+		uint64_t reserved_15_63:49;
+#endif
 	} cn56xxp1;
 };
 
 union cvmx_npei_ctl_status2 {
 	uint64_t u64;
 	struct cvmx_npei_ctl_status2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t mps:1;
 		uint64_t mrrs:3;
@@ -507,6 +834,19 @@
 		uint64_t c1_b0_d:1;
 		uint64_t c0_wi_d:1;
 		uint64_t c0_b0_d:1;
+#else
+		uint64_t c0_b0_d:1;
+		uint64_t c0_wi_d:1;
+		uint64_t c1_b0_d:1;
+		uint64_t c1_wi_d:1;
+		uint64_t c0_b1_s:3;
+		uint64_t c1_b1_s:3;
+		uint64_t c0_w_flt:1;
+		uint64_t c1_w_flt:1;
+		uint64_t mrrs:3;
+		uint64_t mps:1;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_npei_ctl_status2_s cn52xx;
 	struct cvmx_npei_ctl_status2_s cn52xxp1;
@@ -517,11 +857,19 @@
 union cvmx_npei_data_out_cnt {
 	uint64_t u64;
 	struct cvmx_npei_data_out_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_44_63:20;
 		uint64_t p1_ucnt:16;
 		uint64_t p1_fcnt:6;
 		uint64_t p0_ucnt:16;
 		uint64_t p0_fcnt:6;
+#else
+		uint64_t p0_fcnt:6;
+		uint64_t p0_ucnt:16;
+		uint64_t p1_fcnt:6;
+		uint64_t p1_ucnt:16;
+		uint64_t reserved_44_63:20;
+#endif
 	} s;
 	struct cvmx_npei_data_out_cnt_s cn52xx;
 	struct cvmx_npei_data_out_cnt_s cn52xxp1;
@@ -532,6 +880,7 @@
 union cvmx_npei_dbg_data {
 	uint64_t u64;
 	struct cvmx_npei_dbg_data_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_28_63:36;
 		uint64_t qlm0_rev_lanes:1;
 		uint64_t reserved_25_26:2;
@@ -539,8 +888,18 @@
 		uint64_t c_mul:5;
 		uint64_t dsel_ext:1;
 		uint64_t data:17;
+#else
+		uint64_t data:17;
+		uint64_t dsel_ext:1;
+		uint64_t c_mul:5;
+		uint64_t qlm1_spd:2;
+		uint64_t reserved_25_26:2;
+		uint64_t qlm0_rev_lanes:1;
+		uint64_t reserved_28_63:36;
+#endif
 	} s;
 	struct cvmx_npei_dbg_data_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_29_63:35;
 		uint64_t qlm0_link_width:1;
 		uint64_t qlm0_rev_lanes:1;
@@ -549,9 +908,20 @@
 		uint64_t c_mul:5;
 		uint64_t dsel_ext:1;
 		uint64_t data:17;
+#else
+		uint64_t data:17;
+		uint64_t dsel_ext:1;
+		uint64_t c_mul:5;
+		uint64_t qlm1_spd:2;
+		uint64_t qlm1_mode:2;
+		uint64_t qlm0_rev_lanes:1;
+		uint64_t qlm0_link_width:1;
+		uint64_t reserved_29_63:35;
+#endif
 	} cn52xx;
 	struct cvmx_npei_dbg_data_cn52xx cn52xxp1;
 	struct cvmx_npei_dbg_data_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_29_63:35;
 		uint64_t qlm2_rev_lanes:1;
 		uint64_t qlm0_rev_lanes:1;
@@ -560,6 +930,16 @@
 		uint64_t c_mul:5;
 		uint64_t dsel_ext:1;
 		uint64_t data:17;
+#else
+		uint64_t data:17;
+		uint64_t dsel_ext:1;
+		uint64_t c_mul:5;
+		uint64_t qlm1_spd:2;
+		uint64_t qlm3_spd:2;
+		uint64_t qlm0_rev_lanes:1;
+		uint64_t qlm2_rev_lanes:1;
+		uint64_t reserved_29_63:35;
+#endif
 	} cn56xx;
 	struct cvmx_npei_dbg_data_cn56xx cn56xxp1;
 };
@@ -567,8 +947,13 @@
 union cvmx_npei_dbg_select {
 	uint64_t u64;
 	struct cvmx_npei_dbg_select_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t dbg_sel:16;
+#else
+		uint64_t dbg_sel:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_npei_dbg_select_s cn52xx;
 	struct cvmx_npei_dbg_select_s cn52xxp1;
@@ -579,9 +964,15 @@
 union cvmx_npei_dmax_counts {
 	uint64_t u64;
 	struct cvmx_npei_dmax_counts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_39_63:25;
 		uint64_t fcnt:7;
 		uint64_t dbell:32;
+#else
+		uint64_t dbell:32;
+		uint64_t fcnt:7;
+		uint64_t reserved_39_63:25;
+#endif
 	} s;
 	struct cvmx_npei_dmax_counts_s cn52xx;
 	struct cvmx_npei_dmax_counts_s cn52xxp1;
@@ -592,8 +983,13 @@
 union cvmx_npei_dmax_dbell {
 	uint32_t u32;
 	struct cvmx_npei_dmax_dbell_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_16_31:16;
 		uint32_t dbell:16;
+#else
+		uint32_t dbell:16;
+		uint32_t reserved_16_31:16;
+#endif
 	} s;
 	struct cvmx_npei_dmax_dbell_s cn52xx;
 	struct cvmx_npei_dmax_dbell_s cn52xxp1;
@@ -604,16 +1000,29 @@
 union cvmx_npei_dmax_ibuff_saddr {
 	uint64_t u64;
 	struct cvmx_npei_dmax_ibuff_saddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_37_63:27;
 		uint64_t idle:1;
 		uint64_t saddr:29;
 		uint64_t reserved_0_6:7;
+#else
+		uint64_t reserved_0_6:7;
+		uint64_t saddr:29;
+		uint64_t idle:1;
+		uint64_t reserved_37_63:27;
+#endif
 	} s;
 	struct cvmx_npei_dmax_ibuff_saddr_s cn52xx;
 	struct cvmx_npei_dmax_ibuff_saddr_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_36_63:28;
 		uint64_t saddr:29;
 		uint64_t reserved_0_6:7;
+#else
+		uint64_t reserved_0_6:7;
+		uint64_t saddr:29;
+		uint64_t reserved_36_63:28;
+#endif
 	} cn52xxp1;
 	struct cvmx_npei_dmax_ibuff_saddr_s cn56xx;
 	struct cvmx_npei_dmax_ibuff_saddr_cn52xxp1 cn56xxp1;
@@ -622,8 +1031,13 @@
 union cvmx_npei_dmax_naddr {
 	uint64_t u64;
 	struct cvmx_npei_dmax_naddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_36_63:28;
 		uint64_t addr:36;
+#else
+		uint64_t addr:36;
+		uint64_t reserved_36_63:28;
+#endif
 	} s;
 	struct cvmx_npei_dmax_naddr_s cn52xx;
 	struct cvmx_npei_dmax_naddr_s cn52xxp1;
@@ -634,8 +1048,13 @@
 union cvmx_npei_dma0_int_level {
 	uint64_t u64;
 	struct cvmx_npei_dma0_int_level_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t time:32;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t time:32;
+#endif
 	} s;
 	struct cvmx_npei_dma0_int_level_s cn52xx;
 	struct cvmx_npei_dma0_int_level_s cn52xxp1;
@@ -646,8 +1065,13 @@
 union cvmx_npei_dma1_int_level {
 	uint64_t u64;
 	struct cvmx_npei_dma1_int_level_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t time:32;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t time:32;
+#endif
 	} s;
 	struct cvmx_npei_dma1_int_level_s cn52xx;
 	struct cvmx_npei_dma1_int_level_s cn52xxp1;
@@ -658,8 +1082,13 @@
 union cvmx_npei_dma_cnts {
 	uint64_t u64;
 	struct cvmx_npei_dma_cnts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t dma1:32;
 		uint64_t dma0:32;
+#else
+		uint64_t dma0:32;
+		uint64_t dma1:32;
+#endif
 	} s;
 	struct cvmx_npei_dma_cnts_s cn52xx;
 	struct cvmx_npei_dma_cnts_s cn52xxp1;
@@ -670,6 +1099,7 @@
 union cvmx_npei_dma_control {
 	uint64_t u64;
 	struct cvmx_npei_dma_control_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_40_63:24;
 		uint64_t p_32b_m:1;
 		uint64_t dma4_enb:1;
@@ -687,9 +1117,29 @@
 		uint64_t o_es:2;
 		uint64_t o_mode:1;
 		uint64_t csize:14;
+#else
+		uint64_t csize:14;
+		uint64_t o_mode:1;
+		uint64_t o_es:2;
+		uint64_t o_ns:1;
+		uint64_t o_ro:1;
+		uint64_t o_add1:1;
+		uint64_t fpa_que:3;
+		uint64_t dwb_ichk:9;
+		uint64_t dwb_denb:1;
+		uint64_t b0_lend:1;
+		uint64_t dma0_enb:1;
+		uint64_t dma1_enb:1;
+		uint64_t dma2_enb:1;
+		uint64_t dma3_enb:1;
+		uint64_t dma4_enb:1;
+		uint64_t p_32b_m:1;
+		uint64_t reserved_40_63:24;
+#endif
 	} s;
 	struct cvmx_npei_dma_control_s cn52xx;
 	struct cvmx_npei_dma_control_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_38_63:26;
 		uint64_t dma3_enb:1;
 		uint64_t dma2_enb:1;
@@ -705,9 +1155,27 @@
 		uint64_t o_es:2;
 		uint64_t o_mode:1;
 		uint64_t csize:14;
+#else
+		uint64_t csize:14;
+		uint64_t o_mode:1;
+		uint64_t o_es:2;
+		uint64_t o_ns:1;
+		uint64_t o_ro:1;
+		uint64_t o_add1:1;
+		uint64_t fpa_que:3;
+		uint64_t dwb_ichk:9;
+		uint64_t dwb_denb:1;
+		uint64_t b0_lend:1;
+		uint64_t dma0_enb:1;
+		uint64_t dma1_enb:1;
+		uint64_t dma2_enb:1;
+		uint64_t dma3_enb:1;
+		uint64_t reserved_38_63:26;
+#endif
 	} cn52xxp1;
 	struct cvmx_npei_dma_control_s cn56xx;
 	struct cvmx_npei_dma_control_cn56xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_39_63:25;
 		uint64_t dma4_enb:1;
 		uint64_t dma3_enb:1;
@@ -724,12 +1192,31 @@
 		uint64_t o_es:2;
 		uint64_t o_mode:1;
 		uint64_t csize:14;
+#else
+		uint64_t csize:14;
+		uint64_t o_mode:1;
+		uint64_t o_es:2;
+		uint64_t o_ns:1;
+		uint64_t o_ro:1;
+		uint64_t o_add1:1;
+		uint64_t fpa_que:3;
+		uint64_t dwb_ichk:9;
+		uint64_t dwb_denb:1;
+		uint64_t b0_lend:1;
+		uint64_t dma0_enb:1;
+		uint64_t dma1_enb:1;
+		uint64_t dma2_enb:1;
+		uint64_t dma3_enb:1;
+		uint64_t dma4_enb:1;
+		uint64_t reserved_39_63:25;
+#endif
 	} cn56xxp1;
 };
 
 union cvmx_npei_dma_pcie_req_num {
 	uint64_t u64;
 	struct cvmx_npei_dma_pcie_req_num_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t dma_arb:1;
 		uint64_t reserved_53_62:10;
 		uint64_t pkt_cnt:5;
@@ -745,6 +1232,23 @@
 		uint64_t dma0_cnt:5;
 		uint64_t reserved_5_7:3;
 		uint64_t dma_cnt:5;
+#else
+		uint64_t dma_cnt:5;
+		uint64_t reserved_5_7:3;
+		uint64_t dma0_cnt:5;
+		uint64_t reserved_13_15:3;
+		uint64_t dma1_cnt:5;
+		uint64_t reserved_21_23:3;
+		uint64_t dma2_cnt:5;
+		uint64_t reserved_29_31:3;
+		uint64_t dma3_cnt:5;
+		uint64_t reserved_37_39:3;
+		uint64_t dma4_cnt:5;
+		uint64_t reserved_45_47:3;
+		uint64_t pkt_cnt:5;
+		uint64_t reserved_53_62:10;
+		uint64_t dma_arb:1;
+#endif
 	} s;
 	struct cvmx_npei_dma_pcie_req_num_s cn52xx;
 	struct cvmx_npei_dma_pcie_req_num_s cn56xx;
@@ -753,12 +1257,21 @@
 union cvmx_npei_dma_state1 {
 	uint64_t u64;
 	struct cvmx_npei_dma_state1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_40_63:24;
 		uint64_t d4_dwe:8;
 		uint64_t d3_dwe:8;
 		uint64_t d2_dwe:8;
 		uint64_t d1_dwe:8;
 		uint64_t d0_dwe:8;
+#else
+		uint64_t d0_dwe:8;
+		uint64_t d1_dwe:8;
+		uint64_t d2_dwe:8;
+		uint64_t d3_dwe:8;
+		uint64_t d4_dwe:8;
+		uint64_t reserved_40_63:24;
+#endif
 	} s;
 	struct cvmx_npei_dma_state1_s cn52xx;
 };
@@ -766,6 +1279,7 @@
 union cvmx_npei_dma_state1_p1 {
 	uint64_t u64;
 	struct cvmx_npei_dma_state1_p1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_60_63:4;
 		uint64_t d0_difst:7;
 		uint64_t d1_difst:7;
@@ -777,8 +1291,22 @@
 		uint64_t d2_reqst:5;
 		uint64_t d3_reqst:5;
 		uint64_t d4_reqst:5;
+#else
+		uint64_t d4_reqst:5;
+		uint64_t d3_reqst:5;
+		uint64_t d2_reqst:5;
+		uint64_t d1_reqst:5;
+		uint64_t d0_reqst:5;
+		uint64_t d4_difst:7;
+		uint64_t d3_difst:7;
+		uint64_t d2_difst:7;
+		uint64_t d1_difst:7;
+		uint64_t d0_difst:7;
+		uint64_t reserved_60_63:4;
+#endif
 	} s;
 	struct cvmx_npei_dma_state1_p1_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_60_63:4;
 		uint64_t d0_difst:7;
 		uint64_t d1_difst:7;
@@ -790,6 +1318,19 @@
 		uint64_t d2_reqst:5;
 		uint64_t d3_reqst:5;
 		uint64_t reserved_0_4:5;
+#else
+		uint64_t reserved_0_4:5;
+		uint64_t d3_reqst:5;
+		uint64_t d2_reqst:5;
+		uint64_t d1_reqst:5;
+		uint64_t d0_reqst:5;
+		uint64_t reserved_25_31:7;
+		uint64_t d3_difst:7;
+		uint64_t d2_difst:7;
+		uint64_t d1_difst:7;
+		uint64_t d0_difst:7;
+		uint64_t reserved_60_63:4;
+#endif
 	} cn52xxp1;
 	struct cvmx_npei_dma_state1_p1_s cn56xxp1;
 };
@@ -797,12 +1338,21 @@
 union cvmx_npei_dma_state2 {
 	uint64_t u64;
 	struct cvmx_npei_dma_state2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_28_63:36;
 		uint64_t ndwe:4;
 		uint64_t reserved_21_23:3;
 		uint64_t ndre:5;
 		uint64_t reserved_10_15:6;
 		uint64_t prd:10;
+#else
+		uint64_t prd:10;
+		uint64_t reserved_10_15:6;
+		uint64_t ndre:5;
+		uint64_t reserved_21_23:3;
+		uint64_t ndwe:4;
+		uint64_t reserved_28_63:36;
+#endif
 	} s;
 	struct cvmx_npei_dma_state2_s cn52xx;
 };
@@ -810,20 +1360,38 @@
 union cvmx_npei_dma_state2_p1 {
 	uint64_t u64;
 	struct cvmx_npei_dma_state2_p1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_45_63:19;
 		uint64_t d0_dffst:9;
 		uint64_t d1_dffst:9;
 		uint64_t d2_dffst:9;
 		uint64_t d3_dffst:9;
 		uint64_t d4_dffst:9;
+#else
+		uint64_t d4_dffst:9;
+		uint64_t d3_dffst:9;
+		uint64_t d2_dffst:9;
+		uint64_t d1_dffst:9;
+		uint64_t d0_dffst:9;
+		uint64_t reserved_45_63:19;
+#endif
 	} s;
 	struct cvmx_npei_dma_state2_p1_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_45_63:19;
 		uint64_t d0_dffst:9;
 		uint64_t d1_dffst:9;
 		uint64_t d2_dffst:9;
 		uint64_t d3_dffst:9;
 		uint64_t reserved_0_8:9;
+#else
+		uint64_t reserved_0_8:9;
+		uint64_t d3_dffst:9;
+		uint64_t d2_dffst:9;
+		uint64_t d1_dffst:9;
+		uint64_t d0_dffst:9;
+		uint64_t reserved_45_63:19;
+#endif
 	} cn52xxp1;
 	struct cvmx_npei_dma_state2_p1_s cn56xxp1;
 };
@@ -831,11 +1399,19 @@
 union cvmx_npei_dma_state3_p1 {
 	uint64_t u64;
 	struct cvmx_npei_dma_state3_p1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_60_63:4;
 		uint64_t d0_drest:15;
 		uint64_t d1_drest:15;
 		uint64_t d2_drest:15;
 		uint64_t d3_drest:15;
+#else
+		uint64_t d3_drest:15;
+		uint64_t d2_drest:15;
+		uint64_t d1_drest:15;
+		uint64_t d0_drest:15;
+		uint64_t reserved_60_63:4;
+#endif
 	} s;
 	struct cvmx_npei_dma_state3_p1_s cn52xxp1;
 	struct cvmx_npei_dma_state3_p1_s cn56xxp1;
@@ -844,11 +1420,19 @@
 union cvmx_npei_dma_state4_p1 {
 	uint64_t u64;
 	struct cvmx_npei_dma_state4_p1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_52_63:12;
 		uint64_t d0_dwest:13;
 		uint64_t d1_dwest:13;
 		uint64_t d2_dwest:13;
 		uint64_t d3_dwest:13;
+#else
+		uint64_t d3_dwest:13;
+		uint64_t d2_dwest:13;
+		uint64_t d1_dwest:13;
+		uint64_t d0_dwest:13;
+		uint64_t reserved_52_63:12;
+#endif
 	} s;
 	struct cvmx_npei_dma_state4_p1_s cn52xxp1;
 	struct cvmx_npei_dma_state4_p1_s cn56xxp1;
@@ -857,9 +1441,15 @@
 union cvmx_npei_dma_state5_p1 {
 	uint64_t u64;
 	struct cvmx_npei_dma_state5_p1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_28_63:36;
 		uint64_t d4_drest:15;
 		uint64_t d4_dwest:13;
+#else
+		uint64_t d4_dwest:13;
+		uint64_t d4_drest:15;
+		uint64_t reserved_28_63:36;
+#endif
 	} s;
 	struct cvmx_npei_dma_state5_p1_s cn56xxp1;
 };
@@ -867,6 +1457,7 @@
 union cvmx_npei_int_a_enb {
 	uint64_t u64;
 	struct cvmx_npei_int_a_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t pout_err:1;
 		uint64_t pin_bp:1;
@@ -878,12 +1469,31 @@
 		uint64_t pins_err:1;
 		uint64_t dma1_cpl:1;
 		uint64_t dma0_cpl:1;
+#else
+		uint64_t dma0_cpl:1;
+		uint64_t dma1_cpl:1;
+		uint64_t pins_err:1;
+		uint64_t pop_err:1;
+		uint64_t pdi_err:1;
+		uint64_t pgl_err:1;
+		uint64_t p0_rdlk:1;
+		uint64_t p1_rdlk:1;
+		uint64_t pin_bp:1;
+		uint64_t pout_err:1;
+		uint64_t reserved_10_63:54;
+#endif
 	} s;
 	struct cvmx_npei_int_a_enb_s cn52xx;
 	struct cvmx_npei_int_a_enb_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t dma1_cpl:1;
 		uint64_t dma0_cpl:1;
+#else
+		uint64_t dma0_cpl:1;
+		uint64_t dma1_cpl:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} cn52xxp1;
 	struct cvmx_npei_int_a_enb_s cn56xx;
 };
@@ -891,6 +1501,7 @@
 union cvmx_npei_int_a_enb2 {
 	uint64_t u64;
 	struct cvmx_npei_int_a_enb2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t pout_err:1;
 		uint64_t pin_bp:1;
@@ -902,12 +1513,31 @@
 		uint64_t pins_err:1;
 		uint64_t dma1_cpl:1;
 		uint64_t dma0_cpl:1;
+#else
+		uint64_t dma0_cpl:1;
+		uint64_t dma1_cpl:1;
+		uint64_t pins_err:1;
+		uint64_t pop_err:1;
+		uint64_t pdi_err:1;
+		uint64_t pgl_err:1;
+		uint64_t p0_rdlk:1;
+		uint64_t p1_rdlk:1;
+		uint64_t pin_bp:1;
+		uint64_t pout_err:1;
+		uint64_t reserved_10_63:54;
+#endif
 	} s;
 	struct cvmx_npei_int_a_enb2_s cn52xx;
 	struct cvmx_npei_int_a_enb2_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t dma1_cpl:1;
 		uint64_t dma0_cpl:1;
+#else
+		uint64_t dma0_cpl:1;
+		uint64_t dma1_cpl:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} cn52xxp1;
 	struct cvmx_npei_int_a_enb2_s cn56xx;
 };
@@ -915,6 +1545,7 @@
 union cvmx_npei_int_a_sum {
 	uint64_t u64;
 	struct cvmx_npei_int_a_sum_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t pout_err:1;
 		uint64_t pin_bp:1;
@@ -926,12 +1557,31 @@
 		uint64_t pins_err:1;
 		uint64_t dma1_cpl:1;
 		uint64_t dma0_cpl:1;
+#else
+		uint64_t dma0_cpl:1;
+		uint64_t dma1_cpl:1;
+		uint64_t pins_err:1;
+		uint64_t pop_err:1;
+		uint64_t pdi_err:1;
+		uint64_t pgl_err:1;
+		uint64_t p0_rdlk:1;
+		uint64_t p1_rdlk:1;
+		uint64_t pin_bp:1;
+		uint64_t pout_err:1;
+		uint64_t reserved_10_63:54;
+#endif
 	} s;
 	struct cvmx_npei_int_a_sum_s cn52xx;
 	struct cvmx_npei_int_a_sum_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t dma1_cpl:1;
 		uint64_t dma0_cpl:1;
+#else
+		uint64_t dma0_cpl:1;
+		uint64_t dma1_cpl:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} cn52xxp1;
 	struct cvmx_npei_int_a_sum_s cn56xx;
 };
@@ -939,6 +1589,7 @@
 union cvmx_npei_int_enb {
 	uint64_t u64;
 	struct cvmx_npei_int_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t mio_inta:1;
 		uint64_t reserved_62_62:1;
 		uint64_t int_a:1;
@@ -1003,9 +1654,76 @@
 		uint64_t bar0_to:1;
 		uint64_t rml_wto:1;
 		uint64_t rml_rto:1;
+#else
+		uint64_t rml_rto:1;
+		uint64_t rml_wto:1;
+		uint64_t bar0_to:1;
+		uint64_t iob2big:1;
+		uint64_t dma0dbo:1;
+		uint64_t dma1dbo:1;
+		uint64_t dma2dbo:1;
+		uint64_t dma3dbo:1;
+		uint64_t dma4dbo:1;
+		uint64_t dma0fi:1;
+		uint64_t dma1fi:1;
+		uint64_t dcnt0:1;
+		uint64_t dcnt1:1;
+		uint64_t dtime0:1;
+		uint64_t dtime1:1;
+		uint64_t psldbof:1;
+		uint64_t pidbof:1;
+		uint64_t pcnt:1;
+		uint64_t ptime:1;
+		uint64_t c0_aeri:1;
+		uint64_t crs0_er:1;
+		uint64_t c0_se:1;
+		uint64_t crs0_dr:1;
+		uint64_t c0_wake:1;
+		uint64_t c0_pmei:1;
+		uint64_t c0_hpint:1;
+		uint64_t c1_aeri:1;
+		uint64_t crs1_er:1;
+		uint64_t c1_se:1;
+		uint64_t crs1_dr:1;
+		uint64_t c1_wake:1;
+		uint64_t c1_pmei:1;
+		uint64_t c1_hpint:1;
+		uint64_t c0_up_b0:1;
+		uint64_t c0_up_b1:1;
+		uint64_t c0_up_b2:1;
+		uint64_t c0_up_wi:1;
+		uint64_t c0_up_bx:1;
+		uint64_t c0_un_b0:1;
+		uint64_t c0_un_b1:1;
+		uint64_t c0_un_b2:1;
+		uint64_t c0_un_wi:1;
+		uint64_t c0_un_bx:1;
+		uint64_t c1_up_b0:1;
+		uint64_t c1_up_b1:1;
+		uint64_t c1_up_b2:1;
+		uint64_t c1_up_wi:1;
+		uint64_t c1_up_bx:1;
+		uint64_t c1_un_b0:1;
+		uint64_t c1_un_b1:1;
+		uint64_t c1_un_b2:1;
+		uint64_t c1_un_wi:1;
+		uint64_t c1_un_bx:1;
+		uint64_t c0_un_wf:1;
+		uint64_t c1_un_wf:1;
+		uint64_t c0_up_wf:1;
+		uint64_t c1_up_wf:1;
+		uint64_t c0_exc:1;
+		uint64_t c1_exc:1;
+		uint64_t c0_ldwn:1;
+		uint64_t c1_ldwn:1;
+		uint64_t int_a:1;
+		uint64_t reserved_62_62:1;
+		uint64_t mio_inta:1;
+#endif
 	} s;
 	struct cvmx_npei_int_enb_s cn52xx;
 	struct cvmx_npei_int_enb_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t mio_inta:1;
 		uint64_t reserved_62_62:1;
 		uint64_t int_a:1;
@@ -1070,9 +1788,76 @@
 		uint64_t bar0_to:1;
 		uint64_t rml_wto:1;
 		uint64_t rml_rto:1;
+#else
+		uint64_t rml_rto:1;
+		uint64_t rml_wto:1;
+		uint64_t bar0_to:1;
+		uint64_t iob2big:1;
+		uint64_t dma0dbo:1;
+		uint64_t dma1dbo:1;
+		uint64_t dma2dbo:1;
+		uint64_t dma3dbo:1;
+		uint64_t reserved_8_8:1;
+		uint64_t dma0fi:1;
+		uint64_t dma1fi:1;
+		uint64_t dcnt0:1;
+		uint64_t dcnt1:1;
+		uint64_t dtime0:1;
+		uint64_t dtime1:1;
+		uint64_t psldbof:1;
+		uint64_t pidbof:1;
+		uint64_t pcnt:1;
+		uint64_t ptime:1;
+		uint64_t c0_aeri:1;
+		uint64_t crs0_er:1;
+		uint64_t c0_se:1;
+		uint64_t crs0_dr:1;
+		uint64_t c0_wake:1;
+		uint64_t c0_pmei:1;
+		uint64_t c0_hpint:1;
+		uint64_t c1_aeri:1;
+		uint64_t crs1_er:1;
+		uint64_t c1_se:1;
+		uint64_t crs1_dr:1;
+		uint64_t c1_wake:1;
+		uint64_t c1_pmei:1;
+		uint64_t c1_hpint:1;
+		uint64_t c0_up_b0:1;
+		uint64_t c0_up_b1:1;
+		uint64_t c0_up_b2:1;
+		uint64_t c0_up_wi:1;
+		uint64_t c0_up_bx:1;
+		uint64_t c0_un_b0:1;
+		uint64_t c0_un_b1:1;
+		uint64_t c0_un_b2:1;
+		uint64_t c0_un_wi:1;
+		uint64_t c0_un_bx:1;
+		uint64_t c1_up_b0:1;
+		uint64_t c1_up_b1:1;
+		uint64_t c1_up_b2:1;
+		uint64_t c1_up_wi:1;
+		uint64_t c1_up_bx:1;
+		uint64_t c1_un_b0:1;
+		uint64_t c1_un_b1:1;
+		uint64_t c1_un_b2:1;
+		uint64_t c1_un_wi:1;
+		uint64_t c1_un_bx:1;
+		uint64_t c0_un_wf:1;
+		uint64_t c1_un_wf:1;
+		uint64_t c0_up_wf:1;
+		uint64_t c1_up_wf:1;
+		uint64_t c0_exc:1;
+		uint64_t c1_exc:1;
+		uint64_t c0_ldwn:1;
+		uint64_t c1_ldwn:1;
+		uint64_t int_a:1;
+		uint64_t reserved_62_62:1;
+		uint64_t mio_inta:1;
+#endif
 	} cn52xxp1;
 	struct cvmx_npei_int_enb_s cn56xx;
 	struct cvmx_npei_int_enb_cn56xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t mio_inta:1;
 		uint64_t reserved_61_62:2;
 		uint64_t c1_ldwn:1;
@@ -1136,12 +1921,78 @@
 		uint64_t bar0_to:1;
 		uint64_t rml_wto:1;
 		uint64_t rml_rto:1;
+#else
+		uint64_t rml_rto:1;
+		uint64_t rml_wto:1;
+		uint64_t bar0_to:1;
+		uint64_t iob2big:1;
+		uint64_t dma0dbo:1;
+		uint64_t dma1dbo:1;
+		uint64_t dma2dbo:1;
+		uint64_t dma3dbo:1;
+		uint64_t dma4dbo:1;
+		uint64_t dma0fi:1;
+		uint64_t dma1fi:1;
+		uint64_t dcnt0:1;
+		uint64_t dcnt1:1;
+		uint64_t dtime0:1;
+		uint64_t dtime1:1;
+		uint64_t psldbof:1;
+		uint64_t pidbof:1;
+		uint64_t pcnt:1;
+		uint64_t ptime:1;
+		uint64_t c0_aeri:1;
+		uint64_t reserved_20_20:1;
+		uint64_t c0_se:1;
+		uint64_t reserved_22_22:1;
+		uint64_t c0_wake:1;
+		uint64_t c0_pmei:1;
+		uint64_t c0_hpint:1;
+		uint64_t c1_aeri:1;
+		uint64_t reserved_27_27:1;
+		uint64_t c1_se:1;
+		uint64_t reserved_29_29:1;
+		uint64_t c1_wake:1;
+		uint64_t c1_pmei:1;
+		uint64_t c1_hpint:1;
+		uint64_t c0_up_b0:1;
+		uint64_t c0_up_b1:1;
+		uint64_t c0_up_b2:1;
+		uint64_t c0_up_wi:1;
+		uint64_t c0_up_bx:1;
+		uint64_t c0_un_b0:1;
+		uint64_t c0_un_b1:1;
+		uint64_t c0_un_b2:1;
+		uint64_t c0_un_wi:1;
+		uint64_t c0_un_bx:1;
+		uint64_t c1_up_b0:1;
+		uint64_t c1_up_b1:1;
+		uint64_t c1_up_b2:1;
+		uint64_t c1_up_wi:1;
+		uint64_t c1_up_bx:1;
+		uint64_t c1_un_b0:1;
+		uint64_t c1_un_b1:1;
+		uint64_t c1_un_b2:1;
+		uint64_t c1_un_wi:1;
+		uint64_t c1_un_bx:1;
+		uint64_t c0_un_wf:1;
+		uint64_t c1_un_wf:1;
+		uint64_t c0_up_wf:1;
+		uint64_t c1_up_wf:1;
+		uint64_t c0_exc:1;
+		uint64_t c1_exc:1;
+		uint64_t c0_ldwn:1;
+		uint64_t c1_ldwn:1;
+		uint64_t reserved_61_62:2;
+		uint64_t mio_inta:1;
+#endif
 	} cn56xxp1;
 };
 
 union cvmx_npei_int_enb2 {
 	uint64_t u64;
 	struct cvmx_npei_int_enb2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_62_63:2;
 		uint64_t int_a:1;
 		uint64_t c1_ldwn:1;
@@ -1205,9 +2056,75 @@
 		uint64_t bar0_to:1;
 		uint64_t rml_wto:1;
 		uint64_t rml_rto:1;
+#else
+		uint64_t rml_rto:1;
+		uint64_t rml_wto:1;
+		uint64_t bar0_to:1;
+		uint64_t iob2big:1;
+		uint64_t dma0dbo:1;
+		uint64_t dma1dbo:1;
+		uint64_t dma2dbo:1;
+		uint64_t dma3dbo:1;
+		uint64_t dma4dbo:1;
+		uint64_t dma0fi:1;
+		uint64_t dma1fi:1;
+		uint64_t dcnt0:1;
+		uint64_t dcnt1:1;
+		uint64_t dtime0:1;
+		uint64_t dtime1:1;
+		uint64_t psldbof:1;
+		uint64_t pidbof:1;
+		uint64_t pcnt:1;
+		uint64_t ptime:1;
+		uint64_t c0_aeri:1;
+		uint64_t crs0_er:1;
+		uint64_t c0_se:1;
+		uint64_t crs0_dr:1;
+		uint64_t c0_wake:1;
+		uint64_t c0_pmei:1;
+		uint64_t c0_hpint:1;
+		uint64_t c1_aeri:1;
+		uint64_t crs1_er:1;
+		uint64_t c1_se:1;
+		uint64_t crs1_dr:1;
+		uint64_t c1_wake:1;
+		uint64_t c1_pmei:1;
+		uint64_t c1_hpint:1;
+		uint64_t c0_up_b0:1;
+		uint64_t c0_up_b1:1;
+		uint64_t c0_up_b2:1;
+		uint64_t c0_up_wi:1;
+		uint64_t c0_up_bx:1;
+		uint64_t c0_un_b0:1;
+		uint64_t c0_un_b1:1;
+		uint64_t c0_un_b2:1;
+		uint64_t c0_un_wi:1;
+		uint64_t c0_un_bx:1;
+		uint64_t c1_up_b0:1;
+		uint64_t c1_up_b1:1;
+		uint64_t c1_up_b2:1;
+		uint64_t c1_up_wi:1;
+		uint64_t c1_up_bx:1;
+		uint64_t c1_un_b0:1;
+		uint64_t c1_un_b1:1;
+		uint64_t c1_un_b2:1;
+		uint64_t c1_un_wi:1;
+		uint64_t c1_un_bx:1;
+		uint64_t c0_un_wf:1;
+		uint64_t c1_un_wf:1;
+		uint64_t c0_up_wf:1;
+		uint64_t c1_up_wf:1;
+		uint64_t c0_exc:1;
+		uint64_t c1_exc:1;
+		uint64_t c0_ldwn:1;
+		uint64_t c1_ldwn:1;
+		uint64_t int_a:1;
+		uint64_t reserved_62_63:2;
+#endif
 	} s;
 	struct cvmx_npei_int_enb2_s cn52xx;
 	struct cvmx_npei_int_enb2_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_62_63:2;
 		uint64_t int_a:1;
 		uint64_t c1_ldwn:1;
@@ -1271,9 +2188,75 @@
 		uint64_t bar0_to:1;
 		uint64_t rml_wto:1;
 		uint64_t rml_rto:1;
+#else
+		uint64_t rml_rto:1;
+		uint64_t rml_wto:1;
+		uint64_t bar0_to:1;
+		uint64_t iob2big:1;
+		uint64_t dma0dbo:1;
+		uint64_t dma1dbo:1;
+		uint64_t dma2dbo:1;
+		uint64_t dma3dbo:1;
+		uint64_t reserved_8_8:1;
+		uint64_t dma0fi:1;
+		uint64_t dma1fi:1;
+		uint64_t dcnt0:1;
+		uint64_t dcnt1:1;
+		uint64_t dtime0:1;
+		uint64_t dtime1:1;
+		uint64_t psldbof:1;
+		uint64_t pidbof:1;
+		uint64_t pcnt:1;
+		uint64_t ptime:1;
+		uint64_t c0_aeri:1;
+		uint64_t crs0_er:1;
+		uint64_t c0_se:1;
+		uint64_t crs0_dr:1;
+		uint64_t c0_wake:1;
+		uint64_t c0_pmei:1;
+		uint64_t c0_hpint:1;
+		uint64_t c1_aeri:1;
+		uint64_t crs1_er:1;
+		uint64_t c1_se:1;
+		uint64_t crs1_dr:1;
+		uint64_t c1_wake:1;
+		uint64_t c1_pmei:1;
+		uint64_t c1_hpint:1;
+		uint64_t c0_up_b0:1;
+		uint64_t c0_up_b1:1;
+		uint64_t c0_up_b2:1;
+		uint64_t c0_up_wi:1;
+		uint64_t c0_up_bx:1;
+		uint64_t c0_un_b0:1;
+		uint64_t c0_un_b1:1;
+		uint64_t c0_un_b2:1;
+		uint64_t c0_un_wi:1;
+		uint64_t c0_un_bx:1;
+		uint64_t c1_up_b0:1;
+		uint64_t c1_up_b1:1;
+		uint64_t c1_up_b2:1;
+		uint64_t c1_up_wi:1;
+		uint64_t c1_up_bx:1;
+		uint64_t c1_un_b0:1;
+		uint64_t c1_un_b1:1;
+		uint64_t c1_un_b2:1;
+		uint64_t c1_un_wi:1;
+		uint64_t c1_un_bx:1;
+		uint64_t c0_un_wf:1;
+		uint64_t c1_un_wf:1;
+		uint64_t c0_up_wf:1;
+		uint64_t c1_up_wf:1;
+		uint64_t c0_exc:1;
+		uint64_t c1_exc:1;
+		uint64_t c0_ldwn:1;
+		uint64_t c1_ldwn:1;
+		uint64_t int_a:1;
+		uint64_t reserved_62_63:2;
+#endif
 	} cn52xxp1;
 	struct cvmx_npei_int_enb2_s cn56xx;
 	struct cvmx_npei_int_enb2_cn56xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_61_63:3;
 		uint64_t c1_ldwn:1;
 		uint64_t c0_ldwn:1;
@@ -1336,15 +2319,85 @@
 		uint64_t bar0_to:1;
 		uint64_t rml_wto:1;
 		uint64_t rml_rto:1;
+#else
+		uint64_t rml_rto:1;
+		uint64_t rml_wto:1;
+		uint64_t bar0_to:1;
+		uint64_t iob2big:1;
+		uint64_t dma0dbo:1;
+		uint64_t dma1dbo:1;
+		uint64_t dma2dbo:1;
+		uint64_t dma3dbo:1;
+		uint64_t dma4dbo:1;
+		uint64_t dma0fi:1;
+		uint64_t dma1fi:1;
+		uint64_t dcnt0:1;
+		uint64_t dcnt1:1;
+		uint64_t dtime0:1;
+		uint64_t dtime1:1;
+		uint64_t psldbof:1;
+		uint64_t pidbof:1;
+		uint64_t pcnt:1;
+		uint64_t ptime:1;
+		uint64_t c0_aeri:1;
+		uint64_t reserved_20_20:1;
+		uint64_t c0_se:1;
+		uint64_t reserved_22_22:1;
+		uint64_t c0_wake:1;
+		uint64_t c0_pmei:1;
+		uint64_t c0_hpint:1;
+		uint64_t c1_aeri:1;
+		uint64_t reserved_27_27:1;
+		uint64_t c1_se:1;
+		uint64_t reserved_29_29:1;
+		uint64_t c1_wake:1;
+		uint64_t c1_pmei:1;
+		uint64_t c1_hpint:1;
+		uint64_t c0_up_b0:1;
+		uint64_t c0_up_b1:1;
+		uint64_t c0_up_b2:1;
+		uint64_t c0_up_wi:1;
+		uint64_t c0_up_bx:1;
+		uint64_t c0_un_b0:1;
+		uint64_t c0_un_b1:1;
+		uint64_t c0_un_b2:1;
+		uint64_t c0_un_wi:1;
+		uint64_t c0_un_bx:1;
+		uint64_t c1_up_b0:1;
+		uint64_t c1_up_b1:1;
+		uint64_t c1_up_b2:1;
+		uint64_t c1_up_wi:1;
+		uint64_t c1_up_bx:1;
+		uint64_t c1_un_b0:1;
+		uint64_t c1_un_b1:1;
+		uint64_t c1_un_b2:1;
+		uint64_t c1_un_wi:1;
+		uint64_t c1_un_bx:1;
+		uint64_t c0_un_wf:1;
+		uint64_t c1_un_wf:1;
+		uint64_t c0_up_wf:1;
+		uint64_t c1_up_wf:1;
+		uint64_t c0_exc:1;
+		uint64_t c1_exc:1;
+		uint64_t c0_ldwn:1;
+		uint64_t c1_ldwn:1;
+		uint64_t reserved_61_63:3;
+#endif
 	} cn56xxp1;
 };
 
 union cvmx_npei_int_info {
 	uint64_t u64;
 	struct cvmx_npei_int_info_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t pidbof:6;
 		uint64_t psldbof:6;
+#else
+		uint64_t psldbof:6;
+		uint64_t pidbof:6;
+		uint64_t reserved_12_63:52;
+#endif
 	} s;
 	struct cvmx_npei_int_info_s cn52xx;
 	struct cvmx_npei_int_info_s cn56xx;
@@ -1354,6 +2407,7 @@
 union cvmx_npei_int_sum {
 	uint64_t u64;
 	struct cvmx_npei_int_sum_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t mio_inta:1;
 		uint64_t reserved_62_62:1;
 		uint64_t int_a:1;
@@ -1418,9 +2472,76 @@
 		uint64_t bar0_to:1;
 		uint64_t rml_wto:1;
 		uint64_t rml_rto:1;
+#else
+		uint64_t rml_rto:1;
+		uint64_t rml_wto:1;
+		uint64_t bar0_to:1;
+		uint64_t iob2big:1;
+		uint64_t dma0dbo:1;
+		uint64_t dma1dbo:1;
+		uint64_t dma2dbo:1;
+		uint64_t dma3dbo:1;
+		uint64_t dma4dbo:1;
+		uint64_t dma0fi:1;
+		uint64_t dma1fi:1;
+		uint64_t dcnt0:1;
+		uint64_t dcnt1:1;
+		uint64_t dtime0:1;
+		uint64_t dtime1:1;
+		uint64_t psldbof:1;
+		uint64_t pidbof:1;
+		uint64_t pcnt:1;
+		uint64_t ptime:1;
+		uint64_t c0_aeri:1;
+		uint64_t crs0_er:1;
+		uint64_t c0_se:1;
+		uint64_t crs0_dr:1;
+		uint64_t c0_wake:1;
+		uint64_t c0_pmei:1;
+		uint64_t c0_hpint:1;
+		uint64_t c1_aeri:1;
+		uint64_t crs1_er:1;
+		uint64_t c1_se:1;
+		uint64_t crs1_dr:1;
+		uint64_t c1_wake:1;
+		uint64_t c1_pmei:1;
+		uint64_t c1_hpint:1;
+		uint64_t c0_up_b0:1;
+		uint64_t c0_up_b1:1;
+		uint64_t c0_up_b2:1;
+		uint64_t c0_up_wi:1;
+		uint64_t c0_up_bx:1;
+		uint64_t c0_un_b0:1;
+		uint64_t c0_un_b1:1;
+		uint64_t c0_un_b2:1;
+		uint64_t c0_un_wi:1;
+		uint64_t c0_un_bx:1;
+		uint64_t c1_up_b0:1;
+		uint64_t c1_up_b1:1;
+		uint64_t c1_up_b2:1;
+		uint64_t c1_up_wi:1;
+		uint64_t c1_up_bx:1;
+		uint64_t c1_un_b0:1;
+		uint64_t c1_un_b1:1;
+		uint64_t c1_un_b2:1;
+		uint64_t c1_un_wi:1;
+		uint64_t c1_un_bx:1;
+		uint64_t c0_un_wf:1;
+		uint64_t c1_un_wf:1;
+		uint64_t c0_up_wf:1;
+		uint64_t c1_up_wf:1;
+		uint64_t c0_exc:1;
+		uint64_t c1_exc:1;
+		uint64_t c0_ldwn:1;
+		uint64_t c1_ldwn:1;
+		uint64_t int_a:1;
+		uint64_t reserved_62_62:1;
+		uint64_t mio_inta:1;
+#endif
 	} s;
 	struct cvmx_npei_int_sum_s cn52xx;
 	struct cvmx_npei_int_sum_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t mio_inta:1;
 		uint64_t reserved_62_62:1;
 		uint64_t int_a:1;
@@ -1482,9 +2603,73 @@
 		uint64_t bar0_to:1;
 		uint64_t rml_wto:1;
 		uint64_t rml_rto:1;
+#else
+		uint64_t rml_rto:1;
+		uint64_t rml_wto:1;
+		uint64_t bar0_to:1;
+		uint64_t iob2big:1;
+		uint64_t dma0dbo:1;
+		uint64_t dma1dbo:1;
+		uint64_t dma2dbo:1;
+		uint64_t dma3dbo:1;
+		uint64_t reserved_8_8:1;
+		uint64_t dma0fi:1;
+		uint64_t dma1fi:1;
+		uint64_t dcnt0:1;
+		uint64_t dcnt1:1;
+		uint64_t dtime0:1;
+		uint64_t dtime1:1;
+		uint64_t reserved_15_18:4;
+		uint64_t c0_aeri:1;
+		uint64_t crs0_er:1;
+		uint64_t c0_se:1;
+		uint64_t crs0_dr:1;
+		uint64_t c0_wake:1;
+		uint64_t c0_pmei:1;
+		uint64_t c0_hpint:1;
+		uint64_t c1_aeri:1;
+		uint64_t crs1_er:1;
+		uint64_t c1_se:1;
+		uint64_t crs1_dr:1;
+		uint64_t c1_wake:1;
+		uint64_t c1_pmei:1;
+		uint64_t c1_hpint:1;
+		uint64_t c0_up_b0:1;
+		uint64_t c0_up_b1:1;
+		uint64_t c0_up_b2:1;
+		uint64_t c0_up_wi:1;
+		uint64_t c0_up_bx:1;
+		uint64_t c0_un_b0:1;
+		uint64_t c0_un_b1:1;
+		uint64_t c0_un_b2:1;
+		uint64_t c0_un_wi:1;
+		uint64_t c0_un_bx:1;
+		uint64_t c1_up_b0:1;
+		uint64_t c1_up_b1:1;
+		uint64_t c1_up_b2:1;
+		uint64_t c1_up_wi:1;
+		uint64_t c1_up_bx:1;
+		uint64_t c1_un_b0:1;
+		uint64_t c1_un_b1:1;
+		uint64_t c1_un_b2:1;
+		uint64_t c1_un_wi:1;
+		uint64_t c1_un_bx:1;
+		uint64_t c0_un_wf:1;
+		uint64_t c1_un_wf:1;
+		uint64_t c0_up_wf:1;
+		uint64_t c1_up_wf:1;
+		uint64_t c0_exc:1;
+		uint64_t c1_exc:1;
+		uint64_t c0_ldwn:1;
+		uint64_t c1_ldwn:1;
+		uint64_t int_a:1;
+		uint64_t reserved_62_62:1;
+		uint64_t mio_inta:1;
+#endif
 	} cn52xxp1;
 	struct cvmx_npei_int_sum_s cn56xx;
 	struct cvmx_npei_int_sum_cn56xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t mio_inta:1;
 		uint64_t reserved_61_62:2;
 		uint64_t c1_ldwn:1;
@@ -1545,12 +2730,75 @@
 		uint64_t bar0_to:1;
 		uint64_t rml_wto:1;
 		uint64_t rml_rto:1;
+#else
+		uint64_t rml_rto:1;
+		uint64_t rml_wto:1;
+		uint64_t bar0_to:1;
+		uint64_t iob2big:1;
+		uint64_t dma0dbo:1;
+		uint64_t dma1dbo:1;
+		uint64_t dma2dbo:1;
+		uint64_t dma3dbo:1;
+		uint64_t dma4dbo:1;
+		uint64_t dma0fi:1;
+		uint64_t dma1fi:1;
+		uint64_t dcnt0:1;
+		uint64_t dcnt1:1;
+		uint64_t dtime0:1;
+		uint64_t dtime1:1;
+		uint64_t reserved_15_18:4;
+		uint64_t c0_aeri:1;
+		uint64_t reserved_20_20:1;
+		uint64_t c0_se:1;
+		uint64_t reserved_22_22:1;
+		uint64_t c0_wake:1;
+		uint64_t c0_pmei:1;
+		uint64_t c0_hpint:1;
+		uint64_t c1_aeri:1;
+		uint64_t reserved_27_27:1;
+		uint64_t c1_se:1;
+		uint64_t reserved_29_29:1;
+		uint64_t c1_wake:1;
+		uint64_t c1_pmei:1;
+		uint64_t c1_hpint:1;
+		uint64_t c0_up_b0:1;
+		uint64_t c0_up_b1:1;
+		uint64_t c0_up_b2:1;
+		uint64_t c0_up_wi:1;
+		uint64_t c0_up_bx:1;
+		uint64_t c0_un_b0:1;
+		uint64_t c0_un_b1:1;
+		uint64_t c0_un_b2:1;
+		uint64_t c0_un_wi:1;
+		uint64_t c0_un_bx:1;
+		uint64_t c1_up_b0:1;
+		uint64_t c1_up_b1:1;
+		uint64_t c1_up_b2:1;
+		uint64_t c1_up_wi:1;
+		uint64_t c1_up_bx:1;
+		uint64_t c1_un_b0:1;
+		uint64_t c1_un_b1:1;
+		uint64_t c1_un_b2:1;
+		uint64_t c1_un_wi:1;
+		uint64_t c1_un_bx:1;
+		uint64_t c0_un_wf:1;
+		uint64_t c1_un_wf:1;
+		uint64_t c0_up_wf:1;
+		uint64_t c1_up_wf:1;
+		uint64_t c0_exc:1;
+		uint64_t c1_exc:1;
+		uint64_t c0_ldwn:1;
+		uint64_t c1_ldwn:1;
+		uint64_t reserved_61_62:2;
+		uint64_t mio_inta:1;
+#endif
 	} cn56xxp1;
 };
 
 union cvmx_npei_int_sum2 {
 	uint64_t u64;
 	struct cvmx_npei_int_sum2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t mio_inta:1;
 		uint64_t reserved_62_62:1;
 		uint64_t int_a:1;
@@ -1612,6 +2860,69 @@
 		uint64_t bar0_to:1;
 		uint64_t rml_wto:1;
 		uint64_t rml_rto:1;
+#else
+		uint64_t rml_rto:1;
+		uint64_t rml_wto:1;
+		uint64_t bar0_to:1;
+		uint64_t iob2big:1;
+		uint64_t dma0dbo:1;
+		uint64_t dma1dbo:1;
+		uint64_t dma2dbo:1;
+		uint64_t dma3dbo:1;
+		uint64_t reserved_8_8:1;
+		uint64_t dma0fi:1;
+		uint64_t dma1fi:1;
+		uint64_t dcnt0:1;
+		uint64_t dcnt1:1;
+		uint64_t dtime0:1;
+		uint64_t dtime1:1;
+		uint64_t reserved_15_18:4;
+		uint64_t c0_aeri:1;
+		uint64_t crs0_er:1;
+		uint64_t c0_se:1;
+		uint64_t crs0_dr:1;
+		uint64_t c0_wake:1;
+		uint64_t c0_pmei:1;
+		uint64_t c0_hpint:1;
+		uint64_t c1_aeri:1;
+		uint64_t crs1_er:1;
+		uint64_t c1_se:1;
+		uint64_t crs1_dr:1;
+		uint64_t c1_wake:1;
+		uint64_t c1_pmei:1;
+		uint64_t c1_hpint:1;
+		uint64_t c0_up_b0:1;
+		uint64_t c0_up_b1:1;
+		uint64_t c0_up_b2:1;
+		uint64_t c0_up_wi:1;
+		uint64_t c0_up_bx:1;
+		uint64_t c0_un_b0:1;
+		uint64_t c0_un_b1:1;
+		uint64_t c0_un_b2:1;
+		uint64_t c0_un_wi:1;
+		uint64_t c0_un_bx:1;
+		uint64_t c1_up_b0:1;
+		uint64_t c1_up_b1:1;
+		uint64_t c1_up_b2:1;
+		uint64_t c1_up_wi:1;
+		uint64_t c1_up_bx:1;
+		uint64_t c1_un_b0:1;
+		uint64_t c1_un_b1:1;
+		uint64_t c1_un_b2:1;
+		uint64_t c1_un_wi:1;
+		uint64_t c1_un_bx:1;
+		uint64_t c0_un_wf:1;
+		uint64_t c1_un_wf:1;
+		uint64_t c0_up_wf:1;
+		uint64_t c1_up_wf:1;
+		uint64_t c0_exc:1;
+		uint64_t c1_exc:1;
+		uint64_t c0_ldwn:1;
+		uint64_t c1_ldwn:1;
+		uint64_t int_a:1;
+		uint64_t reserved_62_62:1;
+		uint64_t mio_inta:1;
+#endif
 	} s;
 	struct cvmx_npei_int_sum2_s cn52xx;
 	struct cvmx_npei_int_sum2_s cn52xxp1;
@@ -1621,7 +2932,11 @@
 union cvmx_npei_last_win_rdata0 {
 	uint64_t u64;
 	struct cvmx_npei_last_win_rdata0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t data:64;
+#else
+		uint64_t data:64;
+#endif
 	} s;
 	struct cvmx_npei_last_win_rdata0_s cn52xx;
 	struct cvmx_npei_last_win_rdata0_s cn52xxp1;
@@ -1632,7 +2947,11 @@
 union cvmx_npei_last_win_rdata1 {
 	uint64_t u64;
 	struct cvmx_npei_last_win_rdata1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t data:64;
+#else
+		uint64_t data:64;
+#endif
 	} s;
 	struct cvmx_npei_last_win_rdata1_s cn52xx;
 	struct cvmx_npei_last_win_rdata1_s cn52xxp1;
@@ -1643,9 +2962,15 @@
 union cvmx_npei_mem_access_ctl {
 	uint64_t u64;
 	struct cvmx_npei_mem_access_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_14_63:50;
 		uint64_t max_word:4;
 		uint64_t timer:10;
+#else
+		uint64_t timer:10;
+		uint64_t max_word:4;
+		uint64_t reserved_14_63:50;
+#endif
 	} s;
 	struct cvmx_npei_mem_access_ctl_s cn52xx;
 	struct cvmx_npei_mem_access_ctl_s cn52xxp1;
@@ -1656,6 +2981,7 @@
 union cvmx_npei_mem_access_subidx {
 	uint64_t u64;
 	struct cvmx_npei_mem_access_subidx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_42_63:22;
 		uint64_t zero:1;
 		uint64_t port:2;
@@ -1667,6 +2993,19 @@
 		uint64_t ror:1;
 		uint64_t row:1;
 		uint64_t ba:30;
+#else
+		uint64_t ba:30;
+		uint64_t row:1;
+		uint64_t ror:1;
+		uint64_t nsw:1;
+		uint64_t nsr:1;
+		uint64_t esw:2;
+		uint64_t esr:2;
+		uint64_t nmerge:1;
+		uint64_t port:2;
+		uint64_t zero:1;
+		uint64_t reserved_42_63:22;
+#endif
 	} s;
 	struct cvmx_npei_mem_access_subidx_s cn52xx;
 	struct cvmx_npei_mem_access_subidx_s cn52xxp1;
@@ -1677,7 +3016,11 @@
 union cvmx_npei_msi_enb0 {
 	uint64_t u64;
 	struct cvmx_npei_msi_enb0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t enb:64;
+#else
+		uint64_t enb:64;
+#endif
 	} s;
 	struct cvmx_npei_msi_enb0_s cn52xx;
 	struct cvmx_npei_msi_enb0_s cn52xxp1;
@@ -1688,7 +3031,11 @@
 union cvmx_npei_msi_enb1 {
 	uint64_t u64;
 	struct cvmx_npei_msi_enb1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t enb:64;
+#else
+		uint64_t enb:64;
+#endif
 	} s;
 	struct cvmx_npei_msi_enb1_s cn52xx;
 	struct cvmx_npei_msi_enb1_s cn52xxp1;
@@ -1699,7 +3046,11 @@
 union cvmx_npei_msi_enb2 {
 	uint64_t u64;
 	struct cvmx_npei_msi_enb2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t enb:64;
+#else
+		uint64_t enb:64;
+#endif
 	} s;
 	struct cvmx_npei_msi_enb2_s cn52xx;
 	struct cvmx_npei_msi_enb2_s cn52xxp1;
@@ -1710,7 +3061,11 @@
 union cvmx_npei_msi_enb3 {
 	uint64_t u64;
 	struct cvmx_npei_msi_enb3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t enb:64;
+#else
+		uint64_t enb:64;
+#endif
 	} s;
 	struct cvmx_npei_msi_enb3_s cn52xx;
 	struct cvmx_npei_msi_enb3_s cn52xxp1;
@@ -1721,7 +3076,11 @@
 union cvmx_npei_msi_rcv0 {
 	uint64_t u64;
 	struct cvmx_npei_msi_rcv0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t intr:64;
+#else
+		uint64_t intr:64;
+#endif
 	} s;
 	struct cvmx_npei_msi_rcv0_s cn52xx;
 	struct cvmx_npei_msi_rcv0_s cn52xxp1;
@@ -1732,7 +3091,11 @@
 union cvmx_npei_msi_rcv1 {
 	uint64_t u64;
 	struct cvmx_npei_msi_rcv1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t intr:64;
+#else
+		uint64_t intr:64;
+#endif
 	} s;
 	struct cvmx_npei_msi_rcv1_s cn52xx;
 	struct cvmx_npei_msi_rcv1_s cn52xxp1;
@@ -1743,7 +3106,11 @@
 union cvmx_npei_msi_rcv2 {
 	uint64_t u64;
 	struct cvmx_npei_msi_rcv2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t intr:64;
+#else
+		uint64_t intr:64;
+#endif
 	} s;
 	struct cvmx_npei_msi_rcv2_s cn52xx;
 	struct cvmx_npei_msi_rcv2_s cn52xxp1;
@@ -1754,7 +3121,11 @@
 union cvmx_npei_msi_rcv3 {
 	uint64_t u64;
 	struct cvmx_npei_msi_rcv3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t intr:64;
+#else
+		uint64_t intr:64;
+#endif
 	} s;
 	struct cvmx_npei_msi_rcv3_s cn52xx;
 	struct cvmx_npei_msi_rcv3_s cn52xxp1;
@@ -1765,9 +3136,15 @@
 union cvmx_npei_msi_rd_map {
 	uint64_t u64;
 	struct cvmx_npei_msi_rd_map_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t rd_int:8;
 		uint64_t msi_int:8;
+#else
+		uint64_t msi_int:8;
+		uint64_t rd_int:8;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_npei_msi_rd_map_s cn52xx;
 	struct cvmx_npei_msi_rd_map_s cn52xxp1;
@@ -1778,7 +3155,11 @@
 union cvmx_npei_msi_w1c_enb0 {
 	uint64_t u64;
 	struct cvmx_npei_msi_w1c_enb0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t clr:64;
+#else
+		uint64_t clr:64;
+#endif
 	} s;
 	struct cvmx_npei_msi_w1c_enb0_s cn52xx;
 	struct cvmx_npei_msi_w1c_enb0_s cn56xx;
@@ -1787,7 +3168,11 @@
 union cvmx_npei_msi_w1c_enb1 {
 	uint64_t u64;
 	struct cvmx_npei_msi_w1c_enb1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t clr:64;
+#else
+		uint64_t clr:64;
+#endif
 	} s;
 	struct cvmx_npei_msi_w1c_enb1_s cn52xx;
 	struct cvmx_npei_msi_w1c_enb1_s cn56xx;
@@ -1796,7 +3181,11 @@
 union cvmx_npei_msi_w1c_enb2 {
 	uint64_t u64;
 	struct cvmx_npei_msi_w1c_enb2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t clr:64;
+#else
+		uint64_t clr:64;
+#endif
 	} s;
 	struct cvmx_npei_msi_w1c_enb2_s cn52xx;
 	struct cvmx_npei_msi_w1c_enb2_s cn56xx;
@@ -1805,7 +3194,11 @@
 union cvmx_npei_msi_w1c_enb3 {
 	uint64_t u64;
 	struct cvmx_npei_msi_w1c_enb3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t clr:64;
+#else
+		uint64_t clr:64;
+#endif
 	} s;
 	struct cvmx_npei_msi_w1c_enb3_s cn52xx;
 	struct cvmx_npei_msi_w1c_enb3_s cn56xx;
@@ -1814,7 +3207,11 @@
 union cvmx_npei_msi_w1s_enb0 {
 	uint64_t u64;
 	struct cvmx_npei_msi_w1s_enb0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t set:64;
+#else
+		uint64_t set:64;
+#endif
 	} s;
 	struct cvmx_npei_msi_w1s_enb0_s cn52xx;
 	struct cvmx_npei_msi_w1s_enb0_s cn56xx;
@@ -1823,7 +3220,11 @@
 union cvmx_npei_msi_w1s_enb1 {
 	uint64_t u64;
 	struct cvmx_npei_msi_w1s_enb1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t set:64;
+#else
+		uint64_t set:64;
+#endif
 	} s;
 	struct cvmx_npei_msi_w1s_enb1_s cn52xx;
 	struct cvmx_npei_msi_w1s_enb1_s cn56xx;
@@ -1832,7 +3233,11 @@
 union cvmx_npei_msi_w1s_enb2 {
 	uint64_t u64;
 	struct cvmx_npei_msi_w1s_enb2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t set:64;
+#else
+		uint64_t set:64;
+#endif
 	} s;
 	struct cvmx_npei_msi_w1s_enb2_s cn52xx;
 	struct cvmx_npei_msi_w1s_enb2_s cn56xx;
@@ -1841,7 +3246,11 @@
 union cvmx_npei_msi_w1s_enb3 {
 	uint64_t u64;
 	struct cvmx_npei_msi_w1s_enb3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t set:64;
+#else
+		uint64_t set:64;
+#endif
 	} s;
 	struct cvmx_npei_msi_w1s_enb3_s cn52xx;
 	struct cvmx_npei_msi_w1s_enb3_s cn56xx;
@@ -1850,9 +3259,15 @@
 union cvmx_npei_msi_wr_map {
 	uint64_t u64;
 	struct cvmx_npei_msi_wr_map_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t ciu_int:8;
 		uint64_t msi_int:8;
+#else
+		uint64_t msi_int:8;
+		uint64_t ciu_int:8;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_npei_msi_wr_map_s cn52xx;
 	struct cvmx_npei_msi_wr_map_s cn52xxp1;
@@ -1863,6 +3278,7 @@
 union cvmx_npei_pcie_credit_cnt {
 	uint64_t u64;
 	struct cvmx_npei_pcie_credit_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t p1_ccnt:8;
 		uint64_t p1_ncnt:8;
@@ -1870,6 +3286,15 @@
 		uint64_t p0_ccnt:8;
 		uint64_t p0_ncnt:8;
 		uint64_t p0_pcnt:8;
+#else
+		uint64_t p0_pcnt:8;
+		uint64_t p0_ncnt:8;
+		uint64_t p0_ccnt:8;
+		uint64_t p1_pcnt:8;
+		uint64_t p1_ncnt:8;
+		uint64_t p1_ccnt:8;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_npei_pcie_credit_cnt_s cn52xx;
 	struct cvmx_npei_pcie_credit_cnt_s cn56xx;
@@ -1878,8 +3303,13 @@
 union cvmx_npei_pcie_msi_rcv {
 	uint64_t u64;
 	struct cvmx_npei_pcie_msi_rcv_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t intr:8;
+#else
+		uint64_t intr:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_npei_pcie_msi_rcv_s cn52xx;
 	struct cvmx_npei_pcie_msi_rcv_s cn52xxp1;
@@ -1890,9 +3320,15 @@
 union cvmx_npei_pcie_msi_rcv_b1 {
 	uint64_t u64;
 	struct cvmx_npei_pcie_msi_rcv_b1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t intr:8;
 		uint64_t reserved_0_7:8;
+#else
+		uint64_t reserved_0_7:8;
+		uint64_t intr:8;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_npei_pcie_msi_rcv_b1_s cn52xx;
 	struct cvmx_npei_pcie_msi_rcv_b1_s cn52xxp1;
@@ -1903,9 +3339,15 @@
 union cvmx_npei_pcie_msi_rcv_b2 {
 	uint64_t u64;
 	struct cvmx_npei_pcie_msi_rcv_b2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_24_63:40;
 		uint64_t intr:8;
 		uint64_t reserved_0_15:16;
+#else
+		uint64_t reserved_0_15:16;
+		uint64_t intr:8;
+		uint64_t reserved_24_63:40;
+#endif
 	} s;
 	struct cvmx_npei_pcie_msi_rcv_b2_s cn52xx;
 	struct cvmx_npei_pcie_msi_rcv_b2_s cn52xxp1;
@@ -1916,9 +3358,15 @@
 union cvmx_npei_pcie_msi_rcv_b3 {
 	uint64_t u64;
 	struct cvmx_npei_pcie_msi_rcv_b3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t intr:8;
 		uint64_t reserved_0_23:24;
+#else
+		uint64_t reserved_0_23:24;
+		uint64_t intr:8;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_npei_pcie_msi_rcv_b3_s cn52xx;
 	struct cvmx_npei_pcie_msi_rcv_b3_s cn52xxp1;
@@ -1929,9 +3377,15 @@
 union cvmx_npei_pktx_cnts {
 	uint64_t u64;
 	struct cvmx_npei_pktx_cnts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_54_63:10;
 		uint64_t timer:22;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t timer:22;
+		uint64_t reserved_54_63:10;
+#endif
 	} s;
 	struct cvmx_npei_pktx_cnts_s cn52xx;
 	struct cvmx_npei_pktx_cnts_s cn56xx;
@@ -1940,8 +3394,13 @@
 union cvmx_npei_pktx_in_bp {
 	uint64_t u64;
 	struct cvmx_npei_pktx_in_bp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t wmark:32;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t wmark:32;
+#endif
 	} s;
 	struct cvmx_npei_pktx_in_bp_s cn52xx;
 	struct cvmx_npei_pktx_in_bp_s cn56xx;
@@ -1950,8 +3409,13 @@
 union cvmx_npei_pktx_instr_baddr {
 	uint64_t u64;
 	struct cvmx_npei_pktx_instr_baddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t addr:61;
 		uint64_t reserved_0_2:3;
+#else
+		uint64_t reserved_0_2:3;
+		uint64_t addr:61;
+#endif
 	} s;
 	struct cvmx_npei_pktx_instr_baddr_s cn52xx;
 	struct cvmx_npei_pktx_instr_baddr_s cn56xx;
@@ -1960,8 +3424,13 @@
 union cvmx_npei_pktx_instr_baoff_dbell {
 	uint64_t u64;
 	struct cvmx_npei_pktx_instr_baoff_dbell_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t aoff:32;
 		uint64_t dbell:32;
+#else
+		uint64_t dbell:32;
+		uint64_t aoff:32;
+#endif
 	} s;
 	struct cvmx_npei_pktx_instr_baoff_dbell_s cn52xx;
 	struct cvmx_npei_pktx_instr_baoff_dbell_s cn56xx;
@@ -1970,11 +3439,19 @@
 union cvmx_npei_pktx_instr_fifo_rsize {
 	uint64_t u64;
 	struct cvmx_npei_pktx_instr_fifo_rsize_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t max:9;
 		uint64_t rrp:9;
 		uint64_t wrp:9;
 		uint64_t fcnt:5;
 		uint64_t rsize:32;
+#else
+		uint64_t rsize:32;
+		uint64_t fcnt:5;
+		uint64_t wrp:9;
+		uint64_t rrp:9;
+		uint64_t max:9;
+#endif
 	} s;
 	struct cvmx_npei_pktx_instr_fifo_rsize_s cn52xx;
 	struct cvmx_npei_pktx_instr_fifo_rsize_s cn56xx;
@@ -1983,6 +3460,7 @@
 union cvmx_npei_pktx_instr_header {
 	uint64_t u64;
 	struct cvmx_npei_pktx_instr_header_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_44_63:20;
 		uint64_t pbp:1;
 		uint64_t reserved_38_42:5;
@@ -1996,6 +3474,21 @@
 		uint64_t reserved_13_13:1;
 		uint64_t skp_len:7;
 		uint64_t reserved_0_5:6;
+#else
+		uint64_t reserved_0_5:6;
+		uint64_t skp_len:7;
+		uint64_t reserved_13_13:1;
+		uint64_t par_mode:2;
+		uint64_t reserved_16_20:5;
+		uint64_t use_ihdr:1;
+		uint64_t reserved_22_27:6;
+		uint64_t rskp_len:7;
+		uint64_t reserved_35_35:1;
+		uint64_t rparmode:2;
+		uint64_t reserved_38_42:5;
+		uint64_t pbp:1;
+		uint64_t reserved_44_63:20;
+#endif
 	} s;
 	struct cvmx_npei_pktx_instr_header_s cn52xx;
 	struct cvmx_npei_pktx_instr_header_s cn56xx;
@@ -2004,8 +3497,13 @@
 union cvmx_npei_pktx_slist_baddr {
 	uint64_t u64;
 	struct cvmx_npei_pktx_slist_baddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t addr:60;
 		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t addr:60;
+#endif
 	} s;
 	struct cvmx_npei_pktx_slist_baddr_s cn52xx;
 	struct cvmx_npei_pktx_slist_baddr_s cn56xx;
@@ -2014,8 +3512,13 @@
 union cvmx_npei_pktx_slist_baoff_dbell {
 	uint64_t u64;
 	struct cvmx_npei_pktx_slist_baoff_dbell_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t aoff:32;
 		uint64_t dbell:32;
+#else
+		uint64_t dbell:32;
+		uint64_t aoff:32;
+#endif
 	} s;
 	struct cvmx_npei_pktx_slist_baoff_dbell_s cn52xx;
 	struct cvmx_npei_pktx_slist_baoff_dbell_s cn56xx;
@@ -2024,8 +3527,13 @@
 union cvmx_npei_pktx_slist_fifo_rsize {
 	uint64_t u64;
 	struct cvmx_npei_pktx_slist_fifo_rsize_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t rsize:32;
+#else
+		uint64_t rsize:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_npei_pktx_slist_fifo_rsize_s cn52xx;
 	struct cvmx_npei_pktx_slist_fifo_rsize_s cn56xx;
@@ -2034,8 +3542,13 @@
 union cvmx_npei_pkt_cnt_int {
 	uint64_t u64;
 	struct cvmx_npei_pkt_cnt_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t port:32;
+#else
+		uint64_t port:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_npei_pkt_cnt_int_s cn52xx;
 	struct cvmx_npei_pkt_cnt_int_s cn56xx;
@@ -2044,8 +3557,13 @@
 union cvmx_npei_pkt_cnt_int_enb {
 	uint64_t u64;
 	struct cvmx_npei_pkt_cnt_int_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t port:32;
+#else
+		uint64_t port:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_npei_pkt_cnt_int_enb_s cn52xx;
 	struct cvmx_npei_pkt_cnt_int_enb_s cn56xx;
@@ -2054,7 +3572,11 @@
 union cvmx_npei_pkt_data_out_es {
 	uint64_t u64;
 	struct cvmx_npei_pkt_data_out_es_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t es:64;
+#else
+		uint64_t es:64;
+#endif
 	} s;
 	struct cvmx_npei_pkt_data_out_es_s cn52xx;
 	struct cvmx_npei_pkt_data_out_es_s cn56xx;
@@ -2063,8 +3585,13 @@
 union cvmx_npei_pkt_data_out_ns {
 	uint64_t u64;
 	struct cvmx_npei_pkt_data_out_ns_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t nsr:32;
+#else
+		uint64_t nsr:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_npei_pkt_data_out_ns_s cn52xx;
 	struct cvmx_npei_pkt_data_out_ns_s cn56xx;
@@ -2073,8 +3600,13 @@
 union cvmx_npei_pkt_data_out_ror {
 	uint64_t u64;
 	struct cvmx_npei_pkt_data_out_ror_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t ror:32;
+#else
+		uint64_t ror:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_npei_pkt_data_out_ror_s cn52xx;
 	struct cvmx_npei_pkt_data_out_ror_s cn56xx;
@@ -2083,8 +3615,13 @@
 union cvmx_npei_pkt_dpaddr {
 	uint64_t u64;
 	struct cvmx_npei_pkt_dpaddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t dptr:32;
+#else
+		uint64_t dptr:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_npei_pkt_dpaddr_s cn52xx;
 	struct cvmx_npei_pkt_dpaddr_s cn56xx;
@@ -2093,8 +3630,13 @@
 union cvmx_npei_pkt_in_bp {
 	uint64_t u64;
 	struct cvmx_npei_pkt_in_bp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t bp:32;
+#else
+		uint64_t bp:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_npei_pkt_in_bp_s cn52xx;
 	struct cvmx_npei_pkt_in_bp_s cn56xx;
@@ -2103,8 +3645,13 @@
 union cvmx_npei_pkt_in_donex_cnts {
 	uint64_t u64;
 	struct cvmx_npei_pkt_in_donex_cnts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_npei_pkt_in_donex_cnts_s cn52xx;
 	struct cvmx_npei_pkt_in_donex_cnts_s cn56xx;
@@ -2113,8 +3660,13 @@
 union cvmx_npei_pkt_in_instr_counts {
 	uint64_t u64;
 	struct cvmx_npei_pkt_in_instr_counts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t wr_cnt:32;
 		uint64_t rd_cnt:32;
+#else
+		uint64_t rd_cnt:32;
+		uint64_t wr_cnt:32;
+#endif
 	} s;
 	struct cvmx_npei_pkt_in_instr_counts_s cn52xx;
 	struct cvmx_npei_pkt_in_instr_counts_s cn56xx;
@@ -2123,7 +3675,11 @@
 union cvmx_npei_pkt_in_pcie_port {
 	uint64_t u64;
 	struct cvmx_npei_pkt_in_pcie_port_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t pp:64;
+#else
+		uint64_t pp:64;
+#endif
 	} s;
 	struct cvmx_npei_pkt_in_pcie_port_s cn52xx;
 	struct cvmx_npei_pkt_in_pcie_port_s cn56xx;
@@ -2132,6 +3688,7 @@
 union cvmx_npei_pkt_input_control {
 	uint64_t u64;
 	struct cvmx_npei_pkt_input_control_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_23_63:41;
 		uint64_t pkt_rr:1;
 		uint64_t pbp_dhi:13;
@@ -2142,6 +3699,18 @@
 		uint64_t nsr:1;
 		uint64_t esr:2;
 		uint64_t ror:1;
+#else
+		uint64_t ror:1;
+		uint64_t esr:2;
+		uint64_t nsr:1;
+		uint64_t use_csr:1;
+		uint64_t d_ror:1;
+		uint64_t d_esr:2;
+		uint64_t d_nsr:1;
+		uint64_t pbp_dhi:13;
+		uint64_t pkt_rr:1;
+		uint64_t reserved_23_63:41;
+#endif
 	} s;
 	struct cvmx_npei_pkt_input_control_s cn52xx;
 	struct cvmx_npei_pkt_input_control_s cn56xx;
@@ -2150,8 +3719,13 @@
 union cvmx_npei_pkt_instr_enb {
 	uint64_t u64;
 	struct cvmx_npei_pkt_instr_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t enb:32;
+#else
+		uint64_t enb:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_npei_pkt_instr_enb_s cn52xx;
 	struct cvmx_npei_pkt_instr_enb_s cn56xx;
@@ -2160,7 +3734,11 @@
 union cvmx_npei_pkt_instr_rd_size {
 	uint64_t u64;
 	struct cvmx_npei_pkt_instr_rd_size_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t rdsize:64;
+#else
+		uint64_t rdsize:64;
+#endif
 	} s;
 	struct cvmx_npei_pkt_instr_rd_size_s cn52xx;
 	struct cvmx_npei_pkt_instr_rd_size_s cn56xx;
@@ -2169,8 +3747,13 @@
 union cvmx_npei_pkt_instr_size {
 	uint64_t u64;
 	struct cvmx_npei_pkt_instr_size_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t is_64b:32;
+#else
+		uint64_t is_64b:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_npei_pkt_instr_size_s cn52xx;
 	struct cvmx_npei_pkt_instr_size_s cn56xx;
@@ -2179,9 +3762,15 @@
 union cvmx_npei_pkt_int_levels {
 	uint64_t u64;
 	struct cvmx_npei_pkt_int_levels_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_54_63:10;
 		uint64_t time:22;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t time:22;
+		uint64_t reserved_54_63:10;
+#endif
 	} s;
 	struct cvmx_npei_pkt_int_levels_s cn52xx;
 	struct cvmx_npei_pkt_int_levels_s cn56xx;
@@ -2190,8 +3779,13 @@
 union cvmx_npei_pkt_iptr {
 	uint64_t u64;
 	struct cvmx_npei_pkt_iptr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t iptr:32;
+#else
+		uint64_t iptr:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_npei_pkt_iptr_s cn52xx;
 	struct cvmx_npei_pkt_iptr_s cn56xx;
@@ -2200,8 +3794,13 @@
 union cvmx_npei_pkt_out_bmode {
 	uint64_t u64;
 	struct cvmx_npei_pkt_out_bmode_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t bmode:32;
+#else
+		uint64_t bmode:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_npei_pkt_out_bmode_s cn52xx;
 	struct cvmx_npei_pkt_out_bmode_s cn56xx;
@@ -2210,8 +3809,13 @@
 union cvmx_npei_pkt_out_enb {
 	uint64_t u64;
 	struct cvmx_npei_pkt_out_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t enb:32;
+#else
+		uint64_t enb:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_npei_pkt_out_enb_s cn52xx;
 	struct cvmx_npei_pkt_out_enb_s cn56xx;
@@ -2220,8 +3824,13 @@
 union cvmx_npei_pkt_output_wmark {
 	uint64_t u64;
 	struct cvmx_npei_pkt_output_wmark_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t wmark:32;
+#else
+		uint64_t wmark:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_npei_pkt_output_wmark_s cn52xx;
 	struct cvmx_npei_pkt_output_wmark_s cn56xx;
@@ -2230,7 +3839,11 @@
 union cvmx_npei_pkt_pcie_port {
 	uint64_t u64;
 	struct cvmx_npei_pkt_pcie_port_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t pp:64;
+#else
+		uint64_t pp:64;
+#endif
 	} s;
 	struct cvmx_npei_pkt_pcie_port_s cn52xx;
 	struct cvmx_npei_pkt_pcie_port_s cn56xx;
@@ -2239,8 +3852,13 @@
 union cvmx_npei_pkt_port_in_rst {
 	uint64_t u64;
 	struct cvmx_npei_pkt_port_in_rst_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t in_rst:32;
 		uint64_t out_rst:32;
+#else
+		uint64_t out_rst:32;
+		uint64_t in_rst:32;
+#endif
 	} s;
 	struct cvmx_npei_pkt_port_in_rst_s cn52xx;
 	struct cvmx_npei_pkt_port_in_rst_s cn56xx;
@@ -2249,7 +3867,11 @@
 union cvmx_npei_pkt_slist_es {
 	uint64_t u64;
 	struct cvmx_npei_pkt_slist_es_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t es:64;
+#else
+		uint64_t es:64;
+#endif
 	} s;
 	struct cvmx_npei_pkt_slist_es_s cn52xx;
 	struct cvmx_npei_pkt_slist_es_s cn56xx;
@@ -2258,9 +3880,15 @@
 union cvmx_npei_pkt_slist_id_size {
 	uint64_t u64;
 	struct cvmx_npei_pkt_slist_id_size_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_23_63:41;
 		uint64_t isize:7;
 		uint64_t bsize:16;
+#else
+		uint64_t bsize:16;
+		uint64_t isize:7;
+		uint64_t reserved_23_63:41;
+#endif
 	} s;
 	struct cvmx_npei_pkt_slist_id_size_s cn52xx;
 	struct cvmx_npei_pkt_slist_id_size_s cn56xx;
@@ -2269,8 +3897,13 @@
 union cvmx_npei_pkt_slist_ns {
 	uint64_t u64;
 	struct cvmx_npei_pkt_slist_ns_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t nsr:32;
+#else
+		uint64_t nsr:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_npei_pkt_slist_ns_s cn52xx;
 	struct cvmx_npei_pkt_slist_ns_s cn56xx;
@@ -2279,8 +3912,13 @@
 union cvmx_npei_pkt_slist_ror {
 	uint64_t u64;
 	struct cvmx_npei_pkt_slist_ror_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t ror:32;
+#else
+		uint64_t ror:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_npei_pkt_slist_ror_s cn52xx;
 	struct cvmx_npei_pkt_slist_ror_s cn56xx;
@@ -2289,8 +3927,13 @@
 union cvmx_npei_pkt_time_int {
 	uint64_t u64;
 	struct cvmx_npei_pkt_time_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t port:32;
+#else
+		uint64_t port:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_npei_pkt_time_int_s cn52xx;
 	struct cvmx_npei_pkt_time_int_s cn56xx;
@@ -2299,8 +3942,13 @@
 union cvmx_npei_pkt_time_int_enb {
 	uint64_t u64;
 	struct cvmx_npei_pkt_time_int_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t port:32;
+#else
+		uint64_t port:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_npei_pkt_time_int_enb_s cn52xx;
 	struct cvmx_npei_pkt_time_int_enb_s cn56xx;
@@ -2309,6 +3957,7 @@
 union cvmx_npei_rsl_int_blocks {
 	uint64_t u64;
 	struct cvmx_npei_rsl_int_blocks_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_31_63:33;
 		uint64_t iob:1;
 		uint64_t lmc1:1;
@@ -2338,6 +3987,37 @@
 		uint64_t gmx1:1;
 		uint64_t gmx0:1;
 		uint64_t mio:1;
+#else
+		uint64_t mio:1;
+		uint64_t gmx0:1;
+		uint64_t gmx1:1;
+		uint64_t npei:1;
+		uint64_t key:1;
+		uint64_t fpa:1;
+		uint64_t dfa:1;
+		uint64_t zip:1;
+		uint64_t reserved_8_8:1;
+		uint64_t ipd:1;
+		uint64_t pko:1;
+		uint64_t tim:1;
+		uint64_t pow:1;
+		uint64_t usb:1;
+		uint64_t rad:1;
+		uint64_t usb1:1;
+		uint64_t l2c:1;
+		uint64_t lmc0:1;
+		uint64_t spx0:1;
+		uint64_t spx1:1;
+		uint64_t pip:1;
+		uint64_t reserved_21_21:1;
+		uint64_t asxpcs0:1;
+		uint64_t asxpcs1:1;
+		uint64_t reserved_24_27:4;
+		uint64_t agl:1;
+		uint64_t lmc1:1;
+		uint64_t iob:1;
+		uint64_t reserved_31_63:33;
+#endif
 	} s;
 	struct cvmx_npei_rsl_int_blocks_s cn52xx;
 	struct cvmx_npei_rsl_int_blocks_s cn52xxp1;
@@ -2348,7 +4028,11 @@
 union cvmx_npei_scratch_1 {
 	uint64_t u64;
 	struct cvmx_npei_scratch_1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t data:64;
+#else
+		uint64_t data:64;
+#endif
 	} s;
 	struct cvmx_npei_scratch_1_s cn52xx;
 	struct cvmx_npei_scratch_1_s cn52xxp1;
@@ -2359,10 +4043,17 @@
 union cvmx_npei_state1 {
 	uint64_t u64;
 	struct cvmx_npei_state1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t cpl1:12;
 		uint64_t cpl0:12;
 		uint64_t arb:1;
 		uint64_t csr:39;
+#else
+		uint64_t csr:39;
+		uint64_t arb:1;
+		uint64_t cpl0:12;
+		uint64_t cpl1:12;
+#endif
 	} s;
 	struct cvmx_npei_state1_s cn52xx;
 	struct cvmx_npei_state1_s cn52xxp1;
@@ -2373,6 +4064,7 @@
 union cvmx_npei_state2 {
 	uint64_t u64;
 	struct cvmx_npei_state2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t npei:1;
 		uint64_t rac:1;
@@ -2380,6 +4072,15 @@
 		uint64_t csm0:15;
 		uint64_t nnp0:8;
 		uint64_t nnd:8;
+#else
+		uint64_t nnd:8;
+		uint64_t nnp0:8;
+		uint64_t csm0:15;
+		uint64_t csm1:15;
+		uint64_t rac:1;
+		uint64_t npei:1;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_npei_state2_s cn52xx;
 	struct cvmx_npei_state2_s cn52xxp1;
@@ -2390,11 +4091,19 @@
 union cvmx_npei_state3 {
 	uint64_t u64;
 	struct cvmx_npei_state3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_56_63:8;
 		uint64_t psm1:15;
 		uint64_t psm0:15;
 		uint64_t nsm1:13;
 		uint64_t nsm0:13;
+#else
+		uint64_t nsm0:13;
+		uint64_t nsm1:13;
+		uint64_t psm0:15;
+		uint64_t psm1:15;
+		uint64_t reserved_56_63:8;
+#endif
 	} s;
 	struct cvmx_npei_state3_s cn52xx;
 	struct cvmx_npei_state3_s cn52xxp1;
@@ -2405,10 +4114,17 @@
 union cvmx_npei_win_rd_addr {
 	uint64_t u64;
 	struct cvmx_npei_win_rd_addr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_51_63:13;
 		uint64_t ld_cmd:2;
 		uint64_t iobit:1;
 		uint64_t rd_addr:48;
+#else
+		uint64_t rd_addr:48;
+		uint64_t iobit:1;
+		uint64_t ld_cmd:2;
+		uint64_t reserved_51_63:13;
+#endif
 	} s;
 	struct cvmx_npei_win_rd_addr_s cn52xx;
 	struct cvmx_npei_win_rd_addr_s cn52xxp1;
@@ -2419,7 +4135,11 @@
 union cvmx_npei_win_rd_data {
 	uint64_t u64;
 	struct cvmx_npei_win_rd_data_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t rd_data:64;
+#else
+		uint64_t rd_data:64;
+#endif
 	} s;
 	struct cvmx_npei_win_rd_data_s cn52xx;
 	struct cvmx_npei_win_rd_data_s cn52xxp1;
@@ -2430,10 +4150,17 @@
 union cvmx_npei_win_wr_addr {
 	uint64_t u64;
 	struct cvmx_npei_win_wr_addr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_49_63:15;
 		uint64_t iobit:1;
 		uint64_t wr_addr:46;
 		uint64_t reserved_0_1:2;
+#else
+		uint64_t reserved_0_1:2;
+		uint64_t wr_addr:46;
+		uint64_t iobit:1;
+		uint64_t reserved_49_63:15;
+#endif
 	} s;
 	struct cvmx_npei_win_wr_addr_s cn52xx;
 	struct cvmx_npei_win_wr_addr_s cn52xxp1;
@@ -2444,7 +4171,11 @@
 union cvmx_npei_win_wr_data {
 	uint64_t u64;
 	struct cvmx_npei_win_wr_data_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t wr_data:64;
+#else
+		uint64_t wr_data:64;
+#endif
 	} s;
 	struct cvmx_npei_win_wr_data_s cn52xx;
 	struct cvmx_npei_win_wr_data_s cn52xxp1;
@@ -2455,8 +4186,13 @@
 union cvmx_npei_win_wr_mask {
 	uint64_t u64;
 	struct cvmx_npei_win_wr_mask_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t wr_mask:8;
+#else
+		uint64_t wr_mask:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_npei_win_wr_mask_s cn52xx;
 	struct cvmx_npei_win_wr_mask_s cn52xxp1;
@@ -2467,8 +4203,13 @@
 union cvmx_npei_window_ctl {
 	uint64_t u64;
 	struct cvmx_npei_window_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t time:32;
+#else
+		uint64_t time:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_npei_window_ctl_s cn52xx;
 	struct cvmx_npei_window_ctl_s cn52xxp1;
diff --git a/arch/mips/include/asm/octeon/cvmx-npi-defs.h b/arch/mips/include/asm/octeon/cvmx-npi-defs.h
index f089c78..129bb25 100644
--- a/arch/mips/include/asm/octeon/cvmx-npi-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-npi-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -152,8 +152,13 @@
 union cvmx_npi_base_addr_inputx {
 	uint64_t u64;
 	struct cvmx_npi_base_addr_inputx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t baddr:61;
 		uint64_t reserved_0_2:3;
+#else
+		uint64_t reserved_0_2:3;
+		uint64_t baddr:61;
+#endif
 	} s;
 	struct cvmx_npi_base_addr_inputx_s cn30xx;
 	struct cvmx_npi_base_addr_inputx_s cn31xx;
@@ -167,8 +172,13 @@
 union cvmx_npi_base_addr_outputx {
 	uint64_t u64;
 	struct cvmx_npi_base_addr_outputx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t baddr:61;
 		uint64_t reserved_0_2:3;
+#else
+		uint64_t reserved_0_2:3;
+		uint64_t baddr:61;
+#endif
 	} s;
 	struct cvmx_npi_base_addr_outputx_s cn30xx;
 	struct cvmx_npi_base_addr_outputx_s cn31xx;
@@ -182,6 +192,7 @@
 union cvmx_npi_bist_status {
 	uint64_t u64;
 	struct cvmx_npi_bist_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t csr_bs:1;
 		uint64_t dif_bs:1;
@@ -203,8 +214,32 @@
 		uint64_t dob_bs:1;
 		uint64_t pdf_bs:1;
 		uint64_t dpi_bs:1;
+#else
+		uint64_t dpi_bs:1;
+		uint64_t pdf_bs:1;
+		uint64_t dob_bs:1;
+		uint64_t nus_bs:1;
+		uint64_t pos_bs:1;
+		uint64_t pof3_bs:1;
+		uint64_t pof2_bs:1;
+		uint64_t pof1_bs:1;
+		uint64_t pof0_bs:1;
+		uint64_t pig_bs:1;
+		uint64_t pgf_bs:1;
+		uint64_t rdnl_bs:1;
+		uint64_t pcad_bs:1;
+		uint64_t pcac_bs:1;
+		uint64_t rdn_bs:1;
+		uint64_t pcn_bs:1;
+		uint64_t pcnc_bs:1;
+		uint64_t rdp_bs:1;
+		uint64_t dif_bs:1;
+		uint64_t csr_bs:1;
+		uint64_t reserved_20_63:44;
+#endif
 	} s;
 	struct cvmx_npi_bist_status_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t csr_bs:1;
 		uint64_t dif_bs:1;
@@ -224,11 +259,33 @@
 		uint64_t dob_bs:1;
 		uint64_t pdf_bs:1;
 		uint64_t dpi_bs:1;
+#else
+		uint64_t dpi_bs:1;
+		uint64_t pdf_bs:1;
+		uint64_t dob_bs:1;
+		uint64_t nus_bs:1;
+		uint64_t pos_bs:1;
+		uint64_t reserved_5_7:3;
+		uint64_t pof0_bs:1;
+		uint64_t pig_bs:1;
+		uint64_t pgf_bs:1;
+		uint64_t rdnl_bs:1;
+		uint64_t pcad_bs:1;
+		uint64_t pcac_bs:1;
+		uint64_t rdn_bs:1;
+		uint64_t pcn_bs:1;
+		uint64_t pcnc_bs:1;
+		uint64_t rdp_bs:1;
+		uint64_t dif_bs:1;
+		uint64_t csr_bs:1;
+		uint64_t reserved_20_63:44;
+#endif
 	} cn30xx;
 	struct cvmx_npi_bist_status_s cn31xx;
 	struct cvmx_npi_bist_status_s cn38xx;
 	struct cvmx_npi_bist_status_s cn38xxp2;
 	struct cvmx_npi_bist_status_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t csr_bs:1;
 		uint64_t dif_bs:1;
@@ -249,6 +306,28 @@
 		uint64_t dob_bs:1;
 		uint64_t pdf_bs:1;
 		uint64_t dpi_bs:1;
+#else
+		uint64_t dpi_bs:1;
+		uint64_t pdf_bs:1;
+		uint64_t dob_bs:1;
+		uint64_t nus_bs:1;
+		uint64_t pos_bs:1;
+		uint64_t reserved_5_6:2;
+		uint64_t pof1_bs:1;
+		uint64_t pof0_bs:1;
+		uint64_t pig_bs:1;
+		uint64_t pgf_bs:1;
+		uint64_t rdnl_bs:1;
+		uint64_t pcad_bs:1;
+		uint64_t pcac_bs:1;
+		uint64_t rdn_bs:1;
+		uint64_t pcn_bs:1;
+		uint64_t pcnc_bs:1;
+		uint64_t rdp_bs:1;
+		uint64_t dif_bs:1;
+		uint64_t csr_bs:1;
+		uint64_t reserved_20_63:44;
+#endif
 	} cn50xx;
 	struct cvmx_npi_bist_status_s cn58xx;
 	struct cvmx_npi_bist_status_s cn58xxp1;
@@ -257,9 +336,15 @@
 union cvmx_npi_buff_size_outputx {
 	uint64_t u64;
 	struct cvmx_npi_buff_size_outputx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_23_63:41;
 		uint64_t isize:7;
 		uint64_t bsize:16;
+#else
+		uint64_t bsize:16;
+		uint64_t isize:7;
+		uint64_t reserved_23_63:41;
+#endif
 	} s;
 	struct cvmx_npi_buff_size_outputx_s cn30xx;
 	struct cvmx_npi_buff_size_outputx_s cn31xx;
@@ -273,9 +358,15 @@
 union cvmx_npi_comp_ctl {
 	uint64_t u64;
 	struct cvmx_npi_comp_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t pctl:5;
 		uint64_t nctl:5;
+#else
+		uint64_t nctl:5;
+		uint64_t pctl:5;
+		uint64_t reserved_10_63:54;
+#endif
 	} s;
 	struct cvmx_npi_comp_ctl_s cn50xx;
 	struct cvmx_npi_comp_ctl_s cn58xx;
@@ -285,6 +376,7 @@
 union cvmx_npi_ctl_status {
 	uint64_t u64;
 	struct cvmx_npi_ctl_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_63_63:1;
 		uint64_t chip_rev:8;
 		uint64_t dis_pniw:1;
@@ -306,8 +398,32 @@
 		uint64_t max_word:5;
 		uint64_t reserved_10_31:22;
 		uint64_t timer:10;
+#else
+		uint64_t timer:10;
+		uint64_t reserved_10_31:22;
+		uint64_t max_word:5;
+		uint64_t reserved_37_39:3;
+		uint64_t wait_com:1;
+		uint64_t pci_wdis:1;
+		uint64_t ins0_64b:1;
+		uint64_t ins1_64b:1;
+		uint64_t ins2_64b:1;
+		uint64_t ins3_64b:1;
+		uint64_t ins0_enb:1;
+		uint64_t ins1_enb:1;
+		uint64_t ins2_enb:1;
+		uint64_t ins3_enb:1;
+		uint64_t out0_enb:1;
+		uint64_t out1_enb:1;
+		uint64_t out2_enb:1;
+		uint64_t out3_enb:1;
+		uint64_t dis_pniw:1;
+		uint64_t chip_rev:8;
+		uint64_t reserved_63_63:1;
+#endif
 	} s;
 	struct cvmx_npi_ctl_status_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_63_63:1;
 		uint64_t chip_rev:8;
 		uint64_t dis_pniw:1;
@@ -323,8 +439,26 @@
 		uint64_t max_word:5;
 		uint64_t reserved_10_31:22;
 		uint64_t timer:10;
+#else
+		uint64_t timer:10;
+		uint64_t reserved_10_31:22;
+		uint64_t max_word:5;
+		uint64_t reserved_37_39:3;
+		uint64_t wait_com:1;
+		uint64_t pci_wdis:1;
+		uint64_t ins0_64b:1;
+		uint64_t reserved_43_45:3;
+		uint64_t ins0_enb:1;
+		uint64_t reserved_47_49:3;
+		uint64_t out0_enb:1;
+		uint64_t reserved_51_53:3;
+		uint64_t dis_pniw:1;
+		uint64_t chip_rev:8;
+		uint64_t reserved_63_63:1;
+#endif
 	} cn30xx;
 	struct cvmx_npi_ctl_status_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_63_63:1;
 		uint64_t chip_rev:8;
 		uint64_t dis_pniw:1;
@@ -343,6 +477,26 @@
 		uint64_t max_word:5;
 		uint64_t reserved_10_31:22;
 		uint64_t timer:10;
+#else
+		uint64_t timer:10;
+		uint64_t reserved_10_31:22;
+		uint64_t max_word:5;
+		uint64_t reserved_37_39:3;
+		uint64_t wait_com:1;
+		uint64_t pci_wdis:1;
+		uint64_t ins0_64b:1;
+		uint64_t ins1_64b:1;
+		uint64_t reserved_44_45:2;
+		uint64_t ins0_enb:1;
+		uint64_t ins1_enb:1;
+		uint64_t reserved_48_49:2;
+		uint64_t out0_enb:1;
+		uint64_t out1_enb:1;
+		uint64_t reserved_52_53:2;
+		uint64_t dis_pniw:1;
+		uint64_t chip_rev:8;
+		uint64_t reserved_63_63:1;
+#endif
 	} cn31xx;
 	struct cvmx_npi_ctl_status_s cn38xx;
 	struct cvmx_npi_ctl_status_s cn38xxp2;
@@ -354,8 +508,13 @@
 union cvmx_npi_dbg_select {
 	uint64_t u64;
 	struct cvmx_npi_dbg_select_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t dbg_sel:16;
+#else
+		uint64_t dbg_sel:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_npi_dbg_select_s cn30xx;
 	struct cvmx_npi_dbg_select_s cn31xx;
@@ -369,6 +528,7 @@
 union cvmx_npi_dma_control {
 	uint64_t u64;
 	struct cvmx_npi_dma_control_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_36_63:28;
 		uint64_t b0_lend:1;
 		uint64_t dwb_denb:1;
@@ -382,6 +542,21 @@
 		uint64_t hp_enb:1;
 		uint64_t lp_enb:1;
 		uint64_t csize:14;
+#else
+		uint64_t csize:14;
+		uint64_t lp_enb:1;
+		uint64_t hp_enb:1;
+		uint64_t o_mode:1;
+		uint64_t o_es:2;
+		uint64_t o_ns:1;
+		uint64_t o_ro:1;
+		uint64_t o_add1:1;
+		uint64_t fpa_que:3;
+		uint64_t dwb_ichk:9;
+		uint64_t dwb_denb:1;
+		uint64_t b0_lend:1;
+		uint64_t reserved_36_63:28;
+#endif
 	} s;
 	struct cvmx_npi_dma_control_s cn30xx;
 	struct cvmx_npi_dma_control_s cn31xx;
@@ -395,9 +570,15 @@
 union cvmx_npi_dma_highp_counts {
 	uint64_t u64;
 	struct cvmx_npi_dma_highp_counts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_39_63:25;
 		uint64_t fcnt:7;
 		uint64_t dbell:32;
+#else
+		uint64_t dbell:32;
+		uint64_t fcnt:7;
+		uint64_t reserved_39_63:25;
+#endif
 	} s;
 	struct cvmx_npi_dma_highp_counts_s cn30xx;
 	struct cvmx_npi_dma_highp_counts_s cn31xx;
@@ -411,9 +592,15 @@
 union cvmx_npi_dma_highp_naddr {
 	uint64_t u64;
 	struct cvmx_npi_dma_highp_naddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_40_63:24;
 		uint64_t state:4;
 		uint64_t addr:36;
+#else
+		uint64_t addr:36;
+		uint64_t state:4;
+		uint64_t reserved_40_63:24;
+#endif
 	} s;
 	struct cvmx_npi_dma_highp_naddr_s cn30xx;
 	struct cvmx_npi_dma_highp_naddr_s cn31xx;
@@ -427,9 +614,15 @@
 union cvmx_npi_dma_lowp_counts {
 	uint64_t u64;
 	struct cvmx_npi_dma_lowp_counts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_39_63:25;
 		uint64_t fcnt:7;
 		uint64_t dbell:32;
+#else
+		uint64_t dbell:32;
+		uint64_t fcnt:7;
+		uint64_t reserved_39_63:25;
+#endif
 	} s;
 	struct cvmx_npi_dma_lowp_counts_s cn30xx;
 	struct cvmx_npi_dma_lowp_counts_s cn31xx;
@@ -443,9 +636,15 @@
 union cvmx_npi_dma_lowp_naddr {
 	uint64_t u64;
 	struct cvmx_npi_dma_lowp_naddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_40_63:24;
 		uint64_t state:4;
 		uint64_t addr:36;
+#else
+		uint64_t addr:36;
+		uint64_t state:4;
+		uint64_t reserved_40_63:24;
+#endif
 	} s;
 	struct cvmx_npi_dma_lowp_naddr_s cn30xx;
 	struct cvmx_npi_dma_lowp_naddr_s cn31xx;
@@ -459,8 +658,13 @@
 union cvmx_npi_highp_dbell {
 	uint64_t u64;
 	struct cvmx_npi_highp_dbell_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t dbell:16;
+#else
+		uint64_t dbell:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_npi_highp_dbell_s cn30xx;
 	struct cvmx_npi_highp_dbell_s cn31xx;
@@ -474,8 +678,13 @@
 union cvmx_npi_highp_ibuff_saddr {
 	uint64_t u64;
 	struct cvmx_npi_highp_ibuff_saddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_36_63:28;
 		uint64_t saddr:36;
+#else
+		uint64_t saddr:36;
+		uint64_t reserved_36_63:28;
+#endif
 	} s;
 	struct cvmx_npi_highp_ibuff_saddr_s cn30xx;
 	struct cvmx_npi_highp_ibuff_saddr_s cn31xx;
@@ -489,6 +698,7 @@
 union cvmx_npi_input_control {
 	uint64_t u64;
 	struct cvmx_npi_input_control_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_23_63:41;
 		uint64_t pkt_rr:1;
 		uint64_t pbp_dhi:13;
@@ -499,8 +709,21 @@
 		uint64_t nsr:1;
 		uint64_t esr:2;
 		uint64_t ror:1;
+#else
+		uint64_t ror:1;
+		uint64_t esr:2;
+		uint64_t nsr:1;
+		uint64_t use_csr:1;
+		uint64_t d_ror:1;
+		uint64_t d_esr:2;
+		uint64_t d_nsr:1;
+		uint64_t pbp_dhi:13;
+		uint64_t pkt_rr:1;
+		uint64_t reserved_23_63:41;
+#endif
 	} s;
 	struct cvmx_npi_input_control_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_22_63:42;
 		uint64_t pbp_dhi:13;
 		uint64_t d_nsr:1;
@@ -510,6 +733,17 @@
 		uint64_t nsr:1;
 		uint64_t esr:2;
 		uint64_t ror:1;
+#else
+		uint64_t ror:1;
+		uint64_t esr:2;
+		uint64_t nsr:1;
+		uint64_t use_csr:1;
+		uint64_t d_ror:1;
+		uint64_t d_esr:2;
+		uint64_t d_nsr:1;
+		uint64_t pbp_dhi:13;
+		uint64_t reserved_22_63:42;
+#endif
 	} cn30xx;
 	struct cvmx_npi_input_control_cn30xx cn31xx;
 	struct cvmx_npi_input_control_s cn38xx;
@@ -522,6 +756,7 @@
 union cvmx_npi_int_enb {
 	uint64_t u64;
 	struct cvmx_npi_int_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_62_63:2;
 		uint64_t q1_a_f:1;
 		uint64_t q1_s_e:1;
@@ -585,8 +820,74 @@
 		uint64_t pci_rsl:1;
 		uint64_t rml_wto:1;
 		uint64_t rml_rto:1;
+#else
+		uint64_t rml_rto:1;
+		uint64_t rml_wto:1;
+		uint64_t pci_rsl:1;
+		uint64_t po0_2sml:1;
+		uint64_t po1_2sml:1;
+		uint64_t po2_2sml:1;
+		uint64_t po3_2sml:1;
+		uint64_t i0_rtout:1;
+		uint64_t i1_rtout:1;
+		uint64_t i2_rtout:1;
+		uint64_t i3_rtout:1;
+		uint64_t i0_overf:1;
+		uint64_t i1_overf:1;
+		uint64_t i2_overf:1;
+		uint64_t i3_overf:1;
+		uint64_t p0_rtout:1;
+		uint64_t p1_rtout:1;
+		uint64_t p2_rtout:1;
+		uint64_t p3_rtout:1;
+		uint64_t p0_perr:1;
+		uint64_t p1_perr:1;
+		uint64_t p2_perr:1;
+		uint64_t p3_perr:1;
+		uint64_t g0_rtout:1;
+		uint64_t g1_rtout:1;
+		uint64_t g2_rtout:1;
+		uint64_t g3_rtout:1;
+		uint64_t p0_pperr:1;
+		uint64_t p1_pperr:1;
+		uint64_t p2_pperr:1;
+		uint64_t p3_pperr:1;
+		uint64_t p0_ptout:1;
+		uint64_t p1_ptout:1;
+		uint64_t p2_ptout:1;
+		uint64_t p3_ptout:1;
+		uint64_t i0_pperr:1;
+		uint64_t i1_pperr:1;
+		uint64_t i2_pperr:1;
+		uint64_t i3_pperr:1;
+		uint64_t win_rto:1;
+		uint64_t p_dperr:1;
+		uint64_t iobdma:1;
+		uint64_t fcr_s_e:1;
+		uint64_t fcr_a_f:1;
+		uint64_t pcr_s_e:1;
+		uint64_t pcr_a_f:1;
+		uint64_t q2_s_e:1;
+		uint64_t q2_a_f:1;
+		uint64_t q3_s_e:1;
+		uint64_t q3_a_f:1;
+		uint64_t com_s_e:1;
+		uint64_t com_a_f:1;
+		uint64_t pnc_s_e:1;
+		uint64_t pnc_a_f:1;
+		uint64_t rwx_s_e:1;
+		uint64_t rdx_s_e:1;
+		uint64_t pcf_p_e:1;
+		uint64_t pcf_p_f:1;
+		uint64_t pdf_p_e:1;
+		uint64_t pdf_p_f:1;
+		uint64_t q1_s_e:1;
+		uint64_t q1_a_f:1;
+		uint64_t reserved_62_63:2;
+#endif
 	} s;
 	struct cvmx_npi_int_enb_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_62_63:2;
 		uint64_t q1_a_f:1;
 		uint64_t q1_s_e:1;
@@ -632,8 +933,56 @@
 		uint64_t pci_rsl:1;
 		uint64_t rml_wto:1;
 		uint64_t rml_rto:1;
+#else
+		uint64_t rml_rto:1;
+		uint64_t rml_wto:1;
+		uint64_t pci_rsl:1;
+		uint64_t po0_2sml:1;
+		uint64_t reserved_4_6:3;
+		uint64_t i0_rtout:1;
+		uint64_t reserved_8_10:3;
+		uint64_t i0_overf:1;
+		uint64_t reserved_12_14:3;
+		uint64_t p0_rtout:1;
+		uint64_t reserved_16_18:3;
+		uint64_t p0_perr:1;
+		uint64_t reserved_20_22:3;
+		uint64_t g0_rtout:1;
+		uint64_t reserved_24_26:3;
+		uint64_t p0_pperr:1;
+		uint64_t reserved_28_30:3;
+		uint64_t p0_ptout:1;
+		uint64_t reserved_32_34:3;
+		uint64_t i0_pperr:1;
+		uint64_t reserved_36_38:3;
+		uint64_t win_rto:1;
+		uint64_t p_dperr:1;
+		uint64_t iobdma:1;
+		uint64_t fcr_s_e:1;
+		uint64_t fcr_a_f:1;
+		uint64_t pcr_s_e:1;
+		uint64_t pcr_a_f:1;
+		uint64_t q2_s_e:1;
+		uint64_t q2_a_f:1;
+		uint64_t q3_s_e:1;
+		uint64_t q3_a_f:1;
+		uint64_t com_s_e:1;
+		uint64_t com_a_f:1;
+		uint64_t pnc_s_e:1;
+		uint64_t pnc_a_f:1;
+		uint64_t rwx_s_e:1;
+		uint64_t rdx_s_e:1;
+		uint64_t pcf_p_e:1;
+		uint64_t pcf_p_f:1;
+		uint64_t pdf_p_e:1;
+		uint64_t pdf_p_f:1;
+		uint64_t q1_s_e:1;
+		uint64_t q1_a_f:1;
+		uint64_t reserved_62_63:2;
+#endif
 	} cn30xx;
 	struct cvmx_npi_int_enb_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_62_63:2;
 		uint64_t q1_a_f:1;
 		uint64_t q1_s_e:1;
@@ -688,9 +1037,66 @@
 		uint64_t pci_rsl:1;
 		uint64_t rml_wto:1;
 		uint64_t rml_rto:1;
+#else
+		uint64_t rml_rto:1;
+		uint64_t rml_wto:1;
+		uint64_t pci_rsl:1;
+		uint64_t po0_2sml:1;
+		uint64_t po1_2sml:1;
+		uint64_t reserved_5_6:2;
+		uint64_t i0_rtout:1;
+		uint64_t i1_rtout:1;
+		uint64_t reserved_9_10:2;
+		uint64_t i0_overf:1;
+		uint64_t i1_overf:1;
+		uint64_t reserved_13_14:2;
+		uint64_t p0_rtout:1;
+		uint64_t p1_rtout:1;
+		uint64_t reserved_17_18:2;
+		uint64_t p0_perr:1;
+		uint64_t p1_perr:1;
+		uint64_t reserved_21_22:2;
+		uint64_t g0_rtout:1;
+		uint64_t g1_rtout:1;
+		uint64_t reserved_25_26:2;
+		uint64_t p0_pperr:1;
+		uint64_t p1_pperr:1;
+		uint64_t reserved_29_30:2;
+		uint64_t p0_ptout:1;
+		uint64_t p1_ptout:1;
+		uint64_t reserved_33_34:2;
+		uint64_t i0_pperr:1;
+		uint64_t i1_pperr:1;
+		uint64_t reserved_37_38:2;
+		uint64_t win_rto:1;
+		uint64_t p_dperr:1;
+		uint64_t iobdma:1;
+		uint64_t fcr_s_e:1;
+		uint64_t fcr_a_f:1;
+		uint64_t pcr_s_e:1;
+		uint64_t pcr_a_f:1;
+		uint64_t q2_s_e:1;
+		uint64_t q2_a_f:1;
+		uint64_t q3_s_e:1;
+		uint64_t q3_a_f:1;
+		uint64_t com_s_e:1;
+		uint64_t com_a_f:1;
+		uint64_t pnc_s_e:1;
+		uint64_t pnc_a_f:1;
+		uint64_t rwx_s_e:1;
+		uint64_t rdx_s_e:1;
+		uint64_t pcf_p_e:1;
+		uint64_t pcf_p_f:1;
+		uint64_t pdf_p_e:1;
+		uint64_t pdf_p_f:1;
+		uint64_t q1_s_e:1;
+		uint64_t q1_a_f:1;
+		uint64_t reserved_62_63:2;
+#endif
 	} cn31xx;
 	struct cvmx_npi_int_enb_s cn38xx;
 	struct cvmx_npi_int_enb_cn38xxp2 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_42_63:22;
 		uint64_t iobdma:1;
 		uint64_t p_dperr:1;
@@ -734,6 +1140,51 @@
 		uint64_t pci_rsl:1;
 		uint64_t rml_wto:1;
 		uint64_t rml_rto:1;
+#else
+		uint64_t rml_rto:1;
+		uint64_t rml_wto:1;
+		uint64_t pci_rsl:1;
+		uint64_t po0_2sml:1;
+		uint64_t po1_2sml:1;
+		uint64_t po2_2sml:1;
+		uint64_t po3_2sml:1;
+		uint64_t i0_rtout:1;
+		uint64_t i1_rtout:1;
+		uint64_t i2_rtout:1;
+		uint64_t i3_rtout:1;
+		uint64_t i0_overf:1;
+		uint64_t i1_overf:1;
+		uint64_t i2_overf:1;
+		uint64_t i3_overf:1;
+		uint64_t p0_rtout:1;
+		uint64_t p1_rtout:1;
+		uint64_t p2_rtout:1;
+		uint64_t p3_rtout:1;
+		uint64_t p0_perr:1;
+		uint64_t p1_perr:1;
+		uint64_t p2_perr:1;
+		uint64_t p3_perr:1;
+		uint64_t g0_rtout:1;
+		uint64_t g1_rtout:1;
+		uint64_t g2_rtout:1;
+		uint64_t g3_rtout:1;
+		uint64_t p0_pperr:1;
+		uint64_t p1_pperr:1;
+		uint64_t p2_pperr:1;
+		uint64_t p3_pperr:1;
+		uint64_t p0_ptout:1;
+		uint64_t p1_ptout:1;
+		uint64_t p2_ptout:1;
+		uint64_t p3_ptout:1;
+		uint64_t i0_pperr:1;
+		uint64_t i1_pperr:1;
+		uint64_t i2_pperr:1;
+		uint64_t i3_pperr:1;
+		uint64_t win_rto:1;
+		uint64_t p_dperr:1;
+		uint64_t iobdma:1;
+		uint64_t reserved_42_63:22;
+#endif
 	} cn38xxp2;
 	struct cvmx_npi_int_enb_cn31xx cn50xx;
 	struct cvmx_npi_int_enb_s cn58xx;
@@ -743,6 +1194,7 @@
 union cvmx_npi_int_sum {
 	uint64_t u64;
 	struct cvmx_npi_int_sum_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_62_63:2;
 		uint64_t q1_a_f:1;
 		uint64_t q1_s_e:1;
@@ -806,8 +1258,74 @@
 		uint64_t pci_rsl:1;
 		uint64_t rml_wto:1;
 		uint64_t rml_rto:1;
+#else
+		uint64_t rml_rto:1;
+		uint64_t rml_wto:1;
+		uint64_t pci_rsl:1;
+		uint64_t po0_2sml:1;
+		uint64_t po1_2sml:1;
+		uint64_t po2_2sml:1;
+		uint64_t po3_2sml:1;
+		uint64_t i0_rtout:1;
+		uint64_t i1_rtout:1;
+		uint64_t i2_rtout:1;
+		uint64_t i3_rtout:1;
+		uint64_t i0_overf:1;
+		uint64_t i1_overf:1;
+		uint64_t i2_overf:1;
+		uint64_t i3_overf:1;
+		uint64_t p0_rtout:1;
+		uint64_t p1_rtout:1;
+		uint64_t p2_rtout:1;
+		uint64_t p3_rtout:1;
+		uint64_t p0_perr:1;
+		uint64_t p1_perr:1;
+		uint64_t p2_perr:1;
+		uint64_t p3_perr:1;
+		uint64_t g0_rtout:1;
+		uint64_t g1_rtout:1;
+		uint64_t g2_rtout:1;
+		uint64_t g3_rtout:1;
+		uint64_t p0_pperr:1;
+		uint64_t p1_pperr:1;
+		uint64_t p2_pperr:1;
+		uint64_t p3_pperr:1;
+		uint64_t p0_ptout:1;
+		uint64_t p1_ptout:1;
+		uint64_t p2_ptout:1;
+		uint64_t p3_ptout:1;
+		uint64_t i0_pperr:1;
+		uint64_t i1_pperr:1;
+		uint64_t i2_pperr:1;
+		uint64_t i3_pperr:1;
+		uint64_t win_rto:1;
+		uint64_t p_dperr:1;
+		uint64_t iobdma:1;
+		uint64_t fcr_s_e:1;
+		uint64_t fcr_a_f:1;
+		uint64_t pcr_s_e:1;
+		uint64_t pcr_a_f:1;
+		uint64_t q2_s_e:1;
+		uint64_t q2_a_f:1;
+		uint64_t q3_s_e:1;
+		uint64_t q3_a_f:1;
+		uint64_t com_s_e:1;
+		uint64_t com_a_f:1;
+		uint64_t pnc_s_e:1;
+		uint64_t pnc_a_f:1;
+		uint64_t rwx_s_e:1;
+		uint64_t rdx_s_e:1;
+		uint64_t pcf_p_e:1;
+		uint64_t pcf_p_f:1;
+		uint64_t pdf_p_e:1;
+		uint64_t pdf_p_f:1;
+		uint64_t q1_s_e:1;
+		uint64_t q1_a_f:1;
+		uint64_t reserved_62_63:2;
+#endif
 	} s;
 	struct cvmx_npi_int_sum_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_62_63:2;
 		uint64_t q1_a_f:1;
 		uint64_t q1_s_e:1;
@@ -853,8 +1371,56 @@
 		uint64_t pci_rsl:1;
 		uint64_t rml_wto:1;
 		uint64_t rml_rto:1;
+#else
+		uint64_t rml_rto:1;
+		uint64_t rml_wto:1;
+		uint64_t pci_rsl:1;
+		uint64_t po0_2sml:1;
+		uint64_t reserved_4_6:3;
+		uint64_t i0_rtout:1;
+		uint64_t reserved_8_10:3;
+		uint64_t i0_overf:1;
+		uint64_t reserved_12_14:3;
+		uint64_t p0_rtout:1;
+		uint64_t reserved_16_18:3;
+		uint64_t p0_perr:1;
+		uint64_t reserved_20_22:3;
+		uint64_t g0_rtout:1;
+		uint64_t reserved_24_26:3;
+		uint64_t p0_pperr:1;
+		uint64_t reserved_28_30:3;
+		uint64_t p0_ptout:1;
+		uint64_t reserved_32_34:3;
+		uint64_t i0_pperr:1;
+		uint64_t reserved_36_38:3;
+		uint64_t win_rto:1;
+		uint64_t p_dperr:1;
+		uint64_t iobdma:1;
+		uint64_t fcr_s_e:1;
+		uint64_t fcr_a_f:1;
+		uint64_t pcr_s_e:1;
+		uint64_t pcr_a_f:1;
+		uint64_t q2_s_e:1;
+		uint64_t q2_a_f:1;
+		uint64_t q3_s_e:1;
+		uint64_t q3_a_f:1;
+		uint64_t com_s_e:1;
+		uint64_t com_a_f:1;
+		uint64_t pnc_s_e:1;
+		uint64_t pnc_a_f:1;
+		uint64_t rwx_s_e:1;
+		uint64_t rdx_s_e:1;
+		uint64_t pcf_p_e:1;
+		uint64_t pcf_p_f:1;
+		uint64_t pdf_p_e:1;
+		uint64_t pdf_p_f:1;
+		uint64_t q1_s_e:1;
+		uint64_t q1_a_f:1;
+		uint64_t reserved_62_63:2;
+#endif
 	} cn30xx;
 	struct cvmx_npi_int_sum_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_62_63:2;
 		uint64_t q1_a_f:1;
 		uint64_t q1_s_e:1;
@@ -909,9 +1475,66 @@
 		uint64_t pci_rsl:1;
 		uint64_t rml_wto:1;
 		uint64_t rml_rto:1;
+#else
+		uint64_t rml_rto:1;
+		uint64_t rml_wto:1;
+		uint64_t pci_rsl:1;
+		uint64_t po0_2sml:1;
+		uint64_t po1_2sml:1;
+		uint64_t reserved_5_6:2;
+		uint64_t i0_rtout:1;
+		uint64_t i1_rtout:1;
+		uint64_t reserved_9_10:2;
+		uint64_t i0_overf:1;
+		uint64_t i1_overf:1;
+		uint64_t reserved_13_14:2;
+		uint64_t p0_rtout:1;
+		uint64_t p1_rtout:1;
+		uint64_t reserved_17_18:2;
+		uint64_t p0_perr:1;
+		uint64_t p1_perr:1;
+		uint64_t reserved_21_22:2;
+		uint64_t g0_rtout:1;
+		uint64_t g1_rtout:1;
+		uint64_t reserved_25_26:2;
+		uint64_t p0_pperr:1;
+		uint64_t p1_pperr:1;
+		uint64_t reserved_29_30:2;
+		uint64_t p0_ptout:1;
+		uint64_t p1_ptout:1;
+		uint64_t reserved_33_34:2;
+		uint64_t i0_pperr:1;
+		uint64_t i1_pperr:1;
+		uint64_t reserved_37_38:2;
+		uint64_t win_rto:1;
+		uint64_t p_dperr:1;
+		uint64_t iobdma:1;
+		uint64_t fcr_s_e:1;
+		uint64_t fcr_a_f:1;
+		uint64_t pcr_s_e:1;
+		uint64_t pcr_a_f:1;
+		uint64_t q2_s_e:1;
+		uint64_t q2_a_f:1;
+		uint64_t q3_s_e:1;
+		uint64_t q3_a_f:1;
+		uint64_t com_s_e:1;
+		uint64_t com_a_f:1;
+		uint64_t pnc_s_e:1;
+		uint64_t pnc_a_f:1;
+		uint64_t rwx_s_e:1;
+		uint64_t rdx_s_e:1;
+		uint64_t pcf_p_e:1;
+		uint64_t pcf_p_f:1;
+		uint64_t pdf_p_e:1;
+		uint64_t pdf_p_f:1;
+		uint64_t q1_s_e:1;
+		uint64_t q1_a_f:1;
+		uint64_t reserved_62_63:2;
+#endif
 	} cn31xx;
 	struct cvmx_npi_int_sum_s cn38xx;
 	struct cvmx_npi_int_sum_cn38xxp2 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_42_63:22;
 		uint64_t iobdma:1;
 		uint64_t p_dperr:1;
@@ -955,6 +1578,51 @@
 		uint64_t pci_rsl:1;
 		uint64_t rml_wto:1;
 		uint64_t rml_rto:1;
+#else
+		uint64_t rml_rto:1;
+		uint64_t rml_wto:1;
+		uint64_t pci_rsl:1;
+		uint64_t po0_2sml:1;
+		uint64_t po1_2sml:1;
+		uint64_t po2_2sml:1;
+		uint64_t po3_2sml:1;
+		uint64_t i0_rtout:1;
+		uint64_t i1_rtout:1;
+		uint64_t i2_rtout:1;
+		uint64_t i3_rtout:1;
+		uint64_t i0_overf:1;
+		uint64_t i1_overf:1;
+		uint64_t i2_overf:1;
+		uint64_t i3_overf:1;
+		uint64_t p0_rtout:1;
+		uint64_t p1_rtout:1;
+		uint64_t p2_rtout:1;
+		uint64_t p3_rtout:1;
+		uint64_t p0_perr:1;
+		uint64_t p1_perr:1;
+		uint64_t p2_perr:1;
+		uint64_t p3_perr:1;
+		uint64_t g0_rtout:1;
+		uint64_t g1_rtout:1;
+		uint64_t g2_rtout:1;
+		uint64_t g3_rtout:1;
+		uint64_t p0_pperr:1;
+		uint64_t p1_pperr:1;
+		uint64_t p2_pperr:1;
+		uint64_t p3_pperr:1;
+		uint64_t p0_ptout:1;
+		uint64_t p1_ptout:1;
+		uint64_t p2_ptout:1;
+		uint64_t p3_ptout:1;
+		uint64_t i0_pperr:1;
+		uint64_t i1_pperr:1;
+		uint64_t i2_pperr:1;
+		uint64_t i3_pperr:1;
+		uint64_t win_rto:1;
+		uint64_t p_dperr:1;
+		uint64_t iobdma:1;
+		uint64_t reserved_42_63:22;
+#endif
 	} cn38xxp2;
 	struct cvmx_npi_int_sum_cn31xx cn50xx;
 	struct cvmx_npi_int_sum_s cn58xx;
@@ -964,8 +1632,13 @@
 union cvmx_npi_lowp_dbell {
 	uint64_t u64;
 	struct cvmx_npi_lowp_dbell_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t dbell:16;
+#else
+		uint64_t dbell:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_npi_lowp_dbell_s cn30xx;
 	struct cvmx_npi_lowp_dbell_s cn31xx;
@@ -979,8 +1652,13 @@
 union cvmx_npi_lowp_ibuff_saddr {
 	uint64_t u64;
 	struct cvmx_npi_lowp_ibuff_saddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_36_63:28;
 		uint64_t saddr:36;
+#else
+		uint64_t saddr:36;
+		uint64_t reserved_36_63:28;
+#endif
 	} s;
 	struct cvmx_npi_lowp_ibuff_saddr_s cn30xx;
 	struct cvmx_npi_lowp_ibuff_saddr_s cn31xx;
@@ -994,6 +1672,7 @@
 union cvmx_npi_mem_access_subidx {
 	uint64_t u64;
 	struct cvmx_npi_mem_access_subidx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_38_63:26;
 		uint64_t shortl:1;
 		uint64_t nmerge:1;
@@ -1004,9 +1683,22 @@
 		uint64_t ror:1;
 		uint64_t row:1;
 		uint64_t ba:28;
+#else
+		uint64_t ba:28;
+		uint64_t row:1;
+		uint64_t ror:1;
+		uint64_t nsw:1;
+		uint64_t nsr:1;
+		uint64_t esw:2;
+		uint64_t esr:2;
+		uint64_t nmerge:1;
+		uint64_t shortl:1;
+		uint64_t reserved_38_63:26;
+#endif
 	} s;
 	struct cvmx_npi_mem_access_subidx_s cn30xx;
 	struct cvmx_npi_mem_access_subidx_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_36_63:28;
 		uint64_t esr:2;
 		uint64_t esw:2;
@@ -1015,6 +1707,16 @@
 		uint64_t ror:1;
 		uint64_t row:1;
 		uint64_t ba:28;
+#else
+		uint64_t ba:28;
+		uint64_t row:1;
+		uint64_t ror:1;
+		uint64_t nsw:1;
+		uint64_t nsr:1;
+		uint64_t esw:2;
+		uint64_t esr:2;
+		uint64_t reserved_36_63:28;
+#endif
 	} cn31xx;
 	struct cvmx_npi_mem_access_subidx_s cn38xx;
 	struct cvmx_npi_mem_access_subidx_cn31xx cn38xxp2;
@@ -1026,7 +1728,11 @@
 union cvmx_npi_msi_rcv {
 	uint64_t u64;
 	struct cvmx_npi_msi_rcv_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t int_vec:64;
+#else
+		uint64_t int_vec:64;
+#endif
 	} s;
 	struct cvmx_npi_msi_rcv_s cn30xx;
 	struct cvmx_npi_msi_rcv_s cn31xx;
@@ -1040,8 +1746,13 @@
 union cvmx_npi_num_desc_outputx {
 	uint64_t u64;
 	struct cvmx_npi_num_desc_outputx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t size:32;
+#else
+		uint64_t size:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_npi_num_desc_outputx_s cn30xx;
 	struct cvmx_npi_num_desc_outputx_s cn31xx;
@@ -1055,6 +1766,7 @@
 union cvmx_npi_output_control {
 	uint64_t u64;
 	struct cvmx_npi_output_control_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_49_63:15;
 		uint64_t pkt_rr:1;
 		uint64_t p3_bmode:1;
@@ -1094,8 +1806,50 @@
 		uint64_t esr_sl0:2;
 		uint64_t nsr_sl0:1;
 		uint64_t ror_sl0:1;
+#else
+		uint64_t ror_sl0:1;
+		uint64_t nsr_sl0:1;
+		uint64_t esr_sl0:2;
+		uint64_t ror_sl1:1;
+		uint64_t nsr_sl1:1;
+		uint64_t esr_sl1:2;
+		uint64_t ror_sl2:1;
+		uint64_t nsr_sl2:1;
+		uint64_t esr_sl2:2;
+		uint64_t ror_sl3:1;
+		uint64_t nsr_sl3:1;
+		uint64_t esr_sl3:2;
+		uint64_t iptr_o0:1;
+		uint64_t iptr_o1:1;
+		uint64_t iptr_o2:1;
+		uint64_t iptr_o3:1;
+		uint64_t reserved_20_23:4;
+		uint64_t o0_csrm:1;
+		uint64_t o1_csrm:1;
+		uint64_t o2_csrm:1;
+		uint64_t o3_csrm:1;
+		uint64_t o0_ro:1;
+		uint64_t o0_ns:1;
+		uint64_t o0_es:2;
+		uint64_t o1_ro:1;
+		uint64_t o1_ns:1;
+		uint64_t o1_es:2;
+		uint64_t o2_ro:1;
+		uint64_t o2_ns:1;
+		uint64_t o2_es:2;
+		uint64_t o3_ro:1;
+		uint64_t o3_ns:1;
+		uint64_t o3_es:2;
+		uint64_t p0_bmode:1;
+		uint64_t p1_bmode:1;
+		uint64_t p2_bmode:1;
+		uint64_t p3_bmode:1;
+		uint64_t pkt_rr:1;
+		uint64_t reserved_49_63:15;
+#endif
 	} s;
 	struct cvmx_npi_output_control_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_45_63:19;
 		uint64_t p0_bmode:1;
 		uint64_t reserved_32_43:12;
@@ -1110,8 +1864,25 @@
 		uint64_t esr_sl0:2;
 		uint64_t nsr_sl0:1;
 		uint64_t ror_sl0:1;
+#else
+		uint64_t ror_sl0:1;
+		uint64_t nsr_sl0:1;
+		uint64_t esr_sl0:2;
+		uint64_t reserved_4_15:12;
+		uint64_t iptr_o0:1;
+		uint64_t reserved_17_23:7;
+		uint64_t o0_csrm:1;
+		uint64_t reserved_25_27:3;
+		uint64_t o0_ro:1;
+		uint64_t o0_ns:1;
+		uint64_t o0_es:2;
+		uint64_t reserved_32_43:12;
+		uint64_t p0_bmode:1;
+		uint64_t reserved_45_63:19;
+#endif
 	} cn30xx;
 	struct cvmx_npi_output_control_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_46_63:18;
 		uint64_t p1_bmode:1;
 		uint64_t p0_bmode:1;
@@ -1135,9 +1906,35 @@
 		uint64_t esr_sl0:2;
 		uint64_t nsr_sl0:1;
 		uint64_t ror_sl0:1;
+#else
+		uint64_t ror_sl0:1;
+		uint64_t nsr_sl0:1;
+		uint64_t esr_sl0:2;
+		uint64_t ror_sl1:1;
+		uint64_t nsr_sl1:1;
+		uint64_t esr_sl1:2;
+		uint64_t reserved_8_15:8;
+		uint64_t iptr_o0:1;
+		uint64_t iptr_o1:1;
+		uint64_t reserved_18_23:6;
+		uint64_t o0_csrm:1;
+		uint64_t o1_csrm:1;
+		uint64_t reserved_26_27:2;
+		uint64_t o0_ro:1;
+		uint64_t o0_ns:1;
+		uint64_t o0_es:2;
+		uint64_t o1_ro:1;
+		uint64_t o1_ns:1;
+		uint64_t o1_es:2;
+		uint64_t reserved_36_43:8;
+		uint64_t p0_bmode:1;
+		uint64_t p1_bmode:1;
+		uint64_t reserved_46_63:18;
+#endif
 	} cn31xx;
 	struct cvmx_npi_output_control_s cn38xx;
 	struct cvmx_npi_output_control_cn38xxp2 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t p3_bmode:1;
 		uint64_t p2_bmode:1;
@@ -1176,8 +1973,49 @@
 		uint64_t esr_sl0:2;
 		uint64_t nsr_sl0:1;
 		uint64_t ror_sl0:1;
+#else
+		uint64_t ror_sl0:1;
+		uint64_t nsr_sl0:1;
+		uint64_t esr_sl0:2;
+		uint64_t ror_sl1:1;
+		uint64_t nsr_sl1:1;
+		uint64_t esr_sl1:2;
+		uint64_t ror_sl2:1;
+		uint64_t nsr_sl2:1;
+		uint64_t esr_sl2:2;
+		uint64_t ror_sl3:1;
+		uint64_t nsr_sl3:1;
+		uint64_t esr_sl3:2;
+		uint64_t iptr_o0:1;
+		uint64_t iptr_o1:1;
+		uint64_t iptr_o2:1;
+		uint64_t iptr_o3:1;
+		uint64_t reserved_20_23:4;
+		uint64_t o0_csrm:1;
+		uint64_t o1_csrm:1;
+		uint64_t o2_csrm:1;
+		uint64_t o3_csrm:1;
+		uint64_t o0_ro:1;
+		uint64_t o0_ns:1;
+		uint64_t o0_es:2;
+		uint64_t o1_ro:1;
+		uint64_t o1_ns:1;
+		uint64_t o1_es:2;
+		uint64_t o2_ro:1;
+		uint64_t o2_ns:1;
+		uint64_t o2_es:2;
+		uint64_t o3_ro:1;
+		uint64_t o3_ns:1;
+		uint64_t o3_es:2;
+		uint64_t p0_bmode:1;
+		uint64_t p1_bmode:1;
+		uint64_t p2_bmode:1;
+		uint64_t p3_bmode:1;
+		uint64_t reserved_48_63:16;
+#endif
 	} cn38xxp2;
 	struct cvmx_npi_output_control_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_49_63:15;
 		uint64_t pkt_rr:1;
 		uint64_t reserved_46_47:2;
@@ -1203,6 +2041,33 @@
 		uint64_t esr_sl0:2;
 		uint64_t nsr_sl0:1;
 		uint64_t ror_sl0:1;
+#else
+		uint64_t ror_sl0:1;
+		uint64_t nsr_sl0:1;
+		uint64_t esr_sl0:2;
+		uint64_t ror_sl1:1;
+		uint64_t nsr_sl1:1;
+		uint64_t esr_sl1:2;
+		uint64_t reserved_8_15:8;
+		uint64_t iptr_o0:1;
+		uint64_t iptr_o1:1;
+		uint64_t reserved_18_23:6;
+		uint64_t o0_csrm:1;
+		uint64_t o1_csrm:1;
+		uint64_t reserved_26_27:2;
+		uint64_t o0_ro:1;
+		uint64_t o0_ns:1;
+		uint64_t o0_es:2;
+		uint64_t o1_ro:1;
+		uint64_t o1_ns:1;
+		uint64_t o1_es:2;
+		uint64_t reserved_36_43:8;
+		uint64_t p0_bmode:1;
+		uint64_t p1_bmode:1;
+		uint64_t reserved_46_47:2;
+		uint64_t pkt_rr:1;
+		uint64_t reserved_49_63:15;
+#endif
 	} cn50xx;
 	struct cvmx_npi_output_control_s cn58xx;
 	struct cvmx_npi_output_control_s cn58xxp1;
@@ -1211,9 +2076,15 @@
 union cvmx_npi_px_dbpair_addr {
 	uint64_t u64;
 	struct cvmx_npi_px_dbpair_addr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_63_63:1;
 		uint64_t state:2;
 		uint64_t naddr:61;
+#else
+		uint64_t naddr:61;
+		uint64_t state:2;
+		uint64_t reserved_63_63:1;
+#endif
 	} s;
 	struct cvmx_npi_px_dbpair_addr_s cn30xx;
 	struct cvmx_npi_px_dbpair_addr_s cn31xx;
@@ -1227,8 +2098,13 @@
 union cvmx_npi_px_instr_addr {
 	uint64_t u64;
 	struct cvmx_npi_px_instr_addr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t state:3;
 		uint64_t naddr:61;
+#else
+		uint64_t naddr:61;
+		uint64_t state:3;
+#endif
 	} s;
 	struct cvmx_npi_px_instr_addr_s cn30xx;
 	struct cvmx_npi_px_instr_addr_s cn31xx;
@@ -1242,9 +2118,15 @@
 union cvmx_npi_px_instr_cnts {
 	uint64_t u64;
 	struct cvmx_npi_px_instr_cnts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_38_63:26;
 		uint64_t fcnt:6;
 		uint64_t avail:32;
+#else
+		uint64_t avail:32;
+		uint64_t fcnt:6;
+		uint64_t reserved_38_63:26;
+#endif
 	} s;
 	struct cvmx_npi_px_instr_cnts_s cn30xx;
 	struct cvmx_npi_px_instr_cnts_s cn31xx;
@@ -1258,9 +2140,15 @@
 union cvmx_npi_px_pair_cnts {
 	uint64_t u64;
 	struct cvmx_npi_px_pair_cnts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_37_63:27;
 		uint64_t fcnt:5;
 		uint64_t avail:32;
+#else
+		uint64_t avail:32;
+		uint64_t fcnt:5;
+		uint64_t reserved_37_63:27;
+#endif
 	} s;
 	struct cvmx_npi_px_pair_cnts_s cn30xx;
 	struct cvmx_npi_px_pair_cnts_s cn31xx;
@@ -1274,9 +2162,15 @@
 union cvmx_npi_pci_burst_size {
 	uint64_t u64;
 	struct cvmx_npi_pci_burst_size_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_14_63:50;
 		uint64_t wr_brst:7;
 		uint64_t rd_brst:7;
+#else
+		uint64_t rd_brst:7;
+		uint64_t wr_brst:7;
+		uint64_t reserved_14_63:50;
+#endif
 	} s;
 	struct cvmx_npi_pci_burst_size_s cn30xx;
 	struct cvmx_npi_pci_burst_size_s cn31xx;
@@ -1290,6 +2184,7 @@
 union cvmx_npi_pci_int_arb_cfg {
 	uint64_t u64;
 	struct cvmx_npi_pci_int_arb_cfg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_13_63:51;
 		uint64_t hostmode:1;
 		uint64_t pci_ovr:4;
@@ -1297,12 +2192,28 @@
 		uint64_t en:1;
 		uint64_t park_mod:1;
 		uint64_t park_dev:3;
+#else
+		uint64_t park_dev:3;
+		uint64_t park_mod:1;
+		uint64_t en:1;
+		uint64_t reserved_5_7:3;
+		uint64_t pci_ovr:4;
+		uint64_t hostmode:1;
+		uint64_t reserved_13_63:51;
+#endif
 	} s;
 	struct cvmx_npi_pci_int_arb_cfg_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t en:1;
 		uint64_t park_mod:1;
 		uint64_t park_dev:3;
+#else
+		uint64_t park_dev:3;
+		uint64_t park_mod:1;
+		uint64_t en:1;
+		uint64_t reserved_5_63:59;
+#endif
 	} cn30xx;
 	struct cvmx_npi_pci_int_arb_cfg_cn30xx cn31xx;
 	struct cvmx_npi_pci_int_arb_cfg_cn30xx cn38xx;
@@ -1315,8 +2226,13 @@
 union cvmx_npi_pci_read_cmd {
 	uint64_t u64;
 	struct cvmx_npi_pci_read_cmd_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_11_63:53;
 		uint64_t cmd_size:11;
+#else
+		uint64_t cmd_size:11;
+		uint64_t reserved_11_63:53;
+#endif
 	} s;
 	struct cvmx_npi_pci_read_cmd_s cn30xx;
 	struct cvmx_npi_pci_read_cmd_s cn31xx;
@@ -1330,6 +2246,7 @@
 union cvmx_npi_port32_instr_hdr {
 	uint64_t u64;
 	struct cvmx_npi_port32_instr_hdr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_44_63:20;
 		uint64_t pbp:1;
 		uint64_t rsv_f:5;
@@ -1343,6 +2260,21 @@
 		uint64_t rsv_b:1;
 		uint64_t skp_len:7;
 		uint64_t rsv_a:6;
+#else
+		uint64_t rsv_a:6;
+		uint64_t skp_len:7;
+		uint64_t rsv_b:1;
+		uint64_t par_mode:2;
+		uint64_t rsv_c:5;
+		uint64_t use_ihdr:1;
+		uint64_t rsv_d:6;
+		uint64_t rskp_len:7;
+		uint64_t rsv_e:1;
+		uint64_t rparmode:2;
+		uint64_t rsv_f:5;
+		uint64_t pbp:1;
+		uint64_t reserved_44_63:20;
+#endif
 	} s;
 	struct cvmx_npi_port32_instr_hdr_s cn30xx;
 	struct cvmx_npi_port32_instr_hdr_s cn31xx;
@@ -1356,6 +2288,7 @@
 union cvmx_npi_port33_instr_hdr {
 	uint64_t u64;
 	struct cvmx_npi_port33_instr_hdr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_44_63:20;
 		uint64_t pbp:1;
 		uint64_t rsv_f:5;
@@ -1369,6 +2302,21 @@
 		uint64_t rsv_b:1;
 		uint64_t skp_len:7;
 		uint64_t rsv_a:6;
+#else
+		uint64_t rsv_a:6;
+		uint64_t skp_len:7;
+		uint64_t rsv_b:1;
+		uint64_t par_mode:2;
+		uint64_t rsv_c:5;
+		uint64_t use_ihdr:1;
+		uint64_t rsv_d:6;
+		uint64_t rskp_len:7;
+		uint64_t rsv_e:1;
+		uint64_t rparmode:2;
+		uint64_t rsv_f:5;
+		uint64_t pbp:1;
+		uint64_t reserved_44_63:20;
+#endif
 	} s;
 	struct cvmx_npi_port33_instr_hdr_s cn31xx;
 	struct cvmx_npi_port33_instr_hdr_s cn38xx;
@@ -1381,6 +2329,7 @@
 union cvmx_npi_port34_instr_hdr {
 	uint64_t u64;
 	struct cvmx_npi_port34_instr_hdr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_44_63:20;
 		uint64_t pbp:1;
 		uint64_t rsv_f:5;
@@ -1394,6 +2343,21 @@
 		uint64_t rsv_b:1;
 		uint64_t skp_len:7;
 		uint64_t rsv_a:6;
+#else
+		uint64_t rsv_a:6;
+		uint64_t skp_len:7;
+		uint64_t rsv_b:1;
+		uint64_t par_mode:2;
+		uint64_t rsv_c:5;
+		uint64_t use_ihdr:1;
+		uint64_t rsv_d:6;
+		uint64_t rskp_len:7;
+		uint64_t rsv_e:1;
+		uint64_t rparmode:2;
+		uint64_t rsv_f:5;
+		uint64_t pbp:1;
+		uint64_t reserved_44_63:20;
+#endif
 	} s;
 	struct cvmx_npi_port34_instr_hdr_s cn38xx;
 	struct cvmx_npi_port34_instr_hdr_s cn38xxp2;
@@ -1404,6 +2368,7 @@
 union cvmx_npi_port35_instr_hdr {
 	uint64_t u64;
 	struct cvmx_npi_port35_instr_hdr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_44_63:20;
 		uint64_t pbp:1;
 		uint64_t rsv_f:5;
@@ -1417,6 +2382,21 @@
 		uint64_t rsv_b:1;
 		uint64_t skp_len:7;
 		uint64_t rsv_a:6;
+#else
+		uint64_t rsv_a:6;
+		uint64_t skp_len:7;
+		uint64_t rsv_b:1;
+		uint64_t par_mode:2;
+		uint64_t rsv_c:5;
+		uint64_t use_ihdr:1;
+		uint64_t rsv_d:6;
+		uint64_t rskp_len:7;
+		uint64_t rsv_e:1;
+		uint64_t rparmode:2;
+		uint64_t rsv_f:5;
+		uint64_t pbp:1;
+		uint64_t reserved_44_63:20;
+#endif
 	} s;
 	struct cvmx_npi_port35_instr_hdr_s cn38xx;
 	struct cvmx_npi_port35_instr_hdr_s cn38xxp2;
@@ -1427,9 +2407,15 @@
 union cvmx_npi_port_bp_control {
 	uint64_t u64;
 	struct cvmx_npi_port_bp_control_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t bp_on:4;
 		uint64_t enb:4;
+#else
+		uint64_t enb:4;
+		uint64_t bp_on:4;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_npi_port_bp_control_s cn30xx;
 	struct cvmx_npi_port_bp_control_s cn31xx;
@@ -1443,6 +2429,7 @@
 union cvmx_npi_rsl_int_blocks {
 	uint64_t u64;
 	struct cvmx_npi_rsl_int_blocks_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t rint_31:1;
 		uint64_t iob:1;
@@ -1474,8 +2461,42 @@
 		uint64_t gmx1:1;
 		uint64_t gmx0:1;
 		uint64_t mio:1;
+#else
+		uint64_t mio:1;
+		uint64_t gmx0:1;
+		uint64_t gmx1:1;
+		uint64_t npi:1;
+		uint64_t key:1;
+		uint64_t fpa:1;
+		uint64_t dfa:1;
+		uint64_t zip:1;
+		uint64_t rint_8:1;
+		uint64_t ipd:1;
+		uint64_t pko:1;
+		uint64_t tim:1;
+		uint64_t pow:1;
+		uint64_t reserved_13_14:2;
+		uint64_t rint_15:1;
+		uint64_t l2c:1;
+		uint64_t lmc:1;
+		uint64_t spx0:1;
+		uint64_t spx1:1;
+		uint64_t pip:1;
+		uint64_t rint_21:1;
+		uint64_t asx0:1;
+		uint64_t asx1:1;
+		uint64_t rint_24:1;
+		uint64_t rint_25:1;
+		uint64_t rint_26:1;
+		uint64_t rint_27:1;
+		uint64_t reserved_28_29:2;
+		uint64_t iob:1;
+		uint64_t rint_31:1;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_npi_rsl_int_blocks_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t rint_31:1;
 		uint64_t iob:1;
@@ -1509,9 +2530,45 @@
 		uint64_t gmx1:1;
 		uint64_t gmx0:1;
 		uint64_t mio:1;
+#else
+		uint64_t mio:1;
+		uint64_t gmx0:1;
+		uint64_t gmx1:1;
+		uint64_t npi:1;
+		uint64_t key:1;
+		uint64_t fpa:1;
+		uint64_t dfa:1;
+		uint64_t zip:1;
+		uint64_t rint_8:1;
+		uint64_t ipd:1;
+		uint64_t pko:1;
+		uint64_t tim:1;
+		uint64_t pow:1;
+		uint64_t usb:1;
+		uint64_t rint_14:1;
+		uint64_t rint_15:1;
+		uint64_t l2c:1;
+		uint64_t lmc:1;
+		uint64_t spx0:1;
+		uint64_t spx1:1;
+		uint64_t pip:1;
+		uint64_t rint_21:1;
+		uint64_t asx0:1;
+		uint64_t asx1:1;
+		uint64_t rint_24:1;
+		uint64_t rint_25:1;
+		uint64_t rint_26:1;
+		uint64_t rint_27:1;
+		uint64_t rint_28:1;
+		uint64_t rint_29:1;
+		uint64_t iob:1;
+		uint64_t rint_31:1;
+		uint64_t reserved_32_63:32;
+#endif
 	} cn30xx;
 	struct cvmx_npi_rsl_int_blocks_cn30xx cn31xx;
 	struct cvmx_npi_rsl_int_blocks_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t rint_31:1;
 		uint64_t iob:1;
@@ -1545,9 +2602,45 @@
 		uint64_t gmx1:1;
 		uint64_t gmx0:1;
 		uint64_t mio:1;
+#else
+		uint64_t mio:1;
+		uint64_t gmx0:1;
+		uint64_t gmx1:1;
+		uint64_t npi:1;
+		uint64_t key:1;
+		uint64_t fpa:1;
+		uint64_t dfa:1;
+		uint64_t zip:1;
+		uint64_t rint_8:1;
+		uint64_t ipd:1;
+		uint64_t pko:1;
+		uint64_t tim:1;
+		uint64_t pow:1;
+		uint64_t rint_13:1;
+		uint64_t rint_14:1;
+		uint64_t rint_15:1;
+		uint64_t l2c:1;
+		uint64_t lmc:1;
+		uint64_t spx0:1;
+		uint64_t spx1:1;
+		uint64_t pip:1;
+		uint64_t rint_21:1;
+		uint64_t asx0:1;
+		uint64_t asx1:1;
+		uint64_t rint_24:1;
+		uint64_t rint_25:1;
+		uint64_t rint_26:1;
+		uint64_t rint_27:1;
+		uint64_t rint_28:1;
+		uint64_t rint_29:1;
+		uint64_t iob:1;
+		uint64_t rint_31:1;
+		uint64_t reserved_32_63:32;
+#endif
 	} cn38xx;
 	struct cvmx_npi_rsl_int_blocks_cn38xx cn38xxp2;
 	struct cvmx_npi_rsl_int_blocks_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_31_63:33;
 		uint64_t iob:1;
 		uint64_t lmc1:1;
@@ -1577,6 +2670,37 @@
 		uint64_t gmx1:1;
 		uint64_t gmx0:1;
 		uint64_t mio:1;
+#else
+		uint64_t mio:1;
+		uint64_t gmx0:1;
+		uint64_t gmx1:1;
+		uint64_t npi:1;
+		uint64_t key:1;
+		uint64_t fpa:1;
+		uint64_t dfa:1;
+		uint64_t zip:1;
+		uint64_t reserved_8_8:1;
+		uint64_t ipd:1;
+		uint64_t pko:1;
+		uint64_t tim:1;
+		uint64_t pow:1;
+		uint64_t usb:1;
+		uint64_t rad:1;
+		uint64_t reserved_15_15:1;
+		uint64_t l2c:1;
+		uint64_t lmc:1;
+		uint64_t spx0:1;
+		uint64_t spx1:1;
+		uint64_t pip:1;
+		uint64_t reserved_21_21:1;
+		uint64_t asx0:1;
+		uint64_t asx1:1;
+		uint64_t reserved_24_27:4;
+		uint64_t agl:1;
+		uint64_t lmc1:1;
+		uint64_t iob:1;
+		uint64_t reserved_31_63:33;
+#endif
 	} cn50xx;
 	struct cvmx_npi_rsl_int_blocks_cn38xx cn58xx;
 	struct cvmx_npi_rsl_int_blocks_cn38xx cn58xxp1;
@@ -1585,8 +2709,13 @@
 union cvmx_npi_size_inputx {
 	uint64_t u64;
 	struct cvmx_npi_size_inputx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t size:32;
+#else
+		uint64_t size:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_npi_size_inputx_s cn30xx;
 	struct cvmx_npi_size_inputx_s cn31xx;
@@ -1600,8 +2729,13 @@
 union cvmx_npi_win_read_to {
 	uint64_t u64;
 	struct cvmx_npi_win_read_to_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t time:32;
+#else
+		uint64_t time:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_npi_win_read_to_s cn30xx;
 	struct cvmx_npi_win_read_to_s cn31xx;
diff --git a/arch/mips/include/asm/octeon/cvmx-pci-defs.h b/arch/mips/include/asm/octeon/cvmx-pci-defs.h
index 6ff6d9d..25d603f 100644
--- a/arch/mips/include/asm/octeon/cvmx-pci-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pci-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -117,11 +117,19 @@
 union cvmx_pci_bar1_indexx {
 	uint32_t u32;
 	struct cvmx_pci_bar1_indexx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_18_31:14;
 		uint32_t addr_idx:14;
 		uint32_t ca:1;
 		uint32_t end_swp:2;
 		uint32_t addr_v:1;
+#else
+		uint32_t addr_v:1;
+		uint32_t end_swp:2;
+		uint32_t ca:1;
+		uint32_t addr_idx:14;
+		uint32_t reserved_18_31:14;
+#endif
 	} s;
 	struct cvmx_pci_bar1_indexx_s cn30xx;
 	struct cvmx_pci_bar1_indexx_s cn31xx;
@@ -135,6 +143,7 @@
 union cvmx_pci_bist_reg {
 	uint64_t u64;
 	struct cvmx_pci_bist_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t rsp_bs:1;
 		uint64_t dma0_bs:1;
@@ -146,6 +155,19 @@
 		uint64_t csr2n_bs:1;
 		uint64_t dat2n_bs:1;
 		uint64_t dbg2n_bs:1;
+#else
+		uint64_t dbg2n_bs:1;
+		uint64_t dat2n_bs:1;
+		uint64_t csr2n_bs:1;
+		uint64_t rsp2p_bs:1;
+		uint64_t csrr_bs:1;
+		uint64_t csr2p_bs:1;
+		uint64_t cmd_bs:1;
+		uint64_t cmd0_bs:1;
+		uint64_t dma0_bs:1;
+		uint64_t rsp_bs:1;
+		uint64_t reserved_10_63:54;
+#endif
 	} s;
 	struct cvmx_pci_bist_reg_s cn50xx;
 };
@@ -153,8 +175,13 @@
 union cvmx_pci_cfg00 {
 	uint32_t u32;
 	struct cvmx_pci_cfg00_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t devid:16;
 		uint32_t vendid:16;
+#else
+		uint32_t vendid:16;
+		uint32_t devid:16;
+#endif
 	} s;
 	struct cvmx_pci_cfg00_s cn30xx;
 	struct cvmx_pci_cfg00_s cn31xx;
@@ -168,6 +195,7 @@
 union cvmx_pci_cfg01 {
 	uint32_t u32;
 	struct cvmx_pci_cfg01_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t dpe:1;
 		uint32_t sse:1;
 		uint32_t rma:1;
@@ -192,6 +220,32 @@
 		uint32_t me:1;
 		uint32_t msae:1;
 		uint32_t isae:1;
+#else
+		uint32_t isae:1;
+		uint32_t msae:1;
+		uint32_t me:1;
+		uint32_t scse:1;
+		uint32_t mwice:1;
+		uint32_t vps:1;
+		uint32_t pee:1;
+		uint32_t ads:1;
+		uint32_t see:1;
+		uint32_t fbbe:1;
+		uint32_t i_dis:1;
+		uint32_t reserved_11_18:8;
+		uint32_t i_stat:1;
+		uint32_t cle:1;
+		uint32_t m66:1;
+		uint32_t reserved_22_22:1;
+		uint32_t fbb:1;
+		uint32_t mdpe:1;
+		uint32_t devt:2;
+		uint32_t sta:1;
+		uint32_t rta:1;
+		uint32_t rma:1;
+		uint32_t sse:1;
+		uint32_t dpe:1;
+#endif
 	} s;
 	struct cvmx_pci_cfg01_s cn30xx;
 	struct cvmx_pci_cfg01_s cn31xx;
@@ -205,8 +259,13 @@
 union cvmx_pci_cfg02 {
 	uint32_t u32;
 	struct cvmx_pci_cfg02_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t cc:24;
 		uint32_t rid:8;
+#else
+		uint32_t rid:8;
+		uint32_t cc:24;
+#endif
 	} s;
 	struct cvmx_pci_cfg02_s cn30xx;
 	struct cvmx_pci_cfg02_s cn31xx;
@@ -220,6 +279,7 @@
 union cvmx_pci_cfg03 {
 	uint32_t u32;
 	struct cvmx_pci_cfg03_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t bcap:1;
 		uint32_t brb:1;
 		uint32_t reserved_28_29:2;
@@ -227,6 +287,15 @@
 		uint32_t ht:8;
 		uint32_t lt:8;
 		uint32_t cls:8;
+#else
+		uint32_t cls:8;
+		uint32_t lt:8;
+		uint32_t ht:8;
+		uint32_t bcod:4;
+		uint32_t reserved_28_29:2;
+		uint32_t brb:1;
+		uint32_t bcap:1;
+#endif
 	} s;
 	struct cvmx_pci_cfg03_s cn30xx;
 	struct cvmx_pci_cfg03_s cn31xx;
@@ -240,11 +309,19 @@
 union cvmx_pci_cfg04 {
 	uint32_t u32;
 	struct cvmx_pci_cfg04_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t lbase:20;
 		uint32_t lbasez:8;
 		uint32_t pf:1;
 		uint32_t typ:2;
 		uint32_t mspc:1;
+#else
+		uint32_t mspc:1;
+		uint32_t typ:2;
+		uint32_t pf:1;
+		uint32_t lbasez:8;
+		uint32_t lbase:20;
+#endif
 	} s;
 	struct cvmx_pci_cfg04_s cn30xx;
 	struct cvmx_pci_cfg04_s cn31xx;
@@ -258,7 +335,11 @@
 union cvmx_pci_cfg05 {
 	uint32_t u32;
 	struct cvmx_pci_cfg05_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t hbase:32;
+#else
+		uint32_t hbase:32;
+#endif
 	} s;
 	struct cvmx_pci_cfg05_s cn30xx;
 	struct cvmx_pci_cfg05_s cn31xx;
@@ -272,11 +353,19 @@
 union cvmx_pci_cfg06 {
 	uint32_t u32;
 	struct cvmx_pci_cfg06_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t lbase:5;
 		uint32_t lbasez:23;
 		uint32_t pf:1;
 		uint32_t typ:2;
 		uint32_t mspc:1;
+#else
+		uint32_t mspc:1;
+		uint32_t typ:2;
+		uint32_t pf:1;
+		uint32_t lbasez:23;
+		uint32_t lbase:5;
+#endif
 	} s;
 	struct cvmx_pci_cfg06_s cn30xx;
 	struct cvmx_pci_cfg06_s cn31xx;
@@ -290,7 +379,11 @@
 union cvmx_pci_cfg07 {
 	uint32_t u32;
 	struct cvmx_pci_cfg07_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t hbase:32;
+#else
+		uint32_t hbase:32;
+#endif
 	} s;
 	struct cvmx_pci_cfg07_s cn30xx;
 	struct cvmx_pci_cfg07_s cn31xx;
@@ -304,10 +397,17 @@
 union cvmx_pci_cfg08 {
 	uint32_t u32;
 	struct cvmx_pci_cfg08_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t lbasez:28;
 		uint32_t pf:1;
 		uint32_t typ:2;
 		uint32_t mspc:1;
+#else
+		uint32_t mspc:1;
+		uint32_t typ:2;
+		uint32_t pf:1;
+		uint32_t lbasez:28;
+#endif
 	} s;
 	struct cvmx_pci_cfg08_s cn30xx;
 	struct cvmx_pci_cfg08_s cn31xx;
@@ -321,8 +421,13 @@
 union cvmx_pci_cfg09 {
 	uint32_t u32;
 	struct cvmx_pci_cfg09_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t hbase:25;
 		uint32_t hbasez:7;
+#else
+		uint32_t hbasez:7;
+		uint32_t hbase:25;
+#endif
 	} s;
 	struct cvmx_pci_cfg09_s cn30xx;
 	struct cvmx_pci_cfg09_s cn31xx;
@@ -336,7 +441,11 @@
 union cvmx_pci_cfg10 {
 	uint32_t u32;
 	struct cvmx_pci_cfg10_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t cisp:32;
+#else
+		uint32_t cisp:32;
+#endif
 	} s;
 	struct cvmx_pci_cfg10_s cn30xx;
 	struct cvmx_pci_cfg10_s cn31xx;
@@ -350,8 +459,13 @@
 union cvmx_pci_cfg11 {
 	uint32_t u32;
 	struct cvmx_pci_cfg11_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t ssid:16;
 		uint32_t ssvid:16;
+#else
+		uint32_t ssvid:16;
+		uint32_t ssid:16;
+#endif
 	} s;
 	struct cvmx_pci_cfg11_s cn30xx;
 	struct cvmx_pci_cfg11_s cn31xx;
@@ -365,10 +479,17 @@
 union cvmx_pci_cfg12 {
 	uint32_t u32;
 	struct cvmx_pci_cfg12_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t erbar:16;
 		uint32_t erbarz:5;
 		uint32_t reserved_1_10:10;
 		uint32_t erbar_en:1;
+#else
+		uint32_t erbar_en:1;
+		uint32_t reserved_1_10:10;
+		uint32_t erbarz:5;
+		uint32_t erbar:16;
+#endif
 	} s;
 	struct cvmx_pci_cfg12_s cn30xx;
 	struct cvmx_pci_cfg12_s cn31xx;
@@ -382,8 +503,13 @@
 union cvmx_pci_cfg13 {
 	uint32_t u32;
 	struct cvmx_pci_cfg13_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_8_31:24;
 		uint32_t cp:8;
+#else
+		uint32_t cp:8;
+		uint32_t reserved_8_31:24;
+#endif
 	} s;
 	struct cvmx_pci_cfg13_s cn30xx;
 	struct cvmx_pci_cfg13_s cn31xx;
@@ -397,10 +523,17 @@
 union cvmx_pci_cfg15 {
 	uint32_t u32;
 	struct cvmx_pci_cfg15_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t ml:8;
 		uint32_t mg:8;
 		uint32_t inta:8;
 		uint32_t il:8;
+#else
+		uint32_t il:8;
+		uint32_t inta:8;
+		uint32_t mg:8;
+		uint32_t ml:8;
+#endif
 	} s;
 	struct cvmx_pci_cfg15_s cn30xx;
 	struct cvmx_pci_cfg15_s cn31xx;
@@ -414,6 +547,7 @@
 union cvmx_pci_cfg16 {
 	uint32_t u32;
 	struct cvmx_pci_cfg16_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t trdnpr:1;
 		uint32_t trdard:1;
 		uint32_t rdsati:1;
@@ -430,6 +564,24 @@
 		uint32_t reserved_2_2:1;
 		uint32_t tswc:1;
 		uint32_t mltd:1;
+#else
+		uint32_t mltd:1;
+		uint32_t tswc:1;
+		uint32_t reserved_2_2:1;
+		uint32_t dppmr:1;
+		uint32_t pbe:12;
+		uint32_t tilt:4;
+		uint32_t tslte:3;
+		uint32_t tmae:1;
+		uint32_t twtae:1;
+		uint32_t twsen:1;
+		uint32_t twsei:1;
+		uint32_t trtae:1;
+		uint32_t trdrs:1;
+		uint32_t rdsati:1;
+		uint32_t trdard:1;
+		uint32_t trdnpr:1;
+#endif
 	} s;
 	struct cvmx_pci_cfg16_s cn30xx;
 	struct cvmx_pci_cfg16_s cn31xx;
@@ -443,7 +595,11 @@
 union cvmx_pci_cfg17 {
 	uint32_t u32;
 	struct cvmx_pci_cfg17_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t tscme:32;
+#else
+		uint32_t tscme:32;
+#endif
 	} s;
 	struct cvmx_pci_cfg17_s cn30xx;
 	struct cvmx_pci_cfg17_s cn31xx;
@@ -457,7 +613,11 @@
 union cvmx_pci_cfg18 {
 	uint32_t u32;
 	struct cvmx_pci_cfg18_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t tdsrps:32;
+#else
+		uint32_t tdsrps:32;
+#endif
 	} s;
 	struct cvmx_pci_cfg18_s cn30xx;
 	struct cvmx_pci_cfg18_s cn31xx;
@@ -471,6 +631,7 @@
 union cvmx_pci_cfg19 {
 	uint32_t u32;
 	struct cvmx_pci_cfg19_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t mrbcm:1;
 		uint32_t mrbci:1;
 		uint32_t mdwe:1;
@@ -489,6 +650,26 @@
 		uint32_t reserved_6_6:1;
 		uint32_t tidomc:1;
 		uint32_t tdomc:5;
+#else
+		uint32_t tdomc:5;
+		uint32_t tidomc:1;
+		uint32_t reserved_6_6:1;
+		uint32_t tibde:1;
+		uint32_t tibcd:1;
+		uint32_t reserved_9_10:2;
+		uint32_t tmapes:1;
+		uint32_t tmdpes:1;
+		uint32_t tmse:1;
+		uint32_t tmei:1;
+		uint32_t teci:1;
+		uint32_t tmes:8;
+		uint32_t mdrrmc:3;
+		uint32_t mdrimc:1;
+		uint32_t mdre:1;
+		uint32_t mdwe:1;
+		uint32_t mrbci:1;
+		uint32_t mrbcm:1;
+#endif
 	} s;
 	struct cvmx_pci_cfg19_s cn30xx;
 	struct cvmx_pci_cfg19_s cn31xx;
@@ -502,7 +683,11 @@
 union cvmx_pci_cfg20 {
 	uint32_t u32;
 	struct cvmx_pci_cfg20_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t mdsp:32;
+#else
+		uint32_t mdsp:32;
+#endif
 	} s;
 	struct cvmx_pci_cfg20_s cn30xx;
 	struct cvmx_pci_cfg20_s cn31xx;
@@ -516,7 +701,11 @@
 union cvmx_pci_cfg21 {
 	uint32_t u32;
 	struct cvmx_pci_cfg21_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t scmre:32;
+#else
+		uint32_t scmre:32;
+#endif
 	} s;
 	struct cvmx_pci_cfg21_s cn30xx;
 	struct cvmx_pci_cfg21_s cn31xx;
@@ -530,6 +719,7 @@
 union cvmx_pci_cfg22 {
 	uint32_t u32;
 	struct cvmx_pci_cfg22_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t mac:7;
 		uint32_t reserved_19_24:6;
 		uint32_t flush:1;
@@ -537,6 +727,15 @@
 		uint32_t mtta:1;
 		uint32_t mrv:8;
 		uint32_t mttv:8;
+#else
+		uint32_t mttv:8;
+		uint32_t mrv:8;
+		uint32_t mtta:1;
+		uint32_t mra:1;
+		uint32_t flush:1;
+		uint32_t reserved_19_24:6;
+		uint32_t mac:7;
+#endif
 	} s;
 	struct cvmx_pci_cfg22_s cn30xx;
 	struct cvmx_pci_cfg22_s cn31xx;
@@ -550,6 +749,7 @@
 union cvmx_pci_cfg56 {
 	uint32_t u32;
 	struct cvmx_pci_cfg56_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_23_31:9;
 		uint32_t most:3;
 		uint32_t mmbc:2;
@@ -557,6 +757,15 @@
 		uint32_t dpere:1;
 		uint32_t ncp:8;
 		uint32_t pxcid:8;
+#else
+		uint32_t pxcid:8;
+		uint32_t ncp:8;
+		uint32_t dpere:1;
+		uint32_t roe:1;
+		uint32_t mmbc:2;
+		uint32_t most:3;
+		uint32_t reserved_23_31:9;
+#endif
 	} s;
 	struct cvmx_pci_cfg56_s cn30xx;
 	struct cvmx_pci_cfg56_s cn31xx;
@@ -570,6 +779,7 @@
 union cvmx_pci_cfg57 {
 	uint32_t u32;
 	struct cvmx_pci_cfg57_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_30_31:2;
 		uint32_t scemr:1;
 		uint32_t mcrsd:3;
@@ -583,6 +793,21 @@
 		uint32_t bn:8;
 		uint32_t dn:5;
 		uint32_t fn:3;
+#else
+		uint32_t fn:3;
+		uint32_t dn:5;
+		uint32_t bn:8;
+		uint32_t w64:1;
+		uint32_t m133:1;
+		uint32_t scd:1;
+		uint32_t usc:1;
+		uint32_t dc:1;
+		uint32_t mmrbcd:2;
+		uint32_t mostd:3;
+		uint32_t mcrsd:3;
+		uint32_t scemr:1;
+		uint32_t reserved_30_31:2;
+#endif
 	} s;
 	struct cvmx_pci_cfg57_s cn30xx;
 	struct cvmx_pci_cfg57_s cn31xx;
@@ -596,6 +821,7 @@
 union cvmx_pci_cfg58 {
 	uint32_t u32;
 	struct cvmx_pci_cfg58_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t pmes:5;
 		uint32_t d2s:1;
 		uint32_t d1s:1;
@@ -606,6 +832,18 @@
 		uint32_t pcimiv:3;
 		uint32_t ncp:8;
 		uint32_t pmcid:8;
+#else
+		uint32_t pmcid:8;
+		uint32_t ncp:8;
+		uint32_t pcimiv:3;
+		uint32_t pmec:1;
+		uint32_t reserved_20_20:1;
+		uint32_t dsi:1;
+		uint32_t auxc:3;
+		uint32_t d1s:1;
+		uint32_t d2s:1;
+		uint32_t pmes:5;
+#endif
 	} s;
 	struct cvmx_pci_cfg58_s cn30xx;
 	struct cvmx_pci_cfg58_s cn31xx;
@@ -619,6 +857,7 @@
 union cvmx_pci_cfg59 {
 	uint32_t u32;
 	struct cvmx_pci_cfg59_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t pmdia:8;
 		uint32_t bpccen:1;
 		uint32_t bd3h:1;
@@ -629,6 +868,18 @@
 		uint32_t pmeens:1;
 		uint32_t reserved_2_7:6;
 		uint32_t ps:2;
+#else
+		uint32_t ps:2;
+		uint32_t reserved_2_7:6;
+		uint32_t pmeens:1;
+		uint32_t pmds:4;
+		uint32_t pmedsia:2;
+		uint32_t pmess:1;
+		uint32_t reserved_16_21:6;
+		uint32_t bd3h:1;
+		uint32_t bpccen:1;
+		uint32_t pmdia:8;
+#endif
 	} s;
 	struct cvmx_pci_cfg59_s cn30xx;
 	struct cvmx_pci_cfg59_s cn31xx;
@@ -642,6 +893,7 @@
 union cvmx_pci_cfg60 {
 	uint32_t u32;
 	struct cvmx_pci_cfg60_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_24_31:8;
 		uint32_t m64:1;
 		uint32_t mme:3;
@@ -649,6 +901,15 @@
 		uint32_t msien:1;
 		uint32_t ncp:8;
 		uint32_t msicid:8;
+#else
+		uint32_t msicid:8;
+		uint32_t ncp:8;
+		uint32_t msien:1;
+		uint32_t mmc:3;
+		uint32_t mme:3;
+		uint32_t m64:1;
+		uint32_t reserved_24_31:8;
+#endif
 	} s;
 	struct cvmx_pci_cfg60_s cn30xx;
 	struct cvmx_pci_cfg60_s cn31xx;
@@ -662,8 +923,13 @@
 union cvmx_pci_cfg61 {
 	uint32_t u32;
 	struct cvmx_pci_cfg61_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t msi31t2:30;
 		uint32_t reserved_0_1:2;
+#else
+		uint32_t reserved_0_1:2;
+		uint32_t msi31t2:30;
+#endif
 	} s;
 	struct cvmx_pci_cfg61_s cn30xx;
 	struct cvmx_pci_cfg61_s cn31xx;
@@ -677,7 +943,11 @@
 union cvmx_pci_cfg62 {
 	uint32_t u32;
 	struct cvmx_pci_cfg62_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t msi:32;
+#else
+		uint32_t msi:32;
+#endif
 	} s;
 	struct cvmx_pci_cfg62_s cn30xx;
 	struct cvmx_pci_cfg62_s cn31xx;
@@ -691,8 +961,13 @@
 union cvmx_pci_cfg63 {
 	uint32_t u32;
 	struct cvmx_pci_cfg63_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_16_31:16;
 		uint32_t msimd:16;
+#else
+		uint32_t msimd:16;
+		uint32_t reserved_16_31:16;
+#endif
 	} s;
 	struct cvmx_pci_cfg63_s cn30xx;
 	struct cvmx_pci_cfg63_s cn31xx;
@@ -706,12 +981,21 @@
 union cvmx_pci_cnt_reg {
 	uint64_t u64;
 	struct cvmx_pci_cnt_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_38_63:26;
 		uint64_t hm_pcix:1;
 		uint64_t hm_speed:2;
 		uint64_t ap_pcix:1;
 		uint64_t ap_speed:2;
 		uint64_t pcicnt:32;
+#else
+		uint64_t pcicnt:32;
+		uint64_t ap_speed:2;
+		uint64_t ap_pcix:1;
+		uint64_t hm_speed:2;
+		uint64_t hm_pcix:1;
+		uint64_t reserved_38_63:26;
+#endif
 	} s;
 	struct cvmx_pci_cnt_reg_s cn50xx;
 	struct cvmx_pci_cnt_reg_s cn58xx;
@@ -721,6 +1005,7 @@
 union cvmx_pci_ctl_status_2 {
 	uint32_t u32;
 	struct cvmx_pci_ctl_status_2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_29_31:3;
 		uint32_t bb1_hole:3;
 		uint32_t bb1_siz:1;
@@ -743,9 +1028,34 @@
 		uint32_t bar2_enb:1;
 		uint32_t bar2_esx:2;
 		uint32_t bar2_cax:1;
+#else
+		uint32_t bar2_cax:1;
+		uint32_t bar2_esx:2;
+		uint32_t bar2_enb:1;
+		uint32_t tsr_hwm:3;
+		uint32_t pmo_fpc:3;
+		uint32_t pmo_amod:1;
+		uint32_t b12_bist:1;
+		uint32_t ap_64ad:1;
+		uint32_t ap_pcix:1;
+		uint32_t reserved_14_14:1;
+		uint32_t en_wfilt:1;
+		uint32_t scm:1;
+		uint32_t scmtyp:1;
+		uint32_t bar2pres:1;
+		uint32_t erst_n:1;
+		uint32_t bb0:1;
+		uint32_t bb1:1;
+		uint32_t bb_es:2;
+		uint32_t bb_ca:1;
+		uint32_t bb1_siz:1;
+		uint32_t bb1_hole:3;
+		uint32_t reserved_29_31:3;
+#endif
 	} s;
 	struct cvmx_pci_ctl_status_2_s cn30xx;
 	struct cvmx_pci_ctl_status_2_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_20_31:12;
 		uint32_t erst_n:1;
 		uint32_t bar2pres:1;
@@ -762,6 +1072,24 @@
 		uint32_t bar2_enb:1;
 		uint32_t bar2_esx:2;
 		uint32_t bar2_cax:1;
+#else
+		uint32_t bar2_cax:1;
+		uint32_t bar2_esx:2;
+		uint32_t bar2_enb:1;
+		uint32_t tsr_hwm:3;
+		uint32_t pmo_fpc:3;
+		uint32_t pmo_amod:1;
+		uint32_t b12_bist:1;
+		uint32_t ap_64ad:1;
+		uint32_t ap_pcix:1;
+		uint32_t reserved_14_14:1;
+		uint32_t en_wfilt:1;
+		uint32_t scm:1;
+		uint32_t scmtyp:1;
+		uint32_t bar2pres:1;
+		uint32_t erst_n:1;
+		uint32_t reserved_20_31:12;
+#endif
 	} cn31xx;
 	struct cvmx_pci_ctl_status_2_s cn38xx;
 	struct cvmx_pci_ctl_status_2_cn31xx cn38xxp2;
@@ -773,8 +1101,13 @@
 union cvmx_pci_dbellx {
 	uint32_t u32;
 	struct cvmx_pci_dbellx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_16_31:16;
 		uint32_t inc_val:16;
+#else
+		uint32_t inc_val:16;
+		uint32_t reserved_16_31:16;
+#endif
 	} s;
 	struct cvmx_pci_dbellx_s cn30xx;
 	struct cvmx_pci_dbellx_s cn31xx;
@@ -788,7 +1121,11 @@
 union cvmx_pci_dma_cntx {
 	uint32_t u32;
 	struct cvmx_pci_dma_cntx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t dma_cnt:32;
+#else
+		uint32_t dma_cnt:32;
+#endif
 	} s;
 	struct cvmx_pci_dma_cntx_s cn30xx;
 	struct cvmx_pci_dma_cntx_s cn31xx;
@@ -802,7 +1139,11 @@
 union cvmx_pci_dma_int_levx {
 	uint32_t u32;
 	struct cvmx_pci_dma_int_levx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t pkt_cnt:32;
+#else
+		uint32_t pkt_cnt:32;
+#endif
 	} s;
 	struct cvmx_pci_dma_int_levx_s cn30xx;
 	struct cvmx_pci_dma_int_levx_s cn31xx;
@@ -816,7 +1157,11 @@
 union cvmx_pci_dma_timex {
 	uint32_t u32;
 	struct cvmx_pci_dma_timex_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t dma_time:32;
+#else
+		uint32_t dma_time:32;
+#endif
 	} s;
 	struct cvmx_pci_dma_timex_s cn30xx;
 	struct cvmx_pci_dma_timex_s cn31xx;
@@ -830,7 +1175,11 @@
 union cvmx_pci_instr_countx {
 	uint32_t u32;
 	struct cvmx_pci_instr_countx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t icnt:32;
+#else
+		uint32_t icnt:32;
+#endif
 	} s;
 	struct cvmx_pci_instr_countx_s cn30xx;
 	struct cvmx_pci_instr_countx_s cn31xx;
@@ -844,6 +1193,7 @@
 union cvmx_pci_int_enb {
 	uint64_t u64;
 	struct cvmx_pci_int_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_34_63:30;
 		uint64_t ill_rd:1;
 		uint64_t ill_wr:1;
@@ -879,8 +1229,46 @@
 		uint64_t imr_wtto:1;
 		uint64_t imr_wabt:1;
 		uint64_t itr_wabt:1;
+#else
+		uint64_t itr_wabt:1;
+		uint64_t imr_wabt:1;
+		uint64_t imr_wtto:1;
+		uint64_t itr_abt:1;
+		uint64_t imr_abt:1;
+		uint64_t imr_tto:1;
+		uint64_t imsi_per:1;
+		uint64_t imsi_tabt:1;
+		uint64_t imsi_mabt:1;
+		uint64_t imsc_msg:1;
+		uint64_t itsr_abt:1;
+		uint64_t iserr:1;
+		uint64_t iaperr:1;
+		uint64_t idperr:1;
+		uint64_t ill_rwr:1;
+		uint64_t ill_rrd:1;
+		uint64_t irsl_int:1;
+		uint64_t ipcnt0:1;
+		uint64_t ipcnt1:1;
+		uint64_t ipcnt2:1;
+		uint64_t ipcnt3:1;
+		uint64_t iptime0:1;
+		uint64_t iptime1:1;
+		uint64_t iptime2:1;
+		uint64_t iptime3:1;
+		uint64_t idcnt0:1;
+		uint64_t idcnt1:1;
+		uint64_t idtime0:1;
+		uint64_t idtime1:1;
+		uint64_t dma0_fi:1;
+		uint64_t dma1_fi:1;
+		uint64_t win_wr:1;
+		uint64_t ill_wr:1;
+		uint64_t ill_rd:1;
+		uint64_t reserved_34_63:30;
+#endif
 	} s;
 	struct cvmx_pci_int_enb_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_34_63:30;
 		uint64_t ill_rd:1;
 		uint64_t ill_wr:1;
@@ -912,8 +1300,42 @@
 		uint64_t imr_wtto:1;
 		uint64_t imr_wabt:1;
 		uint64_t itr_wabt:1;
+#else
+		uint64_t itr_wabt:1;
+		uint64_t imr_wabt:1;
+		uint64_t imr_wtto:1;
+		uint64_t itr_abt:1;
+		uint64_t imr_abt:1;
+		uint64_t imr_tto:1;
+		uint64_t imsi_per:1;
+		uint64_t imsi_tabt:1;
+		uint64_t imsi_mabt:1;
+		uint64_t imsc_msg:1;
+		uint64_t itsr_abt:1;
+		uint64_t iserr:1;
+		uint64_t iaperr:1;
+		uint64_t idperr:1;
+		uint64_t ill_rwr:1;
+		uint64_t ill_rrd:1;
+		uint64_t irsl_int:1;
+		uint64_t ipcnt0:1;
+		uint64_t reserved_18_20:3;
+		uint64_t iptime0:1;
+		uint64_t reserved_22_24:3;
+		uint64_t idcnt0:1;
+		uint64_t idcnt1:1;
+		uint64_t idtime0:1;
+		uint64_t idtime1:1;
+		uint64_t dma0_fi:1;
+		uint64_t dma1_fi:1;
+		uint64_t win_wr:1;
+		uint64_t ill_wr:1;
+		uint64_t ill_rd:1;
+		uint64_t reserved_34_63:30;
+#endif
 	} cn30xx;
 	struct cvmx_pci_int_enb_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_34_63:30;
 		uint64_t ill_rd:1;
 		uint64_t ill_wr:1;
@@ -947,6 +1369,41 @@
 		uint64_t imr_wtto:1;
 		uint64_t imr_wabt:1;
 		uint64_t itr_wabt:1;
+#else
+		uint64_t itr_wabt:1;
+		uint64_t imr_wabt:1;
+		uint64_t imr_wtto:1;
+		uint64_t itr_abt:1;
+		uint64_t imr_abt:1;
+		uint64_t imr_tto:1;
+		uint64_t imsi_per:1;
+		uint64_t imsi_tabt:1;
+		uint64_t imsi_mabt:1;
+		uint64_t imsc_msg:1;
+		uint64_t itsr_abt:1;
+		uint64_t iserr:1;
+		uint64_t iaperr:1;
+		uint64_t idperr:1;
+		uint64_t ill_rwr:1;
+		uint64_t ill_rrd:1;
+		uint64_t irsl_int:1;
+		uint64_t ipcnt0:1;
+		uint64_t ipcnt1:1;
+		uint64_t reserved_19_20:2;
+		uint64_t iptime0:1;
+		uint64_t iptime1:1;
+		uint64_t reserved_23_24:2;
+		uint64_t idcnt0:1;
+		uint64_t idcnt1:1;
+		uint64_t idtime0:1;
+		uint64_t idtime1:1;
+		uint64_t dma0_fi:1;
+		uint64_t dma1_fi:1;
+		uint64_t win_wr:1;
+		uint64_t ill_wr:1;
+		uint64_t ill_rd:1;
+		uint64_t reserved_34_63:30;
+#endif
 	} cn31xx;
 	struct cvmx_pci_int_enb_s cn38xx;
 	struct cvmx_pci_int_enb_s cn38xxp2;
@@ -958,6 +1415,7 @@
 union cvmx_pci_int_enb2 {
 	uint64_t u64;
 	struct cvmx_pci_int_enb2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_34_63:30;
 		uint64_t ill_rd:1;
 		uint64_t ill_wr:1;
@@ -993,8 +1451,46 @@
 		uint64_t rmr_wtto:1;
 		uint64_t rmr_wabt:1;
 		uint64_t rtr_wabt:1;
+#else
+		uint64_t rtr_wabt:1;
+		uint64_t rmr_wabt:1;
+		uint64_t rmr_wtto:1;
+		uint64_t rtr_abt:1;
+		uint64_t rmr_abt:1;
+		uint64_t rmr_tto:1;
+		uint64_t rmsi_per:1;
+		uint64_t rmsi_tabt:1;
+		uint64_t rmsi_mabt:1;
+		uint64_t rmsc_msg:1;
+		uint64_t rtsr_abt:1;
+		uint64_t rserr:1;
+		uint64_t raperr:1;
+		uint64_t rdperr:1;
+		uint64_t ill_rwr:1;
+		uint64_t ill_rrd:1;
+		uint64_t rrsl_int:1;
+		uint64_t rpcnt0:1;
+		uint64_t rpcnt1:1;
+		uint64_t rpcnt2:1;
+		uint64_t rpcnt3:1;
+		uint64_t rptime0:1;
+		uint64_t rptime1:1;
+		uint64_t rptime2:1;
+		uint64_t rptime3:1;
+		uint64_t rdcnt0:1;
+		uint64_t rdcnt1:1;
+		uint64_t rdtime0:1;
+		uint64_t rdtime1:1;
+		uint64_t dma0_fi:1;
+		uint64_t dma1_fi:1;
+		uint64_t win_wr:1;
+		uint64_t ill_wr:1;
+		uint64_t ill_rd:1;
+		uint64_t reserved_34_63:30;
+#endif
 	} s;
 	struct cvmx_pci_int_enb2_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_34_63:30;
 		uint64_t ill_rd:1;
 		uint64_t ill_wr:1;
@@ -1026,8 +1522,42 @@
 		uint64_t rmr_wtto:1;
 		uint64_t rmr_wabt:1;
 		uint64_t rtr_wabt:1;
+#else
+		uint64_t rtr_wabt:1;
+		uint64_t rmr_wabt:1;
+		uint64_t rmr_wtto:1;
+		uint64_t rtr_abt:1;
+		uint64_t rmr_abt:1;
+		uint64_t rmr_tto:1;
+		uint64_t rmsi_per:1;
+		uint64_t rmsi_tabt:1;
+		uint64_t rmsi_mabt:1;
+		uint64_t rmsc_msg:1;
+		uint64_t rtsr_abt:1;
+		uint64_t rserr:1;
+		uint64_t raperr:1;
+		uint64_t rdperr:1;
+		uint64_t ill_rwr:1;
+		uint64_t ill_rrd:1;
+		uint64_t rrsl_int:1;
+		uint64_t rpcnt0:1;
+		uint64_t reserved_18_20:3;
+		uint64_t rptime0:1;
+		uint64_t reserved_22_24:3;
+		uint64_t rdcnt0:1;
+		uint64_t rdcnt1:1;
+		uint64_t rdtime0:1;
+		uint64_t rdtime1:1;
+		uint64_t dma0_fi:1;
+		uint64_t dma1_fi:1;
+		uint64_t win_wr:1;
+		uint64_t ill_wr:1;
+		uint64_t ill_rd:1;
+		uint64_t reserved_34_63:30;
+#endif
 	} cn30xx;
 	struct cvmx_pci_int_enb2_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_34_63:30;
 		uint64_t ill_rd:1;
 		uint64_t ill_wr:1;
@@ -1061,6 +1591,41 @@
 		uint64_t rmr_wtto:1;
 		uint64_t rmr_wabt:1;
 		uint64_t rtr_wabt:1;
+#else
+		uint64_t rtr_wabt:1;
+		uint64_t rmr_wabt:1;
+		uint64_t rmr_wtto:1;
+		uint64_t rtr_abt:1;
+		uint64_t rmr_abt:1;
+		uint64_t rmr_tto:1;
+		uint64_t rmsi_per:1;
+		uint64_t rmsi_tabt:1;
+		uint64_t rmsi_mabt:1;
+		uint64_t rmsc_msg:1;
+		uint64_t rtsr_abt:1;
+		uint64_t rserr:1;
+		uint64_t raperr:1;
+		uint64_t rdperr:1;
+		uint64_t ill_rwr:1;
+		uint64_t ill_rrd:1;
+		uint64_t rrsl_int:1;
+		uint64_t rpcnt0:1;
+		uint64_t rpcnt1:1;
+		uint64_t reserved_19_20:2;
+		uint64_t rptime0:1;
+		uint64_t rptime1:1;
+		uint64_t reserved_23_24:2;
+		uint64_t rdcnt0:1;
+		uint64_t rdcnt1:1;
+		uint64_t rdtime0:1;
+		uint64_t rdtime1:1;
+		uint64_t dma0_fi:1;
+		uint64_t dma1_fi:1;
+		uint64_t win_wr:1;
+		uint64_t ill_wr:1;
+		uint64_t ill_rd:1;
+		uint64_t reserved_34_63:30;
+#endif
 	} cn31xx;
 	struct cvmx_pci_int_enb2_s cn38xx;
 	struct cvmx_pci_int_enb2_s cn38xxp2;
@@ -1072,6 +1637,7 @@
 union cvmx_pci_int_sum {
 	uint64_t u64;
 	struct cvmx_pci_int_sum_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_34_63:30;
 		uint64_t ill_rd:1;
 		uint64_t ill_wr:1;
@@ -1107,8 +1673,46 @@
 		uint64_t mr_wtto:1;
 		uint64_t mr_wabt:1;
 		uint64_t tr_wabt:1;
+#else
+		uint64_t tr_wabt:1;
+		uint64_t mr_wabt:1;
+		uint64_t mr_wtto:1;
+		uint64_t tr_abt:1;
+		uint64_t mr_abt:1;
+		uint64_t mr_tto:1;
+		uint64_t msi_per:1;
+		uint64_t msi_tabt:1;
+		uint64_t msi_mabt:1;
+		uint64_t msc_msg:1;
+		uint64_t tsr_abt:1;
+		uint64_t serr:1;
+		uint64_t aperr:1;
+		uint64_t dperr:1;
+		uint64_t ill_rwr:1;
+		uint64_t ill_rrd:1;
+		uint64_t rsl_int:1;
+		uint64_t pcnt0:1;
+		uint64_t pcnt1:1;
+		uint64_t pcnt2:1;
+		uint64_t pcnt3:1;
+		uint64_t ptime0:1;
+		uint64_t ptime1:1;
+		uint64_t ptime2:1;
+		uint64_t ptime3:1;
+		uint64_t dcnt0:1;
+		uint64_t dcnt1:1;
+		uint64_t dtime0:1;
+		uint64_t dtime1:1;
+		uint64_t dma0_fi:1;
+		uint64_t dma1_fi:1;
+		uint64_t win_wr:1;
+		uint64_t ill_wr:1;
+		uint64_t ill_rd:1;
+		uint64_t reserved_34_63:30;
+#endif
 	} s;
 	struct cvmx_pci_int_sum_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_34_63:30;
 		uint64_t ill_rd:1;
 		uint64_t ill_wr:1;
@@ -1140,8 +1744,42 @@
 		uint64_t mr_wtto:1;
 		uint64_t mr_wabt:1;
 		uint64_t tr_wabt:1;
+#else
+		uint64_t tr_wabt:1;
+		uint64_t mr_wabt:1;
+		uint64_t mr_wtto:1;
+		uint64_t tr_abt:1;
+		uint64_t mr_abt:1;
+		uint64_t mr_tto:1;
+		uint64_t msi_per:1;
+		uint64_t msi_tabt:1;
+		uint64_t msi_mabt:1;
+		uint64_t msc_msg:1;
+		uint64_t tsr_abt:1;
+		uint64_t serr:1;
+		uint64_t aperr:1;
+		uint64_t dperr:1;
+		uint64_t ill_rwr:1;
+		uint64_t ill_rrd:1;
+		uint64_t rsl_int:1;
+		uint64_t pcnt0:1;
+		uint64_t reserved_18_20:3;
+		uint64_t ptime0:1;
+		uint64_t reserved_22_24:3;
+		uint64_t dcnt0:1;
+		uint64_t dcnt1:1;
+		uint64_t dtime0:1;
+		uint64_t dtime1:1;
+		uint64_t dma0_fi:1;
+		uint64_t dma1_fi:1;
+		uint64_t win_wr:1;
+		uint64_t ill_wr:1;
+		uint64_t ill_rd:1;
+		uint64_t reserved_34_63:30;
+#endif
 	} cn30xx;
 	struct cvmx_pci_int_sum_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_34_63:30;
 		uint64_t ill_rd:1;
 		uint64_t ill_wr:1;
@@ -1175,6 +1813,41 @@
 		uint64_t mr_wtto:1;
 		uint64_t mr_wabt:1;
 		uint64_t tr_wabt:1;
+#else
+		uint64_t tr_wabt:1;
+		uint64_t mr_wabt:1;
+		uint64_t mr_wtto:1;
+		uint64_t tr_abt:1;
+		uint64_t mr_abt:1;
+		uint64_t mr_tto:1;
+		uint64_t msi_per:1;
+		uint64_t msi_tabt:1;
+		uint64_t msi_mabt:1;
+		uint64_t msc_msg:1;
+		uint64_t tsr_abt:1;
+		uint64_t serr:1;
+		uint64_t aperr:1;
+		uint64_t dperr:1;
+		uint64_t ill_rwr:1;
+		uint64_t ill_rrd:1;
+		uint64_t rsl_int:1;
+		uint64_t pcnt0:1;
+		uint64_t pcnt1:1;
+		uint64_t reserved_19_20:2;
+		uint64_t ptime0:1;
+		uint64_t ptime1:1;
+		uint64_t reserved_23_24:2;
+		uint64_t dcnt0:1;
+		uint64_t dcnt1:1;
+		uint64_t dtime0:1;
+		uint64_t dtime1:1;
+		uint64_t dma0_fi:1;
+		uint64_t dma1_fi:1;
+		uint64_t win_wr:1;
+		uint64_t ill_wr:1;
+		uint64_t ill_rd:1;
+		uint64_t reserved_34_63:30;
+#endif
 	} cn31xx;
 	struct cvmx_pci_int_sum_s cn38xx;
 	struct cvmx_pci_int_sum_s cn38xxp2;
@@ -1186,6 +1859,7 @@
 union cvmx_pci_int_sum2 {
 	uint64_t u64;
 	struct cvmx_pci_int_sum2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_34_63:30;
 		uint64_t ill_rd:1;
 		uint64_t ill_wr:1;
@@ -1221,8 +1895,46 @@
 		uint64_t mr_wtto:1;
 		uint64_t mr_wabt:1;
 		uint64_t tr_wabt:1;
+#else
+		uint64_t tr_wabt:1;
+		uint64_t mr_wabt:1;
+		uint64_t mr_wtto:1;
+		uint64_t tr_abt:1;
+		uint64_t mr_abt:1;
+		uint64_t mr_tto:1;
+		uint64_t msi_per:1;
+		uint64_t msi_tabt:1;
+		uint64_t msi_mabt:1;
+		uint64_t msc_msg:1;
+		uint64_t tsr_abt:1;
+		uint64_t serr:1;
+		uint64_t aperr:1;
+		uint64_t dperr:1;
+		uint64_t ill_rwr:1;
+		uint64_t ill_rrd:1;
+		uint64_t rsl_int:1;
+		uint64_t pcnt0:1;
+		uint64_t pcnt1:1;
+		uint64_t pcnt2:1;
+		uint64_t pcnt3:1;
+		uint64_t ptime0:1;
+		uint64_t ptime1:1;
+		uint64_t ptime2:1;
+		uint64_t ptime3:1;
+		uint64_t dcnt0:1;
+		uint64_t dcnt1:1;
+		uint64_t dtime0:1;
+		uint64_t dtime1:1;
+		uint64_t dma0_fi:1;
+		uint64_t dma1_fi:1;
+		uint64_t win_wr:1;
+		uint64_t ill_wr:1;
+		uint64_t ill_rd:1;
+		uint64_t reserved_34_63:30;
+#endif
 	} s;
 	struct cvmx_pci_int_sum2_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_34_63:30;
 		uint64_t ill_rd:1;
 		uint64_t ill_wr:1;
@@ -1254,8 +1966,42 @@
 		uint64_t mr_wtto:1;
 		uint64_t mr_wabt:1;
 		uint64_t tr_wabt:1;
+#else
+		uint64_t tr_wabt:1;
+		uint64_t mr_wabt:1;
+		uint64_t mr_wtto:1;
+		uint64_t tr_abt:1;
+		uint64_t mr_abt:1;
+		uint64_t mr_tto:1;
+		uint64_t msi_per:1;
+		uint64_t msi_tabt:1;
+		uint64_t msi_mabt:1;
+		uint64_t msc_msg:1;
+		uint64_t tsr_abt:1;
+		uint64_t serr:1;
+		uint64_t aperr:1;
+		uint64_t dperr:1;
+		uint64_t ill_rwr:1;
+		uint64_t ill_rrd:1;
+		uint64_t rsl_int:1;
+		uint64_t pcnt0:1;
+		uint64_t reserved_18_20:3;
+		uint64_t ptime0:1;
+		uint64_t reserved_22_24:3;
+		uint64_t dcnt0:1;
+		uint64_t dcnt1:1;
+		uint64_t dtime0:1;
+		uint64_t dtime1:1;
+		uint64_t dma0_fi:1;
+		uint64_t dma1_fi:1;
+		uint64_t win_wr:1;
+		uint64_t ill_wr:1;
+		uint64_t ill_rd:1;
+		uint64_t reserved_34_63:30;
+#endif
 	} cn30xx;
 	struct cvmx_pci_int_sum2_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_34_63:30;
 		uint64_t ill_rd:1;
 		uint64_t ill_wr:1;
@@ -1289,6 +2035,41 @@
 		uint64_t mr_wtto:1;
 		uint64_t mr_wabt:1;
 		uint64_t tr_wabt:1;
+#else
+		uint64_t tr_wabt:1;
+		uint64_t mr_wabt:1;
+		uint64_t mr_wtto:1;
+		uint64_t tr_abt:1;
+		uint64_t mr_abt:1;
+		uint64_t mr_tto:1;
+		uint64_t msi_per:1;
+		uint64_t msi_tabt:1;
+		uint64_t msi_mabt:1;
+		uint64_t msc_msg:1;
+		uint64_t tsr_abt:1;
+		uint64_t serr:1;
+		uint64_t aperr:1;
+		uint64_t dperr:1;
+		uint64_t ill_rwr:1;
+		uint64_t ill_rrd:1;
+		uint64_t rsl_int:1;
+		uint64_t pcnt0:1;
+		uint64_t pcnt1:1;
+		uint64_t reserved_19_20:2;
+		uint64_t ptime0:1;
+		uint64_t ptime1:1;
+		uint64_t reserved_23_24:2;
+		uint64_t dcnt0:1;
+		uint64_t dcnt1:1;
+		uint64_t dtime0:1;
+		uint64_t dtime1:1;
+		uint64_t dma0_fi:1;
+		uint64_t dma1_fi:1;
+		uint64_t win_wr:1;
+		uint64_t ill_wr:1;
+		uint64_t ill_rd:1;
+		uint64_t reserved_34_63:30;
+#endif
 	} cn31xx;
 	struct cvmx_pci_int_sum2_s cn38xx;
 	struct cvmx_pci_int_sum2_s cn38xxp2;
@@ -1300,8 +2081,13 @@
 union cvmx_pci_msi_rcv {
 	uint32_t u32;
 	struct cvmx_pci_msi_rcv_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_6_31:26;
 		uint32_t intr:6;
+#else
+		uint32_t intr:6;
+		uint32_t reserved_6_31:26;
+#endif
 	} s;
 	struct cvmx_pci_msi_rcv_s cn30xx;
 	struct cvmx_pci_msi_rcv_s cn31xx;
@@ -1315,8 +2101,13 @@
 union cvmx_pci_pkt_creditsx {
 	uint32_t u32;
 	struct cvmx_pci_pkt_creditsx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t pkt_cnt:16;
 		uint32_t ptr_cnt:16;
+#else
+		uint32_t ptr_cnt:16;
+		uint32_t pkt_cnt:16;
+#endif
 	} s;
 	struct cvmx_pci_pkt_creditsx_s cn30xx;
 	struct cvmx_pci_pkt_creditsx_s cn31xx;
@@ -1330,7 +2121,11 @@
 union cvmx_pci_pkts_sentx {
 	uint32_t u32;
 	struct cvmx_pci_pkts_sentx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t pkt_cnt:32;
+#else
+		uint32_t pkt_cnt:32;
+#endif
 	} s;
 	struct cvmx_pci_pkts_sentx_s cn30xx;
 	struct cvmx_pci_pkts_sentx_s cn31xx;
@@ -1344,7 +2139,11 @@
 union cvmx_pci_pkts_sent_int_levx {
 	uint32_t u32;
 	struct cvmx_pci_pkts_sent_int_levx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t pkt_cnt:32;
+#else
+		uint32_t pkt_cnt:32;
+#endif
 	} s;
 	struct cvmx_pci_pkts_sent_int_levx_s cn30xx;
 	struct cvmx_pci_pkts_sent_int_levx_s cn31xx;
@@ -1358,7 +2157,11 @@
 union cvmx_pci_pkts_sent_timex {
 	uint32_t u32;
 	struct cvmx_pci_pkts_sent_timex_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t pkt_time:32;
+#else
+		uint32_t pkt_time:32;
+#endif
 	} s;
 	struct cvmx_pci_pkts_sent_timex_s cn30xx;
 	struct cvmx_pci_pkts_sent_timex_s cn31xx;
@@ -1372,9 +2175,15 @@
 union cvmx_pci_read_cmd_6 {
 	uint32_t u32;
 	struct cvmx_pci_read_cmd_6_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_9_31:23;
 		uint32_t min_data:6;
 		uint32_t prefetch:3;
+#else
+		uint32_t prefetch:3;
+		uint32_t min_data:6;
+		uint32_t reserved_9_31:23;
+#endif
 	} s;
 	struct cvmx_pci_read_cmd_6_s cn30xx;
 	struct cvmx_pci_read_cmd_6_s cn31xx;
@@ -1388,9 +2197,15 @@
 union cvmx_pci_read_cmd_c {
 	uint32_t u32;
 	struct cvmx_pci_read_cmd_c_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_9_31:23;
 		uint32_t min_data:6;
 		uint32_t prefetch:3;
+#else
+		uint32_t prefetch:3;
+		uint32_t min_data:6;
+		uint32_t reserved_9_31:23;
+#endif
 	} s;
 	struct cvmx_pci_read_cmd_c_s cn30xx;
 	struct cvmx_pci_read_cmd_c_s cn31xx;
@@ -1404,9 +2219,15 @@
 union cvmx_pci_read_cmd_e {
 	uint32_t u32;
 	struct cvmx_pci_read_cmd_e_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_9_31:23;
 		uint32_t min_data:6;
 		uint32_t prefetch:3;
+#else
+		uint32_t prefetch:3;
+		uint32_t min_data:6;
+		uint32_t reserved_9_31:23;
+#endif
 	} s;
 	struct cvmx_pci_read_cmd_e_s cn30xx;
 	struct cvmx_pci_read_cmd_e_s cn31xx;
@@ -1420,9 +2241,15 @@
 union cvmx_pci_read_timeout {
 	uint64_t u64;
 	struct cvmx_pci_read_timeout_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t enb:1;
 		uint64_t cnt:31;
+#else
+		uint64_t cnt:31;
+		uint64_t enb:1;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_pci_read_timeout_s cn30xx;
 	struct cvmx_pci_read_timeout_s cn31xx;
@@ -1436,8 +2263,13 @@
 union cvmx_pci_scm_reg {
 	uint64_t u64;
 	struct cvmx_pci_scm_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t scm:32;
+#else
+		uint64_t scm:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_pci_scm_reg_s cn30xx;
 	struct cvmx_pci_scm_reg_s cn31xx;
@@ -1451,8 +2283,13 @@
 union cvmx_pci_tsr_reg {
 	uint64_t u64;
 	struct cvmx_pci_tsr_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_36_63:28;
 		uint64_t tsr:36;
+#else
+		uint64_t tsr:36;
+		uint64_t reserved_36_63:28;
+#endif
 	} s;
 	struct cvmx_pci_tsr_reg_s cn30xx;
 	struct cvmx_pci_tsr_reg_s cn31xx;
@@ -1466,22 +2303,42 @@
 union cvmx_pci_win_rd_addr {
 	uint64_t u64;
 	struct cvmx_pci_win_rd_addr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_49_63:15;
 		uint64_t iobit:1;
 		uint64_t reserved_0_47:48;
+#else
+		uint64_t reserved_0_47:48;
+		uint64_t iobit:1;
+		uint64_t reserved_49_63:15;
+#endif
 	} s;
 	struct cvmx_pci_win_rd_addr_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_49_63:15;
 		uint64_t iobit:1;
 		uint64_t rd_addr:46;
 		uint64_t reserved_0_1:2;
+#else
+		uint64_t reserved_0_1:2;
+		uint64_t rd_addr:46;
+		uint64_t iobit:1;
+		uint64_t reserved_49_63:15;
+#endif
 	} cn30xx;
 	struct cvmx_pci_win_rd_addr_cn30xx cn31xx;
 	struct cvmx_pci_win_rd_addr_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_49_63:15;
 		uint64_t iobit:1;
 		uint64_t rd_addr:45;
 		uint64_t reserved_0_2:3;
+#else
+		uint64_t reserved_0_2:3;
+		uint64_t rd_addr:45;
+		uint64_t iobit:1;
+		uint64_t reserved_49_63:15;
+#endif
 	} cn38xx;
 	struct cvmx_pci_win_rd_addr_cn38xx cn38xxp2;
 	struct cvmx_pci_win_rd_addr_cn30xx cn50xx;
@@ -1492,7 +2349,11 @@
 union cvmx_pci_win_rd_data {
 	uint64_t u64;
 	struct cvmx_pci_win_rd_data_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t rd_data:64;
+#else
+		uint64_t rd_data:64;
+#endif
 	} s;
 	struct cvmx_pci_win_rd_data_s cn30xx;
 	struct cvmx_pci_win_rd_data_s cn31xx;
@@ -1506,10 +2367,17 @@
 union cvmx_pci_win_wr_addr {
 	uint64_t u64;
 	struct cvmx_pci_win_wr_addr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_49_63:15;
 		uint64_t iobit:1;
 		uint64_t wr_addr:45;
 		uint64_t reserved_0_2:3;
+#else
+		uint64_t reserved_0_2:3;
+		uint64_t wr_addr:45;
+		uint64_t iobit:1;
+		uint64_t reserved_49_63:15;
+#endif
 	} s;
 	struct cvmx_pci_win_wr_addr_s cn30xx;
 	struct cvmx_pci_win_wr_addr_s cn31xx;
@@ -1523,7 +2391,11 @@
 union cvmx_pci_win_wr_data {
 	uint64_t u64;
 	struct cvmx_pci_win_wr_data_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t wr_data:64;
+#else
+		uint64_t wr_data:64;
+#endif
 	} s;
 	struct cvmx_pci_win_wr_data_s cn30xx;
 	struct cvmx_pci_win_wr_data_s cn31xx;
@@ -1537,8 +2409,13 @@
 union cvmx_pci_win_wr_mask {
 	uint64_t u64;
 	struct cvmx_pci_win_wr_mask_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t wr_mask:8;
+#else
+		uint64_t wr_mask:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_pci_win_wr_mask_s cn30xx;
 	struct cvmx_pci_win_wr_mask_s cn31xx;
diff --git a/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h b/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h
index 7b1dc8b..4bce393 100644
--- a/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2011 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -109,8 +109,13 @@
 union cvmx_pciercx_cfg000 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg000_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t devid:16;
 		uint32_t vendid:16;
+#else
+		uint32_t vendid:16;
+		uint32_t devid:16;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg000_s cn52xx;
 	struct cvmx_pciercx_cfg000_s cn52xxp1;
@@ -122,11 +127,13 @@
 	struct cvmx_pciercx_cfg000_s cn66xx;
 	struct cvmx_pciercx_cfg000_s cn68xx;
 	struct cvmx_pciercx_cfg000_s cn68xxp1;
+	struct cvmx_pciercx_cfg000_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg001 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg001_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t dpe:1;
 		uint32_t sse:1;
 		uint32_t rma:1;
@@ -151,6 +158,32 @@
 		uint32_t me:1;
 		uint32_t msae:1;
 		uint32_t isae:1;
+#else
+		uint32_t isae:1;
+		uint32_t msae:1;
+		uint32_t me:1;
+		uint32_t scse:1;
+		uint32_t mwice:1;
+		uint32_t vps:1;
+		uint32_t per:1;
+		uint32_t ids_wcc:1;
+		uint32_t see:1;
+		uint32_t fbbe:1;
+		uint32_t i_dis:1;
+		uint32_t reserved_11_18:8;
+		uint32_t i_stat:1;
+		uint32_t cl:1;
+		uint32_t m66:1;
+		uint32_t reserved_22_22:1;
+		uint32_t fbb:1;
+		uint32_t mdpe:1;
+		uint32_t devt:2;
+		uint32_t sta:1;
+		uint32_t rta:1;
+		uint32_t rma:1;
+		uint32_t sse:1;
+		uint32_t dpe:1;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg001_s cn52xx;
 	struct cvmx_pciercx_cfg001_s cn52xxp1;
@@ -162,15 +195,23 @@
 	struct cvmx_pciercx_cfg001_s cn66xx;
 	struct cvmx_pciercx_cfg001_s cn68xx;
 	struct cvmx_pciercx_cfg001_s cn68xxp1;
+	struct cvmx_pciercx_cfg001_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg002 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg002_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t bcc:8;
 		uint32_t sc:8;
 		uint32_t pi:8;
 		uint32_t rid:8;
+#else
+		uint32_t rid:8;
+		uint32_t pi:8;
+		uint32_t sc:8;
+		uint32_t bcc:8;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg002_s cn52xx;
 	struct cvmx_pciercx_cfg002_s cn52xxp1;
@@ -182,16 +223,25 @@
 	struct cvmx_pciercx_cfg002_s cn66xx;
 	struct cvmx_pciercx_cfg002_s cn68xx;
 	struct cvmx_pciercx_cfg002_s cn68xxp1;
+	struct cvmx_pciercx_cfg002_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg003 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg003_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t bist:8;
 		uint32_t mfd:1;
 		uint32_t chf:7;
 		uint32_t lt:8;
 		uint32_t cls:8;
+#else
+		uint32_t cls:8;
+		uint32_t lt:8;
+		uint32_t chf:7;
+		uint32_t mfd:1;
+		uint32_t bist:8;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg003_s cn52xx;
 	struct cvmx_pciercx_cfg003_s cn52xxp1;
@@ -203,12 +253,17 @@
 	struct cvmx_pciercx_cfg003_s cn66xx;
 	struct cvmx_pciercx_cfg003_s cn68xx;
 	struct cvmx_pciercx_cfg003_s cn68xxp1;
+	struct cvmx_pciercx_cfg003_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg004 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg004_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_0_31:32;
+#else
+		uint32_t reserved_0_31:32;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg004_s cn52xx;
 	struct cvmx_pciercx_cfg004_s cn52xxp1;
@@ -220,12 +275,17 @@
 	struct cvmx_pciercx_cfg004_s cn66xx;
 	struct cvmx_pciercx_cfg004_s cn68xx;
 	struct cvmx_pciercx_cfg004_s cn68xxp1;
+	struct cvmx_pciercx_cfg004_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg005 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg005_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_0_31:32;
+#else
+		uint32_t reserved_0_31:32;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg005_s cn52xx;
 	struct cvmx_pciercx_cfg005_s cn52xxp1;
@@ -237,15 +297,23 @@
 	struct cvmx_pciercx_cfg005_s cn66xx;
 	struct cvmx_pciercx_cfg005_s cn68xx;
 	struct cvmx_pciercx_cfg005_s cn68xxp1;
+	struct cvmx_pciercx_cfg005_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg006 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg006_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t slt:8;
 		uint32_t subbnum:8;
 		uint32_t sbnum:8;
 		uint32_t pbnum:8;
+#else
+		uint32_t pbnum:8;
+		uint32_t sbnum:8;
+		uint32_t subbnum:8;
+		uint32_t slt:8;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg006_s cn52xx;
 	struct cvmx_pciercx_cfg006_s cn52xxp1;
@@ -257,11 +325,13 @@
 	struct cvmx_pciercx_cfg006_s cn66xx;
 	struct cvmx_pciercx_cfg006_s cn68xx;
 	struct cvmx_pciercx_cfg006_s cn68xxp1;
+	struct cvmx_pciercx_cfg006_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg007 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg007_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t dpe:1;
 		uint32_t sse:1;
 		uint32_t rma:1;
@@ -279,6 +349,25 @@
 		uint32_t lio_base:4;
 		uint32_t reserved_1_3:3;
 		uint32_t io32a:1;
+#else
+		uint32_t io32a:1;
+		uint32_t reserved_1_3:3;
+		uint32_t lio_base:4;
+		uint32_t io32b:1;
+		uint32_t reserved_9_11:3;
+		uint32_t lio_limi:4;
+		uint32_t reserved_16_20:5;
+		uint32_t m66:1;
+		uint32_t reserved_22_22:1;
+		uint32_t fbb:1;
+		uint32_t mdpe:1;
+		uint32_t devt:2;
+		uint32_t sta:1;
+		uint32_t rta:1;
+		uint32_t rma:1;
+		uint32_t sse:1;
+		uint32_t dpe:1;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg007_s cn52xx;
 	struct cvmx_pciercx_cfg007_s cn52xxp1;
@@ -290,15 +379,23 @@
 	struct cvmx_pciercx_cfg007_s cn66xx;
 	struct cvmx_pciercx_cfg007_s cn68xx;
 	struct cvmx_pciercx_cfg007_s cn68xxp1;
+	struct cvmx_pciercx_cfg007_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg008 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg008_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t ml_addr:12;
 		uint32_t reserved_16_19:4;
 		uint32_t mb_addr:12;
 		uint32_t reserved_0_3:4;
+#else
+		uint32_t reserved_0_3:4;
+		uint32_t mb_addr:12;
+		uint32_t reserved_16_19:4;
+		uint32_t ml_addr:12;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg008_s cn52xx;
 	struct cvmx_pciercx_cfg008_s cn52xxp1;
@@ -310,17 +407,27 @@
 	struct cvmx_pciercx_cfg008_s cn66xx;
 	struct cvmx_pciercx_cfg008_s cn68xx;
 	struct cvmx_pciercx_cfg008_s cn68xxp1;
+	struct cvmx_pciercx_cfg008_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg009 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg009_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t lmem_limit:12;
 		uint32_t reserved_17_19:3;
 		uint32_t mem64b:1;
 		uint32_t lmem_base:12;
 		uint32_t reserved_1_3:3;
 		uint32_t mem64a:1;
+#else
+		uint32_t mem64a:1;
+		uint32_t reserved_1_3:3;
+		uint32_t lmem_base:12;
+		uint32_t mem64b:1;
+		uint32_t reserved_17_19:3;
+		uint32_t lmem_limit:12;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg009_s cn52xx;
 	struct cvmx_pciercx_cfg009_s cn52xxp1;
@@ -332,12 +439,17 @@
 	struct cvmx_pciercx_cfg009_s cn66xx;
 	struct cvmx_pciercx_cfg009_s cn68xx;
 	struct cvmx_pciercx_cfg009_s cn68xxp1;
+	struct cvmx_pciercx_cfg009_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg010 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg010_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t umem_base:32;
+#else
+		uint32_t umem_base:32;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg010_s cn52xx;
 	struct cvmx_pciercx_cfg010_s cn52xxp1;
@@ -349,12 +461,17 @@
 	struct cvmx_pciercx_cfg010_s cn66xx;
 	struct cvmx_pciercx_cfg010_s cn68xx;
 	struct cvmx_pciercx_cfg010_s cn68xxp1;
+	struct cvmx_pciercx_cfg010_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg011 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg011_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t umem_limit:32;
+#else
+		uint32_t umem_limit:32;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg011_s cn52xx;
 	struct cvmx_pciercx_cfg011_s cn52xxp1;
@@ -366,13 +483,19 @@
 	struct cvmx_pciercx_cfg011_s cn66xx;
 	struct cvmx_pciercx_cfg011_s cn68xx;
 	struct cvmx_pciercx_cfg011_s cn68xxp1;
+	struct cvmx_pciercx_cfg011_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg012 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg012_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t uio_limit:16;
 		uint32_t uio_base:16;
+#else
+		uint32_t uio_base:16;
+		uint32_t uio_limit:16;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg012_s cn52xx;
 	struct cvmx_pciercx_cfg012_s cn52xxp1;
@@ -384,13 +507,19 @@
 	struct cvmx_pciercx_cfg012_s cn66xx;
 	struct cvmx_pciercx_cfg012_s cn68xx;
 	struct cvmx_pciercx_cfg012_s cn68xxp1;
+	struct cvmx_pciercx_cfg012_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg013 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg013_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_8_31:24;
 		uint32_t cp:8;
+#else
+		uint32_t cp:8;
+		uint32_t reserved_8_31:24;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg013_s cn52xx;
 	struct cvmx_pciercx_cfg013_s cn52xxp1;
@@ -402,12 +531,17 @@
 	struct cvmx_pciercx_cfg013_s cn66xx;
 	struct cvmx_pciercx_cfg013_s cn68xx;
 	struct cvmx_pciercx_cfg013_s cn68xxp1;
+	struct cvmx_pciercx_cfg013_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg014 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg014_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_0_31:32;
+#else
+		uint32_t reserved_0_31:32;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg014_s cn52xx;
 	struct cvmx_pciercx_cfg014_s cn52xxp1;
@@ -419,11 +553,13 @@
 	struct cvmx_pciercx_cfg014_s cn66xx;
 	struct cvmx_pciercx_cfg014_s cn68xx;
 	struct cvmx_pciercx_cfg014_s cn68xxp1;
+	struct cvmx_pciercx_cfg014_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg015 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg015_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_28_31:4;
 		uint32_t dtsees:1;
 		uint32_t dts:1;
@@ -439,6 +575,23 @@
 		uint32_t pere:1;
 		uint32_t inta:8;
 		uint32_t il:8;
+#else
+		uint32_t il:8;
+		uint32_t inta:8;
+		uint32_t pere:1;
+		uint32_t see:1;
+		uint32_t isae:1;
+		uint32_t vgae:1;
+		uint32_t vga16d:1;
+		uint32_t mam:1;
+		uint32_t sbrst:1;
+		uint32_t fbbe:1;
+		uint32_t pdt:1;
+		uint32_t sdt:1;
+		uint32_t dts:1;
+		uint32_t dtsees:1;
+		uint32_t reserved_28_31:4;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg015_s cn52xx;
 	struct cvmx_pciercx_cfg015_s cn52xxp1;
@@ -450,11 +603,13 @@
 	struct cvmx_pciercx_cfg015_s cn66xx;
 	struct cvmx_pciercx_cfg015_s cn68xx;
 	struct cvmx_pciercx_cfg015_s cn68xxp1;
+	struct cvmx_pciercx_cfg015_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg016 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg016_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t pmes:5;
 		uint32_t d2s:1;
 		uint32_t d1s:1;
@@ -465,6 +620,18 @@
 		uint32_t pmsv:3;
 		uint32_t ncp:8;
 		uint32_t pmcid:8;
+#else
+		uint32_t pmcid:8;
+		uint32_t ncp:8;
+		uint32_t pmsv:3;
+		uint32_t pme_clock:1;
+		uint32_t reserved_20_20:1;
+		uint32_t dsi:1;
+		uint32_t auxc:3;
+		uint32_t d1s:1;
+		uint32_t d2s:1;
+		uint32_t pmes:5;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg016_s cn52xx;
 	struct cvmx_pciercx_cfg016_s cn52xxp1;
@@ -476,11 +643,13 @@
 	struct cvmx_pciercx_cfg016_s cn66xx;
 	struct cvmx_pciercx_cfg016_s cn68xx;
 	struct cvmx_pciercx_cfg016_s cn68xxp1;
+	struct cvmx_pciercx_cfg016_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg017 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg017_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t pmdia:8;
 		uint32_t bpccee:1;
 		uint32_t bd3h:1;
@@ -493,6 +662,20 @@
 		uint32_t nsr:1;
 		uint32_t reserved_2_2:1;
 		uint32_t ps:2;
+#else
+		uint32_t ps:2;
+		uint32_t reserved_2_2:1;
+		uint32_t nsr:1;
+		uint32_t reserved_4_7:4;
+		uint32_t pmeens:1;
+		uint32_t pmds:4;
+		uint32_t pmedsia:2;
+		uint32_t pmess:1;
+		uint32_t reserved_16_21:6;
+		uint32_t bd3h:1;
+		uint32_t bpccee:1;
+		uint32_t pmdia:8;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg017_s cn52xx;
 	struct cvmx_pciercx_cfg017_s cn52xxp1;
@@ -504,11 +687,13 @@
 	struct cvmx_pciercx_cfg017_s cn66xx;
 	struct cvmx_pciercx_cfg017_s cn68xx;
 	struct cvmx_pciercx_cfg017_s cn68xxp1;
+	struct cvmx_pciercx_cfg017_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg020 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg020_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_25_31:7;
 		uint32_t pvm:1;
 		uint32_t m64:1;
@@ -517,8 +702,19 @@
 		uint32_t msien:1;
 		uint32_t ncp:8;
 		uint32_t msicid:8;
+#else
+		uint32_t msicid:8;
+		uint32_t ncp:8;
+		uint32_t msien:1;
+		uint32_t mmc:3;
+		uint32_t mme:3;
+		uint32_t m64:1;
+		uint32_t pvm:1;
+		uint32_t reserved_25_31:7;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg020_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_24_31:8;
 		uint32_t m64:1;
 		uint32_t mme:3;
@@ -526,6 +722,15 @@
 		uint32_t msien:1;
 		uint32_t ncp:8;
 		uint32_t msicid:8;
+#else
+		uint32_t msicid:8;
+		uint32_t ncp:8;
+		uint32_t msien:1;
+		uint32_t mmc:3;
+		uint32_t mme:3;
+		uint32_t m64:1;
+		uint32_t reserved_24_31:8;
+#endif
 	} cn52xx;
 	struct cvmx_pciercx_cfg020_cn52xx cn52xxp1;
 	struct cvmx_pciercx_cfg020_cn52xx cn56xx;
@@ -536,13 +741,19 @@
 	struct cvmx_pciercx_cfg020_cn52xx cn66xx;
 	struct cvmx_pciercx_cfg020_cn52xx cn68xx;
 	struct cvmx_pciercx_cfg020_cn52xx cn68xxp1;
+	struct cvmx_pciercx_cfg020_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg021 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg021_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t lmsi:30;
 		uint32_t reserved_0_1:2;
+#else
+		uint32_t reserved_0_1:2;
+		uint32_t lmsi:30;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg021_s cn52xx;
 	struct cvmx_pciercx_cfg021_s cn52xxp1;
@@ -554,12 +765,17 @@
 	struct cvmx_pciercx_cfg021_s cn66xx;
 	struct cvmx_pciercx_cfg021_s cn68xx;
 	struct cvmx_pciercx_cfg021_s cn68xxp1;
+	struct cvmx_pciercx_cfg021_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg022 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg022_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t umsi:32;
+#else
+		uint32_t umsi:32;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg022_s cn52xx;
 	struct cvmx_pciercx_cfg022_s cn52xxp1;
@@ -571,13 +787,19 @@
 	struct cvmx_pciercx_cfg022_s cn66xx;
 	struct cvmx_pciercx_cfg022_s cn68xx;
 	struct cvmx_pciercx_cfg022_s cn68xxp1;
+	struct cvmx_pciercx_cfg022_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg023 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg023_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_16_31:16;
 		uint32_t msimd:16;
+#else
+		uint32_t msimd:16;
+		uint32_t reserved_16_31:16;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg023_s cn52xx;
 	struct cvmx_pciercx_cfg023_s cn52xxp1;
@@ -589,11 +811,13 @@
 	struct cvmx_pciercx_cfg023_s cn66xx;
 	struct cvmx_pciercx_cfg023_s cn68xx;
 	struct cvmx_pciercx_cfg023_s cn68xxp1;
+	struct cvmx_pciercx_cfg023_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg028 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg028_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_30_31:2;
 		uint32_t imn:5;
 		uint32_t si:1;
@@ -601,6 +825,15 @@
 		uint32_t pciecv:4;
 		uint32_t ncp:8;
 		uint32_t pcieid:8;
+#else
+		uint32_t pcieid:8;
+		uint32_t ncp:8;
+		uint32_t pciecv:4;
+		uint32_t dpt:4;
+		uint32_t si:1;
+		uint32_t imn:5;
+		uint32_t reserved_30_31:2;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg028_s cn52xx;
 	struct cvmx_pciercx_cfg028_s cn52xxp1;
@@ -612,11 +845,13 @@
 	struct cvmx_pciercx_cfg028_s cn66xx;
 	struct cvmx_pciercx_cfg028_s cn68xx;
 	struct cvmx_pciercx_cfg028_s cn68xxp1;
+	struct cvmx_pciercx_cfg028_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg029 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg029_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_28_31:4;
 		uint32_t cspls:2;
 		uint32_t csplv:8;
@@ -628,6 +863,19 @@
 		uint32_t etfs:1;
 		uint32_t pfs:2;
 		uint32_t mpss:3;
+#else
+		uint32_t mpss:3;
+		uint32_t pfs:2;
+		uint32_t etfs:1;
+		uint32_t el0al:3;
+		uint32_t el1al:3;
+		uint32_t reserved_12_14:3;
+		uint32_t rber:1;
+		uint32_t reserved_16_17:2;
+		uint32_t csplv:8;
+		uint32_t cspls:2;
+		uint32_t reserved_28_31:4;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg029_s cn52xx;
 	struct cvmx_pciercx_cfg029_s cn52xxp1;
@@ -639,11 +887,13 @@
 	struct cvmx_pciercx_cfg029_s cn66xx;
 	struct cvmx_pciercx_cfg029_s cn68xx;
 	struct cvmx_pciercx_cfg029_s cn68xxp1;
+	struct cvmx_pciercx_cfg029_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg030 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg030_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_22_31:10;
 		uint32_t tp:1;
 		uint32_t ap_d:1;
@@ -663,6 +913,27 @@
 		uint32_t fe_en:1;
 		uint32_t nfe_en:1;
 		uint32_t ce_en:1;
+#else
+		uint32_t ce_en:1;
+		uint32_t nfe_en:1;
+		uint32_t fe_en:1;
+		uint32_t ur_en:1;
+		uint32_t ro_en:1;
+		uint32_t mps:3;
+		uint32_t etf_en:1;
+		uint32_t pf_en:1;
+		uint32_t ap_en:1;
+		uint32_t ns_en:1;
+		uint32_t mrrs:3;
+		uint32_t reserved_15_15:1;
+		uint32_t ce_d:1;
+		uint32_t nfe_d:1;
+		uint32_t fe_d:1;
+		uint32_t ur_d:1;
+		uint32_t ap_d:1;
+		uint32_t tp:1;
+		uint32_t reserved_22_31:10;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg030_s cn52xx;
 	struct cvmx_pciercx_cfg030_s cn52xxp1;
@@ -674,11 +945,13 @@
 	struct cvmx_pciercx_cfg030_s cn66xx;
 	struct cvmx_pciercx_cfg030_s cn68xx;
 	struct cvmx_pciercx_cfg030_s cn68xxp1;
+	struct cvmx_pciercx_cfg030_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg031 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg031_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t pnum:8;
 		uint32_t reserved_23_23:1;
 		uint32_t aspm:1;
@@ -691,8 +964,23 @@
 		uint32_t aslpms:2;
 		uint32_t mlw:6;
 		uint32_t mls:4;
+#else
+		uint32_t mls:4;
+		uint32_t mlw:6;
+		uint32_t aslpms:2;
+		uint32_t l0el:3;
+		uint32_t l1el:3;
+		uint32_t cpm:1;
+		uint32_t sderc:1;
+		uint32_t dllarc:1;
+		uint32_t lbnc:1;
+		uint32_t aspm:1;
+		uint32_t reserved_23_23:1;
+		uint32_t pnum:8;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg031_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t pnum:8;
 		uint32_t reserved_22_23:2;
 		uint32_t lbnc:1;
@@ -704,6 +992,19 @@
 		uint32_t aslpms:2;
 		uint32_t mlw:6;
 		uint32_t mls:4;
+#else
+		uint32_t mls:4;
+		uint32_t mlw:6;
+		uint32_t aslpms:2;
+		uint32_t l0el:3;
+		uint32_t l1el:3;
+		uint32_t cpm:1;
+		uint32_t sderc:1;
+		uint32_t dllarc:1;
+		uint32_t lbnc:1;
+		uint32_t reserved_22_23:2;
+		uint32_t pnum:8;
+#endif
 	} cn52xx;
 	struct cvmx_pciercx_cfg031_cn52xx cn52xxp1;
 	struct cvmx_pciercx_cfg031_cn52xx cn56xx;
@@ -714,11 +1015,13 @@
 	struct cvmx_pciercx_cfg031_s cn66xx;
 	struct cvmx_pciercx_cfg031_s cn68xx;
 	struct cvmx_pciercx_cfg031_cn52xx cn68xxp1;
+	struct cvmx_pciercx_cfg031_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg032 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg032_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t lab:1;
 		uint32_t lbm:1;
 		uint32_t dlla:1;
@@ -739,6 +1042,28 @@
 		uint32_t rcb:1;
 		uint32_t reserved_2_2:1;
 		uint32_t aslpc:2;
+#else
+		uint32_t aslpc:2;
+		uint32_t reserved_2_2:1;
+		uint32_t rcb:1;
+		uint32_t ld:1;
+		uint32_t rl:1;
+		uint32_t ccc:1;
+		uint32_t es:1;
+		uint32_t ecpm:1;
+		uint32_t hawd:1;
+		uint32_t lbm_int_enb:1;
+		uint32_t lab_int_enb:1;
+		uint32_t reserved_12_15:4;
+		uint32_t ls:4;
+		uint32_t nlw:6;
+		uint32_t reserved_26_26:1;
+		uint32_t lt:1;
+		uint32_t scc:1;
+		uint32_t dlla:1;
+		uint32_t lbm:1;
+		uint32_t lab:1;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg032_s cn52xx;
 	struct cvmx_pciercx_cfg032_s cn52xxp1;
@@ -750,11 +1075,13 @@
 	struct cvmx_pciercx_cfg032_s cn66xx;
 	struct cvmx_pciercx_cfg032_s cn68xx;
 	struct cvmx_pciercx_cfg032_s cn68xxp1;
+	struct cvmx_pciercx_cfg032_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg033 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg033_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t ps_num:13;
 		uint32_t nccs:1;
 		uint32_t emip:1;
@@ -767,6 +1094,20 @@
 		uint32_t mrlsp:1;
 		uint32_t pcp:1;
 		uint32_t abp:1;
+#else
+		uint32_t abp:1;
+		uint32_t pcp:1;
+		uint32_t mrlsp:1;
+		uint32_t aip:1;
+		uint32_t pip:1;
+		uint32_t hp_s:1;
+		uint32_t hp_c:1;
+		uint32_t sp_lv:8;
+		uint32_t sp_ls:2;
+		uint32_t emip:1;
+		uint32_t nccs:1;
+		uint32_t ps_num:13;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg033_s cn52xx;
 	struct cvmx_pciercx_cfg033_s cn52xxp1;
@@ -778,11 +1119,13 @@
 	struct cvmx_pciercx_cfg033_s cn66xx;
 	struct cvmx_pciercx_cfg033_s cn68xx;
 	struct cvmx_pciercx_cfg033_s cn68xxp1;
+	struct cvmx_pciercx_cfg033_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg034 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg034_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_25_31:7;
 		uint32_t dlls_c:1;
 		uint32_t emis:1;
@@ -805,6 +1148,30 @@
 		uint32_t mrls_en:1;
 		uint32_t pf_en:1;
 		uint32_t abp_en:1;
+#else
+		uint32_t abp_en:1;
+		uint32_t pf_en:1;
+		uint32_t mrls_en:1;
+		uint32_t pd_en:1;
+		uint32_t ccint_en:1;
+		uint32_t hpint_en:1;
+		uint32_t aic:2;
+		uint32_t pic:2;
+		uint32_t pcc:1;
+		uint32_t emic:1;
+		uint32_t dlls_en:1;
+		uint32_t reserved_13_15:3;
+		uint32_t abp_d:1;
+		uint32_t pf_d:1;
+		uint32_t mrls_c:1;
+		uint32_t pd_c:1;
+		uint32_t ccint_d:1;
+		uint32_t mrlss:1;
+		uint32_t pds:1;
+		uint32_t emis:1;
+		uint32_t dlls_c:1;
+		uint32_t reserved_25_31:7;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg034_s cn52xx;
 	struct cvmx_pciercx_cfg034_s cn52xxp1;
@@ -816,11 +1183,13 @@
 	struct cvmx_pciercx_cfg034_s cn66xx;
 	struct cvmx_pciercx_cfg034_s cn68xx;
 	struct cvmx_pciercx_cfg034_s cn68xxp1;
+	struct cvmx_pciercx_cfg034_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg035 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg035_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_17_31:15;
 		uint32_t crssv:1;
 		uint32_t reserved_5_15:11;
@@ -829,6 +1198,16 @@
 		uint32_t sefee:1;
 		uint32_t senfee:1;
 		uint32_t secee:1;
+#else
+		uint32_t secee:1;
+		uint32_t senfee:1;
+		uint32_t sefee:1;
+		uint32_t pmeie:1;
+		uint32_t crssve:1;
+		uint32_t reserved_5_15:11;
+		uint32_t crssv:1;
+		uint32_t reserved_17_31:15;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg035_s cn52xx;
 	struct cvmx_pciercx_cfg035_s cn52xxp1;
@@ -840,15 +1219,23 @@
 	struct cvmx_pciercx_cfg035_s cn66xx;
 	struct cvmx_pciercx_cfg035_s cn68xx;
 	struct cvmx_pciercx_cfg035_s cn68xxp1;
+	struct cvmx_pciercx_cfg035_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg036 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg036_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_18_31:14;
 		uint32_t pme_pend:1;
 		uint32_t pme_stat:1;
 		uint32_t pme_rid:16;
+#else
+		uint32_t pme_rid:16;
+		uint32_t pme_stat:1;
+		uint32_t pme_pend:1;
+		uint32_t reserved_18_31:14;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg036_s cn52xx;
 	struct cvmx_pciercx_cfg036_s cn52xxp1;
@@ -860,14 +1247,17 @@
 	struct cvmx_pciercx_cfg036_s cn66xx;
 	struct cvmx_pciercx_cfg036_s cn68xx;
 	struct cvmx_pciercx_cfg036_s cn68xxp1;
+	struct cvmx_pciercx_cfg036_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg037 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg037_s {
-		uint32_t reserved_14_31:18;
-		uint32_t tph:2;
-		uint32_t reserved_11_11:1;
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint32_t reserved_20_31:12;
+		uint32_t obffs:2;
+		uint32_t reserved_12_17:6;
+		uint32_t ltrs:1;
 		uint32_t noroprpr:1;
 		uint32_t atom128s:1;
 		uint32_t atom64s:1;
@@ -876,16 +1266,37 @@
 		uint32_t reserved_5_5:1;
 		uint32_t ctds:1;
 		uint32_t ctrs:4;
+#else
+		uint32_t ctrs:4;
+		uint32_t ctds:1;
+		uint32_t reserved_5_5:1;
+		uint32_t atom_ops:1;
+		uint32_t atom32s:1;
+		uint32_t atom64s:1;
+		uint32_t atom128s:1;
+		uint32_t noroprpr:1;
+		uint32_t ltrs:1;
+		uint32_t reserved_12_17:6;
+		uint32_t obffs:2;
+		uint32_t reserved_20_31:12;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg037_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_5_31:27;
 		uint32_t ctds:1;
 		uint32_t ctrs:4;
+#else
+		uint32_t ctrs:4;
+		uint32_t ctds:1;
+		uint32_t reserved_5_31:27;
+#endif
 	} cn52xx;
 	struct cvmx_pciercx_cfg037_cn52xx cn52xxp1;
 	struct cvmx_pciercx_cfg037_cn52xx cn56xx;
 	struct cvmx_pciercx_cfg037_cn52xx cn56xxp1;
 	struct cvmx_pciercx_cfg037_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_14_31:18;
 		uint32_t tph:2;
 		uint32_t reserved_11_11:1;
@@ -897,10 +1308,24 @@
 		uint32_t ari_fw:1;
 		uint32_t ctds:1;
 		uint32_t ctrs:4;
+#else
+		uint32_t ctrs:4;
+		uint32_t ctds:1;
+		uint32_t ari_fw:1;
+		uint32_t atom_ops:1;
+		uint32_t atom32s:1;
+		uint32_t atom64s:1;
+		uint32_t atom128s:1;
+		uint32_t noroprpr:1;
+		uint32_t reserved_11_11:1;
+		uint32_t tph:2;
+		uint32_t reserved_14_31:18;
+#endif
 	} cn61xx;
 	struct cvmx_pciercx_cfg037_cn52xx cn63xx;
 	struct cvmx_pciercx_cfg037_cn52xx cn63xxp1;
 	struct cvmx_pciercx_cfg037_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_14_31:18;
 		uint32_t tph:2;
 		uint32_t reserved_11_11:1;
@@ -912,14 +1337,100 @@
 		uint32_t ari:1;
 		uint32_t ctds:1;
 		uint32_t ctrs:4;
+#else
+		uint32_t ctrs:4;
+		uint32_t ctds:1;
+		uint32_t ari:1;
+		uint32_t atom_ops:1;
+		uint32_t atom32s:1;
+		uint32_t atom64s:1;
+		uint32_t atom128s:1;
+		uint32_t noroprpr:1;
+		uint32_t reserved_11_11:1;
+		uint32_t tph:2;
+		uint32_t reserved_14_31:18;
+#endif
 	} cn66xx;
 	struct cvmx_pciercx_cfg037_cn66xx cn68xx;
 	struct cvmx_pciercx_cfg037_cn66xx cn68xxp1;
+	struct cvmx_pciercx_cfg037_cnf71xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint32_t reserved_20_31:12;
+		uint32_t obffs:2;
+		uint32_t reserved_14_17:4;
+		uint32_t tphs:2;
+		uint32_t ltrs:1;
+		uint32_t noroprpr:1;
+		uint32_t atom128s:1;
+		uint32_t atom64s:1;
+		uint32_t atom32s:1;
+		uint32_t atom_ops:1;
+		uint32_t ari_fw:1;
+		uint32_t ctds:1;
+		uint32_t ctrs:4;
+#else
+		uint32_t ctrs:4;
+		uint32_t ctds:1;
+		uint32_t ari_fw:1;
+		uint32_t atom_ops:1;
+		uint32_t atom32s:1;
+		uint32_t atom64s:1;
+		uint32_t atom128s:1;
+		uint32_t noroprpr:1;
+		uint32_t ltrs:1;
+		uint32_t tphs:2;
+		uint32_t reserved_14_17:4;
+		uint32_t obffs:2;
+		uint32_t reserved_20_31:12;
+#endif
+	} cnf71xx;
 };
 
 union cvmx_pciercx_cfg038 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg038_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint32_t reserved_15_31:17;
+		uint32_t obffe:2;
+		uint32_t reserved_11_12:2;
+		uint32_t ltre:1;
+		uint32_t id0_cp:1;
+		uint32_t id0_rq:1;
+		uint32_t atom_op_eb:1;
+		uint32_t atom_op:1;
+		uint32_t ari:1;
+		uint32_t ctd:1;
+		uint32_t ctv:4;
+#else
+		uint32_t ctv:4;
+		uint32_t ctd:1;
+		uint32_t ari:1;
+		uint32_t atom_op:1;
+		uint32_t atom_op_eb:1;
+		uint32_t id0_rq:1;
+		uint32_t id0_cp:1;
+		uint32_t ltre:1;
+		uint32_t reserved_11_12:2;
+		uint32_t obffe:2;
+		uint32_t reserved_15_31:17;
+#endif
+	} s;
+	struct cvmx_pciercx_cfg038_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint32_t reserved_5_31:27;
+		uint32_t ctd:1;
+		uint32_t ctv:4;
+#else
+		uint32_t ctv:4;
+		uint32_t ctd:1;
+		uint32_t reserved_5_31:27;
+#endif
+	} cn52xx;
+	struct cvmx_pciercx_cfg038_cn52xx cn52xxp1;
+	struct cvmx_pciercx_cfg038_cn52xx cn56xx;
+	struct cvmx_pciercx_cfg038_cn52xx cn56xxp1;
+	struct cvmx_pciercx_cfg038_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_10_31:22;
 		uint32_t id0_cp:1;
 		uint32_t id0_rq:1;
@@ -928,33 +1439,46 @@
 		uint32_t ari:1;
 		uint32_t ctd:1;
 		uint32_t ctv:4;
-	} s;
-	struct cvmx_pciercx_cfg038_cn52xx {
-		uint32_t reserved_5_31:27;
-		uint32_t ctd:1;
+#else
 		uint32_t ctv:4;
-	} cn52xx;
-	struct cvmx_pciercx_cfg038_cn52xx cn52xxp1;
-	struct cvmx_pciercx_cfg038_cn52xx cn56xx;
-	struct cvmx_pciercx_cfg038_cn52xx cn56xxp1;
-	struct cvmx_pciercx_cfg038_s cn61xx;
+		uint32_t ctd:1;
+		uint32_t ari:1;
+		uint32_t atom_op:1;
+		uint32_t atom_op_eb:1;
+		uint32_t id0_rq:1;
+		uint32_t id0_cp:1;
+		uint32_t reserved_10_31:22;
+#endif
+	} cn61xx;
 	struct cvmx_pciercx_cfg038_cn52xx cn63xx;
 	struct cvmx_pciercx_cfg038_cn52xx cn63xxp1;
-	struct cvmx_pciercx_cfg038_s cn66xx;
-	struct cvmx_pciercx_cfg038_s cn68xx;
-	struct cvmx_pciercx_cfg038_s cn68xxp1;
+	struct cvmx_pciercx_cfg038_cn61xx cn66xx;
+	struct cvmx_pciercx_cfg038_cn61xx cn68xx;
+	struct cvmx_pciercx_cfg038_cn61xx cn68xxp1;
+	struct cvmx_pciercx_cfg038_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg039 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg039_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_9_31:23;
 		uint32_t cls:1;
 		uint32_t slsv:7;
 		uint32_t reserved_0_0:1;
+#else
+		uint32_t reserved_0_0:1;
+		uint32_t slsv:7;
+		uint32_t cls:1;
+		uint32_t reserved_9_31:23;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg039_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_0_31:32;
+#else
+		uint32_t reserved_0_31:32;
+#endif
 	} cn52xx;
 	struct cvmx_pciercx_cfg039_cn52xx cn52xxp1;
 	struct cvmx_pciercx_cfg039_cn52xx cn56xx;
@@ -965,11 +1489,13 @@
 	struct cvmx_pciercx_cfg039_s cn66xx;
 	struct cvmx_pciercx_cfg039_s cn68xx;
 	struct cvmx_pciercx_cfg039_s cn68xxp1;
+	struct cvmx_pciercx_cfg039_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg040 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg040_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_17_31:15;
 		uint32_t cdl:1;
 		uint32_t reserved_13_15:3;
@@ -981,9 +1507,26 @@
 		uint32_t hasd:1;
 		uint32_t ec:1;
 		uint32_t tls:4;
+#else
+		uint32_t tls:4;
+		uint32_t ec:1;
+		uint32_t hasd:1;
+		uint32_t sde:1;
+		uint32_t tm:3;
+		uint32_t emc:1;
+		uint32_t csos:1;
+		uint32_t cde:1;
+		uint32_t reserved_13_15:3;
+		uint32_t cdl:1;
+		uint32_t reserved_17_31:15;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg040_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_0_31:32;
+#else
+		uint32_t reserved_0_31:32;
+#endif
 	} cn52xx;
 	struct cvmx_pciercx_cfg040_cn52xx cn52xxp1;
 	struct cvmx_pciercx_cfg040_cn52xx cn56xx;
@@ -994,12 +1537,17 @@
 	struct cvmx_pciercx_cfg040_s cn66xx;
 	struct cvmx_pciercx_cfg040_s cn68xx;
 	struct cvmx_pciercx_cfg040_s cn68xxp1;
+	struct cvmx_pciercx_cfg040_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg041 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg041_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_0_31:32;
+#else
+		uint32_t reserved_0_31:32;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg041_s cn52xx;
 	struct cvmx_pciercx_cfg041_s cn52xxp1;
@@ -1011,12 +1559,17 @@
 	struct cvmx_pciercx_cfg041_s cn66xx;
 	struct cvmx_pciercx_cfg041_s cn68xx;
 	struct cvmx_pciercx_cfg041_s cn68xxp1;
+	struct cvmx_pciercx_cfg041_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg042 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg042_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_0_31:32;
+#else
+		uint32_t reserved_0_31:32;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg042_s cn52xx;
 	struct cvmx_pciercx_cfg042_s cn52xxp1;
@@ -1028,14 +1581,21 @@
 	struct cvmx_pciercx_cfg042_s cn66xx;
 	struct cvmx_pciercx_cfg042_s cn68xx;
 	struct cvmx_pciercx_cfg042_s cn68xxp1;
+	struct cvmx_pciercx_cfg042_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg064 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg064_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t nco:12;
 		uint32_t cv:4;
 		uint32_t pcieec:16;
+#else
+		uint32_t pcieec:16;
+		uint32_t cv:4;
+		uint32_t nco:12;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg064_s cn52xx;
 	struct cvmx_pciercx_cfg064_s cn52xxp1;
@@ -1047,11 +1607,90 @@
 	struct cvmx_pciercx_cfg064_s cn66xx;
 	struct cvmx_pciercx_cfg064_s cn68xx;
 	struct cvmx_pciercx_cfg064_s cn68xxp1;
+	struct cvmx_pciercx_cfg064_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg065 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg065_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint32_t reserved_25_31:7;
+		uint32_t uatombs:1;
+		uint32_t reserved_23_23:1;
+		uint32_t ucies:1;
+		uint32_t reserved_21_21:1;
+		uint32_t ures:1;
+		uint32_t ecrces:1;
+		uint32_t mtlps:1;
+		uint32_t ros:1;
+		uint32_t ucs:1;
+		uint32_t cas:1;
+		uint32_t cts:1;
+		uint32_t fcpes:1;
+		uint32_t ptlps:1;
+		uint32_t reserved_6_11:6;
+		uint32_t sdes:1;
+		uint32_t dlpes:1;
+		uint32_t reserved_0_3:4;
+#else
+		uint32_t reserved_0_3:4;
+		uint32_t dlpes:1;
+		uint32_t sdes:1;
+		uint32_t reserved_6_11:6;
+		uint32_t ptlps:1;
+		uint32_t fcpes:1;
+		uint32_t cts:1;
+		uint32_t cas:1;
+		uint32_t ucs:1;
+		uint32_t ros:1;
+		uint32_t mtlps:1;
+		uint32_t ecrces:1;
+		uint32_t ures:1;
+		uint32_t reserved_21_21:1;
+		uint32_t ucies:1;
+		uint32_t reserved_23_23:1;
+		uint32_t uatombs:1;
+		uint32_t reserved_25_31:7;
+#endif
+	} s;
+	struct cvmx_pciercx_cfg065_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint32_t reserved_21_31:11;
+		uint32_t ures:1;
+		uint32_t ecrces:1;
+		uint32_t mtlps:1;
+		uint32_t ros:1;
+		uint32_t ucs:1;
+		uint32_t cas:1;
+		uint32_t cts:1;
+		uint32_t fcpes:1;
+		uint32_t ptlps:1;
+		uint32_t reserved_6_11:6;
+		uint32_t sdes:1;
+		uint32_t dlpes:1;
+		uint32_t reserved_0_3:4;
+#else
+		uint32_t reserved_0_3:4;
+		uint32_t dlpes:1;
+		uint32_t sdes:1;
+		uint32_t reserved_6_11:6;
+		uint32_t ptlps:1;
+		uint32_t fcpes:1;
+		uint32_t cts:1;
+		uint32_t cas:1;
+		uint32_t ucs:1;
+		uint32_t ros:1;
+		uint32_t mtlps:1;
+		uint32_t ecrces:1;
+		uint32_t ures:1;
+		uint32_t reserved_21_31:11;
+#endif
+	} cn52xx;
+	struct cvmx_pciercx_cfg065_cn52xx cn52xxp1;
+	struct cvmx_pciercx_cfg065_cn52xx cn56xx;
+	struct cvmx_pciercx_cfg065_cn52xx cn56xxp1;
+	struct cvmx_pciercx_cfg065_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_25_31:7;
 		uint32_t uatombs:1;
 		uint32_t reserved_21_23:3;
@@ -1068,37 +1707,114 @@
 		uint32_t sdes:1;
 		uint32_t dlpes:1;
 		uint32_t reserved_0_3:4;
-	} s;
-	struct cvmx_pciercx_cfg065_cn52xx {
-		uint32_t reserved_21_31:11;
-		uint32_t ures:1;
-		uint32_t ecrces:1;
-		uint32_t mtlps:1;
-		uint32_t ros:1;
-		uint32_t ucs:1;
-		uint32_t cas:1;
-		uint32_t cts:1;
-		uint32_t fcpes:1;
-		uint32_t ptlps:1;
-		uint32_t reserved_6_11:6;
-		uint32_t sdes:1;
-		uint32_t dlpes:1;
+#else
 		uint32_t reserved_0_3:4;
-	} cn52xx;
-	struct cvmx_pciercx_cfg065_cn52xx cn52xxp1;
-	struct cvmx_pciercx_cfg065_cn52xx cn56xx;
-	struct cvmx_pciercx_cfg065_cn52xx cn56xxp1;
-	struct cvmx_pciercx_cfg065_s cn61xx;
+		uint32_t dlpes:1;
+		uint32_t sdes:1;
+		uint32_t reserved_6_11:6;
+		uint32_t ptlps:1;
+		uint32_t fcpes:1;
+		uint32_t cts:1;
+		uint32_t cas:1;
+		uint32_t ucs:1;
+		uint32_t ros:1;
+		uint32_t mtlps:1;
+		uint32_t ecrces:1;
+		uint32_t ures:1;
+		uint32_t reserved_21_23:3;
+		uint32_t uatombs:1;
+		uint32_t reserved_25_31:7;
+#endif
+	} cn61xx;
 	struct cvmx_pciercx_cfg065_cn52xx cn63xx;
 	struct cvmx_pciercx_cfg065_cn52xx cn63xxp1;
-	struct cvmx_pciercx_cfg065_s cn66xx;
-	struct cvmx_pciercx_cfg065_s cn68xx;
+	struct cvmx_pciercx_cfg065_cn61xx cn66xx;
+	struct cvmx_pciercx_cfg065_cn61xx cn68xx;
 	struct cvmx_pciercx_cfg065_cn52xx cn68xxp1;
+	struct cvmx_pciercx_cfg065_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg066 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg066_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint32_t reserved_25_31:7;
+		uint32_t uatombm:1;
+		uint32_t reserved_23_23:1;
+		uint32_t uciem:1;
+		uint32_t reserved_21_21:1;
+		uint32_t urem:1;
+		uint32_t ecrcem:1;
+		uint32_t mtlpm:1;
+		uint32_t rom:1;
+		uint32_t ucm:1;
+		uint32_t cam:1;
+		uint32_t ctm:1;
+		uint32_t fcpem:1;
+		uint32_t ptlpm:1;
+		uint32_t reserved_6_11:6;
+		uint32_t sdem:1;
+		uint32_t dlpem:1;
+		uint32_t reserved_0_3:4;
+#else
+		uint32_t reserved_0_3:4;
+		uint32_t dlpem:1;
+		uint32_t sdem:1;
+		uint32_t reserved_6_11:6;
+		uint32_t ptlpm:1;
+		uint32_t fcpem:1;
+		uint32_t ctm:1;
+		uint32_t cam:1;
+		uint32_t ucm:1;
+		uint32_t rom:1;
+		uint32_t mtlpm:1;
+		uint32_t ecrcem:1;
+		uint32_t urem:1;
+		uint32_t reserved_21_21:1;
+		uint32_t uciem:1;
+		uint32_t reserved_23_23:1;
+		uint32_t uatombm:1;
+		uint32_t reserved_25_31:7;
+#endif
+	} s;
+	struct cvmx_pciercx_cfg066_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint32_t reserved_21_31:11;
+		uint32_t urem:1;
+		uint32_t ecrcem:1;
+		uint32_t mtlpm:1;
+		uint32_t rom:1;
+		uint32_t ucm:1;
+		uint32_t cam:1;
+		uint32_t ctm:1;
+		uint32_t fcpem:1;
+		uint32_t ptlpm:1;
+		uint32_t reserved_6_11:6;
+		uint32_t sdem:1;
+		uint32_t dlpem:1;
+		uint32_t reserved_0_3:4;
+#else
+		uint32_t reserved_0_3:4;
+		uint32_t dlpem:1;
+		uint32_t sdem:1;
+		uint32_t reserved_6_11:6;
+		uint32_t ptlpm:1;
+		uint32_t fcpem:1;
+		uint32_t ctm:1;
+		uint32_t cam:1;
+		uint32_t ucm:1;
+		uint32_t rom:1;
+		uint32_t mtlpm:1;
+		uint32_t ecrcem:1;
+		uint32_t urem:1;
+		uint32_t reserved_21_31:11;
+#endif
+	} cn52xx;
+	struct cvmx_pciercx_cfg066_cn52xx cn52xxp1;
+	struct cvmx_pciercx_cfg066_cn52xx cn56xx;
+	struct cvmx_pciercx_cfg066_cn52xx cn56xxp1;
+	struct cvmx_pciercx_cfg066_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_25_31:7;
 		uint32_t uatombm:1;
 		uint32_t reserved_21_23:3;
@@ -1115,37 +1831,114 @@
 		uint32_t sdem:1;
 		uint32_t dlpem:1;
 		uint32_t reserved_0_3:4;
-	} s;
-	struct cvmx_pciercx_cfg066_cn52xx {
-		uint32_t reserved_21_31:11;
-		uint32_t urem:1;
-		uint32_t ecrcem:1;
-		uint32_t mtlpm:1;
-		uint32_t rom:1;
-		uint32_t ucm:1;
-		uint32_t cam:1;
-		uint32_t ctm:1;
-		uint32_t fcpem:1;
-		uint32_t ptlpm:1;
-		uint32_t reserved_6_11:6;
-		uint32_t sdem:1;
-		uint32_t dlpem:1;
+#else
 		uint32_t reserved_0_3:4;
-	} cn52xx;
-	struct cvmx_pciercx_cfg066_cn52xx cn52xxp1;
-	struct cvmx_pciercx_cfg066_cn52xx cn56xx;
-	struct cvmx_pciercx_cfg066_cn52xx cn56xxp1;
-	struct cvmx_pciercx_cfg066_s cn61xx;
+		uint32_t dlpem:1;
+		uint32_t sdem:1;
+		uint32_t reserved_6_11:6;
+		uint32_t ptlpm:1;
+		uint32_t fcpem:1;
+		uint32_t ctm:1;
+		uint32_t cam:1;
+		uint32_t ucm:1;
+		uint32_t rom:1;
+		uint32_t mtlpm:1;
+		uint32_t ecrcem:1;
+		uint32_t urem:1;
+		uint32_t reserved_21_23:3;
+		uint32_t uatombm:1;
+		uint32_t reserved_25_31:7;
+#endif
+	} cn61xx;
 	struct cvmx_pciercx_cfg066_cn52xx cn63xx;
 	struct cvmx_pciercx_cfg066_cn52xx cn63xxp1;
-	struct cvmx_pciercx_cfg066_s cn66xx;
-	struct cvmx_pciercx_cfg066_s cn68xx;
+	struct cvmx_pciercx_cfg066_cn61xx cn66xx;
+	struct cvmx_pciercx_cfg066_cn61xx cn68xx;
 	struct cvmx_pciercx_cfg066_cn52xx cn68xxp1;
+	struct cvmx_pciercx_cfg066_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg067 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg067_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint32_t reserved_25_31:7;
+		uint32_t uatombs:1;
+		uint32_t reserved_23_23:1;
+		uint32_t ucies:1;
+		uint32_t reserved_21_21:1;
+		uint32_t ures:1;
+		uint32_t ecrces:1;
+		uint32_t mtlps:1;
+		uint32_t ros:1;
+		uint32_t ucs:1;
+		uint32_t cas:1;
+		uint32_t cts:1;
+		uint32_t fcpes:1;
+		uint32_t ptlps:1;
+		uint32_t reserved_6_11:6;
+		uint32_t sdes:1;
+		uint32_t dlpes:1;
+		uint32_t reserved_0_3:4;
+#else
+		uint32_t reserved_0_3:4;
+		uint32_t dlpes:1;
+		uint32_t sdes:1;
+		uint32_t reserved_6_11:6;
+		uint32_t ptlps:1;
+		uint32_t fcpes:1;
+		uint32_t cts:1;
+		uint32_t cas:1;
+		uint32_t ucs:1;
+		uint32_t ros:1;
+		uint32_t mtlps:1;
+		uint32_t ecrces:1;
+		uint32_t ures:1;
+		uint32_t reserved_21_21:1;
+		uint32_t ucies:1;
+		uint32_t reserved_23_23:1;
+		uint32_t uatombs:1;
+		uint32_t reserved_25_31:7;
+#endif
+	} s;
+	struct cvmx_pciercx_cfg067_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint32_t reserved_21_31:11;
+		uint32_t ures:1;
+		uint32_t ecrces:1;
+		uint32_t mtlps:1;
+		uint32_t ros:1;
+		uint32_t ucs:1;
+		uint32_t cas:1;
+		uint32_t cts:1;
+		uint32_t fcpes:1;
+		uint32_t ptlps:1;
+		uint32_t reserved_6_11:6;
+		uint32_t sdes:1;
+		uint32_t dlpes:1;
+		uint32_t reserved_0_3:4;
+#else
+		uint32_t reserved_0_3:4;
+		uint32_t dlpes:1;
+		uint32_t sdes:1;
+		uint32_t reserved_6_11:6;
+		uint32_t ptlps:1;
+		uint32_t fcpes:1;
+		uint32_t cts:1;
+		uint32_t cas:1;
+		uint32_t ucs:1;
+		uint32_t ros:1;
+		uint32_t mtlps:1;
+		uint32_t ecrces:1;
+		uint32_t ures:1;
+		uint32_t reserved_21_31:11;
+#endif
+	} cn52xx;
+	struct cvmx_pciercx_cfg067_cn52xx cn52xxp1;
+	struct cvmx_pciercx_cfg067_cn52xx cn56xx;
+	struct cvmx_pciercx_cfg067_cn52xx cn56xxp1;
+	struct cvmx_pciercx_cfg067_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_25_31:7;
 		uint32_t uatombs:1;
 		uint32_t reserved_21_23:3;
@@ -1162,37 +1955,62 @@
 		uint32_t sdes:1;
 		uint32_t dlpes:1;
 		uint32_t reserved_0_3:4;
-	} s;
-	struct cvmx_pciercx_cfg067_cn52xx {
-		uint32_t reserved_21_31:11;
-		uint32_t ures:1;
-		uint32_t ecrces:1;
-		uint32_t mtlps:1;
-		uint32_t ros:1;
-		uint32_t ucs:1;
-		uint32_t cas:1;
-		uint32_t cts:1;
-		uint32_t fcpes:1;
-		uint32_t ptlps:1;
-		uint32_t reserved_6_11:6;
-		uint32_t sdes:1;
-		uint32_t dlpes:1;
+#else
 		uint32_t reserved_0_3:4;
-	} cn52xx;
-	struct cvmx_pciercx_cfg067_cn52xx cn52xxp1;
-	struct cvmx_pciercx_cfg067_cn52xx cn56xx;
-	struct cvmx_pciercx_cfg067_cn52xx cn56xxp1;
-	struct cvmx_pciercx_cfg067_s cn61xx;
+		uint32_t dlpes:1;
+		uint32_t sdes:1;
+		uint32_t reserved_6_11:6;
+		uint32_t ptlps:1;
+		uint32_t fcpes:1;
+		uint32_t cts:1;
+		uint32_t cas:1;
+		uint32_t ucs:1;
+		uint32_t ros:1;
+		uint32_t mtlps:1;
+		uint32_t ecrces:1;
+		uint32_t ures:1;
+		uint32_t reserved_21_23:3;
+		uint32_t uatombs:1;
+		uint32_t reserved_25_31:7;
+#endif
+	} cn61xx;
 	struct cvmx_pciercx_cfg067_cn52xx cn63xx;
 	struct cvmx_pciercx_cfg067_cn52xx cn63xxp1;
-	struct cvmx_pciercx_cfg067_s cn66xx;
-	struct cvmx_pciercx_cfg067_s cn68xx;
+	struct cvmx_pciercx_cfg067_cn61xx cn66xx;
+	struct cvmx_pciercx_cfg067_cn61xx cn68xx;
 	struct cvmx_pciercx_cfg067_cn52xx cn68xxp1;
+	struct cvmx_pciercx_cfg067_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg068 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg068_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint32_t reserved_15_31:17;
+		uint32_t cies:1;
+		uint32_t anfes:1;
+		uint32_t rtts:1;
+		uint32_t reserved_9_11:3;
+		uint32_t rnrs:1;
+		uint32_t bdllps:1;
+		uint32_t btlps:1;
+		uint32_t reserved_1_5:5;
+		uint32_t res:1;
+#else
+		uint32_t res:1;
+		uint32_t reserved_1_5:5;
+		uint32_t btlps:1;
+		uint32_t bdllps:1;
+		uint32_t rnrs:1;
+		uint32_t reserved_9_11:3;
+		uint32_t rtts:1;
+		uint32_t anfes:1;
+		uint32_t cies:1;
+		uint32_t reserved_15_31:17;
+#endif
+	} s;
+	struct cvmx_pciercx_cfg068_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_14_31:18;
 		uint32_t anfes:1;
 		uint32_t rtts:1;
@@ -1202,22 +2020,59 @@
 		uint32_t btlps:1;
 		uint32_t reserved_1_5:5;
 		uint32_t res:1;
-	} s;
-	struct cvmx_pciercx_cfg068_s cn52xx;
-	struct cvmx_pciercx_cfg068_s cn52xxp1;
-	struct cvmx_pciercx_cfg068_s cn56xx;
-	struct cvmx_pciercx_cfg068_s cn56xxp1;
-	struct cvmx_pciercx_cfg068_s cn61xx;
-	struct cvmx_pciercx_cfg068_s cn63xx;
-	struct cvmx_pciercx_cfg068_s cn63xxp1;
-	struct cvmx_pciercx_cfg068_s cn66xx;
-	struct cvmx_pciercx_cfg068_s cn68xx;
-	struct cvmx_pciercx_cfg068_s cn68xxp1;
+#else
+		uint32_t res:1;
+		uint32_t reserved_1_5:5;
+		uint32_t btlps:1;
+		uint32_t bdllps:1;
+		uint32_t rnrs:1;
+		uint32_t reserved_9_11:3;
+		uint32_t rtts:1;
+		uint32_t anfes:1;
+		uint32_t reserved_14_31:18;
+#endif
+	} cn52xx;
+	struct cvmx_pciercx_cfg068_cn52xx cn52xxp1;
+	struct cvmx_pciercx_cfg068_cn52xx cn56xx;
+	struct cvmx_pciercx_cfg068_cn52xx cn56xxp1;
+	struct cvmx_pciercx_cfg068_cn52xx cn61xx;
+	struct cvmx_pciercx_cfg068_cn52xx cn63xx;
+	struct cvmx_pciercx_cfg068_cn52xx cn63xxp1;
+	struct cvmx_pciercx_cfg068_cn52xx cn66xx;
+	struct cvmx_pciercx_cfg068_cn52xx cn68xx;
+	struct cvmx_pciercx_cfg068_cn52xx cn68xxp1;
+	struct cvmx_pciercx_cfg068_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg069 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg069_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint32_t reserved_15_31:17;
+		uint32_t ciem:1;
+		uint32_t anfem:1;
+		uint32_t rttm:1;
+		uint32_t reserved_9_11:3;
+		uint32_t rnrm:1;
+		uint32_t bdllpm:1;
+		uint32_t btlpm:1;
+		uint32_t reserved_1_5:5;
+		uint32_t rem:1;
+#else
+		uint32_t rem:1;
+		uint32_t reserved_1_5:5;
+		uint32_t btlpm:1;
+		uint32_t bdllpm:1;
+		uint32_t rnrm:1;
+		uint32_t reserved_9_11:3;
+		uint32_t rttm:1;
+		uint32_t anfem:1;
+		uint32_t ciem:1;
+		uint32_t reserved_15_31:17;
+#endif
+	} s;
+	struct cvmx_pciercx_cfg069_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_14_31:18;
 		uint32_t anfem:1;
 		uint32_t rttm:1;
@@ -1227,28 +2082,48 @@
 		uint32_t btlpm:1;
 		uint32_t reserved_1_5:5;
 		uint32_t rem:1;
-	} s;
-	struct cvmx_pciercx_cfg069_s cn52xx;
-	struct cvmx_pciercx_cfg069_s cn52xxp1;
-	struct cvmx_pciercx_cfg069_s cn56xx;
-	struct cvmx_pciercx_cfg069_s cn56xxp1;
-	struct cvmx_pciercx_cfg069_s cn61xx;
-	struct cvmx_pciercx_cfg069_s cn63xx;
-	struct cvmx_pciercx_cfg069_s cn63xxp1;
-	struct cvmx_pciercx_cfg069_s cn66xx;
-	struct cvmx_pciercx_cfg069_s cn68xx;
-	struct cvmx_pciercx_cfg069_s cn68xxp1;
+#else
+		uint32_t rem:1;
+		uint32_t reserved_1_5:5;
+		uint32_t btlpm:1;
+		uint32_t bdllpm:1;
+		uint32_t rnrm:1;
+		uint32_t reserved_9_11:3;
+		uint32_t rttm:1;
+		uint32_t anfem:1;
+		uint32_t reserved_14_31:18;
+#endif
+	} cn52xx;
+	struct cvmx_pciercx_cfg069_cn52xx cn52xxp1;
+	struct cvmx_pciercx_cfg069_cn52xx cn56xx;
+	struct cvmx_pciercx_cfg069_cn52xx cn56xxp1;
+	struct cvmx_pciercx_cfg069_cn52xx cn61xx;
+	struct cvmx_pciercx_cfg069_cn52xx cn63xx;
+	struct cvmx_pciercx_cfg069_cn52xx cn63xxp1;
+	struct cvmx_pciercx_cfg069_cn52xx cn66xx;
+	struct cvmx_pciercx_cfg069_cn52xx cn68xx;
+	struct cvmx_pciercx_cfg069_cn52xx cn68xxp1;
+	struct cvmx_pciercx_cfg069_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg070 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg070_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_9_31:23;
 		uint32_t ce:1;
 		uint32_t cc:1;
 		uint32_t ge:1;
 		uint32_t gc:1;
 		uint32_t fep:5;
+#else
+		uint32_t fep:5;
+		uint32_t gc:1;
+		uint32_t ge:1;
+		uint32_t cc:1;
+		uint32_t ce:1;
+		uint32_t reserved_9_31:23;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg070_s cn52xx;
 	struct cvmx_pciercx_cfg070_s cn52xxp1;
@@ -1260,12 +2135,17 @@
 	struct cvmx_pciercx_cfg070_s cn66xx;
 	struct cvmx_pciercx_cfg070_s cn68xx;
 	struct cvmx_pciercx_cfg070_s cn68xxp1;
+	struct cvmx_pciercx_cfg070_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg071 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg071_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t dword1:32;
+#else
+		uint32_t dword1:32;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg071_s cn52xx;
 	struct cvmx_pciercx_cfg071_s cn52xxp1;
@@ -1277,12 +2157,17 @@
 	struct cvmx_pciercx_cfg071_s cn66xx;
 	struct cvmx_pciercx_cfg071_s cn68xx;
 	struct cvmx_pciercx_cfg071_s cn68xxp1;
+	struct cvmx_pciercx_cfg071_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg072 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg072_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t dword2:32;
+#else
+		uint32_t dword2:32;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg072_s cn52xx;
 	struct cvmx_pciercx_cfg072_s cn52xxp1;
@@ -1294,12 +2179,17 @@
 	struct cvmx_pciercx_cfg072_s cn66xx;
 	struct cvmx_pciercx_cfg072_s cn68xx;
 	struct cvmx_pciercx_cfg072_s cn68xxp1;
+	struct cvmx_pciercx_cfg072_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg073 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg073_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t dword3:32;
+#else
+		uint32_t dword3:32;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg073_s cn52xx;
 	struct cvmx_pciercx_cfg073_s cn52xxp1;
@@ -1311,12 +2201,17 @@
 	struct cvmx_pciercx_cfg073_s cn66xx;
 	struct cvmx_pciercx_cfg073_s cn68xx;
 	struct cvmx_pciercx_cfg073_s cn68xxp1;
+	struct cvmx_pciercx_cfg073_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg074 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg074_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t dword4:32;
+#else
+		uint32_t dword4:32;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg074_s cn52xx;
 	struct cvmx_pciercx_cfg074_s cn52xxp1;
@@ -1328,15 +2223,23 @@
 	struct cvmx_pciercx_cfg074_s cn66xx;
 	struct cvmx_pciercx_cfg074_s cn68xx;
 	struct cvmx_pciercx_cfg074_s cn68xxp1;
+	struct cvmx_pciercx_cfg074_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg075 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg075_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_3_31:29;
 		uint32_t fere:1;
 		uint32_t nfere:1;
 		uint32_t cere:1;
+#else
+		uint32_t cere:1;
+		uint32_t nfere:1;
+		uint32_t fere:1;
+		uint32_t reserved_3_31:29;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg075_s cn52xx;
 	struct cvmx_pciercx_cfg075_s cn52xxp1;
@@ -1348,11 +2251,13 @@
 	struct cvmx_pciercx_cfg075_s cn66xx;
 	struct cvmx_pciercx_cfg075_s cn68xx;
 	struct cvmx_pciercx_cfg075_s cn68xxp1;
+	struct cvmx_pciercx_cfg075_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg076 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg076_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t aeimn:5;
 		uint32_t reserved_7_26:20;
 		uint32_t femr:1;
@@ -1362,6 +2267,17 @@
 		uint32_t efnfr:1;
 		uint32_t multi_ecr:1;
 		uint32_t ecr:1;
+#else
+		uint32_t ecr:1;
+		uint32_t multi_ecr:1;
+		uint32_t efnfr:1;
+		uint32_t multi_efnfr:1;
+		uint32_t fuf:1;
+		uint32_t nfemr:1;
+		uint32_t femr:1;
+		uint32_t reserved_7_26:20;
+		uint32_t aeimn:5;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg076_s cn52xx;
 	struct cvmx_pciercx_cfg076_s cn52xxp1;
@@ -1373,13 +2289,19 @@
 	struct cvmx_pciercx_cfg076_s cn66xx;
 	struct cvmx_pciercx_cfg076_s cn68xx;
 	struct cvmx_pciercx_cfg076_s cn68xxp1;
+	struct cvmx_pciercx_cfg076_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg077 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg077_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t efnfsi:16;
 		uint32_t ecsi:16;
+#else
+		uint32_t ecsi:16;
+		uint32_t efnfsi:16;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg077_s cn52xx;
 	struct cvmx_pciercx_cfg077_s cn52xxp1;
@@ -1391,13 +2313,19 @@
 	struct cvmx_pciercx_cfg077_s cn66xx;
 	struct cvmx_pciercx_cfg077_s cn68xx;
 	struct cvmx_pciercx_cfg077_s cn68xxp1;
+	struct cvmx_pciercx_cfg077_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg448 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg448_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t rtl:16;
 		uint32_t rtltl:16;
+#else
+		uint32_t rtltl:16;
+		uint32_t rtl:16;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg448_s cn52xx;
 	struct cvmx_pciercx_cfg448_s cn52xxp1;
@@ -1409,12 +2337,17 @@
 	struct cvmx_pciercx_cfg448_s cn66xx;
 	struct cvmx_pciercx_cfg448_s cn68xx;
 	struct cvmx_pciercx_cfg448_s cn68xxp1;
+	struct cvmx_pciercx_cfg448_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg449 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg449_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t omr:32;
+#else
+		uint32_t omr:32;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg449_s cn52xx;
 	struct cvmx_pciercx_cfg449_s cn52xxp1;
@@ -1426,17 +2359,27 @@
 	struct cvmx_pciercx_cfg449_s cn66xx;
 	struct cvmx_pciercx_cfg449_s cn68xx;
 	struct cvmx_pciercx_cfg449_s cn68xxp1;
+	struct cvmx_pciercx_cfg449_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg450 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg450_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t lpec:8;
 		uint32_t reserved_22_23:2;
 		uint32_t link_state:6;
 		uint32_t force_link:1;
 		uint32_t reserved_8_14:7;
 		uint32_t link_num:8;
+#else
+		uint32_t link_num:8;
+		uint32_t reserved_8_14:7;
+		uint32_t force_link:1;
+		uint32_t link_state:6;
+		uint32_t reserved_22_23:2;
+		uint32_t lpec:8;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg450_s cn52xx;
 	struct cvmx_pciercx_cfg450_s cn52xxp1;
@@ -1448,11 +2391,13 @@
 	struct cvmx_pciercx_cfg450_s cn66xx;
 	struct cvmx_pciercx_cfg450_s cn68xx;
 	struct cvmx_pciercx_cfg450_s cn68xxp1;
+	struct cvmx_pciercx_cfg450_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg451 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg451_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_31_31:1;
 		uint32_t easpml1:1;
 		uint32_t l1el:3;
@@ -1460,14 +2405,32 @@
 		uint32_t n_fts_cc:8;
 		uint32_t n_fts:8;
 		uint32_t ack_freq:8;
+#else
+		uint32_t ack_freq:8;
+		uint32_t n_fts:8;
+		uint32_t n_fts_cc:8;
+		uint32_t l0el:3;
+		uint32_t l1el:3;
+		uint32_t easpml1:1;
+		uint32_t reserved_31_31:1;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg451_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_30_31:2;
 		uint32_t l1el:3;
 		uint32_t l0el:3;
 		uint32_t n_fts_cc:8;
 		uint32_t n_fts:8;
 		uint32_t ack_freq:8;
+#else
+		uint32_t ack_freq:8;
+		uint32_t n_fts:8;
+		uint32_t n_fts_cc:8;
+		uint32_t l0el:3;
+		uint32_t l1el:3;
+		uint32_t reserved_30_31:2;
+#endif
 	} cn52xx;
 	struct cvmx_pciercx_cfg451_cn52xx cn52xxp1;
 	struct cvmx_pciercx_cfg451_cn52xx cn56xx;
@@ -1478,11 +2441,13 @@
 	struct cvmx_pciercx_cfg451_s cn66xx;
 	struct cvmx_pciercx_cfg451_s cn68xx;
 	struct cvmx_pciercx_cfg451_s cn68xxp1;
+	struct cvmx_pciercx_cfg451_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg452 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg452_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_26_31:6;
 		uint32_t eccrc:1;
 		uint32_t reserved_22_24:3;
@@ -1496,12 +2461,28 @@
 		uint32_t le:1;
 		uint32_t sd:1;
 		uint32_t omr:1;
+#else
+		uint32_t omr:1;
+		uint32_t sd:1;
+		uint32_t le:1;
+		uint32_t ra:1;
+		uint32_t reserved_4_4:1;
+		uint32_t dllle:1;
+		uint32_t reserved_6_6:1;
+		uint32_t flm:1;
+		uint32_t reserved_8_15:8;
+		uint32_t lme:6;
+		uint32_t reserved_22_24:3;
+		uint32_t eccrc:1;
+		uint32_t reserved_26_31:6;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg452_s cn52xx;
 	struct cvmx_pciercx_cfg452_s cn52xxp1;
 	struct cvmx_pciercx_cfg452_s cn56xx;
 	struct cvmx_pciercx_cfg452_s cn56xxp1;
 	struct cvmx_pciercx_cfg452_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_22_31:10;
 		uint32_t lme:6;
 		uint32_t reserved_8_15:8;
@@ -1513,22 +2494,44 @@
 		uint32_t le:1;
 		uint32_t sd:1;
 		uint32_t omr:1;
+#else
+		uint32_t omr:1;
+		uint32_t sd:1;
+		uint32_t le:1;
+		uint32_t ra:1;
+		uint32_t reserved_4_4:1;
+		uint32_t dllle:1;
+		uint32_t reserved_6_6:1;
+		uint32_t flm:1;
+		uint32_t reserved_8_15:8;
+		uint32_t lme:6;
+		uint32_t reserved_22_31:10;
+#endif
 	} cn61xx;
 	struct cvmx_pciercx_cfg452_s cn63xx;
 	struct cvmx_pciercx_cfg452_s cn63xxp1;
 	struct cvmx_pciercx_cfg452_cn61xx cn66xx;
 	struct cvmx_pciercx_cfg452_cn61xx cn68xx;
 	struct cvmx_pciercx_cfg452_cn61xx cn68xxp1;
+	struct cvmx_pciercx_cfg452_cn61xx cnf71xx;
 };
 
 union cvmx_pciercx_cfg453 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg453_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t dlld:1;
 		uint32_t reserved_26_30:5;
 		uint32_t ack_nak:1;
 		uint32_t fcd:1;
 		uint32_t ilst:24;
+#else
+		uint32_t ilst:24;
+		uint32_t fcd:1;
+		uint32_t ack_nak:1;
+		uint32_t reserved_26_30:5;
+		uint32_t dlld:1;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg453_s cn52xx;
 	struct cvmx_pciercx_cfg453_s cn52xxp1;
@@ -1540,11 +2543,13 @@
 	struct cvmx_pciercx_cfg453_s cn66xx;
 	struct cvmx_pciercx_cfg453_s cn68xx;
 	struct cvmx_pciercx_cfg453_s cn68xxp1;
+	struct cvmx_pciercx_cfg453_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg454 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg454_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t cx_nfunc:3;
 		uint32_t tmfcwt:5;
 		uint32_t tmanlt:5;
@@ -1552,8 +2557,18 @@
 		uint32_t reserved_11_13:3;
 		uint32_t nskps:3;
 		uint32_t reserved_0_7:8;
+#else
+		uint32_t reserved_0_7:8;
+		uint32_t nskps:3;
+		uint32_t reserved_11_13:3;
+		uint32_t tmrt:5;
+		uint32_t tmanlt:5;
+		uint32_t tmfcwt:5;
+		uint32_t cx_nfunc:3;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg454_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_29_31:3;
 		uint32_t tmfcwt:5;
 		uint32_t tmanlt:5;
@@ -1562,28 +2577,49 @@
 		uint32_t nskps:3;
 		uint32_t reserved_4_7:4;
 		uint32_t ntss:4;
+#else
+		uint32_t ntss:4;
+		uint32_t reserved_4_7:4;
+		uint32_t nskps:3;
+		uint32_t reserved_11_13:3;
+		uint32_t tmrt:5;
+		uint32_t tmanlt:5;
+		uint32_t tmfcwt:5;
+		uint32_t reserved_29_31:3;
+#endif
 	} cn52xx;
 	struct cvmx_pciercx_cfg454_cn52xx cn52xxp1;
 	struct cvmx_pciercx_cfg454_cn52xx cn56xx;
 	struct cvmx_pciercx_cfg454_cn52xx cn56xxp1;
 	struct cvmx_pciercx_cfg454_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t cx_nfunc:3;
 		uint32_t tmfcwt:5;
 		uint32_t tmanlt:5;
 		uint32_t tmrt:5;
 		uint32_t reserved_8_13:6;
 		uint32_t mfuncn:8;
+#else
+		uint32_t mfuncn:8;
+		uint32_t reserved_8_13:6;
+		uint32_t tmrt:5;
+		uint32_t tmanlt:5;
+		uint32_t tmfcwt:5;
+		uint32_t cx_nfunc:3;
+#endif
 	} cn61xx;
 	struct cvmx_pciercx_cfg454_cn52xx cn63xx;
 	struct cvmx_pciercx_cfg454_cn52xx cn63xxp1;
 	struct cvmx_pciercx_cfg454_cn61xx cn66xx;
 	struct cvmx_pciercx_cfg454_cn61xx cn68xx;
 	struct cvmx_pciercx_cfg454_cn52xx cn68xxp1;
+	struct cvmx_pciercx_cfg454_cn61xx cnf71xx;
 };
 
 union cvmx_pciercx_cfg455 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg455_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t m_cfg0_filt:1;
 		uint32_t m_io_filt:1;
 		uint32_t msg_ctrl:1;
@@ -1603,6 +2639,27 @@
 		uint32_t dfcwt:1;
 		uint32_t reserved_11_14:4;
 		uint32_t skpiv:11;
+#else
+		uint32_t skpiv:11;
+		uint32_t reserved_11_14:4;
+		uint32_t dfcwt:1;
+		uint32_t m_fun:1;
+		uint32_t m_pois_filt:1;
+		uint32_t m_bar_match:1;
+		uint32_t m_cfg1_filt:1;
+		uint32_t m_lk_filt:1;
+		uint32_t m_cpl_tag_err:1;
+		uint32_t m_cpl_rid_err:1;
+		uint32_t m_cpl_fun_err:1;
+		uint32_t m_cpl_tc_err:1;
+		uint32_t m_cpl_attr_err:1;
+		uint32_t m_cpl_len_err:1;
+		uint32_t m_ecrc_filt:1;
+		uint32_t m_cpl_ecrc_filt:1;
+		uint32_t msg_ctrl:1;
+		uint32_t m_io_filt:1;
+		uint32_t m_cfg0_filt:1;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg455_s cn52xx;
 	struct cvmx_pciercx_cfg455_s cn52xxp1;
@@ -1614,21 +2671,36 @@
 	struct cvmx_pciercx_cfg455_s cn66xx;
 	struct cvmx_pciercx_cfg455_s cn68xx;
 	struct cvmx_pciercx_cfg455_s cn68xxp1;
+	struct cvmx_pciercx_cfg455_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg456 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg456_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_4_31:28;
 		uint32_t m_handle_flush:1;
 		uint32_t m_dabort_4ucpl:1;
 		uint32_t m_vend1_drp:1;
 		uint32_t m_vend0_drp:1;
+#else
+		uint32_t m_vend0_drp:1;
+		uint32_t m_vend1_drp:1;
+		uint32_t m_dabort_4ucpl:1;
+		uint32_t m_handle_flush:1;
+		uint32_t reserved_4_31:28;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg456_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_2_31:30;
 		uint32_t m_vend1_drp:1;
 		uint32_t m_vend0_drp:1;
+#else
+		uint32_t m_vend0_drp:1;
+		uint32_t m_vend1_drp:1;
+		uint32_t reserved_2_31:30;
+#endif
 	} cn52xx;
 	struct cvmx_pciercx_cfg456_cn52xx cn52xxp1;
 	struct cvmx_pciercx_cfg456_cn52xx cn56xx;
@@ -1639,12 +2711,17 @@
 	struct cvmx_pciercx_cfg456_s cn66xx;
 	struct cvmx_pciercx_cfg456_s cn68xx;
 	struct cvmx_pciercx_cfg456_cn52xx cn68xxp1;
+	struct cvmx_pciercx_cfg456_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg458 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg458_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t dbg_info_l32:32;
+#else
+		uint32_t dbg_info_l32:32;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg458_s cn52xx;
 	struct cvmx_pciercx_cfg458_s cn52xxp1;
@@ -1656,12 +2733,17 @@
 	struct cvmx_pciercx_cfg458_s cn66xx;
 	struct cvmx_pciercx_cfg458_s cn68xx;
 	struct cvmx_pciercx_cfg458_s cn68xxp1;
+	struct cvmx_pciercx_cfg458_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg459 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg459_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t dbg_info_u32:32;
+#else
+		uint32_t dbg_info_u32:32;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg459_s cn52xx;
 	struct cvmx_pciercx_cfg459_s cn52xxp1;
@@ -1673,14 +2755,21 @@
 	struct cvmx_pciercx_cfg459_s cn66xx;
 	struct cvmx_pciercx_cfg459_s cn68xx;
 	struct cvmx_pciercx_cfg459_s cn68xxp1;
+	struct cvmx_pciercx_cfg459_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg460 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg460_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_20_31:12;
 		uint32_t tphfcc:8;
 		uint32_t tpdfcc:12;
+#else
+		uint32_t tpdfcc:12;
+		uint32_t tphfcc:8;
+		uint32_t reserved_20_31:12;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg460_s cn52xx;
 	struct cvmx_pciercx_cfg460_s cn52xxp1;
@@ -1692,14 +2781,21 @@
 	struct cvmx_pciercx_cfg460_s cn66xx;
 	struct cvmx_pciercx_cfg460_s cn68xx;
 	struct cvmx_pciercx_cfg460_s cn68xxp1;
+	struct cvmx_pciercx_cfg460_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg461 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg461_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_20_31:12;
 		uint32_t tchfcc:8;
 		uint32_t tcdfcc:12;
+#else
+		uint32_t tcdfcc:12;
+		uint32_t tchfcc:8;
+		uint32_t reserved_20_31:12;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg461_s cn52xx;
 	struct cvmx_pciercx_cfg461_s cn52xxp1;
@@ -1711,14 +2807,21 @@
 	struct cvmx_pciercx_cfg461_s cn66xx;
 	struct cvmx_pciercx_cfg461_s cn68xx;
 	struct cvmx_pciercx_cfg461_s cn68xxp1;
+	struct cvmx_pciercx_cfg461_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg462 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg462_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_20_31:12;
 		uint32_t tchfcc:8;
 		uint32_t tcdfcc:12;
+#else
+		uint32_t tcdfcc:12;
+		uint32_t tchfcc:8;
+		uint32_t reserved_20_31:12;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg462_s cn52xx;
 	struct cvmx_pciercx_cfg462_s cn52xxp1;
@@ -1730,15 +2833,23 @@
 	struct cvmx_pciercx_cfg462_s cn66xx;
 	struct cvmx_pciercx_cfg462_s cn68xx;
 	struct cvmx_pciercx_cfg462_s cn68xxp1;
+	struct cvmx_pciercx_cfg462_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg463 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg463_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_3_31:29;
 		uint32_t rqne:1;
 		uint32_t trbne:1;
 		uint32_t rtlpfccnr:1;
+#else
+		uint32_t rtlpfccnr:1;
+		uint32_t trbne:1;
+		uint32_t rqne:1;
+		uint32_t reserved_3_31:29;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg463_s cn52xx;
 	struct cvmx_pciercx_cfg463_s cn52xxp1;
@@ -1750,15 +2861,23 @@
 	struct cvmx_pciercx_cfg463_s cn66xx;
 	struct cvmx_pciercx_cfg463_s cn68xx;
 	struct cvmx_pciercx_cfg463_s cn68xxp1;
+	struct cvmx_pciercx_cfg463_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg464 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg464_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t wrr_vc3:8;
 		uint32_t wrr_vc2:8;
 		uint32_t wrr_vc1:8;
 		uint32_t wrr_vc0:8;
+#else
+		uint32_t wrr_vc0:8;
+		uint32_t wrr_vc1:8;
+		uint32_t wrr_vc2:8;
+		uint32_t wrr_vc3:8;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg464_s cn52xx;
 	struct cvmx_pciercx_cfg464_s cn52xxp1;
@@ -1770,15 +2889,23 @@
 	struct cvmx_pciercx_cfg464_s cn66xx;
 	struct cvmx_pciercx_cfg464_s cn68xx;
 	struct cvmx_pciercx_cfg464_s cn68xxp1;
+	struct cvmx_pciercx_cfg464_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg465 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg465_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t wrr_vc7:8;
 		uint32_t wrr_vc6:8;
 		uint32_t wrr_vc5:8;
 		uint32_t wrr_vc4:8;
+#else
+		uint32_t wrr_vc4:8;
+		uint32_t wrr_vc5:8;
+		uint32_t wrr_vc6:8;
+		uint32_t wrr_vc7:8;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg465_s cn52xx;
 	struct cvmx_pciercx_cfg465_s cn52xxp1;
@@ -1790,11 +2917,13 @@
 	struct cvmx_pciercx_cfg465_s cn66xx;
 	struct cvmx_pciercx_cfg465_s cn68xx;
 	struct cvmx_pciercx_cfg465_s cn68xxp1;
+	struct cvmx_pciercx_cfg465_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg466 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg466_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t rx_queue_order:1;
 		uint32_t type_ordering:1;
 		uint32_t reserved_24_29:6;
@@ -1802,6 +2931,15 @@
 		uint32_t reserved_20_20:1;
 		uint32_t header_credits:8;
 		uint32_t data_credits:12;
+#else
+		uint32_t data_credits:12;
+		uint32_t header_credits:8;
+		uint32_t reserved_20_20:1;
+		uint32_t queue_mode:3;
+		uint32_t reserved_24_29:6;
+		uint32_t type_ordering:1;
+		uint32_t rx_queue_order:1;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg466_s cn52xx;
 	struct cvmx_pciercx_cfg466_s cn52xxp1;
@@ -1813,16 +2951,25 @@
 	struct cvmx_pciercx_cfg466_s cn66xx;
 	struct cvmx_pciercx_cfg466_s cn68xx;
 	struct cvmx_pciercx_cfg466_s cn68xxp1;
+	struct cvmx_pciercx_cfg466_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg467 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg467_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_24_31:8;
 		uint32_t queue_mode:3;
 		uint32_t reserved_20_20:1;
 		uint32_t header_credits:8;
 		uint32_t data_credits:12;
+#else
+		uint32_t data_credits:12;
+		uint32_t header_credits:8;
+		uint32_t reserved_20_20:1;
+		uint32_t queue_mode:3;
+		uint32_t reserved_24_31:8;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg467_s cn52xx;
 	struct cvmx_pciercx_cfg467_s cn52xxp1;
@@ -1834,16 +2981,25 @@
 	struct cvmx_pciercx_cfg467_s cn66xx;
 	struct cvmx_pciercx_cfg467_s cn68xx;
 	struct cvmx_pciercx_cfg467_s cn68xxp1;
+	struct cvmx_pciercx_cfg467_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg468 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg468_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_24_31:8;
 		uint32_t queue_mode:3;
 		uint32_t reserved_20_20:1;
 		uint32_t header_credits:8;
 		uint32_t data_credits:12;
+#else
+		uint32_t data_credits:12;
+		uint32_t header_credits:8;
+		uint32_t reserved_20_20:1;
+		uint32_t queue_mode:3;
+		uint32_t reserved_24_31:8;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg468_s cn52xx;
 	struct cvmx_pciercx_cfg468_s cn52xxp1;
@@ -1855,15 +3011,23 @@
 	struct cvmx_pciercx_cfg468_s cn66xx;
 	struct cvmx_pciercx_cfg468_s cn68xx;
 	struct cvmx_pciercx_cfg468_s cn68xxp1;
+	struct cvmx_pciercx_cfg468_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg490 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg490_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_26_31:6;
 		uint32_t header_depth:10;
 		uint32_t reserved_14_15:2;
 		uint32_t data_depth:14;
+#else
+		uint32_t data_depth:14;
+		uint32_t reserved_14_15:2;
+		uint32_t header_depth:10;
+		uint32_t reserved_26_31:6;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg490_s cn52xx;
 	struct cvmx_pciercx_cfg490_s cn52xxp1;
@@ -1875,15 +3039,23 @@
 	struct cvmx_pciercx_cfg490_s cn66xx;
 	struct cvmx_pciercx_cfg490_s cn68xx;
 	struct cvmx_pciercx_cfg490_s cn68xxp1;
+	struct cvmx_pciercx_cfg490_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg491 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg491_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_26_31:6;
 		uint32_t header_depth:10;
 		uint32_t reserved_14_15:2;
 		uint32_t data_depth:14;
+#else
+		uint32_t data_depth:14;
+		uint32_t reserved_14_15:2;
+		uint32_t header_depth:10;
+		uint32_t reserved_26_31:6;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg491_s cn52xx;
 	struct cvmx_pciercx_cfg491_s cn52xxp1;
@@ -1895,15 +3067,23 @@
 	struct cvmx_pciercx_cfg491_s cn66xx;
 	struct cvmx_pciercx_cfg491_s cn68xx;
 	struct cvmx_pciercx_cfg491_s cn68xxp1;
+	struct cvmx_pciercx_cfg491_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg492 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg492_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_26_31:6;
 		uint32_t header_depth:10;
 		uint32_t reserved_14_15:2;
 		uint32_t data_depth:14;
+#else
+		uint32_t data_depth:14;
+		uint32_t reserved_14_15:2;
+		uint32_t header_depth:10;
+		uint32_t reserved_26_31:6;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg492_s cn52xx;
 	struct cvmx_pciercx_cfg492_s cn52xxp1;
@@ -1915,11 +3095,13 @@
 	struct cvmx_pciercx_cfg492_s cn66xx;
 	struct cvmx_pciercx_cfg492_s cn68xx;
 	struct cvmx_pciercx_cfg492_s cn68xxp1;
+	struct cvmx_pciercx_cfg492_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg515 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg515_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t reserved_21_31:11;
 		uint32_t s_d_e:1;
 		uint32_t ctcrb:1;
@@ -1927,6 +3109,15 @@
 		uint32_t dsc:1;
 		uint32_t le:9;
 		uint32_t n_fts:8;
+#else
+		uint32_t n_fts:8;
+		uint32_t le:9;
+		uint32_t dsc:1;
+		uint32_t cpyts:1;
+		uint32_t ctcrb:1;
+		uint32_t s_d_e:1;
+		uint32_t reserved_21_31:11;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg515_s cn61xx;
 	struct cvmx_pciercx_cfg515_s cn63xx;
@@ -1934,12 +3125,17 @@
 	struct cvmx_pciercx_cfg515_s cn66xx;
 	struct cvmx_pciercx_cfg515_s cn68xx;
 	struct cvmx_pciercx_cfg515_s cn68xxp1;
+	struct cvmx_pciercx_cfg515_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg516 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg516_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t phy_stat:32;
+#else
+		uint32_t phy_stat:32;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg516_s cn52xx;
 	struct cvmx_pciercx_cfg516_s cn52xxp1;
@@ -1951,12 +3147,17 @@
 	struct cvmx_pciercx_cfg516_s cn66xx;
 	struct cvmx_pciercx_cfg516_s cn68xx;
 	struct cvmx_pciercx_cfg516_s cn68xxp1;
+	struct cvmx_pciercx_cfg516_s cnf71xx;
 };
 
 union cvmx_pciercx_cfg517 {
 	uint32_t u32;
 	struct cvmx_pciercx_cfg517_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint32_t phy_ctrl:32;
+#else
+		uint32_t phy_ctrl:32;
+#endif
 	} s;
 	struct cvmx_pciercx_cfg517_s cn52xx;
 	struct cvmx_pciercx_cfg517_s cn52xxp1;
@@ -1968,6 +3169,7 @@
 	struct cvmx_pciercx_cfg517_s cn66xx;
 	struct cvmx_pciercx_cfg517_s cn68xx;
 	struct cvmx_pciercx_cfg517_s cn68xxp1;
+	struct cvmx_pciercx_cfg517_s cnf71xx;
 };
 
 #endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pcsx-defs.h b/arch/mips/include/asm/octeon/cvmx-pcsx-defs.h
index d45952d..a5e8fd8 100644
--- a/arch/mips/include/asm/octeon/cvmx-pcsx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pcsx-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -28,44 +28,316 @@
 #ifndef __CVMX_PCSX_DEFS_H__
 #define __CVMX_PCSX_DEFS_H__
 
-#define CVMX_PCSX_ANX_ADV_REG(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0001010ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_ANX_EXT_ST_REG(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0001028ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_ANX_LP_ABIL_REG(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0001018ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_ANX_RESULTS_REG(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0001020ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_INTX_EN_REG(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0001088ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_INTX_REG(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0001080ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_LINKX_TIMER_COUNT_REG(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0001040ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_LOG_ANLX_REG(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0001090ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_MISCX_CTL_REG(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0001078ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_MRX_CONTROL_REG(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0001000ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_MRX_STATUS_REG(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0001008ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_RXX_STATES_REG(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0001058ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_RXX_SYNC_REG(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0001050ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_SGMX_AN_ADV_REG(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0001068ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_SGMX_LP_ADV_REG(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0001070ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_TXX_STATES_REG(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0001060ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSX_TX_RXX_POLARITY_REG(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0001048ull + (((offset) & 3) * 1024) + (((block_id) & 1) * 0x8000000ull))
+static inline uint64_t CVMX_PCSX_ANX_ADV_REG(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001010ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001010ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001010ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001010ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0001010ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_ANX_EXT_ST_REG(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001028ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001028ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001028ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001028ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0001028ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_ANX_LP_ABIL_REG(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001018ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001018ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001018ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001018ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0001018ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_ANX_RESULTS_REG(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001020ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001020ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001020ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001020ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0001020ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_INTX_EN_REG(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001088ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001088ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001088ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001088ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0001088ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_INTX_REG(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001080ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001080ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001080ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001080ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0001080ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_LINKX_TIMER_COUNT_REG(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001040ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001040ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001040ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001040ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0001040ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_LOG_ANLX_REG(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001090ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001090ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001090ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001090ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0001090ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_MISCX_CTL_REG(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001078ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001078ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001078ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001078ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0001078ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_MRX_CONTROL_REG(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001000ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001000ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001000ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001000ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0001000ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_MRX_STATUS_REG(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001008ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001008ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001008ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001008ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0001008ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_RXX_STATES_REG(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001058ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001058ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001058ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001058ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0001058ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_RXX_SYNC_REG(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001050ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001050ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001050ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001050ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0001050ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_SGMX_AN_ADV_REG(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001068ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001068ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001068ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001068ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0001068ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_SGMX_LP_ADV_REG(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001070ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001070ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001070ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001070ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0001070ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_TXX_STATES_REG(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001060ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001060ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001060ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001060ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0001060ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
+
+static inline uint64_t CVMX_PCSX_TX_RXX_POLARITY_REG(unsigned long offset, unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001048ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001048ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001048ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0001048ull) + ((offset) + (block_id) * 0x4000ull) * 1024;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0001048ull) + ((offset) + (block_id) * 0x20000ull) * 1024;
+}
 
 union cvmx_pcsx_anx_adv_reg {
 	uint64_t u64;
 	struct cvmx_pcsx_anx_adv_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t np:1;
 		uint64_t reserved_14_14:1;
@@ -75,32 +347,67 @@
 		uint64_t hfd:1;
 		uint64_t fd:1;
 		uint64_t reserved_0_4:5;
+#else
+		uint64_t reserved_0_4:5;
+		uint64_t fd:1;
+		uint64_t hfd:1;
+		uint64_t pause:2;
+		uint64_t reserved_9_11:3;
+		uint64_t rem_flt:2;
+		uint64_t reserved_14_14:1;
+		uint64_t np:1;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_pcsx_anx_adv_reg_s cn52xx;
 	struct cvmx_pcsx_anx_adv_reg_s cn52xxp1;
 	struct cvmx_pcsx_anx_adv_reg_s cn56xx;
 	struct cvmx_pcsx_anx_adv_reg_s cn56xxp1;
+	struct cvmx_pcsx_anx_adv_reg_s cn61xx;
+	struct cvmx_pcsx_anx_adv_reg_s cn63xx;
+	struct cvmx_pcsx_anx_adv_reg_s cn63xxp1;
+	struct cvmx_pcsx_anx_adv_reg_s cn66xx;
+	struct cvmx_pcsx_anx_adv_reg_s cn68xx;
+	struct cvmx_pcsx_anx_adv_reg_s cn68xxp1;
+	struct cvmx_pcsx_anx_adv_reg_s cnf71xx;
 };
 
 union cvmx_pcsx_anx_ext_st_reg {
 	uint64_t u64;
 	struct cvmx_pcsx_anx_ext_st_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t thou_xfd:1;
 		uint64_t thou_xhd:1;
 		uint64_t thou_tfd:1;
 		uint64_t thou_thd:1;
 		uint64_t reserved_0_11:12;
+#else
+		uint64_t reserved_0_11:12;
+		uint64_t thou_thd:1;
+		uint64_t thou_tfd:1;
+		uint64_t thou_xhd:1;
+		uint64_t thou_xfd:1;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_pcsx_anx_ext_st_reg_s cn52xx;
 	struct cvmx_pcsx_anx_ext_st_reg_s cn52xxp1;
 	struct cvmx_pcsx_anx_ext_st_reg_s cn56xx;
 	struct cvmx_pcsx_anx_ext_st_reg_s cn56xxp1;
+	struct cvmx_pcsx_anx_ext_st_reg_s cn61xx;
+	struct cvmx_pcsx_anx_ext_st_reg_s cn63xx;
+	struct cvmx_pcsx_anx_ext_st_reg_s cn63xxp1;
+	struct cvmx_pcsx_anx_ext_st_reg_s cn66xx;
+	struct cvmx_pcsx_anx_ext_st_reg_s cn68xx;
+	struct cvmx_pcsx_anx_ext_st_reg_s cn68xxp1;
+	struct cvmx_pcsx_anx_ext_st_reg_s cnf71xx;
 };
 
 union cvmx_pcsx_anx_lp_abil_reg {
 	uint64_t u64;
 	struct cvmx_pcsx_anx_lp_abil_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t np:1;
 		uint64_t ack:1;
@@ -110,32 +417,100 @@
 		uint64_t hfd:1;
 		uint64_t fd:1;
 		uint64_t reserved_0_4:5;
+#else
+		uint64_t reserved_0_4:5;
+		uint64_t fd:1;
+		uint64_t hfd:1;
+		uint64_t pause:2;
+		uint64_t reserved_9_11:3;
+		uint64_t rem_flt:2;
+		uint64_t ack:1;
+		uint64_t np:1;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_pcsx_anx_lp_abil_reg_s cn52xx;
 	struct cvmx_pcsx_anx_lp_abil_reg_s cn52xxp1;
 	struct cvmx_pcsx_anx_lp_abil_reg_s cn56xx;
 	struct cvmx_pcsx_anx_lp_abil_reg_s cn56xxp1;
+	struct cvmx_pcsx_anx_lp_abil_reg_s cn61xx;
+	struct cvmx_pcsx_anx_lp_abil_reg_s cn63xx;
+	struct cvmx_pcsx_anx_lp_abil_reg_s cn63xxp1;
+	struct cvmx_pcsx_anx_lp_abil_reg_s cn66xx;
+	struct cvmx_pcsx_anx_lp_abil_reg_s cn68xx;
+	struct cvmx_pcsx_anx_lp_abil_reg_s cn68xxp1;
+	struct cvmx_pcsx_anx_lp_abil_reg_s cnf71xx;
 };
 
 union cvmx_pcsx_anx_results_reg {
 	uint64_t u64;
 	struct cvmx_pcsx_anx_results_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_7_63:57;
 		uint64_t pause:2;
 		uint64_t spd:2;
 		uint64_t an_cpt:1;
 		uint64_t dup:1;
 		uint64_t link_ok:1;
+#else
+		uint64_t link_ok:1;
+		uint64_t dup:1;
+		uint64_t an_cpt:1;
+		uint64_t spd:2;
+		uint64_t pause:2;
+		uint64_t reserved_7_63:57;
+#endif
 	} s;
 	struct cvmx_pcsx_anx_results_reg_s cn52xx;
 	struct cvmx_pcsx_anx_results_reg_s cn52xxp1;
 	struct cvmx_pcsx_anx_results_reg_s cn56xx;
 	struct cvmx_pcsx_anx_results_reg_s cn56xxp1;
+	struct cvmx_pcsx_anx_results_reg_s cn61xx;
+	struct cvmx_pcsx_anx_results_reg_s cn63xx;
+	struct cvmx_pcsx_anx_results_reg_s cn63xxp1;
+	struct cvmx_pcsx_anx_results_reg_s cn66xx;
+	struct cvmx_pcsx_anx_results_reg_s cn68xx;
+	struct cvmx_pcsx_anx_results_reg_s cn68xxp1;
+	struct cvmx_pcsx_anx_results_reg_s cnf71xx;
 };
 
 union cvmx_pcsx_intx_en_reg {
 	uint64_t u64;
 	struct cvmx_pcsx_intx_en_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_13_63:51;
+		uint64_t dbg_sync_en:1;
+		uint64_t dup:1;
+		uint64_t sync_bad_en:1;
+		uint64_t an_bad_en:1;
+		uint64_t rxlock_en:1;
+		uint64_t rxbad_en:1;
+		uint64_t rxerr_en:1;
+		uint64_t txbad_en:1;
+		uint64_t txfifo_en:1;
+		uint64_t txfifu_en:1;
+		uint64_t an_err_en:1;
+		uint64_t xmit_en:1;
+		uint64_t lnkspd_en:1;
+#else
+		uint64_t lnkspd_en:1;
+		uint64_t xmit_en:1;
+		uint64_t an_err_en:1;
+		uint64_t txfifu_en:1;
+		uint64_t txfifo_en:1;
+		uint64_t txbad_en:1;
+		uint64_t rxerr_en:1;
+		uint64_t rxbad_en:1;
+		uint64_t rxlock_en:1;
+		uint64_t an_bad_en:1;
+		uint64_t sync_bad_en:1;
+		uint64_t dup:1;
+		uint64_t dbg_sync_en:1;
+		uint64_t reserved_13_63:51;
+#endif
+	} s;
+	struct cvmx_pcsx_intx_en_reg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t dup:1;
 		uint64_t sync_bad_en:1;
@@ -149,16 +524,71 @@
 		uint64_t an_err_en:1;
 		uint64_t xmit_en:1;
 		uint64_t lnkspd_en:1;
-	} s;
-	struct cvmx_pcsx_intx_en_reg_s cn52xx;
-	struct cvmx_pcsx_intx_en_reg_s cn52xxp1;
-	struct cvmx_pcsx_intx_en_reg_s cn56xx;
-	struct cvmx_pcsx_intx_en_reg_s cn56xxp1;
+#else
+		uint64_t lnkspd_en:1;
+		uint64_t xmit_en:1;
+		uint64_t an_err_en:1;
+		uint64_t txfifu_en:1;
+		uint64_t txfifo_en:1;
+		uint64_t txbad_en:1;
+		uint64_t rxerr_en:1;
+		uint64_t rxbad_en:1;
+		uint64_t rxlock_en:1;
+		uint64_t an_bad_en:1;
+		uint64_t sync_bad_en:1;
+		uint64_t dup:1;
+		uint64_t reserved_12_63:52;
+#endif
+	} cn52xx;
+	struct cvmx_pcsx_intx_en_reg_cn52xx cn52xxp1;
+	struct cvmx_pcsx_intx_en_reg_cn52xx cn56xx;
+	struct cvmx_pcsx_intx_en_reg_cn52xx cn56xxp1;
+	struct cvmx_pcsx_intx_en_reg_s cn61xx;
+	struct cvmx_pcsx_intx_en_reg_s cn63xx;
+	struct cvmx_pcsx_intx_en_reg_s cn63xxp1;
+	struct cvmx_pcsx_intx_en_reg_s cn66xx;
+	struct cvmx_pcsx_intx_en_reg_s cn68xx;
+	struct cvmx_pcsx_intx_en_reg_s cn68xxp1;
+	struct cvmx_pcsx_intx_en_reg_s cnf71xx;
 };
 
 union cvmx_pcsx_intx_reg {
 	uint64_t u64;
 	struct cvmx_pcsx_intx_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_13_63:51;
+		uint64_t dbg_sync:1;
+		uint64_t dup:1;
+		uint64_t sync_bad:1;
+		uint64_t an_bad:1;
+		uint64_t rxlock:1;
+		uint64_t rxbad:1;
+		uint64_t rxerr:1;
+		uint64_t txbad:1;
+		uint64_t txfifo:1;
+		uint64_t txfifu:1;
+		uint64_t an_err:1;
+		uint64_t xmit:1;
+		uint64_t lnkspd:1;
+#else
+		uint64_t lnkspd:1;
+		uint64_t xmit:1;
+		uint64_t an_err:1;
+		uint64_t txfifu:1;
+		uint64_t txfifo:1;
+		uint64_t txbad:1;
+		uint64_t rxerr:1;
+		uint64_t rxbad:1;
+		uint64_t rxlock:1;
+		uint64_t an_bad:1;
+		uint64_t sync_bad:1;
+		uint64_t dup:1;
+		uint64_t dbg_sync:1;
+		uint64_t reserved_13_63:51;
+#endif
+	} s;
+	struct cvmx_pcsx_intx_reg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t dup:1;
 		uint64_t sync_bad:1;
@@ -172,42 +602,90 @@
 		uint64_t an_err:1;
 		uint64_t xmit:1;
 		uint64_t lnkspd:1;
-	} s;
-	struct cvmx_pcsx_intx_reg_s cn52xx;
-	struct cvmx_pcsx_intx_reg_s cn52xxp1;
-	struct cvmx_pcsx_intx_reg_s cn56xx;
-	struct cvmx_pcsx_intx_reg_s cn56xxp1;
+#else
+		uint64_t lnkspd:1;
+		uint64_t xmit:1;
+		uint64_t an_err:1;
+		uint64_t txfifu:1;
+		uint64_t txfifo:1;
+		uint64_t txbad:1;
+		uint64_t rxerr:1;
+		uint64_t rxbad:1;
+		uint64_t rxlock:1;
+		uint64_t an_bad:1;
+		uint64_t sync_bad:1;
+		uint64_t dup:1;
+		uint64_t reserved_12_63:52;
+#endif
+	} cn52xx;
+	struct cvmx_pcsx_intx_reg_cn52xx cn52xxp1;
+	struct cvmx_pcsx_intx_reg_cn52xx cn56xx;
+	struct cvmx_pcsx_intx_reg_cn52xx cn56xxp1;
+	struct cvmx_pcsx_intx_reg_s cn61xx;
+	struct cvmx_pcsx_intx_reg_s cn63xx;
+	struct cvmx_pcsx_intx_reg_s cn63xxp1;
+	struct cvmx_pcsx_intx_reg_s cn66xx;
+	struct cvmx_pcsx_intx_reg_s cn68xx;
+	struct cvmx_pcsx_intx_reg_s cn68xxp1;
+	struct cvmx_pcsx_intx_reg_s cnf71xx;
 };
 
 union cvmx_pcsx_linkx_timer_count_reg {
 	uint64_t u64;
 	struct cvmx_pcsx_linkx_timer_count_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t count:16;
+#else
+		uint64_t count:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_pcsx_linkx_timer_count_reg_s cn52xx;
 	struct cvmx_pcsx_linkx_timer_count_reg_s cn52xxp1;
 	struct cvmx_pcsx_linkx_timer_count_reg_s cn56xx;
 	struct cvmx_pcsx_linkx_timer_count_reg_s cn56xxp1;
+	struct cvmx_pcsx_linkx_timer_count_reg_s cn61xx;
+	struct cvmx_pcsx_linkx_timer_count_reg_s cn63xx;
+	struct cvmx_pcsx_linkx_timer_count_reg_s cn63xxp1;
+	struct cvmx_pcsx_linkx_timer_count_reg_s cn66xx;
+	struct cvmx_pcsx_linkx_timer_count_reg_s cn68xx;
+	struct cvmx_pcsx_linkx_timer_count_reg_s cn68xxp1;
+	struct cvmx_pcsx_linkx_timer_count_reg_s cnf71xx;
 };
 
 union cvmx_pcsx_log_anlx_reg {
 	uint64_t u64;
 	struct cvmx_pcsx_log_anlx_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t lafifovfl:1;
 		uint64_t la_en:1;
 		uint64_t pkt_sz:2;
+#else
+		uint64_t pkt_sz:2;
+		uint64_t la_en:1;
+		uint64_t lafifovfl:1;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_pcsx_log_anlx_reg_s cn52xx;
 	struct cvmx_pcsx_log_anlx_reg_s cn52xxp1;
 	struct cvmx_pcsx_log_anlx_reg_s cn56xx;
 	struct cvmx_pcsx_log_anlx_reg_s cn56xxp1;
+	struct cvmx_pcsx_log_anlx_reg_s cn61xx;
+	struct cvmx_pcsx_log_anlx_reg_s cn63xx;
+	struct cvmx_pcsx_log_anlx_reg_s cn63xxp1;
+	struct cvmx_pcsx_log_anlx_reg_s cn66xx;
+	struct cvmx_pcsx_log_anlx_reg_s cn68xx;
+	struct cvmx_pcsx_log_anlx_reg_s cn68xxp1;
+	struct cvmx_pcsx_log_anlx_reg_s cnf71xx;
 };
 
 union cvmx_pcsx_miscx_ctl_reg {
 	uint64_t u64;
 	struct cvmx_pcsx_miscx_ctl_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_13_63:51;
 		uint64_t sgmii:1;
 		uint64_t gmxeno:1;
@@ -216,16 +694,34 @@
 		uint64_t mode:1;
 		uint64_t an_ovrd:1;
 		uint64_t samp_pt:7;
+#else
+		uint64_t samp_pt:7;
+		uint64_t an_ovrd:1;
+		uint64_t mode:1;
+		uint64_t mac_phy:1;
+		uint64_t loopbck2:1;
+		uint64_t gmxeno:1;
+		uint64_t sgmii:1;
+		uint64_t reserved_13_63:51;
+#endif
 	} s;
 	struct cvmx_pcsx_miscx_ctl_reg_s cn52xx;
 	struct cvmx_pcsx_miscx_ctl_reg_s cn52xxp1;
 	struct cvmx_pcsx_miscx_ctl_reg_s cn56xx;
 	struct cvmx_pcsx_miscx_ctl_reg_s cn56xxp1;
+	struct cvmx_pcsx_miscx_ctl_reg_s cn61xx;
+	struct cvmx_pcsx_miscx_ctl_reg_s cn63xx;
+	struct cvmx_pcsx_miscx_ctl_reg_s cn63xxp1;
+	struct cvmx_pcsx_miscx_ctl_reg_s cn66xx;
+	struct cvmx_pcsx_miscx_ctl_reg_s cn68xx;
+	struct cvmx_pcsx_miscx_ctl_reg_s cn68xxp1;
+	struct cvmx_pcsx_miscx_ctl_reg_s cnf71xx;
 };
 
 union cvmx_pcsx_mrx_control_reg {
 	uint64_t u64;
 	struct cvmx_pcsx_mrx_control_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t reset:1;
 		uint64_t loopbck1:1;
@@ -239,16 +735,39 @@
 		uint64_t spdmsb:1;
 		uint64_t uni:1;
 		uint64_t reserved_0_4:5;
+#else
+		uint64_t reserved_0_4:5;
+		uint64_t uni:1;
+		uint64_t spdmsb:1;
+		uint64_t coltst:1;
+		uint64_t dup:1;
+		uint64_t rst_an:1;
+		uint64_t reserved_10_10:1;
+		uint64_t pwr_dn:1;
+		uint64_t an_en:1;
+		uint64_t spdlsb:1;
+		uint64_t loopbck1:1;
+		uint64_t reset:1;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_pcsx_mrx_control_reg_s cn52xx;
 	struct cvmx_pcsx_mrx_control_reg_s cn52xxp1;
 	struct cvmx_pcsx_mrx_control_reg_s cn56xx;
 	struct cvmx_pcsx_mrx_control_reg_s cn56xxp1;
+	struct cvmx_pcsx_mrx_control_reg_s cn61xx;
+	struct cvmx_pcsx_mrx_control_reg_s cn63xx;
+	struct cvmx_pcsx_mrx_control_reg_s cn63xxp1;
+	struct cvmx_pcsx_mrx_control_reg_s cn66xx;
+	struct cvmx_pcsx_mrx_control_reg_s cn68xx;
+	struct cvmx_pcsx_mrx_control_reg_s cn68xxp1;
+	struct cvmx_pcsx_mrx_control_reg_s cnf71xx;
 };
 
 union cvmx_pcsx_mrx_status_reg {
 	uint64_t u64;
 	struct cvmx_pcsx_mrx_status_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t hun_t4:1;
 		uint64_t hun_xfd:1;
@@ -266,16 +785,43 @@
 		uint64_t lnk_st:1;
 		uint64_t reserved_1_1:1;
 		uint64_t extnd:1;
+#else
+		uint64_t extnd:1;
+		uint64_t reserved_1_1:1;
+		uint64_t lnk_st:1;
+		uint64_t an_abil:1;
+		uint64_t rm_flt:1;
+		uint64_t an_cpt:1;
+		uint64_t prb_sup:1;
+		uint64_t reserved_7_7:1;
+		uint64_t ext_st:1;
+		uint64_t hun_t2hd:1;
+		uint64_t hun_t2fd:1;
+		uint64_t ten_hd:1;
+		uint64_t ten_fd:1;
+		uint64_t hun_xhd:1;
+		uint64_t hun_xfd:1;
+		uint64_t hun_t4:1;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_pcsx_mrx_status_reg_s cn52xx;
 	struct cvmx_pcsx_mrx_status_reg_s cn52xxp1;
 	struct cvmx_pcsx_mrx_status_reg_s cn56xx;
 	struct cvmx_pcsx_mrx_status_reg_s cn56xxp1;
+	struct cvmx_pcsx_mrx_status_reg_s cn61xx;
+	struct cvmx_pcsx_mrx_status_reg_s cn63xx;
+	struct cvmx_pcsx_mrx_status_reg_s cn63xxp1;
+	struct cvmx_pcsx_mrx_status_reg_s cn66xx;
+	struct cvmx_pcsx_mrx_status_reg_s cn68xx;
+	struct cvmx_pcsx_mrx_status_reg_s cn68xxp1;
+	struct cvmx_pcsx_mrx_status_reg_s cnf71xx;
 };
 
 union cvmx_pcsx_rxx_states_reg {
 	uint64_t u64;
 	struct cvmx_pcsx_rxx_states_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t rx_bad:1;
 		uint64_t rx_st:5;
@@ -283,29 +829,59 @@
 		uint64_t sync:4;
 		uint64_t an_bad:1;
 		uint64_t an_st:4;
+#else
+		uint64_t an_st:4;
+		uint64_t an_bad:1;
+		uint64_t sync:4;
+		uint64_t sync_bad:1;
+		uint64_t rx_st:5;
+		uint64_t rx_bad:1;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_pcsx_rxx_states_reg_s cn52xx;
 	struct cvmx_pcsx_rxx_states_reg_s cn52xxp1;
 	struct cvmx_pcsx_rxx_states_reg_s cn56xx;
 	struct cvmx_pcsx_rxx_states_reg_s cn56xxp1;
+	struct cvmx_pcsx_rxx_states_reg_s cn61xx;
+	struct cvmx_pcsx_rxx_states_reg_s cn63xx;
+	struct cvmx_pcsx_rxx_states_reg_s cn63xxp1;
+	struct cvmx_pcsx_rxx_states_reg_s cn66xx;
+	struct cvmx_pcsx_rxx_states_reg_s cn68xx;
+	struct cvmx_pcsx_rxx_states_reg_s cn68xxp1;
+	struct cvmx_pcsx_rxx_states_reg_s cnf71xx;
 };
 
 union cvmx_pcsx_rxx_sync_reg {
 	uint64_t u64;
 	struct cvmx_pcsx_rxx_sync_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t sync:1;
 		uint64_t bit_lock:1;
+#else
+		uint64_t bit_lock:1;
+		uint64_t sync:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_pcsx_rxx_sync_reg_s cn52xx;
 	struct cvmx_pcsx_rxx_sync_reg_s cn52xxp1;
 	struct cvmx_pcsx_rxx_sync_reg_s cn56xx;
 	struct cvmx_pcsx_rxx_sync_reg_s cn56xxp1;
+	struct cvmx_pcsx_rxx_sync_reg_s cn61xx;
+	struct cvmx_pcsx_rxx_sync_reg_s cn63xx;
+	struct cvmx_pcsx_rxx_sync_reg_s cn63xxp1;
+	struct cvmx_pcsx_rxx_sync_reg_s cn66xx;
+	struct cvmx_pcsx_rxx_sync_reg_s cn68xx;
+	struct cvmx_pcsx_rxx_sync_reg_s cn68xxp1;
+	struct cvmx_pcsx_rxx_sync_reg_s cnf71xx;
 };
 
 union cvmx_pcsx_sgmx_an_adv_reg {
 	uint64_t u64;
 	struct cvmx_pcsx_sgmx_an_adv_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t link:1;
 		uint64_t ack:1;
@@ -314,16 +890,34 @@
 		uint64_t speed:2;
 		uint64_t reserved_1_9:9;
 		uint64_t one:1;
+#else
+		uint64_t one:1;
+		uint64_t reserved_1_9:9;
+		uint64_t speed:2;
+		uint64_t dup:1;
+		uint64_t reserved_13_13:1;
+		uint64_t ack:1;
+		uint64_t link:1;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_pcsx_sgmx_an_adv_reg_s cn52xx;
 	struct cvmx_pcsx_sgmx_an_adv_reg_s cn52xxp1;
 	struct cvmx_pcsx_sgmx_an_adv_reg_s cn56xx;
 	struct cvmx_pcsx_sgmx_an_adv_reg_s cn56xxp1;
+	struct cvmx_pcsx_sgmx_an_adv_reg_s cn61xx;
+	struct cvmx_pcsx_sgmx_an_adv_reg_s cn63xx;
+	struct cvmx_pcsx_sgmx_an_adv_reg_s cn63xxp1;
+	struct cvmx_pcsx_sgmx_an_adv_reg_s cn66xx;
+	struct cvmx_pcsx_sgmx_an_adv_reg_s cn68xx;
+	struct cvmx_pcsx_sgmx_an_adv_reg_s cn68xxp1;
+	struct cvmx_pcsx_sgmx_an_adv_reg_s cnf71xx;
 };
 
 union cvmx_pcsx_sgmx_lp_adv_reg {
 	uint64_t u64;
 	struct cvmx_pcsx_sgmx_lp_adv_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t link:1;
 		uint64_t reserved_13_14:2;
@@ -331,40 +925,85 @@
 		uint64_t speed:2;
 		uint64_t reserved_1_9:9;
 		uint64_t one:1;
+#else
+		uint64_t one:1;
+		uint64_t reserved_1_9:9;
+		uint64_t speed:2;
+		uint64_t dup:1;
+		uint64_t reserved_13_14:2;
+		uint64_t link:1;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_pcsx_sgmx_lp_adv_reg_s cn52xx;
 	struct cvmx_pcsx_sgmx_lp_adv_reg_s cn52xxp1;
 	struct cvmx_pcsx_sgmx_lp_adv_reg_s cn56xx;
 	struct cvmx_pcsx_sgmx_lp_adv_reg_s cn56xxp1;
+	struct cvmx_pcsx_sgmx_lp_adv_reg_s cn61xx;
+	struct cvmx_pcsx_sgmx_lp_adv_reg_s cn63xx;
+	struct cvmx_pcsx_sgmx_lp_adv_reg_s cn63xxp1;
+	struct cvmx_pcsx_sgmx_lp_adv_reg_s cn66xx;
+	struct cvmx_pcsx_sgmx_lp_adv_reg_s cn68xx;
+	struct cvmx_pcsx_sgmx_lp_adv_reg_s cn68xxp1;
+	struct cvmx_pcsx_sgmx_lp_adv_reg_s cnf71xx;
 };
 
 union cvmx_pcsx_txx_states_reg {
 	uint64_t u64;
 	struct cvmx_pcsx_txx_states_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_7_63:57;
 		uint64_t xmit:2;
 		uint64_t tx_bad:1;
 		uint64_t ord_st:4;
+#else
+		uint64_t ord_st:4;
+		uint64_t tx_bad:1;
+		uint64_t xmit:2;
+		uint64_t reserved_7_63:57;
+#endif
 	} s;
 	struct cvmx_pcsx_txx_states_reg_s cn52xx;
 	struct cvmx_pcsx_txx_states_reg_s cn52xxp1;
 	struct cvmx_pcsx_txx_states_reg_s cn56xx;
 	struct cvmx_pcsx_txx_states_reg_s cn56xxp1;
+	struct cvmx_pcsx_txx_states_reg_s cn61xx;
+	struct cvmx_pcsx_txx_states_reg_s cn63xx;
+	struct cvmx_pcsx_txx_states_reg_s cn63xxp1;
+	struct cvmx_pcsx_txx_states_reg_s cn66xx;
+	struct cvmx_pcsx_txx_states_reg_s cn68xx;
+	struct cvmx_pcsx_txx_states_reg_s cn68xxp1;
+	struct cvmx_pcsx_txx_states_reg_s cnf71xx;
 };
 
 union cvmx_pcsx_tx_rxx_polarity_reg {
 	uint64_t u64;
 	struct cvmx_pcsx_tx_rxx_polarity_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t rxovrd:1;
 		uint64_t autorxpl:1;
 		uint64_t rxplrt:1;
 		uint64_t txplrt:1;
+#else
+		uint64_t txplrt:1;
+		uint64_t rxplrt:1;
+		uint64_t autorxpl:1;
+		uint64_t rxovrd:1;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_pcsx_tx_rxx_polarity_reg_s cn52xx;
 	struct cvmx_pcsx_tx_rxx_polarity_reg_s cn52xxp1;
 	struct cvmx_pcsx_tx_rxx_polarity_reg_s cn56xx;
 	struct cvmx_pcsx_tx_rxx_polarity_reg_s cn56xxp1;
+	struct cvmx_pcsx_tx_rxx_polarity_reg_s cn61xx;
+	struct cvmx_pcsx_tx_rxx_polarity_reg_s cn63xx;
+	struct cvmx_pcsx_tx_rxx_polarity_reg_s cn63xxp1;
+	struct cvmx_pcsx_tx_rxx_polarity_reg_s cn66xx;
+	struct cvmx_pcsx_tx_rxx_polarity_reg_s cn68xx;
+	struct cvmx_pcsx_tx_rxx_polarity_reg_s cn68xxp1;
+	struct cvmx_pcsx_tx_rxx_polarity_reg_s cnf71xx;
 };
 
 #endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pcsxx-defs.h b/arch/mips/include/asm/octeon/cvmx-pcsxx-defs.h
index 55d120f..b5b45d2 100644
--- a/arch/mips/include/asm/octeon/cvmx-pcsxx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pcsxx-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -28,40 +28,250 @@
 #ifndef __CVMX_PCSXX_DEFS_H__
 #define __CVMX_PCSXX_DEFS_H__
 
-#define CVMX_PCSXX_10GBX_STATUS_REG(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000828ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_BIST_STATUS_REG(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000870ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_BIT_LOCK_STATUS_REG(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000850ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_CONTROL1_REG(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000800ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_CONTROL2_REG(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000818ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_INT_EN_REG(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000860ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_INT_REG(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000858ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_LOG_ANL_REG(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000868ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_MISC_CTL_REG(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000848ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_RX_SYNC_STATES_REG(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000838ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_SPD_ABIL_REG(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000810ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_STATUS1_REG(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000808ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_STATUS2_REG(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000820ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_TX_RX_POLARITY_REG(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000840ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_PCSXX_TX_RX_STATES_REG(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800B0000830ull + (((block_id) & 1) * 0x8000000ull))
+static inline uint64_t CVMX_PCSXX_10GBX_STATUS_REG(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000828ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000828ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000828ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0000828ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_BIST_STATUS_REG(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000870ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000870ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000870ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0000870ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_BIT_LOCK_STATUS_REG(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000850ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000850ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000850ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0000850ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_CONTROL1_REG(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000800ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000800ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000800ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0000800ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_CONTROL2_REG(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000818ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000818ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000818ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0000818ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_INT_EN_REG(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000860ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000860ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000860ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0000860ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_INT_REG(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000858ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000858ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000858ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0000858ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_LOG_ANL_REG(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000868ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000868ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000868ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0000868ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_MISC_CTL_REG(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000848ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000848ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000848ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0000848ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_RX_SYNC_STATES_REG(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000838ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000838ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000838ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0000838ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_SPD_ABIL_REG(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000810ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000810ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000810ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0000810ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_STATUS1_REG(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000808ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000808ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000808ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0000808ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_STATUS2_REG(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000820ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000820ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000820ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0000820ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_TX_RX_POLARITY_REG(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000840ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000840ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000840ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0000840ull) + (block_id) * 0x1000000ull;
+}
+
+static inline uint64_t CVMX_PCSXX_TX_RX_STATES_REG(unsigned long block_id)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000830ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000830ull) + (block_id) * 0x8000000ull;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x00011800B0000830ull) + (block_id) * 0x1000000ull;
+	}
+	return CVMX_ADD_IO_SEG(0x00011800B0000830ull) + (block_id) * 0x1000000ull;
+}
 
 union cvmx_pcsxx_10gbx_status_reg {
 	uint64_t u64;
 	struct cvmx_pcsxx_10gbx_status_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_13_63:51;
 		uint64_t alignd:1;
 		uint64_t pattst:1;
@@ -70,43 +280,85 @@
 		uint64_t l2sync:1;
 		uint64_t l1sync:1;
 		uint64_t l0sync:1;
+#else
+		uint64_t l0sync:1;
+		uint64_t l1sync:1;
+		uint64_t l2sync:1;
+		uint64_t l3sync:1;
+		uint64_t reserved_4_10:7;
+		uint64_t pattst:1;
+		uint64_t alignd:1;
+		uint64_t reserved_13_63:51;
+#endif
 	} s;
 	struct cvmx_pcsxx_10gbx_status_reg_s cn52xx;
 	struct cvmx_pcsxx_10gbx_status_reg_s cn52xxp1;
 	struct cvmx_pcsxx_10gbx_status_reg_s cn56xx;
 	struct cvmx_pcsxx_10gbx_status_reg_s cn56xxp1;
+	struct cvmx_pcsxx_10gbx_status_reg_s cn61xx;
+	struct cvmx_pcsxx_10gbx_status_reg_s cn63xx;
+	struct cvmx_pcsxx_10gbx_status_reg_s cn63xxp1;
+	struct cvmx_pcsxx_10gbx_status_reg_s cn66xx;
+	struct cvmx_pcsxx_10gbx_status_reg_s cn68xx;
+	struct cvmx_pcsxx_10gbx_status_reg_s cn68xxp1;
 };
 
 union cvmx_pcsxx_bist_status_reg {
 	uint64_t u64;
 	struct cvmx_pcsxx_bist_status_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t bist_status:1;
+#else
+		uint64_t bist_status:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_pcsxx_bist_status_reg_s cn52xx;
 	struct cvmx_pcsxx_bist_status_reg_s cn52xxp1;
 	struct cvmx_pcsxx_bist_status_reg_s cn56xx;
 	struct cvmx_pcsxx_bist_status_reg_s cn56xxp1;
+	struct cvmx_pcsxx_bist_status_reg_s cn61xx;
+	struct cvmx_pcsxx_bist_status_reg_s cn63xx;
+	struct cvmx_pcsxx_bist_status_reg_s cn63xxp1;
+	struct cvmx_pcsxx_bist_status_reg_s cn66xx;
+	struct cvmx_pcsxx_bist_status_reg_s cn68xx;
+	struct cvmx_pcsxx_bist_status_reg_s cn68xxp1;
 };
 
 union cvmx_pcsxx_bit_lock_status_reg {
 	uint64_t u64;
 	struct cvmx_pcsxx_bit_lock_status_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t bitlck3:1;
 		uint64_t bitlck2:1;
 		uint64_t bitlck1:1;
 		uint64_t bitlck0:1;
+#else
+		uint64_t bitlck0:1;
+		uint64_t bitlck1:1;
+		uint64_t bitlck2:1;
+		uint64_t bitlck3:1;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_pcsxx_bit_lock_status_reg_s cn52xx;
 	struct cvmx_pcsxx_bit_lock_status_reg_s cn52xxp1;
 	struct cvmx_pcsxx_bit_lock_status_reg_s cn56xx;
 	struct cvmx_pcsxx_bit_lock_status_reg_s cn56xxp1;
+	struct cvmx_pcsxx_bit_lock_status_reg_s cn61xx;
+	struct cvmx_pcsxx_bit_lock_status_reg_s cn63xx;
+	struct cvmx_pcsxx_bit_lock_status_reg_s cn63xxp1;
+	struct cvmx_pcsxx_bit_lock_status_reg_s cn66xx;
+	struct cvmx_pcsxx_bit_lock_status_reg_s cn68xx;
+	struct cvmx_pcsxx_bit_lock_status_reg_s cn68xxp1;
 };
 
 union cvmx_pcsxx_control1_reg {
 	uint64_t u64;
 	struct cvmx_pcsxx_control1_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t reset:1;
 		uint64_t loopbck1:1;
@@ -117,28 +369,79 @@
 		uint64_t spdsel0:1;
 		uint64_t spd:4;
 		uint64_t reserved_0_1:2;
+#else
+		uint64_t reserved_0_1:2;
+		uint64_t spd:4;
+		uint64_t spdsel0:1;
+		uint64_t reserved_7_10:4;
+		uint64_t lo_pwr:1;
+		uint64_t reserved_12_12:1;
+		uint64_t spdsel1:1;
+		uint64_t loopbck1:1;
+		uint64_t reset:1;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_pcsxx_control1_reg_s cn52xx;
 	struct cvmx_pcsxx_control1_reg_s cn52xxp1;
 	struct cvmx_pcsxx_control1_reg_s cn56xx;
 	struct cvmx_pcsxx_control1_reg_s cn56xxp1;
+	struct cvmx_pcsxx_control1_reg_s cn61xx;
+	struct cvmx_pcsxx_control1_reg_s cn63xx;
+	struct cvmx_pcsxx_control1_reg_s cn63xxp1;
+	struct cvmx_pcsxx_control1_reg_s cn66xx;
+	struct cvmx_pcsxx_control1_reg_s cn68xx;
+	struct cvmx_pcsxx_control1_reg_s cn68xxp1;
 };
 
 union cvmx_pcsxx_control2_reg {
 	uint64_t u64;
 	struct cvmx_pcsxx_control2_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t type:2;
+#else
+		uint64_t type:2;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_pcsxx_control2_reg_s cn52xx;
 	struct cvmx_pcsxx_control2_reg_s cn52xxp1;
 	struct cvmx_pcsxx_control2_reg_s cn56xx;
 	struct cvmx_pcsxx_control2_reg_s cn56xxp1;
+	struct cvmx_pcsxx_control2_reg_s cn61xx;
+	struct cvmx_pcsxx_control2_reg_s cn63xx;
+	struct cvmx_pcsxx_control2_reg_s cn63xxp1;
+	struct cvmx_pcsxx_control2_reg_s cn66xx;
+	struct cvmx_pcsxx_control2_reg_s cn68xx;
+	struct cvmx_pcsxx_control2_reg_s cn68xxp1;
 };
 
 union cvmx_pcsxx_int_en_reg {
 	uint64_t u64;
 	struct cvmx_pcsxx_int_en_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_7_63:57;
+		uint64_t dbg_sync_en:1;
+		uint64_t algnlos_en:1;
+		uint64_t synlos_en:1;
+		uint64_t bitlckls_en:1;
+		uint64_t rxsynbad_en:1;
+		uint64_t rxbad_en:1;
+		uint64_t txflt_en:1;
+#else
+		uint64_t txflt_en:1;
+		uint64_t rxbad_en:1;
+		uint64_t rxsynbad_en:1;
+		uint64_t bitlckls_en:1;
+		uint64_t synlos_en:1;
+		uint64_t algnlos_en:1;
+		uint64_t dbg_sync_en:1;
+		uint64_t reserved_7_63:57;
+#endif
+	} s;
+	struct cvmx_pcsxx_int_en_reg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t algnlos_en:1;
 		uint64_t synlos_en:1;
@@ -146,16 +449,52 @@
 		uint64_t rxsynbad_en:1;
 		uint64_t rxbad_en:1;
 		uint64_t txflt_en:1;
-	} s;
-	struct cvmx_pcsxx_int_en_reg_s cn52xx;
-	struct cvmx_pcsxx_int_en_reg_s cn52xxp1;
-	struct cvmx_pcsxx_int_en_reg_s cn56xx;
-	struct cvmx_pcsxx_int_en_reg_s cn56xxp1;
+#else
+		uint64_t txflt_en:1;
+		uint64_t rxbad_en:1;
+		uint64_t rxsynbad_en:1;
+		uint64_t bitlckls_en:1;
+		uint64_t synlos_en:1;
+		uint64_t algnlos_en:1;
+		uint64_t reserved_6_63:58;
+#endif
+	} cn52xx;
+	struct cvmx_pcsxx_int_en_reg_cn52xx cn52xxp1;
+	struct cvmx_pcsxx_int_en_reg_cn52xx cn56xx;
+	struct cvmx_pcsxx_int_en_reg_cn52xx cn56xxp1;
+	struct cvmx_pcsxx_int_en_reg_s cn61xx;
+	struct cvmx_pcsxx_int_en_reg_s cn63xx;
+	struct cvmx_pcsxx_int_en_reg_s cn63xxp1;
+	struct cvmx_pcsxx_int_en_reg_s cn66xx;
+	struct cvmx_pcsxx_int_en_reg_s cn68xx;
+	struct cvmx_pcsxx_int_en_reg_s cn68xxp1;
 };
 
 union cvmx_pcsxx_int_reg {
 	uint64_t u64;
 	struct cvmx_pcsxx_int_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_7_63:57;
+		uint64_t dbg_sync:1;
+		uint64_t algnlos:1;
+		uint64_t synlos:1;
+		uint64_t bitlckls:1;
+		uint64_t rxsynbad:1;
+		uint64_t rxbad:1;
+		uint64_t txflt:1;
+#else
+		uint64_t txflt:1;
+		uint64_t rxbad:1;
+		uint64_t rxsynbad:1;
+		uint64_t bitlckls:1;
+		uint64_t synlos:1;
+		uint64_t algnlos:1;
+		uint64_t dbg_sync:1;
+		uint64_t reserved_7_63:57;
+#endif
+	} s;
+	struct cvmx_pcsxx_int_reg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t algnlos:1;
 		uint64_t synlos:1;
@@ -163,91 +502,176 @@
 		uint64_t rxsynbad:1;
 		uint64_t rxbad:1;
 		uint64_t txflt:1;
-	} s;
-	struct cvmx_pcsxx_int_reg_s cn52xx;
-	struct cvmx_pcsxx_int_reg_s cn52xxp1;
-	struct cvmx_pcsxx_int_reg_s cn56xx;
-	struct cvmx_pcsxx_int_reg_s cn56xxp1;
+#else
+		uint64_t txflt:1;
+		uint64_t rxbad:1;
+		uint64_t rxsynbad:1;
+		uint64_t bitlckls:1;
+		uint64_t synlos:1;
+		uint64_t algnlos:1;
+		uint64_t reserved_6_63:58;
+#endif
+	} cn52xx;
+	struct cvmx_pcsxx_int_reg_cn52xx cn52xxp1;
+	struct cvmx_pcsxx_int_reg_cn52xx cn56xx;
+	struct cvmx_pcsxx_int_reg_cn52xx cn56xxp1;
+	struct cvmx_pcsxx_int_reg_s cn61xx;
+	struct cvmx_pcsxx_int_reg_s cn63xx;
+	struct cvmx_pcsxx_int_reg_s cn63xxp1;
+	struct cvmx_pcsxx_int_reg_s cn66xx;
+	struct cvmx_pcsxx_int_reg_s cn68xx;
+	struct cvmx_pcsxx_int_reg_s cn68xxp1;
 };
 
 union cvmx_pcsxx_log_anl_reg {
 	uint64_t u64;
 	struct cvmx_pcsxx_log_anl_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_7_63:57;
 		uint64_t enc_mode:1;
 		uint64_t drop_ln:2;
 		uint64_t lafifovfl:1;
 		uint64_t la_en:1;
 		uint64_t pkt_sz:2;
+#else
+		uint64_t pkt_sz:2;
+		uint64_t la_en:1;
+		uint64_t lafifovfl:1;
+		uint64_t drop_ln:2;
+		uint64_t enc_mode:1;
+		uint64_t reserved_7_63:57;
+#endif
 	} s;
 	struct cvmx_pcsxx_log_anl_reg_s cn52xx;
 	struct cvmx_pcsxx_log_anl_reg_s cn52xxp1;
 	struct cvmx_pcsxx_log_anl_reg_s cn56xx;
 	struct cvmx_pcsxx_log_anl_reg_s cn56xxp1;
+	struct cvmx_pcsxx_log_anl_reg_s cn61xx;
+	struct cvmx_pcsxx_log_anl_reg_s cn63xx;
+	struct cvmx_pcsxx_log_anl_reg_s cn63xxp1;
+	struct cvmx_pcsxx_log_anl_reg_s cn66xx;
+	struct cvmx_pcsxx_log_anl_reg_s cn68xx;
+	struct cvmx_pcsxx_log_anl_reg_s cn68xxp1;
 };
 
 union cvmx_pcsxx_misc_ctl_reg {
 	uint64_t u64;
 	struct cvmx_pcsxx_misc_ctl_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t tx_swap:1;
 		uint64_t rx_swap:1;
 		uint64_t xaui:1;
 		uint64_t gmxeno:1;
+#else
+		uint64_t gmxeno:1;
+		uint64_t xaui:1;
+		uint64_t rx_swap:1;
+		uint64_t tx_swap:1;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_pcsxx_misc_ctl_reg_s cn52xx;
 	struct cvmx_pcsxx_misc_ctl_reg_s cn52xxp1;
 	struct cvmx_pcsxx_misc_ctl_reg_s cn56xx;
 	struct cvmx_pcsxx_misc_ctl_reg_s cn56xxp1;
+	struct cvmx_pcsxx_misc_ctl_reg_s cn61xx;
+	struct cvmx_pcsxx_misc_ctl_reg_s cn63xx;
+	struct cvmx_pcsxx_misc_ctl_reg_s cn63xxp1;
+	struct cvmx_pcsxx_misc_ctl_reg_s cn66xx;
+	struct cvmx_pcsxx_misc_ctl_reg_s cn68xx;
+	struct cvmx_pcsxx_misc_ctl_reg_s cn68xxp1;
 };
 
 union cvmx_pcsxx_rx_sync_states_reg {
 	uint64_t u64;
 	struct cvmx_pcsxx_rx_sync_states_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t sync3st:4;
 		uint64_t sync2st:4;
 		uint64_t sync1st:4;
 		uint64_t sync0st:4;
+#else
+		uint64_t sync0st:4;
+		uint64_t sync1st:4;
+		uint64_t sync2st:4;
+		uint64_t sync3st:4;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_pcsxx_rx_sync_states_reg_s cn52xx;
 	struct cvmx_pcsxx_rx_sync_states_reg_s cn52xxp1;
 	struct cvmx_pcsxx_rx_sync_states_reg_s cn56xx;
 	struct cvmx_pcsxx_rx_sync_states_reg_s cn56xxp1;
+	struct cvmx_pcsxx_rx_sync_states_reg_s cn61xx;
+	struct cvmx_pcsxx_rx_sync_states_reg_s cn63xx;
+	struct cvmx_pcsxx_rx_sync_states_reg_s cn63xxp1;
+	struct cvmx_pcsxx_rx_sync_states_reg_s cn66xx;
+	struct cvmx_pcsxx_rx_sync_states_reg_s cn68xx;
+	struct cvmx_pcsxx_rx_sync_states_reg_s cn68xxp1;
 };
 
 union cvmx_pcsxx_spd_abil_reg {
 	uint64_t u64;
 	struct cvmx_pcsxx_spd_abil_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t tenpasst:1;
 		uint64_t tengb:1;
+#else
+		uint64_t tengb:1;
+		uint64_t tenpasst:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_pcsxx_spd_abil_reg_s cn52xx;
 	struct cvmx_pcsxx_spd_abil_reg_s cn52xxp1;
 	struct cvmx_pcsxx_spd_abil_reg_s cn56xx;
 	struct cvmx_pcsxx_spd_abil_reg_s cn56xxp1;
+	struct cvmx_pcsxx_spd_abil_reg_s cn61xx;
+	struct cvmx_pcsxx_spd_abil_reg_s cn63xx;
+	struct cvmx_pcsxx_spd_abil_reg_s cn63xxp1;
+	struct cvmx_pcsxx_spd_abil_reg_s cn66xx;
+	struct cvmx_pcsxx_spd_abil_reg_s cn68xx;
+	struct cvmx_pcsxx_spd_abil_reg_s cn68xxp1;
 };
 
 union cvmx_pcsxx_status1_reg {
 	uint64_t u64;
 	struct cvmx_pcsxx_status1_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t flt:1;
 		uint64_t reserved_3_6:4;
 		uint64_t rcv_lnk:1;
 		uint64_t lpable:1;
 		uint64_t reserved_0_0:1;
+#else
+		uint64_t reserved_0_0:1;
+		uint64_t lpable:1;
+		uint64_t rcv_lnk:1;
+		uint64_t reserved_3_6:4;
+		uint64_t flt:1;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_pcsxx_status1_reg_s cn52xx;
 	struct cvmx_pcsxx_status1_reg_s cn52xxp1;
 	struct cvmx_pcsxx_status1_reg_s cn56xx;
 	struct cvmx_pcsxx_status1_reg_s cn56xxp1;
+	struct cvmx_pcsxx_status1_reg_s cn61xx;
+	struct cvmx_pcsxx_status1_reg_s cn63xx;
+	struct cvmx_pcsxx_status1_reg_s cn63xxp1;
+	struct cvmx_pcsxx_status1_reg_s cn66xx;
+	struct cvmx_pcsxx_status1_reg_s cn68xx;
+	struct cvmx_pcsxx_status1_reg_s cn68xxp1;
 };
 
 union cvmx_pcsxx_status2_reg {
 	uint64_t u64;
 	struct cvmx_pcsxx_status2_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t dev:2;
 		uint64_t reserved_12_13:2;
@@ -257,35 +681,73 @@
 		uint64_t tengb_w:1;
 		uint64_t tengb_x:1;
 		uint64_t tengb_r:1;
+#else
+		uint64_t tengb_r:1;
+		uint64_t tengb_x:1;
+		uint64_t tengb_w:1;
+		uint64_t reserved_3_9:7;
+		uint64_t rcvflt:1;
+		uint64_t xmtflt:1;
+		uint64_t reserved_12_13:2;
+		uint64_t dev:2;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_pcsxx_status2_reg_s cn52xx;
 	struct cvmx_pcsxx_status2_reg_s cn52xxp1;
 	struct cvmx_pcsxx_status2_reg_s cn56xx;
 	struct cvmx_pcsxx_status2_reg_s cn56xxp1;
+	struct cvmx_pcsxx_status2_reg_s cn61xx;
+	struct cvmx_pcsxx_status2_reg_s cn63xx;
+	struct cvmx_pcsxx_status2_reg_s cn63xxp1;
+	struct cvmx_pcsxx_status2_reg_s cn66xx;
+	struct cvmx_pcsxx_status2_reg_s cn68xx;
+	struct cvmx_pcsxx_status2_reg_s cn68xxp1;
 };
 
 union cvmx_pcsxx_tx_rx_polarity_reg {
 	uint64_t u64;
 	struct cvmx_pcsxx_tx_rx_polarity_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t xor_rxplrt:4;
 		uint64_t xor_txplrt:4;
 		uint64_t rxplrt:1;
 		uint64_t txplrt:1;
+#else
+		uint64_t txplrt:1;
+		uint64_t rxplrt:1;
+		uint64_t xor_txplrt:4;
+		uint64_t xor_rxplrt:4;
+		uint64_t reserved_10_63:54;
+#endif
 	} s;
 	struct cvmx_pcsxx_tx_rx_polarity_reg_s cn52xx;
 	struct cvmx_pcsxx_tx_rx_polarity_reg_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t rxplrt:1;
 		uint64_t txplrt:1;
+#else
+		uint64_t txplrt:1;
+		uint64_t rxplrt:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} cn52xxp1;
 	struct cvmx_pcsxx_tx_rx_polarity_reg_s cn56xx;
 	struct cvmx_pcsxx_tx_rx_polarity_reg_cn52xxp1 cn56xxp1;
+	struct cvmx_pcsxx_tx_rx_polarity_reg_s cn61xx;
+	struct cvmx_pcsxx_tx_rx_polarity_reg_s cn63xx;
+	struct cvmx_pcsxx_tx_rx_polarity_reg_s cn63xxp1;
+	struct cvmx_pcsxx_tx_rx_polarity_reg_s cn66xx;
+	struct cvmx_pcsxx_tx_rx_polarity_reg_s cn68xx;
+	struct cvmx_pcsxx_tx_rx_polarity_reg_s cn68xxp1;
 };
 
 union cvmx_pcsxx_tx_rx_states_reg {
 	uint64_t u64;
 	struct cvmx_pcsxx_tx_rx_states_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_14_63:50;
 		uint64_t term_err:1;
 		uint64_t syn3bad:1;
@@ -296,9 +758,22 @@
 		uint64_t algn_st:3;
 		uint64_t rx_st:2;
 		uint64_t tx_st:3;
+#else
+		uint64_t tx_st:3;
+		uint64_t rx_st:2;
+		uint64_t algn_st:3;
+		uint64_t rxbad:1;
+		uint64_t syn0bad:1;
+		uint64_t syn1bad:1;
+		uint64_t syn2bad:1;
+		uint64_t syn3bad:1;
+		uint64_t term_err:1;
+		uint64_t reserved_14_63:50;
+#endif
 	} s;
 	struct cvmx_pcsxx_tx_rx_states_reg_s cn52xx;
 	struct cvmx_pcsxx_tx_rx_states_reg_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_13_63:51;
 		uint64_t syn3bad:1;
 		uint64_t syn2bad:1;
@@ -308,9 +783,26 @@
 		uint64_t algn_st:3;
 		uint64_t rx_st:2;
 		uint64_t tx_st:3;
+#else
+		uint64_t tx_st:3;
+		uint64_t rx_st:2;
+		uint64_t algn_st:3;
+		uint64_t rxbad:1;
+		uint64_t syn0bad:1;
+		uint64_t syn1bad:1;
+		uint64_t syn2bad:1;
+		uint64_t syn3bad:1;
+		uint64_t reserved_13_63:51;
+#endif
 	} cn52xxp1;
 	struct cvmx_pcsxx_tx_rx_states_reg_s cn56xx;
 	struct cvmx_pcsxx_tx_rx_states_reg_cn52xxp1 cn56xxp1;
+	struct cvmx_pcsxx_tx_rx_states_reg_s cn61xx;
+	struct cvmx_pcsxx_tx_rx_states_reg_s cn63xx;
+	struct cvmx_pcsxx_tx_rx_states_reg_s cn63xxp1;
+	struct cvmx_pcsxx_tx_rx_states_reg_s cn66xx;
+	struct cvmx_pcsxx_tx_rx_states_reg_s cn68xx;
+	struct cvmx_pcsxx_tx_rx_states_reg_s cn68xxp1;
 };
 
 #endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pemx-defs.h b/arch/mips/include/asm/octeon/cvmx-pemx-defs.h
index be189a2..50a916f 100644
--- a/arch/mips/include/asm/octeon/cvmx-pemx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pemx-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2011 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -54,11 +54,19 @@
 union cvmx_pemx_bar1_indexx {
 	uint64_t u64;
 	struct cvmx_pemx_bar1_indexx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t addr_idx:16;
 		uint64_t ca:1;
 		uint64_t end_swp:2;
 		uint64_t addr_v:1;
+#else
+		uint64_t addr_v:1;
+		uint64_t end_swp:2;
+		uint64_t ca:1;
+		uint64_t addr_idx:16;
+		uint64_t reserved_20_63:44;
+#endif
 	} s;
 	struct cvmx_pemx_bar1_indexx_s cn61xx;
 	struct cvmx_pemx_bar1_indexx_s cn63xx;
@@ -66,29 +74,45 @@
 	struct cvmx_pemx_bar1_indexx_s cn66xx;
 	struct cvmx_pemx_bar1_indexx_s cn68xx;
 	struct cvmx_pemx_bar1_indexx_s cn68xxp1;
+	struct cvmx_pemx_bar1_indexx_s cnf71xx;
 };
 
 union cvmx_pemx_bar2_mask {
 	uint64_t u64;
 	struct cvmx_pemx_bar2_mask_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_38_63:26;
 		uint64_t mask:35;
 		uint64_t reserved_0_2:3;
+#else
+		uint64_t reserved_0_2:3;
+		uint64_t mask:35;
+		uint64_t reserved_38_63:26;
+#endif
 	} s;
 	struct cvmx_pemx_bar2_mask_s cn61xx;
 	struct cvmx_pemx_bar2_mask_s cn66xx;
 	struct cvmx_pemx_bar2_mask_s cn68xx;
 	struct cvmx_pemx_bar2_mask_s cn68xxp1;
+	struct cvmx_pemx_bar2_mask_s cnf71xx;
 };
 
 union cvmx_pemx_bar_ctl {
 	uint64_t u64;
 	struct cvmx_pemx_bar_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_7_63:57;
 		uint64_t bar1_siz:3;
 		uint64_t bar2_enb:1;
 		uint64_t bar2_esx:2;
 		uint64_t bar2_cax:1;
+#else
+		uint64_t bar2_cax:1;
+		uint64_t bar2_esx:2;
+		uint64_t bar2_enb:1;
+		uint64_t bar1_siz:3;
+		uint64_t reserved_7_63:57;
+#endif
 	} s;
 	struct cvmx_pemx_bar_ctl_s cn61xx;
 	struct cvmx_pemx_bar_ctl_s cn63xx;
@@ -96,11 +120,13 @@
 	struct cvmx_pemx_bar_ctl_s cn66xx;
 	struct cvmx_pemx_bar_ctl_s cn68xx;
 	struct cvmx_pemx_bar_ctl_s cn68xxp1;
+	struct cvmx_pemx_bar_ctl_s cnf71xx;
 };
 
 union cvmx_pemx_bist_status {
 	uint64_t u64;
 	struct cvmx_pemx_bist_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t retry:1;
 		uint64_t rqdata0:1;
@@ -110,6 +136,17 @@
 		uint64_t rqhdr1:1;
 		uint64_t rqhdr0:1;
 		uint64_t sot:1;
+#else
+		uint64_t sot:1;
+		uint64_t rqhdr0:1;
+		uint64_t rqhdr1:1;
+		uint64_t rqdata3:1;
+		uint64_t rqdata2:1;
+		uint64_t rqdata1:1;
+		uint64_t rqdata0:1;
+		uint64_t retry:1;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_pemx_bist_status_s cn61xx;
 	struct cvmx_pemx_bist_status_s cn63xx;
@@ -117,11 +154,13 @@
 	struct cvmx_pemx_bist_status_s cn66xx;
 	struct cvmx_pemx_bist_status_s cn68xx;
 	struct cvmx_pemx_bist_status_s cn68xxp1;
+	struct cvmx_pemx_bist_status_s cnf71xx;
 };
 
 union cvmx_pemx_bist_status2 {
 	uint64_t u64;
 	struct cvmx_pemx_bist_status2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t e2p_cpl:1;
 		uint64_t e2p_n:1;
@@ -133,6 +172,19 @@
 		uint64_t pef_tcf1:1;
 		uint64_t pef_tc0:1;
 		uint64_t ppf:1;
+#else
+		uint64_t ppf:1;
+		uint64_t pef_tc0:1;
+		uint64_t pef_tcf1:1;
+		uint64_t pef_tnf:1;
+		uint64_t pef_tpf0:1;
+		uint64_t pef_tpf1:1;
+		uint64_t peai_p2e:1;
+		uint64_t e2p_p:1;
+		uint64_t e2p_n:1;
+		uint64_t e2p_cpl:1;
+		uint64_t reserved_10_63:54;
+#endif
 	} s;
 	struct cvmx_pemx_bist_status2_s cn61xx;
 	struct cvmx_pemx_bist_status2_s cn63xx;
@@ -140,13 +192,19 @@
 	struct cvmx_pemx_bist_status2_s cn66xx;
 	struct cvmx_pemx_bist_status2_s cn68xx;
 	struct cvmx_pemx_bist_status2_s cn68xxp1;
+	struct cvmx_pemx_bist_status2_s cnf71xx;
 };
 
 union cvmx_pemx_cfg_rd {
 	uint64_t u64;
 	struct cvmx_pemx_cfg_rd_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t data:32;
 		uint64_t addr:32;
+#else
+		uint64_t addr:32;
+		uint64_t data:32;
+#endif
 	} s;
 	struct cvmx_pemx_cfg_rd_s cn61xx;
 	struct cvmx_pemx_cfg_rd_s cn63xx;
@@ -154,13 +212,19 @@
 	struct cvmx_pemx_cfg_rd_s cn66xx;
 	struct cvmx_pemx_cfg_rd_s cn68xx;
 	struct cvmx_pemx_cfg_rd_s cn68xxp1;
+	struct cvmx_pemx_cfg_rd_s cnf71xx;
 };
 
 union cvmx_pemx_cfg_wr {
 	uint64_t u64;
 	struct cvmx_pemx_cfg_wr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t data:32;
 		uint64_t addr:32;
+#else
+		uint64_t addr:32;
+		uint64_t data:32;
+#endif
 	} s;
 	struct cvmx_pemx_cfg_wr_s cn61xx;
 	struct cvmx_pemx_cfg_wr_s cn63xx;
@@ -168,13 +232,19 @@
 	struct cvmx_pemx_cfg_wr_s cn66xx;
 	struct cvmx_pemx_cfg_wr_s cn68xx;
 	struct cvmx_pemx_cfg_wr_s cn68xxp1;
+	struct cvmx_pemx_cfg_wr_s cnf71xx;
 };
 
 union cvmx_pemx_cpl_lut_valid {
 	uint64_t u64;
 	struct cvmx_pemx_cpl_lut_valid_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t tag:32;
+#else
+		uint64_t tag:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_pemx_cpl_lut_valid_s cn61xx;
 	struct cvmx_pemx_cpl_lut_valid_s cn63xx;
@@ -182,11 +252,13 @@
 	struct cvmx_pemx_cpl_lut_valid_s cn66xx;
 	struct cvmx_pemx_cpl_lut_valid_s cn68xx;
 	struct cvmx_pemx_cpl_lut_valid_s cn68xxp1;
+	struct cvmx_pemx_cpl_lut_valid_s cnf71xx;
 };
 
 union cvmx_pemx_ctl_status {
 	uint64_t u64;
 	struct cvmx_pemx_ctl_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t auto_sd:1;
 		uint64_t dnum:5;
@@ -205,6 +277,26 @@
 		uint64_t fast_lm:1;
 		uint64_t inv_ecrc:1;
 		uint64_t inv_lcrc:1;
+#else
+		uint64_t inv_lcrc:1;
+		uint64_t inv_ecrc:1;
+		uint64_t fast_lm:1;
+		uint64_t ro_ctlp:1;
+		uint64_t lnk_enb:1;
+		uint64_t dly_one:1;
+		uint64_t nf_ecrc:1;
+		uint64_t reserved_7_8:2;
+		uint64_t ob_p_cmd:1;
+		uint64_t pm_xpme:1;
+		uint64_t pm_xtoff:1;
+		uint64_t reserved_12_15:4;
+		uint64_t cfg_rtry:16;
+		uint64_t reserved_32_33:2;
+		uint64_t pbus:8;
+		uint64_t dnum:5;
+		uint64_t auto_sd:1;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_pemx_ctl_status_s cn61xx;
 	struct cvmx_pemx_ctl_status_s cn63xx;
@@ -212,11 +304,13 @@
 	struct cvmx_pemx_ctl_status_s cn66xx;
 	struct cvmx_pemx_ctl_status_s cn68xx;
 	struct cvmx_pemx_ctl_status_s cn68xxp1;
+	struct cvmx_pemx_ctl_status_s cnf71xx;
 };
 
 union cvmx_pemx_dbg_info {
 	uint64_t u64;
 	struct cvmx_pemx_dbg_info_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_31_63:33;
 		uint64_t ecrc_e:1;
 		uint64_t rawwpp:1;
@@ -249,6 +343,40 @@
 		uint64_t rtlplle:1;
 		uint64_t rtlpmal:1;
 		uint64_t spoison:1;
+#else
+		uint64_t spoison:1;
+		uint64_t rtlpmal:1;
+		uint64_t rtlplle:1;
+		uint64_t recrce:1;
+		uint64_t rpoison:1;
+		uint64_t rcemrc:1;
+		uint64_t rnfemrc:1;
+		uint64_t rfemrc:1;
+		uint64_t rpmerc:1;
+		uint64_t rptamrc:1;
+		uint64_t rumep:1;
+		uint64_t rvdm:1;
+		uint64_t acto:1;
+		uint64_t rte:1;
+		uint64_t mre:1;
+		uint64_t rdwdle:1;
+		uint64_t rtwdle:1;
+		uint64_t dpeoosd:1;
+		uint64_t fcpvwt:1;
+		uint64_t rpe:1;
+		uint64_t fcuv:1;
+		uint64_t rqo:1;
+		uint64_t rauc:1;
+		uint64_t racur:1;
+		uint64_t racca:1;
+		uint64_t caar:1;
+		uint64_t rarwdns:1;
+		uint64_t ramtlp:1;
+		uint64_t racpp:1;
+		uint64_t rawwpp:1;
+		uint64_t ecrc_e:1;
+		uint64_t reserved_31_63:33;
+#endif
 	} s;
 	struct cvmx_pemx_dbg_info_s cn61xx;
 	struct cvmx_pemx_dbg_info_s cn63xx;
@@ -256,11 +384,13 @@
 	struct cvmx_pemx_dbg_info_s cn66xx;
 	struct cvmx_pemx_dbg_info_s cn68xx;
 	struct cvmx_pemx_dbg_info_s cn68xxp1;
+	struct cvmx_pemx_dbg_info_s cnf71xx;
 };
 
 union cvmx_pemx_dbg_info_en {
 	uint64_t u64;
 	struct cvmx_pemx_dbg_info_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_31_63:33;
 		uint64_t ecrc_e:1;
 		uint64_t rawwpp:1;
@@ -293,6 +423,40 @@
 		uint64_t rtlplle:1;
 		uint64_t rtlpmal:1;
 		uint64_t spoison:1;
+#else
+		uint64_t spoison:1;
+		uint64_t rtlpmal:1;
+		uint64_t rtlplle:1;
+		uint64_t recrce:1;
+		uint64_t rpoison:1;
+		uint64_t rcemrc:1;
+		uint64_t rnfemrc:1;
+		uint64_t rfemrc:1;
+		uint64_t rpmerc:1;
+		uint64_t rptamrc:1;
+		uint64_t rumep:1;
+		uint64_t rvdm:1;
+		uint64_t acto:1;
+		uint64_t rte:1;
+		uint64_t mre:1;
+		uint64_t rdwdle:1;
+		uint64_t rtwdle:1;
+		uint64_t dpeoosd:1;
+		uint64_t fcpvwt:1;
+		uint64_t rpe:1;
+		uint64_t fcuv:1;
+		uint64_t rqo:1;
+		uint64_t rauc:1;
+		uint64_t racur:1;
+		uint64_t racca:1;
+		uint64_t caar:1;
+		uint64_t rarwdns:1;
+		uint64_t ramtlp:1;
+		uint64_t racpp:1;
+		uint64_t rawwpp:1;
+		uint64_t ecrc_e:1;
+		uint64_t reserved_31_63:33;
+#endif
 	} s;
 	struct cvmx_pemx_dbg_info_en_s cn61xx;
 	struct cvmx_pemx_dbg_info_en_s cn63xx;
@@ -300,16 +464,25 @@
 	struct cvmx_pemx_dbg_info_en_s cn66xx;
 	struct cvmx_pemx_dbg_info_en_s cn68xx;
 	struct cvmx_pemx_dbg_info_en_s cn68xxp1;
+	struct cvmx_pemx_dbg_info_en_s cnf71xx;
 };
 
 union cvmx_pemx_diag_status {
 	uint64_t u64;
 	struct cvmx_pemx_diag_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t pm_dst:1;
 		uint64_t pm_stat:1;
 		uint64_t pm_en:1;
 		uint64_t aux_en:1;
+#else
+		uint64_t aux_en:1;
+		uint64_t pm_en:1;
+		uint64_t pm_stat:1;
+		uint64_t pm_dst:1;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_pemx_diag_status_s cn61xx;
 	struct cvmx_pemx_diag_status_s cn63xx;
@@ -317,22 +490,30 @@
 	struct cvmx_pemx_diag_status_s cn66xx;
 	struct cvmx_pemx_diag_status_s cn68xx;
 	struct cvmx_pemx_diag_status_s cn68xxp1;
+	struct cvmx_pemx_diag_status_s cnf71xx;
 };
 
 union cvmx_pemx_inb_read_credits {
 	uint64_t u64;
 	struct cvmx_pemx_inb_read_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t num:6;
+#else
+		uint64_t num:6;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
 	struct cvmx_pemx_inb_read_credits_s cn61xx;
 	struct cvmx_pemx_inb_read_credits_s cn66xx;
 	struct cvmx_pemx_inb_read_credits_s cn68xx;
+	struct cvmx_pemx_inb_read_credits_s cnf71xx;
 };
 
 union cvmx_pemx_int_enb {
 	uint64_t u64;
 	struct cvmx_pemx_int_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_14_63:50;
 		uint64_t crs_dr:1;
 		uint64_t crs_er:1;
@@ -348,6 +529,23 @@
 		uint64_t pmei:1;
 		uint64_t se:1;
 		uint64_t aeri:1;
+#else
+		uint64_t aeri:1;
+		uint64_t se:1;
+		uint64_t pmei:1;
+		uint64_t pmem:1;
+		uint64_t up_b1:1;
+		uint64_t up_b2:1;
+		uint64_t up_bx:1;
+		uint64_t un_b1:1;
+		uint64_t un_b2:1;
+		uint64_t un_bx:1;
+		uint64_t exc:1;
+		uint64_t rdlk:1;
+		uint64_t crs_er:1;
+		uint64_t crs_dr:1;
+		uint64_t reserved_14_63:50;
+#endif
 	} s;
 	struct cvmx_pemx_int_enb_s cn61xx;
 	struct cvmx_pemx_int_enb_s cn63xx;
@@ -355,11 +553,13 @@
 	struct cvmx_pemx_int_enb_s cn66xx;
 	struct cvmx_pemx_int_enb_s cn68xx;
 	struct cvmx_pemx_int_enb_s cn68xxp1;
+	struct cvmx_pemx_int_enb_s cnf71xx;
 };
 
 union cvmx_pemx_int_enb_int {
 	uint64_t u64;
 	struct cvmx_pemx_int_enb_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_14_63:50;
 		uint64_t crs_dr:1;
 		uint64_t crs_er:1;
@@ -375,6 +575,23 @@
 		uint64_t pmei:1;
 		uint64_t se:1;
 		uint64_t aeri:1;
+#else
+		uint64_t aeri:1;
+		uint64_t se:1;
+		uint64_t pmei:1;
+		uint64_t pmem:1;
+		uint64_t up_b1:1;
+		uint64_t up_b2:1;
+		uint64_t up_bx:1;
+		uint64_t un_b1:1;
+		uint64_t un_b2:1;
+		uint64_t un_bx:1;
+		uint64_t exc:1;
+		uint64_t rdlk:1;
+		uint64_t crs_er:1;
+		uint64_t crs_dr:1;
+		uint64_t reserved_14_63:50;
+#endif
 	} s;
 	struct cvmx_pemx_int_enb_int_s cn61xx;
 	struct cvmx_pemx_int_enb_int_s cn63xx;
@@ -382,11 +599,13 @@
 	struct cvmx_pemx_int_enb_int_s cn66xx;
 	struct cvmx_pemx_int_enb_int_s cn68xx;
 	struct cvmx_pemx_int_enb_int_s cn68xxp1;
+	struct cvmx_pemx_int_enb_int_s cnf71xx;
 };
 
 union cvmx_pemx_int_sum {
 	uint64_t u64;
 	struct cvmx_pemx_int_sum_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_14_63:50;
 		uint64_t crs_dr:1;
 		uint64_t crs_er:1;
@@ -402,6 +621,23 @@
 		uint64_t pmei:1;
 		uint64_t se:1;
 		uint64_t aeri:1;
+#else
+		uint64_t aeri:1;
+		uint64_t se:1;
+		uint64_t pmei:1;
+		uint64_t pmem:1;
+		uint64_t up_b1:1;
+		uint64_t up_b2:1;
+		uint64_t up_bx:1;
+		uint64_t un_b1:1;
+		uint64_t un_b2:1;
+		uint64_t un_bx:1;
+		uint64_t exc:1;
+		uint64_t rdlk:1;
+		uint64_t crs_er:1;
+		uint64_t crs_dr:1;
+		uint64_t reserved_14_63:50;
+#endif
 	} s;
 	struct cvmx_pemx_int_sum_s cn61xx;
 	struct cvmx_pemx_int_sum_s cn63xx;
@@ -409,13 +645,19 @@
 	struct cvmx_pemx_int_sum_s cn66xx;
 	struct cvmx_pemx_int_sum_s cn68xx;
 	struct cvmx_pemx_int_sum_s cn68xxp1;
+	struct cvmx_pemx_int_sum_s cnf71xx;
 };
 
 union cvmx_pemx_p2n_bar0_start {
 	uint64_t u64;
 	struct cvmx_pemx_p2n_bar0_start_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t addr:50;
 		uint64_t reserved_0_13:14;
+#else
+		uint64_t reserved_0_13:14;
+		uint64_t addr:50;
+#endif
 	} s;
 	struct cvmx_pemx_p2n_bar0_start_s cn61xx;
 	struct cvmx_pemx_p2n_bar0_start_s cn63xx;
@@ -423,13 +665,19 @@
 	struct cvmx_pemx_p2n_bar0_start_s cn66xx;
 	struct cvmx_pemx_p2n_bar0_start_s cn68xx;
 	struct cvmx_pemx_p2n_bar0_start_s cn68xxp1;
+	struct cvmx_pemx_p2n_bar0_start_s cnf71xx;
 };
 
 union cvmx_pemx_p2n_bar1_start {
 	uint64_t u64;
 	struct cvmx_pemx_p2n_bar1_start_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t addr:38;
 		uint64_t reserved_0_25:26;
+#else
+		uint64_t reserved_0_25:26;
+		uint64_t addr:38;
+#endif
 	} s;
 	struct cvmx_pemx_p2n_bar1_start_s cn61xx;
 	struct cvmx_pemx_p2n_bar1_start_s cn63xx;
@@ -437,13 +685,19 @@
 	struct cvmx_pemx_p2n_bar1_start_s cn66xx;
 	struct cvmx_pemx_p2n_bar1_start_s cn68xx;
 	struct cvmx_pemx_p2n_bar1_start_s cn68xxp1;
+	struct cvmx_pemx_p2n_bar1_start_s cnf71xx;
 };
 
 union cvmx_pemx_p2n_bar2_start {
 	uint64_t u64;
 	struct cvmx_pemx_p2n_bar2_start_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t addr:23;
 		uint64_t reserved_0_40:41;
+#else
+		uint64_t reserved_0_40:41;
+		uint64_t addr:23;
+#endif
 	} s;
 	struct cvmx_pemx_p2n_bar2_start_s cn61xx;
 	struct cvmx_pemx_p2n_bar2_start_s cn63xx;
@@ -451,13 +705,19 @@
 	struct cvmx_pemx_p2n_bar2_start_s cn66xx;
 	struct cvmx_pemx_p2n_bar2_start_s cn68xx;
 	struct cvmx_pemx_p2n_bar2_start_s cn68xxp1;
+	struct cvmx_pemx_p2n_bar2_start_s cnf71xx;
 };
 
 union cvmx_pemx_p2p_barx_end {
 	uint64_t u64;
 	struct cvmx_pemx_p2p_barx_end_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t addr:52;
 		uint64_t reserved_0_11:12;
+#else
+		uint64_t reserved_0_11:12;
+		uint64_t addr:52;
+#endif
 	} s;
 	struct cvmx_pemx_p2p_barx_end_s cn63xx;
 	struct cvmx_pemx_p2p_barx_end_s cn63xxp1;
@@ -469,8 +729,13 @@
 union cvmx_pemx_p2p_barx_start {
 	uint64_t u64;
 	struct cvmx_pemx_p2p_barx_start_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t addr:52;
 		uint64_t reserved_0_11:12;
+#else
+		uint64_t reserved_0_11:12;
+		uint64_t addr:52;
+#endif
 	} s;
 	struct cvmx_pemx_p2p_barx_start_s cn63xx;
 	struct cvmx_pemx_p2p_barx_start_s cn63xxp1;
@@ -482,6 +747,7 @@
 union cvmx_pemx_tlp_credits {
 	uint64_t u64;
 	struct cvmx_pemx_tlp_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_56_63:8;
 		uint64_t peai_ppf:8;
 		uint64_t pem_cpl:8;
@@ -490,20 +756,40 @@
 		uint64_t sli_cpl:8;
 		uint64_t sli_np:8;
 		uint64_t sli_p:8;
+#else
+		uint64_t sli_p:8;
+		uint64_t sli_np:8;
+		uint64_t sli_cpl:8;
+		uint64_t pem_p:8;
+		uint64_t pem_np:8;
+		uint64_t pem_cpl:8;
+		uint64_t peai_ppf:8;
+		uint64_t reserved_56_63:8;
+#endif
 	} s;
 	struct cvmx_pemx_tlp_credits_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_56_63:8;
 		uint64_t peai_ppf:8;
 		uint64_t reserved_24_47:24;
 		uint64_t sli_cpl:8;
 		uint64_t sli_np:8;
 		uint64_t sli_p:8;
+#else
+		uint64_t sli_p:8;
+		uint64_t sli_np:8;
+		uint64_t sli_cpl:8;
+		uint64_t reserved_24_47:24;
+		uint64_t peai_ppf:8;
+		uint64_t reserved_56_63:8;
+#endif
 	} cn61xx;
 	struct cvmx_pemx_tlp_credits_s cn63xx;
 	struct cvmx_pemx_tlp_credits_s cn63xxp1;
 	struct cvmx_pemx_tlp_credits_s cn66xx;
 	struct cvmx_pemx_tlp_credits_s cn68xx;
 	struct cvmx_pemx_tlp_credits_s cn68xxp1;
+	struct cvmx_pemx_tlp_credits_cn61xx cnf71xx;
 };
 
 #endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pescx-defs.h b/arch/mips/include/asm/octeon/cvmx-pescx-defs.h
index aef8485..59b3dc5 100644
--- a/arch/mips/include/asm/octeon/cvmx-pescx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pescx-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -48,6 +48,7 @@
 union cvmx_pescx_bist_status {
 	uint64_t u64;
 	struct cvmx_pescx_bist_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_13_63:51;
 		uint64_t rqdata5:1;
 		uint64_t ctlp_or:1;
@@ -62,9 +63,26 @@
 		uint64_t rqhdr1:1;
 		uint64_t rqhdr0:1;
 		uint64_t sot:1;
+#else
+		uint64_t sot:1;
+		uint64_t rqhdr0:1;
+		uint64_t rqhdr1:1;
+		uint64_t rqdata4:1;
+		uint64_t rqdata3:1;
+		uint64_t rqdata2:1;
+		uint64_t rqdata1:1;
+		uint64_t rqdata0:1;
+		uint64_t retry:1;
+		uint64_t ptlp_or:1;
+		uint64_t ntlp_or:1;
+		uint64_t ctlp_or:1;
+		uint64_t rqdata5:1;
+		uint64_t reserved_13_63:51;
+#endif
 	} s;
 	struct cvmx_pescx_bist_status_s cn52xx;
 	struct cvmx_pescx_bist_status_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t ctlp_or:1;
 		uint64_t ntlp_or:1;
@@ -78,6 +96,21 @@
 		uint64_t rqhdr1:1;
 		uint64_t rqhdr0:1;
 		uint64_t sot:1;
+#else
+		uint64_t sot:1;
+		uint64_t rqhdr0:1;
+		uint64_t rqhdr1:1;
+		uint64_t rqdata4:1;
+		uint64_t rqdata3:1;
+		uint64_t rqdata2:1;
+		uint64_t rqdata1:1;
+		uint64_t rqdata0:1;
+		uint64_t retry:1;
+		uint64_t ptlp_or:1;
+		uint64_t ntlp_or:1;
+		uint64_t ctlp_or:1;
+		uint64_t reserved_12_63:52;
+#endif
 	} cn52xxp1;
 	struct cvmx_pescx_bist_status_s cn56xx;
 	struct cvmx_pescx_bist_status_cn52xxp1 cn56xxp1;
@@ -86,6 +119,7 @@
 union cvmx_pescx_bist_status2 {
 	uint64_t u64;
 	struct cvmx_pescx_bist_status2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_14_63:50;
 		uint64_t cto_p2e:1;
 		uint64_t e2p_cpl:1;
@@ -101,6 +135,23 @@
 		uint64_t pef_tcf1:1;
 		uint64_t pef_tc0:1;
 		uint64_t ppf:1;
+#else
+		uint64_t ppf:1;
+		uint64_t pef_tc0:1;
+		uint64_t pef_tcf1:1;
+		uint64_t pef_tnf:1;
+		uint64_t pef_tpf0:1;
+		uint64_t pef_tpf1:1;
+		uint64_t rsl_p2e:1;
+		uint64_t peai_p2e:1;
+		uint64_t dbg_p2e:1;
+		uint64_t e2p_rsl:1;
+		uint64_t e2p_p:1;
+		uint64_t e2p_n:1;
+		uint64_t e2p_cpl:1;
+		uint64_t cto_p2e:1;
+		uint64_t reserved_14_63:50;
+#endif
 	} s;
 	struct cvmx_pescx_bist_status2_s cn52xx;
 	struct cvmx_pescx_bist_status2_s cn52xxp1;
@@ -111,8 +162,13 @@
 union cvmx_pescx_cfg_rd {
 	uint64_t u64;
 	struct cvmx_pescx_cfg_rd_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t data:32;
 		uint64_t addr:32;
+#else
+		uint64_t addr:32;
+		uint64_t data:32;
+#endif
 	} s;
 	struct cvmx_pescx_cfg_rd_s cn52xx;
 	struct cvmx_pescx_cfg_rd_s cn52xxp1;
@@ -123,8 +179,13 @@
 union cvmx_pescx_cfg_wr {
 	uint64_t u64;
 	struct cvmx_pescx_cfg_wr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t data:32;
 		uint64_t addr:32;
+#else
+		uint64_t addr:32;
+		uint64_t data:32;
+#endif
 	} s;
 	struct cvmx_pescx_cfg_wr_s cn52xx;
 	struct cvmx_pescx_cfg_wr_s cn52xxp1;
@@ -135,8 +196,13 @@
 union cvmx_pescx_cpl_lut_valid {
 	uint64_t u64;
 	struct cvmx_pescx_cpl_lut_valid_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t tag:32;
+#else
+		uint64_t tag:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_pescx_cpl_lut_valid_s cn52xx;
 	struct cvmx_pescx_cpl_lut_valid_s cn52xxp1;
@@ -147,6 +213,7 @@
 union cvmx_pescx_ctl_status {
 	uint64_t u64;
 	struct cvmx_pescx_ctl_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_28_63:36;
 		uint64_t dnum:5;
 		uint64_t pbus:8;
@@ -163,10 +230,29 @@
 		uint64_t reserved_2_2:1;
 		uint64_t inv_ecrc:1;
 		uint64_t inv_lcrc:1;
+#else
+		uint64_t inv_lcrc:1;
+		uint64_t inv_ecrc:1;
+		uint64_t reserved_2_2:1;
+		uint64_t ro_ctlp:1;
+		uint64_t lnk_enb:1;
+		uint64_t dly_one:1;
+		uint64_t nf_ecrc:1;
+		uint64_t reserved_7_8:2;
+		uint64_t ob_p_cmd:1;
+		uint64_t pm_xpme:1;
+		uint64_t pm_xtoff:1;
+		uint64_t lane_swp:1;
+		uint64_t qlm_cfg:2;
+		uint64_t pbus:8;
+		uint64_t dnum:5;
+		uint64_t reserved_28_63:36;
+#endif
 	} s;
 	struct cvmx_pescx_ctl_status_s cn52xx;
 	struct cvmx_pescx_ctl_status_s cn52xxp1;
 	struct cvmx_pescx_ctl_status_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_28_63:36;
 		uint64_t dnum:5;
 		uint64_t pbus:8;
@@ -183,6 +269,24 @@
 		uint64_t reserved_2_2:1;
 		uint64_t inv_ecrc:1;
 		uint64_t inv_lcrc:1;
+#else
+		uint64_t inv_lcrc:1;
+		uint64_t inv_ecrc:1;
+		uint64_t reserved_2_2:1;
+		uint64_t ro_ctlp:1;
+		uint64_t lnk_enb:1;
+		uint64_t dly_one:1;
+		uint64_t nf_ecrc:1;
+		uint64_t reserved_7_8:2;
+		uint64_t ob_p_cmd:1;
+		uint64_t pm_xpme:1;
+		uint64_t pm_xtoff:1;
+		uint64_t reserved_12_12:1;
+		uint64_t qlm_cfg:2;
+		uint64_t pbus:8;
+		uint64_t dnum:5;
+		uint64_t reserved_28_63:36;
+#endif
 	} cn56xx;
 	struct cvmx_pescx_ctl_status_cn56xx cn56xxp1;
 };
@@ -190,14 +294,25 @@
 union cvmx_pescx_ctl_status2 {
 	uint64_t u64;
 	struct cvmx_pescx_ctl_status2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t pclk_run:1;
 		uint64_t pcierst:1;
+#else
+		uint64_t pcierst:1;
+		uint64_t pclk_run:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_pescx_ctl_status2_s cn52xx;
 	struct cvmx_pescx_ctl_status2_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t pcierst:1;
+#else
+		uint64_t pcierst:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} cn52xxp1;
 	struct cvmx_pescx_ctl_status2_s cn56xx;
 	struct cvmx_pescx_ctl_status2_cn52xxp1 cn56xxp1;
@@ -206,6 +321,7 @@
 union cvmx_pescx_dbg_info {
 	uint64_t u64;
 	struct cvmx_pescx_dbg_info_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_31_63:33;
 		uint64_t ecrc_e:1;
 		uint64_t rawwpp:1;
@@ -238,6 +354,40 @@
 		uint64_t rtlplle:1;
 		uint64_t rtlpmal:1;
 		uint64_t spoison:1;
+#else
+		uint64_t spoison:1;
+		uint64_t rtlpmal:1;
+		uint64_t rtlplle:1;
+		uint64_t recrce:1;
+		uint64_t rpoison:1;
+		uint64_t rcemrc:1;
+		uint64_t rnfemrc:1;
+		uint64_t rfemrc:1;
+		uint64_t rpmerc:1;
+		uint64_t rptamrc:1;
+		uint64_t rumep:1;
+		uint64_t rvdm:1;
+		uint64_t acto:1;
+		uint64_t rte:1;
+		uint64_t mre:1;
+		uint64_t rdwdle:1;
+		uint64_t rtwdle:1;
+		uint64_t dpeoosd:1;
+		uint64_t fcpvwt:1;
+		uint64_t rpe:1;
+		uint64_t fcuv:1;
+		uint64_t rqo:1;
+		uint64_t rauc:1;
+		uint64_t racur:1;
+		uint64_t racca:1;
+		uint64_t caar:1;
+		uint64_t rarwdns:1;
+		uint64_t ramtlp:1;
+		uint64_t racpp:1;
+		uint64_t rawwpp:1;
+		uint64_t ecrc_e:1;
+		uint64_t reserved_31_63:33;
+#endif
 	} s;
 	struct cvmx_pescx_dbg_info_s cn52xx;
 	struct cvmx_pescx_dbg_info_s cn52xxp1;
@@ -248,6 +398,7 @@
 union cvmx_pescx_dbg_info_en {
 	uint64_t u64;
 	struct cvmx_pescx_dbg_info_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_31_63:33;
 		uint64_t ecrc_e:1;
 		uint64_t rawwpp:1;
@@ -280,6 +431,40 @@
 		uint64_t rtlplle:1;
 		uint64_t rtlpmal:1;
 		uint64_t spoison:1;
+#else
+		uint64_t spoison:1;
+		uint64_t rtlpmal:1;
+		uint64_t rtlplle:1;
+		uint64_t recrce:1;
+		uint64_t rpoison:1;
+		uint64_t rcemrc:1;
+		uint64_t rnfemrc:1;
+		uint64_t rfemrc:1;
+		uint64_t rpmerc:1;
+		uint64_t rptamrc:1;
+		uint64_t rumep:1;
+		uint64_t rvdm:1;
+		uint64_t acto:1;
+		uint64_t rte:1;
+		uint64_t mre:1;
+		uint64_t rdwdle:1;
+		uint64_t rtwdle:1;
+		uint64_t dpeoosd:1;
+		uint64_t fcpvwt:1;
+		uint64_t rpe:1;
+		uint64_t fcuv:1;
+		uint64_t rqo:1;
+		uint64_t rauc:1;
+		uint64_t racur:1;
+		uint64_t racca:1;
+		uint64_t caar:1;
+		uint64_t rarwdns:1;
+		uint64_t ramtlp:1;
+		uint64_t racpp:1;
+		uint64_t rawwpp:1;
+		uint64_t ecrc_e:1;
+		uint64_t reserved_31_63:33;
+#endif
 	} s;
 	struct cvmx_pescx_dbg_info_en_s cn52xx;
 	struct cvmx_pescx_dbg_info_en_s cn52xxp1;
@@ -290,11 +475,19 @@
 union cvmx_pescx_diag_status {
 	uint64_t u64;
 	struct cvmx_pescx_diag_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t pm_dst:1;
 		uint64_t pm_stat:1;
 		uint64_t pm_en:1;
 		uint64_t aux_en:1;
+#else
+		uint64_t aux_en:1;
+		uint64_t pm_en:1;
+		uint64_t pm_stat:1;
+		uint64_t pm_dst:1;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_pescx_diag_status_s cn52xx;
 	struct cvmx_pescx_diag_status_s cn52xxp1;
@@ -305,8 +498,13 @@
 union cvmx_pescx_p2n_bar0_start {
 	uint64_t u64;
 	struct cvmx_pescx_p2n_bar0_start_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t addr:50;
 		uint64_t reserved_0_13:14;
+#else
+		uint64_t reserved_0_13:14;
+		uint64_t addr:50;
+#endif
 	} s;
 	struct cvmx_pescx_p2n_bar0_start_s cn52xx;
 	struct cvmx_pescx_p2n_bar0_start_s cn52xxp1;
@@ -317,8 +515,13 @@
 union cvmx_pescx_p2n_bar1_start {
 	uint64_t u64;
 	struct cvmx_pescx_p2n_bar1_start_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t addr:38;
 		uint64_t reserved_0_25:26;
+#else
+		uint64_t reserved_0_25:26;
+		uint64_t addr:38;
+#endif
 	} s;
 	struct cvmx_pescx_p2n_bar1_start_s cn52xx;
 	struct cvmx_pescx_p2n_bar1_start_s cn52xxp1;
@@ -329,8 +532,13 @@
 union cvmx_pescx_p2n_bar2_start {
 	uint64_t u64;
 	struct cvmx_pescx_p2n_bar2_start_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t addr:25;
 		uint64_t reserved_0_38:39;
+#else
+		uint64_t reserved_0_38:39;
+		uint64_t addr:25;
+#endif
 	} s;
 	struct cvmx_pescx_p2n_bar2_start_s cn52xx;
 	struct cvmx_pescx_p2n_bar2_start_s cn52xxp1;
@@ -341,8 +549,13 @@
 union cvmx_pescx_p2p_barx_end {
 	uint64_t u64;
 	struct cvmx_pescx_p2p_barx_end_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t addr:52;
 		uint64_t reserved_0_11:12;
+#else
+		uint64_t reserved_0_11:12;
+		uint64_t addr:52;
+#endif
 	} s;
 	struct cvmx_pescx_p2p_barx_end_s cn52xx;
 	struct cvmx_pescx_p2p_barx_end_s cn52xxp1;
@@ -353,8 +566,13 @@
 union cvmx_pescx_p2p_barx_start {
 	uint64_t u64;
 	struct cvmx_pescx_p2p_barx_start_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t addr:52;
 		uint64_t reserved_0_11:12;
+#else
+		uint64_t reserved_0_11:12;
+		uint64_t addr:52;
+#endif
 	} s;
 	struct cvmx_pescx_p2p_barx_start_s cn52xx;
 	struct cvmx_pescx_p2p_barx_start_s cn52xxp1;
@@ -365,9 +583,14 @@
 union cvmx_pescx_tlp_credits {
 	uint64_t u64;
 	struct cvmx_pescx_tlp_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_0_63:64;
+#else
+		uint64_t reserved_0_63:64;
+#endif
 	} s;
 	struct cvmx_pescx_tlp_credits_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_56_63:8;
 		uint64_t peai_ppf:8;
 		uint64_t pesc_cpl:8;
@@ -376,8 +599,19 @@
 		uint64_t npei_cpl:8;
 		uint64_t npei_np:8;
 		uint64_t npei_p:8;
+#else
+		uint64_t npei_p:8;
+		uint64_t npei_np:8;
+		uint64_t npei_cpl:8;
+		uint64_t pesc_p:8;
+		uint64_t pesc_np:8;
+		uint64_t pesc_cpl:8;
+		uint64_t peai_ppf:8;
+		uint64_t reserved_56_63:8;
+#endif
 	} cn52xx;
 	struct cvmx_pescx_tlp_credits_cn52xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_38_63:26;
 		uint64_t peai_ppf:8;
 		uint64_t pesc_cpl:5;
@@ -386,6 +620,16 @@
 		uint64_t npei_cpl:5;
 		uint64_t npei_np:5;
 		uint64_t npei_p:5;
+#else
+		uint64_t npei_p:5;
+		uint64_t npei_np:5;
+		uint64_t npei_cpl:5;
+		uint64_t pesc_p:5;
+		uint64_t pesc_np:5;
+		uint64_t pesc_cpl:5;
+		uint64_t peai_ppf:8;
+		uint64_t reserved_38_63:26;
+#endif
 	} cn52xxp1;
 	struct cvmx_pescx_tlp_credits_cn52xx cn56xx;
 	struct cvmx_pescx_tlp_credits_cn52xxp1 cn56xxp1;
diff --git a/arch/mips/include/asm/octeon/cvmx-pexp-defs.h b/arch/mips/include/asm/octeon/cvmx-pexp-defs.h
index 4438d21..eb673f3 100644
--- a/arch/mips/include/asm/octeon/cvmx-pexp-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pexp-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2011 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
diff --git a/arch/mips/include/asm/octeon/cvmx-pip-defs.h b/arch/mips/include/asm/octeon/cvmx-pip-defs.h
index 5a36910..05a917d 100644
--- a/arch/mips/include/asm/octeon/cvmx-pip-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pip-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -51,93 +51,137 @@
 	CVMX_PIP_PORT_CFG_MODE_SKIPIP = 2ull
 };
 
-#define CVMX_PIP_BCK_PRS \
-	 CVMX_ADD_IO_SEG(0x00011800A0000038ull)
-#define CVMX_PIP_BIST_STATUS \
-	 CVMX_ADD_IO_SEG(0x00011800A0000000ull)
-#define CVMX_PIP_CRC_CTLX(offset) \
-	 CVMX_ADD_IO_SEG(0x00011800A0000040ull + (((offset) & 1) * 8))
-#define CVMX_PIP_CRC_IVX(offset) \
-	 CVMX_ADD_IO_SEG(0x00011800A0000050ull + (((offset) & 1) * 8))
-#define CVMX_PIP_DEC_IPSECX(offset) \
-	 CVMX_ADD_IO_SEG(0x00011800A0000080ull + (((offset) & 3) * 8))
-#define CVMX_PIP_DSA_SRC_GRP \
-	 CVMX_ADD_IO_SEG(0x00011800A0000190ull)
-#define CVMX_PIP_DSA_VID_GRP \
-	 CVMX_ADD_IO_SEG(0x00011800A0000198ull)
-#define CVMX_PIP_FRM_LEN_CHKX(offset) \
-	 CVMX_ADD_IO_SEG(0x00011800A0000180ull + (((offset) & 1) * 8))
-#define CVMX_PIP_GBL_CFG \
-	 CVMX_ADD_IO_SEG(0x00011800A0000028ull)
-#define CVMX_PIP_GBL_CTL \
-	 CVMX_ADD_IO_SEG(0x00011800A0000020ull)
-#define CVMX_PIP_HG_PRI_QOS \
-	 CVMX_ADD_IO_SEG(0x00011800A00001A0ull)
-#define CVMX_PIP_INT_EN \
-	 CVMX_ADD_IO_SEG(0x00011800A0000010ull)
-#define CVMX_PIP_INT_REG \
-	 CVMX_ADD_IO_SEG(0x00011800A0000008ull)
-#define CVMX_PIP_IP_OFFSET \
-	 CVMX_ADD_IO_SEG(0x00011800A0000060ull)
-#define CVMX_PIP_PRT_CFGX(offset) \
-	 CVMX_ADD_IO_SEG(0x00011800A0000200ull + (((offset) & 63) * 8))
-#define CVMX_PIP_PRT_TAGX(offset) \
-	 CVMX_ADD_IO_SEG(0x00011800A0000400ull + (((offset) & 63) * 8))
-#define CVMX_PIP_QOS_DIFFX(offset) \
-	 CVMX_ADD_IO_SEG(0x00011800A0000600ull + (((offset) & 63) * 8))
-#define CVMX_PIP_QOS_VLANX(offset) \
-	 CVMX_ADD_IO_SEG(0x00011800A00000C0ull + (((offset) & 7) * 8))
-#define CVMX_PIP_QOS_WATCHX(offset) \
-	 CVMX_ADD_IO_SEG(0x00011800A0000100ull + (((offset) & 7) * 8))
-#define CVMX_PIP_RAW_WORD \
-	 CVMX_ADD_IO_SEG(0x00011800A00000B0ull)
-#define CVMX_PIP_SFT_RST \
-	 CVMX_ADD_IO_SEG(0x00011800A0000030ull)
-#define CVMX_PIP_STAT0_PRTX(offset) \
-	 CVMX_ADD_IO_SEG(0x00011800A0000800ull + (((offset) & 63) * 80))
-#define CVMX_PIP_STAT1_PRTX(offset) \
-	 CVMX_ADD_IO_SEG(0x00011800A0000808ull + (((offset) & 63) * 80))
-#define CVMX_PIP_STAT2_PRTX(offset) \
-	 CVMX_ADD_IO_SEG(0x00011800A0000810ull + (((offset) & 63) * 80))
-#define CVMX_PIP_STAT3_PRTX(offset) \
-	 CVMX_ADD_IO_SEG(0x00011800A0000818ull + (((offset) & 63) * 80))
-#define CVMX_PIP_STAT4_PRTX(offset) \
-	 CVMX_ADD_IO_SEG(0x00011800A0000820ull + (((offset) & 63) * 80))
-#define CVMX_PIP_STAT5_PRTX(offset) \
-	 CVMX_ADD_IO_SEG(0x00011800A0000828ull + (((offset) & 63) * 80))
-#define CVMX_PIP_STAT6_PRTX(offset) \
-	 CVMX_ADD_IO_SEG(0x00011800A0000830ull + (((offset) & 63) * 80))
-#define CVMX_PIP_STAT7_PRTX(offset) \
-	 CVMX_ADD_IO_SEG(0x00011800A0000838ull + (((offset) & 63) * 80))
-#define CVMX_PIP_STAT8_PRTX(offset) \
-	 CVMX_ADD_IO_SEG(0x00011800A0000840ull + (((offset) & 63) * 80))
-#define CVMX_PIP_STAT9_PRTX(offset) \
-	 CVMX_ADD_IO_SEG(0x00011800A0000848ull + (((offset) & 63) * 80))
-#define CVMX_PIP_STAT_CTL \
-	 CVMX_ADD_IO_SEG(0x00011800A0000018ull)
-#define CVMX_PIP_STAT_INB_ERRSX(offset) \
-	 CVMX_ADD_IO_SEG(0x00011800A0001A10ull + (((offset) & 63) * 32))
-#define CVMX_PIP_STAT_INB_OCTSX(offset) \
-	 CVMX_ADD_IO_SEG(0x00011800A0001A08ull + (((offset) & 63) * 32))
-#define CVMX_PIP_STAT_INB_PKTSX(offset) \
-	 CVMX_ADD_IO_SEG(0x00011800A0001A00ull + (((offset) & 63) * 32))
-#define CVMX_PIP_TAG_INCX(offset) \
-	 CVMX_ADD_IO_SEG(0x00011800A0001800ull + (((offset) & 63) * 8))
-#define CVMX_PIP_TAG_MASK \
-	 CVMX_ADD_IO_SEG(0x00011800A0000070ull)
-#define CVMX_PIP_TAG_SECRET \
-	 CVMX_ADD_IO_SEG(0x00011800A0000068ull)
-#define CVMX_PIP_TODO_ENTRY \
-	 CVMX_ADD_IO_SEG(0x00011800A0000078ull)
+#define CVMX_PIP_ALT_SKIP_CFGX(offset) (CVMX_ADD_IO_SEG(0x00011800A0002A00ull) + ((offset) & 3) * 8)
+#define CVMX_PIP_BCK_PRS (CVMX_ADD_IO_SEG(0x00011800A0000038ull))
+#define CVMX_PIP_BIST_STATUS (CVMX_ADD_IO_SEG(0x00011800A0000000ull))
+#define CVMX_PIP_BSEL_EXT_CFGX(offset) (CVMX_ADD_IO_SEG(0x00011800A0002800ull) + ((offset) & 3) * 16)
+#define CVMX_PIP_BSEL_EXT_POSX(offset) (CVMX_ADD_IO_SEG(0x00011800A0002808ull) + ((offset) & 3) * 16)
+#define CVMX_PIP_BSEL_TBL_ENTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0003000ull) + ((offset) & 511) * 8)
+#define CVMX_PIP_CLKEN (CVMX_ADD_IO_SEG(0x00011800A0000040ull))
+#define CVMX_PIP_CRC_CTLX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000040ull) + ((offset) & 1) * 8)
+#define CVMX_PIP_CRC_IVX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000050ull) + ((offset) & 1) * 8)
+#define CVMX_PIP_DEC_IPSECX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000080ull) + ((offset) & 3) * 8)
+#define CVMX_PIP_DSA_SRC_GRP (CVMX_ADD_IO_SEG(0x00011800A0000190ull))
+#define CVMX_PIP_DSA_VID_GRP (CVMX_ADD_IO_SEG(0x00011800A0000198ull))
+#define CVMX_PIP_FRM_LEN_CHKX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000180ull) + ((offset) & 1) * 8)
+#define CVMX_PIP_GBL_CFG (CVMX_ADD_IO_SEG(0x00011800A0000028ull))
+#define CVMX_PIP_GBL_CTL (CVMX_ADD_IO_SEG(0x00011800A0000020ull))
+#define CVMX_PIP_HG_PRI_QOS (CVMX_ADD_IO_SEG(0x00011800A00001A0ull))
+#define CVMX_PIP_INT_EN (CVMX_ADD_IO_SEG(0x00011800A0000010ull))
+#define CVMX_PIP_INT_REG (CVMX_ADD_IO_SEG(0x00011800A0000008ull))
+#define CVMX_PIP_IP_OFFSET (CVMX_ADD_IO_SEG(0x00011800A0000060ull))
+#define CVMX_PIP_PRI_TBLX(offset) (CVMX_ADD_IO_SEG(0x00011800A0004000ull) + ((offset) & 255) * 8)
+#define CVMX_PIP_PRT_CFGBX(offset) (CVMX_ADD_IO_SEG(0x00011800A0008000ull) + ((offset) & 63) * 8)
+#define CVMX_PIP_PRT_CFGX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000200ull) + ((offset) & 63) * 8)
+#define CVMX_PIP_PRT_TAGX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000400ull) + ((offset) & 63) * 8)
+#define CVMX_PIP_QOS_DIFFX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000600ull) + ((offset) & 63) * 8)
+#define CVMX_PIP_QOS_VLANX(offset) (CVMX_ADD_IO_SEG(0x00011800A00000C0ull) + ((offset) & 7) * 8)
+#define CVMX_PIP_QOS_WATCHX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000100ull) + ((offset) & 7) * 8)
+#define CVMX_PIP_RAW_WORD (CVMX_ADD_IO_SEG(0x00011800A00000B0ull))
+#define CVMX_PIP_SFT_RST (CVMX_ADD_IO_SEG(0x00011800A0000030ull))
+#define CVMX_PIP_STAT0_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000800ull) + ((offset) & 63) * 80)
+#define CVMX_PIP_STAT0_X(offset) (CVMX_ADD_IO_SEG(0x00011800A0040000ull) + ((offset) & 63) * 128)
+#define CVMX_PIP_STAT10_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0001480ull) + ((offset) & 63) * 16)
+#define CVMX_PIP_STAT10_X(offset) (CVMX_ADD_IO_SEG(0x00011800A0040050ull) + ((offset) & 63) * 128)
+#define CVMX_PIP_STAT11_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0001488ull) + ((offset) & 63) * 16)
+#define CVMX_PIP_STAT11_X(offset) (CVMX_ADD_IO_SEG(0x00011800A0040058ull) + ((offset) & 63) * 128)
+#define CVMX_PIP_STAT1_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000808ull) + ((offset) & 63) * 80)
+#define CVMX_PIP_STAT1_X(offset) (CVMX_ADD_IO_SEG(0x00011800A0040008ull) + ((offset) & 63) * 128)
+#define CVMX_PIP_STAT2_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000810ull) + ((offset) & 63) * 80)
+#define CVMX_PIP_STAT2_X(offset) (CVMX_ADD_IO_SEG(0x00011800A0040010ull) + ((offset) & 63) * 128)
+#define CVMX_PIP_STAT3_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000818ull) + ((offset) & 63) * 80)
+#define CVMX_PIP_STAT3_X(offset) (CVMX_ADD_IO_SEG(0x00011800A0040018ull) + ((offset) & 63) * 128)
+#define CVMX_PIP_STAT4_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000820ull) + ((offset) & 63) * 80)
+#define CVMX_PIP_STAT4_X(offset) (CVMX_ADD_IO_SEG(0x00011800A0040020ull) + ((offset) & 63) * 128)
+#define CVMX_PIP_STAT5_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000828ull) + ((offset) & 63) * 80)
+#define CVMX_PIP_STAT5_X(offset) (CVMX_ADD_IO_SEG(0x00011800A0040028ull) + ((offset) & 63) * 128)
+#define CVMX_PIP_STAT6_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000830ull) + ((offset) & 63) * 80)
+#define CVMX_PIP_STAT6_X(offset) (CVMX_ADD_IO_SEG(0x00011800A0040030ull) + ((offset) & 63) * 128)
+#define CVMX_PIP_STAT7_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000838ull) + ((offset) & 63) * 80)
+#define CVMX_PIP_STAT7_X(offset) (CVMX_ADD_IO_SEG(0x00011800A0040038ull) + ((offset) & 63) * 128)
+#define CVMX_PIP_STAT8_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000840ull) + ((offset) & 63) * 80)
+#define CVMX_PIP_STAT8_X(offset) (CVMX_ADD_IO_SEG(0x00011800A0040040ull) + ((offset) & 63) * 128)
+#define CVMX_PIP_STAT9_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0000848ull) + ((offset) & 63) * 80)
+#define CVMX_PIP_STAT9_X(offset) (CVMX_ADD_IO_SEG(0x00011800A0040048ull) + ((offset) & 63) * 128)
+#define CVMX_PIP_STAT_CTL (CVMX_ADD_IO_SEG(0x00011800A0000018ull))
+#define CVMX_PIP_STAT_INB_ERRSX(offset) (CVMX_ADD_IO_SEG(0x00011800A0001A10ull) + ((offset) & 63) * 32)
+#define CVMX_PIP_STAT_INB_ERRS_PKNDX(offset) (CVMX_ADD_IO_SEG(0x00011800A0020010ull) + ((offset) & 63) * 32)
+#define CVMX_PIP_STAT_INB_OCTSX(offset) (CVMX_ADD_IO_SEG(0x00011800A0001A08ull) + ((offset) & 63) * 32)
+#define CVMX_PIP_STAT_INB_OCTS_PKNDX(offset) (CVMX_ADD_IO_SEG(0x00011800A0020008ull) + ((offset) & 63) * 32)
+#define CVMX_PIP_STAT_INB_PKTSX(offset) (CVMX_ADD_IO_SEG(0x00011800A0001A00ull) + ((offset) & 63) * 32)
+#define CVMX_PIP_STAT_INB_PKTS_PKNDX(offset) (CVMX_ADD_IO_SEG(0x00011800A0020000ull) + ((offset) & 63) * 32)
+#define CVMX_PIP_SUB_PKIND_FCSX(block_id) (CVMX_ADD_IO_SEG(0x00011800A0080000ull))
+#define CVMX_PIP_TAG_INCX(offset) (CVMX_ADD_IO_SEG(0x00011800A0001800ull) + ((offset) & 63) * 8)
+#define CVMX_PIP_TAG_MASK (CVMX_ADD_IO_SEG(0x00011800A0000070ull))
+#define CVMX_PIP_TAG_SECRET (CVMX_ADD_IO_SEG(0x00011800A0000068ull))
+#define CVMX_PIP_TODO_ENTRY (CVMX_ADD_IO_SEG(0x00011800A0000078ull))
+#define CVMX_PIP_VLAN_ETYPESX(offset) (CVMX_ADD_IO_SEG(0x00011800A00001C0ull) + ((offset) & 1) * 8)
+#define CVMX_PIP_XSTAT0_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0002000ull) + ((offset) & 63) * 80 - 80*40)
+#define CVMX_PIP_XSTAT10_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0001700ull) + ((offset) & 63) * 16 - 16*40)
+#define CVMX_PIP_XSTAT11_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0001708ull) + ((offset) & 63) * 16 - 16*40)
+#define CVMX_PIP_XSTAT1_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0002008ull) + ((offset) & 63) * 80 - 80*40)
+#define CVMX_PIP_XSTAT2_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0002010ull) + ((offset) & 63) * 80 - 80*40)
+#define CVMX_PIP_XSTAT3_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0002018ull) + ((offset) & 63) * 80 - 80*40)
+#define CVMX_PIP_XSTAT4_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0002020ull) + ((offset) & 63) * 80 - 80*40)
+#define CVMX_PIP_XSTAT5_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0002028ull) + ((offset) & 63) * 80 - 80*40)
+#define CVMX_PIP_XSTAT6_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0002030ull) + ((offset) & 63) * 80 - 80*40)
+#define CVMX_PIP_XSTAT7_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0002038ull) + ((offset) & 63) * 80 - 80*40)
+#define CVMX_PIP_XSTAT8_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0002040ull) + ((offset) & 63) * 80 - 80*40)
+#define CVMX_PIP_XSTAT9_PRTX(offset) (CVMX_ADD_IO_SEG(0x00011800A0002048ull) + ((offset) & 63) * 80 - 80*40)
+
+union cvmx_pip_alt_skip_cfgx {
+	uint64_t u64;
+	struct cvmx_pip_alt_skip_cfgx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_57_63:7;
+		uint64_t len:1;
+		uint64_t reserved_46_55:10;
+		uint64_t bit1:6;
+		uint64_t reserved_38_39:2;
+		uint64_t bit0:6;
+		uint64_t reserved_23_31:9;
+		uint64_t skip3:7;
+		uint64_t reserved_15_15:1;
+		uint64_t skip2:7;
+		uint64_t reserved_7_7:1;
+		uint64_t skip1:7;
+#else
+		uint64_t skip1:7;
+		uint64_t reserved_7_7:1;
+		uint64_t skip2:7;
+		uint64_t reserved_15_15:1;
+		uint64_t skip3:7;
+		uint64_t reserved_23_31:9;
+		uint64_t bit0:6;
+		uint64_t reserved_38_39:2;
+		uint64_t bit1:6;
+		uint64_t reserved_46_55:10;
+		uint64_t len:1;
+		uint64_t reserved_57_63:7;
+#endif
+	} s;
+	struct cvmx_pip_alt_skip_cfgx_s cn61xx;
+	struct cvmx_pip_alt_skip_cfgx_s cn66xx;
+	struct cvmx_pip_alt_skip_cfgx_s cn68xx;
+	struct cvmx_pip_alt_skip_cfgx_s cnf71xx;
+};
 
 union cvmx_pip_bck_prs {
 	uint64_t u64;
 	struct cvmx_pip_bck_prs_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t bckprs:1;
 		uint64_t reserved_13_62:50;
 		uint64_t hiwater:5;
 		uint64_t reserved_5_7:3;
 		uint64_t lowater:5;
+#else
+		uint64_t lowater:5;
+		uint64_t reserved_5_7:3;
+		uint64_t hiwater:5;
+		uint64_t reserved_13_62:50;
+		uint64_t bckprs:1;
+#endif
 	} s;
 	struct cvmx_pip_bck_prs_s cn38xx;
 	struct cvmx_pip_bck_prs_s cn38xxp2;
@@ -145,36 +189,236 @@
 	struct cvmx_pip_bck_prs_s cn56xxp1;
 	struct cvmx_pip_bck_prs_s cn58xx;
 	struct cvmx_pip_bck_prs_s cn58xxp1;
+	struct cvmx_pip_bck_prs_s cn61xx;
+	struct cvmx_pip_bck_prs_s cn63xx;
+	struct cvmx_pip_bck_prs_s cn63xxp1;
+	struct cvmx_pip_bck_prs_s cn66xx;
+	struct cvmx_pip_bck_prs_s cn68xx;
+	struct cvmx_pip_bck_prs_s cn68xxp1;
+	struct cvmx_pip_bck_prs_s cnf71xx;
 };
 
 union cvmx_pip_bist_status {
 	uint64_t u64;
 	struct cvmx_pip_bist_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_22_63:42;
+		uint64_t bist:22;
+#else
+		uint64_t bist:22;
+		uint64_t reserved_22_63:42;
+#endif
+	} s;
+	struct cvmx_pip_bist_status_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_18_63:46;
 		uint64_t bist:18;
-	} s;
-	struct cvmx_pip_bist_status_s cn30xx;
-	struct cvmx_pip_bist_status_s cn31xx;
-	struct cvmx_pip_bist_status_s cn38xx;
-	struct cvmx_pip_bist_status_s cn38xxp2;
+#else
+		uint64_t bist:18;
+		uint64_t reserved_18_63:46;
+#endif
+	} cn30xx;
+	struct cvmx_pip_bist_status_cn30xx cn31xx;
+	struct cvmx_pip_bist_status_cn30xx cn38xx;
+	struct cvmx_pip_bist_status_cn30xx cn38xxp2;
 	struct cvmx_pip_bist_status_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_17_63:47;
 		uint64_t bist:17;
+#else
+		uint64_t bist:17;
+		uint64_t reserved_17_63:47;
+#endif
 	} cn50xx;
-	struct cvmx_pip_bist_status_s cn52xx;
-	struct cvmx_pip_bist_status_s cn52xxp1;
-	struct cvmx_pip_bist_status_s cn56xx;
-	struct cvmx_pip_bist_status_s cn56xxp1;
-	struct cvmx_pip_bist_status_s cn58xx;
-	struct cvmx_pip_bist_status_s cn58xxp1;
+	struct cvmx_pip_bist_status_cn30xx cn52xx;
+	struct cvmx_pip_bist_status_cn30xx cn52xxp1;
+	struct cvmx_pip_bist_status_cn30xx cn56xx;
+	struct cvmx_pip_bist_status_cn30xx cn56xxp1;
+	struct cvmx_pip_bist_status_cn30xx cn58xx;
+	struct cvmx_pip_bist_status_cn30xx cn58xxp1;
+	struct cvmx_pip_bist_status_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_20_63:44;
+		uint64_t bist:20;
+#else
+		uint64_t bist:20;
+		uint64_t reserved_20_63:44;
+#endif
+	} cn61xx;
+	struct cvmx_pip_bist_status_cn30xx cn63xx;
+	struct cvmx_pip_bist_status_cn30xx cn63xxp1;
+	struct cvmx_pip_bist_status_cn61xx cn66xx;
+	struct cvmx_pip_bist_status_s cn68xx;
+	struct cvmx_pip_bist_status_cn61xx cn68xxp1;
+	struct cvmx_pip_bist_status_cn61xx cnf71xx;
+};
+
+union cvmx_pip_bsel_ext_cfgx {
+	uint64_t u64;
+	struct cvmx_pip_bsel_ext_cfgx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t upper_tag:16;
+		uint64_t tag:8;
+		uint64_t reserved_25_31:7;
+		uint64_t offset:9;
+		uint64_t reserved_7_15:9;
+		uint64_t skip:7;
+#else
+		uint64_t skip:7;
+		uint64_t reserved_7_15:9;
+		uint64_t offset:9;
+		uint64_t reserved_25_31:7;
+		uint64_t tag:8;
+		uint64_t upper_tag:16;
+		uint64_t reserved_56_63:8;
+#endif
+	} s;
+	struct cvmx_pip_bsel_ext_cfgx_s cn61xx;
+	struct cvmx_pip_bsel_ext_cfgx_s cn68xx;
+	struct cvmx_pip_bsel_ext_cfgx_s cnf71xx;
+};
+
+union cvmx_pip_bsel_ext_posx {
+	uint64_t u64;
+	struct cvmx_pip_bsel_ext_posx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t pos7_val:1;
+		uint64_t pos7:7;
+		uint64_t pos6_val:1;
+		uint64_t pos6:7;
+		uint64_t pos5_val:1;
+		uint64_t pos5:7;
+		uint64_t pos4_val:1;
+		uint64_t pos4:7;
+		uint64_t pos3_val:1;
+		uint64_t pos3:7;
+		uint64_t pos2_val:1;
+		uint64_t pos2:7;
+		uint64_t pos1_val:1;
+		uint64_t pos1:7;
+		uint64_t pos0_val:1;
+		uint64_t pos0:7;
+#else
+		uint64_t pos0:7;
+		uint64_t pos0_val:1;
+		uint64_t pos1:7;
+		uint64_t pos1_val:1;
+		uint64_t pos2:7;
+		uint64_t pos2_val:1;
+		uint64_t pos3:7;
+		uint64_t pos3_val:1;
+		uint64_t pos4:7;
+		uint64_t pos4_val:1;
+		uint64_t pos5:7;
+		uint64_t pos5_val:1;
+		uint64_t pos6:7;
+		uint64_t pos6_val:1;
+		uint64_t pos7:7;
+		uint64_t pos7_val:1;
+#endif
+	} s;
+	struct cvmx_pip_bsel_ext_posx_s cn61xx;
+	struct cvmx_pip_bsel_ext_posx_s cn68xx;
+	struct cvmx_pip_bsel_ext_posx_s cnf71xx;
+};
+
+union cvmx_pip_bsel_tbl_entx {
+	uint64_t u64;
+	struct cvmx_pip_bsel_tbl_entx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t tag_en:1;
+		uint64_t grp_en:1;
+		uint64_t tt_en:1;
+		uint64_t qos_en:1;
+		uint64_t reserved_40_59:20;
+		uint64_t tag:8;
+		uint64_t reserved_22_31:10;
+		uint64_t grp:6;
+		uint64_t reserved_10_15:6;
+		uint64_t tt:2;
+		uint64_t reserved_3_7:5;
+		uint64_t qos:3;
+#else
+		uint64_t qos:3;
+		uint64_t reserved_3_7:5;
+		uint64_t tt:2;
+		uint64_t reserved_10_15:6;
+		uint64_t grp:6;
+		uint64_t reserved_22_31:10;
+		uint64_t tag:8;
+		uint64_t reserved_40_59:20;
+		uint64_t qos_en:1;
+		uint64_t tt_en:1;
+		uint64_t grp_en:1;
+		uint64_t tag_en:1;
+#endif
+	} s;
+	struct cvmx_pip_bsel_tbl_entx_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t tag_en:1;
+		uint64_t grp_en:1;
+		uint64_t tt_en:1;
+		uint64_t qos_en:1;
+		uint64_t reserved_40_59:20;
+		uint64_t tag:8;
+		uint64_t reserved_20_31:12;
+		uint64_t grp:4;
+		uint64_t reserved_10_15:6;
+		uint64_t tt:2;
+		uint64_t reserved_3_7:5;
+		uint64_t qos:3;
+#else
+		uint64_t qos:3;
+		uint64_t reserved_3_7:5;
+		uint64_t tt:2;
+		uint64_t reserved_10_15:6;
+		uint64_t grp:4;
+		uint64_t reserved_20_31:12;
+		uint64_t tag:8;
+		uint64_t reserved_40_59:20;
+		uint64_t qos_en:1;
+		uint64_t tt_en:1;
+		uint64_t grp_en:1;
+		uint64_t tag_en:1;
+#endif
+	} cn61xx;
+	struct cvmx_pip_bsel_tbl_entx_s cn68xx;
+	struct cvmx_pip_bsel_tbl_entx_cn61xx cnf71xx;
+};
+
+union cvmx_pip_clken {
+	uint64_t u64;
+	struct cvmx_pip_clken_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_1_63:63;
+		uint64_t clken:1;
+#else
+		uint64_t clken:1;
+		uint64_t reserved_1_63:63;
+#endif
+	} s;
+	struct cvmx_pip_clken_s cn61xx;
+	struct cvmx_pip_clken_s cn63xx;
+	struct cvmx_pip_clken_s cn63xxp1;
+	struct cvmx_pip_clken_s cn66xx;
+	struct cvmx_pip_clken_s cn68xx;
+	struct cvmx_pip_clken_s cn68xxp1;
+	struct cvmx_pip_clken_s cnf71xx;
 };
 
 union cvmx_pip_crc_ctlx {
 	uint64_t u64;
 	struct cvmx_pip_crc_ctlx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t invres:1;
 		uint64_t reflect:1;
+#else
+		uint64_t reflect:1;
+		uint64_t invres:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_pip_crc_ctlx_s cn38xx;
 	struct cvmx_pip_crc_ctlx_s cn38xxp2;
@@ -185,8 +429,13 @@
 union cvmx_pip_crc_ivx {
 	uint64_t u64;
 	struct cvmx_pip_crc_ivx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t iv:32;
+#else
+		uint64_t iv:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_pip_crc_ivx_s cn38xx;
 	struct cvmx_pip_crc_ivx_s cn38xxp2;
@@ -197,10 +446,17 @@
 union cvmx_pip_dec_ipsecx {
 	uint64_t u64;
 	struct cvmx_pip_dec_ipsecx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_18_63:46;
 		uint64_t tcp:1;
 		uint64_t udp:1;
 		uint64_t dprt:16;
+#else
+		uint64_t dprt:16;
+		uint64_t udp:1;
+		uint64_t tcp:1;
+		uint64_t reserved_18_63:46;
+#endif
 	} s;
 	struct cvmx_pip_dec_ipsecx_s cn30xx;
 	struct cvmx_pip_dec_ipsecx_s cn31xx;
@@ -213,11 +469,19 @@
 	struct cvmx_pip_dec_ipsecx_s cn56xxp1;
 	struct cvmx_pip_dec_ipsecx_s cn58xx;
 	struct cvmx_pip_dec_ipsecx_s cn58xxp1;
+	struct cvmx_pip_dec_ipsecx_s cn61xx;
+	struct cvmx_pip_dec_ipsecx_s cn63xx;
+	struct cvmx_pip_dec_ipsecx_s cn63xxp1;
+	struct cvmx_pip_dec_ipsecx_s cn66xx;
+	struct cvmx_pip_dec_ipsecx_s cn68xx;
+	struct cvmx_pip_dec_ipsecx_s cn68xxp1;
+	struct cvmx_pip_dec_ipsecx_s cnf71xx;
 };
 
 union cvmx_pip_dsa_src_grp {
 	uint64_t u64;
 	struct cvmx_pip_dsa_src_grp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t map15:4;
 		uint64_t map14:4;
 		uint64_t map13:4;
@@ -234,15 +498,41 @@
 		uint64_t map2:4;
 		uint64_t map1:4;
 		uint64_t map0:4;
+#else
+		uint64_t map0:4;
+		uint64_t map1:4;
+		uint64_t map2:4;
+		uint64_t map3:4;
+		uint64_t map4:4;
+		uint64_t map5:4;
+		uint64_t map6:4;
+		uint64_t map7:4;
+		uint64_t map8:4;
+		uint64_t map9:4;
+		uint64_t map10:4;
+		uint64_t map11:4;
+		uint64_t map12:4;
+		uint64_t map13:4;
+		uint64_t map14:4;
+		uint64_t map15:4;
+#endif
 	} s;
 	struct cvmx_pip_dsa_src_grp_s cn52xx;
 	struct cvmx_pip_dsa_src_grp_s cn52xxp1;
 	struct cvmx_pip_dsa_src_grp_s cn56xx;
+	struct cvmx_pip_dsa_src_grp_s cn61xx;
+	struct cvmx_pip_dsa_src_grp_s cn63xx;
+	struct cvmx_pip_dsa_src_grp_s cn63xxp1;
+	struct cvmx_pip_dsa_src_grp_s cn66xx;
+	struct cvmx_pip_dsa_src_grp_s cn68xx;
+	struct cvmx_pip_dsa_src_grp_s cn68xxp1;
+	struct cvmx_pip_dsa_src_grp_s cnf71xx;
 };
 
 union cvmx_pip_dsa_vid_grp {
 	uint64_t u64;
 	struct cvmx_pip_dsa_vid_grp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t map15:4;
 		uint64_t map14:4;
 		uint64_t map13:4;
@@ -259,29 +549,68 @@
 		uint64_t map2:4;
 		uint64_t map1:4;
 		uint64_t map0:4;
+#else
+		uint64_t map0:4;
+		uint64_t map1:4;
+		uint64_t map2:4;
+		uint64_t map3:4;
+		uint64_t map4:4;
+		uint64_t map5:4;
+		uint64_t map6:4;
+		uint64_t map7:4;
+		uint64_t map8:4;
+		uint64_t map9:4;
+		uint64_t map10:4;
+		uint64_t map11:4;
+		uint64_t map12:4;
+		uint64_t map13:4;
+		uint64_t map14:4;
+		uint64_t map15:4;
+#endif
 	} s;
 	struct cvmx_pip_dsa_vid_grp_s cn52xx;
 	struct cvmx_pip_dsa_vid_grp_s cn52xxp1;
 	struct cvmx_pip_dsa_vid_grp_s cn56xx;
+	struct cvmx_pip_dsa_vid_grp_s cn61xx;
+	struct cvmx_pip_dsa_vid_grp_s cn63xx;
+	struct cvmx_pip_dsa_vid_grp_s cn63xxp1;
+	struct cvmx_pip_dsa_vid_grp_s cn66xx;
+	struct cvmx_pip_dsa_vid_grp_s cn68xx;
+	struct cvmx_pip_dsa_vid_grp_s cn68xxp1;
+	struct cvmx_pip_dsa_vid_grp_s cnf71xx;
 };
 
 union cvmx_pip_frm_len_chkx {
 	uint64_t u64;
 	struct cvmx_pip_frm_len_chkx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t maxlen:16;
 		uint64_t minlen:16;
+#else
+		uint64_t minlen:16;
+		uint64_t maxlen:16;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_pip_frm_len_chkx_s cn50xx;
 	struct cvmx_pip_frm_len_chkx_s cn52xx;
 	struct cvmx_pip_frm_len_chkx_s cn52xxp1;
 	struct cvmx_pip_frm_len_chkx_s cn56xx;
 	struct cvmx_pip_frm_len_chkx_s cn56xxp1;
+	struct cvmx_pip_frm_len_chkx_s cn61xx;
+	struct cvmx_pip_frm_len_chkx_s cn63xx;
+	struct cvmx_pip_frm_len_chkx_s cn63xxp1;
+	struct cvmx_pip_frm_len_chkx_s cn66xx;
+	struct cvmx_pip_frm_len_chkx_s cn68xx;
+	struct cvmx_pip_frm_len_chkx_s cn68xxp1;
+	struct cvmx_pip_frm_len_chkx_s cnf71xx;
 };
 
 union cvmx_pip_gbl_cfg {
 	uint64_t u64;
 	struct cvmx_pip_gbl_cfg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_19_63:45;
 		uint64_t tag_syn:1;
 		uint64_t ip6_udp:1;
@@ -290,6 +619,16 @@
 		uint64_t raw_shf:3;
 		uint64_t reserved_3_7:5;
 		uint64_t nip_shf:3;
+#else
+		uint64_t nip_shf:3;
+		uint64_t reserved_3_7:5;
+		uint64_t raw_shf:3;
+		uint64_t reserved_11_15:5;
+		uint64_t max_l2:1;
+		uint64_t ip6_udp:1;
+		uint64_t tag_syn:1;
+		uint64_t reserved_19_63:45;
+#endif
 	} s;
 	struct cvmx_pip_gbl_cfg_s cn30xx;
 	struct cvmx_pip_gbl_cfg_s cn31xx;
@@ -302,11 +641,113 @@
 	struct cvmx_pip_gbl_cfg_s cn56xxp1;
 	struct cvmx_pip_gbl_cfg_s cn58xx;
 	struct cvmx_pip_gbl_cfg_s cn58xxp1;
+	struct cvmx_pip_gbl_cfg_s cn61xx;
+	struct cvmx_pip_gbl_cfg_s cn63xx;
+	struct cvmx_pip_gbl_cfg_s cn63xxp1;
+	struct cvmx_pip_gbl_cfg_s cn66xx;
+	struct cvmx_pip_gbl_cfg_s cn68xx;
+	struct cvmx_pip_gbl_cfg_s cn68xxp1;
+	struct cvmx_pip_gbl_cfg_s cnf71xx;
 };
 
 union cvmx_pip_gbl_ctl {
 	uint64_t u64;
 	struct cvmx_pip_gbl_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_29_63:35;
+		uint64_t egrp_dis:1;
+		uint64_t ihmsk_dis:1;
+		uint64_t dsa_grp_tvid:1;
+		uint64_t dsa_grp_scmd:1;
+		uint64_t dsa_grp_sid:1;
+		uint64_t reserved_21_23:3;
+		uint64_t ring_en:1;
+		uint64_t reserved_17_19:3;
+		uint64_t ignrs:1;
+		uint64_t vs_wqe:1;
+		uint64_t vs_qos:1;
+		uint64_t l2_mal:1;
+		uint64_t tcp_flag:1;
+		uint64_t l4_len:1;
+		uint64_t l4_chk:1;
+		uint64_t l4_prt:1;
+		uint64_t l4_mal:1;
+		uint64_t reserved_6_7:2;
+		uint64_t ip6_eext:2;
+		uint64_t ip4_opts:1;
+		uint64_t ip_hop:1;
+		uint64_t ip_mal:1;
+		uint64_t ip_chk:1;
+#else
+		uint64_t ip_chk:1;
+		uint64_t ip_mal:1;
+		uint64_t ip_hop:1;
+		uint64_t ip4_opts:1;
+		uint64_t ip6_eext:2;
+		uint64_t reserved_6_7:2;
+		uint64_t l4_mal:1;
+		uint64_t l4_prt:1;
+		uint64_t l4_chk:1;
+		uint64_t l4_len:1;
+		uint64_t tcp_flag:1;
+		uint64_t l2_mal:1;
+		uint64_t vs_qos:1;
+		uint64_t vs_wqe:1;
+		uint64_t ignrs:1;
+		uint64_t reserved_17_19:3;
+		uint64_t ring_en:1;
+		uint64_t reserved_21_23:3;
+		uint64_t dsa_grp_sid:1;
+		uint64_t dsa_grp_scmd:1;
+		uint64_t dsa_grp_tvid:1;
+		uint64_t ihmsk_dis:1;
+		uint64_t egrp_dis:1;
+		uint64_t reserved_29_63:35;
+#endif
+	} s;
+	struct cvmx_pip_gbl_ctl_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_17_63:47;
+		uint64_t ignrs:1;
+		uint64_t vs_wqe:1;
+		uint64_t vs_qos:1;
+		uint64_t l2_mal:1;
+		uint64_t tcp_flag:1;
+		uint64_t l4_len:1;
+		uint64_t l4_chk:1;
+		uint64_t l4_prt:1;
+		uint64_t l4_mal:1;
+		uint64_t reserved_6_7:2;
+		uint64_t ip6_eext:2;
+		uint64_t ip4_opts:1;
+		uint64_t ip_hop:1;
+		uint64_t ip_mal:1;
+		uint64_t ip_chk:1;
+#else
+		uint64_t ip_chk:1;
+		uint64_t ip_mal:1;
+		uint64_t ip_hop:1;
+		uint64_t ip4_opts:1;
+		uint64_t ip6_eext:2;
+		uint64_t reserved_6_7:2;
+		uint64_t l4_mal:1;
+		uint64_t l4_prt:1;
+		uint64_t l4_chk:1;
+		uint64_t l4_len:1;
+		uint64_t tcp_flag:1;
+		uint64_t l2_mal:1;
+		uint64_t vs_qos:1;
+		uint64_t vs_wqe:1;
+		uint64_t ignrs:1;
+		uint64_t reserved_17_63:47;
+#endif
+	} cn30xx;
+	struct cvmx_pip_gbl_ctl_cn30xx cn31xx;
+	struct cvmx_pip_gbl_ctl_cn30xx cn38xx;
+	struct cvmx_pip_gbl_ctl_cn30xx cn38xxp2;
+	struct cvmx_pip_gbl_ctl_cn30xx cn50xx;
+	struct cvmx_pip_gbl_ctl_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_27_63:37;
 		uint64_t dsa_grp_tvid:1;
 		uint64_t dsa_grp_scmd:1;
@@ -329,33 +770,35 @@
 		uint64_t ip_hop:1;
 		uint64_t ip_mal:1;
 		uint64_t ip_chk:1;
-	} s;
-	struct cvmx_pip_gbl_ctl_cn30xx {
-		uint64_t reserved_17_63:47;
-		uint64_t ignrs:1;
-		uint64_t vs_wqe:1;
-		uint64_t vs_qos:1;
-		uint64_t l2_mal:1;
-		uint64_t tcp_flag:1;
-		uint64_t l4_len:1;
-		uint64_t l4_chk:1;
-		uint64_t l4_prt:1;
-		uint64_t l4_mal:1;
-		uint64_t reserved_6_7:2;
-		uint64_t ip6_eext:2;
-		uint64_t ip4_opts:1;
-		uint64_t ip_hop:1;
-		uint64_t ip_mal:1;
+#else
 		uint64_t ip_chk:1;
-	} cn30xx;
-	struct cvmx_pip_gbl_ctl_cn30xx cn31xx;
-	struct cvmx_pip_gbl_ctl_cn30xx cn38xx;
-	struct cvmx_pip_gbl_ctl_cn30xx cn38xxp2;
-	struct cvmx_pip_gbl_ctl_cn30xx cn50xx;
-	struct cvmx_pip_gbl_ctl_s cn52xx;
-	struct cvmx_pip_gbl_ctl_s cn52xxp1;
-	struct cvmx_pip_gbl_ctl_s cn56xx;
+		uint64_t ip_mal:1;
+		uint64_t ip_hop:1;
+		uint64_t ip4_opts:1;
+		uint64_t ip6_eext:2;
+		uint64_t reserved_6_7:2;
+		uint64_t l4_mal:1;
+		uint64_t l4_prt:1;
+		uint64_t l4_chk:1;
+		uint64_t l4_len:1;
+		uint64_t tcp_flag:1;
+		uint64_t l2_mal:1;
+		uint64_t vs_qos:1;
+		uint64_t vs_wqe:1;
+		uint64_t ignrs:1;
+		uint64_t reserved_17_19:3;
+		uint64_t ring_en:1;
+		uint64_t reserved_21_23:3;
+		uint64_t dsa_grp_sid:1;
+		uint64_t dsa_grp_scmd:1;
+		uint64_t dsa_grp_tvid:1;
+		uint64_t reserved_27_63:37;
+#endif
+	} cn52xx;
+	struct cvmx_pip_gbl_ctl_cn52xx cn52xxp1;
+	struct cvmx_pip_gbl_ctl_cn52xx cn56xx;
 	struct cvmx_pip_gbl_ctl_cn56xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_21_63:43;
 		uint64_t ring_en:1;
 		uint64_t reserved_17_19:3;
@@ -374,27 +817,215 @@
 		uint64_t ip_hop:1;
 		uint64_t ip_mal:1;
 		uint64_t ip_chk:1;
+#else
+		uint64_t ip_chk:1;
+		uint64_t ip_mal:1;
+		uint64_t ip_hop:1;
+		uint64_t ip4_opts:1;
+		uint64_t ip6_eext:2;
+		uint64_t reserved_6_7:2;
+		uint64_t l4_mal:1;
+		uint64_t l4_prt:1;
+		uint64_t l4_chk:1;
+		uint64_t l4_len:1;
+		uint64_t tcp_flag:1;
+		uint64_t l2_mal:1;
+		uint64_t vs_qos:1;
+		uint64_t vs_wqe:1;
+		uint64_t ignrs:1;
+		uint64_t reserved_17_19:3;
+		uint64_t ring_en:1;
+		uint64_t reserved_21_63:43;
+#endif
 	} cn56xxp1;
 	struct cvmx_pip_gbl_ctl_cn30xx cn58xx;
 	struct cvmx_pip_gbl_ctl_cn30xx cn58xxp1;
+	struct cvmx_pip_gbl_ctl_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_28_63:36;
+		uint64_t ihmsk_dis:1;
+		uint64_t dsa_grp_tvid:1;
+		uint64_t dsa_grp_scmd:1;
+		uint64_t dsa_grp_sid:1;
+		uint64_t reserved_21_23:3;
+		uint64_t ring_en:1;
+		uint64_t reserved_17_19:3;
+		uint64_t ignrs:1;
+		uint64_t vs_wqe:1;
+		uint64_t vs_qos:1;
+		uint64_t l2_mal:1;
+		uint64_t tcp_flag:1;
+		uint64_t l4_len:1;
+		uint64_t l4_chk:1;
+		uint64_t l4_prt:1;
+		uint64_t l4_mal:1;
+		uint64_t reserved_6_7:2;
+		uint64_t ip6_eext:2;
+		uint64_t ip4_opts:1;
+		uint64_t ip_hop:1;
+		uint64_t ip_mal:1;
+		uint64_t ip_chk:1;
+#else
+		uint64_t ip_chk:1;
+		uint64_t ip_mal:1;
+		uint64_t ip_hop:1;
+		uint64_t ip4_opts:1;
+		uint64_t ip6_eext:2;
+		uint64_t reserved_6_7:2;
+		uint64_t l4_mal:1;
+		uint64_t l4_prt:1;
+		uint64_t l4_chk:1;
+		uint64_t l4_len:1;
+		uint64_t tcp_flag:1;
+		uint64_t l2_mal:1;
+		uint64_t vs_qos:1;
+		uint64_t vs_wqe:1;
+		uint64_t ignrs:1;
+		uint64_t reserved_17_19:3;
+		uint64_t ring_en:1;
+		uint64_t reserved_21_23:3;
+		uint64_t dsa_grp_sid:1;
+		uint64_t dsa_grp_scmd:1;
+		uint64_t dsa_grp_tvid:1;
+		uint64_t ihmsk_dis:1;
+		uint64_t reserved_28_63:36;
+#endif
+	} cn61xx;
+	struct cvmx_pip_gbl_ctl_cn61xx cn63xx;
+	struct cvmx_pip_gbl_ctl_cn61xx cn63xxp1;
+	struct cvmx_pip_gbl_ctl_cn61xx cn66xx;
+	struct cvmx_pip_gbl_ctl_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_29_63:35;
+		uint64_t egrp_dis:1;
+		uint64_t ihmsk_dis:1;
+		uint64_t dsa_grp_tvid:1;
+		uint64_t dsa_grp_scmd:1;
+		uint64_t dsa_grp_sid:1;
+		uint64_t reserved_17_23:7;
+		uint64_t ignrs:1;
+		uint64_t vs_wqe:1;
+		uint64_t vs_qos:1;
+		uint64_t l2_mal:1;
+		uint64_t tcp_flag:1;
+		uint64_t l4_len:1;
+		uint64_t l4_chk:1;
+		uint64_t l4_prt:1;
+		uint64_t l4_mal:1;
+		uint64_t reserved_6_7:2;
+		uint64_t ip6_eext:2;
+		uint64_t ip4_opts:1;
+		uint64_t ip_hop:1;
+		uint64_t ip_mal:1;
+		uint64_t ip_chk:1;
+#else
+		uint64_t ip_chk:1;
+		uint64_t ip_mal:1;
+		uint64_t ip_hop:1;
+		uint64_t ip4_opts:1;
+		uint64_t ip6_eext:2;
+		uint64_t reserved_6_7:2;
+		uint64_t l4_mal:1;
+		uint64_t l4_prt:1;
+		uint64_t l4_chk:1;
+		uint64_t l4_len:1;
+		uint64_t tcp_flag:1;
+		uint64_t l2_mal:1;
+		uint64_t vs_qos:1;
+		uint64_t vs_wqe:1;
+		uint64_t ignrs:1;
+		uint64_t reserved_17_23:7;
+		uint64_t dsa_grp_sid:1;
+		uint64_t dsa_grp_scmd:1;
+		uint64_t dsa_grp_tvid:1;
+		uint64_t ihmsk_dis:1;
+		uint64_t egrp_dis:1;
+		uint64_t reserved_29_63:35;
+#endif
+	} cn68xx;
+	struct cvmx_pip_gbl_ctl_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_28_63:36;
+		uint64_t ihmsk_dis:1;
+		uint64_t dsa_grp_tvid:1;
+		uint64_t dsa_grp_scmd:1;
+		uint64_t dsa_grp_sid:1;
+		uint64_t reserved_17_23:7;
+		uint64_t ignrs:1;
+		uint64_t vs_wqe:1;
+		uint64_t vs_qos:1;
+		uint64_t l2_mal:1;
+		uint64_t tcp_flag:1;
+		uint64_t l4_len:1;
+		uint64_t l4_chk:1;
+		uint64_t l4_prt:1;
+		uint64_t l4_mal:1;
+		uint64_t reserved_6_7:2;
+		uint64_t ip6_eext:2;
+		uint64_t ip4_opts:1;
+		uint64_t ip_hop:1;
+		uint64_t ip_mal:1;
+		uint64_t ip_chk:1;
+#else
+		uint64_t ip_chk:1;
+		uint64_t ip_mal:1;
+		uint64_t ip_hop:1;
+		uint64_t ip4_opts:1;
+		uint64_t ip6_eext:2;
+		uint64_t reserved_6_7:2;
+		uint64_t l4_mal:1;
+		uint64_t l4_prt:1;
+		uint64_t l4_chk:1;
+		uint64_t l4_len:1;
+		uint64_t tcp_flag:1;
+		uint64_t l2_mal:1;
+		uint64_t vs_qos:1;
+		uint64_t vs_wqe:1;
+		uint64_t ignrs:1;
+		uint64_t reserved_17_23:7;
+		uint64_t dsa_grp_sid:1;
+		uint64_t dsa_grp_scmd:1;
+		uint64_t dsa_grp_tvid:1;
+		uint64_t ihmsk_dis:1;
+		uint64_t reserved_28_63:36;
+#endif
+	} cn68xxp1;
+	struct cvmx_pip_gbl_ctl_cn61xx cnf71xx;
 };
 
 union cvmx_pip_hg_pri_qos {
 	uint64_t u64;
 	struct cvmx_pip_hg_pri_qos_s {
-		uint64_t reserved_11_63:53;
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_13_63:51;
+		uint64_t up_qos:1;
+		uint64_t reserved_11_11:1;
 		uint64_t qos:3;
 		uint64_t reserved_6_7:2;
 		uint64_t pri:6;
+#else
+		uint64_t pri:6;
+		uint64_t reserved_6_7:2;
+		uint64_t qos:3;
+		uint64_t reserved_11_11:1;
+		uint64_t up_qos:1;
+		uint64_t reserved_13_63:51;
+#endif
 	} s;
 	struct cvmx_pip_hg_pri_qos_s cn52xx;
 	struct cvmx_pip_hg_pri_qos_s cn52xxp1;
 	struct cvmx_pip_hg_pri_qos_s cn56xx;
+	struct cvmx_pip_hg_pri_qos_s cn61xx;
+	struct cvmx_pip_hg_pri_qos_s cn63xx;
+	struct cvmx_pip_hg_pri_qos_s cn63xxp1;
+	struct cvmx_pip_hg_pri_qos_s cn66xx;
+	struct cvmx_pip_hg_pri_qos_s cnf71xx;
 };
 
 union cvmx_pip_int_en {
 	uint64_t u64;
 	struct cvmx_pip_int_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_13_63:51;
 		uint64_t punyerr:1;
 		uint64_t lenerr:1;
@@ -409,8 +1040,25 @@
 		uint64_t bckprs:1;
 		uint64_t crcerr:1;
 		uint64_t pktdrp:1;
+#else
+		uint64_t pktdrp:1;
+		uint64_t crcerr:1;
+		uint64_t bckprs:1;
+		uint64_t prtnxa:1;
+		uint64_t badtag:1;
+		uint64_t skprunt:1;
+		uint64_t todoovr:1;
+		uint64_t feperr:1;
+		uint64_t beperr:1;
+		uint64_t minerr:1;
+		uint64_t maxerr:1;
+		uint64_t lenerr:1;
+		uint64_t punyerr:1;
+		uint64_t reserved_13_63:51;
+#endif
 	} s;
 	struct cvmx_pip_int_en_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t beperr:1;
 		uint64_t feperr:1;
@@ -421,11 +1069,24 @@
 		uint64_t bckprs:1;
 		uint64_t crcerr:1;
 		uint64_t pktdrp:1;
+#else
+		uint64_t pktdrp:1;
+		uint64_t crcerr:1;
+		uint64_t bckprs:1;
+		uint64_t prtnxa:1;
+		uint64_t badtag:1;
+		uint64_t skprunt:1;
+		uint64_t todoovr:1;
+		uint64_t feperr:1;
+		uint64_t beperr:1;
+		uint64_t reserved_9_63:55;
+#endif
 	} cn30xx;
 	struct cvmx_pip_int_en_cn30xx cn31xx;
 	struct cvmx_pip_int_en_cn30xx cn38xx;
 	struct cvmx_pip_int_en_cn30xx cn38xxp2;
 	struct cvmx_pip_int_en_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t lenerr:1;
 		uint64_t maxerr:1;
@@ -439,8 +1100,24 @@
 		uint64_t bckprs:1;
 		uint64_t reserved_1_1:1;
 		uint64_t pktdrp:1;
+#else
+		uint64_t pktdrp:1;
+		uint64_t reserved_1_1:1;
+		uint64_t bckprs:1;
+		uint64_t prtnxa:1;
+		uint64_t badtag:1;
+		uint64_t skprunt:1;
+		uint64_t todoovr:1;
+		uint64_t feperr:1;
+		uint64_t beperr:1;
+		uint64_t minerr:1;
+		uint64_t maxerr:1;
+		uint64_t lenerr:1;
+		uint64_t reserved_12_63:52;
+#endif
 	} cn50xx;
 	struct cvmx_pip_int_en_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_13_63:51;
 		uint64_t punyerr:1;
 		uint64_t lenerr:1;
@@ -455,10 +1132,27 @@
 		uint64_t bckprs:1;
 		uint64_t reserved_1_1:1;
 		uint64_t pktdrp:1;
+#else
+		uint64_t pktdrp:1;
+		uint64_t reserved_1_1:1;
+		uint64_t bckprs:1;
+		uint64_t prtnxa:1;
+		uint64_t badtag:1;
+		uint64_t skprunt:1;
+		uint64_t todoovr:1;
+		uint64_t feperr:1;
+		uint64_t beperr:1;
+		uint64_t minerr:1;
+		uint64_t maxerr:1;
+		uint64_t lenerr:1;
+		uint64_t punyerr:1;
+		uint64_t reserved_13_63:51;
+#endif
 	} cn52xx;
 	struct cvmx_pip_int_en_cn52xx cn52xxp1;
 	struct cvmx_pip_int_en_s cn56xx;
 	struct cvmx_pip_int_en_cn56xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t lenerr:1;
 		uint64_t maxerr:1;
@@ -472,8 +1166,24 @@
 		uint64_t bckprs:1;
 		uint64_t crcerr:1;
 		uint64_t pktdrp:1;
+#else
+		uint64_t pktdrp:1;
+		uint64_t crcerr:1;
+		uint64_t bckprs:1;
+		uint64_t prtnxa:1;
+		uint64_t badtag:1;
+		uint64_t skprunt:1;
+		uint64_t todoovr:1;
+		uint64_t feperr:1;
+		uint64_t beperr:1;
+		uint64_t minerr:1;
+		uint64_t maxerr:1;
+		uint64_t lenerr:1;
+		uint64_t reserved_12_63:52;
+#endif
 	} cn56xxp1;
 	struct cvmx_pip_int_en_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_13_63:51;
 		uint64_t punyerr:1;
 		uint64_t reserved_9_11:3;
@@ -486,13 +1196,35 @@
 		uint64_t bckprs:1;
 		uint64_t crcerr:1;
 		uint64_t pktdrp:1;
+#else
+		uint64_t pktdrp:1;
+		uint64_t crcerr:1;
+		uint64_t bckprs:1;
+		uint64_t prtnxa:1;
+		uint64_t badtag:1;
+		uint64_t skprunt:1;
+		uint64_t todoovr:1;
+		uint64_t feperr:1;
+		uint64_t beperr:1;
+		uint64_t reserved_9_11:3;
+		uint64_t punyerr:1;
+		uint64_t reserved_13_63:51;
+#endif
 	} cn58xx;
 	struct cvmx_pip_int_en_cn30xx cn58xxp1;
+	struct cvmx_pip_int_en_s cn61xx;
+	struct cvmx_pip_int_en_s cn63xx;
+	struct cvmx_pip_int_en_s cn63xxp1;
+	struct cvmx_pip_int_en_s cn66xx;
+	struct cvmx_pip_int_en_s cn68xx;
+	struct cvmx_pip_int_en_s cn68xxp1;
+	struct cvmx_pip_int_en_s cnf71xx;
 };
 
 union cvmx_pip_int_reg {
 	uint64_t u64;
 	struct cvmx_pip_int_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_13_63:51;
 		uint64_t punyerr:1;
 		uint64_t lenerr:1;
@@ -507,8 +1239,25 @@
 		uint64_t bckprs:1;
 		uint64_t crcerr:1;
 		uint64_t pktdrp:1;
+#else
+		uint64_t pktdrp:1;
+		uint64_t crcerr:1;
+		uint64_t bckprs:1;
+		uint64_t prtnxa:1;
+		uint64_t badtag:1;
+		uint64_t skprunt:1;
+		uint64_t todoovr:1;
+		uint64_t feperr:1;
+		uint64_t beperr:1;
+		uint64_t minerr:1;
+		uint64_t maxerr:1;
+		uint64_t lenerr:1;
+		uint64_t punyerr:1;
+		uint64_t reserved_13_63:51;
+#endif
 	} s;
 	struct cvmx_pip_int_reg_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t beperr:1;
 		uint64_t feperr:1;
@@ -519,11 +1268,24 @@
 		uint64_t bckprs:1;
 		uint64_t crcerr:1;
 		uint64_t pktdrp:1;
+#else
+		uint64_t pktdrp:1;
+		uint64_t crcerr:1;
+		uint64_t bckprs:1;
+		uint64_t prtnxa:1;
+		uint64_t badtag:1;
+		uint64_t skprunt:1;
+		uint64_t todoovr:1;
+		uint64_t feperr:1;
+		uint64_t beperr:1;
+		uint64_t reserved_9_63:55;
+#endif
 	} cn30xx;
 	struct cvmx_pip_int_reg_cn30xx cn31xx;
 	struct cvmx_pip_int_reg_cn30xx cn38xx;
 	struct cvmx_pip_int_reg_cn30xx cn38xxp2;
 	struct cvmx_pip_int_reg_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t lenerr:1;
 		uint64_t maxerr:1;
@@ -537,8 +1299,24 @@
 		uint64_t bckprs:1;
 		uint64_t reserved_1_1:1;
 		uint64_t pktdrp:1;
+#else
+		uint64_t pktdrp:1;
+		uint64_t reserved_1_1:1;
+		uint64_t bckprs:1;
+		uint64_t prtnxa:1;
+		uint64_t badtag:1;
+		uint64_t skprunt:1;
+		uint64_t todoovr:1;
+		uint64_t feperr:1;
+		uint64_t beperr:1;
+		uint64_t minerr:1;
+		uint64_t maxerr:1;
+		uint64_t lenerr:1;
+		uint64_t reserved_12_63:52;
+#endif
 	} cn50xx;
 	struct cvmx_pip_int_reg_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_13_63:51;
 		uint64_t punyerr:1;
 		uint64_t lenerr:1;
@@ -553,10 +1331,27 @@
 		uint64_t bckprs:1;
 		uint64_t reserved_1_1:1;
 		uint64_t pktdrp:1;
+#else
+		uint64_t pktdrp:1;
+		uint64_t reserved_1_1:1;
+		uint64_t bckprs:1;
+		uint64_t prtnxa:1;
+		uint64_t badtag:1;
+		uint64_t skprunt:1;
+		uint64_t todoovr:1;
+		uint64_t feperr:1;
+		uint64_t beperr:1;
+		uint64_t minerr:1;
+		uint64_t maxerr:1;
+		uint64_t lenerr:1;
+		uint64_t punyerr:1;
+		uint64_t reserved_13_63:51;
+#endif
 	} cn52xx;
 	struct cvmx_pip_int_reg_cn52xx cn52xxp1;
 	struct cvmx_pip_int_reg_s cn56xx;
 	struct cvmx_pip_int_reg_cn56xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t lenerr:1;
 		uint64_t maxerr:1;
@@ -570,8 +1365,24 @@
 		uint64_t bckprs:1;
 		uint64_t crcerr:1;
 		uint64_t pktdrp:1;
+#else
+		uint64_t pktdrp:1;
+		uint64_t crcerr:1;
+		uint64_t bckprs:1;
+		uint64_t prtnxa:1;
+		uint64_t badtag:1;
+		uint64_t skprunt:1;
+		uint64_t todoovr:1;
+		uint64_t feperr:1;
+		uint64_t beperr:1;
+		uint64_t minerr:1;
+		uint64_t maxerr:1;
+		uint64_t lenerr:1;
+		uint64_t reserved_12_63:52;
+#endif
 	} cn56xxp1;
 	struct cvmx_pip_int_reg_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_13_63:51;
 		uint64_t punyerr:1;
 		uint64_t reserved_9_11:3;
@@ -584,15 +1395,41 @@
 		uint64_t bckprs:1;
 		uint64_t crcerr:1;
 		uint64_t pktdrp:1;
+#else
+		uint64_t pktdrp:1;
+		uint64_t crcerr:1;
+		uint64_t bckprs:1;
+		uint64_t prtnxa:1;
+		uint64_t badtag:1;
+		uint64_t skprunt:1;
+		uint64_t todoovr:1;
+		uint64_t feperr:1;
+		uint64_t beperr:1;
+		uint64_t reserved_9_11:3;
+		uint64_t punyerr:1;
+		uint64_t reserved_13_63:51;
+#endif
 	} cn58xx;
 	struct cvmx_pip_int_reg_cn30xx cn58xxp1;
+	struct cvmx_pip_int_reg_s cn61xx;
+	struct cvmx_pip_int_reg_s cn63xx;
+	struct cvmx_pip_int_reg_s cn63xxp1;
+	struct cvmx_pip_int_reg_s cn66xx;
+	struct cvmx_pip_int_reg_s cn68xx;
+	struct cvmx_pip_int_reg_s cn68xxp1;
+	struct cvmx_pip_int_reg_s cnf71xx;
 };
 
 union cvmx_pip_ip_offset {
 	uint64_t u64;
 	struct cvmx_pip_ip_offset_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_3_63:61;
 		uint64_t offset:3;
+#else
+		uint64_t offset:3;
+		uint64_t reserved_3_63:61;
+#endif
 	} s;
 	struct cvmx_pip_ip_offset_s cn30xx;
 	struct cvmx_pip_ip_offset_s cn31xx;
@@ -605,11 +1442,264 @@
 	struct cvmx_pip_ip_offset_s cn56xxp1;
 	struct cvmx_pip_ip_offset_s cn58xx;
 	struct cvmx_pip_ip_offset_s cn58xxp1;
+	struct cvmx_pip_ip_offset_s cn61xx;
+	struct cvmx_pip_ip_offset_s cn63xx;
+	struct cvmx_pip_ip_offset_s cn63xxp1;
+	struct cvmx_pip_ip_offset_s cn66xx;
+	struct cvmx_pip_ip_offset_s cn68xx;
+	struct cvmx_pip_ip_offset_s cn68xxp1;
+	struct cvmx_pip_ip_offset_s cnf71xx;
+};
+
+union cvmx_pip_pri_tblx {
+	uint64_t u64;
+	struct cvmx_pip_pri_tblx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t diff2_padd:8;
+		uint64_t hg2_padd:8;
+		uint64_t vlan2_padd:8;
+		uint64_t reserved_38_39:2;
+		uint64_t diff2_bpid:6;
+		uint64_t reserved_30_31:2;
+		uint64_t hg2_bpid:6;
+		uint64_t reserved_22_23:2;
+		uint64_t vlan2_bpid:6;
+		uint64_t reserved_11_15:5;
+		uint64_t diff2_qos:3;
+		uint64_t reserved_7_7:1;
+		uint64_t hg2_qos:3;
+		uint64_t reserved_3_3:1;
+		uint64_t vlan2_qos:3;
+#else
+		uint64_t vlan2_qos:3;
+		uint64_t reserved_3_3:1;
+		uint64_t hg2_qos:3;
+		uint64_t reserved_7_7:1;
+		uint64_t diff2_qos:3;
+		uint64_t reserved_11_15:5;
+		uint64_t vlan2_bpid:6;
+		uint64_t reserved_22_23:2;
+		uint64_t hg2_bpid:6;
+		uint64_t reserved_30_31:2;
+		uint64_t diff2_bpid:6;
+		uint64_t reserved_38_39:2;
+		uint64_t vlan2_padd:8;
+		uint64_t hg2_padd:8;
+		uint64_t diff2_padd:8;
+#endif
+	} s;
+	struct cvmx_pip_pri_tblx_s cn68xx;
+	struct cvmx_pip_pri_tblx_s cn68xxp1;
 };
 
 union cvmx_pip_prt_cfgx {
 	uint64_t u64;
 	struct cvmx_pip_prt_cfgx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_55_63:9;
+		uint64_t ih_pri:1;
+		uint64_t len_chk_sel:1;
+		uint64_t pad_len:1;
+		uint64_t vlan_len:1;
+		uint64_t lenerr_en:1;
+		uint64_t maxerr_en:1;
+		uint64_t minerr_en:1;
+		uint64_t grp_wat_47:4;
+		uint64_t qos_wat_47:4;
+		uint64_t reserved_37_39:3;
+		uint64_t rawdrp:1;
+		uint64_t tag_inc:2;
+		uint64_t dyn_rs:1;
+		uint64_t inst_hdr:1;
+		uint64_t grp_wat:4;
+		uint64_t hg_qos:1;
+		uint64_t qos:3;
+		uint64_t qos_wat:4;
+		uint64_t qos_vsel:1;
+		uint64_t qos_vod:1;
+		uint64_t qos_diff:1;
+		uint64_t qos_vlan:1;
+		uint64_t reserved_13_15:3;
+		uint64_t crc_en:1;
+		uint64_t higig_en:1;
+		uint64_t dsa_en:1;
+		uint64_t mode:2;
+		uint64_t reserved_7_7:1;
+		uint64_t skip:7;
+#else
+		uint64_t skip:7;
+		uint64_t reserved_7_7:1;
+		uint64_t mode:2;
+		uint64_t dsa_en:1;
+		uint64_t higig_en:1;
+		uint64_t crc_en:1;
+		uint64_t reserved_13_15:3;
+		uint64_t qos_vlan:1;
+		uint64_t qos_diff:1;
+		uint64_t qos_vod:1;
+		uint64_t qos_vsel:1;
+		uint64_t qos_wat:4;
+		uint64_t qos:3;
+		uint64_t hg_qos:1;
+		uint64_t grp_wat:4;
+		uint64_t inst_hdr:1;
+		uint64_t dyn_rs:1;
+		uint64_t tag_inc:2;
+		uint64_t rawdrp:1;
+		uint64_t reserved_37_39:3;
+		uint64_t qos_wat_47:4;
+		uint64_t grp_wat_47:4;
+		uint64_t minerr_en:1;
+		uint64_t maxerr_en:1;
+		uint64_t lenerr_en:1;
+		uint64_t vlan_len:1;
+		uint64_t pad_len:1;
+		uint64_t len_chk_sel:1;
+		uint64_t ih_pri:1;
+		uint64_t reserved_55_63:9;
+#endif
+	} s;
+	struct cvmx_pip_prt_cfgx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_37_63:27;
+		uint64_t rawdrp:1;
+		uint64_t tag_inc:2;
+		uint64_t dyn_rs:1;
+		uint64_t inst_hdr:1;
+		uint64_t grp_wat:4;
+		uint64_t reserved_27_27:1;
+		uint64_t qos:3;
+		uint64_t qos_wat:4;
+		uint64_t reserved_18_19:2;
+		uint64_t qos_diff:1;
+		uint64_t qos_vlan:1;
+		uint64_t reserved_10_15:6;
+		uint64_t mode:2;
+		uint64_t reserved_7_7:1;
+		uint64_t skip:7;
+#else
+		uint64_t skip:7;
+		uint64_t reserved_7_7:1;
+		uint64_t mode:2;
+		uint64_t reserved_10_15:6;
+		uint64_t qos_vlan:1;
+		uint64_t qos_diff:1;
+		uint64_t reserved_18_19:2;
+		uint64_t qos_wat:4;
+		uint64_t qos:3;
+		uint64_t reserved_27_27:1;
+		uint64_t grp_wat:4;
+		uint64_t inst_hdr:1;
+		uint64_t dyn_rs:1;
+		uint64_t tag_inc:2;
+		uint64_t rawdrp:1;
+		uint64_t reserved_37_63:27;
+#endif
+	} cn30xx;
+	struct cvmx_pip_prt_cfgx_cn30xx cn31xx;
+	struct cvmx_pip_prt_cfgx_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_37_63:27;
+		uint64_t rawdrp:1;
+		uint64_t tag_inc:2;
+		uint64_t dyn_rs:1;
+		uint64_t inst_hdr:1;
+		uint64_t grp_wat:4;
+		uint64_t reserved_27_27:1;
+		uint64_t qos:3;
+		uint64_t qos_wat:4;
+		uint64_t reserved_18_19:2;
+		uint64_t qos_diff:1;
+		uint64_t qos_vlan:1;
+		uint64_t reserved_13_15:3;
+		uint64_t crc_en:1;
+		uint64_t reserved_10_11:2;
+		uint64_t mode:2;
+		uint64_t reserved_7_7:1;
+		uint64_t skip:7;
+#else
+		uint64_t skip:7;
+		uint64_t reserved_7_7:1;
+		uint64_t mode:2;
+		uint64_t reserved_10_11:2;
+		uint64_t crc_en:1;
+		uint64_t reserved_13_15:3;
+		uint64_t qos_vlan:1;
+		uint64_t qos_diff:1;
+		uint64_t reserved_18_19:2;
+		uint64_t qos_wat:4;
+		uint64_t qos:3;
+		uint64_t reserved_27_27:1;
+		uint64_t grp_wat:4;
+		uint64_t inst_hdr:1;
+		uint64_t dyn_rs:1;
+		uint64_t tag_inc:2;
+		uint64_t rawdrp:1;
+		uint64_t reserved_37_63:27;
+#endif
+	} cn38xx;
+	struct cvmx_pip_prt_cfgx_cn38xx cn38xxp2;
+	struct cvmx_pip_prt_cfgx_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_53_63:11;
+		uint64_t pad_len:1;
+		uint64_t vlan_len:1;
+		uint64_t lenerr_en:1;
+		uint64_t maxerr_en:1;
+		uint64_t minerr_en:1;
+		uint64_t grp_wat_47:4;
+		uint64_t qos_wat_47:4;
+		uint64_t reserved_37_39:3;
+		uint64_t rawdrp:1;
+		uint64_t tag_inc:2;
+		uint64_t dyn_rs:1;
+		uint64_t inst_hdr:1;
+		uint64_t grp_wat:4;
+		uint64_t reserved_27_27:1;
+		uint64_t qos:3;
+		uint64_t qos_wat:4;
+		uint64_t reserved_19_19:1;
+		uint64_t qos_vod:1;
+		uint64_t qos_diff:1;
+		uint64_t qos_vlan:1;
+		uint64_t reserved_13_15:3;
+		uint64_t crc_en:1;
+		uint64_t reserved_10_11:2;
+		uint64_t mode:2;
+		uint64_t reserved_7_7:1;
+		uint64_t skip:7;
+#else
+		uint64_t skip:7;
+		uint64_t reserved_7_7:1;
+		uint64_t mode:2;
+		uint64_t reserved_10_11:2;
+		uint64_t crc_en:1;
+		uint64_t reserved_13_15:3;
+		uint64_t qos_vlan:1;
+		uint64_t qos_diff:1;
+		uint64_t qos_vod:1;
+		uint64_t reserved_19_19:1;
+		uint64_t qos_wat:4;
+		uint64_t qos:3;
+		uint64_t reserved_27_27:1;
+		uint64_t grp_wat:4;
+		uint64_t inst_hdr:1;
+		uint64_t dyn_rs:1;
+		uint64_t tag_inc:2;
+		uint64_t rawdrp:1;
+		uint64_t reserved_37_39:3;
+		uint64_t qos_wat_47:4;
+		uint64_t grp_wat_47:4;
+		uint64_t minerr_en:1;
+		uint64_t maxerr_en:1;
+		uint64_t lenerr_en:1;
+		uint64_t vlan_len:1;
+		uint64_t pad_len:1;
+		uint64_t reserved_53_63:11;
+#endif
+	} cn50xx;
+	struct cvmx_pip_prt_cfgx_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_53_63:11;
 		uint64_t pad_len:1;
 		uint64_t vlan_len:1;
@@ -638,27 +1728,42 @@
 		uint64_t mode:2;
 		uint64_t reserved_7_7:1;
 		uint64_t skip:7;
-	} s;
-	struct cvmx_pip_prt_cfgx_cn30xx {
-		uint64_t reserved_37_63:27;
-		uint64_t rawdrp:1;
-		uint64_t tag_inc:2;
-		uint64_t dyn_rs:1;
-		uint64_t inst_hdr:1;
-		uint64_t grp_wat:4;
-		uint64_t reserved_27_27:1;
-		uint64_t qos:3;
-		uint64_t qos_wat:4;
-		uint64_t reserved_18_19:2;
-		uint64_t qos_diff:1;
-		uint64_t qos_vlan:1;
-		uint64_t reserved_10_15:6;
-		uint64_t mode:2;
-		uint64_t reserved_7_7:1;
+#else
 		uint64_t skip:7;
-	} cn30xx;
-	struct cvmx_pip_prt_cfgx_cn30xx cn31xx;
-	struct cvmx_pip_prt_cfgx_cn38xx {
+		uint64_t reserved_7_7:1;
+		uint64_t mode:2;
+		uint64_t dsa_en:1;
+		uint64_t higig_en:1;
+		uint64_t crc_en:1;
+		uint64_t reserved_13_15:3;
+		uint64_t qos_vlan:1;
+		uint64_t qos_diff:1;
+		uint64_t qos_vod:1;
+		uint64_t qos_vsel:1;
+		uint64_t qos_wat:4;
+		uint64_t qos:3;
+		uint64_t hg_qos:1;
+		uint64_t grp_wat:4;
+		uint64_t inst_hdr:1;
+		uint64_t dyn_rs:1;
+		uint64_t tag_inc:2;
+		uint64_t rawdrp:1;
+		uint64_t reserved_37_39:3;
+		uint64_t qos_wat_47:4;
+		uint64_t grp_wat_47:4;
+		uint64_t minerr_en:1;
+		uint64_t maxerr_en:1;
+		uint64_t lenerr_en:1;
+		uint64_t vlan_len:1;
+		uint64_t pad_len:1;
+		uint64_t reserved_53_63:11;
+#endif
+	} cn52xx;
+	struct cvmx_pip_prt_cfgx_cn52xx cn52xxp1;
+	struct cvmx_pip_prt_cfgx_cn52xx cn56xx;
+	struct cvmx_pip_prt_cfgx_cn50xx cn56xxp1;
+	struct cvmx_pip_prt_cfgx_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_37_63:27;
 		uint64_t rawdrp:1;
 		uint64_t tag_inc:2;
@@ -668,7 +1773,8 @@
 		uint64_t reserved_27_27:1;
 		uint64_t qos:3;
 		uint64_t qos_wat:4;
-		uint64_t reserved_18_19:2;
+		uint64_t reserved_19_19:1;
+		uint64_t qos_vod:1;
 		uint64_t qos_diff:1;
 		uint64_t qos_vlan:1;
 		uint64_t reserved_13_15:3;
@@ -677,10 +1783,38 @@
 		uint64_t mode:2;
 		uint64_t reserved_7_7:1;
 		uint64_t skip:7;
-	} cn38xx;
-	struct cvmx_pip_prt_cfgx_cn38xx cn38xxp2;
-	struct cvmx_pip_prt_cfgx_cn50xx {
-		uint64_t reserved_53_63:11;
+#else
+		uint64_t skip:7;
+		uint64_t reserved_7_7:1;
+		uint64_t mode:2;
+		uint64_t reserved_10_11:2;
+		uint64_t crc_en:1;
+		uint64_t reserved_13_15:3;
+		uint64_t qos_vlan:1;
+		uint64_t qos_diff:1;
+		uint64_t qos_vod:1;
+		uint64_t reserved_19_19:1;
+		uint64_t qos_wat:4;
+		uint64_t qos:3;
+		uint64_t reserved_27_27:1;
+		uint64_t grp_wat:4;
+		uint64_t inst_hdr:1;
+		uint64_t dyn_rs:1;
+		uint64_t tag_inc:2;
+		uint64_t rawdrp:1;
+		uint64_t reserved_37_63:27;
+#endif
+	} cn58xx;
+	struct cvmx_pip_prt_cfgx_cn58xx cn58xxp1;
+	struct cvmx_pip_prt_cfgx_cn52xx cn61xx;
+	struct cvmx_pip_prt_cfgx_cn52xx cn63xx;
+	struct cvmx_pip_prt_cfgx_cn52xx cn63xxp1;
+	struct cvmx_pip_prt_cfgx_cn52xx cn66xx;
+	struct cvmx_pip_prt_cfgx_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_55_63:9;
+		uint64_t ih_pri:1;
+		uint64_t len_chk_sel:1;
 		uint64_t pad_len:1;
 		uint64_t vlan_len:1;
 		uint64_t lenerr_en:1;
@@ -694,7 +1828,7 @@
 		uint64_t dyn_rs:1;
 		uint64_t inst_hdr:1;
 		uint64_t grp_wat:4;
-		uint64_t reserved_27_27:1;
+		uint64_t hg_qos:1;
 		uint64_t qos:3;
 		uint64_t qos_wat:4;
 		uint64_t reserved_19_19:1;
@@ -703,43 +1837,137 @@
 		uint64_t qos_vlan:1;
 		uint64_t reserved_13_15:3;
 		uint64_t crc_en:1;
-		uint64_t reserved_10_11:2;
+		uint64_t higig_en:1;
+		uint64_t dsa_en:1;
 		uint64_t mode:2;
 		uint64_t reserved_7_7:1;
 		uint64_t skip:7;
-	} cn50xx;
-	struct cvmx_pip_prt_cfgx_s cn52xx;
-	struct cvmx_pip_prt_cfgx_s cn52xxp1;
-	struct cvmx_pip_prt_cfgx_s cn56xx;
-	struct cvmx_pip_prt_cfgx_cn50xx cn56xxp1;
-	struct cvmx_pip_prt_cfgx_cn58xx {
-		uint64_t reserved_37_63:27;
-		uint64_t rawdrp:1;
-		uint64_t tag_inc:2;
-		uint64_t dyn_rs:1;
-		uint64_t inst_hdr:1;
+#else
+		uint64_t skip:7;
+		uint64_t reserved_7_7:1;
+		uint64_t mode:2;
+		uint64_t dsa_en:1;
+		uint64_t higig_en:1;
+		uint64_t crc_en:1;
+		uint64_t reserved_13_15:3;
+		uint64_t qos_vlan:1;
+		uint64_t qos_diff:1;
+		uint64_t qos_vod:1;
+		uint64_t reserved_19_19:1;
+		uint64_t qos_wat:4;
+		uint64_t qos:3;
+		uint64_t hg_qos:1;
 		uint64_t grp_wat:4;
-		uint64_t reserved_27_27:1;
-		uint64_t qos:3;
-		uint64_t qos_wat:4;
-		uint64_t reserved_19_19:1;
-		uint64_t qos_vod:1;
-		uint64_t qos_diff:1;
-		uint64_t qos_vlan:1;
-		uint64_t reserved_13_15:3;
-		uint64_t crc_en:1;
-		uint64_t reserved_10_11:2;
-		uint64_t mode:2;
-		uint64_t reserved_7_7:1;
-		uint64_t skip:7;
-	} cn58xx;
-	struct cvmx_pip_prt_cfgx_cn58xx cn58xxp1;
+		uint64_t inst_hdr:1;
+		uint64_t dyn_rs:1;
+		uint64_t tag_inc:2;
+		uint64_t rawdrp:1;
+		uint64_t reserved_37_39:3;
+		uint64_t qos_wat_47:4;
+		uint64_t grp_wat_47:4;
+		uint64_t minerr_en:1;
+		uint64_t maxerr_en:1;
+		uint64_t lenerr_en:1;
+		uint64_t vlan_len:1;
+		uint64_t pad_len:1;
+		uint64_t len_chk_sel:1;
+		uint64_t ih_pri:1;
+		uint64_t reserved_55_63:9;
+#endif
+	} cn68xx;
+	struct cvmx_pip_prt_cfgx_cn68xx cn68xxp1;
+	struct cvmx_pip_prt_cfgx_cn52xx cnf71xx;
+};
+
+union cvmx_pip_prt_cfgbx {
+	uint64_t u64;
+	struct cvmx_pip_prt_cfgbx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_39_63:25;
+		uint64_t alt_skp_sel:2;
+		uint64_t alt_skp_en:1;
+		uint64_t reserved_35_35:1;
+		uint64_t bsel_num:2;
+		uint64_t bsel_en:1;
+		uint64_t reserved_24_31:8;
+		uint64_t base:8;
+		uint64_t reserved_6_15:10;
+		uint64_t bpid:6;
+#else
+		uint64_t bpid:6;
+		uint64_t reserved_6_15:10;
+		uint64_t base:8;
+		uint64_t reserved_24_31:8;
+		uint64_t bsel_en:1;
+		uint64_t bsel_num:2;
+		uint64_t reserved_35_35:1;
+		uint64_t alt_skp_en:1;
+		uint64_t alt_skp_sel:2;
+		uint64_t reserved_39_63:25;
+#endif
+	} s;
+	struct cvmx_pip_prt_cfgbx_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_39_63:25;
+		uint64_t alt_skp_sel:2;
+		uint64_t alt_skp_en:1;
+		uint64_t reserved_35_35:1;
+		uint64_t bsel_num:2;
+		uint64_t bsel_en:1;
+		uint64_t reserved_0_31:32;
+#else
+		uint64_t reserved_0_31:32;
+		uint64_t bsel_en:1;
+		uint64_t bsel_num:2;
+		uint64_t reserved_35_35:1;
+		uint64_t alt_skp_en:1;
+		uint64_t alt_skp_sel:2;
+		uint64_t reserved_39_63:25;
+#endif
+	} cn61xx;
+	struct cvmx_pip_prt_cfgbx_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_39_63:25;
+		uint64_t alt_skp_sel:2;
+		uint64_t alt_skp_en:1;
+		uint64_t reserved_0_35:36;
+#else
+		uint64_t reserved_0_35:36;
+		uint64_t alt_skp_en:1;
+		uint64_t alt_skp_sel:2;
+		uint64_t reserved_39_63:25;
+#endif
+	} cn66xx;
+	struct cvmx_pip_prt_cfgbx_s cn68xx;
+	struct cvmx_pip_prt_cfgbx_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_24_63:40;
+		uint64_t base:8;
+		uint64_t reserved_6_15:10;
+		uint64_t bpid:6;
+#else
+		uint64_t bpid:6;
+		uint64_t reserved_6_15:10;
+		uint64_t base:8;
+		uint64_t reserved_24_63:40;
+#endif
+	} cn68xxp1;
+	struct cvmx_pip_prt_cfgbx_cn61xx cnf71xx;
 };
 
 union cvmx_pip_prt_tagx {
 	uint64_t u64;
 	struct cvmx_pip_prt_tagx_s {
-		uint64_t reserved_40_63:24;
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_54_63:10;
+		uint64_t portadd_en:1;
+		uint64_t inc_hwchk:1;
+		uint64_t reserved_50_51:2;
+		uint64_t grptagbase_msb:2;
+		uint64_t reserved_46_47:2;
+		uint64_t grptagmask_msb:2;
+		uint64_t reserved_42_43:2;
+		uint64_t grp_msb:2;
 		uint64_t grptagbase:4;
 		uint64_t grptagmask:4;
 		uint64_t grptag:1;
@@ -764,8 +1992,44 @@
 		uint64_t ip4_tag_type:2;
 		uint64_t non_tag_type:2;
 		uint64_t grp:4;
+#else
+		uint64_t grp:4;
+		uint64_t non_tag_type:2;
+		uint64_t ip4_tag_type:2;
+		uint64_t ip6_tag_type:2;
+		uint64_t tcp4_tag_type:2;
+		uint64_t tcp6_tag_type:2;
+		uint64_t ip4_src_flag:1;
+		uint64_t ip6_src_flag:1;
+		uint64_t ip4_dst_flag:1;
+		uint64_t ip6_dst_flag:1;
+		uint64_t ip4_pctl_flag:1;
+		uint64_t ip6_nxth_flag:1;
+		uint64_t ip4_sprt_flag:1;
+		uint64_t ip6_sprt_flag:1;
+		uint64_t ip4_dprt_flag:1;
+		uint64_t ip6_dprt_flag:1;
+		uint64_t inc_prt_flag:1;
+		uint64_t inc_vlan:1;
+		uint64_t inc_vs:2;
+		uint64_t tag_mode:2;
+		uint64_t grptag_mskip:1;
+		uint64_t grptag:1;
+		uint64_t grptagmask:4;
+		uint64_t grptagbase:4;
+		uint64_t grp_msb:2;
+		uint64_t reserved_42_43:2;
+		uint64_t grptagmask_msb:2;
+		uint64_t reserved_46_47:2;
+		uint64_t grptagbase_msb:2;
+		uint64_t reserved_50_51:2;
+		uint64_t inc_hwchk:1;
+		uint64_t portadd_en:1;
+		uint64_t reserved_54_63:10;
+#endif
 	} s;
 	struct cvmx_pip_prt_tagx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_40_63:24;
 		uint64_t grptagbase:4;
 		uint64_t grptagmask:4;
@@ -791,24 +2055,117 @@
 		uint64_t ip4_tag_type:2;
 		uint64_t non_tag_type:2;
 		uint64_t grp:4;
+#else
+		uint64_t grp:4;
+		uint64_t non_tag_type:2;
+		uint64_t ip4_tag_type:2;
+		uint64_t ip6_tag_type:2;
+		uint64_t tcp4_tag_type:2;
+		uint64_t tcp6_tag_type:2;
+		uint64_t ip4_src_flag:1;
+		uint64_t ip6_src_flag:1;
+		uint64_t ip4_dst_flag:1;
+		uint64_t ip6_dst_flag:1;
+		uint64_t ip4_pctl_flag:1;
+		uint64_t ip6_nxth_flag:1;
+		uint64_t ip4_sprt_flag:1;
+		uint64_t ip6_sprt_flag:1;
+		uint64_t ip4_dprt_flag:1;
+		uint64_t ip6_dprt_flag:1;
+		uint64_t inc_prt_flag:1;
+		uint64_t inc_vlan:1;
+		uint64_t inc_vs:2;
+		uint64_t tag_mode:2;
+		uint64_t reserved_30_30:1;
+		uint64_t grptag:1;
+		uint64_t grptagmask:4;
+		uint64_t grptagbase:4;
+		uint64_t reserved_40_63:24;
+#endif
 	} cn30xx;
 	struct cvmx_pip_prt_tagx_cn30xx cn31xx;
 	struct cvmx_pip_prt_tagx_cn30xx cn38xx;
 	struct cvmx_pip_prt_tagx_cn30xx cn38xxp2;
-	struct cvmx_pip_prt_tagx_s cn50xx;
-	struct cvmx_pip_prt_tagx_s cn52xx;
-	struct cvmx_pip_prt_tagx_s cn52xxp1;
-	struct cvmx_pip_prt_tagx_s cn56xx;
-	struct cvmx_pip_prt_tagx_s cn56xxp1;
+	struct cvmx_pip_prt_tagx_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_40_63:24;
+		uint64_t grptagbase:4;
+		uint64_t grptagmask:4;
+		uint64_t grptag:1;
+		uint64_t grptag_mskip:1;
+		uint64_t tag_mode:2;
+		uint64_t inc_vs:2;
+		uint64_t inc_vlan:1;
+		uint64_t inc_prt_flag:1;
+		uint64_t ip6_dprt_flag:1;
+		uint64_t ip4_dprt_flag:1;
+		uint64_t ip6_sprt_flag:1;
+		uint64_t ip4_sprt_flag:1;
+		uint64_t ip6_nxth_flag:1;
+		uint64_t ip4_pctl_flag:1;
+		uint64_t ip6_dst_flag:1;
+		uint64_t ip4_dst_flag:1;
+		uint64_t ip6_src_flag:1;
+		uint64_t ip4_src_flag:1;
+		uint64_t tcp6_tag_type:2;
+		uint64_t tcp4_tag_type:2;
+		uint64_t ip6_tag_type:2;
+		uint64_t ip4_tag_type:2;
+		uint64_t non_tag_type:2;
+		uint64_t grp:4;
+#else
+		uint64_t grp:4;
+		uint64_t non_tag_type:2;
+		uint64_t ip4_tag_type:2;
+		uint64_t ip6_tag_type:2;
+		uint64_t tcp4_tag_type:2;
+		uint64_t tcp6_tag_type:2;
+		uint64_t ip4_src_flag:1;
+		uint64_t ip6_src_flag:1;
+		uint64_t ip4_dst_flag:1;
+		uint64_t ip6_dst_flag:1;
+		uint64_t ip4_pctl_flag:1;
+		uint64_t ip6_nxth_flag:1;
+		uint64_t ip4_sprt_flag:1;
+		uint64_t ip6_sprt_flag:1;
+		uint64_t ip4_dprt_flag:1;
+		uint64_t ip6_dprt_flag:1;
+		uint64_t inc_prt_flag:1;
+		uint64_t inc_vlan:1;
+		uint64_t inc_vs:2;
+		uint64_t tag_mode:2;
+		uint64_t grptag_mskip:1;
+		uint64_t grptag:1;
+		uint64_t grptagmask:4;
+		uint64_t grptagbase:4;
+		uint64_t reserved_40_63:24;
+#endif
+	} cn50xx;
+	struct cvmx_pip_prt_tagx_cn50xx cn52xx;
+	struct cvmx_pip_prt_tagx_cn50xx cn52xxp1;
+	struct cvmx_pip_prt_tagx_cn50xx cn56xx;
+	struct cvmx_pip_prt_tagx_cn50xx cn56xxp1;
 	struct cvmx_pip_prt_tagx_cn30xx cn58xx;
 	struct cvmx_pip_prt_tagx_cn30xx cn58xxp1;
+	struct cvmx_pip_prt_tagx_cn50xx cn61xx;
+	struct cvmx_pip_prt_tagx_cn50xx cn63xx;
+	struct cvmx_pip_prt_tagx_cn50xx cn63xxp1;
+	struct cvmx_pip_prt_tagx_cn50xx cn66xx;
+	struct cvmx_pip_prt_tagx_s cn68xx;
+	struct cvmx_pip_prt_tagx_s cn68xxp1;
+	struct cvmx_pip_prt_tagx_cn50xx cnf71xx;
 };
 
 union cvmx_pip_qos_diffx {
 	uint64_t u64;
 	struct cvmx_pip_qos_diffx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_3_63:61;
 		uint64_t qos:3;
+#else
+		uint64_t qos:3;
+		uint64_t reserved_3_63:61;
+#endif
 	} s;
 	struct cvmx_pip_qos_diffx_s cn30xx;
 	struct cvmx_pip_qos_diffx_s cn31xx;
@@ -821,19 +2178,36 @@
 	struct cvmx_pip_qos_diffx_s cn56xxp1;
 	struct cvmx_pip_qos_diffx_s cn58xx;
 	struct cvmx_pip_qos_diffx_s cn58xxp1;
+	struct cvmx_pip_qos_diffx_s cn61xx;
+	struct cvmx_pip_qos_diffx_s cn63xx;
+	struct cvmx_pip_qos_diffx_s cn63xxp1;
+	struct cvmx_pip_qos_diffx_s cn66xx;
+	struct cvmx_pip_qos_diffx_s cnf71xx;
 };
 
 union cvmx_pip_qos_vlanx {
 	uint64_t u64;
 	struct cvmx_pip_qos_vlanx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_7_63:57;
 		uint64_t qos1:3;
 		uint64_t reserved_3_3:1;
 		uint64_t qos:3;
+#else
+		uint64_t qos:3;
+		uint64_t reserved_3_3:1;
+		uint64_t qos1:3;
+		uint64_t reserved_7_63:57;
+#endif
 	} s;
 	struct cvmx_pip_qos_vlanx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_3_63:61;
 		uint64_t qos:3;
+#else
+		uint64_t qos:3;
+		uint64_t reserved_3_63:61;
+#endif
 	} cn30xx;
 	struct cvmx_pip_qos_vlanx_cn30xx cn31xx;
 	struct cvmx_pip_qos_vlanx_cn30xx cn38xx;
@@ -845,22 +2219,40 @@
 	struct cvmx_pip_qos_vlanx_cn30xx cn56xxp1;
 	struct cvmx_pip_qos_vlanx_cn30xx cn58xx;
 	struct cvmx_pip_qos_vlanx_cn30xx cn58xxp1;
+	struct cvmx_pip_qos_vlanx_s cn61xx;
+	struct cvmx_pip_qos_vlanx_s cn63xx;
+	struct cvmx_pip_qos_vlanx_s cn63xxp1;
+	struct cvmx_pip_qos_vlanx_s cn66xx;
+	struct cvmx_pip_qos_vlanx_s cnf71xx;
 };
 
 union cvmx_pip_qos_watchx {
 	uint64_t u64;
 	struct cvmx_pip_qos_watchx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t mask:16;
-		uint64_t reserved_28_31:4;
-		uint64_t grp:4;
+		uint64_t reserved_30_31:2;
+		uint64_t grp:6;
 		uint64_t reserved_23_23:1;
 		uint64_t qos:3;
 		uint64_t reserved_19_19:1;
 		uint64_t match_type:3;
 		uint64_t match_value:16;
+#else
+		uint64_t match_value:16;
+		uint64_t match_type:3;
+		uint64_t reserved_19_19:1;
+		uint64_t qos:3;
+		uint64_t reserved_23_23:1;
+		uint64_t grp:6;
+		uint64_t reserved_30_31:2;
+		uint64_t mask:16;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_pip_qos_watchx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t mask:16;
 		uint64_t reserved_28_31:4;
@@ -870,24 +2262,69 @@
 		uint64_t reserved_18_19:2;
 		uint64_t match_type:2;
 		uint64_t match_value:16;
+#else
+		uint64_t match_value:16;
+		uint64_t match_type:2;
+		uint64_t reserved_18_19:2;
+		uint64_t qos:3;
+		uint64_t reserved_23_23:1;
+		uint64_t grp:4;
+		uint64_t reserved_28_31:4;
+		uint64_t mask:16;
+		uint64_t reserved_48_63:16;
+#endif
 	} cn30xx;
 	struct cvmx_pip_qos_watchx_cn30xx cn31xx;
 	struct cvmx_pip_qos_watchx_cn30xx cn38xx;
 	struct cvmx_pip_qos_watchx_cn30xx cn38xxp2;
-	struct cvmx_pip_qos_watchx_s cn50xx;
-	struct cvmx_pip_qos_watchx_s cn52xx;
-	struct cvmx_pip_qos_watchx_s cn52xxp1;
-	struct cvmx_pip_qos_watchx_s cn56xx;
-	struct cvmx_pip_qos_watchx_s cn56xxp1;
+	struct cvmx_pip_qos_watchx_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_48_63:16;
+		uint64_t mask:16;
+		uint64_t reserved_28_31:4;
+		uint64_t grp:4;
+		uint64_t reserved_23_23:1;
+		uint64_t qos:3;
+		uint64_t reserved_19_19:1;
+		uint64_t match_type:3;
+		uint64_t match_value:16;
+#else
+		uint64_t match_value:16;
+		uint64_t match_type:3;
+		uint64_t reserved_19_19:1;
+		uint64_t qos:3;
+		uint64_t reserved_23_23:1;
+		uint64_t grp:4;
+		uint64_t reserved_28_31:4;
+		uint64_t mask:16;
+		uint64_t reserved_48_63:16;
+#endif
+	} cn50xx;
+	struct cvmx_pip_qos_watchx_cn50xx cn52xx;
+	struct cvmx_pip_qos_watchx_cn50xx cn52xxp1;
+	struct cvmx_pip_qos_watchx_cn50xx cn56xx;
+	struct cvmx_pip_qos_watchx_cn50xx cn56xxp1;
 	struct cvmx_pip_qos_watchx_cn30xx cn58xx;
 	struct cvmx_pip_qos_watchx_cn30xx cn58xxp1;
+	struct cvmx_pip_qos_watchx_cn50xx cn61xx;
+	struct cvmx_pip_qos_watchx_cn50xx cn63xx;
+	struct cvmx_pip_qos_watchx_cn50xx cn63xxp1;
+	struct cvmx_pip_qos_watchx_cn50xx cn66xx;
+	struct cvmx_pip_qos_watchx_s cn68xx;
+	struct cvmx_pip_qos_watchx_s cn68xxp1;
+	struct cvmx_pip_qos_watchx_cn50xx cnf71xx;
 };
 
 union cvmx_pip_raw_word {
 	uint64_t u64;
 	struct cvmx_pip_raw_word_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_56_63:8;
 		uint64_t word:56;
+#else
+		uint64_t word:56;
+		uint64_t reserved_56_63:8;
+#endif
 	} s;
 	struct cvmx_pip_raw_word_s cn30xx;
 	struct cvmx_pip_raw_word_s cn31xx;
@@ -900,13 +2337,25 @@
 	struct cvmx_pip_raw_word_s cn56xxp1;
 	struct cvmx_pip_raw_word_s cn58xx;
 	struct cvmx_pip_raw_word_s cn58xxp1;
+	struct cvmx_pip_raw_word_s cn61xx;
+	struct cvmx_pip_raw_word_s cn63xx;
+	struct cvmx_pip_raw_word_s cn63xxp1;
+	struct cvmx_pip_raw_word_s cn66xx;
+	struct cvmx_pip_raw_word_s cn68xx;
+	struct cvmx_pip_raw_word_s cn68xxp1;
+	struct cvmx_pip_raw_word_s cnf71xx;
 };
 
 union cvmx_pip_sft_rst {
 	uint64_t u64;
 	struct cvmx_pip_sft_rst_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t rst:1;
+#else
+		uint64_t rst:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_pip_sft_rst_s cn30xx;
 	struct cvmx_pip_sft_rst_s cn31xx;
@@ -918,13 +2367,40 @@
 	struct cvmx_pip_sft_rst_s cn56xxp1;
 	struct cvmx_pip_sft_rst_s cn58xx;
 	struct cvmx_pip_sft_rst_s cn58xxp1;
+	struct cvmx_pip_sft_rst_s cn61xx;
+	struct cvmx_pip_sft_rst_s cn63xx;
+	struct cvmx_pip_sft_rst_s cn63xxp1;
+	struct cvmx_pip_sft_rst_s cn66xx;
+	struct cvmx_pip_sft_rst_s cn68xx;
+	struct cvmx_pip_sft_rst_s cn68xxp1;
+	struct cvmx_pip_sft_rst_s cnf71xx;
+};
+
+union cvmx_pip_stat0_x {
+	uint64_t u64;
+	struct cvmx_pip_stat0_x_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t drp_pkts:32;
+		uint64_t drp_octs:32;
+#else
+		uint64_t drp_octs:32;
+		uint64_t drp_pkts:32;
+#endif
+	} s;
+	struct cvmx_pip_stat0_x_s cn68xx;
+	struct cvmx_pip_stat0_x_s cn68xxp1;
 };
 
 union cvmx_pip_stat0_prtx {
 	uint64_t u64;
 	struct cvmx_pip_stat0_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t drp_pkts:32;
 		uint64_t drp_octs:32;
+#else
+		uint64_t drp_octs:32;
+		uint64_t drp_pkts:32;
+#endif
 	} s;
 	struct cvmx_pip_stat0_prtx_s cn30xx;
 	struct cvmx_pip_stat0_prtx_s cn31xx;
@@ -937,13 +2413,112 @@
 	struct cvmx_pip_stat0_prtx_s cn56xxp1;
 	struct cvmx_pip_stat0_prtx_s cn58xx;
 	struct cvmx_pip_stat0_prtx_s cn58xxp1;
+	struct cvmx_pip_stat0_prtx_s cn61xx;
+	struct cvmx_pip_stat0_prtx_s cn63xx;
+	struct cvmx_pip_stat0_prtx_s cn63xxp1;
+	struct cvmx_pip_stat0_prtx_s cn66xx;
+	struct cvmx_pip_stat0_prtx_s cnf71xx;
+};
+
+union cvmx_pip_stat10_x {
+	uint64_t u64;
+	struct cvmx_pip_stat10_x_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bcast:32;
+		uint64_t mcast:32;
+#else
+		uint64_t mcast:32;
+		uint64_t bcast:32;
+#endif
+	} s;
+	struct cvmx_pip_stat10_x_s cn68xx;
+	struct cvmx_pip_stat10_x_s cn68xxp1;
+};
+
+union cvmx_pip_stat10_prtx {
+	uint64_t u64;
+	struct cvmx_pip_stat10_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bcast:32;
+		uint64_t mcast:32;
+#else
+		uint64_t mcast:32;
+		uint64_t bcast:32;
+#endif
+	} s;
+	struct cvmx_pip_stat10_prtx_s cn52xx;
+	struct cvmx_pip_stat10_prtx_s cn52xxp1;
+	struct cvmx_pip_stat10_prtx_s cn56xx;
+	struct cvmx_pip_stat10_prtx_s cn56xxp1;
+	struct cvmx_pip_stat10_prtx_s cn61xx;
+	struct cvmx_pip_stat10_prtx_s cn63xx;
+	struct cvmx_pip_stat10_prtx_s cn63xxp1;
+	struct cvmx_pip_stat10_prtx_s cn66xx;
+	struct cvmx_pip_stat10_prtx_s cnf71xx;
+};
+
+union cvmx_pip_stat11_x {
+	uint64_t u64;
+	struct cvmx_pip_stat11_x_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bcast:32;
+		uint64_t mcast:32;
+#else
+		uint64_t mcast:32;
+		uint64_t bcast:32;
+#endif
+	} s;
+	struct cvmx_pip_stat11_x_s cn68xx;
+	struct cvmx_pip_stat11_x_s cn68xxp1;
+};
+
+union cvmx_pip_stat11_prtx {
+	uint64_t u64;
+	struct cvmx_pip_stat11_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bcast:32;
+		uint64_t mcast:32;
+#else
+		uint64_t mcast:32;
+		uint64_t bcast:32;
+#endif
+	} s;
+	struct cvmx_pip_stat11_prtx_s cn52xx;
+	struct cvmx_pip_stat11_prtx_s cn52xxp1;
+	struct cvmx_pip_stat11_prtx_s cn56xx;
+	struct cvmx_pip_stat11_prtx_s cn56xxp1;
+	struct cvmx_pip_stat11_prtx_s cn61xx;
+	struct cvmx_pip_stat11_prtx_s cn63xx;
+	struct cvmx_pip_stat11_prtx_s cn63xxp1;
+	struct cvmx_pip_stat11_prtx_s cn66xx;
+	struct cvmx_pip_stat11_prtx_s cnf71xx;
+};
+
+union cvmx_pip_stat1_x {
+	uint64_t u64;
+	struct cvmx_pip_stat1_x_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_48_63:16;
+		uint64_t octs:48;
+#else
+		uint64_t octs:48;
+		uint64_t reserved_48_63:16;
+#endif
+	} s;
+	struct cvmx_pip_stat1_x_s cn68xx;
+	struct cvmx_pip_stat1_x_s cn68xxp1;
 };
 
 union cvmx_pip_stat1_prtx {
 	uint64_t u64;
 	struct cvmx_pip_stat1_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t octs:48;
+#else
+		uint64_t octs:48;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_pip_stat1_prtx_s cn30xx;
 	struct cvmx_pip_stat1_prtx_s cn31xx;
@@ -956,13 +2531,38 @@
 	struct cvmx_pip_stat1_prtx_s cn56xxp1;
 	struct cvmx_pip_stat1_prtx_s cn58xx;
 	struct cvmx_pip_stat1_prtx_s cn58xxp1;
+	struct cvmx_pip_stat1_prtx_s cn61xx;
+	struct cvmx_pip_stat1_prtx_s cn63xx;
+	struct cvmx_pip_stat1_prtx_s cn63xxp1;
+	struct cvmx_pip_stat1_prtx_s cn66xx;
+	struct cvmx_pip_stat1_prtx_s cnf71xx;
+};
+
+union cvmx_pip_stat2_x {
+	uint64_t u64;
+	struct cvmx_pip_stat2_x_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t pkts:32;
+		uint64_t raw:32;
+#else
+		uint64_t raw:32;
+		uint64_t pkts:32;
+#endif
+	} s;
+	struct cvmx_pip_stat2_x_s cn68xx;
+	struct cvmx_pip_stat2_x_s cn68xxp1;
 };
 
 union cvmx_pip_stat2_prtx {
 	uint64_t u64;
 	struct cvmx_pip_stat2_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t pkts:32;
 		uint64_t raw:32;
+#else
+		uint64_t raw:32;
+		uint64_t pkts:32;
+#endif
 	} s;
 	struct cvmx_pip_stat2_prtx_s cn30xx;
 	struct cvmx_pip_stat2_prtx_s cn31xx;
@@ -975,13 +2575,38 @@
 	struct cvmx_pip_stat2_prtx_s cn56xxp1;
 	struct cvmx_pip_stat2_prtx_s cn58xx;
 	struct cvmx_pip_stat2_prtx_s cn58xxp1;
+	struct cvmx_pip_stat2_prtx_s cn61xx;
+	struct cvmx_pip_stat2_prtx_s cn63xx;
+	struct cvmx_pip_stat2_prtx_s cn63xxp1;
+	struct cvmx_pip_stat2_prtx_s cn66xx;
+	struct cvmx_pip_stat2_prtx_s cnf71xx;
+};
+
+union cvmx_pip_stat3_x {
+	uint64_t u64;
+	struct cvmx_pip_stat3_x_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bcst:32;
+		uint64_t mcst:32;
+#else
+		uint64_t mcst:32;
+		uint64_t bcst:32;
+#endif
+	} s;
+	struct cvmx_pip_stat3_x_s cn68xx;
+	struct cvmx_pip_stat3_x_s cn68xxp1;
 };
 
 union cvmx_pip_stat3_prtx {
 	uint64_t u64;
 	struct cvmx_pip_stat3_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t bcst:32;
 		uint64_t mcst:32;
+#else
+		uint64_t mcst:32;
+		uint64_t bcst:32;
+#endif
 	} s;
 	struct cvmx_pip_stat3_prtx_s cn30xx;
 	struct cvmx_pip_stat3_prtx_s cn31xx;
@@ -994,13 +2619,38 @@
 	struct cvmx_pip_stat3_prtx_s cn56xxp1;
 	struct cvmx_pip_stat3_prtx_s cn58xx;
 	struct cvmx_pip_stat3_prtx_s cn58xxp1;
+	struct cvmx_pip_stat3_prtx_s cn61xx;
+	struct cvmx_pip_stat3_prtx_s cn63xx;
+	struct cvmx_pip_stat3_prtx_s cn63xxp1;
+	struct cvmx_pip_stat3_prtx_s cn66xx;
+	struct cvmx_pip_stat3_prtx_s cnf71xx;
+};
+
+union cvmx_pip_stat4_x {
+	uint64_t u64;
+	struct cvmx_pip_stat4_x_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t h65to127:32;
+		uint64_t h64:32;
+#else
+		uint64_t h64:32;
+		uint64_t h65to127:32;
+#endif
+	} s;
+	struct cvmx_pip_stat4_x_s cn68xx;
+	struct cvmx_pip_stat4_x_s cn68xxp1;
 };
 
 union cvmx_pip_stat4_prtx {
 	uint64_t u64;
 	struct cvmx_pip_stat4_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t h65to127:32;
 		uint64_t h64:32;
+#else
+		uint64_t h64:32;
+		uint64_t h65to127:32;
+#endif
 	} s;
 	struct cvmx_pip_stat4_prtx_s cn30xx;
 	struct cvmx_pip_stat4_prtx_s cn31xx;
@@ -1013,13 +2663,38 @@
 	struct cvmx_pip_stat4_prtx_s cn56xxp1;
 	struct cvmx_pip_stat4_prtx_s cn58xx;
 	struct cvmx_pip_stat4_prtx_s cn58xxp1;
+	struct cvmx_pip_stat4_prtx_s cn61xx;
+	struct cvmx_pip_stat4_prtx_s cn63xx;
+	struct cvmx_pip_stat4_prtx_s cn63xxp1;
+	struct cvmx_pip_stat4_prtx_s cn66xx;
+	struct cvmx_pip_stat4_prtx_s cnf71xx;
+};
+
+union cvmx_pip_stat5_x {
+	uint64_t u64;
+	struct cvmx_pip_stat5_x_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t h256to511:32;
+		uint64_t h128to255:32;
+#else
+		uint64_t h128to255:32;
+		uint64_t h256to511:32;
+#endif
+	} s;
+	struct cvmx_pip_stat5_x_s cn68xx;
+	struct cvmx_pip_stat5_x_s cn68xxp1;
 };
 
 union cvmx_pip_stat5_prtx {
 	uint64_t u64;
 	struct cvmx_pip_stat5_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t h256to511:32;
 		uint64_t h128to255:32;
+#else
+		uint64_t h128to255:32;
+		uint64_t h256to511:32;
+#endif
 	} s;
 	struct cvmx_pip_stat5_prtx_s cn30xx;
 	struct cvmx_pip_stat5_prtx_s cn31xx;
@@ -1032,13 +2707,38 @@
 	struct cvmx_pip_stat5_prtx_s cn56xxp1;
 	struct cvmx_pip_stat5_prtx_s cn58xx;
 	struct cvmx_pip_stat5_prtx_s cn58xxp1;
+	struct cvmx_pip_stat5_prtx_s cn61xx;
+	struct cvmx_pip_stat5_prtx_s cn63xx;
+	struct cvmx_pip_stat5_prtx_s cn63xxp1;
+	struct cvmx_pip_stat5_prtx_s cn66xx;
+	struct cvmx_pip_stat5_prtx_s cnf71xx;
+};
+
+union cvmx_pip_stat6_x {
+	uint64_t u64;
+	struct cvmx_pip_stat6_x_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t h1024to1518:32;
+		uint64_t h512to1023:32;
+#else
+		uint64_t h512to1023:32;
+		uint64_t h1024to1518:32;
+#endif
+	} s;
+	struct cvmx_pip_stat6_x_s cn68xx;
+	struct cvmx_pip_stat6_x_s cn68xxp1;
 };
 
 union cvmx_pip_stat6_prtx {
 	uint64_t u64;
 	struct cvmx_pip_stat6_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t h1024to1518:32;
 		uint64_t h512to1023:32;
+#else
+		uint64_t h512to1023:32;
+		uint64_t h1024to1518:32;
+#endif
 	} s;
 	struct cvmx_pip_stat6_prtx_s cn30xx;
 	struct cvmx_pip_stat6_prtx_s cn31xx;
@@ -1051,13 +2751,38 @@
 	struct cvmx_pip_stat6_prtx_s cn56xxp1;
 	struct cvmx_pip_stat6_prtx_s cn58xx;
 	struct cvmx_pip_stat6_prtx_s cn58xxp1;
+	struct cvmx_pip_stat6_prtx_s cn61xx;
+	struct cvmx_pip_stat6_prtx_s cn63xx;
+	struct cvmx_pip_stat6_prtx_s cn63xxp1;
+	struct cvmx_pip_stat6_prtx_s cn66xx;
+	struct cvmx_pip_stat6_prtx_s cnf71xx;
+};
+
+union cvmx_pip_stat7_x {
+	uint64_t u64;
+	struct cvmx_pip_stat7_x_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t fcs:32;
+		uint64_t h1519:32;
+#else
+		uint64_t h1519:32;
+		uint64_t fcs:32;
+#endif
+	} s;
+	struct cvmx_pip_stat7_x_s cn68xx;
+	struct cvmx_pip_stat7_x_s cn68xxp1;
 };
 
 union cvmx_pip_stat7_prtx {
 	uint64_t u64;
 	struct cvmx_pip_stat7_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t fcs:32;
 		uint64_t h1519:32;
+#else
+		uint64_t h1519:32;
+		uint64_t fcs:32;
+#endif
 	} s;
 	struct cvmx_pip_stat7_prtx_s cn30xx;
 	struct cvmx_pip_stat7_prtx_s cn31xx;
@@ -1070,13 +2795,38 @@
 	struct cvmx_pip_stat7_prtx_s cn56xxp1;
 	struct cvmx_pip_stat7_prtx_s cn58xx;
 	struct cvmx_pip_stat7_prtx_s cn58xxp1;
+	struct cvmx_pip_stat7_prtx_s cn61xx;
+	struct cvmx_pip_stat7_prtx_s cn63xx;
+	struct cvmx_pip_stat7_prtx_s cn63xxp1;
+	struct cvmx_pip_stat7_prtx_s cn66xx;
+	struct cvmx_pip_stat7_prtx_s cnf71xx;
+};
+
+union cvmx_pip_stat8_x {
+	uint64_t u64;
+	struct cvmx_pip_stat8_x_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t frag:32;
+		uint64_t undersz:32;
+#else
+		uint64_t undersz:32;
+		uint64_t frag:32;
+#endif
+	} s;
+	struct cvmx_pip_stat8_x_s cn68xx;
+	struct cvmx_pip_stat8_x_s cn68xxp1;
 };
 
 union cvmx_pip_stat8_prtx {
 	uint64_t u64;
 	struct cvmx_pip_stat8_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t frag:32;
 		uint64_t undersz:32;
+#else
+		uint64_t undersz:32;
+		uint64_t frag:32;
+#endif
 	} s;
 	struct cvmx_pip_stat8_prtx_s cn30xx;
 	struct cvmx_pip_stat8_prtx_s cn31xx;
@@ -1089,13 +2839,38 @@
 	struct cvmx_pip_stat8_prtx_s cn56xxp1;
 	struct cvmx_pip_stat8_prtx_s cn58xx;
 	struct cvmx_pip_stat8_prtx_s cn58xxp1;
+	struct cvmx_pip_stat8_prtx_s cn61xx;
+	struct cvmx_pip_stat8_prtx_s cn63xx;
+	struct cvmx_pip_stat8_prtx_s cn63xxp1;
+	struct cvmx_pip_stat8_prtx_s cn66xx;
+	struct cvmx_pip_stat8_prtx_s cnf71xx;
+};
+
+union cvmx_pip_stat9_x {
+	uint64_t u64;
+	struct cvmx_pip_stat9_x_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t jabber:32;
+		uint64_t oversz:32;
+#else
+		uint64_t oversz:32;
+		uint64_t jabber:32;
+#endif
+	} s;
+	struct cvmx_pip_stat9_x_s cn68xx;
+	struct cvmx_pip_stat9_x_s cn68xxp1;
 };
 
 union cvmx_pip_stat9_prtx {
 	uint64_t u64;
 	struct cvmx_pip_stat9_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t jabber:32;
 		uint64_t oversz:32;
+#else
+		uint64_t oversz:32;
+		uint64_t jabber:32;
+#endif
 	} s;
 	struct cvmx_pip_stat9_prtx_s cn30xx;
 	struct cvmx_pip_stat9_prtx_s cn31xx;
@@ -1108,32 +2883,66 @@
 	struct cvmx_pip_stat9_prtx_s cn56xxp1;
 	struct cvmx_pip_stat9_prtx_s cn58xx;
 	struct cvmx_pip_stat9_prtx_s cn58xxp1;
+	struct cvmx_pip_stat9_prtx_s cn61xx;
+	struct cvmx_pip_stat9_prtx_s cn63xx;
+	struct cvmx_pip_stat9_prtx_s cn63xxp1;
+	struct cvmx_pip_stat9_prtx_s cn66xx;
+	struct cvmx_pip_stat9_prtx_s cnf71xx;
 };
 
 union cvmx_pip_stat_ctl {
 	uint64_t u64;
 	struct cvmx_pip_stat_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_9_63:55;
+		uint64_t mode:1;
+		uint64_t reserved_1_7:7;
+		uint64_t rdclr:1;
+#else
+		uint64_t rdclr:1;
+		uint64_t reserved_1_7:7;
+		uint64_t mode:1;
+		uint64_t reserved_9_63:55;
+#endif
+	} s;
+	struct cvmx_pip_stat_ctl_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t rdclr:1;
-	} s;
-	struct cvmx_pip_stat_ctl_s cn30xx;
-	struct cvmx_pip_stat_ctl_s cn31xx;
-	struct cvmx_pip_stat_ctl_s cn38xx;
-	struct cvmx_pip_stat_ctl_s cn38xxp2;
-	struct cvmx_pip_stat_ctl_s cn50xx;
-	struct cvmx_pip_stat_ctl_s cn52xx;
-	struct cvmx_pip_stat_ctl_s cn52xxp1;
-	struct cvmx_pip_stat_ctl_s cn56xx;
-	struct cvmx_pip_stat_ctl_s cn56xxp1;
-	struct cvmx_pip_stat_ctl_s cn58xx;
-	struct cvmx_pip_stat_ctl_s cn58xxp1;
+#else
+		uint64_t rdclr:1;
+		uint64_t reserved_1_63:63;
+#endif
+	} cn30xx;
+	struct cvmx_pip_stat_ctl_cn30xx cn31xx;
+	struct cvmx_pip_stat_ctl_cn30xx cn38xx;
+	struct cvmx_pip_stat_ctl_cn30xx cn38xxp2;
+	struct cvmx_pip_stat_ctl_cn30xx cn50xx;
+	struct cvmx_pip_stat_ctl_cn30xx cn52xx;
+	struct cvmx_pip_stat_ctl_cn30xx cn52xxp1;
+	struct cvmx_pip_stat_ctl_cn30xx cn56xx;
+	struct cvmx_pip_stat_ctl_cn30xx cn56xxp1;
+	struct cvmx_pip_stat_ctl_cn30xx cn58xx;
+	struct cvmx_pip_stat_ctl_cn30xx cn58xxp1;
+	struct cvmx_pip_stat_ctl_cn30xx cn61xx;
+	struct cvmx_pip_stat_ctl_cn30xx cn63xx;
+	struct cvmx_pip_stat_ctl_cn30xx cn63xxp1;
+	struct cvmx_pip_stat_ctl_cn30xx cn66xx;
+	struct cvmx_pip_stat_ctl_s cn68xx;
+	struct cvmx_pip_stat_ctl_s cn68xxp1;
+	struct cvmx_pip_stat_ctl_cn30xx cnf71xx;
 };
 
 union cvmx_pip_stat_inb_errsx {
 	uint64_t u64;
 	struct cvmx_pip_stat_inb_errsx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t errs:16;
+#else
+		uint64_t errs:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_pip_stat_inb_errsx_s cn30xx;
 	struct cvmx_pip_stat_inb_errsx_s cn31xx;
@@ -1146,13 +2955,38 @@
 	struct cvmx_pip_stat_inb_errsx_s cn56xxp1;
 	struct cvmx_pip_stat_inb_errsx_s cn58xx;
 	struct cvmx_pip_stat_inb_errsx_s cn58xxp1;
+	struct cvmx_pip_stat_inb_errsx_s cn61xx;
+	struct cvmx_pip_stat_inb_errsx_s cn63xx;
+	struct cvmx_pip_stat_inb_errsx_s cn63xxp1;
+	struct cvmx_pip_stat_inb_errsx_s cn66xx;
+	struct cvmx_pip_stat_inb_errsx_s cnf71xx;
+};
+
+union cvmx_pip_stat_inb_errs_pkndx {
+	uint64_t u64;
+	struct cvmx_pip_stat_inb_errs_pkndx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t errs:16;
+#else
+		uint64_t errs:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} s;
+	struct cvmx_pip_stat_inb_errs_pkndx_s cn68xx;
+	struct cvmx_pip_stat_inb_errs_pkndx_s cn68xxp1;
 };
 
 union cvmx_pip_stat_inb_octsx {
 	uint64_t u64;
 	struct cvmx_pip_stat_inb_octsx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t octs:48;
+#else
+		uint64_t octs:48;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_pip_stat_inb_octsx_s cn30xx;
 	struct cvmx_pip_stat_inb_octsx_s cn31xx;
@@ -1165,13 +2999,38 @@
 	struct cvmx_pip_stat_inb_octsx_s cn56xxp1;
 	struct cvmx_pip_stat_inb_octsx_s cn58xx;
 	struct cvmx_pip_stat_inb_octsx_s cn58xxp1;
+	struct cvmx_pip_stat_inb_octsx_s cn61xx;
+	struct cvmx_pip_stat_inb_octsx_s cn63xx;
+	struct cvmx_pip_stat_inb_octsx_s cn63xxp1;
+	struct cvmx_pip_stat_inb_octsx_s cn66xx;
+	struct cvmx_pip_stat_inb_octsx_s cnf71xx;
+};
+
+union cvmx_pip_stat_inb_octs_pkndx {
+	uint64_t u64;
+	struct cvmx_pip_stat_inb_octs_pkndx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_48_63:16;
+		uint64_t octs:48;
+#else
+		uint64_t octs:48;
+		uint64_t reserved_48_63:16;
+#endif
+	} s;
+	struct cvmx_pip_stat_inb_octs_pkndx_s cn68xx;
+	struct cvmx_pip_stat_inb_octs_pkndx_s cn68xxp1;
 };
 
 union cvmx_pip_stat_inb_pktsx {
 	uint64_t u64;
 	struct cvmx_pip_stat_inb_pktsx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t pkts:32;
+#else
+		uint64_t pkts:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_pip_stat_inb_pktsx_s cn30xx;
 	struct cvmx_pip_stat_inb_pktsx_s cn31xx;
@@ -1184,13 +3043,51 @@
 	struct cvmx_pip_stat_inb_pktsx_s cn56xxp1;
 	struct cvmx_pip_stat_inb_pktsx_s cn58xx;
 	struct cvmx_pip_stat_inb_pktsx_s cn58xxp1;
+	struct cvmx_pip_stat_inb_pktsx_s cn61xx;
+	struct cvmx_pip_stat_inb_pktsx_s cn63xx;
+	struct cvmx_pip_stat_inb_pktsx_s cn63xxp1;
+	struct cvmx_pip_stat_inb_pktsx_s cn66xx;
+	struct cvmx_pip_stat_inb_pktsx_s cnf71xx;
+};
+
+union cvmx_pip_stat_inb_pkts_pkndx {
+	uint64_t u64;
+	struct cvmx_pip_stat_inb_pkts_pkndx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t pkts:32;
+#else
+		uint64_t pkts:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_pip_stat_inb_pkts_pkndx_s cn68xx;
+	struct cvmx_pip_stat_inb_pkts_pkndx_s cn68xxp1;
+};
+
+union cvmx_pip_sub_pkind_fcsx {
+	uint64_t u64;
+	struct cvmx_pip_sub_pkind_fcsx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t port_bit:64;
+#else
+		uint64_t port_bit:64;
+#endif
+	} s;
+	struct cvmx_pip_sub_pkind_fcsx_s cn68xx;
+	struct cvmx_pip_sub_pkind_fcsx_s cn68xxp1;
 };
 
 union cvmx_pip_tag_incx {
 	uint64_t u64;
 	struct cvmx_pip_tag_incx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t en:8;
+#else
+		uint64_t en:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_pip_tag_incx_s cn30xx;
 	struct cvmx_pip_tag_incx_s cn31xx;
@@ -1203,13 +3100,25 @@
 	struct cvmx_pip_tag_incx_s cn56xxp1;
 	struct cvmx_pip_tag_incx_s cn58xx;
 	struct cvmx_pip_tag_incx_s cn58xxp1;
+	struct cvmx_pip_tag_incx_s cn61xx;
+	struct cvmx_pip_tag_incx_s cn63xx;
+	struct cvmx_pip_tag_incx_s cn63xxp1;
+	struct cvmx_pip_tag_incx_s cn66xx;
+	struct cvmx_pip_tag_incx_s cn68xx;
+	struct cvmx_pip_tag_incx_s cn68xxp1;
+	struct cvmx_pip_tag_incx_s cnf71xx;
 };
 
 union cvmx_pip_tag_mask {
 	uint64_t u64;
 	struct cvmx_pip_tag_mask_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t mask:16;
+#else
+		uint64_t mask:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_pip_tag_mask_s cn30xx;
 	struct cvmx_pip_tag_mask_s cn31xx;
@@ -1222,14 +3131,27 @@
 	struct cvmx_pip_tag_mask_s cn56xxp1;
 	struct cvmx_pip_tag_mask_s cn58xx;
 	struct cvmx_pip_tag_mask_s cn58xxp1;
+	struct cvmx_pip_tag_mask_s cn61xx;
+	struct cvmx_pip_tag_mask_s cn63xx;
+	struct cvmx_pip_tag_mask_s cn63xxp1;
+	struct cvmx_pip_tag_mask_s cn66xx;
+	struct cvmx_pip_tag_mask_s cn68xx;
+	struct cvmx_pip_tag_mask_s cn68xxp1;
+	struct cvmx_pip_tag_mask_s cnf71xx;
 };
 
 union cvmx_pip_tag_secret {
 	uint64_t u64;
 	struct cvmx_pip_tag_secret_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t dst:16;
 		uint64_t src:16;
+#else
+		uint64_t src:16;
+		uint64_t dst:16;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_pip_tag_secret_s cn30xx;
 	struct cvmx_pip_tag_secret_s cn31xx;
@@ -1242,14 +3164,27 @@
 	struct cvmx_pip_tag_secret_s cn56xxp1;
 	struct cvmx_pip_tag_secret_s cn58xx;
 	struct cvmx_pip_tag_secret_s cn58xxp1;
+	struct cvmx_pip_tag_secret_s cn61xx;
+	struct cvmx_pip_tag_secret_s cn63xx;
+	struct cvmx_pip_tag_secret_s cn63xxp1;
+	struct cvmx_pip_tag_secret_s cn66xx;
+	struct cvmx_pip_tag_secret_s cn68xx;
+	struct cvmx_pip_tag_secret_s cn68xxp1;
+	struct cvmx_pip_tag_secret_s cnf71xx;
 };
 
 union cvmx_pip_todo_entry {
 	uint64_t u64;
 	struct cvmx_pip_todo_entry_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t val:1;
 		uint64_t reserved_62_62:1;
 		uint64_t entry:62;
+#else
+		uint64_t entry:62;
+		uint64_t reserved_62_62:1;
+		uint64_t val:1;
+#endif
 	} s;
 	struct cvmx_pip_todo_entry_s cn30xx;
 	struct cvmx_pip_todo_entry_s cn31xx;
@@ -1262,6 +3197,226 @@
 	struct cvmx_pip_todo_entry_s cn56xxp1;
 	struct cvmx_pip_todo_entry_s cn58xx;
 	struct cvmx_pip_todo_entry_s cn58xxp1;
+	struct cvmx_pip_todo_entry_s cn61xx;
+	struct cvmx_pip_todo_entry_s cn63xx;
+	struct cvmx_pip_todo_entry_s cn63xxp1;
+	struct cvmx_pip_todo_entry_s cn66xx;
+	struct cvmx_pip_todo_entry_s cn68xx;
+	struct cvmx_pip_todo_entry_s cn68xxp1;
+	struct cvmx_pip_todo_entry_s cnf71xx;
+};
+
+union cvmx_pip_vlan_etypesx {
+	uint64_t u64;
+	struct cvmx_pip_vlan_etypesx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t type3:16;
+		uint64_t type2:16;
+		uint64_t type1:16;
+		uint64_t type0:16;
+#else
+		uint64_t type0:16;
+		uint64_t type1:16;
+		uint64_t type2:16;
+		uint64_t type3:16;
+#endif
+	} s;
+	struct cvmx_pip_vlan_etypesx_s cn61xx;
+	struct cvmx_pip_vlan_etypesx_s cn66xx;
+	struct cvmx_pip_vlan_etypesx_s cn68xx;
+	struct cvmx_pip_vlan_etypesx_s cnf71xx;
+};
+
+union cvmx_pip_xstat0_prtx {
+	uint64_t u64;
+	struct cvmx_pip_xstat0_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t drp_pkts:32;
+		uint64_t drp_octs:32;
+#else
+		uint64_t drp_octs:32;
+		uint64_t drp_pkts:32;
+#endif
+	} s;
+	struct cvmx_pip_xstat0_prtx_s cn63xx;
+	struct cvmx_pip_xstat0_prtx_s cn63xxp1;
+	struct cvmx_pip_xstat0_prtx_s cn66xx;
+};
+
+union cvmx_pip_xstat10_prtx {
+	uint64_t u64;
+	struct cvmx_pip_xstat10_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bcast:32;
+		uint64_t mcast:32;
+#else
+		uint64_t mcast:32;
+		uint64_t bcast:32;
+#endif
+	} s;
+	struct cvmx_pip_xstat10_prtx_s cn63xx;
+	struct cvmx_pip_xstat10_prtx_s cn63xxp1;
+	struct cvmx_pip_xstat10_prtx_s cn66xx;
+};
+
+union cvmx_pip_xstat11_prtx {
+	uint64_t u64;
+	struct cvmx_pip_xstat11_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bcast:32;
+		uint64_t mcast:32;
+#else
+		uint64_t mcast:32;
+		uint64_t bcast:32;
+#endif
+	} s;
+	struct cvmx_pip_xstat11_prtx_s cn63xx;
+	struct cvmx_pip_xstat11_prtx_s cn63xxp1;
+	struct cvmx_pip_xstat11_prtx_s cn66xx;
+};
+
+union cvmx_pip_xstat1_prtx {
+	uint64_t u64;
+	struct cvmx_pip_xstat1_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_48_63:16;
+		uint64_t octs:48;
+#else
+		uint64_t octs:48;
+		uint64_t reserved_48_63:16;
+#endif
+	} s;
+	struct cvmx_pip_xstat1_prtx_s cn63xx;
+	struct cvmx_pip_xstat1_prtx_s cn63xxp1;
+	struct cvmx_pip_xstat1_prtx_s cn66xx;
+};
+
+union cvmx_pip_xstat2_prtx {
+	uint64_t u64;
+	struct cvmx_pip_xstat2_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t pkts:32;
+		uint64_t raw:32;
+#else
+		uint64_t raw:32;
+		uint64_t pkts:32;
+#endif
+	} s;
+	struct cvmx_pip_xstat2_prtx_s cn63xx;
+	struct cvmx_pip_xstat2_prtx_s cn63xxp1;
+	struct cvmx_pip_xstat2_prtx_s cn66xx;
+};
+
+union cvmx_pip_xstat3_prtx {
+	uint64_t u64;
+	struct cvmx_pip_xstat3_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t bcst:32;
+		uint64_t mcst:32;
+#else
+		uint64_t mcst:32;
+		uint64_t bcst:32;
+#endif
+	} s;
+	struct cvmx_pip_xstat3_prtx_s cn63xx;
+	struct cvmx_pip_xstat3_prtx_s cn63xxp1;
+	struct cvmx_pip_xstat3_prtx_s cn66xx;
+};
+
+union cvmx_pip_xstat4_prtx {
+	uint64_t u64;
+	struct cvmx_pip_xstat4_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t h65to127:32;
+		uint64_t h64:32;
+#else
+		uint64_t h64:32;
+		uint64_t h65to127:32;
+#endif
+	} s;
+	struct cvmx_pip_xstat4_prtx_s cn63xx;
+	struct cvmx_pip_xstat4_prtx_s cn63xxp1;
+	struct cvmx_pip_xstat4_prtx_s cn66xx;
+};
+
+union cvmx_pip_xstat5_prtx {
+	uint64_t u64;
+	struct cvmx_pip_xstat5_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t h256to511:32;
+		uint64_t h128to255:32;
+#else
+		uint64_t h128to255:32;
+		uint64_t h256to511:32;
+#endif
+	} s;
+	struct cvmx_pip_xstat5_prtx_s cn63xx;
+	struct cvmx_pip_xstat5_prtx_s cn63xxp1;
+	struct cvmx_pip_xstat5_prtx_s cn66xx;
+};
+
+union cvmx_pip_xstat6_prtx {
+	uint64_t u64;
+	struct cvmx_pip_xstat6_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t h1024to1518:32;
+		uint64_t h512to1023:32;
+#else
+		uint64_t h512to1023:32;
+		uint64_t h1024to1518:32;
+#endif
+	} s;
+	struct cvmx_pip_xstat6_prtx_s cn63xx;
+	struct cvmx_pip_xstat6_prtx_s cn63xxp1;
+	struct cvmx_pip_xstat6_prtx_s cn66xx;
+};
+
+union cvmx_pip_xstat7_prtx {
+	uint64_t u64;
+	struct cvmx_pip_xstat7_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t fcs:32;
+		uint64_t h1519:32;
+#else
+		uint64_t h1519:32;
+		uint64_t fcs:32;
+#endif
+	} s;
+	struct cvmx_pip_xstat7_prtx_s cn63xx;
+	struct cvmx_pip_xstat7_prtx_s cn63xxp1;
+	struct cvmx_pip_xstat7_prtx_s cn66xx;
+};
+
+union cvmx_pip_xstat8_prtx {
+	uint64_t u64;
+	struct cvmx_pip_xstat8_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t frag:32;
+		uint64_t undersz:32;
+#else
+		uint64_t undersz:32;
+		uint64_t frag:32;
+#endif
+	} s;
+	struct cvmx_pip_xstat8_prtx_s cn63xx;
+	struct cvmx_pip_xstat8_prtx_s cn63xxp1;
+	struct cvmx_pip_xstat8_prtx_s cn66xx;
+};
+
+union cvmx_pip_xstat9_prtx {
+	uint64_t u64;
+	struct cvmx_pip_xstat9_prtx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t jabber:32;
+		uint64_t oversz:32;
+#else
+		uint64_t oversz:32;
+		uint64_t jabber:32;
+#endif
+	} s;
+	struct cvmx_pip_xstat9_prtx_s cn63xx;
+	struct cvmx_pip_xstat9_prtx_s cn63xxp1;
+	struct cvmx_pip_xstat9_prtx_s cn66xx;
 };
 
 #endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pko-defs.h b/arch/mips/include/asm/octeon/cvmx-pko-defs.h
index 50e779c..87c3b97 100644
--- a/arch/mips/include/asm/octeon/cvmx-pko-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pko-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -28,94 +28,74 @@
 #ifndef __CVMX_PKO_DEFS_H__
 #define __CVMX_PKO_DEFS_H__
 
-#define CVMX_PKO_MEM_COUNT0 \
-	 CVMX_ADD_IO_SEG(0x0001180050001080ull)
-#define CVMX_PKO_MEM_COUNT1 \
-	 CVMX_ADD_IO_SEG(0x0001180050001088ull)
-#define CVMX_PKO_MEM_DEBUG0 \
-	 CVMX_ADD_IO_SEG(0x0001180050001100ull)
-#define CVMX_PKO_MEM_DEBUG1 \
-	 CVMX_ADD_IO_SEG(0x0001180050001108ull)
-#define CVMX_PKO_MEM_DEBUG10 \
-	 CVMX_ADD_IO_SEG(0x0001180050001150ull)
-#define CVMX_PKO_MEM_DEBUG11 \
-	 CVMX_ADD_IO_SEG(0x0001180050001158ull)
-#define CVMX_PKO_MEM_DEBUG12 \
-	 CVMX_ADD_IO_SEG(0x0001180050001160ull)
-#define CVMX_PKO_MEM_DEBUG13 \
-	 CVMX_ADD_IO_SEG(0x0001180050001168ull)
-#define CVMX_PKO_MEM_DEBUG14 \
-	 CVMX_ADD_IO_SEG(0x0001180050001170ull)
-#define CVMX_PKO_MEM_DEBUG2 \
-	 CVMX_ADD_IO_SEG(0x0001180050001110ull)
-#define CVMX_PKO_MEM_DEBUG3 \
-	 CVMX_ADD_IO_SEG(0x0001180050001118ull)
-#define CVMX_PKO_MEM_DEBUG4 \
-	 CVMX_ADD_IO_SEG(0x0001180050001120ull)
-#define CVMX_PKO_MEM_DEBUG5 \
-	 CVMX_ADD_IO_SEG(0x0001180050001128ull)
-#define CVMX_PKO_MEM_DEBUG6 \
-	 CVMX_ADD_IO_SEG(0x0001180050001130ull)
-#define CVMX_PKO_MEM_DEBUG7 \
-	 CVMX_ADD_IO_SEG(0x0001180050001138ull)
-#define CVMX_PKO_MEM_DEBUG8 \
-	 CVMX_ADD_IO_SEG(0x0001180050001140ull)
-#define CVMX_PKO_MEM_DEBUG9 \
-	 CVMX_ADD_IO_SEG(0x0001180050001148ull)
-#define CVMX_PKO_MEM_PORT_PTRS \
-	 CVMX_ADD_IO_SEG(0x0001180050001010ull)
-#define CVMX_PKO_MEM_PORT_QOS \
-	 CVMX_ADD_IO_SEG(0x0001180050001018ull)
-#define CVMX_PKO_MEM_PORT_RATE0 \
-	 CVMX_ADD_IO_SEG(0x0001180050001020ull)
-#define CVMX_PKO_MEM_PORT_RATE1 \
-	 CVMX_ADD_IO_SEG(0x0001180050001028ull)
-#define CVMX_PKO_MEM_QUEUE_PTRS \
-	 CVMX_ADD_IO_SEG(0x0001180050001000ull)
-#define CVMX_PKO_MEM_QUEUE_QOS \
-	 CVMX_ADD_IO_SEG(0x0001180050001008ull)
-#define CVMX_PKO_REG_BIST_RESULT \
-	 CVMX_ADD_IO_SEG(0x0001180050000080ull)
-#define CVMX_PKO_REG_CMD_BUF \
-	 CVMX_ADD_IO_SEG(0x0001180050000010ull)
-#define CVMX_PKO_REG_CRC_CTLX(offset) \
-	 CVMX_ADD_IO_SEG(0x0001180050000028ull + (((offset) & 1) * 8))
-#define CVMX_PKO_REG_CRC_ENABLE \
-	 CVMX_ADD_IO_SEG(0x0001180050000020ull)
-#define CVMX_PKO_REG_CRC_IVX(offset) \
-	 CVMX_ADD_IO_SEG(0x0001180050000038ull + (((offset) & 1) * 8))
-#define CVMX_PKO_REG_DEBUG0 \
-	 CVMX_ADD_IO_SEG(0x0001180050000098ull)
-#define CVMX_PKO_REG_DEBUG1 \
-	 CVMX_ADD_IO_SEG(0x00011800500000A0ull)
-#define CVMX_PKO_REG_DEBUG2 \
-	 CVMX_ADD_IO_SEG(0x00011800500000A8ull)
-#define CVMX_PKO_REG_DEBUG3 \
-	 CVMX_ADD_IO_SEG(0x00011800500000B0ull)
-#define CVMX_PKO_REG_ENGINE_INFLIGHT \
-	 CVMX_ADD_IO_SEG(0x0001180050000050ull)
-#define CVMX_PKO_REG_ENGINE_THRESH \
-	 CVMX_ADD_IO_SEG(0x0001180050000058ull)
-#define CVMX_PKO_REG_ERROR \
-	 CVMX_ADD_IO_SEG(0x0001180050000088ull)
-#define CVMX_PKO_REG_FLAGS \
-	 CVMX_ADD_IO_SEG(0x0001180050000000ull)
-#define CVMX_PKO_REG_GMX_PORT_MODE \
-	 CVMX_ADD_IO_SEG(0x0001180050000018ull)
-#define CVMX_PKO_REG_INT_MASK \
-	 CVMX_ADD_IO_SEG(0x0001180050000090ull)
-#define CVMX_PKO_REG_QUEUE_MODE \
-	 CVMX_ADD_IO_SEG(0x0001180050000048ull)
-#define CVMX_PKO_REG_QUEUE_PTRS1 \
-	 CVMX_ADD_IO_SEG(0x0001180050000100ull)
-#define CVMX_PKO_REG_READ_IDX \
-	 CVMX_ADD_IO_SEG(0x0001180050000008ull)
+#define CVMX_PKO_MEM_COUNT0 (CVMX_ADD_IO_SEG(0x0001180050001080ull))
+#define CVMX_PKO_MEM_COUNT1 (CVMX_ADD_IO_SEG(0x0001180050001088ull))
+#define CVMX_PKO_MEM_DEBUG0 (CVMX_ADD_IO_SEG(0x0001180050001100ull))
+#define CVMX_PKO_MEM_DEBUG1 (CVMX_ADD_IO_SEG(0x0001180050001108ull))
+#define CVMX_PKO_MEM_DEBUG10 (CVMX_ADD_IO_SEG(0x0001180050001150ull))
+#define CVMX_PKO_MEM_DEBUG11 (CVMX_ADD_IO_SEG(0x0001180050001158ull))
+#define CVMX_PKO_MEM_DEBUG12 (CVMX_ADD_IO_SEG(0x0001180050001160ull))
+#define CVMX_PKO_MEM_DEBUG13 (CVMX_ADD_IO_SEG(0x0001180050001168ull))
+#define CVMX_PKO_MEM_DEBUG14 (CVMX_ADD_IO_SEG(0x0001180050001170ull))
+#define CVMX_PKO_MEM_DEBUG2 (CVMX_ADD_IO_SEG(0x0001180050001110ull))
+#define CVMX_PKO_MEM_DEBUG3 (CVMX_ADD_IO_SEG(0x0001180050001118ull))
+#define CVMX_PKO_MEM_DEBUG4 (CVMX_ADD_IO_SEG(0x0001180050001120ull))
+#define CVMX_PKO_MEM_DEBUG5 (CVMX_ADD_IO_SEG(0x0001180050001128ull))
+#define CVMX_PKO_MEM_DEBUG6 (CVMX_ADD_IO_SEG(0x0001180050001130ull))
+#define CVMX_PKO_MEM_DEBUG7 (CVMX_ADD_IO_SEG(0x0001180050001138ull))
+#define CVMX_PKO_MEM_DEBUG8 (CVMX_ADD_IO_SEG(0x0001180050001140ull))
+#define CVMX_PKO_MEM_DEBUG9 (CVMX_ADD_IO_SEG(0x0001180050001148ull))
+#define CVMX_PKO_MEM_IPORT_PTRS (CVMX_ADD_IO_SEG(0x0001180050001030ull))
+#define CVMX_PKO_MEM_IPORT_QOS (CVMX_ADD_IO_SEG(0x0001180050001038ull))
+#define CVMX_PKO_MEM_IQUEUE_PTRS (CVMX_ADD_IO_SEG(0x0001180050001040ull))
+#define CVMX_PKO_MEM_IQUEUE_QOS (CVMX_ADD_IO_SEG(0x0001180050001048ull))
+#define CVMX_PKO_MEM_PORT_PTRS (CVMX_ADD_IO_SEG(0x0001180050001010ull))
+#define CVMX_PKO_MEM_PORT_QOS (CVMX_ADD_IO_SEG(0x0001180050001018ull))
+#define CVMX_PKO_MEM_PORT_RATE0 (CVMX_ADD_IO_SEG(0x0001180050001020ull))
+#define CVMX_PKO_MEM_PORT_RATE1 (CVMX_ADD_IO_SEG(0x0001180050001028ull))
+#define CVMX_PKO_MEM_QUEUE_PTRS (CVMX_ADD_IO_SEG(0x0001180050001000ull))
+#define CVMX_PKO_MEM_QUEUE_QOS (CVMX_ADD_IO_SEG(0x0001180050001008ull))
+#define CVMX_PKO_MEM_THROTTLE_INT (CVMX_ADD_IO_SEG(0x0001180050001058ull))
+#define CVMX_PKO_MEM_THROTTLE_PIPE (CVMX_ADD_IO_SEG(0x0001180050001050ull))
+#define CVMX_PKO_REG_BIST_RESULT (CVMX_ADD_IO_SEG(0x0001180050000080ull))
+#define CVMX_PKO_REG_CMD_BUF (CVMX_ADD_IO_SEG(0x0001180050000010ull))
+#define CVMX_PKO_REG_CRC_CTLX(offset) (CVMX_ADD_IO_SEG(0x0001180050000028ull) + ((offset) & 1) * 8)
+#define CVMX_PKO_REG_CRC_ENABLE (CVMX_ADD_IO_SEG(0x0001180050000020ull))
+#define CVMX_PKO_REG_CRC_IVX(offset) (CVMX_ADD_IO_SEG(0x0001180050000038ull) + ((offset) & 1) * 8)
+#define CVMX_PKO_REG_DEBUG0 (CVMX_ADD_IO_SEG(0x0001180050000098ull))
+#define CVMX_PKO_REG_DEBUG1 (CVMX_ADD_IO_SEG(0x00011800500000A0ull))
+#define CVMX_PKO_REG_DEBUG2 (CVMX_ADD_IO_SEG(0x00011800500000A8ull))
+#define CVMX_PKO_REG_DEBUG3 (CVMX_ADD_IO_SEG(0x00011800500000B0ull))
+#define CVMX_PKO_REG_DEBUG4 (CVMX_ADD_IO_SEG(0x00011800500000B8ull))
+#define CVMX_PKO_REG_ENGINE_INFLIGHT (CVMX_ADD_IO_SEG(0x0001180050000050ull))
+#define CVMX_PKO_REG_ENGINE_INFLIGHT1 (CVMX_ADD_IO_SEG(0x0001180050000318ull))
+#define CVMX_PKO_REG_ENGINE_STORAGEX(offset) (CVMX_ADD_IO_SEG(0x0001180050000300ull) + ((offset) & 1) * 8)
+#define CVMX_PKO_REG_ENGINE_THRESH (CVMX_ADD_IO_SEG(0x0001180050000058ull))
+#define CVMX_PKO_REG_ERROR (CVMX_ADD_IO_SEG(0x0001180050000088ull))
+#define CVMX_PKO_REG_FLAGS (CVMX_ADD_IO_SEG(0x0001180050000000ull))
+#define CVMX_PKO_REG_GMX_PORT_MODE (CVMX_ADD_IO_SEG(0x0001180050000018ull))
+#define CVMX_PKO_REG_INT_MASK (CVMX_ADD_IO_SEG(0x0001180050000090ull))
+#define CVMX_PKO_REG_LOOPBACK_BPID (CVMX_ADD_IO_SEG(0x0001180050000118ull))
+#define CVMX_PKO_REG_LOOPBACK_PKIND (CVMX_ADD_IO_SEG(0x0001180050000068ull))
+#define CVMX_PKO_REG_MIN_PKT (CVMX_ADD_IO_SEG(0x0001180050000070ull))
+#define CVMX_PKO_REG_PREEMPT (CVMX_ADD_IO_SEG(0x0001180050000110ull))
+#define CVMX_PKO_REG_QUEUE_MODE (CVMX_ADD_IO_SEG(0x0001180050000048ull))
+#define CVMX_PKO_REG_QUEUE_PREEMPT (CVMX_ADD_IO_SEG(0x0001180050000108ull))
+#define CVMX_PKO_REG_QUEUE_PTRS1 (CVMX_ADD_IO_SEG(0x0001180050000100ull))
+#define CVMX_PKO_REG_READ_IDX (CVMX_ADD_IO_SEG(0x0001180050000008ull))
+#define CVMX_PKO_REG_THROTTLE (CVMX_ADD_IO_SEG(0x0001180050000078ull))
+#define CVMX_PKO_REG_TIMESTAMP (CVMX_ADD_IO_SEG(0x0001180050000060ull))
 
 union cvmx_pko_mem_count0 {
 	uint64_t u64;
 	struct cvmx_pko_mem_count0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t count:32;
+#else
+		uint64_t count:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_pko_mem_count0_s cn30xx;
 	struct cvmx_pko_mem_count0_s cn31xx;
@@ -128,13 +108,25 @@
 	struct cvmx_pko_mem_count0_s cn56xxp1;
 	struct cvmx_pko_mem_count0_s cn58xx;
 	struct cvmx_pko_mem_count0_s cn58xxp1;
+	struct cvmx_pko_mem_count0_s cn61xx;
+	struct cvmx_pko_mem_count0_s cn63xx;
+	struct cvmx_pko_mem_count0_s cn63xxp1;
+	struct cvmx_pko_mem_count0_s cn66xx;
+	struct cvmx_pko_mem_count0_s cn68xx;
+	struct cvmx_pko_mem_count0_s cn68xxp1;
+	struct cvmx_pko_mem_count0_s cnf71xx;
 };
 
 union cvmx_pko_mem_count1 {
 	uint64_t u64;
 	struct cvmx_pko_mem_count1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t count:48;
+#else
+		uint64_t count:48;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_pko_mem_count1_s cn30xx;
 	struct cvmx_pko_mem_count1_s cn31xx;
@@ -147,15 +139,29 @@
 	struct cvmx_pko_mem_count1_s cn56xxp1;
 	struct cvmx_pko_mem_count1_s cn58xx;
 	struct cvmx_pko_mem_count1_s cn58xxp1;
+	struct cvmx_pko_mem_count1_s cn61xx;
+	struct cvmx_pko_mem_count1_s cn63xx;
+	struct cvmx_pko_mem_count1_s cn63xxp1;
+	struct cvmx_pko_mem_count1_s cn66xx;
+	struct cvmx_pko_mem_count1_s cn68xx;
+	struct cvmx_pko_mem_count1_s cn68xxp1;
+	struct cvmx_pko_mem_count1_s cnf71xx;
 };
 
 union cvmx_pko_mem_debug0 {
 	uint64_t u64;
 	struct cvmx_pko_mem_debug0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t fau:28;
 		uint64_t cmd:14;
 		uint64_t segs:6;
 		uint64_t size:16;
+#else
+		uint64_t size:16;
+		uint64_t segs:6;
+		uint64_t cmd:14;
+		uint64_t fau:28;
+#endif
 	} s;
 	struct cvmx_pko_mem_debug0_s cn30xx;
 	struct cvmx_pko_mem_debug0_s cn31xx;
@@ -168,16 +174,31 @@
 	struct cvmx_pko_mem_debug0_s cn56xxp1;
 	struct cvmx_pko_mem_debug0_s cn58xx;
 	struct cvmx_pko_mem_debug0_s cn58xxp1;
+	struct cvmx_pko_mem_debug0_s cn61xx;
+	struct cvmx_pko_mem_debug0_s cn63xx;
+	struct cvmx_pko_mem_debug0_s cn63xxp1;
+	struct cvmx_pko_mem_debug0_s cn66xx;
+	struct cvmx_pko_mem_debug0_s cn68xx;
+	struct cvmx_pko_mem_debug0_s cn68xxp1;
+	struct cvmx_pko_mem_debug0_s cnf71xx;
 };
 
 union cvmx_pko_mem_debug1 {
 	uint64_t u64;
 	struct cvmx_pko_mem_debug1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t i:1;
 		uint64_t back:4;
 		uint64_t pool:3;
 		uint64_t size:16;
 		uint64_t ptr:40;
+#else
+		uint64_t ptr:40;
+		uint64_t size:16;
+		uint64_t pool:3;
+		uint64_t back:4;
+		uint64_t i:1;
+#endif
 	} s;
 	struct cvmx_pko_mem_debug1_s cn30xx;
 	struct cvmx_pko_mem_debug1_s cn31xx;
@@ -190,27 +211,52 @@
 	struct cvmx_pko_mem_debug1_s cn56xxp1;
 	struct cvmx_pko_mem_debug1_s cn58xx;
 	struct cvmx_pko_mem_debug1_s cn58xxp1;
+	struct cvmx_pko_mem_debug1_s cn61xx;
+	struct cvmx_pko_mem_debug1_s cn63xx;
+	struct cvmx_pko_mem_debug1_s cn63xxp1;
+	struct cvmx_pko_mem_debug1_s cn66xx;
+	struct cvmx_pko_mem_debug1_s cn68xx;
+	struct cvmx_pko_mem_debug1_s cn68xxp1;
+	struct cvmx_pko_mem_debug1_s cnf71xx;
 };
 
 union cvmx_pko_mem_debug10 {
 	uint64_t u64;
 	struct cvmx_pko_mem_debug10_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_0_63:64;
+#else
+		uint64_t reserved_0_63:64;
+#endif
 	} s;
 	struct cvmx_pko_mem_debug10_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t fau:28;
 		uint64_t cmd:14;
 		uint64_t segs:6;
 		uint64_t size:16;
+#else
+		uint64_t size:16;
+		uint64_t segs:6;
+		uint64_t cmd:14;
+		uint64_t fau:28;
+#endif
 	} cn30xx;
 	struct cvmx_pko_mem_debug10_cn30xx cn31xx;
 	struct cvmx_pko_mem_debug10_cn30xx cn38xx;
 	struct cvmx_pko_mem_debug10_cn30xx cn38xxp2;
 	struct cvmx_pko_mem_debug10_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_49_63:15;
 		uint64_t ptrs1:17;
 		uint64_t reserved_17_31:15;
 		uint64_t ptrs2:17;
+#else
+		uint64_t ptrs2:17;
+		uint64_t reserved_17_31:15;
+		uint64_t ptrs1:17;
+		uint64_t reserved_49_63:15;
+#endif
 	} cn50xx;
 	struct cvmx_pko_mem_debug10_cn50xx cn52xx;
 	struct cvmx_pko_mem_debug10_cn50xx cn52xxp1;
@@ -218,28 +264,52 @@
 	struct cvmx_pko_mem_debug10_cn50xx cn56xxp1;
 	struct cvmx_pko_mem_debug10_cn50xx cn58xx;
 	struct cvmx_pko_mem_debug10_cn50xx cn58xxp1;
+	struct cvmx_pko_mem_debug10_cn50xx cn61xx;
+	struct cvmx_pko_mem_debug10_cn50xx cn63xx;
+	struct cvmx_pko_mem_debug10_cn50xx cn63xxp1;
+	struct cvmx_pko_mem_debug10_cn50xx cn66xx;
+	struct cvmx_pko_mem_debug10_cn50xx cn68xx;
+	struct cvmx_pko_mem_debug10_cn50xx cn68xxp1;
+	struct cvmx_pko_mem_debug10_cn50xx cnf71xx;
 };
 
 union cvmx_pko_mem_debug11 {
 	uint64_t u64;
 	struct cvmx_pko_mem_debug11_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t i:1;
 		uint64_t back:4;
 		uint64_t pool:3;
 		uint64_t size:16;
 		uint64_t reserved_0_39:40;
+#else
+		uint64_t reserved_0_39:40;
+		uint64_t size:16;
+		uint64_t pool:3;
+		uint64_t back:4;
+		uint64_t i:1;
+#endif
 	} s;
 	struct cvmx_pko_mem_debug11_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t i:1;
 		uint64_t back:4;
 		uint64_t pool:3;
 		uint64_t size:16;
 		uint64_t ptr:40;
+#else
+		uint64_t ptr:40;
+		uint64_t size:16;
+		uint64_t pool:3;
+		uint64_t back:4;
+		uint64_t i:1;
+#endif
 	} cn30xx;
 	struct cvmx_pko_mem_debug11_cn30xx cn31xx;
 	struct cvmx_pko_mem_debug11_cn30xx cn38xx;
 	struct cvmx_pko_mem_debug11_cn30xx cn38xxp2;
 	struct cvmx_pko_mem_debug11_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_23_63:41;
 		uint64_t maj:1;
 		uint64_t uid:3;
@@ -248,6 +318,16 @@
 		uint64_t chk:1;
 		uint64_t cnt:13;
 		uint64_t mod:3;
+#else
+		uint64_t mod:3;
+		uint64_t cnt:13;
+		uint64_t chk:1;
+		uint64_t len:1;
+		uint64_t sop:1;
+		uint64_t uid:3;
+		uint64_t maj:1;
+		uint64_t reserved_23_63:41;
+#endif
 	} cn50xx;
 	struct cvmx_pko_mem_debug11_cn50xx cn52xx;
 	struct cvmx_pko_mem_debug11_cn50xx cn52xxp1;
@@ -255,24 +335,46 @@
 	struct cvmx_pko_mem_debug11_cn50xx cn56xxp1;
 	struct cvmx_pko_mem_debug11_cn50xx cn58xx;
 	struct cvmx_pko_mem_debug11_cn50xx cn58xxp1;
+	struct cvmx_pko_mem_debug11_cn50xx cn61xx;
+	struct cvmx_pko_mem_debug11_cn50xx cn63xx;
+	struct cvmx_pko_mem_debug11_cn50xx cn63xxp1;
+	struct cvmx_pko_mem_debug11_cn50xx cn66xx;
+	struct cvmx_pko_mem_debug11_cn50xx cn68xx;
+	struct cvmx_pko_mem_debug11_cn50xx cn68xxp1;
+	struct cvmx_pko_mem_debug11_cn50xx cnf71xx;
 };
 
 union cvmx_pko_mem_debug12 {
 	uint64_t u64;
 	struct cvmx_pko_mem_debug12_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_0_63:64;
+#else
+		uint64_t reserved_0_63:64;
+#endif
 	} s;
 	struct cvmx_pko_mem_debug12_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t data:64;
+#else
+		uint64_t data:64;
+#endif
 	} cn30xx;
 	struct cvmx_pko_mem_debug12_cn30xx cn31xx;
 	struct cvmx_pko_mem_debug12_cn30xx cn38xx;
 	struct cvmx_pko_mem_debug12_cn30xx cn38xxp2;
 	struct cvmx_pko_mem_debug12_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t fau:28;
 		uint64_t cmd:14;
 		uint64_t segs:6;
 		uint64_t size:16;
+#else
+		uint64_t size:16;
+		uint64_t segs:6;
+		uint64_t cmd:14;
+		uint64_t fau:28;
+#endif
 	} cn50xx;
 	struct cvmx_pko_mem_debug12_cn50xx cn52xx;
 	struct cvmx_pko_mem_debug12_cn50xx cn52xxp1;
@@ -280,31 +382,60 @@
 	struct cvmx_pko_mem_debug12_cn50xx cn56xxp1;
 	struct cvmx_pko_mem_debug12_cn50xx cn58xx;
 	struct cvmx_pko_mem_debug12_cn50xx cn58xxp1;
+	struct cvmx_pko_mem_debug12_cn50xx cn61xx;
+	struct cvmx_pko_mem_debug12_cn50xx cn63xx;
+	struct cvmx_pko_mem_debug12_cn50xx cn63xxp1;
+	struct cvmx_pko_mem_debug12_cn50xx cn66xx;
+	struct cvmx_pko_mem_debug12_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t state:64;
+#else
+		uint64_t state:64;
+#endif
+	} cn68xx;
+	struct cvmx_pko_mem_debug12_cn68xx cn68xxp1;
+	struct cvmx_pko_mem_debug12_cn50xx cnf71xx;
 };
 
 union cvmx_pko_mem_debug13 {
 	uint64_t u64;
 	struct cvmx_pko_mem_debug13_s {
-		uint64_t i:1;
-		uint64_t back:4;
-		uint64_t pool:3;
-		uint64_t reserved_0_55:56;
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_0_63:64;
+#else
+		uint64_t reserved_0_63:64;
+#endif
 	} s;
 	struct cvmx_pko_mem_debug13_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_51_63:13;
 		uint64_t widx:17;
 		uint64_t ridx2:17;
 		uint64_t widx2:17;
+#else
+		uint64_t widx2:17;
+		uint64_t ridx2:17;
+		uint64_t widx:17;
+		uint64_t reserved_51_63:13;
+#endif
 	} cn30xx;
 	struct cvmx_pko_mem_debug13_cn30xx cn31xx;
 	struct cvmx_pko_mem_debug13_cn30xx cn38xx;
 	struct cvmx_pko_mem_debug13_cn30xx cn38xxp2;
 	struct cvmx_pko_mem_debug13_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t i:1;
 		uint64_t back:4;
 		uint64_t pool:3;
 		uint64_t size:16;
 		uint64_t ptr:40;
+#else
+		uint64_t ptr:40;
+		uint64_t size:16;
+		uint64_t pool:3;
+		uint64_t back:4;
+		uint64_t i:1;
+#endif
 	} cn50xx;
 	struct cvmx_pko_mem_debug13_cn50xx cn52xx;
 	struct cvmx_pko_mem_debug13_cn50xx cn52xxp1;
@@ -312,36 +443,75 @@
 	struct cvmx_pko_mem_debug13_cn50xx cn56xxp1;
 	struct cvmx_pko_mem_debug13_cn50xx cn58xx;
 	struct cvmx_pko_mem_debug13_cn50xx cn58xxp1;
+	struct cvmx_pko_mem_debug13_cn50xx cn61xx;
+	struct cvmx_pko_mem_debug13_cn50xx cn63xx;
+	struct cvmx_pko_mem_debug13_cn50xx cn63xxp1;
+	struct cvmx_pko_mem_debug13_cn50xx cn66xx;
+	struct cvmx_pko_mem_debug13_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t state:64;
+#else
+		uint64_t state:64;
+#endif
+	} cn68xx;
+	struct cvmx_pko_mem_debug13_cn68xx cn68xxp1;
+	struct cvmx_pko_mem_debug13_cn50xx cnf71xx;
 };
 
 union cvmx_pko_mem_debug14 {
 	uint64_t u64;
 	struct cvmx_pko_mem_debug14_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_0_63:64;
+#else
+		uint64_t reserved_0_63:64;
+#endif
 	} s;
 	struct cvmx_pko_mem_debug14_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_17_63:47;
 		uint64_t ridx:17;
+#else
+		uint64_t ridx:17;
+		uint64_t reserved_17_63:47;
+#endif
 	} cn30xx;
 	struct cvmx_pko_mem_debug14_cn30xx cn31xx;
 	struct cvmx_pko_mem_debug14_cn30xx cn38xx;
 	struct cvmx_pko_mem_debug14_cn30xx cn38xxp2;
 	struct cvmx_pko_mem_debug14_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t data:64;
+#else
+		uint64_t data:64;
+#endif
 	} cn52xx;
 	struct cvmx_pko_mem_debug14_cn52xx cn52xxp1;
 	struct cvmx_pko_mem_debug14_cn52xx cn56xx;
 	struct cvmx_pko_mem_debug14_cn52xx cn56xxp1;
+	struct cvmx_pko_mem_debug14_cn52xx cn61xx;
+	struct cvmx_pko_mem_debug14_cn52xx cn63xx;
+	struct cvmx_pko_mem_debug14_cn52xx cn63xxp1;
+	struct cvmx_pko_mem_debug14_cn52xx cn66xx;
+	struct cvmx_pko_mem_debug14_cn52xx cnf71xx;
 };
 
 union cvmx_pko_mem_debug2 {
 	uint64_t u64;
 	struct cvmx_pko_mem_debug2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t i:1;
 		uint64_t back:4;
 		uint64_t pool:3;
 		uint64_t size:16;
 		uint64_t ptr:40;
+#else
+		uint64_t ptr:40;
+		uint64_t size:16;
+		uint64_t pool:3;
+		uint64_t back:4;
+		uint64_t i:1;
+#endif
 	} s;
 	struct cvmx_pko_mem_debug2_s cn30xx;
 	struct cvmx_pko_mem_debug2_s cn31xx;
@@ -354,25 +524,48 @@
 	struct cvmx_pko_mem_debug2_s cn56xxp1;
 	struct cvmx_pko_mem_debug2_s cn58xx;
 	struct cvmx_pko_mem_debug2_s cn58xxp1;
+	struct cvmx_pko_mem_debug2_s cn61xx;
+	struct cvmx_pko_mem_debug2_s cn63xx;
+	struct cvmx_pko_mem_debug2_s cn63xxp1;
+	struct cvmx_pko_mem_debug2_s cn66xx;
+	struct cvmx_pko_mem_debug2_s cn68xx;
+	struct cvmx_pko_mem_debug2_s cn68xxp1;
+	struct cvmx_pko_mem_debug2_s cnf71xx;
 };
 
 union cvmx_pko_mem_debug3 {
 	uint64_t u64;
 	struct cvmx_pko_mem_debug3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_0_63:64;
+#else
+		uint64_t reserved_0_63:64;
+#endif
 	} s;
 	struct cvmx_pko_mem_debug3_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t i:1;
 		uint64_t back:4;
 		uint64_t pool:3;
 		uint64_t size:16;
 		uint64_t ptr:40;
+#else
+		uint64_t ptr:40;
+		uint64_t size:16;
+		uint64_t pool:3;
+		uint64_t back:4;
+		uint64_t i:1;
+#endif
 	} cn30xx;
 	struct cvmx_pko_mem_debug3_cn30xx cn31xx;
 	struct cvmx_pko_mem_debug3_cn30xx cn38xx;
 	struct cvmx_pko_mem_debug3_cn30xx cn38xxp2;
 	struct cvmx_pko_mem_debug3_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t data:64;
+#else
+		uint64_t data:64;
+#endif
 	} cn50xx;
 	struct cvmx_pko_mem_debug3_cn50xx cn52xx;
 	struct cvmx_pko_mem_debug3_cn50xx cn52xxp1;
@@ -380,20 +573,36 @@
 	struct cvmx_pko_mem_debug3_cn50xx cn56xxp1;
 	struct cvmx_pko_mem_debug3_cn50xx cn58xx;
 	struct cvmx_pko_mem_debug3_cn50xx cn58xxp1;
+	struct cvmx_pko_mem_debug3_cn50xx cn61xx;
+	struct cvmx_pko_mem_debug3_cn50xx cn63xx;
+	struct cvmx_pko_mem_debug3_cn50xx cn63xxp1;
+	struct cvmx_pko_mem_debug3_cn50xx cn66xx;
+	struct cvmx_pko_mem_debug3_cn50xx cn68xx;
+	struct cvmx_pko_mem_debug3_cn50xx cn68xxp1;
+	struct cvmx_pko_mem_debug3_cn50xx cnf71xx;
 };
 
 union cvmx_pko_mem_debug4 {
 	uint64_t u64;
 	struct cvmx_pko_mem_debug4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_0_63:64;
+#else
+		uint64_t reserved_0_63:64;
+#endif
 	} s;
 	struct cvmx_pko_mem_debug4_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t data:64;
+#else
+		uint64_t data:64;
+#endif
 	} cn30xx;
 	struct cvmx_pko_mem_debug4_cn30xx cn31xx;
 	struct cvmx_pko_mem_debug4_cn30xx cn38xx;
 	struct cvmx_pko_mem_debug4_cn30xx cn38xxp2;
 	struct cvmx_pko_mem_debug4_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t cmnd_segs:3;
 		uint64_t cmnd_siz:16;
 		uint64_t cmnd_off:6;
@@ -412,8 +621,29 @@
 		uint64_t wait:1;
 		uint64_t minor:2;
 		uint64_t major:3;
+#else
+		uint64_t major:3;
+		uint64_t minor:2;
+		uint64_t wait:1;
+		uint64_t qid_base:8;
+		uint64_t qid_off:4;
+		uint64_t qid_off_max:4;
+		uint64_t qcb_ridx:5;
+		uint64_t qos:3;
+		uint64_t static_p:1;
+		uint64_t active:1;
+		uint64_t chk_mode:1;
+		uint64_t chk_once:1;
+		uint64_t init_dwrite:1;
+		uint64_t dread_sop:1;
+		uint64_t uid:3;
+		uint64_t cmnd_off:6;
+		uint64_t cmnd_siz:16;
+		uint64_t cmnd_segs:3;
+#endif
 	} cn50xx;
 	struct cvmx_pko_mem_debug4_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t curr_siz:8;
 		uint64_t curr_off:16;
 		uint64_t cmnd_segs:6;
@@ -427,20 +657,47 @@
 		uint64_t wait:1;
 		uint64_t minor:2;
 		uint64_t major:3;
+#else
+		uint64_t major:3;
+		uint64_t minor:2;
+		uint64_t wait:1;
+		uint64_t chk_mode:1;
+		uint64_t chk_once:1;
+		uint64_t init_dwrite:1;
+		uint64_t dread_sop:1;
+		uint64_t uid:2;
+		uint64_t cmnd_off:6;
+		uint64_t cmnd_siz:16;
+		uint64_t cmnd_segs:6;
+		uint64_t curr_off:16;
+		uint64_t curr_siz:8;
+#endif
 	} cn52xx;
 	struct cvmx_pko_mem_debug4_cn52xx cn52xxp1;
 	struct cvmx_pko_mem_debug4_cn52xx cn56xx;
 	struct cvmx_pko_mem_debug4_cn52xx cn56xxp1;
 	struct cvmx_pko_mem_debug4_cn50xx cn58xx;
 	struct cvmx_pko_mem_debug4_cn50xx cn58xxp1;
+	struct cvmx_pko_mem_debug4_cn52xx cn61xx;
+	struct cvmx_pko_mem_debug4_cn52xx cn63xx;
+	struct cvmx_pko_mem_debug4_cn52xx cn63xxp1;
+	struct cvmx_pko_mem_debug4_cn52xx cn66xx;
+	struct cvmx_pko_mem_debug4_cn52xx cn68xx;
+	struct cvmx_pko_mem_debug4_cn52xx cn68xxp1;
+	struct cvmx_pko_mem_debug4_cn52xx cnf71xx;
 };
 
 union cvmx_pko_mem_debug5 {
 	uint64_t u64;
 	struct cvmx_pko_mem_debug5_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_0_63:64;
+#else
+		uint64_t reserved_0_63:64;
+#endif
 	} s;
 	struct cvmx_pko_mem_debug5_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t dwri_mod:1;
 		uint64_t dwri_sop:1;
 		uint64_t dwri_len:1;
@@ -460,32 +717,109 @@
 		uint64_t wait:1;
 		uint64_t minor:2;
 		uint64_t major:4;
+#else
+		uint64_t major:4;
+		uint64_t minor:2;
+		uint64_t wait:1;
+		uint64_t qid_base:7;
+		uint64_t qid_off:3;
+		uint64_t qcb_ridx:5;
+		uint64_t qos:3;
+		uint64_t active:1;
+		uint64_t chk_mode:1;
+		uint64_t reserved_27_27:1;
+		uint64_t cbuf_fre:1;
+		uint64_t xfer_dwr:1;
+		uint64_t xfer_wor:1;
+		uint64_t uid:1;
+		uint64_t cmnd_siz:16;
+		uint64_t dwri_cnt:13;
+		uint64_t dwri_len:1;
+		uint64_t dwri_sop:1;
+		uint64_t dwri_mod:1;
+#endif
 	} cn30xx;
 	struct cvmx_pko_mem_debug5_cn30xx cn31xx;
 	struct cvmx_pko_mem_debug5_cn30xx cn38xx;
 	struct cvmx_pko_mem_debug5_cn30xx cn38xxp2;
 	struct cvmx_pko_mem_debug5_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t curr_ptr:29;
 		uint64_t curr_siz:16;
 		uint64_t curr_off:16;
 		uint64_t cmnd_segs:3;
+#else
+		uint64_t cmnd_segs:3;
+		uint64_t curr_off:16;
+		uint64_t curr_siz:16;
+		uint64_t curr_ptr:29;
+#endif
 	} cn50xx;
 	struct cvmx_pko_mem_debug5_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_54_63:10;
 		uint64_t nxt_inflt:6;
 		uint64_t curr_ptr:40;
 		uint64_t curr_siz:8;
+#else
+		uint64_t curr_siz:8;
+		uint64_t curr_ptr:40;
+		uint64_t nxt_inflt:6;
+		uint64_t reserved_54_63:10;
+#endif
 	} cn52xx;
 	struct cvmx_pko_mem_debug5_cn52xx cn52xxp1;
 	struct cvmx_pko_mem_debug5_cn52xx cn56xx;
 	struct cvmx_pko_mem_debug5_cn52xx cn56xxp1;
 	struct cvmx_pko_mem_debug5_cn50xx cn58xx;
 	struct cvmx_pko_mem_debug5_cn50xx cn58xxp1;
+	struct cvmx_pko_mem_debug5_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t ptp:1;
+		uint64_t major_3:1;
+		uint64_t nxt_inflt:6;
+		uint64_t curr_ptr:40;
+		uint64_t curr_siz:8;
+#else
+		uint64_t curr_siz:8;
+		uint64_t curr_ptr:40;
+		uint64_t nxt_inflt:6;
+		uint64_t major_3:1;
+		uint64_t ptp:1;
+		uint64_t reserved_56_63:8;
+#endif
+	} cn61xx;
+	struct cvmx_pko_mem_debug5_cn61xx cn63xx;
+	struct cvmx_pko_mem_debug5_cn61xx cn63xxp1;
+	struct cvmx_pko_mem_debug5_cn61xx cn66xx;
+	struct cvmx_pko_mem_debug5_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_57_63:7;
+		uint64_t uid_2:1;
+		uint64_t ptp:1;
+		uint64_t major_3:1;
+		uint64_t nxt_inflt:6;
+		uint64_t curr_ptr:40;
+		uint64_t curr_siz:8;
+#else
+		uint64_t curr_siz:8;
+		uint64_t curr_ptr:40;
+		uint64_t nxt_inflt:6;
+		uint64_t major_3:1;
+		uint64_t ptp:1;
+		uint64_t uid_2:1;
+		uint64_t reserved_57_63:7;
+#endif
+	} cn68xx;
+	struct cvmx_pko_mem_debug5_cn68xx cn68xxp1;
+	struct cvmx_pko_mem_debug5_cn61xx cnf71xx;
 };
 
 union cvmx_pko_mem_debug6 {
 	uint64_t u64;
 	struct cvmx_pko_mem_debug6_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_37_63:27;
 		uint64_t qid_offres:4;
 		uint64_t qid_offths:4;
@@ -498,8 +832,23 @@
 		uint64_t qcb_ridx:5;
 		uint64_t qid_offmax:4;
 		uint64_t reserved_0_11:12;
+#else
+		uint64_t reserved_0_11:12;
+		uint64_t qid_offmax:4;
+		uint64_t qcb_ridx:5;
+		uint64_t qos:3;
+		uint64_t statc:1;
+		uint64_t active:1;
+		uint64_t preempted:1;
+		uint64_t preemptee:1;
+		uint64_t preempter:1;
+		uint64_t qid_offths:4;
+		uint64_t qid_offres:4;
+		uint64_t reserved_37_63:27;
+#endif
 	} s;
 	struct cvmx_pko_mem_debug6_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_11_63:53;
 		uint64_t qid_offm:3;
 		uint64_t static_p:1;
@@ -507,15 +856,30 @@
 		uint64_t dwri_chk:1;
 		uint64_t dwri_uid:1;
 		uint64_t dwri_mod:2;
+#else
+		uint64_t dwri_mod:2;
+		uint64_t dwri_uid:1;
+		uint64_t dwri_chk:1;
+		uint64_t work_min:3;
+		uint64_t static_p:1;
+		uint64_t qid_offm:3;
+		uint64_t reserved_11_63:53;
+#endif
 	} cn30xx;
 	struct cvmx_pko_mem_debug6_cn30xx cn31xx;
 	struct cvmx_pko_mem_debug6_cn30xx cn38xx;
 	struct cvmx_pko_mem_debug6_cn30xx cn38xxp2;
 	struct cvmx_pko_mem_debug6_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_11_63:53;
 		uint64_t curr_ptr:11;
+#else
+		uint64_t curr_ptr:11;
+		uint64_t reserved_11_63:53;
+#endif
 	} cn50xx;
 	struct cvmx_pko_mem_debug6_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_37_63:27;
 		uint64_t qid_offres:4;
 		uint64_t qid_offths:4;
@@ -529,37 +893,77 @@
 		uint64_t qid_offmax:4;
 		uint64_t qid_off:4;
 		uint64_t qid_base:8;
+#else
+		uint64_t qid_base:8;
+		uint64_t qid_off:4;
+		uint64_t qid_offmax:4;
+		uint64_t qcb_ridx:5;
+		uint64_t qos:3;
+		uint64_t statc:1;
+		uint64_t active:1;
+		uint64_t preempted:1;
+		uint64_t preemptee:1;
+		uint64_t preempter:1;
+		uint64_t qid_offths:4;
+		uint64_t qid_offres:4;
+		uint64_t reserved_37_63:27;
+#endif
 	} cn52xx;
 	struct cvmx_pko_mem_debug6_cn52xx cn52xxp1;
 	struct cvmx_pko_mem_debug6_cn52xx cn56xx;
 	struct cvmx_pko_mem_debug6_cn52xx cn56xxp1;
 	struct cvmx_pko_mem_debug6_cn50xx cn58xx;
 	struct cvmx_pko_mem_debug6_cn50xx cn58xxp1;
+	struct cvmx_pko_mem_debug6_cn52xx cn61xx;
+	struct cvmx_pko_mem_debug6_cn52xx cn63xx;
+	struct cvmx_pko_mem_debug6_cn52xx cn63xxp1;
+	struct cvmx_pko_mem_debug6_cn52xx cn66xx;
+	struct cvmx_pko_mem_debug6_cn52xx cn68xx;
+	struct cvmx_pko_mem_debug6_cn52xx cn68xxp1;
+	struct cvmx_pko_mem_debug6_cn52xx cnf71xx;
 };
 
 union cvmx_pko_mem_debug7 {
 	uint64_t u64;
 	struct cvmx_pko_mem_debug7_s {
-		uint64_t qos:5;
-		uint64_t tail:1;
-		uint64_t reserved_0_57:58;
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_0_63:64;
+#else
+		uint64_t reserved_0_63:64;
+#endif
 	} s;
 	struct cvmx_pko_mem_debug7_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_58_63:6;
 		uint64_t dwb:9;
 		uint64_t start:33;
 		uint64_t size:16;
+#else
+		uint64_t size:16;
+		uint64_t start:33;
+		uint64_t dwb:9;
+		uint64_t reserved_58_63:6;
+#endif
 	} cn30xx;
 	struct cvmx_pko_mem_debug7_cn30xx cn31xx;
 	struct cvmx_pko_mem_debug7_cn30xx cn38xx;
 	struct cvmx_pko_mem_debug7_cn30xx cn38xxp2;
 	struct cvmx_pko_mem_debug7_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t qos:5;
 		uint64_t tail:1;
 		uint64_t buf_siz:13;
 		uint64_t buf_ptr:33;
 		uint64_t qcb_widx:6;
 		uint64_t qcb_ridx:6;
+#else
+		uint64_t qcb_ridx:6;
+		uint64_t qcb_widx:6;
+		uint64_t buf_ptr:33;
+		uint64_t buf_siz:13;
+		uint64_t tail:1;
+		uint64_t qos:5;
+#endif
 	} cn50xx;
 	struct cvmx_pko_mem_debug7_cn50xx cn52xx;
 	struct cvmx_pko_mem_debug7_cn50xx cn52xxp1;
@@ -567,28 +971,68 @@
 	struct cvmx_pko_mem_debug7_cn50xx cn56xxp1;
 	struct cvmx_pko_mem_debug7_cn50xx cn58xx;
 	struct cvmx_pko_mem_debug7_cn50xx cn58xxp1;
+	struct cvmx_pko_mem_debug7_cn50xx cn61xx;
+	struct cvmx_pko_mem_debug7_cn50xx cn63xx;
+	struct cvmx_pko_mem_debug7_cn50xx cn63xxp1;
+	struct cvmx_pko_mem_debug7_cn50xx cn66xx;
+	struct cvmx_pko_mem_debug7_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t qos:3;
+		uint64_t tail:1;
+		uint64_t buf_siz:13;
+		uint64_t buf_ptr:33;
+		uint64_t qcb_widx:7;
+		uint64_t qcb_ridx:7;
+#else
+		uint64_t qcb_ridx:7;
+		uint64_t qcb_widx:7;
+		uint64_t buf_ptr:33;
+		uint64_t buf_siz:13;
+		uint64_t tail:1;
+		uint64_t qos:3;
+#endif
+	} cn68xx;
+	struct cvmx_pko_mem_debug7_cn68xx cn68xxp1;
+	struct cvmx_pko_mem_debug7_cn50xx cnf71xx;
 };
 
 union cvmx_pko_mem_debug8 {
 	uint64_t u64;
 	struct cvmx_pko_mem_debug8_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_59_63:5;
 		uint64_t tail:1;
 		uint64_t buf_siz:13;
 		uint64_t reserved_0_44:45;
+#else
+		uint64_t reserved_0_44:45;
+		uint64_t buf_siz:13;
+		uint64_t tail:1;
+		uint64_t reserved_59_63:5;
+#endif
 	} s;
 	struct cvmx_pko_mem_debug8_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t qos:5;
 		uint64_t tail:1;
 		uint64_t buf_siz:13;
 		uint64_t buf_ptr:33;
 		uint64_t qcb_widx:6;
 		uint64_t qcb_ridx:6;
+#else
+		uint64_t qcb_ridx:6;
+		uint64_t qcb_widx:6;
+		uint64_t buf_ptr:33;
+		uint64_t buf_siz:13;
+		uint64_t tail:1;
+		uint64_t qos:5;
+#endif
 	} cn30xx;
 	struct cvmx_pko_mem_debug8_cn30xx cn31xx;
 	struct cvmx_pko_mem_debug8_cn30xx cn38xx;
 	struct cvmx_pko_mem_debug8_cn30xx cn38xxp2;
 	struct cvmx_pko_mem_debug8_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_28_63:36;
 		uint64_t doorbell:20;
 		uint64_t reserved_6_7:2;
@@ -596,8 +1040,18 @@
 		uint64_t s_tail:1;
 		uint64_t static_q:1;
 		uint64_t qos:3;
+#else
+		uint64_t qos:3;
+		uint64_t static_q:1;
+		uint64_t s_tail:1;
+		uint64_t static_p:1;
+		uint64_t reserved_6_7:2;
+		uint64_t doorbell:20;
+		uint64_t reserved_28_63:36;
+#endif
 	} cn50xx;
 	struct cvmx_pko_mem_debug8_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_29_63:35;
 		uint64_t preempter:1;
 		uint64_t doorbell:20;
@@ -607,31 +1061,115 @@
 		uint64_t s_tail:1;
 		uint64_t static_q:1;
 		uint64_t qos:3;
+#else
+		uint64_t qos:3;
+		uint64_t static_q:1;
+		uint64_t s_tail:1;
+		uint64_t static_p:1;
+		uint64_t preemptee:1;
+		uint64_t reserved_7_7:1;
+		uint64_t doorbell:20;
+		uint64_t preempter:1;
+		uint64_t reserved_29_63:35;
+#endif
 	} cn52xx;
 	struct cvmx_pko_mem_debug8_cn52xx cn52xxp1;
 	struct cvmx_pko_mem_debug8_cn52xx cn56xx;
 	struct cvmx_pko_mem_debug8_cn52xx cn56xxp1;
 	struct cvmx_pko_mem_debug8_cn50xx cn58xx;
 	struct cvmx_pko_mem_debug8_cn50xx cn58xxp1;
+	struct cvmx_pko_mem_debug8_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_42_63:22;
+		uint64_t qid_qqos:8;
+		uint64_t reserved_33_33:1;
+		uint64_t qid_idx:4;
+		uint64_t preempter:1;
+		uint64_t doorbell:20;
+		uint64_t reserved_7_7:1;
+		uint64_t preemptee:1;
+		uint64_t static_p:1;
+		uint64_t s_tail:1;
+		uint64_t static_q:1;
+		uint64_t qos:3;
+#else
+		uint64_t qos:3;
+		uint64_t static_q:1;
+		uint64_t s_tail:1;
+		uint64_t static_p:1;
+		uint64_t preemptee:1;
+		uint64_t reserved_7_7:1;
+		uint64_t doorbell:20;
+		uint64_t preempter:1;
+		uint64_t qid_idx:4;
+		uint64_t reserved_33_33:1;
+		uint64_t qid_qqos:8;
+		uint64_t reserved_42_63:22;
+#endif
+	} cn61xx;
+	struct cvmx_pko_mem_debug8_cn52xx cn63xx;
+	struct cvmx_pko_mem_debug8_cn52xx cn63xxp1;
+	struct cvmx_pko_mem_debug8_cn61xx cn66xx;
+	struct cvmx_pko_mem_debug8_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_37_63:27;
+		uint64_t preempter:1;
+		uint64_t doorbell:20;
+		uint64_t reserved_9_15:7;
+		uint64_t preemptee:1;
+		uint64_t static_p:1;
+		uint64_t s_tail:1;
+		uint64_t static_q:1;
+		uint64_t qos:5;
+#else
+		uint64_t qos:5;
+		uint64_t static_q:1;
+		uint64_t s_tail:1;
+		uint64_t static_p:1;
+		uint64_t preemptee:1;
+		uint64_t reserved_9_15:7;
+		uint64_t doorbell:20;
+		uint64_t preempter:1;
+		uint64_t reserved_37_63:27;
+#endif
+	} cn68xx;
+	struct cvmx_pko_mem_debug8_cn68xx cn68xxp1;
+	struct cvmx_pko_mem_debug8_cn61xx cnf71xx;
 };
 
 union cvmx_pko_mem_debug9 {
 	uint64_t u64;
 	struct cvmx_pko_mem_debug9_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_49_63:15;
 		uint64_t ptrs0:17;
 		uint64_t reserved_0_31:32;
+#else
+		uint64_t reserved_0_31:32;
+		uint64_t ptrs0:17;
+		uint64_t reserved_49_63:15;
+#endif
 	} s;
 	struct cvmx_pko_mem_debug9_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_28_63:36;
 		uint64_t doorbell:20;
 		uint64_t reserved_5_7:3;
 		uint64_t s_tail:1;
 		uint64_t static_q:1;
 		uint64_t qos:3;
+#else
+		uint64_t qos:3;
+		uint64_t static_q:1;
+		uint64_t s_tail:1;
+		uint64_t reserved_5_7:3;
+		uint64_t doorbell:20;
+		uint64_t reserved_28_63:36;
+#endif
 	} cn30xx;
 	struct cvmx_pko_mem_debug9_cn30xx cn31xx;
 	struct cvmx_pko_mem_debug9_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_28_63:36;
 		uint64_t doorbell:20;
 		uint64_t reserved_6_7:2;
@@ -639,13 +1177,29 @@
 		uint64_t s_tail:1;
 		uint64_t static_q:1;
 		uint64_t qos:3;
+#else
+		uint64_t qos:3;
+		uint64_t static_q:1;
+		uint64_t s_tail:1;
+		uint64_t static_p:1;
+		uint64_t reserved_6_7:2;
+		uint64_t doorbell:20;
+		uint64_t reserved_28_63:36;
+#endif
 	} cn38xx;
 	struct cvmx_pko_mem_debug9_cn38xx cn38xxp2;
 	struct cvmx_pko_mem_debug9_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_49_63:15;
 		uint64_t ptrs0:17;
 		uint64_t reserved_17_31:15;
 		uint64_t ptrs3:17;
+#else
+		uint64_t ptrs3:17;
+		uint64_t reserved_17_31:15;
+		uint64_t ptrs0:17;
+		uint64_t reserved_49_63:15;
+#endif
 	} cn50xx;
 	struct cvmx_pko_mem_debug9_cn50xx cn52xx;
 	struct cvmx_pko_mem_debug9_cn50xx cn52xxp1;
@@ -653,11 +1207,131 @@
 	struct cvmx_pko_mem_debug9_cn50xx cn56xxp1;
 	struct cvmx_pko_mem_debug9_cn50xx cn58xx;
 	struct cvmx_pko_mem_debug9_cn50xx cn58xxp1;
+	struct cvmx_pko_mem_debug9_cn50xx cn61xx;
+	struct cvmx_pko_mem_debug9_cn50xx cn63xx;
+	struct cvmx_pko_mem_debug9_cn50xx cn63xxp1;
+	struct cvmx_pko_mem_debug9_cn50xx cn66xx;
+	struct cvmx_pko_mem_debug9_cn50xx cn68xx;
+	struct cvmx_pko_mem_debug9_cn50xx cn68xxp1;
+	struct cvmx_pko_mem_debug9_cn50xx cnf71xx;
+};
+
+union cvmx_pko_mem_iport_ptrs {
+	uint64_t u64;
+	struct cvmx_pko_mem_iport_ptrs_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_63_63:1;
+		uint64_t crc:1;
+		uint64_t static_p:1;
+		uint64_t qos_mask:8;
+		uint64_t min_pkt:3;
+		uint64_t reserved_31_49:19;
+		uint64_t pipe:7;
+		uint64_t reserved_21_23:3;
+		uint64_t intr:5;
+		uint64_t reserved_13_15:3;
+		uint64_t eid:5;
+		uint64_t reserved_7_7:1;
+		uint64_t ipid:7;
+#else
+		uint64_t ipid:7;
+		uint64_t reserved_7_7:1;
+		uint64_t eid:5;
+		uint64_t reserved_13_15:3;
+		uint64_t intr:5;
+		uint64_t reserved_21_23:3;
+		uint64_t pipe:7;
+		uint64_t reserved_31_49:19;
+		uint64_t min_pkt:3;
+		uint64_t qos_mask:8;
+		uint64_t static_p:1;
+		uint64_t crc:1;
+		uint64_t reserved_63_63:1;
+#endif
+	} s;
+	struct cvmx_pko_mem_iport_ptrs_s cn68xx;
+	struct cvmx_pko_mem_iport_ptrs_s cn68xxp1;
+};
+
+union cvmx_pko_mem_iport_qos {
+	uint64_t u64;
+	struct cvmx_pko_mem_iport_qos_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_61_63:3;
+		uint64_t qos_mask:8;
+		uint64_t reserved_13_52:40;
+		uint64_t eid:5;
+		uint64_t reserved_7_7:1;
+		uint64_t ipid:7;
+#else
+		uint64_t ipid:7;
+		uint64_t reserved_7_7:1;
+		uint64_t eid:5;
+		uint64_t reserved_13_52:40;
+		uint64_t qos_mask:8;
+		uint64_t reserved_61_63:3;
+#endif
+	} s;
+	struct cvmx_pko_mem_iport_qos_s cn68xx;
+	struct cvmx_pko_mem_iport_qos_s cn68xxp1;
+};
+
+union cvmx_pko_mem_iqueue_ptrs {
+	uint64_t u64;
+	struct cvmx_pko_mem_iqueue_ptrs_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t s_tail:1;
+		uint64_t static_p:1;
+		uint64_t static_q:1;
+		uint64_t qos_mask:8;
+		uint64_t buf_ptr:31;
+		uint64_t tail:1;
+		uint64_t index:5;
+		uint64_t reserved_15_15:1;
+		uint64_t ipid:7;
+		uint64_t qid:8;
+#else
+		uint64_t qid:8;
+		uint64_t ipid:7;
+		uint64_t reserved_15_15:1;
+		uint64_t index:5;
+		uint64_t tail:1;
+		uint64_t buf_ptr:31;
+		uint64_t qos_mask:8;
+		uint64_t static_q:1;
+		uint64_t static_p:1;
+		uint64_t s_tail:1;
+#endif
+	} s;
+	struct cvmx_pko_mem_iqueue_ptrs_s cn68xx;
+	struct cvmx_pko_mem_iqueue_ptrs_s cn68xxp1;
+};
+
+union cvmx_pko_mem_iqueue_qos {
+	uint64_t u64;
+	struct cvmx_pko_mem_iqueue_qos_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_61_63:3;
+		uint64_t qos_mask:8;
+		uint64_t reserved_15_52:38;
+		uint64_t ipid:7;
+		uint64_t qid:8;
+#else
+		uint64_t qid:8;
+		uint64_t ipid:7;
+		uint64_t reserved_15_52:38;
+		uint64_t qos_mask:8;
+		uint64_t reserved_61_63:3;
+#endif
+	} s;
+	struct cvmx_pko_mem_iqueue_qos_s cn68xx;
+	struct cvmx_pko_mem_iqueue_qos_s cn68xxp1;
 };
 
 union cvmx_pko_mem_port_ptrs {
 	uint64_t u64;
 	struct cvmx_pko_mem_port_ptrs_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_62_63:2;
 		uint64_t static_p:1;
 		uint64_t qos_mask:8;
@@ -665,60 +1339,143 @@
 		uint64_t bp_port:6;
 		uint64_t eid:4;
 		uint64_t pid:6;
+#else
+		uint64_t pid:6;
+		uint64_t eid:4;
+		uint64_t bp_port:6;
+		uint64_t reserved_16_52:37;
+		uint64_t qos_mask:8;
+		uint64_t static_p:1;
+		uint64_t reserved_62_63:2;
+#endif
 	} s;
 	struct cvmx_pko_mem_port_ptrs_s cn52xx;
 	struct cvmx_pko_mem_port_ptrs_s cn52xxp1;
 	struct cvmx_pko_mem_port_ptrs_s cn56xx;
 	struct cvmx_pko_mem_port_ptrs_s cn56xxp1;
+	struct cvmx_pko_mem_port_ptrs_s cn61xx;
+	struct cvmx_pko_mem_port_ptrs_s cn63xx;
+	struct cvmx_pko_mem_port_ptrs_s cn63xxp1;
+	struct cvmx_pko_mem_port_ptrs_s cn66xx;
+	struct cvmx_pko_mem_port_ptrs_s cnf71xx;
 };
 
 union cvmx_pko_mem_port_qos {
 	uint64_t u64;
 	struct cvmx_pko_mem_port_qos_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_61_63:3;
 		uint64_t qos_mask:8;
 		uint64_t reserved_10_52:43;
 		uint64_t eid:4;
 		uint64_t pid:6;
+#else
+		uint64_t pid:6;
+		uint64_t eid:4;
+		uint64_t reserved_10_52:43;
+		uint64_t qos_mask:8;
+		uint64_t reserved_61_63:3;
+#endif
 	} s;
 	struct cvmx_pko_mem_port_qos_s cn52xx;
 	struct cvmx_pko_mem_port_qos_s cn52xxp1;
 	struct cvmx_pko_mem_port_qos_s cn56xx;
 	struct cvmx_pko_mem_port_qos_s cn56xxp1;
+	struct cvmx_pko_mem_port_qos_s cn61xx;
+	struct cvmx_pko_mem_port_qos_s cn63xx;
+	struct cvmx_pko_mem_port_qos_s cn63xxp1;
+	struct cvmx_pko_mem_port_qos_s cn66xx;
+	struct cvmx_pko_mem_port_qos_s cnf71xx;
 };
 
 union cvmx_pko_mem_port_rate0 {
 	uint64_t u64;
 	struct cvmx_pko_mem_port_rate0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_51_63:13;
+		uint64_t rate_word:19;
+		uint64_t rate_pkt:24;
+		uint64_t reserved_7_7:1;
+		uint64_t pid:7;
+#else
+		uint64_t pid:7;
+		uint64_t reserved_7_7:1;
+		uint64_t rate_pkt:24;
+		uint64_t rate_word:19;
+		uint64_t reserved_51_63:13;
+#endif
+	} s;
+	struct cvmx_pko_mem_port_rate0_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_51_63:13;
 		uint64_t rate_word:19;
 		uint64_t rate_pkt:24;
 		uint64_t reserved_6_7:2;
 		uint64_t pid:6;
-	} s;
-	struct cvmx_pko_mem_port_rate0_s cn52xx;
-	struct cvmx_pko_mem_port_rate0_s cn52xxp1;
-	struct cvmx_pko_mem_port_rate0_s cn56xx;
-	struct cvmx_pko_mem_port_rate0_s cn56xxp1;
+#else
+		uint64_t pid:6;
+		uint64_t reserved_6_7:2;
+		uint64_t rate_pkt:24;
+		uint64_t rate_word:19;
+		uint64_t reserved_51_63:13;
+#endif
+	} cn52xx;
+	struct cvmx_pko_mem_port_rate0_cn52xx cn52xxp1;
+	struct cvmx_pko_mem_port_rate0_cn52xx cn56xx;
+	struct cvmx_pko_mem_port_rate0_cn52xx cn56xxp1;
+	struct cvmx_pko_mem_port_rate0_cn52xx cn61xx;
+	struct cvmx_pko_mem_port_rate0_cn52xx cn63xx;
+	struct cvmx_pko_mem_port_rate0_cn52xx cn63xxp1;
+	struct cvmx_pko_mem_port_rate0_cn52xx cn66xx;
+	struct cvmx_pko_mem_port_rate0_s cn68xx;
+	struct cvmx_pko_mem_port_rate0_s cn68xxp1;
+	struct cvmx_pko_mem_port_rate0_cn52xx cnf71xx;
 };
 
 union cvmx_pko_mem_port_rate1 {
 	uint64_t u64;
 	struct cvmx_pko_mem_port_rate1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t rate_lim:24;
+		uint64_t reserved_7_7:1;
+		uint64_t pid:7;
+#else
+		uint64_t pid:7;
+		uint64_t reserved_7_7:1;
+		uint64_t rate_lim:24;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_pko_mem_port_rate1_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t rate_lim:24;
 		uint64_t reserved_6_7:2;
 		uint64_t pid:6;
-	} s;
-	struct cvmx_pko_mem_port_rate1_s cn52xx;
-	struct cvmx_pko_mem_port_rate1_s cn52xxp1;
-	struct cvmx_pko_mem_port_rate1_s cn56xx;
-	struct cvmx_pko_mem_port_rate1_s cn56xxp1;
+#else
+		uint64_t pid:6;
+		uint64_t reserved_6_7:2;
+		uint64_t rate_lim:24;
+		uint64_t reserved_32_63:32;
+#endif
+	} cn52xx;
+	struct cvmx_pko_mem_port_rate1_cn52xx cn52xxp1;
+	struct cvmx_pko_mem_port_rate1_cn52xx cn56xx;
+	struct cvmx_pko_mem_port_rate1_cn52xx cn56xxp1;
+	struct cvmx_pko_mem_port_rate1_cn52xx cn61xx;
+	struct cvmx_pko_mem_port_rate1_cn52xx cn63xx;
+	struct cvmx_pko_mem_port_rate1_cn52xx cn63xxp1;
+	struct cvmx_pko_mem_port_rate1_cn52xx cn66xx;
+	struct cvmx_pko_mem_port_rate1_s cn68xx;
+	struct cvmx_pko_mem_port_rate1_s cn68xxp1;
+	struct cvmx_pko_mem_port_rate1_cn52xx cnf71xx;
 };
 
 union cvmx_pko_mem_queue_ptrs {
 	uint64_t u64;
 	struct cvmx_pko_mem_queue_ptrs_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t s_tail:1;
 		uint64_t static_p:1;
 		uint64_t static_q:1;
@@ -728,6 +1485,17 @@
 		uint64_t index:3;
 		uint64_t port:6;
 		uint64_t queue:7;
+#else
+		uint64_t queue:7;
+		uint64_t port:6;
+		uint64_t index:3;
+		uint64_t tail:1;
+		uint64_t buf_ptr:36;
+		uint64_t qos_mask:8;
+		uint64_t static_q:1;
+		uint64_t static_p:1;
+		uint64_t s_tail:1;
+#endif
 	} s;
 	struct cvmx_pko_mem_queue_ptrs_s cn30xx;
 	struct cvmx_pko_mem_queue_ptrs_s cn31xx;
@@ -740,16 +1508,29 @@
 	struct cvmx_pko_mem_queue_ptrs_s cn56xxp1;
 	struct cvmx_pko_mem_queue_ptrs_s cn58xx;
 	struct cvmx_pko_mem_queue_ptrs_s cn58xxp1;
+	struct cvmx_pko_mem_queue_ptrs_s cn61xx;
+	struct cvmx_pko_mem_queue_ptrs_s cn63xx;
+	struct cvmx_pko_mem_queue_ptrs_s cn63xxp1;
+	struct cvmx_pko_mem_queue_ptrs_s cn66xx;
+	struct cvmx_pko_mem_queue_ptrs_s cnf71xx;
 };
 
 union cvmx_pko_mem_queue_qos {
 	uint64_t u64;
 	struct cvmx_pko_mem_queue_qos_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_61_63:3;
 		uint64_t qos_mask:8;
 		uint64_t reserved_13_52:40;
 		uint64_t pid:6;
 		uint64_t qid:7;
+#else
+		uint64_t qid:7;
+		uint64_t pid:6;
+		uint64_t reserved_13_52:40;
+		uint64_t qos_mask:8;
+		uint64_t reserved_61_63:3;
+#endif
 	} s;
 	struct cvmx_pko_mem_queue_qos_s cn30xx;
 	struct cvmx_pko_mem_queue_qos_s cn31xx;
@@ -762,14 +1543,70 @@
 	struct cvmx_pko_mem_queue_qos_s cn56xxp1;
 	struct cvmx_pko_mem_queue_qos_s cn58xx;
 	struct cvmx_pko_mem_queue_qos_s cn58xxp1;
+	struct cvmx_pko_mem_queue_qos_s cn61xx;
+	struct cvmx_pko_mem_queue_qos_s cn63xx;
+	struct cvmx_pko_mem_queue_qos_s cn63xxp1;
+	struct cvmx_pko_mem_queue_qos_s cn66xx;
+	struct cvmx_pko_mem_queue_qos_s cnf71xx;
+};
+
+union cvmx_pko_mem_throttle_int {
+	uint64_t u64;
+	struct cvmx_pko_mem_throttle_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_47_63:17;
+		uint64_t word:15;
+		uint64_t reserved_14_31:18;
+		uint64_t packet:6;
+		uint64_t reserved_5_7:3;
+		uint64_t intr:5;
+#else
+		uint64_t intr:5;
+		uint64_t reserved_5_7:3;
+		uint64_t packet:6;
+		uint64_t reserved_14_31:18;
+		uint64_t word:15;
+		uint64_t reserved_47_63:17;
+#endif
+	} s;
+	struct cvmx_pko_mem_throttle_int_s cn68xx;
+	struct cvmx_pko_mem_throttle_int_s cn68xxp1;
+};
+
+union cvmx_pko_mem_throttle_pipe {
+	uint64_t u64;
+	struct cvmx_pko_mem_throttle_pipe_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_47_63:17;
+		uint64_t word:15;
+		uint64_t reserved_14_31:18;
+		uint64_t packet:6;
+		uint64_t reserved_7_7:1;
+		uint64_t pipe:7;
+#else
+		uint64_t pipe:7;
+		uint64_t reserved_7_7:1;
+		uint64_t packet:6;
+		uint64_t reserved_14_31:18;
+		uint64_t word:15;
+		uint64_t reserved_47_63:17;
+#endif
+	} s;
+	struct cvmx_pko_mem_throttle_pipe_s cn68xx;
+	struct cvmx_pko_mem_throttle_pipe_s cn68xxp1;
 };
 
 union cvmx_pko_reg_bist_result {
 	uint64_t u64;
 	struct cvmx_pko_reg_bist_result_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_0_63:64;
+#else
+		uint64_t reserved_0_63:64;
+#endif
 	} s;
 	struct cvmx_pko_reg_bist_result_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_27_63:37;
 		uint64_t psb2:5;
 		uint64_t count:1;
@@ -783,11 +1620,27 @@
 		uint64_t qcb:2;
 		uint64_t pdb:4;
 		uint64_t psb:7;
+#else
+		uint64_t psb:7;
+		uint64_t pdb:4;
+		uint64_t qcb:2;
+		uint64_t qsb:2;
+		uint64_t chk:1;
+		uint64_t crc:1;
+		uint64_t out:1;
+		uint64_t ncb:1;
+		uint64_t wif:1;
+		uint64_t rif:1;
+		uint64_t count:1;
+		uint64_t psb2:5;
+		uint64_t reserved_27_63:37;
+#endif
 	} cn30xx;
 	struct cvmx_pko_reg_bist_result_cn30xx cn31xx;
 	struct cvmx_pko_reg_bist_result_cn30xx cn38xx;
 	struct cvmx_pko_reg_bist_result_cn30xx cn38xxp2;
 	struct cvmx_pko_reg_bist_result_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_33_63:31;
 		uint64_t csr:1;
 		uint64_t iob:1;
@@ -803,8 +1656,26 @@
 		uint64_t prt_qsb:3;
 		uint64_t dat_dat:4;
 		uint64_t dat_ptr:4;
+#else
+		uint64_t dat_ptr:4;
+		uint64_t dat_dat:4;
+		uint64_t prt_qsb:3;
+		uint64_t prt_qcb:2;
+		uint64_t ncb_inb:2;
+		uint64_t prt_psb:6;
+		uint64_t prt_nxt:1;
+		uint64_t prt_chk:3;
+		uint64_t out_wif:1;
+		uint64_t out_sta:1;
+		uint64_t out_ctl:3;
+		uint64_t out_crc:1;
+		uint64_t iob:1;
+		uint64_t csr:1;
+		uint64_t reserved_33_63:31;
+#endif
 	} cn50xx;
 	struct cvmx_pko_reg_bist_result_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_35_63:29;
 		uint64_t csr:1;
 		uint64_t iob:1;
@@ -821,21 +1692,139 @@
 		uint64_t prt_ctl:2;
 		uint64_t dat_dat:2;
 		uint64_t dat_ptr:4;
+#else
+		uint64_t dat_ptr:4;
+		uint64_t dat_dat:2;
+		uint64_t prt_ctl:2;
+		uint64_t prt_qsb:3;
+		uint64_t prt_qcb:2;
+		uint64_t ncb_inb:2;
+		uint64_t prt_psb:8;
+		uint64_t prt_nxt:1;
+		uint64_t prt_chk:3;
+		uint64_t out_wif:1;
+		uint64_t out_sta:1;
+		uint64_t out_ctl:3;
+		uint64_t out_dat:1;
+		uint64_t iob:1;
+		uint64_t csr:1;
+		uint64_t reserved_35_63:29;
+#endif
 	} cn52xx;
 	struct cvmx_pko_reg_bist_result_cn52xx cn52xxp1;
 	struct cvmx_pko_reg_bist_result_cn52xx cn56xx;
 	struct cvmx_pko_reg_bist_result_cn52xx cn56xxp1;
 	struct cvmx_pko_reg_bist_result_cn50xx cn58xx;
 	struct cvmx_pko_reg_bist_result_cn50xx cn58xxp1;
+	struct cvmx_pko_reg_bist_result_cn52xx cn61xx;
+	struct cvmx_pko_reg_bist_result_cn52xx cn63xx;
+	struct cvmx_pko_reg_bist_result_cn52xx cn63xxp1;
+	struct cvmx_pko_reg_bist_result_cn52xx cn66xx;
+	struct cvmx_pko_reg_bist_result_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_36_63:28;
+		uint64_t crc:1;
+		uint64_t csr:1;
+		uint64_t iob:1;
+		uint64_t out_dat:1;
+		uint64_t reserved_31_31:1;
+		uint64_t out_ctl:2;
+		uint64_t out_sta:1;
+		uint64_t out_wif:1;
+		uint64_t prt_chk:3;
+		uint64_t prt_nxt:1;
+		uint64_t prt_psb7:1;
+		uint64_t reserved_21_21:1;
+		uint64_t prt_psb:6;
+		uint64_t ncb_inb:2;
+		uint64_t prt_qcb:2;
+		uint64_t prt_qsb:3;
+		uint64_t prt_ctl:2;
+		uint64_t dat_dat:2;
+		uint64_t dat_ptr:4;
+#else
+		uint64_t dat_ptr:4;
+		uint64_t dat_dat:2;
+		uint64_t prt_ctl:2;
+		uint64_t prt_qsb:3;
+		uint64_t prt_qcb:2;
+		uint64_t ncb_inb:2;
+		uint64_t prt_psb:6;
+		uint64_t reserved_21_21:1;
+		uint64_t prt_psb7:1;
+		uint64_t prt_nxt:1;
+		uint64_t prt_chk:3;
+		uint64_t out_wif:1;
+		uint64_t out_sta:1;
+		uint64_t out_ctl:2;
+		uint64_t reserved_31_31:1;
+		uint64_t out_dat:1;
+		uint64_t iob:1;
+		uint64_t csr:1;
+		uint64_t crc:1;
+		uint64_t reserved_36_63:28;
+#endif
+	} cn68xx;
+	struct cvmx_pko_reg_bist_result_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_35_63:29;
+		uint64_t csr:1;
+		uint64_t iob:1;
+		uint64_t out_dat:1;
+		uint64_t reserved_31_31:1;
+		uint64_t out_ctl:2;
+		uint64_t out_sta:1;
+		uint64_t out_wif:1;
+		uint64_t prt_chk:3;
+		uint64_t prt_nxt:1;
+		uint64_t prt_psb7:1;
+		uint64_t reserved_21_21:1;
+		uint64_t prt_psb:6;
+		uint64_t ncb_inb:2;
+		uint64_t prt_qcb:2;
+		uint64_t prt_qsb:3;
+		uint64_t prt_ctl:2;
+		uint64_t dat_dat:2;
+		uint64_t dat_ptr:4;
+#else
+		uint64_t dat_ptr:4;
+		uint64_t dat_dat:2;
+		uint64_t prt_ctl:2;
+		uint64_t prt_qsb:3;
+		uint64_t prt_qcb:2;
+		uint64_t ncb_inb:2;
+		uint64_t prt_psb:6;
+		uint64_t reserved_21_21:1;
+		uint64_t prt_psb7:1;
+		uint64_t prt_nxt:1;
+		uint64_t prt_chk:3;
+		uint64_t out_wif:1;
+		uint64_t out_sta:1;
+		uint64_t out_ctl:2;
+		uint64_t reserved_31_31:1;
+		uint64_t out_dat:1;
+		uint64_t iob:1;
+		uint64_t csr:1;
+		uint64_t reserved_35_63:29;
+#endif
+	} cn68xxp1;
+	struct cvmx_pko_reg_bist_result_cn52xx cnf71xx;
 };
 
 union cvmx_pko_reg_cmd_buf {
 	uint64_t u64;
 	struct cvmx_pko_reg_cmd_buf_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_23_63:41;
 		uint64_t pool:3;
 		uint64_t reserved_13_19:7;
 		uint64_t size:13;
+#else
+		uint64_t size:13;
+		uint64_t reserved_13_19:7;
+		uint64_t pool:3;
+		uint64_t reserved_23_63:41;
+#endif
 	} s;
 	struct cvmx_pko_reg_cmd_buf_s cn30xx;
 	struct cvmx_pko_reg_cmd_buf_s cn31xx;
@@ -848,14 +1837,27 @@
 	struct cvmx_pko_reg_cmd_buf_s cn56xxp1;
 	struct cvmx_pko_reg_cmd_buf_s cn58xx;
 	struct cvmx_pko_reg_cmd_buf_s cn58xxp1;
+	struct cvmx_pko_reg_cmd_buf_s cn61xx;
+	struct cvmx_pko_reg_cmd_buf_s cn63xx;
+	struct cvmx_pko_reg_cmd_buf_s cn63xxp1;
+	struct cvmx_pko_reg_cmd_buf_s cn66xx;
+	struct cvmx_pko_reg_cmd_buf_s cn68xx;
+	struct cvmx_pko_reg_cmd_buf_s cn68xxp1;
+	struct cvmx_pko_reg_cmd_buf_s cnf71xx;
 };
 
 union cvmx_pko_reg_crc_ctlx {
 	uint64_t u64;
 	struct cvmx_pko_reg_crc_ctlx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t invres:1;
 		uint64_t refin:1;
+#else
+		uint64_t refin:1;
+		uint64_t invres:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_pko_reg_crc_ctlx_s cn38xx;
 	struct cvmx_pko_reg_crc_ctlx_s cn38xxp2;
@@ -866,8 +1868,13 @@
 union cvmx_pko_reg_crc_enable {
 	uint64_t u64;
 	struct cvmx_pko_reg_crc_enable_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t enable:32;
+#else
+		uint64_t enable:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_pko_reg_crc_enable_s cn38xx;
 	struct cvmx_pko_reg_crc_enable_s cn38xxp2;
@@ -878,8 +1885,13 @@
 union cvmx_pko_reg_crc_ivx {
 	uint64_t u64;
 	struct cvmx_pko_reg_crc_ivx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t iv:32;
+#else
+		uint64_t iv:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_pko_reg_crc_ivx_s cn38xx;
 	struct cvmx_pko_reg_crc_ivx_s cn38xxp2;
@@ -890,11 +1902,20 @@
 union cvmx_pko_reg_debug0 {
 	uint64_t u64;
 	struct cvmx_pko_reg_debug0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t asserts:64;
+#else
+		uint64_t asserts:64;
+#endif
 	} s;
 	struct cvmx_pko_reg_debug0_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_17_63:47;
 		uint64_t asserts:17;
+#else
+		uint64_t asserts:17;
+		uint64_t reserved_17_63:47;
+#endif
 	} cn30xx;
 	struct cvmx_pko_reg_debug0_cn30xx cn31xx;
 	struct cvmx_pko_reg_debug0_cn30xx cn38xx;
@@ -906,12 +1927,23 @@
 	struct cvmx_pko_reg_debug0_s cn56xxp1;
 	struct cvmx_pko_reg_debug0_s cn58xx;
 	struct cvmx_pko_reg_debug0_s cn58xxp1;
+	struct cvmx_pko_reg_debug0_s cn61xx;
+	struct cvmx_pko_reg_debug0_s cn63xx;
+	struct cvmx_pko_reg_debug0_s cn63xxp1;
+	struct cvmx_pko_reg_debug0_s cn66xx;
+	struct cvmx_pko_reg_debug0_s cn68xx;
+	struct cvmx_pko_reg_debug0_s cn68xxp1;
+	struct cvmx_pko_reg_debug0_s cnf71xx;
 };
 
 union cvmx_pko_reg_debug1 {
 	uint64_t u64;
 	struct cvmx_pko_reg_debug1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t asserts:64;
+#else
+		uint64_t asserts:64;
+#endif
 	} s;
 	struct cvmx_pko_reg_debug1_s cn50xx;
 	struct cvmx_pko_reg_debug1_s cn52xx;
@@ -920,12 +1952,23 @@
 	struct cvmx_pko_reg_debug1_s cn56xxp1;
 	struct cvmx_pko_reg_debug1_s cn58xx;
 	struct cvmx_pko_reg_debug1_s cn58xxp1;
+	struct cvmx_pko_reg_debug1_s cn61xx;
+	struct cvmx_pko_reg_debug1_s cn63xx;
+	struct cvmx_pko_reg_debug1_s cn63xxp1;
+	struct cvmx_pko_reg_debug1_s cn66xx;
+	struct cvmx_pko_reg_debug1_s cn68xx;
+	struct cvmx_pko_reg_debug1_s cn68xxp1;
+	struct cvmx_pko_reg_debug1_s cnf71xx;
 };
 
 union cvmx_pko_reg_debug2 {
 	uint64_t u64;
 	struct cvmx_pko_reg_debug2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t asserts:64;
+#else
+		uint64_t asserts:64;
+#endif
 	} s;
 	struct cvmx_pko_reg_debug2_s cn50xx;
 	struct cvmx_pko_reg_debug2_s cn52xx;
@@ -934,12 +1977,23 @@
 	struct cvmx_pko_reg_debug2_s cn56xxp1;
 	struct cvmx_pko_reg_debug2_s cn58xx;
 	struct cvmx_pko_reg_debug2_s cn58xxp1;
+	struct cvmx_pko_reg_debug2_s cn61xx;
+	struct cvmx_pko_reg_debug2_s cn63xx;
+	struct cvmx_pko_reg_debug2_s cn63xxp1;
+	struct cvmx_pko_reg_debug2_s cn66xx;
+	struct cvmx_pko_reg_debug2_s cn68xx;
+	struct cvmx_pko_reg_debug2_s cn68xxp1;
+	struct cvmx_pko_reg_debug2_s cnf71xx;
 };
 
 union cvmx_pko_reg_debug3 {
 	uint64_t u64;
 	struct cvmx_pko_reg_debug3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t asserts:64;
+#else
+		uint64_t asserts:64;
+#endif
 	} s;
 	struct cvmx_pko_reg_debug3_s cn50xx;
 	struct cvmx_pko_reg_debug3_s cn52xx;
@@ -948,11 +2002,69 @@
 	struct cvmx_pko_reg_debug3_s cn56xxp1;
 	struct cvmx_pko_reg_debug3_s cn58xx;
 	struct cvmx_pko_reg_debug3_s cn58xxp1;
+	struct cvmx_pko_reg_debug3_s cn61xx;
+	struct cvmx_pko_reg_debug3_s cn63xx;
+	struct cvmx_pko_reg_debug3_s cn63xxp1;
+	struct cvmx_pko_reg_debug3_s cn66xx;
+	struct cvmx_pko_reg_debug3_s cn68xx;
+	struct cvmx_pko_reg_debug3_s cn68xxp1;
+	struct cvmx_pko_reg_debug3_s cnf71xx;
+};
+
+union cvmx_pko_reg_debug4 {
+	uint64_t u64;
+	struct cvmx_pko_reg_debug4_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t asserts:64;
+#else
+		uint64_t asserts:64;
+#endif
+	} s;
+	struct cvmx_pko_reg_debug4_s cn68xx;
+	struct cvmx_pko_reg_debug4_s cn68xxp1;
 };
 
 union cvmx_pko_reg_engine_inflight {
 	uint64_t u64;
 	struct cvmx_pko_reg_engine_inflight_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t engine15:4;
+		uint64_t engine14:4;
+		uint64_t engine13:4;
+		uint64_t engine12:4;
+		uint64_t engine11:4;
+		uint64_t engine10:4;
+		uint64_t engine9:4;
+		uint64_t engine8:4;
+		uint64_t engine7:4;
+		uint64_t engine6:4;
+		uint64_t engine5:4;
+		uint64_t engine4:4;
+		uint64_t engine3:4;
+		uint64_t engine2:4;
+		uint64_t engine1:4;
+		uint64_t engine0:4;
+#else
+		uint64_t engine0:4;
+		uint64_t engine1:4;
+		uint64_t engine2:4;
+		uint64_t engine3:4;
+		uint64_t engine4:4;
+		uint64_t engine5:4;
+		uint64_t engine6:4;
+		uint64_t engine7:4;
+		uint64_t engine8:4;
+		uint64_t engine9:4;
+		uint64_t engine10:4;
+		uint64_t engine11:4;
+		uint64_t engine12:4;
+		uint64_t engine13:4;
+		uint64_t engine14:4;
+		uint64_t engine15:4;
+#endif
+	} s;
+	struct cvmx_pko_reg_engine_inflight_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_40_63:24;
 		uint64_t engine9:4;
 		uint64_t engine8:4;
@@ -964,78 +2076,380 @@
 		uint64_t engine2:4;
 		uint64_t engine1:4;
 		uint64_t engine0:4;
+#else
+		uint64_t engine0:4;
+		uint64_t engine1:4;
+		uint64_t engine2:4;
+		uint64_t engine3:4;
+		uint64_t engine4:4;
+		uint64_t engine5:4;
+		uint64_t engine6:4;
+		uint64_t engine7:4;
+		uint64_t engine8:4;
+		uint64_t engine9:4;
+		uint64_t reserved_40_63:24;
+#endif
+	} cn52xx;
+	struct cvmx_pko_reg_engine_inflight_cn52xx cn52xxp1;
+	struct cvmx_pko_reg_engine_inflight_cn52xx cn56xx;
+	struct cvmx_pko_reg_engine_inflight_cn52xx cn56xxp1;
+	struct cvmx_pko_reg_engine_inflight_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_56_63:8;
+		uint64_t engine13:4;
+		uint64_t engine12:4;
+		uint64_t engine11:4;
+		uint64_t engine10:4;
+		uint64_t engine9:4;
+		uint64_t engine8:4;
+		uint64_t engine7:4;
+		uint64_t engine6:4;
+		uint64_t engine5:4;
+		uint64_t engine4:4;
+		uint64_t engine3:4;
+		uint64_t engine2:4;
+		uint64_t engine1:4;
+		uint64_t engine0:4;
+#else
+		uint64_t engine0:4;
+		uint64_t engine1:4;
+		uint64_t engine2:4;
+		uint64_t engine3:4;
+		uint64_t engine4:4;
+		uint64_t engine5:4;
+		uint64_t engine6:4;
+		uint64_t engine7:4;
+		uint64_t engine8:4;
+		uint64_t engine9:4;
+		uint64_t engine10:4;
+		uint64_t engine11:4;
+		uint64_t engine12:4;
+		uint64_t engine13:4;
+		uint64_t reserved_56_63:8;
+#endif
+	} cn61xx;
+	struct cvmx_pko_reg_engine_inflight_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_48_63:16;
+		uint64_t engine11:4;
+		uint64_t engine10:4;
+		uint64_t engine9:4;
+		uint64_t engine8:4;
+		uint64_t engine7:4;
+		uint64_t engine6:4;
+		uint64_t engine5:4;
+		uint64_t engine4:4;
+		uint64_t engine3:4;
+		uint64_t engine2:4;
+		uint64_t engine1:4;
+		uint64_t engine0:4;
+#else
+		uint64_t engine0:4;
+		uint64_t engine1:4;
+		uint64_t engine2:4;
+		uint64_t engine3:4;
+		uint64_t engine4:4;
+		uint64_t engine5:4;
+		uint64_t engine6:4;
+		uint64_t engine7:4;
+		uint64_t engine8:4;
+		uint64_t engine9:4;
+		uint64_t engine10:4;
+		uint64_t engine11:4;
+		uint64_t reserved_48_63:16;
+#endif
+	} cn63xx;
+	struct cvmx_pko_reg_engine_inflight_cn63xx cn63xxp1;
+	struct cvmx_pko_reg_engine_inflight_cn61xx cn66xx;
+	struct cvmx_pko_reg_engine_inflight_s cn68xx;
+	struct cvmx_pko_reg_engine_inflight_s cn68xxp1;
+	struct cvmx_pko_reg_engine_inflight_cn61xx cnf71xx;
+};
+
+union cvmx_pko_reg_engine_inflight1 {
+	uint64_t u64;
+	struct cvmx_pko_reg_engine_inflight1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t engine19:4;
+		uint64_t engine18:4;
+		uint64_t engine17:4;
+		uint64_t engine16:4;
+#else
+		uint64_t engine16:4;
+		uint64_t engine17:4;
+		uint64_t engine18:4;
+		uint64_t engine19:4;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
-	struct cvmx_pko_reg_engine_inflight_s cn52xx;
-	struct cvmx_pko_reg_engine_inflight_s cn52xxp1;
-	struct cvmx_pko_reg_engine_inflight_s cn56xx;
-	struct cvmx_pko_reg_engine_inflight_s cn56xxp1;
+	struct cvmx_pko_reg_engine_inflight1_s cn68xx;
+	struct cvmx_pko_reg_engine_inflight1_s cn68xxp1;
+};
+
+union cvmx_pko_reg_engine_storagex {
+	uint64_t u64;
+	struct cvmx_pko_reg_engine_storagex_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t engine15:4;
+		uint64_t engine14:4;
+		uint64_t engine13:4;
+		uint64_t engine12:4;
+		uint64_t engine11:4;
+		uint64_t engine10:4;
+		uint64_t engine9:4;
+		uint64_t engine8:4;
+		uint64_t engine7:4;
+		uint64_t engine6:4;
+		uint64_t engine5:4;
+		uint64_t engine4:4;
+		uint64_t engine3:4;
+		uint64_t engine2:4;
+		uint64_t engine1:4;
+		uint64_t engine0:4;
+#else
+		uint64_t engine0:4;
+		uint64_t engine1:4;
+		uint64_t engine2:4;
+		uint64_t engine3:4;
+		uint64_t engine4:4;
+		uint64_t engine5:4;
+		uint64_t engine6:4;
+		uint64_t engine7:4;
+		uint64_t engine8:4;
+		uint64_t engine9:4;
+		uint64_t engine10:4;
+		uint64_t engine11:4;
+		uint64_t engine12:4;
+		uint64_t engine13:4;
+		uint64_t engine14:4;
+		uint64_t engine15:4;
+#endif
+	} s;
+	struct cvmx_pko_reg_engine_storagex_s cn68xx;
+	struct cvmx_pko_reg_engine_storagex_s cn68xxp1;
 };
 
 union cvmx_pko_reg_engine_thresh {
 	uint64_t u64;
 	struct cvmx_pko_reg_engine_thresh_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_20_63:44;
+		uint64_t mask:20;
+#else
+		uint64_t mask:20;
+		uint64_t reserved_20_63:44;
+#endif
+	} s;
+	struct cvmx_pko_reg_engine_thresh_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t mask:10;
-	} s;
-	struct cvmx_pko_reg_engine_thresh_s cn52xx;
-	struct cvmx_pko_reg_engine_thresh_s cn52xxp1;
-	struct cvmx_pko_reg_engine_thresh_s cn56xx;
-	struct cvmx_pko_reg_engine_thresh_s cn56xxp1;
+#else
+		uint64_t mask:10;
+		uint64_t reserved_10_63:54;
+#endif
+	} cn52xx;
+	struct cvmx_pko_reg_engine_thresh_cn52xx cn52xxp1;
+	struct cvmx_pko_reg_engine_thresh_cn52xx cn56xx;
+	struct cvmx_pko_reg_engine_thresh_cn52xx cn56xxp1;
+	struct cvmx_pko_reg_engine_thresh_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_14_63:50;
+		uint64_t mask:14;
+#else
+		uint64_t mask:14;
+		uint64_t reserved_14_63:50;
+#endif
+	} cn61xx;
+	struct cvmx_pko_reg_engine_thresh_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_12_63:52;
+		uint64_t mask:12;
+#else
+		uint64_t mask:12;
+		uint64_t reserved_12_63:52;
+#endif
+	} cn63xx;
+	struct cvmx_pko_reg_engine_thresh_cn63xx cn63xxp1;
+	struct cvmx_pko_reg_engine_thresh_cn61xx cn66xx;
+	struct cvmx_pko_reg_engine_thresh_s cn68xx;
+	struct cvmx_pko_reg_engine_thresh_s cn68xxp1;
+	struct cvmx_pko_reg_engine_thresh_cn61xx cnf71xx;
 };
 
 union cvmx_pko_reg_error {
 	uint64_t u64;
 	struct cvmx_pko_reg_error_s {
-		uint64_t reserved_3_63:61;
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t loopback:1;
 		uint64_t currzero:1;
 		uint64_t doorbell:1;
 		uint64_t parity:1;
+#else
+		uint64_t parity:1;
+		uint64_t doorbell:1;
+		uint64_t currzero:1;
+		uint64_t loopback:1;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_pko_reg_error_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t doorbell:1;
 		uint64_t parity:1;
+#else
+		uint64_t parity:1;
+		uint64_t doorbell:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} cn30xx;
 	struct cvmx_pko_reg_error_cn30xx cn31xx;
 	struct cvmx_pko_reg_error_cn30xx cn38xx;
 	struct cvmx_pko_reg_error_cn30xx cn38xxp2;
-	struct cvmx_pko_reg_error_s cn50xx;
-	struct cvmx_pko_reg_error_s cn52xx;
-	struct cvmx_pko_reg_error_s cn52xxp1;
-	struct cvmx_pko_reg_error_s cn56xx;
-	struct cvmx_pko_reg_error_s cn56xxp1;
-	struct cvmx_pko_reg_error_s cn58xx;
-	struct cvmx_pko_reg_error_s cn58xxp1;
+	struct cvmx_pko_reg_error_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_3_63:61;
+		uint64_t currzero:1;
+		uint64_t doorbell:1;
+		uint64_t parity:1;
+#else
+		uint64_t parity:1;
+		uint64_t doorbell:1;
+		uint64_t currzero:1;
+		uint64_t reserved_3_63:61;
+#endif
+	} cn50xx;
+	struct cvmx_pko_reg_error_cn50xx cn52xx;
+	struct cvmx_pko_reg_error_cn50xx cn52xxp1;
+	struct cvmx_pko_reg_error_cn50xx cn56xx;
+	struct cvmx_pko_reg_error_cn50xx cn56xxp1;
+	struct cvmx_pko_reg_error_cn50xx cn58xx;
+	struct cvmx_pko_reg_error_cn50xx cn58xxp1;
+	struct cvmx_pko_reg_error_cn50xx cn61xx;
+	struct cvmx_pko_reg_error_cn50xx cn63xx;
+	struct cvmx_pko_reg_error_cn50xx cn63xxp1;
+	struct cvmx_pko_reg_error_cn50xx cn66xx;
+	struct cvmx_pko_reg_error_s cn68xx;
+	struct cvmx_pko_reg_error_s cn68xxp1;
+	struct cvmx_pko_reg_error_cn50xx cnf71xx;
 };
 
 union cvmx_pko_reg_flags {
 	uint64_t u64;
 	struct cvmx_pko_reg_flags_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_9_63:55;
+		uint64_t dis_perf3:1;
+		uint64_t dis_perf2:1;
+		uint64_t dis_perf1:1;
+		uint64_t dis_perf0:1;
+		uint64_t ena_throttle:1;
+		uint64_t reset:1;
+		uint64_t store_be:1;
+		uint64_t ena_dwb:1;
+		uint64_t ena_pko:1;
+#else
+		uint64_t ena_pko:1;
+		uint64_t ena_dwb:1;
+		uint64_t store_be:1;
+		uint64_t reset:1;
+		uint64_t ena_throttle:1;
+		uint64_t dis_perf0:1;
+		uint64_t dis_perf1:1;
+		uint64_t dis_perf2:1;
+		uint64_t dis_perf3:1;
+		uint64_t reserved_9_63:55;
+#endif
+	} s;
+	struct cvmx_pko_reg_flags_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t reset:1;
 		uint64_t store_be:1;
 		uint64_t ena_dwb:1;
 		uint64_t ena_pko:1;
-	} s;
-	struct cvmx_pko_reg_flags_s cn30xx;
-	struct cvmx_pko_reg_flags_s cn31xx;
-	struct cvmx_pko_reg_flags_s cn38xx;
-	struct cvmx_pko_reg_flags_s cn38xxp2;
-	struct cvmx_pko_reg_flags_s cn50xx;
-	struct cvmx_pko_reg_flags_s cn52xx;
-	struct cvmx_pko_reg_flags_s cn52xxp1;
-	struct cvmx_pko_reg_flags_s cn56xx;
-	struct cvmx_pko_reg_flags_s cn56xxp1;
-	struct cvmx_pko_reg_flags_s cn58xx;
-	struct cvmx_pko_reg_flags_s cn58xxp1;
+#else
+		uint64_t ena_pko:1;
+		uint64_t ena_dwb:1;
+		uint64_t store_be:1;
+		uint64_t reset:1;
+		uint64_t reserved_4_63:60;
+#endif
+	} cn30xx;
+	struct cvmx_pko_reg_flags_cn30xx cn31xx;
+	struct cvmx_pko_reg_flags_cn30xx cn38xx;
+	struct cvmx_pko_reg_flags_cn30xx cn38xxp2;
+	struct cvmx_pko_reg_flags_cn30xx cn50xx;
+	struct cvmx_pko_reg_flags_cn30xx cn52xx;
+	struct cvmx_pko_reg_flags_cn30xx cn52xxp1;
+	struct cvmx_pko_reg_flags_cn30xx cn56xx;
+	struct cvmx_pko_reg_flags_cn30xx cn56xxp1;
+	struct cvmx_pko_reg_flags_cn30xx cn58xx;
+	struct cvmx_pko_reg_flags_cn30xx cn58xxp1;
+	struct cvmx_pko_reg_flags_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_9_63:55;
+		uint64_t dis_perf3:1;
+		uint64_t dis_perf2:1;
+		uint64_t reserved_4_6:3;
+		uint64_t reset:1;
+		uint64_t store_be:1;
+		uint64_t ena_dwb:1;
+		uint64_t ena_pko:1;
+#else
+		uint64_t ena_pko:1;
+		uint64_t ena_dwb:1;
+		uint64_t store_be:1;
+		uint64_t reset:1;
+		uint64_t reserved_4_6:3;
+		uint64_t dis_perf2:1;
+		uint64_t dis_perf3:1;
+		uint64_t reserved_9_63:55;
+#endif
+	} cn61xx;
+	struct cvmx_pko_reg_flags_cn30xx cn63xx;
+	struct cvmx_pko_reg_flags_cn30xx cn63xxp1;
+	struct cvmx_pko_reg_flags_cn61xx cn66xx;
+	struct cvmx_pko_reg_flags_s cn68xx;
+	struct cvmx_pko_reg_flags_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_7_63:57;
+		uint64_t dis_perf1:1;
+		uint64_t dis_perf0:1;
+		uint64_t ena_throttle:1;
+		uint64_t reset:1;
+		uint64_t store_be:1;
+		uint64_t ena_dwb:1;
+		uint64_t ena_pko:1;
+#else
+		uint64_t ena_pko:1;
+		uint64_t ena_dwb:1;
+		uint64_t store_be:1;
+		uint64_t reset:1;
+		uint64_t ena_throttle:1;
+		uint64_t dis_perf0:1;
+		uint64_t dis_perf1:1;
+		uint64_t reserved_7_63:57;
+#endif
+	} cn68xxp1;
+	struct cvmx_pko_reg_flags_cn61xx cnf71xx;
 };
 
 union cvmx_pko_reg_gmx_port_mode {
 	uint64_t u64;
 	struct cvmx_pko_reg_gmx_port_mode_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t mode1:3;
 		uint64_t mode0:3;
+#else
+		uint64_t mode0:3;
+		uint64_t mode1:3;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
 	struct cvmx_pko_reg_gmx_port_mode_s cn30xx;
 	struct cvmx_pko_reg_gmx_port_mode_s cn31xx;
@@ -1048,38 +2462,223 @@
 	struct cvmx_pko_reg_gmx_port_mode_s cn56xxp1;
 	struct cvmx_pko_reg_gmx_port_mode_s cn58xx;
 	struct cvmx_pko_reg_gmx_port_mode_s cn58xxp1;
+	struct cvmx_pko_reg_gmx_port_mode_s cn61xx;
+	struct cvmx_pko_reg_gmx_port_mode_s cn63xx;
+	struct cvmx_pko_reg_gmx_port_mode_s cn63xxp1;
+	struct cvmx_pko_reg_gmx_port_mode_s cn66xx;
+	struct cvmx_pko_reg_gmx_port_mode_s cnf71xx;
 };
 
 union cvmx_pko_reg_int_mask {
 	uint64_t u64;
 	struct cvmx_pko_reg_int_mask_s {
-		uint64_t reserved_3_63:61;
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t loopback:1;
 		uint64_t currzero:1;
 		uint64_t doorbell:1;
 		uint64_t parity:1;
+#else
+		uint64_t parity:1;
+		uint64_t doorbell:1;
+		uint64_t currzero:1;
+		uint64_t loopback:1;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_pko_reg_int_mask_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t doorbell:1;
 		uint64_t parity:1;
+#else
+		uint64_t parity:1;
+		uint64_t doorbell:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} cn30xx;
 	struct cvmx_pko_reg_int_mask_cn30xx cn31xx;
 	struct cvmx_pko_reg_int_mask_cn30xx cn38xx;
 	struct cvmx_pko_reg_int_mask_cn30xx cn38xxp2;
-	struct cvmx_pko_reg_int_mask_s cn50xx;
-	struct cvmx_pko_reg_int_mask_s cn52xx;
-	struct cvmx_pko_reg_int_mask_s cn52xxp1;
-	struct cvmx_pko_reg_int_mask_s cn56xx;
-	struct cvmx_pko_reg_int_mask_s cn56xxp1;
-	struct cvmx_pko_reg_int_mask_s cn58xx;
-	struct cvmx_pko_reg_int_mask_s cn58xxp1;
+	struct cvmx_pko_reg_int_mask_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_3_63:61;
+		uint64_t currzero:1;
+		uint64_t doorbell:1;
+		uint64_t parity:1;
+#else
+		uint64_t parity:1;
+		uint64_t doorbell:1;
+		uint64_t currzero:1;
+		uint64_t reserved_3_63:61;
+#endif
+	} cn50xx;
+	struct cvmx_pko_reg_int_mask_cn50xx cn52xx;
+	struct cvmx_pko_reg_int_mask_cn50xx cn52xxp1;
+	struct cvmx_pko_reg_int_mask_cn50xx cn56xx;
+	struct cvmx_pko_reg_int_mask_cn50xx cn56xxp1;
+	struct cvmx_pko_reg_int_mask_cn50xx cn58xx;
+	struct cvmx_pko_reg_int_mask_cn50xx cn58xxp1;
+	struct cvmx_pko_reg_int_mask_cn50xx cn61xx;
+	struct cvmx_pko_reg_int_mask_cn50xx cn63xx;
+	struct cvmx_pko_reg_int_mask_cn50xx cn63xxp1;
+	struct cvmx_pko_reg_int_mask_cn50xx cn66xx;
+	struct cvmx_pko_reg_int_mask_s cn68xx;
+	struct cvmx_pko_reg_int_mask_s cn68xxp1;
+	struct cvmx_pko_reg_int_mask_cn50xx cnf71xx;
+};
+
+union cvmx_pko_reg_loopback_bpid {
+	uint64_t u64;
+	struct cvmx_pko_reg_loopback_bpid_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_59_63:5;
+		uint64_t bpid7:6;
+		uint64_t reserved_52_52:1;
+		uint64_t bpid6:6;
+		uint64_t reserved_45_45:1;
+		uint64_t bpid5:6;
+		uint64_t reserved_38_38:1;
+		uint64_t bpid4:6;
+		uint64_t reserved_31_31:1;
+		uint64_t bpid3:6;
+		uint64_t reserved_24_24:1;
+		uint64_t bpid2:6;
+		uint64_t reserved_17_17:1;
+		uint64_t bpid1:6;
+		uint64_t reserved_10_10:1;
+		uint64_t bpid0:6;
+		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t bpid0:6;
+		uint64_t reserved_10_10:1;
+		uint64_t bpid1:6;
+		uint64_t reserved_17_17:1;
+		uint64_t bpid2:6;
+		uint64_t reserved_24_24:1;
+		uint64_t bpid3:6;
+		uint64_t reserved_31_31:1;
+		uint64_t bpid4:6;
+		uint64_t reserved_38_38:1;
+		uint64_t bpid5:6;
+		uint64_t reserved_45_45:1;
+		uint64_t bpid6:6;
+		uint64_t reserved_52_52:1;
+		uint64_t bpid7:6;
+		uint64_t reserved_59_63:5;
+#endif
+	} s;
+	struct cvmx_pko_reg_loopback_bpid_s cn68xx;
+	struct cvmx_pko_reg_loopback_bpid_s cn68xxp1;
+};
+
+union cvmx_pko_reg_loopback_pkind {
+	uint64_t u64;
+	struct cvmx_pko_reg_loopback_pkind_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_59_63:5;
+		uint64_t pkind7:6;
+		uint64_t reserved_52_52:1;
+		uint64_t pkind6:6;
+		uint64_t reserved_45_45:1;
+		uint64_t pkind5:6;
+		uint64_t reserved_38_38:1;
+		uint64_t pkind4:6;
+		uint64_t reserved_31_31:1;
+		uint64_t pkind3:6;
+		uint64_t reserved_24_24:1;
+		uint64_t pkind2:6;
+		uint64_t reserved_17_17:1;
+		uint64_t pkind1:6;
+		uint64_t reserved_10_10:1;
+		uint64_t pkind0:6;
+		uint64_t num_ports:4;
+#else
+		uint64_t num_ports:4;
+		uint64_t pkind0:6;
+		uint64_t reserved_10_10:1;
+		uint64_t pkind1:6;
+		uint64_t reserved_17_17:1;
+		uint64_t pkind2:6;
+		uint64_t reserved_24_24:1;
+		uint64_t pkind3:6;
+		uint64_t reserved_31_31:1;
+		uint64_t pkind4:6;
+		uint64_t reserved_38_38:1;
+		uint64_t pkind5:6;
+		uint64_t reserved_45_45:1;
+		uint64_t pkind6:6;
+		uint64_t reserved_52_52:1;
+		uint64_t pkind7:6;
+		uint64_t reserved_59_63:5;
+#endif
+	} s;
+	struct cvmx_pko_reg_loopback_pkind_s cn68xx;
+	struct cvmx_pko_reg_loopback_pkind_s cn68xxp1;
+};
+
+union cvmx_pko_reg_min_pkt {
+	uint64_t u64;
+	struct cvmx_pko_reg_min_pkt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t size7:8;
+		uint64_t size6:8;
+		uint64_t size5:8;
+		uint64_t size4:8;
+		uint64_t size3:8;
+		uint64_t size2:8;
+		uint64_t size1:8;
+		uint64_t size0:8;
+#else
+		uint64_t size0:8;
+		uint64_t size1:8;
+		uint64_t size2:8;
+		uint64_t size3:8;
+		uint64_t size4:8;
+		uint64_t size5:8;
+		uint64_t size6:8;
+		uint64_t size7:8;
+#endif
+	} s;
+	struct cvmx_pko_reg_min_pkt_s cn68xx;
+	struct cvmx_pko_reg_min_pkt_s cn68xxp1;
+};
+
+union cvmx_pko_reg_preempt {
+	uint64_t u64;
+	struct cvmx_pko_reg_preempt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_16_63:48;
+		uint64_t min_size:16;
+#else
+		uint64_t min_size:16;
+		uint64_t reserved_16_63:48;
+#endif
+	} s;
+	struct cvmx_pko_reg_preempt_s cn52xx;
+	struct cvmx_pko_reg_preempt_s cn52xxp1;
+	struct cvmx_pko_reg_preempt_s cn56xx;
+	struct cvmx_pko_reg_preempt_s cn56xxp1;
+	struct cvmx_pko_reg_preempt_s cn61xx;
+	struct cvmx_pko_reg_preempt_s cn63xx;
+	struct cvmx_pko_reg_preempt_s cn63xxp1;
+	struct cvmx_pko_reg_preempt_s cn66xx;
+	struct cvmx_pko_reg_preempt_s cn68xx;
+	struct cvmx_pko_reg_preempt_s cn68xxp1;
+	struct cvmx_pko_reg_preempt_s cnf71xx;
 };
 
 union cvmx_pko_reg_queue_mode {
 	uint64_t u64;
 	struct cvmx_pko_reg_queue_mode_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t mode:2;
+#else
+		uint64_t mode:2;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_pko_reg_queue_mode_s cn30xx;
 	struct cvmx_pko_reg_queue_mode_s cn31xx;
@@ -1092,14 +2691,53 @@
 	struct cvmx_pko_reg_queue_mode_s cn56xxp1;
 	struct cvmx_pko_reg_queue_mode_s cn58xx;
 	struct cvmx_pko_reg_queue_mode_s cn58xxp1;
+	struct cvmx_pko_reg_queue_mode_s cn61xx;
+	struct cvmx_pko_reg_queue_mode_s cn63xx;
+	struct cvmx_pko_reg_queue_mode_s cn63xxp1;
+	struct cvmx_pko_reg_queue_mode_s cn66xx;
+	struct cvmx_pko_reg_queue_mode_s cn68xx;
+	struct cvmx_pko_reg_queue_mode_s cn68xxp1;
+	struct cvmx_pko_reg_queue_mode_s cnf71xx;
+};
+
+union cvmx_pko_reg_queue_preempt {
+	uint64_t u64;
+	struct cvmx_pko_reg_queue_preempt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_2_63:62;
+		uint64_t preemptee:1;
+		uint64_t preempter:1;
+#else
+		uint64_t preempter:1;
+		uint64_t preemptee:1;
+		uint64_t reserved_2_63:62;
+#endif
+	} s;
+	struct cvmx_pko_reg_queue_preempt_s cn52xx;
+	struct cvmx_pko_reg_queue_preempt_s cn52xxp1;
+	struct cvmx_pko_reg_queue_preempt_s cn56xx;
+	struct cvmx_pko_reg_queue_preempt_s cn56xxp1;
+	struct cvmx_pko_reg_queue_preempt_s cn61xx;
+	struct cvmx_pko_reg_queue_preempt_s cn63xx;
+	struct cvmx_pko_reg_queue_preempt_s cn63xxp1;
+	struct cvmx_pko_reg_queue_preempt_s cn66xx;
+	struct cvmx_pko_reg_queue_preempt_s cn68xx;
+	struct cvmx_pko_reg_queue_preempt_s cn68xxp1;
+	struct cvmx_pko_reg_queue_preempt_s cnf71xx;
 };
 
 union cvmx_pko_reg_queue_ptrs1 {
 	uint64_t u64;
 	struct cvmx_pko_reg_queue_ptrs1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t idx3:1;
 		uint64_t qid7:1;
+#else
+		uint64_t qid7:1;
+		uint64_t idx3:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_pko_reg_queue_ptrs1_s cn50xx;
 	struct cvmx_pko_reg_queue_ptrs1_s cn52xx;
@@ -1108,14 +2746,25 @@
 	struct cvmx_pko_reg_queue_ptrs1_s cn56xxp1;
 	struct cvmx_pko_reg_queue_ptrs1_s cn58xx;
 	struct cvmx_pko_reg_queue_ptrs1_s cn58xxp1;
+	struct cvmx_pko_reg_queue_ptrs1_s cn61xx;
+	struct cvmx_pko_reg_queue_ptrs1_s cn63xx;
+	struct cvmx_pko_reg_queue_ptrs1_s cn63xxp1;
+	struct cvmx_pko_reg_queue_ptrs1_s cn66xx;
+	struct cvmx_pko_reg_queue_ptrs1_s cnf71xx;
 };
 
 union cvmx_pko_reg_read_idx {
 	uint64_t u64;
 	struct cvmx_pko_reg_read_idx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t inc:8;
 		uint64_t index:8;
+#else
+		uint64_t index:8;
+		uint64_t inc:8;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_pko_reg_read_idx_s cn30xx;
 	struct cvmx_pko_reg_read_idx_s cn31xx;
@@ -1128,6 +2777,48 @@
 	struct cvmx_pko_reg_read_idx_s cn56xxp1;
 	struct cvmx_pko_reg_read_idx_s cn58xx;
 	struct cvmx_pko_reg_read_idx_s cn58xxp1;
+	struct cvmx_pko_reg_read_idx_s cn61xx;
+	struct cvmx_pko_reg_read_idx_s cn63xx;
+	struct cvmx_pko_reg_read_idx_s cn63xxp1;
+	struct cvmx_pko_reg_read_idx_s cn66xx;
+	struct cvmx_pko_reg_read_idx_s cn68xx;
+	struct cvmx_pko_reg_read_idx_s cn68xxp1;
+	struct cvmx_pko_reg_read_idx_s cnf71xx;
+};
+
+union cvmx_pko_reg_throttle {
+	uint64_t u64;
+	struct cvmx_pko_reg_throttle_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_32_63:32;
+		uint64_t int_mask:32;
+#else
+		uint64_t int_mask:32;
+		uint64_t reserved_32_63:32;
+#endif
+	} s;
+	struct cvmx_pko_reg_throttle_s cn68xx;
+	struct cvmx_pko_reg_throttle_s cn68xxp1;
+};
+
+union cvmx_pko_reg_timestamp {
+	uint64_t u64;
+	struct cvmx_pko_reg_timestamp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t wqe_word:4;
+#else
+		uint64_t wqe_word:4;
+		uint64_t reserved_4_63:60;
+#endif
+	} s;
+	struct cvmx_pko_reg_timestamp_s cn61xx;
+	struct cvmx_pko_reg_timestamp_s cn63xx;
+	struct cvmx_pko_reg_timestamp_s cn63xxp1;
+	struct cvmx_pko_reg_timestamp_s cn66xx;
+	struct cvmx_pko_reg_timestamp_s cn68xx;
+	struct cvmx_pko_reg_timestamp_s cn68xxp1;
+	struct cvmx_pko_reg_timestamp_s cnf71xx;
 };
 
 #endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pow-defs.h b/arch/mips/include/asm/octeon/cvmx-pow-defs.h
index 39fd75b..9020ef4 100644
--- a/arch/mips/include/asm/octeon/cvmx-pow-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pow-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -55,11 +55,18 @@
 union cvmx_pow_bist_stat {
 	uint64_t u64;
 	struct cvmx_pow_bist_stat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t pp:16;
 		uint64_t reserved_0_15:16;
+#else
+		uint64_t reserved_0_15:16;
+		uint64_t pp:16;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_pow_bist_stat_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_17_63:47;
 		uint64_t pp:1;
 		uint64_t reserved_9_15:7;
@@ -72,8 +79,23 @@
 		uint64_t nbr0:1;
 		uint64_t pend:1;
 		uint64_t adr:1;
+#else
+		uint64_t adr:1;
+		uint64_t pend:1;
+		uint64_t nbr0:1;
+		uint64_t nbr1:1;
+		uint64_t fidx:1;
+		uint64_t index:1;
+		uint64_t nbt0:1;
+		uint64_t nbt1:1;
+		uint64_t cam:1;
+		uint64_t reserved_9_15:7;
+		uint64_t pp:1;
+		uint64_t reserved_17_63:47;
+#endif
 	} cn30xx;
 	struct cvmx_pow_bist_stat_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_18_63:46;
 		uint64_t pp:2;
 		uint64_t reserved_9_15:7;
@@ -86,8 +108,23 @@
 		uint64_t nbr0:1;
 		uint64_t pend:1;
 		uint64_t adr:1;
+#else
+		uint64_t adr:1;
+		uint64_t pend:1;
+		uint64_t nbr0:1;
+		uint64_t nbr1:1;
+		uint64_t fidx:1;
+		uint64_t index:1;
+		uint64_t nbt0:1;
+		uint64_t nbt1:1;
+		uint64_t cam:1;
+		uint64_t reserved_9_15:7;
+		uint64_t pp:2;
+		uint64_t reserved_18_63:46;
+#endif
 	} cn31xx;
 	struct cvmx_pow_bist_stat_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t pp:16;
 		uint64_t reserved_10_15:6;
@@ -101,10 +138,26 @@
 		uint64_t pend0:1;
 		uint64_t adr1:1;
 		uint64_t adr0:1;
+#else
+		uint64_t adr0:1;
+		uint64_t adr1:1;
+		uint64_t pend0:1;
+		uint64_t pend1:1;
+		uint64_t nbr0:1;
+		uint64_t nbr1:1;
+		uint64_t fidx:1;
+		uint64_t index:1;
+		uint64_t nbt:1;
+		uint64_t cam:1;
+		uint64_t reserved_10_15:6;
+		uint64_t pp:16;
+		uint64_t reserved_32_63:32;
+#endif
 	} cn38xx;
 	struct cvmx_pow_bist_stat_cn38xx cn38xxp2;
 	struct cvmx_pow_bist_stat_cn31xx cn50xx;
 	struct cvmx_pow_bist_stat_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t pp:4;
 		uint64_t reserved_9_15:7;
@@ -117,9 +170,24 @@
 		uint64_t nbr0:1;
 		uint64_t pend:1;
 		uint64_t adr:1;
+#else
+		uint64_t adr:1;
+		uint64_t pend:1;
+		uint64_t nbr0:1;
+		uint64_t nbr1:1;
+		uint64_t fidx:1;
+		uint64_t index:1;
+		uint64_t nbt0:1;
+		uint64_t nbt1:1;
+		uint64_t cam:1;
+		uint64_t reserved_9_15:7;
+		uint64_t pp:4;
+		uint64_t reserved_20_63:44;
+#endif
 	} cn52xx;
 	struct cvmx_pow_bist_stat_cn52xx cn52xxp1;
 	struct cvmx_pow_bist_stat_cn56xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_28_63:36;
 		uint64_t pp:12;
 		uint64_t reserved_10_15:6;
@@ -133,11 +201,52 @@
 		uint64_t pend0:1;
 		uint64_t adr1:1;
 		uint64_t adr0:1;
+#else
+		uint64_t adr0:1;
+		uint64_t adr1:1;
+		uint64_t pend0:1;
+		uint64_t pend1:1;
+		uint64_t nbr0:1;
+		uint64_t nbr1:1;
+		uint64_t fidx:1;
+		uint64_t index:1;
+		uint64_t nbt:1;
+		uint64_t cam:1;
+		uint64_t reserved_10_15:6;
+		uint64_t pp:12;
+		uint64_t reserved_28_63:36;
+#endif
 	} cn56xx;
 	struct cvmx_pow_bist_stat_cn56xx cn56xxp1;
 	struct cvmx_pow_bist_stat_cn38xx cn58xx;
 	struct cvmx_pow_bist_stat_cn38xx cn58xxp1;
+	struct cvmx_pow_bist_stat_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_20_63:44;
+		uint64_t pp:4;
+		uint64_t reserved_12_15:4;
+		uint64_t cam:1;
+		uint64_t nbr:3;
+		uint64_t nbt:4;
+		uint64_t index:1;
+		uint64_t fidx:1;
+		uint64_t pend:1;
+		uint64_t adr:1;
+#else
+		uint64_t adr:1;
+		uint64_t pend:1;
+		uint64_t fidx:1;
+		uint64_t index:1;
+		uint64_t nbt:4;
+		uint64_t nbr:3;
+		uint64_t cam:1;
+		uint64_t reserved_12_15:4;
+		uint64_t pp:4;
+		uint64_t reserved_20_63:44;
+#endif
+	} cn61xx;
 	struct cvmx_pow_bist_stat_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_22_63:42;
 		uint64_t pp:6;
 		uint64_t reserved_12_15:4;
@@ -148,15 +257,58 @@
 		uint64_t fidx:1;
 		uint64_t pend:1;
 		uint64_t adr:1;
+#else
+		uint64_t adr:1;
+		uint64_t pend:1;
+		uint64_t fidx:1;
+		uint64_t index:1;
+		uint64_t nbt:4;
+		uint64_t nbr:3;
+		uint64_t cam:1;
+		uint64_t reserved_12_15:4;
+		uint64_t pp:6;
+		uint64_t reserved_22_63:42;
+#endif
 	} cn63xx;
 	struct cvmx_pow_bist_stat_cn63xx cn63xxp1;
+	struct cvmx_pow_bist_stat_cn66xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_26_63:38;
+		uint64_t pp:10;
+		uint64_t reserved_12_15:4;
+		uint64_t cam:1;
+		uint64_t nbr:3;
+		uint64_t nbt:4;
+		uint64_t index:1;
+		uint64_t fidx:1;
+		uint64_t pend:1;
+		uint64_t adr:1;
+#else
+		uint64_t adr:1;
+		uint64_t pend:1;
+		uint64_t fidx:1;
+		uint64_t index:1;
+		uint64_t nbt:4;
+		uint64_t nbr:3;
+		uint64_t cam:1;
+		uint64_t reserved_12_15:4;
+		uint64_t pp:10;
+		uint64_t reserved_26_63:38;
+#endif
+	} cn66xx;
+	struct cvmx_pow_bist_stat_cn61xx cnf71xx;
 };
 
 union cvmx_pow_ds_pc {
 	uint64_t u64;
 	struct cvmx_pow_ds_pc_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t ds_pc:32;
+#else
+		uint64_t ds_pc:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_pow_ds_pc_s cn30xx;
 	struct cvmx_pow_ds_pc_s cn31xx;
@@ -169,13 +321,17 @@
 	struct cvmx_pow_ds_pc_s cn56xxp1;
 	struct cvmx_pow_ds_pc_s cn58xx;
 	struct cvmx_pow_ds_pc_s cn58xxp1;
+	struct cvmx_pow_ds_pc_s cn61xx;
 	struct cvmx_pow_ds_pc_s cn63xx;
 	struct cvmx_pow_ds_pc_s cn63xxp1;
+	struct cvmx_pow_ds_pc_s cn66xx;
+	struct cvmx_pow_ds_pc_s cnf71xx;
 };
 
 union cvmx_pow_ecc_err {
 	uint64_t u64;
 	struct cvmx_pow_ecc_err_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_45_63:19;
 		uint64_t iop_ie:13;
 		uint64_t reserved_29_31:3;
@@ -189,9 +345,25 @@
 		uint64_t sbe_ie:1;
 		uint64_t dbe:1;
 		uint64_t sbe:1;
+#else
+		uint64_t sbe:1;
+		uint64_t dbe:1;
+		uint64_t sbe_ie:1;
+		uint64_t dbe_ie:1;
+		uint64_t syn:5;
+		uint64_t reserved_9_11:3;
+		uint64_t rpe:1;
+		uint64_t rpe_ie:1;
+		uint64_t reserved_14_15:2;
+		uint64_t iop:13;
+		uint64_t reserved_29_31:3;
+		uint64_t iop_ie:13;
+		uint64_t reserved_45_63:19;
+#endif
 	} s;
 	struct cvmx_pow_ecc_err_s cn30xx;
 	struct cvmx_pow_ecc_err_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_14_63:50;
 		uint64_t rpe_ie:1;
 		uint64_t rpe:1;
@@ -201,6 +373,17 @@
 		uint64_t sbe_ie:1;
 		uint64_t dbe:1;
 		uint64_t sbe:1;
+#else
+		uint64_t sbe:1;
+		uint64_t dbe:1;
+		uint64_t sbe_ie:1;
+		uint64_t dbe_ie:1;
+		uint64_t syn:5;
+		uint64_t reserved_9_11:3;
+		uint64_t rpe:1;
+		uint64_t rpe_ie:1;
+		uint64_t reserved_14_63:50;
+#endif
 	} cn31xx;
 	struct cvmx_pow_ecc_err_s cn38xx;
 	struct cvmx_pow_ecc_err_cn31xx cn38xxp2;
@@ -211,16 +394,25 @@
 	struct cvmx_pow_ecc_err_s cn56xxp1;
 	struct cvmx_pow_ecc_err_s cn58xx;
 	struct cvmx_pow_ecc_err_s cn58xxp1;
+	struct cvmx_pow_ecc_err_s cn61xx;
 	struct cvmx_pow_ecc_err_s cn63xx;
 	struct cvmx_pow_ecc_err_s cn63xxp1;
+	struct cvmx_pow_ecc_err_s cn66xx;
+	struct cvmx_pow_ecc_err_s cnf71xx;
 };
 
 union cvmx_pow_int_ctl {
 	uint64_t u64;
 	struct cvmx_pow_int_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t pfr_dis:1;
 		uint64_t nbr_thr:5;
+#else
+		uint64_t nbr_thr:5;
+		uint64_t pfr_dis:1;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
 	struct cvmx_pow_int_ctl_s cn30xx;
 	struct cvmx_pow_int_ctl_s cn31xx;
@@ -233,15 +425,23 @@
 	struct cvmx_pow_int_ctl_s cn56xxp1;
 	struct cvmx_pow_int_ctl_s cn58xx;
 	struct cvmx_pow_int_ctl_s cn58xxp1;
+	struct cvmx_pow_int_ctl_s cn61xx;
 	struct cvmx_pow_int_ctl_s cn63xx;
 	struct cvmx_pow_int_ctl_s cn63xxp1;
+	struct cvmx_pow_int_ctl_s cn66xx;
+	struct cvmx_pow_int_ctl_s cnf71xx;
 };
 
 union cvmx_pow_iq_cntx {
 	uint64_t u64;
 	struct cvmx_pow_iq_cntx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t iq_cnt:32;
+#else
+		uint64_t iq_cnt:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_pow_iq_cntx_s cn30xx;
 	struct cvmx_pow_iq_cntx_s cn31xx;
@@ -254,15 +454,23 @@
 	struct cvmx_pow_iq_cntx_s cn56xxp1;
 	struct cvmx_pow_iq_cntx_s cn58xx;
 	struct cvmx_pow_iq_cntx_s cn58xxp1;
+	struct cvmx_pow_iq_cntx_s cn61xx;
 	struct cvmx_pow_iq_cntx_s cn63xx;
 	struct cvmx_pow_iq_cntx_s cn63xxp1;
+	struct cvmx_pow_iq_cntx_s cn66xx;
+	struct cvmx_pow_iq_cntx_s cnf71xx;
 };
 
 union cvmx_pow_iq_com_cnt {
 	uint64_t u64;
 	struct cvmx_pow_iq_com_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t iq_cnt:32;
+#else
+		uint64_t iq_cnt:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_pow_iq_com_cnt_s cn30xx;
 	struct cvmx_pow_iq_com_cnt_s cn31xx;
@@ -275,90 +483,150 @@
 	struct cvmx_pow_iq_com_cnt_s cn56xxp1;
 	struct cvmx_pow_iq_com_cnt_s cn58xx;
 	struct cvmx_pow_iq_com_cnt_s cn58xxp1;
+	struct cvmx_pow_iq_com_cnt_s cn61xx;
 	struct cvmx_pow_iq_com_cnt_s cn63xx;
 	struct cvmx_pow_iq_com_cnt_s cn63xxp1;
+	struct cvmx_pow_iq_com_cnt_s cn66xx;
+	struct cvmx_pow_iq_com_cnt_s cnf71xx;
 };
 
 union cvmx_pow_iq_int {
 	uint64_t u64;
 	struct cvmx_pow_iq_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t iq_int:8;
+#else
+		uint64_t iq_int:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_pow_iq_int_s cn52xx;
 	struct cvmx_pow_iq_int_s cn52xxp1;
 	struct cvmx_pow_iq_int_s cn56xx;
 	struct cvmx_pow_iq_int_s cn56xxp1;
+	struct cvmx_pow_iq_int_s cn61xx;
 	struct cvmx_pow_iq_int_s cn63xx;
 	struct cvmx_pow_iq_int_s cn63xxp1;
+	struct cvmx_pow_iq_int_s cn66xx;
+	struct cvmx_pow_iq_int_s cnf71xx;
 };
 
 union cvmx_pow_iq_int_en {
 	uint64_t u64;
 	struct cvmx_pow_iq_int_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t int_en:8;
+#else
+		uint64_t int_en:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_pow_iq_int_en_s cn52xx;
 	struct cvmx_pow_iq_int_en_s cn52xxp1;
 	struct cvmx_pow_iq_int_en_s cn56xx;
 	struct cvmx_pow_iq_int_en_s cn56xxp1;
+	struct cvmx_pow_iq_int_en_s cn61xx;
 	struct cvmx_pow_iq_int_en_s cn63xx;
 	struct cvmx_pow_iq_int_en_s cn63xxp1;
+	struct cvmx_pow_iq_int_en_s cn66xx;
+	struct cvmx_pow_iq_int_en_s cnf71xx;
 };
 
 union cvmx_pow_iq_thrx {
 	uint64_t u64;
 	struct cvmx_pow_iq_thrx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t iq_thr:32;
+#else
+		uint64_t iq_thr:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_pow_iq_thrx_s cn52xx;
 	struct cvmx_pow_iq_thrx_s cn52xxp1;
 	struct cvmx_pow_iq_thrx_s cn56xx;
 	struct cvmx_pow_iq_thrx_s cn56xxp1;
+	struct cvmx_pow_iq_thrx_s cn61xx;
 	struct cvmx_pow_iq_thrx_s cn63xx;
 	struct cvmx_pow_iq_thrx_s cn63xxp1;
+	struct cvmx_pow_iq_thrx_s cn66xx;
+	struct cvmx_pow_iq_thrx_s cnf71xx;
 };
 
 union cvmx_pow_nos_cnt {
 	uint64_t u64;
 	struct cvmx_pow_nos_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t nos_cnt:12;
+#else
+		uint64_t nos_cnt:12;
+		uint64_t reserved_12_63:52;
+#endif
 	} s;
 	struct cvmx_pow_nos_cnt_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_7_63:57;
 		uint64_t nos_cnt:7;
+#else
+		uint64_t nos_cnt:7;
+		uint64_t reserved_7_63:57;
+#endif
 	} cn30xx;
 	struct cvmx_pow_nos_cnt_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t nos_cnt:9;
+#else
+		uint64_t nos_cnt:9;
+		uint64_t reserved_9_63:55;
+#endif
 	} cn31xx;
 	struct cvmx_pow_nos_cnt_s cn38xx;
 	struct cvmx_pow_nos_cnt_s cn38xxp2;
 	struct cvmx_pow_nos_cnt_cn31xx cn50xx;
 	struct cvmx_pow_nos_cnt_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t nos_cnt:10;
+#else
+		uint64_t nos_cnt:10;
+		uint64_t reserved_10_63:54;
+#endif
 	} cn52xx;
 	struct cvmx_pow_nos_cnt_cn52xx cn52xxp1;
 	struct cvmx_pow_nos_cnt_s cn56xx;
 	struct cvmx_pow_nos_cnt_s cn56xxp1;
 	struct cvmx_pow_nos_cnt_s cn58xx;
 	struct cvmx_pow_nos_cnt_s cn58xxp1;
+	struct cvmx_pow_nos_cnt_cn52xx cn61xx;
 	struct cvmx_pow_nos_cnt_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_11_63:53;
 		uint64_t nos_cnt:11;
+#else
+		uint64_t nos_cnt:11;
+		uint64_t reserved_11_63:53;
+#endif
 	} cn63xx;
 	struct cvmx_pow_nos_cnt_cn63xx cn63xxp1;
+	struct cvmx_pow_nos_cnt_cn63xx cn66xx;
+	struct cvmx_pow_nos_cnt_cn52xx cnf71xx;
 };
 
 union cvmx_pow_nw_tim {
 	uint64_t u64;
 	struct cvmx_pow_nw_tim_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t nw_tim:10;
+#else
+		uint64_t nw_tim:10;
+		uint64_t reserved_10_63:54;
+#endif
 	} s;
 	struct cvmx_pow_nw_tim_s cn30xx;
 	struct cvmx_pow_nw_tim_s cn31xx;
@@ -371,15 +639,23 @@
 	struct cvmx_pow_nw_tim_s cn56xxp1;
 	struct cvmx_pow_nw_tim_s cn58xx;
 	struct cvmx_pow_nw_tim_s cn58xxp1;
+	struct cvmx_pow_nw_tim_s cn61xx;
 	struct cvmx_pow_nw_tim_s cn63xx;
 	struct cvmx_pow_nw_tim_s cn63xxp1;
+	struct cvmx_pow_nw_tim_s cn66xx;
+	struct cvmx_pow_nw_tim_s cnf71xx;
 };
 
 union cvmx_pow_pf_rst_msk {
 	uint64_t u64;
 	struct cvmx_pow_pf_rst_msk_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t rst_msk:8;
+#else
+		uint64_t rst_msk:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_pow_pf_rst_msk_s cn50xx;
 	struct cvmx_pow_pf_rst_msk_s cn52xx;
@@ -388,13 +664,17 @@
 	struct cvmx_pow_pf_rst_msk_s cn56xxp1;
 	struct cvmx_pow_pf_rst_msk_s cn58xx;
 	struct cvmx_pow_pf_rst_msk_s cn58xxp1;
+	struct cvmx_pow_pf_rst_msk_s cn61xx;
 	struct cvmx_pow_pf_rst_msk_s cn63xx;
 	struct cvmx_pow_pf_rst_msk_s cn63xxp1;
+	struct cvmx_pow_pf_rst_msk_s cn66xx;
+	struct cvmx_pow_pf_rst_msk_s cnf71xx;
 };
 
 union cvmx_pow_pp_grp_mskx {
 	uint64_t u64;
 	struct cvmx_pow_pp_grp_mskx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t qos7_pri:4;
 		uint64_t qos6_pri:4;
@@ -405,10 +685,27 @@
 		uint64_t qos1_pri:4;
 		uint64_t qos0_pri:4;
 		uint64_t grp_msk:16;
+#else
+		uint64_t grp_msk:16;
+		uint64_t qos0_pri:4;
+		uint64_t qos1_pri:4;
+		uint64_t qos2_pri:4;
+		uint64_t qos3_pri:4;
+		uint64_t qos4_pri:4;
+		uint64_t qos5_pri:4;
+		uint64_t qos6_pri:4;
+		uint64_t qos7_pri:4;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_pow_pp_grp_mskx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t grp_msk:16;
+#else
+		uint64_t grp_msk:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} cn30xx;
 	struct cvmx_pow_pp_grp_mskx_cn30xx cn31xx;
 	struct cvmx_pow_pp_grp_mskx_cn30xx cn38xx;
@@ -420,18 +717,29 @@
 	struct cvmx_pow_pp_grp_mskx_s cn56xxp1;
 	struct cvmx_pow_pp_grp_mskx_s cn58xx;
 	struct cvmx_pow_pp_grp_mskx_s cn58xxp1;
+	struct cvmx_pow_pp_grp_mskx_s cn61xx;
 	struct cvmx_pow_pp_grp_mskx_s cn63xx;
 	struct cvmx_pow_pp_grp_mskx_s cn63xxp1;
+	struct cvmx_pow_pp_grp_mskx_s cn66xx;
+	struct cvmx_pow_pp_grp_mskx_s cnf71xx;
 };
 
 union cvmx_pow_qos_rndx {
 	uint64_t u64;
 	struct cvmx_pow_qos_rndx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t rnd_p3:8;
 		uint64_t rnd_p2:8;
 		uint64_t rnd_p1:8;
 		uint64_t rnd:8;
+#else
+		uint64_t rnd:8;
+		uint64_t rnd_p1:8;
+		uint64_t rnd_p2:8;
+		uint64_t rnd_p3:8;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_pow_qos_rndx_s cn30xx;
 	struct cvmx_pow_qos_rndx_s cn31xx;
@@ -444,13 +752,17 @@
 	struct cvmx_pow_qos_rndx_s cn56xxp1;
 	struct cvmx_pow_qos_rndx_s cn58xx;
 	struct cvmx_pow_qos_rndx_s cn58xxp1;
+	struct cvmx_pow_qos_rndx_s cn61xx;
 	struct cvmx_pow_qos_rndx_s cn63xx;
 	struct cvmx_pow_qos_rndx_s cn63xxp1;
+	struct cvmx_pow_qos_rndx_s cn66xx;
+	struct cvmx_pow_qos_rndx_s cnf71xx;
 };
 
 union cvmx_pow_qos_thrx {
 	uint64_t u64;
 	struct cvmx_pow_qos_thrx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_60_63:4;
 		uint64_t des_cnt:12;
 		uint64_t buf_cnt:12;
@@ -459,8 +771,19 @@
 		uint64_t max_thr:11;
 		uint64_t reserved_11_11:1;
 		uint64_t min_thr:11;
+#else
+		uint64_t min_thr:11;
+		uint64_t reserved_11_11:1;
+		uint64_t max_thr:11;
+		uint64_t reserved_23_23:1;
+		uint64_t free_cnt:12;
+		uint64_t buf_cnt:12;
+		uint64_t des_cnt:12;
+		uint64_t reserved_60_63:4;
+#endif
 	} s;
 	struct cvmx_pow_qos_thrx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_55_63:9;
 		uint64_t des_cnt:7;
 		uint64_t reserved_43_47:5;
@@ -471,8 +794,21 @@
 		uint64_t max_thr:6;
 		uint64_t reserved_6_11:6;
 		uint64_t min_thr:6;
+#else
+		uint64_t min_thr:6;
+		uint64_t reserved_6_11:6;
+		uint64_t max_thr:6;
+		uint64_t reserved_18_23:6;
+		uint64_t free_cnt:7;
+		uint64_t reserved_31_35:5;
+		uint64_t buf_cnt:7;
+		uint64_t reserved_43_47:5;
+		uint64_t des_cnt:7;
+		uint64_t reserved_55_63:9;
+#endif
 	} cn30xx;
 	struct cvmx_pow_qos_thrx_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_57_63:7;
 		uint64_t des_cnt:9;
 		uint64_t reserved_45_47:3;
@@ -483,11 +819,24 @@
 		uint64_t max_thr:8;
 		uint64_t reserved_8_11:4;
 		uint64_t min_thr:8;
+#else
+		uint64_t min_thr:8;
+		uint64_t reserved_8_11:4;
+		uint64_t max_thr:8;
+		uint64_t reserved_20_23:4;
+		uint64_t free_cnt:9;
+		uint64_t reserved_33_35:3;
+		uint64_t buf_cnt:9;
+		uint64_t reserved_45_47:3;
+		uint64_t des_cnt:9;
+		uint64_t reserved_57_63:7;
+#endif
 	} cn31xx;
 	struct cvmx_pow_qos_thrx_s cn38xx;
 	struct cvmx_pow_qos_thrx_s cn38xxp2;
 	struct cvmx_pow_qos_thrx_cn31xx cn50xx;
 	struct cvmx_pow_qos_thrx_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_58_63:6;
 		uint64_t des_cnt:10;
 		uint64_t reserved_46_47:2;
@@ -498,13 +847,27 @@
 		uint64_t max_thr:9;
 		uint64_t reserved_9_11:3;
 		uint64_t min_thr:9;
+#else
+		uint64_t min_thr:9;
+		uint64_t reserved_9_11:3;
+		uint64_t max_thr:9;
+		uint64_t reserved_21_23:3;
+		uint64_t free_cnt:10;
+		uint64_t reserved_34_35:2;
+		uint64_t buf_cnt:10;
+		uint64_t reserved_46_47:2;
+		uint64_t des_cnt:10;
+		uint64_t reserved_58_63:6;
+#endif
 	} cn52xx;
 	struct cvmx_pow_qos_thrx_cn52xx cn52xxp1;
 	struct cvmx_pow_qos_thrx_s cn56xx;
 	struct cvmx_pow_qos_thrx_s cn56xxp1;
 	struct cvmx_pow_qos_thrx_s cn58xx;
 	struct cvmx_pow_qos_thrx_s cn58xxp1;
+	struct cvmx_pow_qos_thrx_cn52xx cn61xx;
 	struct cvmx_pow_qos_thrx_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_59_63:5;
 		uint64_t des_cnt:11;
 		uint64_t reserved_47_47:1;
@@ -515,15 +878,34 @@
 		uint64_t max_thr:10;
 		uint64_t reserved_10_11:2;
 		uint64_t min_thr:10;
+#else
+		uint64_t min_thr:10;
+		uint64_t reserved_10_11:2;
+		uint64_t max_thr:10;
+		uint64_t reserved_22_23:2;
+		uint64_t free_cnt:11;
+		uint64_t reserved_35_35:1;
+		uint64_t buf_cnt:11;
+		uint64_t reserved_47_47:1;
+		uint64_t des_cnt:11;
+		uint64_t reserved_59_63:5;
+#endif
 	} cn63xx;
 	struct cvmx_pow_qos_thrx_cn63xx cn63xxp1;
+	struct cvmx_pow_qos_thrx_cn63xx cn66xx;
+	struct cvmx_pow_qos_thrx_cn52xx cnf71xx;
 };
 
 union cvmx_pow_ts_pc {
 	uint64_t u64;
 	struct cvmx_pow_ts_pc_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t ts_pc:32;
+#else
+		uint64_t ts_pc:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_pow_ts_pc_s cn30xx;
 	struct cvmx_pow_ts_pc_s cn31xx;
@@ -536,15 +918,23 @@
 	struct cvmx_pow_ts_pc_s cn56xxp1;
 	struct cvmx_pow_ts_pc_s cn58xx;
 	struct cvmx_pow_ts_pc_s cn58xxp1;
+	struct cvmx_pow_ts_pc_s cn61xx;
 	struct cvmx_pow_ts_pc_s cn63xx;
 	struct cvmx_pow_ts_pc_s cn63xxp1;
+	struct cvmx_pow_ts_pc_s cn66xx;
+	struct cvmx_pow_ts_pc_s cnf71xx;
 };
 
 union cvmx_pow_wa_com_pc {
 	uint64_t u64;
 	struct cvmx_pow_wa_com_pc_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t wa_pc:32;
+#else
+		uint64_t wa_pc:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_pow_wa_com_pc_s cn30xx;
 	struct cvmx_pow_wa_com_pc_s cn31xx;
@@ -557,15 +947,23 @@
 	struct cvmx_pow_wa_com_pc_s cn56xxp1;
 	struct cvmx_pow_wa_com_pc_s cn58xx;
 	struct cvmx_pow_wa_com_pc_s cn58xxp1;
+	struct cvmx_pow_wa_com_pc_s cn61xx;
 	struct cvmx_pow_wa_com_pc_s cn63xx;
 	struct cvmx_pow_wa_com_pc_s cn63xxp1;
+	struct cvmx_pow_wa_com_pc_s cn66xx;
+	struct cvmx_pow_wa_com_pc_s cnf71xx;
 };
 
 union cvmx_pow_wa_pcx {
 	uint64_t u64;
 	struct cvmx_pow_wa_pcx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t wa_pc:32;
+#else
+		uint64_t wa_pc:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_pow_wa_pcx_s cn30xx;
 	struct cvmx_pow_wa_pcx_s cn31xx;
@@ -578,16 +976,25 @@
 	struct cvmx_pow_wa_pcx_s cn56xxp1;
 	struct cvmx_pow_wa_pcx_s cn58xx;
 	struct cvmx_pow_wa_pcx_s cn58xxp1;
+	struct cvmx_pow_wa_pcx_s cn61xx;
 	struct cvmx_pow_wa_pcx_s cn63xx;
 	struct cvmx_pow_wa_pcx_s cn63xxp1;
+	struct cvmx_pow_wa_pcx_s cn66xx;
+	struct cvmx_pow_wa_pcx_s cnf71xx;
 };
 
 union cvmx_pow_wq_int {
 	uint64_t u64;
 	struct cvmx_pow_wq_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t iq_dis:16;
 		uint64_t wq_int:16;
+#else
+		uint64_t wq_int:16;
+		uint64_t iq_dis:16;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_pow_wq_int_s cn30xx;
 	struct cvmx_pow_wq_int_s cn31xx;
@@ -600,69 +1007,126 @@
 	struct cvmx_pow_wq_int_s cn56xxp1;
 	struct cvmx_pow_wq_int_s cn58xx;
 	struct cvmx_pow_wq_int_s cn58xxp1;
+	struct cvmx_pow_wq_int_s cn61xx;
 	struct cvmx_pow_wq_int_s cn63xx;
 	struct cvmx_pow_wq_int_s cn63xxp1;
+	struct cvmx_pow_wq_int_s cn66xx;
+	struct cvmx_pow_wq_int_s cnf71xx;
 };
 
 union cvmx_pow_wq_int_cntx {
 	uint64_t u64;
 	struct cvmx_pow_wq_int_cntx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_28_63:36;
 		uint64_t tc_cnt:4;
 		uint64_t ds_cnt:12;
 		uint64_t iq_cnt:12;
+#else
+		uint64_t iq_cnt:12;
+		uint64_t ds_cnt:12;
+		uint64_t tc_cnt:4;
+		uint64_t reserved_28_63:36;
+#endif
 	} s;
 	struct cvmx_pow_wq_int_cntx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_28_63:36;
 		uint64_t tc_cnt:4;
 		uint64_t reserved_19_23:5;
 		uint64_t ds_cnt:7;
 		uint64_t reserved_7_11:5;
 		uint64_t iq_cnt:7;
+#else
+		uint64_t iq_cnt:7;
+		uint64_t reserved_7_11:5;
+		uint64_t ds_cnt:7;
+		uint64_t reserved_19_23:5;
+		uint64_t tc_cnt:4;
+		uint64_t reserved_28_63:36;
+#endif
 	} cn30xx;
 	struct cvmx_pow_wq_int_cntx_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_28_63:36;
 		uint64_t tc_cnt:4;
 		uint64_t reserved_21_23:3;
 		uint64_t ds_cnt:9;
 		uint64_t reserved_9_11:3;
 		uint64_t iq_cnt:9;
+#else
+		uint64_t iq_cnt:9;
+		uint64_t reserved_9_11:3;
+		uint64_t ds_cnt:9;
+		uint64_t reserved_21_23:3;
+		uint64_t tc_cnt:4;
+		uint64_t reserved_28_63:36;
+#endif
 	} cn31xx;
 	struct cvmx_pow_wq_int_cntx_s cn38xx;
 	struct cvmx_pow_wq_int_cntx_s cn38xxp2;
 	struct cvmx_pow_wq_int_cntx_cn31xx cn50xx;
 	struct cvmx_pow_wq_int_cntx_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_28_63:36;
 		uint64_t tc_cnt:4;
 		uint64_t reserved_22_23:2;
 		uint64_t ds_cnt:10;
 		uint64_t reserved_10_11:2;
 		uint64_t iq_cnt:10;
+#else
+		uint64_t iq_cnt:10;
+		uint64_t reserved_10_11:2;
+		uint64_t ds_cnt:10;
+		uint64_t reserved_22_23:2;
+		uint64_t tc_cnt:4;
+		uint64_t reserved_28_63:36;
+#endif
 	} cn52xx;
 	struct cvmx_pow_wq_int_cntx_cn52xx cn52xxp1;
 	struct cvmx_pow_wq_int_cntx_s cn56xx;
 	struct cvmx_pow_wq_int_cntx_s cn56xxp1;
 	struct cvmx_pow_wq_int_cntx_s cn58xx;
 	struct cvmx_pow_wq_int_cntx_s cn58xxp1;
+	struct cvmx_pow_wq_int_cntx_cn52xx cn61xx;
 	struct cvmx_pow_wq_int_cntx_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_28_63:36;
 		uint64_t tc_cnt:4;
 		uint64_t reserved_23_23:1;
 		uint64_t ds_cnt:11;
 		uint64_t reserved_11_11:1;
 		uint64_t iq_cnt:11;
+#else
+		uint64_t iq_cnt:11;
+		uint64_t reserved_11_11:1;
+		uint64_t ds_cnt:11;
+		uint64_t reserved_23_23:1;
+		uint64_t tc_cnt:4;
+		uint64_t reserved_28_63:36;
+#endif
 	} cn63xx;
 	struct cvmx_pow_wq_int_cntx_cn63xx cn63xxp1;
+	struct cvmx_pow_wq_int_cntx_cn63xx cn66xx;
+	struct cvmx_pow_wq_int_cntx_cn52xx cnf71xx;
 };
 
 union cvmx_pow_wq_int_pc {
 	uint64_t u64;
 	struct cvmx_pow_wq_int_pc_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_60_63:4;
 		uint64_t pc:28;
 		uint64_t reserved_28_31:4;
 		uint64_t pc_thr:20;
 		uint64_t reserved_0_7:8;
+#else
+		uint64_t reserved_0_7:8;
+		uint64_t pc_thr:20;
+		uint64_t reserved_28_31:4;
+		uint64_t pc:28;
+		uint64_t reserved_60_63:4;
+#endif
 	} s;
 	struct cvmx_pow_wq_int_pc_s cn30xx;
 	struct cvmx_pow_wq_int_pc_s cn31xx;
@@ -675,13 +1139,17 @@
 	struct cvmx_pow_wq_int_pc_s cn56xxp1;
 	struct cvmx_pow_wq_int_pc_s cn58xx;
 	struct cvmx_pow_wq_int_pc_s cn58xxp1;
+	struct cvmx_pow_wq_int_pc_s cn61xx;
 	struct cvmx_pow_wq_int_pc_s cn63xx;
 	struct cvmx_pow_wq_int_pc_s cn63xxp1;
+	struct cvmx_pow_wq_int_pc_s cn66xx;
+	struct cvmx_pow_wq_int_pc_s cnf71xx;
 };
 
 union cvmx_pow_wq_int_thrx {
 	uint64_t u64;
 	struct cvmx_pow_wq_int_thrx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_29_63:35;
 		uint64_t tc_en:1;
 		uint64_t tc_thr:4;
@@ -689,8 +1157,18 @@
 		uint64_t ds_thr:11;
 		uint64_t reserved_11_11:1;
 		uint64_t iq_thr:11;
+#else
+		uint64_t iq_thr:11;
+		uint64_t reserved_11_11:1;
+		uint64_t ds_thr:11;
+		uint64_t reserved_23_23:1;
+		uint64_t tc_thr:4;
+		uint64_t tc_en:1;
+		uint64_t reserved_29_63:35;
+#endif
 	} s;
 	struct cvmx_pow_wq_int_thrx_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_29_63:35;
 		uint64_t tc_en:1;
 		uint64_t tc_thr:4;
@@ -698,8 +1176,18 @@
 		uint64_t ds_thr:6;
 		uint64_t reserved_6_11:6;
 		uint64_t iq_thr:6;
+#else
+		uint64_t iq_thr:6;
+		uint64_t reserved_6_11:6;
+		uint64_t ds_thr:6;
+		uint64_t reserved_18_23:6;
+		uint64_t tc_thr:4;
+		uint64_t tc_en:1;
+		uint64_t reserved_29_63:35;
+#endif
 	} cn30xx;
 	struct cvmx_pow_wq_int_thrx_cn31xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_29_63:35;
 		uint64_t tc_en:1;
 		uint64_t tc_thr:4;
@@ -707,11 +1195,21 @@
 		uint64_t ds_thr:8;
 		uint64_t reserved_8_11:4;
 		uint64_t iq_thr:8;
+#else
+		uint64_t iq_thr:8;
+		uint64_t reserved_8_11:4;
+		uint64_t ds_thr:8;
+		uint64_t reserved_20_23:4;
+		uint64_t tc_thr:4;
+		uint64_t tc_en:1;
+		uint64_t reserved_29_63:35;
+#endif
 	} cn31xx;
 	struct cvmx_pow_wq_int_thrx_s cn38xx;
 	struct cvmx_pow_wq_int_thrx_s cn38xxp2;
 	struct cvmx_pow_wq_int_thrx_cn31xx cn50xx;
 	struct cvmx_pow_wq_int_thrx_cn52xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_29_63:35;
 		uint64_t tc_en:1;
 		uint64_t tc_thr:4;
@@ -719,13 +1217,24 @@
 		uint64_t ds_thr:9;
 		uint64_t reserved_9_11:3;
 		uint64_t iq_thr:9;
+#else
+		uint64_t iq_thr:9;
+		uint64_t reserved_9_11:3;
+		uint64_t ds_thr:9;
+		uint64_t reserved_21_23:3;
+		uint64_t tc_thr:4;
+		uint64_t tc_en:1;
+		uint64_t reserved_29_63:35;
+#endif
 	} cn52xx;
 	struct cvmx_pow_wq_int_thrx_cn52xx cn52xxp1;
 	struct cvmx_pow_wq_int_thrx_s cn56xx;
 	struct cvmx_pow_wq_int_thrx_s cn56xxp1;
 	struct cvmx_pow_wq_int_thrx_s cn58xx;
 	struct cvmx_pow_wq_int_thrx_s cn58xxp1;
+	struct cvmx_pow_wq_int_thrx_cn52xx cn61xx;
 	struct cvmx_pow_wq_int_thrx_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_29_63:35;
 		uint64_t tc_en:1;
 		uint64_t tc_thr:4;
@@ -733,15 +1242,31 @@
 		uint64_t ds_thr:10;
 		uint64_t reserved_10_11:2;
 		uint64_t iq_thr:10;
+#else
+		uint64_t iq_thr:10;
+		uint64_t reserved_10_11:2;
+		uint64_t ds_thr:10;
+		uint64_t reserved_22_23:2;
+		uint64_t tc_thr:4;
+		uint64_t tc_en:1;
+		uint64_t reserved_29_63:35;
+#endif
 	} cn63xx;
 	struct cvmx_pow_wq_int_thrx_cn63xx cn63xxp1;
+	struct cvmx_pow_wq_int_thrx_cn63xx cn66xx;
+	struct cvmx_pow_wq_int_thrx_cn52xx cnf71xx;
 };
 
 union cvmx_pow_ws_pcx {
 	uint64_t u64;
 	struct cvmx_pow_ws_pcx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t ws_pc:32;
+#else
+		uint64_t ws_pc:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_pow_ws_pcx_s cn30xx;
 	struct cvmx_pow_ws_pcx_s cn31xx;
@@ -754,8 +1279,11 @@
 	struct cvmx_pow_ws_pcx_s cn56xxp1;
 	struct cvmx_pow_ws_pcx_s cn58xx;
 	struct cvmx_pow_ws_pcx_s cn58xxp1;
+	struct cvmx_pow_ws_pcx_s cn61xx;
 	struct cvmx_pow_ws_pcx_s cn63xx;
 	struct cvmx_pow_ws_pcx_s cn63xxp1;
+	struct cvmx_pow_ws_pcx_s cn66xx;
+	struct cvmx_pow_ws_pcx_s cnf71xx;
 };
 
 #endif
diff --git a/arch/mips/include/asm/octeon/cvmx-rnm-defs.h b/arch/mips/include/asm/octeon/cvmx-rnm-defs.h
index c45da1f..87d6f92 100644
--- a/arch/mips/include/asm/octeon/cvmx-rnm-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-rnm-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -28,8 +28,6 @@
 #ifndef __CVMX_RNM_DEFS_H__
 #define __CVMX_RNM_DEFS_H__
 
-#include <linux/types.h>
-
 #define CVMX_RNM_BIST_STATUS (CVMX_ADD_IO_SEG(0x0001180040000008ull))
 #define CVMX_RNM_CTL_STATUS (CVMX_ADD_IO_SEG(0x0001180040000000ull))
 #define CVMX_RNM_EER_DBG (CVMX_ADD_IO_SEG(0x0001180040000018ull))
@@ -39,9 +37,15 @@
 union cvmx_rnm_bist_status {
 	uint64_t u64;
 	struct cvmx_rnm_bist_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t rrc:1;
 		uint64_t mem:1;
+#else
+		uint64_t mem:1;
+		uint64_t rrc:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_rnm_bist_status_s cn30xx;
 	struct cvmx_rnm_bist_status_s cn31xx;
@@ -54,13 +58,88 @@
 	struct cvmx_rnm_bist_status_s cn56xxp1;
 	struct cvmx_rnm_bist_status_s cn58xx;
 	struct cvmx_rnm_bist_status_s cn58xxp1;
+	struct cvmx_rnm_bist_status_s cn61xx;
 	struct cvmx_rnm_bist_status_s cn63xx;
 	struct cvmx_rnm_bist_status_s cn63xxp1;
+	struct cvmx_rnm_bist_status_s cn66xx;
+	struct cvmx_rnm_bist_status_s cn68xx;
+	struct cvmx_rnm_bist_status_s cn68xxp1;
+	struct cvmx_rnm_bist_status_s cnf71xx;
 };
 
 union cvmx_rnm_ctl_status {
 	uint64_t u64;
 	struct cvmx_rnm_ctl_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_12_63:52;
+		uint64_t dis_mak:1;
+		uint64_t eer_lck:1;
+		uint64_t eer_val:1;
+		uint64_t ent_sel:4;
+		uint64_t exp_ent:1;
+		uint64_t rng_rst:1;
+		uint64_t rnm_rst:1;
+		uint64_t rng_en:1;
+		uint64_t ent_en:1;
+#else
+		uint64_t ent_en:1;
+		uint64_t rng_en:1;
+		uint64_t rnm_rst:1;
+		uint64_t rng_rst:1;
+		uint64_t exp_ent:1;
+		uint64_t ent_sel:4;
+		uint64_t eer_val:1;
+		uint64_t eer_lck:1;
+		uint64_t dis_mak:1;
+		uint64_t reserved_12_63:52;
+#endif
+	} s;
+	struct cvmx_rnm_ctl_status_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_4_63:60;
+		uint64_t rng_rst:1;
+		uint64_t rnm_rst:1;
+		uint64_t rng_en:1;
+		uint64_t ent_en:1;
+#else
+		uint64_t ent_en:1;
+		uint64_t rng_en:1;
+		uint64_t rnm_rst:1;
+		uint64_t rng_rst:1;
+		uint64_t reserved_4_63:60;
+#endif
+	} cn30xx;
+	struct cvmx_rnm_ctl_status_cn30xx cn31xx;
+	struct cvmx_rnm_ctl_status_cn30xx cn38xx;
+	struct cvmx_rnm_ctl_status_cn30xx cn38xxp2;
+	struct cvmx_rnm_ctl_status_cn50xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+		uint64_t reserved_9_63:55;
+		uint64_t ent_sel:4;
+		uint64_t exp_ent:1;
+		uint64_t rng_rst:1;
+		uint64_t rnm_rst:1;
+		uint64_t rng_en:1;
+		uint64_t ent_en:1;
+#else
+		uint64_t ent_en:1;
+		uint64_t rng_en:1;
+		uint64_t rnm_rst:1;
+		uint64_t rng_rst:1;
+		uint64_t exp_ent:1;
+		uint64_t ent_sel:4;
+		uint64_t reserved_9_63:55;
+#endif
+	} cn50xx;
+	struct cvmx_rnm_ctl_status_cn50xx cn52xx;
+	struct cvmx_rnm_ctl_status_cn50xx cn52xxp1;
+	struct cvmx_rnm_ctl_status_cn50xx cn56xx;
+	struct cvmx_rnm_ctl_status_cn50xx cn56xxp1;
+	struct cvmx_rnm_ctl_status_cn50xx cn58xx;
+	struct cvmx_rnm_ctl_status_cn50xx cn58xxp1;
+	struct cvmx_rnm_ctl_status_s cn61xx;
+	struct cvmx_rnm_ctl_status_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_11_63:53;
 		uint64_t eer_lck:1;
 		uint64_t eer_val:1;
@@ -70,60 +149,76 @@
 		uint64_t rnm_rst:1;
 		uint64_t rng_en:1;
 		uint64_t ent_en:1;
-	} s;
-	struct cvmx_rnm_ctl_status_cn30xx {
-		uint64_t reserved_4_63:60;
-		uint64_t rng_rst:1;
-		uint64_t rnm_rst:1;
-		uint64_t rng_en:1;
+#else
 		uint64_t ent_en:1;
-	} cn30xx;
-	struct cvmx_rnm_ctl_status_cn30xx cn31xx;
-	struct cvmx_rnm_ctl_status_cn30xx cn38xx;
-	struct cvmx_rnm_ctl_status_cn30xx cn38xxp2;
-	struct cvmx_rnm_ctl_status_cn50xx {
-		uint64_t reserved_9_63:55;
-		uint64_t ent_sel:4;
+		uint64_t rng_en:1;
+		uint64_t rnm_rst:1;
+		uint64_t rng_rst:1;
 		uint64_t exp_ent:1;
-		uint64_t rng_rst:1;
-		uint64_t rnm_rst:1;
-		uint64_t rng_en:1;
-		uint64_t ent_en:1;
-	} cn50xx;
-	struct cvmx_rnm_ctl_status_cn50xx cn52xx;
-	struct cvmx_rnm_ctl_status_cn50xx cn52xxp1;
-	struct cvmx_rnm_ctl_status_cn50xx cn56xx;
-	struct cvmx_rnm_ctl_status_cn50xx cn56xxp1;
-	struct cvmx_rnm_ctl_status_cn50xx cn58xx;
-	struct cvmx_rnm_ctl_status_cn50xx cn58xxp1;
-	struct cvmx_rnm_ctl_status_s cn63xx;
-	struct cvmx_rnm_ctl_status_s cn63xxp1;
+		uint64_t ent_sel:4;
+		uint64_t eer_val:1;
+		uint64_t eer_lck:1;
+		uint64_t reserved_11_63:53;
+#endif
+	} cn63xx;
+	struct cvmx_rnm_ctl_status_cn63xx cn63xxp1;
+	struct cvmx_rnm_ctl_status_s cn66xx;
+	struct cvmx_rnm_ctl_status_cn63xx cn68xx;
+	struct cvmx_rnm_ctl_status_cn63xx cn68xxp1;
+	struct cvmx_rnm_ctl_status_s cnf71xx;
 };
 
 union cvmx_rnm_eer_dbg {
 	uint64_t u64;
 	struct cvmx_rnm_eer_dbg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t dat:64;
+#else
+		uint64_t dat:64;
+#endif
 	} s;
+	struct cvmx_rnm_eer_dbg_s cn61xx;
 	struct cvmx_rnm_eer_dbg_s cn63xx;
 	struct cvmx_rnm_eer_dbg_s cn63xxp1;
+	struct cvmx_rnm_eer_dbg_s cn66xx;
+	struct cvmx_rnm_eer_dbg_s cn68xx;
+	struct cvmx_rnm_eer_dbg_s cn68xxp1;
+	struct cvmx_rnm_eer_dbg_s cnf71xx;
 };
 
 union cvmx_rnm_eer_key {
 	uint64_t u64;
 	struct cvmx_rnm_eer_key_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t key:64;
+#else
+		uint64_t key:64;
+#endif
 	} s;
+	struct cvmx_rnm_eer_key_s cn61xx;
 	struct cvmx_rnm_eer_key_s cn63xx;
 	struct cvmx_rnm_eer_key_s cn63xxp1;
+	struct cvmx_rnm_eer_key_s cn66xx;
+	struct cvmx_rnm_eer_key_s cn68xx;
+	struct cvmx_rnm_eer_key_s cn68xxp1;
+	struct cvmx_rnm_eer_key_s cnf71xx;
 };
 
 union cvmx_rnm_serial_num {
 	uint64_t u64;
 	struct cvmx_rnm_serial_num_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t dat:64;
+#else
+		uint64_t dat:64;
+#endif
 	} s;
+	struct cvmx_rnm_serial_num_s cn61xx;
 	struct cvmx_rnm_serial_num_s cn63xx;
+	struct cvmx_rnm_serial_num_s cn66xx;
+	struct cvmx_rnm_serial_num_s cn68xx;
+	struct cvmx_rnm_serial_num_s cn68xxp1;
+	struct cvmx_rnm_serial_num_s cnf71xx;
 };
 
 #endif
diff --git a/arch/mips/include/asm/octeon/cvmx-sli-defs.h b/arch/mips/include/asm/octeon/cvmx-sli-defs.h
index 7c6c901..e697c2f 100644
--- a/arch/mips/include/asm/octeon/cvmx-sli-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-sli-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2011 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -127,6 +127,7 @@
 union cvmx_sli_bist_status {
 	uint64_t u64;
 	struct cvmx_sli_bist_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t ncb_req:1;
 		uint64_t n2p0_c:1;
@@ -153,8 +154,37 @@
 		uint64_t dsi0_0:1;
 		uint64_t msi:1;
 		uint64_t ncb_cmd:1;
+#else
+		uint64_t ncb_cmd:1;
+		uint64_t msi:1;
+		uint64_t dsi0_0:1;
+		uint64_t dsi0_1:1;
+		uint64_t dsi1_0:1;
+		uint64_t dsi1_1:1;
+		uint64_t reserved_6_8:3;
+		uint64_t p2n1_p1:1;
+		uint64_t p2n1_p0:1;
+		uint64_t p2n1_n:1;
+		uint64_t p2n1_c1:1;
+		uint64_t p2n1_c0:1;
+		uint64_t p2n0_p1:1;
+		uint64_t p2n0_p0:1;
+		uint64_t p2n0_n:1;
+		uint64_t p2n0_c1:1;
+		uint64_t p2n0_c0:1;
+		uint64_t reserved_19_24:6;
+		uint64_t cpl_p1:1;
+		uint64_t cpl_p0:1;
+		uint64_t n2p1_o:1;
+		uint64_t n2p1_c:1;
+		uint64_t n2p0_o:1;
+		uint64_t n2p0_c:1;
+		uint64_t ncb_req:1;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sli_bist_status_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_31_63:33;
 		uint64_t n2p0_c:1;
 		uint64_t n2p0_o:1;
@@ -179,8 +209,35 @@
 		uint64_t dsi0_0:1;
 		uint64_t msi:1;
 		uint64_t ncb_cmd:1;
+#else
+		uint64_t ncb_cmd:1;
+		uint64_t msi:1;
+		uint64_t dsi0_0:1;
+		uint64_t dsi0_1:1;
+		uint64_t dsi1_0:1;
+		uint64_t dsi1_1:1;
+		uint64_t reserved_6_8:3;
+		uint64_t p2n1_p1:1;
+		uint64_t p2n1_p0:1;
+		uint64_t p2n1_n:1;
+		uint64_t p2n1_c1:1;
+		uint64_t p2n1_c0:1;
+		uint64_t p2n0_p1:1;
+		uint64_t p2n0_p0:1;
+		uint64_t p2n0_n:1;
+		uint64_t p2n0_c1:1;
+		uint64_t p2n0_c0:1;
+		uint64_t reserved_19_24:6;
+		uint64_t cpl_p1:1;
+		uint64_t cpl_p0:1;
+		uint64_t reserved_27_28:2;
+		uint64_t n2p0_o:1;
+		uint64_t n2p0_c:1;
+		uint64_t reserved_31_63:33;
+#endif
 	} cn61xx;
 	struct cvmx_sli_bist_status_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_31_63:33;
 		uint64_t n2p0_c:1;
 		uint64_t n2p0_o:1;
@@ -206,16 +263,45 @@
 		uint64_t dsi0_0:1;
 		uint64_t msi:1;
 		uint64_t ncb_cmd:1;
+#else
+		uint64_t ncb_cmd:1;
+		uint64_t msi:1;
+		uint64_t dsi0_0:1;
+		uint64_t dsi0_1:1;
+		uint64_t dsi1_0:1;
+		uint64_t dsi1_1:1;
+		uint64_t reserved_6_8:3;
+		uint64_t p2n1_p1:1;
+		uint64_t p2n1_p0:1;
+		uint64_t p2n1_n:1;
+		uint64_t p2n1_c1:1;
+		uint64_t p2n1_c0:1;
+		uint64_t p2n0_p1:1;
+		uint64_t p2n0_p0:1;
+		uint64_t p2n0_n:1;
+		uint64_t p2n0_c1:1;
+		uint64_t p2n0_c0:1;
+		uint64_t reserved_19_24:6;
+		uint64_t cpl_p1:1;
+		uint64_t cpl_p0:1;
+		uint64_t n2p1_o:1;
+		uint64_t n2p1_c:1;
+		uint64_t n2p0_o:1;
+		uint64_t n2p0_c:1;
+		uint64_t reserved_31_63:33;
+#endif
 	} cn63xx;
 	struct cvmx_sli_bist_status_cn63xx cn63xxp1;
 	struct cvmx_sli_bist_status_cn61xx cn66xx;
 	struct cvmx_sli_bist_status_s cn68xx;
 	struct cvmx_sli_bist_status_s cn68xxp1;
+	struct cvmx_sli_bist_status_cn61xx cnf71xx;
 };
 
 union cvmx_sli_ctl_portx {
 	uint64_t u64;
 	struct cvmx_sli_ctl_portx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_22_63:42;
 		uint64_t intd:1;
 		uint64_t intc:1;
@@ -232,6 +318,24 @@
 		uint64_t ptlp_ro:1;
 		uint64_t reserved_1_4:4;
 		uint64_t wait_com:1;
+#else
+		uint64_t wait_com:1;
+		uint64_t reserved_1_4:4;
+		uint64_t ptlp_ro:1;
+		uint64_t reserved_6_6:1;
+		uint64_t ctlp_ro:1;
+		uint64_t inta_map:2;
+		uint64_t intb_map:2;
+		uint64_t intc_map:2;
+		uint64_t intd_map:2;
+		uint64_t waitl_com:1;
+		uint64_t dis_port:1;
+		uint64_t inta:1;
+		uint64_t intb:1;
+		uint64_t intc:1;
+		uint64_t intd:1;
+		uint64_t reserved_22_63:42;
+#endif
 	} s;
 	struct cvmx_sli_ctl_portx_s cn61xx;
 	struct cvmx_sli_ctl_portx_s cn63xx;
@@ -239,36 +343,59 @@
 	struct cvmx_sli_ctl_portx_s cn66xx;
 	struct cvmx_sli_ctl_portx_s cn68xx;
 	struct cvmx_sli_ctl_portx_s cn68xxp1;
+	struct cvmx_sli_ctl_portx_s cnf71xx;
 };
 
 union cvmx_sli_ctl_status {
 	uint64_t u64;
 	struct cvmx_sli_ctl_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t p1_ntags:6;
 		uint64_t p0_ntags:6;
 		uint64_t chip_rev:8;
+#else
+		uint64_t chip_rev:8;
+		uint64_t p0_ntags:6;
+		uint64_t p1_ntags:6;
+		uint64_t reserved_20_63:44;
+#endif
 	} s;
 	struct cvmx_sli_ctl_status_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_14_63:50;
 		uint64_t p0_ntags:6;
 		uint64_t chip_rev:8;
+#else
+		uint64_t chip_rev:8;
+		uint64_t p0_ntags:6;
+		uint64_t reserved_14_63:50;
+#endif
 	} cn61xx;
 	struct cvmx_sli_ctl_status_s cn63xx;
 	struct cvmx_sli_ctl_status_s cn63xxp1;
 	struct cvmx_sli_ctl_status_cn61xx cn66xx;
 	struct cvmx_sli_ctl_status_s cn68xx;
 	struct cvmx_sli_ctl_status_s cn68xxp1;
+	struct cvmx_sli_ctl_status_cn61xx cnf71xx;
 };
 
 union cvmx_sli_data_out_cnt {
 	uint64_t u64;
 	struct cvmx_sli_data_out_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_44_63:20;
 		uint64_t p1_ucnt:16;
 		uint64_t p1_fcnt:6;
 		uint64_t p0_ucnt:16;
 		uint64_t p0_fcnt:6;
+#else
+		uint64_t p0_fcnt:6;
+		uint64_t p0_ucnt:16;
+		uint64_t p1_fcnt:6;
+		uint64_t p1_ucnt:16;
+		uint64_t reserved_44_63:20;
+#endif
 	} s;
 	struct cvmx_sli_data_out_cnt_s cn61xx;
 	struct cvmx_sli_data_out_cnt_s cn63xx;
@@ -276,14 +403,21 @@
 	struct cvmx_sli_data_out_cnt_s cn66xx;
 	struct cvmx_sli_data_out_cnt_s cn68xx;
 	struct cvmx_sli_data_out_cnt_s cn68xxp1;
+	struct cvmx_sli_data_out_cnt_s cnf71xx;
 };
 
 union cvmx_sli_dbg_data {
 	uint64_t u64;
 	struct cvmx_sli_dbg_data_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_18_63:46;
 		uint64_t dsel_ext:1;
 		uint64_t data:17;
+#else
+		uint64_t data:17;
+		uint64_t dsel_ext:1;
+		uint64_t reserved_18_63:46;
+#endif
 	} s;
 	struct cvmx_sli_dbg_data_s cn61xx;
 	struct cvmx_sli_dbg_data_s cn63xx;
@@ -291,14 +425,21 @@
 	struct cvmx_sli_dbg_data_s cn66xx;
 	struct cvmx_sli_dbg_data_s cn68xx;
 	struct cvmx_sli_dbg_data_s cn68xxp1;
+	struct cvmx_sli_dbg_data_s cnf71xx;
 };
 
 union cvmx_sli_dbg_select {
 	uint64_t u64;
 	struct cvmx_sli_dbg_select_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_33_63:31;
 		uint64_t adbg_sel:1;
 		uint64_t dbg_sel:32;
+#else
+		uint64_t dbg_sel:32;
+		uint64_t adbg_sel:1;
+		uint64_t reserved_33_63:31;
+#endif
 	} s;
 	struct cvmx_sli_dbg_select_s cn61xx;
 	struct cvmx_sli_dbg_select_s cn63xx;
@@ -306,13 +447,19 @@
 	struct cvmx_sli_dbg_select_s cn66xx;
 	struct cvmx_sli_dbg_select_s cn68xx;
 	struct cvmx_sli_dbg_select_s cn68xxp1;
+	struct cvmx_sli_dbg_select_s cnf71xx;
 };
 
 union cvmx_sli_dmax_cnt {
 	uint64_t u64;
 	struct cvmx_sli_dmax_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sli_dmax_cnt_s cn61xx;
 	struct cvmx_sli_dmax_cnt_s cn63xx;
@@ -320,13 +467,19 @@
 	struct cvmx_sli_dmax_cnt_s cn66xx;
 	struct cvmx_sli_dmax_cnt_s cn68xx;
 	struct cvmx_sli_dmax_cnt_s cn68xxp1;
+	struct cvmx_sli_dmax_cnt_s cnf71xx;
 };
 
 union cvmx_sli_dmax_int_level {
 	uint64_t u64;
 	struct cvmx_sli_dmax_int_level_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t time:32;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t time:32;
+#endif
 	} s;
 	struct cvmx_sli_dmax_int_level_s cn61xx;
 	struct cvmx_sli_dmax_int_level_s cn63xx;
@@ -334,13 +487,19 @@
 	struct cvmx_sli_dmax_int_level_s cn66xx;
 	struct cvmx_sli_dmax_int_level_s cn68xx;
 	struct cvmx_sli_dmax_int_level_s cn68xxp1;
+	struct cvmx_sli_dmax_int_level_s cnf71xx;
 };
 
 union cvmx_sli_dmax_tim {
 	uint64_t u64;
 	struct cvmx_sli_dmax_tim_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t tim:32;
+#else
+		uint64_t tim:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sli_dmax_tim_s cn61xx;
 	struct cvmx_sli_dmax_tim_s cn63xx;
@@ -348,11 +507,13 @@
 	struct cvmx_sli_dmax_tim_s cn66xx;
 	struct cvmx_sli_dmax_tim_s cn68xx;
 	struct cvmx_sli_dmax_tim_s cn68xxp1;
+	struct cvmx_sli_dmax_tim_s cnf71xx;
 };
 
 union cvmx_sli_int_enb_ciu {
 	uint64_t u64;
 	struct cvmx_sli_int_enb_ciu_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_62_63:2;
 		uint64_t pipe_err:1;
 		uint64_t ill_pad:1;
@@ -399,8 +560,57 @@
 		uint64_t bar0_to:1;
 		uint64_t reserved_1_1:1;
 		uint64_t rml_to:1;
+#else
+		uint64_t rml_to:1;
+		uint64_t reserved_1_1:1;
+		uint64_t bar0_to:1;
+		uint64_t iob2big:1;
+		uint64_t pcnt:1;
+		uint64_t ptime:1;
+		uint64_t reserved_6_7:2;
+		uint64_t m0_up_b0:1;
+		uint64_t m0_up_wi:1;
+		uint64_t m0_un_b0:1;
+		uint64_t m0_un_wi:1;
+		uint64_t m1_up_b0:1;
+		uint64_t m1_up_wi:1;
+		uint64_t m1_un_b0:1;
+		uint64_t m1_un_wi:1;
+		uint64_t mio_int0:1;
+		uint64_t mio_int1:1;
+		uint64_t reserved_18_19:2;
+		uint64_t m2_up_b0:1;
+		uint64_t m2_up_wi:1;
+		uint64_t m2_un_b0:1;
+		uint64_t m2_un_wi:1;
+		uint64_t m3_up_b0:1;
+		uint64_t m3_up_wi:1;
+		uint64_t m3_un_b0:1;
+		uint64_t m3_un_wi:1;
+		uint64_t reserved_28_31:4;
+		uint64_t dmafi:2;
+		uint64_t dcnt:2;
+		uint64_t dtime:2;
+		uint64_t reserved_38_47:10;
+		uint64_t pidbof:1;
+		uint64_t psldbof:1;
+		uint64_t pout_err:1;
+		uint64_t pin_bp:1;
+		uint64_t pgl_err:1;
+		uint64_t pdi_err:1;
+		uint64_t pop_err:1;
+		uint64_t pins_err:1;
+		uint64_t sprt0_err:1;
+		uint64_t sprt1_err:1;
+		uint64_t sprt2_err:1;
+		uint64_t sprt3_err:1;
+		uint64_t ill_pad:1;
+		uint64_t pipe_err:1;
+		uint64_t reserved_62_63:2;
+#endif
 	} s;
 	struct cvmx_sli_int_enb_ciu_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_61_63:3;
 		uint64_t ill_pad:1;
 		uint64_t sprt3_err:1;
@@ -446,8 +656,56 @@
 		uint64_t bar0_to:1;
 		uint64_t reserved_1_1:1;
 		uint64_t rml_to:1;
+#else
+		uint64_t rml_to:1;
+		uint64_t reserved_1_1:1;
+		uint64_t bar0_to:1;
+		uint64_t iob2big:1;
+		uint64_t pcnt:1;
+		uint64_t ptime:1;
+		uint64_t reserved_6_7:2;
+		uint64_t m0_up_b0:1;
+		uint64_t m0_up_wi:1;
+		uint64_t m0_un_b0:1;
+		uint64_t m0_un_wi:1;
+		uint64_t m1_up_b0:1;
+		uint64_t m1_up_wi:1;
+		uint64_t m1_un_b0:1;
+		uint64_t m1_un_wi:1;
+		uint64_t mio_int0:1;
+		uint64_t mio_int1:1;
+		uint64_t reserved_18_19:2;
+		uint64_t m2_up_b0:1;
+		uint64_t m2_up_wi:1;
+		uint64_t m2_un_b0:1;
+		uint64_t m2_un_wi:1;
+		uint64_t m3_up_b0:1;
+		uint64_t m3_up_wi:1;
+		uint64_t m3_un_b0:1;
+		uint64_t m3_un_wi:1;
+		uint64_t reserved_28_31:4;
+		uint64_t dmafi:2;
+		uint64_t dcnt:2;
+		uint64_t dtime:2;
+		uint64_t reserved_38_47:10;
+		uint64_t pidbof:1;
+		uint64_t psldbof:1;
+		uint64_t pout_err:1;
+		uint64_t pin_bp:1;
+		uint64_t pgl_err:1;
+		uint64_t pdi_err:1;
+		uint64_t pop_err:1;
+		uint64_t pins_err:1;
+		uint64_t sprt0_err:1;
+		uint64_t sprt1_err:1;
+		uint64_t sprt2_err:1;
+		uint64_t sprt3_err:1;
+		uint64_t ill_pad:1;
+		uint64_t reserved_61_63:3;
+#endif
 	} cn61xx;
 	struct cvmx_sli_int_enb_ciu_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_61_63:3;
 		uint64_t ill_pad:1;
 		uint64_t reserved_58_59:2;
@@ -483,10 +741,48 @@
 		uint64_t bar0_to:1;
 		uint64_t reserved_1_1:1;
 		uint64_t rml_to:1;
+#else
+		uint64_t rml_to:1;
+		uint64_t reserved_1_1:1;
+		uint64_t bar0_to:1;
+		uint64_t iob2big:1;
+		uint64_t pcnt:1;
+		uint64_t ptime:1;
+		uint64_t reserved_6_7:2;
+		uint64_t m0_up_b0:1;
+		uint64_t m0_up_wi:1;
+		uint64_t m0_un_b0:1;
+		uint64_t m0_un_wi:1;
+		uint64_t m1_up_b0:1;
+		uint64_t m1_up_wi:1;
+		uint64_t m1_un_b0:1;
+		uint64_t m1_un_wi:1;
+		uint64_t mio_int0:1;
+		uint64_t mio_int1:1;
+		uint64_t reserved_18_31:14;
+		uint64_t dmafi:2;
+		uint64_t dcnt:2;
+		uint64_t dtime:2;
+		uint64_t reserved_38_47:10;
+		uint64_t pidbof:1;
+		uint64_t psldbof:1;
+		uint64_t pout_err:1;
+		uint64_t pin_bp:1;
+		uint64_t pgl_err:1;
+		uint64_t pdi_err:1;
+		uint64_t pop_err:1;
+		uint64_t pins_err:1;
+		uint64_t sprt0_err:1;
+		uint64_t sprt1_err:1;
+		uint64_t reserved_58_59:2;
+		uint64_t ill_pad:1;
+		uint64_t reserved_61_63:3;
+#endif
 	} cn63xx;
 	struct cvmx_sli_int_enb_ciu_cn63xx cn63xxp1;
 	struct cvmx_sli_int_enb_ciu_cn61xx cn66xx;
 	struct cvmx_sli_int_enb_ciu_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_62_63:2;
 		uint64_t pipe_err:1;
 		uint64_t ill_pad:1;
@@ -523,13 +819,53 @@
 		uint64_t bar0_to:1;
 		uint64_t reserved_1_1:1;
 		uint64_t rml_to:1;
+#else
+		uint64_t rml_to:1;
+		uint64_t reserved_1_1:1;
+		uint64_t bar0_to:1;
+		uint64_t iob2big:1;
+		uint64_t pcnt:1;
+		uint64_t ptime:1;
+		uint64_t reserved_6_7:2;
+		uint64_t m0_up_b0:1;
+		uint64_t m0_up_wi:1;
+		uint64_t m0_un_b0:1;
+		uint64_t m0_un_wi:1;
+		uint64_t m1_up_b0:1;
+		uint64_t m1_up_wi:1;
+		uint64_t m1_un_b0:1;
+		uint64_t m1_un_wi:1;
+		uint64_t mio_int0:1;
+		uint64_t mio_int1:1;
+		uint64_t reserved_18_31:14;
+		uint64_t dmafi:2;
+		uint64_t dcnt:2;
+		uint64_t dtime:2;
+		uint64_t reserved_38_47:10;
+		uint64_t pidbof:1;
+		uint64_t psldbof:1;
+		uint64_t pout_err:1;
+		uint64_t reserved_51_51:1;
+		uint64_t pgl_err:1;
+		uint64_t pdi_err:1;
+		uint64_t pop_err:1;
+		uint64_t pins_err:1;
+		uint64_t sprt0_err:1;
+		uint64_t sprt1_err:1;
+		uint64_t reserved_58_59:2;
+		uint64_t ill_pad:1;
+		uint64_t pipe_err:1;
+		uint64_t reserved_62_63:2;
+#endif
 	} cn68xx;
 	struct cvmx_sli_int_enb_ciu_cn68xx cn68xxp1;
+	struct cvmx_sli_int_enb_ciu_cn61xx cnf71xx;
 };
 
 union cvmx_sli_int_enb_portx {
 	uint64_t u64;
 	struct cvmx_sli_int_enb_portx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_62_63:2;
 		uint64_t pipe_err:1;
 		uint64_t ill_pad:1;
@@ -577,8 +913,58 @@
 		uint64_t bar0_to:1;
 		uint64_t reserved_1_1:1;
 		uint64_t rml_to:1;
+#else
+		uint64_t rml_to:1;
+		uint64_t reserved_1_1:1;
+		uint64_t bar0_to:1;
+		uint64_t iob2big:1;
+		uint64_t pcnt:1;
+		uint64_t ptime:1;
+		uint64_t reserved_6_7:2;
+		uint64_t m0_up_b0:1;
+		uint64_t m0_up_wi:1;
+		uint64_t m0_un_b0:1;
+		uint64_t m0_un_wi:1;
+		uint64_t m1_up_b0:1;
+		uint64_t m1_up_wi:1;
+		uint64_t m1_un_b0:1;
+		uint64_t m1_un_wi:1;
+		uint64_t mio_int0:1;
+		uint64_t mio_int1:1;
+		uint64_t mac0_int:1;
+		uint64_t mac1_int:1;
+		uint64_t m2_up_b0:1;
+		uint64_t m2_up_wi:1;
+		uint64_t m2_un_b0:1;
+		uint64_t m2_un_wi:1;
+		uint64_t m3_up_b0:1;
+		uint64_t m3_up_wi:1;
+		uint64_t m3_un_b0:1;
+		uint64_t m3_un_wi:1;
+		uint64_t reserved_28_31:4;
+		uint64_t dmafi:2;
+		uint64_t dcnt:2;
+		uint64_t dtime:2;
+		uint64_t reserved_38_47:10;
+		uint64_t pidbof:1;
+		uint64_t psldbof:1;
+		uint64_t pout_err:1;
+		uint64_t pin_bp:1;
+		uint64_t pgl_err:1;
+		uint64_t pdi_err:1;
+		uint64_t pop_err:1;
+		uint64_t pins_err:1;
+		uint64_t sprt0_err:1;
+		uint64_t sprt1_err:1;
+		uint64_t sprt2_err:1;
+		uint64_t sprt3_err:1;
+		uint64_t ill_pad:1;
+		uint64_t pipe_err:1;
+		uint64_t reserved_62_63:2;
+#endif
 	} s;
 	struct cvmx_sli_int_enb_portx_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_61_63:3;
 		uint64_t ill_pad:1;
 		uint64_t sprt3_err:1;
@@ -625,8 +1011,57 @@
 		uint64_t bar0_to:1;
 		uint64_t reserved_1_1:1;
 		uint64_t rml_to:1;
+#else
+		uint64_t rml_to:1;
+		uint64_t reserved_1_1:1;
+		uint64_t bar0_to:1;
+		uint64_t iob2big:1;
+		uint64_t pcnt:1;
+		uint64_t ptime:1;
+		uint64_t reserved_6_7:2;
+		uint64_t m0_up_b0:1;
+		uint64_t m0_up_wi:1;
+		uint64_t m0_un_b0:1;
+		uint64_t m0_un_wi:1;
+		uint64_t m1_up_b0:1;
+		uint64_t m1_up_wi:1;
+		uint64_t m1_un_b0:1;
+		uint64_t m1_un_wi:1;
+		uint64_t mio_int0:1;
+		uint64_t mio_int1:1;
+		uint64_t mac0_int:1;
+		uint64_t mac1_int:1;
+		uint64_t m2_up_b0:1;
+		uint64_t m2_up_wi:1;
+		uint64_t m2_un_b0:1;
+		uint64_t m2_un_wi:1;
+		uint64_t m3_up_b0:1;
+		uint64_t m3_up_wi:1;
+		uint64_t m3_un_b0:1;
+		uint64_t m3_un_wi:1;
+		uint64_t reserved_28_31:4;
+		uint64_t dmafi:2;
+		uint64_t dcnt:2;
+		uint64_t dtime:2;
+		uint64_t reserved_38_47:10;
+		uint64_t pidbof:1;
+		uint64_t psldbof:1;
+		uint64_t pout_err:1;
+		uint64_t pin_bp:1;
+		uint64_t pgl_err:1;
+		uint64_t pdi_err:1;
+		uint64_t pop_err:1;
+		uint64_t pins_err:1;
+		uint64_t sprt0_err:1;
+		uint64_t sprt1_err:1;
+		uint64_t sprt2_err:1;
+		uint64_t sprt3_err:1;
+		uint64_t ill_pad:1;
+		uint64_t reserved_61_63:3;
+#endif
 	} cn61xx;
 	struct cvmx_sli_int_enb_portx_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_61_63:3;
 		uint64_t ill_pad:1;
 		uint64_t reserved_58_59:2;
@@ -664,10 +1099,50 @@
 		uint64_t bar0_to:1;
 		uint64_t reserved_1_1:1;
 		uint64_t rml_to:1;
+#else
+		uint64_t rml_to:1;
+		uint64_t reserved_1_1:1;
+		uint64_t bar0_to:1;
+		uint64_t iob2big:1;
+		uint64_t pcnt:1;
+		uint64_t ptime:1;
+		uint64_t reserved_6_7:2;
+		uint64_t m0_up_b0:1;
+		uint64_t m0_up_wi:1;
+		uint64_t m0_un_b0:1;
+		uint64_t m0_un_wi:1;
+		uint64_t m1_up_b0:1;
+		uint64_t m1_up_wi:1;
+		uint64_t m1_un_b0:1;
+		uint64_t m1_un_wi:1;
+		uint64_t mio_int0:1;
+		uint64_t mio_int1:1;
+		uint64_t mac0_int:1;
+		uint64_t mac1_int:1;
+		uint64_t reserved_20_31:12;
+		uint64_t dmafi:2;
+		uint64_t dcnt:2;
+		uint64_t dtime:2;
+		uint64_t reserved_38_47:10;
+		uint64_t pidbof:1;
+		uint64_t psldbof:1;
+		uint64_t pout_err:1;
+		uint64_t pin_bp:1;
+		uint64_t pgl_err:1;
+		uint64_t pdi_err:1;
+		uint64_t pop_err:1;
+		uint64_t pins_err:1;
+		uint64_t sprt0_err:1;
+		uint64_t sprt1_err:1;
+		uint64_t reserved_58_59:2;
+		uint64_t ill_pad:1;
+		uint64_t reserved_61_63:3;
+#endif
 	} cn63xx;
 	struct cvmx_sli_int_enb_portx_cn63xx cn63xxp1;
 	struct cvmx_sli_int_enb_portx_cn61xx cn66xx;
 	struct cvmx_sli_int_enb_portx_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_62_63:2;
 		uint64_t pipe_err:1;
 		uint64_t ill_pad:1;
@@ -706,13 +1181,55 @@
 		uint64_t bar0_to:1;
 		uint64_t reserved_1_1:1;
 		uint64_t rml_to:1;
+#else
+		uint64_t rml_to:1;
+		uint64_t reserved_1_1:1;
+		uint64_t bar0_to:1;
+		uint64_t iob2big:1;
+		uint64_t pcnt:1;
+		uint64_t ptime:1;
+		uint64_t reserved_6_7:2;
+		uint64_t m0_up_b0:1;
+		uint64_t m0_up_wi:1;
+		uint64_t m0_un_b0:1;
+		uint64_t m0_un_wi:1;
+		uint64_t m1_up_b0:1;
+		uint64_t m1_up_wi:1;
+		uint64_t m1_un_b0:1;
+		uint64_t m1_un_wi:1;
+		uint64_t mio_int0:1;
+		uint64_t mio_int1:1;
+		uint64_t mac0_int:1;
+		uint64_t mac1_int:1;
+		uint64_t reserved_20_31:12;
+		uint64_t dmafi:2;
+		uint64_t dcnt:2;
+		uint64_t dtime:2;
+		uint64_t reserved_38_47:10;
+		uint64_t pidbof:1;
+		uint64_t psldbof:1;
+		uint64_t pout_err:1;
+		uint64_t reserved_51_51:1;
+		uint64_t pgl_err:1;
+		uint64_t pdi_err:1;
+		uint64_t pop_err:1;
+		uint64_t pins_err:1;
+		uint64_t sprt0_err:1;
+		uint64_t sprt1_err:1;
+		uint64_t reserved_58_59:2;
+		uint64_t ill_pad:1;
+		uint64_t pipe_err:1;
+		uint64_t reserved_62_63:2;
+#endif
 	} cn68xx;
 	struct cvmx_sli_int_enb_portx_cn68xx cn68xxp1;
+	struct cvmx_sli_int_enb_portx_cn61xx cnf71xx;
 };
 
 union cvmx_sli_int_sum {
 	uint64_t u64;
 	struct cvmx_sli_int_sum_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_62_63:2;
 		uint64_t pipe_err:1;
 		uint64_t ill_pad:1;
@@ -760,8 +1277,58 @@
 		uint64_t bar0_to:1;
 		uint64_t reserved_1_1:1;
 		uint64_t rml_to:1;
+#else
+		uint64_t rml_to:1;
+		uint64_t reserved_1_1:1;
+		uint64_t bar0_to:1;
+		uint64_t iob2big:1;
+		uint64_t pcnt:1;
+		uint64_t ptime:1;
+		uint64_t reserved_6_7:2;
+		uint64_t m0_up_b0:1;
+		uint64_t m0_up_wi:1;
+		uint64_t m0_un_b0:1;
+		uint64_t m0_un_wi:1;
+		uint64_t m1_up_b0:1;
+		uint64_t m1_up_wi:1;
+		uint64_t m1_un_b0:1;
+		uint64_t m1_un_wi:1;
+		uint64_t mio_int0:1;
+		uint64_t mio_int1:1;
+		uint64_t mac0_int:1;
+		uint64_t mac1_int:1;
+		uint64_t m2_up_b0:1;
+		uint64_t m2_up_wi:1;
+		uint64_t m2_un_b0:1;
+		uint64_t m2_un_wi:1;
+		uint64_t m3_up_b0:1;
+		uint64_t m3_up_wi:1;
+		uint64_t m3_un_b0:1;
+		uint64_t m3_un_wi:1;
+		uint64_t reserved_28_31:4;
+		uint64_t dmafi:2;
+		uint64_t dcnt:2;
+		uint64_t dtime:2;
+		uint64_t reserved_38_47:10;
+		uint64_t pidbof:1;
+		uint64_t psldbof:1;
+		uint64_t pout_err:1;
+		uint64_t pin_bp:1;
+		uint64_t pgl_err:1;
+		uint64_t pdi_err:1;
+		uint64_t pop_err:1;
+		uint64_t pins_err:1;
+		uint64_t sprt0_err:1;
+		uint64_t sprt1_err:1;
+		uint64_t sprt2_err:1;
+		uint64_t sprt3_err:1;
+		uint64_t ill_pad:1;
+		uint64_t pipe_err:1;
+		uint64_t reserved_62_63:2;
+#endif
 	} s;
 	struct cvmx_sli_int_sum_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_61_63:3;
 		uint64_t ill_pad:1;
 		uint64_t sprt3_err:1;
@@ -808,8 +1375,57 @@
 		uint64_t bar0_to:1;
 		uint64_t reserved_1_1:1;
 		uint64_t rml_to:1;
+#else
+		uint64_t rml_to:1;
+		uint64_t reserved_1_1:1;
+		uint64_t bar0_to:1;
+		uint64_t iob2big:1;
+		uint64_t pcnt:1;
+		uint64_t ptime:1;
+		uint64_t reserved_6_7:2;
+		uint64_t m0_up_b0:1;
+		uint64_t m0_up_wi:1;
+		uint64_t m0_un_b0:1;
+		uint64_t m0_un_wi:1;
+		uint64_t m1_up_b0:1;
+		uint64_t m1_up_wi:1;
+		uint64_t m1_un_b0:1;
+		uint64_t m1_un_wi:1;
+		uint64_t mio_int0:1;
+		uint64_t mio_int1:1;
+		uint64_t mac0_int:1;
+		uint64_t mac1_int:1;
+		uint64_t m2_up_b0:1;
+		uint64_t m2_up_wi:1;
+		uint64_t m2_un_b0:1;
+		uint64_t m2_un_wi:1;
+		uint64_t m3_up_b0:1;
+		uint64_t m3_up_wi:1;
+		uint64_t m3_un_b0:1;
+		uint64_t m3_un_wi:1;
+		uint64_t reserved_28_31:4;
+		uint64_t dmafi:2;
+		uint64_t dcnt:2;
+		uint64_t dtime:2;
+		uint64_t reserved_38_47:10;
+		uint64_t pidbof:1;
+		uint64_t psldbof:1;
+		uint64_t pout_err:1;
+		uint64_t pin_bp:1;
+		uint64_t pgl_err:1;
+		uint64_t pdi_err:1;
+		uint64_t pop_err:1;
+		uint64_t pins_err:1;
+		uint64_t sprt0_err:1;
+		uint64_t sprt1_err:1;
+		uint64_t sprt2_err:1;
+		uint64_t sprt3_err:1;
+		uint64_t ill_pad:1;
+		uint64_t reserved_61_63:3;
+#endif
 	} cn61xx;
 	struct cvmx_sli_int_sum_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_61_63:3;
 		uint64_t ill_pad:1;
 		uint64_t reserved_58_59:2;
@@ -847,10 +1463,50 @@
 		uint64_t bar0_to:1;
 		uint64_t reserved_1_1:1;
 		uint64_t rml_to:1;
+#else
+		uint64_t rml_to:1;
+		uint64_t reserved_1_1:1;
+		uint64_t bar0_to:1;
+		uint64_t iob2big:1;
+		uint64_t pcnt:1;
+		uint64_t ptime:1;
+		uint64_t reserved_6_7:2;
+		uint64_t m0_up_b0:1;
+		uint64_t m0_up_wi:1;
+		uint64_t m0_un_b0:1;
+		uint64_t m0_un_wi:1;
+		uint64_t m1_up_b0:1;
+		uint64_t m1_up_wi:1;
+		uint64_t m1_un_b0:1;
+		uint64_t m1_un_wi:1;
+		uint64_t mio_int0:1;
+		uint64_t mio_int1:1;
+		uint64_t mac0_int:1;
+		uint64_t mac1_int:1;
+		uint64_t reserved_20_31:12;
+		uint64_t dmafi:2;
+		uint64_t dcnt:2;
+		uint64_t dtime:2;
+		uint64_t reserved_38_47:10;
+		uint64_t pidbof:1;
+		uint64_t psldbof:1;
+		uint64_t pout_err:1;
+		uint64_t pin_bp:1;
+		uint64_t pgl_err:1;
+		uint64_t pdi_err:1;
+		uint64_t pop_err:1;
+		uint64_t pins_err:1;
+		uint64_t sprt0_err:1;
+		uint64_t sprt1_err:1;
+		uint64_t reserved_58_59:2;
+		uint64_t ill_pad:1;
+		uint64_t reserved_61_63:3;
+#endif
 	} cn63xx;
 	struct cvmx_sli_int_sum_cn63xx cn63xxp1;
 	struct cvmx_sli_int_sum_cn61xx cn66xx;
 	struct cvmx_sli_int_sum_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_62_63:2;
 		uint64_t pipe_err:1;
 		uint64_t ill_pad:1;
@@ -889,14 +1545,59 @@
 		uint64_t bar0_to:1;
 		uint64_t reserved_1_1:1;
 		uint64_t rml_to:1;
+#else
+		uint64_t rml_to:1;
+		uint64_t reserved_1_1:1;
+		uint64_t bar0_to:1;
+		uint64_t iob2big:1;
+		uint64_t pcnt:1;
+		uint64_t ptime:1;
+		uint64_t reserved_6_7:2;
+		uint64_t m0_up_b0:1;
+		uint64_t m0_up_wi:1;
+		uint64_t m0_un_b0:1;
+		uint64_t m0_un_wi:1;
+		uint64_t m1_up_b0:1;
+		uint64_t m1_up_wi:1;
+		uint64_t m1_un_b0:1;
+		uint64_t m1_un_wi:1;
+		uint64_t mio_int0:1;
+		uint64_t mio_int1:1;
+		uint64_t mac0_int:1;
+		uint64_t mac1_int:1;
+		uint64_t reserved_20_31:12;
+		uint64_t dmafi:2;
+		uint64_t dcnt:2;
+		uint64_t dtime:2;
+		uint64_t reserved_38_47:10;
+		uint64_t pidbof:1;
+		uint64_t psldbof:1;
+		uint64_t pout_err:1;
+		uint64_t reserved_51_51:1;
+		uint64_t pgl_err:1;
+		uint64_t pdi_err:1;
+		uint64_t pop_err:1;
+		uint64_t pins_err:1;
+		uint64_t sprt0_err:1;
+		uint64_t sprt1_err:1;
+		uint64_t reserved_58_59:2;
+		uint64_t ill_pad:1;
+		uint64_t pipe_err:1;
+		uint64_t reserved_62_63:2;
+#endif
 	} cn68xx;
 	struct cvmx_sli_int_sum_cn68xx cn68xxp1;
+	struct cvmx_sli_int_sum_cn61xx cnf71xx;
 };
 
 union cvmx_sli_last_win_rdata0 {
 	uint64_t u64;
 	struct cvmx_sli_last_win_rdata0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t data:64;
+#else
+		uint64_t data:64;
+#endif
 	} s;
 	struct cvmx_sli_last_win_rdata0_s cn61xx;
 	struct cvmx_sli_last_win_rdata0_s cn63xx;
@@ -904,12 +1605,17 @@
 	struct cvmx_sli_last_win_rdata0_s cn66xx;
 	struct cvmx_sli_last_win_rdata0_s cn68xx;
 	struct cvmx_sli_last_win_rdata0_s cn68xxp1;
+	struct cvmx_sli_last_win_rdata0_s cnf71xx;
 };
 
 union cvmx_sli_last_win_rdata1 {
 	uint64_t u64;
 	struct cvmx_sli_last_win_rdata1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t data:64;
+#else
+		uint64_t data:64;
+#endif
 	} s;
 	struct cvmx_sli_last_win_rdata1_s cn61xx;
 	struct cvmx_sli_last_win_rdata1_s cn63xx;
@@ -917,29 +1623,41 @@
 	struct cvmx_sli_last_win_rdata1_s cn66xx;
 	struct cvmx_sli_last_win_rdata1_s cn68xx;
 	struct cvmx_sli_last_win_rdata1_s cn68xxp1;
+	struct cvmx_sli_last_win_rdata1_s cnf71xx;
 };
 
 union cvmx_sli_last_win_rdata2 {
 	uint64_t u64;
 	struct cvmx_sli_last_win_rdata2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t data:64;
+#else
+		uint64_t data:64;
+#endif
 	} s;
 	struct cvmx_sli_last_win_rdata2_s cn61xx;
 	struct cvmx_sli_last_win_rdata2_s cn66xx;
+	struct cvmx_sli_last_win_rdata2_s cnf71xx;
 };
 
 union cvmx_sli_last_win_rdata3 {
 	uint64_t u64;
 	struct cvmx_sli_last_win_rdata3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t data:64;
+#else
+		uint64_t data:64;
+#endif
 	} s;
 	struct cvmx_sli_last_win_rdata3_s cn61xx;
 	struct cvmx_sli_last_win_rdata3_s cn66xx;
+	struct cvmx_sli_last_win_rdata3_s cnf71xx;
 };
 
 union cvmx_sli_mac_credit_cnt {
 	uint64_t u64;
 	struct cvmx_sli_mac_credit_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_54_63:10;
 		uint64_t p1_c_d:1;
 		uint64_t p1_n_d:1;
@@ -953,10 +1671,26 @@
 		uint64_t p0_ccnt:8;
 		uint64_t p0_ncnt:8;
 		uint64_t p0_pcnt:8;
+#else
+		uint64_t p0_pcnt:8;
+		uint64_t p0_ncnt:8;
+		uint64_t p0_ccnt:8;
+		uint64_t p1_pcnt:8;
+		uint64_t p1_ncnt:8;
+		uint64_t p1_ccnt:8;
+		uint64_t p0_p_d:1;
+		uint64_t p0_n_d:1;
+		uint64_t p0_c_d:1;
+		uint64_t p1_p_d:1;
+		uint64_t p1_n_d:1;
+		uint64_t p1_c_d:1;
+		uint64_t reserved_54_63:10;
+#endif
 	} s;
 	struct cvmx_sli_mac_credit_cnt_s cn61xx;
 	struct cvmx_sli_mac_credit_cnt_s cn63xx;
 	struct cvmx_sli_mac_credit_cnt_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t p1_ccnt:8;
 		uint64_t p1_ncnt:8;
@@ -964,15 +1698,26 @@
 		uint64_t p0_ccnt:8;
 		uint64_t p0_ncnt:8;
 		uint64_t p0_pcnt:8;
+#else
+		uint64_t p0_pcnt:8;
+		uint64_t p0_ncnt:8;
+		uint64_t p0_ccnt:8;
+		uint64_t p1_pcnt:8;
+		uint64_t p1_ncnt:8;
+		uint64_t p1_ccnt:8;
+		uint64_t reserved_48_63:16;
+#endif
 	} cn63xxp1;
 	struct cvmx_sli_mac_credit_cnt_s cn66xx;
 	struct cvmx_sli_mac_credit_cnt_s cn68xx;
 	struct cvmx_sli_mac_credit_cnt_s cn68xxp1;
+	struct cvmx_sli_mac_credit_cnt_s cnf71xx;
 };
 
 union cvmx_sli_mac_credit_cnt2 {
 	uint64_t u64;
 	struct cvmx_sli_mac_credit_cnt2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_54_63:10;
 		uint64_t p3_c_d:1;
 		uint64_t p3_n_d:1;
@@ -986,34 +1731,68 @@
 		uint64_t p2_ccnt:8;
 		uint64_t p2_ncnt:8;
 		uint64_t p2_pcnt:8;
+#else
+		uint64_t p2_pcnt:8;
+		uint64_t p2_ncnt:8;
+		uint64_t p2_ccnt:8;
+		uint64_t p3_pcnt:8;
+		uint64_t p3_ncnt:8;
+		uint64_t p3_ccnt:8;
+		uint64_t p2_p_d:1;
+		uint64_t p2_n_d:1;
+		uint64_t p2_c_d:1;
+		uint64_t p3_p_d:1;
+		uint64_t p3_n_d:1;
+		uint64_t p3_c_d:1;
+		uint64_t reserved_54_63:10;
+#endif
 	} s;
 	struct cvmx_sli_mac_credit_cnt2_s cn61xx;
 	struct cvmx_sli_mac_credit_cnt2_s cn66xx;
+	struct cvmx_sli_mac_credit_cnt2_s cnf71xx;
 };
 
 union cvmx_sli_mac_number {
 	uint64_t u64;
 	struct cvmx_sli_mac_number_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t a_mode:1;
 		uint64_t num:8;
+#else
+		uint64_t num:8;
+		uint64_t a_mode:1;
+		uint64_t reserved_9_63:55;
+#endif
 	} s;
 	struct cvmx_sli_mac_number_s cn61xx;
 	struct cvmx_sli_mac_number_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t num:8;
+#else
+		uint64_t num:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} cn63xx;
 	struct cvmx_sli_mac_number_s cn66xx;
 	struct cvmx_sli_mac_number_cn63xx cn68xx;
 	struct cvmx_sli_mac_number_cn63xx cn68xxp1;
+	struct cvmx_sli_mac_number_s cnf71xx;
 };
 
 union cvmx_sli_mem_access_ctl {
 	uint64_t u64;
 	struct cvmx_sli_mem_access_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_14_63:50;
 		uint64_t max_word:4;
 		uint64_t timer:10;
+#else
+		uint64_t timer:10;
+		uint64_t max_word:4;
+		uint64_t reserved_14_63:50;
+#endif
 	} s;
 	struct cvmx_sli_mem_access_ctl_s cn61xx;
 	struct cvmx_sli_mem_access_ctl_s cn63xx;
@@ -1021,11 +1800,13 @@
 	struct cvmx_sli_mem_access_ctl_s cn66xx;
 	struct cvmx_sli_mem_access_ctl_s cn68xx;
 	struct cvmx_sli_mem_access_ctl_s cn68xxp1;
+	struct cvmx_sli_mem_access_ctl_s cnf71xx;
 };
 
 union cvmx_sli_mem_access_subidx {
 	uint64_t u64;
 	struct cvmx_sli_mem_access_subidx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_43_63:21;
 		uint64_t zero:1;
 		uint64_t port:3;
@@ -1035,8 +1816,20 @@
 		uint64_t wtype:2;
 		uint64_t rtype:2;
 		uint64_t reserved_0_29:30;
+#else
+		uint64_t reserved_0_29:30;
+		uint64_t rtype:2;
+		uint64_t wtype:2;
+		uint64_t esw:2;
+		uint64_t esr:2;
+		uint64_t nmerge:1;
+		uint64_t port:3;
+		uint64_t zero:1;
+		uint64_t reserved_43_63:21;
+#endif
 	} s;
 	struct cvmx_sli_mem_access_subidx_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_43_63:21;
 		uint64_t zero:1;
 		uint64_t port:3;
@@ -1046,11 +1839,23 @@
 		uint64_t wtype:2;
 		uint64_t rtype:2;
 		uint64_t ba:30;
+#else
+		uint64_t ba:30;
+		uint64_t rtype:2;
+		uint64_t wtype:2;
+		uint64_t esw:2;
+		uint64_t esr:2;
+		uint64_t nmerge:1;
+		uint64_t port:3;
+		uint64_t zero:1;
+		uint64_t reserved_43_63:21;
+#endif
 	} cn61xx;
 	struct cvmx_sli_mem_access_subidx_cn61xx cn63xx;
 	struct cvmx_sli_mem_access_subidx_cn61xx cn63xxp1;
 	struct cvmx_sli_mem_access_subidx_cn61xx cn66xx;
 	struct cvmx_sli_mem_access_subidx_cn68xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_43_63:21;
 		uint64_t zero:1;
 		uint64_t port:3;
@@ -1061,14 +1866,31 @@
 		uint64_t rtype:2;
 		uint64_t ba:28;
 		uint64_t reserved_0_1:2;
+#else
+		uint64_t reserved_0_1:2;
+		uint64_t ba:28;
+		uint64_t rtype:2;
+		uint64_t wtype:2;
+		uint64_t esw:2;
+		uint64_t esr:2;
+		uint64_t nmerge:1;
+		uint64_t port:3;
+		uint64_t zero:1;
+		uint64_t reserved_43_63:21;
+#endif
 	} cn68xx;
 	struct cvmx_sli_mem_access_subidx_cn68xx cn68xxp1;
+	struct cvmx_sli_mem_access_subidx_cn61xx cnf71xx;
 };
 
 union cvmx_sli_msi_enb0 {
 	uint64_t u64;
 	struct cvmx_sli_msi_enb0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t enb:64;
+#else
+		uint64_t enb:64;
+#endif
 	} s;
 	struct cvmx_sli_msi_enb0_s cn61xx;
 	struct cvmx_sli_msi_enb0_s cn63xx;
@@ -1076,12 +1898,17 @@
 	struct cvmx_sli_msi_enb0_s cn66xx;
 	struct cvmx_sli_msi_enb0_s cn68xx;
 	struct cvmx_sli_msi_enb0_s cn68xxp1;
+	struct cvmx_sli_msi_enb0_s cnf71xx;
 };
 
 union cvmx_sli_msi_enb1 {
 	uint64_t u64;
 	struct cvmx_sli_msi_enb1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t enb:64;
+#else
+		uint64_t enb:64;
+#endif
 	} s;
 	struct cvmx_sli_msi_enb1_s cn61xx;
 	struct cvmx_sli_msi_enb1_s cn63xx;
@@ -1089,12 +1916,17 @@
 	struct cvmx_sli_msi_enb1_s cn66xx;
 	struct cvmx_sli_msi_enb1_s cn68xx;
 	struct cvmx_sli_msi_enb1_s cn68xxp1;
+	struct cvmx_sli_msi_enb1_s cnf71xx;
 };
 
 union cvmx_sli_msi_enb2 {
 	uint64_t u64;
 	struct cvmx_sli_msi_enb2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t enb:64;
+#else
+		uint64_t enb:64;
+#endif
 	} s;
 	struct cvmx_sli_msi_enb2_s cn61xx;
 	struct cvmx_sli_msi_enb2_s cn63xx;
@@ -1102,12 +1934,17 @@
 	struct cvmx_sli_msi_enb2_s cn66xx;
 	struct cvmx_sli_msi_enb2_s cn68xx;
 	struct cvmx_sli_msi_enb2_s cn68xxp1;
+	struct cvmx_sli_msi_enb2_s cnf71xx;
 };
 
 union cvmx_sli_msi_enb3 {
 	uint64_t u64;
 	struct cvmx_sli_msi_enb3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t enb:64;
+#else
+		uint64_t enb:64;
+#endif
 	} s;
 	struct cvmx_sli_msi_enb3_s cn61xx;
 	struct cvmx_sli_msi_enb3_s cn63xx;
@@ -1115,12 +1952,17 @@
 	struct cvmx_sli_msi_enb3_s cn66xx;
 	struct cvmx_sli_msi_enb3_s cn68xx;
 	struct cvmx_sli_msi_enb3_s cn68xxp1;
+	struct cvmx_sli_msi_enb3_s cnf71xx;
 };
 
 union cvmx_sli_msi_rcv0 {
 	uint64_t u64;
 	struct cvmx_sli_msi_rcv0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t intr:64;
+#else
+		uint64_t intr:64;
+#endif
 	} s;
 	struct cvmx_sli_msi_rcv0_s cn61xx;
 	struct cvmx_sli_msi_rcv0_s cn63xx;
@@ -1128,12 +1970,17 @@
 	struct cvmx_sli_msi_rcv0_s cn66xx;
 	struct cvmx_sli_msi_rcv0_s cn68xx;
 	struct cvmx_sli_msi_rcv0_s cn68xxp1;
+	struct cvmx_sli_msi_rcv0_s cnf71xx;
 };
 
 union cvmx_sli_msi_rcv1 {
 	uint64_t u64;
 	struct cvmx_sli_msi_rcv1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t intr:64;
+#else
+		uint64_t intr:64;
+#endif
 	} s;
 	struct cvmx_sli_msi_rcv1_s cn61xx;
 	struct cvmx_sli_msi_rcv1_s cn63xx;
@@ -1141,12 +1988,17 @@
 	struct cvmx_sli_msi_rcv1_s cn66xx;
 	struct cvmx_sli_msi_rcv1_s cn68xx;
 	struct cvmx_sli_msi_rcv1_s cn68xxp1;
+	struct cvmx_sli_msi_rcv1_s cnf71xx;
 };
 
 union cvmx_sli_msi_rcv2 {
 	uint64_t u64;
 	struct cvmx_sli_msi_rcv2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t intr:64;
+#else
+		uint64_t intr:64;
+#endif
 	} s;
 	struct cvmx_sli_msi_rcv2_s cn61xx;
 	struct cvmx_sli_msi_rcv2_s cn63xx;
@@ -1154,12 +2006,17 @@
 	struct cvmx_sli_msi_rcv2_s cn66xx;
 	struct cvmx_sli_msi_rcv2_s cn68xx;
 	struct cvmx_sli_msi_rcv2_s cn68xxp1;
+	struct cvmx_sli_msi_rcv2_s cnf71xx;
 };
 
 union cvmx_sli_msi_rcv3 {
 	uint64_t u64;
 	struct cvmx_sli_msi_rcv3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t intr:64;
+#else
+		uint64_t intr:64;
+#endif
 	} s;
 	struct cvmx_sli_msi_rcv3_s cn61xx;
 	struct cvmx_sli_msi_rcv3_s cn63xx;
@@ -1167,14 +2024,21 @@
 	struct cvmx_sli_msi_rcv3_s cn66xx;
 	struct cvmx_sli_msi_rcv3_s cn68xx;
 	struct cvmx_sli_msi_rcv3_s cn68xxp1;
+	struct cvmx_sli_msi_rcv3_s cnf71xx;
 };
 
 union cvmx_sli_msi_rd_map {
 	uint64_t u64;
 	struct cvmx_sli_msi_rd_map_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t rd_int:8;
 		uint64_t msi_int:8;
+#else
+		uint64_t msi_int:8;
+		uint64_t rd_int:8;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_sli_msi_rd_map_s cn61xx;
 	struct cvmx_sli_msi_rd_map_s cn63xx;
@@ -1182,12 +2046,17 @@
 	struct cvmx_sli_msi_rd_map_s cn66xx;
 	struct cvmx_sli_msi_rd_map_s cn68xx;
 	struct cvmx_sli_msi_rd_map_s cn68xxp1;
+	struct cvmx_sli_msi_rd_map_s cnf71xx;
 };
 
 union cvmx_sli_msi_w1c_enb0 {
 	uint64_t u64;
 	struct cvmx_sli_msi_w1c_enb0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t clr:64;
+#else
+		uint64_t clr:64;
+#endif
 	} s;
 	struct cvmx_sli_msi_w1c_enb0_s cn61xx;
 	struct cvmx_sli_msi_w1c_enb0_s cn63xx;
@@ -1195,12 +2064,17 @@
 	struct cvmx_sli_msi_w1c_enb0_s cn66xx;
 	struct cvmx_sli_msi_w1c_enb0_s cn68xx;
 	struct cvmx_sli_msi_w1c_enb0_s cn68xxp1;
+	struct cvmx_sli_msi_w1c_enb0_s cnf71xx;
 };
 
 union cvmx_sli_msi_w1c_enb1 {
 	uint64_t u64;
 	struct cvmx_sli_msi_w1c_enb1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t clr:64;
+#else
+		uint64_t clr:64;
+#endif
 	} s;
 	struct cvmx_sli_msi_w1c_enb1_s cn61xx;
 	struct cvmx_sli_msi_w1c_enb1_s cn63xx;
@@ -1208,12 +2082,17 @@
 	struct cvmx_sli_msi_w1c_enb1_s cn66xx;
 	struct cvmx_sli_msi_w1c_enb1_s cn68xx;
 	struct cvmx_sli_msi_w1c_enb1_s cn68xxp1;
+	struct cvmx_sli_msi_w1c_enb1_s cnf71xx;
 };
 
 union cvmx_sli_msi_w1c_enb2 {
 	uint64_t u64;
 	struct cvmx_sli_msi_w1c_enb2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t clr:64;
+#else
+		uint64_t clr:64;
+#endif
 	} s;
 	struct cvmx_sli_msi_w1c_enb2_s cn61xx;
 	struct cvmx_sli_msi_w1c_enb2_s cn63xx;
@@ -1221,12 +2100,17 @@
 	struct cvmx_sli_msi_w1c_enb2_s cn66xx;
 	struct cvmx_sli_msi_w1c_enb2_s cn68xx;
 	struct cvmx_sli_msi_w1c_enb2_s cn68xxp1;
+	struct cvmx_sli_msi_w1c_enb2_s cnf71xx;
 };
 
 union cvmx_sli_msi_w1c_enb3 {
 	uint64_t u64;
 	struct cvmx_sli_msi_w1c_enb3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t clr:64;
+#else
+		uint64_t clr:64;
+#endif
 	} s;
 	struct cvmx_sli_msi_w1c_enb3_s cn61xx;
 	struct cvmx_sli_msi_w1c_enb3_s cn63xx;
@@ -1234,12 +2118,17 @@
 	struct cvmx_sli_msi_w1c_enb3_s cn66xx;
 	struct cvmx_sli_msi_w1c_enb3_s cn68xx;
 	struct cvmx_sli_msi_w1c_enb3_s cn68xxp1;
+	struct cvmx_sli_msi_w1c_enb3_s cnf71xx;
 };
 
 union cvmx_sli_msi_w1s_enb0 {
 	uint64_t u64;
 	struct cvmx_sli_msi_w1s_enb0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t set:64;
+#else
+		uint64_t set:64;
+#endif
 	} s;
 	struct cvmx_sli_msi_w1s_enb0_s cn61xx;
 	struct cvmx_sli_msi_w1s_enb0_s cn63xx;
@@ -1247,12 +2136,17 @@
 	struct cvmx_sli_msi_w1s_enb0_s cn66xx;
 	struct cvmx_sli_msi_w1s_enb0_s cn68xx;
 	struct cvmx_sli_msi_w1s_enb0_s cn68xxp1;
+	struct cvmx_sli_msi_w1s_enb0_s cnf71xx;
 };
 
 union cvmx_sli_msi_w1s_enb1 {
 	uint64_t u64;
 	struct cvmx_sli_msi_w1s_enb1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t set:64;
+#else
+		uint64_t set:64;
+#endif
 	} s;
 	struct cvmx_sli_msi_w1s_enb1_s cn61xx;
 	struct cvmx_sli_msi_w1s_enb1_s cn63xx;
@@ -1260,12 +2154,17 @@
 	struct cvmx_sli_msi_w1s_enb1_s cn66xx;
 	struct cvmx_sli_msi_w1s_enb1_s cn68xx;
 	struct cvmx_sli_msi_w1s_enb1_s cn68xxp1;
+	struct cvmx_sli_msi_w1s_enb1_s cnf71xx;
 };
 
 union cvmx_sli_msi_w1s_enb2 {
 	uint64_t u64;
 	struct cvmx_sli_msi_w1s_enb2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t set:64;
+#else
+		uint64_t set:64;
+#endif
 	} s;
 	struct cvmx_sli_msi_w1s_enb2_s cn61xx;
 	struct cvmx_sli_msi_w1s_enb2_s cn63xx;
@@ -1273,12 +2172,17 @@
 	struct cvmx_sli_msi_w1s_enb2_s cn66xx;
 	struct cvmx_sli_msi_w1s_enb2_s cn68xx;
 	struct cvmx_sli_msi_w1s_enb2_s cn68xxp1;
+	struct cvmx_sli_msi_w1s_enb2_s cnf71xx;
 };
 
 union cvmx_sli_msi_w1s_enb3 {
 	uint64_t u64;
 	struct cvmx_sli_msi_w1s_enb3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t set:64;
+#else
+		uint64_t set:64;
+#endif
 	} s;
 	struct cvmx_sli_msi_w1s_enb3_s cn61xx;
 	struct cvmx_sli_msi_w1s_enb3_s cn63xx;
@@ -1286,14 +2190,21 @@
 	struct cvmx_sli_msi_w1s_enb3_s cn66xx;
 	struct cvmx_sli_msi_w1s_enb3_s cn68xx;
 	struct cvmx_sli_msi_w1s_enb3_s cn68xxp1;
+	struct cvmx_sli_msi_w1s_enb3_s cnf71xx;
 };
 
 union cvmx_sli_msi_wr_map {
 	uint64_t u64;
 	struct cvmx_sli_msi_wr_map_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t ciu_int:8;
 		uint64_t msi_int:8;
+#else
+		uint64_t msi_int:8;
+		uint64_t ciu_int:8;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_sli_msi_wr_map_s cn61xx;
 	struct cvmx_sli_msi_wr_map_s cn63xx;
@@ -1301,13 +2212,19 @@
 	struct cvmx_sli_msi_wr_map_s cn66xx;
 	struct cvmx_sli_msi_wr_map_s cn68xx;
 	struct cvmx_sli_msi_wr_map_s cn68xxp1;
+	struct cvmx_sli_msi_wr_map_s cnf71xx;
 };
 
 union cvmx_sli_pcie_msi_rcv {
 	uint64_t u64;
 	struct cvmx_sli_pcie_msi_rcv_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t intr:8;
+#else
+		uint64_t intr:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_sli_pcie_msi_rcv_s cn61xx;
 	struct cvmx_sli_pcie_msi_rcv_s cn63xx;
@@ -1315,14 +2232,21 @@
 	struct cvmx_sli_pcie_msi_rcv_s cn66xx;
 	struct cvmx_sli_pcie_msi_rcv_s cn68xx;
 	struct cvmx_sli_pcie_msi_rcv_s cn68xxp1;
+	struct cvmx_sli_pcie_msi_rcv_s cnf71xx;
 };
 
 union cvmx_sli_pcie_msi_rcv_b1 {
 	uint64_t u64;
 	struct cvmx_sli_pcie_msi_rcv_b1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t intr:8;
 		uint64_t reserved_0_7:8;
+#else
+		uint64_t reserved_0_7:8;
+		uint64_t intr:8;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_sli_pcie_msi_rcv_b1_s cn61xx;
 	struct cvmx_sli_pcie_msi_rcv_b1_s cn63xx;
@@ -1330,14 +2254,21 @@
 	struct cvmx_sli_pcie_msi_rcv_b1_s cn66xx;
 	struct cvmx_sli_pcie_msi_rcv_b1_s cn68xx;
 	struct cvmx_sli_pcie_msi_rcv_b1_s cn68xxp1;
+	struct cvmx_sli_pcie_msi_rcv_b1_s cnf71xx;
 };
 
 union cvmx_sli_pcie_msi_rcv_b2 {
 	uint64_t u64;
 	struct cvmx_sli_pcie_msi_rcv_b2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_24_63:40;
 		uint64_t intr:8;
 		uint64_t reserved_0_15:16;
+#else
+		uint64_t reserved_0_15:16;
+		uint64_t intr:8;
+		uint64_t reserved_24_63:40;
+#endif
 	} s;
 	struct cvmx_sli_pcie_msi_rcv_b2_s cn61xx;
 	struct cvmx_sli_pcie_msi_rcv_b2_s cn63xx;
@@ -1345,14 +2276,21 @@
 	struct cvmx_sli_pcie_msi_rcv_b2_s cn66xx;
 	struct cvmx_sli_pcie_msi_rcv_b2_s cn68xx;
 	struct cvmx_sli_pcie_msi_rcv_b2_s cn68xxp1;
+	struct cvmx_sli_pcie_msi_rcv_b2_s cnf71xx;
 };
 
 union cvmx_sli_pcie_msi_rcv_b3 {
 	uint64_t u64;
 	struct cvmx_sli_pcie_msi_rcv_b3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t intr:8;
 		uint64_t reserved_0_23:24;
+#else
+		uint64_t reserved_0_23:24;
+		uint64_t intr:8;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sli_pcie_msi_rcv_b3_s cn61xx;
 	struct cvmx_sli_pcie_msi_rcv_b3_s cn63xx;
@@ -1360,14 +2298,21 @@
 	struct cvmx_sli_pcie_msi_rcv_b3_s cn66xx;
 	struct cvmx_sli_pcie_msi_rcv_b3_s cn68xx;
 	struct cvmx_sli_pcie_msi_rcv_b3_s cn68xxp1;
+	struct cvmx_sli_pcie_msi_rcv_b3_s cnf71xx;
 };
 
 union cvmx_sli_pktx_cnts {
 	uint64_t u64;
 	struct cvmx_sli_pktx_cnts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_54_63:10;
 		uint64_t timer:22;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t timer:22;
+		uint64_t reserved_54_63:10;
+#endif
 	} s;
 	struct cvmx_sli_pktx_cnts_s cn61xx;
 	struct cvmx_sli_pktx_cnts_s cn63xx;
@@ -1375,25 +2320,37 @@
 	struct cvmx_sli_pktx_cnts_s cn66xx;
 	struct cvmx_sli_pktx_cnts_s cn68xx;
 	struct cvmx_sli_pktx_cnts_s cn68xxp1;
+	struct cvmx_sli_pktx_cnts_s cnf71xx;
 };
 
 union cvmx_sli_pktx_in_bp {
 	uint64_t u64;
 	struct cvmx_sli_pktx_in_bp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t wmark:32;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t wmark:32;
+#endif
 	} s;
 	struct cvmx_sli_pktx_in_bp_s cn61xx;
 	struct cvmx_sli_pktx_in_bp_s cn63xx;
 	struct cvmx_sli_pktx_in_bp_s cn63xxp1;
 	struct cvmx_sli_pktx_in_bp_s cn66xx;
+	struct cvmx_sli_pktx_in_bp_s cnf71xx;
 };
 
 union cvmx_sli_pktx_instr_baddr {
 	uint64_t u64;
 	struct cvmx_sli_pktx_instr_baddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t addr:61;
 		uint64_t reserved_0_2:3;
+#else
+		uint64_t reserved_0_2:3;
+		uint64_t addr:61;
+#endif
 	} s;
 	struct cvmx_sli_pktx_instr_baddr_s cn61xx;
 	struct cvmx_sli_pktx_instr_baddr_s cn63xx;
@@ -1401,13 +2358,19 @@
 	struct cvmx_sli_pktx_instr_baddr_s cn66xx;
 	struct cvmx_sli_pktx_instr_baddr_s cn68xx;
 	struct cvmx_sli_pktx_instr_baddr_s cn68xxp1;
+	struct cvmx_sli_pktx_instr_baddr_s cnf71xx;
 };
 
 union cvmx_sli_pktx_instr_baoff_dbell {
 	uint64_t u64;
 	struct cvmx_sli_pktx_instr_baoff_dbell_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t aoff:32;
 		uint64_t dbell:32;
+#else
+		uint64_t dbell:32;
+		uint64_t aoff:32;
+#endif
 	} s;
 	struct cvmx_sli_pktx_instr_baoff_dbell_s cn61xx;
 	struct cvmx_sli_pktx_instr_baoff_dbell_s cn63xx;
@@ -1415,16 +2378,25 @@
 	struct cvmx_sli_pktx_instr_baoff_dbell_s cn66xx;
 	struct cvmx_sli_pktx_instr_baoff_dbell_s cn68xx;
 	struct cvmx_sli_pktx_instr_baoff_dbell_s cn68xxp1;
+	struct cvmx_sli_pktx_instr_baoff_dbell_s cnf71xx;
 };
 
 union cvmx_sli_pktx_instr_fifo_rsize {
 	uint64_t u64;
 	struct cvmx_sli_pktx_instr_fifo_rsize_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t max:9;
 		uint64_t rrp:9;
 		uint64_t wrp:9;
 		uint64_t fcnt:5;
 		uint64_t rsize:32;
+#else
+		uint64_t rsize:32;
+		uint64_t fcnt:5;
+		uint64_t wrp:9;
+		uint64_t rrp:9;
+		uint64_t max:9;
+#endif
 	} s;
 	struct cvmx_sli_pktx_instr_fifo_rsize_s cn61xx;
 	struct cvmx_sli_pktx_instr_fifo_rsize_s cn63xx;
@@ -1432,11 +2404,13 @@
 	struct cvmx_sli_pktx_instr_fifo_rsize_s cn66xx;
 	struct cvmx_sli_pktx_instr_fifo_rsize_s cn68xx;
 	struct cvmx_sli_pktx_instr_fifo_rsize_s cn68xxp1;
+	struct cvmx_sli_pktx_instr_fifo_rsize_s cnf71xx;
 };
 
 union cvmx_sli_pktx_instr_header {
 	uint64_t u64;
 	struct cvmx_sli_pktx_instr_header_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_44_63:20;
 		uint64_t pbp:1;
 		uint64_t reserved_38_42:5;
@@ -1458,8 +2432,32 @@
 		uint64_t ngrp:1;
 		uint64_t ntt:1;
 		uint64_t ntag:1;
+#else
+		uint64_t ntag:1;
+		uint64_t ntt:1;
+		uint64_t ngrp:1;
+		uint64_t nqos:1;
+		uint64_t ngrpext:2;
+		uint64_t skp_len:7;
+		uint64_t reserved_13_13:1;
+		uint64_t par_mode:2;
+		uint64_t reserved_16_20:5;
+		uint64_t use_ihdr:1;
+		uint64_t rntag:1;
+		uint64_t rntt:1;
+		uint64_t rngrp:1;
+		uint64_t rnqos:1;
+		uint64_t rngrpext:2;
+		uint64_t rskp_len:7;
+		uint64_t reserved_35_35:1;
+		uint64_t rparmode:2;
+		uint64_t reserved_38_42:5;
+		uint64_t pbp:1;
+		uint64_t reserved_44_63:20;
+#endif
 	} s;
 	struct cvmx_sli_pktx_instr_header_cn61xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_44_63:20;
 		uint64_t pbp:1;
 		uint64_t reserved_38_42:5;
@@ -1481,20 +2479,50 @@
 		uint64_t ngrp:1;
 		uint64_t ntt:1;
 		uint64_t ntag:1;
+#else
+		uint64_t ntag:1;
+		uint64_t ntt:1;
+		uint64_t ngrp:1;
+		uint64_t nqos:1;
+		uint64_t reserved_4_5:2;
+		uint64_t skp_len:7;
+		uint64_t reserved_13_13:1;
+		uint64_t par_mode:2;
+		uint64_t reserved_16_20:5;
+		uint64_t use_ihdr:1;
+		uint64_t rntag:1;
+		uint64_t rntt:1;
+		uint64_t rngrp:1;
+		uint64_t rnqos:1;
+		uint64_t reserved_26_27:2;
+		uint64_t rskp_len:7;
+		uint64_t reserved_35_35:1;
+		uint64_t rparmode:2;
+		uint64_t reserved_38_42:5;
+		uint64_t pbp:1;
+		uint64_t reserved_44_63:20;
+#endif
 	} cn61xx;
 	struct cvmx_sli_pktx_instr_header_cn61xx cn63xx;
 	struct cvmx_sli_pktx_instr_header_cn61xx cn63xxp1;
 	struct cvmx_sli_pktx_instr_header_cn61xx cn66xx;
 	struct cvmx_sli_pktx_instr_header_s cn68xx;
 	struct cvmx_sli_pktx_instr_header_cn61xx cn68xxp1;
+	struct cvmx_sli_pktx_instr_header_cn61xx cnf71xx;
 };
 
 union cvmx_sli_pktx_out_size {
 	uint64_t u64;
 	struct cvmx_sli_pktx_out_size_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_23_63:41;
 		uint64_t isize:7;
 		uint64_t bsize:16;
+#else
+		uint64_t bsize:16;
+		uint64_t isize:7;
+		uint64_t reserved_23_63:41;
+#endif
 	} s;
 	struct cvmx_sli_pktx_out_size_s cn61xx;
 	struct cvmx_sli_pktx_out_size_s cn63xx;
@@ -1502,13 +2530,19 @@
 	struct cvmx_sli_pktx_out_size_s cn66xx;
 	struct cvmx_sli_pktx_out_size_s cn68xx;
 	struct cvmx_sli_pktx_out_size_s cn68xxp1;
+	struct cvmx_sli_pktx_out_size_s cnf71xx;
 };
 
 union cvmx_sli_pktx_slist_baddr {
 	uint64_t u64;
 	struct cvmx_sli_pktx_slist_baddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t addr:60;
 		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t addr:60;
+#endif
 	} s;
 	struct cvmx_sli_pktx_slist_baddr_s cn61xx;
 	struct cvmx_sli_pktx_slist_baddr_s cn63xx;
@@ -1516,13 +2550,19 @@
 	struct cvmx_sli_pktx_slist_baddr_s cn66xx;
 	struct cvmx_sli_pktx_slist_baddr_s cn68xx;
 	struct cvmx_sli_pktx_slist_baddr_s cn68xxp1;
+	struct cvmx_sli_pktx_slist_baddr_s cnf71xx;
 };
 
 union cvmx_sli_pktx_slist_baoff_dbell {
 	uint64_t u64;
 	struct cvmx_sli_pktx_slist_baoff_dbell_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t aoff:32;
 		uint64_t dbell:32;
+#else
+		uint64_t dbell:32;
+		uint64_t aoff:32;
+#endif
 	} s;
 	struct cvmx_sli_pktx_slist_baoff_dbell_s cn61xx;
 	struct cvmx_sli_pktx_slist_baoff_dbell_s cn63xx;
@@ -1530,13 +2570,19 @@
 	struct cvmx_sli_pktx_slist_baoff_dbell_s cn66xx;
 	struct cvmx_sli_pktx_slist_baoff_dbell_s cn68xx;
 	struct cvmx_sli_pktx_slist_baoff_dbell_s cn68xxp1;
+	struct cvmx_sli_pktx_slist_baoff_dbell_s cnf71xx;
 };
 
 union cvmx_sli_pktx_slist_fifo_rsize {
 	uint64_t u64;
 	struct cvmx_sli_pktx_slist_fifo_rsize_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t rsize:32;
+#else
+		uint64_t rsize:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sli_pktx_slist_fifo_rsize_s cn61xx;
 	struct cvmx_sli_pktx_slist_fifo_rsize_s cn63xx;
@@ -1544,13 +2590,19 @@
 	struct cvmx_sli_pktx_slist_fifo_rsize_s cn66xx;
 	struct cvmx_sli_pktx_slist_fifo_rsize_s cn68xx;
 	struct cvmx_sli_pktx_slist_fifo_rsize_s cn68xxp1;
+	struct cvmx_sli_pktx_slist_fifo_rsize_s cnf71xx;
 };
 
 union cvmx_sli_pkt_cnt_int {
 	uint64_t u64;
 	struct cvmx_sli_pkt_cnt_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t port:32;
+#else
+		uint64_t port:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sli_pkt_cnt_int_s cn61xx;
 	struct cvmx_sli_pkt_cnt_int_s cn63xx;
@@ -1558,13 +2610,19 @@
 	struct cvmx_sli_pkt_cnt_int_s cn66xx;
 	struct cvmx_sli_pkt_cnt_int_s cn68xx;
 	struct cvmx_sli_pkt_cnt_int_s cn68xxp1;
+	struct cvmx_sli_pkt_cnt_int_s cnf71xx;
 };
 
 union cvmx_sli_pkt_cnt_int_enb {
 	uint64_t u64;
 	struct cvmx_sli_pkt_cnt_int_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t port:32;
+#else
+		uint64_t port:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sli_pkt_cnt_int_enb_s cn61xx;
 	struct cvmx_sli_pkt_cnt_int_enb_s cn63xx;
@@ -1572,14 +2630,21 @@
 	struct cvmx_sli_pkt_cnt_int_enb_s cn66xx;
 	struct cvmx_sli_pkt_cnt_int_enb_s cn68xx;
 	struct cvmx_sli_pkt_cnt_int_enb_s cn68xxp1;
+	struct cvmx_sli_pkt_cnt_int_enb_s cnf71xx;
 };
 
 union cvmx_sli_pkt_ctl {
 	uint64_t u64;
 	struct cvmx_sli_pkt_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t ring_en:1;
 		uint64_t pkt_bp:4;
+#else
+		uint64_t pkt_bp:4;
+		uint64_t ring_en:1;
+		uint64_t reserved_5_63:59;
+#endif
 	} s;
 	struct cvmx_sli_pkt_ctl_s cn61xx;
 	struct cvmx_sli_pkt_ctl_s cn63xx;
@@ -1587,12 +2652,17 @@
 	struct cvmx_sli_pkt_ctl_s cn66xx;
 	struct cvmx_sli_pkt_ctl_s cn68xx;
 	struct cvmx_sli_pkt_ctl_s cn68xxp1;
+	struct cvmx_sli_pkt_ctl_s cnf71xx;
 };
 
 union cvmx_sli_pkt_data_out_es {
 	uint64_t u64;
 	struct cvmx_sli_pkt_data_out_es_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t es:64;
+#else
+		uint64_t es:64;
+#endif
 	} s;
 	struct cvmx_sli_pkt_data_out_es_s cn61xx;
 	struct cvmx_sli_pkt_data_out_es_s cn63xx;
@@ -1600,13 +2670,19 @@
 	struct cvmx_sli_pkt_data_out_es_s cn66xx;
 	struct cvmx_sli_pkt_data_out_es_s cn68xx;
 	struct cvmx_sli_pkt_data_out_es_s cn68xxp1;
+	struct cvmx_sli_pkt_data_out_es_s cnf71xx;
 };
 
 union cvmx_sli_pkt_data_out_ns {
 	uint64_t u64;
 	struct cvmx_sli_pkt_data_out_ns_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t nsr:32;
+#else
+		uint64_t nsr:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sli_pkt_data_out_ns_s cn61xx;
 	struct cvmx_sli_pkt_data_out_ns_s cn63xx;
@@ -1614,13 +2690,19 @@
 	struct cvmx_sli_pkt_data_out_ns_s cn66xx;
 	struct cvmx_sli_pkt_data_out_ns_s cn68xx;
 	struct cvmx_sli_pkt_data_out_ns_s cn68xxp1;
+	struct cvmx_sli_pkt_data_out_ns_s cnf71xx;
 };
 
 union cvmx_sli_pkt_data_out_ror {
 	uint64_t u64;
 	struct cvmx_sli_pkt_data_out_ror_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t ror:32;
+#else
+		uint64_t ror:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sli_pkt_data_out_ror_s cn61xx;
 	struct cvmx_sli_pkt_data_out_ror_s cn63xx;
@@ -1628,13 +2710,19 @@
 	struct cvmx_sli_pkt_data_out_ror_s cn66xx;
 	struct cvmx_sli_pkt_data_out_ror_s cn68xx;
 	struct cvmx_sli_pkt_data_out_ror_s cn68xxp1;
+	struct cvmx_sli_pkt_data_out_ror_s cnf71xx;
 };
 
 union cvmx_sli_pkt_dpaddr {
 	uint64_t u64;
 	struct cvmx_sli_pkt_dpaddr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t dptr:32;
+#else
+		uint64_t dptr:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sli_pkt_dpaddr_s cn61xx;
 	struct cvmx_sli_pkt_dpaddr_s cn63xx;
@@ -1642,25 +2730,37 @@
 	struct cvmx_sli_pkt_dpaddr_s cn66xx;
 	struct cvmx_sli_pkt_dpaddr_s cn68xx;
 	struct cvmx_sli_pkt_dpaddr_s cn68xxp1;
+	struct cvmx_sli_pkt_dpaddr_s cnf71xx;
 };
 
 union cvmx_sli_pkt_in_bp {
 	uint64_t u64;
 	struct cvmx_sli_pkt_in_bp_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t bp:32;
+#else
+		uint64_t bp:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sli_pkt_in_bp_s cn61xx;
 	struct cvmx_sli_pkt_in_bp_s cn63xx;
 	struct cvmx_sli_pkt_in_bp_s cn63xxp1;
 	struct cvmx_sli_pkt_in_bp_s cn66xx;
+	struct cvmx_sli_pkt_in_bp_s cnf71xx;
 };
 
 union cvmx_sli_pkt_in_donex_cnts {
 	uint64_t u64;
 	struct cvmx_sli_pkt_in_donex_cnts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sli_pkt_in_donex_cnts_s cn61xx;
 	struct cvmx_sli_pkt_in_donex_cnts_s cn63xx;
@@ -1668,13 +2768,19 @@
 	struct cvmx_sli_pkt_in_donex_cnts_s cn66xx;
 	struct cvmx_sli_pkt_in_donex_cnts_s cn68xx;
 	struct cvmx_sli_pkt_in_donex_cnts_s cn68xxp1;
+	struct cvmx_sli_pkt_in_donex_cnts_s cnf71xx;
 };
 
 union cvmx_sli_pkt_in_instr_counts {
 	uint64_t u64;
 	struct cvmx_sli_pkt_in_instr_counts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t wr_cnt:32;
 		uint64_t rd_cnt:32;
+#else
+		uint64_t rd_cnt:32;
+		uint64_t wr_cnt:32;
+#endif
 	} s;
 	struct cvmx_sli_pkt_in_instr_counts_s cn61xx;
 	struct cvmx_sli_pkt_in_instr_counts_s cn63xx;
@@ -1682,12 +2788,17 @@
 	struct cvmx_sli_pkt_in_instr_counts_s cn66xx;
 	struct cvmx_sli_pkt_in_instr_counts_s cn68xx;
 	struct cvmx_sli_pkt_in_instr_counts_s cn68xxp1;
+	struct cvmx_sli_pkt_in_instr_counts_s cnf71xx;
 };
 
 union cvmx_sli_pkt_in_pcie_port {
 	uint64_t u64;
 	struct cvmx_sli_pkt_in_pcie_port_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t pp:64;
+#else
+		uint64_t pp:64;
+#endif
 	} s;
 	struct cvmx_sli_pkt_in_pcie_port_s cn61xx;
 	struct cvmx_sli_pkt_in_pcie_port_s cn63xx;
@@ -1695,11 +2806,13 @@
 	struct cvmx_sli_pkt_in_pcie_port_s cn66xx;
 	struct cvmx_sli_pkt_in_pcie_port_s cn68xx;
 	struct cvmx_sli_pkt_in_pcie_port_s cn68xxp1;
+	struct cvmx_sli_pkt_in_pcie_port_s cnf71xx;
 };
 
 union cvmx_sli_pkt_input_control {
 	uint64_t u64;
 	struct cvmx_sli_pkt_input_control_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t prd_erst:1;
 		uint64_t prd_rds:7;
 		uint64_t gii_erst:1;
@@ -1717,9 +2830,29 @@
 		uint64_t nsr:1;
 		uint64_t esr:2;
 		uint64_t ror:1;
+#else
+		uint64_t ror:1;
+		uint64_t esr:2;
+		uint64_t nsr:1;
+		uint64_t use_csr:1;
+		uint64_t d_ror:1;
+		uint64_t d_esr:2;
+		uint64_t d_nsr:1;
+		uint64_t pbp_dhi:13;
+		uint64_t pkt_rr:1;
+		uint64_t pin_rst:1;
+		uint64_t reserved_24_39:16;
+		uint64_t prc_idle:1;
+		uint64_t reserved_41_47:7;
+		uint64_t gii_rds:7;
+		uint64_t gii_erst:1;
+		uint64_t prd_rds:7;
+		uint64_t prd_erst:1;
+#endif
 	} s;
 	struct cvmx_sli_pkt_input_control_s cn61xx;
 	struct cvmx_sli_pkt_input_control_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_23_63:41;
 		uint64_t pkt_rr:1;
 		uint64_t pbp_dhi:13;
@@ -1730,18 +2863,36 @@
 		uint64_t nsr:1;
 		uint64_t esr:2;
 		uint64_t ror:1;
+#else
+		uint64_t ror:1;
+		uint64_t esr:2;
+		uint64_t nsr:1;
+		uint64_t use_csr:1;
+		uint64_t d_ror:1;
+		uint64_t d_esr:2;
+		uint64_t d_nsr:1;
+		uint64_t pbp_dhi:13;
+		uint64_t pkt_rr:1;
+		uint64_t reserved_23_63:41;
+#endif
 	} cn63xx;
 	struct cvmx_sli_pkt_input_control_cn63xx cn63xxp1;
 	struct cvmx_sli_pkt_input_control_s cn66xx;
 	struct cvmx_sli_pkt_input_control_s cn68xx;
 	struct cvmx_sli_pkt_input_control_s cn68xxp1;
+	struct cvmx_sli_pkt_input_control_s cnf71xx;
 };
 
 union cvmx_sli_pkt_instr_enb {
 	uint64_t u64;
 	struct cvmx_sli_pkt_instr_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t enb:32;
+#else
+		uint64_t enb:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sli_pkt_instr_enb_s cn61xx;
 	struct cvmx_sli_pkt_instr_enb_s cn63xx;
@@ -1749,12 +2900,17 @@
 	struct cvmx_sli_pkt_instr_enb_s cn66xx;
 	struct cvmx_sli_pkt_instr_enb_s cn68xx;
 	struct cvmx_sli_pkt_instr_enb_s cn68xxp1;
+	struct cvmx_sli_pkt_instr_enb_s cnf71xx;
 };
 
 union cvmx_sli_pkt_instr_rd_size {
 	uint64_t u64;
 	struct cvmx_sli_pkt_instr_rd_size_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t rdsize:64;
+#else
+		uint64_t rdsize:64;
+#endif
 	} s;
 	struct cvmx_sli_pkt_instr_rd_size_s cn61xx;
 	struct cvmx_sli_pkt_instr_rd_size_s cn63xx;
@@ -1762,13 +2918,19 @@
 	struct cvmx_sli_pkt_instr_rd_size_s cn66xx;
 	struct cvmx_sli_pkt_instr_rd_size_s cn68xx;
 	struct cvmx_sli_pkt_instr_rd_size_s cn68xxp1;
+	struct cvmx_sli_pkt_instr_rd_size_s cnf71xx;
 };
 
 union cvmx_sli_pkt_instr_size {
 	uint64_t u64;
 	struct cvmx_sli_pkt_instr_size_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t is_64b:32;
+#else
+		uint64_t is_64b:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sli_pkt_instr_size_s cn61xx;
 	struct cvmx_sli_pkt_instr_size_s cn63xx;
@@ -1776,14 +2938,21 @@
 	struct cvmx_sli_pkt_instr_size_s cn66xx;
 	struct cvmx_sli_pkt_instr_size_s cn68xx;
 	struct cvmx_sli_pkt_instr_size_s cn68xxp1;
+	struct cvmx_sli_pkt_instr_size_s cnf71xx;
 };
 
 union cvmx_sli_pkt_int_levels {
 	uint64_t u64;
 	struct cvmx_sli_pkt_int_levels_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_54_63:10;
 		uint64_t time:22;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t time:22;
+		uint64_t reserved_54_63:10;
+#endif
 	} s;
 	struct cvmx_sli_pkt_int_levels_s cn61xx;
 	struct cvmx_sli_pkt_int_levels_s cn63xx;
@@ -1791,13 +2960,19 @@
 	struct cvmx_sli_pkt_int_levels_s cn66xx;
 	struct cvmx_sli_pkt_int_levels_s cn68xx;
 	struct cvmx_sli_pkt_int_levels_s cn68xxp1;
+	struct cvmx_sli_pkt_int_levels_s cnf71xx;
 };
 
 union cvmx_sli_pkt_iptr {
 	uint64_t u64;
 	struct cvmx_sli_pkt_iptr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t iptr:32;
+#else
+		uint64_t iptr:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sli_pkt_iptr_s cn61xx;
 	struct cvmx_sli_pkt_iptr_s cn63xx;
@@ -1805,13 +2980,19 @@
 	struct cvmx_sli_pkt_iptr_s cn66xx;
 	struct cvmx_sli_pkt_iptr_s cn68xx;
 	struct cvmx_sli_pkt_iptr_s cn68xxp1;
+	struct cvmx_sli_pkt_iptr_s cnf71xx;
 };
 
 union cvmx_sli_pkt_out_bmode {
 	uint64_t u64;
 	struct cvmx_sli_pkt_out_bmode_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t bmode:32;
+#else
+		uint64_t bmode:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sli_pkt_out_bmode_s cn61xx;
 	struct cvmx_sli_pkt_out_bmode_s cn63xx;
@@ -1819,13 +3000,19 @@
 	struct cvmx_sli_pkt_out_bmode_s cn66xx;
 	struct cvmx_sli_pkt_out_bmode_s cn68xx;
 	struct cvmx_sli_pkt_out_bmode_s cn68xxp1;
+	struct cvmx_sli_pkt_out_bmode_s cnf71xx;
 };
 
 union cvmx_sli_pkt_out_bp_en {
 	uint64_t u64;
 	struct cvmx_sli_pkt_out_bp_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t bp_en:32;
+#else
+		uint64_t bp_en:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sli_pkt_out_bp_en_s cn68xx;
 	struct cvmx_sli_pkt_out_bp_en_s cn68xxp1;
@@ -1834,8 +3021,13 @@
 union cvmx_sli_pkt_out_enb {
 	uint64_t u64;
 	struct cvmx_sli_pkt_out_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t enb:32;
+#else
+		uint64_t enb:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sli_pkt_out_enb_s cn61xx;
 	struct cvmx_sli_pkt_out_enb_s cn63xx;
@@ -1843,13 +3035,19 @@
 	struct cvmx_sli_pkt_out_enb_s cn66xx;
 	struct cvmx_sli_pkt_out_enb_s cn68xx;
 	struct cvmx_sli_pkt_out_enb_s cn68xxp1;
+	struct cvmx_sli_pkt_out_enb_s cnf71xx;
 };
 
 union cvmx_sli_pkt_output_wmark {
 	uint64_t u64;
 	struct cvmx_sli_pkt_output_wmark_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t wmark:32;
+#else
+		uint64_t wmark:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sli_pkt_output_wmark_s cn61xx;
 	struct cvmx_sli_pkt_output_wmark_s cn63xx;
@@ -1857,12 +3055,17 @@
 	struct cvmx_sli_pkt_output_wmark_s cn66xx;
 	struct cvmx_sli_pkt_output_wmark_s cn68xx;
 	struct cvmx_sli_pkt_output_wmark_s cn68xxp1;
+	struct cvmx_sli_pkt_output_wmark_s cnf71xx;
 };
 
 union cvmx_sli_pkt_pcie_port {
 	uint64_t u64;
 	struct cvmx_sli_pkt_pcie_port_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t pp:64;
+#else
+		uint64_t pp:64;
+#endif
 	} s;
 	struct cvmx_sli_pkt_pcie_port_s cn61xx;
 	struct cvmx_sli_pkt_pcie_port_s cn63xx;
@@ -1870,13 +3073,19 @@
 	struct cvmx_sli_pkt_pcie_port_s cn66xx;
 	struct cvmx_sli_pkt_pcie_port_s cn68xx;
 	struct cvmx_sli_pkt_pcie_port_s cn68xxp1;
+	struct cvmx_sli_pkt_pcie_port_s cnf71xx;
 };
 
 union cvmx_sli_pkt_port_in_rst {
 	uint64_t u64;
 	struct cvmx_sli_pkt_port_in_rst_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t in_rst:32;
 		uint64_t out_rst:32;
+#else
+		uint64_t out_rst:32;
+		uint64_t in_rst:32;
+#endif
 	} s;
 	struct cvmx_sli_pkt_port_in_rst_s cn61xx;
 	struct cvmx_sli_pkt_port_in_rst_s cn63xx;
@@ -1884,12 +3093,17 @@
 	struct cvmx_sli_pkt_port_in_rst_s cn66xx;
 	struct cvmx_sli_pkt_port_in_rst_s cn68xx;
 	struct cvmx_sli_pkt_port_in_rst_s cn68xxp1;
+	struct cvmx_sli_pkt_port_in_rst_s cnf71xx;
 };
 
 union cvmx_sli_pkt_slist_es {
 	uint64_t u64;
 	struct cvmx_sli_pkt_slist_es_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t es:64;
+#else
+		uint64_t es:64;
+#endif
 	} s;
 	struct cvmx_sli_pkt_slist_es_s cn61xx;
 	struct cvmx_sli_pkt_slist_es_s cn63xx;
@@ -1897,13 +3111,19 @@
 	struct cvmx_sli_pkt_slist_es_s cn66xx;
 	struct cvmx_sli_pkt_slist_es_s cn68xx;
 	struct cvmx_sli_pkt_slist_es_s cn68xxp1;
+	struct cvmx_sli_pkt_slist_es_s cnf71xx;
 };
 
 union cvmx_sli_pkt_slist_ns {
 	uint64_t u64;
 	struct cvmx_sli_pkt_slist_ns_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t nsr:32;
+#else
+		uint64_t nsr:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sli_pkt_slist_ns_s cn61xx;
 	struct cvmx_sli_pkt_slist_ns_s cn63xx;
@@ -1911,13 +3131,19 @@
 	struct cvmx_sli_pkt_slist_ns_s cn66xx;
 	struct cvmx_sli_pkt_slist_ns_s cn68xx;
 	struct cvmx_sli_pkt_slist_ns_s cn68xxp1;
+	struct cvmx_sli_pkt_slist_ns_s cnf71xx;
 };
 
 union cvmx_sli_pkt_slist_ror {
 	uint64_t u64;
 	struct cvmx_sli_pkt_slist_ror_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t ror:32;
+#else
+		uint64_t ror:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sli_pkt_slist_ror_s cn61xx;
 	struct cvmx_sli_pkt_slist_ror_s cn63xx;
@@ -1925,13 +3151,19 @@
 	struct cvmx_sli_pkt_slist_ror_s cn66xx;
 	struct cvmx_sli_pkt_slist_ror_s cn68xx;
 	struct cvmx_sli_pkt_slist_ror_s cn68xxp1;
+	struct cvmx_sli_pkt_slist_ror_s cnf71xx;
 };
 
 union cvmx_sli_pkt_time_int {
 	uint64_t u64;
 	struct cvmx_sli_pkt_time_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t port:32;
+#else
+		uint64_t port:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sli_pkt_time_int_s cn61xx;
 	struct cvmx_sli_pkt_time_int_s cn63xx;
@@ -1939,13 +3171,19 @@
 	struct cvmx_sli_pkt_time_int_s cn66xx;
 	struct cvmx_sli_pkt_time_int_s cn68xx;
 	struct cvmx_sli_pkt_time_int_s cn68xxp1;
+	struct cvmx_sli_pkt_time_int_s cnf71xx;
 };
 
 union cvmx_sli_pkt_time_int_enb {
 	uint64_t u64;
 	struct cvmx_sli_pkt_time_int_enb_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t port:32;
+#else
+		uint64_t port:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sli_pkt_time_int_enb_s cn61xx;
 	struct cvmx_sli_pkt_time_int_enb_s cn63xx;
@@ -1953,11 +3191,13 @@
 	struct cvmx_sli_pkt_time_int_enb_s cn66xx;
 	struct cvmx_sli_pkt_time_int_enb_s cn68xx;
 	struct cvmx_sli_pkt_time_int_enb_s cn68xxp1;
+	struct cvmx_sli_pkt_time_int_enb_s cnf71xx;
 };
 
 union cvmx_sli_portx_pkind {
 	uint64_t u64;
 	struct cvmx_sli_portx_pkind_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_25_63:39;
 		uint64_t rpk_enb:1;
 		uint64_t reserved_22_23:2;
@@ -1966,23 +3206,47 @@
 		uint64_t bpkind:6;
 		uint64_t reserved_6_7:2;
 		uint64_t pkind:6;
+#else
+		uint64_t pkind:6;
+		uint64_t reserved_6_7:2;
+		uint64_t bpkind:6;
+		uint64_t reserved_14_15:2;
+		uint64_t pkindr:6;
+		uint64_t reserved_22_23:2;
+		uint64_t rpk_enb:1;
+		uint64_t reserved_25_63:39;
+#endif
 	} s;
 	struct cvmx_sli_portx_pkind_s cn68xx;
 	struct cvmx_sli_portx_pkind_cn68xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_14_63:50;
 		uint64_t bpkind:6;
 		uint64_t reserved_6_7:2;
 		uint64_t pkind:6;
+#else
+		uint64_t pkind:6;
+		uint64_t reserved_6_7:2;
+		uint64_t bpkind:6;
+		uint64_t reserved_14_63:50;
+#endif
 	} cn68xxp1;
 };
 
 union cvmx_sli_s2m_portx_ctl {
 	uint64_t u64;
 	struct cvmx_sli_s2m_portx_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t wind_d:1;
 		uint64_t bar0_d:1;
 		uint64_t mrrs:3;
+#else
+		uint64_t mrrs:3;
+		uint64_t bar0_d:1;
+		uint64_t wind_d:1;
+		uint64_t reserved_5_63:59;
+#endif
 	} s;
 	struct cvmx_sli_s2m_portx_ctl_s cn61xx;
 	struct cvmx_sli_s2m_portx_ctl_s cn63xx;
@@ -1990,12 +3254,17 @@
 	struct cvmx_sli_s2m_portx_ctl_s cn66xx;
 	struct cvmx_sli_s2m_portx_ctl_s cn68xx;
 	struct cvmx_sli_s2m_portx_ctl_s cn68xxp1;
+	struct cvmx_sli_s2m_portx_ctl_s cnf71xx;
 };
 
 union cvmx_sli_scratch_1 {
 	uint64_t u64;
 	struct cvmx_sli_scratch_1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t data:64;
+#else
+		uint64_t data:64;
+#endif
 	} s;
 	struct cvmx_sli_scratch_1_s cn61xx;
 	struct cvmx_sli_scratch_1_s cn63xx;
@@ -2003,12 +3272,17 @@
 	struct cvmx_sli_scratch_1_s cn66xx;
 	struct cvmx_sli_scratch_1_s cn68xx;
 	struct cvmx_sli_scratch_1_s cn68xxp1;
+	struct cvmx_sli_scratch_1_s cnf71xx;
 };
 
 union cvmx_sli_scratch_2 {
 	uint64_t u64;
 	struct cvmx_sli_scratch_2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t data:64;
+#else
+		uint64_t data:64;
+#endif
 	} s;
 	struct cvmx_sli_scratch_2_s cn61xx;
 	struct cvmx_sli_scratch_2_s cn63xx;
@@ -2016,15 +3290,23 @@
 	struct cvmx_sli_scratch_2_s cn66xx;
 	struct cvmx_sli_scratch_2_s cn68xx;
 	struct cvmx_sli_scratch_2_s cn68xxp1;
+	struct cvmx_sli_scratch_2_s cnf71xx;
 };
 
 union cvmx_sli_state1 {
 	uint64_t u64;
 	struct cvmx_sli_state1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t cpl1:12;
 		uint64_t cpl0:12;
 		uint64_t arb:1;
 		uint64_t csr:39;
+#else
+		uint64_t csr:39;
+		uint64_t arb:1;
+		uint64_t cpl0:12;
+		uint64_t cpl1:12;
+#endif
 	} s;
 	struct cvmx_sli_state1_s cn61xx;
 	struct cvmx_sli_state1_s cn63xx;
@@ -2032,11 +3314,13 @@
 	struct cvmx_sli_state1_s cn66xx;
 	struct cvmx_sli_state1_s cn68xx;
 	struct cvmx_sli_state1_s cn68xxp1;
+	struct cvmx_sli_state1_s cnf71xx;
 };
 
 union cvmx_sli_state2 {
 	uint64_t u64;
 	struct cvmx_sli_state2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_56_63:8;
 		uint64_t nnp1:8;
 		uint64_t reserved_47_47:1;
@@ -2045,6 +3329,16 @@
 		uint64_t csm0:15;
 		uint64_t nnp0:8;
 		uint64_t nnd:8;
+#else
+		uint64_t nnd:8;
+		uint64_t nnp0:8;
+		uint64_t csm0:15;
+		uint64_t csm1:15;
+		uint64_t rac:1;
+		uint64_t reserved_47_47:1;
+		uint64_t nnp1:8;
+		uint64_t reserved_56_63:8;
+#endif
 	} s;
 	struct cvmx_sli_state2_s cn61xx;
 	struct cvmx_sli_state2_s cn63xx;
@@ -2052,16 +3346,25 @@
 	struct cvmx_sli_state2_s cn66xx;
 	struct cvmx_sli_state2_s cn68xx;
 	struct cvmx_sli_state2_s cn68xxp1;
+	struct cvmx_sli_state2_s cnf71xx;
 };
 
 union cvmx_sli_state3 {
 	uint64_t u64;
 	struct cvmx_sli_state3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_56_63:8;
 		uint64_t psm1:15;
 		uint64_t psm0:15;
 		uint64_t nsm1:13;
 		uint64_t nsm0:13;
+#else
+		uint64_t nsm0:13;
+		uint64_t nsm1:13;
+		uint64_t psm0:15;
+		uint64_t psm1:15;
+		uint64_t reserved_56_63:8;
+#endif
 	} s;
 	struct cvmx_sli_state3_s cn61xx;
 	struct cvmx_sli_state3_s cn63xx;
@@ -2069,15 +3372,23 @@
 	struct cvmx_sli_state3_s cn66xx;
 	struct cvmx_sli_state3_s cn68xx;
 	struct cvmx_sli_state3_s cn68xxp1;
+	struct cvmx_sli_state3_s cnf71xx;
 };
 
 union cvmx_sli_tx_pipe {
 	uint64_t u64;
 	struct cvmx_sli_tx_pipe_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_24_63:40;
 		uint64_t nump:8;
 		uint64_t reserved_7_15:9;
 		uint64_t base:7;
+#else
+		uint64_t base:7;
+		uint64_t reserved_7_15:9;
+		uint64_t nump:8;
+		uint64_t reserved_24_63:40;
+#endif
 	} s;
 	struct cvmx_sli_tx_pipe_s cn68xx;
 	struct cvmx_sli_tx_pipe_s cn68xxp1;
@@ -2086,10 +3397,17 @@
 union cvmx_sli_win_rd_addr {
 	uint64_t u64;
 	struct cvmx_sli_win_rd_addr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_51_63:13;
 		uint64_t ld_cmd:2;
 		uint64_t iobit:1;
 		uint64_t rd_addr:48;
+#else
+		uint64_t rd_addr:48;
+		uint64_t iobit:1;
+		uint64_t ld_cmd:2;
+		uint64_t reserved_51_63:13;
+#endif
 	} s;
 	struct cvmx_sli_win_rd_addr_s cn61xx;
 	struct cvmx_sli_win_rd_addr_s cn63xx;
@@ -2097,12 +3415,17 @@
 	struct cvmx_sli_win_rd_addr_s cn66xx;
 	struct cvmx_sli_win_rd_addr_s cn68xx;
 	struct cvmx_sli_win_rd_addr_s cn68xxp1;
+	struct cvmx_sli_win_rd_addr_s cnf71xx;
 };
 
 union cvmx_sli_win_rd_data {
 	uint64_t u64;
 	struct cvmx_sli_win_rd_data_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t rd_data:64;
+#else
+		uint64_t rd_data:64;
+#endif
 	} s;
 	struct cvmx_sli_win_rd_data_s cn61xx;
 	struct cvmx_sli_win_rd_data_s cn63xx;
@@ -2110,15 +3433,23 @@
 	struct cvmx_sli_win_rd_data_s cn66xx;
 	struct cvmx_sli_win_rd_data_s cn68xx;
 	struct cvmx_sli_win_rd_data_s cn68xxp1;
+	struct cvmx_sli_win_rd_data_s cnf71xx;
 };
 
 union cvmx_sli_win_wr_addr {
 	uint64_t u64;
 	struct cvmx_sli_win_wr_addr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_49_63:15;
 		uint64_t iobit:1;
 		uint64_t wr_addr:45;
 		uint64_t reserved_0_2:3;
+#else
+		uint64_t reserved_0_2:3;
+		uint64_t wr_addr:45;
+		uint64_t iobit:1;
+		uint64_t reserved_49_63:15;
+#endif
 	} s;
 	struct cvmx_sli_win_wr_addr_s cn61xx;
 	struct cvmx_sli_win_wr_addr_s cn63xx;
@@ -2126,12 +3457,17 @@
 	struct cvmx_sli_win_wr_addr_s cn66xx;
 	struct cvmx_sli_win_wr_addr_s cn68xx;
 	struct cvmx_sli_win_wr_addr_s cn68xxp1;
+	struct cvmx_sli_win_wr_addr_s cnf71xx;
 };
 
 union cvmx_sli_win_wr_data {
 	uint64_t u64;
 	struct cvmx_sli_win_wr_data_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t wr_data:64;
+#else
+		uint64_t wr_data:64;
+#endif
 	} s;
 	struct cvmx_sli_win_wr_data_s cn61xx;
 	struct cvmx_sli_win_wr_data_s cn63xx;
@@ -2139,13 +3475,19 @@
 	struct cvmx_sli_win_wr_data_s cn66xx;
 	struct cvmx_sli_win_wr_data_s cn68xx;
 	struct cvmx_sli_win_wr_data_s cn68xxp1;
+	struct cvmx_sli_win_wr_data_s cnf71xx;
 };
 
 union cvmx_sli_win_wr_mask {
 	uint64_t u64;
 	struct cvmx_sli_win_wr_mask_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t wr_mask:8;
+#else
+		uint64_t wr_mask:8;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_sli_win_wr_mask_s cn61xx;
 	struct cvmx_sli_win_wr_mask_s cn63xx;
@@ -2153,13 +3495,19 @@
 	struct cvmx_sli_win_wr_mask_s cn66xx;
 	struct cvmx_sli_win_wr_mask_s cn68xx;
 	struct cvmx_sli_win_wr_mask_s cn68xxp1;
+	struct cvmx_sli_win_wr_mask_s cnf71xx;
 };
 
 union cvmx_sli_window_ctl {
 	uint64_t u64;
 	struct cvmx_sli_window_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t time:32;
+#else
+		uint64_t time:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sli_window_ctl_s cn61xx;
 	struct cvmx_sli_window_ctl_s cn63xx;
@@ -2167,6 +3515,7 @@
 	struct cvmx_sli_window_ctl_s cn66xx;
 	struct cvmx_sli_window_ctl_s cn68xx;
 	struct cvmx_sli_window_ctl_s cn68xxp1;
+	struct cvmx_sli_window_ctl_s cnf71xx;
 };
 
 #endif
diff --git a/arch/mips/include/asm/octeon/cvmx-smix-defs.h b/arch/mips/include/asm/octeon/cvmx-smix-defs.h
index 4f3c066..8a278e6dd 100644
--- a/arch/mips/include/asm/octeon/cvmx-smix-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-smix-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -28,15 +28,120 @@
 #ifndef __CVMX_SMIX_DEFS_H__
 #define __CVMX_SMIX_DEFS_H__
 
-#define CVMX_SMIX_CLK(offset) (CVMX_ADD_IO_SEG(0x0001180000001818ull) + ((offset) & 1) * 256)
-#define CVMX_SMIX_CMD(offset) (CVMX_ADD_IO_SEG(0x0001180000001800ull) + ((offset) & 1) * 256)
-#define CVMX_SMIX_EN(offset) (CVMX_ADD_IO_SEG(0x0001180000001820ull) + ((offset) & 1) * 256)
-#define CVMX_SMIX_RD_DAT(offset) (CVMX_ADD_IO_SEG(0x0001180000001810ull) + ((offset) & 1) * 256)
-#define CVMX_SMIX_WR_DAT(offset) (CVMX_ADD_IO_SEG(0x0001180000001808ull) + ((offset) & 1) * 256)
+static inline uint64_t CVMX_SMIX_CLK(unsigned long offset)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180000001818ull) + (offset) * 256;
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180000001818ull) + (offset) * 256;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180000003818ull) + (offset) * 128;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180000001818ull) + (offset) * 256;
+}
+
+static inline uint64_t CVMX_SMIX_CMD(unsigned long offset)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180000001800ull) + (offset) * 256;
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180000001800ull) + (offset) * 256;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180000003800ull) + (offset) * 128;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180000001800ull) + (offset) * 256;
+}
+
+static inline uint64_t CVMX_SMIX_EN(unsigned long offset)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180000001820ull) + (offset) * 256;
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180000001820ull) + (offset) * 256;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180000003820ull) + (offset) * 128;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180000001820ull) + (offset) * 256;
+}
+
+static inline uint64_t CVMX_SMIX_RD_DAT(unsigned long offset)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180000001810ull) + (offset) * 256;
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180000001810ull) + (offset) * 256;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180000003810ull) + (offset) * 128;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180000001810ull) + (offset) * 256;
+}
+
+static inline uint64_t CVMX_SMIX_WR_DAT(unsigned long offset)
+{
+	switch (cvmx_get_octeon_family()) {
+	case OCTEON_CN30XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN50XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN38XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN31XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN58XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180000001808ull) + (offset) * 256;
+	case OCTEON_CNF71XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN61XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN56XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN66XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN52XX & OCTEON_FAMILY_MASK:
+	case OCTEON_CN63XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180000001808ull) + (offset) * 256;
+	case OCTEON_CN68XX & OCTEON_FAMILY_MASK:
+		return CVMX_ADD_IO_SEG(0x0001180000003808ull) + (offset) * 128;
+	}
+	return CVMX_ADD_IO_SEG(0x0001180000001808ull) + (offset) * 256;
+}
 
 union cvmx_smix_clk {
 	uint64_t u64;
 	struct cvmx_smix_clk_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_25_63:39;
 		uint64_t mode:1;
 		uint64_t reserved_21_23:3;
@@ -47,8 +152,21 @@
 		uint64_t preamble:1;
 		uint64_t sample:4;
 		uint64_t phase:8;
+#else
+		uint64_t phase:8;
+		uint64_t sample:4;
+		uint64_t preamble:1;
+		uint64_t clk_idle:1;
+		uint64_t reserved_14_14:1;
+		uint64_t sample_mode:1;
+		uint64_t sample_hi:5;
+		uint64_t reserved_21_23:3;
+		uint64_t mode:1;
+		uint64_t reserved_25_63:39;
+#endif
 	} s;
 	struct cvmx_smix_clk_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_21_63:43;
 		uint64_t sample_hi:5;
 		uint64_t sample_mode:1;
@@ -57,6 +175,16 @@
 		uint64_t preamble:1;
 		uint64_t sample:4;
 		uint64_t phase:8;
+#else
+		uint64_t phase:8;
+		uint64_t sample:4;
+		uint64_t preamble:1;
+		uint64_t clk_idle:1;
+		uint64_t reserved_14_14:1;
+		uint64_t sample_mode:1;
+		uint64_t sample_hi:5;
+		uint64_t reserved_21_63:43;
+#endif
 	} cn30xx;
 	struct cvmx_smix_clk_cn30xx cn31xx;
 	struct cvmx_smix_clk_cn30xx cn38xx;
@@ -68,27 +196,50 @@
 	struct cvmx_smix_clk_s cn56xxp1;
 	struct cvmx_smix_clk_cn30xx cn58xx;
 	struct cvmx_smix_clk_cn30xx cn58xxp1;
+	struct cvmx_smix_clk_s cn61xx;
 	struct cvmx_smix_clk_s cn63xx;
 	struct cvmx_smix_clk_s cn63xxp1;
+	struct cvmx_smix_clk_s cn66xx;
+	struct cvmx_smix_clk_s cn68xx;
+	struct cvmx_smix_clk_s cn68xxp1;
+	struct cvmx_smix_clk_s cnf71xx;
 };
 
 union cvmx_smix_cmd {
 	uint64_t u64;
 	struct cvmx_smix_cmd_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_18_63:46;
 		uint64_t phy_op:2;
 		uint64_t reserved_13_15:3;
 		uint64_t phy_adr:5;
 		uint64_t reserved_5_7:3;
 		uint64_t reg_adr:5;
+#else
+		uint64_t reg_adr:5;
+		uint64_t reserved_5_7:3;
+		uint64_t phy_adr:5;
+		uint64_t reserved_13_15:3;
+		uint64_t phy_op:2;
+		uint64_t reserved_18_63:46;
+#endif
 	} s;
 	struct cvmx_smix_cmd_cn30xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_17_63:47;
 		uint64_t phy_op:1;
 		uint64_t reserved_13_15:3;
 		uint64_t phy_adr:5;
 		uint64_t reserved_5_7:3;
 		uint64_t reg_adr:5;
+#else
+		uint64_t reg_adr:5;
+		uint64_t reserved_5_7:3;
+		uint64_t phy_adr:5;
+		uint64_t reserved_13_15:3;
+		uint64_t phy_op:1;
+		uint64_t reserved_17_63:47;
+#endif
 	} cn30xx;
 	struct cvmx_smix_cmd_cn30xx cn31xx;
 	struct cvmx_smix_cmd_cn30xx cn38xx;
@@ -100,15 +251,25 @@
 	struct cvmx_smix_cmd_s cn56xxp1;
 	struct cvmx_smix_cmd_cn30xx cn58xx;
 	struct cvmx_smix_cmd_cn30xx cn58xxp1;
+	struct cvmx_smix_cmd_s cn61xx;
 	struct cvmx_smix_cmd_s cn63xx;
 	struct cvmx_smix_cmd_s cn63xxp1;
+	struct cvmx_smix_cmd_s cn66xx;
+	struct cvmx_smix_cmd_s cn68xx;
+	struct cvmx_smix_cmd_s cn68xxp1;
+	struct cvmx_smix_cmd_s cnf71xx;
 };
 
 union cvmx_smix_en {
 	uint64_t u64;
 	struct cvmx_smix_en_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t en:1;
+#else
+		uint64_t en:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_smix_en_s cn30xx;
 	struct cvmx_smix_en_s cn31xx;
@@ -121,17 +282,29 @@
 	struct cvmx_smix_en_s cn56xxp1;
 	struct cvmx_smix_en_s cn58xx;
 	struct cvmx_smix_en_s cn58xxp1;
+	struct cvmx_smix_en_s cn61xx;
 	struct cvmx_smix_en_s cn63xx;
 	struct cvmx_smix_en_s cn63xxp1;
+	struct cvmx_smix_en_s cn66xx;
+	struct cvmx_smix_en_s cn68xx;
+	struct cvmx_smix_en_s cn68xxp1;
+	struct cvmx_smix_en_s cnf71xx;
 };
 
 union cvmx_smix_rd_dat {
 	uint64_t u64;
 	struct cvmx_smix_rd_dat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_18_63:46;
 		uint64_t pending:1;
 		uint64_t val:1;
 		uint64_t dat:16;
+#else
+		uint64_t dat:16;
+		uint64_t val:1;
+		uint64_t pending:1;
+		uint64_t reserved_18_63:46;
+#endif
 	} s;
 	struct cvmx_smix_rd_dat_s cn30xx;
 	struct cvmx_smix_rd_dat_s cn31xx;
@@ -144,17 +317,29 @@
 	struct cvmx_smix_rd_dat_s cn56xxp1;
 	struct cvmx_smix_rd_dat_s cn58xx;
 	struct cvmx_smix_rd_dat_s cn58xxp1;
+	struct cvmx_smix_rd_dat_s cn61xx;
 	struct cvmx_smix_rd_dat_s cn63xx;
 	struct cvmx_smix_rd_dat_s cn63xxp1;
+	struct cvmx_smix_rd_dat_s cn66xx;
+	struct cvmx_smix_rd_dat_s cn68xx;
+	struct cvmx_smix_rd_dat_s cn68xxp1;
+	struct cvmx_smix_rd_dat_s cnf71xx;
 };
 
 union cvmx_smix_wr_dat {
 	uint64_t u64;
 	struct cvmx_smix_wr_dat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_18_63:46;
 		uint64_t pending:1;
 		uint64_t val:1;
 		uint64_t dat:16;
+#else
+		uint64_t dat:16;
+		uint64_t val:1;
+		uint64_t pending:1;
+		uint64_t reserved_18_63:46;
+#endif
 	} s;
 	struct cvmx_smix_wr_dat_s cn30xx;
 	struct cvmx_smix_wr_dat_s cn31xx;
@@ -167,8 +352,13 @@
 	struct cvmx_smix_wr_dat_s cn56xxp1;
 	struct cvmx_smix_wr_dat_s cn58xx;
 	struct cvmx_smix_wr_dat_s cn58xxp1;
+	struct cvmx_smix_wr_dat_s cn61xx;
 	struct cvmx_smix_wr_dat_s cn63xx;
 	struct cvmx_smix_wr_dat_s cn63xxp1;
+	struct cvmx_smix_wr_dat_s cn66xx;
+	struct cvmx_smix_wr_dat_s cn68xx;
+	struct cvmx_smix_wr_dat_s cn68xxp1;
+	struct cvmx_smix_wr_dat_s cnf71xx;
 };
 
 #endif
diff --git a/arch/mips/include/asm/octeon/cvmx-spxx-defs.h b/arch/mips/include/asm/octeon/cvmx-spxx-defs.h
index b16940e..c7d601d 100644
--- a/arch/mips/include/asm/octeon/cvmx-spxx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-spxx-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -28,44 +28,33 @@
 #ifndef __CVMX_SPXX_DEFS_H__
 #define __CVMX_SPXX_DEFS_H__
 
-#define CVMX_SPXX_BCKPRS_CNT(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000340ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_BIST_STAT(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800900007F8ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_CLK_CTL(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000348ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_CLK_STAT(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000350ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_DBG_DESKEW_CTL(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000368ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_DBG_DESKEW_STATE(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000370ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_DRV_CTL(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000358ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_ERR_CTL(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000320ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_INT_DAT(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000318ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_INT_MSK(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000308ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_INT_REG(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000300ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_INT_SYNC(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000310ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_TPA_ACC(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000338ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_TPA_MAX(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000330ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_TPA_SEL(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000328ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SPXX_TRN4_CTL(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000360ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_SPXX_BCKPRS_CNT(block_id) (CVMX_ADD_IO_SEG(0x0001180090000340ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_BIST_STAT(block_id) (CVMX_ADD_IO_SEG(0x00011800900007F8ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_CLK_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180090000348ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_CLK_STAT(block_id) (CVMX_ADD_IO_SEG(0x0001180090000350ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_DBG_DESKEW_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180090000368ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_DBG_DESKEW_STATE(block_id) (CVMX_ADD_IO_SEG(0x0001180090000370ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_DRV_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180090000358ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_ERR_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180090000320ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_INT_DAT(block_id) (CVMX_ADD_IO_SEG(0x0001180090000318ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_INT_MSK(block_id) (CVMX_ADD_IO_SEG(0x0001180090000308ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_INT_REG(block_id) (CVMX_ADD_IO_SEG(0x0001180090000300ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_INT_SYNC(block_id) (CVMX_ADD_IO_SEG(0x0001180090000310ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_TPA_ACC(block_id) (CVMX_ADD_IO_SEG(0x0001180090000338ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_TPA_MAX(block_id) (CVMX_ADD_IO_SEG(0x0001180090000330ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_TPA_SEL(block_id) (CVMX_ADD_IO_SEG(0x0001180090000328ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SPXX_TRN4_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180090000360ull) + ((block_id) & 1) * 0x8000000ull)
 
 union cvmx_spxx_bckprs_cnt {
 	uint64_t u64;
 	struct cvmx_spxx_bckprs_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_spxx_bckprs_cnt_s cn38xx;
 	struct cvmx_spxx_bckprs_cnt_s cn38xxp2;
@@ -76,10 +65,17 @@
 union cvmx_spxx_bist_stat {
 	uint64_t u64;
 	struct cvmx_spxx_bist_stat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_3_63:61;
 		uint64_t stat2:1;
 		uint64_t stat1:1;
 		uint64_t stat0:1;
+#else
+		uint64_t stat0:1;
+		uint64_t stat1:1;
+		uint64_t stat2:1;
+		uint64_t reserved_3_63:61;
+#endif
 	} s;
 	struct cvmx_spxx_bist_stat_s cn38xx;
 	struct cvmx_spxx_bist_stat_s cn38xxp2;
@@ -90,6 +86,7 @@
 union cvmx_spxx_clk_ctl {
 	uint64_t u64;
 	struct cvmx_spxx_clk_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_17_63:47;
 		uint64_t seetrn:1;
 		uint64_t reserved_12_15:4;
@@ -101,6 +98,19 @@
 		uint64_t drptrn:1;
 		uint64_t rcvtrn:1;
 		uint64_t srxdlck:1;
+#else
+		uint64_t srxdlck:1;
+		uint64_t rcvtrn:1;
+		uint64_t drptrn:1;
+		uint64_t sndtrn:1;
+		uint64_t statrcv:1;
+		uint64_t statdrv:1;
+		uint64_t runbist:1;
+		uint64_t clkdly:5;
+		uint64_t reserved_12_15:4;
+		uint64_t seetrn:1;
+		uint64_t reserved_17_63:47;
+#endif
 	} s;
 	struct cvmx_spxx_clk_ctl_s cn38xx;
 	struct cvmx_spxx_clk_ctl_s cn38xxp2;
@@ -111,6 +121,7 @@
 union cvmx_spxx_clk_stat {
 	uint64_t u64;
 	struct cvmx_spxx_clk_stat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_11_63:53;
 		uint64_t stxcal:1;
 		uint64_t reserved_9_9:1;
@@ -120,6 +131,17 @@
 		uint64_t d4clk1:1;
 		uint64_t d4clk0:1;
 		uint64_t reserved_0_3:4;
+#else
+		uint64_t reserved_0_3:4;
+		uint64_t d4clk0:1;
+		uint64_t d4clk1:1;
+		uint64_t s4clk0:1;
+		uint64_t s4clk1:1;
+		uint64_t srxtrn:1;
+		uint64_t reserved_9_9:1;
+		uint64_t stxcal:1;
+		uint64_t reserved_11_63:53;
+#endif
 	} s;
 	struct cvmx_spxx_clk_stat_s cn38xx;
 	struct cvmx_spxx_clk_stat_s cn38xxp2;
@@ -130,6 +152,7 @@
 union cvmx_spxx_dbg_deskew_ctl {
 	uint64_t u64;
 	struct cvmx_spxx_dbg_deskew_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_30_63:34;
 		uint64_t fallnop:1;
 		uint64_t fall8:1;
@@ -146,6 +169,24 @@
 		uint64_t offdly:6;
 		uint64_t dllfrc:1;
 		uint64_t dlldis:1;
+#else
+		uint64_t dlldis:1;
+		uint64_t dllfrc:1;
+		uint64_t offdly:6;
+		uint64_t bitsel:5;
+		uint64_t offset:5;
+		uint64_t mux:1;
+		uint64_t inc:1;
+		uint64_t dec:1;
+		uint64_t clrdly:1;
+		uint64_t reserved_22_23:2;
+		uint64_t sstep:1;
+		uint64_t sstep_go:1;
+		uint64_t reserved_26_27:2;
+		uint64_t fall8:1;
+		uint64_t fallnop:1;
+		uint64_t reserved_30_63:34;
+#endif
 	} s;
 	struct cvmx_spxx_dbg_deskew_ctl_s cn38xx;
 	struct cvmx_spxx_dbg_deskew_ctl_s cn38xxp2;
@@ -156,11 +197,19 @@
 union cvmx_spxx_dbg_deskew_state {
 	uint64_t u64;
 	struct cvmx_spxx_dbg_deskew_state_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t testres:1;
 		uint64_t unxterm:1;
 		uint64_t muxsel:2;
 		uint64_t offset:5;
+#else
+		uint64_t offset:5;
+		uint64_t muxsel:2;
+		uint64_t unxterm:1;
+		uint64_t testres:1;
+		uint64_t reserved_9_63:55;
+#endif
 	} s;
 	struct cvmx_spxx_dbg_deskew_state_s cn38xx;
 	struct cvmx_spxx_dbg_deskew_state_s cn38xxp2;
@@ -171,21 +220,40 @@
 union cvmx_spxx_drv_ctl {
 	uint64_t u64;
 	struct cvmx_spxx_drv_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_0_63:64;
+#else
+		uint64_t reserved_0_63:64;
+#endif
 	} s;
 	struct cvmx_spxx_drv_ctl_cn38xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t stx4ncmp:4;
 		uint64_t stx4pcmp:4;
 		uint64_t srx4cmp:8;
+#else
+		uint64_t srx4cmp:8;
+		uint64_t stx4pcmp:4;
+		uint64_t stx4ncmp:4;
+		uint64_t reserved_16_63:48;
+#endif
 	} cn38xx;
 	struct cvmx_spxx_drv_ctl_cn38xx cn38xxp2;
 	struct cvmx_spxx_drv_ctl_cn58xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_24_63:40;
 		uint64_t stx4ncmp:4;
 		uint64_t stx4pcmp:4;
 		uint64_t reserved_10_15:6;
 		uint64_t srx4cmp:10;
+#else
+		uint64_t srx4cmp:10;
+		uint64_t reserved_10_15:6;
+		uint64_t stx4pcmp:4;
+		uint64_t stx4ncmp:4;
+		uint64_t reserved_24_63:40;
+#endif
 	} cn58xx;
 	struct cvmx_spxx_drv_ctl_cn58xx cn58xxp1;
 };
@@ -193,12 +261,21 @@
 union cvmx_spxx_err_ctl {
 	uint64_t u64;
 	struct cvmx_spxx_err_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t prtnxa:1;
 		uint64_t dipcls:1;
 		uint64_t dippay:1;
 		uint64_t reserved_4_5:2;
 		uint64_t errcnt:4;
+#else
+		uint64_t errcnt:4;
+		uint64_t reserved_4_5:2;
+		uint64_t dippay:1;
+		uint64_t dipcls:1;
+		uint64_t prtnxa:1;
+		uint64_t reserved_9_63:55;
+#endif
 	} s;
 	struct cvmx_spxx_err_ctl_s cn38xx;
 	struct cvmx_spxx_err_ctl_s cn38xxp2;
@@ -209,12 +286,21 @@
 union cvmx_spxx_int_dat {
 	uint64_t u64;
 	struct cvmx_spxx_int_dat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t mul:1;
 		uint64_t reserved_14_30:17;
 		uint64_t calbnk:2;
 		uint64_t rsvop:4;
 		uint64_t prt:8;
+#else
+		uint64_t prt:8;
+		uint64_t rsvop:4;
+		uint64_t calbnk:2;
+		uint64_t reserved_14_30:17;
+		uint64_t mul:1;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_spxx_int_dat_s cn38xx;
 	struct cvmx_spxx_int_dat_s cn38xxp2;
@@ -225,6 +311,7 @@
 union cvmx_spxx_int_msk {
 	uint64_t u64;
 	struct cvmx_spxx_int_msk_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t calerr:1;
 		uint64_t syncerr:1;
@@ -237,6 +324,20 @@
 		uint64_t reserved_2_3:2;
 		uint64_t abnorm:1;
 		uint64_t prtnxa:1;
+#else
+		uint64_t prtnxa:1;
+		uint64_t abnorm:1;
+		uint64_t reserved_2_3:2;
+		uint64_t spiovr:1;
+		uint64_t clserr:1;
+		uint64_t drwnng:1;
+		uint64_t rsverr:1;
+		uint64_t tpaovr:1;
+		uint64_t diperr:1;
+		uint64_t syncerr:1;
+		uint64_t calerr:1;
+		uint64_t reserved_12_63:52;
+#endif
 	} s;
 	struct cvmx_spxx_int_msk_s cn38xx;
 	struct cvmx_spxx_int_msk_s cn38xxp2;
@@ -247,6 +348,7 @@
 union cvmx_spxx_int_reg {
 	uint64_t u64;
 	struct cvmx_spxx_int_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t spf:1;
 		uint64_t reserved_12_30:19;
@@ -261,6 +363,22 @@
 		uint64_t reserved_2_3:2;
 		uint64_t abnorm:1;
 		uint64_t prtnxa:1;
+#else
+		uint64_t prtnxa:1;
+		uint64_t abnorm:1;
+		uint64_t reserved_2_3:2;
+		uint64_t spiovr:1;
+		uint64_t clserr:1;
+		uint64_t drwnng:1;
+		uint64_t rsverr:1;
+		uint64_t tpaovr:1;
+		uint64_t diperr:1;
+		uint64_t syncerr:1;
+		uint64_t calerr:1;
+		uint64_t reserved_12_30:19;
+		uint64_t spf:1;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_spxx_int_reg_s cn38xx;
 	struct cvmx_spxx_int_reg_s cn38xxp2;
@@ -271,6 +389,7 @@
 union cvmx_spxx_int_sync {
 	uint64_t u64;
 	struct cvmx_spxx_int_sync_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_12_63:52;
 		uint64_t calerr:1;
 		uint64_t syncerr:1;
@@ -283,6 +402,20 @@
 		uint64_t reserved_2_3:2;
 		uint64_t abnorm:1;
 		uint64_t prtnxa:1;
+#else
+		uint64_t prtnxa:1;
+		uint64_t abnorm:1;
+		uint64_t reserved_2_3:2;
+		uint64_t spiovr:1;
+		uint64_t clserr:1;
+		uint64_t drwnng:1;
+		uint64_t rsverr:1;
+		uint64_t tpaovr:1;
+		uint64_t diperr:1;
+		uint64_t syncerr:1;
+		uint64_t calerr:1;
+		uint64_t reserved_12_63:52;
+#endif
 	} s;
 	struct cvmx_spxx_int_sync_s cn38xx;
 	struct cvmx_spxx_int_sync_s cn38xxp2;
@@ -293,8 +426,13 @@
 union cvmx_spxx_tpa_acc {
 	uint64_t u64;
 	struct cvmx_spxx_tpa_acc_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_spxx_tpa_acc_s cn38xx;
 	struct cvmx_spxx_tpa_acc_s cn38xxp2;
@@ -305,8 +443,13 @@
 union cvmx_spxx_tpa_max {
 	uint64_t u64;
 	struct cvmx_spxx_tpa_max_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t max:32;
+#else
+		uint64_t max:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_spxx_tpa_max_s cn38xx;
 	struct cvmx_spxx_tpa_max_s cn38xxp2;
@@ -317,8 +460,13 @@
 union cvmx_spxx_tpa_sel {
 	uint64_t u64;
 	struct cvmx_spxx_tpa_sel_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t prtsel:4;
+#else
+		uint64_t prtsel:4;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_spxx_tpa_sel_s cn38xx;
 	struct cvmx_spxx_tpa_sel_s cn38xxp2;
@@ -329,6 +477,7 @@
 union cvmx_spxx_trn4_ctl {
 	uint64_t u64;
 	struct cvmx_spxx_trn4_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_13_63:51;
 		uint64_t trntest:1;
 		uint64_t jitter:3;
@@ -337,6 +486,16 @@
 		uint64_t maxdist:5;
 		uint64_t macro_en:1;
 		uint64_t mux_en:1;
+#else
+		uint64_t mux_en:1;
+		uint64_t macro_en:1;
+		uint64_t maxdist:5;
+		uint64_t set_boot:1;
+		uint64_t clr_boot:1;
+		uint64_t jitter:3;
+		uint64_t trntest:1;
+		uint64_t reserved_13_63:51;
+#endif
 	} s;
 	struct cvmx_spxx_trn4_ctl_s cn38xx;
 	struct cvmx_spxx_trn4_ctl_s cn38xxp2;
diff --git a/arch/mips/include/asm/octeon/cvmx-sriox-defs.h b/arch/mips/include/asm/octeon/cvmx-sriox-defs.h
index 7be7e9e..5140f2d 100644
--- a/arch/mips/include/asm/octeon/cvmx-sriox-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-sriox-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2011 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -79,6 +79,7 @@
 union cvmx_sriox_acc_ctrl {
 	uint64_t u64;
 	struct cvmx_sriox_acc_ctrl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_7_63:57;
 		uint64_t deny_adr2:1;
 		uint64_t deny_adr1:1;
@@ -87,12 +88,29 @@
 		uint64_t deny_bar2:1;
 		uint64_t deny_bar1:1;
 		uint64_t deny_bar0:1;
+#else
+		uint64_t deny_bar0:1;
+		uint64_t deny_bar1:1;
+		uint64_t deny_bar2:1;
+		uint64_t reserved_3_3:1;
+		uint64_t deny_adr0:1;
+		uint64_t deny_adr1:1;
+		uint64_t deny_adr2:1;
+		uint64_t reserved_7_63:57;
+#endif
 	} s;
 	struct cvmx_sriox_acc_ctrl_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_3_63:61;
 		uint64_t deny_bar2:1;
 		uint64_t deny_bar1:1;
 		uint64_t deny_bar0:1;
+#else
+		uint64_t deny_bar0:1;
+		uint64_t deny_bar1:1;
+		uint64_t deny_bar2:1;
+		uint64_t reserved_3_63:61;
+#endif
 	} cn63xx;
 	struct cvmx_sriox_acc_ctrl_cn63xx cn63xxp1;
 	struct cvmx_sriox_acc_ctrl_s cn66xx;
@@ -101,9 +119,15 @@
 union cvmx_sriox_asmbly_id {
 	uint64_t u64;
 	struct cvmx_sriox_asmbly_id_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t assy_id:16;
 		uint64_t assy_ven:16;
+#else
+		uint64_t assy_ven:16;
+		uint64_t assy_id:16;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sriox_asmbly_id_s cn63xx;
 	struct cvmx_sriox_asmbly_id_s cn63xxp1;
@@ -113,9 +137,15 @@
 union cvmx_sriox_asmbly_info {
 	uint64_t u64;
 	struct cvmx_sriox_asmbly_info_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t assy_rev:16;
 		uint64_t reserved_0_15:16;
+#else
+		uint64_t reserved_0_15:16;
+		uint64_t assy_rev:16;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sriox_asmbly_info_s cn63xx;
 	struct cvmx_sriox_asmbly_info_s cn63xxp1;
@@ -125,11 +155,19 @@
 union cvmx_sriox_bell_resp_ctrl {
 	uint64_t u64;
 	struct cvmx_sriox_bell_resp_ctrl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t rp1_sid:1;
 		uint64_t rp0_sid:2;
 		uint64_t rp1_pid:1;
 		uint64_t rp0_pid:2;
+#else
+		uint64_t rp0_pid:2;
+		uint64_t rp1_pid:1;
+		uint64_t rp0_sid:2;
+		uint64_t rp1_sid:1;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
 	struct cvmx_sriox_bell_resp_ctrl_s cn63xx;
 	struct cvmx_sriox_bell_resp_ctrl_s cn63xxp1;
@@ -139,6 +177,7 @@
 union cvmx_sriox_bist_status {
 	uint64_t u64;
 	struct cvmx_sriox_bist_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_45_63:19;
 		uint64_t lram:1;
 		uint64_t mram:2;
@@ -159,8 +198,31 @@
 		uint64_t rxbuf:2;
 		uint64_t imsg:5;
 		uint64_t omsg:7;
+#else
+		uint64_t omsg:7;
+		uint64_t imsg:5;
+		uint64_t rxbuf:2;
+		uint64_t txbuf:2;
+		uint64_t ospf:1;
+		uint64_t ispf:1;
+		uint64_t oarb:2;
+		uint64_t rxbuf2:2;
+		uint64_t oarb2:2;
+		uint64_t optrs:4;
+		uint64_t obulk:4;
+		uint64_t rtn:2;
+		uint64_t ofree:1;
+		uint64_t itag:1;
+		uint64_t otag:2;
+		uint64_t bell:2;
+		uint64_t cram:2;
+		uint64_t mram:2;
+		uint64_t lram:1;
+		uint64_t reserved_45_63:19;
+#endif
 	} s;
 	struct cvmx_sriox_bist_status_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_44_63:20;
 		uint64_t mram:2;
 		uint64_t cram:2;
@@ -180,8 +242,30 @@
 		uint64_t rxbuf:2;
 		uint64_t imsg:5;
 		uint64_t omsg:7;
+#else
+		uint64_t omsg:7;
+		uint64_t imsg:5;
+		uint64_t rxbuf:2;
+		uint64_t txbuf:2;
+		uint64_t ospf:1;
+		uint64_t ispf:1;
+		uint64_t oarb:2;
+		uint64_t rxbuf2:2;
+		uint64_t oarb2:2;
+		uint64_t optrs:4;
+		uint64_t obulk:4;
+		uint64_t rtn:2;
+		uint64_t ofree:1;
+		uint64_t itag:1;
+		uint64_t otag:2;
+		uint64_t bell:2;
+		uint64_t cram:2;
+		uint64_t mram:2;
+		uint64_t reserved_44_63:20;
+#endif
 	} cn63xx;
 	struct cvmx_sriox_bist_status_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_44_63:20;
 		uint64_t mram:2;
 		uint64_t cram:2;
@@ -200,6 +284,26 @@
 		uint64_t rxbuf:2;
 		uint64_t imsg:5;
 		uint64_t omsg:7;
+#else
+		uint64_t omsg:7;
+		uint64_t imsg:5;
+		uint64_t rxbuf:2;
+		uint64_t txbuf:2;
+		uint64_t ospf:1;
+		uint64_t ispf:1;
+		uint64_t oarb:2;
+		uint64_t reserved_20_23:4;
+		uint64_t optrs:4;
+		uint64_t obulk:4;
+		uint64_t rtn:2;
+		uint64_t ofree:1;
+		uint64_t itag:1;
+		uint64_t otag:2;
+		uint64_t bell:2;
+		uint64_t cram:2;
+		uint64_t mram:2;
+		uint64_t reserved_44_63:20;
+#endif
 	} cn63xxp1;
 	struct cvmx_sriox_bist_status_s cn66xx;
 };
@@ -207,6 +311,7 @@
 union cvmx_sriox_imsg_ctrl {
 	uint64_t u64;
 	struct cvmx_sriox_imsg_ctrl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t to_mode:1;
 		uint64_t reserved_30_30:1;
@@ -221,6 +326,22 @@
 		uint64_t lttr:4;
 		uint64_t prio:4;
 		uint64_t mbox:4;
+#else
+		uint64_t mbox:4;
+		uint64_t prio:4;
+		uint64_t lttr:4;
+		uint64_t prt_sel:3;
+		uint64_t reserved_15_15:1;
+		uint64_t rp0_pid:2;
+		uint64_t rp1_pid:1;
+		uint64_t rp0_sid:2;
+		uint64_t rp1_sid:1;
+		uint64_t reserved_22_23:2;
+		uint64_t rsp_thr:6;
+		uint64_t reserved_30_30:1;
+		uint64_t to_mode:1;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sriox_imsg_ctrl_s cn63xx;
 	struct cvmx_sriox_imsg_ctrl_s cn63xxp1;
@@ -230,6 +351,7 @@
 union cvmx_sriox_imsg_inst_hdrx {
 	uint64_t u64;
 	struct cvmx_sriox_imsg_inst_hdrx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t r:1;
 		uint64_t reserved_58_62:5;
 		uint64_t pm:2;
@@ -244,6 +366,22 @@
 		uint64_t rs:1;
 		uint64_t tt:2;
 		uint64_t tag:32;
+#else
+		uint64_t tag:32;
+		uint64_t tt:2;
+		uint64_t rs:1;
+		uint64_t reserved_35_41:7;
+		uint64_t ntag:1;
+		uint64_t ntt:1;
+		uint64_t ngrp:1;
+		uint64_t nqos:1;
+		uint64_t reserved_46_47:2;
+		uint64_t sl:7;
+		uint64_t reserved_55_55:1;
+		uint64_t pm:2;
+		uint64_t reserved_58_62:5;
+		uint64_t r:1;
+#endif
 	} s;
 	struct cvmx_sriox_imsg_inst_hdrx_s cn63xx;
 	struct cvmx_sriox_imsg_inst_hdrx_s cn63xxp1;
@@ -253,6 +391,7 @@
 union cvmx_sriox_imsg_qos_grpx {
 	uint64_t u64;
 	struct cvmx_sriox_imsg_qos_grpx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_63_63:1;
 		uint64_t qos7:3;
 		uint64_t grp7:4;
@@ -277,6 +416,32 @@
 		uint64_t reserved_7_7:1;
 		uint64_t qos0:3;
 		uint64_t grp0:4;
+#else
+		uint64_t grp0:4;
+		uint64_t qos0:3;
+		uint64_t reserved_7_7:1;
+		uint64_t grp1:4;
+		uint64_t qos1:3;
+		uint64_t reserved_15_15:1;
+		uint64_t grp2:4;
+		uint64_t qos2:3;
+		uint64_t reserved_23_23:1;
+		uint64_t grp3:4;
+		uint64_t qos3:3;
+		uint64_t reserved_31_31:1;
+		uint64_t grp4:4;
+		uint64_t qos4:3;
+		uint64_t reserved_39_39:1;
+		uint64_t grp5:4;
+		uint64_t qos5:3;
+		uint64_t reserved_47_47:1;
+		uint64_t grp6:4;
+		uint64_t qos6:3;
+		uint64_t reserved_55_55:1;
+		uint64_t grp7:4;
+		uint64_t qos7:3;
+		uint64_t reserved_63_63:1;
+#endif
 	} s;
 	struct cvmx_sriox_imsg_qos_grpx_s cn63xx;
 	struct cvmx_sriox_imsg_qos_grpx_s cn63xxp1;
@@ -286,6 +451,7 @@
 union cvmx_sriox_imsg_statusx {
 	uint64_t u64;
 	struct cvmx_sriox_imsg_statusx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t val1:1;
 		uint64_t err1:1;
 		uint64_t toe1:1;
@@ -310,6 +476,32 @@
 		uint64_t mbox0:2;
 		uint64_t lttr0:2;
 		uint64_t sid0:16;
+#else
+		uint64_t sid0:16;
+		uint64_t lttr0:2;
+		uint64_t mbox0:2;
+		uint64_t seg0:4;
+		uint64_t dis0:1;
+		uint64_t tt0:1;
+		uint64_t reserved_26_26:1;
+		uint64_t prt0:1;
+		uint64_t toc0:1;
+		uint64_t toe0:1;
+		uint64_t err0:1;
+		uint64_t val0:1;
+		uint64_t sid1:16;
+		uint64_t lttr1:2;
+		uint64_t mbox1:2;
+		uint64_t seg1:4;
+		uint64_t dis1:1;
+		uint64_t tt1:1;
+		uint64_t reserved_58_58:1;
+		uint64_t prt1:1;
+		uint64_t toc1:1;
+		uint64_t toe1:1;
+		uint64_t err1:1;
+		uint64_t val1:1;
+#endif
 	} s;
 	struct cvmx_sriox_imsg_statusx_s cn63xx;
 	struct cvmx_sriox_imsg_statusx_s cn63xxp1;
@@ -319,6 +511,7 @@
 union cvmx_sriox_imsg_vport_thr {
 	uint64_t u64;
 	struct cvmx_sriox_imsg_vport_thr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_54_63:10;
 		uint64_t max_tot:6;
 		uint64_t reserved_46_47:2;
@@ -332,6 +525,21 @@
 		uint64_t max_p1:6;
 		uint64_t reserved_6_7:2;
 		uint64_t max_p0:6;
+#else
+		uint64_t max_p0:6;
+		uint64_t reserved_6_7:2;
+		uint64_t max_p1:6;
+		uint64_t reserved_14_15:2;
+		uint64_t buf_thr:4;
+		uint64_t reserved_20_30:11;
+		uint64_t sp_vport:1;
+		uint64_t max_s0:6;
+		uint64_t reserved_38_39:2;
+		uint64_t max_s1:6;
+		uint64_t reserved_46_47:2;
+		uint64_t max_tot:6;
+		uint64_t reserved_54_63:10;
+#endif
 	} s;
 	struct cvmx_sriox_imsg_vport_thr_s cn63xx;
 	struct cvmx_sriox_imsg_vport_thr_s cn63xxp1;
@@ -341,11 +549,19 @@
 union cvmx_sriox_imsg_vport_thr2 {
 	uint64_t u64;
 	struct cvmx_sriox_imsg_vport_thr2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_46_63:18;
 		uint64_t max_s3:6;
 		uint64_t reserved_38_39:2;
 		uint64_t max_s2:6;
 		uint64_t reserved_0_31:32;
+#else
+		uint64_t reserved_0_31:32;
+		uint64_t max_s2:6;
+		uint64_t reserved_38_39:2;
+		uint64_t max_s3:6;
+		uint64_t reserved_46_63:18;
+#endif
 	} s;
 	struct cvmx_sriox_imsg_vport_thr2_s cn66xx;
 };
@@ -353,8 +569,13 @@
 union cvmx_sriox_int2_enable {
 	uint64_t u64;
 	struct cvmx_sriox_int2_enable_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t pko_rst:1;
+#else
+		uint64_t pko_rst:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_sriox_int2_enable_s cn63xx;
 	struct cvmx_sriox_int2_enable_s cn66xx;
@@ -363,10 +584,17 @@
 union cvmx_sriox_int2_reg {
 	uint64_t u64;
 	struct cvmx_sriox_int2_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t int_sum:1;
 		uint64_t reserved_1_30:30;
 		uint64_t pko_rst:1;
+#else
+		uint64_t pko_rst:1;
+		uint64_t reserved_1_30:30;
+		uint64_t int_sum:1;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sriox_int2_reg_s cn63xx;
 	struct cvmx_sriox_int2_reg_s cn66xx;
@@ -375,6 +603,7 @@
 union cvmx_sriox_int_enable {
 	uint64_t u64;
 	struct cvmx_sriox_int_enable_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_27_63:37;
 		uint64_t zero_pkt:1;
 		uint64_t ttl_tout:1;
@@ -403,9 +632,40 @@
 		uint64_t rxbell:1;
 		uint64_t bell_err:1;
 		uint64_t txbell:1;
+#else
+		uint64_t txbell:1;
+		uint64_t bell_err:1;
+		uint64_t rxbell:1;
+		uint64_t maint_op:1;
+		uint64_t bar_err:1;
+		uint64_t deny_wr:1;
+		uint64_t sli_err:1;
+		uint64_t wr_done:1;
+		uint64_t mce_tx:1;
+		uint64_t mce_rx:1;
+		uint64_t soft_tx:1;
+		uint64_t soft_rx:1;
+		uint64_t log_erb:1;
+		uint64_t phy_erb:1;
+		uint64_t link_dwn:1;
+		uint64_t link_up:1;
+		uint64_t omsg0:1;
+		uint64_t omsg1:1;
+		uint64_t omsg_err:1;
+		uint64_t pko_err:1;
+		uint64_t rtry_err:1;
+		uint64_t f_error:1;
+		uint64_t mac_buf:1;
+		uint64_t degrade:1;
+		uint64_t fail:1;
+		uint64_t ttl_tout:1;
+		uint64_t zero_pkt:1;
+		uint64_t reserved_27_63:37;
+#endif
 	} s;
 	struct cvmx_sriox_int_enable_s cn63xx;
 	struct cvmx_sriox_int_enable_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_22_63:42;
 		uint64_t f_error:1;
 		uint64_t rtry_err:1;
@@ -429,6 +689,31 @@
 		uint64_t rxbell:1;
 		uint64_t bell_err:1;
 		uint64_t txbell:1;
+#else
+		uint64_t txbell:1;
+		uint64_t bell_err:1;
+		uint64_t rxbell:1;
+		uint64_t maint_op:1;
+		uint64_t bar_err:1;
+		uint64_t deny_wr:1;
+		uint64_t sli_err:1;
+		uint64_t wr_done:1;
+		uint64_t mce_tx:1;
+		uint64_t mce_rx:1;
+		uint64_t soft_tx:1;
+		uint64_t soft_rx:1;
+		uint64_t log_erb:1;
+		uint64_t phy_erb:1;
+		uint64_t link_dwn:1;
+		uint64_t link_up:1;
+		uint64_t omsg0:1;
+		uint64_t omsg1:1;
+		uint64_t omsg_err:1;
+		uint64_t pko_err:1;
+		uint64_t rtry_err:1;
+		uint64_t f_error:1;
+		uint64_t reserved_22_63:42;
+#endif
 	} cn63xxp1;
 	struct cvmx_sriox_int_enable_s cn66xx;
 };
@@ -436,6 +721,7 @@
 union cvmx_sriox_int_info0 {
 	uint64_t u64;
 	struct cvmx_sriox_int_info0_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t cmd:4;
 		uint64_t type:4;
 		uint64_t tag:8;
@@ -445,6 +731,17 @@
 		uint64_t reserved_16_28:13;
 		uint64_t be0:8;
 		uint64_t be1:8;
+#else
+		uint64_t be1:8;
+		uint64_t be0:8;
+		uint64_t reserved_16_28:13;
+		uint64_t status:3;
+		uint64_t length:10;
+		uint64_t reserved_42_47:6;
+		uint64_t tag:8;
+		uint64_t type:4;
+		uint64_t cmd:4;
+#endif
 	} s;
 	struct cvmx_sriox_int_info0_s cn63xx;
 	struct cvmx_sriox_int_info0_s cn63xxp1;
@@ -454,7 +751,11 @@
 union cvmx_sriox_int_info1 {
 	uint64_t u64;
 	struct cvmx_sriox_int_info1_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t info1:64;
+#else
+		uint64_t info1:64;
+#endif
 	} s;
 	struct cvmx_sriox_int_info1_s cn63xx;
 	struct cvmx_sriox_int_info1_s cn63xxp1;
@@ -464,6 +765,7 @@
 union cvmx_sriox_int_info2 {
 	uint64_t u64;
 	struct cvmx_sriox_int_info2_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t prio:2;
 		uint64_t tt:1;
 		uint64_t sis:1;
@@ -475,6 +777,19 @@
 		uint64_t rsrvd:30;
 		uint64_t lns:1;
 		uint64_t intr:1;
+#else
+		uint64_t intr:1;
+		uint64_t lns:1;
+		uint64_t rsrvd:30;
+		uint64_t letter:2;
+		uint64_t mbox:2;
+		uint64_t xmbox:4;
+		uint64_t did:16;
+		uint64_t ssize:4;
+		uint64_t sis:1;
+		uint64_t tt:1;
+		uint64_t prio:2;
+#endif
 	} s;
 	struct cvmx_sriox_int_info2_s cn63xx;
 	struct cvmx_sriox_int_info2_s cn63xxp1;
@@ -484,11 +799,19 @@
 union cvmx_sriox_int_info3 {
 	uint64_t u64;
 	struct cvmx_sriox_int_info3_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t prio:2;
 		uint64_t tt:2;
 		uint64_t type:4;
 		uint64_t other:48;
 		uint64_t reserved_0_7:8;
+#else
+		uint64_t reserved_0_7:8;
+		uint64_t other:48;
+		uint64_t type:4;
+		uint64_t tt:2;
+		uint64_t prio:2;
+#endif
 	} s;
 	struct cvmx_sriox_int_info3_s cn63xx;
 	struct cvmx_sriox_int_info3_s cn63xxp1;
@@ -498,6 +821,7 @@
 union cvmx_sriox_int_reg {
 	uint64_t u64;
 	struct cvmx_sriox_int_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t int2_sum:1;
 		uint64_t reserved_27_30:4;
@@ -528,9 +852,42 @@
 		uint64_t rxbell:1;
 		uint64_t bell_err:1;
 		uint64_t txbell:1;
+#else
+		uint64_t txbell:1;
+		uint64_t bell_err:1;
+		uint64_t rxbell:1;
+		uint64_t maint_op:1;
+		uint64_t bar_err:1;
+		uint64_t deny_wr:1;
+		uint64_t sli_err:1;
+		uint64_t wr_done:1;
+		uint64_t mce_tx:1;
+		uint64_t mce_rx:1;
+		uint64_t soft_tx:1;
+		uint64_t soft_rx:1;
+		uint64_t log_erb:1;
+		uint64_t phy_erb:1;
+		uint64_t link_dwn:1;
+		uint64_t link_up:1;
+		uint64_t omsg0:1;
+		uint64_t omsg1:1;
+		uint64_t omsg_err:1;
+		uint64_t pko_err:1;
+		uint64_t rtry_err:1;
+		uint64_t f_error:1;
+		uint64_t mac_buf:1;
+		uint64_t degrad:1;
+		uint64_t fail:1;
+		uint64_t ttl_tout:1;
+		uint64_t zero_pkt:1;
+		uint64_t reserved_27_30:4;
+		uint64_t int2_sum:1;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sriox_int_reg_s cn63xx;
 	struct cvmx_sriox_int_reg_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_22_63:42;
 		uint64_t f_error:1;
 		uint64_t rtry_err:1;
@@ -554,6 +911,31 @@
 		uint64_t rxbell:1;
 		uint64_t bell_err:1;
 		uint64_t txbell:1;
+#else
+		uint64_t txbell:1;
+		uint64_t bell_err:1;
+		uint64_t rxbell:1;
+		uint64_t maint_op:1;
+		uint64_t bar_err:1;
+		uint64_t deny_wr:1;
+		uint64_t sli_err:1;
+		uint64_t wr_done:1;
+		uint64_t mce_tx:1;
+		uint64_t mce_rx:1;
+		uint64_t soft_tx:1;
+		uint64_t soft_rx:1;
+		uint64_t log_erb:1;
+		uint64_t phy_erb:1;
+		uint64_t link_dwn:1;
+		uint64_t link_up:1;
+		uint64_t omsg0:1;
+		uint64_t omsg1:1;
+		uint64_t omsg_err:1;
+		uint64_t pko_err:1;
+		uint64_t rtry_err:1;
+		uint64_t f_error:1;
+		uint64_t reserved_22_63:42;
+#endif
 	} cn63xxp1;
 	struct cvmx_sriox_int_reg_s cn66xx;
 };
@@ -561,6 +943,7 @@
 union cvmx_sriox_ip_feature {
 	uint64_t u64;
 	struct cvmx_sriox_ip_feature_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t ops:32;
 		uint64_t reserved_15_31:17;
 		uint64_t no_vmin:1;
@@ -571,8 +954,21 @@
 		uint64_t pt_width:2;
 		uint64_t tx_pol:4;
 		uint64_t rx_pol:4;
+#else
+		uint64_t rx_pol:4;
+		uint64_t tx_pol:4;
+		uint64_t pt_width:2;
+		uint64_t tx_flow:1;
+		uint64_t reserved_11_11:1;
+		uint64_t a50:1;
+		uint64_t a66:1;
+		uint64_t no_vmin:1;
+		uint64_t reserved_15_31:17;
+		uint64_t ops:32;
+#endif
 	} s;
 	struct cvmx_sriox_ip_feature_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t ops:32;
 		uint64_t reserved_14_31:18;
 		uint64_t a66:1;
@@ -582,6 +978,17 @@
 		uint64_t pt_width:2;
 		uint64_t tx_pol:4;
 		uint64_t rx_pol:4;
+#else
+		uint64_t rx_pol:4;
+		uint64_t tx_pol:4;
+		uint64_t pt_width:2;
+		uint64_t tx_flow:1;
+		uint64_t reserved_11_11:1;
+		uint64_t a50:1;
+		uint64_t a66:1;
+		uint64_t reserved_14_31:18;
+		uint64_t ops:32;
+#endif
 	} cn63xx;
 	struct cvmx_sriox_ip_feature_cn63xx cn63xxp1;
 	struct cvmx_sriox_ip_feature_s cn66xx;
@@ -590,6 +997,7 @@
 union cvmx_sriox_mac_buffers {
 	uint64_t u64;
 	struct cvmx_sriox_mac_buffers_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_56_63:8;
 		uint64_t tx_enb:8;
 		uint64_t reserved_44_47:4;
@@ -600,6 +1008,18 @@
 		uint64_t reserved_12_15:4;
 		uint64_t rx_inuse:4;
 		uint64_t rx_stat:8;
+#else
+		uint64_t rx_stat:8;
+		uint64_t rx_inuse:4;
+		uint64_t reserved_12_15:4;
+		uint64_t rx_enb:8;
+		uint64_t reserved_24_31:8;
+		uint64_t tx_stat:8;
+		uint64_t tx_inuse:4;
+		uint64_t reserved_44_47:4;
+		uint64_t tx_enb:8;
+		uint64_t reserved_56_63:8;
+#endif
 	} s;
 	struct cvmx_sriox_mac_buffers_s cn63xx;
 	struct cvmx_sriox_mac_buffers_s cn66xx;
@@ -608,12 +1028,21 @@
 union cvmx_sriox_maint_op {
 	uint64_t u64;
 	struct cvmx_sriox_maint_op_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t wr_data:32;
 		uint64_t reserved_27_31:5;
 		uint64_t fail:1;
 		uint64_t pending:1;
 		uint64_t op:1;
 		uint64_t addr:24;
+#else
+		uint64_t addr:24;
+		uint64_t op:1;
+		uint64_t pending:1;
+		uint64_t fail:1;
+		uint64_t reserved_27_31:5;
+		uint64_t wr_data:32;
+#endif
 	} s;
 	struct cvmx_sriox_maint_op_s cn63xx;
 	struct cvmx_sriox_maint_op_s cn63xxp1;
@@ -623,9 +1052,15 @@
 union cvmx_sriox_maint_rd_data {
 	uint64_t u64;
 	struct cvmx_sriox_maint_rd_data_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_33_63:31;
 		uint64_t valid:1;
 		uint64_t rd_data:32;
+#else
+		uint64_t rd_data:32;
+		uint64_t valid:1;
+		uint64_t reserved_33_63:31;
+#endif
 	} s;
 	struct cvmx_sriox_maint_rd_data_s cn63xx;
 	struct cvmx_sriox_maint_rd_data_s cn63xxp1;
@@ -635,8 +1070,13 @@
 union cvmx_sriox_mce_tx_ctl {
 	uint64_t u64;
 	struct cvmx_sriox_mce_tx_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t mce:1;
+#else
+		uint64_t mce:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
 	struct cvmx_sriox_mce_tx_ctl_s cn63xx;
 	struct cvmx_sriox_mce_tx_ctl_s cn63xxp1;
@@ -646,6 +1086,7 @@
 union cvmx_sriox_mem_op_ctrl {
 	uint64_t u64;
 	struct cvmx_sriox_mem_op_ctrl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t rr_ro:1;
 		uint64_t w_ro:1;
@@ -654,6 +1095,16 @@
 		uint64_t rp0_sid:2;
 		uint64_t rp1_pid:1;
 		uint64_t rp0_pid:2;
+#else
+		uint64_t rp0_pid:2;
+		uint64_t rp1_pid:1;
+		uint64_t rp0_sid:2;
+		uint64_t rp1_sid:1;
+		uint64_t reserved_6_7:2;
+		uint64_t w_ro:1;
+		uint64_t rr_ro:1;
+		uint64_t reserved_10_63:54;
+#endif
 	} s;
 	struct cvmx_sriox_mem_op_ctrl_s cn63xx;
 	struct cvmx_sriox_mem_op_ctrl_s cn63xxp1;
@@ -663,6 +1114,7 @@
 union cvmx_sriox_omsg_ctrlx {
 	uint64_t u64;
 	struct cvmx_sriox_omsg_ctrlx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t testmode:1;
 		uint64_t reserved_37_62:26;
 		uint64_t silo_max:5;
@@ -674,9 +1126,23 @@
 		uint64_t idm_did:1;
 		uint64_t lttr_sp:4;
 		uint64_t lttr_mp:4;
+#else
+		uint64_t lttr_mp:4;
+		uint64_t lttr_sp:4;
+		uint64_t idm_did:1;
+		uint64_t idm_sis:1;
+		uint64_t idm_tt:1;
+		uint64_t reserved_11_14:4;
+		uint64_t rtry_en:1;
+		uint64_t rtry_thr:16;
+		uint64_t silo_max:5;
+		uint64_t reserved_37_62:26;
+		uint64_t testmode:1;
+#endif
 	} s;
 	struct cvmx_sriox_omsg_ctrlx_s cn63xx;
 	struct cvmx_sriox_omsg_ctrlx_cn63xxp1 {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t testmode:1;
 		uint64_t reserved_32_62:31;
 		uint64_t rtry_thr:16;
@@ -687,6 +1153,18 @@
 		uint64_t idm_did:1;
 		uint64_t lttr_sp:4;
 		uint64_t lttr_mp:4;
+#else
+		uint64_t lttr_mp:4;
+		uint64_t lttr_sp:4;
+		uint64_t idm_did:1;
+		uint64_t idm_sis:1;
+		uint64_t idm_tt:1;
+		uint64_t reserved_11_14:4;
+		uint64_t rtry_en:1;
+		uint64_t rtry_thr:16;
+		uint64_t reserved_32_62:31;
+		uint64_t testmode:1;
+#endif
 	} cn63xxp1;
 	struct cvmx_sriox_omsg_ctrlx_s cn66xx;
 };
@@ -694,9 +1172,15 @@
 union cvmx_sriox_omsg_done_countsx {
 	uint64_t u64;
 	struct cvmx_sriox_omsg_done_countsx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t bad:16;
 		uint64_t good:16;
+#else
+		uint64_t good:16;
+		uint64_t bad:16;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sriox_omsg_done_countsx_s cn63xx;
 	struct cvmx_sriox_omsg_done_countsx_s cn66xx;
@@ -705,6 +1189,7 @@
 union cvmx_sriox_omsg_fmp_mrx {
 	uint64_t u64;
 	struct cvmx_sriox_omsg_fmp_mrx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_15_63:49;
 		uint64_t ctlr_sp:1;
 		uint64_t ctlr_fmp:1;
@@ -721,6 +1206,24 @@
 		uint64_t all_fmp:1;
 		uint64_t all_nmp:1;
 		uint64_t all_psd:1;
+#else
+		uint64_t all_psd:1;
+		uint64_t all_nmp:1;
+		uint64_t all_fmp:1;
+		uint64_t all_sp:1;
+		uint64_t mbox_psd:1;
+		uint64_t mbox_nmp:1;
+		uint64_t mbox_fmp:1;
+		uint64_t mbox_sp:1;
+		uint64_t id_psd:1;
+		uint64_t id_nmp:1;
+		uint64_t id_fmp:1;
+		uint64_t id_sp:1;
+		uint64_t ctlr_nmp:1;
+		uint64_t ctlr_fmp:1;
+		uint64_t ctlr_sp:1;
+		uint64_t reserved_15_63:49;
+#endif
 	} s;
 	struct cvmx_sriox_omsg_fmp_mrx_s cn63xx;
 	struct cvmx_sriox_omsg_fmp_mrx_s cn63xxp1;
@@ -730,6 +1233,7 @@
 union cvmx_sriox_omsg_nmp_mrx {
 	uint64_t u64;
 	struct cvmx_sriox_omsg_nmp_mrx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_15_63:49;
 		uint64_t ctlr_sp:1;
 		uint64_t ctlr_fmp:1;
@@ -746,6 +1250,24 @@
 		uint64_t all_fmp:1;
 		uint64_t all_nmp:1;
 		uint64_t reserved_0_0:1;
+#else
+		uint64_t reserved_0_0:1;
+		uint64_t all_nmp:1;
+		uint64_t all_fmp:1;
+		uint64_t all_sp:1;
+		uint64_t reserved_4_4:1;
+		uint64_t mbox_nmp:1;
+		uint64_t mbox_fmp:1;
+		uint64_t mbox_sp:1;
+		uint64_t reserved_8_8:1;
+		uint64_t id_nmp:1;
+		uint64_t id_fmp:1;
+		uint64_t id_sp:1;
+		uint64_t ctlr_nmp:1;
+		uint64_t ctlr_fmp:1;
+		uint64_t ctlr_sp:1;
+		uint64_t reserved_15_63:49;
+#endif
 	} s;
 	struct cvmx_sriox_omsg_nmp_mrx_s cn63xx;
 	struct cvmx_sriox_omsg_nmp_mrx_s cn63xxp1;
@@ -755,16 +1277,30 @@
 union cvmx_sriox_omsg_portx {
 	uint64_t u64;
 	struct cvmx_sriox_omsg_portx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t enable:1;
 		uint64_t reserved_3_30:28;
 		uint64_t port:3;
+#else
+		uint64_t port:3;
+		uint64_t reserved_3_30:28;
+		uint64_t enable:1;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sriox_omsg_portx_cn63xx {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t enable:1;
 		uint64_t reserved_2_30:29;
 		uint64_t port:2;
+#else
+		uint64_t port:2;
+		uint64_t reserved_2_30:29;
+		uint64_t enable:1;
+		uint64_t reserved_32_63:32;
+#endif
 	} cn63xx;
 	struct cvmx_sriox_omsg_portx_cn63xx cn63xxp1;
 	struct cvmx_sriox_omsg_portx_s cn66xx;
@@ -773,8 +1309,13 @@
 union cvmx_sriox_omsg_silo_thr {
 	uint64_t u64;
 	struct cvmx_sriox_omsg_silo_thr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t tot_silo:5;
+#else
+		uint64_t tot_silo:5;
+		uint64_t reserved_5_63:59;
+#endif
 	} s;
 	struct cvmx_sriox_omsg_silo_thr_s cn63xx;
 	struct cvmx_sriox_omsg_silo_thr_s cn66xx;
@@ -783,6 +1324,7 @@
 union cvmx_sriox_omsg_sp_mrx {
 	uint64_t u64;
 	struct cvmx_sriox_omsg_sp_mrx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t xmbox_sp:1;
 		uint64_t ctlr_sp:1;
@@ -800,6 +1342,25 @@
 		uint64_t all_fmp:1;
 		uint64_t all_nmp:1;
 		uint64_t all_psd:1;
+#else
+		uint64_t all_psd:1;
+		uint64_t all_nmp:1;
+		uint64_t all_fmp:1;
+		uint64_t all_sp:1;
+		uint64_t mbox_psd:1;
+		uint64_t mbox_nmp:1;
+		uint64_t mbox_fmp:1;
+		uint64_t mbox_sp:1;
+		uint64_t id_psd:1;
+		uint64_t id_nmp:1;
+		uint64_t id_fmp:1;
+		uint64_t id_sp:1;
+		uint64_t ctlr_nmp:1;
+		uint64_t ctlr_fmp:1;
+		uint64_t ctlr_sp:1;
+		uint64_t xmbox_sp:1;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_sriox_omsg_sp_mrx_s cn63xx;
 	struct cvmx_sriox_omsg_sp_mrx_s cn63xxp1;
@@ -809,9 +1370,15 @@
 union cvmx_sriox_priox_in_use {
 	uint64_t u64;
 	struct cvmx_sriox_priox_in_use_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t end_cnt:16;
 		uint64_t start_cnt:16;
+#else
+		uint64_t start_cnt:16;
+		uint64_t end_cnt:16;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sriox_priox_in_use_s cn63xx;
 	struct cvmx_sriox_priox_in_use_s cn66xx;
@@ -820,6 +1387,7 @@
 union cvmx_sriox_rx_bell {
 	uint64_t u64;
 	struct cvmx_sriox_rx_bell_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t data:16;
 		uint64_t src_id:16;
@@ -829,6 +1397,17 @@
 		uint64_t id16:1;
 		uint64_t reserved_2_2:1;
 		uint64_t priority:2;
+#else
+		uint64_t priority:2;
+		uint64_t reserved_2_2:1;
+		uint64_t id16:1;
+		uint64_t dest_id:1;
+		uint64_t reserved_5_7:3;
+		uint64_t count:8;
+		uint64_t src_id:16;
+		uint64_t data:16;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_sriox_rx_bell_s cn63xx;
 	struct cvmx_sriox_rx_bell_s cn63xxp1;
@@ -838,9 +1417,15 @@
 union cvmx_sriox_rx_bell_seq {
 	uint64_t u64;
 	struct cvmx_sriox_rx_bell_seq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_40_63:24;
 		uint64_t count:8;
 		uint64_t seq:32;
+#else
+		uint64_t seq:32;
+		uint64_t count:8;
+		uint64_t reserved_40_63:24;
+#endif
 	} s;
 	struct cvmx_sriox_rx_bell_seq_s cn63xx;
 	struct cvmx_sriox_rx_bell_seq_s cn63xxp1;
@@ -850,6 +1435,7 @@
 union cvmx_sriox_rx_status {
 	uint64_t u64;
 	struct cvmx_sriox_rx_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t rtn_pr3:8;
 		uint64_t rtn_pr2:8;
 		uint64_t rtn_pr1:8;
@@ -859,6 +1445,17 @@
 		uint64_t reserved_13_15:3;
 		uint64_t n_post:5;
 		uint64_t post:8;
+#else
+		uint64_t post:8;
+		uint64_t n_post:5;
+		uint64_t reserved_13_15:3;
+		uint64_t comp:8;
+		uint64_t mbox:4;
+		uint64_t reserved_28_39:12;
+		uint64_t rtn_pr1:8;
+		uint64_t rtn_pr2:8;
+		uint64_t rtn_pr3:8;
+#endif
 	} s;
 	struct cvmx_sriox_rx_status_s cn63xx;
 	struct cvmx_sriox_rx_status_s cn63xxp1;
@@ -868,6 +1465,7 @@
 union cvmx_sriox_s2m_typex {
 	uint64_t u64;
 	struct cvmx_sriox_s2m_typex_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_19_63:45;
 		uint64_t wr_op:3;
 		uint64_t reserved_15_15:1;
@@ -879,6 +1477,19 @@
 		uint64_t id16:1;
 		uint64_t reserved_2_3:2;
 		uint64_t iaow_sel:2;
+#else
+		uint64_t iaow_sel:2;
+		uint64_t reserved_2_3:2;
+		uint64_t id16:1;
+		uint64_t src_id:1;
+		uint64_t reserved_6_7:2;
+		uint64_t rd_prior:2;
+		uint64_t wr_prior:2;
+		uint64_t rd_op:3;
+		uint64_t reserved_15_15:1;
+		uint64_t wr_op:3;
+		uint64_t reserved_19_63:45;
+#endif
 	} s;
 	struct cvmx_sriox_s2m_typex_s cn63xx;
 	struct cvmx_sriox_s2m_typex_s cn63xxp1;
@@ -888,8 +1499,13 @@
 union cvmx_sriox_seq {
 	uint64_t u64;
 	struct cvmx_sriox_seq_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t seq:32;
+#else
+		uint64_t seq:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sriox_seq_s cn63xx;
 	struct cvmx_sriox_seq_s cn63xxp1;
@@ -899,9 +1515,15 @@
 union cvmx_sriox_status_reg {
 	uint64_t u64;
 	struct cvmx_sriox_status_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_2_63:62;
 		uint64_t access:1;
 		uint64_t srio:1;
+#else
+		uint64_t srio:1;
+		uint64_t access:1;
+		uint64_t reserved_2_63:62;
+#endif
 	} s;
 	struct cvmx_sriox_status_reg_s cn63xx;
 	struct cvmx_sriox_status_reg_s cn63xxp1;
@@ -911,12 +1533,21 @@
 union cvmx_sriox_tag_ctrl {
 	uint64_t u64;
 	struct cvmx_sriox_tag_ctrl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_17_63:47;
 		uint64_t o_clr:1;
 		uint64_t reserved_13_15:3;
 		uint64_t otag:5;
 		uint64_t reserved_5_7:3;
 		uint64_t itag:5;
+#else
+		uint64_t itag:5;
+		uint64_t reserved_5_7:3;
+		uint64_t otag:5;
+		uint64_t reserved_13_15:3;
+		uint64_t o_clr:1;
+		uint64_t reserved_17_63:47;
+#endif
 	} s;
 	struct cvmx_sriox_tag_ctrl_s cn63xx;
 	struct cvmx_sriox_tag_ctrl_s cn63xxp1;
@@ -926,12 +1557,21 @@
 union cvmx_sriox_tlp_credits {
 	uint64_t u64;
 	struct cvmx_sriox_tlp_credits_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_28_63:36;
 		uint64_t mbox:4;
 		uint64_t comp:8;
 		uint64_t reserved_13_15:3;
 		uint64_t n_post:5;
 		uint64_t post:8;
+#else
+		uint64_t post:8;
+		uint64_t n_post:5;
+		uint64_t reserved_13_15:3;
+		uint64_t comp:8;
+		uint64_t mbox:4;
+		uint64_t reserved_28_63:36;
+#endif
 	} s;
 	struct cvmx_sriox_tlp_credits_s cn63xx;
 	struct cvmx_sriox_tlp_credits_s cn63xxp1;
@@ -941,6 +1581,7 @@
 union cvmx_sriox_tx_bell {
 	uint64_t u64;
 	struct cvmx_sriox_tx_bell_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t data:16;
 		uint64_t dest_id:16;
@@ -951,6 +1592,18 @@
 		uint64_t id16:1;
 		uint64_t reserved_2_2:1;
 		uint64_t priority:2;
+#else
+		uint64_t priority:2;
+		uint64_t reserved_2_2:1;
+		uint64_t id16:1;
+		uint64_t src_id:1;
+		uint64_t reserved_5_7:3;
+		uint64_t pending:1;
+		uint64_t reserved_9_15:7;
+		uint64_t dest_id:16;
+		uint64_t data:16;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_sriox_tx_bell_s cn63xx;
 	struct cvmx_sriox_tx_bell_s cn63xxp1;
@@ -960,6 +1613,7 @@
 union cvmx_sriox_tx_bell_info {
 	uint64_t u64;
 	struct cvmx_sriox_tx_bell_info_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_48_63:16;
 		uint64_t data:16;
 		uint64_t dest_id:16;
@@ -971,6 +1625,19 @@
 		uint64_t id16:1;
 		uint64_t reserved_2_2:1;
 		uint64_t priority:2;
+#else
+		uint64_t priority:2;
+		uint64_t reserved_2_2:1;
+		uint64_t id16:1;
+		uint64_t src_id:1;
+		uint64_t retry:1;
+		uint64_t error:1;
+		uint64_t timeout:1;
+		uint64_t reserved_8_15:8;
+		uint64_t dest_id:16;
+		uint64_t data:16;
+		uint64_t reserved_48_63:16;
+#endif
 	} s;
 	struct cvmx_sriox_tx_bell_info_s cn63xx;
 	struct cvmx_sriox_tx_bell_info_s cn63xxp1;
@@ -980,6 +1647,7 @@
 union cvmx_sriox_tx_ctrl {
 	uint64_t u64;
 	struct cvmx_sriox_tx_ctrl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_53_63:11;
 		uint64_t tag_th2:5;
 		uint64_t reserved_45_47:3;
@@ -992,6 +1660,20 @@
 		uint64_t tx_th1:4;
 		uint64_t reserved_4_7:4;
 		uint64_t tx_th0:4;
+#else
+		uint64_t tx_th0:4;
+		uint64_t reserved_4_7:4;
+		uint64_t tx_th1:4;
+		uint64_t reserved_12_15:4;
+		uint64_t tx_th2:4;
+		uint64_t reserved_20_31:12;
+		uint64_t tag_th0:5;
+		uint64_t reserved_37_39:3;
+		uint64_t tag_th1:5;
+		uint64_t reserved_45_47:3;
+		uint64_t tag_th2:5;
+		uint64_t reserved_53_63:11;
+#endif
 	} s;
 	struct cvmx_sriox_tx_ctrl_s cn63xx;
 	struct cvmx_sriox_tx_ctrl_s cn63xxp1;
@@ -1001,8 +1683,13 @@
 union cvmx_sriox_tx_emphasis {
 	uint64_t u64;
 	struct cvmx_sriox_tx_emphasis_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t emph:4;
+#else
+		uint64_t emph:4;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_sriox_tx_emphasis_s cn63xx;
 	struct cvmx_sriox_tx_emphasis_s cn66xx;
@@ -1011,11 +1698,19 @@
 union cvmx_sriox_tx_status {
 	uint64_t u64;
 	struct cvmx_sriox_tx_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t s2m_pr3:8;
 		uint64_t s2m_pr2:8;
 		uint64_t s2m_pr1:8;
 		uint64_t s2m_pr0:8;
+#else
+		uint64_t s2m_pr0:8;
+		uint64_t s2m_pr1:8;
+		uint64_t s2m_pr2:8;
+		uint64_t s2m_pr3:8;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sriox_tx_status_s cn63xx;
 	struct cvmx_sriox_tx_status_s cn63xxp1;
@@ -1025,9 +1720,15 @@
 union cvmx_sriox_wr_done_counts {
 	uint64_t u64;
 	struct cvmx_sriox_wr_done_counts_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t bad:16;
 		uint64_t good:16;
+#else
+		uint64_t good:16;
+		uint64_t bad:16;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_sriox_wr_done_counts_s cn63xx;
 	struct cvmx_sriox_wr_done_counts_s cn66xx;
diff --git a/arch/mips/include/asm/octeon/cvmx-srxx-defs.h b/arch/mips/include/asm/octeon/cvmx-srxx-defs.h
index d82b366..c98e625 100644
--- a/arch/mips/include/asm/octeon/cvmx-srxx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-srxx-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -28,27 +28,29 @@
 #ifndef __CVMX_SRXX_DEFS_H__
 #define __CVMX_SRXX_DEFS_H__
 
-#define CVMX_SRXX_COM_CTL(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000200ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SRXX_IGN_RX_FULL(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000218ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SRXX_SPI4_CALX(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000000ull + (((offset) & 31) * 8) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SRXX_SPI4_STAT(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000208ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SRXX_SW_TICK_CTL(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000220ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_SRXX_SW_TICK_DAT(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000228ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_SRXX_COM_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180090000200ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SRXX_IGN_RX_FULL(block_id) (CVMX_ADD_IO_SEG(0x0001180090000218ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SRXX_SPI4_CALX(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180090000000ull) + (((offset) & 31) + ((block_id) & 1) * 0x1000000ull) * 8)
+#define CVMX_SRXX_SPI4_STAT(block_id) (CVMX_ADD_IO_SEG(0x0001180090000208ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SRXX_SW_TICK_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180090000220ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_SRXX_SW_TICK_DAT(block_id) (CVMX_ADD_IO_SEG(0x0001180090000228ull) + ((block_id) & 1) * 0x8000000ull)
 
 union cvmx_srxx_com_ctl {
 	uint64_t u64;
 	struct cvmx_srxx_com_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t prts:4;
 		uint64_t st_en:1;
 		uint64_t reserved_1_2:2;
 		uint64_t inf_en:1;
+#else
+		uint64_t inf_en:1;
+		uint64_t reserved_1_2:2;
+		uint64_t st_en:1;
+		uint64_t prts:4;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_srxx_com_ctl_s cn38xx;
 	struct cvmx_srxx_com_ctl_s cn38xxp2;
@@ -59,8 +61,13 @@
 union cvmx_srxx_ign_rx_full {
 	uint64_t u64;
 	struct cvmx_srxx_ign_rx_full_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t ignore:16;
+#else
+		uint64_t ignore:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_srxx_ign_rx_full_s cn38xx;
 	struct cvmx_srxx_ign_rx_full_s cn38xxp2;
@@ -71,12 +78,21 @@
 union cvmx_srxx_spi4_calx {
 	uint64_t u64;
 	struct cvmx_srxx_spi4_calx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_17_63:47;
 		uint64_t oddpar:1;
 		uint64_t prt3:4;
 		uint64_t prt2:4;
 		uint64_t prt1:4;
 		uint64_t prt0:4;
+#else
+		uint64_t prt0:4;
+		uint64_t prt1:4;
+		uint64_t prt2:4;
+		uint64_t prt3:4;
+		uint64_t oddpar:1;
+		uint64_t reserved_17_63:47;
+#endif
 	} s;
 	struct cvmx_srxx_spi4_calx_s cn38xx;
 	struct cvmx_srxx_spi4_calx_s cn38xxp2;
@@ -87,10 +103,17 @@
 union cvmx_srxx_spi4_stat {
 	uint64_t u64;
 	struct cvmx_srxx_spi4_stat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t m:8;
 		uint64_t reserved_7_7:1;
 		uint64_t len:7;
+#else
+		uint64_t len:7;
+		uint64_t reserved_7_7:1;
+		uint64_t m:8;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_srxx_spi4_stat_s cn38xx;
 	struct cvmx_srxx_spi4_stat_s cn38xxp2;
@@ -101,12 +124,21 @@
 union cvmx_srxx_sw_tick_ctl {
 	uint64_t u64;
 	struct cvmx_srxx_sw_tick_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_14_63:50;
 		uint64_t eop:1;
 		uint64_t sop:1;
 		uint64_t mod:4;
 		uint64_t opc:4;
 		uint64_t adr:4;
+#else
+		uint64_t adr:4;
+		uint64_t opc:4;
+		uint64_t mod:4;
+		uint64_t sop:1;
+		uint64_t eop:1;
+		uint64_t reserved_14_63:50;
+#endif
 	} s;
 	struct cvmx_srxx_sw_tick_ctl_s cn38xx;
 	struct cvmx_srxx_sw_tick_ctl_s cn58xx;
@@ -116,7 +148,11 @@
 union cvmx_srxx_sw_tick_dat {
 	uint64_t u64;
 	struct cvmx_srxx_sw_tick_dat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t dat:64;
+#else
+		uint64_t dat:64;
+#endif
 	} s;
 	struct cvmx_srxx_sw_tick_dat_s cn38xx;
 	struct cvmx_srxx_sw_tick_dat_s cn58xx;
diff --git a/arch/mips/include/asm/octeon/cvmx-stxx-defs.h b/arch/mips/include/asm/octeon/cvmx-stxx-defs.h
index 4f209b6..1463540 100644
--- a/arch/mips/include/asm/octeon/cvmx-stxx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-stxx-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -28,47 +28,39 @@
 #ifndef __CVMX_STXX_DEFS_H__
 #define __CVMX_STXX_DEFS_H__
 
-#define CVMX_STXX_ARB_CTL(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000608ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_BCKPRS_CNT(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000688ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_COM_CTL(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000600ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_DIP_CNT(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000690ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_IGN_CAL(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000610ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_INT_MSK(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800900006A0ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_INT_REG(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000698ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_INT_SYNC(block_id) \
-	 CVMX_ADD_IO_SEG(0x00011800900006A8ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_MIN_BST(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000618ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_SPI4_CALX(offset, block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000400ull + (((offset) & 31) * 8) + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_SPI4_DAT(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000628ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_SPI4_STAT(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000630ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_STAT_BYTES_HI(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000648ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_STAT_BYTES_LO(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000680ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_STAT_CTL(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000638ull + (((block_id) & 1) * 0x8000000ull))
-#define CVMX_STXX_STAT_PKT_XMT(block_id) \
-	 CVMX_ADD_IO_SEG(0x0001180090000640ull + (((block_id) & 1) * 0x8000000ull))
+#define CVMX_STXX_ARB_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180090000608ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_BCKPRS_CNT(block_id) (CVMX_ADD_IO_SEG(0x0001180090000688ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_COM_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180090000600ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_DIP_CNT(block_id) (CVMX_ADD_IO_SEG(0x0001180090000690ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_IGN_CAL(block_id) (CVMX_ADD_IO_SEG(0x0001180090000610ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_INT_MSK(block_id) (CVMX_ADD_IO_SEG(0x00011800900006A0ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_INT_REG(block_id) (CVMX_ADD_IO_SEG(0x0001180090000698ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_INT_SYNC(block_id) (CVMX_ADD_IO_SEG(0x00011800900006A8ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_MIN_BST(block_id) (CVMX_ADD_IO_SEG(0x0001180090000618ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_SPI4_CALX(offset, block_id) (CVMX_ADD_IO_SEG(0x0001180090000400ull) + (((offset) & 31) + ((block_id) & 1) * 0x1000000ull) * 8)
+#define CVMX_STXX_SPI4_DAT(block_id) (CVMX_ADD_IO_SEG(0x0001180090000628ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_SPI4_STAT(block_id) (CVMX_ADD_IO_SEG(0x0001180090000630ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_STAT_BYTES_HI(block_id) (CVMX_ADD_IO_SEG(0x0001180090000648ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_STAT_BYTES_LO(block_id) (CVMX_ADD_IO_SEG(0x0001180090000680ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_STAT_CTL(block_id) (CVMX_ADD_IO_SEG(0x0001180090000638ull) + ((block_id) & 1) * 0x8000000ull)
+#define CVMX_STXX_STAT_PKT_XMT(block_id) (CVMX_ADD_IO_SEG(0x0001180090000640ull) + ((block_id) & 1) * 0x8000000ull)
 
 union cvmx_stxx_arb_ctl {
 	uint64_t u64;
 	struct cvmx_stxx_arb_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t mintrn:1;
 		uint64_t reserved_4_4:1;
 		uint64_t igntpa:1;
 		uint64_t reserved_0_2:3;
+#else
+		uint64_t reserved_0_2:3;
+		uint64_t igntpa:1;
+		uint64_t reserved_4_4:1;
+		uint64_t mintrn:1;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
 	struct cvmx_stxx_arb_ctl_s cn38xx;
 	struct cvmx_stxx_arb_ctl_s cn38xxp2;
@@ -79,8 +71,13 @@
 union cvmx_stxx_bckprs_cnt {
 	uint64_t u64;
 	struct cvmx_stxx_bckprs_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_stxx_bckprs_cnt_s cn38xx;
 	struct cvmx_stxx_bckprs_cnt_s cn38xxp2;
@@ -91,10 +88,17 @@
 union cvmx_stxx_com_ctl {
 	uint64_t u64;
 	struct cvmx_stxx_com_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_4_63:60;
 		uint64_t st_en:1;
 		uint64_t reserved_1_2:2;
 		uint64_t inf_en:1;
+#else
+		uint64_t inf_en:1;
+		uint64_t reserved_1_2:2;
+		uint64_t st_en:1;
+		uint64_t reserved_4_63:60;
+#endif
 	} s;
 	struct cvmx_stxx_com_ctl_s cn38xx;
 	struct cvmx_stxx_com_ctl_s cn38xxp2;
@@ -105,9 +109,15 @@
 union cvmx_stxx_dip_cnt {
 	uint64_t u64;
 	struct cvmx_stxx_dip_cnt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t frmmax:4;
 		uint64_t dipmax:4;
+#else
+		uint64_t dipmax:4;
+		uint64_t frmmax:4;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_stxx_dip_cnt_s cn38xx;
 	struct cvmx_stxx_dip_cnt_s cn38xxp2;
@@ -118,8 +128,13 @@
 union cvmx_stxx_ign_cal {
 	uint64_t u64;
 	struct cvmx_stxx_ign_cal_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t igntpa:16;
+#else
+		uint64_t igntpa:16;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_stxx_ign_cal_s cn38xx;
 	struct cvmx_stxx_ign_cal_s cn38xxp2;
@@ -130,6 +145,7 @@
 union cvmx_stxx_int_msk {
 	uint64_t u64;
 	struct cvmx_stxx_int_msk_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t frmerr:1;
 		uint64_t unxfrm:1;
@@ -139,6 +155,17 @@
 		uint64_t ovrbst:1;
 		uint64_t calpar1:1;
 		uint64_t calpar0:1;
+#else
+		uint64_t calpar0:1;
+		uint64_t calpar1:1;
+		uint64_t ovrbst:1;
+		uint64_t datovr:1;
+		uint64_t diperr:1;
+		uint64_t nosync:1;
+		uint64_t unxfrm:1;
+		uint64_t frmerr:1;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_stxx_int_msk_s cn38xx;
 	struct cvmx_stxx_int_msk_s cn38xxp2;
@@ -149,6 +176,7 @@
 union cvmx_stxx_int_reg {
 	uint64_t u64;
 	struct cvmx_stxx_int_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t syncerr:1;
 		uint64_t frmerr:1;
@@ -159,6 +187,18 @@
 		uint64_t ovrbst:1;
 		uint64_t calpar1:1;
 		uint64_t calpar0:1;
+#else
+		uint64_t calpar0:1;
+		uint64_t calpar1:1;
+		uint64_t ovrbst:1;
+		uint64_t datovr:1;
+		uint64_t diperr:1;
+		uint64_t nosync:1;
+		uint64_t unxfrm:1;
+		uint64_t frmerr:1;
+		uint64_t syncerr:1;
+		uint64_t reserved_9_63:55;
+#endif
 	} s;
 	struct cvmx_stxx_int_reg_s cn38xx;
 	struct cvmx_stxx_int_reg_s cn38xxp2;
@@ -169,6 +209,7 @@
 union cvmx_stxx_int_sync {
 	uint64_t u64;
 	struct cvmx_stxx_int_sync_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t frmerr:1;
 		uint64_t unxfrm:1;
@@ -178,6 +219,17 @@
 		uint64_t ovrbst:1;
 		uint64_t calpar1:1;
 		uint64_t calpar0:1;
+#else
+		uint64_t calpar0:1;
+		uint64_t calpar1:1;
+		uint64_t ovrbst:1;
+		uint64_t datovr:1;
+		uint64_t diperr:1;
+		uint64_t nosync:1;
+		uint64_t unxfrm:1;
+		uint64_t frmerr:1;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
 	struct cvmx_stxx_int_sync_s cn38xx;
 	struct cvmx_stxx_int_sync_s cn38xxp2;
@@ -188,8 +240,13 @@
 union cvmx_stxx_min_bst {
 	uint64_t u64;
 	struct cvmx_stxx_min_bst_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_9_63:55;
 		uint64_t minb:9;
+#else
+		uint64_t minb:9;
+		uint64_t reserved_9_63:55;
+#endif
 	} s;
 	struct cvmx_stxx_min_bst_s cn38xx;
 	struct cvmx_stxx_min_bst_s cn38xxp2;
@@ -200,12 +257,21 @@
 union cvmx_stxx_spi4_calx {
 	uint64_t u64;
 	struct cvmx_stxx_spi4_calx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_17_63:47;
 		uint64_t oddpar:1;
 		uint64_t prt3:4;
 		uint64_t prt2:4;
 		uint64_t prt1:4;
 		uint64_t prt0:4;
+#else
+		uint64_t prt0:4;
+		uint64_t prt1:4;
+		uint64_t prt2:4;
+		uint64_t prt3:4;
+		uint64_t oddpar:1;
+		uint64_t reserved_17_63:47;
+#endif
 	} s;
 	struct cvmx_stxx_spi4_calx_s cn38xx;
 	struct cvmx_stxx_spi4_calx_s cn38xxp2;
@@ -216,9 +282,15 @@
 union cvmx_stxx_spi4_dat {
 	uint64_t u64;
 	struct cvmx_stxx_spi4_dat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t alpha:16;
 		uint64_t max_t:16;
+#else
+		uint64_t max_t:16;
+		uint64_t alpha:16;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_stxx_spi4_dat_s cn38xx;
 	struct cvmx_stxx_spi4_dat_s cn38xxp2;
@@ -229,10 +301,17 @@
 union cvmx_stxx_spi4_stat {
 	uint64_t u64;
 	struct cvmx_stxx_spi4_stat_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_16_63:48;
 		uint64_t m:8;
 		uint64_t reserved_7_7:1;
 		uint64_t len:7;
+#else
+		uint64_t len:7;
+		uint64_t reserved_7_7:1;
+		uint64_t m:8;
+		uint64_t reserved_16_63:48;
+#endif
 	} s;
 	struct cvmx_stxx_spi4_stat_s cn38xx;
 	struct cvmx_stxx_spi4_stat_s cn38xxp2;
@@ -243,8 +322,13 @@
 union cvmx_stxx_stat_bytes_hi {
 	uint64_t u64;
 	struct cvmx_stxx_stat_bytes_hi_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_stxx_stat_bytes_hi_s cn38xx;
 	struct cvmx_stxx_stat_bytes_hi_s cn38xxp2;
@@ -255,8 +339,13 @@
 union cvmx_stxx_stat_bytes_lo {
 	uint64_t u64;
 	struct cvmx_stxx_stat_bytes_lo_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_stxx_stat_bytes_lo_s cn38xx;
 	struct cvmx_stxx_stat_bytes_lo_s cn38xxp2;
@@ -267,9 +356,15 @@
 union cvmx_stxx_stat_ctl {
 	uint64_t u64;
 	struct cvmx_stxx_stat_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t clr:1;
 		uint64_t bckprs:4;
+#else
+		uint64_t bckprs:4;
+		uint64_t clr:1;
+		uint64_t reserved_5_63:59;
+#endif
 	} s;
 	struct cvmx_stxx_stat_ctl_s cn38xx;
 	struct cvmx_stxx_stat_ctl_s cn38xxp2;
@@ -280,8 +375,13 @@
 union cvmx_stxx_stat_pkt_xmt {
 	uint64_t u64;
 	struct cvmx_stxx_stat_pkt_xmt_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t cnt:32;
+#else
+		uint64_t cnt:32;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
 	struct cvmx_stxx_stat_pkt_xmt_s cn38xx;
 	struct cvmx_stxx_stat_pkt_xmt_s cn38xxp2;
diff --git a/arch/mips/include/asm/octeon/cvmx-uctlx-defs.h b/arch/mips/include/asm/octeon/cvmx-uctlx-defs.h
index 594f1b6..bc5b80c 100644
--- a/arch/mips/include/asm/octeon/cvmx-uctlx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-uctlx-defs.h
@@ -4,7 +4,7 @@
  * Contact: support@caviumnetworks.com
  * This file is part of the OCTEON SDK
  *
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2012 Cavium Networks
  *
  * This file is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License, Version 2, as
@@ -25,8 +25,8 @@
  * Contact Cavium Networks for more information
  ***********************license end**************************************/
 
-#ifndef __CVMX_UCTLX_TYPEDEFS_H__
-#define __CVMX_UCTLX_TYPEDEFS_H__
+#ifndef __CVMX_UCTLX_DEFS_H__
+#define __CVMX_UCTLX_DEFS_H__
 
 #define CVMX_UCTLX_BIST_STATUS(block_id) (CVMX_ADD_IO_SEG(0x000118006F0000A0ull))
 #define CVMX_UCTLX_CLK_RST_CTL(block_id) (CVMX_ADD_IO_SEG(0x000118006F000000ull))
@@ -45,6 +45,7 @@
 union cvmx_uctlx_bist_status {
 	uint64_t u64;
 	struct cvmx_uctlx_bist_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t data_bis:1;
 		uint64_t desc_bis:1;
@@ -52,14 +53,29 @@
 		uint64_t orbm_bis:1;
 		uint64_t wrbm_bis:1;
 		uint64_t ppaf_bis:1;
+#else
+		uint64_t ppaf_bis:1;
+		uint64_t wrbm_bis:1;
+		uint64_t orbm_bis:1;
+		uint64_t erbm_bis:1;
+		uint64_t desc_bis:1;
+		uint64_t data_bis:1;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
-	struct cvmx_uctlx_bist_status_s       cn63xx;
-	struct cvmx_uctlx_bist_status_s       cn63xxp1;
+	struct cvmx_uctlx_bist_status_s cn61xx;
+	struct cvmx_uctlx_bist_status_s cn63xx;
+	struct cvmx_uctlx_bist_status_s cn63xxp1;
+	struct cvmx_uctlx_bist_status_s cn66xx;
+	struct cvmx_uctlx_bist_status_s cn68xx;
+	struct cvmx_uctlx_bist_status_s cn68xxp1;
+	struct cvmx_uctlx_bist_status_s cnf71xx;
 };
 
 union cvmx_uctlx_clk_rst_ctl {
 	uint64_t u64;
 	struct cvmx_uctlx_clk_rst_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_25_63:39;
 		uint64_t clear_bist:1;
 		uint64_t start_bist:1;
@@ -81,14 +97,43 @@
 		uint64_t p_por:1;
 		uint64_t p_prst:1;
 		uint64_t hrst:1;
+#else
+		uint64_t hrst:1;
+		uint64_t p_prst:1;
+		uint64_t p_por:1;
+		uint64_t p_com_on:1;
+		uint64_t reserved_4_4:1;
+		uint64_t p_refclk_div:2;
+		uint64_t p_refclk_sel:2;
+		uint64_t h_div:4;
+		uint64_t o_clkdiv_en:1;
+		uint64_t h_clkdiv_en:1;
+		uint64_t h_clkdiv_rst:1;
+		uint64_t h_clkdiv_byp:1;
+		uint64_t o_clkdiv_rst:1;
+		uint64_t app_start_clk:1;
+		uint64_t ohci_susp_lgcy:1;
+		uint64_t ohci_sm:1;
+		uint64_t ohci_clkcktrst:1;
+		uint64_t ehci_sm:1;
+		uint64_t start_bist:1;
+		uint64_t clear_bist:1;
+		uint64_t reserved_25_63:39;
+#endif
 	} s;
-	struct cvmx_uctlx_clk_rst_ctl_s       cn63xx;
-	struct cvmx_uctlx_clk_rst_ctl_s       cn63xxp1;
+	struct cvmx_uctlx_clk_rst_ctl_s cn61xx;
+	struct cvmx_uctlx_clk_rst_ctl_s cn63xx;
+	struct cvmx_uctlx_clk_rst_ctl_s cn63xxp1;
+	struct cvmx_uctlx_clk_rst_ctl_s cn66xx;
+	struct cvmx_uctlx_clk_rst_ctl_s cn68xx;
+	struct cvmx_uctlx_clk_rst_ctl_s cn68xxp1;
+	struct cvmx_uctlx_clk_rst_ctl_s cnf71xx;
 };
 
 union cvmx_uctlx_ehci_ctl {
 	uint64_t u64;
 	struct cvmx_uctlx_ehci_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_20_63:44;
 		uint64_t desc_rbm:1;
 		uint64_t reg_nb:1;
@@ -101,45 +146,96 @@
 		uint64_t inv_reg_a2:1;
 		uint64_t ehci_64b_addr_en:1;
 		uint64_t l2c_addr_msb:8;
+#else
+		uint64_t l2c_addr_msb:8;
+		uint64_t ehci_64b_addr_en:1;
+		uint64_t inv_reg_a2:1;
+		uint64_t l2c_desc_emod:2;
+		uint64_t l2c_buff_emod:2;
+		uint64_t l2c_stt:1;
+		uint64_t l2c_0pag:1;
+		uint64_t l2c_bc:1;
+		uint64_t l2c_dc:1;
+		uint64_t reg_nb:1;
+		uint64_t desc_rbm:1;
+		uint64_t reserved_20_63:44;
+#endif
 	} s;
-	struct cvmx_uctlx_ehci_ctl_s          cn63xx;
-	struct cvmx_uctlx_ehci_ctl_s          cn63xxp1;
+	struct cvmx_uctlx_ehci_ctl_s cn61xx;
+	struct cvmx_uctlx_ehci_ctl_s cn63xx;
+	struct cvmx_uctlx_ehci_ctl_s cn63xxp1;
+	struct cvmx_uctlx_ehci_ctl_s cn66xx;
+	struct cvmx_uctlx_ehci_ctl_s cn68xx;
+	struct cvmx_uctlx_ehci_ctl_s cn68xxp1;
+	struct cvmx_uctlx_ehci_ctl_s cnf71xx;
 };
 
 union cvmx_uctlx_ehci_fla {
 	uint64_t u64;
 	struct cvmx_uctlx_ehci_fla_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_6_63:58;
 		uint64_t fla:6;
+#else
+		uint64_t fla:6;
+		uint64_t reserved_6_63:58;
+#endif
 	} s;
-	struct cvmx_uctlx_ehci_fla_s          cn63xx;
-	struct cvmx_uctlx_ehci_fla_s          cn63xxp1;
+	struct cvmx_uctlx_ehci_fla_s cn61xx;
+	struct cvmx_uctlx_ehci_fla_s cn63xx;
+	struct cvmx_uctlx_ehci_fla_s cn63xxp1;
+	struct cvmx_uctlx_ehci_fla_s cn66xx;
+	struct cvmx_uctlx_ehci_fla_s cn68xx;
+	struct cvmx_uctlx_ehci_fla_s cn68xxp1;
+	struct cvmx_uctlx_ehci_fla_s cnf71xx;
 };
 
 union cvmx_uctlx_erto_ctl {
 	uint64_t u64;
 	struct cvmx_uctlx_erto_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t to_val:27;
 		uint64_t reserved_0_4:5;
+#else
+		uint64_t reserved_0_4:5;
+		uint64_t to_val:27;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
-	struct cvmx_uctlx_erto_ctl_s          cn63xx;
-	struct cvmx_uctlx_erto_ctl_s          cn63xxp1;
+	struct cvmx_uctlx_erto_ctl_s cn61xx;
+	struct cvmx_uctlx_erto_ctl_s cn63xx;
+	struct cvmx_uctlx_erto_ctl_s cn63xxp1;
+	struct cvmx_uctlx_erto_ctl_s cn66xx;
+	struct cvmx_uctlx_erto_ctl_s cn68xx;
+	struct cvmx_uctlx_erto_ctl_s cn68xxp1;
+	struct cvmx_uctlx_erto_ctl_s cnf71xx;
 };
 
 union cvmx_uctlx_if_ena {
 	uint64_t u64;
 	struct cvmx_uctlx_if_ena_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_1_63:63;
 		uint64_t en:1;
+#else
+		uint64_t en:1;
+		uint64_t reserved_1_63:63;
+#endif
 	} s;
-	struct cvmx_uctlx_if_ena_s            cn63xx;
-	struct cvmx_uctlx_if_ena_s            cn63xxp1;
+	struct cvmx_uctlx_if_ena_s cn61xx;
+	struct cvmx_uctlx_if_ena_s cn63xx;
+	struct cvmx_uctlx_if_ena_s cn63xxp1;
+	struct cvmx_uctlx_if_ena_s cn66xx;
+	struct cvmx_uctlx_if_ena_s cn68xx;
+	struct cvmx_uctlx_if_ena_s cn68xxp1;
+	struct cvmx_uctlx_if_ena_s cnf71xx;
 };
 
 union cvmx_uctlx_int_ena {
 	uint64_t u64;
 	struct cvmx_uctlx_int_ena_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t ec_ovf_e:1;
 		uint64_t oc_ovf_e:1;
@@ -149,14 +245,31 @@
 		uint64_t or_psh_f:1;
 		uint64_t er_psh_f:1;
 		uint64_t pp_psh_f:1;
+#else
+		uint64_t pp_psh_f:1;
+		uint64_t er_psh_f:1;
+		uint64_t or_psh_f:1;
+		uint64_t cf_psh_f:1;
+		uint64_t wb_psh_f:1;
+		uint64_t wb_pop_e:1;
+		uint64_t oc_ovf_e:1;
+		uint64_t ec_ovf_e:1;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
-	struct cvmx_uctlx_int_ena_s           cn63xx;
-	struct cvmx_uctlx_int_ena_s           cn63xxp1;
+	struct cvmx_uctlx_int_ena_s cn61xx;
+	struct cvmx_uctlx_int_ena_s cn63xx;
+	struct cvmx_uctlx_int_ena_s cn63xxp1;
+	struct cvmx_uctlx_int_ena_s cn66xx;
+	struct cvmx_uctlx_int_ena_s cn68xx;
+	struct cvmx_uctlx_int_ena_s cn68xxp1;
+	struct cvmx_uctlx_int_ena_s cnf71xx;
 };
 
 union cvmx_uctlx_int_reg {
 	uint64_t u64;
 	struct cvmx_uctlx_int_reg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_8_63:56;
 		uint64_t ec_ovf_e:1;
 		uint64_t oc_ovf_e:1;
@@ -166,14 +279,31 @@
 		uint64_t or_psh_f:1;
 		uint64_t er_psh_f:1;
 		uint64_t pp_psh_f:1;
+#else
+		uint64_t pp_psh_f:1;
+		uint64_t er_psh_f:1;
+		uint64_t or_psh_f:1;
+		uint64_t cf_psh_f:1;
+		uint64_t wb_psh_f:1;
+		uint64_t wb_pop_e:1;
+		uint64_t oc_ovf_e:1;
+		uint64_t ec_ovf_e:1;
+		uint64_t reserved_8_63:56;
+#endif
 	} s;
-	struct cvmx_uctlx_int_reg_s           cn63xx;
-	struct cvmx_uctlx_int_reg_s           cn63xxp1;
+	struct cvmx_uctlx_int_reg_s cn61xx;
+	struct cvmx_uctlx_int_reg_s cn63xx;
+	struct cvmx_uctlx_int_reg_s cn63xxp1;
+	struct cvmx_uctlx_int_reg_s cn66xx;
+	struct cvmx_uctlx_int_reg_s cn68xx;
+	struct cvmx_uctlx_int_reg_s cn68xxp1;
+	struct cvmx_uctlx_int_reg_s cnf71xx;
 };
 
 union cvmx_uctlx_ohci_ctl {
 	uint64_t u64;
 	struct cvmx_uctlx_ohci_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_19_63:45;
 		uint64_t reg_nb:1;
 		uint64_t l2c_dc:1;
@@ -185,35 +315,73 @@
 		uint64_t inv_reg_a2:1;
 		uint64_t reserved_8_8:1;
 		uint64_t l2c_addr_msb:8;
+#else
+		uint64_t l2c_addr_msb:8;
+		uint64_t reserved_8_8:1;
+		uint64_t inv_reg_a2:1;
+		uint64_t l2c_desc_emod:2;
+		uint64_t l2c_buff_emod:2;
+		uint64_t l2c_stt:1;
+		uint64_t l2c_0pag:1;
+		uint64_t l2c_bc:1;
+		uint64_t l2c_dc:1;
+		uint64_t reg_nb:1;
+		uint64_t reserved_19_63:45;
+#endif
 	} s;
-	struct cvmx_uctlx_ohci_ctl_s          cn63xx;
-	struct cvmx_uctlx_ohci_ctl_s          cn63xxp1;
+	struct cvmx_uctlx_ohci_ctl_s cn61xx;
+	struct cvmx_uctlx_ohci_ctl_s cn63xx;
+	struct cvmx_uctlx_ohci_ctl_s cn63xxp1;
+	struct cvmx_uctlx_ohci_ctl_s cn66xx;
+	struct cvmx_uctlx_ohci_ctl_s cn68xx;
+	struct cvmx_uctlx_ohci_ctl_s cn68xxp1;
+	struct cvmx_uctlx_ohci_ctl_s cnf71xx;
 };
 
 union cvmx_uctlx_orto_ctl {
 	uint64_t u64;
 	struct cvmx_uctlx_orto_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_32_63:32;
 		uint64_t to_val:24;
 		uint64_t reserved_0_7:8;
+#else
+		uint64_t reserved_0_7:8;
+		uint64_t to_val:24;
+		uint64_t reserved_32_63:32;
+#endif
 	} s;
-	struct cvmx_uctlx_orto_ctl_s          cn63xx;
-	struct cvmx_uctlx_orto_ctl_s          cn63xxp1;
+	struct cvmx_uctlx_orto_ctl_s cn61xx;
+	struct cvmx_uctlx_orto_ctl_s cn63xx;
+	struct cvmx_uctlx_orto_ctl_s cn63xxp1;
+	struct cvmx_uctlx_orto_ctl_s cn66xx;
+	struct cvmx_uctlx_orto_ctl_s cn68xx;
+	struct cvmx_uctlx_orto_ctl_s cn68xxp1;
+	struct cvmx_uctlx_orto_ctl_s cnf71xx;
 };
 
 union cvmx_uctlx_ppaf_wm {
 	uint64_t u64;
 	struct cvmx_uctlx_ppaf_wm_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_5_63:59;
 		uint64_t wm:5;
+#else
+		uint64_t wm:5;
+		uint64_t reserved_5_63:59;
+#endif
 	} s;
-	struct cvmx_uctlx_ppaf_wm_s           cn63xx;
-	struct cvmx_uctlx_ppaf_wm_s           cn63xxp1;
+	struct cvmx_uctlx_ppaf_wm_s cn61xx;
+	struct cvmx_uctlx_ppaf_wm_s cn63xx;
+	struct cvmx_uctlx_ppaf_wm_s cn63xxp1;
+	struct cvmx_uctlx_ppaf_wm_s cn66xx;
+	struct cvmx_uctlx_ppaf_wm_s cnf71xx;
 };
 
 union cvmx_uctlx_uphy_ctl_status {
 	uint64_t u64;
 	struct cvmx_uctlx_uphy_ctl_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_10_63:54;
 		uint64_t bist_done:1;
 		uint64_t bist_err:1;
@@ -225,14 +393,33 @@
 		uint64_t uphy_bist:1;
 		uint64_t bist_en:1;
 		uint64_t ate_reset:1;
+#else
+		uint64_t ate_reset:1;
+		uint64_t bist_en:1;
+		uint64_t uphy_bist:1;
+		uint64_t vtest_en:1;
+		uint64_t siddq:1;
+		uint64_t lsbist:1;
+		uint64_t fsbist:1;
+		uint64_t hsbist:1;
+		uint64_t bist_err:1;
+		uint64_t bist_done:1;
+		uint64_t reserved_10_63:54;
+#endif
 	} s;
-	struct cvmx_uctlx_uphy_ctl_status_s   cn63xx;
-	struct cvmx_uctlx_uphy_ctl_status_s   cn63xxp1;
+	struct cvmx_uctlx_uphy_ctl_status_s cn61xx;
+	struct cvmx_uctlx_uphy_ctl_status_s cn63xx;
+	struct cvmx_uctlx_uphy_ctl_status_s cn63xxp1;
+	struct cvmx_uctlx_uphy_ctl_status_s cn66xx;
+	struct cvmx_uctlx_uphy_ctl_status_s cn68xx;
+	struct cvmx_uctlx_uphy_ctl_status_s cn68xxp1;
+	struct cvmx_uctlx_uphy_ctl_status_s cnf71xx;
 };
 
 union cvmx_uctlx_uphy_portx_ctl_status {
 	uint64_t u64;
 	struct cvmx_uctlx_uphy_portx_ctl_status_s {
+#ifdef __BIG_ENDIAN_BITFIELD
 		uint64_t reserved_43_63:21;
 		uint64_t tdata_out:4;
 		uint64_t txbiststuffenh:1;
@@ -253,9 +440,36 @@
 		uint64_t tdata_sel:1;
 		uint64_t taddr_in:4;
 		uint64_t tdata_in:8;
+#else
+		uint64_t tdata_in:8;
+		uint64_t taddr_in:4;
+		uint64_t tdata_sel:1;
+		uint64_t tclk:1;
+		uint64_t loop_en:1;
+		uint64_t compdistune:3;
+		uint64_t sqrxtune:3;
+		uint64_t txfslstune:4;
+		uint64_t txpreemphasistune:1;
+		uint64_t txrisetune:1;
+		uint64_t txvreftune:4;
+		uint64_t txhsvxtune:2;
+		uint64_t portreset:1;
+		uint64_t vbusvldext:1;
+		uint64_t dppulldown:1;
+		uint64_t dmpulldown:1;
+		uint64_t txbiststuffen:1;
+		uint64_t txbiststuffenh:1;
+		uint64_t tdata_out:4;
+		uint64_t reserved_43_63:21;
+#endif
 	} s;
+	struct cvmx_uctlx_uphy_portx_ctl_status_s cn61xx;
 	struct cvmx_uctlx_uphy_portx_ctl_status_s cn63xx;
 	struct cvmx_uctlx_uphy_portx_ctl_status_s cn63xxp1;
+	struct cvmx_uctlx_uphy_portx_ctl_status_s cn66xx;
+	struct cvmx_uctlx_uphy_portx_ctl_status_s cn68xx;
+	struct cvmx_uctlx_uphy_portx_ctl_status_s cn68xxp1;
+	struct cvmx_uctlx_uphy_portx_ctl_status_s cnf71xx;
 };
 
 #endif
diff --git a/arch/mips/include/asm/octeon/octeon-model.h b/arch/mips/include/asm/octeon/octeon-model.h
index 23b895c..14dd11f 100644
--- a/arch/mips/include/asm/octeon/octeon-model.h
+++ b/arch/mips/include/asm/octeon/octeon-model.h
@@ -61,6 +61,16 @@
 #define OM_MATCH_5XXX_FAMILY_MODELS     0x20000000
 /* Match all cn6XXX Octeon models. */
 #define OM_MATCH_6XXX_FAMILY_MODELS     0x40000000
+/* Match all cnf7XXX Octeon models. */
+#define OM_MATCH_F7XXX_FAMILY_MODELS    0x80000000
+
+/*
+ * CNF7XXX models with new revision encoding
+ */
+#define OCTEON_CNF71XX_PASS1_0  0x000d9400
+
+#define OCTEON_CNF71XX          (OCTEON_CNF71XX_PASS1_0 | OM_IGNORE_REVISION)
+#define OCTEON_CNF71XX_PASS1_X  (OCTEON_CNF71XX_PASS1_0 | OM_IGNORE_MINOR_REVISION)
 
 /*
  * CN6XXX models with new revision encoding
@@ -313,6 +323,14 @@
 const char *octeon_model_get_string(uint32_t chip_id);
 const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer);
 
+/*
+ * Return the octeon family, i.e., ProcessorID of the PrID register.
+ */
+static inline uint32_t cvmx_get_octeon_family(void)
+{
+	return cvmx_get_proc_id() & OCTEON_FAMILY_MASK;
+}
+
 #include <asm/octeon/octeon-feature.h>
 
 #endif /* __OCTEON_MODEL_H__ */
diff --git a/arch/mips/include/asm/octeon/octeon.h b/arch/mips/include/asm/octeon/octeon.h
index c4a1b31..790939d 100644
--- a/arch/mips/include/asm/octeon/octeon.h
+++ b/arch/mips/include/asm/octeon/octeon.h
@@ -52,6 +52,7 @@
 
 extern void octeon_init_cvmcount(void);
 extern void octeon_setup_delays(void);
+extern void octeon_io_clk_delay(unsigned long);
 
 #define OCTEON_ARGV_MAX_ARGS	64
 #define OCTOEN_SERIAL_LEN	20
@@ -254,4 +255,7 @@
 
 extern void (*octeon_irq_setup_secondary)(void);
 
+typedef void (*octeon_irq_ip4_handler_t)(void);
+void octeon_irq_set_ip4_handler(octeon_irq_ip4_handler_t);
+
 #endif /* __ASM_OCTEON_OCTEON_H */
diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h
index e9fe7e9..da4ba49 100644
--- a/arch/mips/include/asm/pgtable-bits.h
+++ b/arch/mips/include/asm/pgtable-bits.h
@@ -79,9 +79,9 @@
 /* implemented in software */
 #define _PAGE_PRESENT_SHIFT	(0)
 #define _PAGE_PRESENT		(1 << _PAGE_PRESENT_SHIFT)
-/* implemented in software, should be unused if kernel_uses_smartmips_rixi. */
-#define _PAGE_READ_SHIFT	(kernel_uses_smartmips_rixi ? _PAGE_PRESENT_SHIFT : _PAGE_PRESENT_SHIFT + 1)
-#define _PAGE_READ ({if (kernel_uses_smartmips_rixi) BUG(); 1 << _PAGE_READ_SHIFT; })
+/* implemented in software, should be unused if cpu_has_rixi. */
+#define _PAGE_READ_SHIFT	(cpu_has_rixi ? _PAGE_PRESENT_SHIFT : _PAGE_PRESENT_SHIFT + 1)
+#define _PAGE_READ ({BUG_ON(cpu_has_rixi); 1 << _PAGE_READ_SHIFT; })
 /* implemented in software */
 #define _PAGE_WRITE_SHIFT	(_PAGE_READ_SHIFT + 1)
 #define _PAGE_WRITE		(1 << _PAGE_WRITE_SHIFT)
@@ -104,12 +104,12 @@
 #endif
 
 /* Page cannot be executed */
-#define _PAGE_NO_EXEC_SHIFT	(kernel_uses_smartmips_rixi ? _PAGE_HUGE_SHIFT + 1 : _PAGE_HUGE_SHIFT)
-#define _PAGE_NO_EXEC		({if (!kernel_uses_smartmips_rixi) BUG(); 1 << _PAGE_NO_EXEC_SHIFT; })
+#define _PAGE_NO_EXEC_SHIFT	(cpu_has_rixi ? _PAGE_HUGE_SHIFT + 1 : _PAGE_HUGE_SHIFT)
+#define _PAGE_NO_EXEC		({BUG_ON(!cpu_has_rixi); 1 << _PAGE_NO_EXEC_SHIFT; })
 
 /* Page cannot be read */
-#define _PAGE_NO_READ_SHIFT	(kernel_uses_smartmips_rixi ? _PAGE_NO_EXEC_SHIFT + 1 : _PAGE_NO_EXEC_SHIFT)
-#define _PAGE_NO_READ		({if (!kernel_uses_smartmips_rixi) BUG(); 1 << _PAGE_NO_READ_SHIFT; })
+#define _PAGE_NO_READ_SHIFT	(cpu_has_rixi ? _PAGE_NO_EXEC_SHIFT + 1 : _PAGE_NO_EXEC_SHIFT)
+#define _PAGE_NO_READ		({BUG_ON(!cpu_has_rixi); 1 << _PAGE_NO_READ_SHIFT; })
 
 #define _PAGE_GLOBAL_SHIFT	(_PAGE_NO_READ_SHIFT + 1)
 #define _PAGE_GLOBAL		(1 << _PAGE_GLOBAL_SHIFT)
@@ -155,7 +155,7 @@
  */
 static inline uint64_t pte_to_entrylo(unsigned long pte_val)
 {
-	if (kernel_uses_smartmips_rixi) {
+	if (cpu_has_rixi) {
 		int sa;
 #ifdef CONFIG_32BIT
 		sa = 31 - _PAGE_NO_READ_SHIFT;
@@ -220,7 +220,7 @@
 
 #endif
 
-#define __READABLE	(_PAGE_SILENT_READ | _PAGE_ACCESSED | (kernel_uses_smartmips_rixi ? 0 : _PAGE_READ))
+#define __READABLE	(_PAGE_SILENT_READ | _PAGE_ACCESSED | (cpu_has_rixi ? 0 : _PAGE_READ))
 #define __WRITEABLE	(_PAGE_WRITE | _PAGE_SILENT_WRITE | _PAGE_MODIFIED)
 
 #define _PAGE_CHG_MASK  (_PFN_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED | _CACHE_MASK)
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index b2202a6..c02158b 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -22,15 +22,15 @@
 struct vm_area_struct;
 
 #define PAGE_NONE	__pgprot(_PAGE_PRESENT | _CACHE_CACHABLE_NONCOHERENT)
-#define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_WRITE | (kernel_uses_smartmips_rixi ? 0 : _PAGE_READ) | \
+#define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_WRITE | (cpu_has_rixi ? 0 : _PAGE_READ) | \
 				 _page_cachable_default)
-#define PAGE_COPY	__pgprot(_PAGE_PRESENT | (kernel_uses_smartmips_rixi ? 0 : _PAGE_READ) | \
-				 (kernel_uses_smartmips_rixi ?  _PAGE_NO_EXEC : 0) | _page_cachable_default)
-#define PAGE_READONLY	__pgprot(_PAGE_PRESENT | (kernel_uses_smartmips_rixi ? 0 : _PAGE_READ) | \
+#define PAGE_COPY	__pgprot(_PAGE_PRESENT | (cpu_has_rixi ? 0 : _PAGE_READ) | \
+				 (cpu_has_rixi ?  _PAGE_NO_EXEC : 0) | _page_cachable_default)
+#define PAGE_READONLY	__pgprot(_PAGE_PRESENT | (cpu_has_rixi ? 0 : _PAGE_READ) | \
 				 _page_cachable_default)
 #define PAGE_KERNEL	__pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
 				 _PAGE_GLOBAL | _page_cachable_default)
-#define PAGE_USERIO	__pgprot(_PAGE_PRESENT | (kernel_uses_smartmips_rixi ? 0 : _PAGE_READ) | _PAGE_WRITE | \
+#define PAGE_USERIO	__pgprot(_PAGE_PRESENT | (cpu_has_rixi ? 0 : _PAGE_READ) | _PAGE_WRITE | \
 				 _page_cachable_default)
 #define PAGE_KERNEL_UNCACHED __pgprot(_PAGE_PRESENT | __READABLE | \
 			__WRITEABLE | _PAGE_GLOBAL | _CACHE_UNCACHED)
@@ -299,7 +299,7 @@
 static inline pte_t pte_mkyoung(pte_t pte)
 {
 	pte_val(pte) |= _PAGE_ACCESSED;
-	if (kernel_uses_smartmips_rixi) {
+	if (cpu_has_rixi) {
 		if (!(pte_val(pte) & _PAGE_NO_READ))
 			pte_val(pte) |= _PAGE_SILENT_READ;
 	} else {
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h
index ca97e0e..8debe9e 100644
--- a/arch/mips/include/asm/thread_info.h
+++ b/arch/mips/include/asm/thread_info.h
@@ -103,7 +103,6 @@
 #define TIF_NOTIFY_RESUME	5	/* callback before returning to user */
 #define TIF_RESTORE_SIGMASK	9	/* restore signal mask in do_signal() */
 #define TIF_USEDFPU		16	/* FPU was used by this task this quantum (SMP) */
-#define TIF_POLLING_NRFLAG	17	/* true if poll_idle() is polling TIF_NEED_RESCHED */
 #define TIF_MEMDIE		18	/* is terminating due to OOM killer */
 #define TIF_FIXADE		20	/* Fix address errors in software */
 #define TIF_LOGADE		21	/* Log address errors to syslog */
@@ -125,9 +124,7 @@
 #define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP		(1<<TIF_SECCOMP)
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
-#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
 #define _TIF_USEDFPU		(1<<TIF_USEDFPU)
-#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 #define _TIF_FIXADE		(1<<TIF_FIXADE)
 #define _TIF_LOGADE		(1<<TIF_LOGADE)
 #define _TIF_32BIT_REGS		(1<<TIF_32BIT_REGS)
@@ -139,10 +136,10 @@
 #define _TIF_WORK_SYSCALL_EXIT	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT)
 
 /* work to do on interrupt/exception return */
-#define _TIF_WORK_MASK		(0x0000ffef &				\
-					~(_TIF_SECCOMP | _TIF_SYSCALL_AUDIT))
+#define _TIF_WORK_MASK		\
+	(_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME)
 /* work to do on any return to u-space */
-#define _TIF_ALLWORK_MASK	(0x8000ffff & ~_TIF_SECCOMP)
+#define _TIF_ALLWORK_MASK	(_TIF_WORK_MASK | _TIF_WORK_SYSCALL_EXIT)
 
 #endif /* __KERNEL__ */
 
diff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h
index 3d9f75f..7e0bf17 100644
--- a/arch/mips/include/asm/uasm.h
+++ b/arch/mips/include/asm/uasm.h
@@ -90,6 +90,8 @@
 Ip_u2u1u3(_dsrl32);
 Ip_u3u1u2(_dsubu);
 Ip_0(_eret);
+Ip_u2u1msbu3(_ext);
+Ip_u2u1msbu3(_ins);
 Ip_u1(_j);
 Ip_u1(_jal);
 Ip_u1(_jr);
diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h
index bebbde0..161fc4d 100644
--- a/arch/mips/include/asm/unistd.h
+++ b/arch/mips/include/asm/unistd.h
@@ -367,16 +367,17 @@
 #define __NR_setns			(__NR_Linux + 344)
 #define __NR_process_vm_readv		(__NR_Linux + 345)
 #define __NR_process_vm_writev		(__NR_Linux + 346)
+#define __NR_kcmp			(__NR_Linux + 347)
 
 /*
  * Offset of the last Linux o32 flavoured syscall
  */
-#define __NR_Linux_syscalls		346
+#define __NR_Linux_syscalls		347
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
 
 #define __NR_O32_Linux			4000
-#define __NR_O32_Linux_syscalls		346
+#define __NR_O32_Linux_syscalls		347
 
 #if _MIPS_SIM == _MIPS_SIM_ABI64
 
@@ -690,16 +691,17 @@
 #define __NR_setns			(__NR_Linux + 303)
 #define __NR_process_vm_readv		(__NR_Linux + 304)
 #define __NR_process_vm_writev		(__NR_Linux + 305)
+#define __NR_kcmp			(__NR_Linux + 306)
 
 /*
  * Offset of the last Linux 64-bit flavoured syscall
  */
-#define __NR_Linux_syscalls		305
+#define __NR_Linux_syscalls		306
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
 
 #define __NR_64_Linux			5000
-#define __NR_64_Linux_syscalls		305
+#define __NR_64_Linux_syscalls		306
 
 #if _MIPS_SIM == _MIPS_SIM_NABI32
 
@@ -1018,16 +1020,17 @@
 #define __NR_setns			(__NR_Linux + 308)
 #define __NR_process_vm_readv		(__NR_Linux + 309)
 #define __NR_process_vm_writev		(__NR_Linux + 310)
+#define __NR_kcmp			(__NR_Linux + 311)
 
 /*
  * Offset of the last N32 flavoured syscall
  */
-#define __NR_Linux_syscalls		310
+#define __NR_Linux_syscalls		311
 
 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
 
 #define __NR_N32_Linux			6000
-#define __NR_N32_Linux_syscalls		310
+#define __NR_N32_Linux_syscalls		311
 
 #ifdef __KERNEL__
 
diff --git a/arch/mips/jz4740/Kconfig b/arch/mips/jz4740/Kconfig
index 3e7141f..4689030 100644
--- a/arch/mips/jz4740/Kconfig
+++ b/arch/mips/jz4740/Kconfig
@@ -7,6 +7,3 @@
 	bool "Qi Hardware Ben NanoNote"
 
 endchoice
-
-config HAVE_PWM
-	bool
diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile
index e44abea..63bad0e 100644
--- a/arch/mips/jz4740/Makefile
+++ b/arch/mips/jz4740/Makefile
@@ -5,7 +5,7 @@
 # Object file lists.
 
 obj-y += prom.o irq.o time.o reset.o setup.o dma.o \
-	gpio.o clock.o platform.o timer.o pwm.o serial.o
+	gpio.o clock.o platform.o timer.o serial.o
 
 obj-$(CONFIG_DEBUG_FS) += clock-debugfs.o
 
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c
index 9a3d9de..43d964d 100644
--- a/arch/mips/jz4740/board-qi_lb60.c
+++ b/arch/mips/jz4740/board-qi_lb60.c
@@ -437,6 +437,7 @@
 	&jz4740_codec_device,
 	&jz4740_rtc_device,
 	&jz4740_adc_device,
+	&jz4740_pwm_device,
 	&qi_lb60_gpio_keys,
 	&qi_lb60_pwm_beeper,
 	&qi_lb60_charger_device,
diff --git a/arch/mips/jz4740/platform.c b/arch/mips/jz4740/platform.c
index e342ed4..6d14dcd 100644
--- a/arch/mips/jz4740/platform.c
+++ b/arch/mips/jz4740/platform.c
@@ -323,3 +323,9 @@
 	.num_resources = ARRAY_SIZE(jz4740_wdt_resources),
 	.resource      = jz4740_wdt_resources,
 };
+
+/* PWM */
+struct platform_device jz4740_pwm_device = {
+	.name = "jz4740-pwm",
+	.id   = -1,
+};
diff --git a/arch/mips/jz4740/pwm.c b/arch/mips/jz4740/pwm.c
deleted file mode 100644
index a26a6fa..0000000
--- a/arch/mips/jz4740/pwm.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
- *  JZ4740 platform PWM support
- *
- *  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.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <linux/kernel.h>
-
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/pwm.h>
-#include <linux/gpio.h>
-
-#include <asm/mach-jz4740/gpio.h>
-#include "timer.h"
-
-static struct clk *jz4740_pwm_clk;
-
-DEFINE_MUTEX(jz4740_pwm_mutex);
-
-struct pwm_device {
-	unsigned int id;
-	unsigned int gpio;
-	bool used;
-};
-
-static struct pwm_device jz4740_pwm_list[] = {
-	{ 2, JZ_GPIO_PWM2, false },
-	{ 3, JZ_GPIO_PWM3, false },
-	{ 4, JZ_GPIO_PWM4, false },
-	{ 5, JZ_GPIO_PWM5, false },
-	{ 6, JZ_GPIO_PWM6, false },
-	{ 7, JZ_GPIO_PWM7, false },
-};
-
-struct pwm_device *pwm_request(int id, const char *label)
-{
-	int ret = 0;
-	struct pwm_device *pwm;
-
-	if (id < 2 || id > 7 || !jz4740_pwm_clk)
-		return ERR_PTR(-ENODEV);
-
-	mutex_lock(&jz4740_pwm_mutex);
-
-	pwm = &jz4740_pwm_list[id - 2];
-	if (pwm->used)
-		ret = -EBUSY;
-	else
-		pwm->used = true;
-
-	mutex_unlock(&jz4740_pwm_mutex);
-
-	if (ret)
-		return ERR_PTR(ret);
-
-	ret = gpio_request(pwm->gpio, label);
-
-	if (ret) {
-		printk(KERN_ERR "Failed to request pwm gpio: %d\n", ret);
-		pwm->used = false;
-		return ERR_PTR(ret);
-	}
-
-	jz_gpio_set_function(pwm->gpio, JZ_GPIO_FUNC_PWM);
-
-	jz4740_timer_start(id);
-
-	return pwm;
-}
-
-void pwm_free(struct pwm_device *pwm)
-{
-	pwm_disable(pwm);
-	jz4740_timer_set_ctrl(pwm->id, 0);
-
-	jz_gpio_set_function(pwm->gpio, JZ_GPIO_FUNC_NONE);
-	gpio_free(pwm->gpio);
-
-	jz4740_timer_stop(pwm->id);
-
-	pwm->used = false;
-}
-
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
-{
-	unsigned long long tmp;
-	unsigned long period, duty;
-	unsigned int prescaler = 0;
-	unsigned int id = pwm->id;
-	uint16_t ctrl;
-	bool is_enabled;
-
-	if (duty_ns < 0 || duty_ns > period_ns)
-		return -EINVAL;
-
-	tmp = (unsigned long long)clk_get_rate(jz4740_pwm_clk) * period_ns;
-	do_div(tmp, 1000000000);
-	period = tmp;
-
-	while (period > 0xffff && prescaler < 6) {
-		period >>= 2;
-		++prescaler;
-	}
-
-	if (prescaler == 6)
-		return -EINVAL;
-
-	tmp = (unsigned long long)period * duty_ns;
-	do_div(tmp, period_ns);
-	duty = period - tmp;
-
-	if (duty >= period)
-		duty = period - 1;
-
-	is_enabled = jz4740_timer_is_enabled(id);
-	if (is_enabled)
-		pwm_disable(pwm);
-
-	jz4740_timer_set_count(id, 0);
-	jz4740_timer_set_duty(id, duty);
-	jz4740_timer_set_period(id, period);
-
-	ctrl = JZ_TIMER_CTRL_PRESCALER(prescaler) | JZ_TIMER_CTRL_SRC_EXT |
-		JZ_TIMER_CTRL_PWM_ABBRUPT_SHUTDOWN;
-
-	jz4740_timer_set_ctrl(id, ctrl);
-
-	if (is_enabled)
-		pwm_enable(pwm);
-
-	return 0;
-}
-
-int pwm_enable(struct pwm_device *pwm)
-{
-	uint32_t ctrl = jz4740_timer_get_ctrl(pwm->id);
-
-	ctrl |= JZ_TIMER_CTRL_PWM_ENABLE;
-	jz4740_timer_set_ctrl(pwm->id, ctrl);
-	jz4740_timer_enable(pwm->id);
-
-	return 0;
-}
-
-void pwm_disable(struct pwm_device *pwm)
-{
-	uint32_t ctrl = jz4740_timer_get_ctrl(pwm->id);
-
-	ctrl &= ~JZ_TIMER_CTRL_PWM_ENABLE;
-	jz4740_timer_disable(pwm->id);
-	jz4740_timer_set_ctrl(pwm->id, ctrl);
-}
-
-static int __init jz4740_pwm_init(void)
-{
-	int ret = 0;
-
-	jz4740_pwm_clk = clk_get(NULL, "ext");
-
-	if (IS_ERR(jz4740_pwm_clk)) {
-		ret = PTR_ERR(jz4740_pwm_clk);
-		jz4740_pwm_clk = NULL;
-	}
-
-	return ret;
-}
-subsys_initcall(jz4740_pwm_init);
diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c
index f83c2dd..39bb4bb 100644
--- a/arch/mips/jz4740/time.c
+++ b/arch/mips/jz4740/time.c
@@ -20,10 +20,10 @@
 #include <linux/clockchips.h>
 
 #include <asm/mach-jz4740/irq.h>
+#include <asm/mach-jz4740/timer.h>
 #include <asm/time.h>
 
 #include "clock.h"
-#include "timer.h"
 
 #define TIMER_CLOCKEVENT 0
 #define TIMER_CLOCKSOURCE 1
diff --git a/arch/mips/jz4740/timer.c b/arch/mips/jz4740/timer.c
index 654d5c3..22f11d7 100644
--- a/arch/mips/jz4740/timer.c
+++ b/arch/mips/jz4740/timer.c
@@ -17,11 +17,11 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 
-#include "timer.h"
-
 #include <asm/mach-jz4740/base.h>
+#include <asm/mach-jz4740/timer.h>
 
 void __iomem *jz4740_timer_base;
+EXPORT_SYMBOL_GPL(jz4740_timer_base);
 
 void jz4740_timer_enable_watchdog(void)
 {
diff --git a/arch/mips/jz4740/timer.h b/arch/mips/jz4740/timer.h
deleted file mode 100644
index fca3994..0000000
--- a/arch/mips/jz4740/timer.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
- *  JZ4740 platform timer support
- *
- *  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.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#ifndef __MIPS_JZ4740_TIMER_H__
-#define __MIPS_JZ4740_TIMER_H__
-
-#include <linux/module.h>
-#include <linux/io.h>
-
-#define JZ_REG_TIMER_STOP		0x0C
-#define JZ_REG_TIMER_STOP_SET		0x1C
-#define JZ_REG_TIMER_STOP_CLEAR		0x2C
-#define JZ_REG_TIMER_ENABLE		0x00
-#define JZ_REG_TIMER_ENABLE_SET		0x04
-#define JZ_REG_TIMER_ENABLE_CLEAR	0x08
-#define JZ_REG_TIMER_FLAG		0x10
-#define JZ_REG_TIMER_FLAG_SET		0x14
-#define JZ_REG_TIMER_FLAG_CLEAR		0x18
-#define JZ_REG_TIMER_MASK		0x20
-#define JZ_REG_TIMER_MASK_SET		0x24
-#define JZ_REG_TIMER_MASK_CLEAR		0x28
-
-#define JZ_REG_TIMER_DFR(x) (((x) * 0x10) + 0x30)
-#define JZ_REG_TIMER_DHR(x) (((x) * 0x10) + 0x34)
-#define JZ_REG_TIMER_CNT(x) (((x) * 0x10) + 0x38)
-#define JZ_REG_TIMER_CTRL(x) (((x) * 0x10) + 0x3C)
-
-#define JZ_TIMER_IRQ_HALF(x) BIT((x) + 0x10)
-#define JZ_TIMER_IRQ_FULL(x) BIT(x)
-
-#define JZ_TIMER_CTRL_PWM_ABBRUPT_SHUTDOWN	BIT(9)
-#define JZ_TIMER_CTRL_PWM_ACTIVE_LOW		BIT(8)
-#define JZ_TIMER_CTRL_PWM_ENABLE		BIT(7)
-#define JZ_TIMER_CTRL_PRESCALE_MASK		0x1c
-#define JZ_TIMER_CTRL_PRESCALE_OFFSET		0x3
-#define JZ_TIMER_CTRL_PRESCALE_1		(0 << 3)
-#define JZ_TIMER_CTRL_PRESCALE_4		(1 << 3)
-#define JZ_TIMER_CTRL_PRESCALE_16		(2 << 3)
-#define JZ_TIMER_CTRL_PRESCALE_64		(3 << 3)
-#define JZ_TIMER_CTRL_PRESCALE_256		(4 << 3)
-#define JZ_TIMER_CTRL_PRESCALE_1024		(5 << 3)
-
-#define JZ_TIMER_CTRL_PRESCALER(x) ((x) << JZ_TIMER_CTRL_PRESCALE_OFFSET)
-
-#define JZ_TIMER_CTRL_SRC_EXT		BIT(2)
-#define JZ_TIMER_CTRL_SRC_RTC		BIT(1)
-#define JZ_TIMER_CTRL_SRC_PCLK		BIT(0)
-
-extern void __iomem *jz4740_timer_base;
-void __init jz4740_timer_init(void);
-
-static inline void jz4740_timer_stop(unsigned int timer)
-{
-	writel(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_STOP_SET);
-}
-
-static inline void jz4740_timer_start(unsigned int timer)
-{
-	writel(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_STOP_CLEAR);
-}
-
-static inline bool jz4740_timer_is_enabled(unsigned int timer)
-{
-	return readb(jz4740_timer_base + JZ_REG_TIMER_ENABLE) & BIT(timer);
-}
-
-static inline void jz4740_timer_enable(unsigned int timer)
-{
-	writeb(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_ENABLE_SET);
-}
-
-static inline void jz4740_timer_disable(unsigned int timer)
-{
-	writeb(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_ENABLE_CLEAR);
-}
-
-
-static inline void jz4740_timer_set_period(unsigned int timer, uint16_t period)
-{
-	writew(period, jz4740_timer_base + JZ_REG_TIMER_DFR(timer));
-}
-
-static inline void jz4740_timer_set_duty(unsigned int timer, uint16_t duty)
-{
-	writew(duty, jz4740_timer_base + JZ_REG_TIMER_DHR(timer));
-}
-
-static inline void jz4740_timer_set_count(unsigned int timer, uint16_t count)
-{
-	writew(count, jz4740_timer_base + JZ_REG_TIMER_CNT(timer));
-}
-
-static inline uint16_t jz4740_timer_get_count(unsigned int timer)
-{
-	return readw(jz4740_timer_base + JZ_REG_TIMER_CNT(timer));
-}
-
-static inline void jz4740_timer_ack_full(unsigned int timer)
-{
-	writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_FLAG_CLEAR);
-}
-
-static inline void jz4740_timer_irq_full_enable(unsigned int timer)
-{
-	writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_FLAG_CLEAR);
-	writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_CLEAR);
-}
-
-static inline void jz4740_timer_irq_full_disable(unsigned int timer)
-{
-	writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_SET);
-}
-
-static inline void jz4740_timer_set_ctrl(unsigned int timer, uint16_t ctrl)
-{
-	writew(ctrl, jz4740_timer_base + JZ_REG_TIMER_CTRL(timer));
-}
-
-static inline uint16_t jz4740_timer_get_ctrl(unsigned int timer)
-{
-	return readw(jz4740_timer_base + JZ_REG_TIMER_CTRL(timer));
-}
-
-#endif
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index fdaf65e..d6c2a74 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -34,28 +34,11 @@
 
 obj-$(CONFIG_FUNCTION_TRACER)	+= mcount.o ftrace.o
 
-obj-$(CONFIG_CPU_LOONGSON2)	+= r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_MIPS32)	+= r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_MIPS64)	+= r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_R4K_FPU)	+= r4k_fpu.o r4k_switch.o
 obj-$(CONFIG_CPU_R3000)		+= r2300_fpu.o r2300_switch.o
-obj-$(CONFIG_CPU_R4300)		+= r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_R4X00)		+= r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_R5000)		+= r4k_fpu.o r4k_switch.o
 obj-$(CONFIG_CPU_R6000)		+= r6000_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_R5432)		+= r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_R5500)		+= r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_R8000)		+= r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_RM7000)	+= r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_RM9000)	+= r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_NEVADA)	+= r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_R10000)	+= r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_SB1)		+= r4k_fpu.o r4k_switch.o
 obj-$(CONFIG_CPU_TX39XX)	+= r2300_fpu.o r2300_switch.o
-obj-$(CONFIG_CPU_TX49XX)	+= r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_VR41XX)	+= r4k_fpu.o r4k_switch.o
 obj-$(CONFIG_CPU_CAVIUM_OCTEON)	+= octeon_switch.o
-obj-$(CONFIG_CPU_XLR)		+= r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_XLP)		+= r4k_fpu.o r4k_switch.o
 
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_SMP_UP)		+= smp-up.o
@@ -104,7 +87,7 @@
 
 obj-$(CONFIG_OF)		+= prom.o
 
-CFLAGS_cpu-bugs64.o	= $(shell if $(CC) $(KBUILD_CFLAGS) -Wa,-mdaddi -c -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi)
+CFLAGS_cpu-bugs64.o	= $(shell if $(CC) $(KBUILD_CFLAGS) -Wa,-mdaddi -c -o /dev/null -x c /dev/null >/dev/null 2>&1; then echo "-DHAVE_AS_SET_DADDI"; fi)
 
 obj-$(CONFIG_HAVE_STD_PC_SERIAL_PORT)	+= 8250-platform.o
 
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c
index 51095dd9..7532392 100644
--- a/arch/mips/kernel/cevt-r4k.c
+++ b/arch/mips/kernel/cevt-r4k.c
@@ -15,6 +15,7 @@
 #include <asm/smtc_ipi.h>
 #include <asm/time.h>
 #include <asm/cevt-r4k.h>
+#include <asm/gic.h>
 
 /*
  * The SMTC Kernel for the 34K, 1004K, et. al. replaces several
@@ -98,6 +99,10 @@
  */
 static int c0_compare_int_pending(void)
 {
+#ifdef CONFIG_IRQ_GIC
+	if (cpu_has_veic)
+		return gic_get_timer_pending();
+#endif
 	return (read_c0_cause() >> cp0_compare_irq_shift) & (1ul << CAUSEB_IP);
 }
 
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 1b51046..bc58bd1 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -421,8 +421,12 @@
 
 	config3 = read_c0_config3();
 
-	if (config3 & MIPS_CONF3_SM)
+	if (config3 & MIPS_CONF3_SM) {
 		c->ases |= MIPS_ASE_SMARTMIPS;
+		c->options |= MIPS_CPU_RIXI;
+	}
+	if (config3 & MIPS_CONF3_RXI)
+		c->options |= MIPS_CPU_RIXI;
 	if (config3 & MIPS_CONF3_DSP)
 		c->ases |= MIPS_ASE_DSP;
 	if (config3 & MIPS_CONF3_VINT)
@@ -857,6 +861,10 @@
 		c->cputype = CPU_1004K;
 		__cpu_name[cpu] = "MIPS 1004Kc";
 		break;
+	case PRID_IMP_1074K:
+		c->cputype = CPU_74K;
+		__cpu_name[cpu] = "MIPS 1074Kc";
+		break;
 	}
 
 	spram_config();
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S
index 37acfa0..a6c1332 100644
--- a/arch/mips/kernel/entry.S
+++ b/arch/mips/kernel/entry.S
@@ -77,7 +77,7 @@
 	and	t0, a2, t0
 	bnez	t0, syscall_exit_work
 
-FEXPORT(restore_all)			# restore full frame
+restore_all:				# restore full frame
 #ifdef CONFIG_MIPS_MT_SMTC
 #ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP
 /* Re-arm any temporarily masked interrupts not explicitly "acked" */
@@ -117,7 +117,7 @@
 	RESTORE_TEMP
 	RESTORE_AT
 	RESTORE_STATIC
-FEXPORT(restore_partial)		# restore partial frame
+restore_partial:		# restore partial frame
 #ifdef CONFIG_TRACE_IRQFLAGS
 	SAVE_STATIC
 	SAVE_AT
@@ -164,9 +164,18 @@
 	jal	do_notify_resume	# a2 already loaded
 	j	resume_userspace
 
-FEXPORT(syscall_exit_work_partial)
+FEXPORT(syscall_exit_partial)
+	local_irq_disable		# make sure need_resched doesn't
+					# change between and return
+	LONG_L	a2, TI_FLAGS($28)	# current->work
+	li	t0, _TIF_ALLWORK_MASK
+	and	t0, a2
+	beqz	t0, restore_partial
 	SAVE_STATIC
 syscall_exit_work:
+	LONG_L	t0, PT_STATUS(sp)		# returning to kernel mode?
+	andi	t0, t0, KU_USER
+	beqz	t0, resume_kernel
 	li	t0, _TIF_WORK_SYSCALL_EXIT
 	and	t0, a2			# a2 is preloaded with TI_FLAGS
 	beqz	t0, work_pending	# trace bit set?
diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c
index 0c527f6..485e6a9 100644
--- a/arch/mips/kernel/irq-gic.c
+++ b/arch/mips/kernel/irq-gic.c
@@ -1,5 +1,11 @@
-#undef DEBUG
-
+/*
+ * 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.
+ *
+ * Copyright (C) 2008 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
+ */
 #include <linux/bitmap.h>
 #include <linux/init.h>
 #include <linux/smp.h>
@@ -7,33 +13,80 @@
 
 #include <asm/io.h>
 #include <asm/gic.h>
+#include <asm/setup.h>
+#include <asm/traps.h>
 #include <asm/gcmpregs.h>
 #include <linux/hardirq.h>
 #include <asm-generic/bitops/find.h>
 
+unsigned long _gic_base;
+unsigned int gic_irq_base;
+unsigned int gic_irq_flags[GIC_NUM_INTRS];
 
-static unsigned long _gic_base;
-static unsigned int _irqbase;
-static unsigned int gic_irq_flags[GIC_NUM_INTRS];
-#define GIC_IRQ_FLAG_EDGE      0x0001
+/* The index into this array is the vector # of the interrupt. */
+struct gic_shared_intr_map gic_shared_intr_map[GIC_NUM_INTRS];
 
-struct gic_pcpu_mask pcpu_masks[NR_CPUS];
+static struct gic_pcpu_mask pcpu_masks[NR_CPUS];
 static struct gic_pending_regs pending_regs[NR_CPUS];
 static struct gic_intrmask_regs intrmask_regs[NR_CPUS];
 
+unsigned int gic_get_timer_pending(void)
+{
+	unsigned int vpe_pending;
+
+	GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), 0);
+	GICREAD(GIC_REG(VPE_OTHER, GIC_VPE_PEND), vpe_pending);
+	return (vpe_pending & GIC_VPE_PEND_TIMER_MSK);
+}
+
+void gic_bind_eic_interrupt(int irq, int set)
+{
+	/* Convert irq vector # to hw int # */
+	irq -= GIC_PIN_TO_VEC_OFFSET;
+
+	/* Set irq to use shadow set */
+	GICWRITE(GIC_REG_ADDR(VPE_LOCAL, GIC_VPE_EIC_SS(irq)), set);
+}
+
 void gic_send_ipi(unsigned int intr)
 {
-	pr_debug("CPU%d: %s status %08x\n", smp_processor_id(), __func__,
-		 read_c0_status());
 	GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr);
 }
 
-/* This is Malta specific and needs to be exported */
+static void gic_eic_irq_dispatch(void)
+{
+	unsigned int cause = read_c0_cause();
+	int irq;
+
+	irq = (cause & ST0_IM) >> STATUSB_IP2;
+	if (irq == 0)
+		irq = -1;
+
+	if (irq >= 0)
+		do_IRQ(gic_irq_base + irq);
+	else
+		spurious_interrupt();
+}
+
 static void __init vpe_local_setup(unsigned int numvpes)
 {
-	int i;
-	unsigned long timer_interrupt = 5, perf_interrupt = 5;
+	unsigned long timer_intr = GIC_INT_TMR;
+	unsigned long perf_intr = GIC_INT_PERFCTR;
 	unsigned int vpe_ctl;
+	int i;
+
+	if (cpu_has_veic) {
+		/*
+		 * GIC timer interrupt -> CPU HW Int X (vector X+2) ->
+		 * map to pin X+2-1 (since GIC adds 1)
+		 */
+		timer_intr += (GIC_CPU_TO_VEC_OFFSET - GIC_PIN_TO_VEC_OFFSET);
+		/*
+		 * GIC perfcnt interrupt -> CPU HW Int X (vector X+2) ->
+		 * map to pin X+2-1 (since GIC adds 1)
+		 */
+		perf_intr += (GIC_CPU_TO_VEC_OFFSET - GIC_PIN_TO_VEC_OFFSET);
+	}
 
 	/*
 	 * Setup the default performance counter timer interrupts
@@ -46,11 +99,20 @@
 		GICREAD(GIC_REG(VPE_OTHER, GIC_VPE_CTL), vpe_ctl);
 		if (vpe_ctl & GIC_VPE_CTL_TIMER_RTBL_MSK)
 			GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_TIMER_MAP),
-				 GIC_MAP_TO_PIN_MSK | timer_interrupt);
+				 GIC_MAP_TO_PIN_MSK | timer_intr);
+		if (cpu_has_veic) {
+			set_vi_handler(timer_intr + GIC_PIN_TO_VEC_OFFSET,
+				gic_eic_irq_dispatch);
+			gic_shared_intr_map[timer_intr + GIC_PIN_TO_VEC_OFFSET].local_intr_mask |= GIC_VPE_RMASK_TIMER_MSK;
+		}
 
 		if (vpe_ctl & GIC_VPE_CTL_PERFCNT_RTBL_MSK)
 			GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_PERFCTR_MAP),
-				 GIC_MAP_TO_PIN_MSK | perf_interrupt);
+				 GIC_MAP_TO_PIN_MSK | perf_intr);
+		if (cpu_has_veic) {
+			set_vi_handler(perf_intr + GIC_PIN_TO_VEC_OFFSET, gic_eic_irq_dispatch);
+			gic_shared_intr_map[perf_intr + GIC_PIN_TO_VEC_OFFSET].local_intr_mask |= GIC_VPE_RMASK_PERFCNT_MSK;
+		}
 	}
 }
 
@@ -80,51 +142,30 @@
 	bitmap_and(pending, pending, intrmask, GIC_NUM_INTRS);
 	bitmap_and(pending, pending, pcpu_mask, GIC_NUM_INTRS);
 
-	i = find_first_bit(pending, GIC_NUM_INTRS);
-
-	pr_debug("CPU%d: %s pend=%d\n", smp_processor_id(), __func__, i);
-
-	return i;
-}
-
-static void gic_irq_ack(struct irq_data *d)
-{
-	unsigned int irq = d->irq - _irqbase;
-
-	pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
-	GIC_CLR_INTR_MASK(irq);
-
-	if (gic_irq_flags[irq] & GIC_IRQ_FLAG_EDGE)
-		GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq);
+	return find_first_bit(pending, GIC_NUM_INTRS);
 }
 
 static void gic_mask_irq(struct irq_data *d)
 {
-	unsigned int irq = d->irq - _irqbase;
-	pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
-	GIC_CLR_INTR_MASK(irq);
+	GIC_CLR_INTR_MASK(d->irq - gic_irq_base);
 }
 
 static void gic_unmask_irq(struct irq_data *d)
 {
-	unsigned int irq = d->irq - _irqbase;
-	pr_debug("CPU%d: %s: irq%d\n", smp_processor_id(), __func__, irq);
-	GIC_SET_INTR_MASK(irq);
+	GIC_SET_INTR_MASK(d->irq - gic_irq_base);
 }
 
 #ifdef CONFIG_SMP
-
 static DEFINE_SPINLOCK(gic_lock);
 
 static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
 			    bool force)
 {
-	unsigned int irq = d->irq - _irqbase;
+	unsigned int irq = (d->irq - gic_irq_base);
 	cpumask_t	tmp = CPU_MASK_NONE;
 	unsigned long	flags;
 	int		i;
 
-	pr_debug("%s(%d) called\n", __func__, irq);
 	cpumask_and(&tmp, cpumask, cpu_online_mask);
 	if (cpus_empty(tmp))
 		return -1;
@@ -154,7 +195,7 @@
 	.irq_mask		=	gic_mask_irq,
 	.irq_mask_ack		=	gic_mask_irq,
 	.irq_unmask		=	gic_unmask_irq,
-	.irq_eoi		=	gic_unmask_irq,
+	.irq_eoi		=	gic_finish_irq,
 #ifdef CONFIG_SMP
 	.irq_set_affinity	=	gic_set_affinity,
 #endif
@@ -164,6 +205,8 @@
 	unsigned int pin, unsigned int polarity, unsigned int trigtype,
 	unsigned int flags)
 {
+	struct gic_shared_intr_map *map_ptr;
+
 	/* Setup Intr to Pin mapping */
 	if (pin & GIC_MAP_TO_NMI_MSK) {
 		GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), pin);
@@ -178,6 +221,14 @@
 			 GIC_MAP_TO_PIN_MSK | pin);
 		/* Setup Intr to CPU mapping */
 		GIC_SH_MAP_TO_VPE_SMASK(intr, cpu);
+		if (cpu_has_veic) {
+			set_vi_handler(pin + GIC_PIN_TO_VEC_OFFSET,
+				gic_eic_irq_dispatch);
+			map_ptr = &gic_shared_intr_map[pin + GIC_PIN_TO_VEC_OFFSET];
+			if (map_ptr->num_shared_intr >= GIC_MAX_SHARED_INTR)
+				BUG();
+			map_ptr->intr_list[map_ptr->num_shared_intr++] = intr;
+		}
 	}
 
 	/* Setup Intr Polarity */
@@ -191,26 +242,39 @@
 	/* Initialise per-cpu Interrupt software masks */
 	if (flags & GIC_FLAG_IPI)
 		set_bit(intr, pcpu_masks[cpu].pcpu_mask);
-	if (flags & GIC_FLAG_TRANSPARENT)
+	if ((flags & GIC_FLAG_TRANSPARENT) && (cpu_has_veic == 0))
 		GIC_SET_INTR_MASK(intr);
 	if (trigtype == GIC_TRIG_EDGE)
-		gic_irq_flags[intr] |= GIC_IRQ_FLAG_EDGE;
+		gic_irq_flags[intr] |= GIC_TRIG_EDGE;
 }
 
 static void __init gic_basic_init(int numintrs, int numvpes,
 			struct gic_intr_map *intrmap, int mapsize)
 {
 	unsigned int i, cpu;
+	unsigned int pin_offset = 0;
+
+	board_bind_eic_interrupt = &gic_bind_eic_interrupt;
 
 	/* Setup defaults */
 	for (i = 0; i < numintrs; i++) {
 		GIC_SET_POLARITY(i, GIC_POL_POS);
 		GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL);
 		GIC_CLR_INTR_MASK(i);
-		if (i < GIC_NUM_INTRS)
+		if (i < GIC_NUM_INTRS) {
 			gic_irq_flags[i] = 0;
+			gic_shared_intr_map[i].num_shared_intr = 0;
+			gic_shared_intr_map[i].local_intr_mask = 0;
+		}
 	}
 
+	/*
+	 * In EIC mode, the HW_INT# is offset by (2-1). Need to subtract
+	 * one because the GIC will add one (since 0=no intr).
+	 */
+	if (cpu_has_veic)
+		pin_offset = (GIC_CPU_TO_VEC_OFFSET - GIC_PIN_TO_VEC_OFFSET);
+
 	/* Setup specifics */
 	for (i = 0; i < mapsize; i++) {
 		cpu = intrmap[i].cpunum;
@@ -220,16 +284,13 @@
 			continue;
 		gic_setup_intr(i,
 			intrmap[i].cpunum,
-			intrmap[i].pin,
+			intrmap[i].pin + pin_offset,
 			intrmap[i].polarity,
 			intrmap[i].trigtype,
 			intrmap[i].flags);
 	}
 
 	vpe_local_setup(numvpes);
-
-	for (i = _irqbase; i < (_irqbase + numintrs); i++)
-		irq_set_chip(i, &gic_irq_controller);
 }
 
 void __init gic_init(unsigned long gic_base_addr,
@@ -242,7 +303,7 @@
 
 	_gic_base = (unsigned long) ioremap_nocache(gic_base_addr,
 						    gic_addrspace_size);
-	_irqbase = irqbase;
+	gic_irq_base = irqbase;
 
 	GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig);
 	numintrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >>
@@ -251,8 +312,9 @@
 
 	numvpes = (gicconfig & GIC_SH_CONFIG_NUMVPES_MSK) >>
 		  GIC_SH_CONFIG_NUMVPES_SHF;
-
-	pr_debug("%s called\n", __func__);
+	numvpes = numvpes + 1;
 
 	gic_basic_init(numintrs, numvpes, intr_map, intr_map_size);
+
+	gic_platform_init(numintrs, &gic_irq_controller);
 }
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S
index a632bc1..374f66e 100644
--- a/arch/mips/kernel/scall32-o32.S
+++ b/arch/mips/kernel/scall32-o32.S
@@ -69,18 +69,7 @@
 1:	sw	v0, PT_R2(sp)		# result
 
 o32_syscall_exit:
-	local_irq_disable		# make sure need_resched and
-					# signals dont change between
-					# sampling and return
-	lw	a2, TI_FLAGS($28)	# current->work
-	li	t0, _TIF_ALLWORK_MASK
-	and	t0, a2
-	bnez	t0, o32_syscall_exit_work
-
-	j	restore_partial
-
-o32_syscall_exit_work:
-	j	syscall_exit_work_partial
+	j	syscall_exit_partial
 
 /* ------------------------------------------------------------------------ */
 
@@ -593,6 +582,7 @@
 	sys	sys_setns		2
 	sys	sys_process_vm_readv	6	/* 4345 */
 	sys	sys_process_vm_writev	6
+	sys	sys_kcmp		5
 	.endm
 
 	/* We pre-compute the number of _instruction_ bytes needed to
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S
index 3b5a5e9..169de6a 100644
--- a/arch/mips/kernel/scall64-64.S
+++ b/arch/mips/kernel/scall64-64.S
@@ -72,18 +72,7 @@
 1:	sd	v0, PT_R2(sp)		# result
 
 n64_syscall_exit:
-	local_irq_disable		# make sure need_resched and
-					# signals dont change between
-					# sampling and return
-	LONG_L	a2, TI_FLAGS($28)	# current->work
-	li	t0, _TIF_ALLWORK_MASK
-	and	t0, a2, t0
-	bnez	t0, n64_syscall_exit_work
-
-	j	restore_partial
-
-n64_syscall_exit_work:
-	j	syscall_exit_work_partial
+	j	syscall_exit_partial
 
 /* ------------------------------------------------------------------------ */
 
@@ -432,4 +421,5 @@
 	PTR	sys_setns
 	PTR	sys_process_vm_readv
 	PTR	sys_process_vm_writev		/* 5305 */
+	PTR	sys_kcmp
 	.size	sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index 6be6f70..f6ba838 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -70,18 +70,7 @@
 	sd	t1, PT_R0(sp)		# save it for syscall restarting
 1:	sd	v0, PT_R2(sp)		# result
 
-	local_irq_disable		# make sure need_resched and
-					# signals dont change between
-					# sampling and return
-	LONG_L  a2, TI_FLAGS($28)	# current->work
-	li	t0, _TIF_ALLWORK_MASK
-	and	t0, a2, t0
-	bnez	t0, n32_syscall_exit_work
-
-	j	restore_partial
-
-n32_syscall_exit_work:
-	j	syscall_exit_work_partial
+	j	syscall_exit_partial
 
 /* ------------------------------------------------------------------------ */
 
@@ -432,4 +421,5 @@
 	PTR	sys_setns
 	PTR	compat_sys_process_vm_readv
 	PTR	compat_sys_process_vm_writev	/* 6310 */
+	PTR	sys_kcmp
 	.size	sysn32_call_table,.-sysn32_call_table
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index 5422855..53c2d724 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -99,18 +99,7 @@
 1:	sd	v0, PT_R2(sp)		# result
 
 o32_syscall_exit:
-	local_irq_disable		# make need_resched and
-					# signals dont change between
-					# sampling and return
-	LONG_L	a2, TI_FLAGS($28)
-	li	t0, _TIF_ALLWORK_MASK
-	and	t0, a2, t0
-	bnez	t0, o32_syscall_exit_work
-
-	j	restore_partial
-
-o32_syscall_exit_work:
-	j	syscall_exit_work_partial
+	j	syscall_exit_partial
 
 /* ------------------------------------------------------------------------ */
 
@@ -550,4 +539,5 @@
 	PTR	sys_setns
 	PTR	compat_sys_process_vm_readv	/* 4345 */
 	PTR	compat_sys_process_vm_writev
+	PTR	sys_kcmp
 	.size	sys_call_table,.-sys_call_table
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index f2c09cf..0e1a5b8 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -560,14 +560,6 @@
 	siginfo_t info;
 	int signr;
 
-	/*
-	 * We want the common case to go fast, which is why we may in certain
-	 * cases get here from kernel mode. Just return without doing anything
-	 * if so.
-	 */
-	if (!user_mode(regs))
-		return;
-
 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
 	if (signr > 0) {
 		/* Whee!  Actually deliver the signal.  */
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c
index ff17868..2defa2b 100644
--- a/arch/mips/kernel/smp-mt.c
+++ b/arch/mips/kernel/smp-mt.c
@@ -150,6 +150,7 @@
 
 static void __cpuinit vsmp_init_secondary(void)
 {
+#ifdef CONFIG_IRQ_GIC
 	extern int gic_present;
 
 	/* This is Malta specific: IPI,performance and timer interrupts */
@@ -157,6 +158,7 @@
 		change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 |
 					 STATUSF_IP6 | STATUSF_IP7);
 	else
+#endif
 		change_c0_status(ST0_IM, STATUSF_IP0 | STATUSF_IP1 |
 					 STATUSF_IP6 | STATUSF_IP7);
 }
diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig
index 20bdf40..d84f361 100644
--- a/arch/mips/lantiq/Kconfig
+++ b/arch/mips/lantiq/Kconfig
@@ -2,6 +2,7 @@
 
 config SOC_TYPE_XWAY
 	bool
+	select PINCTRL_XWAY
 	default n
 
 choice
@@ -19,6 +20,7 @@
 
 config SOC_FALCON
 	bool "FALCON"
+	select PINCTRL_FALCON
 
 endchoice
 
diff --git a/arch/mips/lantiq/falcon/prom.c b/arch/mips/lantiq/falcon/prom.c
index c1d278f..aa94979 100644
--- a/arch/mips/lantiq/falcon/prom.c
+++ b/arch/mips/lantiq/falcon/prom.c
@@ -8,6 +8,8 @@
  */
 
 #include <linux/kernel.h>
+#include <asm/cacheflush.h>
+#include <asm/traps.h>
 #include <asm/io.h>
 
 #include <lantiq_soc.h>
@@ -84,4 +86,7 @@
 		unreachable();
 		break;
 	}
+
+	board_nmi_handler_setup = ltq_soc_nmi_setup;
+	board_ejtag_handler_setup = ltq_soc_ejtag_setup;
 }
diff --git a/arch/mips/lantiq/falcon/sysctrl.c b/arch/mips/lantiq/falcon/sysctrl.c
index ba0123d..2d4ced3 100644
--- a/arch/mips/lantiq/falcon/sysctrl.c
+++ b/arch/mips/lantiq/falcon/sysctrl.c
@@ -171,6 +171,7 @@
 	clk->cl.con_id = NULL;
 	clk->cl.clk = clk;
 	clk->module = module;
+	clk->bits = bits;
 	clk->activate = sysctl_activate;
 	clk->deactivate = sysctl_deactivate;
 	clk->enable = sysctl_clken;
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
index 57c1a4e..f36acd1 100644
--- a/arch/mips/lantiq/irq.c
+++ b/arch/mips/lantiq/irq.c
@@ -55,8 +55,8 @@
  */
 #define LTQ_ICU_EBU_IRQ		22
 
-#define ltq_icu_w32(x, y)	ltq_w32((x), ltq_icu_membase + (y))
-#define ltq_icu_r32(x)		ltq_r32(ltq_icu_membase + (x))
+#define ltq_icu_w32(m, x, y)	ltq_w32((x), ltq_icu_membase[m] + (y))
+#define ltq_icu_r32(m, x)	ltq_r32(ltq_icu_membase[m] + (x))
 
 #define ltq_eiu_w32(x, y)	ltq_w32((x), ltq_eiu_membase + (y))
 #define ltq_eiu_r32(x)		ltq_r32(ltq_eiu_membase + (x))
@@ -82,17 +82,18 @@
 };
 
 static int exin_avail;
-static void __iomem *ltq_icu_membase;
+static void __iomem *ltq_icu_membase[MAX_IM];
 static void __iomem *ltq_eiu_membase;
+static struct irq_domain *ltq_domain;
 
 void ltq_disable_irq(struct irq_data *d)
 {
 	u32 ier = LTQ_ICU_IM0_IER;
 	int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE;
+	int im = offset / INT_NUM_IM_OFFSET;
 
-	ier += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET);
 	offset %= INT_NUM_IM_OFFSET;
-	ltq_icu_w32(ltq_icu_r32(ier) & ~BIT(offset), ier);
+	ltq_icu_w32(im, ltq_icu_r32(im, ier) & ~BIT(offset), ier);
 }
 
 void ltq_mask_and_ack_irq(struct irq_data *d)
@@ -100,32 +101,31 @@
 	u32 ier = LTQ_ICU_IM0_IER;
 	u32 isr = LTQ_ICU_IM0_ISR;
 	int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE;
+	int im = offset / INT_NUM_IM_OFFSET;
 
-	ier += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET);
-	isr += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET);
 	offset %= INT_NUM_IM_OFFSET;
-	ltq_icu_w32(ltq_icu_r32(ier) & ~BIT(offset), ier);
-	ltq_icu_w32(BIT(offset), isr);
+	ltq_icu_w32(im, ltq_icu_r32(im, ier) & ~BIT(offset), ier);
+	ltq_icu_w32(im, BIT(offset), isr);
 }
 
 static void ltq_ack_irq(struct irq_data *d)
 {
 	u32 isr = LTQ_ICU_IM0_ISR;
 	int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE;
+	int im = offset / INT_NUM_IM_OFFSET;
 
-	isr += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET);
 	offset %= INT_NUM_IM_OFFSET;
-	ltq_icu_w32(BIT(offset), isr);
+	ltq_icu_w32(im, BIT(offset), isr);
 }
 
 void ltq_enable_irq(struct irq_data *d)
 {
 	u32 ier = LTQ_ICU_IM0_IER;
 	int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE;
+	int im = offset / INT_NUM_IM_OFFSET;
 
-	ier += LTQ_ICU_OFFSET  * (offset / INT_NUM_IM_OFFSET);
 	offset %= INT_NUM_IM_OFFSET;
-	ltq_icu_w32(ltq_icu_r32(ier) | BIT(offset), ier);
+	ltq_icu_w32(im, ltq_icu_r32(im, ier) | BIT(offset), ier);
 }
 
 static unsigned int ltq_startup_eiu_irq(struct irq_data *d)
@@ -192,7 +192,7 @@
 {
 	u32 irq;
 
-	irq = ltq_icu_r32(LTQ_ICU_IM0_IOSR + (module * LTQ_ICU_OFFSET));
+	irq = ltq_icu_r32(module, LTQ_ICU_IM0_IOSR);
 	if (irq == 0)
 		return;
 
@@ -220,10 +220,14 @@
 DEFINE_HWx_IRQDISPATCH(3)
 DEFINE_HWx_IRQDISPATCH(4)
 
+#if MIPS_CPU_TIMER_IRQ == 7
 static void ltq_hw5_irqdispatch(void)
 {
 	do_IRQ(MIPS_CPU_TIMER_IRQ);
 }
+#else
+DEFINE_HWx_IRQDISPATCH(5)
+#endif
 
 #ifdef CONFIG_MIPS_MT_SMP
 void __init arch_init_ipiirq(int irq, struct irqaction *action)
@@ -271,11 +275,11 @@
 	unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
 	unsigned int i;
 
-	if (pending & CAUSEF_IP7) {
+	if ((MIPS_CPU_TIMER_IRQ == 7) && (pending & CAUSEF_IP7)) {
 		do_IRQ(MIPS_CPU_TIMER_IRQ);
 		goto out;
 	} else {
-		for (i = 0; i < 5; i++) {
+		for (i = 0; i < MAX_IM; i++) {
 			if (pending & (CAUSEF_IP2 << i)) {
 				ltq_hw_irqdispatch(i);
 				goto out;
@@ -293,6 +297,9 @@
 	struct irq_chip *chip = &ltq_irq_type;
 	int i;
 
+	if (hw < MIPS_CPU_IRQ_CASCADE)
+		return 0;
+
 	for (i = 0; i < exin_avail; i++)
 		if (hw == ltq_eiu_irq[i])
 			chip = &ltq_eiu_type;
@@ -318,19 +325,23 @@
 	struct resource res;
 	int i;
 
-	if (of_address_to_resource(node, 0, &res))
-		panic("Failed to get icu memory range");
+	for (i = 0; i < MAX_IM; i++) {
+		if (of_address_to_resource(node, i, &res))
+			panic("Failed to get icu memory range");
 
-	if (request_mem_region(res.start, resource_size(&res), res.name) < 0)
-		pr_err("Failed to request icu memory");
+		if (request_mem_region(res.start, resource_size(&res),
+					res.name) < 0)
+			pr_err("Failed to request icu memory");
 
-	ltq_icu_membase = ioremap_nocache(res.start, resource_size(&res));
-	if (!ltq_icu_membase)
-		panic("Failed to remap icu memory");
+		ltq_icu_membase[i] = ioremap_nocache(res.start,
+					resource_size(&res));
+		if (!ltq_icu_membase[i])
+			panic("Failed to remap icu memory");
+	}
 
 	/* the external interrupts are optional and xway only */
 	eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu");
-	if (eiu_node && of_address_to_resource(eiu_node, 0, &res)) {
+	if (eiu_node && !of_address_to_resource(eiu_node, 0, &res)) {
 		/* find out how many external irq sources we have */
 		const __be32 *count = of_get_property(node,
 							"lantiq,count",	NULL);
@@ -351,17 +362,17 @@
 	}
 
 	/* turn off all irqs by default */
-	for (i = 0; i < 5; i++) {
+	for (i = 0; i < MAX_IM; i++) {
 		/* make sure all irqs are turned off by default */
-		ltq_icu_w32(0, LTQ_ICU_IM0_IER + (i * LTQ_ICU_OFFSET));
+		ltq_icu_w32(i, 0, LTQ_ICU_IM0_IER);
 		/* clear all possibly pending interrupts */
-		ltq_icu_w32(~0, LTQ_ICU_IM0_ISR + (i * LTQ_ICU_OFFSET));
+		ltq_icu_w32(i, ~0, LTQ_ICU_IM0_ISR);
 	}
 
 	mips_cpu_irq_init();
 
-	for (i = 2; i <= 6; i++)
-		setup_irq(i, &cascade);
+	for (i = 0; i < MAX_IM; i++)
+		setup_irq(i + 2, &cascade);
 
 	if (cpu_has_vint) {
 		pr_info("Setting up vectored interrupts\n");
@@ -373,7 +384,8 @@
 		set_vi_handler(7, ltq_hw5_irqdispatch);
 	}
 
-	irq_domain_add_linear(node, 6 * INT_NUM_IM_OFFSET,
+	ltq_domain = irq_domain_add_linear(node,
+		(MAX_IM * INT_NUM_IM_OFFSET) + MIPS_CPU_IRQ_CASCADE,
 		&irq_domain_ops, 0);
 
 #if defined(CONFIG_MIPS_MT_SMP)
@@ -397,12 +409,20 @@
 
 	/* tell oprofile which irq to use */
 	cp0_perfcount_irq = LTQ_PERF_IRQ;
+
+	/*
+	 * if the timer irq is not one of the mips irqs we need to
+	 * create a mapping
+	 */
+	if (MIPS_CPU_TIMER_IRQ != 7)
+		irq_create_mapping(ltq_domain, MIPS_CPU_TIMER_IRQ);
+
 	return 0;
 }
 
 unsigned int __cpuinit get_c0_compare_int(void)
 {
-	return CP0_LEGACY_COMPARE_IRQ;
+	return MIPS_CPU_TIMER_IRQ;
 }
 
 static struct of_device_id __initdata of_irq_ids[] = {
diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile
index dc3194f..70a58c7 100644
--- a/arch/mips/lantiq/xway/Makefile
+++ b/arch/mips/lantiq/xway/Makefile
@@ -1 +1 @@
-obj-y := prom.o sysctrl.o clk.o reset.o gpio.o dma.o
+obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o
diff --git a/arch/mips/lantiq/xway/gpio.c b/arch/mips/lantiq/xway/gpio.c
deleted file mode 100644
index 2ab39e9..0000000
--- a/arch/mips/lantiq/xway/gpio.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- *  This program is free software; you can redistribute it and/or modify it
- *  under the terms of the GNU General Public License version 2 as published
- *  by the Free Software Foundation.
- *
- *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
- */
-
-#include <linux/slab.h>
-#include <linux/export.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/ioport.h>
-#include <linux/io.h>
-
-#include <lantiq_soc.h>
-
-#define LTQ_GPIO_OUT		0x00
-#define LTQ_GPIO_IN		0x04
-#define LTQ_GPIO_DIR		0x08
-#define LTQ_GPIO_ALTSEL0	0x0C
-#define LTQ_GPIO_ALTSEL1	0x10
-#define LTQ_GPIO_OD		0x14
-
-#define PINS_PER_PORT		16
-#define MAX_PORTS		3
-
-#define ltq_gpio_getbit(m, r, p)	(!!(ltq_r32(m + r) & (1 << p)))
-#define ltq_gpio_setbit(m, r, p)	ltq_w32_mask(0, (1 << p), m + r)
-#define ltq_gpio_clearbit(m, r, p)	ltq_w32_mask((1 << p), 0, m + r)
-
-struct ltq_gpio {
-	void __iomem *membase;
-	struct gpio_chip chip;
-};
-
-static struct ltq_gpio ltq_gpio_port[MAX_PORTS];
-
-int ltq_gpio_request(unsigned int pin, unsigned int alt0,
-	unsigned int alt1, unsigned int dir, const char *name)
-{
-	int id = 0;
-
-	if (pin >= (MAX_PORTS * PINS_PER_PORT))
-		return -EINVAL;
-	if (gpio_request(pin, name)) {
-		pr_err("failed to setup lantiq gpio: %s\n", name);
-		return -EBUSY;
-	}
-	if (dir)
-		gpio_direction_output(pin, 1);
-	else
-		gpio_direction_input(pin);
-	while (pin >= PINS_PER_PORT) {
-		pin -= PINS_PER_PORT;
-		id++;
-	}
-	if (alt0)
-		ltq_gpio_setbit(ltq_gpio_port[id].membase,
-			LTQ_GPIO_ALTSEL0, pin);
-	else
-		ltq_gpio_clearbit(ltq_gpio_port[id].membase,
-			LTQ_GPIO_ALTSEL0, pin);
-	if (alt1)
-		ltq_gpio_setbit(ltq_gpio_port[id].membase,
-			LTQ_GPIO_ALTSEL1, pin);
-	else
-		ltq_gpio_clearbit(ltq_gpio_port[id].membase,
-			LTQ_GPIO_ALTSEL1, pin);
-	return 0;
-}
-EXPORT_SYMBOL(ltq_gpio_request);
-
-static void ltq_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
-{
-	struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
-
-	if (value)
-		ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OUT, offset);
-	else
-		ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OUT, offset);
-}
-
-static int ltq_gpio_get(struct gpio_chip *chip, unsigned int offset)
-{
-	struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
-
-	return ltq_gpio_getbit(ltq_gpio->membase, LTQ_GPIO_IN, offset);
-}
-
-static int ltq_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
-{
-	struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
-
-	ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
-	ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset);
-
-	return 0;
-}
-
-static int ltq_gpio_direction_output(struct gpio_chip *chip,
-	unsigned int offset, int value)
-{
-	struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
-
-	ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
-	ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset);
-	ltq_gpio_set(chip, offset, value);
-
-	return 0;
-}
-
-static int ltq_gpio_req(struct gpio_chip *chip, unsigned offset)
-{
-	struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
-
-	ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL0, offset);
-	ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL1, offset);
-	return 0;
-}
-
-static int ltq_gpio_probe(struct platform_device *pdev)
-{
-	struct resource *res;
-
-	if (pdev->id >= MAX_PORTS) {
-		dev_err(&pdev->dev, "invalid gpio port %d\n",
-			pdev->id);
-		return -EINVAL;
-	}
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		dev_err(&pdev->dev, "failed to get memory for gpio port %d\n",
-			pdev->id);
-		return -ENOENT;
-	}
-	res = devm_request_mem_region(&pdev->dev, res->start,
-		resource_size(res), dev_name(&pdev->dev));
-	if (!res) {
-		dev_err(&pdev->dev,
-			"failed to request memory for gpio port %d\n",
-			pdev->id);
-		return -EBUSY;
-	}
-	ltq_gpio_port[pdev->id].membase = devm_ioremap_nocache(&pdev->dev,
-		res->start, resource_size(res));
-	if (!ltq_gpio_port[pdev->id].membase) {
-		dev_err(&pdev->dev, "failed to remap memory for gpio port %d\n",
-			pdev->id);
-		return -ENOMEM;
-	}
-	ltq_gpio_port[pdev->id].chip.label = "ltq_gpio";
-	ltq_gpio_port[pdev->id].chip.direction_input = ltq_gpio_direction_input;
-	ltq_gpio_port[pdev->id].chip.direction_output =
-		ltq_gpio_direction_output;
-	ltq_gpio_port[pdev->id].chip.get = ltq_gpio_get;
-	ltq_gpio_port[pdev->id].chip.set = ltq_gpio_set;
-	ltq_gpio_port[pdev->id].chip.request = ltq_gpio_req;
-	ltq_gpio_port[pdev->id].chip.base = PINS_PER_PORT * pdev->id;
-	ltq_gpio_port[pdev->id].chip.ngpio = PINS_PER_PORT;
-	platform_set_drvdata(pdev, &ltq_gpio_port[pdev->id]);
-	return gpiochip_add(&ltq_gpio_port[pdev->id].chip);
-}
-
-static struct platform_driver
-ltq_gpio_driver = {
-	.probe = ltq_gpio_probe,
-	.driver = {
-		.name = "ltq_gpio",
-		.owner = THIS_MODULE,
-	},
-};
-
-int __init ltq_gpio_init(void)
-{
-	int ret = platform_driver_register(&ltq_gpio_driver);
-
-	if (ret)
-		pr_info("ltq_gpio : Error registering platform driver!");
-	return ret;
-}
-
-postcore_initcall(ltq_gpio_init);
diff --git a/arch/mips/lantiq/xway/gptu.c b/arch/mips/lantiq/xway/gptu.c
new file mode 100644
index 0000000..cbb56fc
--- /dev/null
+++ b/arch/mips/lantiq/xway/gptu.c
@@ -0,0 +1,214 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2012 John Crispin <blogic@openwrt.org>
+ *  Copyright (C) 2012 Lantiq GmbH
+ */
+
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/of_irq.h>
+
+#include <lantiq_soc.h>
+#include "../clk.h"
+
+/* the magic ID byte of the core */
+#define GPTU_MAGIC	0x59
+/* clock control register */
+#define GPTU_CLC	0x00
+/* id register */
+#define GPTU_ID		0x08
+/* interrupt node enable */
+#define GPTU_IRNEN	0xf4
+/* interrupt control register */
+#define GPTU_IRCR	0xf8
+/* interrupt capture register */
+#define GPTU_IRNCR	0xfc
+/* there are 3 identical blocks of 2 timers. calculate register offsets */
+#define GPTU_SHIFT(x)	(x % 2 ? 4 : 0)
+#define GPTU_BASE(x)	(((x >> 1) * 0x20) + 0x10)
+/* timer control register */
+#define GPTU_CON(x)	(GPTU_BASE(x) + GPTU_SHIFT(x) + 0x00)
+/* timer auto reload register */
+#define GPTU_RUN(x)	(GPTU_BASE(x) + GPTU_SHIFT(x) + 0x08)
+/* timer manual reload register */
+#define GPTU_RLD(x)	(GPTU_BASE(x) + GPTU_SHIFT(x) + 0x10)
+/* timer count register */
+#define GPTU_CNT(x)	(GPTU_BASE(x) + GPTU_SHIFT(x) + 0x18)
+
+/* GPTU_CON(x) */
+#define CON_CNT		BIT(2)
+#define CON_EDGE_ANY	(BIT(7) | BIT(6))
+#define CON_SYNC	BIT(8)
+#define CON_CLK_INT	BIT(10)
+
+/* GPTU_RUN(x) */
+#define RUN_SEN		BIT(0)
+#define RUN_RL		BIT(2)
+
+/* set clock to runmode */
+#define CLC_RMC		BIT(8)
+/* bring core out of suspend */
+#define CLC_SUSPEND	BIT(4)
+/* the disable bit */
+#define CLC_DISABLE	BIT(0)
+
+#define gptu_w32(x, y)	ltq_w32((x), gptu_membase + (y))
+#define gptu_r32(x)	ltq_r32(gptu_membase + (x))
+
+enum gptu_timer {
+	TIMER1A = 0,
+	TIMER1B,
+	TIMER2A,
+	TIMER2B,
+	TIMER3A,
+	TIMER3B
+};
+
+static void __iomem *gptu_membase;
+static struct resource irqres[6];
+
+static irqreturn_t timer_irq_handler(int irq, void *priv)
+{
+	int timer = irq - irqres[0].start;
+	gptu_w32(1 << timer, GPTU_IRNCR);
+	return IRQ_HANDLED;
+}
+
+static void gptu_hwinit(void)
+{
+	gptu_w32(0x00, GPTU_IRNEN);
+	gptu_w32(0xff, GPTU_IRNCR);
+	gptu_w32(CLC_RMC | CLC_SUSPEND, GPTU_CLC);
+}
+
+static void gptu_hwexit(void)
+{
+	gptu_w32(0x00, GPTU_IRNEN);
+	gptu_w32(0xff, GPTU_IRNCR);
+	gptu_w32(CLC_DISABLE, GPTU_CLC);
+}
+
+static int gptu_enable(struct clk *clk)
+{
+	int ret = request_irq(irqres[clk->bits].start, timer_irq_handler,
+		IRQF_TIMER, "gtpu", NULL);
+	if (ret) {
+		pr_err("gptu: failed to request irq\n");
+		return ret;
+	}
+
+	gptu_w32(CON_CNT | CON_EDGE_ANY | CON_SYNC | CON_CLK_INT,
+		GPTU_CON(clk->bits));
+	gptu_w32(1, GPTU_RLD(clk->bits));
+	gptu_w32(gptu_r32(GPTU_IRNEN) | BIT(clk->bits), GPTU_IRNEN);
+	gptu_w32(RUN_SEN | RUN_RL, GPTU_RUN(clk->bits));
+	return 0;
+}
+
+static void gptu_disable(struct clk *clk)
+{
+	gptu_w32(0, GPTU_RUN(clk->bits));
+	gptu_w32(0, GPTU_CON(clk->bits));
+	gptu_w32(0, GPTU_RLD(clk->bits));
+	gptu_w32(gptu_r32(GPTU_IRNEN) & ~BIT(clk->bits), GPTU_IRNEN);
+	free_irq(irqres[clk->bits].start, NULL);
+}
+
+static inline void clkdev_add_gptu(struct device *dev, const char *con,
+							unsigned int timer)
+{
+	struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL);
+
+	clk->cl.dev_id = dev_name(dev);
+	clk->cl.con_id = con;
+	clk->cl.clk = clk;
+	clk->enable = gptu_enable;
+	clk->disable = gptu_disable;
+	clk->bits = timer;
+	clkdev_add(&clk->cl);
+}
+
+static int __devinit gptu_probe(struct platform_device *pdev)
+{
+	struct clk *clk;
+	struct resource *res;
+
+	if (of_irq_to_resource_table(pdev->dev.of_node, irqres, 6) != 6) {
+		dev_err(&pdev->dev, "Failed to get IRQ list\n");
+		return -EINVAL;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "Failed to get resource\n");
+		return -ENOMEM;
+	}
+
+	/* remap gptu register range */
+	gptu_membase = devm_request_and_ioremap(&pdev->dev, res);
+	if (!gptu_membase) {
+		dev_err(&pdev->dev, "Failed to remap resource\n");
+		return -ENOMEM;
+	}
+
+	/* enable our clock */
+	clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(clk)) {
+		dev_err(&pdev->dev, "Failed to get clock\n");
+		return -ENOENT;
+	}
+	clk_enable(clk);
+
+	/* power up the core */
+	gptu_hwinit();
+
+	/* the gptu has a ID register */
+	if (((gptu_r32(GPTU_ID) >> 8) & 0xff) != GPTU_MAGIC) {
+		dev_err(&pdev->dev, "Failed to find magic\n");
+		gptu_hwexit();
+		return -ENAVAIL;
+	}
+
+	/* register the clocks */
+	clkdev_add_gptu(&pdev->dev, "timer1a", TIMER1A);
+	clkdev_add_gptu(&pdev->dev, "timer1b", TIMER1B);
+	clkdev_add_gptu(&pdev->dev, "timer2a", TIMER2A);
+	clkdev_add_gptu(&pdev->dev, "timer2b", TIMER2B);
+	clkdev_add_gptu(&pdev->dev, "timer3a", TIMER3A);
+	clkdev_add_gptu(&pdev->dev, "timer3b", TIMER3B);
+
+	dev_info(&pdev->dev, "gptu: 6 timers loaded\n");
+
+	return 0;
+}
+
+static const struct of_device_id gptu_match[] = {
+	{ .compatible = "lantiq,gptu-xway" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, dma_match);
+
+static struct platform_driver dma_driver = {
+	.probe = gptu_probe,
+	.driver = {
+		.name = "gptu-xway",
+		.owner = THIS_MODULE,
+		.of_match_table = gptu_match,
+	},
+};
+
+int __init gptu_init(void)
+{
+	int ret = platform_driver_register(&dma_driver);
+
+	if (ret)
+		pr_info("gptu: Error registering platform driver\n");
+	return ret;
+}
+
+arch_initcall(gptu_init);
diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c
index befbb76..2917b56 100644
--- a/arch/mips/lantiq/xway/sysctrl.c
+++ b/arch/mips/lantiq/xway/sysctrl.c
@@ -145,7 +145,8 @@
 {
 	unsigned int val = ltq_cgu_r32(ifccr);
 	/* set bus clock speed */
-	if (of_machine_is_compatible("lantiq,ar9")) {
+	if (of_machine_is_compatible("lantiq,ar9") ||
+			of_machine_is_compatible("lantiq,vr9")) {
 		val &= ~0x1f00000;
 		if (clk->rate == CLOCK_33M)
 			val |= 0xe00000;
@@ -187,10 +188,12 @@
 	for (i = 0; i < 4; i++) {
 		if (clk->rates[i] == clk->rate) {
 			int shift = 14 - (2 * clk->module);
+			int enable = 7 - clk->module;
 			unsigned int val = ltq_cgu_r32(ifccr);
 
 			val &= ~(3 << shift);
 			val |= i << shift;
+			val |= enable;
 			ltq_cgu_w32(val, ifccr);
 			return 0;
 		}
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index 399a50a..c4a82e8 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -8,28 +8,9 @@
 obj-y			+= iomap.o
 obj-$(CONFIG_PCI)	+= iomap-pci.o
 
-obj-$(CONFIG_CPU_LOONGSON2)	+= dump_tlb.o
-obj-$(CONFIG_CPU_MIPS32)	+= dump_tlb.o
-obj-$(CONFIG_CPU_MIPS64)	+= dump_tlb.o
-obj-$(CONFIG_CPU_NEVADA)	+= dump_tlb.o
-obj-$(CONFIG_CPU_R10000)	+= dump_tlb.o
+obj-$(CONFIG_CPU_GENERIC_DUMP_TLB) += dump_tlb.o
 obj-$(CONFIG_CPU_R3000)		+= r3k_dump_tlb.o
-obj-$(CONFIG_CPU_R4300)		+= dump_tlb.o
-obj-$(CONFIG_CPU_R4X00)		+= dump_tlb.o
-obj-$(CONFIG_CPU_R5000)		+= dump_tlb.o
-obj-$(CONFIG_CPU_R5432)		+= dump_tlb.o
-obj-$(CONFIG_CPU_R5500)		+= dump_tlb.o
-obj-$(CONFIG_CPU_R6000)		+=
-obj-$(CONFIG_CPU_R8000)		+=
-obj-$(CONFIG_CPU_RM7000)	+= dump_tlb.o
-obj-$(CONFIG_CPU_RM9000)	+= dump_tlb.o
-obj-$(CONFIG_CPU_SB1)		+= dump_tlb.o
 obj-$(CONFIG_CPU_TX39XX)	+= r3k_dump_tlb.o
-obj-$(CONFIG_CPU_TX49XX)	+= dump_tlb.o
-obj-$(CONFIG_CPU_VR41XX)	+= dump_tlb.o
-obj-$(CONFIG_CPU_CAVIUM_OCTEON)	+= dump_tlb.o
-obj-$(CONFIG_CPU_XLR)		+= dump_tlb.o
-obj-$(CONFIG_CPU_XLP)		+= dump_tlb.o
 
 # libgcc-style stuff needed in the kernel
 obj-y += ashldi3.o ashrdi3.o cmpdi2.o lshrdi3.o ucmpdi2.o
diff --git a/arch/mips/mipssim/Makefile b/arch/mips/mipssim/Makefile
deleted file mode 100644
index 01410a3..0000000
--- a/arch/mips/mipssim/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (C) 2005 MIPS Technologies, Inc.  All rights reserved.
-# Copyright (C) 2007 MIPS Technologies, Inc.
-#   written by Ralf Baechle (ralf@linux-mips.org)
-#
-# This program is free software; you can distribute it and/or modify it
-# under the terms of the GNU General Public License (Version 2) as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
-#
-
-obj-y := sim_platform.o sim_setup.o sim_mem.o sim_time.o sim_int.o
-
-obj-$(CONFIG_EARLY_PRINTK) += sim_console.o
-obj-$(CONFIG_MIPS_MT_SMTC) += sim_smtc.o
diff --git a/arch/mips/mipssim/Platform b/arch/mips/mipssim/Platform
deleted file mode 100644
index 3df60b8..0000000
--- a/arch/mips/mipssim/Platform
+++ /dev/null
@@ -1,6 +0,0 @@
-#
-# MIPS SIM
-#
-platform-$(CONFIG_MIPS_SIM)	+= mipssim/
-cflags-$(CONFIG_MIPS_SIM)	+= -I$(srctree)/arch/mips/include/asm/mach-mipssim
-load-$(CONFIG_MIPS_SIM)		+= 0x80100000
diff --git a/arch/mips/mipssim/sim_console.c b/arch/mips/mipssim/sim_console.c
deleted file mode 100644
index a2f4167..0000000
--- a/arch/mips/mipssim/sim_console.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Carsten Langgaard, carstenl@mips.com
- * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
- * Copyright (C) 2007 MIPS Technologies, Inc.
- *   written by Ralf Baechle
- */
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/serial_reg.h>
-
-static inline unsigned int serial_in(int offset)
-{
-	return inb(0x3f8 + offset);
-}
-
-static inline void serial_out(int offset, int value)
-{
-	outb(value, 0x3f8 + offset);
-}
-
-void __init prom_putchar(char c)
-{
-	while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0)
-		;
-
-	serial_out(UART_TX, c);
-}
diff --git a/arch/mips/mipssim/sim_int.c b/arch/mips/mipssim/sim_int.c
deleted file mode 100644
index 5c779be..0000000
--- a/arch/mips/mipssim/sim_int.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 1999, 2005 MIPS Technologies, Inc.  All rights reserved.
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- */
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
-#include <asm/mips-boards/simint.h>
-#include <asm/irq_cpu.h>
-
-static inline int clz(unsigned long x)
-{
-	__asm__(
-	"	.set	push					\n"
-	"	.set	mips32					\n"
-	"	clz	%0, %1					\n"
-	"	.set	pop					\n"
-	: "=r" (x)
-	: "r" (x));
-
-	return x;
-}
-
-/*
- * Version of ffs that only looks at bits 12..15.
- */
-static inline unsigned int irq_ffs(unsigned int pending)
-{
-#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
-	return -clz(pending) + 31 - CAUSEB_IP;
-#else
-	unsigned int a0 = 7;
-	unsigned int t0;
-
-	t0 = s0 & 0xf000;
-	t0 = t0 < 1;
-	t0 = t0 << 2;
-	a0 = a0 - t0;
-	s0 = s0 << t0;
-
-	t0 = s0 & 0xc000;
-	t0 = t0 < 1;
-	t0 = t0 << 1;
-	a0 = a0 - t0;
-	s0 = s0 << t0;
-
-	t0 = s0 & 0x8000;
-	t0 = t0 < 1;
-	/* t0 = t0 << 2; */
-	a0 = a0 - t0;
-	/* s0 = s0 << t0; */
-
-	return a0;
-#endif
-}
-
-asmlinkage void plat_irq_dispatch(void)
-{
-	unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
-	int irq;
-
-	irq = irq_ffs(pending);
-
-	if (irq > 0)
-		do_IRQ(MIPS_CPU_IRQ_BASE + irq);
-	else
-		spurious_interrupt();
-}
-
-void __init arch_init_irq(void)
-{
-	mips_cpu_irq_init();
-}
diff --git a/arch/mips/mipssim/sim_mem.c b/arch/mips/mipssim/sim_mem.c
deleted file mode 100644
index 953d836..0000000
--- a/arch/mips/mipssim/sim_mem.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2005 MIPS Technologies, Inc.  All rights reserved.
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- */
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/bootmem.h>
-#include <linux/pfn.h>
-
-#include <asm/bootinfo.h>
-#include <asm/page.h>
-#include <asm/sections.h>
-
-#include <asm/mips-boards/prom.h>
-
-/*#define DEBUG*/
-
-enum simmem_memtypes {
-	simmem_reserved = 0,
-	simmem_free,
-};
-struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
-
-#ifdef DEBUG
-static char *mtypes[3] = {
-	"SIM reserved memory",
-	"SIM free memory",
-};
-#endif
-
-struct prom_pmemblock * __init prom_getmdesc(void)
-{
-	unsigned int memsize;
-
-	memsize = 0x02000000;
-	pr_info("Setting default memory size 0x%08x\n", memsize);
-
-	memset(mdesc, 0, sizeof(mdesc));
-
-	mdesc[0].type = simmem_reserved;
-	mdesc[0].base = 0x00000000;
-	mdesc[0].size = 0x00001000;
-
-	mdesc[1].type = simmem_free;
-	mdesc[1].base = 0x00001000;
-	mdesc[1].size = 0x000ff000;
-
-	mdesc[2].type = simmem_reserved;
-	mdesc[2].base = 0x00100000;
-	mdesc[2].size = CPHYSADDR(PFN_ALIGN(&_end)) - mdesc[2].base;
-
-	mdesc[3].type = simmem_free;
-	mdesc[3].base = CPHYSADDR(PFN_ALIGN(&_end));
-	mdesc[3].size = memsize - mdesc[3].base;
-
-	return &mdesc[0];
-}
-
-static int __init prom_memtype_classify(unsigned int type)
-{
-	switch (type) {
-	case simmem_free:
-		return BOOT_MEM_RAM;
-	case simmem_reserved:
-	default:
-		return BOOT_MEM_RESERVED;
-	}
-}
-
-void __init prom_meminit(void)
-{
-	struct prom_pmemblock *p;
-
-	p = prom_getmdesc();
-
-	while (p->size) {
-		long type;
-		unsigned long base, size;
-
-		type = prom_memtype_classify(p->type);
-		base = p->base;
-		size = p->size;
-
-		add_memory_region(base, size, type);
-		p++;
-	}
-}
-
-void __init prom_free_prom_memory(void)
-{
-	int i;
-	unsigned long addr;
-
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
-			continue;
-
-		addr = boot_mem_map.map[i].addr;
-		free_init_pages("prom memory",
-				addr, addr + boot_mem_map.map[i].size);
-	}
-}
diff --git a/arch/mips/mipssim/sim_platform.c b/arch/mips/mipssim/sim_platform.c
deleted file mode 100644
index 53210a8..0000000
--- a/arch/mips/mipssim/sim_platform.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.
- *
- * Copyright (C) 2007 by Ralf Baechle (ralf@linux-mips.org)
- */
-#include <linux/init.h>
-#include <linux/if_ether.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-
-static char mipsnet_string[] = "mipsnet";
-
-static struct platform_device eth1_device = {
-	.name		= mipsnet_string,
-	.id		= 0,
-};
-
-/*
- * Create a platform device for the GPI port that receives the
- * image data from the embedded camera.
- */
-static int __init mipsnet_devinit(void)
-{
-	int err;
-
-	err = platform_device_register(&eth1_device);
-	if (err)
-		printk(KERN_ERR "%s: registration failed\n", mipsnet_string);
-
-	return err;
-}
-
-device_initcall(mipsnet_devinit);
diff --git a/arch/mips/mipssim/sim_setup.c b/arch/mips/mipssim/sim_setup.c
deleted file mode 100644
index 256e0cd..0000000
--- a/arch/mips/mipssim/sim_setup.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2005 MIPS Technologies, Inc.  All rights reserved.
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- */
-
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/ioport.h>
-#include <linux/tty.h>
-#include <linux/serial.h>
-#include <linux/serial_core.h>
-#include <linux/serial_8250.h>
-
-#include <asm/cpu.h>
-#include <asm/bootinfo.h>
-#include <asm/mips-boards/generic.h>
-#include <asm/mips-boards/prom.h>
-#include <asm/time.h>
-#include <asm/mips-boards/sim.h>
-#include <asm/mips-boards/simint.h>
-#include <asm/smp-ops.h>
-
-
-static void __init serial_init(void);
-unsigned int _isbonito;
-
-const char *get_system_type(void)
-{
-	return "MIPSsim";
-}
-
-void __init plat_mem_setup(void)
-{
-	set_io_port_base(0xbfd00000);
-
-	serial_init();
-}
-
-extern struct plat_smp_ops ssmtc_smp_ops;
-
-void __init prom_init(void)
-{
-	set_io_port_base(0xbfd00000);
-
-	prom_meminit();
-
-	if (cpu_has_mipsmt) {
-		if (!register_vsmp_smp_ops())
-			return;
-
-#ifdef CONFIG_MIPS_MT_SMTC
-		register_smp_ops(&ssmtc_smp_ops);
-			return;
-#endif
-	}
-
-	register_up_smp_ops();
-}
-
-static void __init serial_init(void)
-{
-#ifdef CONFIG_SERIAL_8250
-	struct uart_port s;
-
-	memset(&s, 0, sizeof(s));
-
-	s.iobase = 0x3f8;
-
-	/* hardware int 4 - the serial int, is CPU int 6
-	 but poll for now */
-	s.irq =  0;
-	s.uartclk = 1843200;
-	s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
-	s.iotype = UPIO_PORT;
-	s.regshift = 0;
-	s.timeout = 4;
-
-	if (early_serial_setup(&s) != 0) {
-		printk(KERN_ERR "Serial setup failed!\n");
-	}
-
-#endif
-}
diff --git a/arch/mips/mipssim/sim_smtc.c b/arch/mips/mipssim/sim_smtc.c
deleted file mode 100644
index 3c104ab..0000000
--- a/arch/mips/mipssim/sim_smtc.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2005 MIPS Technologies, Inc.  All rights reserved.
- *
- *  This program is free software; you can distribute it and/or modify it
- *  under the terms of the GNU General Public License (Version 2) as
- *  published by the Free Software Foundation.
- *
- *  This program is distributed in the hope it will be useful, but WITHOUT
- *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- *  for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- */
-/*
- * Simulator Platform-specific hooks for SMTC operation
- */
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/cpumask.h>
-#include <linux/interrupt.h>
-#include <linux/smp.h>
-
-#include <linux/atomic.h>
-#include <asm/cpu.h>
-#include <asm/processor.h>
-#include <asm/smtc.h>
-#include <asm/mmu_context.h>
-#include <asm/smtc_ipi.h>
-
-/* VPE/SMP Prototype implements platform interfaces directly */
-
-/*
- * Cause the specified action to be performed on a targeted "CPU"
- */
-
-static void ssmtc_send_ipi_single(int cpu, unsigned int action)
-{
-	smtc_send_ipi(cpu, LINUX_SMP_IPI, action);
-	/* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */
-}
-
-static inline void ssmtc_send_ipi_mask(const struct cpumask *mask,
-				       unsigned int action)
-{
-	unsigned int i;
-
-	for_each_cpu(i, mask)
-		ssmtc_send_ipi_single(i, action);
-}
-
-/*
- * Post-config but pre-boot cleanup entry point
- */
-static void __cpuinit ssmtc_init_secondary(void)
-{
-	smtc_init_secondary();
-}
-
-/*
- * SMP initialization finalization entry point
- */
-static void __cpuinit ssmtc_smp_finish(void)
-{
-	smtc_smp_finish();
-}
-
-/*
- * Hook for after all CPUs are online
- */
-static void ssmtc_cpus_done(void)
-{
-}
-
-/*
- * Platform "CPU" startup hook
- */
-static void __cpuinit ssmtc_boot_secondary(int cpu, struct task_struct *idle)
-{
-	smtc_boot_secondary(cpu, idle);
-}
-
-static void __init ssmtc_smp_setup(void)
-{
-	if (read_c0_config3() & (1 << 2))
-		mipsmt_build_cpu_map(0);
-}
-
-/*
- * Platform SMP pre-initialization
- */
-static void ssmtc_prepare_cpus(unsigned int max_cpus)
-{
-	/*
-	 * As noted above, we can assume a single CPU for now
-	 * but it may be multithreaded.
-	 */
-
-	if (read_c0_config3() & (1 << 2)) {
-		mipsmt_prepare_cpus();
-	}
-}
-
-struct plat_smp_ops ssmtc_smp_ops = {
-	.send_ipi_single	= ssmtc_send_ipi_single,
-	.send_ipi_mask		= ssmtc_send_ipi_mask,
-	.init_secondary		= ssmtc_init_secondary,
-	.smp_finish		= ssmtc_smp_finish,
-	.cpus_done		= ssmtc_cpus_done,
-	.boot_secondary		= ssmtc_boot_secondary,
-	.smp_setup		= ssmtc_smp_setup,
-	.prepare_cpus		= ssmtc_prepare_cpus,
-};
diff --git a/arch/mips/mipssim/sim_time.c b/arch/mips/mipssim/sim_time.c
deleted file mode 100644
index 77bad3c..0000000
--- a/arch/mips/mipssim/sim_time.c
+++ /dev/null
@@ -1,117 +0,0 @@
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/kernel_stat.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/mc146818rtc.h>
-#include <linux/smp.h>
-#include <linux/timex.h>
-
-#include <asm/hardirq.h>
-#include <asm/div64.h>
-#include <asm/cpu.h>
-#include <asm/setup.h>
-#include <asm/time.h>
-#include <asm/irq.h>
-#include <asm/mc146818-time.h>
-#include <asm/msc01_ic.h>
-
-#include <asm/mips-boards/generic.h>
-#include <asm/mips-boards/prom.h>
-#include <asm/mips-boards/simint.h>
-
-
-unsigned long cpu_khz;
-
-/*
- * Estimate CPU frequency.  Sets mips_hpt_frequency as a side-effect
- */
-static unsigned int __init estimate_cpu_frequency(void)
-{
-	unsigned int prid = read_c0_prid() & 0xffff00;
-	unsigned int count;
-
-#if 1
-	/*
-	 * hardwire the board frequency to 12MHz.
-	 */
-
-	if ((prid == (PRID_COMP_MIPS | PRID_IMP_20KC)) ||
-	    (prid == (PRID_COMP_MIPS | PRID_IMP_25KF)))
-		count = 12000000;
-	else
-		count =  6000000;
-#else
-	unsigned int flags;
-
-	local_irq_save(flags);
-
-	/* Start counter exactly on falling edge of update flag */
-	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
-	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
-
-	/* Start r4k counter. */
-	write_c0_count(0);
-
-	/* Read counter exactly on falling edge of update flag */
-	while (CMOS_READ(RTC_REG_A) & RTC_UIP);
-	while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
-
-	count = read_c0_count();
-
-	/* restore interrupts */
-	local_irq_restore(flags);
-#endif
-
-	mips_hpt_frequency = count;
-
-	if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) &&
-	    (prid != (PRID_COMP_MIPS | PRID_IMP_25KF)))
-		count *= 2;
-
-	count += 5000;    /* round */
-	count -= count%10000;
-
-	return count;
-}
-
-static int mips_cpu_timer_irq;
-
-static void mips_timer_dispatch(void)
-{
-	do_IRQ(mips_cpu_timer_irq);
-}
-
-
-unsigned __cpuinit get_c0_compare_int(void)
-{
-#ifdef MSC01E_INT_BASE
-	if (cpu_has_veic) {
-		set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch);
-		mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
-
-		return mips_cpu_timer_irq;
-	}
-#endif
-	if (cpu_has_vint)
-		set_vi_handler(cp0_compare_irq, mips_timer_dispatch);
-	mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
-
-	return mips_cpu_timer_irq;
-}
-
-void __init plat_time_init(void)
-{
-	unsigned int est_freq;
-
-	/* Set Data mode - binary. */
-	CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
-
-	est_freq = estimate_cpu_frequency();
-
-	printk(KERN_INFO "CPU frequency %d.%02d MHz\n", est_freq / 1000000,
-	       (est_freq % 1000000) * 100 / 1000000);
-
-	cpu_khz = est_freq / 1000;
-}
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
index fd6203f..90ceb963 100644
--- a/arch/mips/mm/Makefile
+++ b/arch/mips/mm/Makefile
@@ -11,27 +11,12 @@
 obj-$(CONFIG_HIGHMEM)		+= highmem.o
 obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
 
-obj-$(CONFIG_CPU_LOONGSON2)	+= c-r4k.o cex-gen.o tlb-r4k.o
-obj-$(CONFIG_CPU_MIPS32)	+= c-r4k.o cex-gen.o tlb-r4k.o
-obj-$(CONFIG_CPU_MIPS64)	+= c-r4k.o cex-gen.o tlb-r4k.o
-obj-$(CONFIG_CPU_NEVADA)	+= c-r4k.o cex-gen.o tlb-r4k.o
-obj-$(CONFIG_CPU_R10000)	+= c-r4k.o cex-gen.o tlb-r4k.o
+obj-$(CONFIG_CPU_R4K_CACHE_TLB) += c-r4k.o cex-gen.o tlb-r4k.o
 obj-$(CONFIG_CPU_R3000)		+= c-r3k.o tlb-r3k.o
-obj-$(CONFIG_CPU_R4300)		+= c-r4k.o cex-gen.o tlb-r4k.o
-obj-$(CONFIG_CPU_R4X00)		+= c-r4k.o cex-gen.o tlb-r4k.o
-obj-$(CONFIG_CPU_R5000)		+= c-r4k.o cex-gen.o tlb-r4k.o
-obj-$(CONFIG_CPU_R5432)		+= c-r4k.o cex-gen.o tlb-r4k.o
-obj-$(CONFIG_CPU_R5500)		+= c-r4k.o cex-gen.o tlb-r4k.o
 obj-$(CONFIG_CPU_R8000)		+= c-r4k.o cex-gen.o tlb-r8k.o
-obj-$(CONFIG_CPU_RM7000)	+= c-r4k.o cex-gen.o tlb-r4k.o
-obj-$(CONFIG_CPU_RM9000)	+= c-r4k.o cex-gen.o tlb-r4k.o
 obj-$(CONFIG_CPU_SB1)		+= c-r4k.o cerr-sb1.o cex-sb1.o tlb-r4k.o
 obj-$(CONFIG_CPU_TX39XX)	+= c-tx39.o tlb-r3k.o
-obj-$(CONFIG_CPU_TX49XX)	+= c-r4k.o cex-gen.o tlb-r4k.o
-obj-$(CONFIG_CPU_VR41XX)	+= c-r4k.o cex-gen.o tlb-r4k.o
 obj-$(CONFIG_CPU_CAVIUM_OCTEON)	+= c-octeon.o cex-oct.o tlb-r4k.o
-obj-$(CONFIG_CPU_XLR)		+= c-r4k.o tlb-r4k.o cex-gen.o
-obj-$(CONFIG_CPU_XLP)		+= c-r4k.o tlb-r4k.o cex-gen.o
 
 obj-$(CONFIG_IP22_CPU_SCACHE)	+= sc-ip22.o
 obj-$(CONFIG_R5000_CPU_SCACHE)  += sc-r5k.o
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index f092c26..4c32ede 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -786,6 +786,25 @@
 	}
 }
 
+static inline void alias_74k_erratum(struct cpuinfo_mips *c)
+{
+	/*
+	 * Early versions of the 74K do not update the cache tags on a
+	 * vtag miss/ptag hit which can occur in the case of KSEG0/KUSEG
+	 * aliases. In this case it is better to treat the cache as always
+	 * having aliases.
+	 */
+	if ((c->processor_id & 0xff) <= PRID_REV_ENCODE_332(2, 4, 0))
+		c->dcache.flags |= MIPS_CACHE_VTAG;
+	if ((c->processor_id & 0xff) == PRID_REV_ENCODE_332(2, 4, 0))
+		write_c0_config6(read_c0_config6() | MIPS_CONF6_SYND);
+	if (((c->processor_id & 0xff00) == PRID_IMP_1074K) &&
+	    ((c->processor_id & 0xff) <= PRID_REV_ENCODE_332(1, 1, 0))) {
+		c->dcache.flags |= MIPS_CACHE_VTAG;
+		write_c0_config6(read_c0_config6() | MIPS_CONF6_SYND);
+	}
+}
+
 static char *way_string[] __cpuinitdata = { NULL, "direct mapped", "2-way",
 	"3-way", "4-way", "5-way", "6-way", "7-way", "8-way"
 };
@@ -1056,6 +1075,8 @@
 	case CPU_34K:
 	case CPU_74K:
 	case CPU_1004K:
+		if (c->cputype == CPU_74K)
+			alias_74k_erratum(c);
 		if ((read_c0_config7() & (1 << 16))) {
 			/* effectively physically indexed dcache,
 			   thus no virtual aliases. */
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index 829320c..07cec44 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -142,7 +142,7 @@
 
 static inline void setup_protection_map(void)
 {
-	if (kernel_uses_smartmips_rixi) {
+	if (cpu_has_rixi) {
 		protection_map[0]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
 		protection_map[1]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC);
 		protection_map[2]  = __pgprot(_page_cachable_default | _PAGE_PRESENT | _PAGE_NO_EXEC | _PAGE_NO_READ);
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index c14f6df..ddcec1e 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -114,7 +114,7 @@
 		if (!(vma->vm_flags & VM_WRITE))
 			goto bad_area;
 	} else {
-		if (kernel_uses_smartmips_rixi) {
+		if (cpu_has_rixi) {
 			if (address == regs->cp0_epc && !(vma->vm_flags & VM_EXEC)) {
 #if 0
 				pr_notice("Cpu%d[%s:%d:%0*lx:%ld:%0*lx] XI violation\n",
@@ -171,6 +171,7 @@
 		}
 		if (fault & VM_FAULT_RETRY) {
 			flags &= ~FAULT_FLAG_ALLOW_RETRY;
+			flags |= FAULT_FLAG_TRIED;
 
 			/*
 			 * No need to up_read(&mm->mmap_sem) as we would
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index d2572cb..87b9cfc 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -401,7 +401,7 @@
 	    current_cpu_type() == CPU_R14000)
 		write_c0_framemask(0);
 
-	if (kernel_uses_smartmips_rixi) {
+	if (cpu_has_rixi) {
 		/*
 		 * Enable the no read, no exec bits, and enable large virtual
 		 * address.
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 03eb0ef..e09d492 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -449,8 +449,20 @@
 	}
 
 	if (cpu_has_mips_r2) {
-		if (cpu_has_mips_r2_exec_hazard)
+		/*
+		 * The architecture spec says an ehb is required here,
+		 * but a number of cores do not have the hazard and
+		 * using an ehb causes an expensive pipeline stall.
+		 */
+		switch (current_cpu_type()) {
+		case CPU_M14KC:
+		case CPU_74K:
+			break;
+
+		default:
 			uasm_i_ehb(p);
+			break;
+		}
 		tlbw(p);
 		return;
 	}
@@ -586,7 +598,7 @@
 static __cpuinit __maybe_unused void build_convert_pte_to_entrylo(u32 **p,
 								  unsigned int reg)
 {
-	if (kernel_uses_smartmips_rixi) {
+	if (cpu_has_rixi) {
 		UASM_i_SRL(p, reg, reg, ilog2(_PAGE_NO_EXEC));
 		UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
 	} else {
@@ -921,6 +933,13 @@
 #endif
 	uasm_i_mfc0(p, tmp, C0_BADVADDR); /* get faulting address */
 	uasm_i_lw(p, ptr, uasm_rel_lo(pgdc), ptr);
+
+	if (cpu_has_mips_r2) {
+		uasm_i_ext(p, tmp, tmp, PGDIR_SHIFT, (32 - PGDIR_SHIFT));
+		uasm_i_ins(p, ptr, tmp, PGD_T_LOG2, (32 - PGDIR_SHIFT));
+		return;
+	}
+
 	uasm_i_srl(p, tmp, tmp, PGDIR_SHIFT); /* get pgd only bits */
 	uasm_i_sll(p, tmp, tmp, PGD_T_LOG2);
 	uasm_i_addu(p, ptr, ptr, tmp); /* add in pgd offset */
@@ -956,6 +975,15 @@
 
 static void __cpuinit build_get_ptep(u32 **p, unsigned int tmp, unsigned int ptr)
 {
+	if (cpu_has_mips_r2) {
+		/* PTE ptr offset is obtained from BadVAddr */
+		UASM_i_MFC0(p, tmp, C0_BADVADDR);
+		UASM_i_LW(p, ptr, 0, ptr);
+		uasm_i_ext(p, tmp, tmp, PAGE_SHIFT+1, PGDIR_SHIFT-PAGE_SHIFT-1);
+		uasm_i_ins(p, ptr, tmp, PTE_T_LOG2+1, PGDIR_SHIFT-PAGE_SHIFT-1);
+		return;
+	}
+
 	/*
 	 * Bug workaround for the Nevada. It seems as if under certain
 	 * circumstances the move from cp0_context might produce a
@@ -990,7 +1018,7 @@
 	if (cpu_has_64bits) {
 		uasm_i_ld(p, tmp, 0, ptep); /* get even pte */
 		uasm_i_ld(p, ptep, sizeof(pte_t), ptep); /* get odd pte */
-		if (kernel_uses_smartmips_rixi) {
+		if (cpu_has_rixi) {
 			UASM_i_SRL(p, tmp, tmp, ilog2(_PAGE_NO_EXEC));
 			UASM_i_SRL(p, ptep, ptep, ilog2(_PAGE_NO_EXEC));
 			UASM_i_ROTR(p, tmp, tmp, ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
@@ -1017,7 +1045,7 @@
 	UASM_i_LW(p, ptep, sizeof(pte_t), ptep); /* get odd pte */
 	if (r45k_bvahwbug())
 		build_tlb_probe_entry(p);
-	if (kernel_uses_smartmips_rixi) {
+	if (cpu_has_rixi) {
 		UASM_i_SRL(p, tmp, tmp, ilog2(_PAGE_NO_EXEC));
 		UASM_i_SRL(p, ptep, ptep, ilog2(_PAGE_NO_EXEC));
 		UASM_i_ROTR(p, tmp, tmp, ilog2(_PAGE_GLOBAL) - ilog2(_PAGE_NO_EXEC));
@@ -1183,7 +1211,7 @@
 		UASM_i_LW(p, even, 0, ptr); /* get even pte */
 		UASM_i_LW(p, odd, sizeof(pte_t), ptr); /* get odd pte */
 	}
-	if (kernel_uses_smartmips_rixi) {
+	if (cpu_has_rixi) {
 		uasm_i_dsrl_safe(p, even, even, ilog2(_PAGE_NO_EXEC));
 		uasm_i_dsrl_safe(p, odd, odd, ilog2(_PAGE_NO_EXEC));
 		uasm_i_drotr(p, even, even,
@@ -1545,7 +1573,7 @@
 {
 	int t = scratch >= 0 ? scratch : pte;
 
-	if (kernel_uses_smartmips_rixi) {
+	if (cpu_has_rixi) {
 		if (use_bbit_insns()) {
 			uasm_il_bbit0(p, r, pte, ilog2(_PAGE_PRESENT), lid);
 			uasm_i_nop(p);
@@ -1875,7 +1903,7 @@
 	if (m4kc_tlbp_war())
 		build_tlb_probe_entry(&p);
 
-	if (kernel_uses_smartmips_rixi) {
+	if (cpu_has_rixi) {
 		/*
 		 * If the page is not _PAGE_VALID, RI or XI could not
 		 * have triggered it.  Skip the expensive test..
@@ -1929,7 +1957,7 @@
 	build_pte_present(&p, &r, wr.r1, wr.r2, wr.r3, label_nopage_tlbl);
 	build_tlb_probe_entry(&p);
 
-	if (kernel_uses_smartmips_rixi) {
+	if (cpu_has_rixi) {
 		/*
 		 * If the page is not _PAGE_VALID, RI or XI could not
 		 * have triggered it.  Skip the expensive test..
diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c
index 64a28e8..39b8910 100644
--- a/arch/mips/mm/uasm.c
+++ b/arch/mips/mm/uasm.c
@@ -63,11 +63,12 @@
 	insn_bne, insn_cache, insn_daddiu, insn_daddu, insn_dins, insn_dinsm,
 	insn_dmfc0, insn_dmtc0, insn_drotr, insn_drotr32, insn_dsll,
 	insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, insn_dsubu, insn_eret,
-	insn_j, insn_jal, insn_jr, insn_ld, insn_ldx, insn_ll, insn_lld,
-	insn_lui, insn_lw, insn_lwx, insn_mfc0, insn_mtc0, insn_or, insn_ori,
-	insn_pref, insn_rfe, insn_rotr, insn_sc, insn_scd, insn_sd, insn_sll,
-	insn_sra, insn_srl, insn_subu, insn_sw, insn_syscall, insn_tlbp,
-	insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori,
+	insn_ext, insn_ins, insn_j, insn_jal, insn_jr, insn_ld, insn_ldx,
+	insn_ll, insn_lld, insn_lui, insn_lw, insn_lwx, insn_mfc0, insn_mtc0,
+	insn_or, insn_ori, insn_pref, insn_rfe, insn_rotr, insn_sc, insn_scd,
+	insn_sd, insn_sll, insn_sra, insn_srl, insn_subu, insn_sw,
+	insn_syscall, insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor,
+	insn_xori,
 };
 
 struct insn {
@@ -115,6 +116,9 @@
 	{ insn_dsrl, M(spec_op, 0, 0, 0, 0, dsrl_op), RT | RD | RE },
 	{ insn_dsubu, M(spec_op, 0, 0, 0, 0, dsubu_op), RS | RT | RD },
 	{ insn_eret,  M(cop0_op, cop_op, 0, 0, 0, eret_op),  0 },
+	{ insn_ext, M(spec3_op, 0, 0, 0, 0, ext_op), RS | RT | RD | RE },
+	{ insn_ins, M(spec3_op, 0, 0, 0, 0, ins_op), RS | RT | RD | RE },
+	{ insn_j,  M(j_op, 0, 0, 0, 0, 0),  JIMM },
 	{ insn_jal,  M(jal_op, 0, 0, 0, 0, 0),  JIMM },
 	{ insn_j,  M(j_op, 0, 0, 0, 0, 0),  JIMM },
 	{ insn_jr,  M(spec_op, 0, 0, 0, 0, jr_op),  RS },
@@ -341,6 +345,13 @@
 }							\
 UASM_EXPORT_SYMBOL(uasm_i##op);
 
+#define I_u2u1msbdu3(op) 				\
+Ip_u2u1msbu3(op)					\
+{							\
+	build_insn(buf, insn##op, b, a, d-1, c);	\
+}							\
+UASM_EXPORT_SYMBOL(uasm_i##op);
+
 #define I_u1u2(op)					\
 Ip_u1u2(op)						\
 {							\
@@ -394,6 +405,8 @@
 I_u2u1u3(_drotr32)
 I_u3u1u2(_dsubu)
 I_0(_eret)
+I_u2u1msbdu3(_ext)
+I_u2u1msbu3(_ins)
 I_u1(_j)
 I_u1(_jal)
 I_u1(_jr)
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c
index fea823f..647b863 100644
--- a/arch/mips/mti-malta/malta-int.c
+++ b/arch/mips/mti-malta/malta-int.c
@@ -750,3 +750,37 @@
 
 	return retval;
 }
+
+void gic_enable_interrupt(int irq_vec)
+{
+	GIC_SET_INTR_MASK(irq_vec);
+}
+
+void gic_disable_interrupt(int irq_vec)
+{
+	GIC_CLR_INTR_MASK(irq_vec);
+}
+
+void gic_irq_ack(struct irq_data *d)
+{
+	int irq = (d->irq - gic_irq_base);
+
+	GIC_CLR_INTR_MASK(irq);
+
+	if (gic_irq_flags[irq] & GIC_TRIG_EDGE)
+		GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq);
+}
+
+void gic_finish_irq(struct irq_data *d)
+{
+	/* Enable interrupts. */
+	GIC_SET_INTR_MASK(d->irq - gic_irq_base);
+}
+
+void __init gic_platform_init(int irqs, struct irq_chip *irq_controller)
+{
+	int i;
+
+	for (i = gic_irq_base; i < (gic_irq_base + irqs); i++)
+		irq_set_chip(i, irq_controller);
+}
diff --git a/arch/mips/mti-sead3/Makefile b/arch/mips/mti-sead3/Makefile
new file mode 100644
index 0000000..626afeac
--- /dev/null
+++ b/arch/mips/mti-sead3/Makefile
@@ -0,0 +1,19 @@
+#
+# Carsten Langgaard, carstenl@mips.com
+# Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+#
+# Copyright (C) 2008 Wind River Systems, Inc.
+#   written by Ralf Baechle <ralf@linux-mips.org>
+#
+obj-y				:= sead3-lcd.o sead3-cmdline.o \
+				   sead3-display.o sead3-init.o sead3-int.o \
+				   sead3-mtd.o sead3-net.o \
+				   sead3-memory.o sead3-platform.o \
+				   sead3-reset.o sead3-setup.o sead3-time.o
+
+obj-y				+= sead3-i2c-dev.o sead3-i2c.o \
+				   sead3-pic32-i2c-drv.o sead3-pic32-bus.o \
+				   leds-sead3.o sead3-leds.o
+
+obj-$(CONFIG_EARLY_PRINTK)	+= sead3-console.o
+obj-$(CONFIG_USB_EHCI_HCD)	+= sead3-ehci.o
diff --git a/arch/mips/mti-sead3/Platform b/arch/mips/mti-sead3/Platform
new file mode 100644
index 0000000..3870924
--- /dev/null
+++ b/arch/mips/mti-sead3/Platform
@@ -0,0 +1,7 @@
+#
+# MIPS SEAD-3 board
+#
+platform-$(CONFIG_MIPS_SEAD3)	+= mti-sead3/
+cflags-$(CONFIG_MIPS_SEAD3)	+= -I$(srctree)/arch/mips/include/asm/mach-sead3
+load-$(CONFIG_MIPS_SEAD3)	+= 0xffffffff80100000
+all-$(CONFIG_MIPS_SEAD3)	:= $(COMPRESSION_FNAME).srec
diff --git a/arch/mips/mti-sead3/leds-sead3.c b/arch/mips/mti-sead3/leds-sead3.c
new file mode 100644
index 0000000..a95ac59
--- /dev/null
+++ b/arch/mips/mti-sead3/leds-sead3.c
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#define DRVNAME "sead3-led"
+
+static struct platform_device *pdev;
+
+static void sead3_pled_set(struct led_classdev *led_cdev,
+		enum led_brightness value)
+{
+	pr_debug("sead3_pled_set\n");
+	writel(value, (void __iomem *)0xBF000210);	/* FIXME */
+}
+
+static void sead3_fled_set(struct led_classdev *led_cdev,
+		enum led_brightness value)
+{
+	pr_debug("sead3_fled_set\n");
+	writel(value, (void __iomem *)0xBF000218);	/* FIXME */
+}
+
+static struct led_classdev sead3_pled = {
+	.name		= "sead3::pled",
+	.brightness_set	= sead3_pled_set,
+};
+
+static struct led_classdev sead3_fled = {
+	.name		= "sead3::fled",
+	.brightness_set	= sead3_fled_set,
+};
+
+#ifdef CONFIG_PM
+static int sead3_led_suspend(struct platform_device *dev,
+		pm_message_t state)
+{
+	led_classdev_suspend(&sead3_pled);
+	led_classdev_suspend(&sead3_fled);
+	return 0;
+}
+
+static int sead3_led_resume(struct platform_device *dev)
+{
+	led_classdev_resume(&sead3_pled);
+	led_classdev_resume(&sead3_fled);
+	return 0;
+}
+#else
+#define sead3_led_suspend NULL
+#define sead3_led_resume NULL
+#endif
+
+static int sead3_led_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = led_classdev_register(&pdev->dev, &sead3_pled);
+	if (ret < 0)
+		return ret;
+
+	ret = led_classdev_register(&pdev->dev, &sead3_fled);
+	if (ret < 0)
+		led_classdev_unregister(&sead3_pled);
+
+	return ret;
+}
+
+static int sead3_led_remove(struct platform_device *pdev)
+{
+	led_classdev_unregister(&sead3_pled);
+	led_classdev_unregister(&sead3_fled);
+	return 0;
+}
+
+static struct platform_driver sead3_led_driver = {
+	.probe		= sead3_led_probe,
+	.remove		= sead3_led_remove,
+	.suspend	= sead3_led_suspend,
+	.resume		= sead3_led_resume,
+	.driver		= {
+		.name		= DRVNAME,
+		.owner		= THIS_MODULE,
+	},
+};
+
+static int __init sead3_led_init(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&sead3_led_driver);
+	if (ret < 0)
+		goto out;
+
+	pdev = platform_device_register_simple(DRVNAME, -1, NULL, 0);
+	if (IS_ERR(pdev)) {
+		ret = PTR_ERR(pdev);
+		platform_driver_unregister(&sead3_led_driver);
+		goto out;
+	}
+
+out:
+	return ret;
+}
+
+static void __exit sead3_led_exit(void)
+{
+	platform_device_unregister(pdev);
+	platform_driver_unregister(&sead3_led_driver);
+}
+
+module_init(sead3_led_init);
+module_exit(sead3_led_exit);
+
+MODULE_AUTHOR("Kristian Kielhofner <kris@krisk.org>");
+MODULE_DESCRIPTION("SEAD3 LED driver");
+MODULE_LICENSE("GPL");
+
diff --git a/arch/mips/mti-sead3/sead3-cmdline.c b/arch/mips/mti-sead3/sead3-cmdline.c
new file mode 100644
index 0000000..a2e6cec
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-cmdline.c
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
+ */
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+
+extern int prom_argc;
+extern int *_prom_argv;
+
+/*
+ * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer.
+ * This macro take care of sign extension.
+ */
+#define prom_argv(index) ((char *)(long)_prom_argv[(index)])
+
+char * __init prom_getcmdline(void)
+{
+	return &(arcs_cmdline[0]);
+}
+
+void  __init prom_init_cmdline(void)
+{
+	char *cp;
+	int actr;
+
+	actr = 1; /* Always ignore argv[0] */
+
+	cp = &(arcs_cmdline[0]);
+	while (actr < prom_argc) {
+		strcpy(cp, prom_argv(actr));
+		cp += strlen(prom_argv(actr));
+		*cp++ = ' ';
+		actr++;
+	}
+	if (cp != &(arcs_cmdline[0])) {
+		/* get rid of trailing space */
+		--cp;
+		*cp = '\0';
+	}
+}
diff --git a/arch/mips/mti-sead3/sead3-console.c b/arch/mips/mti-sead3/sead3-console.c
new file mode 100644
index 0000000..b367391
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-console.c
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
+ */
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/serial_reg.h>
+#include <linux/io.h>
+
+#define SEAD_UART1_REGS_BASE    0xbf000800   /* ttyS1 = DB9 port */
+#define SEAD_UART0_REGS_BASE    0xbf000900   /* ttyS0 = USB port   */
+#define PORT(base_addr, offset) ((unsigned int __iomem *)(base_addr+(offset)*4))
+
+static char console_port = 1;
+
+static inline unsigned int serial_in(int offset, unsigned int base_addr)
+{
+	return __raw_readl(PORT(base_addr, offset)) & 0xff;
+}
+
+static inline void serial_out(int offset, int value, unsigned int base_addr)
+{
+	__raw_writel(value, PORT(base_addr, offset));
+}
+
+void __init prom_init_early_console(char port)
+{
+	console_port = port;
+}
+
+int prom_putchar(char c)
+{
+	unsigned int base_addr;
+
+	base_addr = console_port ? SEAD_UART1_REGS_BASE : SEAD_UART0_REGS_BASE;
+
+	while ((serial_in(UART_LSR, base_addr) & UART_LSR_THRE) == 0)
+		;
+
+	serial_out(UART_TX, c, base_addr);
+
+	return 1;
+}
diff --git a/arch/mips/mti-sead3/sead3-display.c b/arch/mips/mti-sead3/sead3-display.c
new file mode 100644
index 0000000..8308c7f
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-display.c
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
+ */
+#include <linux/timer.h>
+#include <linux/io.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+
+static unsigned int display_count;
+static unsigned int max_display_count;
+
+#define LCD_DISPLAY_POS_BASE		0x1f000400
+#define DISPLAY_LCDINSTRUCTION		(0*2)
+#define DISPLAY_LCDDATA			(1*2)
+#define DISPLAY_CPLDSTATUS		(2*2)
+#define DISPLAY_CPLDDATA		(3*2)
+#define LCD_SETDDRAM			0x80
+#define LCD_IR_BF			0x80
+
+const char display_string[] = "               LINUX ON SEAD3               ";
+
+static void scroll_display_message(unsigned long data);
+static DEFINE_TIMER(mips_scroll_timer, scroll_display_message, HZ, 0);
+
+static void lcd_wait(unsigned int __iomem *display)
+{
+	/* Wait for CPLD state machine to become idle. */
+	do { } while (__raw_readl(display + DISPLAY_CPLDSTATUS) & 1);
+
+	do {
+		__raw_readl(display + DISPLAY_LCDINSTRUCTION);
+
+		/* Wait for CPLD state machine to become idle. */
+		do { } while (__raw_readl(display + DISPLAY_CPLDSTATUS) & 1);
+	} while (__raw_readl(display + DISPLAY_CPLDDATA) & LCD_IR_BF);
+}
+
+void mips_display_message(const char *str)
+{
+	static unsigned int __iomem *display;
+	char ch;
+	int i;
+
+	if (unlikely(display == NULL))
+		display = ioremap_nocache(LCD_DISPLAY_POS_BASE,
+			(8 * sizeof(int)));
+
+	for (i = 0; i < 16; i++) {
+		if (*str)
+			ch = *str++;
+		else
+			ch = ' ';
+		lcd_wait(display);
+		__raw_writel((LCD_SETDDRAM | i),
+			(display + DISPLAY_LCDINSTRUCTION));
+		lcd_wait(display);
+		__raw_writel(ch, display + DISPLAY_LCDDATA);
+	}
+}
+
+static void scroll_display_message(unsigned long data)
+{
+	mips_display_message(&display_string[display_count++]);
+	if (display_count == max_display_count)
+		display_count = 0;
+	mod_timer(&mips_scroll_timer, jiffies + HZ);
+}
+
+void mips_scroll_message(void)
+{
+	del_timer_sync(&mips_scroll_timer);
+	max_display_count = strlen(display_string) + 1 - 16;
+	mod_timer(&mips_scroll_timer, jiffies + 1);
+}
diff --git a/arch/mips/mti-sead3/sead3-ehci.c b/arch/mips/mti-sead3/sead3-ehci.c
new file mode 100644
index 0000000..772fc05
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-ehci.c
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
+ */
+#include <linux/module.h>
+#include <linux/irq.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+
+struct resource ehci_resources[] = {
+	{
+		.start			= 0x1b200000,
+		.end			= 0x1b200fff,
+		.flags			= IORESOURCE_MEM
+	},
+	{
+		.start			= MIPS_CPU_IRQ_BASE + 2,
+		.flags			= IORESOURCE_IRQ
+	}
+};
+
+u64 sead3_usbdev_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device ehci_device = {
+	.name		= "sead3-ehci",
+	.id		= 0,
+	.dev		= {
+		.dma_mask		= &sead3_usbdev_dma_mask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32)
+	},
+	.num_resources	= ARRAY_SIZE(ehci_resources),
+	.resource	= ehci_resources
+};
+
+static int __init ehci_init(void)
+{
+	return platform_device_register(&ehci_device);
+}
+
+module_init(ehci_init);
+
+MODULE_AUTHOR("Chris Dearman <chris@mips.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("EHCI probe driver for SEAD3");
diff --git a/arch/mips/mti-sead3/sead3-i2c-dev.c b/arch/mips/mti-sead3/sead3-i2c-dev.c
new file mode 100644
index 0000000..eca0b53
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-i2c-dev.c
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
+ */
+#include <linux/init.h>
+#include <linux/i2c.h>
+
+static struct i2c_board_info __initdata sead3_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("adt7476", 0x2c),
+		.irq = 0,
+	},
+	{
+		I2C_BOARD_INFO("m41t80", 0x68),
+		.irq = 0,
+	},
+};
+
+static int __init sead3_i2c_init(void)
+{
+	int err;
+
+	err = i2c_register_board_info(0, sead3_i2c_devices,
+					ARRAY_SIZE(sead3_i2c_devices));
+	if (err < 0)
+		pr_err("sead3-i2c-dev: cannot register board I2C devices\n");
+	return err;
+}
+
+arch_initcall(sead3_i2c_init);
diff --git a/arch/mips/mti-sead3/sead3-i2c-drv.c b/arch/mips/mti-sead3/sead3-i2c-drv.c
new file mode 100644
index 0000000..0375ee6
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-i2c-drv.c
@@ -0,0 +1,405 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+
+#define PIC32_I2CxCON		0x0000
+#define  PIC32_I2CCON_ON	(1<<15)
+#define  PIC32_I2CCON_ACKDT	(1<<5)
+#define  PIC32_I2CCON_ACKEN	(1<<4)
+#define  PIC32_I2CCON_RCEN	(1<<3)
+#define  PIC32_I2CCON_PEN	(1<<2)
+#define  PIC32_I2CCON_RSEN	(1<<1)
+#define  PIC32_I2CCON_SEN	(1<<0)
+#define PIC32_I2CxCONCLR	0x0004
+#define PIC32_I2CxCONSET	0x0008
+#define PIC32_I2CxSTAT		0x0010
+#define PIC32_I2CxSTATCLR	0x0014
+#define  PIC32_I2CSTAT_ACKSTAT	(1<<15)
+#define  PIC32_I2CSTAT_TRSTAT	(1<<14)
+#define  PIC32_I2CSTAT_BCL	(1<<10)
+#define  PIC32_I2CSTAT_IWCOL	(1<<7)
+#define  PIC32_I2CSTAT_I2COV	(1<<6)
+#define PIC32_I2CxBRG		0x0040
+#define PIC32_I2CxTRN		0x0050
+#define PIC32_I2CxRCV		0x0060
+
+static DEFINE_SPINLOCK(pic32_bus_lock);
+
+static void __iomem *bus_xfer   = (void __iomem *)0xbf000600;
+static void __iomem *bus_status = (void __iomem *)0xbf000060;
+
+#define DELAY()	udelay(100)
+
+static inline unsigned int ioready(void)
+{
+	return readl(bus_status) & 1;
+}
+
+static inline void wait_ioready(void)
+{
+	do { } while (!ioready());
+}
+
+static inline void wait_ioclear(void)
+{
+	do { } while (ioready());
+}
+
+static inline void check_ioclear(void)
+{
+	if (ioready()) {
+		do {
+			(void) readl(bus_xfer);
+			DELAY();
+		} while (ioready());
+	}
+}
+
+static u32 pic32_bus_readl(u32 reg)
+{
+	unsigned long flags;
+	u32 status, val;
+
+	spin_lock_irqsave(&pic32_bus_lock, flags);
+
+	check_ioclear();
+	writel((0x01 << 24) | (reg & 0x00ffffff), bus_xfer);
+	DELAY();
+	wait_ioready();
+	status = readl(bus_xfer);
+	DELAY();
+	val = readl(bus_xfer);
+	wait_ioclear();
+
+	spin_unlock_irqrestore(&pic32_bus_lock, flags);
+
+	return val;
+}
+
+static void pic32_bus_writel(u32 val, u32 reg)
+{
+	unsigned long flags;
+	u32 status;
+
+	spin_lock_irqsave(&pic32_bus_lock, flags);
+
+	check_ioclear();
+	writel((0x10 << 24) | (reg & 0x00ffffff), bus_xfer);
+	DELAY();
+	writel(val, bus_xfer);
+	DELAY();
+	wait_ioready();
+	status = readl(bus_xfer);
+	wait_ioclear();
+
+	spin_unlock_irqrestore(&pic32_bus_lock, flags);
+}
+
+struct pic32_i2c_platform_data {
+	u32	base;
+	struct i2c_adapter adap;
+	u32	xfer_timeout;
+	u32	ack_timeout;
+	u32	ctl_timeout;
+};
+
+static inline void pic32_i2c_start(struct pic32_i2c_platform_data *adap)
+{
+	pic32_bus_writel(PIC32_I2CCON_SEN, adap->base + PIC32_I2CxCONSET);
+}
+
+static inline void pic32_i2c_stop(struct pic32_i2c_platform_data *adap)
+{
+	pic32_bus_writel(PIC32_I2CCON_PEN, adap->base + PIC32_I2CxCONSET);
+}
+
+static inline void pic32_i2c_ack(struct pic32_i2c_platform_data *adap)
+{
+	pic32_bus_writel(PIC32_I2CCON_ACKDT, adap->base + PIC32_I2CxCONCLR);
+	pic32_bus_writel(PIC32_I2CCON_ACKEN, adap->base + PIC32_I2CxCONSET);
+}
+
+static inline void pic32_i2c_nack(struct pic32_i2c_platform_data *adap)
+{
+	pic32_bus_writel(PIC32_I2CCON_ACKDT, adap->base + PIC32_I2CxCONSET);
+	pic32_bus_writel(PIC32_I2CCON_ACKEN, adap->base + PIC32_I2CxCONSET);
+}
+
+static inline int pic32_i2c_idle(struct pic32_i2c_platform_data *adap)
+{
+	int i;
+
+	for (i = 0; i < adap->ctl_timeout; i++) {
+		if (((pic32_bus_readl(adap->base + PIC32_I2CxCON) &
+		      (PIC32_I2CCON_ACKEN | PIC32_I2CCON_RCEN |
+		       PIC32_I2CCON_PEN | PIC32_I2CCON_RSEN |
+		       PIC32_I2CCON_SEN)) == 0) &&
+		    ((pic32_bus_readl(adap->base + PIC32_I2CxSTAT) &
+		      (PIC32_I2CSTAT_TRSTAT)) == 0))
+			return 0;
+		udelay(1);
+	}
+	return -ETIMEDOUT;
+}
+
+static inline u32 pic32_i2c_master_write(struct pic32_i2c_platform_data *adap,
+		u32 byte)
+{
+	pic32_bus_writel(byte, adap->base + PIC32_I2CxTRN);
+	return pic32_bus_readl(adap->base + PIC32_I2CxSTAT) &
+			PIC32_I2CSTAT_IWCOL;
+}
+
+static inline u32 pic32_i2c_master_read(struct pic32_i2c_platform_data *adap)
+{
+	pic32_bus_writel(PIC32_I2CCON_RCEN, adap->base + PIC32_I2CxCONSET);
+	while (pic32_bus_readl(adap->base + PIC32_I2CxCON) & PIC32_I2CCON_RCEN)
+		;
+	pic32_bus_writel(PIC32_I2CSTAT_I2COV, adap->base + PIC32_I2CxSTATCLR);
+	return pic32_bus_readl(adap->base + PIC32_I2CxRCV);
+}
+
+static int pic32_i2c_address(struct pic32_i2c_platform_data *adap,
+		unsigned int addr, int rd)
+{
+	pic32_i2c_idle(adap);
+	pic32_i2c_start(adap);
+	pic32_i2c_idle(adap);
+
+	addr <<= 1;
+	if (rd)
+		addr |= 1;
+
+	if (pic32_i2c_master_write(adap, addr))
+		return -EIO;
+	pic32_i2c_idle(adap);
+	if (pic32_bus_readl(adap->base + PIC32_I2CxSTAT) &
+			PIC32_I2CSTAT_ACKSTAT)
+		return -EIO;
+	return 0;
+}
+
+static int sead3_i2c_read(struct pic32_i2c_platform_data *adap,
+		unsigned char *buf, unsigned int len)
+{
+	u32 data;
+	int i;
+
+	i = 0;
+	while (i < len) {
+		data = pic32_i2c_master_read(adap);
+		buf[i++] = data;
+		if (i < len)
+			pic32_i2c_ack(adap);
+		else
+			pic32_i2c_nack(adap);
+	}
+
+	pic32_i2c_stop(adap);
+	pic32_i2c_idle(adap);
+	return 0;
+}
+
+static int sead3_i2c_write(struct pic32_i2c_platform_data *adap,
+		unsigned char *buf, unsigned int len)
+{
+	int i;
+	u32 data;
+
+	i = 0;
+	while (i < len) {
+		data = buf[i];
+		if (pic32_i2c_master_write(adap, data))
+			return -EIO;
+		pic32_i2c_idle(adap);
+		if (pic32_bus_readl(adap->base + PIC32_I2CxSTAT) &
+					PIC32_I2CSTAT_ACKSTAT)
+			return -EIO;
+		i++;
+	}
+
+	pic32_i2c_stop(adap);
+	pic32_i2c_idle(adap);
+	return 0;
+}
+
+static int sead3_pic32_platform_xfer(struct i2c_adapter *i2c_adap,
+		struct i2c_msg *msgs, int num)
+{
+	struct pic32_i2c_platform_data *adap = i2c_adap->algo_data;
+	struct i2c_msg *p;
+	int i, err = 0;
+
+	for (i = 0; i < num; i++) {
+#define __BUFSIZE 80
+		int ii;
+		static char buf[__BUFSIZE];
+		char *b = buf;
+
+		p = &msgs[i];
+		b += sprintf(buf, " [%d bytes]", p->len);
+		if ((p->flags & I2C_M_RD) == 0) {
+			for (ii = 0; ii < p->len; ii++) {
+				if (b < &buf[__BUFSIZE-4]) {
+					b += sprintf(b, " %02x", p->buf[ii]);
+				} else {
+					strcat(b, "...");
+					break;
+				}
+			}
+		}
+	}
+
+	for (i = 0; !err && i < num; i++) {
+		p = &msgs[i];
+		err = pic32_i2c_address(adap, p->addr, p->flags & I2C_M_RD);
+		if (err || !p->len)
+			continue;
+		if (p->flags & I2C_M_RD)
+			err = sead3_i2c_read(adap, p->buf, p->len);
+		else
+			err = sead3_i2c_write(adap, p->buf, p->len);
+	}
+
+	/* Return the number of messages processed, or the error code. */
+	if (err == 0)
+		err = num;
+
+	return err;
+}
+
+static u32 sead3_pic32_platform_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm sead3_platform_algo = {
+	.master_xfer	= sead3_pic32_platform_xfer,
+	.functionality	= sead3_pic32_platform_func,
+};
+
+static void sead3_i2c_platform_setup(struct pic32_i2c_platform_data *priv)
+{
+	pic32_bus_writel(500, priv->base + PIC32_I2CxBRG);
+	pic32_bus_writel(PIC32_I2CCON_ON, priv->base + PIC32_I2CxCONCLR);
+	pic32_bus_writel(PIC32_I2CCON_ON, priv->base + PIC32_I2CxCONSET);
+	pic32_bus_writel(PIC32_I2CSTAT_BCL | PIC32_I2CSTAT_IWCOL,
+		priv->base + PIC32_I2CxSTATCLR);
+}
+
+static int __devinit sead3_i2c_platform_probe(struct platform_device *pdev)
+{
+	struct pic32_i2c_platform_data *priv;
+	struct resource *r;
+	int ret;
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!r) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	priv = kzalloc(sizeof(struct pic32_i2c_platform_data), GFP_KERNEL);
+	if (!priv) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	priv->base = r->start;
+	if (!priv->base) {
+		ret = -EBUSY;
+		goto out_mem;
+	}
+
+	priv->xfer_timeout = 200;
+	priv->ack_timeout = 200;
+	priv->ctl_timeout = 200;
+
+	priv->adap.nr = pdev->id;
+	priv->adap.algo = &sead3_platform_algo;
+	priv->adap.algo_data = priv;
+	priv->adap.dev.parent = &pdev->dev;
+	strlcpy(priv->adap.name, "SEAD3 PIC32", sizeof(priv->adap.name));
+
+	sead3_i2c_platform_setup(priv);
+
+	ret = i2c_add_numbered_adapter(&priv->adap);
+	if (ret == 0) {
+		platform_set_drvdata(pdev, priv);
+		return 0;
+	}
+
+out_mem:
+	kfree(priv);
+out:
+	return ret;
+}
+
+static int __devexit sead3_i2c_platform_remove(struct platform_device *pdev)
+{
+	struct pic32_i2c_platform_data *priv = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+	i2c_del_adapter(&priv->adap);
+	kfree(priv);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int sead3_i2c_platform_suspend(struct platform_device *pdev,
+		pm_message_t state)
+{
+	dev_dbg(&pdev->dev, "i2c_platform_disable\n");
+	return 0;
+}
+
+static int sead3_i2c_platform_resume(struct platform_device *pdev)
+{
+	struct pic32_i2c_platform_data *priv = platform_get_drvdata(pdev);
+
+	dev_dbg(&pdev->dev, "sead3_i2c_platform_setup\n");
+	sead3_i2c_platform_setup(priv);
+
+	return 0;
+}
+#else
+#define sead3_i2c_platform_suspend	NULL
+#define sead3_i2c_platform_resume	NULL
+#endif
+
+static struct platform_driver sead3_i2c_platform_driver = {
+	.driver = {
+		.name	= "sead3-i2c",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= sead3_i2c_platform_probe,
+	.remove		= __devexit_p(sead3_i2c_platform_remove),
+	.suspend	= sead3_i2c_platform_suspend,
+	.resume		= sead3_i2c_platform_resume,
+};
+
+static int __init sead3_i2c_platform_init(void)
+{
+	return platform_driver_register(&sead3_i2c_platform_driver);
+}
+module_init(sead3_i2c_platform_init);
+
+static void __exit sead3_i2c_platform_exit(void)
+{
+	platform_driver_unregister(&sead3_i2c_platform_driver);
+}
+module_exit(sead3_i2c_platform_exit);
+
+MODULE_AUTHOR("Chris Dearman, MIPS Technologies INC.");
+MODULE_DESCRIPTION("SEAD3 PIC32 I2C driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/mips/mti-sead3/sead3-i2c.c b/arch/mips/mti-sead3/sead3-i2c.c
new file mode 100644
index 0000000..f70d5fc
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-i2c.c
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <irq.h>
+
+struct resource sead3_i2c_resources[] = {
+	{
+		.start	= 0x805200,
+		.end	= 0x8053ff,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device sead3_i2c_device = {
+	.name		= "sead3-i2c",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(sead3_i2c_resources),
+	.resource	= sead3_i2c_resources,
+};
+
+static int __init sead3_i2c_init(void)
+{
+	return platform_device_register(&sead3_i2c_device);
+}
+
+module_init(sead3_i2c_init);
+
+MODULE_AUTHOR("Chris Dearman <chris@mips.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("I2C probe driver for SEAD3");
diff --git a/arch/mips/mti-sead3/sead3-init.c b/arch/mips/mti-sead3/sead3-init.c
new file mode 100644
index 0000000..a958cad
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-init.c
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <asm/bootinfo.h>
+#include <asm/cacheflush.h>
+#include <asm/traps.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+
+extern void prom_init_early_console(char port);
+
+extern char except_vec_nmi;
+extern char except_vec_ejtag_debug;
+
+int prom_argc;
+int *_prom_argv, *_prom_envp;
+
+#define prom_envp(index) ((char *)(long)_prom_envp[(index)])
+
+char *prom_getenv(char *envname)
+{
+	/*
+	 * Return a pointer to the given environment variable.
+	 * In 64-bit mode: we're using 64-bit pointers, but all pointers
+	 * in the PROM structures are only 32-bit, so we need some
+	 * workarounds, if we are running in 64-bit mode.
+	 */
+	int i, index = 0;
+
+	i = strlen(envname);
+
+	while (prom_envp(index)) {
+		if (strncmp(envname, prom_envp(index), i) == 0)
+			return prom_envp(index+1);
+		index += 2;
+	}
+
+	return NULL;
+}
+
+static void __init mips_nmi_setup(void)
+{
+	void *base;
+
+	base = cpu_has_veic ?
+		(void *)(CAC_BASE + 0xa80) :
+		(void *)(CAC_BASE + 0x380);
+	memcpy(base, &except_vec_nmi, 0x80);
+	flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
+}
+
+static void __init mips_ejtag_setup(void)
+{
+	void *base;
+
+	base = cpu_has_veic ?
+		(void *)(CAC_BASE + 0xa00) :
+		(void *)(CAC_BASE + 0x300);
+	memcpy(base, &except_vec_ejtag_debug, 0x80);
+	flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
+}
+
+void __init prom_init(void)
+{
+	prom_argc = fw_arg0;
+	_prom_argv = (int *) fw_arg1;
+	_prom_envp = (int *) fw_arg2;
+
+	board_nmi_handler_setup = mips_nmi_setup;
+	board_ejtag_handler_setup = mips_ejtag_setup;
+
+	prom_init_cmdline();
+	prom_meminit();
+#ifdef CONFIG_EARLY_PRINTK
+	if ((strstr(prom_getcmdline(), "console=ttyS0")) != NULL)
+		prom_init_early_console(0);
+	else if ((strstr(prom_getcmdline(), "console=ttyS1")) != NULL)
+		prom_init_early_console(1);
+#endif
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+	if ((strstr(prom_getcmdline(), "console=")) == NULL)
+		strcat(prom_getcmdline(), " console=ttyS0,38400n8r");
+#endif
+}
diff --git a/arch/mips/mti-sead3/sead3-int.c b/arch/mips/mti-sead3/sead3-int.c
new file mode 100644
index 0000000..e26e082
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-int.c
@@ -0,0 +1,158 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/gic.h>
+#include <asm/irq_cpu.h>
+#include <asm/setup.h>
+
+#include <asm/mips-boards/sead3int.h>
+
+#define SEAD_CONFIG_GIC_PRESENT_SHF	1
+#define SEAD_CONFIG_GIC_PRESENT_MSK	(1 << SEAD_CONFIG_GIC_PRESENT_SHF)
+#define SEAD_CONFIG_BASE		0x1b100110
+#define SEAD_CONFIG_SIZE		4
+
+int gic_present;
+static unsigned long sead3_config_reg;
+
+/*
+ * This table defines the setup for each external GIC interrupt. It is
+ * indexed by interrupt number.
+ */
+#define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK
+static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = {
+	{ 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+	{ 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+	{ 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+	{ 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+	{ 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+	{ 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+	{ 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+	{ 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+	{ 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT },
+	{ GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
+	{ GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
+	{ GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
+	{ GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
+	{ GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
+	{ GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
+	{ GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED },
+};
+
+asmlinkage void plat_irq_dispatch(void)
+{
+	unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
+	int irq;
+
+	irq = (fls(pending) - CAUSEB_IP - 1);
+	if (irq >= 0)
+		do_IRQ(MIPS_CPU_IRQ_BASE + irq);
+	else
+		spurious_interrupt();
+}
+
+void __init arch_init_irq(void)
+{
+	int i;
+
+	if (!cpu_has_veic) {
+		mips_cpu_irq_init();
+
+		if (cpu_has_vint) {
+			/* install generic handler */
+			for (i = 0; i < 8; i++)
+				set_vi_handler(i, plat_irq_dispatch);
+		}
+	}
+
+	sead3_config_reg = (unsigned long)ioremap_nocache(SEAD_CONFIG_BASE,
+		SEAD_CONFIG_SIZE);
+	gic_present = (REG32(sead3_config_reg) & SEAD_CONFIG_GIC_PRESENT_MSK) >>
+		SEAD_CONFIG_GIC_PRESENT_SHF;
+	pr_info("GIC: %spresent\n", (gic_present) ? "" : "not ");
+	pr_info("EIC: %s\n",
+		(current_cpu_data.options & MIPS_CPU_VEIC) ?  "on" : "off");
+
+	if (gic_present)
+		gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map,
+			ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE);
+}
+
+void gic_enable_interrupt(int irq_vec)
+{
+	unsigned int i, irq_source;
+
+	/* enable all the interrupts associated with this vector */
+	for (i = 0; i < gic_shared_intr_map[irq_vec].num_shared_intr; i++) {
+		irq_source = gic_shared_intr_map[irq_vec].intr_list[i];
+		GIC_SET_INTR_MASK(irq_source);
+	}
+	/* enable all local interrupts associated with this vector */
+	if (gic_shared_intr_map[irq_vec].local_intr_mask) {
+		GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), 0);
+		GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_SMASK),
+			gic_shared_intr_map[irq_vec].local_intr_mask);
+	}
+}
+
+void gic_disable_interrupt(int irq_vec)
+{
+	unsigned int i, irq_source;
+
+	/* disable all the interrupts associated with this vector */
+	for (i = 0; i < gic_shared_intr_map[irq_vec].num_shared_intr; i++) {
+		irq_source = gic_shared_intr_map[irq_vec].intr_list[i];
+		GIC_CLR_INTR_MASK(irq_source);
+	}
+	/* disable all local interrupts associated with this vector */
+	if (gic_shared_intr_map[irq_vec].local_intr_mask) {
+		GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), 0);
+		GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_RMASK),
+			gic_shared_intr_map[irq_vec].local_intr_mask);
+	}
+}
+
+void gic_irq_ack(struct irq_data *d)
+{
+	GIC_CLR_INTR_MASK(d->irq - gic_irq_base);
+}
+
+void gic_finish_irq(struct irq_data *d)
+{
+	unsigned int irq = (d->irq - gic_irq_base);
+	unsigned int i, irq_source;
+
+	/* Clear edge detectors. */
+	for (i = 0; i < gic_shared_intr_map[irq].num_shared_intr; i++) {
+		irq_source = gic_shared_intr_map[irq].intr_list[i];
+		if (gic_irq_flags[irq_source] & GIC_TRIG_EDGE)
+			GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq_source);
+	}
+
+	/* Enable interrupts. */
+	GIC_SET_INTR_MASK(irq);
+}
+
+void __init gic_platform_init(int irqs, struct irq_chip *irq_controller)
+{
+	int i;
+
+	/*
+	 * For non-EIC mode, we want to setup the GIC in pass-through
+	 * mode, as if the GIC didn't exist. Do not map any interrupts
+	 * for an external interrupt controller.
+	 */
+	if (!cpu_has_veic)
+		return;
+
+	for (i = gic_irq_base; i < (gic_irq_base + irqs); i++)
+		irq_set_chip_and_handler(i, irq_controller, handle_percpu_irq);
+}
diff --git a/arch/mips/mti-sead3/sead3-lcd.c b/arch/mips/mti-sead3/sead3-lcd.c
new file mode 100644
index 0000000..10b10ed2
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-lcd.c
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+static struct resource __initdata sead3_lcd_resource = {
+		.start	= 0x1f000400,
+		.end	= 0x1f00041f,
+		.flags	= IORESOURCE_MEM,
+};
+
+static __init int sead3_lcd_add(void)
+{
+	struct platform_device *pdev;
+	int retval;
+
+	/* SEAD-3 and Cobalt platforms use same display type. */
+	pdev = platform_device_alloc("cobalt-lcd", -1);
+	if (!pdev)
+		return -ENOMEM;
+
+	retval = platform_device_add_resources(pdev, &sead3_lcd_resource, 1);
+	if (retval)
+		goto err_free_device;
+
+	retval = platform_device_add(pdev);
+	if (retval)
+		goto err_free_device;
+
+	return 0;
+
+err_free_device:
+	platform_device_put(pdev);
+
+	return retval;
+}
+
+device_initcall(sead3_lcd_add);
diff --git a/arch/mips/mti-sead3/sead3-leds.c b/arch/mips/mti-sead3/sead3-leds.c
new file mode 100644
index 0000000..20102a6
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-leds.c
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
+ */
+#include <linux/module.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+
+#define LEDFLAGS(bits, shift)		\
+	((bits << 8) | (shift << 8))
+
+#define LEDBITS(id, shift, bits)	\
+	.name = id #shift,		\
+	.flags = LEDFLAGS(bits, shift)
+
+struct led_info led_data_info[] = {
+	{ LEDBITS("bit", 0, 1) },
+	{ LEDBITS("bit", 1, 1) },
+	{ LEDBITS("bit", 2, 1) },
+	{ LEDBITS("bit", 3, 1) },
+	{ LEDBITS("bit", 4, 1) },
+	{ LEDBITS("bit", 5, 1) },
+	{ LEDBITS("bit", 6, 1) },
+	{ LEDBITS("bit", 7, 1) },
+	{ LEDBITS("all", 0, 8) },
+};
+
+static struct led_platform_data led_data = {
+	.num_leds	= ARRAY_SIZE(led_data_info),
+	.leds		= led_data_info
+};
+
+static struct resource pled_resources[] = {
+	{
+		.start	= 0x1f000210,
+		.end	= 0x1f000217,
+		.flags	= IORESOURCE_MEM
+	}
+};
+
+static struct platform_device pled_device = {
+	.name			= "sead3::pled",
+	.id			= 0,
+	.dev			= {
+		.platform_data	= &led_data,
+	},
+	.num_resources		= ARRAY_SIZE(pled_resources),
+	.resource		= pled_resources
+};
+
+
+static struct resource fled_resources[] = {
+	{
+		.start			= 0x1f000218,
+		.end			= 0x1f00021f,
+		.flags			= IORESOURCE_MEM
+	}
+};
+
+static struct platform_device fled_device = {
+	.name			= "sead3::fled",
+	.id			= 0,
+	.dev			= {
+		.platform_data	= &led_data,
+	},
+	.num_resources		= ARRAY_SIZE(fled_resources),
+	.resource		= fled_resources
+};
+
+static int __init led_init(void)
+{
+	platform_device_register(&pled_device);
+	return platform_device_register(&fled_device);
+}
+
+module_init(led_init);
+
+MODULE_AUTHOR("Chris Dearman <chris@mips.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("LED probe driver for SEAD-3");
diff --git a/arch/mips/mti-sead3/sead3-memory.c b/arch/mips/mti-sead3/sead3-memory.c
new file mode 100644
index 0000000..da92441
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-memory.c
@@ -0,0 +1,138 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
+ */
+#include <linux/bootmem.h>
+
+#include <asm/bootinfo.h>
+#include <asm/sections.h>
+#include <asm/mips-boards/prom.h>
+
+enum yamon_memtypes {
+	yamon_dontuse,
+	yamon_prom,
+	yamon_free,
+};
+
+static struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
+
+/* determined physical memory size, not overridden by command line args  */
+unsigned long physical_memsize = 0L;
+
+struct prom_pmemblock * __init prom_getmdesc(void)
+{
+	char *memsize_str, *ptr;
+	unsigned int memsize;
+	static char cmdline[COMMAND_LINE_SIZE] __initdata;
+	long val;
+	int tmp;
+
+	/* otherwise look in the environment */
+	memsize_str = prom_getenv("memsize");
+	if (!memsize_str) {
+		pr_warn("memsize not set in boot prom, set to default 32Mb\n");
+		physical_memsize = 0x02000000;
+	} else {
+		tmp = kstrtol(memsize_str, 0, &val);
+		physical_memsize = (unsigned long)val;
+	}
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+	/* SOC-it swaps, or perhaps doesn't swap, when DMA'ing the last
+	   word of physical memory */
+	physical_memsize -= PAGE_SIZE;
+#endif
+
+	/* Check the command line for a memsize directive that overrides
+	   the physical/default amount */
+	strcpy(cmdline, arcs_cmdline);
+	ptr = strstr(cmdline, "memsize=");
+	if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' '))
+		ptr = strstr(ptr, " memsize=");
+
+	if (ptr)
+		memsize = memparse(ptr + 8, &ptr);
+	else
+		memsize = physical_memsize;
+
+	memset(mdesc, 0, sizeof(mdesc));
+
+	mdesc[0].type = yamon_dontuse;
+	mdesc[0].base = 0x00000000;
+	mdesc[0].size = 0x00001000;
+
+	mdesc[1].type = yamon_prom;
+	mdesc[1].base = 0x00001000;
+	mdesc[1].size = 0x000ef000;
+
+	/*
+	 * The area 0x000f0000-0x000fffff is allocated for BIOS memory by the
+	 * south bridge and PCI access always forwarded to the ISA Bus and
+	 * BIOSCS# is always generated.
+	 * This mean that this area can't be used as DMA memory for PCI
+	 * devices.
+	 */
+	mdesc[2].type = yamon_dontuse;
+	mdesc[2].base = 0x000f0000;
+	mdesc[2].size = 0x00010000;
+
+	mdesc[3].type = yamon_dontuse;
+	mdesc[3].base = 0x00100000;
+	mdesc[3].size = CPHYSADDR(PFN_ALIGN((unsigned long)&_end)) -
+		mdesc[3].base;
+
+	mdesc[4].type = yamon_free;
+	mdesc[4].base = CPHYSADDR(PFN_ALIGN(&_end));
+	mdesc[4].size = memsize - mdesc[4].base;
+
+	return &mdesc[0];
+}
+
+static int __init prom_memtype_classify(unsigned int type)
+{
+	switch (type) {
+	case yamon_free:
+		return BOOT_MEM_RAM;
+	case yamon_prom:
+		return BOOT_MEM_ROM_DATA;
+	default:
+		return BOOT_MEM_RESERVED;
+	}
+}
+
+void __init prom_meminit(void)
+{
+	struct prom_pmemblock *p;
+
+	p = prom_getmdesc();
+
+	while (p->size) {
+		long type;
+		unsigned long base, size;
+
+		type = prom_memtype_classify(p->type);
+		base = p->base;
+		size = p->size;
+
+		add_memory_region(base, size, type);
+		p++;
+	}
+}
+
+void __init prom_free_prom_memory(void)
+{
+	unsigned long addr;
+	int i;
+
+	for (i = 0; i < boot_mem_map.nr_map; i++) {
+		if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
+			continue;
+
+		addr = boot_mem_map.map[i].addr;
+		free_init_pages("prom memory",
+				addr, addr + boot_mem_map.map[i].size);
+	}
+}
diff --git a/arch/mips/mti-sead3/sead3-mtd.c b/arch/mips/mti-sead3/sead3-mtd.c
new file mode 100644
index 0000000..ffa35f5
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-mtd.c
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
+ */
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+
+static struct mtd_partition sead3_mtd_partitions[] = {
+	{
+		.name =		"User FS",
+		.offset =	0x00000000,
+		.size =		0x01fc0000,
+	}, {
+		.name =		"Board Config",
+		.offset =	0x01fc0000,
+		.size =		0x00040000,
+		.mask_flags =	MTD_WRITEABLE
+	},
+};
+
+static struct physmap_flash_data sead3_flash_data = {
+	.width		= 4,
+	.nr_parts	= ARRAY_SIZE(sead3_mtd_partitions),
+	.parts		= sead3_mtd_partitions
+};
+
+static struct resource sead3_flash_resource = {
+	.start		= 0x1c000000,
+	.end		= 0x1dffffff,
+	.flags		= IORESOURCE_MEM
+};
+
+static struct platform_device sead3_flash = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &sead3_flash_data,
+	},
+	.num_resources	= 1,
+	.resource	= &sead3_flash_resource,
+};
+
+static int __init sead3_mtd_init(void)
+{
+	platform_device_register(&sead3_flash);
+
+	return 0;
+}
+
+module_init(sead3_mtd_init)
diff --git a/arch/mips/mti-sead3/sead3-net.c b/arch/mips/mti-sead3/sead3-net.c
new file mode 100644
index 0000000..04d704d
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-net.c
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
+ */
+#include <linux/module.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/smsc911x.h>
+
+static struct smsc911x_platform_config sead3_smsc911x_data = {
+	.irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+	.irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+	.flags	= SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
+	.phy_interface = PHY_INTERFACE_MODE_MII,
+};
+
+struct resource sead3_net_resourcess[] = {
+	{
+		.start                  = 0x1f010000,
+		.end                    = 0x1f01ffff,
+		.flags			= IORESOURCE_MEM
+	},
+	{
+		.start			= MIPS_CPU_IRQ_BASE + 6,
+		.flags			= IORESOURCE_IRQ
+	}
+};
+
+static struct platform_device sead3_net_device = {
+	.name			= "smsc911x",
+	.id			= 0,
+	.dev			= {
+		.platform_data	= &sead3_smsc911x_data,
+	},
+	.num_resources		= ARRAY_SIZE(sead3_net_resourcess),
+	.resource		= sead3_net_resourcess
+};
+
+static int __init sead3_net_init(void)
+{
+	return platform_device_register(&sead3_net_device);
+}
+
+module_init(sead3_net_init);
+
+MODULE_AUTHOR("Chris Dearman <chris@mips.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Network probe driver for SEAD-3");
diff --git a/arch/mips/mti-sead3/sead3-pic32-bus.c b/arch/mips/mti-sead3/sead3-pic32-bus.c
new file mode 100644
index 0000000..9f0d89b
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-pic32-bus.c
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
+ */
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/errno.h>
+
+#define PIC32_NULL	0x00
+#define PIC32_RD	0x01
+#define PIC32_SYSRD	0x02
+#define PIC32_WR	0x10
+#define PIC32_SYSWR	0x20
+#define PIC32_IRQ_CLR   0x40
+#define PIC32_STATUS	0x80
+
+#define DELAY()	udelay(100)	/* FIXME: needed? */
+
+/* spinlock to ensure atomic access to PIC32 */
+static DEFINE_SPINLOCK(pic32_bus_lock);
+
+/* FIXME: io_remap these */
+static void __iomem *bus_xfer   = (void __iomem *)0xbf000600;
+static void __iomem *bus_status = (void __iomem *)0xbf000060;
+
+static inline unsigned int ioready(void)
+{
+	return readl(bus_status) & 1;
+}
+
+static inline void wait_ioready(void)
+{
+	do { } while (!ioready());
+}
+
+static inline void wait_ioclear(void)
+{
+	do { } while (ioready());
+}
+
+static inline void check_ioclear(void)
+{
+	if (ioready()) {
+		pr_debug("ioclear: initially busy\n");
+		do {
+			(void) readl(bus_xfer);
+			DELAY();
+		} while (ioready());
+		pr_debug("ioclear: cleared busy\n");
+	}
+}
+
+u32 pic32_bus_readl(u32 reg)
+{
+	unsigned long flags;
+	u32 status, val;
+
+	spin_lock_irqsave(&pic32_bus_lock, flags);
+
+	check_ioclear();
+
+	writel((PIC32_RD << 24) | (reg & 0x00ffffff), bus_xfer);
+	DELAY();
+	wait_ioready();
+	status = readl(bus_xfer);
+	DELAY();
+	val = readl(bus_xfer);
+	wait_ioclear();
+
+	pr_debug("pic32_bus_readl: *%x -> %x (status=%x)\n", reg, val, status);
+
+	spin_unlock_irqrestore(&pic32_bus_lock, flags);
+
+	return val;
+}
+
+void pic32_bus_writel(u32 val, u32 reg)
+{
+	unsigned long flags;
+	u32 status;
+
+	spin_lock_irqsave(&pic32_bus_lock, flags);
+
+	check_ioclear();
+
+	writel((PIC32_WR << 24) | (reg & 0x00ffffff), bus_xfer);
+	DELAY();
+	writel(val, bus_xfer);
+	DELAY();
+	wait_ioready();
+	status = readl(bus_xfer);
+	wait_ioclear();
+
+	pr_debug("pic32_bus_writel: *%x <- %x (status=%x)\n", reg, val, status);
+
+	spin_unlock_irqrestore(&pic32_bus_lock, flags);
+}
diff --git a/arch/mips/mti-sead3/sead3-pic32-i2c-drv.c b/arch/mips/mti-sead3/sead3-pic32-i2c-drv.c
new file mode 100644
index 0000000..46509b0
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-pic32-i2c-drv.c
@@ -0,0 +1,435 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
+ */
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+
+#define PIC32_I2CxCON		0x0000
+#define PIC32_I2CxCONCLR	0x0004
+#define PIC32_I2CxCONSET	0x0008
+#define PIC32_I2CxCONINV	0x000C
+#define  I2CCON_ON		(1<<15)
+#define  I2CCON_FRZ		(1<<14)
+#define  I2CCON_SIDL		(1<<13)
+#define  I2CCON_SCLREL		(1<<12)
+#define  I2CCON_STRICT		(1<<11)
+#define  I2CCON_A10M		(1<<10)
+#define  I2CCON_DISSLW		(1<<9)
+#define  I2CCON_SMEN		(1<<8)
+#define  I2CCON_GCEN		(1<<7)
+#define  I2CCON_STREN		(1<<6)
+#define  I2CCON_ACKDT		(1<<5)
+#define  I2CCON_ACKEN		(1<<4)
+#define  I2CCON_RCEN		(1<<3)
+#define  I2CCON_PEN		(1<<2)
+#define  I2CCON_RSEN		(1<<1)
+#define  I2CCON_SEN		(1<<0)
+
+#define PIC32_I2CxSTAT		0x0010
+#define PIC32_I2CxSTATCLR	0x0014
+#define PIC32_I2CxSTATSET	0x0018
+#define PIC32_I2CxSTATINV	0x001C
+#define  I2CSTAT_ACKSTAT	(1<<15)
+#define  I2CSTAT_TRSTAT		(1<<14)
+#define  I2CSTAT_BCL		(1<<10)
+#define  I2CSTAT_GCSTAT		(1<<9)
+#define  I2CSTAT_ADD10		(1<<8)
+#define  I2CSTAT_IWCOL		(1<<7)
+#define  I2CSTAT_I2COV		(1<<6)
+#define  I2CSTAT_DA		(1<<5)
+#define  I2CSTAT_P		(1<<4)
+#define  I2CSTAT_S		(1<<3)
+#define  I2CSTAT_RW		(1<<2)
+#define  I2CSTAT_RBF		(1<<1)
+#define  I2CSTAT_TBF		(1<<0)
+
+#define PIC32_I2CxADD		0x0020
+#define PIC32_I2CxADDCLR	0x0024
+#define PIC32_I2CxADDSET	0x0028
+#define PIC32_I2CxADDINV	0x002C
+#define PIC32_I2CxMSK		0x0030
+#define PIC32_I2CxMSKCLR	0x0034
+#define PIC32_I2CxMSKSET	0x0038
+#define PIC32_I2CxMSKINV	0x003C
+#define PIC32_I2CxBRG		0x0040
+#define PIC32_I2CxBRGCLR	0x0044
+#define PIC32_I2CxBRGSET	0x0048
+#define PIC32_I2CxBRGINV	0x004C
+#define PIC32_I2CxTRN		0x0050
+#define PIC32_I2CxTRNCLR	0x0054
+#define PIC32_I2CxTRNSET	0x0058
+#define PIC32_I2CxTRNINV	0x005C
+#define PIC32_I2CxRCV		0x0060
+
+struct i2c_platform_data {
+	u32	base;
+	struct i2c_adapter adap;
+	u32	xfer_timeout;
+	u32	ack_timeout;
+	u32	ctl_timeout;
+};
+
+extern u32 pic32_bus_readl(u32 reg);
+extern void pic32_bus_writel(u32 val, u32 reg);
+
+static inline void
+StartI2C(struct i2c_platform_data *adap)
+{
+	pr_debug("StartI2C\n");
+	pic32_bus_writel(I2CCON_SEN, adap->base + PIC32_I2CxCONSET);
+}
+
+static inline void
+StopI2C(struct i2c_platform_data *adap)
+{
+	pr_debug("StopI2C\n");
+	pic32_bus_writel(I2CCON_PEN, adap->base + PIC32_I2CxCONSET);
+}
+
+static inline void
+AckI2C(struct i2c_platform_data *adap)
+{
+	pr_debug("AckI2C\n");
+	pic32_bus_writel(I2CCON_ACKDT, adap->base + PIC32_I2CxCONCLR);
+	pic32_bus_writel(I2CCON_ACKEN, adap->base + PIC32_I2CxCONSET);
+}
+
+static inline void
+NotAckI2C(struct i2c_platform_data *adap)
+{
+	pr_debug("NakI2C\n");
+	pic32_bus_writel(I2CCON_ACKDT, adap->base + PIC32_I2CxCONSET);
+	pic32_bus_writel(I2CCON_ACKEN, adap->base + PIC32_I2CxCONSET);
+}
+
+static inline int
+IdleI2C(struct i2c_platform_data *adap)
+{
+	int i;
+
+	pr_debug("IdleI2C\n");
+	for (i = 0; i < adap->ctl_timeout; i++) {
+		if (((pic32_bus_readl(adap->base + PIC32_I2CxCON) &
+		     (I2CCON_ACKEN | I2CCON_RCEN | I2CCON_PEN | I2CCON_RSEN |
+		      I2CCON_SEN)) == 0) &&
+		    ((pic32_bus_readl(adap->base + PIC32_I2CxSTAT) &
+		     (I2CSTAT_TRSTAT)) == 0))
+			return 0;
+		udelay(1);
+	}
+	return -ETIMEDOUT;
+}
+
+static inline u32
+MasterWriteI2C(struct i2c_platform_data *adap, u32 byte)
+{
+	pr_debug("MasterWriteI2C\n");
+
+	pic32_bus_writel(byte, adap->base + PIC32_I2CxTRN);
+
+	return pic32_bus_readl(adap->base + PIC32_I2CxSTAT) & I2CSTAT_IWCOL;
+}
+
+static inline u32
+MasterReadI2C(struct i2c_platform_data *adap)
+{
+	pr_debug("MasterReadI2C\n");
+
+	pic32_bus_writel(I2CCON_RCEN, adap->base + PIC32_I2CxCONSET);
+
+	while (pic32_bus_readl(adap->base + PIC32_I2CxCON) & I2CCON_RCEN)
+		;
+
+	pic32_bus_writel(I2CSTAT_I2COV, adap->base + PIC32_I2CxSTATCLR);
+
+	return pic32_bus_readl(adap->base + PIC32_I2CxRCV);
+}
+
+static int
+do_address(struct i2c_platform_data *adap, unsigned int addr, int rd)
+{
+	pr_debug("doaddress\n");
+
+	IdleI2C(adap);
+	StartI2C(adap);
+	IdleI2C(adap);
+
+	addr <<= 1;
+	if (rd)
+		addr |= 1;
+
+	if (MasterWriteI2C(adap, addr))
+		return -EIO;
+	IdleI2C(adap);
+	if (pic32_bus_readl(adap->base + PIC32_I2CxSTAT) & I2CSTAT_ACKSTAT)
+		return -EIO;
+	return 0;
+}
+
+static int
+i2c_read(struct i2c_platform_data *adap, unsigned char *buf,
+		    unsigned int len)
+{
+	int	i;
+	u32	data;
+
+	pr_debug("i2c_read\n");
+
+	i = 0;
+	while (i < len) {
+		data = MasterReadI2C(adap);
+		buf[i++] = data;
+		if (i < len)
+			AckI2C(adap);
+		else
+			NotAckI2C(adap);
+	}
+
+	StopI2C(adap);
+	IdleI2C(adap);
+	return 0;
+}
+
+static int
+i2c_write(struct i2c_platform_data *adap, unsigned char *buf,
+		     unsigned int len)
+{
+	int	i;
+	u32	data;
+
+	pr_debug("i2c_write\n");
+
+	i = 0;
+	while (i < len) {
+		data = buf[i];
+		if (MasterWriteI2C(adap, data))
+			return -EIO;
+		IdleI2C(adap);
+		if (pic32_bus_readl(adap->base + PIC32_I2CxSTAT) &
+		    I2CSTAT_ACKSTAT)
+			return -EIO;
+		i++;
+	}
+
+	StopI2C(adap);
+	IdleI2C(adap);
+	return 0;
+}
+
+static int
+platform_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
+{
+	struct i2c_platform_data *adap = i2c_adap->algo_data;
+	struct i2c_msg *p;
+	int i, err = 0;
+
+	pr_debug("platform_xfer\n");
+	for (i = 0; i < num; i++) {
+#define __BUFSIZE 80
+		int ii;
+		static char buf[__BUFSIZE];
+		char *b = buf;
+
+		p = &msgs[i];
+		b += sprintf(buf, " [%d bytes]", p->len);
+		if ((p->flags & I2C_M_RD) == 0) {
+			for (ii = 0; ii < p->len; ii++) {
+				if (b < &buf[__BUFSIZE-4]) {
+					b += sprintf(b, " %02x", p->buf[ii]);
+				} else {
+					strcat(b, "...");
+					break;
+				}
+			}
+		}
+		pr_debug("xfer%d: DevAddr: %04x Op:%s Data:%s\n", i, p->addr,
+			 (p->flags & I2C_M_RD) ? "Rd" : "Wr", buf);
+	}
+
+
+	for (i = 0; !err && i < num; i++) {
+		p = &msgs[i];
+		err = do_address(adap, p->addr, p->flags & I2C_M_RD);
+		if (err || !p->len)
+			continue;
+		if (p->flags & I2C_M_RD)
+			err = i2c_read(adap, p->buf, p->len);
+		else
+			err = i2c_write(adap, p->buf, p->len);
+	}
+
+	/* Return the number of messages processed, or the error code. */
+	if (err == 0)
+		err = num;
+
+	return err;
+}
+
+static u32
+platform_func(struct i2c_adapter *adap)
+{
+	pr_debug("platform_algo\n");
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm platform_algo = {
+	.master_xfer	= platform_xfer,
+	.functionality	= platform_func,
+};
+
+static void i2c_platform_setup(struct i2c_platform_data *priv)
+{
+	pr_debug("i2c_platform_setup\n");
+
+	pic32_bus_writel(500, priv->base + PIC32_I2CxBRG);
+	pic32_bus_writel(I2CCON_ON, priv->base + PIC32_I2CxCONCLR);
+	pic32_bus_writel(I2CCON_ON, priv->base + PIC32_I2CxCONSET);
+	pic32_bus_writel((I2CSTAT_BCL | I2CSTAT_IWCOL),
+		(priv->base + PIC32_I2CxSTATCLR));
+}
+
+static void i2c_platform_disable(struct i2c_platform_data *priv)
+{
+	pr_debug("i2c_platform_disable\n");
+}
+
+static int __devinit
+i2c_platform_probe(struct platform_device *pdev)
+{
+	struct i2c_platform_data *priv;
+	struct resource *r;
+	int ret;
+
+	pr_debug("i2c_platform_probe\n");
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!r) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	priv = kzalloc(sizeof(struct i2c_platform_data), GFP_KERNEL);
+	if (!priv) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* FIXME: need to allocate resource in PIC32 space */
+#if 0
+	priv->base = bus_request_region(r->start, resource_size(r),
+					  pdev->name);
+#else
+	priv->base = r->start;
+#endif
+	if (!priv->base) {
+		ret = -EBUSY;
+		goto out_mem;
+	}
+
+	priv->xfer_timeout = 200;
+	priv->ack_timeout = 200;
+	priv->ctl_timeout = 200;
+
+	priv->adap.nr = pdev->id;
+	priv->adap.algo = &platform_algo;
+	priv->adap.algo_data = priv;
+	priv->adap.dev.parent = &pdev->dev;
+	strlcpy(priv->adap.name, "PIC32 I2C", sizeof(priv->adap.name));
+
+	i2c_platform_setup(priv);
+
+	ret = i2c_add_numbered_adapter(&priv->adap);
+	if (ret == 0) {
+		platform_set_drvdata(pdev, priv);
+		return 0;
+	}
+
+	i2c_platform_disable(priv);
+
+out_mem:
+	kfree(priv);
+out:
+	return ret;
+}
+
+static int __devexit
+i2c_platform_remove(struct platform_device *pdev)
+{
+	struct i2c_platform_data *priv = platform_get_drvdata(pdev);
+
+	pr_debug("i2c_platform_remove\n");
+	platform_set_drvdata(pdev, NULL);
+	i2c_del_adapter(&priv->adap);
+	i2c_platform_disable(priv);
+	kfree(priv);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int
+i2c_platform_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct i2c_platform_data *priv = platform_get_drvdata(pdev);
+
+	dev_dbg(&pdev->dev, "i2c_platform_disable\n");
+	i2c_platform_disable(priv);
+
+	return 0;
+}
+
+static int
+i2c_platform_resume(struct platform_device *pdev)
+{
+	struct i2c_platform_data *priv = platform_get_drvdata(pdev);
+
+	dev_dbg(&pdev->dev, "i2c_platform_setup\n");
+	i2c_platform_setup(priv);
+
+	return 0;
+}
+#else
+#define i2c_platform_suspend	NULL
+#define i2c_platform_resume	NULL
+#endif
+
+static struct platform_driver i2c_platform_driver = {
+	.driver = {
+		.name	= "i2c_pic32",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= i2c_platform_probe,
+	.remove		= __devexit_p(i2c_platform_remove),
+	.suspend	= i2c_platform_suspend,
+	.resume		= i2c_platform_resume,
+};
+
+static int __init
+i2c_platform_init(void)
+{
+	pr_debug("i2c_platform_init\n");
+	return platform_driver_register(&i2c_platform_driver);
+}
+
+static void __exit
+i2c_platform_exit(void)
+{
+	pr_debug("i2c_platform_exit\n");
+	platform_driver_unregister(&i2c_platform_driver);
+}
+
+MODULE_AUTHOR("Chris Dearman, MIPS Technologies INC.");
+MODULE_DESCRIPTION("PIC32 I2C driver");
+MODULE_LICENSE("GPL");
+
+module_init(i2c_platform_init);
+module_exit(i2c_platform_exit);
diff --git a/arch/mips/mti-sead3/sead3-platform.c b/arch/mips/mti-sead3/sead3-platform.c
new file mode 100644
index 0000000..6c3b33d
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-platform.c
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+
+#define UART(base, int)							\
+{									\
+	.mapbase	= base,						\
+	.irq		= int,						\
+	.uartclk	= 14745600,					\
+	.iotype		= UPIO_MEM32,					\
+	.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, \
+	.regshift	= 2,						\
+}
+
+static struct plat_serial8250_port uart8250_data[] = {
+	UART(0x1f000900, MIPS_CPU_IRQ_BASE + 4),   /* ttyS0 = USB   */
+	UART(0x1f000800, MIPS_CPU_IRQ_BASE + 4),   /* ttyS1 = RS232 */
+	{ },
+};
+
+static struct platform_device uart8250_device = {
+	.name			= "serial8250",
+	.id			= PLAT8250_DEV_PLATFORM2,
+	.dev			= {
+		.platform_data	= uart8250_data,
+	},
+};
+
+static int __init uart8250_init(void)
+{
+	return platform_device_register(&uart8250_device);
+}
+
+module_init(uart8250_init);
+
+MODULE_AUTHOR("Chris Dearman <chris@mips.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("8250 UART probe driver for SEAD3");
diff --git a/arch/mips/mti-sead3/sead3-reset.c b/arch/mips/mti-sead3/sead3-reset.c
new file mode 100644
index 0000000..20475c5
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-reset.c
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
+ */
+#include <linux/io.h>
+#include <linux/pm.h>
+
+#include <asm/reboot.h>
+#include <asm/mips-boards/generic.h>
+
+static void mips_machine_restart(char *command)
+{
+	unsigned int __iomem *softres_reg =
+		ioremap(SOFTRES_REG, sizeof(unsigned int));
+
+	__raw_writel(GORESET, softres_reg);
+}
+
+static void mips_machine_halt(void)
+{
+	unsigned int __iomem *softres_reg =
+		ioremap(SOFTRES_REG, sizeof(unsigned int));
+
+	__raw_writel(GORESET, softres_reg);
+}
+
+static int __init mips_reboot_setup(void)
+{
+	_machine_restart = mips_machine_restart;
+	_machine_halt = mips_machine_halt;
+	pm_power_off = mips_machine_halt;
+
+	return 0;
+}
+
+arch_initcall(mips_reboot_setup);
diff --git a/arch/mips/mti-sead3/sead3-serial.c b/arch/mips/mti-sead3/sead3-serial.c
new file mode 100644
index 0000000..bc52705
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-serial.c
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/serial_8250.h>
+
+#define UART(base, int)							\
+{									\
+	.mapbase	= base,						\
+	.irq		= int,						\
+	.uartclk	= 14745600,					\
+	.iotype		= UPIO_MEM32,					\
+	.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, \
+	.regshift	= 2,						\
+}
+
+static struct plat_serial8250_port uart8250_data[] = {
+	UART(0x1f000900, MIPS_CPU_IRQ_BASE + 4),   /* ttyS0 = USB   */
+	UART(0x1f000800, MIPS_CPU_IRQ_BASE + 4),   /* ttyS1 = RS232 */
+	{ },
+};
+
+static struct platform_device uart8250_device = {
+	.name			= "serial8250",
+	.id			= PLAT8250_DEV_PLATFORM,
+	.dev			= {
+		.platform_data	= uart8250_data,
+	},
+};
+
+static int __init uart8250_init(void)
+{
+	return platform_device_register(&uart8250_device);
+}
+
+module_init(uart8250_init);
+
+MODULE_AUTHOR("Chris Dearman <chris@mips.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("8250 UART probe driver for the SEAD-3 platform");
diff --git a/arch/mips/mti-sead3/sead3-setup.c b/arch/mips/mti-sead3/sead3-setup.c
new file mode 100644
index 0000000..8ad46ad
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-setup.c
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
+ */
+#include <linux/init.h>
+
+int coherentio;		/* 0 => no DMA cache coherency (may be set by user) */
+int hw_coherentio;	/* 0 => no HW DMA cache coherency (reflects real HW) */
+
+const char *get_system_type(void)
+{
+	return "MIPS SEAD3";
+}
+
+void __init plat_mem_setup(void)
+{
+}
diff --git a/arch/mips/mti-sead3/sead3-time.c b/arch/mips/mti-sead3/sead3-time.c
new file mode 100644
index 0000000..048e781
--- /dev/null
+++ b/arch/mips/mti-sead3/sead3-time.c
@@ -0,0 +1,117 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2012 MIPS Technologies, Inc.  All rights reserved.
+ */
+#include <linux/init.h>
+
+#include <asm/setup.h>
+#include <asm/time.h>
+#include <asm/irq.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+
+unsigned long cpu_khz;
+
+static int mips_cpu_timer_irq;
+static int mips_cpu_perf_irq;
+
+static void mips_timer_dispatch(void)
+{
+	do_IRQ(mips_cpu_timer_irq);
+}
+
+static void mips_perf_dispatch(void)
+{
+	do_IRQ(mips_cpu_perf_irq);
+}
+
+static void __iomem *status_reg = (void __iomem *)0xbf000410;
+
+/*
+ * Estimate CPU frequency.  Sets mips_hpt_frequency as a side-effect.
+ */
+static unsigned int __init estimate_cpu_frequency(void)
+{
+	unsigned int prid = read_c0_prid() & 0xffff00;
+	unsigned int tick = 0;
+	unsigned int freq;
+	unsigned int orig;
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	orig = readl(status_reg) & 0x2;               /* get original sample */
+	/* wait for transition */
+	while ((readl(status_reg) & 0x2) == orig)
+		;
+	orig = orig ^ 0x2;                            /* flip the bit */
+
+	write_c0_count(0);
+
+	/* wait 1 second (the sampling clock transitions every 10ms) */
+	while (tick < 100) {
+		/* wait for transition */
+		while ((readl(status_reg) & 0x2) == orig)
+			;
+		orig = orig ^ 0x2;                            /* flip the bit */
+		tick++;
+	}
+
+	freq = read_c0_count();
+
+	local_irq_restore(flags);
+
+	mips_hpt_frequency = freq;
+
+	/* Adjust for processor */
+	if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) &&
+		(prid != (PRID_COMP_MIPS | PRID_IMP_25KF)))
+		freq *= 2;
+
+	freq += 5000;        /* rounding */
+	freq -= freq%10000;
+
+	return freq ;
+}
+
+void read_persistent_clock(struct timespec *ts)
+{
+	ts->tv_sec = 0;
+	ts->tv_nsec = 0;
+}
+
+static void __init plat_perf_setup(void)
+{
+	if (cp0_perfcount_irq >= 0) {
+		if (cpu_has_vint)
+			set_vi_handler(cp0_perfcount_irq, mips_perf_dispatch);
+		mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
+	}
+}
+
+unsigned int __cpuinit get_c0_compare_int(void)
+{
+	if (cpu_has_vint)
+		set_vi_handler(cp0_compare_irq, mips_timer_dispatch);
+	mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
+	return mips_cpu_timer_irq;
+}
+
+void __init plat_time_init(void)
+{
+	unsigned int est_freq;
+
+	est_freq = estimate_cpu_frequency();
+
+	pr_debug("CPU frequency %d.%02d MHz\n", (est_freq / 1000000),
+		(est_freq % 1000000) * 100 / 1000000);
+
+	cpu_khz = est_freq / 1000;
+
+	mips_scroll_message();
+
+	plat_perf_setup();
+}
diff --git a/arch/mips/netlogic/Kconfig b/arch/mips/netlogic/Kconfig
index 75bec44..8059eb7 100644
--- a/arch/mips/netlogic/Kconfig
+++ b/arch/mips/netlogic/Kconfig
@@ -1,2 +1,17 @@
+if NLM_XLP_BOARD || NLM_XLR_BOARD
+
+if NLM_XLP_BOARD
+config DT_XLP_EVP
+	bool "Built-in device tree for XLP EVP/SVP boards"
+	default y
+	help
+	  Add an FDT blob for XLP EVP and SVP boards into the kernel.
+	  This DTB will be used if the firmware does not pass in a DTB
+          pointer to the kernel.  The corresponding DTS file is at
+          arch/mips/netlogic/dts/xlp_evp.dts
+endif
+
 config NLM_COMMON
 	bool
+
+endif
diff --git a/arch/mips/netlogic/Makefile b/arch/mips/netlogic/Makefile
index 36d169b..7602d13 100644
--- a/arch/mips/netlogic/Makefile
+++ b/arch/mips/netlogic/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_NLM_COMMON)	+=	common/
 obj-$(CONFIG_CPU_XLR)		+=	xlr/
 obj-$(CONFIG_CPU_XLP)		+=	xlp/
+obj-$(CONFIG_CPU_XLP)		+=	dts/
diff --git a/arch/mips/netlogic/dts/Makefile b/arch/mips/netlogic/dts/Makefile
new file mode 100644
index 0000000..67ae3fe2
--- /dev/null
+++ b/arch/mips/netlogic/dts/Makefile
@@ -0,0 +1,4 @@
+obj-$(CONFIG_DT_XLP_EVP) := xlp_evp.dtb.o
+
+$(obj)/%.dtb: $(obj)/%.dts
+	$(call if_changed,dtc)
diff --git a/arch/mips/netlogic/dts/xlp_evp.dts b/arch/mips/netlogic/dts/xlp_evp.dts
new file mode 100644
index 0000000..e14f423
--- /dev/null
+++ b/arch/mips/netlogic/dts/xlp_evp.dts
@@ -0,0 +1,124 @@
+/*
+ * XLP8XX Device Tree Source for EVP boards
+ */
+
+/dts-v1/;
+/ {
+	model = "netlogic,XLP-EVP";
+	compatible = "netlogic,xlp";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	memory {
+		device_type = "memory";
+		reg =  <0 0x00100000 0 0x0FF00000	// 255M at 1M
+			0 0x20000000 0 0xa0000000	// 2560M at 512M
+			0 0xe0000000 1 0x00000000>;
+	};
+
+	soc {
+		#address-cells = <2>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+		ranges = <0 0  0 0x18000000  0x04000000   // PCIe CFG
+			  1 0  0 0x16000000  0x01000000>; // GBU chipselects
+
+		serial0: serial@30000 {
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0 0x30100 0xa00>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clock-frequency = <133333333>;
+			interrupt-parent = <&pic>;
+			interrupts = <17>;
+		};
+		serial1: serial@31000 {
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0 0x31100 0xa00>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clock-frequency = <133333333>;
+			interrupt-parent = <&pic>;
+			interrupts = <18>;
+		};
+		i2c0: ocores@32000 {
+			compatible = "opencores,i2c-ocores";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0 0x32100 0xa00>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clock-frequency = <32000000>;
+			interrupt-parent = <&pic>;
+			interrupts = <30>;
+		};
+		i2c1: ocores@33000 {
+			compatible = "opencores,i2c-ocores";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0 0x33100 0xa00>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clock-frequency = <32000000>;
+			interrupt-parent = <&pic>;
+			interrupts = <31>;
+
+			rtc@68 {
+				compatible = "dallas,ds1374";
+				reg = <0x68>;
+			};
+
+			dtt@4c {
+				compatible = "national,lm90";
+				reg = <0x4c>;
+			};
+		};
+		pic: pic@4000 {
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <1>;
+			reg = <0 0x4000 0x200>;
+		};
+
+		nor_flash@1,0 {
+			compatible = "cfi-flash";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			bank-width = <2>;
+			reg = <1 0 0x1000000>;
+
+			partition@0 {
+				label = "x-loader";
+				reg = <0x0 0x100000>; /* 1M */
+				read-only;
+			};
+
+			partition@100000 {
+				label = "u-boot";
+				reg = <0x100000 0x100000>; /* 1M */
+			};
+
+			partition@200000 {
+				label = "kernel";
+				reg = <0x200000 0x500000>; /* 5M */
+			};
+
+			partition@700000 {
+				label = "rootfs";
+				reg = <0x700000 0x800000>; /* 8M */
+			};
+
+			partition@f00000 {
+				label = "env";
+				reg = <0xf00000 0x100000>; /* 1M */
+				read-only;
+			};
+		};
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200 rdinit=/sbin/init";
+	};
+};
diff --git a/arch/mips/netlogic/xlp/Makefile b/arch/mips/netlogic/xlp/Makefile
index 6b4b972..a84d6ed 100644
--- a/arch/mips/netlogic/xlp/Makefile
+++ b/arch/mips/netlogic/xlp/Makefile
@@ -1,4 +1,3 @@
-obj-y				+= setup.o platform.o nlm_hal.o
-obj-$(CONFIG_OF)		+= of.o
+obj-y				+= setup.o nlm_hal.o
 obj-$(CONFIG_SMP)		+= wakeup.o
 obj-$(CONFIG_USB)		+= usb-init.o
diff --git a/arch/mips/netlogic/xlp/of.c b/arch/mips/netlogic/xlp/of.c
deleted file mode 100644
index 8e3921c..0000000
--- a/arch/mips/netlogic/xlp/of.c
+++ /dev/null
@@ -1,34 +0,0 @@
-#include <linux/bootmem.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/of_fdt.h>
-#include <asm/byteorder.h>
-
-static int __init reserve_mem_mach(unsigned long addr, unsigned long size)
-{
-	return reserve_bootmem(addr, size, BOOTMEM_DEFAULT);
-}
-
-void __init free_mem_mach(unsigned long addr, unsigned long size)
-{
-	return free_bootmem(addr, size);
-}
-
-void __init device_tree_init(void)
-{
-	unsigned long base, size;
-
-	if (!initial_boot_params)
-		return;
-
-	base = virt_to_phys((void *)initial_boot_params);
-	size = be32_to_cpu(initial_boot_params->totalsize);
-
-	/* Before we do anything, lets reserve the dt blob */
-	reserve_mem_mach(base, size);
-
-	unflatten_device_tree();
-
-	/* free the space reserved for the dt blob */
-	free_mem_mach(base, size);
-}
diff --git a/arch/mips/netlogic/xlp/platform.c b/arch/mips/netlogic/xlp/platform.c
deleted file mode 100644
index 2c510d5..0000000
--- a/arch/mips/netlogic/xlp/platform.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
- * reserved.
- *
- * This software is available to you under a choice of one of two
- * licenses.  You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the NetLogic
- * license below:
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <linux/dma-mapping.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/serial.h>
-#include <linux/serial_8250.h>
-#include <linux/pci.h>
-#include <linux/serial_reg.h>
-#include <linux/spinlock.h>
-
-#include <asm/time.h>
-#include <asm/addrspace.h>
-#include <asm/netlogic/haldefs.h>
-#include <asm/netlogic/xlp-hal/iomap.h>
-#include <asm/netlogic/xlp-hal/xlp.h>
-#include <asm/netlogic/xlp-hal/pic.h>
-#include <asm/netlogic/xlp-hal/uart.h>
-
-static unsigned int nlm_xlp_uart_in(struct uart_port *p, int offset)
-{
-	return nlm_read_reg(p->iobase, offset);
-}
-
-static void nlm_xlp_uart_out(struct uart_port *p, int offset, int value)
-{
-	nlm_write_reg(p->iobase, offset, value);
-}
-
-#define PORT(_irq)					\
-	{						\
-		.irq		= _irq,			\
-		.regshift	= 2,			\
-		.iotype		= UPIO_MEM32,		\
-		.flags		= (UPF_SKIP_TEST|UPF_FIXED_TYPE|\
-					UPF_BOOT_AUTOCONF),	\
-		.uartclk	= XLP_IO_CLK,		\
-		.type		= PORT_16550A,		\
-		.serial_in	= nlm_xlp_uart_in,	\
-		.serial_out	= nlm_xlp_uart_out,	\
-	}
-
-static struct plat_serial8250_port xlp_uart_data[] = {
-	PORT(PIC_UART_0_IRQ),
-	PORT(PIC_UART_1_IRQ),
-	{},
-};
-
-static struct platform_device uart_device = {
-	.name		= "serial8250",
-	.id		= PLAT8250_DEV_PLATFORM,
-	.dev = {
-		.platform_data = xlp_uart_data,
-	},
-};
-
-static int __init nlm_platform_uart_init(void)
-{
-	unsigned long mmio;
-
-	mmio = (unsigned long)nlm_get_uart_regbase(0, 0);
-	xlp_uart_data[0].iobase = mmio;
-	xlp_uart_data[0].membase = (void __iomem *)mmio;
-	xlp_uart_data[0].mapbase = mmio;
-
-	mmio = (unsigned long)nlm_get_uart_regbase(0, 1);
-	xlp_uart_data[1].iobase = mmio;
-	xlp_uart_data[1].membase = (void __iomem *)mmio;
-	xlp_uart_data[1].mapbase = mmio;
-
-	return platform_device_register(&uart_device);
-}
-
-arch_initcall(nlm_platform_uart_init);
diff --git a/arch/mips/netlogic/xlp/setup.c b/arch/mips/netlogic/xlp/setup.c
index 3dec9f2..d899709 100644
--- a/arch/mips/netlogic/xlp/setup.c
+++ b/arch/mips/netlogic/xlp/setup.c
@@ -35,6 +35,7 @@
 #include <linux/kernel.h>
 #include <linux/serial_8250.h>
 #include <linux/pm.h>
+#include <linux/bootmem.h>
 
 #include <asm/reboot.h>
 #include <asm/time.h>
@@ -56,6 +57,7 @@
 /* default to uniprocessor */
 uint32_t nlm_coremask = 1, nlm_cpumask  = 1;
 int  nlm_threads_per_core = 1;
+extern u32 __dtb_start[];
 
 static void nlm_linux_exit(void)
 {
@@ -96,9 +98,18 @@
 {
 	void *fdtp;
 
-	fdtp = (void *)(long)fw_arg0;
 	xlp_mmu_init();
 	nlm_hal_init();
+
+	/*
+	 * If no FDT pointer is passed in, use the built-in FDT.
+	 * device_tree_init() does not handle CKSEG0 pointers in
+	 * 64-bit, so convert pointer.
+	 */
+	fdtp = (void *)(long)fw_arg0;
+	if (!fdtp)
+		fdtp = __dtb_start;
+	fdtp = phys_to_virt(__pa(fdtp));
 	early_init_devtree(fdtp);
 
 	nlm_common_ebase = read_c0_ebase() & (~((1 << 12) - 1));
@@ -112,6 +123,25 @@
 #endif
 }
 
+void __init device_tree_init(void)
+{
+	unsigned long base, size;
+
+	if (!initial_boot_params)
+		return;
+
+	base = virt_to_phys((void *)initial_boot_params);
+	size = be32_to_cpu(initial_boot_params->totalsize);
+
+	/* Before we do anything, lets reserve the dt blob */
+	reserve_bootmem(base, size, BOOTMEM_DEFAULT);
+
+	unflatten_device_tree();
+
+	/* free the space reserved for the dt blob */
+	free_bootmem(base, size);
+}
+
 static struct of_device_id __initdata xlp_ids[] = {
 	{ .compatible = "simple-bus", },
 	{},
diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig
index 5cfb086..ddbdc33 100644
--- a/arch/mn10300/Kconfig
+++ b/arch/mn10300/Kconfig
@@ -8,6 +8,7 @@
 	select HAVE_ARCH_KGDB
 	select HAVE_NMI_WATCHDOG if MN10300_WD_TIMER
 	select GENERIC_CLOCKEVENTS
+	select GENERIC_KERNEL_THREAD
 
 config AM33_2
 	def_bool n
diff --git a/arch/mn10300/include/asm/Kbuild b/arch/mn10300/include/asm/Kbuild
index c68e168..fccd81e 100644
--- a/arch/mn10300/include/asm/Kbuild
+++ b/arch/mn10300/include/asm/Kbuild
@@ -1 +1,4 @@
 include include/asm-generic/Kbuild.asm
+
+generic-y += clkdev.h
+generic-y += exec.h
diff --git a/arch/mn10300/include/asm/exec.h b/arch/mn10300/include/asm/exec.h
deleted file mode 100644
index c74e367..0000000
--- a/arch/mn10300/include/asm/exec.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* MN10300 process execution definitions
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#ifndef _ASM_EXEC_H
-#define _ASM_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _ASM_EXEC_H */
diff --git a/arch/mn10300/include/asm/frame.inc b/arch/mn10300/include/asm/frame.inc
index 2ee58e3..1c3eb4f 100644
--- a/arch/mn10300/include/asm/frame.inc
+++ b/arch/mn10300/include/asm/frame.inc
@@ -61,7 +61,7 @@
 ###############################################################################
 .macro RESTORE_ALL
 	# peel back the stack to the calling frame
-	# - this permits execve() to discard extra frames due to kernel syscalls
+	# - we need that when returning from interrupts to kernel mode
 	GET_THREAD_INFO a0
 	mov	(TI_frame,a0),fp
 	mov	fp,sp
diff --git a/arch/mn10300/include/asm/processor.h b/arch/mn10300/include/asm/processor.h
index 247928c..8b80b19 100644
--- a/arch/mn10300/include/asm/processor.h
+++ b/arch/mn10300/include/asm/processor.h
@@ -119,20 +119,13 @@
 
 /*
  * do necessary setup to start up a newly executed thread
- * - need to discard the frame stacked by the kernel thread invoking the execve
- *   syscall (see RESTORE_ALL macro)
  */
 static inline void start_thread(struct pt_regs *regs,
 				unsigned long new_pc, unsigned long new_sp)
 {
-	struct thread_info *ti = current_thread_info();
-	struct pt_regs *frame0;
-
-	frame0 = thread_info_to_uregs(ti);
-	frame0->epsw = EPSW_nSL | EPSW_IE | EPSW_IM;
-	frame0->pc = new_pc;
-	frame0->sp = new_sp;
-	ti->frame = frame0;
+	regs->epsw = EPSW_nSL | EPSW_IE | EPSW_IM;
+	regs->pc = new_pc;
+	regs->sp = new_sp;
 }
 
 
@@ -140,11 +133,6 @@
 extern void release_thread(struct task_struct *);
 
 /*
- * create a kernel thread without removing it from tasklists
- */
-extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
-/*
  * Return saved PC of a blocked thread.
  */
 extern unsigned long thread_saved_pc(struct task_struct *tsk);
diff --git a/arch/mn10300/include/asm/ptrace.h b/arch/mn10300/include/asm/ptrace.h
index 44251b9..08ac856 100644
--- a/arch/mn10300/include/asm/ptrace.h
+++ b/arch/mn10300/include/asm/ptrace.h
@@ -86,6 +86,7 @@
 #define user_mode(regs)			(((regs)->epsw & EPSW_nSL) == EPSW_nSL)
 #define instruction_pointer(regs)	((regs)->pc)
 #define user_stack_pointer(regs)	((regs)->sp)
+#define current_pt_regs()		current_frame()
 
 #define arch_has_single_step()	(1)
 
diff --git a/arch/mn10300/include/asm/thread_info.h b/arch/mn10300/include/asm/thread_info.h
index ac519bb..f90062b 100644
--- a/arch/mn10300/include/asm/thread_info.h
+++ b/arch/mn10300/include/asm/thread_info.h
@@ -160,12 +160,13 @@
 #define _TIF_SIGPENDING		+(1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	+(1 << TIF_NEED_RESCHED)
 #define _TIF_SINGLESTEP		+(1 << TIF_SINGLESTEP)
-#define _TIF_RESTORE_SIGMASK	+(1 << TIF_RESTORE_SIGMASK)
 #define _TIF_POLLING_NRFLAG	+(1 << TIF_POLLING_NRFLAG)
 
 #define _TIF_WORK_MASK		0x0000FFFE	/* work to do on interrupt/exception return */
 #define _TIF_ALLWORK_MASK	0x0000FFFF	/* work to do on any return to u-space */
 
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
+
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_THREAD_INFO_H */
diff --git a/arch/mn10300/include/asm/unistd.h b/arch/mn10300/include/asm/unistd.h
index 866eb14..044c770 100644
--- a/arch/mn10300/include/asm/unistd.h
+++ b/arch/mn10300/include/asm/unistd.h
@@ -382,6 +382,8 @@
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGACTION
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_SYS_EXECVE
+#define __ARCH_WANT_KERNEL_EXECVE
 
 /*
  * "Conditional" syscalls
diff --git a/arch/mn10300/kernel/Makefile b/arch/mn10300/kernel/Makefile
index d067491..561029f 100644
--- a/arch/mn10300/kernel/Makefile
+++ b/arch/mn10300/kernel/Makefile
@@ -7,8 +7,8 @@
 fpu-obj-$(CONFIG_FPU) := fpu.o fpu-low.o
 
 obj-y   := process.o signal.o entry.o traps.o irq.o \
-	   ptrace.o setup.o time.o sys_mn10300.o io.o kthread.o \
-	   switch_to.o mn10300_ksyms.o kernel_execve.o $(fpu-obj-y) \
+	   ptrace.o setup.o time.o sys_mn10300.o io.o \
+	   switch_to.o mn10300_ksyms.o $(fpu-obj-y) \
 	   csrc-mn10300.o cevt-mn10300.o
 
 obj-$(CONFIG_SMP) += smp.o smp-low.o
diff --git a/arch/mn10300/kernel/entry.S b/arch/mn10300/kernel/entry.S
index 8e11f9f..0c631d3 100644
--- a/arch/mn10300/kernel/entry.S
+++ b/arch/mn10300/kernel/entry.S
@@ -55,6 +55,20 @@
 	mov	d0,(REG_D0,fp)
 	jmp	syscall_exit
 
+ENTRY(ret_from_kernel_thread)
+	call	schedule_tail[],0
+	mov	(REG_D0,fp),d0
+	mov	(REG_A0,fp),a0
+	calls	(a0)
+	jmp	sys_exit
+
+ENTRY(ret_from_kernel_execve)
+	add	-12,d0	/* pt_regs -> frame */
+	mov	d0,sp
+	GET_THREAD_INFO a2
+	clr	d0
+	jmp	syscall_exit
+
 ###############################################################################
 #
 # system call handler
@@ -94,6 +108,10 @@
 ###############################################################################
 	ALIGN
 syscall_exit_work:
+	mov	(REG_EPSW,fp),d0
+	and	EPSW_nSL,d0
+	beq	resume_kernel		# returning to supervisor mode
+
 	btst	_TIF_SYSCALL_TRACE,d2
 	beq	work_pending
 	LOCAL_IRQ_ENABLE		# could let syscall_trace_exit() call
diff --git a/arch/mn10300/kernel/internal.h b/arch/mn10300/kernel/internal.h
index 2df4401..5617855 100644
--- a/arch/mn10300/kernel/internal.h
+++ b/arch/mn10300/kernel/internal.h
@@ -15,14 +15,10 @@
 struct clock_event_device;
 
 /*
- * kthread.S
- */
-extern int kernel_thread_helper(int);
-
-/*
  * entry.S
  */
 extern void ret_from_fork(struct task_struct *) __attribute__((noreturn));
+extern void ret_from_kernel_thread(struct task_struct *) __attribute__((noreturn));
 
 /*
  * smp-low.S
diff --git a/arch/mn10300/kernel/kernel_execve.S b/arch/mn10300/kernel/kernel_execve.S
deleted file mode 100644
index 86039f1..0000000
--- a/arch/mn10300/kernel/kernel_execve.S
+++ /dev/null
@@ -1,37 +0,0 @@
-/* MN10300 In-kernel program execution
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#include <linux/linkage.h>
-#include <asm/unistd.h>
-
-###############################################################################
-#
-# Do a system call from kernel instead of calling sys_execve so we end up with
-# proper pt_regs.
-#
-# int kernel_execve(const char *filename, char *const argv[],
-#		    char *const envp[])
-#
-# On entry: D0/D1/8(SP): arguments to function
-# On return: D0: syscall return.
-#
-###############################################################################
-	.globl		kernel_execve
-	.type		kernel_execve,@function
-kernel_execve:
-	mov		a3,a1
-	mov		d0,a0
-	mov		(12,sp),a3
-	mov		+__NR_execve,d0
-	syscall		0
-	mov		a1,a3
-	rets
-
-	.size		kernel_execve,.-kernel_execve
diff --git a/arch/mn10300/kernel/kthread.S b/arch/mn10300/kernel/kthread.S
deleted file mode 100644
index b5ae467..0000000
--- a/arch/mn10300/kernel/kthread.S
+++ /dev/null
@@ -1,31 +0,0 @@
-/* MN10300 Kernel thread trampoline function
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by Mark Salter (msalter@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-	.text
-
-###############################################################################
-#
-# kernel_thread_helper - trampoline for kernel_thread()
-#
-# On entry:
-#   A2 = address of function to call
-#   D2 = function argument
-#
-###############################################################################
-	.globl	kernel_thread_helper
-	.type	kernel_thread_helper,@function
-kernel_thread_helper:
-	mov	do_exit,d1
-	mov	d1,(sp)
-	mov	d1,mdr
-	mov	d2,d0
-	jmp	(a2)
-
-	.size	kernel_thread_helper,.-kernel_thread_helper
diff --git a/arch/mn10300/kernel/process.c b/arch/mn10300/kernel/process.c
index e9cceba..d0c671b 100644
--- a/arch/mn10300/kernel/process.c
+++ b/arch/mn10300/kernel/process.c
@@ -165,27 +165,6 @@
 }
 
 /*
- * create a kernel thread
- */
-int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
-{
-	struct pt_regs regs;
-
-	memset(&regs, 0, sizeof(regs));
-
-	regs.a2 = (unsigned long) fn;
-	regs.d2 = (unsigned long) arg;
-	regs.pc = (unsigned long) kernel_thread_helper;
-	local_save_flags(regs.epsw);
-	regs.epsw |= EPSW_IE | EPSW_IM_7;
-
-	/* Ok, create the new process.. */
-	return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0,
-		       NULL, NULL);
-}
-EXPORT_SYMBOL(kernel_thread);
-
-/*
  * free current thread data structures etc..
  */
 void exit_thread(void)
@@ -230,50 +209,42 @@
 		struct task_struct *p, struct pt_regs *kregs)
 {
 	struct thread_info *ti = task_thread_info(p);
-	struct pt_regs *c_uregs, *c_kregs, *uregs;
+	struct pt_regs *c_regs;
 	unsigned long c_ksp;
 
-	uregs = current->thread.uregs;
-
 	c_ksp = (unsigned long) task_stack_page(p) + THREAD_SIZE;
 
 	/* allocate the userspace exception frame and set it up */
 	c_ksp -= sizeof(struct pt_regs);
-	c_uregs = (struct pt_regs *) c_ksp;
-
-	p->thread.uregs = c_uregs;
-	*c_uregs = *uregs;
-	c_uregs->sp = c_usp;
-	c_uregs->epsw &= ~EPSW_FE; /* my FPU */
-
+	c_regs = (struct pt_regs *) c_ksp;
 	c_ksp -= 12; /* allocate function call ABI slack */
 
+	/* set up things up so the scheduler can start the new task */
+	p->thread.uregs = c_regs;
+	ti->frame	= c_regs;
+	p->thread.a3	= (unsigned long) c_regs;
+	p->thread.sp	= c_ksp;
+	p->thread.wchan	= p->thread.pc;
+	p->thread.usp	= c_usp;
+
+	if (unlikely(!kregs)) {
+		memset(c_regs, 0, sizeof(struct pt_regs));
+		c_regs->a0 = c_usp; /* function */
+		c_regs->d0 = ustk_size; /* argument */
+		local_save_flags(c_regs->epsw);
+		c_regs->epsw |= EPSW_IE | EPSW_IM_7;
+		p->thread.pc	= (unsigned long) ret_from_kernel_thread;
+		return 0;
+	}
+	*c_regs = *kregs;
+	c_regs->sp = c_usp;
+	c_regs->epsw &= ~EPSW_FE; /* my FPU */
+
 	/* the new TLS pointer is passed in as arg #5 to sys_clone() */
 	if (clone_flags & CLONE_SETTLS)
-		c_uregs->e2 = current_frame()->d3;
+		c_regs->e2 = current_frame()->d3;
 
-	/* set up the return kernel frame if called from kernel_thread() */
-	c_kregs = c_uregs;
-	if (kregs != uregs) {
-		c_ksp -= sizeof(struct pt_regs);
-		c_kregs = (struct pt_regs *) c_ksp;
-		*c_kregs = *kregs;
-		c_kregs->sp = c_usp;
-		c_kregs->next = c_uregs;
-#ifdef CONFIG_MN10300_CURRENT_IN_E2
-		c_kregs->e2 = (unsigned long) p; /* current */
-#endif
-
-		c_ksp -= 12; /* allocate function call ABI slack */
-	}
-
-	/* set up things up so the scheduler can start the new task */
-	ti->frame	= c_kregs;
-	p->thread.a3	= (unsigned long) c_kregs;
-	p->thread.sp	= c_ksp;
 	p->thread.pc	= (unsigned long) ret_from_fork;
-	p->thread.wchan	= (unsigned long) ret_from_fork;
-	p->thread.usp	= c_usp;
 
 	return 0;
 }
@@ -302,22 +273,6 @@
 		       current_frame(), 0, NULL, NULL);
 }
 
-asmlinkage long sys_execve(const char __user *name,
-			   const char __user *const __user *argv,
-			   const char __user *const __user *envp)
-{
-	char *filename;
-	int error;
-
-	filename = getname(name);
-	error = PTR_ERR(filename);
-	if (IS_ERR(filename))
-		return error;
-	error = do_execve(filename, argv, envp, current_frame());
-	putname(filename);
-	return error;
-}
-
 unsigned long get_wchan(struct task_struct *p)
 {
 	return p->thread.wchan;
diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c
index 4d584ae..f570b30 100644
--- a/arch/mn10300/kernel/signal.c
+++ b/arch/mn10300/kernel/signal.c
@@ -317,10 +317,6 @@
 	regs->d0 = sig;
 	regs->d1 = (unsigned long) &frame->sc;
 
-	/* the tracer may want to single-step inside the handler */
-	if (test_thread_flag(TIF_SINGLESTEP))
-		ptrace_notify(SIGTRAP);
-
 #if DEBUG_SIG
 	printk(KERN_DEBUG "SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
 	       sig, current->comm, current->pid, frame, regs->pc,
@@ -398,10 +394,6 @@
 	regs->d0 = sig;
 	regs->d1 = (long) &frame->info;
 
-	/* the tracer may want to single-step inside the handler */
-	if (test_thread_flag(TIF_SINGLESTEP))
-		ptrace_notify(SIGTRAP);
-
 #if DEBUG_SIG
 	printk(KERN_DEBUG "SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
 	       sig, current->comm, current->pid, frame, regs->pc,
@@ -475,11 +467,6 @@
 	siginfo_t info;
 	int signr;
 
-	/* we want the common case to go fast, which is why we may in certain
-	 * cases get here from kernel mode */
-	if (!user_mode(regs))
-		return;
-
 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
 	if (signr > 0) {
 		if (handle_signal(signr, &info, &ka, regs) == 0) {
diff --git a/arch/openrisc/include/asm/Kbuild b/arch/openrisc/include/asm/Kbuild
index 0922959..7140b6b 100644
--- a/arch/openrisc/include/asm/Kbuild
+++ b/arch/openrisc/include/asm/Kbuild
@@ -11,6 +11,7 @@
 generic-y += bugs.h
 generic-y += cacheflush.h
 generic-y += checksum.h
+generic-y += clkdev.h
 generic-y += cmpxchg.h
 generic-y += cmpxchg-local.h
 generic-y += cputime.h
diff --git a/arch/openrisc/include/asm/thread_info.h b/arch/openrisc/include/asm/thread_info.h
index 07a8bc0..07f3212 100644
--- a/arch/openrisc/include/asm/thread_info.h
+++ b/arch/openrisc/include/asm/thread_info.h
@@ -121,7 +121,6 @@
 #define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
 #define _TIF_SINGLESTEP		(1<<TIF_SINGLESTEP)
-#define _TIF_RESTORE_SIGMASK     (1<<TIF_RESTORE_SIGMASK)
 #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 
 
@@ -129,6 +128,8 @@
 /* For OpenRISC, this is anything in the LSW other than syscall trace */
 #define _TIF_WORK_MASK (0xff & ~(_TIF_SYSCALL_TRACE|_TIF_SINGLESTEP))
 
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
+
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_THREAD_INFO_H */
diff --git a/arch/openrisc/mm/fault.c b/arch/openrisc/mm/fault.c
index 40f850e..e2bfafc 100644
--- a/arch/openrisc/mm/fault.c
+++ b/arch/openrisc/mm/fault.c
@@ -183,6 +183,7 @@
 			tsk->min_flt++;
 		if (fault & VM_FAULT_RETRY) {
 			flags &= ~FAULT_FLAG_ALLOW_RETRY;
+			flags |= FAULT_FLAG_TRIED;
 
 			 /* No need to up_read(&mm->mmap_sem) as we would
 			 * have already released it in __lock_page_or_retry
diff --git a/arch/parisc/hpux/gate.S b/arch/parisc/hpux/gate.S
index 38a1c1b..0114688 100644
--- a/arch/parisc/hpux/gate.S
+++ b/arch/parisc/hpux/gate.S
@@ -71,7 +71,7 @@
 	STREG	%r26, TASK_PT_GR26(%r1)	 	/* 1st argument */
 	STREG	%r27, TASK_PT_GR27(%r1)		/* user dp */
 	STREG   %r28, TASK_PT_GR28(%r1)         /* return value 0 */
-	STREG   %r28, TASK_PT_ORIG_R28(%r1)     /* return value 0 (saved for signals) */
+	STREG   %r0, TASK_PT_ORIG_R28(%r1)     /* don't prohibit restarts */
 	STREG   %r29, TASK_PT_GR29(%r1)         /* 8th argument */
 	STREG	%r31, TASK_PT_GR31(%r1)		/* preserve syscall return ptr */
 	
diff --git a/arch/parisc/include/asm/Kbuild b/arch/parisc/include/asm/Kbuild
index 4383707..458371a 100644
--- a/arch/parisc/include/asm/Kbuild
+++ b/arch/parisc/include/asm/Kbuild
@@ -1,4 +1,6 @@
 include include/asm-generic/Kbuild.asm
 
 header-y += pdc.h
+generic-y += clkdev.h
 generic-y += word-at-a-time.h
+generic-y += exec.h
diff --git a/arch/parisc/include/asm/exec.h b/arch/parisc/include/asm/exec.h
deleted file mode 100644
index 6bb5af7..0000000
--- a/arch/parisc/include/asm/exec.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __PARISC_EXEC_H
-#define __PARISC_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* __PARISC_EXEC_H */
diff --git a/arch/parisc/include/asm/thread_info.h b/arch/parisc/include/asm/thread_info.h
index 22b4726..d1fb79a 100644
--- a/arch/parisc/include/asm/thread_info.h
+++ b/arch/parisc/include/asm/thread_info.h
@@ -68,13 +68,16 @@
 #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
 #define _TIF_POLLING_NRFLAG	(1 << TIF_POLLING_NRFLAG)
 #define _TIF_32BIT		(1 << TIF_32BIT)
-#define _TIF_RESTORE_SIGMASK	(1 << TIF_RESTORE_SIGMASK)
 #define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
 #define _TIF_SINGLESTEP		(1 << TIF_SINGLESTEP)
 #define _TIF_BLOCKSTEP		(1 << TIF_BLOCKSTEP)
 
 #define _TIF_USER_WORK_MASK     (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | \
                                  _TIF_NEED_RESCHED)
+#define _TIF_SYSCALL_TRACE_MASK (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP |	\
+				 _TIF_BLOCKSTEP)
+
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
 
 #endif /* __KERNEL__ */
 
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index 9d18189..48e16dc 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -276,7 +276,6 @@
 {
 	struct address_space *mapping = page_mapping(page);
 	struct vm_area_struct *mpnt;
-	struct prio_tree_iter iter;
 	unsigned long offset;
 	unsigned long addr, old_addr = 0;
 	pgoff_t pgoff;
@@ -299,7 +298,7 @@
 	 * to flush one address here for them all to become coherent */
 
 	flush_dcache_mmap_lock(mapping);
-	vma_prio_tree_foreach(mpnt, &iter, &mapping->i_mmap, pgoff, pgoff) {
+	vma_interval_tree_foreach(mpnt, &mapping->i_mmap, pgoff, pgoff) {
 		offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT;
 		addr = mpnt->vm_start + offset;
 
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index 594459b..5379969 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -113,6 +113,8 @@
 		(usp - sigframe_size);
 	DBG(2,"sys_rt_sigreturn: frame is %p\n", frame);
 
+	regs->orig_r28 = 1; /* no restarts for sigreturn */
+
 #ifdef CONFIG_64BIT
 	compat_frame = (struct compat_rt_sigframe __user *)frame;
 	
@@ -437,7 +439,7 @@
  * OK, we're invoking a handler.
  */	
 
-static long
+static void
 handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
 		struct pt_regs *regs, int in_syscall)
 {
@@ -447,7 +449,7 @@
 	
 	/* Set up the stack frame */
 	if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall))
-		return 0;
+		return;
 
 	signal_delivered(sig, info, ka, regs, 
 		test_thread_flag(TIF_SINGLESTEP) ||
@@ -455,13 +457,14 @@
 
 	DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n",
 		regs->gr[28]);
-
-	return 1;
 }
 
 static inline void
 syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
 {
+	if (regs->orig_r28)
+		return;
+	regs->orig_r28 = 1; /* no more restarts */
 	/* Check the return code */
 	switch (regs->gr[28]) {
 	case -ERESTART_RESTARTBLOCK:
@@ -482,8 +485,6 @@
 		 * we have to do is fiddle the return pointer.
 		 */
 		regs->gr[31] -= 8; /* delayed branching */
-		/* Preserve original r28. */
-		regs->gr[28] = regs->orig_r28;
 		break;
 	}
 }
@@ -491,6 +492,9 @@
 static inline void
 insert_restart_trampoline(struct pt_regs *regs)
 {
+	if (regs->orig_r28)
+		return;
+	regs->orig_r28 = 1; /* no more restarts */
 	switch(regs->gr[28]) {
 	case -ERESTART_RESTARTBLOCK: {
 		/* Restart the system call - no handlers present */
@@ -525,9 +529,6 @@
 		flush_user_icache_range(regs->gr[30], regs->gr[30] + 4);
 
 		regs->gr[31] = regs->gr[30] + 8;
-		/* Preserve original r28. */
-		regs->gr[28] = regs->orig_r28;
-
 		return;
 	}
 	case -ERESTARTNOHAND:
@@ -539,9 +540,6 @@
 		 * slot of the branch external instruction.
 		 */
 		regs->gr[31] -= 8;
-		/* Preserve original r28. */
-		regs->gr[28] = regs->orig_r28;
-
 		return;
 	}
 	default:
@@ -570,30 +568,17 @@
 	DBG(1,"\ndo_signal: regs=0x%p, sr7 %#lx, in_syscall=%d\n",
 	       regs, regs->sr[7], in_syscall);
 
-	/* Everyone else checks to see if they are in kernel mode at
-	   this point and exits if that's the case.  I'm not sure why
-	   we would be called in that case, but for some reason we
-	   are. */
-
-	/* May need to force signal if handle_signal failed to deliver */
-	while (1) {
-		signr = get_signal_to_deliver(&info, &ka, regs, NULL);
-		DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]); 
+	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+	DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]); 
 	
-		if (signr <= 0)
-		  break;
-		
+	if (signr > 0) {
 		/* Restart a system call if necessary. */
 		if (in_syscall)
 			syscall_restart(regs, &ka);
 
-		/* Whee!  Actually deliver the signal.  If the
-		   delivery failed, we need to continue to iterate in
-		   this loop so we can deliver the SIGSEGV... */
-		if (handle_signal(signr, &info, &ka, regs, in_syscall))
-			return;
+		handle_signal(signr, &info, &ka, regs, in_syscall);
+		return;
 	}
-	/* end of while(1) looping forever if we can't force a signal */
 
 	/* Did we come from a system call? */
 	if (in_syscall)
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
index 82a52b2..86742df 100644
--- a/arch/parisc/kernel/syscall.S
+++ b/arch/parisc/kernel/syscall.S
@@ -156,7 +156,7 @@
 	STREG	%r26, TASK_PT_GR26(%r1)	 	/* 1st argument */
 	STREG	%r27, TASK_PT_GR27(%r1)		/* user dp */
 	STREG   %r28, TASK_PT_GR28(%r1)         /* return value 0 */
-	STREG   %r28, TASK_PT_ORIG_R28(%r1)     /* return value 0 (saved for signals) */
+	STREG   %r0, TASK_PT_ORIG_R28(%r1)      /* don't prohibit restarts */
 	STREG	%r29, TASK_PT_GR29(%r1)		/* return value 1 */
 	STREG	%r31, TASK_PT_GR31(%r1)		/* preserve syscall return ptr */
 	
@@ -180,9 +180,10 @@
 
 	/* Are we being ptraced? */
 	mfctl	%cr30, %r1
-	LDREG	TI_TASK(%r1),%r1
-	ldw	TASK_PTRACE(%r1), %r1
-	bb,<,n	%r1,31,.Ltracesys
+	LDREG	TI_FLAGS(%r1),%r1
+	ldi	_TIF_SYSCALL_TRACE_MASK, %r19
+	and,COND(=) %r1, %r19, %r0
+	b,n	.Ltracesys
 	
 	/* Note!  We cannot use the syscall table that is mapped
 	nearby since the gateway page is mapped execute-only. */
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 4ce0be3..78d6588 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -99,6 +99,7 @@
 	select HAVE_DYNAMIC_FTRACE
 	select HAVE_FUNCTION_TRACER
 	select HAVE_FUNCTION_GRAPH_TRACER
+	select SYSCTL_EXCEPTION_TRACE
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select HAVE_IDE
 	select HAVE_IOREMAP_PROT
@@ -113,6 +114,7 @@
 	select HAVE_DMA_API_DEBUG
 	select USE_GENERIC_SMP_HELPERS if SMP
 	select HAVE_OPROFILE
+	select HAVE_DEBUG_KMEMLEAK
 	select HAVE_SYSCALL_WRAPPERS if PPC64
 	select GENERIC_ATOMIC64 if PPC32
 	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
@@ -139,6 +141,7 @@
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_STRNCPY_FROM_USER
 	select GENERIC_STRNLEN_USER
+	select GENERIC_KERNEL_THREAD
 
 config EARLY_PRINTK
 	bool
diff --git a/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig b/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig
index 126ef1b0..e4ad2e2 100644
--- a/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig
+++ b/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig
@@ -38,7 +38,6 @@
 CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_PHYSMAP_OF=y
 CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
 CONFIG_MTD_NAND_FSL_ELBC=y
 CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
diff --git a/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig b/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig
index abcf00a..34ff568 100644
--- a/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig
+++ b/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig
@@ -37,7 +37,6 @@
 CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_PHYSMAP_OF=y
 CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
 CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
diff --git a/arch/powerpc/configs/mpc83xx_defconfig b/arch/powerpc/configs/mpc83xx_defconfig
index 9352e44..09116c6 100644
--- a/arch/powerpc/configs/mpc83xx_defconfig
+++ b/arch/powerpc/configs/mpc83xx_defconfig
@@ -50,7 +50,6 @@
 CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_PHYSMAP_OF=y
 CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
 CONFIG_MTD_NAND_FSL_ELBC=y
 CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
diff --git a/arch/powerpc/include/asm/Kbuild b/arch/powerpc/include/asm/Kbuild
index 7e313f1..ace53db 100644
--- a/arch/powerpc/include/asm/Kbuild
+++ b/arch/powerpc/include/asm/Kbuild
@@ -35,4 +35,5 @@
 header-y += ucontext.h
 header-y += unistd.h
 
+generic-y += clkdev.h
 generic-y += rwsem.h
diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h
index da29032..e3b1d41 100644
--- a/arch/powerpc/include/asm/atomic.h
+++ b/arch/powerpc/include/asm/atomic.h
@@ -268,6 +268,7 @@
 
 	return t;
 }
+#define atomic_dec_if_positive atomic_dec_if_positive
 
 #define smp_mb__before_atomic_dec()     smp_mb()
 #define smp_mb__after_atomic_dec()      smp_mb()
diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
index dfdb95b..62e11a3 100644
--- a/arch/powerpc/include/asm/hugetlb.h
+++ b/arch/powerpc/include/asm/hugetlb.h
@@ -151,6 +151,10 @@
 {
 }
 
+static inline void arch_clear_hugepage_flags(struct page *page)
+{
+}
+
 #else /* ! CONFIG_HUGETLB_PAGE */
 static inline void flush_hugetlb_page(struct vm_area_struct *vma,
 				      unsigned long vmaddr)
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 9dc5cd1..8734b38 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -74,9 +74,6 @@
 void start_thread(struct pt_regs *regs, unsigned long fdptr, unsigned long sp);
 void release_thread(struct task_struct *);
 
-/* Create a new kernel thread. */
-extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
 /* Lazy FPU handling on uni-processor */
 extern struct task_struct *last_task_used_math;
 extern struct task_struct *last_task_used_altivec;
diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h
index 9c21ed4..f76b88c 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -125,6 +125,8 @@
 extern int ptrace_put_reg(struct task_struct *task, int regno,
 			  unsigned long data);
 
+#define current_pt_regs() \
+	((struct pt_regs *)((unsigned long)current_thread_info() + THREAD_SIZE) - 1)
 /*
  * We use the least-significant bit of the trap field to indicate
  * whether we have saved the full set of registers, or only a
diff --git a/arch/powerpc/include/asm/syscalls.h b/arch/powerpc/include/asm/syscalls.h
index 4084e56..329db4e 100644
--- a/arch/powerpc/include/asm/syscalls.h
+++ b/arch/powerpc/include/asm/syscalls.h
@@ -17,9 +17,6 @@
 asmlinkage unsigned long sys_mmap2(unsigned long addr, size_t len,
 		unsigned long prot, unsigned long flags,
 		unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_execve(unsigned long a0, unsigned long a1,
-		unsigned long a2, unsigned long a3, unsigned long a4,
-		unsigned long a5, struct pt_regs *regs);
 asmlinkage int sys_clone(unsigned long clone_flags, unsigned long usp,
 		int __user *parent_tidp, void __user *child_threadptr,
 		int __user *child_tidp, int p6, struct pt_regs *regs);
diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h
index 8ceea14..406b7b9 100644
--- a/arch/powerpc/include/asm/thread_info.h
+++ b/arch/powerpc/include/asm/thread_info.h
@@ -182,6 +182,8 @@
 #define is_32bit_task()	(1)
 #endif
 
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
+
 #endif	/* !__ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
index c683fa3..2533752 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -421,6 +421,8 @@
 #define __ARCH_WANT_SYS_NEWFSTATAT
 #define __ARCH_WANT_COMPAT_SYS_SENDFILE
 #endif
+#define __ARCH_WANT_SYS_EXECVE
+#define __ARCH_WANT_KERNEL_EXECVE
 
 /*
  * "Conditional" syscalls
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index af37528..9499385 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -435,6 +435,22 @@
 	li	r3,0
 	b	ret_from_syscall
 
+	.globl	ret_from_kernel_thread
+ret_from_kernel_thread:
+	REST_NVGPRS(r1)
+	bl	schedule_tail
+	mtlr	r14
+	mr	r3,r15
+	PPC440EP_ERR42
+	blrl
+	li	r3,0
+	b	do_exit		# no return
+
+	.globl	__ret_from_kernel_execve
+__ret_from_kernel_execve:
+	addi	r1,r3,-STACK_FRAME_OVERHEAD
+	b	ret_from_syscall
+
 /* Traced system call support */
 syscall_dotrace:
 	SAVE_NVGPRS(r1)
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 0e931aa..56e0ff0 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -370,6 +370,22 @@
 	li	r3,0
 	b	syscall_exit
 
+_GLOBAL(ret_from_kernel_thread)
+	bl	.schedule_tail
+	REST_NVGPRS(r1)
+	REST_GPR(2,r1)
+	mtlr	r14
+	mr	r3,r15
+	blrl
+	li	r3,0
+	b	.do_exit	# no return
+
+_GLOBAL(__ret_from_kernel_execve)
+	addi	r1,r3,-STACK_FRAME_OVERHEAD
+	li	r10,1
+	std	r10,SOFTE(r1)
+	b	syscall_exit
+
 	.section	".toc","aw"
 DSCR_DEFAULT:
 	.tc dscr_default[TC],dscr_default
diff --git a/arch/powerpc/kernel/misc.S b/arch/powerpc/kernel/misc.S
index ba16874..7ce26d4 100644
--- a/arch/powerpc/kernel/misc.S
+++ b/arch/powerpc/kernel/misc.S
@@ -54,13 +54,6 @@
 	.align	3
 2:	PPC_LONG 1b
 
-_GLOBAL(kernel_execve)
-	li	r0,__NR_execve
-	sc
-	bnslr
-	neg	r3,r3
-	blr
-
 _GLOBAL(setjmp)
 	mflr	r0
 	PPC_STL	r0,0(r3)
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 407e293..19e096b 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -663,39 +663,6 @@
 	sub	r3,r3,r4
 	blr
 
-/*
- * Create a kernel thread
- *   kernel_thread(fn, arg, flags)
- */
-_GLOBAL(kernel_thread)
-	stwu	r1,-16(r1)
-	stw	r30,8(r1)
-	stw	r31,12(r1)
-	mr	r30,r3		/* function */
-	mr	r31,r4		/* argument */
-	ori	r3,r5,CLONE_VM	/* flags */
-	oris	r3,r3,CLONE_UNTRACED>>16
-	li	r4,0		/* new sp (unused) */
-	li	r0,__NR_clone
-	sc
-	bns+	1f		/* did system call indicate error? */
-	neg	r3,r3		/* if so, make return code negative */
-1:	cmpwi	0,r3,0		/* parent or child? */
-	bne	2f		/* return if parent */
-	li	r0,0		/* make top-level stack frame */
-	stwu	r0,-16(r1)
-	mtlr	r30		/* fn addr in lr */
-	mr	r3,r31		/* load arg and call fn */
-	PPC440EP_ERR42
-	blrl
-	li	r0,__NR_exit	/* exit if function returns */
-	li	r3,0
-	sc
-2:	lwz	r30,8(r1)
-	lwz	r31,12(r1)
-	addi	r1,r1,16
-	blr
-
 #ifdef CONFIG_SMP
 _GLOBAL(start_secondary_resume)
 	/* Reset stack */
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
index 565b786..5cfa800 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -407,40 +407,6 @@
 
 
 /*
- * Create a kernel thread
- *   kernel_thread(fn, arg, flags)
- */
-_GLOBAL(kernel_thread)
-	std	r29,-24(r1)
-	std	r30,-16(r1)
-	stdu	r1,-STACK_FRAME_OVERHEAD(r1)
-	mr	r29,r3
-	mr	r30,r4
-	ori	r3,r5,CLONE_VM	/* flags */
-	oris	r3,r3,(CLONE_UNTRACED>>16)
-	li	r4,0		/* new sp (unused) */
-	li	r0,__NR_clone
-	sc
-	bns+	1f		/* did system call indicate error? */
-	neg	r3,r3		/* if so, make return code negative */
-1:	cmpdi	0,r3,0		/* parent or child? */
-	bne	2f		/* return if parent */
-	li	r0,0
-	stdu	r0,-STACK_FRAME_OVERHEAD(r1)
-	ld	r2,8(r29)
-	ld	r29,0(r29)
-	mtlr	r29              /* fn addr in lr */
-	mr	r3,r30	        /* load arg and call fn */
-	blrl
-	li	r0,__NR_exit	/* exit after child exits */
-        li	r3,0
-	sc
-2:	addi	r1,r1,STACK_FRAME_OVERHEAD
-	ld	r29,-24(r1)
-	ld	r30,-16(r1)
-	blr
-
-/*
  * disable_kernel_fp()
  * Disable the FPU.
  */
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index 3e40315..19e4288 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -94,7 +94,6 @@
 #endif /* CONFIG_PCI */
 
 EXPORT_SYMBOL(start_thread);
-EXPORT_SYMBOL(kernel_thread);
 
 EXPORT_SYMBOL(giveup_fpu);
 #ifdef CONFIG_ALTIVEC
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index d5ad666..ba48233 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -733,30 +733,39 @@
 extern unsigned long dscr_default; /* defined in arch/powerpc/kernel/sysfs.c */
 
 int copy_thread(unsigned long clone_flags, unsigned long usp,
-		unsigned long unused, struct task_struct *p,
+		unsigned long arg, struct task_struct *p,
 		struct pt_regs *regs)
 {
 	struct pt_regs *childregs, *kregs;
 	extern void ret_from_fork(void);
+	extern void ret_from_kernel_thread(void);
+	void (*f)(void);
 	unsigned long sp = (unsigned long)task_stack_page(p) + THREAD_SIZE;
 
-	CHECK_FULL_REGS(regs);
 	/* Copy registers */
 	sp -= sizeof(struct pt_regs);
 	childregs = (struct pt_regs *) sp;
-	*childregs = *regs;
-	if ((childregs->msr & MSR_PR) == 0) {
+	if (!regs) {
 		/* for kernel thread, set `current' and stackptr in new task */
+		memset(childregs, 0, sizeof(struct pt_regs));
 		childregs->gpr[1] = sp + sizeof(struct pt_regs);
-#ifdef CONFIG_PPC32
-		childregs->gpr[2] = (unsigned long) p;
-#else
+#ifdef CONFIG_PPC64
+		childregs->gpr[14] = *(unsigned long *)usp;
+		childregs->gpr[2] = ((unsigned long *)usp)[1],
 		clear_tsk_thread_flag(p, TIF_32BIT);
+#else
+		childregs->gpr[14] = usp;	/* function */
+		childregs->gpr[2] = (unsigned long) p;
 #endif
+		childregs->gpr[15] = arg;
 		p->thread.regs = NULL;	/* no user register state */
+		f = ret_from_kernel_thread;
 	} else {
+		CHECK_FULL_REGS(regs);
+		*childregs = *regs;
 		childregs->gpr[1] = usp;
 		p->thread.regs = childregs;
+		childregs->gpr[3] = 0;  /* Result from fork() */
 		if (clone_flags & CLONE_SETTLS) {
 #ifdef CONFIG_PPC64
 			if (!is_32bit_task())
@@ -765,8 +774,9 @@
 #endif
 				childregs->gpr[2] = childregs->gpr[6];
 		}
+
+		f = ret_from_fork;
 	}
-	childregs->gpr[3] = 0;  /* Result from fork() */
 	sp -= STACK_FRAME_OVERHEAD;
 
 	/*
@@ -805,19 +815,17 @@
 		p->thread.dscr = current->thread.dscr;
 	}
 #endif
-
 	/*
 	 * The PPC64 ABI makes use of a TOC to contain function 
 	 * pointers.  The function (ret_from_except) is actually a pointer
 	 * to the TOC entry.  The first entry is a pointer to the actual
 	 * function.
- 	 */
+	 */
 #ifdef CONFIG_PPC64
-	kregs->nip = *((unsigned long *)ret_from_fork);
+	kregs->nip = *((unsigned long *)f);
 #else
-	kregs->nip = (unsigned long)ret_from_fork;
+	kregs->nip = (unsigned long)f;
 #endif
-
 	return 0;
 }
 
@@ -1055,26 +1063,13 @@
 			regs, 0, NULL, NULL);
 }
 
-int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
-	       unsigned long a3, unsigned long a4, unsigned long a5,
-	       struct pt_regs *regs)
-{
-	int error;
-	char *filename;
+void __ret_from_kernel_execve(struct pt_regs *normal)
+__noreturn;
 
-	filename = getname((const char __user *) a0);
-	error = PTR_ERR(filename);
-	if (IS_ERR(filename))
-		goto out;
-	flush_fp_to_thread(current);
-	flush_altivec_to_thread(current);
-	flush_spe_to_thread(current);
-	error = do_execve(filename,
-			  (const char __user *const __user *) a1,
-			  (const char __user *const __user *) a2, regs);
-	putname(filename);
-out:
-	return error;
+void ret_from_kernel_execve(struct pt_regs *normal)
+{
+	set_thread_flag(TIF_RESTOREALL);
+	__ret_from_kernel_execve(normal);
 }
 
 static inline int valid_irq_stack(unsigned long sp, struct task_struct *p,
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 8b4c049..804e323 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -35,7 +35,6 @@
 #include <linux/stddef.h>
 #include <linux/tty.h>
 #include <linux/binfmts.h>
-#include <linux/freezer.h>
 #endif
 
 #include <asm/uaccess.h>
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c
index abd1112..9c2ed90 100644
--- a/arch/powerpc/kernel/sys_ppc32.c
+++ b/arch/powerpc/kernel/sys_ppc32.c
@@ -156,28 +156,6 @@
 			    (off_t __user *)offset, count);
 }
 
-long compat_sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
-		  unsigned long a3, unsigned long a4, unsigned long a5,
-		  struct pt_regs *regs)
-{
-	int error;
-	char * filename;
-	
-	filename = getname((char __user *) a0);
-	error = PTR_ERR(filename);
-	if (IS_ERR(filename))
-		goto out;
-	flush_fp_to_thread(current);
-	flush_altivec_to_thread(current);
-
-	error = compat_do_execve(filename, compat_ptr(a1), compat_ptr(a2), regs);
-
-	putname(filename);
-
-out:
-	return error;
-}
-
 /* Note: it is necessary to treat option as an unsigned int, 
  * with the corresponding cast to a signed int to insure that the 
  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 83e929e..721d460 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -1183,7 +1183,7 @@
 
 static int kvm_rma_mmap(struct file *file, struct vm_area_struct *vma)
 {
-	vma->vm_flags |= VM_RESERVED;
+	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 	vma->vm_ops = &kvm_rma_vm_ops;
 	return 0;
 }
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 5495ebe9..0a6b283 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -451,6 +451,7 @@
 			/* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
 			 * of starvation. */
 			flags &= ~FAULT_FLAG_ALLOW_RETRY;
+			flags |= FAULT_FLAG_TRIED;
 			goto retry;
 		}
 	}
diff --git a/arch/powerpc/oprofile/cell/spu_task_sync.c b/arch/powerpc/oprofile/cell/spu_task_sync.c
index 642fca1..28f1af2 100644
--- a/arch/powerpc/oprofile/cell/spu_task_sync.c
+++ b/arch/powerpc/oprofile/cell/spu_task_sync.c
@@ -304,7 +304,7 @@
 	return cookie;
 }
 
-/* Look up the dcookie for the task's first VM_EXECUTABLE mapping,
+/* Look up the dcookie for the task's mm->exe_file,
  * which corresponds loosely to "application name". Also, determine
  * the offset for the SPU ELF object.  If computed offset is
  * non-zero, it implies an embedded SPU object; otherwise, it's a
@@ -321,7 +321,6 @@
 {
 	unsigned long app_cookie = 0;
 	unsigned int my_offset = 0;
-	struct file *app = NULL;
 	struct vm_area_struct *vma;
 	struct mm_struct *mm = spu->mm;
 
@@ -330,16 +329,10 @@
 
 	down_read(&mm->mmap_sem);
 
-	for (vma = mm->mmap; vma; vma = vma->vm_next) {
-		if (!vma->vm_file)
-			continue;
-		if (!(vma->vm_flags & VM_EXECUTABLE))
-			continue;
-		app_cookie = fast_get_dcookie(&vma->vm_file->f_path);
+	if (mm->exe_file) {
+		app_cookie = fast_get_dcookie(&mm->exe_file->f_path);
 		pr_debug("got dcookie for %s\n",
-			 vma->vm_file->f_dentry->d_name.name);
-		app = vma->vm_file;
-		break;
+			 mm->exe_file->f_dentry->d_name.name);
 	}
 
 	for (vma = mm->mmap; vma; vma = vma->vm_next) {
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c
index 11d8e05..ecdb0a6 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -78,6 +78,8 @@
 	unsigned long start, start_pfn;
 	struct zone *zone;
 	int ret;
+	unsigned long section;
+	unsigned long sections_to_remove;
 
 	start_pfn = base >> PAGE_SHIFT;
 
@@ -97,9 +99,13 @@
 	 * to sysfs "state" file and we can't remove sysfs entries
 	 * while writing to it. So we have to defer it to here.
 	 */
-	ret = __remove_pages(zone, start_pfn, memblock_size >> PAGE_SHIFT);
-	if (ret)
-		return ret;
+	sections_to_remove = (memblock_size >> PAGE_SHIFT) / PAGES_PER_SECTION;
+	for (section = 0; section < sections_to_remove; section++) {
+		unsigned long pfn = start_pfn + section * PAGES_PER_SECTION;
+		ret = __remove_pages(zone, pfn, PAGES_PER_SECTION);
+		if (ret)
+			return ret;
+	}
 
 	/*
 	 * Update memory regions for memory remove
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index c8af429..99d2d79 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -68,6 +68,7 @@
 	select HAVE_FTRACE_MCOUNT_RECORD
 	select HAVE_C_RECORDMCOUNT
 	select HAVE_SYSCALL_TRACEPOINTS
+	select SYSCTL_EXCEPTION_TRACE
 	select HAVE_DYNAMIC_FTRACE
 	select HAVE_FUNCTION_GRAPH_TRACER
 	select HAVE_REGS_AND_STACK_ACCESS_API
@@ -80,6 +81,7 @@
 	select HAVE_IRQ_WORK
 	select HAVE_PERF_EVENTS
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
+	select HAVE_DEBUG_KMEMLEAK
 	select HAVE_KERNEL_GZIP
 	select HAVE_KERNEL_BZIP2
 	select HAVE_KERNEL_LZMA
@@ -126,12 +128,14 @@
 	select ARCH_INLINE_WRITE_UNLOCK_BH
 	select ARCH_INLINE_WRITE_UNLOCK_IRQ
 	select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE
+	select HAVE_UID16 if 32BIT
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_TIME_VSYSCALL
 	select GENERIC_CLOCKEVENTS
 	select KTIME_SCALAR if 32BIT
 	select HAVE_ARCH_SECCOMP_FILTER
+	select GENERIC_KERNEL_THREAD
 
 config SCHED_OMIT_FRAME_POINTER
 	def_bool y
diff --git a/arch/s390/Kconfig.debug b/arch/s390/Kconfig.debug
index d76cef3..fc32a2d 100644
--- a/arch/s390/Kconfig.debug
+++ b/arch/s390/Kconfig.debug
@@ -31,6 +31,18 @@
 
 	  If unsure, or if you run an older (pre 4.4) gcc, say N.
 
+config S390_PTDUMP
+	bool "Export kernel pagetable layout to userspace via debugfs"
+	depends on DEBUG_KERNEL
+	select DEBUG_FS
+	---help---
+	  Say Y here if you want to show the kernel pagetable layout in a
+	  debugfs file. This information is only useful for kernel developers
+	  who are working in architecture specific areas of the kernel.
+	  It is probably not a good idea to enable this feature in a production
+	  kernel.
+	  If in doubt, say "N"
+
 config DEBUG_SET_MODULE_RONX
 	def_bool y
 	depends on MODULES
diff --git a/arch/s390/include/asm/Kbuild b/arch/s390/include/asm/Kbuild
index 287d7bb..0633dc6 100644
--- a/arch/s390/include/asm/Kbuild
+++ b/arch/s390/include/asm/Kbuild
@@ -1,15 +1,3 @@
-include include/asm-generic/Kbuild.asm
 
-header-y += chpid.h
-header-y += chsc.h
-header-y += cmb.h
-header-y += dasd.h
-header-y += debug.h
-header-y += kvm_virtio.h
-header-y += monwriter.h
-header-y += qeth.h
-header-y += schid.h
-header-y += tape390.h
-header-y += ucontext.h
-header-y += vtoc.h
-header-y += zcrypt.h
+
+generic-y += clkdev.h
diff --git a/arch/s390/include/asm/chpid.h b/arch/s390/include/asm/chpid.h
index e5bde9f..38c405e 100644
--- a/arch/s390/include/asm/chpid.h
+++ b/arch/s390/include/asm/chpid.h
@@ -1,24 +1,11 @@
 /*
- *    Copyright IBM Corp. 2007
+ *    Copyright IBM Corp. 2007, 2012
  *    Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
  */
-
 #ifndef _ASM_S390_CHPID_H
 #define _ASM_S390_CHPID_H
 
-#include <linux/string.h>
-#include <linux/types.h>
-
-#define __MAX_CHPID 255
-
-struct chp_id {
-	u8 reserved1;
-	u8 cssid;
-	u8 reserved2;
-	u8 id;
-} __attribute__((packed));
-
-#ifdef __KERNEL__
+#include <uapi/asm/chpid.h>
 #include <asm/cio.h>
 
 static inline void chp_id_init(struct chp_id *chpid)
@@ -49,6 +36,4 @@
 
 #define chp_id_for_each(c) \
 	for (chp_id_init(c); chp_id_is_valid(c); chp_id_next(c))
-#endif /* __KERNEL */
-
 #endif /* _ASM_S390_CHPID_H */
diff --git a/arch/s390/include/asm/cmb.h b/arch/s390/include/asm/cmb.h
index 39ae032..806eac1 100644
--- a/arch/s390/include/asm/cmb.h
+++ b/arch/s390/include/asm/cmb.h
@@ -1,61 +1,12 @@
 #ifndef S390_CMB_H
 #define S390_CMB_H
 
-#include <linux/types.h>
+#include <uapi/asm/cmb.h>
 
-/**
- * struct cmbdata - channel measurement block data for user space
- * @size: size of the stored data
- * @elapsed_time: time since last sampling
- * @ssch_rsch_count: number of ssch and rsch
- * @sample_count: number of samples
- * @device_connect_time: time of device connect
- * @function_pending_time: time of function pending
- * @device_disconnect_time: time of device disconnect
- * @control_unit_queuing_time: time of control unit queuing
- * @device_active_only_time: time of device active only
- * @device_busy_time: time of device busy (ext. format)
- * @initial_command_response_time: initial command response time (ext. format)
- *
- * All values are stored as 64 bit for simplicity, especially
- * in 32 bit emulation mode. All time values are normalized to
- * nanoseconds.
- * Currently, two formats are known, which differ by the size of
- * this structure, i.e. the last two members are only set when
- * the extended channel measurement facility (first shipped in
- * z990 machines) is activated.
- * Potentially, more fields could be added, which would result in a
- * new ioctl number.
- */
-struct cmbdata {
-	__u64 size;
-	__u64 elapsed_time;
- /* basic and exended format: */
-	__u64 ssch_rsch_count;
-	__u64 sample_count;
-	__u64 device_connect_time;
-	__u64 function_pending_time;
-	__u64 device_disconnect_time;
-	__u64 control_unit_queuing_time;
-	__u64 device_active_only_time;
- /* extended format only: */
-	__u64 device_busy_time;
-	__u64 initial_command_response_time;
-};
-
-/* enable channel measurement */
-#define BIODASDCMFENABLE	_IO(DASD_IOCTL_LETTER, 32)
-/* enable channel measurement */
-#define BIODASDCMFDISABLE	_IO(DASD_IOCTL_LETTER, 33)
-/* read channel measurement data */
-#define BIODASDREADALLCMB	_IOWR(DASD_IOCTL_LETTER, 33, struct cmbdata)
-
-#ifdef __KERNEL__
 struct ccw_device;
 extern int enable_cmf(struct ccw_device *cdev);
 extern int disable_cmf(struct ccw_device *cdev);
 extern u64 cmf_read(struct ccw_device *cdev, int index);
 extern int cmf_readall(struct ccw_device *cdev, struct cmbdata *data);
 
-#endif /* __KERNEL__ */
 #endif /* S390_CMB_H */
diff --git a/arch/s390/include/asm/css_chars.h b/arch/s390/include/asm/css_chars.h
index a06ebc2..7e1c917 100644
--- a/arch/s390/include/asm/css_chars.h
+++ b/arch/s390/include/asm/css_chars.h
@@ -3,8 +3,6 @@
 
 #include <linux/types.h>
 
-#ifdef __KERNEL__
-
 struct css_general_char {
 	u64 : 12;
 	u32 dynio : 1;	 /* bit 12 */
@@ -35,5 +33,4 @@
 
 extern struct css_general_char css_general_characteristics;
 
-#endif /* __KERNEL__ */
 #endif
diff --git a/arch/s390/include/asm/debug.h b/arch/s390/include/asm/debug.h
index f39677e..188c505 100644
--- a/arch/s390/include/asm/debug.h
+++ b/arch/s390/include/asm/debug.h
@@ -3,39 +3,14 @@
  *
  *    Copyright IBM Corp. 1999, 2000
  */
-
 #ifndef DEBUG_H
 #define DEBUG_H
 
-#include <linux/fs.h>
-
-/* Note:
- * struct __debug_entry must be defined outside of #ifdef __KERNEL__ 
- * in order to allow a user program to analyze the 'raw'-view.
- */
-
-struct __debug_entry{
-        union {
-                struct {
-                        unsigned long long clock:52;
-                        unsigned long long exception:1;
-                        unsigned long long level:3;
-                        unsigned long long cpuid:8;
-                } fields;
-
-                unsigned long long stck;
-        } id;
-        void* caller;
-} __attribute__((packed));
-
-
-#define __DEBUG_FEATURE_VERSION      2  /* version of debug feature */
-
-#ifdef __KERNEL__
 #include <linux/string.h>
 #include <linux/spinlock.h>
 #include <linux/kernel.h>
 #include <linux/time.h>
+#include <uapi/asm/debug.h>
 
 #define DEBUG_MAX_LEVEL            6  /* debug levels range from 0 to 6 */
 #define DEBUG_OFF_LEVEL            -1 /* level where debug is switched off */
@@ -254,5 +229,4 @@
 #define PRINT_FATAL(x...) printk ( KERN_DEBUG PRINTK_HEADER x )
 #endif				/* DASD_DEBUG */
 
-#endif				/* __KERNEL__ */
 #endif				/* DEBUG_H */
diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/hugetlb.h
index 2d6e6e3..593753e 100644
--- a/arch/s390/include/asm/hugetlb.h
+++ b/arch/s390/include/asm/hugetlb.h
@@ -33,6 +33,7 @@
 }
 
 #define hugetlb_prefault_arch_hook(mm)		do { } while (0)
+#define arch_clear_hugepage_flags(page)		do { } while (0)
 
 int arch_prepare_hugepage(struct page *page);
 void arch_release_hugepage(struct page *page);
@@ -77,23 +78,6 @@
 		"	csp %1,%3"
 		: "=m" (*pmdp)
 		: "d" (reg2), "d" (reg3), "d" (reg4), "m" (*pmdp) : "cc");
-	pmd_val(*pmdp) = _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY;
-}
-
-static inline void __pmd_idte(unsigned long address, pmd_t *pmdp)
-{
-	unsigned long sto = (unsigned long) pmdp -
-				pmd_index(address) * sizeof(pmd_t);
-
-	if (!(pmd_val(*pmdp) & _SEGMENT_ENTRY_INV)) {
-		asm volatile(
-			"	.insn	rrf,0xb98e0000,%2,%3,0,0"
-			: "=m" (*pmdp)
-			: "m" (*pmdp), "a" (sto),
-			  "a" ((address & HPAGE_MASK))
-		);
-	}
-	pmd_val(*pmdp) = _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY;
 }
 
 static inline void huge_ptep_invalidate(struct mm_struct *mm,
@@ -105,6 +89,7 @@
 		__pmd_idte(address, pmdp);
 	else
 		__pmd_csp(pmdp);
+	pmd_val(*pmdp) = _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY;
 }
 
 static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
diff --git a/arch/s390/include/asm/kvm_para.h b/arch/s390/include/asm/kvm_para.h
index da44867..e0f8423 100644
--- a/arch/s390/include/asm/kvm_para.h
+++ b/arch/s390/include/asm/kvm_para.h
@@ -9,12 +9,6 @@
  *
  *    Author(s): Christian Borntraeger <borntraeger@de.ibm.com>
  */
-
-#ifndef __S390_KVM_PARA_H
-#define __S390_KVM_PARA_H
-
-#ifdef __KERNEL__
-
 /*
  * Hypercalls for KVM on s390. The calling convention is similar to the
  * s390 ABI, so we use R2-R6 for parameters 1-5. In addition we use R1
@@ -29,6 +23,12 @@
  *
  * This work is licensed under the terms of the GNU GPL, version 2.
  */
+#ifndef __S390_KVM_PARA_H
+#define __S390_KVM_PARA_H
+
+#include <uapi/asm/kvm_para.h>
+
+
 
 static inline long kvm_hypercall0(unsigned long nr)
 {
@@ -154,6 +154,4 @@
 	return false;
 }
 
-#endif
-
 #endif /* __S390_KVM_PARA_H */
diff --git a/arch/s390/include/asm/mman.h b/arch/s390/include/asm/mman.h
index abc1932..0e47a57 100644
--- a/arch/s390/include/asm/mman.h
+++ b/arch/s390/include/asm/mman.h
@@ -3,17 +3,13 @@
  *
  *  Derived from "include/asm-i386/mman.h"
  */
-
 #ifndef __S390_MMAN_H__
 #define __S390_MMAN_H__
 
-#include <asm-generic/mman.h>
+#include <uapi/asm/mman.h>
 
-#if defined(__KERNEL__)
 #if !defined(__ASSEMBLY__) && defined(CONFIG_64BIT)
 int s390_mmap_check(unsigned long addr, unsigned long len);
 #define arch_mmap_check(addr,len,flags)	s390_mmap_check(addr,len)
 #endif
-#endif
-
 #endif /* __S390_MMAN_H__ */
diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h
index 27ab3c7..6d53670 100644
--- a/arch/s390/include/asm/page.h
+++ b/arch/s390/include/asm/page.h
@@ -30,12 +30,20 @@
 #include <asm/setup.h>
 #ifndef __ASSEMBLY__
 
+static unsigned long pfmf(unsigned long function, unsigned long address)
+{
+	asm volatile(
+		"	.insn	rre,0xb9af0000,%[function],%[address]"
+		: [address] "+a" (address)
+		: [function] "d" (function)
+		: "memory");
+	return address;
+}
+
 static inline void clear_page(void *page)
 {
 	if (MACHINE_HAS_PFMF) {
-		asm volatile(
-			"	.insn	rre,0xb9af0000,%0,%1"
-			: : "d" (0x10000), "a" (page) : "memory", "cc");
+		pfmf(0x10000, (unsigned long)page);
 	} else {
 		register unsigned long reg1 asm ("1") = 0;
 		register void *reg2 asm ("2") = page;
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index 6bd7d74..dd647c9 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -42,6 +42,7 @@
  * tables contain all the necessary information.
  */
 #define update_mmu_cache(vma, address, ptep)     do { } while (0)
+#define update_mmu_cache_pmd(vma, address, ptep) do { } while (0)
 
 /*
  * ZERO_PAGE is a global shared page that is always zero; used
@@ -118,13 +119,12 @@
 
 #ifndef __ASSEMBLY__
 /*
- * The vmalloc area will always be on the topmost area of the kernel
- * mapping. We reserve 96MB (31bit) / 128GB (64bit) for vmalloc,
- * which should be enough for any sane case.
- * By putting vmalloc at the top, we maximise the gap between physical
- * memory and vmalloc to catch misplaced memory accesses. As a side
- * effect, this also makes sure that 64 bit module code cannot be used
- * as system call address.
+ * The vmalloc and module area will always be on the topmost area of the kernel
+ * mapping. We reserve 96MB (31bit) / 128GB (64bit) for vmalloc and modules.
+ * On 64 bit kernels we have a 2GB area at the top of the vmalloc area where
+ * modules will reside. That makes sure that inter module branches always
+ * happen without trampolines and in addition the placement within a 2GB frame
+ * is branch prediction unit friendly.
  */
 extern unsigned long VMALLOC_START;
 extern unsigned long VMALLOC_END;
@@ -132,6 +132,14 @@
 
 #define VMEM_MAX_PHYS ((unsigned long) vmemmap)
 
+#ifdef CONFIG_64BIT
+extern unsigned long MODULES_VADDR;
+extern unsigned long MODULES_END;
+#define MODULES_VADDR	MODULES_VADDR
+#define MODULES_END	MODULES_END
+#define MODULES_LEN	(1UL << 31)
+#endif
+
 /*
  * A 31 bit pagetable entry of S390 has following format:
  *  |   PFRA          |    |  OS  |
@@ -347,6 +355,12 @@
 
 #define _SEGMENT_ENTRY_LARGE	0x400	/* STE-format control, large page   */
 #define _SEGMENT_ENTRY_CO	0x100	/* change-recording override   */
+#define _SEGMENT_ENTRY_SPLIT_BIT 0	/* THP splitting bit number */
+#define _SEGMENT_ENTRY_SPLIT	(1UL << _SEGMENT_ENTRY_SPLIT_BIT)
+
+/* Set of bits not changed in pmd_modify */
+#define _SEGMENT_CHG_MASK	(_SEGMENT_ENTRY_ORIGIN | _SEGMENT_ENTRY_LARGE \
+				 | _SEGMENT_ENTRY_SPLIT | _SEGMENT_ENTRY_CO)
 
 /* Page status table bits for virtualization */
 #define RCP_ACC_BITS	0xf000000000000000UL
@@ -500,12 +514,45 @@
 	return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) != 0UL;
 }
 
+static inline int pmd_large(pmd_t pmd)
+{
+#ifdef CONFIG_64BIT
+	return !!(pmd_val(pmd) & _SEGMENT_ENTRY_LARGE);
+#else
+	return 0;
+#endif
+}
+
 static inline int pmd_bad(pmd_t pmd)
 {
 	unsigned long mask = ~_SEGMENT_ENTRY_ORIGIN & ~_SEGMENT_ENTRY_INV;
 	return (pmd_val(pmd) & mask) != _SEGMENT_ENTRY;
 }
 
+#define __HAVE_ARCH_PMDP_SPLITTING_FLUSH
+extern void pmdp_splitting_flush(struct vm_area_struct *vma,
+				 unsigned long addr, pmd_t *pmdp);
+
+#define  __HAVE_ARCH_PMDP_SET_ACCESS_FLAGS
+extern int pmdp_set_access_flags(struct vm_area_struct *vma,
+				 unsigned long address, pmd_t *pmdp,
+				 pmd_t entry, int dirty);
+
+#define __HAVE_ARCH_PMDP_CLEAR_YOUNG_FLUSH
+extern int pmdp_clear_flush_young(struct vm_area_struct *vma,
+				  unsigned long address, pmd_t *pmdp);
+
+#define __HAVE_ARCH_PMD_WRITE
+static inline int pmd_write(pmd_t pmd)
+{
+	return (pmd_val(pmd) & _SEGMENT_ENTRY_RO) == 0;
+}
+
+static inline int pmd_young(pmd_t pmd)
+{
+	return 0;
+}
+
 static inline int pte_none(pte_t pte)
 {
 	return (pte_val(pte) & _PAGE_INVALID) && !(pte_val(pte) & _PAGE_SWT);
@@ -1159,6 +1206,185 @@
 #define pte_offset_map(pmd, address) pte_offset_kernel(pmd, address)
 #define pte_unmap(pte) do { } while (0)
 
+static inline void __pmd_idte(unsigned long address, pmd_t *pmdp)
+{
+	unsigned long sto = (unsigned long) pmdp -
+			    pmd_index(address) * sizeof(pmd_t);
+
+	if (!(pmd_val(*pmdp) & _SEGMENT_ENTRY_INV)) {
+		asm volatile(
+			"	.insn	rrf,0xb98e0000,%2,%3,0,0"
+			: "=m" (*pmdp)
+			: "m" (*pmdp), "a" (sto),
+			  "a" ((address & HPAGE_MASK))
+			: "cc"
+		);
+	}
+}
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#define __HAVE_ARCH_PGTABLE_DEPOSIT
+extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable);
+
+#define __HAVE_ARCH_PGTABLE_WITHDRAW
+extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm);
+
+static inline int pmd_trans_splitting(pmd_t pmd)
+{
+	return pmd_val(pmd) & _SEGMENT_ENTRY_SPLIT;
+}
+
+static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
+			      pmd_t *pmdp, pmd_t entry)
+{
+	*pmdp = entry;
+}
+
+static inline unsigned long massage_pgprot_pmd(pgprot_t pgprot)
+{
+	unsigned long pgprot_pmd = 0;
+
+	if (pgprot_val(pgprot) & _PAGE_INVALID) {
+		if (pgprot_val(pgprot) & _PAGE_SWT)
+			pgprot_pmd |= _HPAGE_TYPE_NONE;
+		pgprot_pmd |= _SEGMENT_ENTRY_INV;
+	}
+	if (pgprot_val(pgprot) & _PAGE_RO)
+		pgprot_pmd |= _SEGMENT_ENTRY_RO;
+	return pgprot_pmd;
+}
+
+static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
+{
+	pmd_val(pmd) &= _SEGMENT_CHG_MASK;
+	pmd_val(pmd) |= massage_pgprot_pmd(newprot);
+	return pmd;
+}
+
+static inline pmd_t pmd_mkhuge(pmd_t pmd)
+{
+	pmd_val(pmd) |= _SEGMENT_ENTRY_LARGE;
+	return pmd;
+}
+
+static inline pmd_t pmd_mkwrite(pmd_t pmd)
+{
+	pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO;
+	return pmd;
+}
+
+static inline pmd_t pmd_wrprotect(pmd_t pmd)
+{
+	pmd_val(pmd) |= _SEGMENT_ENTRY_RO;
+	return pmd;
+}
+
+static inline pmd_t pmd_mkdirty(pmd_t pmd)
+{
+	/* No dirty bit in the segment table entry. */
+	return pmd;
+}
+
+static inline pmd_t pmd_mkold(pmd_t pmd)
+{
+	/* No referenced bit in the segment table entry. */
+	return pmd;
+}
+
+static inline pmd_t pmd_mkyoung(pmd_t pmd)
+{
+	/* No referenced bit in the segment table entry. */
+	return pmd;
+}
+
+#define __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG
+static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
+					    unsigned long address, pmd_t *pmdp)
+{
+	unsigned long pmd_addr = pmd_val(*pmdp) & HPAGE_MASK;
+	long tmp, rc;
+	int counter;
+
+	rc = 0;
+	if (MACHINE_HAS_RRBM) {
+		counter = PTRS_PER_PTE >> 6;
+		asm volatile(
+			"0:	.insn	rre,0xb9ae0000,%0,%3\n"	/* rrbm */
+			"	ogr	%1,%0\n"
+			"	la	%3,0(%4,%3)\n"
+			"	brct	%2,0b\n"
+			: "=&d" (tmp), "+&d" (rc), "+d" (counter),
+			  "+a" (pmd_addr)
+			: "a" (64 * 4096UL) : "cc");
+		rc = !!rc;
+	} else {
+		counter = PTRS_PER_PTE;
+		asm volatile(
+			"0:	rrbe	0,%2\n"
+			"	la	%2,0(%3,%2)\n"
+			"	brc	12,1f\n"
+			"	lhi	%0,1\n"
+			"1:	brct	%1,0b\n"
+			: "+d" (rc), "+d" (counter), "+a" (pmd_addr)
+			: "a" (4096UL) : "cc");
+	}
+	return rc;
+}
+
+#define __HAVE_ARCH_PMDP_GET_AND_CLEAR
+static inline pmd_t pmdp_get_and_clear(struct mm_struct *mm,
+				       unsigned long address, pmd_t *pmdp)
+{
+	pmd_t pmd = *pmdp;
+
+	__pmd_idte(address, pmdp);
+	pmd_clear(pmdp);
+	return pmd;
+}
+
+#define __HAVE_ARCH_PMDP_CLEAR_FLUSH
+static inline pmd_t pmdp_clear_flush(struct vm_area_struct *vma,
+				     unsigned long address, pmd_t *pmdp)
+{
+	return pmdp_get_and_clear(vma->vm_mm, address, pmdp);
+}
+
+#define __HAVE_ARCH_PMDP_INVALIDATE
+static inline void pmdp_invalidate(struct vm_area_struct *vma,
+				   unsigned long address, pmd_t *pmdp)
+{
+	__pmd_idte(address, pmdp);
+}
+
+static inline pmd_t mk_pmd_phys(unsigned long physpage, pgprot_t pgprot)
+{
+	pmd_t __pmd;
+	pmd_val(__pmd) = physpage + massage_pgprot_pmd(pgprot);
+	return __pmd;
+}
+
+#define pfn_pmd(pfn, pgprot)	mk_pmd_phys(__pa((pfn) << PAGE_SHIFT), (pgprot))
+#define mk_pmd(page, pgprot)	pfn_pmd(page_to_pfn(page), (pgprot))
+
+static inline int pmd_trans_huge(pmd_t pmd)
+{
+	return pmd_val(pmd) & _SEGMENT_ENTRY_LARGE;
+}
+
+static inline int has_transparent_hugepage(void)
+{
+	return MACHINE_HAS_HPAGE ? 1 : 0;
+}
+
+static inline unsigned long pmd_pfn(pmd_t pmd)
+{
+	if (pmd_trans_huge(pmd))
+		return pmd_val(pmd) >> HPAGE_SHIFT;
+	else
+		return pmd_val(pmd) >> PAGE_SHIFT;
+}
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+
 /*
  * 31 bit swap entry format:
  * A page-table entry has some bits we have to treat in a special way.
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
index 56831df..94e749c 100644
--- a/arch/s390/include/asm/processor.h
+++ b/arch/s390/include/asm/processor.h
@@ -35,6 +35,7 @@
 extern void s390_adjust_jiffies(void);
 extern const struct seq_operations cpuinfo_op;
 extern int sysctl_ieee_emulation_warnings;
+extern void execve_tail(void);
 
 /*
  * User space process size: 2GB for 31 bit, 4TB or 8PT for 64 bit.
@@ -126,6 +127,7 @@
 	regs->psw.mask	= psw_user_bits | PSW_MASK_EA | PSW_MASK_BA;	\
 	regs->psw.addr	= new_psw | PSW_ADDR_AMODE;			\
 	regs->gprs[15]	= new_stackp;					\
+	execve_tail();							\
 } while (0)
 
 #define start_thread31(regs, new_psw, new_stackp) do {			\
@@ -135,6 +137,7 @@
 	__tlb_flush_mm(current->mm);					\
 	crst_table_downgrade(current->mm, 1UL << 31);			\
 	update_mm(current->mm, current);				\
+	execve_tail();							\
 } while (0)
 
 /* Forward declaration, a strange C thing */
@@ -150,7 +153,6 @@
 
 /* Free all resources held by a thread. */
 extern void release_thread(struct task_struct *);
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
 /*
  * Return saved PC of a blocked thread.
diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h
index ce20a53..3ee5da3 100644
--- a/arch/s390/include/asm/ptrace.h
+++ b/arch/s390/include/asm/ptrace.h
@@ -3,316 +3,17 @@
  *    Copyright IBM Corp. 1999, 2000
  *    Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
  */
-
 #ifndef _S390_PTRACE_H
 #define _S390_PTRACE_H
 
-/*
- * Offsets in the user_regs_struct. They are used for the ptrace
- * system call and in entry.S
- */
-#ifndef __s390x__
-
-#define PT_PSWMASK  0x00
-#define PT_PSWADDR  0x04
-#define PT_GPR0     0x08
-#define PT_GPR1     0x0C
-#define PT_GPR2     0x10
-#define PT_GPR3     0x14
-#define PT_GPR4     0x18
-#define PT_GPR5     0x1C
-#define PT_GPR6     0x20
-#define PT_GPR7     0x24
-#define PT_GPR8     0x28
-#define PT_GPR9     0x2C
-#define PT_GPR10    0x30
-#define PT_GPR11    0x34
-#define PT_GPR12    0x38
-#define PT_GPR13    0x3C
-#define PT_GPR14    0x40
-#define PT_GPR15    0x44
-#define PT_ACR0     0x48
-#define PT_ACR1     0x4C
-#define PT_ACR2     0x50
-#define PT_ACR3     0x54
-#define PT_ACR4	    0x58
-#define PT_ACR5	    0x5C
-#define PT_ACR6	    0x60
-#define PT_ACR7	    0x64
-#define PT_ACR8	    0x68
-#define PT_ACR9	    0x6C
-#define PT_ACR10    0x70
-#define PT_ACR11    0x74
-#define PT_ACR12    0x78
-#define PT_ACR13    0x7C
-#define PT_ACR14    0x80
-#define PT_ACR15    0x84
-#define PT_ORIGGPR2 0x88
-#define PT_FPC	    0x90
-/*
- * A nasty fact of life that the ptrace api
- * only supports passing of longs.
- */
-#define PT_FPR0_HI  0x98
-#define PT_FPR0_LO  0x9C
-#define PT_FPR1_HI  0xA0
-#define PT_FPR1_LO  0xA4
-#define PT_FPR2_HI  0xA8
-#define PT_FPR2_LO  0xAC
-#define PT_FPR3_HI  0xB0
-#define PT_FPR3_LO  0xB4
-#define PT_FPR4_HI  0xB8
-#define PT_FPR4_LO  0xBC
-#define PT_FPR5_HI  0xC0
-#define PT_FPR5_LO  0xC4
-#define PT_FPR6_HI  0xC8
-#define PT_FPR6_LO  0xCC
-#define PT_FPR7_HI  0xD0
-#define PT_FPR7_LO  0xD4
-#define PT_FPR8_HI  0xD8
-#define PT_FPR8_LO  0XDC
-#define PT_FPR9_HI  0xE0
-#define PT_FPR9_LO  0xE4
-#define PT_FPR10_HI 0xE8
-#define PT_FPR10_LO 0xEC
-#define PT_FPR11_HI 0xF0
-#define PT_FPR11_LO 0xF4
-#define PT_FPR12_HI 0xF8
-#define PT_FPR12_LO 0xFC
-#define PT_FPR13_HI 0x100
-#define PT_FPR13_LO 0x104
-#define PT_FPR14_HI 0x108
-#define PT_FPR14_LO 0x10C
-#define PT_FPR15_HI 0x110
-#define PT_FPR15_LO 0x114
-#define PT_CR_9	    0x118
-#define PT_CR_10    0x11C
-#define PT_CR_11    0x120
-#define PT_IEEE_IP  0x13C
-#define PT_LASTOFF  PT_IEEE_IP
-#define PT_ENDREGS  0x140-1
-
-#define GPR_SIZE	4
-#define CR_SIZE		4
-
-#define STACK_FRAME_OVERHEAD	96	/* size of minimum stack frame */
-
-#else /* __s390x__ */
-
-#define PT_PSWMASK  0x00
-#define PT_PSWADDR  0x08
-#define PT_GPR0     0x10
-#define PT_GPR1     0x18
-#define PT_GPR2     0x20
-#define PT_GPR3     0x28
-#define PT_GPR4     0x30
-#define PT_GPR5     0x38
-#define PT_GPR6     0x40
-#define PT_GPR7     0x48
-#define PT_GPR8     0x50
-#define PT_GPR9     0x58
-#define PT_GPR10    0x60
-#define PT_GPR11    0x68
-#define PT_GPR12    0x70
-#define PT_GPR13    0x78
-#define PT_GPR14    0x80
-#define PT_GPR15    0x88
-#define PT_ACR0     0x90
-#define PT_ACR1     0x94
-#define PT_ACR2     0x98
-#define PT_ACR3     0x9C
-#define PT_ACR4	    0xA0
-#define PT_ACR5	    0xA4
-#define PT_ACR6	    0xA8
-#define PT_ACR7	    0xAC
-#define PT_ACR8	    0xB0
-#define PT_ACR9	    0xB4
-#define PT_ACR10    0xB8
-#define PT_ACR11    0xBC
-#define PT_ACR12    0xC0
-#define PT_ACR13    0xC4
-#define PT_ACR14    0xC8
-#define PT_ACR15    0xCC
-#define PT_ORIGGPR2 0xD0
-#define PT_FPC	    0xD8
-#define PT_FPR0     0xE0
-#define PT_FPR1     0xE8
-#define PT_FPR2     0xF0
-#define PT_FPR3     0xF8
-#define PT_FPR4     0x100
-#define PT_FPR5     0x108
-#define PT_FPR6     0x110
-#define PT_FPR7     0x118
-#define PT_FPR8     0x120
-#define PT_FPR9     0x128
-#define PT_FPR10    0x130
-#define PT_FPR11    0x138
-#define PT_FPR12    0x140
-#define PT_FPR13    0x148
-#define PT_FPR14    0x150
-#define PT_FPR15    0x158
-#define PT_CR_9     0x160
-#define PT_CR_10    0x168
-#define PT_CR_11    0x170
-#define PT_IEEE_IP  0x1A8
-#define PT_LASTOFF  PT_IEEE_IP
-#define PT_ENDREGS  0x1B0-1
-
-#define GPR_SIZE	8
-#define CR_SIZE		8
-
-#define STACK_FRAME_OVERHEAD    160      /* size of minimum stack frame */
-
-#endif /* __s390x__ */
-
-#define NUM_GPRS	16
-#define NUM_FPRS	16
-#define NUM_CRS		16
-#define NUM_ACRS	16
-
-#define NUM_CR_WORDS	3
-
-#define FPR_SIZE	8
-#define FPC_SIZE	4
-#define FPC_PAD_SIZE	4 /* gcc insists on aligning the fpregs */
-#define ACR_SIZE	4
-
-
-#define PTRACE_OLDSETOPTIONS         21
+#include <uapi/asm/ptrace.h>
 
 #ifndef __ASSEMBLY__
-#include <linux/stddef.h>
-#include <linux/types.h>
-
-typedef union
-{
-	float   f;
-	double  d;
-        __u64   ui;
-	struct
-	{
-		__u32 hi;
-		__u32 lo;
-	} fp;
-} freg_t;
-
-typedef struct
-{
-	__u32   fpc;
-	freg_t  fprs[NUM_FPRS];              
-} s390_fp_regs;
-
-#define FPC_EXCEPTION_MASK      0xF8000000
-#define FPC_FLAGS_MASK          0x00F80000
-#define FPC_DXC_MASK            0x0000FF00
-#define FPC_RM_MASK             0x00000003
-#define FPC_VALID_MASK          0xF8F8FF03
-
-/* this typedef defines how a Program Status Word looks like */
-typedef struct 
-{
-        unsigned long mask;
-        unsigned long addr;
-} __attribute__ ((aligned(8))) psw_t;
-
-typedef struct
-{
-	__u32	mask;
-	__u32	addr;
-} __attribute__ ((aligned(8))) psw_compat_t;
-
 #ifndef __s390x__
-
-#define PSW_MASK_PER		0x40000000UL
-#define PSW_MASK_DAT		0x04000000UL
-#define PSW_MASK_IO		0x02000000UL
-#define PSW_MASK_EXT		0x01000000UL
-#define PSW_MASK_KEY		0x00F00000UL
-#define PSW_MASK_BASE		0x00080000UL	/* always one */
-#define PSW_MASK_MCHECK		0x00040000UL
-#define PSW_MASK_WAIT		0x00020000UL
-#define PSW_MASK_PSTATE		0x00010000UL
-#define PSW_MASK_ASC		0x0000C000UL
-#define PSW_MASK_CC		0x00003000UL
-#define PSW_MASK_PM		0x00000F00UL
-#define PSW_MASK_RI		0x00000000UL
-#define PSW_MASK_EA		0x00000000UL
-#define PSW_MASK_BA		0x00000000UL
-
-#define PSW_MASK_USER		0x00003F00UL
-
-#define PSW_ADDR_AMODE		0x80000000UL
-#define PSW_ADDR_INSN		0x7FFFFFFFUL
-
-#define PSW_DEFAULT_KEY		(((unsigned long) PAGE_DEFAULT_ACC) << 20)
-
-#define PSW_ASC_PRIMARY		0x00000000UL
-#define PSW_ASC_ACCREG		0x00004000UL
-#define PSW_ASC_SECONDARY	0x00008000UL
-#define PSW_ASC_HOME		0x0000C000UL
-
 #else /* __s390x__ */
-
-#define PSW_MASK_PER		0x4000000000000000UL
-#define PSW_MASK_DAT		0x0400000000000000UL
-#define PSW_MASK_IO		0x0200000000000000UL
-#define PSW_MASK_EXT		0x0100000000000000UL
-#define PSW_MASK_BASE		0x0000000000000000UL
-#define PSW_MASK_KEY		0x00F0000000000000UL
-#define PSW_MASK_MCHECK		0x0004000000000000UL
-#define PSW_MASK_WAIT		0x0002000000000000UL
-#define PSW_MASK_PSTATE		0x0001000000000000UL
-#define PSW_MASK_ASC		0x0000C00000000000UL
-#define PSW_MASK_CC		0x0000300000000000UL
-#define PSW_MASK_PM		0x00000F0000000000UL
-#define PSW_MASK_RI		0x0000008000000000UL
-#define PSW_MASK_EA		0x0000000100000000UL
-#define PSW_MASK_BA		0x0000000080000000UL
-
-#define PSW_MASK_USER		0x00003F8180000000UL
-
-#define PSW_ADDR_AMODE		0x0000000000000000UL
-#define PSW_ADDR_INSN		0xFFFFFFFFFFFFFFFFUL
-
-#define PSW_DEFAULT_KEY		(((unsigned long) PAGE_DEFAULT_ACC) << 52)
-
-#define PSW_ASC_PRIMARY		0x0000000000000000UL
-#define PSW_ASC_ACCREG		0x0000400000000000UL
-#define PSW_ASC_SECONDARY	0x0000800000000000UL
-#define PSW_ASC_HOME		0x0000C00000000000UL
-
 #endif /* __s390x__ */
-
-#ifdef __KERNEL__
 extern long psw_kernel_bits;
 extern long psw_user_bits;
-#endif
-
-/*
- * The s390_regs structure is used to define the elf_gregset_t.
- */
-typedef struct
-{
-	psw_t psw;
-	unsigned long gprs[NUM_GPRS];
-	unsigned int  acrs[NUM_ACRS];
-	unsigned long orig_gpr2;
-} s390_regs;
-
-typedef struct
-{
-	psw_compat_t	psw;
-	__u32		gprs[NUM_GPRS];
-	__u32		acrs[NUM_ACRS];
-	__u32		orig_gpr2;
-} s390_compat_regs;
-
-typedef struct
-{
-	__u32		gprs_high[NUM_GPRS];
-} s390_compat_regs_high;
-
-#ifdef __KERNEL__
 
 /*
  * The pt_regs struct defines the way the registers are stored on
@@ -376,167 +77,8 @@
 #define PER_CONTROL_SUSPENSION		0x00400000UL
 #define PER_CONTROL_ALTERATION		0x00200000UL
 
-#endif
-
-/*
- * Now for the user space program event recording (trace) definitions.
- * The following structures are used only for the ptrace interface, don't
- * touch or even look at it if you don't want to modify the user-space
- * ptrace interface. In particular stay away from it for in-kernel PER.
- */
-typedef struct
-{
-	unsigned long cr[NUM_CR_WORDS];
-} per_cr_words;
-
-#define PER_EM_MASK 0xE8000000UL
-
-typedef	struct
-{
 #ifdef __s390x__
-	unsigned                       : 32;
 #endif /* __s390x__ */
-	unsigned em_branching          : 1;
-	unsigned em_instruction_fetch  : 1;
-	/*
-	 * Switching on storage alteration automatically fixes
-	 * the storage alteration event bit in the users std.
-	 */
-	unsigned em_storage_alteration : 1;
-	unsigned em_gpr_alt_unused     : 1;
-	unsigned em_store_real_address : 1;
-	unsigned                       : 3;
-	unsigned branch_addr_ctl       : 1;
-	unsigned                       : 1;
-	unsigned storage_alt_space_ctl : 1;
-	unsigned                       : 21;
-	unsigned long starting_addr;
-	unsigned long ending_addr;
-} per_cr_bits;
-
-typedef struct
-{
-	unsigned short perc_atmid;
-	unsigned long address;
-	unsigned char access_id;
-} per_lowcore_words;
-
-typedef struct
-{
-	unsigned perc_branching          : 1;
-	unsigned perc_instruction_fetch  : 1;
-	unsigned perc_storage_alteration : 1;
-	unsigned perc_gpr_alt_unused     : 1;
-	unsigned perc_store_real_address : 1;
-	unsigned                         : 3;
-	unsigned atmid_psw_bit_31        : 1;
-	unsigned atmid_validity_bit      : 1;
-	unsigned atmid_psw_bit_32        : 1;
-	unsigned atmid_psw_bit_5         : 1;
-	unsigned atmid_psw_bit_16        : 1;
-	unsigned atmid_psw_bit_17        : 1;
-	unsigned si                      : 2;
-	unsigned long address;
-	unsigned                         : 4;
-	unsigned access_id               : 4;
-} per_lowcore_bits;
-
-typedef struct
-{
-	union {
-		per_cr_words   words;
-		per_cr_bits    bits;
-	} control_regs;
-	/*
-	 * Use these flags instead of setting em_instruction_fetch
-	 * directly they are used so that single stepping can be
-	 * switched on & off while not affecting other tracing
-	 */
-	unsigned  single_step       : 1;
-	unsigned  instruction_fetch : 1;
-	unsigned                    : 30;
-	/*
-	 * These addresses are copied into cr10 & cr11 if single
-	 * stepping is switched off
-	 */
-	unsigned long starting_addr;
-	unsigned long ending_addr;
-	union {
-		per_lowcore_words words;
-		per_lowcore_bits  bits;
-	} lowcore; 
-} per_struct;
-
-typedef struct
-{
-	unsigned int  len;
-	unsigned long kernel_addr;
-	unsigned long process_addr;
-} ptrace_area;
-
-/*
- * S/390 specific non posix ptrace requests. I chose unusual values so
- * they are unlikely to clash with future ptrace definitions.
- */
-#define PTRACE_PEEKUSR_AREA           0x5000
-#define PTRACE_POKEUSR_AREA           0x5001
-#define PTRACE_PEEKTEXT_AREA	      0x5002
-#define PTRACE_PEEKDATA_AREA	      0x5003
-#define PTRACE_POKETEXT_AREA	      0x5004
-#define PTRACE_POKEDATA_AREA 	      0x5005
-#define PTRACE_GET_LAST_BREAK	      0x5006
-#define PTRACE_PEEK_SYSTEM_CALL       0x5007
-#define PTRACE_POKE_SYSTEM_CALL	      0x5008
-#define PTRACE_ENABLE_TE	      0x5009
-#define PTRACE_DISABLE_TE	      0x5010
-
-/*
- * PT_PROT definition is loosely based on hppa bsd definition in
- * gdb/hppab-nat.c
- */
-#define PTRACE_PROT                       21
-
-typedef enum
-{
-	ptprot_set_access_watchpoint,
-	ptprot_set_write_watchpoint,
-	ptprot_disable_watchpoint
-} ptprot_flags;
-
-typedef struct
-{
-	unsigned long lowaddr;
-	unsigned long hiaddr;
-	ptprot_flags prot;
-} ptprot_area;                     
-
-/* Sequence of bytes for breakpoint illegal instruction.  */
-#define S390_BREAKPOINT     {0x0,0x1}
-#define S390_BREAKPOINT_U16 ((__u16)0x0001)
-#define S390_SYSCALL_OPCODE ((__u16)0x0a00)
-#define S390_SYSCALL_SIZE   2
-
-/*
- * The user_regs_struct defines the way the user registers are
- * store on the stack for signal handling.
- */
-struct user_regs_struct
-{
-	psw_t psw;
-	unsigned long gprs[NUM_GPRS];
-	unsigned int  acrs[NUM_ACRS];
-	unsigned long orig_gpr2;
-	s390_fp_regs fp_regs;
-	/*
-	 * These per registers are in here so that gdb can modify them
-	 * itself as there is no "official" ptrace interface for hardware
-	 * watchpoints. This is the way intel does it.
-	 */
-	per_struct per_info;
-	unsigned long ieee_instruction_pointer;	/* obsolete, always 0 */
-};
-
-#ifdef __KERNEL__
 /*
  * These are defined as per linux/ptrace.h, which see.
  */
@@ -562,7 +104,5 @@
 	return regs->gprs[15] & PSW_ADDR_INSN;
 }
 
-#endif /* __KERNEL__ */
 #endif /* __ASSEMBLY__ */
-
 #endif /* _S390_PTRACE_H */
diff --git a/arch/s390/include/asm/schid.h b/arch/s390/include/asm/schid.h
index 3e4d401..40b47df 100644
--- a/arch/s390/include/asm/schid.h
+++ b/arch/s390/include/asm/schid.h
@@ -1,19 +1,8 @@
 #ifndef ASM_SCHID_H
 #define ASM_SCHID_H
 
-#include <linux/types.h>
-
-struct subchannel_id {
-	__u32 cssid : 8;
-	__u32 : 4;
-	__u32 m : 1;
-	__u32 ssid : 2;
-	__u32 one : 1;
-	__u32 sch_no : 16;
-} __attribute__ ((packed, aligned(4)));
-
-#ifdef __KERNEL__
 #include <linux/string.h>
+#include <uapi/asm/schid.h>
 
 /* Helper function for sane state of pre-allocated subchannel_id. */
 static inline void
@@ -29,6 +18,4 @@
 	return !memcmp(schid1, schid2, sizeof(struct subchannel_id));
 }
 
-#endif /* __KERNEL__ */
-
 #endif /* ASM_SCHID_H */
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h
index 87b47ca..f69f76b 100644
--- a/arch/s390/include/asm/setup.h
+++ b/arch/s390/include/asm/setup.h
@@ -2,15 +2,11 @@
  *  S390 version
  *    Copyright IBM Corp. 1999, 2010
  */
-
 #ifndef _ASM_S390_SETUP_H
 #define _ASM_S390_SETUP_H
 
-#define COMMAND_LINE_SIZE	4096
+#include <uapi/asm/setup.h>
 
-#define ARCH_COMMAND_LINE_SIZE	896
-
-#ifdef __KERNEL__
 
 #define PARMAREA		0x10400
 #define MEMORY_CHUNKS		256
@@ -75,18 +71,21 @@
 #define MACHINE_FLAG_DIAG9C	(1UL << 7)
 #define MACHINE_FLAG_MVCOS	(1UL << 8)
 #define MACHINE_FLAG_KVM	(1UL << 9)
-#define MACHINE_FLAG_HPAGE	(1UL << 10)
-#define MACHINE_FLAG_PFMF	(1UL << 11)
+#define MACHINE_FLAG_EDAT1	(1UL << 10)
+#define MACHINE_FLAG_EDAT2	(1UL << 11)
 #define MACHINE_FLAG_LPAR	(1UL << 12)
 #define MACHINE_FLAG_SPP	(1UL << 13)
 #define MACHINE_FLAG_TOPOLOGY	(1UL << 14)
 #define MACHINE_FLAG_TE		(1UL << 15)
+#define MACHINE_FLAG_RRBM	(1UL << 16)
 
 #define MACHINE_IS_VM		(S390_lowcore.machine_flags & MACHINE_FLAG_VM)
 #define MACHINE_IS_KVM		(S390_lowcore.machine_flags & MACHINE_FLAG_KVM)
 #define MACHINE_IS_LPAR		(S390_lowcore.machine_flags & MACHINE_FLAG_LPAR)
 
 #define MACHINE_HAS_DIAG9C	(S390_lowcore.machine_flags & MACHINE_FLAG_DIAG9C)
+#define MACHINE_HAS_PFMF	MACHINE_HAS_EDAT1
+#define MACHINE_HAS_HPAGE	MACHINE_HAS_EDAT1
 
 #ifndef CONFIG_64BIT
 #define MACHINE_HAS_IEEE	(S390_lowcore.machine_flags & MACHINE_FLAG_IEEE)
@@ -95,11 +94,12 @@
 #define MACHINE_HAS_DIAG44	(1)
 #define MACHINE_HAS_MVPG	(S390_lowcore.machine_flags & MACHINE_FLAG_MVPG)
 #define MACHINE_HAS_MVCOS	(0)
-#define MACHINE_HAS_HPAGE	(0)
-#define MACHINE_HAS_PFMF	(0)
+#define MACHINE_HAS_EDAT1	(0)
+#define MACHINE_HAS_EDAT2	(0)
 #define MACHINE_HAS_SPP		(0)
 #define MACHINE_HAS_TOPOLOGY	(0)
-#define MACHINE_HAS_TE		      (0)
+#define MACHINE_HAS_TE		(0)
+#define MACHINE_HAS_RRBM	(0)
 #else /* CONFIG_64BIT */
 #define MACHINE_HAS_IEEE	(1)
 #define MACHINE_HAS_CSP		(1)
@@ -107,11 +107,12 @@
 #define MACHINE_HAS_DIAG44	(S390_lowcore.machine_flags & MACHINE_FLAG_DIAG44)
 #define MACHINE_HAS_MVPG	(1)
 #define MACHINE_HAS_MVCOS	(S390_lowcore.machine_flags & MACHINE_FLAG_MVCOS)
-#define MACHINE_HAS_HPAGE	(S390_lowcore.machine_flags & MACHINE_FLAG_HPAGE)
-#define MACHINE_HAS_PFMF	(S390_lowcore.machine_flags & MACHINE_FLAG_PFMF)
+#define MACHINE_HAS_EDAT1	(S390_lowcore.machine_flags & MACHINE_FLAG_EDAT1)
+#define MACHINE_HAS_EDAT2	(S390_lowcore.machine_flags & MACHINE_FLAG_EDAT2)
 #define MACHINE_HAS_SPP		(S390_lowcore.machine_flags & MACHINE_FLAG_SPP)
 #define MACHINE_HAS_TOPOLOGY	(S390_lowcore.machine_flags & MACHINE_FLAG_TOPOLOGY)
 #define MACHINE_HAS_TE		(S390_lowcore.machine_flags & MACHINE_FLAG_TE)
+#define MACHINE_HAS_RRBM	(S390_lowcore.machine_flags & MACHINE_FLAG_RRBM)
 #endif /* CONFIG_64BIT */
 
 #define ZFCPDUMP_HSA_SIZE	(32UL<<20)
@@ -170,5 +171,4 @@
 #define COMMAND_LINE      0x10480
 
 #endif /* __ASSEMBLY__ */
-#endif /* __KERNEL__ */
 #endif /* _ASM_S390_SETUP_H */
diff --git a/arch/s390/include/asm/signal.h b/arch/s390/include/asm/signal.h
index 6d4d9d1..bffdbdd 100644
--- a/arch/s390/include/asm/signal.h
+++ b/arch/s390/include/asm/signal.h
@@ -3,18 +3,11 @@
  *
  *  Derived from "include/asm-i386/signal.h"
  */
-
 #ifndef _ASMS390_SIGNAL_H
 #define _ASMS390_SIGNAL_H
 
-#include <linux/types.h>
-#include <linux/time.h>
+#include <uapi/asm/signal.h>
 
-/* Avoid too many header ordering problems.  */
-struct siginfo;
-struct pt_regs;
-
-#ifdef __KERNEL__
 /* Most things should be clean enough to redefine this at will, if care
    is taken to make libc match.  */
 #include <asm/sigcontext.h>
@@ -28,94 +21,6 @@
         unsigned long sig[_NSIG_WORDS];
 } sigset_t;
 
-#else
-/* Here we must cater to libcs that poke about in kernel headers.  */
-
-#define NSIG            32
-typedef unsigned long sigset_t;
-
-#endif /* __KERNEL__ */
-
-#define SIGHUP           1
-#define SIGINT           2
-#define SIGQUIT          3
-#define SIGILL           4
-#define SIGTRAP          5
-#define SIGABRT          6
-#define SIGIOT           6
-#define SIGBUS           7
-#define SIGFPE           8
-#define SIGKILL          9
-#define SIGUSR1         10
-#define SIGSEGV         11
-#define SIGUSR2         12
-#define SIGPIPE         13
-#define SIGALRM         14
-#define SIGTERM         15
-#define SIGSTKFLT       16
-#define SIGCHLD         17
-#define SIGCONT         18
-#define SIGSTOP         19
-#define SIGTSTP         20
-#define SIGTTIN         21
-#define SIGTTOU         22
-#define SIGURG          23
-#define SIGXCPU         24
-#define SIGXFSZ         25
-#define SIGVTALRM       26
-#define SIGPROF         27
-#define SIGWINCH        28
-#define SIGIO           29
-#define SIGPOLL         SIGIO
-/*
-#define SIGLOST         29
-*/
-#define SIGPWR          30
-#define SIGSYS		31
-#define SIGUNUSED       31
-
-/* These should not be considered constants from userland.  */
-#define SIGRTMIN        32
-#define SIGRTMAX        _NSIG
-
-/*
- * SA_FLAGS values:
- *
- * SA_ONSTACK indicates that a registered stack_t will be used.
- * SA_RESTART flag to get restarting signals (which were the default long ago)
- * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
- * SA_RESETHAND clears the handler when the signal is delivered.
- * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
- * SA_NODEFER prevents the current signal from being masked in the handler.
- *
- * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
- * Unix names RESETHAND and NODEFER respectively.
- */
-#define SA_NOCLDSTOP    0x00000001
-#define SA_NOCLDWAIT    0x00000002
-#define SA_SIGINFO      0x00000004
-#define SA_ONSTACK      0x08000000
-#define SA_RESTART      0x10000000
-#define SA_NODEFER      0x40000000
-#define SA_RESETHAND    0x80000000
-
-#define SA_NOMASK       SA_NODEFER
-#define SA_ONESHOT      SA_RESETHAND
-
-#define SA_RESTORER     0x04000000
-
-/*
- * sigaltstack controls
- */
-#define SS_ONSTACK      1
-#define SS_DISABLE      2
-
-#define MINSIGSTKSZ     2048
-#define SIGSTKSZ        8192
-
-#include <asm-generic/signal-defs.h>
-
-#ifdef __KERNEL__
 struct old_sigaction {
         __sighandler_t sa_handler;
         old_sigset_t sa_mask;
@@ -136,35 +41,4 @@
 
 #define ptrace_signal_deliver(regs, cookie) do { } while (0)
 
-#else
-/* Here we must cater to libcs that poke about in kernel headers.  */
-
-struct sigaction {
-        union {
-          __sighandler_t _sa_handler;
-          void (*_sa_sigaction)(int, struct siginfo *, void *);
-        } _u;
-#ifndef __s390x__ /* lovely */
-        sigset_t sa_mask;
-        unsigned long sa_flags;
-        void (*sa_restorer)(void);
-#else  /* __s390x__ */
-        unsigned long sa_flags;
-        void (*sa_restorer)(void);
-	sigset_t sa_mask;
-#endif /* __s390x__ */
-};
-
-#define sa_handler      _u._sa_handler
-#define sa_sigaction    _u._sa_sigaction
-
-#endif /* __KERNEL__ */
-
-typedef struct sigaltstack {
-        void __user *ss_sp;
-        int ss_flags;
-        size_t ss_size;
-} stack_t;
-
-
 #endif
diff --git a/arch/s390/include/asm/termios.h b/arch/s390/include/asm/termios.h
index cb9fe27..db028d1 100644
--- a/arch/s390/include/asm/termios.h
+++ b/arch/s390/include/asm/termios.h
@@ -3,49 +3,11 @@
  *
  *  Derived from "include/asm-i386/termios.h"
  */
-
 #ifndef _S390_TERMIOS_H
 #define _S390_TERMIOS_H
 
-#include <asm/termbits.h>
-#include <asm/ioctls.h>
+#include <uapi/asm/termios.h>
 
-struct winsize {
-	unsigned short ws_row;
-	unsigned short ws_col;
-	unsigned short ws_xpixel;
-	unsigned short ws_ypixel;
-};
-
-#define NCC 8
-struct termio {
-	unsigned short c_iflag;		/* input mode flags */
-	unsigned short c_oflag;		/* output mode flags */
-	unsigned short c_cflag;		/* control mode flags */
-	unsigned short c_lflag;		/* local mode flags */
-	unsigned char c_line;		/* line discipline */
-	unsigned char c_cc[NCC];	/* control characters */
-};
-
-/* modem lines */
-#define TIOCM_LE	0x001
-#define TIOCM_DTR	0x002
-#define TIOCM_RTS	0x004
-#define TIOCM_ST	0x008
-#define TIOCM_SR	0x010
-#define TIOCM_CTS	0x020
-#define TIOCM_CAR	0x040
-#define TIOCM_RNG	0x080
-#define TIOCM_DSR	0x100
-#define TIOCM_CD	TIOCM_CAR
-#define TIOCM_RI	TIOCM_RNG
-#define TIOCM_OUT1	0x2000
-#define TIOCM_OUT2	0x4000
-#define TIOCM_LOOP	0x8000
-
-/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
-
-#ifdef __KERNEL__
 
 /*	intr=^C		quit=^\		erase=del	kill=^U
 	eof=^D		vtime=\0	vmin=\1		sxtc=\0
@@ -60,6 +22,4 @@
 
 #include <asm-generic/termios-base.h>
 
-#endif	/* __KERNEL__ */
-
 #endif	/* _S390_TERMIOS_H */
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h
index bb08e2a..9e2cfe0 100644
--- a/arch/s390/include/asm/thread_info.h
+++ b/arch/s390/include/asm/thread_info.h
@@ -91,8 +91,6 @@
 #define TIF_SYSCALL_AUDIT	9	/* syscall auditing active */
 #define TIF_SECCOMP		10	/* secure computing */
 #define TIF_SYSCALL_TRACEPOINT	11	/* syscall tracepoint instrumentation */
-#define TIF_POLLING_NRFLAG	16	/* true if poll_idle() is polling
-					   TIF_NEED_RESCHED */
 #define TIF_31BIT		17	/* 32bit process */
 #define TIF_MEMDIE		18	/* is terminating due to OOM killer */
 #define TIF_RESTORE_SIGMASK	19	/* restore signal mask in do_signal() */
@@ -100,7 +98,6 @@
 
 #define _TIF_SYSCALL		(1<<TIF_SYSCALL)
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
-#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
 #define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
 #define _TIF_PER_TRAP		(1<<TIF_PER_TRAP)
@@ -109,7 +106,6 @@
 #define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP		(1<<TIF_SECCOMP)
 #define _TIF_SYSCALL_TRACEPOINT	(1<<TIF_SYSCALL_TRACEPOINT)
-#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 #define _TIF_31BIT		(1<<TIF_31BIT)
 #define _TIF_SINGLE_STEP	(1<<TIF_SINGLE_STEP)
 
diff --git a/arch/s390/include/asm/tlb.h b/arch/s390/include/asm/tlb.h
index 06e5acb..b75d7d6 100644
--- a/arch/s390/include/asm/tlb.h
+++ b/arch/s390/include/asm/tlb.h
@@ -137,6 +137,7 @@
 #define tlb_start_vma(tlb, vma)			do { } while (0)
 #define tlb_end_vma(tlb, vma)			do { } while (0)
 #define tlb_remove_tlb_entry(tlb, ptep, addr)	do { } while (0)
+#define tlb_remove_pmd_tlb_entry(tlb, pmdp, addr)	do { } while (0)
 #define tlb_migrate_finish(mm)			do { } while (0)
 
 #endif /* _S390_TLB_H */
diff --git a/arch/s390/include/asm/types.h b/arch/s390/include/asm/types.h
index 6ba7c2c..dccef3c 100644
--- a/arch/s390/include/asm/types.h
+++ b/arch/s390/include/asm/types.h
@@ -3,26 +3,14 @@
  *
  *  Derived from "include/asm-i386/types.h"
  */
-
 #ifndef _S390_TYPES_H
 #define _S390_TYPES_H
 
-#include <asm-generic/int-ll64.h>
-
-#ifndef __ASSEMBLY__
-
-/* A address type so that arithmetic can be done on it & it can be upgraded to
-   64 bit when necessary 
-*/
-typedef unsigned long addr_t; 
-typedef __signed__ long saddr_t;
-
-#endif /* __ASSEMBLY__ */
+#include <uapi/asm/types.h>
 
 /*
  * These aren't exported outside the kernel to avoid name space clashes
  */
-#ifdef __KERNEL__
 
 #ifndef __ASSEMBLY__
 
@@ -37,5 +25,4 @@
 
 #endif /* ! CONFIG_64BIT   */
 #endif /* __ASSEMBLY__  */
-#endif /* __KERNEL__    */
 #endif /* _S390_TYPES_H */
diff --git a/arch/s390/include/asm/unistd.h b/arch/s390/include/asm/unistd.h
index 4e64b5c..bbbae41 100644
--- a/arch/s390/include/asm/unistd.h
+++ b/arch/s390/include/asm/unistd.h
@@ -3,375 +3,11 @@
  *
  *  Derived from "include/asm-i386/unistd.h"
  */
-
 #ifndef _ASM_S390_UNISTD_H_
 #define _ASM_S390_UNISTD_H_
 
-/*
- * This file contains the system call numbers.
- */
+#include <uapi/asm/unistd.h>
 
-#define __NR_exit                 1
-#define __NR_fork                 2
-#define __NR_read                 3
-#define __NR_write                4
-#define __NR_open                 5
-#define __NR_close                6
-#define __NR_restart_syscall	  7
-#define __NR_creat                8
-#define __NR_link                 9
-#define __NR_unlink              10
-#define __NR_execve              11
-#define __NR_chdir               12
-#define __NR_mknod               14
-#define __NR_chmod               15
-#define __NR_lseek               19
-#define __NR_getpid              20
-#define __NR_mount               21
-#define __NR_umount              22
-#define __NR_ptrace              26
-#define __NR_alarm               27
-#define __NR_pause               29
-#define __NR_utime               30
-#define __NR_access              33
-#define __NR_nice                34
-#define __NR_sync                36
-#define __NR_kill                37
-#define __NR_rename              38
-#define __NR_mkdir               39
-#define __NR_rmdir               40
-#define __NR_dup                 41
-#define __NR_pipe                42
-#define __NR_times               43
-#define __NR_brk                 45
-#define __NR_signal              48
-#define __NR_acct                51
-#define __NR_umount2             52
-#define __NR_ioctl               54
-#define __NR_fcntl               55
-#define __NR_setpgid             57
-#define __NR_umask               60
-#define __NR_chroot              61
-#define __NR_ustat               62
-#define __NR_dup2                63
-#define __NR_getppid             64
-#define __NR_getpgrp             65
-#define __NR_setsid              66
-#define __NR_sigaction           67
-#define __NR_sigsuspend          72
-#define __NR_sigpending          73
-#define __NR_sethostname         74
-#define __NR_setrlimit           75
-#define __NR_getrusage           77
-#define __NR_gettimeofday        78
-#define __NR_settimeofday        79
-#define __NR_symlink             83
-#define __NR_readlink            85
-#define __NR_uselib              86
-#define __NR_swapon              87
-#define __NR_reboot              88
-#define __NR_readdir             89
-#define __NR_mmap                90
-#define __NR_munmap              91
-#define __NR_truncate            92
-#define __NR_ftruncate           93
-#define __NR_fchmod              94
-#define __NR_getpriority         96
-#define __NR_setpriority         97
-#define __NR_statfs              99
-#define __NR_fstatfs            100
-#define __NR_socketcall         102
-#define __NR_syslog             103
-#define __NR_setitimer          104
-#define __NR_getitimer          105
-#define __NR_stat               106
-#define __NR_lstat              107
-#define __NR_fstat              108
-#define __NR_lookup_dcookie     110
-#define __NR_vhangup            111
-#define __NR_idle               112
-#define __NR_wait4              114
-#define __NR_swapoff            115
-#define __NR_sysinfo            116
-#define __NR_ipc                117
-#define __NR_fsync              118
-#define __NR_sigreturn          119
-#define __NR_clone              120
-#define __NR_setdomainname      121
-#define __NR_uname              122
-#define __NR_adjtimex           124
-#define __NR_mprotect           125
-#define __NR_sigprocmask        126
-#define __NR_create_module      127
-#define __NR_init_module        128
-#define __NR_delete_module      129
-#define __NR_get_kernel_syms    130
-#define __NR_quotactl           131
-#define __NR_getpgid            132
-#define __NR_fchdir             133
-#define __NR_bdflush            134
-#define __NR_sysfs              135
-#define __NR_personality        136
-#define __NR_afs_syscall        137 /* Syscall for Andrew File System */
-#define __NR_getdents           141
-#define __NR_flock              143
-#define __NR_msync              144
-#define __NR_readv              145
-#define __NR_writev             146
-#define __NR_getsid             147
-#define __NR_fdatasync          148
-#define __NR__sysctl            149
-#define __NR_mlock              150
-#define __NR_munlock            151
-#define __NR_mlockall           152
-#define __NR_munlockall         153
-#define __NR_sched_setparam             154
-#define __NR_sched_getparam             155
-#define __NR_sched_setscheduler         156
-#define __NR_sched_getscheduler         157
-#define __NR_sched_yield                158
-#define __NR_sched_get_priority_max     159
-#define __NR_sched_get_priority_min     160
-#define __NR_sched_rr_get_interval      161
-#define __NR_nanosleep          162
-#define __NR_mremap             163
-#define __NR_query_module       167
-#define __NR_poll               168
-#define __NR_nfsservctl         169
-#define __NR_prctl              172
-#define __NR_rt_sigreturn       173
-#define __NR_rt_sigaction       174
-#define __NR_rt_sigprocmask     175
-#define __NR_rt_sigpending      176
-#define __NR_rt_sigtimedwait    177
-#define __NR_rt_sigqueueinfo    178
-#define __NR_rt_sigsuspend      179
-#define __NR_pread64            180
-#define __NR_pwrite64           181
-#define __NR_getcwd             183
-#define __NR_capget             184
-#define __NR_capset             185
-#define __NR_sigaltstack        186
-#define __NR_sendfile           187
-#define __NR_getpmsg		188
-#define __NR_putpmsg		189
-#define __NR_vfork		190
-#define __NR_pivot_root         217
-#define __NR_mincore            218
-#define __NR_madvise            219
-#define __NR_getdents64		220
-#define __NR_readahead		222
-#define __NR_setxattr		224
-#define __NR_lsetxattr		225
-#define __NR_fsetxattr		226
-#define __NR_getxattr		227
-#define __NR_lgetxattr		228
-#define __NR_fgetxattr		229
-#define __NR_listxattr		230
-#define __NR_llistxattr		231
-#define __NR_flistxattr		232
-#define __NR_removexattr	233
-#define __NR_lremovexattr	234
-#define __NR_fremovexattr	235
-#define __NR_gettid		236
-#define __NR_tkill		237
-#define __NR_futex		238
-#define __NR_sched_setaffinity	239
-#define __NR_sched_getaffinity	240
-#define __NR_tgkill		241
-/* Number 242 is reserved for tux */
-#define __NR_io_setup		243
-#define __NR_io_destroy		244
-#define __NR_io_getevents	245
-#define __NR_io_submit		246
-#define __NR_io_cancel		247
-#define __NR_exit_group		248
-#define __NR_epoll_create	249
-#define __NR_epoll_ctl		250
-#define __NR_epoll_wait		251
-#define __NR_set_tid_address	252
-#define __NR_fadvise64		253
-#define __NR_timer_create	254
-#define __NR_timer_settime	(__NR_timer_create+1)
-#define __NR_timer_gettime	(__NR_timer_create+2)
-#define __NR_timer_getoverrun	(__NR_timer_create+3)
-#define __NR_timer_delete	(__NR_timer_create+4)
-#define __NR_clock_settime	(__NR_timer_create+5)
-#define __NR_clock_gettime	(__NR_timer_create+6)
-#define __NR_clock_getres	(__NR_timer_create+7)
-#define __NR_clock_nanosleep	(__NR_timer_create+8)
-/* Number 263 is reserved for vserver */
-#define __NR_statfs64		265
-#define __NR_fstatfs64		266
-#define __NR_remap_file_pages	267
-/* Number 268 is reserved for new sys_mbind */
-/* Number 269 is reserved for new sys_get_mempolicy */
-/* Number 270 is reserved for new sys_set_mempolicy */
-#define __NR_mq_open		271
-#define __NR_mq_unlink		272
-#define __NR_mq_timedsend	273
-#define __NR_mq_timedreceive	274
-#define __NR_mq_notify		275
-#define __NR_mq_getsetattr	276
-#define __NR_kexec_load		277
-#define __NR_add_key		278
-#define __NR_request_key	279
-#define __NR_keyctl		280
-#define __NR_waitid		281
-#define __NR_ioprio_set		282
-#define __NR_ioprio_get		283
-#define __NR_inotify_init	284
-#define __NR_inotify_add_watch	285
-#define __NR_inotify_rm_watch	286
-/* Number 287 is reserved for new sys_migrate_pages */
-#define __NR_openat		288
-#define __NR_mkdirat		289
-#define __NR_mknodat		290
-#define __NR_fchownat		291
-#define __NR_futimesat		292
-#define __NR_unlinkat		294
-#define __NR_renameat		295
-#define __NR_linkat		296
-#define __NR_symlinkat		297
-#define __NR_readlinkat		298
-#define __NR_fchmodat		299
-#define __NR_faccessat		300
-#define __NR_pselect6		301
-#define __NR_ppoll		302
-#define __NR_unshare		303
-#define __NR_set_robust_list	304
-#define __NR_get_robust_list	305
-#define __NR_splice		306
-#define __NR_sync_file_range	307
-#define __NR_tee		308
-#define __NR_vmsplice		309
-/* Number 310 is reserved for new sys_move_pages */
-#define __NR_getcpu		311
-#define __NR_epoll_pwait	312
-#define __NR_utimes		313
-#define __NR_fallocate		314
-#define __NR_utimensat		315
-#define __NR_signalfd		316
-#define __NR_timerfd		317
-#define __NR_eventfd		318
-#define __NR_timerfd_create	319
-#define __NR_timerfd_settime	320
-#define __NR_timerfd_gettime	321
-#define __NR_signalfd4		322
-#define __NR_eventfd2		323
-#define __NR_inotify_init1	324
-#define __NR_pipe2		325
-#define __NR_dup3		326
-#define __NR_epoll_create1	327
-#define	__NR_preadv		328
-#define	__NR_pwritev		329
-#define __NR_rt_tgsigqueueinfo	330
-#define __NR_perf_event_open	331
-#define __NR_fanotify_init	332
-#define __NR_fanotify_mark	333
-#define __NR_prlimit64		334
-#define __NR_name_to_handle_at	335
-#define __NR_open_by_handle_at	336
-#define __NR_clock_adjtime	337
-#define __NR_syncfs		338
-#define __NR_setns		339
-#define __NR_process_vm_readv	340
-#define __NR_process_vm_writev	341
-#define __NR_s390_runtime_instr 342
-#define __NR_kcmp		343
-#define NR_syscalls 344
-
-/* 
- * There are some system calls that are not present on 64 bit, some
- * have a different name although they do the same (e.g. __NR_chown32
- * is __NR_chown on 64 bit).
- */
-#ifndef __s390x__
-
-#define __NR_time		 13
-#define __NR_lchown		 16
-#define __NR_setuid		 23
-#define __NR_getuid		 24
-#define __NR_stime		 25
-#define __NR_setgid		 46
-#define __NR_getgid		 47
-#define __NR_geteuid		 49
-#define __NR_getegid		 50
-#define __NR_setreuid		 70
-#define __NR_setregid		 71
-#define __NR_getrlimit		 76
-#define __NR_getgroups		 80
-#define __NR_setgroups		 81
-#define __NR_fchown		 95
-#define __NR_ioperm		101
-#define __NR_setfsuid		138
-#define __NR_setfsgid		139
-#define __NR__llseek		140
-#define __NR__newselect 	142
-#define __NR_setresuid		164
-#define __NR_getresuid		165
-#define __NR_setresgid		170
-#define __NR_getresgid		171
-#define __NR_chown		182
-#define __NR_ugetrlimit		191	/* SuS compliant getrlimit */
-#define __NR_mmap2		192
-#define __NR_truncate64		193
-#define __NR_ftruncate64	194
-#define __NR_stat64		195
-#define __NR_lstat64		196
-#define __NR_fstat64		197
-#define __NR_lchown32		198
-#define __NR_getuid32		199
-#define __NR_getgid32		200
-#define __NR_geteuid32		201
-#define __NR_getegid32		202
-#define __NR_setreuid32		203
-#define __NR_setregid32		204
-#define __NR_getgroups32	205
-#define __NR_setgroups32	206
-#define __NR_fchown32		207
-#define __NR_setresuid32	208
-#define __NR_getresuid32	209
-#define __NR_setresgid32	210
-#define __NR_getresgid32	211
-#define __NR_chown32		212
-#define __NR_setuid32		213
-#define __NR_setgid32		214
-#define __NR_setfsuid32		215
-#define __NR_setfsgid32		216
-#define __NR_fcntl64		221
-#define __NR_sendfile64		223
-#define __NR_fadvise64_64	264
-#define __NR_fstatat64		293
-
-#else
-
-#define __NR_select		142
-#define __NR_getrlimit		191	/* SuS compliant getrlimit */
-#define __NR_lchown  		198
-#define __NR_getuid  		199
-#define __NR_getgid  		200
-#define __NR_geteuid  		201
-#define __NR_getegid  		202
-#define __NR_setreuid  		203
-#define __NR_setregid  		204
-#define __NR_getgroups  	205
-#define __NR_setgroups  	206
-#define __NR_fchown  		207
-#define __NR_setresuid  	208
-#define __NR_getresuid  	209
-#define __NR_setresgid  	210
-#define __NR_getresgid  	211
-#define __NR_chown  		212
-#define __NR_setuid  		213
-#define __NR_setgid  		214
-#define __NR_setfsuid  		215
-#define __NR_setfsgid  		216
-#define __NR_newfstatat		293
-
-#endif
-
-#ifdef __KERNEL__
 
 #ifndef CONFIG_64BIT
 #define __IGNORE_select
@@ -417,6 +53,8 @@
 #   define __ARCH_WANT_COMPAT_SYS_TIME
 #   define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
 # endif
+#define __ARCH_WANT_SYS_EXECVE
+#define __ARCH_WANT_KERNEL_EXECVE
 
 /*
  * "Conditional" syscalls
@@ -426,5 +64,4 @@
  */
 #define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
 
-#endif /* __KERNEL__ */
 #endif /* _ASM_S390_UNISTD_H_ */
diff --git a/arch/s390/include/uapi/asm/Kbuild b/arch/s390/include/uapi/asm/Kbuild
index baebb3d..7bf68ff 100644
--- a/arch/s390/include/uapi/asm/Kbuild
+++ b/arch/s390/include/uapi/asm/Kbuild
@@ -1,3 +1,48 @@
 # UAPI Header export list
 include include/uapi/asm-generic/Kbuild.asm
 
+header-y += auxvec.h
+header-y += bitsperlong.h
+header-y += byteorder.h
+header-y += chpid.h
+header-y += chsc.h
+header-y += cmb.h
+header-y += dasd.h
+header-y += debug.h
+header-y += errno.h
+header-y += fcntl.h
+header-y += ioctl.h
+header-y += ioctls.h
+header-y += ipcbuf.h
+header-y += kvm.h
+header-y += kvm_para.h
+header-y += kvm_virtio.h
+header-y += mman.h
+header-y += monwriter.h
+header-y += msgbuf.h
+header-y += param.h
+header-y += poll.h
+header-y += posix_types.h
+header-y += ptrace.h
+header-y += qeth.h
+header-y += resource.h
+header-y += schid.h
+header-y += sembuf.h
+header-y += setup.h
+header-y += shmbuf.h
+header-y += sigcontext.h
+header-y += siginfo.h
+header-y += signal.h
+header-y += socket.h
+header-y += sockios.h
+header-y += stat.h
+header-y += statfs.h
+header-y += swab.h
+header-y += tape390.h
+header-y += termbits.h
+header-y += termios.h
+header-y += types.h
+header-y += ucontext.h
+header-y += unistd.h
+header-y += vtoc.h
+header-y += zcrypt.h
diff --git a/arch/s390/include/asm/auxvec.h b/arch/s390/include/uapi/asm/auxvec.h
similarity index 100%
rename from arch/s390/include/asm/auxvec.h
rename to arch/s390/include/uapi/asm/auxvec.h
diff --git a/arch/s390/include/asm/bitsperlong.h b/arch/s390/include/uapi/asm/bitsperlong.h
similarity index 100%
rename from arch/s390/include/asm/bitsperlong.h
rename to arch/s390/include/uapi/asm/bitsperlong.h
diff --git a/arch/s390/include/asm/byteorder.h b/arch/s390/include/uapi/asm/byteorder.h
similarity index 100%
rename from arch/s390/include/asm/byteorder.h
rename to arch/s390/include/uapi/asm/byteorder.h
diff --git a/arch/s390/include/uapi/asm/chpid.h b/arch/s390/include/uapi/asm/chpid.h
new file mode 100644
index 0000000..581992d
--- /dev/null
+++ b/arch/s390/include/uapi/asm/chpid.h
@@ -0,0 +1,22 @@
+/*
+ *    Copyright IBM Corp. 2007
+ *    Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
+ */
+
+#ifndef _UAPI_ASM_S390_CHPID_H
+#define _UAPI_ASM_S390_CHPID_H
+
+#include <linux/string.h>
+#include <linux/types.h>
+
+#define __MAX_CHPID 255
+
+struct chp_id {
+	u8 reserved1;
+	u8 cssid;
+	u8 reserved2;
+	u8 id;
+} __attribute__((packed));
+
+
+#endif /* _UAPI_ASM_S390_CHPID_H */
diff --git a/arch/s390/include/asm/chsc.h b/arch/s390/include/uapi/asm/chsc.h
similarity index 91%
rename from arch/s390/include/asm/chsc.h
rename to arch/s390/include/uapi/asm/chsc.h
index aea451f..1c6a7f8 100644
--- a/arch/s390/include/asm/chsc.h
+++ b/arch/s390/include/uapi/asm/chsc.h
@@ -1,7 +1,7 @@
 /*
  * ioctl interface for /dev/chsc
  *
- * Copyright IBM Corp. 2008
+ * Copyright IBM Corp. 2008, 2012
  * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
  */
 
@@ -9,9 +9,12 @@
 #define _ASM_CHSC_H
 
 #include <linux/types.h>
+#include <linux/ioctl.h>
 #include <asm/chpid.h>
 #include <asm/schid.h>
 
+#define CHSC_SIZE 0x1000
+
 struct chsc_async_header {
 	__u16 length;
 	__u16 code;
@@ -23,15 +26,14 @@
 
 struct chsc_async_area {
 	struct chsc_async_header header;
-	__u8 data[PAGE_SIZE - 16 /* size of chsc_async_header */];
+	__u8 data[CHSC_SIZE - sizeof(struct chsc_async_header)];
 } __attribute__ ((packed));
 
-
 struct chsc_response_struct {
 	__u16 length;
 	__u16 code;
 	__u32 parms;
-	__u8 data[PAGE_SIZE - 8];
+	__u8 data[CHSC_SIZE - 2 * sizeof(__u16) - sizeof(__u32)];
 } __attribute__ ((packed));
 
 struct chsc_chp_cd {
diff --git a/arch/s390/include/uapi/asm/cmb.h b/arch/s390/include/uapi/asm/cmb.h
new file mode 100644
index 0000000..0c086d0
--- /dev/null
+++ b/arch/s390/include/uapi/asm/cmb.h
@@ -0,0 +1,53 @@
+#ifndef _UAPIS390_CMB_H
+#define _UAPIS390_CMB_H
+
+#include <linux/types.h>
+
+/**
+ * struct cmbdata - channel measurement block data for user space
+ * @size: size of the stored data
+ * @elapsed_time: time since last sampling
+ * @ssch_rsch_count: number of ssch and rsch
+ * @sample_count: number of samples
+ * @device_connect_time: time of device connect
+ * @function_pending_time: time of function pending
+ * @device_disconnect_time: time of device disconnect
+ * @control_unit_queuing_time: time of control unit queuing
+ * @device_active_only_time: time of device active only
+ * @device_busy_time: time of device busy (ext. format)
+ * @initial_command_response_time: initial command response time (ext. format)
+ *
+ * All values are stored as 64 bit for simplicity, especially
+ * in 32 bit emulation mode. All time values are normalized to
+ * nanoseconds.
+ * Currently, two formats are known, which differ by the size of
+ * this structure, i.e. the last two members are only set when
+ * the extended channel measurement facility (first shipped in
+ * z990 machines) is activated.
+ * Potentially, more fields could be added, which would result in a
+ * new ioctl number.
+ */
+struct cmbdata {
+	__u64 size;
+	__u64 elapsed_time;
+ /* basic and exended format: */
+	__u64 ssch_rsch_count;
+	__u64 sample_count;
+	__u64 device_connect_time;
+	__u64 function_pending_time;
+	__u64 device_disconnect_time;
+	__u64 control_unit_queuing_time;
+	__u64 device_active_only_time;
+ /* extended format only: */
+	__u64 device_busy_time;
+	__u64 initial_command_response_time;
+};
+
+/* enable channel measurement */
+#define BIODASDCMFENABLE	_IO(DASD_IOCTL_LETTER, 32)
+/* enable channel measurement */
+#define BIODASDCMFDISABLE	_IO(DASD_IOCTL_LETTER, 33)
+/* read channel measurement data */
+#define BIODASDREADALLCMB	_IOWR(DASD_IOCTL_LETTER, 33, struct cmbdata)
+
+#endif /* _UAPIS390_CMB_H */
diff --git a/arch/s390/include/asm/dasd.h b/arch/s390/include/uapi/asm/dasd.h
similarity index 100%
rename from arch/s390/include/asm/dasd.h
rename to arch/s390/include/uapi/asm/dasd.h
diff --git a/arch/s390/include/uapi/asm/debug.h b/arch/s390/include/uapi/asm/debug.h
new file mode 100644
index 0000000..c59fc79
--- /dev/null
+++ b/arch/s390/include/uapi/asm/debug.h
@@ -0,0 +1,34 @@
+/*
+ *   S/390 debug facility
+ *
+ *    Copyright IBM Corp. 1999, 2000
+ */
+
+#ifndef _UAPIDEBUG_H
+#define _UAPIDEBUG_H
+
+#include <linux/fs.h>
+
+/* Note:
+ * struct __debug_entry must be defined outside of #ifdef __KERNEL__ 
+ * in order to allow a user program to analyze the 'raw'-view.
+ */
+
+struct __debug_entry{
+        union {
+                struct {
+                        unsigned long long clock:52;
+                        unsigned long long exception:1;
+                        unsigned long long level:3;
+                        unsigned long long cpuid:8;
+                } fields;
+
+                unsigned long long stck;
+        } id;
+        void* caller;
+} __attribute__((packed));
+
+
+#define __DEBUG_FEATURE_VERSION      2  /* version of debug feature */
+
+#endif /* _UAPIDEBUG_H */
diff --git a/arch/s390/include/asm/errno.h b/arch/s390/include/uapi/asm/errno.h
similarity index 100%
rename from arch/s390/include/asm/errno.h
rename to arch/s390/include/uapi/asm/errno.h
diff --git a/arch/s390/include/asm/fcntl.h b/arch/s390/include/uapi/asm/fcntl.h
similarity index 100%
rename from arch/s390/include/asm/fcntl.h
rename to arch/s390/include/uapi/asm/fcntl.h
diff --git a/arch/s390/include/asm/ioctl.h b/arch/s390/include/uapi/asm/ioctl.h
similarity index 100%
rename from arch/s390/include/asm/ioctl.h
rename to arch/s390/include/uapi/asm/ioctl.h
diff --git a/arch/s390/include/asm/ioctls.h b/arch/s390/include/uapi/asm/ioctls.h
similarity index 100%
rename from arch/s390/include/asm/ioctls.h
rename to arch/s390/include/uapi/asm/ioctls.h
diff --git a/arch/s390/include/asm/ipcbuf.h b/arch/s390/include/uapi/asm/ipcbuf.h
similarity index 100%
rename from arch/s390/include/asm/ipcbuf.h
rename to arch/s390/include/uapi/asm/ipcbuf.h
diff --git a/arch/s390/include/asm/kvm.h b/arch/s390/include/uapi/asm/kvm.h
similarity index 100%
rename from arch/s390/include/asm/kvm.h
rename to arch/s390/include/uapi/asm/kvm.h
diff --git a/arch/s390/include/uapi/asm/kvm_para.h b/arch/s390/include/uapi/asm/kvm_para.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/arch/s390/include/uapi/asm/kvm_para.h
diff --git a/arch/s390/include/asm/kvm_virtio.h b/arch/s390/include/uapi/asm/kvm_virtio.h
similarity index 100%
rename from arch/s390/include/asm/kvm_virtio.h
rename to arch/s390/include/uapi/asm/kvm_virtio.h
diff --git a/arch/s390/include/uapi/asm/mman.h b/arch/s390/include/uapi/asm/mman.h
new file mode 100644
index 0000000..de23da1
--- /dev/null
+++ b/arch/s390/include/uapi/asm/mman.h
@@ -0,0 +1,6 @@
+/*
+ *  S390 version
+ *
+ *  Derived from "include/asm-i386/mman.h"
+ */
+#include <asm-generic/mman.h>
diff --git a/arch/s390/include/asm/monwriter.h b/arch/s390/include/uapi/asm/monwriter.h
similarity index 100%
rename from arch/s390/include/asm/monwriter.h
rename to arch/s390/include/uapi/asm/monwriter.h
diff --git a/arch/s390/include/asm/msgbuf.h b/arch/s390/include/uapi/asm/msgbuf.h
similarity index 100%
rename from arch/s390/include/asm/msgbuf.h
rename to arch/s390/include/uapi/asm/msgbuf.h
diff --git a/arch/s390/include/asm/param.h b/arch/s390/include/uapi/asm/param.h
similarity index 100%
rename from arch/s390/include/asm/param.h
rename to arch/s390/include/uapi/asm/param.h
diff --git a/arch/s390/include/asm/poll.h b/arch/s390/include/uapi/asm/poll.h
similarity index 100%
rename from arch/s390/include/asm/poll.h
rename to arch/s390/include/uapi/asm/poll.h
diff --git a/arch/s390/include/asm/posix_types.h b/arch/s390/include/uapi/asm/posix_types.h
similarity index 100%
rename from arch/s390/include/asm/posix_types.h
rename to arch/s390/include/uapi/asm/posix_types.h
diff --git a/arch/s390/include/uapi/asm/ptrace.h b/arch/s390/include/uapi/asm/ptrace.h
new file mode 100644
index 0000000..705588a
--- /dev/null
+++ b/arch/s390/include/uapi/asm/ptrace.h
@@ -0,0 +1,472 @@
+/*
+ *  S390 version
+ *    Copyright IBM Corp. 1999, 2000
+ *    Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
+ */
+
+#ifndef _UAPI_S390_PTRACE_H
+#define _UAPI_S390_PTRACE_H
+
+/*
+ * Offsets in the user_regs_struct. They are used for the ptrace
+ * system call and in entry.S
+ */
+#ifndef __s390x__
+
+#define PT_PSWMASK  0x00
+#define PT_PSWADDR  0x04
+#define PT_GPR0     0x08
+#define PT_GPR1     0x0C
+#define PT_GPR2     0x10
+#define PT_GPR3     0x14
+#define PT_GPR4     0x18
+#define PT_GPR5     0x1C
+#define PT_GPR6     0x20
+#define PT_GPR7     0x24
+#define PT_GPR8     0x28
+#define PT_GPR9     0x2C
+#define PT_GPR10    0x30
+#define PT_GPR11    0x34
+#define PT_GPR12    0x38
+#define PT_GPR13    0x3C
+#define PT_GPR14    0x40
+#define PT_GPR15    0x44
+#define PT_ACR0     0x48
+#define PT_ACR1     0x4C
+#define PT_ACR2     0x50
+#define PT_ACR3     0x54
+#define PT_ACR4	    0x58
+#define PT_ACR5	    0x5C
+#define PT_ACR6	    0x60
+#define PT_ACR7	    0x64
+#define PT_ACR8	    0x68
+#define PT_ACR9	    0x6C
+#define PT_ACR10    0x70
+#define PT_ACR11    0x74
+#define PT_ACR12    0x78
+#define PT_ACR13    0x7C
+#define PT_ACR14    0x80
+#define PT_ACR15    0x84
+#define PT_ORIGGPR2 0x88
+#define PT_FPC	    0x90
+/*
+ * A nasty fact of life that the ptrace api
+ * only supports passing of longs.
+ */
+#define PT_FPR0_HI  0x98
+#define PT_FPR0_LO  0x9C
+#define PT_FPR1_HI  0xA0
+#define PT_FPR1_LO  0xA4
+#define PT_FPR2_HI  0xA8
+#define PT_FPR2_LO  0xAC
+#define PT_FPR3_HI  0xB0
+#define PT_FPR3_LO  0xB4
+#define PT_FPR4_HI  0xB8
+#define PT_FPR4_LO  0xBC
+#define PT_FPR5_HI  0xC0
+#define PT_FPR5_LO  0xC4
+#define PT_FPR6_HI  0xC8
+#define PT_FPR6_LO  0xCC
+#define PT_FPR7_HI  0xD0
+#define PT_FPR7_LO  0xD4
+#define PT_FPR8_HI  0xD8
+#define PT_FPR8_LO  0XDC
+#define PT_FPR9_HI  0xE0
+#define PT_FPR9_LO  0xE4
+#define PT_FPR10_HI 0xE8
+#define PT_FPR10_LO 0xEC
+#define PT_FPR11_HI 0xF0
+#define PT_FPR11_LO 0xF4
+#define PT_FPR12_HI 0xF8
+#define PT_FPR12_LO 0xFC
+#define PT_FPR13_HI 0x100
+#define PT_FPR13_LO 0x104
+#define PT_FPR14_HI 0x108
+#define PT_FPR14_LO 0x10C
+#define PT_FPR15_HI 0x110
+#define PT_FPR15_LO 0x114
+#define PT_CR_9	    0x118
+#define PT_CR_10    0x11C
+#define PT_CR_11    0x120
+#define PT_IEEE_IP  0x13C
+#define PT_LASTOFF  PT_IEEE_IP
+#define PT_ENDREGS  0x140-1
+
+#define GPR_SIZE	4
+#define CR_SIZE		4
+
+#define STACK_FRAME_OVERHEAD	96	/* size of minimum stack frame */
+
+#else /* __s390x__ */
+
+#define PT_PSWMASK  0x00
+#define PT_PSWADDR  0x08
+#define PT_GPR0     0x10
+#define PT_GPR1     0x18
+#define PT_GPR2     0x20
+#define PT_GPR3     0x28
+#define PT_GPR4     0x30
+#define PT_GPR5     0x38
+#define PT_GPR6     0x40
+#define PT_GPR7     0x48
+#define PT_GPR8     0x50
+#define PT_GPR9     0x58
+#define PT_GPR10    0x60
+#define PT_GPR11    0x68
+#define PT_GPR12    0x70
+#define PT_GPR13    0x78
+#define PT_GPR14    0x80
+#define PT_GPR15    0x88
+#define PT_ACR0     0x90
+#define PT_ACR1     0x94
+#define PT_ACR2     0x98
+#define PT_ACR3     0x9C
+#define PT_ACR4	    0xA0
+#define PT_ACR5	    0xA4
+#define PT_ACR6	    0xA8
+#define PT_ACR7	    0xAC
+#define PT_ACR8	    0xB0
+#define PT_ACR9	    0xB4
+#define PT_ACR10    0xB8
+#define PT_ACR11    0xBC
+#define PT_ACR12    0xC0
+#define PT_ACR13    0xC4
+#define PT_ACR14    0xC8
+#define PT_ACR15    0xCC
+#define PT_ORIGGPR2 0xD0
+#define PT_FPC	    0xD8
+#define PT_FPR0     0xE0
+#define PT_FPR1     0xE8
+#define PT_FPR2     0xF0
+#define PT_FPR3     0xF8
+#define PT_FPR4     0x100
+#define PT_FPR5     0x108
+#define PT_FPR6     0x110
+#define PT_FPR7     0x118
+#define PT_FPR8     0x120
+#define PT_FPR9     0x128
+#define PT_FPR10    0x130
+#define PT_FPR11    0x138
+#define PT_FPR12    0x140
+#define PT_FPR13    0x148
+#define PT_FPR14    0x150
+#define PT_FPR15    0x158
+#define PT_CR_9     0x160
+#define PT_CR_10    0x168
+#define PT_CR_11    0x170
+#define PT_IEEE_IP  0x1A8
+#define PT_LASTOFF  PT_IEEE_IP
+#define PT_ENDREGS  0x1B0-1
+
+#define GPR_SIZE	8
+#define CR_SIZE		8
+
+#define STACK_FRAME_OVERHEAD    160      /* size of minimum stack frame */
+
+#endif /* __s390x__ */
+
+#define NUM_GPRS	16
+#define NUM_FPRS	16
+#define NUM_CRS		16
+#define NUM_ACRS	16
+
+#define NUM_CR_WORDS	3
+
+#define FPR_SIZE	8
+#define FPC_SIZE	4
+#define FPC_PAD_SIZE	4 /* gcc insists on aligning the fpregs */
+#define ACR_SIZE	4
+
+
+#define PTRACE_OLDSETOPTIONS         21
+
+#ifndef __ASSEMBLY__
+#include <linux/stddef.h>
+#include <linux/types.h>
+
+typedef union
+{
+	float   f;
+	double  d;
+        __u64   ui;
+	struct
+	{
+		__u32 hi;
+		__u32 lo;
+	} fp;
+} freg_t;
+
+typedef struct
+{
+	__u32   fpc;
+	freg_t  fprs[NUM_FPRS];              
+} s390_fp_regs;
+
+#define FPC_EXCEPTION_MASK      0xF8000000
+#define FPC_FLAGS_MASK          0x00F80000
+#define FPC_DXC_MASK            0x0000FF00
+#define FPC_RM_MASK             0x00000003
+#define FPC_VALID_MASK          0xF8F8FF03
+
+/* this typedef defines how a Program Status Word looks like */
+typedef struct 
+{
+        unsigned long mask;
+        unsigned long addr;
+} __attribute__ ((aligned(8))) psw_t;
+
+typedef struct
+{
+	__u32	mask;
+	__u32	addr;
+} __attribute__ ((aligned(8))) psw_compat_t;
+
+#ifndef __s390x__
+
+#define PSW_MASK_PER		0x40000000UL
+#define PSW_MASK_DAT		0x04000000UL
+#define PSW_MASK_IO		0x02000000UL
+#define PSW_MASK_EXT		0x01000000UL
+#define PSW_MASK_KEY		0x00F00000UL
+#define PSW_MASK_BASE		0x00080000UL	/* always one */
+#define PSW_MASK_MCHECK		0x00040000UL
+#define PSW_MASK_WAIT		0x00020000UL
+#define PSW_MASK_PSTATE		0x00010000UL
+#define PSW_MASK_ASC		0x0000C000UL
+#define PSW_MASK_CC		0x00003000UL
+#define PSW_MASK_PM		0x00000F00UL
+#define PSW_MASK_RI		0x00000000UL
+#define PSW_MASK_EA		0x00000000UL
+#define PSW_MASK_BA		0x00000000UL
+
+#define PSW_MASK_USER		0x00003F00UL
+
+#define PSW_ADDR_AMODE		0x80000000UL
+#define PSW_ADDR_INSN		0x7FFFFFFFUL
+
+#define PSW_DEFAULT_KEY		(((unsigned long) PAGE_DEFAULT_ACC) << 20)
+
+#define PSW_ASC_PRIMARY		0x00000000UL
+#define PSW_ASC_ACCREG		0x00004000UL
+#define PSW_ASC_SECONDARY	0x00008000UL
+#define PSW_ASC_HOME		0x0000C000UL
+
+#else /* __s390x__ */
+
+#define PSW_MASK_PER		0x4000000000000000UL
+#define PSW_MASK_DAT		0x0400000000000000UL
+#define PSW_MASK_IO		0x0200000000000000UL
+#define PSW_MASK_EXT		0x0100000000000000UL
+#define PSW_MASK_BASE		0x0000000000000000UL
+#define PSW_MASK_KEY		0x00F0000000000000UL
+#define PSW_MASK_MCHECK		0x0004000000000000UL
+#define PSW_MASK_WAIT		0x0002000000000000UL
+#define PSW_MASK_PSTATE		0x0001000000000000UL
+#define PSW_MASK_ASC		0x0000C00000000000UL
+#define PSW_MASK_CC		0x0000300000000000UL
+#define PSW_MASK_PM		0x00000F0000000000UL
+#define PSW_MASK_RI		0x0000008000000000UL
+#define PSW_MASK_EA		0x0000000100000000UL
+#define PSW_MASK_BA		0x0000000080000000UL
+
+#define PSW_MASK_USER		0x00003F8180000000UL
+
+#define PSW_ADDR_AMODE		0x0000000000000000UL
+#define PSW_ADDR_INSN		0xFFFFFFFFFFFFFFFFUL
+
+#define PSW_DEFAULT_KEY		(((unsigned long) PAGE_DEFAULT_ACC) << 52)
+
+#define PSW_ASC_PRIMARY		0x0000000000000000UL
+#define PSW_ASC_ACCREG		0x0000400000000000UL
+#define PSW_ASC_SECONDARY	0x0000800000000000UL
+#define PSW_ASC_HOME		0x0000C00000000000UL
+
+#endif /* __s390x__ */
+
+
+/*
+ * The s390_regs structure is used to define the elf_gregset_t.
+ */
+typedef struct
+{
+	psw_t psw;
+	unsigned long gprs[NUM_GPRS];
+	unsigned int  acrs[NUM_ACRS];
+	unsigned long orig_gpr2;
+} s390_regs;
+
+typedef struct
+{
+	psw_compat_t	psw;
+	__u32		gprs[NUM_GPRS];
+	__u32		acrs[NUM_ACRS];
+	__u32		orig_gpr2;
+} s390_compat_regs;
+
+typedef struct
+{
+	__u32		gprs_high[NUM_GPRS];
+} s390_compat_regs_high;
+
+
+/*
+ * Now for the user space program event recording (trace) definitions.
+ * The following structures are used only for the ptrace interface, don't
+ * touch or even look at it if you don't want to modify the user-space
+ * ptrace interface. In particular stay away from it for in-kernel PER.
+ */
+typedef struct
+{
+	unsigned long cr[NUM_CR_WORDS];
+} per_cr_words;
+
+#define PER_EM_MASK 0xE8000000UL
+
+typedef	struct
+{
+#ifdef __s390x__
+	unsigned                       : 32;
+#endif /* __s390x__ */
+	unsigned em_branching          : 1;
+	unsigned em_instruction_fetch  : 1;
+	/*
+	 * Switching on storage alteration automatically fixes
+	 * the storage alteration event bit in the users std.
+	 */
+	unsigned em_storage_alteration : 1;
+	unsigned em_gpr_alt_unused     : 1;
+	unsigned em_store_real_address : 1;
+	unsigned                       : 3;
+	unsigned branch_addr_ctl       : 1;
+	unsigned                       : 1;
+	unsigned storage_alt_space_ctl : 1;
+	unsigned                       : 21;
+	unsigned long starting_addr;
+	unsigned long ending_addr;
+} per_cr_bits;
+
+typedef struct
+{
+	unsigned short perc_atmid;
+	unsigned long address;
+	unsigned char access_id;
+} per_lowcore_words;
+
+typedef struct
+{
+	unsigned perc_branching          : 1;
+	unsigned perc_instruction_fetch  : 1;
+	unsigned perc_storage_alteration : 1;
+	unsigned perc_gpr_alt_unused     : 1;
+	unsigned perc_store_real_address : 1;
+	unsigned                         : 3;
+	unsigned atmid_psw_bit_31        : 1;
+	unsigned atmid_validity_bit      : 1;
+	unsigned atmid_psw_bit_32        : 1;
+	unsigned atmid_psw_bit_5         : 1;
+	unsigned atmid_psw_bit_16        : 1;
+	unsigned atmid_psw_bit_17        : 1;
+	unsigned si                      : 2;
+	unsigned long address;
+	unsigned                         : 4;
+	unsigned access_id               : 4;
+} per_lowcore_bits;
+
+typedef struct
+{
+	union {
+		per_cr_words   words;
+		per_cr_bits    bits;
+	} control_regs;
+	/*
+	 * Use these flags instead of setting em_instruction_fetch
+	 * directly they are used so that single stepping can be
+	 * switched on & off while not affecting other tracing
+	 */
+	unsigned  single_step       : 1;
+	unsigned  instruction_fetch : 1;
+	unsigned                    : 30;
+	/*
+	 * These addresses are copied into cr10 & cr11 if single
+	 * stepping is switched off
+	 */
+	unsigned long starting_addr;
+	unsigned long ending_addr;
+	union {
+		per_lowcore_words words;
+		per_lowcore_bits  bits;
+	} lowcore; 
+} per_struct;
+
+typedef struct
+{
+	unsigned int  len;
+	unsigned long kernel_addr;
+	unsigned long process_addr;
+} ptrace_area;
+
+/*
+ * S/390 specific non posix ptrace requests. I chose unusual values so
+ * they are unlikely to clash with future ptrace definitions.
+ */
+#define PTRACE_PEEKUSR_AREA           0x5000
+#define PTRACE_POKEUSR_AREA           0x5001
+#define PTRACE_PEEKTEXT_AREA	      0x5002
+#define PTRACE_PEEKDATA_AREA	      0x5003
+#define PTRACE_POKETEXT_AREA	      0x5004
+#define PTRACE_POKEDATA_AREA 	      0x5005
+#define PTRACE_GET_LAST_BREAK	      0x5006
+#define PTRACE_PEEK_SYSTEM_CALL       0x5007
+#define PTRACE_POKE_SYSTEM_CALL	      0x5008
+#define PTRACE_ENABLE_TE	      0x5009
+#define PTRACE_DISABLE_TE	      0x5010
+
+/*
+ * PT_PROT definition is loosely based on hppa bsd definition in
+ * gdb/hppab-nat.c
+ */
+#define PTRACE_PROT                       21
+
+typedef enum
+{
+	ptprot_set_access_watchpoint,
+	ptprot_set_write_watchpoint,
+	ptprot_disable_watchpoint
+} ptprot_flags;
+
+typedef struct
+{
+	unsigned long lowaddr;
+	unsigned long hiaddr;
+	ptprot_flags prot;
+} ptprot_area;                     
+
+/* Sequence of bytes for breakpoint illegal instruction.  */
+#define S390_BREAKPOINT     {0x0,0x1}
+#define S390_BREAKPOINT_U16 ((__u16)0x0001)
+#define S390_SYSCALL_OPCODE ((__u16)0x0a00)
+#define S390_SYSCALL_SIZE   2
+
+/*
+ * The user_regs_struct defines the way the user registers are
+ * store on the stack for signal handling.
+ */
+struct user_regs_struct
+{
+	psw_t psw;
+	unsigned long gprs[NUM_GPRS];
+	unsigned int  acrs[NUM_ACRS];
+	unsigned long orig_gpr2;
+	s390_fp_regs fp_regs;
+	/*
+	 * These per registers are in here so that gdb can modify them
+	 * itself as there is no "official" ptrace interface for hardware
+	 * watchpoints. This is the way intel does it.
+	 */
+	per_struct per_info;
+	unsigned long ieee_instruction_pointer;	/* obsolete, always 0 */
+};
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _UAPI_S390_PTRACE_H */
diff --git a/arch/s390/include/asm/qeth.h b/arch/s390/include/uapi/asm/qeth.h
similarity index 100%
rename from arch/s390/include/asm/qeth.h
rename to arch/s390/include/uapi/asm/qeth.h
diff --git a/arch/s390/include/asm/resource.h b/arch/s390/include/uapi/asm/resource.h
similarity index 100%
rename from arch/s390/include/asm/resource.h
rename to arch/s390/include/uapi/asm/resource.h
diff --git a/arch/s390/include/uapi/asm/schid.h b/arch/s390/include/uapi/asm/schid.h
new file mode 100644
index 0000000..32f3ab2
--- /dev/null
+++ b/arch/s390/include/uapi/asm/schid.h
@@ -0,0 +1,16 @@
+#ifndef _UAPIASM_SCHID_H
+#define _UAPIASM_SCHID_H
+
+#include <linux/types.h>
+
+struct subchannel_id {
+	__u32 cssid : 8;
+	__u32 : 4;
+	__u32 m : 1;
+	__u32 ssid : 2;
+	__u32 one : 1;
+	__u32 sch_no : 16;
+} __attribute__ ((packed, aligned(4)));
+
+
+#endif /* _UAPIASM_SCHID_H */
diff --git a/arch/s390/include/asm/sembuf.h b/arch/s390/include/uapi/asm/sembuf.h
similarity index 100%
rename from arch/s390/include/asm/sembuf.h
rename to arch/s390/include/uapi/asm/sembuf.h
diff --git a/arch/s390/include/uapi/asm/setup.h b/arch/s390/include/uapi/asm/setup.h
new file mode 100644
index 0000000..5a637e3
--- /dev/null
+++ b/arch/s390/include/uapi/asm/setup.h
@@ -0,0 +1,13 @@
+/*
+ *  S390 version
+ *    Copyright IBM Corp. 1999, 2010
+ */
+
+#ifndef _UAPI_ASM_S390_SETUP_H
+#define _UAPI_ASM_S390_SETUP_H
+
+#define COMMAND_LINE_SIZE	4096
+
+#define ARCH_COMMAND_LINE_SIZE	896
+
+#endif /* _UAPI_ASM_S390_SETUP_H */
diff --git a/arch/s390/include/asm/shmbuf.h b/arch/s390/include/uapi/asm/shmbuf.h
similarity index 100%
rename from arch/s390/include/asm/shmbuf.h
rename to arch/s390/include/uapi/asm/shmbuf.h
diff --git a/arch/s390/include/asm/sigcontext.h b/arch/s390/include/uapi/asm/sigcontext.h
similarity index 100%
rename from arch/s390/include/asm/sigcontext.h
rename to arch/s390/include/uapi/asm/sigcontext.h
diff --git a/arch/s390/include/asm/siginfo.h b/arch/s390/include/uapi/asm/siginfo.h
similarity index 100%
rename from arch/s390/include/asm/siginfo.h
rename to arch/s390/include/uapi/asm/siginfo.h
diff --git a/arch/s390/include/uapi/asm/signal.h b/arch/s390/include/uapi/asm/signal.h
new file mode 100644
index 0000000..8c6a49e
--- /dev/null
+++ b/arch/s390/include/uapi/asm/signal.h
@@ -0,0 +1,135 @@
+/*
+ *  S390 version
+ *
+ *  Derived from "include/asm-i386/signal.h"
+ */
+
+#ifndef _UAPI_ASMS390_SIGNAL_H
+#define _UAPI_ASMS390_SIGNAL_H
+
+#include <linux/types.h>
+#include <linux/time.h>
+
+/* Avoid too many header ordering problems.  */
+struct siginfo;
+struct pt_regs;
+
+#ifndef __KERNEL__
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+#define NSIG            32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#define SIGHUP           1
+#define SIGINT           2
+#define SIGQUIT          3
+#define SIGILL           4
+#define SIGTRAP          5
+#define SIGABRT          6
+#define SIGIOT           6
+#define SIGBUS           7
+#define SIGFPE           8
+#define SIGKILL          9
+#define SIGUSR1         10
+#define SIGSEGV         11
+#define SIGUSR2         12
+#define SIGPIPE         13
+#define SIGALRM         14
+#define SIGTERM         15
+#define SIGSTKFLT       16
+#define SIGCHLD         17
+#define SIGCONT         18
+#define SIGSTOP         19
+#define SIGTSTP         20
+#define SIGTTIN         21
+#define SIGTTOU         22
+#define SIGURG          23
+#define SIGXCPU         24
+#define SIGXFSZ         25
+#define SIGVTALRM       26
+#define SIGPROF         27
+#define SIGWINCH        28
+#define SIGIO           29
+#define SIGPOLL         SIGIO
+/*
+#define SIGLOST         29
+*/
+#define SIGPWR          30
+#define SIGSYS		31
+#define SIGUNUSED       31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN        32
+#define SIGRTMAX        _NSIG
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP    0x00000001
+#define SA_NOCLDWAIT    0x00000002
+#define SA_SIGINFO      0x00000004
+#define SA_ONSTACK      0x08000000
+#define SA_RESTART      0x10000000
+#define SA_NODEFER      0x40000000
+#define SA_RESETHAND    0x80000000
+
+#define SA_NOMASK       SA_NODEFER
+#define SA_ONESHOT      SA_RESETHAND
+
+#define SA_RESTORER     0x04000000
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK      1
+#define SS_DISABLE      2
+
+#define MINSIGSTKSZ     2048
+#define SIGSTKSZ        8192
+
+#include <asm-generic/signal-defs.h>
+
+#ifndef __KERNEL__
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+struct sigaction {
+        union {
+          __sighandler_t _sa_handler;
+          void (*_sa_sigaction)(int, struct siginfo *, void *);
+        } _u;
+#ifndef __s390x__ /* lovely */
+        sigset_t sa_mask;
+        unsigned long sa_flags;
+        void (*sa_restorer)(void);
+#else  /* __s390x__ */
+        unsigned long sa_flags;
+        void (*sa_restorer)(void);
+	sigset_t sa_mask;
+#endif /* __s390x__ */
+};
+
+#define sa_handler      _u._sa_handler
+#define sa_sigaction    _u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+        void __user *ss_sp;
+        int ss_flags;
+        size_t ss_size;
+} stack_t;
+
+
+#endif /* _UAPI_ASMS390_SIGNAL_H */
diff --git a/arch/s390/include/asm/socket.h b/arch/s390/include/uapi/asm/socket.h
similarity index 100%
rename from arch/s390/include/asm/socket.h
rename to arch/s390/include/uapi/asm/socket.h
diff --git a/arch/s390/include/asm/sockios.h b/arch/s390/include/uapi/asm/sockios.h
similarity index 100%
rename from arch/s390/include/asm/sockios.h
rename to arch/s390/include/uapi/asm/sockios.h
diff --git a/arch/s390/include/asm/stat.h b/arch/s390/include/uapi/asm/stat.h
similarity index 100%
rename from arch/s390/include/asm/stat.h
rename to arch/s390/include/uapi/asm/stat.h
diff --git a/arch/s390/include/asm/statfs.h b/arch/s390/include/uapi/asm/statfs.h
similarity index 100%
rename from arch/s390/include/asm/statfs.h
rename to arch/s390/include/uapi/asm/statfs.h
diff --git a/arch/s390/include/asm/swab.h b/arch/s390/include/uapi/asm/swab.h
similarity index 100%
rename from arch/s390/include/asm/swab.h
rename to arch/s390/include/uapi/asm/swab.h
diff --git a/arch/s390/include/asm/tape390.h b/arch/s390/include/uapi/asm/tape390.h
similarity index 100%
rename from arch/s390/include/asm/tape390.h
rename to arch/s390/include/uapi/asm/tape390.h
diff --git a/arch/s390/include/asm/termbits.h b/arch/s390/include/uapi/asm/termbits.h
similarity index 100%
rename from arch/s390/include/asm/termbits.h
rename to arch/s390/include/uapi/asm/termbits.h
diff --git a/arch/s390/include/uapi/asm/termios.h b/arch/s390/include/uapi/asm/termios.h
new file mode 100644
index 0000000..554f973
--- /dev/null
+++ b/arch/s390/include/uapi/asm/termios.h
@@ -0,0 +1,49 @@
+/*
+ *  S390 version
+ *
+ *  Derived from "include/asm-i386/termios.h"
+ */
+
+#ifndef _UAPI_S390_TERMIOS_H
+#define _UAPI_S390_TERMIOS_H
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+	unsigned short c_iflag;		/* input mode flags */
+	unsigned short c_oflag;		/* output mode flags */
+	unsigned short c_cflag;		/* control mode flags */
+	unsigned short c_lflag;		/* local mode flags */
+	unsigned char c_line;		/* line discipline */
+	unsigned char c_cc[NCC];	/* control characters */
+};
+
+/* modem lines */
+#define TIOCM_LE	0x001
+#define TIOCM_DTR	0x002
+#define TIOCM_RTS	0x004
+#define TIOCM_ST	0x008
+#define TIOCM_SR	0x010
+#define TIOCM_CTS	0x020
+#define TIOCM_CAR	0x040
+#define TIOCM_RNG	0x080
+#define TIOCM_DSR	0x100
+#define TIOCM_CD	TIOCM_CAR
+#define TIOCM_RI	TIOCM_RNG
+#define TIOCM_OUT1	0x2000
+#define TIOCM_OUT2	0x4000
+#define TIOCM_LOOP	0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+
+#endif /* _UAPI_S390_TERMIOS_H */
diff --git a/arch/s390/include/uapi/asm/types.h b/arch/s390/include/uapi/asm/types.h
new file mode 100644
index 0000000..038f2b9
--- /dev/null
+++ b/arch/s390/include/uapi/asm/types.h
@@ -0,0 +1,22 @@
+/*
+ *  S390 version
+ *
+ *  Derived from "include/asm-i386/types.h"
+ */
+
+#ifndef _UAPI_S390_TYPES_H
+#define _UAPI_S390_TYPES_H
+
+#include <asm-generic/int-ll64.h>
+
+#ifndef __ASSEMBLY__
+
+/* A address type so that arithmetic can be done on it & it can be upgraded to
+   64 bit when necessary 
+*/
+typedef unsigned long addr_t; 
+typedef __signed__ long saddr_t;
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _UAPI_S390_TYPES_H */
diff --git a/arch/s390/include/asm/ucontext.h b/arch/s390/include/uapi/asm/ucontext.h
similarity index 100%
rename from arch/s390/include/asm/ucontext.h
rename to arch/s390/include/uapi/asm/ucontext.h
diff --git a/arch/s390/include/uapi/asm/unistd.h b/arch/s390/include/uapi/asm/unistd.h
new file mode 100644
index 0000000..63e6078
--- /dev/null
+++ b/arch/s390/include/uapi/asm/unistd.h
@@ -0,0 +1,374 @@
+/*
+ *  S390 version
+ *
+ *  Derived from "include/asm-i386/unistd.h"
+ */
+
+#ifndef _UAPI_ASM_S390_UNISTD_H_
+#define _UAPI_ASM_S390_UNISTD_H_
+
+/*
+ * This file contains the system call numbers.
+ */
+
+#define __NR_exit                 1
+#define __NR_fork                 2
+#define __NR_read                 3
+#define __NR_write                4
+#define __NR_open                 5
+#define __NR_close                6
+#define __NR_restart_syscall	  7
+#define __NR_creat                8
+#define __NR_link                 9
+#define __NR_unlink              10
+#define __NR_execve              11
+#define __NR_chdir               12
+#define __NR_mknod               14
+#define __NR_chmod               15
+#define __NR_lseek               19
+#define __NR_getpid              20
+#define __NR_mount               21
+#define __NR_umount              22
+#define __NR_ptrace              26
+#define __NR_alarm               27
+#define __NR_pause               29
+#define __NR_utime               30
+#define __NR_access              33
+#define __NR_nice                34
+#define __NR_sync                36
+#define __NR_kill                37
+#define __NR_rename              38
+#define __NR_mkdir               39
+#define __NR_rmdir               40
+#define __NR_dup                 41
+#define __NR_pipe                42
+#define __NR_times               43
+#define __NR_brk                 45
+#define __NR_signal              48
+#define __NR_acct                51
+#define __NR_umount2             52
+#define __NR_ioctl               54
+#define __NR_fcntl               55
+#define __NR_setpgid             57
+#define __NR_umask               60
+#define __NR_chroot              61
+#define __NR_ustat               62
+#define __NR_dup2                63
+#define __NR_getppid             64
+#define __NR_getpgrp             65
+#define __NR_setsid              66
+#define __NR_sigaction           67
+#define __NR_sigsuspend          72
+#define __NR_sigpending          73
+#define __NR_sethostname         74
+#define __NR_setrlimit           75
+#define __NR_getrusage           77
+#define __NR_gettimeofday        78
+#define __NR_settimeofday        79
+#define __NR_symlink             83
+#define __NR_readlink            85
+#define __NR_uselib              86
+#define __NR_swapon              87
+#define __NR_reboot              88
+#define __NR_readdir             89
+#define __NR_mmap                90
+#define __NR_munmap              91
+#define __NR_truncate            92
+#define __NR_ftruncate           93
+#define __NR_fchmod              94
+#define __NR_getpriority         96
+#define __NR_setpriority         97
+#define __NR_statfs              99
+#define __NR_fstatfs            100
+#define __NR_socketcall         102
+#define __NR_syslog             103
+#define __NR_setitimer          104
+#define __NR_getitimer          105
+#define __NR_stat               106
+#define __NR_lstat              107
+#define __NR_fstat              108
+#define __NR_lookup_dcookie     110
+#define __NR_vhangup            111
+#define __NR_idle               112
+#define __NR_wait4              114
+#define __NR_swapoff            115
+#define __NR_sysinfo            116
+#define __NR_ipc                117
+#define __NR_fsync              118
+#define __NR_sigreturn          119
+#define __NR_clone              120
+#define __NR_setdomainname      121
+#define __NR_uname              122
+#define __NR_adjtimex           124
+#define __NR_mprotect           125
+#define __NR_sigprocmask        126
+#define __NR_create_module      127
+#define __NR_init_module        128
+#define __NR_delete_module      129
+#define __NR_get_kernel_syms    130
+#define __NR_quotactl           131
+#define __NR_getpgid            132
+#define __NR_fchdir             133
+#define __NR_bdflush            134
+#define __NR_sysfs              135
+#define __NR_personality        136
+#define __NR_afs_syscall        137 /* Syscall for Andrew File System */
+#define __NR_getdents           141
+#define __NR_flock              143
+#define __NR_msync              144
+#define __NR_readv              145
+#define __NR_writev             146
+#define __NR_getsid             147
+#define __NR_fdatasync          148
+#define __NR__sysctl            149
+#define __NR_mlock              150
+#define __NR_munlock            151
+#define __NR_mlockall           152
+#define __NR_munlockall         153
+#define __NR_sched_setparam             154
+#define __NR_sched_getparam             155
+#define __NR_sched_setscheduler         156
+#define __NR_sched_getscheduler         157
+#define __NR_sched_yield                158
+#define __NR_sched_get_priority_max     159
+#define __NR_sched_get_priority_min     160
+#define __NR_sched_rr_get_interval      161
+#define __NR_nanosleep          162
+#define __NR_mremap             163
+#define __NR_query_module       167
+#define __NR_poll               168
+#define __NR_nfsservctl         169
+#define __NR_prctl              172
+#define __NR_rt_sigreturn       173
+#define __NR_rt_sigaction       174
+#define __NR_rt_sigprocmask     175
+#define __NR_rt_sigpending      176
+#define __NR_rt_sigtimedwait    177
+#define __NR_rt_sigqueueinfo    178
+#define __NR_rt_sigsuspend      179
+#define __NR_pread64            180
+#define __NR_pwrite64           181
+#define __NR_getcwd             183
+#define __NR_capget             184
+#define __NR_capset             185
+#define __NR_sigaltstack        186
+#define __NR_sendfile           187
+#define __NR_getpmsg		188
+#define __NR_putpmsg		189
+#define __NR_vfork		190
+#define __NR_pivot_root         217
+#define __NR_mincore            218
+#define __NR_madvise            219
+#define __NR_getdents64		220
+#define __NR_readahead		222
+#define __NR_setxattr		224
+#define __NR_lsetxattr		225
+#define __NR_fsetxattr		226
+#define __NR_getxattr		227
+#define __NR_lgetxattr		228
+#define __NR_fgetxattr		229
+#define __NR_listxattr		230
+#define __NR_llistxattr		231
+#define __NR_flistxattr		232
+#define __NR_removexattr	233
+#define __NR_lremovexattr	234
+#define __NR_fremovexattr	235
+#define __NR_gettid		236
+#define __NR_tkill		237
+#define __NR_futex		238
+#define __NR_sched_setaffinity	239
+#define __NR_sched_getaffinity	240
+#define __NR_tgkill		241
+/* Number 242 is reserved for tux */
+#define __NR_io_setup		243
+#define __NR_io_destroy		244
+#define __NR_io_getevents	245
+#define __NR_io_submit		246
+#define __NR_io_cancel		247
+#define __NR_exit_group		248
+#define __NR_epoll_create	249
+#define __NR_epoll_ctl		250
+#define __NR_epoll_wait		251
+#define __NR_set_tid_address	252
+#define __NR_fadvise64		253
+#define __NR_timer_create	254
+#define __NR_timer_settime	(__NR_timer_create+1)
+#define __NR_timer_gettime	(__NR_timer_create+2)
+#define __NR_timer_getoverrun	(__NR_timer_create+3)
+#define __NR_timer_delete	(__NR_timer_create+4)
+#define __NR_clock_settime	(__NR_timer_create+5)
+#define __NR_clock_gettime	(__NR_timer_create+6)
+#define __NR_clock_getres	(__NR_timer_create+7)
+#define __NR_clock_nanosleep	(__NR_timer_create+8)
+/* Number 263 is reserved for vserver */
+#define __NR_statfs64		265
+#define __NR_fstatfs64		266
+#define __NR_remap_file_pages	267
+/* Number 268 is reserved for new sys_mbind */
+/* Number 269 is reserved for new sys_get_mempolicy */
+/* Number 270 is reserved for new sys_set_mempolicy */
+#define __NR_mq_open		271
+#define __NR_mq_unlink		272
+#define __NR_mq_timedsend	273
+#define __NR_mq_timedreceive	274
+#define __NR_mq_notify		275
+#define __NR_mq_getsetattr	276
+#define __NR_kexec_load		277
+#define __NR_add_key		278
+#define __NR_request_key	279
+#define __NR_keyctl		280
+#define __NR_waitid		281
+#define __NR_ioprio_set		282
+#define __NR_ioprio_get		283
+#define __NR_inotify_init	284
+#define __NR_inotify_add_watch	285
+#define __NR_inotify_rm_watch	286
+/* Number 287 is reserved for new sys_migrate_pages */
+#define __NR_openat		288
+#define __NR_mkdirat		289
+#define __NR_mknodat		290
+#define __NR_fchownat		291
+#define __NR_futimesat		292
+#define __NR_unlinkat		294
+#define __NR_renameat		295
+#define __NR_linkat		296
+#define __NR_symlinkat		297
+#define __NR_readlinkat		298
+#define __NR_fchmodat		299
+#define __NR_faccessat		300
+#define __NR_pselect6		301
+#define __NR_ppoll		302
+#define __NR_unshare		303
+#define __NR_set_robust_list	304
+#define __NR_get_robust_list	305
+#define __NR_splice		306
+#define __NR_sync_file_range	307
+#define __NR_tee		308
+#define __NR_vmsplice		309
+/* Number 310 is reserved for new sys_move_pages */
+#define __NR_getcpu		311
+#define __NR_epoll_pwait	312
+#define __NR_utimes		313
+#define __NR_fallocate		314
+#define __NR_utimensat		315
+#define __NR_signalfd		316
+#define __NR_timerfd		317
+#define __NR_eventfd		318
+#define __NR_timerfd_create	319
+#define __NR_timerfd_settime	320
+#define __NR_timerfd_gettime	321
+#define __NR_signalfd4		322
+#define __NR_eventfd2		323
+#define __NR_inotify_init1	324
+#define __NR_pipe2		325
+#define __NR_dup3		326
+#define __NR_epoll_create1	327
+#define	__NR_preadv		328
+#define	__NR_pwritev		329
+#define __NR_rt_tgsigqueueinfo	330
+#define __NR_perf_event_open	331
+#define __NR_fanotify_init	332
+#define __NR_fanotify_mark	333
+#define __NR_prlimit64		334
+#define __NR_name_to_handle_at	335
+#define __NR_open_by_handle_at	336
+#define __NR_clock_adjtime	337
+#define __NR_syncfs		338
+#define __NR_setns		339
+#define __NR_process_vm_readv	340
+#define __NR_process_vm_writev	341
+#define __NR_s390_runtime_instr 342
+#define __NR_kcmp		343
+#define NR_syscalls 344
+
+/* 
+ * There are some system calls that are not present on 64 bit, some
+ * have a different name although they do the same (e.g. __NR_chown32
+ * is __NR_chown on 64 bit).
+ */
+#ifndef __s390x__
+
+#define __NR_time		 13
+#define __NR_lchown		 16
+#define __NR_setuid		 23
+#define __NR_getuid		 24
+#define __NR_stime		 25
+#define __NR_setgid		 46
+#define __NR_getgid		 47
+#define __NR_geteuid		 49
+#define __NR_getegid		 50
+#define __NR_setreuid		 70
+#define __NR_setregid		 71
+#define __NR_getrlimit		 76
+#define __NR_getgroups		 80
+#define __NR_setgroups		 81
+#define __NR_fchown		 95
+#define __NR_ioperm		101
+#define __NR_setfsuid		138
+#define __NR_setfsgid		139
+#define __NR__llseek		140
+#define __NR__newselect 	142
+#define __NR_setresuid		164
+#define __NR_getresuid		165
+#define __NR_setresgid		170
+#define __NR_getresgid		171
+#define __NR_chown		182
+#define __NR_ugetrlimit		191	/* SuS compliant getrlimit */
+#define __NR_mmap2		192
+#define __NR_truncate64		193
+#define __NR_ftruncate64	194
+#define __NR_stat64		195
+#define __NR_lstat64		196
+#define __NR_fstat64		197
+#define __NR_lchown32		198
+#define __NR_getuid32		199
+#define __NR_getgid32		200
+#define __NR_geteuid32		201
+#define __NR_getegid32		202
+#define __NR_setreuid32		203
+#define __NR_setregid32		204
+#define __NR_getgroups32	205
+#define __NR_setgroups32	206
+#define __NR_fchown32		207
+#define __NR_setresuid32	208
+#define __NR_getresuid32	209
+#define __NR_setresgid32	210
+#define __NR_getresgid32	211
+#define __NR_chown32		212
+#define __NR_setuid32		213
+#define __NR_setgid32		214
+#define __NR_setfsuid32		215
+#define __NR_setfsgid32		216
+#define __NR_fcntl64		221
+#define __NR_sendfile64		223
+#define __NR_fadvise64_64	264
+#define __NR_fstatat64		293
+
+#else
+
+#define __NR_select		142
+#define __NR_getrlimit		191	/* SuS compliant getrlimit */
+#define __NR_lchown  		198
+#define __NR_getuid  		199
+#define __NR_getgid  		200
+#define __NR_geteuid  		201
+#define __NR_getegid  		202
+#define __NR_setreuid  		203
+#define __NR_setregid  		204
+#define __NR_getgroups  	205
+#define __NR_setgroups  	206
+#define __NR_fchown  		207
+#define __NR_setresuid  	208
+#define __NR_getresuid  	209
+#define __NR_setresgid  	210
+#define __NR_getresgid  	211
+#define __NR_chown  		212
+#define __NR_setuid  		213
+#define __NR_setgid  		214
+#define __NR_setfsuid  		215
+#define __NR_setfsgid  		216
+#define __NR_newfstatat		293
+
+#endif
+
+#endif /* _UAPI_ASM_S390_UNISTD_H_ */
diff --git a/arch/s390/include/asm/vtoc.h b/arch/s390/include/uapi/asm/vtoc.h
similarity index 100%
rename from arch/s390/include/asm/vtoc.h
rename to arch/s390/include/uapi/asm/vtoc.h
diff --git a/arch/s390/include/asm/zcrypt.h b/arch/s390/include/uapi/asm/zcrypt.h
similarity index 100%
rename from arch/s390/include/asm/zcrypt.h
rename to arch/s390/include/uapi/asm/zcrypt.h
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 189963c..65cca95 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -432,32 +432,6 @@
 	return ret;
 }
 
-/*
- * sys32_execve() executes a new program after the asm stub has set
- * things up for us.  This should basically do what I want it to.
- */
-asmlinkage long sys32_execve(const char __user *name, compat_uptr_t __user *argv,
-			     compat_uptr_t __user *envp)
-{
-	struct pt_regs *regs = task_pt_regs(current);
-	char *filename;
-	long rc;
-
-	filename = getname(name);
-	rc = PTR_ERR(filename);
-	if (IS_ERR(filename))
-		return rc;
-	rc = compat_do_execve(filename, argv, envp, regs);
-	if (rc)
-		goto out;
-	current->thread.fp_regs.fpc=0;
-	asm volatile("sfpc %0,0" : : "d" (0));
-	rc = regs->gprs[2];
-out:
-	putname(filename);
-	return rc;
-}
-
 asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf,
 				size_t count, u32 poshi, u32 poslo)
 {
diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h
index 90887bd..d4d0239 100644
--- a/arch/s390/kernel/compat_linux.h
+++ b/arch/s390/kernel/compat_linux.h
@@ -125,8 +125,6 @@
 			  compat_sigset_t __user *oset, size_t sigsetsize);
 long sys32_rt_sigpending(compat_sigset_t __user *set, size_t sigsetsize);
 long sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo);
-long sys32_execve(const char __user *name, compat_uptr_t __user *argv,
-		  compat_uptr_t __user *envp);
 long sys32_init_module(void __user *umod, unsigned long len,
 		       const char __user *uargs);
 long sys32_delete_module(const char __user *name_user, unsigned int flags);
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index 3afba80..ad79b84 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -1576,7 +1576,7 @@
 	llgtr	%r2,%r2			# char *
 	llgtr	%r3,%r3			# compat_uptr_t *
 	llgtr	%r4,%r4			# compat_uptr_t *
-	jg	sys32_execve		# branch to system call
+	jg	compat_sys_execve	# branch to system call
 
 ENTRY(sys_fanotify_init_wrapper)
 	llgfr	%r2,%r2			# unsigned int
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index 7f47176..1f0eee9 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -283,14 +283,6 @@
 	      ARRAY_SIZE(S390_lowcore.stfle_fac_list));
 }
 
-static noinline __init void setup_hpage(void)
-{
-	if (!test_facility(2) || !test_facility(8))
-		return;
-	S390_lowcore.machine_flags |= MACHINE_FLAG_HPAGE;
-	__ctl_set_bit(0, 23);
-}
-
 static __init void detect_mvpg(void)
 {
 #ifndef CONFIG_64BIT
@@ -378,16 +370,22 @@
 static __init void detect_machine_facilities(void)
 {
 #ifdef CONFIG_64BIT
+	if (test_facility(8)) {
+		S390_lowcore.machine_flags |= MACHINE_FLAG_EDAT1;
+		__ctl_set_bit(0, 23);
+	}
+	if (test_facility(78))
+		S390_lowcore.machine_flags |= MACHINE_FLAG_EDAT2;
 	if (test_facility(3))
 		S390_lowcore.machine_flags |= MACHINE_FLAG_IDTE;
-	if (test_facility(8))
-		S390_lowcore.machine_flags |= MACHINE_FLAG_PFMF;
 	if (test_facility(27))
 		S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS;
 	if (test_facility(40))
 		S390_lowcore.machine_flags |= MACHINE_FLAG_SPP;
 	if (test_facility(50) && test_facility(73))
 		S390_lowcore.machine_flags |= MACHINE_FLAG_TE;
+	if (test_facility(66))
+		S390_lowcore.machine_flags |= MACHINE_FLAG_RRBM;
 #endif
 }
 
@@ -482,7 +480,6 @@
 	detect_diag9c();
 	detect_diag44();
 	detect_machine_facilities();
-	setup_hpage();
 	setup_topology();
 	sclp_facilities_detect();
 	detect_memory_layout(memory_chunk);
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 870bad6..ef46f66 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -331,45 +331,38 @@
 	l	%r12,__LC_THREAD_INFO
 	l	%r13,__LC_SVC_NEW_PSW+4
 	tm	__PT_PSW+1(%r11),0x01	# forking a kernel thread ?
-	jo	0f
-	st	%r15,__PT_R15(%r11)	# store stack pointer for new kthread
-0:	l	%r1,BASED(.Lschedule_tail)
+	je	1f
+	l	%r1,BASED(.Lschedule_tail)
 	basr	%r14,%r1		# call schedule_tail
 	TRACE_IRQS_ON
 	ssm	__LC_SVC_NEW_PSW	# reenable interrupts
 	j	sysc_tracenogo
 
+1:	# it's a kernel thread
+	st	%r15,__PT_R15(%r11)	# store stack pointer for new kthread
+	l	%r1,BASED(.Lschedule_tail)
+	basr	%r14,%r1		# call schedule_tail
+	TRACE_IRQS_ON
+	ssm	__LC_SVC_NEW_PSW	# reenable interrupts
+	lm	%r9,%r11,__PT_R9(%r11)	# load gprs
+ENTRY(kernel_thread_starter)
+	la	%r2,0(%r10)
+	basr	%r14,%r9
+	la	%r2,0
+	br	%r11			# do_exit
+
 #
 # kernel_execve function needs to deal with pt_regs that is not
 # at the usual place
 #
-ENTRY(kernel_execve)
-	stm	%r12,%r15,48(%r15)
-	lr	%r14,%r15
-	l	%r13,__LC_SVC_NEW_PSW+4
-	ahi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
-	st	%r14,__SF_BACKCHAIN(%r15)
-	la	%r12,STACK_FRAME_OVERHEAD(%r15)
-	xc	0(__PT_SIZE,%r12),0(%r12)
-	l	%r1,BASED(.Ldo_execve)
-	lr	%r5,%r12
-	basr	%r14,%r1		# call do_execve
-	ltr	%r2,%r2
-	je	0f
-	ahi	%r15,(STACK_FRAME_OVERHEAD + __PT_SIZE)
-	lm	%r12,%r15,48(%r15)
-	br	%r14
-	# execve succeeded.
-0:	ssm	__LC_PGM_NEW_PSW	# disable I/O and ext. interrupts
-	l	%r15,__LC_KERNEL_STACK	# load ksp
-	ahi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
-	la	%r11,STACK_FRAME_OVERHEAD(%r15)
-	mvc	0(__PT_SIZE,%r11),0(%r12)	# copy pt_regs
-	l	%r12,__LC_THREAD_INFO
+ENTRY(ret_from_kernel_execve)
+	ssm	__LC_PGM_NEW_PSW	# disable I/O and ext. interrupts
+	lr	%r15,%r2
+	lr	%r11,%r2
+	ahi	%r15,-STACK_FRAME_OVERHEAD
 	xc	__SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
+	l	%r12,__LC_THREAD_INFO
 	ssm	__LC_SVC_NEW_PSW	# reenable interrupts
-	l	%r1,BASED(.Lexecve_tail)
-	basr	%r14,%r1		# call execve_tail
 	j	sysc_return
 
 /*
@@ -931,8 +924,6 @@
 .Ldo_signal:		.long	do_signal
 .Ldo_notify_resume:	.long	do_notify_resume
 .Ldo_per_trap:		.long	do_per_trap
-.Ldo_execve:		.long	do_execve
-.Lexecve_tail:		.long	execve_tail
 .Ljump_table:		.long	pgm_check_table
 .Lschedule:		.long	schedule
 #ifdef CONFIG_PREEMPT
diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h
index a5f4dc4..d0d3f69 100644
--- a/arch/s390/kernel/entry.h
+++ b/arch/s390/kernel/entry.h
@@ -58,9 +58,6 @@
 long sys_clone(unsigned long newsp, unsigned long clone_flags,
 	       int __user *parent_tidptr, int __user *child_tidptr);
 long sys_vfork(void);
-void execve_tail(void);
-long sys_execve(const char __user *name, const char __user *const __user *argv,
-		const char __user *const __user *envp);
 long sys_sigsuspend(int history0, int history1, old_sigset_t mask);
 long sys_sigaction(int sig, const struct old_sigaction __user *act,
 		   struct old_sigaction __user *oact);
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 7549985..07d8de3 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -295,7 +295,7 @@
 	jno	sysc_return
 	lmg	%r2,%r7,__PT_R2(%r11)	# load svc arguments
 	lghi	%r8,0			# svc 0 returns -ENOSYS
-	lh	%r1,__PT_INT_CODE+2(%r11)	# load new svc number
+	llgh	%r1,__PT_INT_CODE+2(%r11)	# load new svc number
 	cghi	%r1,NR_syscalls
 	jnl	sysc_nr_ok		# invalid svc number -> do svc 0
 	slag	%r8,%r1,2
@@ -353,41 +353,31 @@
 	la	%r11,STACK_FRAME_OVERHEAD(%r15)
 	lg	%r12,__LC_THREAD_INFO
 	tm	__PT_PSW+1(%r11),0x01	# forking a kernel thread ?
-	jo	0f
-	stg	%r15,__PT_R15(%r11)	# store stack pointer for new kthread
-0:	brasl	%r14,schedule_tail
+	je	1f
+	brasl	%r14,schedule_tail
 	TRACE_IRQS_ON
 	ssm	__LC_SVC_NEW_PSW	# reenable interrupts
 	j	sysc_tracenogo
-
-#
-# kernel_execve function needs to deal with pt_regs that is not
-# at the usual place
-#
-ENTRY(kernel_execve)
-	stmg	%r12,%r15,96(%r15)
-	lgr	%r14,%r15
-	aghi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
-	stg	%r14,__SF_BACKCHAIN(%r15)
-	la	%r12,STACK_FRAME_OVERHEAD(%r15)
-	xc	0(__PT_SIZE,%r12),0(%r12)
-	lgr	%r5,%r12
-	brasl	%r14,do_execve
-	ltgfr	%r2,%r2
-	je	0f
-	aghi	%r15,(STACK_FRAME_OVERHEAD + __PT_SIZE)
-	lmg	%r12,%r15,96(%r15)
-	br	%r14
-	# execve succeeded.
-0:	ssm	__LC_PGM_NEW_PSW	# disable I/O and ext. interrupts
-	lg	%r15,__LC_KERNEL_STACK	# load ksp
-	aghi	%r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
-	la	%r11,STACK_FRAME_OVERHEAD(%r15)
-	mvc	0(__PT_SIZE,%r11),0(%r12)	# copy pt_regs
-	lg	%r12,__LC_THREAD_INFO
-	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
+1:	# it's a kernel thread
+	stg	%r15,__PT_R15(%r11)	# store stack pointer for new kthread
+	brasl	%r14,schedule_tail
+	TRACE_IRQS_ON
 	ssm	__LC_SVC_NEW_PSW	# reenable interrupts
-	brasl	%r14,execve_tail
+	lmg	%r9,%r11,__PT_R9(%r11)	# load gprs
+ENTRY(kernel_thread_starter)
+	la	%r2,0(%r10)
+	basr	%r14,%r9
+	la	%r2,0
+	br	%r11			# do_exit
+
+ENTRY(ret_from_kernel_execve)
+	ssm	__LC_PGM_NEW_PSW	# disable I/O and ext. interrupts
+	lgr	%r15,%r2
+	lgr	%r11,%r2
+	aghi	%r15,-STACK_FRAME_OVERHEAD
+	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
+	lg	%r12,__LC_THREAD_INFO
+	ssm	__LC_SVC_NEW_PSW	# reenable interrupts
 	j	sysc_return
 
 /*
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index 805b668..984726c 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -52,7 +52,7 @@
 	.long	0x02000370,0x60000050		# the channel program the PSW
 	.long	0x020003c0,0x60000050		# at location 0 is loaded.
 	.long	0x02000410,0x60000050		# Initial processing starts
-	.long	0x02000460,0x60000050		# at 0xf0 = iplstart.
+	.long	0x02000460,0x60000050		# at 0x200 = iplstart.
 	.long	0x020004b0,0x60000050
 	.long	0x02000500,0x60000050
 	.long	0x02000550,0x60000050
@@ -62,11 +62,54 @@
 	.long	0x02000690,0x60000050
 	.long	0x020006e0,0x20000050
 
-	.org	0xf0
+	.org	0x200
+#
+# subroutine to set architecture mode
+#
+.Lsetmode:
+#ifdef CONFIG_64BIT
+	mvi	__LC_AR_MODE_ID,1	# set esame flag
+	slr	%r0,%r0 		# set cpuid to zero
+	lhi	%r1,2			# mode 2 = esame (dump)
+	sigp	%r1,%r0,0x12		# switch to esame mode
+	bras	%r13,0f
+	.fill	16,4,0x0
+0:	lmh	%r0,%r15,0(%r13)	# clear high-order half of gprs
+	sam31				# switch to 31 bit addressing mode
+#else
+	mvi	__LC_AR_MODE_ID,0	# set ESA flag (mode 0)
+#endif
+	br	%r14
+
+#
+# subroutine to wait for end I/O
+#
+.Lirqwait:
+#ifdef CONFIG_64BIT
+	mvc	0x1f0(16),.Lnewpsw	# set up IO interrupt psw
+	lpsw	.Lwaitpsw
+.Lioint:
+	br	%r14
+	.align	8
+.Lnewpsw:
+	.quad	0x0000000080000000,.Lioint
+#else
+	mvc	0x78(8),.Lnewpsw	# set up IO interrupt psw
+	lpsw	.Lwaitpsw
+.Lioint:
+	br	%r14
+	.align	8
+.Lnewpsw:
+	.long	0x00080000,0x80000000+.Lioint
+#endif
+.Lwaitpsw:
+	.long	0x020a0000,0x80000000+.Lioint
+
 #
 # subroutine for loading cards from the reader
 #
 .Lloader:
+	la	%r4,0(%r14)
 	la	%r3,.Lorb		# r2 = address of orb into r2
 	la	%r5,.Lirb		# r4 = address of irb
 	la	%r6,.Lccws
@@ -83,9 +126,7 @@
 	ssch	0(%r3)			# load chunk of 1600 bytes
 	bnz	.Llderr
 .Lwait4irq:
-	mvc	0x78(8),.Lnewpsw	# set up IO interrupt psw
-	lpsw	.Lwaitpsw
-.Lioint:
+	bas	%r14,.Lirqwait
 	c	%r1,0xb8		# compare subchannel number
 	bne	.Lwait4irq
 	tsch	0(%r5)
@@ -104,7 +145,7 @@
 	sr	%r0,%r3 		# #ccws*80-residual=#bytes read
 	ar	%r2,%r0
 
-	br	%r14			# r2 contains the total size
+	br	%r4			# r2 contains the total size
 
 .Lcont:
 	ahi	%r2,0x640		# add 0x640 to total size
@@ -128,10 +169,6 @@
 .Lloadp:.long	0,0
 	.align	8
 .Lcrash:.long	0x000a0000,0x00000000
-.Lnewpsw:
-	.long	0x00080000,0x80000000+.Lioint
-.Lwaitpsw:
-	.long	0x020a0000,0x80000000+.Lioint
 
 	.align	8
 .Lccws: .rept	19
@@ -140,6 +177,7 @@
 	.long	0x02200050,0x00000000
 
 iplstart:
+	bas	%r14,.Lsetmode		# Immediately switch to 64 bit mode
 	lh	%r1,0xb8		# test if subchannel number
 	bct	%r1,.Lnoload		#  is valid
 	l	%r1,0xb8		# load ipl subchannel number
@@ -209,8 +247,8 @@
 #
 # reset files in VM reader
 #
-	stidp	__LC_SAVE_AREA_SYNC	# store cpuid
-	tm	__LC_SAVE_AREA_SYNC,0xff# running VM ?
+	stidp	.Lcpuid			# store cpuid
+	tm	.Lcpuid,0xff		# running VM ?
 	bno	.Lnoreset
 	la	%r2,.Lreset
 	lhi	%r3,26
@@ -222,23 +260,14 @@
 	tm	31(%r5),0xff		# bits is set in the schib
 	bz	.Lnoreset
 .Lwaitforirq:
-	mvc	0x78(8),.Lrdrnewpsw	# set up IO interrupt psw
-.Lwaitrdrirq:
-	lpsw	.Lrdrwaitpsw
-.Lrdrint:
+	bas	%r14,.Lirqwait		# wait for IO interrupt
 	c	%r1,0xb8		# compare subchannel number
-	bne	.Lwaitrdrirq
+	bne	.Lwaitforirq
 	la	%r5,.Lirb
 	tsch	0(%r5)
 .Lnoreset:
 	b	.Lnoload
 
-	.align	8
-.Lrdrnewpsw:
-	.long	0x00080000,0x80000000+.Lrdrint
-.Lrdrwaitpsw:
-	.long	0x020a0000,0x80000000+.Lrdrint
-
 #
 # everything loaded, go for it
 #
@@ -254,6 +283,8 @@
 	.byte	0xc8,0xd6,0xd3,0xc4	# "change rdr all keep nohold"
 .L_eof: .long	0xc5d6c600	 /* C'EOF' */
 .L_hdr: .long	0xc8c4d900	 /* C'HDR' */
+	.align	8
+.Lcpuid:.fill	8,1,0
 
 #
 # SALIPL loader support. Based on a patch by Rob van der Heij.
@@ -263,6 +294,7 @@
 	.org	0x800
 ENTRY(start)
 	stm	%r0,%r15,0x07b0		# store registers
+	bas	%r14,.Lsetmode		# Immediately switch to 64 bit mode
 	basr	%r12,%r0
 .base:
 	l	%r11,.parm
@@ -343,6 +375,18 @@
 ENTRY(startup_kdump)
 	j	.Lep_startup_kdump
 .Lep_startup_normal:
+#ifdef CONFIG_64BIT
+	mvi	__LC_AR_MODE_ID,1	# set esame flag
+	slr	%r0,%r0 		# set cpuid to zero
+	lhi	%r1,2			# mode 2 = esame (dump)
+	sigp	%r1,%r0,0x12		# switch to esame mode
+	bras	%r13,0f
+	.fill	16,4,0x0
+0:	lmh	%r0,%r15,0(%r13)	# clear high-order half of gprs
+	sam31				# switch to 31 bit addressing mode
+#else
+	mvi	__LC_AR_MODE_ID,0	# set ESA flag (mode 0)
+#endif
 	basr	%r13,0			# get base
 .LPG0:
 	xc	0x200(256),0x200	# partially clear lowcore
@@ -410,22 +454,17 @@
 #endif
 
 #ifdef CONFIG_64BIT
-	mvi	__LC_AR_MODE_ID,1	# set esame flag
-	slr	%r0,%r0 		# set cpuid to zero
-	lhi	%r1,2			# mode 2 = esame (dump)
-	sigp	%r1,%r0,0x12		# switch to esame mode
+	/* Continue with 64bit startup code in head64.S */
 	sam64				# switch to 64 bit mode
-	larl	%r13,4f
-	lmh	%r0,%r15,0(%r13)	# clear high-order half
 	jg	startup_continue
-4:	.fill	16,4,0x0
 #else
-	mvi	__LC_AR_MODE_ID,0	# set ESA flag (mode 0)
+	/* Continue with 31bit startup code in head31.S */
 	l	%r13,4f-.LPG0(%r13)
 	b	0(%r13)
 	.align	8
 4:	.long	startup_continue
 #endif
+
 	.align	8
 5:	.long	0x7fffffff,0xffffffff
 
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S
index a1372ae..9a99856 100644
--- a/arch/s390/kernel/head31.S
+++ b/arch/s390/kernel/head31.S
@@ -78,10 +78,7 @@
 
 ENTRY(_ehead)
 
-#ifdef CONFIG_SHARED_KERNEL
 	.org	0x100000 - 0x11000	# head.o ends at 0x11000
-#endif
-
 #
 # startup-code, running in absolute addressing mode
 #
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
index c108af2..b9e25ae 100644
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -76,10 +76,7 @@
 
 ENTRY(_ehead)
 
-#ifdef CONFIG_SHARED_KERNEL
 	.org	0x100000 - 0x11000	# head.o ends at 0x11000
-#endif
-
 #
 # startup-code, running in absolute addressing mode
 #
diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c
index 46412b1..4610dea 100644
--- a/arch/s390/kernel/module.c
+++ b/arch/s390/kernel/module.c
@@ -44,6 +44,17 @@
 #define PLT_ENTRY_SIZE 20
 #endif /* CONFIG_64BIT */
 
+#ifdef CONFIG_64BIT
+void *module_alloc(unsigned long size)
+{
+	if (PAGE_ALIGN(size) > MODULES_LEN)
+		return NULL;
+	return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
+				    GFP_KERNEL, PAGE_KERNEL, -1,
+				    __builtin_return_address(0));
+}
+#endif
+
 /* Free memory returned from module_alloc */
 void module_free(struct module *mod, void *module_region)
 {
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 5024be2..cd31ad4 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -100,35 +100,6 @@
 
 extern void __kprobes kernel_thread_starter(void);
 
-asm(
-	".section .kprobes.text, \"ax\"\n"
-	".global kernel_thread_starter\n"
-	"kernel_thread_starter:\n"
-	"    la    2,0(10)\n"
-	"    basr  14,9\n"
-	"    la    2,0\n"
-	"    br    11\n"
-	".previous\n");
-
-int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-{
-	struct pt_regs regs;
-
-	memset(&regs, 0, sizeof(regs));
-	regs.psw.mask = psw_kernel_bits |
-		PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
-	regs.psw.addr = (unsigned long) kernel_thread_starter | PSW_ADDR_AMODE;
-	regs.gprs[9] = (unsigned long) fn;
-	regs.gprs[10] = (unsigned long) arg;
-	regs.gprs[11] = (unsigned long) do_exit;
-	regs.orig_gpr2 = -1;
-
-	/* Ok, create the new process.. */
-	return do_fork(flags | CLONE_VM | CLONE_UNTRACED,
-		       0, &regs, 0, NULL, NULL);
-}
-EXPORT_SYMBOL(kernel_thread);
-
 /*
  * Free current thread data structures etc..
  */
@@ -146,7 +117,7 @@
 }
 
 int copy_thread(unsigned long clone_flags, unsigned long new_stackp,
-		unsigned long unused,
+		unsigned long arg,
 		struct task_struct *p, struct pt_regs *regs)
 {
 	struct thread_info *ti;
@@ -158,20 +129,44 @@
 
 	frame = container_of(task_pt_regs(p), struct fake_frame, childregs);
 	p->thread.ksp = (unsigned long) frame;
-	/* Store access registers to kernel stack of new process. */
-	frame->childregs = *regs;
-	frame->childregs.gprs[2] = 0;	/* child returns 0 on fork. */
-	frame->childregs.gprs[15] = new_stackp;
-	frame->sf.back_chain = 0;
+	/* Save access registers to new thread structure. */
+	save_access_regs(&p->thread.acrs[0]);
+	/* start new process with ar4 pointing to the correct address space */
+	p->thread.mm_segment = get_fs();
+	/* Don't copy debug registers */
+	memset(&p->thread.per_user, 0, sizeof(p->thread.per_user));
+	memset(&p->thread.per_event, 0, sizeof(p->thread.per_event));
+	clear_tsk_thread_flag(p, TIF_SINGLE_STEP);
+	clear_tsk_thread_flag(p, TIF_PER_TRAP);
+	/* Initialize per thread user and system timer values */
+	ti = task_thread_info(p);
+	ti->user_timer = 0;
+	ti->system_timer = 0;
 
+	frame->sf.back_chain = 0;
 	/* new return point is ret_from_fork */
 	frame->sf.gprs[8] = (unsigned long) ret_from_fork;
-
 	/* fake return stack for resume(), don't go back to schedule */
 	frame->sf.gprs[9] = (unsigned long) frame;
 
-	/* Save access registers to new thread structure. */
-	save_access_regs(&p->thread.acrs[0]);
+	/* Store access registers to kernel stack of new process. */
+	if (unlikely(!regs)) {
+		/* kernel thread */
+		memset(&frame->childregs, 0, sizeof(struct pt_regs));
+		frame->childregs.psw.mask = psw_kernel_bits | PSW_MASK_DAT |
+				PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
+		frame->childregs.psw.addr = PSW_ADDR_AMODE |
+				(unsigned long) kernel_thread_starter;
+		frame->childregs.gprs[9] = new_stackp; /* function */
+		frame->childregs.gprs[10] = arg;
+		frame->childregs.gprs[11] = (unsigned long) do_exit;
+		frame->childregs.orig_gpr2 = -1;
+
+		return 0;
+	}
+	frame->childregs = *regs;
+	frame->childregs.gprs[2] = 0;	/* child returns 0 on fork. */
+	frame->childregs.gprs[15] = new_stackp;
 
 	/* Don't copy runtime instrumentation info */
 	p->thread.ri_cb = NULL;
@@ -202,17 +197,6 @@
 		}
 	}
 #endif /* CONFIG_64BIT */
-	/* start new process with ar4 pointing to the correct address space */
-	p->thread.mm_segment = get_fs();
-	/* Don't copy debug registers */
-	memset(&p->thread.per_user, 0, sizeof(p->thread.per_user));
-	memset(&p->thread.per_event, 0, sizeof(p->thread.per_event));
-	clear_tsk_thread_flag(p, TIF_SINGLE_STEP);
-	clear_tsk_thread_flag(p, TIF_PER_TRAP);
-	/* Initialize per thread user and system timer values */
-	ti = task_thread_info(p);
-	ti->user_timer = 0;
-	ti->system_timer = 0;
 	return 0;
 }
 
@@ -258,31 +242,6 @@
 }
 
 /*
- * sys_execve() executes a new program.
- */
-SYSCALL_DEFINE3(execve, const char __user *, name,
-		const char __user *const __user *, argv,
-		const char __user *const __user *, envp)
-{
-	struct pt_regs *regs = task_pt_regs(current);
-	char *filename;
-	long rc;
-
-	filename = getname(name);
-	rc = PTR_ERR(filename);
-	if (IS_ERR(filename))
-		return rc;
-	rc = do_execve(filename, argv, envp, regs);
-	if (rc)
-		goto out;
-	execve_tail();
-	rc = regs->gprs[2];
-out:
-	putname(filename);
-	return rc;
-}
-
-/*
  * fill in the FPU structure for a core dump.
  */
 int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs)
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index afa9fdb..b1f2be9 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -105,6 +105,11 @@
 struct page *vmemmap;
 EXPORT_SYMBOL(vmemmap);
 
+#ifdef CONFIG_64BIT
+unsigned long MODULES_VADDR;
+unsigned long MODULES_END;
+#endif
+
 /* An array with a pointer to the lowcore of every CPU. */
 struct _lowcore *lowcore_ptr[NR_CPUS];
 EXPORT_SYMBOL(lowcore_ptr);
@@ -544,19 +549,23 @@
 
 	/* Choose kernel address space layout: 2, 3, or 4 levels. */
 #ifdef CONFIG_64BIT
-	vmalloc_size = VMALLOC_END ?: 128UL << 30;
+	vmalloc_size = VMALLOC_END ?: (128UL << 30) - MODULES_LEN;
 	tmp = (memory_end ?: real_memory_size) / PAGE_SIZE;
 	tmp = tmp * (sizeof(struct page) + PAGE_SIZE) + vmalloc_size;
 	if (tmp <= (1UL << 42))
 		vmax = 1UL << 42;	/* 3-level kernel page table */
 	else
 		vmax = 1UL << 53;	/* 4-level kernel page table */
+	/* module area is at the end of the kernel address space. */
+	MODULES_END = vmax;
+	MODULES_VADDR = MODULES_END - MODULES_LEN;
+	VMALLOC_END = MODULES_VADDR;
 #else
 	vmalloc_size = VMALLOC_END ?: 96UL << 20;
 	vmax = 1UL << 31;		/* 2-level kernel page table */
-#endif
 	/* vmalloc area is at the end of the kernel address space. */
 	VMALLOC_END = vmax;
+#endif
 	VMALLOC_START = vmax - vmalloc_size;
 
 	/* Split remaining virtual space between 1:1 mapping & vmemmap array */
@@ -768,6 +777,40 @@
 #endif
 }
 
+static void __init init_storage_keys(unsigned long start, unsigned long end)
+{
+	unsigned long boundary, function, size;
+
+	while (start < end) {
+		if (MACHINE_HAS_EDAT2) {
+			/* set storage keys for a 2GB frame */
+			function = 0x22000 | PAGE_DEFAULT_KEY;
+			size = 1UL << 31;
+			boundary = (start + size) & ~(size - 1);
+			if (boundary <= end) {
+				do {
+					start = pfmf(function, start);
+				} while (start < boundary);
+				continue;
+			}
+		}
+		if (MACHINE_HAS_EDAT1) {
+			/* set storage keys for a 1MB frame */
+			function = 0x21000 | PAGE_DEFAULT_KEY;
+			size = 1UL << 20;
+			boundary = (start + size) & ~(size - 1);
+			if (boundary <= end) {
+				do {
+					start = pfmf(function, start);
+				} while (start < boundary);
+				continue;
+			}
+		}
+		page_set_storage_key(start, PAGE_DEFAULT_KEY, 0);
+		start += PAGE_SIZE;
+	}
+}
+
 static void __init setup_memory(void)
 {
         unsigned long bootmap_size;
@@ -846,9 +889,7 @@
 		memblock_add_node(PFN_PHYS(start_chunk),
 				  PFN_PHYS(end_chunk - start_chunk), 0);
 		pfn = max(start_chunk, start_pfn);
-		for (; pfn < end_chunk; pfn++)
-			page_set_storage_key(PFN_PHYS(pfn),
-					     PAGE_DEFAULT_KEY, 0);
+		init_storage_keys(PFN_PHYS(pfn), PFN_PHYS(end_chunk));
 	}
 
 	psw_set_key(PAGE_DEFAULT_KEY);
diff --git a/arch/s390/mm/Makefile b/arch/s390/mm/Makefile
index 0f5536b..1bea6d1 100644
--- a/arch/s390/mm/Makefile
+++ b/arch/s390/mm/Makefile
@@ -7,3 +7,4 @@
 obj-$(CONFIG_CMM) += cmm.o
 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
 obj-$(CONFIG_DEBUG_SET_MODULE_RONX) += pageattr.o
+obj-$(CONFIG_S390_PTDUMP) += dump_pagetables.o
diff --git a/arch/s390/mm/dump_pagetables.c b/arch/s390/mm/dump_pagetables.c
new file mode 100644
index 0000000..cbc6668
--- /dev/null
+++ b/arch/s390/mm/dump_pagetables.c
@@ -0,0 +1,226 @@
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <asm/sections.h>
+#include <asm/pgtable.h>
+
+static unsigned long max_addr;
+
+struct addr_marker {
+	unsigned long start_address;
+	const char *name;
+};
+
+enum address_markers_idx {
+	IDENTITY_NR = 0,
+	KERNEL_START_NR,
+	KERNEL_END_NR,
+	VMEMMAP_NR,
+	VMALLOC_NR,
+#ifdef CONFIG_64BIT
+	MODULES_NR,
+#endif
+};
+
+static struct addr_marker address_markers[] = {
+	[IDENTITY_NR]	  = {0, "Identity Mapping"},
+	[KERNEL_START_NR] = {(unsigned long)&_stext, "Kernel Image Start"},
+	[KERNEL_END_NR]	  = {(unsigned long)&_end, "Kernel Image End"},
+	[VMEMMAP_NR]	  = {0, "vmemmap Area"},
+	[VMALLOC_NR]	  = {0, "vmalloc Area"},
+#ifdef CONFIG_64BIT
+	[MODULES_NR]	  = {0, "Modules Area"},
+#endif
+	{ -1, NULL }
+};
+
+struct pg_state {
+	int level;
+	unsigned int current_prot;
+	unsigned long start_address;
+	unsigned long current_address;
+	const struct addr_marker *marker;
+};
+
+static void print_prot(struct seq_file *m, unsigned int pr, int level)
+{
+	static const char * const level_name[] =
+		{ "ASCE", "PGD", "PUD", "PMD", "PTE" };
+
+	seq_printf(m, "%s ", level_name[level]);
+	if (pr & _PAGE_INVALID)
+		seq_printf(m, "I\n");
+	else
+		seq_printf(m, "%s\n", pr & _PAGE_RO ? "RO" : "RW");
+}
+
+static void note_page(struct seq_file *m, struct pg_state *st,
+		     unsigned int new_prot, int level)
+{
+	static const char units[] = "KMGTPE";
+	int width = sizeof(unsigned long) * 2;
+	const char *unit = units;
+	unsigned int prot, cur;
+	unsigned long delta;
+
+	/*
+	 * If we have a "break" in the series, we need to flush the state
+	 * that we have now. "break" is either changing perms, levels or
+	 * address space marker.
+	 */
+	prot = new_prot;
+	cur = st->current_prot;
+
+	if (!st->level) {
+		/* First entry */
+		st->current_prot = new_prot;
+		st->level = level;
+		st->marker = address_markers;
+		seq_printf(m, "---[ %s ]---\n", st->marker->name);
+	} else if (prot != cur || level != st->level ||
+		   st->current_address >= st->marker[1].start_address) {
+		/* Print the actual finished series */
+		seq_printf(m, "0x%0*lx-0x%0*lx",
+			   width, st->start_address,
+			   width, st->current_address);
+		delta = (st->current_address - st->start_address) >> 10;
+		while (!(delta & 0x3ff) && unit[1]) {
+			delta >>= 10;
+			unit++;
+		}
+		seq_printf(m, "%9lu%c ", delta, *unit);
+		print_prot(m, st->current_prot, st->level);
+		if (st->current_address >= st->marker[1].start_address) {
+			st->marker++;
+			seq_printf(m, "---[ %s ]---\n", st->marker->name);
+		}
+		st->start_address = st->current_address;
+		st->current_prot = new_prot;
+		st->level = level;
+	}
+}
+
+/*
+ * The actual page table walker functions. In order to keep the implementation
+ * of print_prot() short, we only check and pass _PAGE_INVALID and _PAGE_RO
+ * flags to note_page() if a region, segment or page table entry is invalid or
+ * read-only.
+ * After all it's just a hint that the current level being walked contains an
+ * invalid or read-only entry.
+ */
+static void walk_pte_level(struct seq_file *m, struct pg_state *st,
+			   pmd_t *pmd, unsigned long addr)
+{
+	unsigned int prot;
+	pte_t *pte;
+	int i;
+
+	for (i = 0; i < PTRS_PER_PTE && addr < max_addr; i++) {
+		st->current_address = addr;
+		pte = pte_offset_kernel(pmd, addr);
+		prot = pte_val(*pte) & (_PAGE_RO | _PAGE_INVALID);
+		note_page(m, st, prot, 4);
+		addr += PAGE_SIZE;
+	}
+}
+
+static void walk_pmd_level(struct seq_file *m, struct pg_state *st,
+			   pud_t *pud, unsigned long addr)
+{
+	unsigned int prot;
+	pmd_t *pmd;
+	int i;
+
+	for (i = 0; i < PTRS_PER_PMD && addr < max_addr; i++) {
+		st->current_address = addr;
+		pmd = pmd_offset(pud, addr);
+		if (!pmd_none(*pmd)) {
+			if (pmd_large(*pmd)) {
+				prot = pmd_val(*pmd) & _SEGMENT_ENTRY_RO;
+				note_page(m, st, prot, 3);
+			} else
+				walk_pte_level(m, st, pmd, addr);
+		} else
+			note_page(m, st, _PAGE_INVALID, 3);
+		addr += PMD_SIZE;
+	}
+}
+
+static void walk_pud_level(struct seq_file *m, struct pg_state *st,
+			   pgd_t *pgd, unsigned long addr)
+{
+	pud_t *pud;
+	int i;
+
+	for (i = 0; i < PTRS_PER_PUD && addr < max_addr; i++) {
+		st->current_address = addr;
+		pud = pud_offset(pgd, addr);
+		if (!pud_none(*pud))
+			walk_pmd_level(m, st, pud, addr);
+		else
+			note_page(m, st, _PAGE_INVALID, 2);
+		addr += PUD_SIZE;
+	}
+}
+
+static void walk_pgd_level(struct seq_file *m)
+{
+	unsigned long addr = 0;
+	struct pg_state st;
+	pgd_t *pgd;
+	int i;
+
+	memset(&st, 0, sizeof(st));
+	for (i = 0; i < PTRS_PER_PGD && addr < max_addr; i++) {
+		st.current_address = addr;
+		pgd = pgd_offset_k(addr);
+		if (!pgd_none(*pgd))
+			walk_pud_level(m, &st, pgd, addr);
+		else
+			note_page(m, &st, _PAGE_INVALID, 1);
+		addr += PGDIR_SIZE;
+	}
+	/* Flush out the last page */
+	st.current_address = max_addr;
+	note_page(m, &st, 0, 0);
+}
+
+static int ptdump_show(struct seq_file *m, void *v)
+{
+	walk_pgd_level(m);
+	return 0;
+}
+
+static int ptdump_open(struct inode *inode, struct file *filp)
+{
+	return single_open(filp, ptdump_show, NULL);
+}
+
+static const struct file_operations ptdump_fops = {
+	.open		= ptdump_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int pt_dump_init(void)
+{
+	/*
+	 * Figure out the maximum virtual address being accessible with the
+	 * kernel ASCE. We need this to keep the page table walker functions
+	 * from accessing non-existent entries.
+	 */
+#ifdef CONFIG_32BIT
+	max_addr = 1UL << 31;
+#else
+	max_addr = (S390_lowcore.kernel_asce & _REGION_ENTRY_TYPE_MASK) >> 2;
+	max_addr = 1UL << (max_addr * 11 + 31);
+	address_markers[MODULES_NR].start_address = MODULES_VADDR;
+#endif
+	address_markers[VMEMMAP_NR].start_address = (unsigned long) vmemmap;
+	address_markers[VMALLOC_NR].start_address = VMALLOC_START;
+	debugfs_create_file("kernel_page_tables", 0400, NULL, NULL, &ptdump_fops);
+	return 0;
+}
+device_initcall(pt_dump_init);
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index ac9122c..04ad400 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -367,6 +367,7 @@
 			/* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
 			 * of starvation. */
 			flags &= ~FAULT_FLAG_ALLOW_RETRY;
+			flags |= FAULT_FLAG_TRIED;
 			down_read(&mm->mmap_sem);
 			goto retry;
 		}
diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c
index eeaf802..60acb93 100644
--- a/arch/s390/mm/gup.c
+++ b/arch/s390/mm/gup.c
@@ -115,7 +115,16 @@
 		pmd = *pmdp;
 		barrier();
 		next = pmd_addr_end(addr, end);
-		if (pmd_none(pmd))
+		/*
+		 * The pmd_trans_splitting() check below explains why
+		 * pmdp_splitting_flush() has to serialize with
+		 * smp_call_function() against our disabled IRQs, to stop
+		 * this gup-fast code from running while we set the
+		 * splitting bit in the pmd. Returning zero will take
+		 * the slow path that will call wait_split_huge_page()
+		 * if the pmd is still in splitting state.
+		 */
+		if (pmd_none(pmd) || pmd_trans_splitting(pmd))
 			return 0;
 		if (unlikely(pmd_huge(pmd))) {
 			if (!gup_huge_pmd(pmdp, pmd, addr, next,
diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c
index b36537a..00be01c 100644
--- a/arch/s390/mm/pageattr.c
+++ b/arch/s390/mm/pageattr.c
@@ -8,25 +8,38 @@
 #include <asm/cacheflush.h>
 #include <asm/pgtable.h>
 
+static pte_t *walk_page_table(unsigned long addr)
+{
+	pgd_t *pgdp;
+	pud_t *pudp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	pgdp = pgd_offset_k(addr);
+	if (pgd_none(*pgdp))
+		return NULL;
+	pudp = pud_offset(pgdp, addr);
+	if (pud_none(*pudp))
+		return NULL;
+	pmdp = pmd_offset(pudp, addr);
+	if (pmd_none(*pmdp) || pmd_large(*pmdp))
+		return NULL;
+	ptep = pte_offset_kernel(pmdp, addr);
+	if (pte_none(*ptep))
+		return NULL;
+	return ptep;
+}
+
 static void change_page_attr(unsigned long addr, int numpages,
 			     pte_t (*set) (pte_t))
 {
 	pte_t *ptep, pte;
-	pmd_t *pmdp;
-	pud_t *pudp;
-	pgd_t *pgdp;
 	int i;
 
 	for (i = 0; i < numpages; i++) {
-		pgdp = pgd_offset(&init_mm, addr);
-		pudp = pud_offset(pgdp, addr);
-		pmdp = pmd_offset(pudp, addr);
-		if (pmd_huge(*pmdp)) {
-			WARN_ON_ONCE(1);
-			continue;
-		}
-		ptep = pte_offset_kernel(pmdp, addr);
-
+		ptep = walk_page_table(addr);
+		if (WARN_ON_ONCE(!ptep))
+			break;
 		pte = *ptep;
 		pte = set(pte);
 		__ptep_ipte(addr, ptep);
@@ -40,21 +53,18 @@
 	change_page_attr(addr, numpages, pte_wrprotect);
 	return 0;
 }
-EXPORT_SYMBOL_GPL(set_memory_ro);
 
 int set_memory_rw(unsigned long addr, int numpages)
 {
 	change_page_attr(addr, numpages, pte_mkwrite);
 	return 0;
 }
-EXPORT_SYMBOL_GPL(set_memory_rw);
 
 /* not possible */
 int set_memory_nx(unsigned long addr, int numpages)
 {
 	return 0;
 }
-EXPORT_SYMBOL_GPL(set_memory_nx);
 
 int set_memory_x(unsigned long addr, int numpages)
 {
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index b402991..c8188a1 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -787,6 +787,30 @@
 		tlb_table_flush(tlb);
 }
 
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+void thp_split_vma(struct vm_area_struct *vma)
+{
+	unsigned long addr;
+	struct page *page;
+
+	for (addr = vma->vm_start; addr < vma->vm_end; addr += PAGE_SIZE) {
+		page = follow_page(vma, addr, FOLL_SPLIT);
+	}
+}
+
+void thp_split_mm(struct mm_struct *mm)
+{
+	struct vm_area_struct *vma = mm->mmap;
+
+	while (vma != NULL) {
+		thp_split_vma(vma);
+		vma->vm_flags &= ~VM_HUGEPAGE;
+		vma->vm_flags |= VM_NOHUGEPAGE;
+		vma = vma->vm_next;
+	}
+}
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+
 /*
  * switch on pgstes for its userspace process (for kvm)
  */
@@ -824,6 +848,12 @@
 	if (!mm)
 		return -ENOMEM;
 
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+	/* split thp mappings and disable thp for future mappings */
+	thp_split_mm(mm);
+	mm->def_flags |= VM_NOHUGEPAGE;
+#endif
+
 	/* Now lets check again if something happened */
 	task_lock(tsk);
 	if (!tsk->mm || atomic_read(&tsk->mm->mm_users) > 1 ||
@@ -866,3 +896,81 @@
 	return cc == 0;
 }
 #endif /* CONFIG_HIBERNATION && CONFIG_DEBUG_PAGEALLOC */
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+int pmdp_clear_flush_young(struct vm_area_struct *vma, unsigned long address,
+			   pmd_t *pmdp)
+{
+	VM_BUG_ON(address & ~HPAGE_PMD_MASK);
+	/* No need to flush TLB
+	 * On s390 reference bits are in storage key and never in TLB */
+	return pmdp_test_and_clear_young(vma, address, pmdp);
+}
+
+int pmdp_set_access_flags(struct vm_area_struct *vma,
+			  unsigned long address, pmd_t *pmdp,
+			  pmd_t entry, int dirty)
+{
+	VM_BUG_ON(address & ~HPAGE_PMD_MASK);
+
+	if (pmd_same(*pmdp, entry))
+		return 0;
+	pmdp_invalidate(vma, address, pmdp);
+	set_pmd_at(vma->vm_mm, address, pmdp, entry);
+	return 1;
+}
+
+static void pmdp_splitting_flush_sync(void *arg)
+{
+	/* Simply deliver the interrupt */
+}
+
+void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
+			  pmd_t *pmdp)
+{
+	VM_BUG_ON(address & ~HPAGE_PMD_MASK);
+	if (!test_and_set_bit(_SEGMENT_ENTRY_SPLIT_BIT,
+			      (unsigned long *) pmdp)) {
+		/* need to serialize against gup-fast (IRQ disabled) */
+		smp_call_function(pmdp_splitting_flush_sync, NULL, 1);
+	}
+}
+
+void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable)
+{
+	struct list_head *lh = (struct list_head *) pgtable;
+
+	assert_spin_locked(&mm->page_table_lock);
+
+	/* FIFO */
+	if (!mm->pmd_huge_pte)
+		INIT_LIST_HEAD(lh);
+	else
+		list_add(lh, (struct list_head *) mm->pmd_huge_pte);
+	mm->pmd_huge_pte = pgtable;
+}
+
+pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm)
+{
+	struct list_head *lh;
+	pgtable_t pgtable;
+	pte_t *ptep;
+
+	assert_spin_locked(&mm->page_table_lock);
+
+	/* FIFO */
+	pgtable = mm->pmd_huge_pte;
+	lh = (struct list_head *) pgtable;
+	if (list_empty(lh))
+		mm->pmd_huge_pte = NULL;
+	else {
+		mm->pmd_huge_pte = (pgtable_t) lh->next;
+		list_del(lh);
+	}
+	ptep = (pte_t *) pgtable;
+	pte_val(*ptep) = _PAGE_TYPE_EMPTY;
+	ptep++;
+	pte_val(*ptep) = _PAGE_TYPE_EMPTY;
+	return pgtable;
+}
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
index c22abf9..387c7c6 100644
--- a/arch/s390/mm/vmem.c
+++ b/arch/s390/mm/vmem.c
@@ -79,7 +79,8 @@
  */
 static int vmem_add_mem(unsigned long start, unsigned long size, int ro)
 {
-	unsigned long address;
+	unsigned long end = start + size;
+	unsigned long address = start;
 	pgd_t *pg_dir;
 	pud_t *pu_dir;
 	pmd_t *pm_dir;
@@ -87,7 +88,7 @@
 	pte_t  pte;
 	int ret = -ENOMEM;
 
-	for (address = start; address < start + size; address += PAGE_SIZE) {
+	while (address < end) {
 		pg_dir = pgd_offset_k(address);
 		if (pgd_none(*pg_dir)) {
 			pu_dir = vmem_pud_alloc();
@@ -108,12 +109,11 @@
 		pm_dir = pmd_offset(pu_dir, address);
 
 #if defined(CONFIG_64BIT) && !defined(CONFIG_DEBUG_PAGEALLOC)
-		if (MACHINE_HAS_HPAGE && !(address & ~HPAGE_MASK) &&
-		    (address + HPAGE_SIZE <= start + size) &&
-		    (address >= HPAGE_SIZE)) {
+		if (MACHINE_HAS_EDAT1 && pmd_none(*pm_dir) && address &&
+		    !(address & ~PMD_MASK) && (address + PMD_SIZE <= end)) {
 			pte_val(pte) |= _SEGMENT_ENTRY_LARGE;
 			pmd_val(*pm_dir) = pte_val(pte);
-			address += HPAGE_SIZE - PAGE_SIZE;
+			address += PMD_SIZE;
 			continue;
 		}
 #endif
@@ -126,10 +126,11 @@
 
 		pt_dir = pte_offset_kernel(pm_dir, address);
 		*pt_dir = pte;
+		address += PAGE_SIZE;
 	}
 	ret = 0;
 out:
-	flush_tlb_kernel_range(start, start + size);
+	flush_tlb_kernel_range(start, end);
 	return ret;
 }
 
@@ -139,7 +140,8 @@
  */
 static void vmem_remove_range(unsigned long start, unsigned long size)
 {
-	unsigned long address;
+	unsigned long end = start + size;
+	unsigned long address = start;
 	pgd_t *pg_dir;
 	pud_t *pu_dir;
 	pmd_t *pm_dir;
@@ -147,25 +149,32 @@
 	pte_t  pte;
 
 	pte_val(pte) = _PAGE_TYPE_EMPTY;
-	for (address = start; address < start + size; address += PAGE_SIZE) {
+	while (address < end) {
 		pg_dir = pgd_offset_k(address);
-		pu_dir = pud_offset(pg_dir, address);
-		if (pud_none(*pu_dir))
-			continue;
-		pm_dir = pmd_offset(pu_dir, address);
-		if (pmd_none(*pm_dir))
-			continue;
-
-		if (pmd_huge(*pm_dir)) {
-			pmd_clear(pm_dir);
-			address += HPAGE_SIZE - PAGE_SIZE;
+		if (pgd_none(*pg_dir)) {
+			address += PGDIR_SIZE;
 			continue;
 		}
-
+		pu_dir = pud_offset(pg_dir, address);
+		if (pud_none(*pu_dir)) {
+			address += PUD_SIZE;
+			continue;
+		}
+		pm_dir = pmd_offset(pu_dir, address);
+		if (pmd_none(*pm_dir)) {
+			address += PMD_SIZE;
+			continue;
+		}
+		if (pmd_large(*pm_dir)) {
+			pmd_clear(pm_dir);
+			address += PMD_SIZE;
+			continue;
+		}
 		pt_dir = pte_offset_kernel(pm_dir, address);
 		*pt_dir = pte;
+		address += PAGE_SIZE;
 	}
-	flush_tlb_kernel_range(start, start + size);
+	flush_tlb_kernel_range(start, end);
 }
 
 /*
@@ -330,8 +339,8 @@
 	unsigned long start, end;
 	int i;
 
-	ro_start = ((unsigned long)&_stext) & PAGE_MASK;
-	ro_end = PFN_ALIGN((unsigned long)&_eshared);
+	ro_start = PFN_ALIGN((unsigned long)&_stext);
+	ro_end = (unsigned long)&_eshared & PAGE_MASK;
 	for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) {
 		if (memory_chunk[i].type == CHUNK_CRASHK ||
 		    memory_chunk[i].type == CHUNK_OLDMEM)
diff --git a/arch/score/include/asm/Kbuild b/arch/score/include/asm/Kbuild
index b367abd..ec697ae 100644
--- a/arch/score/include/asm/Kbuild
+++ b/arch/score/include/asm/Kbuild
@@ -1,3 +1,5 @@
 include include/asm-generic/Kbuild.asm
 
 header-y +=
+
+generic-y += clkdev.h
diff --git a/arch/score/include/asm/thread_info.h b/arch/score/include/asm/thread_info.h
index a18006e9..1425cc0 100644
--- a/arch/score/include/asm/thread_info.h
+++ b/arch/score/include/asm/thread_info.h
@@ -86,16 +86,12 @@
 #define TIF_NEED_RESCHED	2	/* rescheduling necessary */
 #define TIF_NOTIFY_RESUME	5	/* callback before returning to user */
 #define TIF_RESTORE_SIGMASK	9	/* restore signal mask in do_signal() */
-#define TIF_POLLING_NRFLAG	17	/* true if poll_idle() is polling
-						 TIF_NEED_RESCHED */
 #define TIF_MEMDIE		18	/* is terminating due to OOM killer */
 
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
-#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
-#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 
 #define _TIF_WORK_MASK		(0x0000ffff)
 
diff --git a/arch/score/kernel/signal.c b/arch/score/kernel/signal.c
index e382c52..c268bbf 100644
--- a/arch/score/kernel/signal.c
+++ b/arch/score/kernel/signal.c
@@ -174,6 +174,7 @@
 	/* It is more difficult to avoid calling this function than to
 	   call it and ignore errors.  */
 	do_sigaltstack((stack_t __user *)&st, NULL, regs->regs[0]);
+	regs->is_syscall = 0;
 
 	__asm__ __volatile__(
 		"mv\tr0, %0\n\t"
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 36f5141..3b3e27a 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -13,14 +13,17 @@
 	select HAVE_DMA_ATTRS
 	select HAVE_IRQ_WORK
 	select HAVE_PERF_EVENTS
+	select HAVE_DEBUG_BUGVERBOSE
 	select ARCH_HAVE_CUSTOM_GPIO_H
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG if (GUSA_RB || CPU_SH4A)
 	select PERF_USE_VMALLOC
+	select HAVE_DEBUG_KMEMLEAK
 	select HAVE_KERNEL_GZIP
 	select HAVE_KERNEL_BZIP2
 	select HAVE_KERNEL_LZMA
 	select HAVE_KERNEL_XZ
 	select HAVE_KERNEL_LZO
+	select HAVE_UID16
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select HAVE_SYSCALL_TRACEPOINTS
 	select HAVE_REGS_AND_STACK_ACCESS_API
diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild
index 7b673dd..86eadce 100644
--- a/arch/sh/include/asm/Kbuild
+++ b/arch/sh/include/asm/Kbuild
@@ -7,6 +7,7 @@
 generic-y += div64.h
 generic-y += emergency-restart.h
 generic-y += errno.h
+generic-y += exec.h
 generic-y += fcntl.h
 generic-y += ioctl.h
 generic-y += ipcbuf.h
diff --git a/arch/sh/include/asm/exec.h b/arch/sh/include/asm/exec.h
deleted file mode 100644
index 69486a9..0000000
--- a/arch/sh/include/asm/exec.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Copyright (C) 1999, 2000  Niibe Yutaka  &  Kaz Kojima
- * Copyright (C) 2002 Paul Mundt
- */
-#ifndef __ASM_SH_EXEC_H
-#define __ASM_SH_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* __ASM_SH_EXEC_H */
diff --git a/arch/sh/include/asm/hugetlb.h b/arch/sh/include/asm/hugetlb.h
index 967068f..b3808c7 100644
--- a/arch/sh/include/asm/hugetlb.h
+++ b/arch/sh/include/asm/hugetlb.h
@@ -1,6 +1,7 @@
 #ifndef _ASM_SH_HUGETLB_H
 #define _ASM_SH_HUGETLB_H
 
+#include <asm/cacheflush.h>
 #include <asm/page.h>
 
 
@@ -89,4 +90,9 @@
 {
 }
 
+static inline void arch_clear_hugepage_flags(struct page *page)
+{
+	clear_bit(PG_dcache_clean, &page->flags);
+}
+
 #endif /* _ASM_SH_HUGETLB_H */
diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h
index bc13b57..7d5ac4e 100644
--- a/arch/sh/include/asm/thread_info.h
+++ b/arch/sh/include/asm/thread_info.h
@@ -206,6 +206,9 @@
 	ti->status &= ~TS_RESTORE_SIGMASK;
 	return true;
 }
+
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
+
 #endif	/* !__ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index d6b7b61..2f1f653 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -22,7 +22,6 @@
 #include <linux/elf.h>
 #include <linux/personality.h>
 #include <linux/binfmts.h>
-#include <linux/freezer.h>
 #include <linux/io.h>
 #include <linux/tracehook.h>
 #include <asm/ucontext.h>
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
index 6b5b3df..2385381 100644
--- a/arch/sh/kernel/signal_64.c
+++ b/arch/sh/kernel/signal_64.c
@@ -18,7 +18,6 @@
 #include <linux/errno.h>
 #include <linux/wait.h>
 #include <linux/personality.h>
-#include <linux/freezer.h>
 #include <linux/ptrace.h>
 #include <linux/unistd.h>
 #include <linux/stddef.h>
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index 3bdc1ad..cbbdcad8 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -504,6 +504,7 @@
 		}
 		if (fault & VM_FAULT_RETRY) {
 			flags &= ~FAULT_FLAG_ALLOW_RETRY;
+			flags |= FAULT_FLAG_TRIED;
 
 			/*
 			 * No need to up_read(&mm->mmap_sem) as we would
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 67f1f6f..91c780c 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -18,6 +18,7 @@
 	select HAVE_OPROFILE
 	select HAVE_ARCH_KGDB if !SMP || SPARC64
 	select HAVE_ARCH_TRACEHOOK
+	select SYSCTL_EXCEPTION_TRACE
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select RTC_CLASS
 	select RTC_DRV_M48T59
@@ -32,6 +33,7 @@
 	select GENERIC_PCI_IOMAP
 	select HAVE_NMI_WATCHDOG if SPARC64
 	select HAVE_BPF_JIT
+	select HAVE_DEBUG_BUGVERBOSE
 	select GENERIC_SMP_IDLE_THREAD
 	select GENERIC_CMOS_UPDATE
 	select GENERIC_CLOCKEVENTS
@@ -42,6 +44,7 @@
 	def_bool !64BIT
 	select GENERIC_ATOMIC64
 	select CLZ_TAB
+	select HAVE_UID16
 
 config SPARC64
 	def_bool 64BIT
@@ -59,6 +62,7 @@
 	select HAVE_DYNAMIC_FTRACE
 	select HAVE_FTRACE_MCOUNT_RECORD
 	select HAVE_SYSCALL_TRACEPOINTS
+	select HAVE_DEBUG_KMEMLEAK
 	select RTC_DRV_CMOS
 	select RTC_DRV_BQ4802
 	select RTC_DRV_SUN4V
@@ -226,25 +230,6 @@
 	help
 	  Say Y here to enable a faster early framebuffer boot console.
 
-choice
-	prompt "Kernel page size" if SPARC64
-	default SPARC64_PAGE_SIZE_8KB
-
-config SPARC64_PAGE_SIZE_8KB
-	bool "8KB"
-	help
-	  This lets you select the page size of the kernel.
-
-	  8KB and 64KB work quite well, since SPARC ELF sections
-	  provide for up to 64KB alignment.
-
-	  If you don't know what to do, choose 8KB.
-
-config SPARC64_PAGE_SIZE_64KB
-	bool "64KB"
-
-endchoice
-
 config SECCOMP
 	bool "Enable seccomp to safely compute untrusted bytecode"
 	depends on SPARC64 && PROC_FS
@@ -316,23 +301,6 @@
 	default y
 	depends on SPARC64 && SMP && PREEMPT
 
-choice
-	prompt "SPARC64 Huge TLB Page Size"
-	depends on SPARC64 && HUGETLB_PAGE
-	default HUGETLB_PAGE_SIZE_4MB
-
-config HUGETLB_PAGE_SIZE_4MB
-	bool "4MB"
-
-config HUGETLB_PAGE_SIZE_512K
-	bool "512K"
-
-config HUGETLB_PAGE_SIZE_64K
-	depends on !SPARC64_PAGE_SIZE_64KB
-	bool "64K"
-
-endchoice
-
 config NUMA
 	bool "NUMA support"
 	depends on SPARC64 && SMP
@@ -571,6 +539,7 @@
 	depends on SPARC64
 	default y
 	select COMPAT_BINFMT_ELF
+	select HAVE_UID16
 	select ARCH_WANT_OLD_COMPAT_IPC
 
 config SYSVIPC_COMPAT
diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild
index 67f83e0..10d54e5 100644
--- a/arch/sparc/include/asm/Kbuild
+++ b/arch/sparc/include/asm/Kbuild
@@ -1,23 +1,9 @@
 # User exported sparc header files
-include include/asm-generic/Kbuild.asm
 
-header-y += apc.h
-header-y += asi.h
-header-y += display7seg.h
-header-y += envctrl.h
-header-y += fbio.h
-header-y += jsflash.h
-header-y += openpromio.h
-header-y += perfctr.h
-header-y += psrcompat.h
-header-y += psr.h
-header-y += pstate.h
-header-y += traps.h
-header-y += uctx.h
-header-y += utrap.h
-header-y += watchdog.h
 
+generic-y += clkdev.h
 generic-y += div64.h
+generic-y += exec.h
 generic-y += local64.h
 generic-y += irq_regs.h
 generic-y += local.h
diff --git a/arch/sparc/include/asm/exec.h b/arch/sparc/include/asm/exec.h
deleted file mode 100644
index 2e08588..0000000
--- a/arch/sparc/include/asm/exec.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __SPARC_EXEC_H
-#define __SPARC_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* __SPARC_EXEC_H */
diff --git a/arch/sparc/include/asm/fbio.h b/arch/sparc/include/asm/fbio.h
index 0a21da8..1d9afe2 100644
--- a/arch/sparc/include/asm/fbio.h
+++ b/arch/sparc/include/asm/fbio.h
@@ -1,225 +1,10 @@
 #ifndef __LINUX_FBIO_H
 #define __LINUX_FBIO_H
 
-#include <linux/compiler.h>
-#include <linux/types.h>
+#include <uapi/asm/fbio.h>
 
-/* Constants used for fbio SunOS compatibility */
-/* (C) 1996 Miguel de Icaza */
-
-/* Frame buffer types */
-#define FBTYPE_NOTYPE           -1
-#define FBTYPE_SUN1BW           0   /* mono */
-#define FBTYPE_SUN1COLOR        1 
-#define FBTYPE_SUN2BW           2 
-#define FBTYPE_SUN2COLOR        3 
-#define FBTYPE_SUN2GP           4 
-#define FBTYPE_SUN5COLOR        5 
-#define FBTYPE_SUN3COLOR        6 
-#define FBTYPE_MEMCOLOR         7 
-#define FBTYPE_SUN4COLOR        8 
- 
-#define FBTYPE_NOTSUN1          9 
-#define FBTYPE_NOTSUN2          10
-#define FBTYPE_NOTSUN3          11
- 
-#define FBTYPE_SUNFAST_COLOR    12  /* cg6 */
-#define FBTYPE_SUNROP_COLOR     13
-#define FBTYPE_SUNFB_VIDEO      14
-#define FBTYPE_SUNGIFB          15
-#define FBTYPE_SUNGPLAS         16
-#define FBTYPE_SUNGP3           17
-#define FBTYPE_SUNGT            18
-#define FBTYPE_SUNLEO           19      /* zx Leo card */
-#define FBTYPE_MDICOLOR         20      /* cg14 */
-#define FBTYPE_TCXCOLOR		21	/* SUNW,tcx card */
-
-#define FBTYPE_LASTPLUSONE      21	/* This is not last + 1 in fact... */
-
-/* Does not seem to be listed in the Sun file either */
-#define FBTYPE_CREATOR          22
-#define FBTYPE_PCI_IGA1682	23
-#define FBTYPE_P9100COLOR	24
-
-#define FBTYPE_PCI_GENERIC	1000
-#define FBTYPE_PCI_MACH64	1001
-
-/* fbio ioctls */
-/* Returned by FBIOGTYPE */
-struct  fbtype {
-        int     fb_type;        /* fb type, see above */
-        int     fb_height;      /* pixels */
-        int     fb_width;       /* pixels */
-        int     fb_depth;
-        int     fb_cmsize;      /* color map entries */
-        int     fb_size;        /* fb size in bytes */
-};
-#define FBIOGTYPE _IOR('F', 0, struct fbtype)
-
-struct  fbcmap {
-        int             index;          /* first element (0 origin) */
-        int             count;
-        unsigned char   __user *red;
-        unsigned char   __user *green;
-        unsigned char   __user *blue;
-};
-
-#ifdef __KERNEL__
 #define FBIOPUTCMAP_SPARC _IOW('F', 3, struct fbcmap)
 #define FBIOGETCMAP_SPARC _IOW('F', 4, struct fbcmap)
-#else
-#define FBIOPUTCMAP _IOW('F', 3, struct fbcmap)
-#define FBIOGETCMAP _IOW('F', 4, struct fbcmap)
-#endif
-
-/* # of device specific values */
-#define FB_ATTR_NDEVSPECIFIC    8
-/* # of possible emulations */
-#define FB_ATTR_NEMUTYPES       4
- 
-struct fbsattr {
-        int     flags;
-        int     emu_type;	/* -1 if none */
-        int     dev_specific[FB_ATTR_NDEVSPECIFIC];
-};
- 
-struct fbgattr {
-        int     real_type;	/* real frame buffer type */
-        int     owner;		/* unknown */
-        struct fbtype fbtype;	/* real frame buffer fbtype */
-        struct fbsattr sattr;   
-        int     emu_types[FB_ATTR_NEMUTYPES]; /* supported emulations */
-};
-#define FBIOSATTR  _IOW('F', 5, struct fbgattr) /* Unsupported: */
-#define FBIOGATTR  _IOR('F', 6, struct fbgattr)	/* supported */
-
-#define FBIOSVIDEO _IOW('F', 7, int)
-#define FBIOGVIDEO _IOR('F', 8, int)
-
-struct fbcursor {
-        short set;              /* what to set, choose from the list above */
-        short enable;           /* cursor on/off */
-        struct fbcurpos pos;    /* cursor position */
-        struct fbcurpos hot;    /* cursor hot spot */
-        struct fbcmap cmap;     /* color map info */
-        struct fbcurpos size;   /* cursor bit map size */
-        char __user *image;     /* cursor image bits */
-        char __user *mask;      /* cursor mask bits */
-};
-
-/* set/get cursor attributes/shape */
-#define FBIOSCURSOR     _IOW('F', 24, struct fbcursor)
-#define FBIOGCURSOR     _IOWR('F', 25, struct fbcursor)
- 
-/* set/get cursor position */
-#define FBIOSCURPOS     _IOW('F', 26, struct fbcurpos)
-#define FBIOGCURPOS     _IOW('F', 27, struct fbcurpos)
- 
-/* get max cursor size */
-#define FBIOGCURMAX     _IOR('F', 28, struct fbcurpos)
-
-/* wid manipulation */
-struct fb_wid_alloc {
-#define FB_WID_SHARED_8		0
-#define FB_WID_SHARED_24	1
-#define FB_WID_DBL_8		2
-#define FB_WID_DBL_24		3
-	__u32	wa_type;
-	__s32	wa_index;	/* Set on return */
-	__u32	wa_count;	
-};
-struct fb_wid_item {
-	__u32	wi_type;
-	__s32	wi_index;
-	__u32	wi_attrs;
-	__u32	wi_values[32];
-};
-struct fb_wid_list {
-	__u32	wl_flags;
-	__u32	wl_count;
-	struct fb_wid_item	*wl_list;
-};
-
-#define FBIO_WID_ALLOC	_IOWR('F', 30, struct fb_wid_alloc)
-#define FBIO_WID_FREE	_IOW('F', 31, struct fb_wid_alloc)
-#define FBIO_WID_PUT	_IOW('F', 32, struct fb_wid_list)
-#define FBIO_WID_GET	_IOWR('F', 33, struct fb_wid_list)
-
-/* Creator ioctls */
-#define FFB_IOCTL	('F'<<8)
-#define FFB_SYS_INFO		(FFB_IOCTL|80)
-#define FFB_CLUTREAD		(FFB_IOCTL|81)
-#define FFB_CLUTPOST		(FFB_IOCTL|82)
-#define FFB_SETDIAGMODE		(FFB_IOCTL|83)
-#define FFB_GETMONITORID	(FFB_IOCTL|84)
-#define FFB_GETVIDEOMODE	(FFB_IOCTL|85)
-#define FFB_SETVIDEOMODE	(FFB_IOCTL|86)
-#define FFB_SETSERVER		(FFB_IOCTL|87)
-#define FFB_SETOVCTL		(FFB_IOCTL|88)
-#define FFB_GETOVCTL		(FFB_IOCTL|89)
-#define FFB_GETSAXNUM		(FFB_IOCTL|90)
-#define FFB_FBDEBUG		(FFB_IOCTL|91)
-
-/* Cg14 ioctls */
-#define MDI_IOCTL          ('M'<<8)
-#define MDI_RESET          (MDI_IOCTL|1)
-#define MDI_GET_CFGINFO    (MDI_IOCTL|2)
-#define MDI_SET_PIXELMODE  (MDI_IOCTL|3)
-#    define MDI_32_PIX     32
-#    define MDI_16_PIX     16
-#    define MDI_8_PIX      8
-
-struct mdi_cfginfo {
-	int     mdi_ncluts;     /* Number of implemented CLUTs in this MDI */
-        int     mdi_type;       /* FBTYPE name */
-        int     mdi_height;     /* height */
-        int     mdi_width;      /* width */
-        int     mdi_size;       /* available ram */
-        int     mdi_mode;       /* 8bpp, 16bpp or 32bpp */
-        int     mdi_pixfreq;    /* pixel clock (from PROM) */
-};
-
-/* SparcLinux specific ioctl for the MDI, should be replaced for
- * the SET_XLUT/SET_CLUTn ioctls instead
- */
-#define MDI_CLEAR_XLUT       (MDI_IOCTL|9)
-
-/* leo & ffb ioctls */
-struct fb_clut_alloc {
-	__u32	clutid;	/* Set on return */
- 	__u32	flag;
- 	__u32	index;
-};
-
-struct fb_clut {
-#define FB_CLUT_WAIT	0x00000001	/* Not yet implemented */
- 	__u32	flag;
- 	__u32	clutid;
- 	__u32	offset;
- 	__u32	count;
- 	char *	red;
- 	char *	green;
- 	char *	blue;
-};
-
-struct fb_clut32 {
- 	__u32	flag;
- 	__u32	clutid;
- 	__u32	offset;
- 	__u32	count;
- 	__u32	red;
- 	__u32	green;
- 	__u32	blue;
-};
-
-#define LEO_CLUTALLOC	_IOWR('L', 53, struct fb_clut_alloc)
-#define LEO_CLUTFREE	_IOW('L', 54, struct fb_clut_alloc)
-#define LEO_CLUTREAD	_IOW('L', 55, struct fb_clut)
-#define LEO_CLUTPOST	_IOW('L', 56, struct fb_clut)
-#define LEO_SETGAMMA	_IOW('L', 68, int) /* Not yet implemented */
-#define LEO_GETGAMMA	_IOR('L', 69, int) /* Not yet implemented */
-
-#ifdef __KERNEL__
 /* Addresses on the fd of a cgsix that are mappable */
 #define CG6_FBC    0x70000000
 #define CG6_TEC    0x70001000
@@ -260,47 +45,6 @@
 #define CG14_CLUT3       0x6000  /* Color Look Up Table */
 #define CG14_AUTO	 0xf000
 
-#endif /* KERNEL */
-
-/* These are exported to userland for applications to use */
-/* Mappable offsets for the cg14: control registers */
-#define MDI_DIRECT_MAP 0x10000000
-#define MDI_CTLREG_MAP 0x20000000
-#define MDI_CURSOR_MAP 0x30000000
-#define MDI_SHDW_VRT_MAP 0x40000000
-
-/* Mappable offsets for the cg14: frame buffer resolutions */
-/* 32 bits */
-#define MDI_CHUNKY_XBGR_MAP 0x50000000
-#define MDI_CHUNKY_BGR_MAP 0x60000000
-
-/* 16 bits */
-#define MDI_PLANAR_X16_MAP 0x70000000
-#define MDI_PLANAR_C16_MAP 0x80000000
-
-/* 8 bit is done as CG3 MMAP offset */
-/* 32 bits, planar */
-#define MDI_PLANAR_X32_MAP 0x90000000
-#define MDI_PLANAR_B32_MAP 0xa0000000
-#define MDI_PLANAR_G32_MAP 0xb0000000
-#define MDI_PLANAR_R32_MAP 0xc0000000
-
-/* Mappable offsets on leo */
-#define LEO_SS0_MAP            0x00000000
-#define LEO_LC_SS0_USR_MAP     0x00800000
-#define LEO_LD_SS0_MAP         0x00801000
-#define LEO_LX_CURSOR_MAP      0x00802000
-#define LEO_SS1_MAP            0x00803000
-#define LEO_LC_SS1_USR_MAP     0x01003000
-#define LEO_LD_SS1_MAP         0x01004000
-#define LEO_UNK_MAP            0x01005000
-#define LEO_LX_KRN_MAP         0x01006000
-#define LEO_LC_SS0_KRN_MAP     0x01007000
-#define LEO_LC_SS1_KRN_MAP     0x01008000
-#define LEO_LD_GBL_MAP         0x01009000
-#define LEO_UNK2_MAP           0x0100a000
-
-#ifdef __KERNEL__
 struct  fbcmap32 {
 	int             index;          /* first element (0 origin) */
 	int             count;
@@ -325,6 +69,4 @@
 
 #define FBIOSCURSOR32	_IOW('F', 24, struct fbcursor32)
 #define FBIOGCURSOR32	_IOW('F', 25, struct fbcursor32)
-#endif
-
 #endif /* __LINUX_FBIO_H */
diff --git a/arch/sparc/include/asm/hugetlb.h b/arch/sparc/include/asm/hugetlb.h
index 1770610..8c5eed6 100644
--- a/arch/sparc/include/asm/hugetlb.h
+++ b/arch/sparc/include/asm/hugetlb.h
@@ -10,7 +10,10 @@
 pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
 			      pte_t *ptep);
 
-void hugetlb_prefault_arch_hook(struct mm_struct *mm);
+static inline void hugetlb_prefault_arch_hook(struct mm_struct *mm)
+{
+	hugetlb_setup(mm);
+}
 
 static inline int is_hugepage_only_range(struct mm_struct *mm,
 					 unsigned long addr,
@@ -82,4 +85,8 @@
 {
 }
 
+static inline void arch_clear_hugepage_flags(struct page *page)
+{
+}
+
 #endif /* _ASM_SPARC64_HUGETLB_H */
diff --git a/arch/sparc/include/asm/ioctls.h b/arch/sparc/include/asm/ioctls.h
index 28d0c8b..77413b7 100644
--- a/arch/sparc/include/asm/ioctls.h
+++ b/arch/sparc/include/asm/ioctls.h
@@ -1,123 +1,8 @@
 #ifndef _ASM_SPARC_IOCTLS_H
 #define _ASM_SPARC_IOCTLS_H
 
-#include <asm/ioctl.h>
+#include <uapi/asm/ioctls.h>
 
-/* Big T */
-#define TCGETA		_IOR('T', 1, struct termio)
-#define TCSETA		_IOW('T', 2, struct termio)
-#define TCSETAW		_IOW('T', 3, struct termio)
-#define TCSETAF		_IOW('T', 4, struct termio)
-#define TCSBRK		_IO('T', 5)
-#define TCXONC		_IO('T', 6)
-#define TCFLSH		_IO('T', 7)
-#define TCGETS		_IOR('T', 8, struct termios)
-#define TCSETS		_IOW('T', 9, struct termios)
-#define TCSETSW		_IOW('T', 10, struct termios)
-#define TCSETSF		_IOW('T', 11, struct termios)
-#define TCGETS2		_IOR('T', 12, struct termios2)
-#define TCSETS2		_IOW('T', 13, struct termios2)
-#define TCSETSW2	_IOW('T', 14, struct termios2)
-#define TCSETSF2	_IOW('T', 15, struct termios2)
-#define TIOCGDEV	_IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */
-#define TIOCVHANGUP	_IO('T', 0x37)
-
-/* Note that all the ioctls that are not available in Linux have a 
- * double underscore on the front to: a) avoid some programs to
- * think we support some ioctls under Linux (autoconfiguration stuff)
- */
-/* Little t */
-#define TIOCGETD	_IOR('t', 0, int)
-#define TIOCSETD	_IOW('t', 1, int)
-#define __TIOCHPCL        _IO('t', 2) /* SunOS Specific */
-#define __TIOCMODG        _IOR('t', 3, int) /* SunOS Specific */
-#define __TIOCMODS        _IOW('t', 4, int) /* SunOS Specific */
-#define __TIOCGETP        _IOR('t', 8, struct sgttyb) /* SunOS Specific */
-#define __TIOCSETP        _IOW('t', 9, struct sgttyb) /* SunOS Specific */
-#define __TIOCSETN        _IOW('t', 10, struct sgttyb) /* SunOS Specific */
-#define TIOCEXCL	_IO('t', 13)
-#define TIOCNXCL	_IO('t', 14)
-#define __TIOCFLUSH       _IOW('t', 16, int) /* SunOS Specific */
-#define __TIOCSETC        _IOW('t', 17, struct tchars) /* SunOS Specific */
-#define __TIOCGETC        _IOR('t', 18, struct tchars) /* SunOS Specific */
-#define __TIOCTCNTL       _IOW('t', 32, int) /* SunOS Specific */
-#define __TIOCSIGNAL      _IOW('t', 33, int) /* SunOS Specific */
-#define __TIOCSETX        _IOW('t', 34, int) /* SunOS Specific */
-#define __TIOCGETX        _IOR('t', 35, int) /* SunOS Specific */
-#define TIOCCONS	_IO('t', 36)
-#define TIOCGSOFTCAR	_IOR('t', 100, int)
-#define TIOCSSOFTCAR	_IOW('t', 101, int)
-#define __TIOCUCNTL       _IOW('t', 102, int) /* SunOS Specific */
-#define TIOCSWINSZ	_IOW('t', 103, struct winsize)
-#define TIOCGWINSZ	_IOR('t', 104, struct winsize)
-#define __TIOCREMOTE      _IOW('t', 105, int) /* SunOS Specific */
-#define TIOCMGET	_IOR('t', 106, int)
-#define TIOCMBIC	_IOW('t', 107, int)
-#define TIOCMBIS	_IOW('t', 108, int)
-#define TIOCMSET	_IOW('t', 109, int)
-#define TIOCSTART       _IO('t', 110)
-#define TIOCSTOP        _IO('t', 111)
-#define TIOCPKT		_IOW('t', 112, int)
-#define TIOCNOTTY	_IO('t', 113)
-#define TIOCSTI		_IOW('t', 114, char)
-#define TIOCOUTQ	_IOR('t', 115, int)
-#define __TIOCGLTC        _IOR('t', 116, struct ltchars) /* SunOS Specific */
-#define __TIOCSLTC        _IOW('t', 117, struct ltchars) /* SunOS Specific */
-/* 118 is the non-posix setpgrp tty ioctl */
-/* 119 is the non-posix getpgrp tty ioctl */
-#define __TIOCCDTR        _IO('t', 120) /* SunOS Specific */
-#define __TIOCSDTR        _IO('t', 121) /* SunOS Specific */
-#define TIOCCBRK        _IO('t', 122)
-#define TIOCSBRK        _IO('t', 123)
-#define __TIOCLGET        _IOW('t', 124, int) /* SunOS Specific */
-#define __TIOCLSET        _IOW('t', 125, int) /* SunOS Specific */
-#define __TIOCLBIC        _IOW('t', 126, int) /* SunOS Specific */
-#define __TIOCLBIS        _IOW('t', 127, int) /* SunOS Specific */
-#define __TIOCISPACE      _IOR('t', 128, int) /* SunOS Specific */
-#define __TIOCISIZE       _IOR('t', 129, int) /* SunOS Specific */
-#define TIOCSPGRP	_IOW('t', 130, int)
-#define TIOCGPGRP	_IOR('t', 131, int)
-#define TIOCSCTTY	_IO('t', 132)
-#define TIOCGSID	_IOR('t', 133, int)
-/* Get minor device of a pty master's FD -- Solaris equiv is ISPTM */
-#define TIOCGPTN	_IOR('t', 134, unsigned int) /* Get Pty Number */
-#define TIOCSPTLCK	_IOW('t', 135, int) /* Lock/unlock PTY */
-#define TIOCSIG		_IOW('t', 136, int) /* Generate signal on Pty slave */
-
-/* Little f */
-#define FIOCLEX		_IO('f', 1)
-#define FIONCLEX	_IO('f', 2)
-#define FIOASYNC	_IOW('f', 125, int)
-#define FIONBIO		_IOW('f', 126, int)
-#define FIONREAD	_IOR('f', 127, int)
-#define TIOCINQ		FIONREAD
-#define FIOQSIZE	_IOR('f', 128, loff_t)
-
-/* SCARY Rutgers local SunOS kernel hackery, perhaps I will support it
- * someday.  This is completely bogus, I know...
- */
-#define __TCGETSTAT       _IO('T', 200) /* Rutgers specific */
-#define __TCSETSTAT       _IO('T', 201) /* Rutgers specific */
-
-/* Linux specific, no SunOS equivalent. */
-#define TIOCLINUX	0x541C
-#define TIOCGSERIAL	0x541E
-#define TIOCSSERIAL	0x541F
-#define TCSBRKP		0x5425
-#define TIOCSERCONFIG	0x5453
-#define TIOCSERGWILD	0x5454
-#define TIOCSERSWILD	0x5455
-#define TIOCGLCKTRMIOS	0x5456
-#define TIOCSLCKTRMIOS	0x5457
-#define TIOCSERGSTRUCT	0x5458 /* For debugging only */
-#define TIOCSERGETLSR   0x5459 /* Get line status register */
-#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
-#define TIOCSERSETMULTI 0x545B /* Set multiport config */
-#define TIOCMIWAIT	0x545C /* Wait for change on serial input line(s) */
-#define TIOCGICOUNT	0x545D /* Read serial port inline interrupt counts */
-
-/* Kernel definitions */
-#ifdef __KERNEL__
 #define TIOCGETC __TIOCGETC
 #define TIOCGETP __TIOCGETP
 #define TIOCGLTC __TIOCGLTC
@@ -125,16 +10,4 @@
 #define TIOCSETP __TIOCSETP
 #define TIOCSETN __TIOCSETN
 #define TIOCSETC __TIOCSETC
-#endif
-
-/* Used for packet mode */
-#define TIOCPKT_DATA		 0
-#define TIOCPKT_FLUSHREAD	 1
-#define TIOCPKT_FLUSHWRITE	 2
-#define TIOCPKT_STOP		 4
-#define TIOCPKT_START		 8
-#define TIOCPKT_NOSTOP		16
-#define TIOCPKT_DOSTOP		32
-#define TIOCPKT_IOCTL		64
-
 #endif /* !(_ASM_SPARC_IOCTLS_H) */
diff --git a/arch/sparc/include/asm/mman.h b/arch/sparc/include/asm/mman.h
index c3029ad..59bb593 100644
--- a/arch/sparc/include/asm/mman.h
+++ b/arch/sparc/include/asm/mman.h
@@ -1,33 +1,10 @@
 #ifndef __SPARC_MMAN_H__
 #define __SPARC_MMAN_H__
 
-#include <asm-generic/mman-common.h>
+#include <uapi/asm/mman.h>
 
-/* SunOS'ified... */
-
-#define MAP_RENAME      MAP_ANONYMOUS   /* In SunOS terminology */
-#define MAP_NORESERVE   0x40            /* don't reserve swap pages */
-#define MAP_INHERIT     0x80            /* SunOS doesn't do this, but... */
-#define MAP_LOCKED      0x100           /* lock the mapping */
-#define _MAP_NEW        0x80000000      /* Binary compatibility is fun... */
-
-#define MAP_GROWSDOWN	0x0200		/* stack-like segment */
-#define MAP_DENYWRITE	0x0800		/* ETXTBSY */
-#define MAP_EXECUTABLE	0x1000		/* mark it as an executable */
-
-#define MCL_CURRENT     0x2000          /* lock all currently mapped pages */
-#define MCL_FUTURE      0x4000          /* lock all additions to address space */
-
-#define MAP_POPULATE	0x8000		/* populate (prefault) pagetables */
-#define MAP_NONBLOCK	0x10000		/* do not block on IO */
-#define MAP_STACK	0x20000		/* give out an address that is best suited for process/thread stacks */
-#define MAP_HUGETLB	0x40000		/* create a huge page mapping */
-
-#ifdef __KERNEL__
 #ifndef __ASSEMBLY__
 #define arch_mmap_check(addr,len,flags)	sparc_mmap_check(addr,len)
 int sparc_mmap_check(unsigned long addr, unsigned long len);
 #endif
-#endif
-
 #endif /* __SPARC_MMAN_H__ */
diff --git a/arch/sparc/include/asm/mmu_64.h b/arch/sparc/include/asm/mmu_64.h
index 9067dc5..76092c4 100644
--- a/arch/sparc/include/asm/mmu_64.h
+++ b/arch/sparc/include/asm/mmu_64.h
@@ -30,22 +30,8 @@
 #define CTX_PGSZ_MASK		((CTX_PGSZ_BITS << CTX_PGSZ0_SHIFT) | \
 				 (CTX_PGSZ_BITS << CTX_PGSZ1_SHIFT))
 
-#if defined(CONFIG_SPARC64_PAGE_SIZE_8KB)
 #define CTX_PGSZ_BASE	CTX_PGSZ_8KB
-#elif defined(CONFIG_SPARC64_PAGE_SIZE_64KB)
-#define CTX_PGSZ_BASE	CTX_PGSZ_64KB
-#else
-#error No page size specified in kernel configuration
-#endif
-
-#if defined(CONFIG_HUGETLB_PAGE_SIZE_4MB)
-#define CTX_PGSZ_HUGE		CTX_PGSZ_4MB
-#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K)
-#define CTX_PGSZ_HUGE		CTX_PGSZ_512KB
-#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
-#define CTX_PGSZ_HUGE		CTX_PGSZ_64KB
-#endif
-
+#define CTX_PGSZ_HUGE	CTX_PGSZ_4MB
 #define CTX_PGSZ_KERN	CTX_PGSZ_4MB
 
 /* Thus, when running on UltraSPARC-III+ and later, we use the following
@@ -96,7 +82,7 @@
 
 #define MM_TSB_BASE	0
 
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
 #define MM_TSB_HUGE	1
 #define MM_NUM_TSBS	2
 #else
@@ -107,6 +93,7 @@
 	spinlock_t		lock;
 	unsigned long		sparc64_ctx_val;
 	unsigned long		huge_pte_count;
+	struct page		*pgtable_page;
 	struct tsb_config	tsb_block[MM_NUM_TSBS];
 	struct hv_tsb_descr	tsb_descr[MM_NUM_TSBS];
 } mm_context_t;
diff --git a/arch/sparc/include/asm/mmu_context_64.h b/arch/sparc/include/asm/mmu_context_64.h
index a97fd08..9191ca6 100644
--- a/arch/sparc/include/asm/mmu_context_64.h
+++ b/arch/sparc/include/asm/mmu_context_64.h
@@ -36,7 +36,7 @@
 {
 	__tsb_context_switch(__pa(mm->pgd),
 			     &mm->context.tsb_block[0],
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
 			     (mm->context.tsb_block[1].tsb ?
 			      &mm->context.tsb_block[1] :
 			      NULL)
diff --git a/arch/sparc/include/asm/page_64.h b/arch/sparc/include/asm/page_64.h
index f0d09b4..4b39f74 100644
--- a/arch/sparc/include/asm/page_64.h
+++ b/arch/sparc/include/asm/page_64.h
@@ -3,13 +3,7 @@
 
 #include <linux/const.h>
 
-#if defined(CONFIG_SPARC64_PAGE_SIZE_8KB)
 #define PAGE_SHIFT   13
-#elif defined(CONFIG_SPARC64_PAGE_SIZE_64KB)
-#define PAGE_SHIFT   16
-#else
-#error No page size specified in kernel configuration
-#endif
 
 #define PAGE_SIZE    (_AC(1,UL) << PAGE_SHIFT)
 #define PAGE_MASK    (~(PAGE_SIZE-1))
@@ -21,15 +15,9 @@
 #define DCACHE_ALIASING_POSSIBLE
 #endif
 
-#if defined(CONFIG_HUGETLB_PAGE_SIZE_4MB)
 #define HPAGE_SHIFT		22
-#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K)
-#define HPAGE_SHIFT		19
-#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
-#define HPAGE_SHIFT		16
-#endif
 
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
 #define HPAGE_SIZE		(_AC(1,UL) << HPAGE_SHIFT)
 #define HPAGE_MASK		(~(HPAGE_SIZE - 1UL))
 #define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT - PAGE_SHIFT)
@@ -38,6 +26,11 @@
 
 #ifndef __ASSEMBLY__
 
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
+struct mm_struct;
+extern void hugetlb_setup(struct mm_struct *mm);
+#endif
+
 #define WANT_PAGE_VIRTUAL
 
 extern void _clear_page(void *page);
@@ -98,7 +91,7 @@
 
 #endif /* (STRICT_MM_TYPECHECKS) */
 
-typedef struct page *pgtable_t;
+typedef pte_t *pgtable_t;
 
 #define TASK_UNMAPPED_BASE	(test_thread_flag(TIF_32BIT) ? \
 				 (_AC(0x0000000070000000,UL)) : \
diff --git a/arch/sparc/include/asm/pgalloc_64.h b/arch/sparc/include/asm/pgalloc_64.h
index 40b2d7a..bcfe063 100644
--- a/arch/sparc/include/asm/pgalloc_64.h
+++ b/arch/sparc/include/asm/pgalloc_64.h
@@ -38,51 +38,20 @@
 	kmem_cache_free(pgtable_cache, pmd);
 }
 
-static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
-					  unsigned long address)
-{
-	return (pte_t *)__get_free_page(GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO);
-}
+extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
+				   unsigned long address);
+extern pgtable_t pte_alloc_one(struct mm_struct *mm,
+			       unsigned long address);
+extern void pte_free_kernel(struct mm_struct *mm, pte_t *pte);
+extern void pte_free(struct mm_struct *mm, pgtable_t ptepage);
 
-static inline pgtable_t pte_alloc_one(struct mm_struct *mm,
-					unsigned long address)
-{
-	struct page *page;
-	pte_t *pte;
-
-	pte = pte_alloc_one_kernel(mm, address);
-	if (!pte)
-		return NULL;
-	page = virt_to_page(pte);
-	pgtable_page_ctor(page);
-	return page;
-}
-
-static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
-{
-	free_page((unsigned long)pte);
-}
-
-static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage)
-{
-	pgtable_page_dtor(ptepage);
-	__free_page(ptepage);
-}
-
-#define pmd_populate_kernel(MM, PMD, PTE)	pmd_set(PMD, PTE)
-#define pmd_populate(MM,PMD,PTE_PAGE)		\
-	pmd_populate_kernel(MM,PMD,page_address(PTE_PAGE))
-#define pmd_pgtable(pmd) pmd_page(pmd)
+#define pmd_populate_kernel(MM, PMD, PTE)	pmd_set(MM, PMD, PTE)
+#define pmd_populate(MM, PMD, PTE)		pmd_set(MM, PMD, PTE)
+#define pmd_pgtable(PMD)			((pte_t *)__pmd_page(PMD))
 
 #define check_pgt_cache()	do { } while (0)
 
-static inline void pgtable_free(void *table, bool is_page)
-{
-	if (is_page)
-		free_page((unsigned long)table);
-	else
-		kmem_cache_free(pgtable_cache, table);
-}
+extern void pgtable_free(void *table, bool is_page);
 
 #ifdef CONFIG_SMP
 
@@ -113,11 +82,10 @@
 }
 #endif /* !CONFIG_SMP */
 
-static inline void __pte_free_tlb(struct mmu_gather *tlb, struct page *ptepage,
+static inline void __pte_free_tlb(struct mmu_gather *tlb, pte_t *pte,
 				  unsigned long address)
 {
-	pgtable_page_dtor(ptepage);
-	pgtable_free_tlb(tlb, page_address(ptepage), true);
+	pgtable_free_tlb(tlb, pte, true);
 }
 
 #define __pmd_free_tlb(tlb, pmd, addr)		      \
diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h
index 61210db..95515f1 100644
--- a/arch/sparc/include/asm/pgtable_64.h
+++ b/arch/sparc/include/asm/pgtable_64.h
@@ -45,40 +45,59 @@
 
 #define vmemmap			((struct page *)VMEMMAP_BASE)
 
-/* XXX All of this needs to be rethought so we can take advantage
- * XXX cheetah's full 64-bit virtual address space, ie. no more hole
- * XXX in the middle like on spitfire. -DaveM
- */
-/*
- * Given a virtual address, the lowest PAGE_SHIFT bits determine offset
- * into the page; the next higher PAGE_SHIFT-3 bits determine the pte#
- * in the proper pagetable (the -3 is from the 8 byte ptes, and each page
- * table is a single page long). The next higher PMD_BITS determine pmd#
- * in the proper pmdtable (where we must have PMD_BITS <= (PAGE_SHIFT-2)
- * since the pmd entries are 4 bytes, and each pmd page is a single page
- * long). Finally, the higher few bits determine pgde#.
- */
-
 /* PMD_SHIFT determines the size of the area a second-level page
  * table can map
  */
-#define PMD_SHIFT	(PAGE_SHIFT + (PAGE_SHIFT-3))
+#define PMD_SHIFT	(PAGE_SHIFT + (PAGE_SHIFT-4))
 #define PMD_SIZE	(_AC(1,UL) << PMD_SHIFT)
 #define PMD_MASK	(~(PMD_SIZE-1))
 #define PMD_BITS	(PAGE_SHIFT - 2)
 
 /* PGDIR_SHIFT determines what a third-level page table entry can map */
-#define PGDIR_SHIFT	(PAGE_SHIFT + (PAGE_SHIFT-3) + PMD_BITS)
+#define PGDIR_SHIFT	(PAGE_SHIFT + (PAGE_SHIFT-4) + PMD_BITS)
 #define PGDIR_SIZE	(_AC(1,UL) << PGDIR_SHIFT)
 #define PGDIR_MASK	(~(PGDIR_SIZE-1))
 #define PGDIR_BITS	(PAGE_SHIFT - 2)
 
+#if (PGDIR_SHIFT + PGDIR_BITS) != 44
+#error Page table parameters do not cover virtual address space properly.
+#endif
+
+#if (PMD_SHIFT != HPAGE_SHIFT)
+#error PMD_SHIFT must equal HPAGE_SHIFT for transparent huge pages.
+#endif
+
+/* PMDs point to PTE tables which are 4K aligned.  */
+#define PMD_PADDR	_AC(0xfffffffe,UL)
+#define PMD_PADDR_SHIFT	_AC(11,UL)
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#define PMD_ISHUGE	_AC(0x00000001,UL)
+
+/* This is the PMD layout when PMD_ISHUGE is set.  With 4MB huge
+ * pages, this frees up a bunch of bits in the layout that we can
+ * use for the protection settings and software metadata.
+ */
+#define PMD_HUGE_PADDR		_AC(0xfffff800,UL)
+#define PMD_HUGE_PROTBITS	_AC(0x000007ff,UL)
+#define PMD_HUGE_PRESENT	_AC(0x00000400,UL)
+#define PMD_HUGE_WRITE		_AC(0x00000200,UL)
+#define PMD_HUGE_DIRTY		_AC(0x00000100,UL)
+#define PMD_HUGE_ACCESSED	_AC(0x00000080,UL)
+#define PMD_HUGE_EXEC		_AC(0x00000040,UL)
+#define PMD_HUGE_SPLITTING	_AC(0x00000020,UL)
+#endif
+
+/* PGDs point to PMD tables which are 8K aligned.  */
+#define PGD_PADDR	_AC(0xfffffffc,UL)
+#define PGD_PADDR_SHIFT	_AC(11,UL)
+
 #ifndef __ASSEMBLY__
 
 #include <linux/sched.h>
 
 /* Entries per page directory level. */
-#define PTRS_PER_PTE	(1UL << (PAGE_SHIFT-3))
+#define PTRS_PER_PTE	(1UL << (PAGE_SHIFT-4))
 #define PTRS_PER_PMD	(1UL << PMD_BITS)
 #define PTRS_PER_PGD	(1UL << PGDIR_BITS)
 
@@ -160,26 +179,11 @@
 #define _PAGE_SZ8K_4V	  _AC(0x0000000000000000,UL) /* 8K Page              */
 #define _PAGE_SZALL_4V	  _AC(0x0000000000000007,UL) /* All pgsz bits        */
 
-#if PAGE_SHIFT == 13
 #define _PAGE_SZBITS_4U	_PAGE_SZ8K_4U
 #define _PAGE_SZBITS_4V	_PAGE_SZ8K_4V
-#elif PAGE_SHIFT == 16
-#define _PAGE_SZBITS_4U	_PAGE_SZ64K_4U
-#define _PAGE_SZBITS_4V	_PAGE_SZ64K_4V
-#else
-#error Wrong PAGE_SHIFT specified
-#endif
 
-#if defined(CONFIG_HUGETLB_PAGE_SIZE_4MB)
 #define _PAGE_SZHUGE_4U	_PAGE_SZ4MB_4U
 #define _PAGE_SZHUGE_4V	_PAGE_SZ4MB_4V
-#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K)
-#define _PAGE_SZHUGE_4U	_PAGE_SZ512K_4U
-#define _PAGE_SZHUGE_4V	_PAGE_SZ512K_4V
-#elif defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
-#define _PAGE_SZHUGE_4U	_PAGE_SZ64K_4U
-#define _PAGE_SZHUGE_4V	_PAGE_SZ64K_4V
-#endif
 
 /* These are actually filled in at boot time by sun4{u,v}_pgprot_init() */
 #define __P000	__pgprot(0)
@@ -218,7 +222,6 @@
 
 extern unsigned long pg_iobits;
 extern unsigned long _PAGE_ALL_SZ_BITS;
-extern unsigned long _PAGE_SZBITS;
 
 extern struct page *mem_map_zero;
 #define ZERO_PAGE(vaddr)	(mem_map_zero)
@@ -231,25 +234,25 @@
 static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot)
 {
 	unsigned long paddr = pfn << PAGE_SHIFT;
-	unsigned long sz_bits;
 
-	sz_bits = 0UL;
-	if (_PAGE_SZBITS_4U != 0UL || _PAGE_SZBITS_4V != 0UL) {
-		__asm__ __volatile__(
-		"\n661:	sethi		%%uhi(%1), %0\n"
-		"	sllx		%0, 32, %0\n"
-		"	.section	.sun4v_2insn_patch, \"ax\"\n"
-		"	.word		661b\n"
-		"	mov		%2, %0\n"
-		"	nop\n"
-		"	.previous\n"
-		: "=r" (sz_bits)
-		: "i" (_PAGE_SZBITS_4U), "i" (_PAGE_SZBITS_4V));
-	}
-	return __pte(paddr | sz_bits | pgprot_val(prot));
+	BUILD_BUG_ON(_PAGE_SZBITS_4U != 0UL || _PAGE_SZBITS_4V != 0UL);
+	return __pte(paddr | pgprot_val(prot));
 }
 #define mk_pte(page, pgprot)	pfn_pte(page_to_pfn(page), (pgprot))
 
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+extern pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot);
+#define mk_pmd(page, pgprot)	pfn_pmd(page_to_pfn(page), (pgprot))
+
+extern pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot);
+
+static inline pmd_t pmd_mkhuge(pmd_t pmd)
+{
+	/* Do nothing, mk_pmd() does this part.  */
+	return pmd;
+}
+#endif
+
 /* This one can be done with two shifts.  */
 static inline unsigned long pte_pfn(pte_t pte)
 {
@@ -286,6 +289,7 @@
 	 * Note: We encode this into 3 sun4v 2-insn patch sequences.
 	 */
 
+	BUILD_BUG_ON(_PAGE_SZBITS_4U != 0UL || _PAGE_SZBITS_4V != 0UL);
 	__asm__ __volatile__(
 	"\n661:	sethi		%%uhi(%2), %1\n"
 	"	sethi		%%hi(%2), %0\n"
@@ -307,10 +311,10 @@
 	: "=r" (mask), "=r" (tmp)
 	: "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U |
 	       _PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U | _PAGE_PRESENT_4U |
-	       _PAGE_SZBITS_4U | _PAGE_SPECIAL),
+	       _PAGE_SPECIAL),
 	  "i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V |
 	       _PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V | _PAGE_PRESENT_4V |
-	       _PAGE_SZBITS_4V | _PAGE_SPECIAL));
+	       _PAGE_SPECIAL));
 
 	return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask));
 }
@@ -618,19 +622,130 @@
 	return pte_val(pte) & _PAGE_SPECIAL;
 }
 
-#define pmd_set(pmdp, ptep)	\
-	(pmd_val(*(pmdp)) = (__pa((unsigned long) (ptep)) >> 11UL))
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+static inline int pmd_young(pmd_t pmd)
+{
+	return pmd_val(pmd) & PMD_HUGE_ACCESSED;
+}
+
+static inline int pmd_write(pmd_t pmd)
+{
+	return pmd_val(pmd) & PMD_HUGE_WRITE;
+}
+
+static inline unsigned long pmd_pfn(pmd_t pmd)
+{
+	unsigned long val = pmd_val(pmd) & PMD_HUGE_PADDR;
+
+	return val >> (PAGE_SHIFT - PMD_PADDR_SHIFT);
+}
+
+static inline int pmd_large(pmd_t pmd)
+{
+	return (pmd_val(pmd) & (PMD_ISHUGE | PMD_HUGE_PRESENT)) ==
+		(PMD_ISHUGE | PMD_HUGE_PRESENT);
+}
+
+static inline int pmd_trans_splitting(pmd_t pmd)
+{
+	return (pmd_val(pmd) & (PMD_ISHUGE|PMD_HUGE_SPLITTING)) ==
+		(PMD_ISHUGE|PMD_HUGE_SPLITTING);
+}
+
+static inline int pmd_trans_huge(pmd_t pmd)
+{
+	return pmd_val(pmd) & PMD_ISHUGE;
+}
+
+#define has_transparent_hugepage() 1
+
+static inline pmd_t pmd_mkold(pmd_t pmd)
+{
+	pmd_val(pmd) &= ~PMD_HUGE_ACCESSED;
+	return pmd;
+}
+
+static inline pmd_t pmd_wrprotect(pmd_t pmd)
+{
+	pmd_val(pmd) &= ~PMD_HUGE_WRITE;
+	return pmd;
+}
+
+static inline pmd_t pmd_mkdirty(pmd_t pmd)
+{
+	pmd_val(pmd) |= PMD_HUGE_DIRTY;
+	return pmd;
+}
+
+static inline pmd_t pmd_mkyoung(pmd_t pmd)
+{
+	pmd_val(pmd) |= PMD_HUGE_ACCESSED;
+	return pmd;
+}
+
+static inline pmd_t pmd_mkwrite(pmd_t pmd)
+{
+	pmd_val(pmd) |= PMD_HUGE_WRITE;
+	return pmd;
+}
+
+static inline pmd_t pmd_mknotpresent(pmd_t pmd)
+{
+	pmd_val(pmd) &= ~PMD_HUGE_PRESENT;
+	return pmd;
+}
+
+static inline pmd_t pmd_mksplitting(pmd_t pmd)
+{
+	pmd_val(pmd) |= PMD_HUGE_SPLITTING;
+	return pmd;
+}
+
+extern pgprot_t pmd_pgprot(pmd_t entry);
+#endif
+
+static inline int pmd_present(pmd_t pmd)
+{
+	return pmd_val(pmd) != 0U;
+}
+
+#define pmd_none(pmd)			(!pmd_val(pmd))
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+extern void set_pmd_at(struct mm_struct *mm, unsigned long addr,
+		       pmd_t *pmdp, pmd_t pmd);
+#else
+static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
+			      pmd_t *pmdp, pmd_t pmd)
+{
+	*pmdp = pmd;
+}
+#endif
+
+static inline void pmd_set(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
+{
+	unsigned long val = __pa((unsigned long) (ptep)) >> PMD_PADDR_SHIFT;
+
+	pmd_val(*pmdp) = val;
+}
+
 #define pud_set(pudp, pmdp)	\
-	(pud_val(*(pudp)) = (__pa((unsigned long) (pmdp)) >> 11UL))
-#define __pmd_page(pmd)		\
-	((unsigned long) __va((((unsigned long)pmd_val(pmd))<<11UL)))
+	(pud_val(*(pudp)) = (__pa((unsigned long) (pmdp)) >> PGD_PADDR_SHIFT))
+static inline unsigned long __pmd_page(pmd_t pmd)
+{
+	unsigned long paddr = (unsigned long) pmd_val(pmd);
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+	if (pmd_val(pmd) & PMD_ISHUGE)
+		paddr &= PMD_HUGE_PADDR;
+#endif
+	paddr <<= PMD_PADDR_SHIFT;
+	return ((unsigned long) __va(paddr));
+}
 #define pmd_page(pmd) 			virt_to_page((void *)__pmd_page(pmd))
 #define pud_page_vaddr(pud)		\
-	((unsigned long) __va((((unsigned long)pud_val(pud))<<11UL)))
+	((unsigned long) __va((((unsigned long)pud_val(pud))<<PGD_PADDR_SHIFT)))
 #define pud_page(pud) 			virt_to_page((void *)pud_page_vaddr(pud))
-#define pmd_none(pmd)			(!pmd_val(pmd))
 #define pmd_bad(pmd)			(0)
-#define pmd_present(pmd)		(pmd_val(pmd) != 0U)
 #define pmd_clear(pmdp)			(pmd_val(*(pmdp)) = 0U)
 #define pud_none(pud)			(!pud_val(pud))
 #define pud_bad(pud)			(0)
@@ -664,6 +779,16 @@
 extern void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
 			  pte_t *ptep, pte_t orig, int fullmm);
 
+#define __HAVE_ARCH_PMDP_GET_AND_CLEAR
+static inline pmd_t pmdp_get_and_clear(struct mm_struct *mm,
+				       unsigned long addr,
+				       pmd_t *pmdp)
+{
+	pmd_t pmd = *pmdp;
+	set_pmd_at(mm, addr, pmdp, __pmd(0U));
+	return pmd;
+}
+
 static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
 			     pte_t *ptep, pte_t pte, int fullmm)
 {
@@ -719,6 +844,16 @@
 
 struct vm_area_struct;
 extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *);
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr,
+				 pmd_t *pmd);
+
+#define __HAVE_ARCH_PGTABLE_DEPOSIT
+extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable);
+
+#define __HAVE_ARCH_PGTABLE_WITHDRAW
+extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm);
+#endif
 
 /* Encode and de-code a swap entry */
 #define __swp_type(entry)	(((entry).val >> PAGE_SHIFT) & 0xffUL)
diff --git a/arch/sparc/include/asm/psr.h b/arch/sparc/include/asm/psr.h
index cee7ed9..e71eb57 100644
--- a/arch/sparc/include/asm/psr.h
+++ b/arch/sparc/include/asm/psr.h
@@ -7,43 +7,11 @@
  *
  * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
  */
-
 #ifndef __LINUX_SPARC_PSR_H
 #define __LINUX_SPARC_PSR_H
 
-/* The Sparc PSR fields are laid out as the following:
- *
- *  ------------------------------------------------------------------------
- *  | impl  | vers  | icc   | resv  | EC | EF | PIL  | S | PS | ET |  CWP  |
- *  | 31-28 | 27-24 | 23-20 | 19-14 | 13 | 12 | 11-8 | 7 | 6  | 5  |  4-0  |
- *  ------------------------------------------------------------------------
- */
-#define PSR_CWP     0x0000001f         /* current window pointer     */
-#define PSR_ET      0x00000020         /* enable traps field         */
-#define PSR_PS      0x00000040         /* previous privilege level   */
-#define PSR_S       0x00000080         /* current privilege level    */
-#define PSR_PIL     0x00000f00         /* processor interrupt level  */
-#define PSR_EF      0x00001000         /* enable floating point      */
-#define PSR_EC      0x00002000         /* enable co-processor        */
-#define PSR_SYSCALL 0x00004000         /* inside of a syscall        */
-#define PSR_LE      0x00008000         /* SuperSparcII little-endian */
-#define PSR_ICC     0x00f00000         /* integer condition codes    */
-#define PSR_C       0x00100000         /* carry bit                  */
-#define PSR_V       0x00200000         /* overflow bit               */
-#define PSR_Z       0x00400000         /* zero bit                   */
-#define PSR_N       0x00800000         /* negative bit               */
-#define PSR_VERS    0x0f000000         /* cpu-version field          */
-#define PSR_IMPL    0xf0000000         /* cpu-implementation field   */
+#include <uapi/asm/psr.h>
 
-#define PSR_VERS_SHIFT		24
-#define PSR_IMPL_SHIFT		28
-#define PSR_VERS_SHIFTED_MASK	0xf
-#define PSR_IMPL_SHIFTED_MASK	0xf
-
-#define PSR_IMPL_TI		0x4
-#define PSR_IMPL_LEON		0xf
-
-#ifdef __KERNEL__
 
 #ifndef __ASSEMBLY__
 /* Get the %psr register. */
@@ -96,6 +64,4 @@
 
 #endif /* !(__ASSEMBLY__) */
 
-#endif /* (__KERNEL__) */
-
 #endif /* !(__LINUX_SPARC_PSR_H) */
diff --git a/arch/sparc/include/asm/ptrace.h b/arch/sparc/include/asm/ptrace.h
index fd9c3f2..0c6f6b0 100644
--- a/arch/sparc/include/asm/ptrace.h
+++ b/arch/sparc/include/asm/ptrace.h
@@ -1,169 +1,11 @@
 #ifndef __SPARC_PTRACE_H
 #define __SPARC_PTRACE_H
 
-#if defined(__sparc__) && defined(__arch64__)
-/* 64 bit sparc */
-#include <asm/pstate.h>
-
-/* This struct defines the way the registers are stored on the
- * stack during a system call and basically all traps.
- */
-
-/* This magic value must have the low 9 bits clear,
- * as that is where we encode the %tt value, see below.
- */
-#define PT_REGS_MAGIC 0x57ac6c00
-
-#ifndef __ASSEMBLY__
-
-#include <linux/types.h>
-
-struct pt_regs {
-	unsigned long u_regs[16]; /* globals and ins */
-	unsigned long tstate;
-	unsigned long tpc;
-	unsigned long tnpc;
-	unsigned int y;
-
-	/* We encode a magic number, PT_REGS_MAGIC, along
-	 * with the %tt (trap type) register value at trap
-	 * entry time.  The magic number allows us to identify
-	 * accurately a trap stack frame in the stack
-	 * unwinder, and the %tt value allows us to test
-	 * things like "in a system call" etc. for an arbitray
-	 * process.
-	 *
-	 * The PT_REGS_MAGIC is chosen such that it can be
-	 * loaded completely using just a sethi instruction.
-	 */
-	unsigned int magic;
-};
-
-struct pt_regs32 {
-	unsigned int psr;
-	unsigned int pc;
-	unsigned int npc;
-	unsigned int y;
-	unsigned int u_regs[16]; /* globals and ins */
-};
-
-/* A V9 register window */
-struct reg_window {
-	unsigned long locals[8];
-	unsigned long ins[8];
-};
-
-/* A 32-bit register window. */
-struct reg_window32 {
-	unsigned int locals[8];
-	unsigned int ins[8];
-};
-
-/* A V9 Sparc stack frame */
-struct sparc_stackf {
-	unsigned long locals[8];
-        unsigned long ins[6];
-	struct sparc_stackf *fp;
-	unsigned long callers_pc;
-	char *structptr;
-	unsigned long xargs[6];
-	unsigned long xxargs[1];
-};
-
-/* A 32-bit Sparc stack frame */
-struct sparc_stackf32 {
-	unsigned int locals[8];
-        unsigned int ins[6];
-	unsigned int fp;
-	unsigned int callers_pc;
-	unsigned int structptr;
-	unsigned int xargs[6];
-	unsigned int xxargs[1];
-};
-
-struct sparc_trapf {
-	unsigned long locals[8];
-	unsigned long ins[8];
-	unsigned long _unused;
-	struct pt_regs *regs;
-};
-#endif /* (!__ASSEMBLY__) */
-#else
-/* 32 bit sparc */
-
-#include <asm/psr.h>
-
-/* This struct defines the way the registers are stored on the
- * stack during a system call and basically all traps.
- */
-#ifndef __ASSEMBLY__
-
-#include <linux/types.h>
-
-struct pt_regs {
-	unsigned long psr;
-	unsigned long pc;
-	unsigned long npc;
-	unsigned long y;
-	unsigned long u_regs[16]; /* globals and ins */
-};
-
-/* A 32-bit register window. */
-struct reg_window32 {
-	unsigned long locals[8];
-	unsigned long ins[8];
-};
-
-/* A Sparc stack frame */
-struct sparc_stackf {
-	unsigned long locals[8];
-        unsigned long ins[6];
-	struct sparc_stackf *fp;
-	unsigned long callers_pc;
-	char *structptr;
-	unsigned long xargs[6];
-	unsigned long xxargs[1];
-};
-#endif /* (!__ASSEMBLY__) */
-
-#endif /* (defined(__sparc__) && defined(__arch64__))*/
-
-#ifndef __ASSEMBLY__
-
-#define TRACEREG_SZ	sizeof(struct pt_regs)
-#define STACKFRAME_SZ	sizeof(struct sparc_stackf)
-
-#define TRACEREG32_SZ	sizeof(struct pt_regs32)
-#define STACKFRAME32_SZ	sizeof(struct sparc_stackf32)
-
-#endif /* (!__ASSEMBLY__) */
-
-#define UREG_G0        0
-#define UREG_G1        1
-#define UREG_G2        2
-#define UREG_G3        3
-#define UREG_G4        4
-#define UREG_G5        5
-#define UREG_G6        6
-#define UREG_G7        7
-#define UREG_I0        8
-#define UREG_I1        9
-#define UREG_I2        10
-#define UREG_I3        11
-#define UREG_I4        12
-#define UREG_I5        13
-#define UREG_I6        14
-#define UREG_I7        15
-#define UREG_FP        UREG_I6
-#define UREG_RETPC     UREG_I7
+#include <uapi/asm/ptrace.h>
 
 #if defined(__sparc__) && defined(__arch64__)
-/* 64 bit sparc */
-
 #ifndef __ASSEMBLY__
 
-#ifdef __KERNEL__
-
 #include <linux/threads.h>
 #include <asm/switch_to.h>
 
@@ -223,24 +65,10 @@
 #else
 #define profile_pc(regs) instruction_pointer(regs)
 #endif
-#endif /* (__KERNEL__) */
-
 #else /* __ASSEMBLY__ */
-/* For assembly code. */
-#define TRACEREG_SZ		0xa0
-#define STACKFRAME_SZ		0xc0
-
-#define TRACEREG32_SZ		0x50
-#define STACKFRAME32_SZ		0x60
 #endif /* __ASSEMBLY__ */
-
 #else /* (defined(__sparc__) && defined(__arch64__)) */
-
-/* 32 bit sparc */
-
 #ifndef __ASSEMBLY__
-
-#ifdef __KERNEL__
 #include <asm/switch_to.h>
 
 static inline bool pt_regs_is_syscall(struct pt_regs *regs)
@@ -265,158 +93,10 @@
 #define instruction_pointer(regs) ((regs)->pc)
 #define user_stack_pointer(regs) ((regs)->u_regs[UREG_FP])
 unsigned long profile_pc(struct pt_regs *);
-#endif /* (__KERNEL__) */
-
 #else /* (!__ASSEMBLY__) */
-/* For assembly code. */
-#define TRACEREG_SZ       0x50
-#define STACKFRAME_SZ     0x60
 #endif /* (!__ASSEMBLY__) */
-
 #endif /* (defined(__sparc__) && defined(__arch64__)) */
-
-#ifdef __KERNEL__
 #define STACK_BIAS		2047
-#endif
-
-/* These are for pt_regs. */
-#define PT_V9_G0     0x00
-#define PT_V9_G1     0x08
-#define PT_V9_G2     0x10
-#define PT_V9_G3     0x18
-#define PT_V9_G4     0x20
-#define PT_V9_G5     0x28
-#define PT_V9_G6     0x30
-#define PT_V9_G7     0x38
-#define PT_V9_I0     0x40
-#define PT_V9_I1     0x48
-#define PT_V9_I2     0x50
-#define PT_V9_I3     0x58
-#define PT_V9_I4     0x60
-#define PT_V9_I5     0x68
-#define PT_V9_I6     0x70
-#define PT_V9_FP     PT_V9_I6
-#define PT_V9_I7     0x78
-#define PT_V9_TSTATE 0x80
-#define PT_V9_TPC    0x88
-#define PT_V9_TNPC   0x90
-#define PT_V9_Y      0x98
-#define PT_V9_MAGIC  0x9c
-#define PT_TSTATE	PT_V9_TSTATE
-#define PT_TPC		PT_V9_TPC
-#define PT_TNPC		PT_V9_TNPC
-
-/* These for pt_regs32. */
-#define PT_PSR    0x0
-#define PT_PC     0x4
-#define PT_NPC    0x8
-#define PT_Y      0xc
-#define PT_G0     0x10
-#define PT_WIM    PT_G0
-#define PT_G1     0x14
-#define PT_G2     0x18
-#define PT_G3     0x1c
-#define PT_G4     0x20
-#define PT_G5     0x24
-#define PT_G6     0x28
-#define PT_G7     0x2c
-#define PT_I0     0x30
-#define PT_I1     0x34
-#define PT_I2     0x38
-#define PT_I3     0x3c
-#define PT_I4     0x40
-#define PT_I5     0x44
-#define PT_I6     0x48
-#define PT_FP     PT_I6
-#define PT_I7     0x4c
-
-/* Reg_window offsets */
-#define RW_V9_L0     0x00
-#define RW_V9_L1     0x08
-#define RW_V9_L2     0x10
-#define RW_V9_L3     0x18
-#define RW_V9_L4     0x20
-#define RW_V9_L5     0x28
-#define RW_V9_L6     0x30
-#define RW_V9_L7     0x38
-#define RW_V9_I0     0x40
-#define RW_V9_I1     0x48
-#define RW_V9_I2     0x50
-#define RW_V9_I3     0x58
-#define RW_V9_I4     0x60
-#define RW_V9_I5     0x68
-#define RW_V9_I6     0x70
-#define RW_V9_I7     0x78
-
-#define RW_L0     0x00
-#define RW_L1     0x04
-#define RW_L2     0x08
-#define RW_L3     0x0c
-#define RW_L4     0x10
-#define RW_L5     0x14
-#define RW_L6     0x18
-#define RW_L7     0x1c
-#define RW_I0     0x20
-#define RW_I1     0x24
-#define RW_I2     0x28
-#define RW_I3     0x2c
-#define RW_I4     0x30
-#define RW_I5     0x34
-#define RW_I6     0x38
-#define RW_I7     0x3c
-
-/* Stack_frame offsets */
-#define SF_V9_L0     0x00
-#define SF_V9_L1     0x08
-#define SF_V9_L2     0x10
-#define SF_V9_L3     0x18
-#define SF_V9_L4     0x20
-#define SF_V9_L5     0x28
-#define SF_V9_L6     0x30
-#define SF_V9_L7     0x38
-#define SF_V9_I0     0x40
-#define SF_V9_I1     0x48
-#define SF_V9_I2     0x50
-#define SF_V9_I3     0x58
-#define SF_V9_I4     0x60
-#define SF_V9_I5     0x68
-#define SF_V9_FP     0x70
-#define SF_V9_PC     0x78
-#define SF_V9_RETP   0x80
-#define SF_V9_XARG0  0x88
-#define SF_V9_XARG1  0x90
-#define SF_V9_XARG2  0x98
-#define SF_V9_XARG3  0xa0
-#define SF_V9_XARG4  0xa8
-#define SF_V9_XARG5  0xb0
-#define SF_V9_XXARG  0xb8
-
-#define SF_L0     0x00
-#define SF_L1     0x04
-#define SF_L2     0x08
-#define SF_L3     0x0c
-#define SF_L4     0x10
-#define SF_L5     0x14
-#define SF_L6     0x18
-#define SF_L7     0x1c
-#define SF_I0     0x20
-#define SF_I1     0x24
-#define SF_I2     0x28
-#define SF_I3     0x2c
-#define SF_I4     0x30
-#define SF_I5     0x34
-#define SF_FP     0x38
-#define SF_PC     0x3c
-#define SF_RETP   0x40
-#define SF_XARG0  0x44
-#define SF_XARG1  0x48
-#define SF_XARG2  0x4c
-#define SF_XARG3  0x50
-#define SF_XARG4  0x54
-#define SF_XARG5  0x58
-#define SF_XXARG  0x5c
-
-#ifdef __KERNEL__
 
 /* global_reg_snapshot offsets */
 #define GR_SNAP_TSTATE	0x00
@@ -428,29 +108,4 @@
 #define GR_SNAP_THREAD	0x30
 #define GR_SNAP_PAD1	0x38
 
-#endif  /*  __KERNEL__  */
-
-/* Stuff for the ptrace system call */
-#define PTRACE_SPARC_DETACH       11
-#define PTRACE_GETREGS            12
-#define PTRACE_SETREGS            13
-#define PTRACE_GETFPREGS          14
-#define PTRACE_SETFPREGS          15
-#define PTRACE_READDATA           16
-#define PTRACE_WRITEDATA          17
-#define PTRACE_READTEXT           18
-#define PTRACE_WRITETEXT          19
-#define PTRACE_GETFPAREGS         20
-#define PTRACE_SETFPAREGS         21
-
-/* There are for debugging 64-bit processes, either from a 32 or 64 bit
- * parent.  Thus their complements are for debugging 32-bit processes only.
- */
-
-#define PTRACE_GETREGS64	  22
-#define PTRACE_SETREGS64	  23
-/* PTRACE_SYSCALL is 24 */
-#define PTRACE_GETFPREGS64	  25
-#define PTRACE_SETFPREGS64	  26
-
 #endif /* !(__SPARC_PTRACE_H) */
diff --git a/arch/sparc/include/asm/setup.h b/arch/sparc/include/asm/setup.h
index 8a83699..5e35e05 100644
--- a/arch/sparc/include/asm/setup.h
+++ b/arch/sparc/include/asm/setup.h
@@ -1,17 +1,11 @@
 /*
  *	Just a place holder. 
  */
-
 #ifndef _SPARC_SETUP_H
 #define _SPARC_SETUP_H
 
-#if defined(__sparc__) && defined(__arch64__)
-# define COMMAND_LINE_SIZE 2048
-#else
-# define COMMAND_LINE_SIZE 256
-#endif
+#include <uapi/asm/setup.h>
 
-#ifdef __KERNEL__
 
 extern char reboot_command[];
 
@@ -34,6 +28,4 @@
 extern int stop_a_enabled;
 extern int scons_pwroff;
 
-#endif /* __KERNEL__ */
-
 #endif /* _SPARC_SETUP_H */
diff --git a/arch/sparc/include/asm/sigcontext.h b/arch/sparc/include/asm/sigcontext.h
index 69914d7..fc2df1e 100644
--- a/arch/sparc/include/asm/sigcontext.h
+++ b/arch/sparc/include/asm/sigcontext.h
@@ -1,8 +1,8 @@
 #ifndef __SPARC_SIGCONTEXT_H
 #define __SPARC_SIGCONTEXT_H
 
-#ifdef __KERNEL__
 #include <asm/ptrace.h>
+#include <uapi/asm/sigcontext.h>
 
 #ifndef __ASSEMBLY__
 
@@ -105,6 +105,4 @@
 
 #endif /* !(__ASSEMBLY__) */
 
-#endif /* (__KERNEL__) */
-
 #endif /* !(__SPARC_SIGCONTEXT_H) */
diff --git a/arch/sparc/include/asm/siginfo.h b/arch/sparc/include/asm/siginfo.h
index dbc182c..48c34c1 100644
--- a/arch/sparc/include/asm/siginfo.h
+++ b/arch/sparc/include/asm/siginfo.h
@@ -1,19 +1,8 @@
 #ifndef __SPARC_SIGINFO_H
 #define __SPARC_SIGINFO_H
 
-#if defined(__sparc__) && defined(__arch64__)
+#include <uapi/asm/siginfo.h>
 
-#define __ARCH_SI_PREAMBLE_SIZE	(4 * sizeof(int))
-#define __ARCH_SI_BAND_T int
-
-#endif /* defined(__sparc__) && defined(__arch64__) */
-
-
-#define __ARCH_SI_TRAPNO
-
-#include <asm-generic/siginfo.h>
-
-#ifdef __KERNEL__
 
 #ifdef CONFIG_COMPAT
 
@@ -21,14 +10,4 @@
 
 #endif /* CONFIG_COMPAT */
 
-#endif /* __KERNEL__ */
-
-#define SI_NOINFO	32767		/* no information in siginfo_t */
-
-/*
- * SIGEMT si_codes
- */
-#define EMT_TAGOVF	(__SI_FAULT|1)	/* tag overflow */
-#define NSIGEMT		1
-
 #endif /* !(__SPARC_SIGINFO_H) */
diff --git a/arch/sparc/include/asm/signal.h b/arch/sparc/include/asm/signal.h
index aa42fe3..d243c2a 100644
--- a/arch/sparc/include/asm/signal.h
+++ b/arch/sparc/include/asm/signal.h
@@ -1,168 +1,13 @@
 #ifndef __SPARC_SIGNAL_H
 #define __SPARC_SIGNAL_H
 
-#include <asm/sigcontext.h>
-#include <linux/compiler.h>
-
-#ifdef __KERNEL__
 #ifndef __ASSEMBLY__
 #include <linux/personality.h>
 #include <linux/types.h>
 #endif
-#endif
-
-/* On the Sparc the signal handlers get passed a 'sub-signal' code
- * for certain signal types, which we document here.
- */
-#define SIGHUP		 1
-#define SIGINT		 2
-#define SIGQUIT		 3
-#define SIGILL		 4
-#define    SUBSIG_STACK       0
-#define    SUBSIG_ILLINST     2
-#define    SUBSIG_PRIVINST    3
-#define    SUBSIG_BADTRAP(t)  (0x80 + (t))
-
-#define SIGTRAP		 5
-#define SIGABRT		 6
-#define SIGIOT		 6
-
-#define SIGEMT           7
-#define    SUBSIG_TAG    10
-
-#define SIGFPE		 8
-#define    SUBSIG_FPDISABLED     0x400
-#define    SUBSIG_FPERROR        0x404
-#define    SUBSIG_FPINTOVFL      0x001
-#define    SUBSIG_FPSTSIG        0x002
-#define    SUBSIG_IDIVZERO       0x014
-#define    SUBSIG_FPINEXACT      0x0c4
-#define    SUBSIG_FPDIVZERO      0x0c8
-#define    SUBSIG_FPUNFLOW       0x0cc
-#define    SUBSIG_FPOPERROR      0x0d0
-#define    SUBSIG_FPOVFLOW       0x0d4
-
-#define SIGKILL		 9
-#define SIGBUS          10
-#define    SUBSIG_BUSTIMEOUT    1
-#define    SUBSIG_ALIGNMENT     2
-#define    SUBSIG_MISCERROR     5
-
-#define SIGSEGV		11
-#define    SUBSIG_NOMAPPING     3
-#define    SUBSIG_PROTECTION    4
-#define    SUBSIG_SEGERROR      5
-
-#define SIGSYS		12
-
-#define SIGPIPE		13
-#define SIGALRM		14
-#define SIGTERM		15
-#define SIGURG          16
-
-/* SunOS values which deviate from the Linux/i386 ones */
-#define SIGSTOP		17
-#define SIGTSTP		18
-#define SIGCONT		19
-#define SIGCHLD		20
-#define SIGTTIN		21
-#define SIGTTOU		22
-#define SIGIO		23
-#define SIGPOLL		SIGIO   /* SysV name for SIGIO */
-#define SIGXCPU		24
-#define SIGXFSZ		25
-#define SIGVTALRM	26
-#define SIGPROF		27
-#define SIGWINCH	28
-#define SIGLOST		29
-#define SIGPWR		SIGLOST
-#define SIGUSR1		30
-#define SIGUSR2		31
-
-/* Most things should be clean enough to redefine this at will, if care
-   is taken to make libc match.  */
-
-#define __OLD_NSIG	32
-#define __NEW_NSIG      64
-#ifdef __arch64__
-#define _NSIG_BPW       64
-#else
-#define _NSIG_BPW       32
-#endif
-#define _NSIG_WORDS     (__NEW_NSIG / _NSIG_BPW)
-
-#define SIGRTMIN       32
-#define SIGRTMAX       __NEW_NSIG
-
-#if defined(__KERNEL__) || defined(__WANT_POSIX1B_SIGNALS__)
-#define _NSIG			__NEW_NSIG
-#define __new_sigset_t		sigset_t
-#define __new_sigaction		sigaction
-#define __new_sigaction32	sigaction32
-#define __old_sigset_t		old_sigset_t
-#define __old_sigaction		old_sigaction
-#define __old_sigaction32	old_sigaction32
-#else
-#define _NSIG			__OLD_NSIG
-#define NSIG			_NSIG
-#define __old_sigset_t		sigset_t
-#define __old_sigaction		sigaction
-#define __old_sigaction32	sigaction32
-#endif
+#include <uapi/asm/signal.h>
 
 #ifndef __ASSEMBLY__
-
-typedef unsigned long __old_sigset_t;            /* at least 32 bits */
-
-typedef struct {
-       unsigned long sig[_NSIG_WORDS];
-} __new_sigset_t;
-
-/* A SunOS sigstack */
-struct sigstack {
-	/* XXX 32-bit pointers pinhead XXX */
-	char *the_stack;
-	int   cur_status;
-};
-
-/* Sigvec flags */
-#define _SV_SSTACK    1u    /* This signal handler should use sig-stack */
-#define _SV_INTR      2u    /* Sig return should not restart system call */
-#define _SV_RESET     4u    /* Set handler to SIG_DFL upon taken signal */
-#define _SV_IGNCHILD  8u    /* Do not send SIGCHLD */
-
-/*
- * sa_flags values: SA_STACK is not currently supported, but will allow the
- * usage of signal stacks by using the (now obsolete) sa_restorer field in
- * the sigaction structure as a stack pointer. This is now possible due to
- * the changes in signal handling. LBT 010493.
- * SA_RESTART flag to get restarting signals (which were the default long ago)
- */
-#define SA_NOCLDSTOP	_SV_IGNCHILD
-#define SA_STACK	_SV_SSTACK
-#define SA_ONSTACK	_SV_SSTACK
-#define SA_RESTART	_SV_INTR
-#define SA_ONESHOT	_SV_RESET
-#define SA_NODEFER	0x20u
-#define SA_NOCLDWAIT    0x100u
-#define SA_SIGINFO      0x200u
-
-#define SA_NOMASK	SA_NODEFER
-
-#define SIG_BLOCK          0x01	/* for blocking signals */
-#define SIG_UNBLOCK        0x02	/* for unblocking signals */
-#define SIG_SETMASK        0x04	/* for setting the signal mask */
-
-/*
- * sigaltstack controls
- */
-#define SS_ONSTACK	1
-#define SS_DISABLE	2
-
-#define MINSIGSTKSZ	4096
-#define SIGSTKSZ	16384
-
-#ifdef __KERNEL__
 /*
  * DJHR
  * SA_STATIC_ALLOC is used for the sparc32 system to indicate that this
@@ -175,31 +20,6 @@
  *
  */
 #define SA_STATIC_ALLOC         0x8000
-#endif
-
-#include <asm-generic/signal-defs.h>
-
-struct __new_sigaction {
-	__sighandler_t		sa_handler;
-	unsigned long		sa_flags;
-	__sigrestore_t		sa_restorer;  /* not used by Linux/SPARC yet */
-	__new_sigset_t		sa_mask;
-};
-
-struct __old_sigaction {
-	__sighandler_t		sa_handler;
-	__old_sigset_t		sa_mask;
-	unsigned long		sa_flags;
-	void			(*sa_restorer)(void);  /* not used by Linux/SPARC yet */
-};
-
-typedef struct sigaltstack {
-	void			__user *ss_sp;
-	int			ss_flags;
-	size_t			ss_size;
-} stack_t;
-
-#ifdef __KERNEL__
 
 struct k_sigaction {
 	struct			__new_sigaction sa;
@@ -208,8 +28,5 @@
 
 #define ptrace_signal_deliver(regs, cookie) do { } while (0)
 
-#endif /* !(__KERNEL__) */
-
 #endif /* !(__ASSEMBLY__) */
-
 #endif /* !(__SPARC_SIGNAL_H) */
diff --git a/arch/sparc/include/asm/termbits.h b/arch/sparc/include/asm/termbits.h
index 23b10ff..9480670 100644
--- a/arch/sparc/include/asm/termbits.h
+++ b/arch/sparc/include/asm/termbits.h
@@ -1,266 +1,8 @@
 #ifndef _SPARC_TERMBITS_H
 #define _SPARC_TERMBITS_H
 
-#include <linux/posix_types.h>
+#include <uapi/asm/termbits.h>
 
-typedef unsigned char   cc_t;
-typedef unsigned int    speed_t;
-
-#if defined(__sparc__) && defined(__arch64__)
-typedef unsigned int    tcflag_t;
-#else
-typedef unsigned long   tcflag_t;
-#endif
-
-#define NCC 8
-struct termio {
-	unsigned short c_iflag;		/* input mode flags */
-	unsigned short c_oflag;		/* output mode flags */
-	unsigned short c_cflag;		/* control mode flags */
-	unsigned short c_lflag;		/* local mode flags */
-	unsigned char c_line;		/* line discipline */
-	unsigned char c_cc[NCC];	/* control characters */
-};
-
-#define NCCS 17
-struct termios {
-	tcflag_t c_iflag;		/* input mode flags */
-	tcflag_t c_oflag;		/* output mode flags */
-	tcflag_t c_cflag;		/* control mode flags */
-	tcflag_t c_lflag;		/* local mode flags */
-	cc_t c_line;			/* line discipline */
-#ifndef __KERNEL__
-	cc_t c_cc[NCCS];		/* control characters */
-#else
-	cc_t c_cc[NCCS+2];	/* kernel needs 2 more to hold vmin/vtime */
-#define SIZEOF_USER_TERMIOS sizeof (struct termios) - (2*sizeof (cc_t))
-#endif
-};
-
-struct termios2 {
-	tcflag_t c_iflag;		/* input mode flags */
-	tcflag_t c_oflag;		/* output mode flags */
-	tcflag_t c_cflag;		/* control mode flags */
-	tcflag_t c_lflag;		/* local mode flags */
-	cc_t c_line;			/* line discipline */
-	cc_t c_cc[NCCS+2];		/* control characters */
-	speed_t c_ispeed;		/* input speed */
-	speed_t c_ospeed;		/* output speed */
-};
-
-struct ktermios {
-	tcflag_t c_iflag;		/* input mode flags */
-	tcflag_t c_oflag;		/* output mode flags */
-	tcflag_t c_cflag;		/* control mode flags */
-	tcflag_t c_lflag;		/* local mode flags */
-	cc_t c_line;			/* line discipline */
-	cc_t c_cc[NCCS+2];		/* control characters */
-	speed_t c_ispeed;		/* input speed */
-	speed_t c_ospeed;		/* output speed */
-};
-
-/* c_cc characters */
-#define VINTR    0
-#define VQUIT    1
-#define VERASE   2
-#define VKILL    3
-#define VEOF     4
-#define VEOL     5
-#define VEOL2    6
-#define VSWTC    7
-#define VSTART   8
-#define VSTOP    9
-
-
-
-#define VSUSP    10
-#define VDSUSP   11  /* SunOS POSIX nicety I do believe... */
-#define VREPRINT 12
-#define VDISCARD 13
-#define VWERASE  14
-#define VLNEXT   15
-
-/* Kernel keeps vmin/vtime separated, user apps assume vmin/vtime is
- * shared with eof/eol
- */
-#ifdef __KERNEL__
 #define VMIN     16
 #define VTIME    17
-#else
-#define VMIN     VEOF
-#define VTIME    VEOL
-#endif
-
-/* c_iflag bits */
-#define IGNBRK	0x00000001
-#define BRKINT	0x00000002
-#define IGNPAR	0x00000004
-#define PARMRK	0x00000008
-#define INPCK	0x00000010
-#define ISTRIP	0x00000020
-#define INLCR	0x00000040
-#define IGNCR	0x00000080
-#define ICRNL	0x00000100
-#define IUCLC	0x00000200
-#define IXON	0x00000400
-#define IXANY	0x00000800
-#define IXOFF	0x00001000
-#define IMAXBEL	0x00002000
-#define IUTF8   0x00004000
-
-/* c_oflag bits */
-#define OPOST	0x00000001
-#define OLCUC	0x00000002
-#define ONLCR	0x00000004
-#define OCRNL	0x00000008
-#define ONOCR	0x00000010
-#define ONLRET	0x00000020
-#define OFILL	0x00000040
-#define OFDEL	0x00000080
-#define NLDLY	0x00000100
-#define   NL0	0x00000000
-#define   NL1	0x00000100
-#define CRDLY	0x00000600
-#define   CR0	0x00000000
-#define   CR1	0x00000200
-#define   CR2	0x00000400
-#define   CR3	0x00000600
-#define TABDLY	0x00001800
-#define   TAB0	0x00000000
-#define   TAB1	0x00000800
-#define   TAB2	0x00001000
-#define   TAB3	0x00001800
-#define   XTABS	0x00001800
-#define BSDLY	0x00002000
-#define   BS0	0x00000000
-#define   BS1	0x00002000
-#define VTDLY	0x00004000
-#define   VT0	0x00000000
-#define   VT1	0x00004000
-#define FFDLY	0x00008000
-#define   FF0	0x00000000
-#define   FF1	0x00008000
-#define PAGEOUT 0x00010000  /* SUNOS specific */
-#define WRAP    0x00020000  /* SUNOS specific */
-
-/* c_cflag bit meaning */
-#define CBAUD	  0x0000100f
-#define  B0	  0x00000000   /* hang up */
-#define  B50	  0x00000001
-#define  B75	  0x00000002
-#define  B110	  0x00000003
-#define  B134	  0x00000004
-#define  B150	  0x00000005
-#define  B200	  0x00000006
-#define  B300	  0x00000007
-#define  B600	  0x00000008
-#define  B1200	  0x00000009
-#define  B1800	  0x0000000a
-#define  B2400	  0x0000000b
-#define  B4800	  0x0000000c
-#define  B9600	  0x0000000d
-#define  B19200	  0x0000000e
-#define  B38400	  0x0000000f
-#define EXTA      B19200
-#define EXTB      B38400
-#define  CSIZE    0x00000030
-#define   CS5	  0x00000000
-#define   CS6	  0x00000010
-#define   CS7	  0x00000020
-#define   CS8	  0x00000030
-#define CSTOPB	  0x00000040
-#define CREAD	  0x00000080
-#define PARENB	  0x00000100
-#define PARODD	  0x00000200
-#define HUPCL	  0x00000400
-#define CLOCAL	  0x00000800
-#define CBAUDEX   0x00001000
-/* We'll never see these speeds with the Zilogs, but for completeness... */
-#define  BOTHER   0x00001000
-#define  B57600   0x00001001
-#define  B115200  0x00001002
-#define  B230400  0x00001003
-#define  B460800  0x00001004
-/* This is what we can do with the Zilogs. */
-#define  B76800   0x00001005
-/* This is what we can do with the SAB82532. */
-#define  B153600  0x00001006
-#define  B307200  0x00001007
-#define  B614400  0x00001008
-#define  B921600  0x00001009
-/* And these are the rest... */
-#define  B500000  0x0000100a
-#define  B576000  0x0000100b
-#define B1000000  0x0000100c
-#define B1152000  0x0000100d
-#define B1500000  0x0000100e
-#define B2000000  0x0000100f
-/* These have totally bogus values and nobody uses them
-   so far. Later on we'd have to use say 0x10000x and
-   adjust CBAUD constant and drivers accordingly.
-#define B2500000  0x00001010
-#define B3000000  0x00001011
-#define B3500000  0x00001012
-#define B4000000  0x00001013  */
-#define CIBAUD	  0x100f0000  /* input baud rate (not used) */
-#define CMSPAR	  0x40000000  /* mark or space (stick) parity */
-#define CRTSCTS	  0x80000000  /* flow control */
-
-#define IBSHIFT	  16		/* Shift from CBAUD to CIBAUD */
-
-/* c_lflag bits */
-#define ISIG	0x00000001
-#define ICANON	0x00000002
-#define XCASE	0x00000004
-#define ECHO	0x00000008
-#define ECHOE	0x00000010
-#define ECHOK	0x00000020
-#define ECHONL	0x00000040
-#define NOFLSH	0x00000080
-#define TOSTOP	0x00000100
-#define ECHOCTL	0x00000200
-#define ECHOPRT	0x00000400
-#define ECHOKE	0x00000800
-#define DEFECHO 0x00001000  /* SUNOS thing, what is it? */
-#define FLUSHO	0x00002000
-#define PENDIN	0x00004000
-#define IEXTEN	0x00008000
-#define EXTPROC	0x00010000
-
-/* modem lines */
-#define TIOCM_LE	0x001
-#define TIOCM_DTR	0x002
-#define TIOCM_RTS	0x004
-#define TIOCM_ST	0x008
-#define TIOCM_SR	0x010
-#define TIOCM_CTS	0x020
-#define TIOCM_CAR	0x040
-#define TIOCM_RNG	0x080
-#define TIOCM_DSR	0x100
-#define TIOCM_CD	TIOCM_CAR
-#define TIOCM_RI	TIOCM_RNG
-#define TIOCM_OUT1	0x2000
-#define TIOCM_OUT2	0x4000
-#define TIOCM_LOOP	0x8000
-
-/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
-#define TIOCSER_TEMT    0x01	/* Transmitter physically empty */
-
-
-/* tcflow() and TCXONC use these */
-#define	TCOOFF		0
-#define	TCOON		1
-#define	TCIOFF		2
-#define	TCION		3
-
-/* tcflush() and TCFLSH use these */
-#define	TCIFLUSH	0
-#define	TCOFLUSH	1
-#define	TCIOFLUSH	2
-
-/* tcsetattr uses these */
-#define	TCSANOW		0
-#define	TCSADRAIN	1
-#define	TCSAFLUSH	2
-
 #endif /* !(_SPARC_TERMBITS_H) */
diff --git a/arch/sparc/include/asm/termios.h b/arch/sparc/include/asm/termios.h
index e2f4670..0c2414d 100644
--- a/arch/sparc/include/asm/termios.h
+++ b/arch/sparc/include/asm/termios.h
@@ -1,45 +1,8 @@
 #ifndef _SPARC_TERMIOS_H
 #define _SPARC_TERMIOS_H
 
-#include <asm/ioctls.h>
-#include <asm/termbits.h>
+#include <uapi/asm/termios.h>
 
-#if defined(__KERNEL__) || defined(__DEFINE_BSD_TERMIOS)
-struct sgttyb {
-	char	sg_ispeed;
-	char	sg_ospeed;
-	char	sg_erase;
-	char	sg_kill;
-	short	sg_flags;
-};
-
-struct tchars {
-	char	t_intrc;
-	char	t_quitc;
-	char	t_startc;
-	char	t_stopc;
-	char	t_eofc;
-	char	t_brkc;
-};
-
-struct ltchars {
-	char	t_suspc;
-	char	t_dsuspc;
-	char	t_rprntc;
-	char	t_flushc;
-	char	t_werasc;
-	char	t_lnextc;
-};
-#endif /* __KERNEL__ */
-
-struct winsize {
-	unsigned short ws_row;
-	unsigned short ws_col;
-	unsigned short ws_xpixel;
-	unsigned short ws_ypixel;
-};
-
-#ifdef __KERNEL__
 
 /*
  * c_cc characters in the termio structure.  Oh, how I love being
@@ -180,6 +143,4 @@
 	err; \
 })
 
-#endif	/* __KERNEL__ */
-
 #endif /* _SPARC_TERMIOS_H */
diff --git a/arch/sparc/include/asm/thread_info_32.h b/arch/sparc/include/asm/thread_info_32.h
index e6cd224..25849ae 100644
--- a/arch/sparc/include/asm/thread_info_32.h
+++ b/arch/sparc/include/asm/thread_info_32.h
@@ -126,13 +126,14 @@
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
 #define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
-#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
 #define _TIF_USEDFPU		(1<<TIF_USEDFPU)
 #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
 
 #define _TIF_DO_NOTIFY_RESUME_MASK	(_TIF_NOTIFY_RESUME | \
 					 _TIF_SIGPENDING)
 
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
+
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_THREAD_INFO_H */
diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h
index cfa8c38..4e227663 100644
--- a/arch/sparc/include/asm/thread_info_64.h
+++ b/arch/sparc/include/asm/thread_info_64.h
@@ -256,6 +256,9 @@
 	ti->status &= ~TS_RESTORE_SIGMASK;
 	return true;
 }
+
+#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
+
 #endif	/* !__ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
diff --git a/arch/sparc/include/asm/traps.h b/arch/sparc/include/asm/traps.h
index 3aa62dd..51abcb1 100644
--- a/arch/sparc/include/asm/traps.h
+++ b/arch/sparc/include/asm/traps.h
@@ -3,14 +3,12 @@
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
  */
-
 #ifndef _SPARC_TRAPS_H
 #define _SPARC_TRAPS_H
 
-#define NUM_SPARC_TRAPS  255
+#include <uapi/asm/traps.h>
 
 #ifndef __ASSEMBLY__
-#ifdef __KERNEL__
 /* This is for V8 compliant Sparc CPUS */
 struct tt_entry {
 	unsigned long inst_one;
@@ -22,112 +20,5 @@
 /* We set this to _start in system setup. */
 extern struct tt_entry *sparc_ttable;
 
-#endif /* (__KERNEL__) */
 #endif /* !(__ASSEMBLY__) */
-
-/* For patching the trap table at boot time, we need to know how to
- * form various common Sparc instructions.  Thus these macros...
- */
-
-#define SPARC_MOV_CONST_L3(const) (0xa6102000 | (const&0xfff))
-
-/* The following assumes that the branch lies before the place we
- * are branching to.  This is the case for a trap vector...
- * You have been warned.
- */
-#define SPARC_BRANCH(dest_addr, inst_addr) \
-          (0x10800000 | (((dest_addr-inst_addr)>>2)&0x3fffff))
-
-#define SPARC_RD_PSR_L0  (0xa1480000)
-#define SPARC_RD_WIM_L3  (0xa7500000)
-#define SPARC_NOP (0x01000000)
-
-/* Various interesting trap levels. */
-/* First, hardware traps. */
-#define SP_TRAP_TFLT    0x1          /* Text fault */
-#define SP_TRAP_II      0x2          /* Illegal Instruction */
-#define SP_TRAP_PI      0x3          /* Privileged Instruction */
-#define SP_TRAP_FPD     0x4          /* Floating Point Disabled */
-#define SP_TRAP_WOVF    0x5          /* Window Overflow */
-#define SP_TRAP_WUNF    0x6          /* Window Underflow */
-#define SP_TRAP_MNA     0x7          /* Memory Address Unaligned */
-#define SP_TRAP_FPE     0x8          /* Floating Point Exception */
-#define SP_TRAP_DFLT    0x9          /* Data Fault */
-#define SP_TRAP_TOF     0xa          /* Tag Overflow */
-#define SP_TRAP_WDOG    0xb          /* Watchpoint Detected */
-#define SP_TRAP_IRQ1    0x11         /* IRQ level 1 */
-#define SP_TRAP_IRQ2    0x12         /* IRQ level 2 */
-#define SP_TRAP_IRQ3    0x13         /* IRQ level 3 */
-#define SP_TRAP_IRQ4    0x14         /* IRQ level 4 */
-#define SP_TRAP_IRQ5    0x15         /* IRQ level 5 */
-#define SP_TRAP_IRQ6    0x16         /* IRQ level 6 */
-#define SP_TRAP_IRQ7    0x17         /* IRQ level 7 */
-#define SP_TRAP_IRQ8    0x18         /* IRQ level 8 */
-#define SP_TRAP_IRQ9    0x19         /* IRQ level 9 */
-#define SP_TRAP_IRQ10   0x1a         /* IRQ level 10 */
-#define SP_TRAP_IRQ11   0x1b         /* IRQ level 11 */
-#define SP_TRAP_IRQ12   0x1c         /* IRQ level 12 */
-#define SP_TRAP_IRQ13   0x1d         /* IRQ level 13 */
-#define SP_TRAP_IRQ14   0x1e         /* IRQ level 14 */
-#define SP_TRAP_IRQ15   0x1f         /* IRQ level 15 Non-maskable */
-#define SP_TRAP_RACC    0x20         /* Register Access Error ??? */
-#define SP_TRAP_IACC    0x21         /* Instruction Access Error */
-#define SP_TRAP_CPDIS   0x24         /* Co-Processor Disabled */
-#define SP_TRAP_BADFL   0x25         /* Unimplemented Flush Instruction */
-#define SP_TRAP_CPEXP   0x28         /* Co-Processor Exception */
-#define SP_TRAP_DACC    0x29         /* Data Access Error */
-#define SP_TRAP_DIVZ    0x2a         /* Divide By Zero */
-#define SP_TRAP_DSTORE  0x2b         /* Data Store Error ??? */
-#define SP_TRAP_DMM     0x2c         /* Data Access MMU Miss ??? */
-#define SP_TRAP_IMM     0x3c         /* Instruction Access MMU Miss ??? */
-
-/* Now the Software Traps... */
-#define SP_TRAP_SUNOS   0x80         /* SunOS System Call */
-#define SP_TRAP_SBPT    0x81         /* Software Breakpoint */
-#define SP_TRAP_SDIVZ   0x82         /* Software Divide-by-Zero trap */
-#define SP_TRAP_FWIN    0x83         /* Flush Windows */
-#define SP_TRAP_CWIN    0x84         /* Clean Windows */
-#define SP_TRAP_RCHK    0x85         /* Range Check */
-#define SP_TRAP_FUNA    0x86         /* Fix Unaligned Access */
-#define SP_TRAP_IOWFL   0x87         /* Integer Overflow */
-#define SP_TRAP_SOLARIS 0x88         /* Solaris System Call */
-#define SP_TRAP_NETBSD  0x89         /* NetBSD System Call */
-#define SP_TRAP_LINUX   0x90         /* Linux System Call */
-
-/* Names used for compatibility with SunOS */
-#define ST_SYSCALL              0x00
-#define ST_BREAKPOINT           0x01
-#define ST_DIV0                 0x02
-#define ST_FLUSH_WINDOWS        0x03
-#define ST_CLEAN_WINDOWS        0x04
-#define ST_RANGE_CHECK          0x05
-#define ST_FIX_ALIGN            0x06
-#define ST_INT_OVERFLOW         0x07
-
-/* Special traps... */
-#define SP_TRAP_KBPT1   0xfe         /* KADB/PROM Breakpoint one */
-#define SP_TRAP_KBPT2   0xff         /* KADB/PROM Breakpoint two */
-
-/* Handy Macros */
-/* Is this a trap we never expect to get? */
-#define BAD_TRAP_P(level) \
-        ((level > SP_TRAP_WDOG && level < SP_TRAP_IRQ1) || \
-	 (level > SP_TRAP_IACC && level < SP_TRAP_CPDIS) || \
-	 (level > SP_TRAP_BADFL && level < SP_TRAP_CPEXP) || \
-	 (level > SP_TRAP_DMM && level < SP_TRAP_IMM) || \
-	 (level > SP_TRAP_IMM && level < SP_TRAP_SUNOS) || \
-	 (level > SP_TRAP_LINUX && level < SP_TRAP_KBPT1))
-
-/* Is this a Hardware trap? */
-#define HW_TRAP_P(level) ((level > 0) && (level < SP_TRAP_SUNOS))
-
-/* Is this a Software trap? */
-#define SW_TRAP_P(level) ((level >= SP_TRAP_SUNOS) && (level <= SP_TRAP_KBPT2))
-
-/* Is this a system call for some OS we know about? */
-#define SCALL_TRAP_P(level) ((level == SP_TRAP_SUNOS) || \
-			     (level == SP_TRAP_SOLARIS) || \
-			     (level == SP_TRAP_NETBSD) || \
-			     (level == SP_TRAP_LINUX))
-
 #endif /* !(_SPARC_TRAPS_H) */
diff --git a/arch/sparc/include/asm/tsb.h b/arch/sparc/include/asm/tsb.h
index 1a8afd1..b4c258d 100644
--- a/arch/sparc/include/asm/tsb.h
+++ b/arch/sparc/include/asm/tsb.h
@@ -147,20 +147,96 @@
 	brz,pn		REG1, FAIL_LABEL; \
 	 sllx		VADDR, 64 - (PMD_SHIFT + PMD_BITS), REG2; \
 	srlx		REG2, 64 - PAGE_SHIFT, REG2; \
-	sllx		REG1, 11, REG1; \
+	sllx		REG1, PGD_PADDR_SHIFT, REG1; \
 	andn		REG2, 0x3, REG2; \
 	lduwa		[REG1 + REG2] ASI_PHYS_USE_EC, REG1; \
 	brz,pn		REG1, FAIL_LABEL; \
 	 sllx		VADDR, 64 - PMD_SHIFT, REG2; \
-	srlx		REG2, 64 - PAGE_SHIFT, REG2; \
-	sllx		REG1, 11, REG1; \
+	srlx		REG2, 64 - (PAGE_SHIFT - 1), REG2; \
+	sllx		REG1, PMD_PADDR_SHIFT, REG1; \
 	andn		REG2, 0x7, REG2; \
 	add		REG1, REG2, REG1;
 
-	/* Do a user page table walk in MMU globals.  Leaves physical PTE
-	 * pointer in REG1.  Jumps to FAIL_LABEL on early page table walk
-	 * termination.  Physical base of page tables is in PHYS_PGD which
-	 * will not be modified.
+	/* This macro exists only to make the PMD translator below easier
+	 * to read.  It hides the ELF section switch for the sun4v code
+	 * patching.
+	 */
+#define OR_PTE_BIT(REG, NAME)				\
+661:	or		REG, _PAGE_##NAME##_4U, REG;	\
+	.section	.sun4v_1insn_patch, "ax";	\
+	.word		661b;				\
+	or		REG, _PAGE_##NAME##_4V, REG;	\
+	.previous;
+
+	/* Load into REG the PTE value for VALID, CACHE, and SZHUGE.  */
+#define BUILD_PTE_VALID_SZHUGE_CACHE(REG)				   \
+661:	sethi		%uhi(_PAGE_VALID|_PAGE_SZHUGE_4U), REG;		   \
+	.section	.sun4v_1insn_patch, "ax";			   \
+	.word		661b;						   \
+	sethi		%uhi(_PAGE_VALID), REG;				   \
+	.previous;							   \
+	sllx		REG, 32, REG;					   \
+661:	or		REG, _PAGE_CP_4U|_PAGE_CV_4U, REG;		   \
+	.section	.sun4v_1insn_patch, "ax";			   \
+	.word		661b;						   \
+	or		REG, _PAGE_CP_4V|_PAGE_CV_4V|_PAGE_SZHUGE_4V, REG; \
+	.previous;
+
+	/* PMD has been loaded into REG1, interpret the value, seeing
+	 * if it is a HUGE PMD or a normal one.  If it is not valid
+	 * then jump to FAIL_LABEL.  If it is a HUGE PMD, and it
+	 * translates to a valid PTE, branch to PTE_LABEL.
+	 *
+	 * We translate the PMD by hand, one bit at a time,
+	 * constructing the huge PTE.
+	 *
+	 * So we construct the PTE in REG2 as follows:
+	 *
+	 * 1) Extract the PMD PFN from REG1 and place it into REG2.
+	 *
+	 * 2) Translate PMD protection bits in REG1 into REG2, one bit
+	 *    at a time using andcc tests on REG1 and OR's into REG2.
+	 *
+	 *    Only two bits to be concerned with here, EXEC and WRITE.
+	 *    Now REG1 is freed up and we can use it as a temporary.
+	 *
+	 * 3) Construct the VALID, CACHE, and page size PTE bits in
+	 *    REG1, OR with REG2 to form final PTE.
+	 */
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#define USER_PGTABLE_CHECK_PMD_HUGE(VADDR, REG1, REG2, FAIL_LABEL, PTE_LABEL) \
+	brz,pn		REG1, FAIL_LABEL;				      \
+	 andcc		REG1, PMD_ISHUGE, %g0;				      \
+	be,pt		%xcc, 700f;					      \
+	 and		REG1, PMD_HUGE_PRESENT|PMD_HUGE_ACCESSED, REG2;	      \
+	cmp		REG2, PMD_HUGE_PRESENT|PMD_HUGE_ACCESSED;	      \
+	bne,pn		%xcc, FAIL_LABEL;				      \
+	 andn		REG1, PMD_HUGE_PROTBITS, REG2;			      \
+	sllx		REG2, PMD_PADDR_SHIFT, REG2;			      \
+	/* REG2 now holds PFN << PAGE_SHIFT */				      \
+	andcc		REG1, PMD_HUGE_EXEC, %g0;			      \
+	bne,a,pt	%xcc, 1f;					      \
+	 OR_PTE_BIT(REG2, EXEC);					      \
+1:	andcc		REG1, PMD_HUGE_WRITE, %g0;			      \
+	bne,a,pt	%xcc, 1f;					      \
+	 OR_PTE_BIT(REG2, W);						      \
+	/* REG1 can now be clobbered, build final PTE */		      \
+1:	BUILD_PTE_VALID_SZHUGE_CACHE(REG1);				      \
+	ba,pt		%xcc, PTE_LABEL;				      \
+	 or		REG1, REG2, REG1;				      \
+700:
+#else
+#define USER_PGTABLE_CHECK_PMD_HUGE(VADDR, REG1, REG2, FAIL_LABEL, PTE_LABEL) \
+	brz,pn		REG1, FAIL_LABEL; \
+	 nop;
+#endif
+
+	/* Do a user page table walk in MMU globals.  Leaves final,
+	 * valid, PTE value in REG1.  Jumps to FAIL_LABEL on early
+	 * page table walk termination or if the PTE is not valid.
+	 *
+	 * Physical base of page tables is in PHYS_PGD which will not
+	 * be modified.
 	 *
 	 * VADDR will not be clobbered, but REG1 and REG2 will.
 	 */
@@ -172,15 +248,19 @@
 	brz,pn		REG1, FAIL_LABEL; \
 	 sllx		VADDR, 64 - (PMD_SHIFT + PMD_BITS), REG2; \
 	srlx		REG2, 64 - PAGE_SHIFT, REG2; \
-	sllx		REG1, 11, REG1; \
+	sllx		REG1, PGD_PADDR_SHIFT, REG1; \
 	andn		REG2, 0x3, REG2; \
 	lduwa		[REG1 + REG2] ASI_PHYS_USE_EC, REG1; \
-	brz,pn		REG1, FAIL_LABEL; \
-	 sllx		VADDR, 64 - PMD_SHIFT, REG2; \
-	srlx		REG2, 64 - PAGE_SHIFT, REG2; \
-	sllx		REG1, 11, REG1; \
+	USER_PGTABLE_CHECK_PMD_HUGE(VADDR, REG1, REG2, FAIL_LABEL, 800f) \
+	sllx		VADDR, 64 - PMD_SHIFT, REG2; \
+	srlx		REG2, 64 - (PAGE_SHIFT - 1), REG2; \
+	sllx		REG1, PMD_PADDR_SHIFT, REG1; \
 	andn		REG2, 0x7, REG2; \
-	add		REG1, REG2, REG1;
+	add		REG1, REG2, REG1; \
+	ldxa		[REG1] ASI_PHYS_USE_EC, REG1; \
+	brgez,pn	REG1, FAIL_LABEL; \
+	 nop; \
+800:
 
 /* Lookup a OBP mapping on VADDR in the prom_trans[] table at TL>0.
  * If no entry is found, FAIL_LABEL will be branched to.  On success
diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h
index d9a677c..0ecea6e 100644
--- a/arch/sparc/include/asm/unistd.h
+++ b/arch/sparc/include/asm/unistd.h
@@ -1,6 +1,3 @@
-#ifndef _SPARC_UNISTD_H
-#define _SPARC_UNISTD_H
-
 /*
  * System calls under the Sparc.
  *
@@ -14,415 +11,15 @@
  *
  * Copyright (C) 1995 Adrian M. Rodriguez (adrian@remus.rutgers.edu)
  */
-#ifndef __32bit_syscall_numbers__
-#ifndef __arch64__
-#define __32bit_syscall_numbers__
-#endif
-#endif
+#ifndef _SPARC_UNISTD_H
+#define _SPARC_UNISTD_H
 
-#define __NR_restart_syscall      0 /* Linux Specific				   */
-#define __NR_exit                 1 /* Common                                      */
-#define __NR_fork                 2 /* Common                                      */
-#define __NR_read                 3 /* Common                                      */
-#define __NR_write                4 /* Common                                      */
-#define __NR_open                 5 /* Common                                      */
-#define __NR_close                6 /* Common                                      */
-#define __NR_wait4                7 /* Common                                      */
-#define __NR_creat                8 /* Common                                      */
-#define __NR_link                 9 /* Common                                      */
-#define __NR_unlink              10 /* Common                                      */
-#define __NR_execv               11 /* SunOS Specific                              */
-#define __NR_chdir               12 /* Common                                      */
-#define __NR_chown		 13 /* Common					   */
-#define __NR_mknod               14 /* Common                                      */
-#define __NR_chmod               15 /* Common                                      */
-#define __NR_lchown              16 /* Common                                      */
-#define __NR_brk                 17 /* Common                                      */
-#define __NR_perfctr             18 /* Performance counter operations              */
-#define __NR_lseek               19 /* Common                                      */
-#define __NR_getpid              20 /* Common                                      */
-#define __NR_capget		 21 /* Linux Specific				   */
-#define __NR_capset		 22 /* Linux Specific				   */
-#define __NR_setuid              23 /* Implemented via setreuid in SunOS           */
-#define __NR_getuid              24 /* Common                                      */
-#define __NR_vmsplice	         25 /* ENOSYS under SunOS			   */
-#define __NR_ptrace              26 /* Common                                      */
-#define __NR_alarm               27 /* Implemented via setitimer in SunOS          */
-#define __NR_sigaltstack	 28 /* Common					   */
-#define __NR_pause               29 /* Is sigblock(0)->sigpause() in SunOS         */
-#define __NR_utime               30 /* Implemented via utimes() under SunOS        */
+#include <uapi/asm/unistd.h>
+
 #ifdef __32bit_syscall_numbers__
-#define __NR_lchown32            31 /* Linux sparc32 specific                      */
-#define __NR_fchown32            32 /* Linux sparc32 specific                      */
-#endif
-#define __NR_access              33 /* Common                                      */
-#define __NR_nice                34 /* Implemented via get/setpriority() in SunOS  */
-#ifdef __32bit_syscall_numbers__
-#define __NR_chown32             35 /* Linux sparc32 specific                      */
-#endif
-#define __NR_sync                36 /* Common                                      */
-#define __NR_kill                37 /* Common                                      */
-#define __NR_stat                38 /* Common                                      */
-#define __NR_sendfile		 39 /* Linux Specific				   */
-#define __NR_lstat               40 /* Common                                      */
-#define __NR_dup                 41 /* Common                                      */
-#define __NR_pipe                42 /* Common                                      */
-#define __NR_times               43 /* Implemented via getrusage() in SunOS        */
-#ifdef __32bit_syscall_numbers__
-#define __NR_getuid32            44 /* Linux sparc32 specific                      */
-#endif
-#define __NR_umount2             45 /* Linux Specific                              */
-#define __NR_setgid              46 /* Implemented via setregid() in SunOS         */
-#define __NR_getgid              47 /* Common                                      */
-#define __NR_signal              48 /* Implemented via sigvec() in SunOS           */
-#define __NR_geteuid             49 /* SunOS calls getuid()                        */
-#define __NR_getegid             50 /* SunOS calls getgid()                        */
-#define __NR_acct                51 /* Common                                      */
-#ifdef __32bit_syscall_numbers__
-#define __NR_getgid32            53 /* Linux sparc32 specific                      */
 #else
-#define __NR_memory_ordering	 52 /* Linux Specific				   */
-#endif
-#define __NR_ioctl               54 /* Common                                      */
-#define __NR_reboot              55 /* Common                                      */
-#ifdef __32bit_syscall_numbers__
-#define __NR_mmap2		 56 /* Linux sparc32 Specific			   */
-#endif
-#define __NR_symlink             57 /* Common                                      */
-#define __NR_readlink            58 /* Common                                      */
-#define __NR_execve              59 /* Common                                      */
-#define __NR_umask               60 /* Common                                      */
-#define __NR_chroot              61 /* Common                                      */
-#define __NR_fstat               62 /* Common                                      */
-#define __NR_fstat64		 63 /* Linux Specific			           */
-#define __NR_getpagesize         64 /* Common                                      */
-#define __NR_msync               65 /* Common in newer 1.3.x revs...               */
-#define __NR_vfork               66 /* Common                                      */
-#define __NR_pread64             67 /* Linux Specific                              */
-#define __NR_pwrite64            68 /* Linux Specific                              */
-#ifdef __32bit_syscall_numbers__
-#define __NR_geteuid32           69 /* Linux sparc32, sbrk under SunOS             */
-#define __NR_getegid32           70 /* Linux sparc32, sstk under SunOS             */
-#endif
-#define __NR_mmap                71 /* Common                                      */
-#ifdef __32bit_syscall_numbers__
-#define __NR_setreuid32          72 /* Linux sparc32, vadvise under SunOS          */
-#endif
-#define __NR_munmap              73 /* Common                                      */
-#define __NR_mprotect            74 /* Common                                      */
-#define __NR_madvise             75 /* Common                                      */
-#define __NR_vhangup             76 /* Common                                      */
-#ifdef __32bit_syscall_numbers__
-#define __NR_truncate64		 77 /* Linux sparc32 Specific			   */
-#endif
-#define __NR_mincore             78 /* Common                                      */
-#define __NR_getgroups           79 /* Common                                      */
-#define __NR_setgroups           80 /* Common                                      */
-#define __NR_getpgrp             81 /* Common                                      */
-#ifdef __32bit_syscall_numbers__
-#define __NR_setgroups32         82 /* Linux sparc32, setpgrp under SunOS          */
-#endif
-#define __NR_setitimer           83 /* Common                                      */
-#ifdef __32bit_syscall_numbers__
-#define __NR_ftruncate64	 84 /* Linux sparc32 Specific			   */
-#endif
-#define __NR_swapon              85 /* Common                                      */
-#define __NR_getitimer           86 /* Common                                      */
-#ifdef __32bit_syscall_numbers__
-#define __NR_setuid32            87 /* Linux sparc32, gethostname under SunOS      */
-#endif
-#define __NR_sethostname         88 /* Common                                      */
-#ifdef __32bit_syscall_numbers__
-#define __NR_setgid32            89 /* Linux sparc32, getdtablesize under SunOS    */
-#endif
-#define __NR_dup2                90 /* Common                                      */
-#ifdef __32bit_syscall_numbers__
-#define __NR_setfsuid32          91 /* Linux sparc32, getdopt under SunOS          */
-#endif
-#define __NR_fcntl               92 /* Common                                      */
-#define __NR_select              93 /* Common                                      */
-#ifdef __32bit_syscall_numbers__
-#define __NR_setfsgid32          94 /* Linux sparc32, setdopt under SunOS          */
-#endif
-#define __NR_fsync               95 /* Common                                      */
-#define __NR_setpriority         96 /* Common                                      */
-#define __NR_socket              97 /* Common                                      */
-#define __NR_connect             98 /* Common                                      */
-#define __NR_accept              99 /* Common                                      */
-#define __NR_getpriority        100 /* Common                                      */
-#define __NR_rt_sigreturn       101 /* Linux Specific                              */
-#define __NR_rt_sigaction       102 /* Linux Specific                              */
-#define __NR_rt_sigprocmask     103 /* Linux Specific                              */
-#define __NR_rt_sigpending      104 /* Linux Specific                              */
-#define __NR_rt_sigtimedwait    105 /* Linux Specific                              */
-#define __NR_rt_sigqueueinfo    106 /* Linux Specific                              */
-#define __NR_rt_sigsuspend      107 /* Linux Specific                              */
-#ifdef __32bit_syscall_numbers__
-#define __NR_setresuid32        108 /* Linux Specific, sigvec under SunOS	   */
-#define __NR_getresuid32        109 /* Linux Specific, sigblock under SunOS	   */
-#define __NR_setresgid32        110 /* Linux Specific, sigsetmask under SunOS	   */
-#define __NR_getresgid32        111 /* Linux Specific, sigpause under SunOS	   */
-#define __NR_setregid32         112 /* Linux sparc32, sigstack under SunOS         */
-#else
-#define __NR_setresuid          108 /* Linux Specific, sigvec under SunOS	   */
-#define __NR_getresuid          109 /* Linux Specific, sigblock under SunOS	   */
-#define __NR_setresgid          110 /* Linux Specific, sigsetmask under SunOS	   */
-#define __NR_getresgid          111 /* Linux Specific, sigpause under SunOS	   */
-#endif
-#define __NR_recvmsg            113 /* Common                                      */
-#define __NR_sendmsg            114 /* Common                                      */
-#ifdef __32bit_syscall_numbers__
-#define __NR_getgroups32        115 /* Linux sparc32, vtrace under SunOS           */
-#endif
-#define __NR_gettimeofday       116 /* Common                                      */
-#define __NR_getrusage          117 /* Common                                      */
-#define __NR_getsockopt         118 /* Common                                      */
-#define __NR_getcwd		119 /* Linux Specific				   */
-#define __NR_readv              120 /* Common                                      */
-#define __NR_writev             121 /* Common                                      */
-#define __NR_settimeofday       122 /* Common                                      */
-#define __NR_fchown             123 /* Common                                      */
-#define __NR_fchmod             124 /* Common                                      */
-#define __NR_recvfrom           125 /* Common                                      */
-#define __NR_setreuid           126 /* Common                                      */
-#define __NR_setregid           127 /* Common                                      */
-#define __NR_rename             128 /* Common                                      */
-#define __NR_truncate           129 /* Common                                      */
-#define __NR_ftruncate          130 /* Common                                      */
-#define __NR_flock              131 /* Common                                      */
-#define __NR_lstat64		132 /* Linux Specific			           */
-#define __NR_sendto             133 /* Common                                      */
-#define __NR_shutdown           134 /* Common                                      */
-#define __NR_socketpair         135 /* Common                                      */
-#define __NR_mkdir              136 /* Common                                      */
-#define __NR_rmdir              137 /* Common                                      */
-#define __NR_utimes             138 /* SunOS Specific                              */
-#define __NR_stat64		139 /* Linux Specific			           */
-#define __NR_sendfile64         140 /* adjtime under SunOS                         */
-#define __NR_getpeername        141 /* Common                                      */
-#define __NR_futex              142 /* gethostid under SunOS                       */
-#define __NR_gettid             143 /* ENOSYS under SunOS                          */
-#define __NR_getrlimit		144 /* Common                                      */
-#define __NR_setrlimit          145 /* Common                                      */
-#define __NR_pivot_root		146 /* Linux Specific, killpg under SunOS          */
-#define __NR_prctl		147 /* ENOSYS under SunOS                          */
-#define __NR_pciconfig_read	148 /* ENOSYS under SunOS                          */
-#define __NR_pciconfig_write	149 /* ENOSYS under SunOS                          */
-#define __NR_getsockname        150 /* Common                                      */
-#define __NR_inotify_init       151 /* Linux specific                              */
-#define __NR_inotify_add_watch  152 /* Linux specific                              */
-#define __NR_poll               153 /* Common                                      */
-#define __NR_getdents64		154 /* Linux specific				   */
-#ifdef __32bit_syscall_numbers__
-#define __NR_fcntl64		155 /* Linux sparc32 Specific                      */
-#endif
-#define __NR_inotify_rm_watch   156 /* Linux specific				   */
-#define __NR_statfs             157 /* Common                                      */
-#define __NR_fstatfs            158 /* Common                                      */
-#define __NR_umount             159 /* Common                                      */
-#define __NR_sched_set_affinity 160 /* Linux specific, async_daemon under SunOS    */
-#define __NR_sched_get_affinity 161 /* Linux specific, getfh under SunOS           */
-#define __NR_getdomainname      162 /* SunOS Specific                              */
-#define __NR_setdomainname      163 /* Common                                      */
-#ifndef __32bit_syscall_numbers__
-#define __NR_utrap_install	164 /* SYSV ABI/v9 required			   */
-#endif
-#define __NR_quotactl           165 /* Common                                      */
-#define __NR_set_tid_address    166 /* Linux specific, exportfs under SunOS        */
-#define __NR_mount              167 /* Common                                      */
-#define __NR_ustat              168 /* Common                                      */
-#define __NR_setxattr           169 /* SunOS: semsys                               */
-#define __NR_lsetxattr          170 /* SunOS: msgsys                               */
-#define __NR_fsetxattr          171 /* SunOS: shmsys                               */
-#define __NR_getxattr           172 /* SunOS: auditsys                             */
-#define __NR_lgetxattr          173 /* SunOS: rfssys                               */
-#define __NR_getdents           174 /* Common                                      */
-#define __NR_setsid             175 /* Common                                      */
-#define __NR_fchdir             176 /* Common                                      */
-#define __NR_fgetxattr          177 /* SunOS: fchroot                              */
-#define __NR_listxattr          178 /* SunOS: vpixsys                              */
-#define __NR_llistxattr         179 /* SunOS: aioread                              */
-#define __NR_flistxattr         180 /* SunOS: aiowrite                             */
-#define __NR_removexattr        181 /* SunOS: aiowait                              */
-#define __NR_lremovexattr       182 /* SunOS: aiocancel                            */
-#define __NR_sigpending         183 /* Common                                      */
-#define __NR_query_module	184 /* Linux Specific				   */
-#define __NR_setpgid            185 /* Common                                      */
-#define __NR_fremovexattr       186 /* SunOS: pathconf                             */
-#define __NR_tkill              187 /* SunOS: fpathconf                            */
-#define __NR_exit_group		188 /* Linux specific, sysconf undef SunOS         */
-#define __NR_uname              189 /* Linux Specific                              */
-#define __NR_init_module        190 /* Linux Specific                              */
-#define __NR_personality        191 /* Linux Specific                              */
-#define __NR_remap_file_pages   192 /* Linux Specific                              */
-#define __NR_epoll_create       193 /* Linux Specific                              */
-#define __NR_epoll_ctl          194 /* Linux Specific                              */
-#define __NR_epoll_wait         195 /* Linux Specific                              */
-#define __NR_ioprio_set         196 /* Linux Specific                              */
-#define __NR_getppid            197 /* Linux Specific                              */
-#define __NR_sigaction          198 /* Linux Specific                              */
-#define __NR_sgetmask           199 /* Linux Specific                              */
-#define __NR_ssetmask           200 /* Linux Specific                              */
-#define __NR_sigsuspend         201 /* Linux Specific                              */
-#define __NR_oldlstat           202 /* Linux Specific                              */
-#define __NR_uselib             203 /* Linux Specific                              */
-#define __NR_readdir            204 /* Linux Specific                              */
-#define __NR_readahead          205 /* Linux Specific                              */
-#define __NR_socketcall         206 /* Linux Specific                              */
-#define __NR_syslog             207 /* Linux Specific                              */
-#define __NR_lookup_dcookie     208 /* Linux Specific                              */
-#define __NR_fadvise64          209 /* Linux Specific                              */
-#define __NR_fadvise64_64       210 /* Linux Specific                              */
-#define __NR_tgkill             211 /* Linux Specific                              */
-#define __NR_waitpid            212 /* Linux Specific                              */
-#define __NR_swapoff            213 /* Linux Specific                              */
-#define __NR_sysinfo            214 /* Linux Specific                              */
-#define __NR_ipc                215 /* Linux Specific                              */
-#define __NR_sigreturn          216 /* Linux Specific                              */
-#define __NR_clone              217 /* Linux Specific                              */
-#define __NR_ioprio_get         218 /* Linux Specific                              */
-#define __NR_adjtimex           219 /* Linux Specific                              */
-#define __NR_sigprocmask        220 /* Linux Specific                              */
-#define __NR_create_module      221 /* Linux Specific                              */
-#define __NR_delete_module      222 /* Linux Specific                              */
-#define __NR_get_kernel_syms    223 /* Linux Specific                              */
-#define __NR_getpgid            224 /* Linux Specific                              */
-#define __NR_bdflush            225 /* Linux Specific                              */
-#define __NR_sysfs              226 /* Linux Specific                              */
-#define __NR_afs_syscall        227 /* Linux Specific                              */
-#define __NR_setfsuid           228 /* Linux Specific                              */
-#define __NR_setfsgid           229 /* Linux Specific                              */
-#define __NR__newselect         230 /* Linux Specific                              */
-#ifdef __32bit_syscall_numbers__
-#define __NR_time               231 /* Linux Specific                              */
-#else
-#ifdef __KERNEL__
 #define __NR_time		231 /* Linux sparc32                               */
 #endif
-#endif
-#define __NR_splice             232 /* Linux Specific                              */
-#define __NR_stime              233 /* Linux Specific                              */
-#define __NR_statfs64           234 /* Linux Specific                              */
-#define __NR_fstatfs64          235 /* Linux Specific                              */
-#define __NR__llseek            236 /* Linux Specific                              */
-#define __NR_mlock              237
-#define __NR_munlock            238
-#define __NR_mlockall           239
-#define __NR_munlockall         240
-#define __NR_sched_setparam     241
-#define __NR_sched_getparam     242
-#define __NR_sched_setscheduler 243
-#define __NR_sched_getscheduler 244
-#define __NR_sched_yield        245
-#define __NR_sched_get_priority_max 246
-#define __NR_sched_get_priority_min 247
-#define __NR_sched_rr_get_interval  248
-#define __NR_nanosleep          249
-#define __NR_mremap             250
-#define __NR__sysctl            251
-#define __NR_getsid             252
-#define __NR_fdatasync          253
-#define __NR_nfsservctl         254
-#define __NR_sync_file_range	255
-#define __NR_clock_settime	256
-#define __NR_clock_gettime	257
-#define __NR_clock_getres	258
-#define __NR_clock_nanosleep	259
-#define __NR_sched_getaffinity	260
-#define __NR_sched_setaffinity	261
-#define __NR_timer_settime	262
-#define __NR_timer_gettime	263
-#define __NR_timer_getoverrun	264
-#define __NR_timer_delete	265
-#define __NR_timer_create	266
-/* #define __NR_vserver		267 Reserved for VSERVER */
-#define __NR_io_setup		268
-#define __NR_io_destroy		269
-#define __NR_io_submit		270
-#define __NR_io_cancel		271
-#define __NR_io_getevents	272
-#define __NR_mq_open		273
-#define __NR_mq_unlink		274
-#define __NR_mq_timedsend	275
-#define __NR_mq_timedreceive	276
-#define __NR_mq_notify		277
-#define __NR_mq_getsetattr	278
-#define __NR_waitid		279
-#define __NR_tee		280
-#define __NR_add_key		281
-#define __NR_request_key	282
-#define __NR_keyctl		283
-#define __NR_openat		284
-#define __NR_mkdirat		285
-#define __NR_mknodat		286
-#define __NR_fchownat		287
-#define __NR_futimesat		288
-#define __NR_fstatat64		289
-#define __NR_unlinkat		290
-#define __NR_renameat		291
-#define __NR_linkat		292
-#define __NR_symlinkat		293
-#define __NR_readlinkat		294
-#define __NR_fchmodat		295
-#define __NR_faccessat		296
-#define __NR_pselect6		297
-#define __NR_ppoll		298
-#define __NR_unshare		299
-#define __NR_set_robust_list	300
-#define __NR_get_robust_list	301
-#define __NR_migrate_pages	302
-#define __NR_mbind		303
-#define __NR_get_mempolicy	304
-#define __NR_set_mempolicy	305
-#define __NR_kexec_load		306
-#define __NR_move_pages		307
-#define __NR_getcpu		308
-#define __NR_epoll_pwait	309
-#define __NR_utimensat		310
-#define __NR_signalfd		311
-#define __NR_timerfd_create	312
-#define __NR_eventfd		313
-#define __NR_fallocate		314
-#define __NR_timerfd_settime	315
-#define __NR_timerfd_gettime	316
-#define __NR_signalfd4		317
-#define __NR_eventfd2		318
-#define __NR_epoll_create1	319
-#define __NR_dup3		320
-#define __NR_pipe2		321
-#define __NR_inotify_init1	322
-#define __NR_accept4		323
-#define __NR_preadv		324
-#define __NR_pwritev		325
-#define __NR_rt_tgsigqueueinfo	326
-#define __NR_perf_event_open	327
-#define __NR_recvmmsg		328
-#define __NR_fanotify_init	329
-#define __NR_fanotify_mark	330
-#define __NR_prlimit64		331
-#define __NR_name_to_handle_at	332
-#define __NR_open_by_handle_at	333
-#define __NR_clock_adjtime	334
-#define __NR_syncfs		335
-#define __NR_sendmmsg		336
-#define __NR_setns		337
-#define __NR_process_vm_readv	338
-#define __NR_process_vm_writev	339
-
-#define NR_syscalls		340
-
-#ifdef __32bit_syscall_numbers__
-/* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,
- * it never had the plain ones and there is no value to adding those
- * old versions into the syscall table.
- */
-#define __IGNORE_setresuid
-#define __IGNORE_getresuid
-#define __IGNORE_setresgid
-#define __IGNORE_getresgid
-#endif
-
-#ifdef __KERNEL__
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
@@ -458,5 +55,4 @@
  */
 #define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
 
-#endif /* __KERNEL__ */
 #endif /* _SPARC_UNISTD_H */
diff --git a/arch/sparc/include/uapi/asm/Kbuild b/arch/sparc/include/uapi/asm/Kbuild
index 7518ad2..ce175af 100644
--- a/arch/sparc/include/uapi/asm/Kbuild
+++ b/arch/sparc/include/uapi/asm/Kbuild
@@ -3,3 +3,49 @@
 
 include include/uapi/asm-generic/Kbuild.asm
 
+header-y += apc.h
+header-y += asi.h
+header-y += auxvec.h
+header-y += bitsperlong.h
+header-y += byteorder.h
+header-y += display7seg.h
+header-y += envctrl.h
+header-y += errno.h
+header-y += fbio.h
+header-y += fcntl.h
+header-y += ioctl.h
+header-y += ioctls.h
+header-y += ipcbuf.h
+header-y += jsflash.h
+header-y += kvm_para.h
+header-y += mman.h
+header-y += msgbuf.h
+header-y += openpromio.h
+header-y += param.h
+header-y += perfctr.h
+header-y += poll.h
+header-y += posix_types.h
+header-y += psr.h
+header-y += psrcompat.h
+header-y += pstate.h
+header-y += ptrace.h
+header-y += resource.h
+header-y += sembuf.h
+header-y += setup.h
+header-y += shmbuf.h
+header-y += sigcontext.h
+header-y += siginfo.h
+header-y += signal.h
+header-y += socket.h
+header-y += sockios.h
+header-y += stat.h
+header-y += statfs.h
+header-y += swab.h
+header-y += termbits.h
+header-y += termios.h
+header-y += traps.h
+header-y += types.h
+header-y += uctx.h
+header-y += unistd.h
+header-y += utrap.h
+header-y += watchdog.h
diff --git a/arch/sparc/include/asm/apc.h b/arch/sparc/include/uapi/asm/apc.h
similarity index 100%
rename from arch/sparc/include/asm/apc.h
rename to arch/sparc/include/uapi/asm/apc.h
diff --git a/arch/sparc/include/asm/asi.h b/arch/sparc/include/uapi/asm/asi.h
similarity index 95%
rename from arch/sparc/include/asm/asi.h
rename to arch/sparc/include/uapi/asm/asi.h
index cc0006d..aace6f3 100644
--- a/arch/sparc/include/asm/asi.h
+++ b/arch/sparc/include/uapi/asm/asi.h
@@ -270,9 +270,28 @@
 #define ASI_BLK_INIT_QUAD_LDD_P	0xe2 /* (NG) init-store, twin load,
 				      * primary, implicit
 				      */
+#define ASI_BLK_INIT_QUAD_LDD_S	0xe3 /* (NG) init-store, twin load,
+				      * secondary, implicit
+				      */
 #define ASI_BLK_P		0xf0 /* Primary, blk ld/st		*/
 #define ASI_BLK_S		0xf1 /* Secondary, blk ld/st		*/
+#define ASI_ST_BLKINIT_MRU_P	0xf2 /* (NG4) init-store, twin load,
+				      * Most-Recently-Used, primary,
+				      * implicit
+				      */
+#define ASI_ST_BLKINIT_MRU_S	0xf2 /* (NG4) init-store, twin load,
+				      * Most-Recently-Used, secondary,
+				      * implicit
+				      */
 #define ASI_BLK_PL		0xf8 /* Primary, blk ld/st, little	*/
 #define ASI_BLK_SL		0xf9 /* Secondary, blk ld/st, little	*/
+#define ASI_ST_BLKINIT_MRU_PL	0xfa /* (NG4) init-store, twin load,
+				      * Most-Recently-Used, primary,
+				      * implicit, little-endian
+				      */
+#define ASI_ST_BLKINIT_MRU_SL	0xfb /* (NG4) init-store, twin load,
+				      * Most-Recently-Used, secondary,
+				      * implicit, little-endian
+				      */
 
 #endif /* _SPARC_ASI_H */
diff --git a/arch/sparc/include/asm/auxvec.h b/arch/sparc/include/uapi/asm/auxvec.h
similarity index 100%
rename from arch/sparc/include/asm/auxvec.h
rename to arch/sparc/include/uapi/asm/auxvec.h
diff --git a/arch/sparc/include/asm/bitsperlong.h b/arch/sparc/include/uapi/asm/bitsperlong.h
similarity index 100%
rename from arch/sparc/include/asm/bitsperlong.h
rename to arch/sparc/include/uapi/asm/bitsperlong.h
diff --git a/arch/sparc/include/asm/byteorder.h b/arch/sparc/include/uapi/asm/byteorder.h
similarity index 100%
rename from arch/sparc/include/asm/byteorder.h
rename to arch/sparc/include/uapi/asm/byteorder.h
diff --git a/arch/sparc/include/asm/display7seg.h b/arch/sparc/include/uapi/asm/display7seg.h
similarity index 100%
rename from arch/sparc/include/asm/display7seg.h
rename to arch/sparc/include/uapi/asm/display7seg.h
diff --git a/arch/sparc/include/asm/envctrl.h b/arch/sparc/include/uapi/asm/envctrl.h
similarity index 100%
rename from arch/sparc/include/asm/envctrl.h
rename to arch/sparc/include/uapi/asm/envctrl.h
diff --git a/arch/sparc/include/asm/errno.h b/arch/sparc/include/uapi/asm/errno.h
similarity index 100%
rename from arch/sparc/include/asm/errno.h
rename to arch/sparc/include/uapi/asm/errno.h
diff --git a/arch/sparc/include/uapi/asm/fbio.h b/arch/sparc/include/uapi/asm/fbio.h
new file mode 100644
index 0000000..d6cea07
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/fbio.h
@@ -0,0 +1,259 @@
+#ifndef _UAPI__LINUX_FBIO_H
+#define _UAPI__LINUX_FBIO_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+/* Constants used for fbio SunOS compatibility */
+/* (C) 1996 Miguel de Icaza */
+
+/* Frame buffer types */
+#define FBTYPE_NOTYPE           -1
+#define FBTYPE_SUN1BW           0   /* mono */
+#define FBTYPE_SUN1COLOR        1 
+#define FBTYPE_SUN2BW           2 
+#define FBTYPE_SUN2COLOR        3 
+#define FBTYPE_SUN2GP           4 
+#define FBTYPE_SUN5COLOR        5 
+#define FBTYPE_SUN3COLOR        6 
+#define FBTYPE_MEMCOLOR         7 
+#define FBTYPE_SUN4COLOR        8 
+ 
+#define FBTYPE_NOTSUN1          9 
+#define FBTYPE_NOTSUN2          10
+#define FBTYPE_NOTSUN3          11
+ 
+#define FBTYPE_SUNFAST_COLOR    12  /* cg6 */
+#define FBTYPE_SUNROP_COLOR     13
+#define FBTYPE_SUNFB_VIDEO      14
+#define FBTYPE_SUNGIFB          15
+#define FBTYPE_SUNGPLAS         16
+#define FBTYPE_SUNGP3           17
+#define FBTYPE_SUNGT            18
+#define FBTYPE_SUNLEO           19      /* zx Leo card */
+#define FBTYPE_MDICOLOR         20      /* cg14 */
+#define FBTYPE_TCXCOLOR		21	/* SUNW,tcx card */
+
+#define FBTYPE_LASTPLUSONE      21	/* This is not last + 1 in fact... */
+
+/* Does not seem to be listed in the Sun file either */
+#define FBTYPE_CREATOR          22
+#define FBTYPE_PCI_IGA1682	23
+#define FBTYPE_P9100COLOR	24
+
+#define FBTYPE_PCI_GENERIC	1000
+#define FBTYPE_PCI_MACH64	1001
+
+/* fbio ioctls */
+/* Returned by FBIOGTYPE */
+struct  fbtype {
+        int     fb_type;        /* fb type, see above */
+        int     fb_height;      /* pixels */
+        int     fb_width;       /* pixels */
+        int     fb_depth;
+        int     fb_cmsize;      /* color map entries */
+        int     fb_size;        /* fb size in bytes */
+};
+#define FBIOGTYPE _IOR('F', 0, struct fbtype)
+
+struct  fbcmap {
+        int             index;          /* first element (0 origin) */
+        int             count;
+        unsigned char   __user *red;
+        unsigned char   __user *green;
+        unsigned char   __user *blue;
+};
+
+#ifndef __KERNEL__
+#define FBIOPUTCMAP _IOW('F', 3, struct fbcmap)
+#define FBIOGETCMAP _IOW('F', 4, struct fbcmap)
+#endif
+
+/* # of device specific values */
+#define FB_ATTR_NDEVSPECIFIC    8
+/* # of possible emulations */
+#define FB_ATTR_NEMUTYPES       4
+ 
+struct fbsattr {
+        int     flags;
+        int     emu_type;	/* -1 if none */
+        int     dev_specific[FB_ATTR_NDEVSPECIFIC];
+};
+ 
+struct fbgattr {
+        int     real_type;	/* real frame buffer type */
+        int     owner;		/* unknown */
+        struct fbtype fbtype;	/* real frame buffer fbtype */
+        struct fbsattr sattr;   
+        int     emu_types[FB_ATTR_NEMUTYPES]; /* supported emulations */
+};
+#define FBIOSATTR  _IOW('F', 5, struct fbgattr) /* Unsupported: */
+#define FBIOGATTR  _IOR('F', 6, struct fbgattr)	/* supported */
+
+#define FBIOSVIDEO _IOW('F', 7, int)
+#define FBIOGVIDEO _IOR('F', 8, int)
+
+struct fbcursor {
+        short set;              /* what to set, choose from the list above */
+        short enable;           /* cursor on/off */
+        struct fbcurpos pos;    /* cursor position */
+        struct fbcurpos hot;    /* cursor hot spot */
+        struct fbcmap cmap;     /* color map info */
+        struct fbcurpos size;   /* cursor bit map size */
+        char __user *image;     /* cursor image bits */
+        char __user *mask;      /* cursor mask bits */
+};
+
+/* set/get cursor attributes/shape */
+#define FBIOSCURSOR     _IOW('F', 24, struct fbcursor)
+#define FBIOGCURSOR     _IOWR('F', 25, struct fbcursor)
+ 
+/* set/get cursor position */
+#define FBIOSCURPOS     _IOW('F', 26, struct fbcurpos)
+#define FBIOGCURPOS     _IOW('F', 27, struct fbcurpos)
+ 
+/* get max cursor size */
+#define FBIOGCURMAX     _IOR('F', 28, struct fbcurpos)
+
+/* wid manipulation */
+struct fb_wid_alloc {
+#define FB_WID_SHARED_8		0
+#define FB_WID_SHARED_24	1
+#define FB_WID_DBL_8		2
+#define FB_WID_DBL_24		3
+	__u32	wa_type;
+	__s32	wa_index;	/* Set on return */
+	__u32	wa_count;	
+};
+struct fb_wid_item {
+	__u32	wi_type;
+	__s32	wi_index;
+	__u32	wi_attrs;
+	__u32	wi_values[32];
+};
+struct fb_wid_list {
+	__u32	wl_flags;
+	__u32	wl_count;
+	struct fb_wid_item	*wl_list;
+};
+
+#define FBIO_WID_ALLOC	_IOWR('F', 30, struct fb_wid_alloc)
+#define FBIO_WID_FREE	_IOW('F', 31, struct fb_wid_alloc)
+#define FBIO_WID_PUT	_IOW('F', 32, struct fb_wid_list)
+#define FBIO_WID_GET	_IOWR('F', 33, struct fb_wid_list)
+
+/* Creator ioctls */
+#define FFB_IOCTL	('F'<<8)
+#define FFB_SYS_INFO		(FFB_IOCTL|80)
+#define FFB_CLUTREAD		(FFB_IOCTL|81)
+#define FFB_CLUTPOST		(FFB_IOCTL|82)
+#define FFB_SETDIAGMODE		(FFB_IOCTL|83)
+#define FFB_GETMONITORID	(FFB_IOCTL|84)
+#define FFB_GETVIDEOMODE	(FFB_IOCTL|85)
+#define FFB_SETVIDEOMODE	(FFB_IOCTL|86)
+#define FFB_SETSERVER		(FFB_IOCTL|87)
+#define FFB_SETOVCTL		(FFB_IOCTL|88)
+#define FFB_GETOVCTL		(FFB_IOCTL|89)
+#define FFB_GETSAXNUM		(FFB_IOCTL|90)
+#define FFB_FBDEBUG		(FFB_IOCTL|91)
+
+/* Cg14 ioctls */
+#define MDI_IOCTL          ('M'<<8)
+#define MDI_RESET          (MDI_IOCTL|1)
+#define MDI_GET_CFGINFO    (MDI_IOCTL|2)
+#define MDI_SET_PIXELMODE  (MDI_IOCTL|3)
+#    define MDI_32_PIX     32
+#    define MDI_16_PIX     16
+#    define MDI_8_PIX      8
+
+struct mdi_cfginfo {
+	int     mdi_ncluts;     /* Number of implemented CLUTs in this MDI */
+        int     mdi_type;       /* FBTYPE name */
+        int     mdi_height;     /* height */
+        int     mdi_width;      /* width */
+        int     mdi_size;       /* available ram */
+        int     mdi_mode;       /* 8bpp, 16bpp or 32bpp */
+        int     mdi_pixfreq;    /* pixel clock (from PROM) */
+};
+
+/* SparcLinux specific ioctl for the MDI, should be replaced for
+ * the SET_XLUT/SET_CLUTn ioctls instead
+ */
+#define MDI_CLEAR_XLUT       (MDI_IOCTL|9)
+
+/* leo & ffb ioctls */
+struct fb_clut_alloc {
+	__u32	clutid;	/* Set on return */
+ 	__u32	flag;
+ 	__u32	index;
+};
+
+struct fb_clut {
+#define FB_CLUT_WAIT	0x00000001	/* Not yet implemented */
+ 	__u32	flag;
+ 	__u32	clutid;
+ 	__u32	offset;
+ 	__u32	count;
+ 	char *	red;
+ 	char *	green;
+ 	char *	blue;
+};
+
+struct fb_clut32 {
+ 	__u32	flag;
+ 	__u32	clutid;
+ 	__u32	offset;
+ 	__u32	count;
+ 	__u32	red;
+ 	__u32	green;
+ 	__u32	blue;
+};
+
+#define LEO_CLUTALLOC	_IOWR('L', 53, struct fb_clut_alloc)
+#define LEO_CLUTFREE	_IOW('L', 54, struct fb_clut_alloc)
+#define LEO_CLUTREAD	_IOW('L', 55, struct fb_clut)
+#define LEO_CLUTPOST	_IOW('L', 56, struct fb_clut)
+#define LEO_SETGAMMA	_IOW('L', 68, int) /* Not yet implemented */
+#define LEO_GETGAMMA	_IOR('L', 69, int) /* Not yet implemented */
+
+
+/* These are exported to userland for applications to use */
+/* Mappable offsets for the cg14: control registers */
+#define MDI_DIRECT_MAP 0x10000000
+#define MDI_CTLREG_MAP 0x20000000
+#define MDI_CURSOR_MAP 0x30000000
+#define MDI_SHDW_VRT_MAP 0x40000000
+
+/* Mappable offsets for the cg14: frame buffer resolutions */
+/* 32 bits */
+#define MDI_CHUNKY_XBGR_MAP 0x50000000
+#define MDI_CHUNKY_BGR_MAP 0x60000000
+
+/* 16 bits */
+#define MDI_PLANAR_X16_MAP 0x70000000
+#define MDI_PLANAR_C16_MAP 0x80000000
+
+/* 8 bit is done as CG3 MMAP offset */
+/* 32 bits, planar */
+#define MDI_PLANAR_X32_MAP 0x90000000
+#define MDI_PLANAR_B32_MAP 0xa0000000
+#define MDI_PLANAR_G32_MAP 0xb0000000
+#define MDI_PLANAR_R32_MAP 0xc0000000
+
+/* Mappable offsets on leo */
+#define LEO_SS0_MAP            0x00000000
+#define LEO_LC_SS0_USR_MAP     0x00800000
+#define LEO_LD_SS0_MAP         0x00801000
+#define LEO_LX_CURSOR_MAP      0x00802000
+#define LEO_SS1_MAP            0x00803000
+#define LEO_LC_SS1_USR_MAP     0x01003000
+#define LEO_LD_SS1_MAP         0x01004000
+#define LEO_UNK_MAP            0x01005000
+#define LEO_LX_KRN_MAP         0x01006000
+#define LEO_LC_SS0_KRN_MAP     0x01007000
+#define LEO_LC_SS1_KRN_MAP     0x01008000
+#define LEO_LD_GBL_MAP         0x01009000
+#define LEO_UNK2_MAP           0x0100a000
+
+
+#endif /* _UAPI__LINUX_FBIO_H */
diff --git a/arch/sparc/include/asm/fcntl.h b/arch/sparc/include/uapi/asm/fcntl.h
similarity index 100%
rename from arch/sparc/include/asm/fcntl.h
rename to arch/sparc/include/uapi/asm/fcntl.h
diff --git a/arch/sparc/include/asm/ioctl.h b/arch/sparc/include/uapi/asm/ioctl.h
similarity index 100%
rename from arch/sparc/include/asm/ioctl.h
rename to arch/sparc/include/uapi/asm/ioctl.h
diff --git a/arch/sparc/include/uapi/asm/ioctls.h b/arch/sparc/include/uapi/asm/ioctls.h
new file mode 100644
index 0000000..9155f70
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/ioctls.h
@@ -0,0 +1,131 @@
+#ifndef _UAPI_ASM_SPARC_IOCTLS_H
+#define _UAPI_ASM_SPARC_IOCTLS_H
+
+#include <asm/ioctl.h>
+
+/* Big T */
+#define TCGETA		_IOR('T', 1, struct termio)
+#define TCSETA		_IOW('T', 2, struct termio)
+#define TCSETAW		_IOW('T', 3, struct termio)
+#define TCSETAF		_IOW('T', 4, struct termio)
+#define TCSBRK		_IO('T', 5)
+#define TCXONC		_IO('T', 6)
+#define TCFLSH		_IO('T', 7)
+#define TCGETS		_IOR('T', 8, struct termios)
+#define TCSETS		_IOW('T', 9, struct termios)
+#define TCSETSW		_IOW('T', 10, struct termios)
+#define TCSETSF		_IOW('T', 11, struct termios)
+#define TCGETS2		_IOR('T', 12, struct termios2)
+#define TCSETS2		_IOW('T', 13, struct termios2)
+#define TCSETSW2	_IOW('T', 14, struct termios2)
+#define TCSETSF2	_IOW('T', 15, struct termios2)
+#define TIOCGDEV	_IOR('T',0x32, unsigned int) /* Get primary device node of /dev/console */
+#define TIOCVHANGUP	_IO('T', 0x37)
+
+/* Note that all the ioctls that are not available in Linux have a 
+ * double underscore on the front to: a) avoid some programs to
+ * think we support some ioctls under Linux (autoconfiguration stuff)
+ */
+/* Little t */
+#define TIOCGETD	_IOR('t', 0, int)
+#define TIOCSETD	_IOW('t', 1, int)
+#define __TIOCHPCL        _IO('t', 2) /* SunOS Specific */
+#define __TIOCMODG        _IOR('t', 3, int) /* SunOS Specific */
+#define __TIOCMODS        _IOW('t', 4, int) /* SunOS Specific */
+#define __TIOCGETP        _IOR('t', 8, struct sgttyb) /* SunOS Specific */
+#define __TIOCSETP        _IOW('t', 9, struct sgttyb) /* SunOS Specific */
+#define __TIOCSETN        _IOW('t', 10, struct sgttyb) /* SunOS Specific */
+#define TIOCEXCL	_IO('t', 13)
+#define TIOCNXCL	_IO('t', 14)
+#define __TIOCFLUSH       _IOW('t', 16, int) /* SunOS Specific */
+#define __TIOCSETC        _IOW('t', 17, struct tchars) /* SunOS Specific */
+#define __TIOCGETC        _IOR('t', 18, struct tchars) /* SunOS Specific */
+#define __TIOCTCNTL       _IOW('t', 32, int) /* SunOS Specific */
+#define __TIOCSIGNAL      _IOW('t', 33, int) /* SunOS Specific */
+#define __TIOCSETX        _IOW('t', 34, int) /* SunOS Specific */
+#define __TIOCGETX        _IOR('t', 35, int) /* SunOS Specific */
+#define TIOCCONS	_IO('t', 36)
+#define TIOCGSOFTCAR	_IOR('t', 100, int)
+#define TIOCSSOFTCAR	_IOW('t', 101, int)
+#define __TIOCUCNTL       _IOW('t', 102, int) /* SunOS Specific */
+#define TIOCSWINSZ	_IOW('t', 103, struct winsize)
+#define TIOCGWINSZ	_IOR('t', 104, struct winsize)
+#define __TIOCREMOTE      _IOW('t', 105, int) /* SunOS Specific */
+#define TIOCMGET	_IOR('t', 106, int)
+#define TIOCMBIC	_IOW('t', 107, int)
+#define TIOCMBIS	_IOW('t', 108, int)
+#define TIOCMSET	_IOW('t', 109, int)
+#define TIOCSTART       _IO('t', 110)
+#define TIOCSTOP        _IO('t', 111)
+#define TIOCPKT		_IOW('t', 112, int)
+#define TIOCNOTTY	_IO('t', 113)
+#define TIOCSTI		_IOW('t', 114, char)
+#define TIOCOUTQ	_IOR('t', 115, int)
+#define __TIOCGLTC        _IOR('t', 116, struct ltchars) /* SunOS Specific */
+#define __TIOCSLTC        _IOW('t', 117, struct ltchars) /* SunOS Specific */
+/* 118 is the non-posix setpgrp tty ioctl */
+/* 119 is the non-posix getpgrp tty ioctl */
+#define __TIOCCDTR        _IO('t', 120) /* SunOS Specific */
+#define __TIOCSDTR        _IO('t', 121) /* SunOS Specific */
+#define TIOCCBRK        _IO('t', 122)
+#define TIOCSBRK        _IO('t', 123)
+#define __TIOCLGET        _IOW('t', 124, int) /* SunOS Specific */
+#define __TIOCLSET        _IOW('t', 125, int) /* SunOS Specific */
+#define __TIOCLBIC        _IOW('t', 126, int) /* SunOS Specific */
+#define __TIOCLBIS        _IOW('t', 127, int) /* SunOS Specific */
+#define __TIOCISPACE      _IOR('t', 128, int) /* SunOS Specific */
+#define __TIOCISIZE       _IOR('t', 129, int) /* SunOS Specific */
+#define TIOCSPGRP	_IOW('t', 130, int)
+#define TIOCGPGRP	_IOR('t', 131, int)
+#define TIOCSCTTY	_IO('t', 132)
+#define TIOCGSID	_IOR('t', 133, int)
+/* Get minor device of a pty master's FD -- Solaris equiv is ISPTM */
+#define TIOCGPTN	_IOR('t', 134, unsigned int) /* Get Pty Number */
+#define TIOCSPTLCK	_IOW('t', 135, int) /* Lock/unlock PTY */
+#define TIOCSIG		_IOW('t', 136, int) /* Generate signal on Pty slave */
+
+/* Little f */
+#define FIOCLEX		_IO('f', 1)
+#define FIONCLEX	_IO('f', 2)
+#define FIOASYNC	_IOW('f', 125, int)
+#define FIONBIO		_IOW('f', 126, int)
+#define FIONREAD	_IOR('f', 127, int)
+#define TIOCINQ		FIONREAD
+#define FIOQSIZE	_IOR('f', 128, loff_t)
+
+/* SCARY Rutgers local SunOS kernel hackery, perhaps I will support it
+ * someday.  This is completely bogus, I know...
+ */
+#define __TCGETSTAT       _IO('T', 200) /* Rutgers specific */
+#define __TCSETSTAT       _IO('T', 201) /* Rutgers specific */
+
+/* Linux specific, no SunOS equivalent. */
+#define TIOCLINUX	0x541C
+#define TIOCGSERIAL	0x541E
+#define TIOCSSERIAL	0x541F
+#define TCSBRKP		0x5425
+#define TIOCSERCONFIG	0x5453
+#define TIOCSERGWILD	0x5454
+#define TIOCSERSWILD	0x5455
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458 /* For debugging only */
+#define TIOCSERGETLSR   0x5459 /* Get line status register */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+#define TIOCMIWAIT	0x545C /* Wait for change on serial input line(s) */
+#define TIOCGICOUNT	0x545D /* Read serial port inline interrupt counts */
+
+/* Kernel definitions */
+
+/* Used for packet mode */
+#define TIOCPKT_DATA		 0
+#define TIOCPKT_FLUSHREAD	 1
+#define TIOCPKT_FLUSHWRITE	 2
+#define TIOCPKT_STOP		 4
+#define TIOCPKT_START		 8
+#define TIOCPKT_NOSTOP		16
+#define TIOCPKT_DOSTOP		32
+#define TIOCPKT_IOCTL		64
+
+#endif /* _UAPI_ASM_SPARC_IOCTLS_H */
diff --git a/arch/sparc/include/asm/ipcbuf.h b/arch/sparc/include/uapi/asm/ipcbuf.h
similarity index 100%
rename from arch/sparc/include/asm/ipcbuf.h
rename to arch/sparc/include/uapi/asm/ipcbuf.h
diff --git a/arch/sparc/include/asm/jsflash.h b/arch/sparc/include/uapi/asm/jsflash.h
similarity index 100%
rename from arch/sparc/include/asm/jsflash.h
rename to arch/sparc/include/uapi/asm/jsflash.h
diff --git a/arch/sparc/include/asm/kvm_para.h b/arch/sparc/include/uapi/asm/kvm_para.h
similarity index 100%
rename from arch/sparc/include/asm/kvm_para.h
rename to arch/sparc/include/uapi/asm/kvm_para.h
diff --git a/arch/sparc/include/uapi/asm/mman.h b/arch/sparc/include/uapi/asm/mman.h
new file mode 100644
index 0000000..0b14df3
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/mman.h
@@ -0,0 +1,27 @@
+#ifndef _UAPI__SPARC_MMAN_H__
+#define _UAPI__SPARC_MMAN_H__
+
+#include <asm-generic/mman-common.h>
+
+/* SunOS'ified... */
+
+#define MAP_RENAME      MAP_ANONYMOUS   /* In SunOS terminology */
+#define MAP_NORESERVE   0x40            /* don't reserve swap pages */
+#define MAP_INHERIT     0x80            /* SunOS doesn't do this, but... */
+#define MAP_LOCKED      0x100           /* lock the mapping */
+#define _MAP_NEW        0x80000000      /* Binary compatibility is fun... */
+
+#define MAP_GROWSDOWN	0x0200		/* stack-like segment */
+#define MAP_DENYWRITE	0x0800		/* ETXTBSY */
+#define MAP_EXECUTABLE	0x1000		/* mark it as an executable */
+
+#define MCL_CURRENT     0x2000          /* lock all currently mapped pages */
+#define MCL_FUTURE      0x4000          /* lock all additions to address space */
+
+#define MAP_POPULATE	0x8000		/* populate (prefault) pagetables */
+#define MAP_NONBLOCK	0x10000		/* do not block on IO */
+#define MAP_STACK	0x20000		/* give out an address that is best suited for process/thread stacks */
+#define MAP_HUGETLB	0x40000		/* create a huge page mapping */
+
+
+#endif /* _UAPI__SPARC_MMAN_H__ */
diff --git a/arch/sparc/include/asm/msgbuf.h b/arch/sparc/include/uapi/asm/msgbuf.h
similarity index 100%
rename from arch/sparc/include/asm/msgbuf.h
rename to arch/sparc/include/uapi/asm/msgbuf.h
diff --git a/arch/sparc/include/asm/openpromio.h b/arch/sparc/include/uapi/asm/openpromio.h
similarity index 100%
rename from arch/sparc/include/asm/openpromio.h
rename to arch/sparc/include/uapi/asm/openpromio.h
diff --git a/arch/sparc/include/asm/param.h b/arch/sparc/include/uapi/asm/param.h
similarity index 100%
rename from arch/sparc/include/asm/param.h
rename to arch/sparc/include/uapi/asm/param.h
diff --git a/arch/sparc/include/asm/perfctr.h b/arch/sparc/include/uapi/asm/perfctr.h
similarity index 100%
rename from arch/sparc/include/asm/perfctr.h
rename to arch/sparc/include/uapi/asm/perfctr.h
diff --git a/arch/sparc/include/asm/poll.h b/arch/sparc/include/uapi/asm/poll.h
similarity index 100%
rename from arch/sparc/include/asm/poll.h
rename to arch/sparc/include/uapi/asm/poll.h
diff --git a/arch/sparc/include/asm/posix_types.h b/arch/sparc/include/uapi/asm/posix_types.h
similarity index 100%
rename from arch/sparc/include/asm/posix_types.h
rename to arch/sparc/include/uapi/asm/posix_types.h
diff --git a/arch/sparc/include/uapi/asm/psr.h b/arch/sparc/include/uapi/asm/psr.h
new file mode 100644
index 0000000..2f0ed85
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/psr.h
@@ -0,0 +1,47 @@
+/*
+ * psr.h: This file holds the macros for masking off various parts of
+ *        the processor status register on the Sparc. This is valid
+ *        for Version 8. On the V9 this is renamed to the PSTATE
+ *        register and its members are accessed as fields like
+ *        PSTATE.PRIV for the current CPU privilege level.
+ *
+ * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _UAPI__LINUX_SPARC_PSR_H
+#define _UAPI__LINUX_SPARC_PSR_H
+
+/* The Sparc PSR fields are laid out as the following:
+ *
+ *  ------------------------------------------------------------------------
+ *  | impl  | vers  | icc   | resv  | EC | EF | PIL  | S | PS | ET |  CWP  |
+ *  | 31-28 | 27-24 | 23-20 | 19-14 | 13 | 12 | 11-8 | 7 | 6  | 5  |  4-0  |
+ *  ------------------------------------------------------------------------
+ */
+#define PSR_CWP     0x0000001f         /* current window pointer     */
+#define PSR_ET      0x00000020         /* enable traps field         */
+#define PSR_PS      0x00000040         /* previous privilege level   */
+#define PSR_S       0x00000080         /* current privilege level    */
+#define PSR_PIL     0x00000f00         /* processor interrupt level  */
+#define PSR_EF      0x00001000         /* enable floating point      */
+#define PSR_EC      0x00002000         /* enable co-processor        */
+#define PSR_SYSCALL 0x00004000         /* inside of a syscall        */
+#define PSR_LE      0x00008000         /* SuperSparcII little-endian */
+#define PSR_ICC     0x00f00000         /* integer condition codes    */
+#define PSR_C       0x00100000         /* carry bit                  */
+#define PSR_V       0x00200000         /* overflow bit               */
+#define PSR_Z       0x00400000         /* zero bit                   */
+#define PSR_N       0x00800000         /* negative bit               */
+#define PSR_VERS    0x0f000000         /* cpu-version field          */
+#define PSR_IMPL    0xf0000000         /* cpu-implementation field   */
+
+#define PSR_VERS_SHIFT		24
+#define PSR_IMPL_SHIFT		28
+#define PSR_VERS_SHIFTED_MASK	0xf
+#define PSR_IMPL_SHIFTED_MASK	0xf
+
+#define PSR_IMPL_TI		0x4
+#define PSR_IMPL_LEON		0xf
+
+
+#endif /* _UAPI__LINUX_SPARC_PSR_H */
diff --git a/arch/sparc/include/asm/psrcompat.h b/arch/sparc/include/uapi/asm/psrcompat.h
similarity index 100%
rename from arch/sparc/include/asm/psrcompat.h
rename to arch/sparc/include/uapi/asm/psrcompat.h
diff --git a/arch/sparc/include/asm/pstate.h b/arch/sparc/include/uapi/asm/pstate.h
similarity index 100%
rename from arch/sparc/include/asm/pstate.h
rename to arch/sparc/include/uapi/asm/pstate.h
diff --git a/arch/sparc/include/uapi/asm/ptrace.h b/arch/sparc/include/uapi/asm/ptrace.h
new file mode 100644
index 0000000..56fe4ea
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/ptrace.h
@@ -0,0 +1,352 @@
+#ifndef _UAPI__SPARC_PTRACE_H
+#define _UAPI__SPARC_PTRACE_H
+
+#if defined(__sparc__) && defined(__arch64__)
+/* 64 bit sparc */
+#include <asm/pstate.h>
+
+/* This struct defines the way the registers are stored on the
+ * stack during a system call and basically all traps.
+ */
+
+/* This magic value must have the low 9 bits clear,
+ * as that is where we encode the %tt value, see below.
+ */
+#define PT_REGS_MAGIC 0x57ac6c00
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+
+struct pt_regs {
+	unsigned long u_regs[16]; /* globals and ins */
+	unsigned long tstate;
+	unsigned long tpc;
+	unsigned long tnpc;
+	unsigned int y;
+
+	/* We encode a magic number, PT_REGS_MAGIC, along
+	 * with the %tt (trap type) register value at trap
+	 * entry time.  The magic number allows us to identify
+	 * accurately a trap stack frame in the stack
+	 * unwinder, and the %tt value allows us to test
+	 * things like "in a system call" etc. for an arbitray
+	 * process.
+	 *
+	 * The PT_REGS_MAGIC is chosen such that it can be
+	 * loaded completely using just a sethi instruction.
+	 */
+	unsigned int magic;
+};
+
+struct pt_regs32 {
+	unsigned int psr;
+	unsigned int pc;
+	unsigned int npc;
+	unsigned int y;
+	unsigned int u_regs[16]; /* globals and ins */
+};
+
+/* A V9 register window */
+struct reg_window {
+	unsigned long locals[8];
+	unsigned long ins[8];
+};
+
+/* A 32-bit register window. */
+struct reg_window32 {
+	unsigned int locals[8];
+	unsigned int ins[8];
+};
+
+/* A V9 Sparc stack frame */
+struct sparc_stackf {
+	unsigned long locals[8];
+        unsigned long ins[6];
+	struct sparc_stackf *fp;
+	unsigned long callers_pc;
+	char *structptr;
+	unsigned long xargs[6];
+	unsigned long xxargs[1];
+};
+
+/* A 32-bit Sparc stack frame */
+struct sparc_stackf32 {
+	unsigned int locals[8];
+        unsigned int ins[6];
+	unsigned int fp;
+	unsigned int callers_pc;
+	unsigned int structptr;
+	unsigned int xargs[6];
+	unsigned int xxargs[1];
+};
+
+struct sparc_trapf {
+	unsigned long locals[8];
+	unsigned long ins[8];
+	unsigned long _unused;
+	struct pt_regs *regs;
+};
+#endif /* (!__ASSEMBLY__) */
+#else
+/* 32 bit sparc */
+
+#include <asm/psr.h>
+
+/* This struct defines the way the registers are stored on the
+ * stack during a system call and basically all traps.
+ */
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+
+struct pt_regs {
+	unsigned long psr;
+	unsigned long pc;
+	unsigned long npc;
+	unsigned long y;
+	unsigned long u_regs[16]; /* globals and ins */
+};
+
+/* A 32-bit register window. */
+struct reg_window32 {
+	unsigned long locals[8];
+	unsigned long ins[8];
+};
+
+/* A Sparc stack frame */
+struct sparc_stackf {
+	unsigned long locals[8];
+        unsigned long ins[6];
+	struct sparc_stackf *fp;
+	unsigned long callers_pc;
+	char *structptr;
+	unsigned long xargs[6];
+	unsigned long xxargs[1];
+};
+#endif /* (!__ASSEMBLY__) */
+
+#endif /* (defined(__sparc__) && defined(__arch64__))*/
+
+#ifndef __ASSEMBLY__
+
+#define TRACEREG_SZ	sizeof(struct pt_regs)
+#define STACKFRAME_SZ	sizeof(struct sparc_stackf)
+
+#define TRACEREG32_SZ	sizeof(struct pt_regs32)
+#define STACKFRAME32_SZ	sizeof(struct sparc_stackf32)
+
+#endif /* (!__ASSEMBLY__) */
+
+#define UREG_G0        0
+#define UREG_G1        1
+#define UREG_G2        2
+#define UREG_G3        3
+#define UREG_G4        4
+#define UREG_G5        5
+#define UREG_G6        6
+#define UREG_G7        7
+#define UREG_I0        8
+#define UREG_I1        9
+#define UREG_I2        10
+#define UREG_I3        11
+#define UREG_I4        12
+#define UREG_I5        13
+#define UREG_I6        14
+#define UREG_I7        15
+#define UREG_FP        UREG_I6
+#define UREG_RETPC     UREG_I7
+
+#if defined(__sparc__) && defined(__arch64__)
+/* 64 bit sparc */
+
+#ifndef __ASSEMBLY__
+
+
+#else /* __ASSEMBLY__ */
+/* For assembly code. */
+#define TRACEREG_SZ		0xa0
+#define STACKFRAME_SZ		0xc0
+
+#define TRACEREG32_SZ		0x50
+#define STACKFRAME32_SZ		0x60
+#endif /* __ASSEMBLY__ */
+
+#else /* (defined(__sparc__) && defined(__arch64__)) */
+
+/* 32 bit sparc */
+
+#ifndef __ASSEMBLY__
+
+
+#else /* (!__ASSEMBLY__) */
+/* For assembly code. */
+#define TRACEREG_SZ       0x50
+#define STACKFRAME_SZ     0x60
+#endif /* (!__ASSEMBLY__) */
+
+#endif /* (defined(__sparc__) && defined(__arch64__)) */
+
+
+/* These are for pt_regs. */
+#define PT_V9_G0     0x00
+#define PT_V9_G1     0x08
+#define PT_V9_G2     0x10
+#define PT_V9_G3     0x18
+#define PT_V9_G4     0x20
+#define PT_V9_G5     0x28
+#define PT_V9_G6     0x30
+#define PT_V9_G7     0x38
+#define PT_V9_I0     0x40
+#define PT_V9_I1     0x48
+#define PT_V9_I2     0x50
+#define PT_V9_I3     0x58
+#define PT_V9_I4     0x60
+#define PT_V9_I5     0x68
+#define PT_V9_I6     0x70
+#define PT_V9_FP     PT_V9_I6
+#define PT_V9_I7     0x78
+#define PT_V9_TSTATE 0x80
+#define PT_V9_TPC    0x88
+#define PT_V9_TNPC   0x90
+#define PT_V9_Y      0x98
+#define PT_V9_MAGIC  0x9c
+#define PT_TSTATE	PT_V9_TSTATE
+#define PT_TPC		PT_V9_TPC
+#define PT_TNPC		PT_V9_TNPC
+
+/* These for pt_regs32. */
+#define PT_PSR    0x0
+#define PT_PC     0x4
+#define PT_NPC    0x8
+#define PT_Y      0xc
+#define PT_G0     0x10
+#define PT_WIM    PT_G0
+#define PT_G1     0x14
+#define PT_G2     0x18
+#define PT_G3     0x1c
+#define PT_G4     0x20
+#define PT_G5     0x24
+#define PT_G6     0x28
+#define PT_G7     0x2c
+#define PT_I0     0x30
+#define PT_I1     0x34
+#define PT_I2     0x38
+#define PT_I3     0x3c
+#define PT_I4     0x40
+#define PT_I5     0x44
+#define PT_I6     0x48
+#define PT_FP     PT_I6
+#define PT_I7     0x4c
+
+/* Reg_window offsets */
+#define RW_V9_L0     0x00
+#define RW_V9_L1     0x08
+#define RW_V9_L2     0x10
+#define RW_V9_L3     0x18
+#define RW_V9_L4     0x20
+#define RW_V9_L5     0x28
+#define RW_V9_L6     0x30
+#define RW_V9_L7     0x38
+#define RW_V9_I0     0x40
+#define RW_V9_I1     0x48
+#define RW_V9_I2     0x50
+#define RW_V9_I3     0x58
+#define RW_V9_I4     0x60
+#define RW_V9_I5     0x68
+#define RW_V9_I6     0x70
+#define RW_V9_I7     0x78
+
+#define RW_L0     0x00
+#define RW_L1     0x04
+#define RW_L2     0x08
+#define RW_L3     0x0c
+#define RW_L4     0x10
+#define RW_L5     0x14
+#define RW_L6     0x18
+#define RW_L7     0x1c
+#define RW_I0     0x20
+#define RW_I1     0x24
+#define RW_I2     0x28
+#define RW_I3     0x2c
+#define RW_I4     0x30
+#define RW_I5     0x34
+#define RW_I6     0x38
+#define RW_I7     0x3c
+
+/* Stack_frame offsets */
+#define SF_V9_L0     0x00
+#define SF_V9_L1     0x08
+#define SF_V9_L2     0x10
+#define SF_V9_L3     0x18
+#define SF_V9_L4     0x20
+#define SF_V9_L5     0x28
+#define SF_V9_L6     0x30
+#define SF_V9_L7     0x38
+#define SF_V9_I0     0x40
+#define SF_V9_I1     0x48
+#define SF_V9_I2     0x50
+#define SF_V9_I3     0x58
+#define SF_V9_I4     0x60
+#define SF_V9_I5     0x68
+#define SF_V9_FP     0x70
+#define SF_V9_PC     0x78
+#define SF_V9_RETP   0x80
+#define SF_V9_XARG0  0x88
+#define SF_V9_XARG1  0x90
+#define SF_V9_XARG2  0x98
+#define SF_V9_XARG3  0xa0
+#define SF_V9_XARG4  0xa8
+#define SF_V9_XARG5  0xb0
+#define SF_V9_XXARG  0xb8
+
+#define SF_L0     0x00
+#define SF_L1     0x04
+#define SF_L2     0x08
+#define SF_L3     0x0c
+#define SF_L4     0x10
+#define SF_L5     0x14
+#define SF_L6     0x18
+#define SF_L7     0x1c
+#define SF_I0     0x20
+#define SF_I1     0x24
+#define SF_I2     0x28
+#define SF_I3     0x2c
+#define SF_I4     0x30
+#define SF_I5     0x34
+#define SF_FP     0x38
+#define SF_PC     0x3c
+#define SF_RETP   0x40
+#define SF_XARG0  0x44
+#define SF_XARG1  0x48
+#define SF_XARG2  0x4c
+#define SF_XARG3  0x50
+#define SF_XARG4  0x54
+#define SF_XARG5  0x58
+#define SF_XXARG  0x5c
+
+
+/* Stuff for the ptrace system call */
+#define PTRACE_SPARC_DETACH       11
+#define PTRACE_GETREGS            12
+#define PTRACE_SETREGS            13
+#define PTRACE_GETFPREGS          14
+#define PTRACE_SETFPREGS          15
+#define PTRACE_READDATA           16
+#define PTRACE_WRITEDATA          17
+#define PTRACE_READTEXT           18
+#define PTRACE_WRITETEXT          19
+#define PTRACE_GETFPAREGS         20
+#define PTRACE_SETFPAREGS         21
+
+/* There are for debugging 64-bit processes, either from a 32 or 64 bit
+ * parent.  Thus their complements are for debugging 32-bit processes only.
+ */
+
+#define PTRACE_GETREGS64	  22
+#define PTRACE_SETREGS64	  23
+/* PTRACE_SYSCALL is 24 */
+#define PTRACE_GETFPREGS64	  25
+#define PTRACE_SETFPREGS64	  26
+
+#endif /* _UAPI__SPARC_PTRACE_H */
diff --git a/arch/sparc/include/asm/resource.h b/arch/sparc/include/uapi/asm/resource.h
similarity index 100%
rename from arch/sparc/include/asm/resource.h
rename to arch/sparc/include/uapi/asm/resource.h
diff --git a/arch/sparc/include/asm/sembuf.h b/arch/sparc/include/uapi/asm/sembuf.h
similarity index 100%
rename from arch/sparc/include/asm/sembuf.h
rename to arch/sparc/include/uapi/asm/sembuf.h
diff --git a/arch/sparc/include/uapi/asm/setup.h b/arch/sparc/include/uapi/asm/setup.h
new file mode 100644
index 0000000..5337684
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/setup.h
@@ -0,0 +1,15 @@
+/*
+ *	Just a place holder. 
+ */
+
+#ifndef _UAPI_SPARC_SETUP_H
+#define _UAPI_SPARC_SETUP_H
+
+#if defined(__sparc__) && defined(__arch64__)
+# define COMMAND_LINE_SIZE 2048
+#else
+# define COMMAND_LINE_SIZE 256
+#endif
+
+
+#endif /* _UAPI_SPARC_SETUP_H */
diff --git a/arch/sparc/include/asm/shmbuf.h b/arch/sparc/include/uapi/asm/shmbuf.h
similarity index 100%
rename from arch/sparc/include/asm/shmbuf.h
rename to arch/sparc/include/uapi/asm/shmbuf.h
diff --git a/arch/sparc/include/uapi/asm/sigcontext.h b/arch/sparc/include/uapi/asm/sigcontext.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/sigcontext.h
diff --git a/arch/sparc/include/uapi/asm/siginfo.h b/arch/sparc/include/uapi/asm/siginfo.h
new file mode 100644
index 0000000..2d9b79cc
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/siginfo.h
@@ -0,0 +1,25 @@
+#ifndef _UAPI__SPARC_SIGINFO_H
+#define _UAPI__SPARC_SIGINFO_H
+
+#if defined(__sparc__) && defined(__arch64__)
+
+#define __ARCH_SI_PREAMBLE_SIZE	(4 * sizeof(int))
+#define __ARCH_SI_BAND_T int
+
+#endif /* defined(__sparc__) && defined(__arch64__) */
+
+
+#define __ARCH_SI_TRAPNO
+
+#include <asm-generic/siginfo.h>
+
+
+#define SI_NOINFO	32767		/* no information in siginfo_t */
+
+/*
+ * SIGEMT si_codes
+ */
+#define EMT_TAGOVF	(__SI_FAULT|1)	/* tag overflow */
+#define NSIGEMT		1
+
+#endif /* _UAPI__SPARC_SIGINFO_H */
diff --git a/arch/sparc/include/uapi/asm/signal.h b/arch/sparc/include/uapi/asm/signal.h
new file mode 100644
index 0000000..1a04189
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/signal.h
@@ -0,0 +1,185 @@
+#ifndef _UAPI__SPARC_SIGNAL_H
+#define _UAPI__SPARC_SIGNAL_H
+
+#include <asm/sigcontext.h>
+#include <linux/compiler.h>
+
+
+/* On the Sparc the signal handlers get passed a 'sub-signal' code
+ * for certain signal types, which we document here.
+ */
+#define SIGHUP		 1
+#define SIGINT		 2
+#define SIGQUIT		 3
+#define SIGILL		 4
+#define    SUBSIG_STACK       0
+#define    SUBSIG_ILLINST     2
+#define    SUBSIG_PRIVINST    3
+#define    SUBSIG_BADTRAP(t)  (0x80 + (t))
+
+#define SIGTRAP		 5
+#define SIGABRT		 6
+#define SIGIOT		 6
+
+#define SIGEMT           7
+#define    SUBSIG_TAG    10
+
+#define SIGFPE		 8
+#define    SUBSIG_FPDISABLED     0x400
+#define    SUBSIG_FPERROR        0x404
+#define    SUBSIG_FPINTOVFL      0x001
+#define    SUBSIG_FPSTSIG        0x002
+#define    SUBSIG_IDIVZERO       0x014
+#define    SUBSIG_FPINEXACT      0x0c4
+#define    SUBSIG_FPDIVZERO      0x0c8
+#define    SUBSIG_FPUNFLOW       0x0cc
+#define    SUBSIG_FPOPERROR      0x0d0
+#define    SUBSIG_FPOVFLOW       0x0d4
+
+#define SIGKILL		 9
+#define SIGBUS          10
+#define    SUBSIG_BUSTIMEOUT    1
+#define    SUBSIG_ALIGNMENT     2
+#define    SUBSIG_MISCERROR     5
+
+#define SIGSEGV		11
+#define    SUBSIG_NOMAPPING     3
+#define    SUBSIG_PROTECTION    4
+#define    SUBSIG_SEGERROR      5
+
+#define SIGSYS		12
+
+#define SIGPIPE		13
+#define SIGALRM		14
+#define SIGTERM		15
+#define SIGURG          16
+
+/* SunOS values which deviate from the Linux/i386 ones */
+#define SIGSTOP		17
+#define SIGTSTP		18
+#define SIGCONT		19
+#define SIGCHLD		20
+#define SIGTTIN		21
+#define SIGTTOU		22
+#define SIGIO		23
+#define SIGPOLL		SIGIO   /* SysV name for SIGIO */
+#define SIGXCPU		24
+#define SIGXFSZ		25
+#define SIGVTALRM	26
+#define SIGPROF		27
+#define SIGWINCH	28
+#define SIGLOST		29
+#define SIGPWR		SIGLOST
+#define SIGUSR1		30
+#define SIGUSR2		31
+
+/* Most things should be clean enough to redefine this at will, if care
+   is taken to make libc match.  */
+
+#define __OLD_NSIG	32
+#define __NEW_NSIG      64
+#ifdef __arch64__
+#define _NSIG_BPW       64
+#else
+#define _NSIG_BPW       32
+#endif
+#define _NSIG_WORDS     (__NEW_NSIG / _NSIG_BPW)
+
+#define SIGRTMIN       32
+#define SIGRTMAX       __NEW_NSIG
+
+#if defined(__KERNEL__) || defined(__WANT_POSIX1B_SIGNALS__)
+#define _NSIG			__NEW_NSIG
+#define __new_sigset_t		sigset_t
+#define __new_sigaction		sigaction
+#define __new_sigaction32	sigaction32
+#define __old_sigset_t		old_sigset_t
+#define __old_sigaction		old_sigaction
+#define __old_sigaction32	old_sigaction32
+#else
+#define _NSIG			__OLD_NSIG
+#define NSIG			_NSIG
+#define __old_sigset_t		sigset_t
+#define __old_sigaction		sigaction
+#define __old_sigaction32	sigaction32
+#endif
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned long __old_sigset_t;            /* at least 32 bits */
+
+typedef struct {
+       unsigned long sig[_NSIG_WORDS];
+} __new_sigset_t;
+
+/* A SunOS sigstack */
+struct sigstack {
+	/* XXX 32-bit pointers pinhead XXX */
+	char *the_stack;
+	int   cur_status;
+};
+
+/* Sigvec flags */
+#define _SV_SSTACK    1u    /* This signal handler should use sig-stack */
+#define _SV_INTR      2u    /* Sig return should not restart system call */
+#define _SV_RESET     4u    /* Set handler to SIG_DFL upon taken signal */
+#define _SV_IGNCHILD  8u    /* Do not send SIGCHLD */
+
+/*
+ * sa_flags values: SA_STACK is not currently supported, but will allow the
+ * usage of signal stacks by using the (now obsolete) sa_restorer field in
+ * the sigaction structure as a stack pointer. This is now possible due to
+ * the changes in signal handling. LBT 010493.
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ */
+#define SA_NOCLDSTOP	_SV_IGNCHILD
+#define SA_STACK	_SV_SSTACK
+#define SA_ONSTACK	_SV_SSTACK
+#define SA_RESTART	_SV_INTR
+#define SA_ONESHOT	_SV_RESET
+#define SA_NODEFER	0x20u
+#define SA_NOCLDWAIT    0x100u
+#define SA_SIGINFO      0x200u
+
+#define SA_NOMASK	SA_NODEFER
+
+#define SIG_BLOCK          0x01	/* for blocking signals */
+#define SIG_UNBLOCK        0x02	/* for unblocking signals */
+#define SIG_SETMASK        0x04	/* for setting the signal mask */
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK	1
+#define SS_DISABLE	2
+
+#define MINSIGSTKSZ	4096
+#define SIGSTKSZ	16384
+
+
+#include <asm-generic/signal-defs.h>
+
+struct __new_sigaction {
+	__sighandler_t		sa_handler;
+	unsigned long		sa_flags;
+	__sigrestore_t		sa_restorer;  /* not used by Linux/SPARC yet */
+	__new_sigset_t		sa_mask;
+};
+
+struct __old_sigaction {
+	__sighandler_t		sa_handler;
+	__old_sigset_t		sa_mask;
+	unsigned long		sa_flags;
+	void			(*sa_restorer)(void);  /* not used by Linux/SPARC yet */
+};
+
+typedef struct sigaltstack {
+	void			__user *ss_sp;
+	int			ss_flags;
+	size_t			ss_size;
+} stack_t;
+
+
+#endif /* !(__ASSEMBLY__) */
+
+#endif /* _UAPI__SPARC_SIGNAL_H */
diff --git a/arch/sparc/include/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h
similarity index 100%
rename from arch/sparc/include/asm/socket.h
rename to arch/sparc/include/uapi/asm/socket.h
diff --git a/arch/sparc/include/asm/sockios.h b/arch/sparc/include/uapi/asm/sockios.h
similarity index 100%
rename from arch/sparc/include/asm/sockios.h
rename to arch/sparc/include/uapi/asm/sockios.h
diff --git a/arch/sparc/include/asm/stat.h b/arch/sparc/include/uapi/asm/stat.h
similarity index 100%
rename from arch/sparc/include/asm/stat.h
rename to arch/sparc/include/uapi/asm/stat.h
diff --git a/arch/sparc/include/asm/statfs.h b/arch/sparc/include/uapi/asm/statfs.h
similarity index 100%
rename from arch/sparc/include/asm/statfs.h
rename to arch/sparc/include/uapi/asm/statfs.h
diff --git a/arch/sparc/include/asm/swab.h b/arch/sparc/include/uapi/asm/swab.h
similarity index 100%
rename from arch/sparc/include/asm/swab.h
rename to arch/sparc/include/uapi/asm/swab.h
diff --git a/arch/sparc/include/uapi/asm/termbits.h b/arch/sparc/include/uapi/asm/termbits.h
new file mode 100644
index 0000000..dd91642f
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/termbits.h
@@ -0,0 +1,263 @@
+#ifndef _UAPI_SPARC_TERMBITS_H
+#define _UAPI_SPARC_TERMBITS_H
+
+#include <linux/posix_types.h>
+
+typedef unsigned char   cc_t;
+typedef unsigned int    speed_t;
+
+#if defined(__sparc__) && defined(__arch64__)
+typedef unsigned int    tcflag_t;
+#else
+typedef unsigned long   tcflag_t;
+#endif
+
+#define NCC 8
+struct termio {
+	unsigned short c_iflag;		/* input mode flags */
+	unsigned short c_oflag;		/* output mode flags */
+	unsigned short c_cflag;		/* control mode flags */
+	unsigned short c_lflag;		/* local mode flags */
+	unsigned char c_line;		/* line discipline */
+	unsigned char c_cc[NCC];	/* control characters */
+};
+
+#define NCCS 17
+struct termios {
+	tcflag_t c_iflag;		/* input mode flags */
+	tcflag_t c_oflag;		/* output mode flags */
+	tcflag_t c_cflag;		/* control mode flags */
+	tcflag_t c_lflag;		/* local mode flags */
+	cc_t c_line;			/* line discipline */
+#ifndef __KERNEL__
+	cc_t c_cc[NCCS];		/* control characters */
+#else
+	cc_t c_cc[NCCS+2];	/* kernel needs 2 more to hold vmin/vtime */
+#define SIZEOF_USER_TERMIOS sizeof (struct termios) - (2*sizeof (cc_t))
+#endif
+};
+
+struct termios2 {
+	tcflag_t c_iflag;		/* input mode flags */
+	tcflag_t c_oflag;		/* output mode flags */
+	tcflag_t c_cflag;		/* control mode flags */
+	tcflag_t c_lflag;		/* local mode flags */
+	cc_t c_line;			/* line discipline */
+	cc_t c_cc[NCCS+2];		/* control characters */
+	speed_t c_ispeed;		/* input speed */
+	speed_t c_ospeed;		/* output speed */
+};
+
+struct ktermios {
+	tcflag_t c_iflag;		/* input mode flags */
+	tcflag_t c_oflag;		/* output mode flags */
+	tcflag_t c_cflag;		/* control mode flags */
+	tcflag_t c_lflag;		/* local mode flags */
+	cc_t c_line;			/* line discipline */
+	cc_t c_cc[NCCS+2];		/* control characters */
+	speed_t c_ispeed;		/* input speed */
+	speed_t c_ospeed;		/* output speed */
+};
+
+/* c_cc characters */
+#define VINTR    0
+#define VQUIT    1
+#define VERASE   2
+#define VKILL    3
+#define VEOF     4
+#define VEOL     5
+#define VEOL2    6
+#define VSWTC    7
+#define VSTART   8
+#define VSTOP    9
+
+
+
+#define VSUSP    10
+#define VDSUSP   11  /* SunOS POSIX nicety I do believe... */
+#define VREPRINT 12
+#define VDISCARD 13
+#define VWERASE  14
+#define VLNEXT   15
+
+/* Kernel keeps vmin/vtime separated, user apps assume vmin/vtime is
+ * shared with eof/eol
+ */
+#ifndef __KERNEL__
+#define VMIN     VEOF
+#define VTIME    VEOL
+#endif
+
+/* c_iflag bits */
+#define IGNBRK	0x00000001
+#define BRKINT	0x00000002
+#define IGNPAR	0x00000004
+#define PARMRK	0x00000008
+#define INPCK	0x00000010
+#define ISTRIP	0x00000020
+#define INLCR	0x00000040
+#define IGNCR	0x00000080
+#define ICRNL	0x00000100
+#define IUCLC	0x00000200
+#define IXON	0x00000400
+#define IXANY	0x00000800
+#define IXOFF	0x00001000
+#define IMAXBEL	0x00002000
+#define IUTF8   0x00004000
+
+/* c_oflag bits */
+#define OPOST	0x00000001
+#define OLCUC	0x00000002
+#define ONLCR	0x00000004
+#define OCRNL	0x00000008
+#define ONOCR	0x00000010
+#define ONLRET	0x00000020
+#define OFILL	0x00000040
+#define OFDEL	0x00000080
+#define NLDLY	0x00000100
+#define   NL0	0x00000000
+#define   NL1	0x00000100
+#define CRDLY	0x00000600
+#define   CR0	0x00000000
+#define   CR1	0x00000200
+#define   CR2	0x00000400
+#define   CR3	0x00000600
+#define TABDLY	0x00001800
+#define   TAB0	0x00000000
+#define   TAB1	0x00000800
+#define   TAB2	0x00001000
+#define   TAB3	0x00001800
+#define   XTABS	0x00001800
+#define BSDLY	0x00002000
+#define   BS0	0x00000000
+#define   BS1	0x00002000
+#define VTDLY	0x00004000
+#define   VT0	0x00000000
+#define   VT1	0x00004000
+#define FFDLY	0x00008000
+#define   FF0	0x00000000
+#define   FF1	0x00008000
+#define PAGEOUT 0x00010000  /* SUNOS specific */
+#define WRAP    0x00020000  /* SUNOS specific */
+
+/* c_cflag bit meaning */
+#define CBAUD	  0x0000100f
+#define  B0	  0x00000000   /* hang up */
+#define  B50	  0x00000001
+#define  B75	  0x00000002
+#define  B110	  0x00000003
+#define  B134	  0x00000004
+#define  B150	  0x00000005
+#define  B200	  0x00000006
+#define  B300	  0x00000007
+#define  B600	  0x00000008
+#define  B1200	  0x00000009
+#define  B1800	  0x0000000a
+#define  B2400	  0x0000000b
+#define  B4800	  0x0000000c
+#define  B9600	  0x0000000d
+#define  B19200	  0x0000000e
+#define  B38400	  0x0000000f
+#define EXTA      B19200
+#define EXTB      B38400
+#define  CSIZE    0x00000030
+#define   CS5	  0x00000000
+#define   CS6	  0x00000010
+#define   CS7	  0x00000020
+#define   CS8	  0x00000030
+#define CSTOPB	  0x00000040
+#define CREAD	  0x00000080
+#define PARENB	  0x00000100
+#define PARODD	  0x00000200
+#define HUPCL	  0x00000400
+#define CLOCAL	  0x00000800
+#define CBAUDEX   0x00001000
+/* We'll never see these speeds with the Zilogs, but for completeness... */
+#define  BOTHER   0x00001000
+#define  B57600   0x00001001
+#define  B115200  0x00001002
+#define  B230400  0x00001003
+#define  B460800  0x00001004
+/* This is what we can do with the Zilogs. */
+#define  B76800   0x00001005
+/* This is what we can do with the SAB82532. */
+#define  B153600  0x00001006
+#define  B307200  0x00001007
+#define  B614400  0x00001008
+#define  B921600  0x00001009
+/* And these are the rest... */
+#define  B500000  0x0000100a
+#define  B576000  0x0000100b
+#define B1000000  0x0000100c
+#define B1152000  0x0000100d
+#define B1500000  0x0000100e
+#define B2000000  0x0000100f
+/* These have totally bogus values and nobody uses them
+   so far. Later on we'd have to use say 0x10000x and
+   adjust CBAUD constant and drivers accordingly.
+#define B2500000  0x00001010
+#define B3000000  0x00001011
+#define B3500000  0x00001012
+#define B4000000  0x00001013  */
+#define CIBAUD	  0x100f0000  /* input baud rate (not used) */
+#define CMSPAR	  0x40000000  /* mark or space (stick) parity */
+#define CRTSCTS	  0x80000000  /* flow control */
+
+#define IBSHIFT	  16		/* Shift from CBAUD to CIBAUD */
+
+/* c_lflag bits */
+#define ISIG	0x00000001
+#define ICANON	0x00000002
+#define XCASE	0x00000004
+#define ECHO	0x00000008
+#define ECHOE	0x00000010
+#define ECHOK	0x00000020
+#define ECHONL	0x00000040
+#define NOFLSH	0x00000080
+#define TOSTOP	0x00000100
+#define ECHOCTL	0x00000200
+#define ECHOPRT	0x00000400
+#define ECHOKE	0x00000800
+#define DEFECHO 0x00001000  /* SUNOS thing, what is it? */
+#define FLUSHO	0x00002000
+#define PENDIN	0x00004000
+#define IEXTEN	0x00008000
+#define EXTPROC	0x00010000
+
+/* modem lines */
+#define TIOCM_LE	0x001
+#define TIOCM_DTR	0x002
+#define TIOCM_RTS	0x004
+#define TIOCM_ST	0x008
+#define TIOCM_SR	0x010
+#define TIOCM_CTS	0x020
+#define TIOCM_CAR	0x040
+#define TIOCM_RNG	0x080
+#define TIOCM_DSR	0x100
+#define TIOCM_CD	TIOCM_CAR
+#define TIOCM_RI	TIOCM_RNG
+#define TIOCM_OUT1	0x2000
+#define TIOCM_OUT2	0x4000
+#define TIOCM_LOOP	0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+#define TIOCSER_TEMT    0x01	/* Transmitter physically empty */
+
+
+/* tcflow() and TCXONC use these */
+#define	TCOOFF		0
+#define	TCOON		1
+#define	TCIOFF		2
+#define	TCION		3
+
+/* tcflush() and TCFLSH use these */
+#define	TCIFLUSH	0
+#define	TCOFLUSH	1
+#define	TCIOFLUSH	2
+
+/* tcsetattr uses these */
+#define	TCSANOW		0
+#define	TCSADRAIN	1
+#define	TCSAFLUSH	2
+
+#endif /* _UAPI_SPARC_TERMBITS_H */
diff --git a/arch/sparc/include/uapi/asm/termios.h b/arch/sparc/include/uapi/asm/termios.h
new file mode 100644
index 0000000..ea6f09e5
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/termios.h
@@ -0,0 +1,43 @@
+#ifndef _UAPI_SPARC_TERMIOS_H
+#define _UAPI_SPARC_TERMIOS_H
+
+#include <asm/ioctls.h>
+#include <asm/termbits.h>
+
+#if defined(__KERNEL__) || defined(__DEFINE_BSD_TERMIOS)
+struct sgttyb {
+	char	sg_ispeed;
+	char	sg_ospeed;
+	char	sg_erase;
+	char	sg_kill;
+	short	sg_flags;
+};
+
+struct tchars {
+	char	t_intrc;
+	char	t_quitc;
+	char	t_startc;
+	char	t_stopc;
+	char	t_eofc;
+	char	t_brkc;
+};
+
+struct ltchars {
+	char	t_suspc;
+	char	t_dsuspc;
+	char	t_rprntc;
+	char	t_flushc;
+	char	t_werasc;
+	char	t_lnextc;
+};
+#endif /* __KERNEL__ */
+
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+
+#endif /* _UAPI_SPARC_TERMIOS_H */
diff --git a/arch/sparc/include/uapi/asm/traps.h b/arch/sparc/include/uapi/asm/traps.h
new file mode 100644
index 0000000..a4eceac
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/traps.h
@@ -0,0 +1,120 @@
+/*
+ * traps.h:  Format of entries for the Sparc trap table.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ */
+
+#ifndef _UAPI_SPARC_TRAPS_H
+#define _UAPI_SPARC_TRAPS_H
+
+#define NUM_SPARC_TRAPS  255
+
+#ifndef __ASSEMBLY__
+#endif /* !(__ASSEMBLY__) */
+
+/* For patching the trap table at boot time, we need to know how to
+ * form various common Sparc instructions.  Thus these macros...
+ */
+
+#define SPARC_MOV_CONST_L3(const) (0xa6102000 | (const&0xfff))
+
+/* The following assumes that the branch lies before the place we
+ * are branching to.  This is the case for a trap vector...
+ * You have been warned.
+ */
+#define SPARC_BRANCH(dest_addr, inst_addr) \
+          (0x10800000 | (((dest_addr-inst_addr)>>2)&0x3fffff))
+
+#define SPARC_RD_PSR_L0  (0xa1480000)
+#define SPARC_RD_WIM_L3  (0xa7500000)
+#define SPARC_NOP (0x01000000)
+
+/* Various interesting trap levels. */
+/* First, hardware traps. */
+#define SP_TRAP_TFLT    0x1          /* Text fault */
+#define SP_TRAP_II      0x2          /* Illegal Instruction */
+#define SP_TRAP_PI      0x3          /* Privileged Instruction */
+#define SP_TRAP_FPD     0x4          /* Floating Point Disabled */
+#define SP_TRAP_WOVF    0x5          /* Window Overflow */
+#define SP_TRAP_WUNF    0x6          /* Window Underflow */
+#define SP_TRAP_MNA     0x7          /* Memory Address Unaligned */
+#define SP_TRAP_FPE     0x8          /* Floating Point Exception */
+#define SP_TRAP_DFLT    0x9          /* Data Fault */
+#define SP_TRAP_TOF     0xa          /* Tag Overflow */
+#define SP_TRAP_WDOG    0xb          /* Watchpoint Detected */
+#define SP_TRAP_IRQ1    0x11         /* IRQ level 1 */
+#define SP_TRAP_IRQ2    0x12         /* IRQ level 2 */
+#define SP_TRAP_IRQ3    0x13         /* IRQ level 3 */
+#define SP_TRAP_IRQ4    0x14         /* IRQ level 4 */
+#define SP_TRAP_IRQ5    0x15         /* IRQ level 5 */
+#define SP_TRAP_IRQ6    0x16         /* IRQ level 6 */
+#define SP_TRAP_IRQ7    0x17         /* IRQ level 7 */
+#define SP_TRAP_IRQ8    0x18         /* IRQ level 8 */
+#define SP_TRAP_IRQ9    0x19         /* IRQ level 9 */
+#define SP_TRAP_IRQ10   0x1a         /* IRQ level 10 */
+#define SP_TRAP_IRQ11   0x1b         /* IRQ level 11 */
+#define SP_TRAP_IRQ12   0x1c         /* IRQ level 12 */
+#define SP_TRAP_IRQ13   0x1d         /* IRQ level 13 */
+#define SP_TRAP_IRQ14   0x1e         /* IRQ level 14 */
+#define SP_TRAP_IRQ15   0x1f         /* IRQ level 15 Non-maskable */
+#define SP_TRAP_RACC    0x20         /* Register Access Error ??? */
+#define SP_TRAP_IACC    0x21         /* Instruction Access Error */
+#define SP_TRAP_CPDIS   0x24         /* Co-Processor Disabled */
+#define SP_TRAP_BADFL   0x25         /* Unimplemented Flush Instruction */
+#define SP_TRAP_CPEXP   0x28         /* Co-Processor Exception */
+#define SP_TRAP_DACC    0x29         /* Data Access Error */
+#define SP_TRAP_DIVZ    0x2a         /* Divide By Zero */
+#define SP_TRAP_DSTORE  0x2b         /* Data Store Error ??? */
+#define SP_TRAP_DMM     0x2c         /* Data Access MMU Miss ??? */
+#define SP_TRAP_IMM     0x3c         /* Instruction Access MMU Miss ??? */
+
+/* Now the Software Traps... */
+#define SP_TRAP_SUNOS   0x80         /* SunOS System Call */
+#define SP_TRAP_SBPT    0x81         /* Software Breakpoint */
+#define SP_TRAP_SDIVZ   0x82         /* Software Divide-by-Zero trap */
+#define SP_TRAP_FWIN    0x83         /* Flush Windows */
+#define SP_TRAP_CWIN    0x84         /* Clean Windows */
+#define SP_TRAP_RCHK    0x85         /* Range Check */
+#define SP_TRAP_FUNA    0x86         /* Fix Unaligned Access */
+#define SP_TRAP_IOWFL   0x87         /* Integer Overflow */
+#define SP_TRAP_SOLARIS 0x88         /* Solaris System Call */
+#define SP_TRAP_NETBSD  0x89         /* NetBSD System Call */
+#define SP_TRAP_LINUX   0x90         /* Linux System Call */
+
+/* Names used for compatibility with SunOS */
+#define ST_SYSCALL              0x00
+#define ST_BREAKPOINT           0x01
+#define ST_DIV0                 0x02
+#define ST_FLUSH_WINDOWS        0x03
+#define ST_CLEAN_WINDOWS        0x04
+#define ST_RANGE_CHECK          0x05
+#define ST_FIX_ALIGN            0x06
+#define ST_INT_OVERFLOW         0x07
+
+/* Special traps... */
+#define SP_TRAP_KBPT1   0xfe         /* KADB/PROM Breakpoint one */
+#define SP_TRAP_KBPT2   0xff         /* KADB/PROM Breakpoint two */
+
+/* Handy Macros */
+/* Is this a trap we never expect to get? */
+#define BAD_TRAP_P(level) \
+        ((level > SP_TRAP_WDOG && level < SP_TRAP_IRQ1) || \
+	 (level > SP_TRAP_IACC && level < SP_TRAP_CPDIS) || \
+	 (level > SP_TRAP_BADFL && level < SP_TRAP_CPEXP) || \
+	 (level > SP_TRAP_DMM && level < SP_TRAP_IMM) || \
+	 (level > SP_TRAP_IMM && level < SP_TRAP_SUNOS) || \
+	 (level > SP_TRAP_LINUX && level < SP_TRAP_KBPT1))
+
+/* Is this a Hardware trap? */
+#define HW_TRAP_P(level) ((level > 0) && (level < SP_TRAP_SUNOS))
+
+/* Is this a Software trap? */
+#define SW_TRAP_P(level) ((level >= SP_TRAP_SUNOS) && (level <= SP_TRAP_KBPT2))
+
+/* Is this a system call for some OS we know about? */
+#define SCALL_TRAP_P(level) ((level == SP_TRAP_SUNOS) || \
+			     (level == SP_TRAP_SOLARIS) || \
+			     (level == SP_TRAP_NETBSD) || \
+			     (level == SP_TRAP_LINUX))
+
+#endif /* _UAPI_SPARC_TRAPS_H */
diff --git a/arch/sparc/include/asm/types.h b/arch/sparc/include/uapi/asm/types.h
similarity index 100%
rename from arch/sparc/include/asm/types.h
rename to arch/sparc/include/uapi/asm/types.h
diff --git a/arch/sparc/include/asm/uctx.h b/arch/sparc/include/uapi/asm/uctx.h
similarity index 100%
rename from arch/sparc/include/asm/uctx.h
rename to arch/sparc/include/uapi/asm/uctx.h
diff --git a/arch/sparc/include/uapi/asm/unistd.h b/arch/sparc/include/uapi/asm/unistd.h
new file mode 100644
index 0000000..8974ef7a
--- /dev/null
+++ b/arch/sparc/include/uapi/asm/unistd.h
@@ -0,0 +1,422 @@
+/*
+ * System calls under the Sparc.
+ *
+ * Don't be scared by the ugly clobbers, it is the only way I can
+ * think of right now to force the arguments into fixed registers
+ * before the trap into the system call with gcc 'asm' statements.
+ *
+ * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net)
+ *
+ * SunOS compatibility based upon preliminary work which is:
+ *
+ * Copyright (C) 1995 Adrian M. Rodriguez (adrian@remus.rutgers.edu)
+ */
+#ifndef _UAPI_SPARC_UNISTD_H
+#define _UAPI_SPARC_UNISTD_H
+
+#ifndef __32bit_syscall_numbers__
+#ifndef __arch64__
+#define __32bit_syscall_numbers__
+#endif
+#endif
+
+#define __NR_restart_syscall      0 /* Linux Specific				   */
+#define __NR_exit                 1 /* Common                                      */
+#define __NR_fork                 2 /* Common                                      */
+#define __NR_read                 3 /* Common                                      */
+#define __NR_write                4 /* Common                                      */
+#define __NR_open                 5 /* Common                                      */
+#define __NR_close                6 /* Common                                      */
+#define __NR_wait4                7 /* Common                                      */
+#define __NR_creat                8 /* Common                                      */
+#define __NR_link                 9 /* Common                                      */
+#define __NR_unlink              10 /* Common                                      */
+#define __NR_execv               11 /* SunOS Specific                              */
+#define __NR_chdir               12 /* Common                                      */
+#define __NR_chown		 13 /* Common					   */
+#define __NR_mknod               14 /* Common                                      */
+#define __NR_chmod               15 /* Common                                      */
+#define __NR_lchown              16 /* Common                                      */
+#define __NR_brk                 17 /* Common                                      */
+#define __NR_perfctr             18 /* Performance counter operations              */
+#define __NR_lseek               19 /* Common                                      */
+#define __NR_getpid              20 /* Common                                      */
+#define __NR_capget		 21 /* Linux Specific				   */
+#define __NR_capset		 22 /* Linux Specific				   */
+#define __NR_setuid              23 /* Implemented via setreuid in SunOS           */
+#define __NR_getuid              24 /* Common                                      */
+#define __NR_vmsplice	         25 /* ENOSYS under SunOS			   */
+#define __NR_ptrace              26 /* Common                                      */
+#define __NR_alarm               27 /* Implemented via setitimer in SunOS          */
+#define __NR_sigaltstack	 28 /* Common					   */
+#define __NR_pause               29 /* Is sigblock(0)->sigpause() in SunOS         */
+#define __NR_utime               30 /* Implemented via utimes() under SunOS        */
+#ifdef __32bit_syscall_numbers__
+#define __NR_lchown32            31 /* Linux sparc32 specific                      */
+#define __NR_fchown32            32 /* Linux sparc32 specific                      */
+#endif
+#define __NR_access              33 /* Common                                      */
+#define __NR_nice                34 /* Implemented via get/setpriority() in SunOS  */
+#ifdef __32bit_syscall_numbers__
+#define __NR_chown32             35 /* Linux sparc32 specific                      */
+#endif
+#define __NR_sync                36 /* Common                                      */
+#define __NR_kill                37 /* Common                                      */
+#define __NR_stat                38 /* Common                                      */
+#define __NR_sendfile		 39 /* Linux Specific				   */
+#define __NR_lstat               40 /* Common                                      */
+#define __NR_dup                 41 /* Common                                      */
+#define __NR_pipe                42 /* Common                                      */
+#define __NR_times               43 /* Implemented via getrusage() in SunOS        */
+#ifdef __32bit_syscall_numbers__
+#define __NR_getuid32            44 /* Linux sparc32 specific                      */
+#endif
+#define __NR_umount2             45 /* Linux Specific                              */
+#define __NR_setgid              46 /* Implemented via setregid() in SunOS         */
+#define __NR_getgid              47 /* Common                                      */
+#define __NR_signal              48 /* Implemented via sigvec() in SunOS           */
+#define __NR_geteuid             49 /* SunOS calls getuid()                        */
+#define __NR_getegid             50 /* SunOS calls getgid()                        */
+#define __NR_acct                51 /* Common                                      */
+#ifdef __32bit_syscall_numbers__
+#define __NR_getgid32            53 /* Linux sparc32 specific                      */
+#else
+#define __NR_memory_ordering	 52 /* Linux Specific				   */
+#endif
+#define __NR_ioctl               54 /* Common                                      */
+#define __NR_reboot              55 /* Common                                      */
+#ifdef __32bit_syscall_numbers__
+#define __NR_mmap2		 56 /* Linux sparc32 Specific			   */
+#endif
+#define __NR_symlink             57 /* Common                                      */
+#define __NR_readlink            58 /* Common                                      */
+#define __NR_execve              59 /* Common                                      */
+#define __NR_umask               60 /* Common                                      */
+#define __NR_chroot              61 /* Common                                      */
+#define __NR_fstat               62 /* Common                                      */
+#define __NR_fstat64		 63 /* Linux Specific			           */
+#define __NR_getpagesize         64 /* Common                                      */
+#define __NR_msync               65 /* Common in newer 1.3.x revs...               */
+#define __NR_vfork               66 /* Common                                      */
+#define __NR_pread64             67 /* Linux Specific                              */
+#define __NR_pwrite64            68 /* Linux Specific                              */
+#ifdef __32bit_syscall_numbers__
+#define __NR_geteuid32           69 /* Linux sparc32, sbrk under SunOS             */
+#define __NR_getegid32           70 /* Linux sparc32, sstk under SunOS             */
+#endif
+#define __NR_mmap                71 /* Common                                      */
+#ifdef __32bit_syscall_numbers__
+#define __NR_setreuid32          72 /* Linux sparc32, vadvise under SunOS          */
+#endif
+#define __NR_munmap              73 /* Common                                      */
+#define __NR_mprotect            74 /* Common                                      */
+#define __NR_madvise             75 /* Common                                      */
+#define __NR_vhangup             76 /* Common                                      */
+#ifdef __32bit_syscall_numbers__
+#define __NR_truncate64		 77 /* Linux sparc32 Specific			   */
+#endif
+#define __NR_mincore             78 /* Common                                      */
+#define __NR_getgroups           79 /* Common                                      */
+#define __NR_setgroups           80 /* Common                                      */
+#define __NR_getpgrp             81 /* Common                                      */
+#ifdef __32bit_syscall_numbers__
+#define __NR_setgroups32         82 /* Linux sparc32, setpgrp under SunOS          */
+#endif
+#define __NR_setitimer           83 /* Common                                      */
+#ifdef __32bit_syscall_numbers__
+#define __NR_ftruncate64	 84 /* Linux sparc32 Specific			   */
+#endif
+#define __NR_swapon              85 /* Common                                      */
+#define __NR_getitimer           86 /* Common                                      */
+#ifdef __32bit_syscall_numbers__
+#define __NR_setuid32            87 /* Linux sparc32, gethostname under SunOS      */
+#endif
+#define __NR_sethostname         88 /* Common                                      */
+#ifdef __32bit_syscall_numbers__
+#define __NR_setgid32            89 /* Linux sparc32, getdtablesize under SunOS    */
+#endif
+#define __NR_dup2                90 /* Common                                      */
+#ifdef __32bit_syscall_numbers__
+#define __NR_setfsuid32          91 /* Linux sparc32, getdopt under SunOS          */
+#endif
+#define __NR_fcntl               92 /* Common                                      */
+#define __NR_select              93 /* Common                                      */
+#ifdef __32bit_syscall_numbers__
+#define __NR_setfsgid32          94 /* Linux sparc32, setdopt under SunOS          */
+#endif
+#define __NR_fsync               95 /* Common                                      */
+#define __NR_setpriority         96 /* Common                                      */
+#define __NR_socket              97 /* Common                                      */
+#define __NR_connect             98 /* Common                                      */
+#define __NR_accept              99 /* Common                                      */
+#define __NR_getpriority        100 /* Common                                      */
+#define __NR_rt_sigreturn       101 /* Linux Specific                              */
+#define __NR_rt_sigaction       102 /* Linux Specific                              */
+#define __NR_rt_sigprocmask     103 /* Linux Specific                              */
+#define __NR_rt_sigpending      104 /* Linux Specific                              */
+#define __NR_rt_sigtimedwait    105 /* Linux Specific                              */
+#define __NR_rt_sigqueueinfo    106 /* Linux Specific                              */
+#define __NR_rt_sigsuspend      107 /* Linux Specific                              */
+#ifdef __32bit_syscall_numbers__
+#define __NR_setresuid32        108 /* Linux Specific, sigvec under SunOS	   */
+#define __NR_getresuid32        109 /* Linux Specific, sigblock under SunOS	   */
+#define __NR_setresgid32        110 /* Linux Specific, sigsetmask under SunOS	   */
+#define __NR_getresgid32        111 /* Linux Specific, sigpause under SunOS	   */
+#define __NR_setregid32         112 /* Linux sparc32, sigstack under SunOS         */
+#else
+#define __NR_setresuid          108 /* Linux Specific, sigvec under SunOS	   */
+#define __NR_getresuid          109 /* Linux Specific, sigblock under SunOS	   */
+#define __NR_setresgid          110 /* Linux Specific, sigsetmask under SunOS	   */
+#define __NR_getresgid          111 /* Linux Specific, sigpause under SunOS	   */
+#endif
+#define __NR_recvmsg            113 /* Common                                      */
+#define __NR_sendmsg            114 /* Common                                      */
+#ifdef __32bit_syscall_numbers__
+#define __NR_getgroups32        115 /* Linux sparc32, vtrace under SunOS           */
+#endif
+#define __NR_gettimeofday       116 /* Common                                      */
+#define __NR_getrusage          117 /* Common                                      */
+#define __NR_getsockopt         118 /* Common                                      */
+#define __NR_getcwd		119 /* Linux Specific				   */
+#define __NR_readv              120 /* Common                                      */
+#define __NR_writev             121 /* Common                                      */
+#define __NR_settimeofday       122 /* Common                                      */
+#define __NR_fchown             123 /* Common                                      */
+#define __NR_fchmod             124 /* Common                                      */
+#define __NR_recvfrom           125 /* Common                                      */
+#define __NR_setreuid           126 /* Common                                      */
+#define __NR_setregid           127 /* Common                                      */
+#define __NR_rename             128 /* Common                                      */
+#define __NR_truncate           129 /* Common                                      */
+#define __NR_ftruncate          130 /* Common                                      */
+#define __NR_flock              131 /* Common                                      */
+#define __NR_lstat64		132 /* Linux Specific			           */
+#define __NR_sendto             133 /* Common                                      */
+#define __NR_shutdown           134 /* Common                                      */
+#define __NR_socketpair         135 /* Common                                      */
+#define __NR_mkdir              136 /* Common                                      */
+#define __NR_rmdir              137 /* Common                                      */
+#define __NR_utimes             138 /* SunOS Specific                              */
+#define __NR_stat64		139 /* Linux Specific			           */
+#define __NR_sendfile64         140 /* adjtime under SunOS                         */
+#define __NR_getpeername        141 /* Common                                      */
+#define __NR_futex              142 /* gethostid under SunOS                       */
+#define __NR_gettid             143 /* ENOSYS under SunOS                          */
+#define __NR_getrlimit		144 /* Common                                      */
+#define __NR_setrlimit          145 /* Common                                      */
+#define __NR_pivot_root		146 /* Linux Specific, killpg under SunOS          */
+#define __NR_prctl		147 /* ENOSYS under SunOS                          */
+#define __NR_pciconfig_read	148 /* ENOSYS under SunOS                          */
+#define __NR_pciconfig_write	149 /* ENOSYS under SunOS                          */
+#define __NR_getsockname        150 /* Common                                      */
+#define __NR_inotify_init       151 /* Linux specific                              */
+#define __NR_inotify_add_watch  152 /* Linux specific                              */
+#define __NR_poll               153 /* Common                                      */
+#define __NR_getdents64		154 /* Linux specific				   */
+#ifdef __32bit_syscall_numbers__
+#define __NR_fcntl64		155 /* Linux sparc32 Specific                      */
+#endif
+#define __NR_inotify_rm_watch   156 /* Linux specific				   */
+#define __NR_statfs             157 /* Common                                      */
+#define __NR_fstatfs            158 /* Common                                      */
+#define __NR_umount             159 /* Common                                      */
+#define __NR_sched_set_affinity 160 /* Linux specific, async_daemon under SunOS    */
+#define __NR_sched_get_affinity 161 /* Linux specific, getfh under SunOS           */
+#define __NR_getdomainname      162 /* SunOS Specific                              */
+#define __NR_setdomainname      163 /* Common                                      */
+#ifndef __32bit_syscall_numbers__
+#define __NR_utrap_install	164 /* SYSV ABI/v9 required			   */
+#endif
+#define __NR_quotactl           165 /* Common                                      */
+#define __NR_set_tid_address    166 /* Linux specific, exportfs under SunOS        */
+#define __NR_mount              167 /* Common                                      */
+#define __NR_ustat              168 /* Common                                      */
+#define __NR_setxattr           169 /* SunOS: semsys                               */
+#define __NR_lsetxattr          170 /* SunOS: msgsys                               */
+#define __NR_fsetxattr          171 /* SunOS: shmsys                               */
+#define __NR_getxattr           172 /* SunOS: auditsys                             */
+#define __NR_lgetxattr          173 /* SunOS: rfssys                               */
+#define __NR_getdents           174 /* Common                                      */
+#define __NR_setsid             175 /* Common                                      */
+#define __NR_fchdir             176 /* Common                                      */
+#define __NR_fgetxattr          177 /* SunOS: fchroot                              */
+#define __NR_listxattr          178 /* SunOS: vpixsys                              */
+#define __NR_llistxattr         179 /* SunOS: aioread                              */
+#define __NR_flistxattr         180 /* SunOS: aiowrite                             */
+#define __NR_removexattr        181 /* SunOS: aiowait                              */
+#define __NR_lremovexattr       182 /* SunOS: aiocancel                            */
+#define __NR_sigpending         183 /* Common                                      */
+#define __NR_query_module	184 /* Linux Specific				   */
+#define __NR_setpgid            185 /* Common                                      */
+#define __NR_fremovexattr       186 /* SunOS: pathconf                             */
+#define __NR_tkill              187 /* SunOS: fpathconf                            */
+#define __NR_exit_group		188 /* Linux specific, sysconf undef SunOS         */
+#define __NR_uname              189 /* Linux Specific                              */
+#define __NR_init_module        190 /* Linux Specific                              */
+#define __NR_personality        191 /* Linux Specific                              */
+#define __NR_remap_file_pages   192 /* Linux Specific                              */
+#define __NR_epoll_create       193 /* Linux Specific                              */
+#define __NR_epoll_ctl          194 /* Linux Specific                              */
+#define __NR_epoll_wait         195 /* Linux Specific                              */
+#define __NR_ioprio_set         196 /* Linux Specific                              */
+#define __NR_getppid            197 /* Linux Specific                              */
+#define __NR_sigaction          198 /* Linux Specific                              */
+#define __NR_sgetmask           199 /* Linux Specific                              */
+#define __NR_ssetmask           200 /* Linux Specific                              */
+#define __NR_sigsuspend         201 /* Linux Specific                              */
+#define __NR_oldlstat           202 /* Linux Specific                              */
+#define __NR_uselib             203 /* Linux Specific                              */
+#define __NR_readdir            204 /* Linux Specific                              */
+#define __NR_readahead          205 /* Linux Specific                              */
+#define __NR_socketcall         206 /* Linux Specific                              */
+#define __NR_syslog             207 /* Linux Specific                              */
+#define __NR_lookup_dcookie     208 /* Linux Specific                              */
+#define __NR_fadvise64          209 /* Linux Specific                              */
+#define __NR_fadvise64_64       210 /* Linux Specific                              */
+#define __NR_tgkill             211 /* Linux Specific                              */
+#define __NR_waitpid            212 /* Linux Specific                              */
+#define __NR_swapoff            213 /* Linux Specific                              */
+#define __NR_sysinfo            214 /* Linux Specific                              */
+#define __NR_ipc                215 /* Linux Specific                              */
+#define __NR_sigreturn          216 /* Linux Specific                              */
+#define __NR_clone              217 /* Linux Specific                              */
+#define __NR_ioprio_get         218 /* Linux Specific                              */
+#define __NR_adjtimex           219 /* Linux Specific                              */
+#define __NR_sigprocmask        220 /* Linux Specific                              */
+#define __NR_create_module      221 /* Linux Specific                              */
+#define __NR_delete_module      222 /* Linux Specific                              */
+#define __NR_get_kernel_syms    223 /* Linux Specific                              */
+#define __NR_getpgid            224 /* Linux Specific                              */
+#define __NR_bdflush            225 /* Linux Specific                              */
+#define __NR_sysfs              226 /* Linux Specific                              */
+#define __NR_afs_syscall        227 /* Linux Specific                              */
+#define __NR_setfsuid           228 /* Linux Specific                              */
+#define __NR_setfsgid           229 /* Linux Specific                              */
+#define __NR__newselect         230 /* Linux Specific                              */
+#ifdef __32bit_syscall_numbers__
+#define __NR_time               231 /* Linux Specific                              */
+#else
+#endif
+#define __NR_splice             232 /* Linux Specific                              */
+#define __NR_stime              233 /* Linux Specific                              */
+#define __NR_statfs64           234 /* Linux Specific                              */
+#define __NR_fstatfs64          235 /* Linux Specific                              */
+#define __NR__llseek            236 /* Linux Specific                              */
+#define __NR_mlock              237
+#define __NR_munlock            238
+#define __NR_mlockall           239
+#define __NR_munlockall         240
+#define __NR_sched_setparam     241
+#define __NR_sched_getparam     242
+#define __NR_sched_setscheduler 243
+#define __NR_sched_getscheduler 244
+#define __NR_sched_yield        245
+#define __NR_sched_get_priority_max 246
+#define __NR_sched_get_priority_min 247
+#define __NR_sched_rr_get_interval  248
+#define __NR_nanosleep          249
+#define __NR_mremap             250
+#define __NR__sysctl            251
+#define __NR_getsid             252
+#define __NR_fdatasync          253
+#define __NR_nfsservctl         254
+#define __NR_sync_file_range	255
+#define __NR_clock_settime	256
+#define __NR_clock_gettime	257
+#define __NR_clock_getres	258
+#define __NR_clock_nanosleep	259
+#define __NR_sched_getaffinity	260
+#define __NR_sched_setaffinity	261
+#define __NR_timer_settime	262
+#define __NR_timer_gettime	263
+#define __NR_timer_getoverrun	264
+#define __NR_timer_delete	265
+#define __NR_timer_create	266
+/* #define __NR_vserver		267 Reserved for VSERVER */
+#define __NR_io_setup		268
+#define __NR_io_destroy		269
+#define __NR_io_submit		270
+#define __NR_io_cancel		271
+#define __NR_io_getevents	272
+#define __NR_mq_open		273
+#define __NR_mq_unlink		274
+#define __NR_mq_timedsend	275
+#define __NR_mq_timedreceive	276
+#define __NR_mq_notify		277
+#define __NR_mq_getsetattr	278
+#define __NR_waitid		279
+#define __NR_tee		280
+#define __NR_add_key		281
+#define __NR_request_key	282
+#define __NR_keyctl		283
+#define __NR_openat		284
+#define __NR_mkdirat		285
+#define __NR_mknodat		286
+#define __NR_fchownat		287
+#define __NR_futimesat		288
+#define __NR_fstatat64		289
+#define __NR_unlinkat		290
+#define __NR_renameat		291
+#define __NR_linkat		292
+#define __NR_symlinkat		293
+#define __NR_readlinkat		294
+#define __NR_fchmodat		295
+#define __NR_faccessat		296
+#define __NR_pselect6		297
+#define __NR_ppoll		298
+#define __NR_unshare		299
+#define __NR_set_robust_list	300
+#define __NR_get_robust_list	301
+#define __NR_migrate_pages	302
+#define __NR_mbind		303
+#define __NR_get_mempolicy	304
+#define __NR_set_mempolicy	305
+#define __NR_kexec_load		306
+#define __NR_move_pages		307
+#define __NR_getcpu		308
+#define __NR_epoll_pwait	309
+#define __NR_utimensat		310
+#define __NR_signalfd		311
+#define __NR_timerfd_create	312
+#define __NR_eventfd		313
+#define __NR_fallocate		314
+#define __NR_timerfd_settime	315
+#define __NR_timerfd_gettime	316
+#define __NR_signalfd4		317
+#define __NR_eventfd2		318
+#define __NR_epoll_create1	319
+#define __NR_dup3		320
+#define __NR_pipe2		321
+#define __NR_inotify_init1	322
+#define __NR_accept4		323
+#define __NR_preadv		324
+#define __NR_pwritev		325
+#define __NR_rt_tgsigqueueinfo	326
+#define __NR_perf_event_open	327
+#define __NR_recvmmsg		328
+#define __NR_fanotify_init	329
+#define __NR_fanotify_mark	330
+#define __NR_prlimit64		331
+#define __NR_name_to_handle_at	332
+#define __NR_open_by_handle_at	333
+#define __NR_clock_adjtime	334
+#define __NR_syncfs		335
+#define __NR_sendmmsg		336
+#define __NR_setns		337
+#define __NR_process_vm_readv	338
+#define __NR_process_vm_writev	339
+
+#define NR_syscalls		340
+
+#ifdef __32bit_syscall_numbers__
+/* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,
+ * it never had the plain ones and there is no value to adding those
+ * old versions into the syscall table.
+ */
+#define __IGNORE_setresuid
+#define __IGNORE_getresuid
+#define __IGNORE_setresgid
+#define __IGNORE_getresgid
+#endif
+
+#endif /* _UAPI_SPARC_UNISTD_H */
diff --git a/arch/sparc/include/asm/utrap.h b/arch/sparc/include/uapi/asm/utrap.h
similarity index 100%
rename from arch/sparc/include/asm/utrap.h
rename to arch/sparc/include/uapi/asm/utrap.h
diff --git a/arch/sparc/include/asm/watchdog.h b/arch/sparc/include/uapi/asm/watchdog.h
similarity index 100%
rename from arch/sparc/include/asm/watchdog.h
rename to arch/sparc/include/uapi/asm/watchdog.h
diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S
index ee5dcce..2feb15c 100644
--- a/arch/sparc/kernel/head_64.S
+++ b/arch/sparc/kernel/head_64.S
@@ -576,7 +576,7 @@
 niagara4_patch:
 	call	niagara4_patch_copyops
 	 nop
-	call	niagara_patch_bzero
+	call	niagara4_patch_bzero
 	 nop
 	call	niagara4_patch_pageops
 	 nop
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index acc8c83..75b31bc 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -779,7 +779,7 @@
 static void __pci_mmap_set_flags(struct pci_dev *dev, struct vm_area_struct *vma,
 					    enum pci_mmap_state mmap_state)
 {
-	vma->vm_flags |= (VM_IO | VM_RESERVED);
+	vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
 }
 
 /* Set vm_page_prot of VMA, as appropriate for this architecture, for a pci
diff --git a/arch/sparc/kernel/sun4v_tlb_miss.S b/arch/sparc/kernel/sun4v_tlb_miss.S
index e1fbf8c..bde867f 100644
--- a/arch/sparc/kernel/sun4v_tlb_miss.S
+++ b/arch/sparc/kernel/sun4v_tlb_miss.S
@@ -176,7 +176,7 @@
 
 	sub	%g2, TRAP_PER_CPU_FAULT_INFO, %g2
 
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
 	mov	SCRATCHPAD_UTSBREG2, %g5
 	ldxa	[%g5] ASI_SCRATCHPAD, %g5
 	cmp	%g5, -1
diff --git a/arch/sparc/kernel/tsb.S b/arch/sparc/kernel/tsb.S
index db15d12..d4bdc7a 100644
--- a/arch/sparc/kernel/tsb.S
+++ b/arch/sparc/kernel/tsb.S
@@ -49,7 +49,7 @@
 	/* Before committing to a full page table walk,
 	 * check the huge page TSB.
 	 */
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
 
 661:	ldx		[%g7 + TRAP_PER_CPU_TSB_HUGE], %g5
 	nop
@@ -110,12 +110,9 @@
 tsb_miss_page_table_walk_sun4v_fastpath:
 	USER_PGTABLE_WALK_TL1(%g4, %g7, %g5, %g2, tsb_do_fault)
 
-	/* Load and check PTE.  */
-	ldxa		[%g5] ASI_PHYS_USE_EC, %g5
-	brgez,pn	%g5, tsb_do_fault
-	 nop
+	/* Valid PTE is now in %g5.  */
 
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
 661:	sethi		%uhi(_PAGE_SZALL_4U), %g7
 	sllx		%g7, 32, %g7
 	.section	.sun4v_2insn_patch, "ax"
diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile
index 30f6ab5..8410065f2 100644
--- a/arch/sparc/lib/Makefile
+++ b/arch/sparc/lib/Makefile
@@ -33,7 +33,7 @@
 lib-$(CONFIG_SPARC64) +=  NG2patch.o
 
 lib-$(CONFIG_SPARC64) += NG4memcpy.o NG4copy_from_user.o NG4copy_to_user.o
-lib-$(CONFIG_SPARC64) +=  NG4patch.o NG4copy_page.o
+lib-$(CONFIG_SPARC64) +=  NG4patch.o NG4copy_page.o NG4clear_page.o NG4memset.o
 
 lib-$(CONFIG_SPARC64) += GENmemcpy.o GENcopy_from_user.o GENcopy_to_user.o
 lib-$(CONFIG_SPARC64) += GENpatch.o GENpage.o GENbzero.o
diff --git a/arch/sparc/lib/NG4clear_page.S b/arch/sparc/lib/NG4clear_page.S
new file mode 100644
index 0000000..e16c882
--- /dev/null
+++ b/arch/sparc/lib/NG4clear_page.S
@@ -0,0 +1,29 @@
+/* NG4copy_page.S: Niagara-4 optimized clear page.
+ *
+ * Copyright (C) 2012 (davem@davemloft.net)
+ */
+
+#include <asm/asi.h>
+#include <asm/page.h>
+
+	.text
+
+	.register	%g3, #scratch
+
+	.align		32
+	.globl		NG4clear_page
+	.globl		NG4clear_user_page
+NG4clear_page:		/* %o0=dest */
+NG4clear_user_page:	/* %o0=dest, %o1=vaddr */
+	set		PAGE_SIZE, %g7
+	mov		0x20, %g3
+1:	stxa		%g0, [%o0 + %g0] ASI_ST_BLKINIT_MRU_P
+	subcc		%g7, 0x40, %g7
+	stxa		%g0, [%o0 + %g3] ASI_ST_BLKINIT_MRU_P
+	bne,pt		%xcc, 1b
+	 add		%o0, 0x40, %o0
+	membar		#StoreLoad|#StoreStore
+	retl
+	 nop
+	.size		NG4clear_page,.-NG4clear_page
+	.size		NG4clear_user_page,.-NG4clear_user_page
\ No newline at end of file
diff --git a/arch/sparc/lib/NG4copy_page.S b/arch/sparc/lib/NG4copy_page.S
index f30ec10..28504e8 100644
--- a/arch/sparc/lib/NG4copy_page.S
+++ b/arch/sparc/lib/NG4copy_page.S
@@ -30,25 +30,25 @@
 	ldx		[%o1 + 0x10], %o4
 	ldx		[%o1 + 0x18], %o5
 	ldx		[%o1 + 0x20], %g1
-	stxa		%o2, [%o0] ASI_BLK_INIT_QUAD_LDD_P
+	stxa		%o2, [%o0] ASI_ST_BLKINIT_MRU_P
 	add		%o0, 0x08, %o0
 	ldx		[%o1 + 0x28], %g2
-	stxa		%o3, [%o0] ASI_BLK_INIT_QUAD_LDD_P
+	stxa		%o3, [%o0] ASI_ST_BLKINIT_MRU_P
 	add		%o0, 0x08, %o0
 	ldx		[%o1 + 0x30], %g3
-	stxa		%o4, [%o0] ASI_BLK_INIT_QUAD_LDD_P
+	stxa		%o4, [%o0] ASI_ST_BLKINIT_MRU_P
 	add		%o0, 0x08, %o0
 	ldx		[%o1 + 0x38], %o2
 	add		%o1, 0x40, %o1
-	stxa		%o5, [%o0] ASI_BLK_INIT_QUAD_LDD_P
+	stxa		%o5, [%o0] ASI_ST_BLKINIT_MRU_P
 	add		%o0, 0x08, %o0
-	stxa		%g1, [%o0] ASI_BLK_INIT_QUAD_LDD_P
+	stxa		%g1, [%o0] ASI_ST_BLKINIT_MRU_P
 	add		%o0, 0x08, %o0
-	stxa		%g2, [%o0] ASI_BLK_INIT_QUAD_LDD_P
+	stxa		%g2, [%o0] ASI_ST_BLKINIT_MRU_P
 	add		%o0, 0x08, %o0
-	stxa		%g3, [%o0] ASI_BLK_INIT_QUAD_LDD_P
+	stxa		%g3, [%o0] ASI_ST_BLKINIT_MRU_P
 	add		%o0, 0x08, %o0
-	stxa		%o2, [%o0] ASI_BLK_INIT_QUAD_LDD_P
+	stxa		%o2, [%o0] ASI_ST_BLKINIT_MRU_P
 	add		%o0, 0x08, %o0
 	bne,pt		%icc, 1b
 	 prefetch	[%o1 + 0x200], #n_reads_strong
diff --git a/arch/sparc/lib/NG4memset.S b/arch/sparc/lib/NG4memset.S
new file mode 100644
index 0000000..41da4bd
--- /dev/null
+++ b/arch/sparc/lib/NG4memset.S
@@ -0,0 +1,105 @@
+/* NG4memset.S: Niagara-4 optimized memset/bzero.
+ *
+ * Copyright (C) 2012 David S. Miller (davem@davemloft.net)
+ */
+
+#include <asm/asi.h>
+
+	.register	%g2, #scratch
+	.register	%g3, #scratch
+
+	.text
+	.align		32
+	.globl		NG4memset
+NG4memset:
+	andcc		%o1, 0xff, %o4
+	be,pt		%icc, 1f
+	 mov		%o2, %o1
+	sllx		%o4, 8, %g1
+	or		%g1, %o4, %o2
+	sllx		%o2, 16, %g1
+	or		%g1, %o2, %o2
+	sllx		%o2, 32, %g1
+	ba,pt		%icc, 1f
+	 or		%g1, %o2, %o4
+	.size		NG4memset,.-NG4memset
+
+	.align		32
+	.globl		NG4bzero
+NG4bzero:
+	clr		%o4
+1:	cmp		%o1, 16
+	ble		%icc, .Ltiny
+	 mov		%o0, %o3
+	sub		%g0, %o0, %g1
+	and		%g1, 0x7, %g1
+	brz,pt		%g1, .Laligned8
+	 sub		%o1, %g1, %o1
+1:	stb		%o4, [%o0 + 0x00]
+	subcc		%g1, 1, %g1
+	bne,pt		%icc, 1b
+	 add		%o0, 1, %o0
+.Laligned8:
+	cmp		%o1, 64 + (64 - 8)
+	ble		.Lmedium
+	 sub		%g0, %o0, %g1
+	andcc		%g1, (64 - 1), %g1
+	brz,pn		%g1, .Laligned64
+	 sub		%o1, %g1, %o1
+1:	stx		%o4, [%o0 + 0x00]
+	subcc		%g1, 8, %g1
+	bne,pt		%icc, 1b
+	 add		%o0, 0x8, %o0
+.Laligned64:
+	andn		%o1, 64 - 1, %g1
+	sub		%o1, %g1, %o1
+	brnz,pn		%o4, .Lnon_bzero_loop
+	 mov		0x20, %g2
+1:	stxa		%o4, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P
+	subcc		%g1, 0x40, %g1
+	stxa		%o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P
+	bne,pt		%icc, 1b
+	 add		%o0, 0x40, %o0
+.Lpostloop:
+	cmp		%o1, 8
+	bl,pn		%icc, .Ltiny
+	 membar		#StoreStore|#StoreLoad
+.Lmedium:
+	andn		%o1, 0x7, %g1
+	sub		%o1, %g1, %o1
+1:	stx		%o4, [%o0 + 0x00]
+	subcc		%g1, 0x8, %g1
+	bne,pt		%icc, 1b
+	 add		%o0, 0x08, %o0
+	andcc		%o1, 0x4, %g1
+	be,pt		%icc, .Ltiny
+	 sub		%o1, %g1, %o1
+	stw		%o4, [%o0 + 0x00]
+	add		%o0, 0x4, %o0
+.Ltiny:
+	cmp		%o1, 0
+	be,pn		%icc, .Lexit
+1:	 subcc		%o1, 1, %o1
+	stb		%o4, [%o0 + 0x00]
+	bne,pt		%icc, 1b
+	 add		%o0, 1, %o0
+.Lexit:
+	retl
+	 mov		%o3, %o0
+.Lnon_bzero_loop:
+	mov		0x08, %g3
+	mov		0x28, %o5
+1:	stxa		%o4, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P
+	subcc		%g1, 0x40, %g1
+	stxa		%o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P
+	stxa		%o4, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P
+	stxa		%o4, [%o0 + %o5] ASI_BLK_INIT_QUAD_LDD_P
+	add		%o0, 0x10, %o0
+	stxa		%o4, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P
+	stxa		%o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P
+	stxa		%o4, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P
+	stxa		%o4, [%o0 + %o5] ASI_BLK_INIT_QUAD_LDD_P
+	bne,pt		%icc, 1b
+	 add		%o0, 0x30, %o0
+	ba,a,pt		%icc, .Lpostloop
+	.size		NG4bzero,.-NG4bzero
diff --git a/arch/sparc/lib/NG4patch.S b/arch/sparc/lib/NG4patch.S
index c21c34c..a114cbc 100644
--- a/arch/sparc/lib/NG4patch.S
+++ b/arch/sparc/lib/NG4patch.S
@@ -32,12 +32,23 @@
 	 nop
 	.size	niagara4_patch_copyops,.-niagara4_patch_copyops
 
+	.globl	niagara4_patch_bzero
+	.type	niagara4_patch_bzero,#function
+niagara4_patch_bzero:
+	NG_DO_PATCH(memset, NG4memset)
+	NG_DO_PATCH(__bzero, NG4bzero)
+	NG_DO_PATCH(__clear_user, NGclear_user)
+	NG_DO_PATCH(tsb_init, NGtsb_init)
+	retl
+	 nop
+	.size	niagara4_patch_bzero,.-niagara4_patch_bzero
+
 	.globl	niagara4_patch_pageops
 	.type	niagara4_patch_pageops,#function
 niagara4_patch_pageops:
 	NG_DO_PATCH(copy_user_page, NG4copy_user_page)
-	NG_DO_PATCH(_clear_page, NGclear_page)
-	NG_DO_PATCH(clear_user_page, NGclear_user_page)
+	NG_DO_PATCH(_clear_page, NG4clear_page)
+	NG_DO_PATCH(clear_user_page, NG4clear_user_page)
 	retl
 	 nop
 	.size	niagara4_patch_pageops,.-niagara4_patch_pageops
diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c
index 77ac917..e98bfda 100644
--- a/arch/sparc/mm/fault_32.c
+++ b/arch/sparc/mm/fault_32.c
@@ -265,6 +265,7 @@
 		}
 		if (fault & VM_FAULT_RETRY) {
 			flags &= ~FAULT_FLAG_ALLOW_RETRY;
+			flags |= FAULT_FLAG_TRIED;
 
 			/* No need to up_read(&mm->mmap_sem) as we would
 			 * have already released it in __lock_page_or_retry
diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c
index 1fe0429..2976dba 100644
--- a/arch/sparc/mm/fault_64.c
+++ b/arch/sparc/mm/fault_64.c
@@ -452,6 +452,7 @@
 		}
 		if (fault & VM_FAULT_RETRY) {
 			flags &= ~FAULT_FLAG_ALLOW_RETRY;
+			flags |= FAULT_FLAG_TRIED;
 
 			/* No need to up_read(&mm->mmap_sem) as we would
 			 * have already released it in __lock_page_or_retry
@@ -464,13 +465,13 @@
 	up_read(&mm->mmap_sem);
 
 	mm_rss = get_mm_rss(mm);
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
 	mm_rss -= (mm->context.huge_pte_count * (HPAGE_SIZE / PAGE_SIZE));
 #endif
 	if (unlikely(mm_rss >
 		     mm->context.tsb_block[MM_TSB_BASE].tsb_rss_limit))
 		tsb_grow(mm, MM_TSB_BASE, mm_rss);
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
 	mm_rss = mm->context.huge_pte_count;
 	if (unlikely(mm_rss >
 		     mm->context.tsb_block[MM_TSB_HUGE].tsb_rss_limit))
diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c
index 07e1453..f76f83d 100644
--- a/arch/sparc/mm/hugetlbpage.c
+++ b/arch/sparc/mm/hugetlbpage.c
@@ -303,53 +303,3 @@
 {
 	return NULL;
 }
-
-static void context_reload(void *__data)
-{
-	struct mm_struct *mm = __data;
-
-	if (mm == current->mm)
-		load_secondary_context(mm);
-}
-
-void hugetlb_prefault_arch_hook(struct mm_struct *mm)
-{
-	struct tsb_config *tp = &mm->context.tsb_block[MM_TSB_HUGE];
-
-	if (likely(tp->tsb != NULL))
-		return;
-
-	tsb_grow(mm, MM_TSB_HUGE, 0);
-	tsb_context_switch(mm);
-	smp_tsb_sync(mm);
-
-	/* On UltraSPARC-III+ and later, configure the second half of
-	 * the Data-TLB for huge pages.
-	 */
-	if (tlb_type == cheetah_plus) {
-		unsigned long ctx;
-
-		spin_lock(&ctx_alloc_lock);
-		ctx = mm->context.sparc64_ctx_val;
-		ctx &= ~CTX_PGSZ_MASK;
-		ctx |= CTX_PGSZ_BASE << CTX_PGSZ0_SHIFT;
-		ctx |= CTX_PGSZ_HUGE << CTX_PGSZ1_SHIFT;
-
-		if (ctx != mm->context.sparc64_ctx_val) {
-			/* When changing the page size fields, we
-			 * must perform a context flush so that no
-			 * stale entries match.  This flush must
-			 * occur with the original context register
-			 * settings.
-			 */
-			do_flush_tlb_mm(mm);
-
-			/* Reload the context register of all processors
-			 * also executing in this address space.
-			 */
-			mm->context.sparc64_ctx_val = ctx;
-			on_each_cpu(context_reload, mm, 0);
-		}
-		spin_unlock(&ctx_alloc_lock);
-	}
-}
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 7a9b788..9e28a11 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -276,7 +276,6 @@
 }
 
 unsigned long _PAGE_ALL_SZ_BITS __read_mostly;
-unsigned long _PAGE_SZBITS __read_mostly;
 
 static void flush_dcache(unsigned long pfn)
 {
@@ -307,12 +306,24 @@
 	}
 }
 
+/* mm->context.lock must be held */
+static void __update_mmu_tsb_insert(struct mm_struct *mm, unsigned long tsb_index,
+				    unsigned long tsb_hash_shift, unsigned long address,
+				    unsigned long tte)
+{
+	struct tsb *tsb = mm->context.tsb_block[tsb_index].tsb;
+	unsigned long tag;
+
+	tsb += ((address >> tsb_hash_shift) &
+		(mm->context.tsb_block[tsb_index].tsb_nentries - 1UL));
+	tag = (address >> 22UL);
+	tsb_insert(tsb, tag, tte);
+}
+
 void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
 {
+	unsigned long tsb_index, tsb_hash_shift, flags;
 	struct mm_struct *mm;
-	struct tsb *tsb;
-	unsigned long tag, flags;
-	unsigned long tsb_index, tsb_hash_shift;
 	pte_t pte = *ptep;
 
 	if (tlb_type != hypervisor) {
@@ -329,7 +340,7 @@
 
 	spin_lock_irqsave(&mm->context.lock, flags);
 
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
 	if (mm->context.tsb_block[MM_TSB_HUGE].tsb != NULL) {
 		if ((tlb_type == hypervisor &&
 		     (pte_val(pte) & _PAGE_SZALL_4V) == _PAGE_SZHUGE_4V) ||
@@ -341,11 +352,8 @@
 	}
 #endif
 
-	tsb = mm->context.tsb_block[tsb_index].tsb;
-	tsb += ((address >> tsb_hash_shift) &
-		(mm->context.tsb_block[tsb_index].tsb_nentries - 1UL));
-	tag = (address >> 22UL);
-	tsb_insert(tsb, tag, pte_val(pte));
+	__update_mmu_tsb_insert(mm, tsb_index, tsb_hash_shift,
+				address, pte_val(pte));
 
 	spin_unlock_irqrestore(&mm->context.lock, flags);
 }
@@ -2275,8 +2283,7 @@
 		     __ACCESS_BITS_4U | _PAGE_E_4U);
 
 #ifdef CONFIG_DEBUG_PAGEALLOC
-	kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZBITS_4U) ^
-		0xfffff80000000000UL;
+	kern_linear_pte_xor[0] = _PAGE_VALID ^ 0xfffff80000000000UL;
 #else
 	kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZ4MB_4U) ^
 		0xfffff80000000000UL;
@@ -2287,7 +2294,6 @@
 	for (i = 1; i < 4; i++)
 		kern_linear_pte_xor[i] = kern_linear_pte_xor[0];
 
-	_PAGE_SZBITS = _PAGE_SZBITS_4U;
 	_PAGE_ALL_SZ_BITS =  (_PAGE_SZ4MB_4U | _PAGE_SZ512K_4U |
 			      _PAGE_SZ64K_4U | _PAGE_SZ8K_4U |
 			      _PAGE_SZ32MB_4U | _PAGE_SZ256MB_4U);
@@ -2324,8 +2330,7 @@
 	_PAGE_CACHE = _PAGE_CACHE_4V;
 
 #ifdef CONFIG_DEBUG_PAGEALLOC
-	kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZBITS_4V) ^
-		0xfffff80000000000UL;
+	kern_linear_pte_xor[0] = _PAGE_VALID ^ 0xfffff80000000000UL;
 #else
 	kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZ4MB_4V) ^
 		0xfffff80000000000UL;
@@ -2339,7 +2344,6 @@
 	pg_iobits = (_PAGE_VALID | _PAGE_PRESENT_4V | __DIRTY_BITS_4V |
 		     __ACCESS_BITS_4V | _PAGE_E_4V);
 
-	_PAGE_SZBITS = _PAGE_SZBITS_4V;
 	_PAGE_ALL_SZ_BITS = (_PAGE_SZ16GB_4V | _PAGE_SZ2GB_4V |
 			     _PAGE_SZ256MB_4V | _PAGE_SZ32MB_4V |
 			     _PAGE_SZ4MB_4V | _PAGE_SZ512K_4V |
@@ -2472,3 +2476,281 @@
 	__asm__ __volatile__("wrpr	%0, 0, %%pstate"
 			     : : "r" (pstate));
 }
+
+static pte_t *get_from_cache(struct mm_struct *mm)
+{
+	struct page *page;
+	pte_t *ret;
+
+	spin_lock(&mm->page_table_lock);
+	page = mm->context.pgtable_page;
+	ret = NULL;
+	if (page) {
+		void *p = page_address(page);
+
+		mm->context.pgtable_page = NULL;
+
+		ret = (pte_t *) (p + (PAGE_SIZE / 2));
+	}
+	spin_unlock(&mm->page_table_lock);
+
+	return ret;
+}
+
+static struct page *__alloc_for_cache(struct mm_struct *mm)
+{
+	struct page *page = alloc_page(GFP_KERNEL | __GFP_NOTRACK |
+				       __GFP_REPEAT | __GFP_ZERO);
+
+	if (page) {
+		spin_lock(&mm->page_table_lock);
+		if (!mm->context.pgtable_page) {
+			atomic_set(&page->_count, 2);
+			mm->context.pgtable_page = page;
+		}
+		spin_unlock(&mm->page_table_lock);
+	}
+	return page;
+}
+
+pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
+			    unsigned long address)
+{
+	struct page *page;
+	pte_t *pte;
+
+	pte = get_from_cache(mm);
+	if (pte)
+		return pte;
+
+	page = __alloc_for_cache(mm);
+	if (page)
+		pte = (pte_t *) page_address(page);
+
+	return pte;
+}
+
+pgtable_t pte_alloc_one(struct mm_struct *mm,
+			unsigned long address)
+{
+	struct page *page;
+	pte_t *pte;
+
+	pte = get_from_cache(mm);
+	if (pte)
+		return pte;
+
+	page = __alloc_for_cache(mm);
+	if (page) {
+		pgtable_page_ctor(page);
+		pte = (pte_t *) page_address(page);
+	}
+
+	return pte;
+}
+
+void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
+{
+	struct page *page = virt_to_page(pte);
+	if (put_page_testzero(page))
+		free_hot_cold_page(page, 0);
+}
+
+static void __pte_free(pgtable_t pte)
+{
+	struct page *page = virt_to_page(pte);
+	if (put_page_testzero(page)) {
+		pgtable_page_dtor(page);
+		free_hot_cold_page(page, 0);
+	}
+}
+
+void pte_free(struct mm_struct *mm, pgtable_t pte)
+{
+	__pte_free(pte);
+}
+
+void pgtable_free(void *table, bool is_page)
+{
+	if (is_page)
+		__pte_free(table);
+	else
+		kmem_cache_free(pgtable_cache, table);
+}
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+static pmd_t pmd_set_protbits(pmd_t pmd, pgprot_t pgprot, bool for_modify)
+{
+	if (pgprot_val(pgprot) & _PAGE_VALID)
+		pmd_val(pmd) |= PMD_HUGE_PRESENT;
+	if (tlb_type == hypervisor) {
+		if (pgprot_val(pgprot) & _PAGE_WRITE_4V)
+			pmd_val(pmd) |= PMD_HUGE_WRITE;
+		if (pgprot_val(pgprot) & _PAGE_EXEC_4V)
+			pmd_val(pmd) |= PMD_HUGE_EXEC;
+
+		if (!for_modify) {
+			if (pgprot_val(pgprot) & _PAGE_ACCESSED_4V)
+				pmd_val(pmd) |= PMD_HUGE_ACCESSED;
+			if (pgprot_val(pgprot) & _PAGE_MODIFIED_4V)
+				pmd_val(pmd) |= PMD_HUGE_DIRTY;
+		}
+	} else {
+		if (pgprot_val(pgprot) & _PAGE_WRITE_4U)
+			pmd_val(pmd) |= PMD_HUGE_WRITE;
+		if (pgprot_val(pgprot) & _PAGE_EXEC_4U)
+			pmd_val(pmd) |= PMD_HUGE_EXEC;
+
+		if (!for_modify) {
+			if (pgprot_val(pgprot) & _PAGE_ACCESSED_4U)
+				pmd_val(pmd) |= PMD_HUGE_ACCESSED;
+			if (pgprot_val(pgprot) & _PAGE_MODIFIED_4U)
+				pmd_val(pmd) |= PMD_HUGE_DIRTY;
+		}
+	}
+
+	return pmd;
+}
+
+pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot)
+{
+	pmd_t pmd;
+
+	pmd_val(pmd) = (page_nr << ((PAGE_SHIFT - PMD_PADDR_SHIFT)));
+	pmd_val(pmd) |= PMD_ISHUGE;
+	pmd = pmd_set_protbits(pmd, pgprot, false);
+	return pmd;
+}
+
+pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
+{
+	pmd_val(pmd) &= ~(PMD_HUGE_PRESENT |
+			  PMD_HUGE_WRITE |
+			  PMD_HUGE_EXEC);
+	pmd = pmd_set_protbits(pmd, newprot, true);
+	return pmd;
+}
+
+pgprot_t pmd_pgprot(pmd_t entry)
+{
+	unsigned long pte = 0;
+
+	if (pmd_val(entry) & PMD_HUGE_PRESENT)
+		pte |= _PAGE_VALID;
+
+	if (tlb_type == hypervisor) {
+		if (pmd_val(entry) & PMD_HUGE_PRESENT)
+			pte |= _PAGE_PRESENT_4V;
+		if (pmd_val(entry) & PMD_HUGE_EXEC)
+			pte |= _PAGE_EXEC_4V;
+		if (pmd_val(entry) & PMD_HUGE_WRITE)
+			pte |= _PAGE_W_4V;
+		if (pmd_val(entry) & PMD_HUGE_ACCESSED)
+			pte |= _PAGE_ACCESSED_4V;
+		if (pmd_val(entry) & PMD_HUGE_DIRTY)
+			pte |= _PAGE_MODIFIED_4V;
+		pte |= _PAGE_CP_4V|_PAGE_CV_4V;
+	} else {
+		if (pmd_val(entry) & PMD_HUGE_PRESENT)
+			pte |= _PAGE_PRESENT_4U;
+		if (pmd_val(entry) & PMD_HUGE_EXEC)
+			pte |= _PAGE_EXEC_4U;
+		if (pmd_val(entry) & PMD_HUGE_WRITE)
+			pte |= _PAGE_W_4U;
+		if (pmd_val(entry) & PMD_HUGE_ACCESSED)
+			pte |= _PAGE_ACCESSED_4U;
+		if (pmd_val(entry) & PMD_HUGE_DIRTY)
+			pte |= _PAGE_MODIFIED_4U;
+		pte |= _PAGE_CP_4U|_PAGE_CV_4U;
+	}
+
+	return __pgprot(pte);
+}
+
+void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr,
+			  pmd_t *pmd)
+{
+	unsigned long pte, flags;
+	struct mm_struct *mm;
+	pmd_t entry = *pmd;
+	pgprot_t prot;
+
+	if (!pmd_large(entry) || !pmd_young(entry))
+		return;
+
+	pte = (pmd_val(entry) & ~PMD_HUGE_PROTBITS);
+	pte <<= PMD_PADDR_SHIFT;
+	pte |= _PAGE_VALID;
+
+	prot = pmd_pgprot(entry);
+
+	if (tlb_type == hypervisor)
+		pgprot_val(prot) |= _PAGE_SZHUGE_4V;
+	else
+		pgprot_val(prot) |= _PAGE_SZHUGE_4U;
+
+	pte |= pgprot_val(prot);
+
+	mm = vma->vm_mm;
+
+	spin_lock_irqsave(&mm->context.lock, flags);
+
+	if (mm->context.tsb_block[MM_TSB_HUGE].tsb != NULL)
+		__update_mmu_tsb_insert(mm, MM_TSB_HUGE, HPAGE_SHIFT,
+					addr, pte);
+
+	spin_unlock_irqrestore(&mm->context.lock, flags);
+}
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
+static void context_reload(void *__data)
+{
+	struct mm_struct *mm = __data;
+
+	if (mm == current->mm)
+		load_secondary_context(mm);
+}
+
+void hugetlb_setup(struct mm_struct *mm)
+{
+	struct tsb_config *tp = &mm->context.tsb_block[MM_TSB_HUGE];
+
+	if (likely(tp->tsb != NULL))
+		return;
+
+	tsb_grow(mm, MM_TSB_HUGE, 0);
+	tsb_context_switch(mm);
+	smp_tsb_sync(mm);
+
+	/* On UltraSPARC-III+ and later, configure the second half of
+	 * the Data-TLB for huge pages.
+	 */
+	if (tlb_type == cheetah_plus) {
+		unsigned long ctx;
+
+		spin_lock(&ctx_alloc_lock);
+		ctx = mm->context.sparc64_ctx_val;
+		ctx &= ~CTX_PGSZ_MASK;
+		ctx |= CTX_PGSZ_BASE << CTX_PGSZ0_SHIFT;
+		ctx |= CTX_PGSZ_HUGE << CTX_PGSZ1_SHIFT;
+
+		if (ctx != mm->context.sparc64_ctx_val) {
+			/* When changing the page size fields, we
+			 * must perform a context flush so that no
+			 * stale entries match.  This flush must
+			 * occur with the original context register
+			 * settings.
+			 */
+			do_flush_tlb_mm(mm);
+
+			/* Reload the context register of all processors
+			 * also executing in this address space.
+			 */
+			mm->context.sparc64_ctx_val = ctx;
+			on_each_cpu(context_reload, mm, 0);
+		}
+		spin_unlock(&ctx_alloc_lock);
+	}
+}
+#endif
diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c
index b1f279c..3e8fec3 100644
--- a/arch/sparc/mm/tlb.c
+++ b/arch/sparc/mm/tlb.c
@@ -43,16 +43,37 @@
 	put_cpu_var(tlb_batch);
 }
 
-void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
-		   pte_t *ptep, pte_t orig, int fullmm)
+static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr,
+			      bool exec)
 {
 	struct tlb_batch *tb = &get_cpu_var(tlb_batch);
 	unsigned long nr;
 
 	vaddr &= PAGE_MASK;
-	if (pte_exec(orig))
+	if (exec)
 		vaddr |= 0x1UL;
 
+	nr = tb->tlb_nr;
+
+	if (unlikely(nr != 0 && mm != tb->mm)) {
+		flush_tlb_pending();
+		nr = 0;
+	}
+
+	if (nr == 0)
+		tb->mm = mm;
+
+	tb->vaddrs[nr] = vaddr;
+	tb->tlb_nr = ++nr;
+	if (nr >= TLB_BATCH_NR)
+		flush_tlb_pending();
+
+	put_cpu_var(tlb_batch);
+}
+
+void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
+		   pte_t *ptep, pte_t orig, int fullmm)
+{
 	if (tlb_type != hypervisor &&
 	    pte_dirty(orig)) {
 		unsigned long paddr, pfn = pte_pfn(orig);
@@ -77,26 +98,91 @@
 	}
 
 no_cache_flush:
-
-	if (fullmm) {
-		put_cpu_var(tlb_batch);
-		return;
-	}
-
-	nr = tb->tlb_nr;
-
-	if (unlikely(nr != 0 && mm != tb->mm)) {
-		flush_tlb_pending();
-		nr = 0;
-	}
-
-	if (nr == 0)
-		tb->mm = mm;
-
-	tb->vaddrs[nr] = vaddr;
-	tb->tlb_nr = ++nr;
-	if (nr >= TLB_BATCH_NR)
-		flush_tlb_pending();
-
-	put_cpu_var(tlb_batch);
+	if (!fullmm)
+		tlb_batch_add_one(mm, vaddr, pte_exec(orig));
 }
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+static void tlb_batch_pmd_scan(struct mm_struct *mm, unsigned long vaddr,
+			       pmd_t pmd, bool exec)
+{
+	unsigned long end;
+	pte_t *pte;
+
+	pte = pte_offset_map(&pmd, vaddr);
+	end = vaddr + HPAGE_SIZE;
+	while (vaddr < end) {
+		if (pte_val(*pte) & _PAGE_VALID)
+			tlb_batch_add_one(mm, vaddr, exec);
+		pte++;
+		vaddr += PAGE_SIZE;
+	}
+	pte_unmap(pte);
+}
+
+void set_pmd_at(struct mm_struct *mm, unsigned long addr,
+		pmd_t *pmdp, pmd_t pmd)
+{
+	pmd_t orig = *pmdp;
+
+	*pmdp = pmd;
+
+	if (mm == &init_mm)
+		return;
+
+	if ((pmd_val(pmd) ^ pmd_val(orig)) & PMD_ISHUGE) {
+		if (pmd_val(pmd) & PMD_ISHUGE)
+			mm->context.huge_pte_count++;
+		else
+			mm->context.huge_pte_count--;
+		if (mm->context.huge_pte_count == 1)
+			hugetlb_setup(mm);
+	}
+
+	if (!pmd_none(orig)) {
+		bool exec = ((pmd_val(orig) & PMD_HUGE_EXEC) != 0);
+
+		addr &= HPAGE_MASK;
+		if (pmd_val(orig) & PMD_ISHUGE)
+			tlb_batch_add_one(mm, addr, exec);
+		else
+			tlb_batch_pmd_scan(mm, addr, orig, exec);
+	}
+}
+
+void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable)
+{
+	struct list_head *lh = (struct list_head *) pgtable;
+
+	assert_spin_locked(&mm->page_table_lock);
+
+	/* FIFO */
+	if (!mm->pmd_huge_pte)
+		INIT_LIST_HEAD(lh);
+	else
+		list_add(lh, (struct list_head *) mm->pmd_huge_pte);
+	mm->pmd_huge_pte = pgtable;
+}
+
+pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm)
+{
+	struct list_head *lh;
+	pgtable_t pgtable;
+
+	assert_spin_locked(&mm->page_table_lock);
+
+	/* FIFO */
+	pgtable = mm->pmd_huge_pte;
+	lh = (struct list_head *) pgtable;
+	if (list_empty(lh))
+		mm->pmd_huge_pte = NULL;
+	else {
+		mm->pmd_huge_pte = (pgtable_t) lh->next;
+		list_del(lh);
+	}
+	pte_val(pgtable[0]) = 0;
+	pte_val(pgtable[1]) = 0;
+
+	return pgtable;
+}
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
diff --git a/arch/sparc/mm/tsb.c b/arch/sparc/mm/tsb.c
index c52add7..7f64743 100644
--- a/arch/sparc/mm/tsb.c
+++ b/arch/sparc/mm/tsb.c
@@ -78,7 +78,7 @@
 		base = __pa(base);
 	__flush_tsb_one(tb, PAGE_SHIFT, base, nentries);
 
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
 	if (mm->context.tsb_block[MM_TSB_HUGE].tsb) {
 		base = (unsigned long) mm->context.tsb_block[MM_TSB_HUGE].tsb;
 		nentries = mm->context.tsb_block[MM_TSB_HUGE].tsb_nentries;
@@ -90,29 +90,12 @@
 	spin_unlock_irqrestore(&mm->context.lock, flags);
 }
 
-#if defined(CONFIG_SPARC64_PAGE_SIZE_8KB)
 #define HV_PGSZ_IDX_BASE	HV_PGSZ_IDX_8K
 #define HV_PGSZ_MASK_BASE	HV_PGSZ_MASK_8K
-#elif defined(CONFIG_SPARC64_PAGE_SIZE_64KB)
-#define HV_PGSZ_IDX_BASE	HV_PGSZ_IDX_64K
-#define HV_PGSZ_MASK_BASE	HV_PGSZ_MASK_64K
-#else
-#error Broken base page size setting...
-#endif
 
-#ifdef CONFIG_HUGETLB_PAGE
-#if defined(CONFIG_HUGETLB_PAGE_SIZE_64K)
-#define HV_PGSZ_IDX_HUGE	HV_PGSZ_IDX_64K
-#define HV_PGSZ_MASK_HUGE	HV_PGSZ_MASK_64K
-#elif defined(CONFIG_HUGETLB_PAGE_SIZE_512K)
-#define HV_PGSZ_IDX_HUGE	HV_PGSZ_IDX_512K
-#define HV_PGSZ_MASK_HUGE	HV_PGSZ_MASK_512K
-#elif defined(CONFIG_HUGETLB_PAGE_SIZE_4MB)
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
 #define HV_PGSZ_IDX_HUGE	HV_PGSZ_IDX_4MB
 #define HV_PGSZ_MASK_HUGE	HV_PGSZ_MASK_4MB
-#else
-#error Broken huge page size setting...
-#endif
 #endif
 
 static void setup_tsb_params(struct mm_struct *mm, unsigned long tsb_idx, unsigned long tsb_bytes)
@@ -207,7 +190,7 @@
 		case MM_TSB_BASE:
 			hp->pgsz_idx = HV_PGSZ_IDX_BASE;
 			break;
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
 		case MM_TSB_HUGE:
 			hp->pgsz_idx = HV_PGSZ_IDX_HUGE;
 			break;
@@ -222,7 +205,7 @@
 		case MM_TSB_BASE:
 			hp->pgsz_mask = HV_PGSZ_MASK_BASE;
 			break;
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
 		case MM_TSB_HUGE:
 			hp->pgsz_mask = HV_PGSZ_MASK_HUGE;
 			break;
@@ -444,7 +427,7 @@
 
 int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
 {
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
 	unsigned long huge_pte_count;
 #endif
 	unsigned int i;
@@ -453,7 +436,7 @@
 
 	mm->context.sparc64_ctx_val = 0UL;
 
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
 	/* We reset it to zero because the fork() page copying
 	 * will re-increment the counters as the parent PTEs are
 	 * copied into the child address space.
@@ -462,6 +445,8 @@
 	mm->context.huge_pte_count = 0;
 #endif
 
+	mm->context.pgtable_page = NULL;
+
 	/* copy_mm() copies over the parent's mm_struct before calling
 	 * us, so we need to zero out the TSB pointer or else tsb_grow()
 	 * will be confused and think there is an older TSB to free up.
@@ -474,7 +459,7 @@
 	 */
 	tsb_grow(mm, MM_TSB_BASE, get_mm_rss(mm));
 
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
 	if (unlikely(huge_pte_count))
 		tsb_grow(mm, MM_TSB_HUGE, huge_pte_count);
 #endif
@@ -500,10 +485,17 @@
 void destroy_context(struct mm_struct *mm)
 {
 	unsigned long flags, i;
+	struct page *page;
 
 	for (i = 0; i < MM_NUM_TSBS; i++)
 		tsb_destroy_one(&mm->context.tsb_block[i]);
 
+	page = mm->context.pgtable_page;
+	if (page && put_page_testzero(page)) {
+		pgtable_page_dtor(page);
+		free_hot_cold_page(page, 0);
+	}
+
 	spin_lock_irqsave(&ctx_alloc_lock, flags);
 
 	if (CTX_VALID(mm->context)) {
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig
index c9a3c1f..dc46490 100644
--- a/arch/tile/Kconfig
+++ b/arch/tile/Kconfig
@@ -7,12 +7,15 @@
 	select HAVE_DMA_API_DEBUG
 	select HAVE_KVM if !TILEGX
 	select GENERIC_FIND_FIRST_BIT
+	select SYSCTL_EXCEPTION_TRACE
 	select USE_GENERIC_SMP_HELPERS
 	select CC_OPTIMIZE_FOR_SIZE
+	select HAVE_DEBUG_KMEMLEAK
 	select HAVE_GENERIC_HARDIRQS
 	select GENERIC_IRQ_PROBE
 	select GENERIC_PENDING_IRQ if SMP
 	select GENERIC_IRQ_SHOW
+	select HAVE_DEBUG_BUGVERBOSE
 	select HAVE_SYSCALL_WRAPPERS if TILEGX
 	select SYS_HYPERVISOR
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild
index 5bd7199..5cd98fa 100644
--- a/arch/tile/include/asm/Kbuild
+++ b/arch/tile/include/asm/Kbuild
@@ -8,10 +8,12 @@
 
 generic-y += bug.h
 generic-y += bugs.h
+generic-y += clkdev.h
 generic-y += cputime.h
 generic-y += div64.h
 generic-y += emergency-restart.h
 generic-y += errno.h
+generic-y += exec.h
 generic-y += fb.h
 generic-y += fcntl.h
 generic-y += ioctl.h
diff --git a/arch/tile/include/asm/exec.h b/arch/tile/include/asm/exec.h
deleted file mode 100644
index a714e19..0000000
--- a/arch/tile/include/asm/exec.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2010 Tilera Corporation. All Rights Reserved.
- *
- *   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, version 2.
- *
- *   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, GOOD TITLE or
- *   NON INFRINGEMENT.  See the GNU General Public License for
- *   more details.
- */
-
-#ifndef _ASM_TILE_EXEC_H
-#define _ASM_TILE_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _ASM_TILE_EXEC_H */
diff --git a/arch/tile/include/asm/hugetlb.h b/arch/tile/include/asm/hugetlb.h
index b204238..0f885af 100644
--- a/arch/tile/include/asm/hugetlb.h
+++ b/arch/tile/include/asm/hugetlb.h
@@ -106,6 +106,10 @@
 {
 }
 
+static inline void arch_clear_hugepage_flags(struct page *page)
+{
+}
+
 #ifdef CONFIG_HUGETLB_SUPER_PAGES
 static inline pte_t arch_make_huge_pte(pte_t entry, struct vm_area_struct *vma,
 				       struct page *page, int writable)
diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c
index 7bc0859..08b4fe1 100644
--- a/arch/tile/kernel/compat_signal.c
+++ b/arch/tile/kernel/compat_signal.c
@@ -354,15 +354,6 @@
 	regs->regs[1] = ptr_to_compat_reg(&frame->info);
 	regs->regs[2] = ptr_to_compat_reg(&frame->uc);
 	regs->flags |= PT_FLAGS_CALLER_SAVES;
-
-	/*
-	 * Notify any tracer that was single-stepping it.
-	 * The tracer may want to single-step inside the
-	 * handler too.
-	 */
-	if (test_thread_flag(TIF_SINGLESTEP))
-		ptrace_notify(SIGTRAP);
-
 	return 0;
 
 give_sigsegv:
diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c
index e29b055..67efb65 100644
--- a/arch/tile/kernel/signal.c
+++ b/arch/tile/kernel/signal.c
@@ -219,15 +219,6 @@
 	regs->regs[1] = (unsigned long) &frame->info;
 	regs->regs[2] = (unsigned long) &frame->uc;
 	regs->flags |= PT_FLAGS_CALLER_SAVES;
-
-	/*
-	 * Notify any tracer that was single-stepping it.
-	 * The tracer may want to single-step inside the
-	 * handler too.
-	 */
-	if (test_thread_flag(TIF_SINGLESTEP))
-		ptrace_notify(SIGTRAP);
-
 	return 0;
 
 give_sigsegv:
@@ -278,7 +269,8 @@
 		ret = setup_rt_frame(sig, ka, info, oldset, regs);
 	if (ret)
 		return;
-	signal_delivered(sig, info, ka, regs, 0);
+	signal_delivered(sig, info, ka, regs,
+			test_thread_flag(TIF_SINGLESTEP));
 }
 
 /*
diff --git a/arch/tile/mm/elf.c b/arch/tile/mm/elf.c
index 758b603..3cfa98b 100644
--- a/arch/tile/mm/elf.c
+++ b/arch/tile/mm/elf.c
@@ -36,19 +36,14 @@
 	} while (c);
 }
 
-static int notify_exec(void)
+static int notify_exec(struct mm_struct *mm)
 {
 	int retval = 0;  /* failure */
-	struct vm_area_struct *vma = current->mm->mmap;
-	while (vma) {
-		if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
-			break;
-		vma = vma->vm_next;
-	}
-	if (vma) {
+
+	if (mm->exe_file) {
 		char *buf = (char *) __get_free_page(GFP_KERNEL);
 		if (buf) {
-			char *path = d_path(&vma->vm_file->f_path,
+			char *path = d_path(&mm->exe_file->f_path,
 					    buf, PAGE_SIZE);
 			if (!IS_ERR(path)) {
 				sim_notify_exec(path);
@@ -106,16 +101,16 @@
 	unsigned long vdso_base;
 	int retval = 0;
 
+	down_write(&mm->mmap_sem);
+
 	/*
 	 * Notify the simulator that an exec just occurred.
 	 * If we can't find the filename of the mapping, just use
 	 * whatever was passed as the linux_binprm filename.
 	 */
-	if (!notify_exec())
+	if (!notify_exec(mm))
 		sim_notify_exec(bprm->filename);
 
-	down_write(&mm->mmap_sem);
-
 	/*
 	 * MAYWRITE to allow gdb to COW and set breakpoints
 	 */
diff --git a/arch/tile/mm/fault.c b/arch/tile/mm/fault.c
index 84ce7ab..fe811fa 100644
--- a/arch/tile/mm/fault.c
+++ b/arch/tile/mm/fault.c
@@ -454,6 +454,7 @@
 			tsk->min_flt++;
 		if (fault & VM_FAULT_RETRY) {
 			flags &= ~FAULT_FLAG_ALLOW_RETRY;
+			flags |= FAULT_FLAG_TRIED;
 
 			 /*
 			  * No need to up_read(&mm->mmap_sem) as we would
diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common
index cb837c2..648121b 100644
--- a/arch/um/Kconfig.common
+++ b/arch/um/Kconfig.common
@@ -7,6 +7,7 @@
 	bool
 	default y
 	select HAVE_GENERIC_HARDIRQS
+	select HAVE_UID16
 	select GENERIC_IRQ_SHOW
 	select GENERIC_CPU_DEVICES
 	select GENERIC_IO
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 87eebfe..c3bba73 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -7,8 +7,8 @@
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
 #include "chan.h"
-#include "os.h"
-#include "irq_kern.h"
+#include <os.h>
+#include <irq_kern.h>
 
 #ifdef CONFIG_NOCONFIG_CHAN
 static void *not_configged_init(char *str, int device,
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index f180813..9be670a 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -11,8 +11,8 @@
 #include <termios.h>
 #include <sys/ioctl.h>
 #include "chan_user.h"
-#include "os.h"
-#include "um_malloc.h"
+#include <os.h>
+#include <um_malloc.h>
 
 void generic_close(int fd, void *unused)
 {
diff --git a/arch/um/drivers/chan_user.h b/arch/um/drivers/chan_user.h
index 6257b7a..dc693298 100644
--- a/arch/um/drivers/chan_user.h
+++ b/arch/um/drivers/chan_user.h
@@ -6,7 +6,7 @@
 #ifndef __CHAN_USER_H__
 #define __CHAN_USER_H__
 
-#include "init.h"
+#include <init.h>
 
 struct chan_opts {
 	void (*const announce)(char *dev_name, int dev);
diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h
index 7f2ed0b..67cbee6 100644
--- a/arch/um/drivers/cow_sys.h
+++ b/arch/um/drivers/cow_sys.h
@@ -1,9 +1,9 @@
 #ifndef __COW_SYS_H__
 #define __COW_SYS_H__
 
-#include "kern_util.h"
-#include "os.h"
-#include "um_malloc.h"
+#include <kern_util.h>
+#include <os.h>
+#include <um_malloc.h>
 
 static inline void *cow_malloc(int size)
 {
diff --git a/arch/um/drivers/daemon.h b/arch/um/drivers/daemon.h
index 6e0e891..c2dd195 100644
--- a/arch/um/drivers/daemon.h
+++ b/arch/um/drivers/daemon.h
@@ -6,7 +6,7 @@
 #ifndef __DAEMON_H__
 #define __DAEMON_H__
 
-#include "net_user.h"
+#include <net_user.h>
 
 #define SWITCH_VERSION 3
 
diff --git a/arch/um/drivers/daemon_kern.c b/arch/um/drivers/daemon_kern.c
index b4a1522..7568cc2 100644
--- a/arch/um/drivers/daemon_kern.c
+++ b/arch/um/drivers/daemon_kern.c
@@ -6,9 +6,9 @@
  * Licensed under the GPL.
  */
 
-#include "linux/init.h"
+#include <linux/init.h>
 #include <linux/netdevice.h>
-#include "net_kern.h"
+#include <net_kern.h>
 #include "daemon.h"
 
 struct daemon_init {
diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c
index a4fd7bc..8813c10 100644
--- a/arch/um/drivers/daemon_user.c
+++ b/arch/um/drivers/daemon_user.c
@@ -14,9 +14,9 @@
 #include <sys/time.h>
 #include <sys/un.h>
 #include "daemon.h"
-#include "net_user.h"
-#include "os.h"
-#include "um_malloc.h"
+#include <net_user.h>
+#include <os.h>
+#include <um_malloc.h>
 
 enum request_type { REQ_NEW_CONTROL };
 
diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c
index 5b81d25..a13a427 100644
--- a/arch/um/drivers/fd.c
+++ b/arch/um/drivers/fd.c
@@ -9,8 +9,8 @@
 #include <errno.h>
 #include <termios.h>
 #include "chan_user.h"
-#include "os.h"
-#include "um_malloc.h"
+#include <os.h>
+#include <um_malloc.h>
 
 struct fd_chan {
 	int fd;
diff --git a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c
index 0345d62..f99b32a 100644
--- a/arch/um/drivers/harddog_user.c
+++ b/arch/um/drivers/harddog_user.c
@@ -6,7 +6,7 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <errno.h>
-#include "os.h"
+#include <os.h>
 
 struct dog_data {
 	int stdin;
diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c
index f9f6a4e..9b90fdc 100644
--- a/arch/um/drivers/hostaudio_kern.c
+++ b/arch/um/drivers/hostaudio_kern.c
@@ -3,15 +3,15 @@
  * Licensed under the GPL
  */
 
-#include "linux/fs.h"
-#include "linux/module.h"
-#include "linux/slab.h"
-#include "linux/sound.h"
-#include "linux/soundcard.h"
-#include "linux/mutex.h"
-#include "asm/uaccess.h"
-#include "init.h"
-#include "os.h"
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sound.h>
+#include <linux/soundcard.h>
+#include <linux/mutex.h>
+#include <asm/uaccess.h>
+#include <init.h>
+#include <os.h>
 
 struct hostaudio_state {
 	int fd;
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 457475f..fd9a15b 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -3,15 +3,15 @@
  * Licensed under the GPL
  */
 
-#include "linux/irqreturn.h"
-#include "linux/kd.h"
-#include "linux/sched.h"
-#include "linux/slab.h"
+#include <linux/irqreturn.h>
+#include <linux/kd.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
 #include "chan.h"
-#include "irq_kern.h"
-#include "irq_user.h"
-#include "kern_util.h"
-#include "os.h"
+#include <irq_kern.h>
+#include <irq_user.h>
+#include <kern_util.h>
+#include <os.h>
 
 #define LINE_BUFSIZE 4096
 
diff --git a/arch/um/drivers/line.h b/arch/um/drivers/line.h
index bae9561..138a145 100644
--- a/arch/um/drivers/line.h
+++ b/arch/um/drivers/line.h
@@ -6,12 +6,12 @@
 #ifndef __LINE_H__
 #define __LINE_H__
 
-#include "linux/list.h"
-#include "linux/workqueue.h"
-#include "linux/tty.h"
-#include "linux/interrupt.h"
-#include "linux/spinlock.h"
-#include "linux/mutex.h"
+#include <linux/list.h>
+#include <linux/workqueue.h>
+#include <linux/tty.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
 #include "chan_user.h"
 #include "mconsole_kern.h"
 
diff --git a/arch/um/drivers/mconsole.h b/arch/um/drivers/mconsole.h
index c139ae1..8b22535 100644
--- a/arch/um/drivers/mconsole.h
+++ b/arch/um/drivers/mconsole.h
@@ -12,7 +12,7 @@
 #define u32 uint32_t
 #endif
 
-#include "sysdep/ptrace.h"
+#include <sysdep/ptrace.h>
 
 #define MCONSOLE_MAGIC (0xcafebabe)
 #define MCONSOLE_MAX_DATA (512)
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 9efeb6d..79ccfe6 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -27,13 +27,13 @@
 #include <asm/uaccess.h>
 #include <asm/switch_to.h>
 
-#include "init.h"
-#include "irq_kern.h"
-#include "irq_user.h"
-#include "kern_util.h"
+#include <init.h>
+#include <irq_kern.h>
+#include <irq_user.h>
+#include <kern_util.h>
 #include "mconsole.h"
 #include "mconsole_kern.h"
-#include "os.h"
+#include <os.h>
 
 static int do_unlink_socket(struct notifier_block *notifier,
 			    unsigned long what, void *data)
diff --git a/arch/um/drivers/mconsole_kern.h b/arch/um/drivers/mconsole_kern.h
index d2fe07e..7a0c6a1 100644
--- a/arch/um/drivers/mconsole_kern.h
+++ b/arch/um/drivers/mconsole_kern.h
@@ -6,7 +6,7 @@
 #ifndef __MCONSOLE_KERN_H__
 #define __MCONSOLE_KERN_H__
 
-#include "linux/list.h"
+#include <linux/list.h>
 #include "mconsole.h"
 
 struct mconsole_entry {
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
index c0ef803..62145c2 100644
--- a/arch/um/drivers/mmapper_kern.c
+++ b/arch/um/drivers/mmapper_kern.c
@@ -18,7 +18,7 @@
 #include <linux/mm.h>
 
 #include <asm/uaccess.h>
-#include "mem_user.h"
+#include <mem_user.h>
 
 /* These are set in mmapper_init, which is called at boot time */
 static unsigned long mmapper_size;
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 458d324..b1314eb 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -18,12 +18,12 @@
 #include <linux/skbuff.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
-#include "init.h"
-#include "irq_kern.h"
-#include "irq_user.h"
+#include <init.h>
+#include <irq_kern.h>
+#include <irq_user.h>
 #include "mconsole_kern.h"
-#include "net_kern.h"
-#include "net_user.h"
+#include <net_kern.h>
+#include <net_user.h>
 
 #define DRIVER_NAME "uml-netdev"
 
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
index 05090c3..cd14157 100644
--- a/arch/um/drivers/net_user.c
+++ b/arch/um/drivers/net_user.c
@@ -11,9 +11,9 @@
 #include <string.h>
 #include <sys/socket.h>
 #include <sys/wait.h>
-#include "net_user.h"
-#include "os.h"
-#include "um_malloc.h"
+#include <net_user.h>
+#include <os.h>
+#include <um_malloc.h>
 
 int tap_open_common(void *dev, char *gate_addr)
 {
diff --git a/arch/um/drivers/null.c b/arch/um/drivers/null.c
index 2b45a14..1049574 100644
--- a/arch/um/drivers/null.c
+++ b/arch/um/drivers/null.c
@@ -7,7 +7,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include "chan_user.h"
-#include "os.h"
+#include <os.h>
 
 /* This address is used only as a unique identifier */
 static int null_chan;
diff --git a/arch/um/drivers/pcap_kern.c b/arch/um/drivers/pcap_kern.c
index 2860525..be0fb57bd 100644
--- a/arch/um/drivers/pcap_kern.c
+++ b/arch/um/drivers/pcap_kern.c
@@ -3,9 +3,9 @@
  * Licensed under the GPL.
  */
 
-#include "linux/init.h"
+#include <linux/init.h>
 #include <linux/netdevice.h>
-#include "net_kern.h"
+#include <net_kern.h>
 #include "pcap_user.h"
 
 struct pcap_init {
diff --git a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c
index 702a75b..c07b9c7 100644
--- a/arch/um/drivers/pcap_user.c
+++ b/arch/um/drivers/pcap_user.c
@@ -7,9 +7,9 @@
 #include <pcap.h>
 #include <string.h>
 #include <asm/types.h>
-#include "net_user.h"
+#include <net_user.h>
 #include "pcap_user.h"
-#include "um_malloc.h"
+#include <um_malloc.h>
 
 #define PCAP_FD(p) (*(int *)(p))
 
diff --git a/arch/um/drivers/pcap_user.h b/arch/um/drivers/pcap_user.h
index d8ba615..1ca7c76 100644
--- a/arch/um/drivers/pcap_user.h
+++ b/arch/um/drivers/pcap_user.h
@@ -3,7 +3,7 @@
  * Licensed under the GPL
  */
 
-#include "net_user.h"
+#include <net_user.h>
 
 struct pcap_data {
 	char *host_if;
diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c
index 1d83d50..40ca5cc 100644
--- a/arch/um/drivers/port_kern.c
+++ b/arch/um/drivers/port_kern.c
@@ -3,16 +3,16 @@
  * Licensed under the GPL
  */
 
-#include "linux/completion.h"
-#include "linux/interrupt.h"
-#include "linux/list.h"
-#include "linux/mutex.h"
-#include "linux/slab.h"
-#include "linux/workqueue.h"
-#include "asm/atomic.h"
-#include "init.h"
-#include "irq_kern.h"
-#include "os.h"
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <asm/atomic.h>
+#include <init.h>
+#include <irq_kern.h>
+#include <os.h>
 #include "port.h"
 
 struct port_list {
diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c
index 7b010b7..9a8e1b6 100644
--- a/arch/um/drivers/port_user.c
+++ b/arch/um/drivers/port_user.c
@@ -10,9 +10,9 @@
 #include <unistd.h>
 #include <netinet/in.h>
 #include "chan_user.h"
-#include "os.h"
+#include <os.h>
 #include "port.h"
-#include "um_malloc.h"
+#include <um_malloc.h>
 
 struct port_chan {
 	int raw;
diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c
index cff2b75..f1fcc2c 100644
--- a/arch/um/drivers/pty.c
+++ b/arch/um/drivers/pty.c
@@ -12,8 +12,8 @@
 #include <termios.h>
 #include <sys/stat.h>
 #include "chan_user.h"
-#include "os.h"
-#include "um_malloc.h"
+#include <os.h>
+#include <um_malloc.h>
 
 struct pty_chan {
 	void (*announce)(char *dev_name, int dev);
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c
index e32c6aa..9e3a722 100644
--- a/arch/um/drivers/random.c
+++ b/arch/um/drivers/random.c
@@ -13,8 +13,8 @@
 #include <linux/miscdevice.h>
 #include <linux/delay.h>
 #include <asm/uaccess.h>
-#include "irq_kern.h"
-#include "os.h"
+#include <irq_kern.h>
+#include <os.h>
 
 /*
  * core module and version information
diff --git a/arch/um/drivers/slip_common.c b/arch/um/drivers/slip_common.c
index e89cfc6..f597fa7 100644
--- a/arch/um/drivers/slip_common.c
+++ b/arch/um/drivers/slip_common.c
@@ -1,6 +1,6 @@
 #include <string.h>
 #include "slip_common.h"
-#include "net_user.h"
+#include <net_user.h>
 
 int slip_proto_read(int fd, void *buf, int len, struct slip_proto *slip)
 {
diff --git a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c
index dd2aadc..ed5249f 100644
--- a/arch/um/drivers/slip_kern.c
+++ b/arch/um/drivers/slip_kern.c
@@ -6,7 +6,7 @@
 #include <linux/if_arp.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
-#include "net_kern.h"
+#include <net_kern.h>
 #include "slip.h"
 
 struct slip_init {
diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c
index 932b4d6..55c290d 100644
--- a/arch/um/drivers/slip_user.c
+++ b/arch/um/drivers/slip_user.c
@@ -11,10 +11,10 @@
 #include <string.h>
 #include <sys/termios.h>
 #include <sys/wait.h>
-#include "net_user.h"
-#include "os.h"
+#include <net_user.h>
+#include <os.h>
 #include "slip.h"
-#include "um_malloc.h"
+#include <um_malloc.h>
 
 static int slip_user_init(void *data, void *dev)
 {
diff --git a/arch/um/drivers/slirp_kern.c b/arch/um/drivers/slirp_kern.c
index e376284..4ef11ca 100644
--- a/arch/um/drivers/slirp_kern.c
+++ b/arch/um/drivers/slirp_kern.c
@@ -4,11 +4,11 @@
  */
 
 #include <linux/if_arp.h>
-#include "linux/init.h"
+#include <linux/init.h>
 #include <linux/netdevice.h>
 #include <linux/string.h>
-#include "net_kern.h"
-#include "net_user.h"
+#include <net_kern.h>
+#include <net_user.h>
 #include "slirp.h"
 
 struct slirp_init {
diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c
index db4adb6..c999d18 100644
--- a/arch/um/drivers/slirp_user.c
+++ b/arch/um/drivers/slirp_user.c
@@ -7,8 +7,8 @@
 #include <errno.h>
 #include <string.h>
 #include <sys/wait.h>
-#include "net_user.h"
-#include "os.h"
+#include <net_user.h>
+#include <os.h>
 #include "slirp.h"
 
 static int slirp_user_init(void *data, void *dev)
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
index 7e86f00..16fdd0a 100644
--- a/arch/um/drivers/ssl.c
+++ b/arch/um/drivers/ssl.c
@@ -3,19 +3,19 @@
  * Licensed under the GPL
  */
 
-#include "linux/fs.h"
-#include "linux/tty.h"
-#include "linux/tty_driver.h"
-#include "linux/major.h"
-#include "linux/mm.h"
-#include "linux/init.h"
-#include "linux/console.h"
-#include "asm/termbits.h"
-#include "asm/irq.h"
+#include <linux/fs.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/major.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <asm/termbits.h>
+#include <asm/irq.h>
 #include "ssl.h"
 #include "chan.h"
-#include "init.h"
-#include "irq_user.h"
+#include <init.h>
+#include <irq_user.h>
 #include "mconsole_kern.h"
 
 static const int ssl_version = 1;
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index 929b99a..827777a 100644
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -3,27 +3,27 @@
  * Licensed under the GPL
  */
 
-#include "linux/posix_types.h"
-#include "linux/tty.h"
-#include "linux/tty_flip.h"
-#include "linux/types.h"
-#include "linux/major.h"
-#include "linux/kdev_t.h"
-#include "linux/console.h"
-#include "linux/string.h"
-#include "linux/sched.h"
-#include "linux/list.h"
-#include "linux/init.h"
-#include "linux/interrupt.h"
-#include "linux/slab.h"
-#include "linux/hardirq.h"
-#include "asm/current.h"
-#include "asm/irq.h"
+#include <linux/posix_types.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/types.h>
+#include <linux/major.h>
+#include <linux/kdev_t.h>
+#include <linux/console.h>
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/hardirq.h>
+#include <asm/current.h>
+#include <asm/irq.h>
 #include "stdio_console.h"
 #include "chan.h"
-#include "irq_user.h"
+#include <irq_user.h>
 #include "mconsole_kern.h"
-#include "init.h"
+#include <init.h>
 
 #define MAX_TTYS (16)
 
diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c
index a97391f..eaa201b 100644
--- a/arch/um/drivers/tty.c
+++ b/arch/um/drivers/tty.c
@@ -7,8 +7,8 @@
 #include <fcntl.h>
 #include <termios.h>
 #include "chan_user.h"
-#include "os.h"
-#include "um_malloc.h"
+#include <os.h>
+#include <um_malloc.h>
 
 struct tty_chan {
 	char *dev;
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 0643e5b..41bf720 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -33,12 +33,12 @@
 #include <linux/platform_device.h>
 #include <linux/scatterlist.h>
 #include <asm/tlbflush.h>
-#include "kern_util.h"
+#include <kern_util.h>
 #include "mconsole_kern.h"
-#include "init.h"
-#include "irq_kern.h"
+#include <init.h>
+#include <irq_kern.h>
 #include "ubd.h"
-#include "os.h"
+#include <os.h>
 #include "cow.h"
 
 enum ubd_req { UBD_READ, UBD_WRITE };
diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c
index ffe02c4..a703e45 100644
--- a/arch/um/drivers/ubd_user.c
+++ b/arch/um/drivers/ubd_user.c
@@ -19,7 +19,7 @@
 #include <byteswap.h>
 
 #include "ubd.h"
-#include "os.h"
+#include <os.h>
 
 void ignore_sigwinch_sig(void)
 {
diff --git a/arch/um/drivers/umcast.h b/arch/um/drivers/umcast.h
index 6f8c0fe..c190c64 100644
--- a/arch/um/drivers/umcast.h
+++ b/arch/um/drivers/umcast.h
@@ -6,7 +6,7 @@
 #ifndef __DRIVERS_UMCAST_H
 #define __DRIVERS_UMCAST_H
 
-#include "net_user.h"
+#include <net_user.h>
 
 struct umcast_data {
 	char *addr;
diff --git a/arch/um/drivers/umcast_kern.c b/arch/um/drivers/umcast_kern.c
index 42dab11..f5ba6e3 100644
--- a/arch/um/drivers/umcast_kern.c
+++ b/arch/um/drivers/umcast_kern.c
@@ -11,10 +11,10 @@
  * Licensed under the GPL.
  */
 
-#include "linux/init.h"
+#include <linux/init.h>
 #include <linux/netdevice.h>
 #include "umcast.h"
-#include "net_kern.h"
+#include <net_kern.h>
 
 struct umcast_init {
 	char *addr;
diff --git a/arch/um/drivers/umcast_user.c b/arch/um/drivers/umcast_user.c
index 010fa2d..6074184 100644
--- a/arch/um/drivers/umcast_user.c
+++ b/arch/um/drivers/umcast_user.c
@@ -16,8 +16,8 @@
 #include <errno.h>
 #include <netinet/in.h>
 #include "umcast.h"
-#include "net_user.h"
-#include "um_malloc.h"
+#include <net_user.h>
+#include <um_malloc.h>
 
 static struct sockaddr_in *new_addr(char *addr, unsigned short port)
 {
diff --git a/arch/um/drivers/vde_kern.c b/arch/um/drivers/vde_kern.c
index 1b852bf..6a365fa 100644
--- a/arch/um/drivers/vde_kern.c
+++ b/arch/um/drivers/vde_kern.c
@@ -7,10 +7,10 @@
  *
  */
 
-#include "linux/init.h"
+#include <linux/init.h>
 #include <linux/netdevice.h>
-#include "net_kern.h"
-#include "net_user.h"
+#include <net_kern.h>
+#include <net_user.h>
 #include "vde.h"
 
 static void vde_init(struct net_device *dev, void *data)
diff --git a/arch/um/drivers/vde_user.c b/arch/um/drivers/vde_user.c
index b8c2867..64cb630 100644
--- a/arch/um/drivers/vde_user.c
+++ b/arch/um/drivers/vde_user.c
@@ -6,8 +6,8 @@
 #include <stddef.h>
 #include <errno.h>
 #include <libvdeplug.h>
-#include "net_user.h"
-#include "um_malloc.h"
+#include <net_user.h>
+#include <um_malloc.h>
 #include "vde.h"
 
 static int vde_user_init(void *data, void *dev)
diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
index 969110e..20e30be 100644
--- a/arch/um/drivers/xterm.c
+++ b/arch/um/drivers/xterm.c
@@ -11,8 +11,8 @@
 #include <string.h>
 #include <termios.h>
 #include "chan_user.h"
-#include "os.h"
-#include "um_malloc.h"
+#include <os.h>
+#include <um_malloc.h>
 #include "xterm.h"
 
 struct xterm_chan {
diff --git a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c
index e3031e6..e8f9957 100644
--- a/arch/um/drivers/xterm_kern.c
+++ b/arch/um/drivers/xterm_kern.c
@@ -7,8 +7,8 @@
 #include <linux/completion.h>
 #include <linux/irqreturn.h>
 #include <asm/irq.h>
-#include "irq_kern.h"
-#include "os.h"
+#include <irq_kern.h>
+#include <os.h>
 
 struct xterm_wait {
 	struct completion ready;
diff --git a/arch/um/include/asm/Kbuild b/arch/um/include/asm/Kbuild
index fff2435..0f6e7b3 100644
--- a/arch/um/include/asm/Kbuild
+++ b/arch/um/include/asm/Kbuild
@@ -1,4 +1,4 @@
 generic-y += bug.h cputime.h device.h emergency-restart.h futex.h hardirq.h
 generic-y += hw_irq.h irq_regs.h kdebug.h percpu.h sections.h topology.h xor.h
 generic-y += ftrace.h pci.h io.h param.h delay.h mutex.h current.h exec.h
-generic-y += switch_to.h
+generic-y += switch_to.h clkdev.h
diff --git a/arch/um/include/asm/dma.h b/arch/um/include/asm/dma.h
index 9f6139a..f88c586 100644
--- a/arch/um/include/asm/dma.h
+++ b/arch/um/include/asm/dma.h
@@ -1,7 +1,7 @@
 #ifndef __UM_DMA_H
 #define __UM_DMA_H
 
-#include "asm/io.h"
+#include <asm/io.h>
 
 extern unsigned long uml_physmem;
 
diff --git a/arch/um/include/asm/mmu.h b/arch/um/include/asm/mmu.h
index 53e8b49..da70544 100644
--- a/arch/um/include/asm/mmu.h
+++ b/arch/um/include/asm/mmu.h
@@ -6,7 +6,7 @@
 #ifndef __ARCH_UM_MMU_H
 #define __ARCH_UM_MMU_H
 
-#include "mm_id.h"
+#include <mm_id.h>
 #include <asm/mm_context.h>
 
 typedef struct mm_context {
diff --git a/arch/um/include/asm/page.h b/arch/um/include/asm/page.h
index 7cfc3ce..5ff53d9 100644
--- a/arch/um/include/asm/page.h
+++ b/arch/um/include/asm/page.h
@@ -99,7 +99,7 @@
 
 #define __va_space (8*1024*1024)
 
-#include "mem.h"
+#include <mem.h>
 
 /* Cast to unsigned long before casting to void * to avoid a warning from
  * mmap_kmem about cutting a long long down to a void *.  Not sure that
diff --git a/arch/um/include/asm/pgtable.h b/arch/um/include/asm/pgtable.h
index 5888f1b..ae02909 100644
--- a/arch/um/include/asm/pgtable.h
+++ b/arch/um/include/asm/pgtable.h
@@ -23,9 +23,9 @@
 				   pte_present gives true */
 
 #ifdef CONFIG_3_LEVEL_PGTABLES
-#include "asm/pgtable-3level.h"
+#include <asm/pgtable-3level.h>
 #else
-#include "asm/pgtable-2level.h"
+#include <asm/pgtable-2level.h>
 #endif
 
 extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
diff --git a/arch/um/include/asm/processor-generic.h b/arch/um/include/asm/processor-generic.h
index 33a6a24..1e82e95 100644
--- a/arch/um/include/asm/processor-generic.h
+++ b/arch/um/include/asm/processor-generic.h
@@ -10,9 +10,9 @@
 
 struct task_struct;
 
-#include "asm/ptrace.h"
-#include "registers.h"
-#include "sysdep/archsetjmp.h"
+#include <asm/ptrace.h>
+#include <registers.h>
+#include <sysdep/archsetjmp.h>
 
 #include <linux/prefetch.h>
 
@@ -63,8 +63,6 @@
 {
 }
 
-extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
 extern unsigned long thread_saved_pc(struct task_struct *t);
 
 static inline void mm_copy_segments(struct mm_struct *from_mm,
diff --git a/arch/um/include/asm/ptrace-generic.h b/arch/um/include/asm/ptrace-generic.h
index 442f1d0..cb9b3c4 100644
--- a/arch/um/include/asm/ptrace-generic.h
+++ b/arch/um/include/asm/ptrace-generic.h
@@ -9,7 +9,7 @@
 #ifndef __ASSEMBLY__
 
 #include <asm/ptrace-abi.h>
-#include "sysdep/ptrace.h"
+#include <sysdep/ptrace.h>
 
 struct pt_regs {
 	struct uml_pt_regs regs;
diff --git a/arch/um/include/asm/smp.h b/arch/um/include/asm/smp.h
index 4a4b09d..e450793 100644
--- a/arch/um/include/asm/smp.h
+++ b/arch/um/include/asm/smp.h
@@ -3,9 +3,9 @@
 
 #ifdef CONFIG_SMP
 
-#include "linux/bitops.h"
-#include "asm/current.h"
-#include "linux/cpumask.h"
+#include <linux/bitops.h>
+#include <asm/current.h>
+#include <linux/cpumask.h>
 
 #define raw_smp_processor_id() (current_thread->cpu)
 
diff --git a/arch/um/include/shared/sysrq.h b/arch/um/include/asm/sysrq.h
similarity index 100%
rename from arch/um/include/shared/sysrq.h
rename to arch/um/include/asm/sysrq.h
diff --git a/arch/um/include/asm/thread_info.h b/arch/um/include/asm/thread_info.h
index c04e5ab..2c8eeb2 100644
--- a/arch/um/include/asm/thread_info.h
+++ b/arch/um/include/asm/thread_info.h
@@ -65,8 +65,6 @@
 #define TIF_SYSCALL_TRACE	0	/* syscall trace active */
 #define TIF_SIGPENDING		1	/* signal pending */
 #define TIF_NEED_RESCHED	2	/* rescheduling necessary */
-#define TIF_POLLING_NRFLAG      3       /* true if poll_idle() is polling
-					 * TIF_NEED_RESCHED */
 #define TIF_RESTART_BLOCK	4
 #define TIF_MEMDIE		5	/* is terminating due to OOM killer */
 #define TIF_SYSCALL_AUDIT	6
@@ -76,7 +74,6 @@
 #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
-#define _TIF_POLLING_NRFLAG     (1 << TIF_POLLING_NRFLAG)
 #define _TIF_MEMDIE		(1 << TIF_MEMDIE)
 #define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
 
diff --git a/arch/um/include/shared/arch.h b/arch/um/include/shared/arch.h
index 2de92a0..4f46abd 100644
--- a/arch/um/include/shared/arch.h
+++ b/arch/um/include/shared/arch.h
@@ -6,7 +6,7 @@
 #ifndef __ARCH_H__
 #define __ARCH_H__
 
-#include "sysdep/ptrace.h"
+#include <sysdep/ptrace.h>
 
 extern void arch_check_bugs(void);
 extern int arch_fixup(unsigned long address, struct uml_pt_regs *regs);
diff --git a/arch/um/include/shared/as-layout.h b/arch/um/include/shared/as-layout.h
index 86daa54..694c792 100644
--- a/arch/um/include/shared/as-layout.h
+++ b/arch/um/include/shared/as-layout.h
@@ -35,7 +35,7 @@
 
 #ifndef __ASSEMBLY__
 
-#include "sysdep/ptrace.h"
+#include <sysdep/ptrace.h>
 
 struct cpu_task {
 	int pid;
diff --git a/arch/um/include/shared/irq_kern.h b/arch/um/include/shared/irq_kern.h
index 7a5bfa6..e05bd66 100644
--- a/arch/um/include/shared/irq_kern.h
+++ b/arch/um/include/shared/irq_kern.h
@@ -6,8 +6,8 @@
 #ifndef __IRQ_KERN_H__
 #define __IRQ_KERN_H__
 
-#include "linux/interrupt.h"
-#include "asm/ptrace.h"
+#include <linux/interrupt.h>
+#include <asm/ptrace.h>
 
 extern int um_request_irq(unsigned int irq, int fd, int type,
 			  irq_handler_t handler,
diff --git a/arch/um/include/shared/irq_user.h b/arch/um/include/shared/irq_user.h
index 2b6d703..df56330 100644
--- a/arch/um/include/shared/irq_user.h
+++ b/arch/um/include/shared/irq_user.h
@@ -6,7 +6,7 @@
 #ifndef __IRQ_USER_H__
 #define __IRQ_USER_H__
 
-#include "sysdep/ptrace.h"
+#include <sysdep/ptrace.h>
 
 struct irq_fd {
 	struct irq_fd *next;
diff --git a/arch/um/include/shared/kern_util.h b/arch/um/include/shared/kern_util.h
index af6b6dc..83a91f9 100644
--- a/arch/um/include/shared/kern_util.h
+++ b/arch/um/include/shared/kern_util.h
@@ -6,8 +6,8 @@
 #ifndef __KERN_UTIL_H__
 #define __KERN_UTIL_H__
 
-#include "sysdep/ptrace.h"
-#include "sysdep/faultinfo.h"
+#include <sysdep/ptrace.h>
+#include <sysdep/faultinfo.h>
 
 struct siginfo;
 
diff --git a/arch/um/include/shared/longjmp.h b/arch/um/include/shared/longjmp.h
index e860bc584..9bdddf4 100644
--- a/arch/um/include/shared/longjmp.h
+++ b/arch/um/include/shared/longjmp.h
@@ -1,8 +1,8 @@
 #ifndef __UML_LONGJMP_H
 #define __UML_LONGJMP_H
 
-#include "sysdep/archsetjmp.h"
-#include "os.h"
+#include <sysdep/archsetjmp.h>
+#include <os.h>
 
 extern int setjmp(jmp_buf);
 extern void longjmp(jmp_buf, int);
diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h
index 89b686c1..4488304 100644
--- a/arch/um/include/shared/os.h
+++ b/arch/um/include/shared/os.h
@@ -7,9 +7,9 @@
 #define __OS_H__
 
 #include <stdarg.h>
-#include "irq_user.h"
-#include "longjmp.h"
-#include "mm_id.h"
+#include <irq_user.h>
+#include <longjmp.h>
+#include <mm_id.h>
 
 #define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR))
 
diff --git a/arch/um/include/shared/registers.h b/arch/um/include/shared/registers.h
index f1e0aa5..f5b7635 100644
--- a/arch/um/include/shared/registers.h
+++ b/arch/um/include/shared/registers.h
@@ -6,8 +6,8 @@
 #ifndef __REGISTERS_H
 #define __REGISTERS_H
 
-#include "sysdep/ptrace.h"
-#include "sysdep/archsetjmp.h"
+#include <sysdep/ptrace.h>
+#include <sysdep/archsetjmp.h>
 
 extern int save_fp_registers(int pid, unsigned long *fp_regs);
 extern int restore_fp_registers(int pid, unsigned long *fp_regs);
diff --git a/arch/um/include/shared/skas/skas.h b/arch/um/include/shared/skas/skas.h
index 64d2c74..c45df96 100644
--- a/arch/um/include/shared/skas/skas.h
+++ b/arch/um/include/shared/skas/skas.h
@@ -6,7 +6,7 @@
 #ifndef __SKAS_H
 #define __SKAS_H
 
-#include "sysdep/ptrace.h"
+#include <sysdep/ptrace.h>
 
 extern int userspace_pid[];
 extern int proc_mm, ptrace_faultinfo, ptrace_ldt;
diff --git a/arch/um/include/shared/skas_ptrace.h b/arch/um/include/shared/skas_ptrace.h
index 3d31bba..630a9c9 100644
--- a/arch/um/include/shared/skas_ptrace.h
+++ b/arch/um/include/shared/skas_ptrace.h
@@ -9,6 +9,6 @@
 #define PTRACE_FAULTINFO 52
 #define PTRACE_SWITCH_MM 55
 
-#include "sysdep/skas_ptrace.h"
+#include <sysdep/skas_ptrace.h>
 
 #endif
diff --git a/arch/um/kernel/asm-offsets.c b/arch/um/kernel/asm-offsets.c
index 91ea538..1fb1223 100644
--- a/arch/um/kernel/asm-offsets.c
+++ b/arch/um/kernel/asm-offsets.c
@@ -1 +1 @@
-#include "sysdep/kernel-offsets.h"
+#include <sysdep/kernel-offsets.h>
diff --git a/arch/um/kernel/config.c.in b/arch/um/kernel/config.c.in
index b7a43fe..972bf16 100644
--- a/arch/um/kernel/config.c.in
+++ b/arch/um/kernel/config.c.in
@@ -5,7 +5,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include "init.h"
+#include <init.h>
 
 static __initdata const char *config[] = {
 "CONFIG"
diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S
index a3cab6d3..fb8fd6f 100644
--- a/arch/um/kernel/dyn.lds.S
+++ b/arch/um/kernel/dyn.lds.S
@@ -89,7 +89,7 @@
 
   .kstrtab : { *(.kstrtab) }
 
-  #include "asm/common.lds.S"
+  #include <asm/common.lds.S>
 
   init.data : { INIT_DATA }
 
diff --git a/arch/um/kernel/early_printk.c b/arch/um/kernel/early_printk.c
index ec649bf..49480f0 100644
--- a/arch/um/kernel/early_printk.c
+++ b/arch/um/kernel/early_printk.c
@@ -9,7 +9,7 @@
 #include <linux/kernel.h>
 #include <linux/console.h>
 #include <linux/init.h>
-#include "os.h"
+#include <os.h>
 
 static void early_console_write(struct console *con, const char *s, unsigned int n)
 {
diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c
index 8c82786..ab019c7 100644
--- a/arch/um/kernel/exec.c
+++ b/arch/um/kernel/exec.c
@@ -12,11 +12,10 @@
 #include <asm/current.h>
 #include <asm/processor.h>
 #include <asm/uaccess.h>
-#include "as-layout.h"
-#include "mem_user.h"
-#include "skas.h"
-#include "os.h"
-#include "internal.h"
+#include <as-layout.h>
+#include <mem_user.h>
+#include <skas.h>
+#include <os.h>
 
 void flush_thread(void)
 {
@@ -49,27 +48,7 @@
 }
 EXPORT_SYMBOL(start_thread);
 
-long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env)
+void __noreturn ret_from_kernel_execve(struct pt_regs *unused)
 {
-	long err;
-
-	err = do_execve(file, argv, env, &current->thread.regs);
-	if (!err)
-		UML_LONGJMP(current->thread.exec_buf, 1);
-	return err;
-}
-
-long sys_execve(const char __user *file, const char __user *const __user *argv,
-		const char __user *const __user *env)
-{
-	long error;
-	char *filename;
-
-	filename = getname(file);
-	error = PTR_ERR(filename);
-	if (IS_ERR(filename)) goto out;
-	error = do_execve(filename, argv, env, &current->thread.regs);
-	putname(filename);
- out:
-	return error;
+	UML_LONGJMP(current->thread.exec_buf, 1);
 }
diff --git a/arch/um/kernel/gmon_syms.c b/arch/um/kernel/gmon_syms.c
index e9bcf247..1bf6126 100644
--- a/arch/um/kernel/gmon_syms.c
+++ b/arch/um/kernel/gmon_syms.c
@@ -3,7 +3,7 @@
  * Licensed under the GPL
  */
 
-#include "linux/module.h"
+#include <linux/module.h>
 
 extern void __bb_init_func(void *)  __attribute__((weak));
 EXPORT_SYMBOL(__bb_init_func);
diff --git a/arch/um/kernel/gprof_syms.c b/arch/um/kernel/gprof_syms.c
index e2f043d..74ddb44 100644
--- a/arch/um/kernel/gprof_syms.c
+++ b/arch/um/kernel/gprof_syms.c
@@ -3,7 +3,7 @@
  * Licensed under the GPL
  */
 
-#include "linux/module.h"
+#include <linux/module.h>
 
 extern void mcount(void);
 EXPORT_SYMBOL(mcount);
diff --git a/arch/um/kernel/initrd.c b/arch/um/kernel/initrd.c
index 10cc18f..55cead8 100644
--- a/arch/um/kernel/initrd.c
+++ b/arch/um/kernel/initrd.c
@@ -3,12 +3,12 @@
  * Licensed under the GPL
  */
 
-#include "linux/init.h"
-#include "linux/bootmem.h"
-#include "linux/initrd.h"
-#include "asm/types.h"
-#include "init.h"
-#include "os.h"
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/initrd.h>
+#include <asm/types.h>
+#include <init.h>
+#include <os.h>
 
 /* Changed by uml_initrd_setup, which is a setup */
 static char *initrd __initdata = NULL;
diff --git a/arch/um/kernel/internal.h b/arch/um/kernel/internal.h
deleted file mode 100644
index 5bf97db..0000000
--- a/arch/um/kernel/internal.h
+++ /dev/null
@@ -1 +0,0 @@
-extern long um_execve(const char *file, const char __user *const __user *argv, const char __user *const __user *env);
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index 9883026..36e12f0 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -5,17 +5,17 @@
  *	Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
  */
 
-#include "linux/cpumask.h"
-#include "linux/hardirq.h"
-#include "linux/interrupt.h"
-#include "linux/kernel_stat.h"
-#include "linux/module.h"
-#include "linux/sched.h"
-#include "linux/seq_file.h"
-#include "linux/slab.h"
-#include "as-layout.h"
-#include "kern_util.h"
-#include "os.h"
+#include <linux/cpumask.h>
+#include <linux/hardirq.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+#include <as-layout.h>
+#include <kern_util.h>
+#include <os.h>
 
 /*
  * This list is accessed under irq_lock, except in sigio_handler,
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
index e17bea0..543c047 100644
--- a/arch/um/kernel/ksyms.c
+++ b/arch/um/kernel/ksyms.c
@@ -4,7 +4,7 @@
  */
 
 #include <linux/module.h>
-#include "os.h"
+#include <os.h>
 
 EXPORT_SYMBOL(set_signals);
 EXPORT_SYMBOL(get_signals);
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index ebb86b2..5abcbfb 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -12,12 +12,12 @@
 #include <linux/slab.h>
 #include <asm/fixmap.h>
 #include <asm/page.h>
-#include "as-layout.h"
-#include "init.h"
-#include "kern.h"
-#include "kern_util.h"
-#include "mem_user.h"
-#include "os.h"
+#include <as-layout.h>
+#include <init.h>
+#include <kern.h>
+#include <kern_util.h>
+#include <mem_user.h>
+#include <os.h>
 
 /* allocated in paging_init, zeroed in mem_init, and unchanged thereafter */
 unsigned long *empty_zero_page = NULL;
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index c5f5afa..3062978 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -23,10 +23,10 @@
 #include <asm/pgtable.h>
 #include <asm/mmu_context.h>
 #include <asm/uaccess.h>
-#include "as-layout.h"
-#include "kern_util.h"
-#include "os.h"
-#include "skas.h"
+#include <as-layout.h>
+#include <kern_util.h>
+#include <os.h>
+#include <skas.h>
 
 /*
  * This is a per-cpu array.  A processor only modifies its entry and it only
@@ -69,18 +69,6 @@
 	return page;
 }
 
-int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-{
-	int pid;
-
-	current->thread.request.u.thread.proc = fn;
-	current->thread.request.u.thread.arg = arg;
-	pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0,
-		      &current->thread.regs, 0, NULL, NULL);
-	return pid;
-}
-EXPORT_SYMBOL(kernel_thread);
-
 static inline void set_current(struct task_struct *task)
 {
 	cpu_tasks[task_thread_info(task)->cpu] = ((struct cpu_task)
@@ -177,7 +165,7 @@
 }
 
 int copy_thread(unsigned long clone_flags, unsigned long sp,
-		unsigned long stack_top, struct task_struct * p,
+		unsigned long arg, struct task_struct * p,
 		struct pt_regs *regs)
 {
 	void (*handler)(void);
@@ -198,7 +186,8 @@
 		arch_copy_thread(&current->thread.arch, &p->thread.arch);
 	} else {
 		get_safe_registers(p->thread.regs.regs.gp, p->thread.regs.regs.fp);
-		p->thread.request.u.thread = current->thread.request.u.thread;
+		p->thread.request.u.thread.proc = (int (*)(void *))sp;
+		p->thread.request.u.thread.arg = (void *)arg;
 		handler = new_thread_handler;
 	}
 
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
index 3d15243..ced8903 100644
--- a/arch/um/kernel/reboot.c
+++ b/arch/um/kernel/reboot.c
@@ -3,13 +3,13 @@
  * Licensed under the GPL
  */
 
-#include "linux/sched.h"
-#include "linux/spinlock.h"
-#include "linux/slab.h"
-#include "linux/oom.h"
-#include "kern_util.h"
-#include "os.h"
-#include "skas.h"
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/oom.h>
+#include <kern_util.h>
+#include <os.h>
+#include <skas.h>
 
 void (*pm_power_off)(void);
 
diff --git a/arch/um/kernel/sigio.c b/arch/um/kernel/sigio.c
index c882111..b5e0cbb 100644
--- a/arch/um/kernel/sigio.c
+++ b/arch/um/kernel/sigio.c
@@ -4,9 +4,9 @@
  */
 
 #include <linux/interrupt.h>
-#include "irq_kern.h"
-#include "os.h"
-#include "sigio.h"
+#include <irq_kern.h>
+#include <os.h>
+#include <sigio.h>
 
 /* Protected by sigio_lock() called from write_sigio_workaround */
 static int sigio_irq_fd = -1;
diff --git a/arch/um/kernel/signal.c b/arch/um/kernel/signal.c
index cc9c235..db18eb6 100644
--- a/arch/um/kernel/signal.c
+++ b/arch/um/kernel/signal.c
@@ -9,8 +9,8 @@
 #include <asm/siginfo.h>
 #include <asm/signal.h>
 #include <asm/unistd.h>
-#include "frame_kern.h"
-#include "kern_util.h"
+#include <frame_kern.h>
+#include <kern_util.h>
 
 EXPORT_SYMBOL(block_signals);
 EXPORT_SYMBOL(unblock_signals);
diff --git a/arch/um/kernel/skas/clone.c b/arch/um/kernel/skas/clone.c
index e1fd066..289771d 100644
--- a/arch/um/kernel/skas/clone.c
+++ b/arch/um/kernel/skas/clone.c
@@ -7,10 +7,10 @@
 #include <sched.h>
 #include <asm/unistd.h>
 #include <sys/time.h>
-#include "as-layout.h"
-#include "ptrace_user.h"
-#include "stub-data.h"
-#include "sysdep/stub.h"
+#include <as-layout.h>
+#include <ptrace_user.h>
+#include <stub-data.h>
+#include <sysdep/stub.h>
 
 /*
  * This is in a separate file because it needs to be compiled with any
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
index 0a49ef0..ff03067 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -3,14 +3,14 @@
  * Licensed under the GPL
  */
 
-#include "linux/mm.h"
-#include "linux/sched.h"
-#include "linux/slab.h"
-#include "asm/pgalloc.h"
-#include "asm/pgtable.h"
-#include "as-layout.h"
-#include "os.h"
-#include "skas.h"
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+#include <as-layout.h>
+#include <os.h>
+#include <skas.h>
 
 extern int __syscall_stub_start;
 
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index 0a9e57e..4da11b3 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -3,12 +3,12 @@
  * Licensed under the GPL
  */
 
-#include "linux/init.h"
-#include "linux/sched.h"
-#include "as-layout.h"
-#include "kern.h"
-#include "os.h"
-#include "skas.h"
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <as-layout.h>
+#include <kern.h>
+#include <os.h>
+#include <skas.h>
 
 int new_mm(unsigned long stack)
 {
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c
index 86368a0..c0681e0 100644
--- a/arch/um/kernel/skas/syscall.c
+++ b/arch/um/kernel/skas/syscall.c
@@ -3,11 +3,11 @@
  * Licensed under the GPL
  */
 
-#include "linux/kernel.h"
-#include "linux/ptrace.h"
-#include "kern_util.h"
-#include "sysdep/ptrace.h"
-#include "sysdep/syscalls.h"
+#include <linux/kernel.h>
+#include <linux/ptrace.h>
+#include <kern_util.h>
+#include <sysdep/ptrace.h>
+#include <sysdep/syscalls.h>
 
 extern int syscall_table_size;
 #define NR_SYSCALLS (syscall_table_size / sizeof(void *))
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
index cd7df79..1d3e0c1 100644
--- a/arch/um/kernel/skas/uaccess.c
+++ b/arch/um/kernel/skas/uaccess.c
@@ -11,8 +11,8 @@
 #include <asm/current.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
-#include "kern_util.h"
-#include "os.h"
+#include <kern_util.h>
+#include <os.h>
 
 pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr)
 {
diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c
index a02b7e9..5c8c3ea 100644
--- a/arch/um/kernel/smp.c
+++ b/arch/um/kernel/smp.c
@@ -3,24 +3,24 @@
  * Licensed under the GPL
  */
 
-#include "linux/percpu.h"
-#include "asm/pgalloc.h"
-#include "asm/tlb.h"
+#include <linux/percpu.h>
+#include <asm/pgalloc.h>
+#include <asm/tlb.h>
 
 #ifdef CONFIG_SMP
 
-#include "linux/sched.h"
-#include "linux/module.h"
-#include "linux/threads.h"
-#include "linux/interrupt.h"
-#include "linux/err.h"
-#include "linux/hardirq.h"
-#include "asm/smp.h"
-#include "asm/processor.h"
-#include "asm/spinlock.h"
-#include "kern.h"
-#include "irq_user.h"
-#include "os.h"
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/threads.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/hardirq.h>
+#include <asm/smp.h>
+#include <asm/processor.h>
+#include <asm/spinlock.h>
+#include <kern.h>
+#include <irq_user.h>
+#include <os.h>
 
 /* Per CPU bogomips and other parameters
  * The only piece used here is the ipi pipe, which is set before SMP is
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c
index a4c6d8e..a81f370 100644
--- a/arch/um/kernel/syscall.c
+++ b/arch/um/kernel/syscall.c
@@ -3,17 +3,16 @@
  * Licensed under the GPL
  */
 
-#include "linux/file.h"
-#include "linux/fs.h"
-#include "linux/mm.h"
-#include "linux/sched.h"
-#include "linux/utsname.h"
-#include "linux/syscalls.h"
-#include "asm/current.h"
-#include "asm/mman.h"
-#include "asm/uaccess.h"
-#include "asm/unistd.h"
-#include "internal.h"
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/utsname.h>
+#include <linux/syscalls.h>
+#include <asm/current.h>
+#include <asm/mman.h>
+#include <asm/uaccess.h>
+#include <asm/unistd.h>
 
 long sys_fork(void)
 {
@@ -50,19 +49,3 @@
  out:
 	return err;
 }
-
-int kernel_execve(const char *filename,
-		  const char *const argv[],
-		  const char *const envp[])
-{
-	mm_segment_t fs;
-	int ret;
-
-	fs = get_fs();
-	set_fs(KERNEL_DS);
-	ret = um_execve(filename, (const char __user *const __user *)argv,
-			(const char __user *const __user *) envp);
-	set_fs(fs);
-
-	return ret;
-}
diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c
index 0960de5..e562ff8 100644
--- a/arch/um/kernel/sysrq.c
+++ b/arch/um/kernel/sysrq.c
@@ -7,7 +7,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/sched.h>
-#include "sysrq.h"
+#include <asm/sysrq.h>
 
 /* Catch non-i386 SUBARCH's. */
 #if !defined(CONFIG_UML_X86) || defined(CONFIG_64BIT)
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
index 5f76d4b..117568d 100644
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -10,8 +10,8 @@
 #include <linux/threads.h>
 #include <asm/irq.h>
 #include <asm/param.h>
-#include "kern_util.h"
-#include "os.h"
+#include <kern_util.h>
+#include <os.h>
 
 void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs)
 {
diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c
index f819af9..9472079 100644
--- a/arch/um/kernel/tlb.c
+++ b/arch/um/kernel/tlb.c
@@ -8,10 +8,10 @@
 #include <linux/sched.h>
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
-#include "as-layout.h"
-#include "mem_user.h"
-#include "os.h"
-#include "skas.h"
+#include <as-layout.h>
+#include <mem_user.h>
+#include <os.h>
+#include <skas.h>
 
 struct host_vm_change {
 	struct host_vm_op {
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index 0353b98..089f398 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -10,11 +10,11 @@
 #include <asm/current.h>
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
-#include "arch.h"
-#include "as-layout.h"
-#include "kern_util.h"
-#include "os.h"
-#include "skas.h"
+#include <arch.h>
+#include <as-layout.h>
+#include <kern_util.h>
+#include <os.h>
+#include <skas.h>
 
 /*
  * Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by
@@ -89,6 +89,7 @@
 				current->min_flt++;
 			if (fault & VM_FAULT_RETRY) {
 				flags &= ~FAULT_FLAG_ALLOW_RETRY;
+				flags |= FAULT_FLAG_TRIED;
 
 				goto retry;
 			}
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 4db8770..87df5e3 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -14,13 +14,13 @@
 #include <asm/pgtable.h>
 #include <asm/processor.h>
 #include <asm/setup.h>
-#include "as-layout.h"
-#include "arch.h"
-#include "init.h"
-#include "kern.h"
-#include "kern_util.h"
-#include "mem_user.h"
-#include "os.h"
+#include <as-layout.h>
+#include <arch.h>
+#include <init.h>
+#include <kern.h>
+#include <kern_util.h>
+#include <mem_user.h>
+#include <os.h>
 
 #define DEFAULT_COMMAND_LINE "root=98:0"
 
diff --git a/arch/um/kernel/umid.c b/arch/um/kernel/umid.c
index 81e07e2b..f6cc3bd 100644
--- a/arch/um/kernel/umid.c
+++ b/arch/um/kernel/umid.c
@@ -4,9 +4,9 @@
  */
 
 #include <asm/errno.h>
-#include "init.h"
-#include "kern.h"
-#include "os.h"
+#include <init.h>
+#include <kern.h>
+#include <os.h>
 
 /* Changed by set_umid_arg */
 static int umid_inited = 0;
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
index fbd9940..ff65fb4 100644
--- a/arch/um/kernel/uml.lds.S
+++ b/arch/um/kernel/uml.lds.S
@@ -60,7 +60,7 @@
 	PROVIDE_HIDDEN(__rela_iplt_end = .);
   }
 
-  #include "asm/common.lds.S"
+  #include <asm/common.lds.S>
 
   init.data : { INIT_DATA }
   .data    :
diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c
index c5d039e..3a6bc2a 100644
--- a/arch/um/os-Linux/aio.c
+++ b/arch/um/os-Linux/aio.c
@@ -9,10 +9,10 @@
 #include <errno.h>
 #include <sys/time.h>
 #include <asm/unistd.h>
-#include "aio.h"
-#include "init.h"
-#include "kern_util.h"
-#include "os.h"
+#include <aio.h>
+#include <init.h>
+#include <kern_util.h>
+#include <os.h>
 
 struct aio_thread_req {
 	enum aio_type type;
diff --git a/arch/um/os-Linux/drivers/etap.h b/arch/um/os-Linux/drivers/etap.h
index ddffd41..54183a6 100644
--- a/arch/um/os-Linux/drivers/etap.h
+++ b/arch/um/os-Linux/drivers/etap.h
@@ -6,7 +6,7 @@
 #ifndef __DRIVERS_ETAP_H
 #define __DRIVERS_ETAP_H
 
-#include "net_user.h"
+#include <net_user.h>
 
 struct ethertap_data {
 	char *dev_name;
diff --git a/arch/um/os-Linux/drivers/ethertap_kern.c b/arch/um/os-Linux/drivers/ethertap_kern.c
index 7f6f9a71..f424600 100644
--- a/arch/um/os-Linux/drivers/ethertap_kern.c
+++ b/arch/um/os-Linux/drivers/ethertap_kern.c
@@ -9,7 +9,7 @@
 #include <linux/init.h>
 #include <linux/netdevice.h>
 #include "etap.h"
-#include "net_kern.h"
+#include <net_kern.h>
 
 struct ethertap_init {
 	char *dev_name;
diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c
index db3d648..b39b669 100644
--- a/arch/um/os-Linux/drivers/ethertap_user.c
+++ b/arch/um/os-Linux/drivers/ethertap_user.c
@@ -13,9 +13,9 @@
 #include <sys/socket.h>
 #include <sys/wait.h>
 #include "etap.h"
-#include "os.h"
-#include "net_user.h"
-#include "um_malloc.h"
+#include <os.h>
+#include <net_user.h>
+#include <um_malloc.h>
 
 #define MAX_PACKET ETH_MAX_PACKET
 
diff --git a/arch/um/os-Linux/drivers/tuntap.h b/arch/um/os-Linux/drivers/tuntap.h
index f17c315..7367354 100644
--- a/arch/um/os-Linux/drivers/tuntap.h
+++ b/arch/um/os-Linux/drivers/tuntap.h
@@ -6,7 +6,7 @@
 #ifndef __UM_TUNTAP_H
 #define __UM_TUNTAP_H
 
-#include "net_user.h"
+#include <net_user.h>
 
 struct tuntap_data {
 	char *dev_name;
diff --git a/arch/um/os-Linux/drivers/tuntap_kern.c b/arch/um/os-Linux/drivers/tuntap_kern.c
index 4048800..d9d56e5 100644
--- a/arch/um/os-Linux/drivers/tuntap_kern.c
+++ b/arch/um/os-Linux/drivers/tuntap_kern.c
@@ -7,7 +7,7 @@
 #include <linux/init.h>
 #include <linux/skbuff.h>
 #include <asm/errno.h>
-#include "net_kern.h"
+#include <net_kern.h>
 #include "tuntap.h"
 
 struct tuntap_init {
diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c
index a2aacff..14126d9 100644
--- a/arch/um/os-Linux/drivers/tuntap_user.c
+++ b/arch/um/os-Linux/drivers/tuntap_user.c
@@ -13,8 +13,8 @@
 #include <sys/socket.h>
 #include <sys/wait.h>
 #include <sys/uio.h>
-#include "kern_util.h"
-#include "os.h"
+#include <kern_util.h>
+#include <os.h>
 #include "tuntap.h"
 
 static int tuntap_user_init(void *data, void *dev)
diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c
index d895271..1a365dd 100644
--- a/arch/um/os-Linux/elf_aux.c
+++ b/arch/um/os-Linux/elf_aux.c
@@ -9,9 +9,9 @@
  */
 #include <elf.h>
 #include <stddef.h>
-#include "init.h"
-#include "elf_user.h"
-#include "mem_user.h"
+#include <init.h>
+#include <elf_user.h>
+#include <mem_user.h>
 
 typedef Elf32_auxv_t elf_auxv_t;
 
diff --git a/arch/um/os-Linux/execvp.c b/arch/um/os-Linux/execvp.c
index 66e583a..8fb25ca 100644
--- a/arch/um/os-Linux/execvp.c
+++ b/arch/um/os-Linux/execvp.c
@@ -27,12 +27,12 @@
 #include <limits.h>
 
 #ifndef TEST
-#include "um_malloc.h"
+#include <um_malloc.h>
 #else
 #include <stdio.h>
 #define um_kmalloc malloc
 #endif
-#include "os.h"
+#include <os.h>
 
 /* Execute FILE, searching in the `PATH' environment variable if it contains
    no slashes, with arguments ARGV and environment from `environ'.  */
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
index b049a63..c17bd6f 100644
--- a/arch/um/os-Linux/file.c
+++ b/arch/um/os-Linux/file.c
@@ -13,7 +13,7 @@
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/un.h>
-#include "os.h"
+#include <os.h>
 
 static void copy_stat(struct uml_stat *dst, const struct stat64 *src)
 {
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c
index cf26c4a..e3ee4a5 100644
--- a/arch/um/os-Linux/helper.c
+++ b/arch/um/os-Linux/helper.c
@@ -10,9 +10,9 @@
 #include <linux/limits.h>
 #include <sys/socket.h>
 #include <sys/wait.h>
-#include "kern_util.h"
-#include "os.h"
-#include "um_malloc.h"
+#include <kern_util.h>
+#include <os.h>
+#include <um_malloc.h>
 
 struct helper_data {
 	void (*pre_exec)(void*);
diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c
index 9a49908..b9afb74 100644
--- a/arch/um/os-Linux/irq.c
+++ b/arch/um/os-Linux/irq.c
@@ -8,9 +8,9 @@
 #include <poll.h>
 #include <signal.h>
 #include <string.h>
-#include "irq_user.h"
-#include "os.h"
-#include "um_malloc.h"
+#include <irq_user.h>
+#include <os.h>
+#include <um_malloc.h>
 
 /*
  * Locked by irq_lock in arch/um/kernel/irq.c.  Changed by os_create_pollfd
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c
index 7a86dd5..749c96d 100644
--- a/arch/um/os-Linux/main.c
+++ b/arch/um/os-Linux/main.c
@@ -10,11 +10,11 @@
 #include <signal.h>
 #include <string.h>
 #include <sys/resource.h>
-#include "as-layout.h"
-#include "init.h"
-#include "kern_util.h"
-#include "os.h"
-#include "um_malloc.h"
+#include <as-layout.h>
+#include <init.h>
+#include <kern_util.h>
+#include <os.h>
+#include <um_malloc.h>
 
 #define PGD_BOUND (4 * 1024 * 1024)
 #define STACKSIZE (8 * 1024 * 1024)
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c
index 8e421e1..ba43980 100644
--- a/arch/um/os-Linux/mem.c
+++ b/arch/um/os-Linux/mem.c
@@ -13,8 +13,8 @@
 #include <sys/stat.h>
 #include <sys/mman.h>
 #include <sys/param.h>
-#include "init.h"
-#include "os.h"
+#include <init.h>
+#include <os.h>
 
 /* Modified by which_tmpdir, which is called during early boot */
 static char *default_tmpdir = "/tmp";
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index 307f173..162bea3 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -12,10 +12,10 @@
 #include <sys/ptrace.h>
 #include <sys/wait.h>
 #include <asm/unistd.h>
-#include "init.h"
-#include "longjmp.h"
-#include "os.h"
-#include "skas_ptrace.h"
+#include <init.h>
+#include <longjmp.h>
+#include <os.h>
+#include <skas_ptrace.h>
 
 #define ARBITRARY_ADDR -1
 #define FAILURE_PID    -1
diff --git a/arch/um/os-Linux/registers.c b/arch/um/os-Linux/registers.c
index b866b9e..2ff8d4f 100644
--- a/arch/um/os-Linux/registers.c
+++ b/arch/um/os-Linux/registers.c
@@ -7,9 +7,9 @@
 #include <errno.h>
 #include <string.h>
 #include <sys/ptrace.h>
-#include "sysdep/ptrace.h"
-#include "sysdep/ptrace_user.h"
-#include "registers.h"
+#include <sysdep/ptrace.h>
+#include <sysdep/ptrace_user.h>
+#include <registers.h>
 
 int save_registers(int pid, struct uml_pt_regs *regs)
 {
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c
index 3c16121..8b61cc0 100644
--- a/arch/um/os-Linux/sigio.c
+++ b/arch/um/os-Linux/sigio.c
@@ -11,11 +11,11 @@
 #include <sched.h>
 #include <signal.h>
 #include <string.h>
-#include "kern_util.h"
-#include "init.h"
-#include "os.h"
-#include "sigio.h"
-#include "um_malloc.h"
+#include <kern_util.h>
+#include <init.h>
+#include <os.h>
+#include <sigio.h>
+#include <um_malloc.h>
 
 /*
  * Protected by sigio_lock(), also used by sigio_cleanup, which is an
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index 6366ce9..b1469fe 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -9,10 +9,10 @@
 #include <errno.h>
 #include <signal.h>
 #include <strings.h>
-#include "as-layout.h"
-#include "kern_util.h"
-#include "os.h"
-#include "sysdep/mcontext.h"
+#include <as-layout.h>
+#include <kern_util.h>
+#include <os.h>
+#include <sysdep/mcontext.h>
 #include "internal.h"
 
 void (*sig_info[NSIG])(int, siginfo_t *, struct uml_pt_regs *) = {
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c
index 90b310d..689b18d 100644
--- a/arch/um/os-Linux/skas/mem.c
+++ b/arch/um/os-Linux/skas/mem.c
@@ -8,16 +8,16 @@
 #include <errno.h>
 #include <string.h>
 #include <sys/mman.h>
-#include "init.h"
-#include "as-layout.h"
-#include "mm_id.h"
-#include "os.h"
-#include "proc_mm.h"
-#include "ptrace_user.h"
-#include "registers.h"
-#include "skas.h"
-#include "sysdep/ptrace.h"
-#include "sysdep/stub.h"
+#include <init.h>
+#include <as-layout.h>
+#include <mm_id.h>
+#include <os.h>
+#include <proc_mm.h>
+#include <ptrace_user.h>
+#include <registers.h>
+#include <skas.h>
+#include <sysdep/ptrace.h>
+#include <sysdep/stub.h>
 
 extern unsigned long batch_syscall_stub, __syscall_stub_start;
 
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index d93bb40..4625949 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -11,17 +11,17 @@
 #include <sys/mman.h>
 #include <sys/wait.h>
 #include <asm/unistd.h>
-#include "as-layout.h"
-#include "init.h"
-#include "kern_util.h"
-#include "mem.h"
-#include "os.h"
-#include "proc_mm.h"
-#include "ptrace_user.h"
-#include "registers.h"
-#include "skas.h"
-#include "skas_ptrace.h"
-#include "sysdep/stub.h"
+#include <as-layout.h>
+#include <init.h>
+#include <kern_util.h>
+#include <mem.h>
+#include <os.h>
+#include <proc_mm.h>
+#include <ptrace_user.h>
+#include <registers.h>
+#include <skas.h>
+#include <skas_ptrace.h>
+#include <sysdep/stub.h>
 
 int is_skas_winch(int pid, int fd, void *data)
 {
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 425162e..da4b9e9 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -16,13 +16,13 @@
 #include <sys/stat.h>
 #include <sys/wait.h>
 #include <asm/unistd.h>
-#include "init.h"
-#include "os.h"
-#include "mem_user.h"
-#include "ptrace_user.h"
-#include "registers.h"
-#include "skas.h"
-#include "skas_ptrace.h"
+#include <init.h>
+#include <os.h>
+#include <mem_user.h>
+#include <ptrace_user.h>
+#include <registers.h>
+#include <skas.h>
+#include <skas_ptrace.h>
 
 static void ptrace_child(void)
 {
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c
index 0748fe0..fac388c 100644
--- a/arch/um/os-Linux/time.c
+++ b/arch/um/os-Linux/time.c
@@ -8,8 +8,8 @@
 #include <signal.h>
 #include <time.h>
 #include <sys/time.h>
-#include "kern_util.h"
-#include "os.h"
+#include <kern_util.h>
+#include <os.h>
 #include "internal.h"
 
 int set_interval(void)
diff --git a/arch/um/os-Linux/tty.c b/arch/um/os-Linux/tty.c
index dd12b99..721d8af 100644
--- a/arch/um/os-Linux/tty.c
+++ b/arch/um/os-Linux/tty.c
@@ -7,8 +7,8 @@
 #include <unistd.h>
 #include <errno.h>
 #include <fcntl.h>
-#include "kern_util.h"
-#include "os.h"
+#include <kern_util.h>
+#include <os.h>
 
 struct grantpt_info {
 	int fd;
diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c
index 4832eb5..c1dc892 100644
--- a/arch/um/os-Linux/umid.c
+++ b/arch/um/os-Linux/umid.c
@@ -12,8 +12,8 @@
 #include <string.h>
 #include <unistd.h>
 #include <sys/stat.h>
-#include "init.h"
-#include "os.h"
+#include <init.h>
+#include <os.h>
 
 #define UML_DIR "~/.uml/"
 
diff --git a/arch/um/os-Linux/user_syms.c b/arch/um/os-Linux/user_syms.c
index 73926fa..db4a034 100644
--- a/arch/um/os-Linux/user_syms.c
+++ b/arch/um/os-Linux/user_syms.c
@@ -1,5 +1,5 @@
-#include "linux/types.h"
-#include "linux/module.h"
+#include <linux/types.h>
+#include <linux/module.h>
 
 /* Some of this are builtin function (some are not but could in the future),
  * so I *must* declare good prototypes for them and then EXPORT them.
diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c
index 9e3b43b..492ef5e 100644
--- a/arch/um/os-Linux/util.c
+++ b/arch/um/os-Linux/util.c
@@ -13,7 +13,7 @@
 #include <wait.h>
 #include <sys/mman.h>
 #include <sys/utsname.h>
-#include "os.h"
+#include <os.h>
 
 void stack_protections(unsigned long address)
 {
diff --git a/arch/um/sys-ppc/miscthings.c b/arch/um/sys-ppc/miscthings.c
index 1c11aed..25908d2 100644
--- a/arch/um/sys-ppc/miscthings.c
+++ b/arch/um/sys-ppc/miscthings.c
@@ -1,6 +1,6 @@
-#include "linux/threads.h"
-#include "linux/stddef.h"  // for NULL
-#include "linux/elf.h"  // for AT_NULL
+#include <linux/threads.h>
+#include <linux/stddef.h>  // for NULL
+#include <linux/elf.h>  // for AT_NULL
 
 /* The following function nicked from arch/ppc/kernel/process.c and
  * adapted slightly */
diff --git a/arch/um/sys-ppc/ptrace.c b/arch/um/sys-ppc/ptrace.c
index 66ef155..8245df4 100644
--- a/arch/um/sys-ppc/ptrace.c
+++ b/arch/um/sys-ppc/ptrace.c
@@ -1,4 +1,4 @@
-#include "linux/sched.h"
+#include <linux/sched.h>
 #include "asm/ptrace.h"
 
 int putreg(struct task_struct *child, unsigned long regno, 
diff --git a/arch/um/sys-ppc/ptrace_user.c b/arch/um/sys-ppc/ptrace_user.c
index 224d240..4601b92 100644
--- a/arch/um/sys-ppc/ptrace_user.c
+++ b/arch/um/sys-ppc/ptrace_user.c
@@ -1,6 +1,6 @@
 #include <errno.h>
 #include <asm/ptrace.h>
-#include "sysdep/ptrace.h"
+#include <sysdep/ptrace.h>
 
 int ptrace_getregs(long pid, unsigned long *regs_out)
 {
diff --git a/arch/um/sys-ppc/shared/sysdep/ptrace.h b/arch/um/sys-ppc/shared/sysdep/ptrace.h
index 0e3230e..efe0c1a 100644
--- a/arch/um/sys-ppc/shared/sysdep/ptrace.h
+++ b/arch/um/sys-ppc/shared/sysdep/ptrace.h
@@ -5,7 +5,7 @@
 #ifndef __SYS_PTRACE_PPC_H
 #define __SYS_PTRACE_PPC_H
 
-#include "linux/types.h"
+#include <linux/types.h>
 
 /* the following taken from <asm-ppc/ptrace.h> */
 
diff --git a/arch/um/sys-ppc/sigcontext.c b/arch/um/sys-ppc/sigcontext.c
index 40694d0..aac6c83 100644
--- a/arch/um/sys-ppc/sigcontext.c
+++ b/arch/um/sys-ppc/sigcontext.c
@@ -1,4 +1,4 @@
 #include "asm/ptrace.h"
 #include "asm/sigcontext.h"
-#include "sysdep/ptrace.h"
+#include <sysdep/ptrace.h>
 
diff --git a/arch/um/sys-ppc/sysrq.c b/arch/um/sys-ppc/sysrq.c
index 2f816f1..f889449 100644
--- a/arch/um/sys-ppc/sysrq.c
+++ b/arch/um/sys-ppc/sysrq.c
@@ -3,8 +3,8 @@
  * Licensed under the GPL
  */
 
-#include "linux/kernel.h"
-#include "linux/smp.h"
+#include <linux/kernel.h>
+#include <linux/smp.h>
 #include "asm/ptrace.h"
 #include "sysrq.h"
 
diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig
index 1e638e7..35ee2bf 100644
--- a/arch/unicore32/Kconfig
+++ b/arch/unicore32/Kconfig
@@ -21,9 +21,6 @@
 	  designs licensed by PKUnity Ltd.
 	  Please see web page at <http://www.pkunity.com/>.
 
-config HAVE_PWM
-	bool
-
 config GENERIC_GPIO
 	def_bool y
 
@@ -106,7 +103,8 @@
 
 config PUV3_NB0916
 	bool "NetBook board (0916)"
-	select HAVE_PWM
+	select PWM
+	select PWM_PUV3
 
 config PUV3_SMW0919
 	bool "Security Mini-Workstation board (0919)"
@@ -220,12 +218,6 @@
 	select GPIO_SYSFS if EXPERIMENTAL
 	default y
 
-config PUV3_PWM
-	tristate
-	default BACKLIGHT_PWM
-	help
-	  Enable support for NB0916 PWM controllers
-
 if PUV3_NB0916
 
 menu "PKUnity NetBook-0916 Features"
diff --git a/arch/unicore32/include/asm/Kbuild b/arch/unicore32/include/asm/Kbuild
index 34b789b..c910c98 100644
--- a/arch/unicore32/include/asm/Kbuild
+++ b/arch/unicore32/include/asm/Kbuild
@@ -4,12 +4,14 @@
 generic-y += auxvec.h
 generic-y += bitsperlong.h
 generic-y += bugs.h
+generic-y += clkdev.h
 generic-y += cputime.h
 generic-y += current.h
 generic-y += device.h
 generic-y += div64.h
 generic-y += emergency-restart.h
 generic-y += errno.h
+generic-y += exec.h
 generic-y += fb.h
 generic-y += fcntl.h
 generic-y += ftrace.h
diff --git a/arch/unicore32/include/asm/exec.h b/arch/unicore32/include/asm/exec.h
deleted file mode 100644
index 06d1f0f..0000000
--- a/arch/unicore32/include/asm/exec.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Process execution bits for PKUnity SoC and UniCore ISA
- *
- * Copyright (C) 2001-2012 GUAN Xue-tao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef __UNICORE_EXEC_H__
-#define __UNICORE_EXEC_H__
-
-#define arch_align_stack(x)		(x)
-
-#endif /* __UNICORE_EXEC_H__ */
diff --git a/arch/unicore32/include/asm/thread_info.h b/arch/unicore32/include/asm/thread_info.h
index 89f7557..818b4a1 100644
--- a/arch/unicore32/include/asm/thread_info.h
+++ b/arch/unicore32/include/asm/thread_info.h
@@ -141,12 +141,12 @@
 #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
 #define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
 #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
-#define _TIF_RESTORE_SIGMASK	(1 << TIF_RESTORE_SIGMASK)
 
 /*
  * Change these and you break ASM code in entry-common.S
  */
-#define _TIF_WORK_MASK		0x000000ff
+#define _TIF_WORK_MASK \
+	(_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_NOTIFY_RESUME)
 
 #endif /* __KERNEL__ */
 #endif /* __UNICORE_THREAD_INFO_H__ */
diff --git a/arch/unicore32/include/mach/regs-ost.h b/arch/unicore32/include/mach/regs-ost.h
index 7b91fe6..4a85fb4 100644
--- a/arch/unicore32/include/mach/regs-ost.h
+++ b/arch/unicore32/include/mach/regs-ost.h
@@ -33,18 +33,16 @@
  * Interrupt Enable Reg OST_OIER
  */
 #define OST_OIER	(PKUNITY_OST_BASE + 0x001C)
+
 /*
- * PWM Pulse Width Control Reg OST_PWMPWCR
+ * PWM Registers: IO base address: PKUNITY_OST_BASE + 0x80
+ *      PWCR: Pulse Width Control Reg
+ *      DCCR: Duty Cycle Control Reg
+ *      PCR: Period Control Reg
  */
-#define OST_PWMPWCR	(PKUNITY_OST_BASE + 0x0080)
-/*
- * PWM Duty Cycle Control Reg OST_PWMDCCR
- */
-#define OST_PWMDCCR	(PKUNITY_OST_BASE + 0x0084)
-/*
- * PWM Period Control Reg OST_PWMPCR
- */
-#define OST_PWMPCR	(PKUNITY_OST_BASE + 0x0088)
+#define OST_PWM_PWCR	(0x00)
+#define OST_PWM_DCCR	(0x04)
+#define OST_PWM_PCR 	(0x08)
 
 /*
  * Match detected 0 OST_OSSR_M0
diff --git a/arch/unicore32/kernel/Makefile b/arch/unicore32/kernel/Makefile
index 3240101..fa497e0 100644
--- a/arch/unicore32/kernel/Makefile
+++ b/arch/unicore32/kernel/Makefile
@@ -16,7 +16,6 @@
 obj-$(CONFIG_ARCH_PUV3)		+= clock.o irq.o time.o
 
 obj-$(CONFIG_PUV3_GPIO)		+= gpio.o
-obj-$(CONFIG_PUV3_PWM)		+= pwm.o
 obj-$(CONFIG_PUV3_PM)		+= pm.o sleep.o
 obj-$(CONFIG_HIBERNATION)	+= hibernate.o hibernate_asm.o
 
diff --git a/arch/unicore32/kernel/entry.S b/arch/unicore32/kernel/entry.S
index 00a259f..dcb87ab 100644
--- a/arch/unicore32/kernel/entry.S
+++ b/arch/unicore32/kernel/entry.S
@@ -544,8 +544,6 @@
 work_pending:
 	cand.a	r1, #_TIF_NEED_RESCHED
 	bne	work_resched
-	cand.a	r1, #_TIF_SIGPENDING|_TIF_NOTIFY_RESUME
-	beq	no_work_pending
 	mov	r0, sp				@ 'regs'
 	mov	r2, why				@ 'syscall'
 	cand.a	r1, #_TIF_SIGPENDING		@ delivering a signal?
diff --git a/arch/unicore32/kernel/process.c b/arch/unicore32/kernel/process.c
index b6f0458..b008586 100644
--- a/arch/unicore32/kernel/process.c
+++ b/arch/unicore32/kernel/process.c
@@ -380,7 +380,7 @@
 	return install_special_mapping(mm, 0xffff0000, PAGE_SIZE,
 				       VM_READ | VM_EXEC |
 				       VM_MAYREAD | VM_MAYEXEC |
-				       VM_RESERVED,
+				       VM_DONTEXPAND | VM_DONTDUMP,
 				       NULL);
 }
 
diff --git a/arch/unicore32/kernel/pwm.c b/arch/unicore32/kernel/pwm.c
deleted file mode 100644
index 4615d51..0000000
--- a/arch/unicore32/kernel/pwm.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * linux/arch/unicore32/kernel/pwm.c
- *
- * Code specific to PKUnity SoC and UniCore ISA
- *
- *	Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
- *	Copyright (C) 2001-2010 Guan Xuetao
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/pwm.h>
-
-#include <asm/div64.h>
-#include <mach/hardware.h>
-
-struct pwm_device {
-	struct list_head	node;
-	struct platform_device *pdev;
-
-	const char	*label;
-	struct clk	*clk;
-	int		clk_enabled;
-
-	unsigned int	use_count;
-	unsigned int	pwm_id;
-};
-
-/*
- * period_ns = 10^9 * (PRESCALE + 1) * (PV + 1) / PWM_CLK_RATE
- * duty_ns   = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE
- */
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
-{
-	unsigned long long c;
-	unsigned long period_cycles, prescale, pv, dc;
-
-	if (pwm == NULL || period_ns == 0 || duty_ns > period_ns)
-		return -EINVAL;
-
-	c = clk_get_rate(pwm->clk);
-	c = c * period_ns;
-	do_div(c, 1000000000);
-	period_cycles = c;
-
-	if (period_cycles < 1)
-		period_cycles = 1;
-	prescale = (period_cycles - 1) / 1024;
-	pv = period_cycles / (prescale + 1) - 1;
-
-	if (prescale > 63)
-		return -EINVAL;
-
-	if (duty_ns == period_ns)
-		dc = OST_PWMDCCR_FDCYCLE;
-	else
-		dc = (pv + 1) * duty_ns / period_ns;
-
-	/* NOTE: the clock to PWM has to be enabled first
-	 * before writing to the registers
-	 */
-	clk_enable(pwm->clk);
-	OST_PWMPWCR = prescale;
-	OST_PWMDCCR = pv - dc;
-	OST_PWMPCR  = pv;
-	clk_disable(pwm->clk);
-
-	return 0;
-}
-EXPORT_SYMBOL(pwm_config);
-
-int pwm_enable(struct pwm_device *pwm)
-{
-	int rc = 0;
-
-	if (!pwm->clk_enabled) {
-		rc = clk_enable(pwm->clk);
-		if (!rc)
-			pwm->clk_enabled = 1;
-	}
-	return rc;
-}
-EXPORT_SYMBOL(pwm_enable);
-
-void pwm_disable(struct pwm_device *pwm)
-{
-	if (pwm->clk_enabled) {
-		clk_disable(pwm->clk);
-		pwm->clk_enabled = 0;
-	}
-}
-EXPORT_SYMBOL(pwm_disable);
-
-static DEFINE_MUTEX(pwm_lock);
-static LIST_HEAD(pwm_list);
-
-struct pwm_device *pwm_request(int pwm_id, const char *label)
-{
-	struct pwm_device *pwm;
-	int found = 0;
-
-	mutex_lock(&pwm_lock);
-
-	list_for_each_entry(pwm, &pwm_list, node) {
-		if (pwm->pwm_id == pwm_id) {
-			found = 1;
-			break;
-		}
-	}
-
-	if (found) {
-		if (pwm->use_count == 0) {
-			pwm->use_count++;
-			pwm->label = label;
-		} else
-			pwm = ERR_PTR(-EBUSY);
-	} else
-		pwm = ERR_PTR(-ENOENT);
-
-	mutex_unlock(&pwm_lock);
-	return pwm;
-}
-EXPORT_SYMBOL(pwm_request);
-
-void pwm_free(struct pwm_device *pwm)
-{
-	mutex_lock(&pwm_lock);
-
-	if (pwm->use_count) {
-		pwm->use_count--;
-		pwm->label = NULL;
-	} else
-		pr_warning("PWM device already freed\n");
-
-	mutex_unlock(&pwm_lock);
-}
-EXPORT_SYMBOL(pwm_free);
-
-static inline void __add_pwm(struct pwm_device *pwm)
-{
-	mutex_lock(&pwm_lock);
-	list_add_tail(&pwm->node, &pwm_list);
-	mutex_unlock(&pwm_lock);
-}
-
-static struct pwm_device *pwm_probe(struct platform_device *pdev,
-		unsigned int pwm_id, struct pwm_device *parent_pwm)
-{
-	struct pwm_device *pwm;
-	struct resource *r;
-	int ret = 0;
-
-	pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
-	if (pwm == NULL) {
-		dev_err(&pdev->dev, "failed to allocate memory\n");
-		return ERR_PTR(-ENOMEM);
-	}
-
-	pwm->clk = clk_get(NULL, "OST_CLK");
-	if (IS_ERR(pwm->clk)) {
-		ret = PTR_ERR(pwm->clk);
-		goto err_free;
-	}
-	pwm->clk_enabled = 0;
-
-	pwm->use_count = 0;
-	pwm->pwm_id = pwm_id;
-	pwm->pdev = pdev;
-
-	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (r == NULL) {
-		dev_err(&pdev->dev, "no memory resource defined\n");
-		ret = -ENODEV;
-		goto err_free_clk;
-	}
-
-	r = request_mem_region(r->start, resource_size(r), pdev->name);
-	if (r == NULL) {
-		dev_err(&pdev->dev, "failed to request memory resource\n");
-		ret = -EBUSY;
-		goto err_free_clk;
-	}
-
-	__add_pwm(pwm);
-	platform_set_drvdata(pdev, pwm);
-	return pwm;
-
-err_free_clk:
-	clk_put(pwm->clk);
-err_free:
-	kfree(pwm);
-	return ERR_PTR(ret);
-}
-
-static int __devinit puv3_pwm_probe(struct platform_device *pdev)
-{
-	struct pwm_device *pwm = pwm_probe(pdev, pdev->id, NULL);
-
-	if (IS_ERR(pwm))
-		return PTR_ERR(pwm);
-
-	return 0;
-}
-
-static int __devexit pwm_remove(struct platform_device *pdev)
-{
-	struct pwm_device *pwm;
-	struct resource *r;
-
-	pwm = platform_get_drvdata(pdev);
-	if (pwm == NULL)
-		return -ENODEV;
-
-	mutex_lock(&pwm_lock);
-	list_del(&pwm->node);
-	mutex_unlock(&pwm_lock);
-
-	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	release_mem_region(r->start, resource_size(r));
-
-	clk_put(pwm->clk);
-	kfree(pwm);
-	return 0;
-}
-
-static struct platform_driver puv3_pwm_driver = {
-	.driver		= {
-		.name	= "PKUnity-v3-PWM",
-	},
-	.probe		= puv3_pwm_probe,
-	.remove		= __devexit_p(pwm_remove),
-};
-
-static int __init pwm_init(void)
-{
-	int ret = 0;
-
-	ret = platform_driver_register(&puv3_pwm_driver);
-	if (ret) {
-		printk(KERN_ERR "failed to register puv3_pwm_driver\n");
-		return ret;
-	}
-
-	return ret;
-}
-arch_initcall(pwm_init);
-
-static void __exit pwm_exit(void)
-{
-	platform_driver_unregister(&puv3_pwm_driver);
-}
-module_exit(pwm_exit);
-
-MODULE_LICENSE("GPL v2");
diff --git a/arch/unicore32/kernel/signal.c b/arch/unicore32/kernel/signal.c
index 8adedb3..b8b2ffd 100644
--- a/arch/unicore32/kernel/signal.c
+++ b/arch/unicore32/kernel/signal.c
@@ -12,7 +12,6 @@
 #include <linux/errno.h>
 #include <linux/signal.h>
 #include <linux/personality.h>
-#include <linux/freezer.h>
 #include <linux/uaccess.h>
 #include <linux/tracehook.h>
 #include <linux/elf.h>
diff --git a/arch/unicore32/kernel/sys.c b/arch/unicore32/kernel/sys.c
index 3afe60a..5fd9af7 100644
--- a/arch/unicore32/kernel/sys.c
+++ b/arch/unicore32/kernel/sys.c
@@ -104,7 +104,6 @@
  out:
 	return ret;
 }
-EXPORT_SYMBOL(kernel_execve);
 
 /* Note: used by the compat code even in 64-bit Linux. */
 SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index b72777f..42d2c35 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -10,6 +10,7 @@
 	def_bool y
 	depends on !64BIT
 	select CLKSRC_I8253
+	select HAVE_UID16
 
 config X86_64
 	def_bool y
@@ -46,6 +47,7 @@
 	select HAVE_FUNCTION_GRAPH_FP_TEST
 	select HAVE_FUNCTION_TRACE_MCOUNT_TEST
 	select HAVE_SYSCALL_TRACEPOINTS
+	select SYSCTL_EXCEPTION_TRACE
 	select HAVE_KVM
 	select HAVE_ARCH_KGDB
 	select HAVE_ARCH_TRACEHOOK
@@ -65,6 +67,7 @@
 	select HAVE_PERF_EVENTS_NMI
 	select HAVE_PERF_REGS
 	select HAVE_PERF_USER_STACK_DUMP
+	select HAVE_DEBUG_KMEMLEAK
 	select ANON_INODES
 	select HAVE_ALIGNED_STRUCT_PAGE if SLUB && !M386
 	select HAVE_CMPXCHG_LOCAL if !M386
@@ -85,6 +88,7 @@
 	select IRQ_FORCED_THREADING
 	select USE_GENERIC_SMP_HELPERS if SMP
 	select HAVE_BPF_JIT if X86_64
+	select HAVE_ARCH_TRANSPARENT_HUGEPAGE
 	select CLKEVT_I8253
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select GENERIC_IOMAP
@@ -104,6 +108,7 @@
 	select GENERIC_STRNLEN_USER
 	select HAVE_RCU_USER_QS if X86_64
 	select HAVE_IRQ_TIME_ACCOUNTING
+	select GENERIC_KERNEL_THREAD
 
 config INSTRUCTION_DECODER
 	def_bool y
@@ -2168,6 +2173,7 @@
 	bool "IA32 Emulation"
 	depends on X86_64
 	select COMPAT_BINFMT_ELF
+	select HAVE_UID16
 	---help---
 	  Include code to run legacy 32-bit programs under a
 	  64-bit kernel. You should likely turn this on, unless you're
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 474ca35..58790bd 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -92,7 +92,7 @@
 ifdef CONFIG_X86_X32
 	x32_ld_ok := $(call try-run,\
 			/bin/echo -e '1: .quad 1b' | \
-			$(CC) $(KBUILD_AFLAGS) -c -xassembler -o "$$TMP" - && \
+			$(CC) $(KBUILD_AFLAGS) -c -x assembler -o "$$TMP" - && \
 			$(OBJCOPY) -O elf32-x86-64 "$$TMP" "$$TMPO" && \
 			$(LD) -m elf32_x86_64 "$$TMPO" -o "$$TMP",y,n)
         ifeq ($(x32_ld_ok),y)
@@ -142,7 +142,7 @@
 KBUILD_CFLAGS += $(mflags-y)
 KBUILD_AFLAGS += $(mflags-y)
 
-archscripts: scripts_basic
+archscripts:
 	$(Q)$(MAKE) $(build)=arch/x86/tools relocs
 
 ###
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
index 9c28950..076745f 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -465,7 +465,7 @@
 	PTREGSCALL stub32_rt_sigreturn, sys32_rt_sigreturn, %rdi
 	PTREGSCALL stub32_sigreturn, sys32_sigreturn, %rdi
 	PTREGSCALL stub32_sigaltstack, sys32_sigaltstack, %rdx
-	PTREGSCALL stub32_execve, sys32_execve, %rcx
+	PTREGSCALL stub32_execve, compat_sys_execve, %rcx
 	PTREGSCALL stub32_fork, sys_fork, %rdi
 	PTREGSCALL stub32_clone, sys32_clone, %rdx
 	PTREGSCALL stub32_vfork, sys_vfork, %rdi
diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c
index c5b938d..86d68d1 100644
--- a/arch/x86/ia32/sys_ia32.c
+++ b/arch/x86/ia32/sys_ia32.c
@@ -385,21 +385,6 @@
 	return ret;
 }
 
-asmlinkage long sys32_execve(const char __user *name, compat_uptr_t __user *argv,
-			     compat_uptr_t __user *envp, struct pt_regs *regs)
-{
-	long error;
-	char *filename;
-
-	filename = getname(name);
-	error = PTR_ERR(filename);
-	if (IS_ERR(filename))
-		return error;
-	error = compat_do_execve(filename, argv, envp, regs);
-	putname(filename);
-	return error;
-}
-
 asmlinkage long sys32_clone(unsigned int clone_flags, unsigned int newsp,
 			    struct pt_regs *regs)
 {
diff --git a/arch/x86/include/asm/Kbuild b/arch/x86/include/asm/Kbuild
index 1595d68..66e5f0e 100644
--- a/arch/x86/include/asm/Kbuild
+++ b/arch/x86/include/asm/Kbuild
@@ -22,3 +22,9 @@
 header-y += ucontext.h
 header-y += vm86.h
 header-y += vsyscall.h
+
+genhdr-y += unistd_32.h
+genhdr-y += unistd_64.h
+genhdr-y += unistd_x32.h
+
+generic-y += clkdev.h
diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h
index 250b877..b6c3b82 100644
--- a/arch/x86/include/asm/atomic.h
+++ b/arch/x86/include/asm/atomic.h
@@ -240,30 +240,6 @@
 	return c;
 }
 
-
-/*
- * atomic_dec_if_positive - decrement by 1 if old value positive
- * @v: pointer of type atomic_t
- *
- * The function returns the old value of *v minus 1, even if
- * the atomic variable, v, was not decremented.
- */
-static inline int atomic_dec_if_positive(atomic_t *v)
-{
-	int c, old, dec;
-	c = atomic_read(v);
-	for (;;) {
-		dec = c - 1;
-		if (unlikely(dec < 0))
-			break;
-		old = atomic_cmpxchg((v), c, dec);
-		if (likely(old == c))
-			break;
-		c = old;
-	}
-	return dec;
-}
-
 /**
  * atomic_inc_short - increment of a short integer
  * @v: pointer to type int
diff --git a/arch/x86/include/asm/hugetlb.h b/arch/x86/include/asm/hugetlb.h
index 439a9ac..bdd35db 100644
--- a/arch/x86/include/asm/hugetlb.h
+++ b/arch/x86/include/asm/hugetlb.h
@@ -90,4 +90,8 @@
 {
 }
 
+static inline void arch_clear_hugepage_flags(struct page *page)
+{
+}
+
 #endif /* _ASM_X86_HUGETLB_H */
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index fc99484..a1f780d 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -146,8 +146,7 @@
 
 static inline int pmd_large(pmd_t pte)
 {
-	return (pmd_flags(pte) & (_PAGE_PSE | _PAGE_PRESENT)) ==
-		(_PAGE_PSE | _PAGE_PRESENT);
+	return pmd_flags(pte) & _PAGE_PSE;
 }
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
@@ -415,7 +414,13 @@
 
 static inline int pmd_present(pmd_t pmd)
 {
-	return pmd_flags(pmd) & _PAGE_PRESENT;
+	/*
+	 * Checking for _PAGE_PSE is needed too because
+	 * split_huge_page will temporarily clear the present bit (but
+	 * the _PAGE_PSE flag will remain set at all times while the
+	 * _PAGE_PRESENT bit is clear).
+	 */
+	return pmd_flags(pmd) & (_PAGE_PRESENT | _PAGE_PROTNONE | _PAGE_PSE);
 }
 
 static inline int pmd_none(pmd_t pmd)
diff --git a/arch/x86/include/asm/pgtable_32.h b/arch/x86/include/asm/pgtable_32.h
index 0c92113..8faa215 100644
--- a/arch/x86/include/asm/pgtable_32.h
+++ b/arch/x86/include/asm/pgtable_32.h
@@ -71,6 +71,7 @@
  * tables contain all the necessary information.
  */
 #define update_mmu_cache(vma, address, ptep) do { } while (0)
+#define update_mmu_cache_pmd(vma, address, pmd) do { } while (0)
 
 #endif /* !__ASSEMBLY__ */
 
diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h
index 8251be0..47356f9 100644
--- a/arch/x86/include/asm/pgtable_64.h
+++ b/arch/x86/include/asm/pgtable_64.h
@@ -143,6 +143,7 @@
 #define pte_unmap(pte) ((void)(pte))/* NOP */
 
 #define update_mmu_cache(vma, address, ptep) do { } while (0)
+#define update_mmu_cache_pmd(vma, address, pmd) do { } while (0)
 
 /* Encode and de-code a swap entry */
 #if _PAGE_BIT_FILE < _PAGE_BIT_PROTNONE
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index b98c0d9..ad1fc85 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -588,11 +588,6 @@
 } mm_segment_t;
 
 
-/*
- * create a kernel thread without removing it from tasklists
- */
-extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
 /* Free all resources held by a thread. */
 extern void release_thread(struct task_struct *);
 
diff --git a/arch/x86/include/asm/sys_ia32.h b/arch/x86/include/asm/sys_ia32.h
index 4ca1c61..a9a8cf3 100644
--- a/arch/x86/include/asm/sys_ia32.h
+++ b/arch/x86/include/asm/sys_ia32.h
@@ -54,8 +54,6 @@
 asmlinkage long sys32_personality(unsigned long);
 asmlinkage long sys32_sendfile(int, int, compat_off_t __user *, s32);
 
-asmlinkage long sys32_execve(const char __user *, compat_uptr_t __user *,
-			     compat_uptr_t __user *, struct pt_regs *);
 asmlinkage long sys32_clone(unsigned int, unsigned int, struct pt_regs *);
 
 long sys32_lseek(unsigned int, int, unsigned int);
diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h
index f1d8b44..2be0b88 100644
--- a/arch/x86/include/asm/syscalls.h
+++ b/arch/x86/include/asm/syscalls.h
@@ -25,7 +25,7 @@
 int sys_vfork(struct pt_regs *);
 long sys_execve(const char __user *,
 		const char __user *const __user *,
-		const char __user *const __user *, struct pt_regs *);
+		const char __user *const __user *);
 long sys_clone(unsigned long, unsigned long, void __user *,
 	       void __user *, struct pt_regs *);
 
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index c535d847..2d946e6 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -79,7 +79,6 @@
 #define TIF_SIGPENDING		2	/* signal pending */
 #define TIF_NEED_RESCHED	3	/* rescheduling necessary */
 #define TIF_SINGLESTEP		4	/* reenable singlestep on user return*/
-#define TIF_IRET		5	/* force IRET */
 #define TIF_SYSCALL_EMU		6	/* syscall emulation active */
 #define TIF_SYSCALL_AUDIT	7	/* syscall auditing active */
 #define TIF_SECCOMP		8	/* secure computing */
@@ -105,7 +104,6 @@
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
 #define _TIF_SINGLESTEP		(1 << TIF_SINGLESTEP)
 #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
-#define _TIF_IRET		(1 << TIF_IRET)
 #define _TIF_SYSCALL_EMU	(1 << TIF_SYSCALL_EMU)
 #define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP		(1 << TIF_SECCOMP)
diff --git a/arch/x86/include/asm/unistd.h b/arch/x86/include/asm/unistd.h
index 0d9776e..55d1555 100644
--- a/arch/x86/include/asm/unistd.h
+++ b/arch/x86/include/asm/unistd.h
@@ -50,6 +50,8 @@
 # define __ARCH_WANT_SYS_TIME
 # define __ARCH_WANT_SYS_UTIME
 # define __ARCH_WANT_SYS_WAITPID
+# define __ARCH_WANT_SYS_EXECVE
+# define __ARCH_WANT_KERNEL_EXECVE
 
 /*
  * "Conditional" syscalls
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index a48ea05..91ce48f 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -23,7 +23,7 @@
 obj-y			+= setup.o x86_init.o i8259.o irqinit.o jump_label.o
 obj-$(CONFIG_IRQ_WORK)  += irq_work.o
 obj-y			+= probe_roms.o
-obj-$(CONFIG_X86_32)	+= sys_i386_32.o i386_ksyms_32.o
+obj-$(CONFIG_X86_32)	+= i386_ksyms_32.o
 obj-$(CONFIG_X86_64)	+= sys_x86_64.o x8664_ksyms_64.o
 obj-y			+= syscall_$(BITS).o
 obj-$(CONFIG_X86_64)	+= vsyscall_64.o
diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c
index 68de2dc..2861082 100644
--- a/arch/x86/kernel/asm-offsets.c
+++ b/arch/x86/kernel/asm-offsets.c
@@ -69,4 +69,7 @@
 	OFFSET(BP_kernel_alignment, boot_params, hdr.kernel_alignment);
 	OFFSET(BP_pref_address, boot_params, hdr.pref_address);
 	OFFSET(BP_code32_start, boot_params, hdr.code32_start);
+
+	BLANK();
+	DEFINE(PTREGS_SIZE, sizeof(struct pt_regs));
 }
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 0750e3b..2c63407 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -299,6 +299,13 @@
 	CFI_ENDPROC
 END(ret_from_fork)
 
+ENTRY(ret_from_kernel_execve)
+	movl %eax, %esp
+	movl $0,PT_EAX(%esp)
+	GET_THREAD_INFO(%ebp)
+	jmp syscall_exit
+END(ret_from_kernel_execve)
+
 /*
  * Interrupt exit functions should be protected against kprobes
  */
@@ -323,8 +330,7 @@
 	andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax
 #else
 	/*
-	 * We can be coming here from a syscall done in the kernel space,
-	 * e.g. a failed kernel_execve().
+	 * We can be coming here from child spawned by kernel_thread().
 	 */
 	movl PT_CS(%esp), %eax
 	andl $SEGMENT_RPL_MASK, %eax
@@ -616,22 +622,7 @@
 	movl %esp, %eax
 	jne work_notifysig_v86		# returning to kernel-space or
 					# vm86-space
-	TRACE_IRQS_ON
-	ENABLE_INTERRUPTS(CLBR_NONE)
-	movb PT_CS(%esp), %bl
-	andb $SEGMENT_RPL_MASK, %bl
-	cmpb $USER_RPL, %bl
-	jb resume_kernel
-	xorl %edx, %edx
-	call do_notify_resume
-	jmp resume_userspace
-
-	ALIGN
-work_notifysig_v86:
-	pushl_cfi %ecx			# save ti_flags for do_notify_resume
-	call save_v86_state		# %eax contains pt_regs pointer
-	popl_cfi %ecx
-	movl %eax, %esp
+1:
 #else
 	movl %esp, %eax
 #endif
@@ -644,6 +635,16 @@
 	xorl %edx, %edx
 	call do_notify_resume
 	jmp resume_userspace
+
+#ifdef CONFIG_VM86
+	ALIGN
+work_notifysig_v86:
+	pushl_cfi %ecx			# save ti_flags for do_notify_resume
+	call save_v86_state		# %eax contains pt_regs pointer
+	popl_cfi %ecx
+	movl %eax, %esp
+	jmp 1b
+#endif
 END(work_pending)
 
 	# perform syscall exit tracing
@@ -732,7 +733,6 @@
 PTREGSCALL1(iopl)
 PTREGSCALL0(fork)
 PTREGSCALL0(vfork)
-PTREGSCALL3(execve)
 PTREGSCALL2(sigaltstack)
 PTREGSCALL0(sigreturn)
 PTREGSCALL0(rt_sigreturn)
@@ -1015,15 +1015,20 @@
  */
 	.popsection
 
-ENTRY(kernel_thread_helper)
-	pushl $0		# fake return address for unwinder
+ENTRY(ret_from_kernel_thread)
 	CFI_STARTPROC
-	movl %edi,%eax
-	call *%esi
+	pushl_cfi %eax
+	call schedule_tail
+	GET_THREAD_INFO(%ebp)
+	popl_cfi %eax
+	pushl_cfi $0x0202		# Reset kernel eflags
+	popfl_cfi
+	movl PT_EBP(%esp),%eax
+	call *PT_EBX(%esp)
 	call do_exit
 	ud2			# padding for call trace
 	CFI_ENDPROC
-ENDPROC(kernel_thread_helper)
+ENDPROC(ret_from_kernel_thread)
 
 #ifdef CONFIG_XEN
 /* Xen doesn't set %esp to be precisely what the normal sysenter
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 44531ac..cdc790c 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -554,7 +554,7 @@
 	RESTORE_REST
 
 	testl $3, CS-ARGOFFSET(%rsp)		# from kernel_thread?
-	jz   retint_restore_args
+	jz   1f
 
 	testl $_TIF_IA32, TI_flags(%rcx)	# 32-bit compat task needs IRET
 	jnz  int_ret_from_sys_call
@@ -562,6 +562,16 @@
 	RESTORE_TOP_OF_STACK %rdi, -ARGOFFSET
 	jmp ret_from_sys_call			# go to the SYSRET fastpath
 
+1:
+	subq $REST_SKIP, %rsp	# move the stack pointer back
+	CFI_ADJUST_CFA_OFFSET	REST_SKIP
+	movq %rbp, %rdi
+	call *%rbx
+	# exit
+	mov %eax, %edi
+	call do_exit
+	ud2			# padding for call trace
+
 	CFI_ENDPROC
 END(ret_from_fork)
 
@@ -862,7 +872,6 @@
 	PARTIAL_FRAME 0
 	SAVE_REST
 	FIXUP_TOP_OF_STACK %r11
-	movq %rsp, %rcx
 	call sys_execve
 	RESTORE_TOP_OF_STACK %r11
 	movq %rax,RAX(%rsp)
@@ -912,8 +921,7 @@
 	PARTIAL_FRAME 0
 	SAVE_REST
 	FIXUP_TOP_OF_STACK %r11
-	movq %rsp, %rcx
-	call sys32_execve
+	call compat_sys_execve
 	RESTORE_TOP_OF_STACK %r11
 	movq %rax,RAX(%rsp)
 	RESTORE_REST
@@ -1318,51 +1326,19 @@
 	jmp  2b
 	.previous
 
-ENTRY(kernel_thread_helper)
-	pushq $0		# fake return address
-	CFI_STARTPROC
-	/*
-	 * Here we are in the child and the registers are set as they were
-	 * at kernel_thread() invocation in the parent.
-	 */
-	call *%rsi
-	# exit
-	mov %eax, %edi
-	call do_exit
-	ud2			# padding for call trace
-	CFI_ENDPROC
-END(kernel_thread_helper)
-
-/*
- * execve(). This function needs to use IRET, not SYSRET, to set up all state properly.
- *
- * C extern interface:
- *	 extern long execve(const char *name, char **argv, char **envp)
- *
- * asm input arguments:
- *	rdi: name, rsi: argv, rdx: envp
- *
- * We want to fallback into:
- *	extern long sys_execve(const char *name, char **argv,char **envp, struct pt_regs *regs)
- *
- * do_sys_execve asm fallback arguments:
- *	rdi: name, rsi: argv, rdx: envp, rcx: fake frame on the stack
- */
-ENTRY(kernel_execve)
-	CFI_STARTPROC
-	FAKE_STACK_FRAME $0
-	SAVE_ALL
-	movq %rsp,%rcx
-	call sys_execve
-	movq %rax, RAX(%rsp)
-	RESTORE_REST
-	testq %rax,%rax
-	je int_ret_from_sys_call
-	RESTORE_ARGS
-	UNFAKE_STACK_FRAME
-	ret
-	CFI_ENDPROC
-END(kernel_execve)
+ENTRY(ret_from_kernel_execve)
+	movq %rdi, %rsp
+	movl $0, RAX(%rsp)
+	// RESTORE_REST
+	movq 0*8(%rsp), %r15
+	movq 1*8(%rsp), %r14
+	movq 2*8(%rsp), %r13
+	movq 3*8(%rsp), %r12
+	movq 4*8(%rsp), %rbp
+	movq 5*8(%rsp), %rbx
+	addq $(6*8), %rsp
+	jmp int_ret_from_sys_call
+END(ret_from_kernel_execve)
 
 /* Call softirq on interrupt stack. Interrupts are off. */
 ENTRY(call_softirq)
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index dc3567e..b644e1c 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -293,71 +293,6 @@
 }
 
 /*
- * This gets run with %si containing the
- * function to call, and %di containing
- * the "args".
- */
-extern void kernel_thread_helper(void);
-
-/*
- * Create a kernel thread
- */
-int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
-{
-	struct pt_regs regs;
-
-	memset(&regs, 0, sizeof(regs));
-
-	regs.si = (unsigned long) fn;
-	regs.di = (unsigned long) arg;
-
-#ifdef CONFIG_X86_32
-	regs.ds = __USER_DS;
-	regs.es = __USER_DS;
-	regs.fs = __KERNEL_PERCPU;
-	regs.gs = __KERNEL_STACK_CANARY;
-#else
-	regs.ss = __KERNEL_DS;
-#endif
-
-	regs.orig_ax = -1;
-	regs.ip = (unsigned long) kernel_thread_helper;
-	regs.cs = __KERNEL_CS | get_kernel_rpl();
-	regs.flags = X86_EFLAGS_IF | X86_EFLAGS_BIT1;
-
-	/* Ok, create the new process.. */
-	return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
-}
-EXPORT_SYMBOL(kernel_thread);
-
-/*
- * sys_execve() executes a new program.
- */
-long sys_execve(const char __user *name,
-		const char __user *const __user *argv,
-		const char __user *const __user *envp, struct pt_regs *regs)
-{
-	long error;
-	char *filename;
-
-	filename = getname(name);
-	error = PTR_ERR(filename);
-	if (IS_ERR(filename))
-		return error;
-	error = do_execve(filename, argv, envp, regs);
-
-#ifdef CONFIG_X86_32
-	if (error == 0) {
-		/* Make sure we don't return using sysenter.. */
-                set_thread_flag(TIF_IRET);
-        }
-#endif
-
-	putname(filename);
-	return error;
-}
-
-/*
  * Idle related variables and functions
  */
 unsigned long boot_option_idle_override = IDLE_NO_OVERRIDE;
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index b9ff83c..44e0bff 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -57,6 +57,7 @@
 #include <asm/switch_to.h>
 
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
+asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread");
 
 /*
  * Return saved PC of a blocked thread.
@@ -127,23 +128,39 @@
 }
 
 int copy_thread(unsigned long clone_flags, unsigned long sp,
-	unsigned long unused,
+	unsigned long arg,
 	struct task_struct *p, struct pt_regs *regs)
 {
-	struct pt_regs *childregs;
+	struct pt_regs *childregs = task_pt_regs(p);
 	struct task_struct *tsk;
 	int err;
 
-	childregs = task_pt_regs(p);
-	*childregs = *regs;
-	childregs->ax = 0;
-	childregs->sp = sp;
-
 	p->thread.sp = (unsigned long) childregs;
 	p->thread.sp0 = (unsigned long) (childregs+1);
 
-	p->thread.ip = (unsigned long) ret_from_fork;
+	if (unlikely(!regs)) {
+		/* kernel thread */
+		memset(childregs, 0, sizeof(struct pt_regs));
+		p->thread.ip = (unsigned long) ret_from_kernel_thread;
+		task_user_gs(p) = __KERNEL_STACK_CANARY;
+		childregs->ds = __USER_DS;
+		childregs->es = __USER_DS;
+		childregs->fs = __KERNEL_PERCPU;
+		childregs->bx = sp;	/* function */
+		childregs->bp = arg;
+		childregs->orig_ax = -1;
+		childregs->cs = __KERNEL_CS | get_kernel_rpl();
+		childregs->flags = X86_EFLAGS_IF | X86_EFLAGS_BIT1;
+		p->fpu_counter = 0;
+		p->thread.io_bitmap_ptr = NULL;
+		memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
+		return 0;
+	}
+	*childregs = *regs;
+	childregs->ax = 0;
+	childregs->sp = sp;
 
+	p->thread.ip = (unsigned long) ret_from_fork;
 	task_user_gs(p) = get_user_gs(regs);
 
 	p->fpu_counter = 0;
@@ -190,6 +207,12 @@
 	regs->cs		= __USER_CS;
 	regs->ip		= new_ip;
 	regs->sp		= new_sp;
+	regs->flags		= X86_EFLAGS_IF;
+	/*
+	 * force it to the iret return path by making it look as if there was
+	 * some work pending.
+	 */
+	set_thread_flag(TIF_NOTIFY_RESUME);
 }
 EXPORT_SYMBOL_GPL(start_thread);
 
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 8a6d20c..16c6365 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -146,29 +146,18 @@
 }
 
 int copy_thread(unsigned long clone_flags, unsigned long sp,
-		unsigned long unused,
+		unsigned long arg,
 	struct task_struct *p, struct pt_regs *regs)
 {
 	int err;
 	struct pt_regs *childregs;
 	struct task_struct *me = current;
 
-	childregs = ((struct pt_regs *)
-			(THREAD_SIZE + task_stack_page(p))) - 1;
-	*childregs = *regs;
-
-	childregs->ax = 0;
-	if (user_mode(regs))
-		childregs->sp = sp;
-	else
-		childregs->sp = (unsigned long)childregs;
-
+	p->thread.sp0 = (unsigned long)task_stack_page(p) + THREAD_SIZE;
+	childregs = task_pt_regs(p);
 	p->thread.sp = (unsigned long) childregs;
-	p->thread.sp0 = (unsigned long) (childregs+1);
 	p->thread.usersp = me->thread.usersp;
-
 	set_tsk_thread_flag(p, TIF_FORK);
-
 	p->fpu_counter = 0;
 	p->thread.io_bitmap_ptr = NULL;
 
@@ -178,6 +167,24 @@
 	p->thread.fs = p->thread.fsindex ? 0 : me->thread.fs;
 	savesegment(es, p->thread.es);
 	savesegment(ds, p->thread.ds);
+	memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
+
+	if (unlikely(!regs)) {
+		/* kernel thread */
+		memset(childregs, 0, sizeof(struct pt_regs));
+		childregs->sp = (unsigned long)childregs;
+		childregs->ss = __KERNEL_DS;
+		childregs->bx = sp; /* function */
+		childregs->bp = arg;
+		childregs->orig_ax = -1;
+		childregs->cs = __KERNEL_CS | get_kernel_rpl();
+		childregs->flags = X86_EFLAGS_IF | X86_EFLAGS_BIT1;
+		return 0;
+	}
+	*childregs = *regs;
+
+	childregs->ax = 0;
+	childregs->sp = sp;
 
 	err = -ENOMEM;
 	memset(p->thread.ptrace_bps, 0, sizeof(p->thread.ptrace_bps));
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index b33144c..29ad351 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -840,10 +840,6 @@
 	if (thread_info_flags & _TIF_USER_RETURN_NOTIFY)
 		fire_user_return_notifiers();
 
-#ifdef CONFIG_X86_32
-	clear_thread_flag(TIF_IRET);
-#endif /* CONFIG_X86_32 */
-
 	rcu_user_enter();
 }
 
diff --git a/arch/x86/kernel/sys_i386_32.c b/arch/x86/kernel/sys_i386_32.c
deleted file mode 100644
index 0b0cb5f..0000000
--- a/arch/x86/kernel/sys_i386_32.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * This file contains various random system calls that
- * have a non-standard calling sequence on the Linux/i386
- * platform.
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/fs.h>
-#include <linux/smp.h>
-#include <linux/sem.h>
-#include <linux/msg.h>
-#include <linux/shm.h>
-#include <linux/stat.h>
-#include <linux/syscalls.h>
-#include <linux/mman.h>
-#include <linux/file.h>
-#include <linux/utsname.h>
-#include <linux/ipc.h>
-
-#include <linux/uaccess.h>
-#include <linux/unistd.h>
-
-#include <asm/syscalls.h>
-
-/*
- * Do a system call from kernel instead of calling sys_execve so we
- * end up with proper pt_regs.
- */
-int kernel_execve(const char *filename,
-		  const char *const argv[],
-		  const char *const envp[])
-{
-	long __res;
-	asm volatile ("int $0x80"
-	: "=a" (__res)
-	: "0" (__NR_execve), "b" (filename), "c" (argv), "d" (envp) : "memory");
-	return __res;
-}
diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
index 54abcc0..5c9687b 100644
--- a/arch/x86/kernel/vm86_32.c
+++ b/arch/x86/kernel/vm86_32.c
@@ -561,9 +561,9 @@
 		if ((trapno == 3) || (trapno == 1)) {
 			KVM86->regs32->ax = VM86_TRAP + (trapno << 8);
 			/* setting this flag forces the code in entry_32.S to
-			   call save_v86_state() and change the stack pointer
-			   to KVM86->regs32 */
-			set_thread_flag(TIF_IRET);
+			   the path where we call save_v86_state() and change
+			   the stack pointer to KVM86->regs32 */
+			set_thread_flag(TIF_NOTIFY_RESUME);
 			return 0;
 		}
 		do_int(regs, trapno, (unsigned char __user *) (regs->pt.ss << 4), SP(regs));
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index a530b23..8e13ecb 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -1220,6 +1220,7 @@
 			/* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
 			 * of starvation. */
 			flags &= ~FAULT_FLAG_ALLOW_RETRY;
+			flags |= FAULT_FLAG_TRIED;
 			goto retry;
 		}
 	}
diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c
index b91e485..937bff5 100644
--- a/arch/x86/mm/hugetlbpage.c
+++ b/arch/x86/mm/hugetlbpage.c
@@ -71,7 +71,6 @@
 	struct address_space *mapping = vma->vm_file->f_mapping;
 	pgoff_t idx = ((addr - vma->vm_start) >> PAGE_SHIFT) +
 			vma->vm_pgoff;
-	struct prio_tree_iter iter;
 	struct vm_area_struct *svma;
 	unsigned long saddr;
 	pte_t *spte = NULL;
@@ -81,7 +80,7 @@
 		return (pte_t *)pmd_alloc(mm, pud, addr);
 
 	mutex_lock(&mapping->i_mmap_mutex);
-	vma_prio_tree_foreach(svma, &iter, &mapping->i_mmap, idx, idx) {
+	vma_interval_tree_foreach(svma, &mapping->i_mmap, idx, idx) {
 		if (svma == vma)
 			continue;
 
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index 3d68ef6..0eb572e 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -664,20 +664,20 @@
 }
 
 /*
- * track_pfn_vma_copy is called when vma that is covering the pfnmap gets
+ * track_pfn_copy is called when vma that is covering the pfnmap gets
  * copied through copy_page_range().
  *
  * If the vma has a linear pfn mapping for the entire range, we get the prot
  * from pte and reserve the entire vma range with single reserve_pfn_range call.
  */
-int track_pfn_vma_copy(struct vm_area_struct *vma)
+int track_pfn_copy(struct vm_area_struct *vma)
 {
 	resource_size_t paddr;
 	unsigned long prot;
 	unsigned long vma_size = vma->vm_end - vma->vm_start;
 	pgprot_t pgprot;
 
-	if (is_linear_pfn_mapping(vma)) {
+	if (vma->vm_flags & VM_PAT) {
 		/*
 		 * reserve the whole chunk covered by vma. We need the
 		 * starting address and protection from pte.
@@ -694,31 +694,59 @@
 }
 
 /*
- * track_pfn_vma_new is called when a _new_ pfn mapping is being established
- * for physical range indicated by pfn and size.
- *
  * prot is passed in as a parameter for the new mapping. If the vma has a
  * linear pfn mapping for the entire range reserve the entire vma range with
  * single reserve_pfn_range call.
  */
-int track_pfn_vma_new(struct vm_area_struct *vma, pgprot_t *prot,
-			unsigned long pfn, unsigned long size)
+int track_pfn_remap(struct vm_area_struct *vma, pgprot_t *prot,
+		    unsigned long pfn, unsigned long addr, unsigned long size)
 {
+	resource_size_t paddr = (resource_size_t)pfn << PAGE_SHIFT;
 	unsigned long flags;
-	resource_size_t paddr;
-	unsigned long vma_size = vma->vm_end - vma->vm_start;
 
-	if (is_linear_pfn_mapping(vma)) {
-		/* reserve the whole chunk starting from vm_pgoff */
-		paddr = (resource_size_t)vma->vm_pgoff << PAGE_SHIFT;
-		return reserve_pfn_range(paddr, vma_size, prot, 0);
+	/* reserve the whole chunk starting from paddr */
+	if (addr == vma->vm_start && size == (vma->vm_end - vma->vm_start)) {
+		int ret;
+
+		ret = reserve_pfn_range(paddr, size, prot, 0);
+		if (!ret)
+			vma->vm_flags |= VM_PAT;
+		return ret;
 	}
 
 	if (!pat_enabled)
 		return 0;
 
-	/* for vm_insert_pfn and friends, we set prot based on lookup */
-	flags = lookup_memtype(pfn << PAGE_SHIFT);
+	/*
+	 * For anything smaller than the vma size we set prot based on the
+	 * lookup.
+	 */
+	flags = lookup_memtype(paddr);
+
+	/* Check memtype for the remaining pages */
+	while (size > PAGE_SIZE) {
+		size -= PAGE_SIZE;
+		paddr += PAGE_SIZE;
+		if (flags != lookup_memtype(paddr))
+			return -EINVAL;
+	}
+
+	*prot = __pgprot((pgprot_val(vma->vm_page_prot) & (~_PAGE_CACHE_MASK)) |
+			 flags);
+
+	return 0;
+}
+
+int track_pfn_insert(struct vm_area_struct *vma, pgprot_t *prot,
+		     unsigned long pfn)
+{
+	unsigned long flags;
+
+	if (!pat_enabled)
+		return 0;
+
+	/* Set prot based on lookup */
+	flags = lookup_memtype((resource_size_t)pfn << PAGE_SHIFT);
 	*prot = __pgprot((pgprot_val(vma->vm_page_prot) & (~_PAGE_CACHE_MASK)) |
 			 flags);
 
@@ -726,22 +754,31 @@
 }
 
 /*
- * untrack_pfn_vma is called while unmapping a pfnmap for a region.
+ * untrack_pfn is called while unmapping a pfnmap for a region.
  * untrack can be called for a specific region indicated by pfn and size or
- * can be for the entire vma (in which case size can be zero).
+ * can be for the entire vma (in which case pfn, size are zero).
  */
-void untrack_pfn_vma(struct vm_area_struct *vma, unsigned long pfn,
-			unsigned long size)
+void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn,
+		 unsigned long size)
 {
 	resource_size_t paddr;
-	unsigned long vma_size = vma->vm_end - vma->vm_start;
+	unsigned long prot;
 
-	if (is_linear_pfn_mapping(vma)) {
-		/* free the whole chunk starting from vm_pgoff */
-		paddr = (resource_size_t)vma->vm_pgoff << PAGE_SHIFT;
-		free_pfn_range(paddr, vma_size);
+	if (!(vma->vm_flags & VM_PAT))
 		return;
+
+	/* free the chunk starting from pfn or the whole chunk */
+	paddr = (resource_size_t)pfn << PAGE_SHIFT;
+	if (!paddr && !size) {
+		if (follow_phys(vma, vma->vm_start, 0, &prot, &paddr)) {
+			WARN_ON_ONCE(1);
+			return;
+		}
+
+		size = vma->vm_end - vma->vm_start;
 	}
+	free_pfn_range(paddr, size);
+	vma->vm_flags &= ~VM_PAT;
 }
 
 pgprot_t pgprot_writecombine(pgprot_t prot)
diff --git a/arch/x86/mm/pat_rbtree.c b/arch/x86/mm/pat_rbtree.c
index 8acaddd..415f6c4 100644
--- a/arch/x86/mm/pat_rbtree.c
+++ b/arch/x86/mm/pat_rbtree.c
@@ -12,7 +12,7 @@
 #include <linux/debugfs.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/rbtree.h>
+#include <linux/rbtree_augmented.h>
 #include <linux/sched.h>
 #include <linux/gfp.h>
 
@@ -54,29 +54,24 @@
 	return ret;
 }
 
-/* Update 'subtree_max_end' for a node, based on node and its children */
-static void memtype_rb_augment_cb(struct rb_node *node, void *__unused)
+static u64 compute_subtree_max_end(struct memtype *data)
 {
-	struct memtype *data;
-	u64 max_end, child_max_end;
+	u64 max_end = data->end, child_max_end;
 
-	if (!node)
-		return;
-
-	data = container_of(node, struct memtype, rb);
-	max_end = data->end;
-
-	child_max_end = get_subtree_max_end(node->rb_right);
+	child_max_end = get_subtree_max_end(data->rb.rb_right);
 	if (child_max_end > max_end)
 		max_end = child_max_end;
 
-	child_max_end = get_subtree_max_end(node->rb_left);
+	child_max_end = get_subtree_max_end(data->rb.rb_left);
 	if (child_max_end > max_end)
 		max_end = child_max_end;
 
-	data->subtree_max_end = max_end;
+	return max_end;
 }
 
+RB_DECLARE_CALLBACKS(static, memtype_rb_augment_cb, struct memtype, rb,
+		     u64, subtree_max_end, compute_subtree_max_end)
+
 /* Find the first (lowest start addr) overlapping range from rb tree */
 static struct memtype *memtype_rb_lowest_match(struct rb_root *root,
 				u64 start, u64 end)
@@ -179,15 +174,17 @@
 		struct memtype *data = container_of(*node, struct memtype, rb);
 
 		parent = *node;
+		if (data->subtree_max_end < newdata->end)
+			data->subtree_max_end = newdata->end;
 		if (newdata->start <= data->start)
 			node = &((*node)->rb_left);
 		else if (newdata->start > data->start)
 			node = &((*node)->rb_right);
 	}
 
+	newdata->subtree_max_end = newdata->end;
 	rb_link_node(&newdata->rb, parent, node);
-	rb_insert_color(&newdata->rb, root);
-	rb_augment_insert(&newdata->rb, memtype_rb_augment_cb, NULL);
+	rb_insert_augmented(&newdata->rb, root, &memtype_rb_augment_cb);
 }
 
 int rbt_memtype_check_insert(struct memtype *new, unsigned long *ret_type)
@@ -209,16 +206,13 @@
 
 struct memtype *rbt_memtype_erase(u64 start, u64 end)
 {
-	struct rb_node *deepest;
 	struct memtype *data;
 
 	data = memtype_rb_exact_match(&memtype_rbroot, start, end);
 	if (!data)
 		goto out;
 
-	deepest = rb_augment_erase_begin(&data->rb);
-	rb_erase(&data->rb, &memtype_rbroot);
-	rb_augment_erase_end(deepest, memtype_rb_augment_cb, NULL);
+	rb_erase_augmented(&data->rb, &memtype_rbroot, &memtype_rb_augment_cb);
 out:
 	return data;
 }
diff --git a/arch/x86/syscalls/syscall_32.tbl b/arch/x86/syscalls/syscall_32.tbl
index 7a35a6e..a47103f 100644
--- a/arch/x86/syscalls/syscall_32.tbl
+++ b/arch/x86/syscalls/syscall_32.tbl
@@ -17,7 +17,7 @@
 8	i386	creat			sys_creat
 9	i386	link			sys_link
 10	i386	unlink			sys_unlink
-11	i386	execve			ptregs_execve			stub32_execve
+11	i386	execve			sys_execve			stub32_execve
 12	i386	chdir			sys_chdir
 13	i386	time			sys_time			compat_sys_time
 14	i386	mknod			sys_mknod
diff --git a/arch/x86/um/Kconfig b/arch/x86/um/Kconfig
index aeaff8b..30c4eec 100644
--- a/arch/x86/um/Kconfig
+++ b/arch/x86/um/Kconfig
@@ -13,6 +13,7 @@
 config UML_X86
 	def_bool y
 	select GENERIC_FIND_FIRST_BIT
+	select GENERIC_KERNEL_THREAD
 
 config 64BIT
 	bool "64-bit kernel" if SUBARCH = "x86"
diff --git a/arch/x86/um/asm/checksum.h b/arch/x86/um/asm/checksum.h
index b6efe23..4b181b7 100644
--- a/arch/x86/um/asm/checksum.h
+++ b/arch/x86/um/asm/checksum.h
@@ -1,6 +1,150 @@
 #ifndef __UM_CHECKSUM_H
 #define __UM_CHECKSUM_H
 
+#include <linux/string.h>
+#include <linux/in6.h>
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+extern __wsum csum_partial(const void *buff, int len, __wsum sum);
+
+/*
+ *	Note: when you get a NULL pointer exception here this means someone
+ *	passed in an incorrect kernel address to one of these functions.
+ *
+ *	If you use these functions directly please don't forget the
+ *	access_ok().
+ */
+
+static __inline__
+__wsum csum_partial_copy_nocheck(const void *src, void *dst,
+				       int len, __wsum sum)
+{
+	memcpy(dst, src, len);
+	return csum_partial(dst, len, sum);
+}
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums, and handles user-space pointer exceptions correctly, when needed.
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+
+static __inline__
+__wsum csum_partial_copy_from_user(const void __user *src, void *dst,
+					 int len, __wsum sum, int *err_ptr)
+{
+	if (copy_from_user(dst, src, len)) {
+		*err_ptr = -EFAULT;
+		return (__force __wsum)-1;
+	}
+
+	return csum_partial(dst, len, sum);
+}
+
+/**
+ * csum_fold - Fold and invert a 32bit checksum.
+ * sum: 32bit unfolded sum
+ *
+ * Fold a 32bit running checksum to 16bit and invert it. This is usually
+ * the last step before putting a checksum into a packet.
+ * Make sure not to mix with 64bit checksums.
+ */
+static inline __sum16 csum_fold(__wsum sum)
+{
+	__asm__(
+		"  addl %1,%0\n"
+		"  adcl $0xffff,%0"
+		: "=r" (sum)
+		: "r" ((__force u32)sum << 16),
+		  "0" ((__force u32)sum & 0xffff0000)
+	);
+	return (__force __sum16)(~(__force u32)sum >> 16);
+}
+
+/**
+ * csum_tcpup_nofold - Compute an IPv4 pseudo header checksum.
+ * @saddr: source address
+ * @daddr: destination address
+ * @len: length of packet
+ * @proto: ip protocol of packet
+ * @sum: initial sum to be added in (32bit unfolded)
+ *
+ * Returns the pseudo header checksum the input data. Result is
+ * 32bit unfolded.
+ */
+static inline __wsum
+csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
+		   unsigned short proto, __wsum sum)
+{
+	asm("  addl %1, %0\n"
+	    "  adcl %2, %0\n"
+	    "  adcl %3, %0\n"
+	    "  adcl $0, %0\n"
+		: "=r" (sum)
+	    : "g" (daddr), "g" (saddr), "g" ((len + proto) << 8), "0" (sum));
+	return sum;
+}
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
+					   unsigned short len,
+					   unsigned short proto,
+					   __wsum sum)
+{
+	return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
+}
+
+/**
+ * ip_fast_csum - Compute the IPv4 header checksum efficiently.
+ * iph: ipv4 header
+ * ihl: length of header / 4
+ */
+static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
+{
+	unsigned int sum;
+
+	asm(	"  movl (%1), %0\n"
+		"  subl $4, %2\n"
+		"  jbe 2f\n"
+		"  addl 4(%1), %0\n"
+		"  adcl 8(%1), %0\n"
+		"  adcl 12(%1), %0\n"
+		"1: adcl 16(%1), %0\n"
+		"  lea 4(%1), %1\n"
+		"  decl %2\n"
+		"  jne	1b\n"
+		"  adcl $0, %0\n"
+		"  movl %0, %2\n"
+		"  shrl $16, %0\n"
+		"  addw %w2, %w0\n"
+		"  adcl $0, %0\n"
+		"  notl %0\n"
+		"2:"
+	/* Since the input registers which are loaded with iph and ipl
+	   are modified, we must also specify them as outputs, or gcc
+	   will assume they contain their original values. */
+	: "=r" (sum), "=r" (iph), "=r" (ihl)
+	: "1" (iph), "2" (ihl)
+	: "memory");
+	return (__force __sum16)sum;
+}
+
 #ifdef CONFIG_X86_32
 # include "checksum_32.h"
 #else
diff --git a/arch/x86/um/asm/checksum_32.h b/arch/x86/um/asm/checksum_32.h
index caab742..ab77b6f 100644
--- a/arch/x86/um/asm/checksum_32.h
+++ b/arch/x86/um/asm/checksum_32.h
@@ -5,145 +5,6 @@
 #ifndef __UM_SYSDEP_CHECKSUM_H
 #define __UM_SYSDEP_CHECKSUM_H
 
-#include "linux/in6.h"
-#include "linux/string.h"
-
-/*
- * computes the checksum of a memory block at buff, length len,
- * and adds in "sum" (32-bit)
- *
- * returns a 32-bit number suitable for feeding into itself
- * or csum_tcpudp_magic
- *
- * this function must be called with even lengths, except
- * for the last fragment, which may be odd
- *
- * it's best to have buff aligned on a 32-bit boundary
- */
-__wsum csum_partial(const void *buff, int len, __wsum sum);
-
-/*
- *	Note: when you get a NULL pointer exception here this means someone
- *	passed in an incorrect kernel address to one of these functions.
- *
- *	If you use these functions directly please don't forget the
- *	access_ok().
- */
-
-static __inline__
-__wsum csum_partial_copy_nocheck(const void *src, void *dst,
-				       int len, __wsum sum)
-{
-	memcpy(dst, src, len);
-	return csum_partial(dst, len, sum);
-}
-
-/*
- * the same as csum_partial, but copies from src while it
- * checksums, and handles user-space pointer exceptions correctly, when needed.
- *
- * here even more important to align src and dst on a 32-bit (or even
- * better 64-bit) boundary
- */
-
-static __inline__
-__wsum csum_partial_copy_from_user(const void __user *src, void *dst,
-					 int len, __wsum sum, int *err_ptr)
-{
-	if (copy_from_user(dst, src, len)) {
-		*err_ptr = -EFAULT;
-		return (__force __wsum)-1;
-	}
-
-	return csum_partial(dst, len, sum);
-}
-
-/*
- *	This is a version of ip_compute_csum() optimized for IP headers,
- *	which always checksum on 4 octet boundaries.
- *
- *	By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by
- *	Arnt Gulbrandsen.
- */
-static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
-{
-	unsigned int sum;
-
-	__asm__ __volatile__(
-	    "movl (%1), %0	;\n"
-	    "subl $4, %2	;\n"
-	    "jbe 2f		;\n"
-	    "addl 4(%1), %0	;\n"
-	    "adcl 8(%1), %0	;\n"
-	    "adcl 12(%1), %0	;\n"
-"1:	    adcl 16(%1), %0	;\n"
-	    "lea 4(%1), %1	;\n"
-	    "decl %2		;\n"
-	    "jne 1b		;\n"
-	    "adcl $0, %0	;\n"
-	    "movl %0, %2	;\n"
-	    "shrl $16, %0	;\n"
-	    "addw %w2, %w0	;\n"
-	    "adcl $0, %0	;\n"
-	    "notl %0		;\n"
-"2:				;\n"
-	/* Since the input registers which are loaded with iph and ipl
-	   are modified, we must also specify them as outputs, or gcc
-	   will assume they contain their original values. */
-	: "=r" (sum), "=r" (iph), "=r" (ihl)
-	: "1" (iph), "2" (ihl)
-	: "memory");
-	return (__force __sum16)sum;
-}
-
-/*
- *	Fold a partial checksum
- */
-
-static inline __sum16 csum_fold(__wsum sum)
-{
-	__asm__(
-		"addl %1, %0		;\n"
-		"adcl $0xffff, %0	;\n"
-		: "=r" (sum)
-		: "r" ((__force u32)sum << 16),
-		  "0" ((__force u32)sum & 0xffff0000)
-	);
-	return (__force __sum16)(~(__force u32)sum >> 16);
-}
-
-static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
-						   unsigned short len,
-						   unsigned short proto,
-						   __wsum sum)
-{
-    __asm__(
-	"addl %1, %0	;\n"
-	"adcl %2, %0	;\n"
-	"adcl %3, %0	;\n"
-	"adcl $0, %0	;\n"
-	: "=r" (sum)
-	: "g" (daddr), "g"(saddr), "g"((len + proto) << 8), "0"(sum));
-    return sum;
-}
-
-/*
- * computes the checksum of the TCP/UDP pseudo-header
- * returns a 16-bit checksum, already complemented
- */
-static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
-						   unsigned short len,
-						   unsigned short proto,
-						   __wsum sum)
-{
-	return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
-}
-
-/*
- * this routine is used for miscellaneous IP-like checksums, mainly
- * in icmp.c
- */
-
 static inline __sum16 ip_compute_csum(const void *buff, int len)
 {
     return csum_fold (csum_partial(buff, len, 0));
@@ -198,4 +59,3 @@
 }
 
 #endif
-
diff --git a/arch/x86/um/asm/checksum_64.h b/arch/x86/um/asm/checksum_64.h
index a5be903..7b6cd19 100644
--- a/arch/x86/um/asm/checksum_64.h
+++ b/arch/x86/um/asm/checksum_64.h
@@ -5,131 +5,6 @@
 #ifndef __UM_SYSDEP_CHECKSUM_H
 #define __UM_SYSDEP_CHECKSUM_H
 
-#include "linux/string.h"
-#include "linux/in6.h"
-#include "asm/uaccess.h"
-
-extern __wsum csum_partial(const void *buff, int len, __wsum sum);
-
-/*
- *	Note: when you get a NULL pointer exception here this means someone
- *	passed in an incorrect kernel address to one of these functions.
- *
- *	If you use these functions directly please don't forget the
- *	access_ok().
- */
-
-static __inline__
-__wsum csum_partial_copy_nocheck(const void *src, void *dst,
-				       int len, __wsum sum)
-{
-	memcpy(dst, src, len);
-	return(csum_partial(dst, len, sum));
-}
-
-static __inline__
-__wsum csum_partial_copy_from_user(const void __user *src,
-                                         void *dst, int len, __wsum sum,
-                                         int *err_ptr)
-{
-        if (copy_from_user(dst, src, len)) {
-                *err_ptr = -EFAULT;
-                return (__force __wsum)-1;
-        }
-        return csum_partial(dst, len, sum);
-}
-
-/**
- * csum_fold - Fold and invert a 32bit checksum.
- * sum: 32bit unfolded sum
- *
- * Fold a 32bit running checksum to 16bit and invert it. This is usually
- * the last step before putting a checksum into a packet.
- * Make sure not to mix with 64bit checksums.
- */
-static inline __sum16 csum_fold(__wsum sum)
-{
-	__asm__(
-		"  addl %1,%0\n"
-		"  adcl $0xffff,%0"
-		: "=r" (sum)
-		: "r" ((__force u32)sum << 16),
-		  "0" ((__force u32)sum & 0xffff0000)
-	);
-	return (__force __sum16)(~(__force u32)sum >> 16);
-}
-
-/**
- * csum_tcpup_nofold - Compute an IPv4 pseudo header checksum.
- * @saddr: source address
- * @daddr: destination address
- * @len: length of packet
- * @proto: ip protocol of packet
- * @sum: initial sum to be added in (32bit unfolded)
- *
- * Returns the pseudo header checksum the input data. Result is
- * 32bit unfolded.
- */
-static inline __wsum
-csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
-		   unsigned short proto, __wsum sum)
-{
-	asm("  addl %1, %0\n"
-	    "  adcl %2, %0\n"
-	    "  adcl %3, %0\n"
-	    "  adcl $0, %0\n"
-		: "=r" (sum)
-	    : "g" (daddr), "g" (saddr), "g" ((len + proto) << 8), "0" (sum));
-	return sum;
-}
-
-/*
- * computes the checksum of the TCP/UDP pseudo-header
- * returns a 16-bit checksum, already complemented
- */
-static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
-					   unsigned short len,
-					   unsigned short proto,
-					   __wsum sum)
-{
-	return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
-}
-
-/**
- * ip_fast_csum - Compute the IPv4 header checksum efficiently.
- * iph: ipv4 header
- * ihl: length of header / 4
- */
-static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
-{
-	unsigned int sum;
-
-	asm(	"  movl (%1), %0\n"
-		"  subl $4, %2\n"
-		"  jbe 2f\n"
-		"  addl 4(%1), %0\n"
-		"  adcl 8(%1), %0\n"
-		"  adcl 12(%1), %0\n"
-		"1: adcl 16(%1), %0\n"
-		"  lea 4(%1), %1\n"
-		"  decl %2\n"
-		"  jne	1b\n"
-		"  adcl $0, %0\n"
-		"  movl %0, %2\n"
-		"  shrl $16, %0\n"
-		"  addw %w2, %w0\n"
-		"  adcl $0, %0\n"
-		"  notl %0\n"
-		"2:"
-	/* Since the input registers which are loaded with iph and ipl
-	   are modified, we must also specify them as outputs, or gcc
-	   will assume they contain their original values. */
-	: "=r" (sum), "=r" (iph), "=r" (ihl)
-	: "1" (iph), "2" (ihl)
-	: "memory");
-	return (__force __sum16)sum;
-}
-
 static inline unsigned add32_with_carry(unsigned a, unsigned b)
 {
         asm("addl %2,%0\n\t"
diff --git a/arch/x86/um/asm/elf.h b/arch/x86/um/asm/elf.h
index 0e07adc..0feee2f 100644
--- a/arch/x86/um/asm/elf.h
+++ b/arch/x86/um/asm/elf.h
@@ -6,7 +6,7 @@
 #define __UM_ELF_X86_H
 
 #include <asm/user.h>
-#include "skas.h"
+#include <skas.h>
 
 #ifdef CONFIG_X86_32
 
diff --git a/arch/x86/um/asm/ptrace.h b/arch/x86/um/asm/ptrace.h
index e72cd0d..75513325 100644
--- a/arch/x86/um/asm/ptrace.h
+++ b/arch/x86/um/asm/ptrace.h
@@ -1,11 +1,13 @@
 #ifndef __UM_X86_PTRACE_H
 #define __UM_X86_PTRACE_H
 
-#ifdef CONFIG_X86_32
-# include "ptrace_32.h"
-#else
-# include "ptrace_64.h"
+#include <linux/compiler.h>
+#ifndef CONFIG_X86_32
+#define __FRAME_OFFSETS /* Needed to get the R* macros */
 #endif
+#include <asm/ptrace-generic.h>
+
+#define user_mode(r) UPT_IS_USER(&(r)->regs)
 
 #define PT_REGS_AX(r) UPT_AX(&(r)->regs)
 #define PT_REGS_BX(r) UPT_BX(&(r)->regs)
@@ -36,4 +38,52 @@
 {
 	return PT_REGS_AX(regs);
 }
+
+/*
+ * Forward declaration to avoid including sysdep/tls.h, which causes a
+ * circular include, and compilation failures.
+ */
+struct user_desc;
+
+#ifdef CONFIG_X86_32
+
+#define HOST_AUDIT_ARCH AUDIT_ARCH_I386
+
+extern int ptrace_get_thread_area(struct task_struct *child, int idx,
+                                  struct user_desc __user *user_desc);
+
+extern int ptrace_set_thread_area(struct task_struct *child, int idx,
+                                  struct user_desc __user *user_desc);
+
+#else
+
+#define HOST_AUDIT_ARCH AUDIT_ARCH_X86_64
+
+#define PT_REGS_R8(r) UPT_R8(&(r)->regs)
+#define PT_REGS_R9(r) UPT_R9(&(r)->regs)
+#define PT_REGS_R10(r) UPT_R10(&(r)->regs)
+#define PT_REGS_R11(r) UPT_R11(&(r)->regs)
+#define PT_REGS_R12(r) UPT_R12(&(r)->regs)
+#define PT_REGS_R13(r) UPT_R13(&(r)->regs)
+#define PT_REGS_R14(r) UPT_R14(&(r)->regs)
+#define PT_REGS_R15(r) UPT_R15(&(r)->regs)
+
+#include <asm/errno.h>
+
+static inline int ptrace_get_thread_area(struct task_struct *child, int idx,
+                                         struct user_desc __user *user_desc)
+{
+        return -ENOSYS;
+}
+
+static inline int ptrace_set_thread_area(struct task_struct *child, int idx,
+                                         struct user_desc __user *user_desc)
+{
+        return -ENOSYS;
+}
+
+extern long arch_prctl(struct task_struct *task, int code,
+		       unsigned long __user *addr);
+
+#endif
 #endif /* __UM_X86_PTRACE_H */
diff --git a/arch/x86/um/asm/ptrace_32.h b/arch/x86/um/asm/ptrace_32.h
deleted file mode 100644
index 2cf2253..0000000
--- a/arch/x86/um/asm/ptrace_32.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* 
- * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- * Licensed under the GPL
- */
-
-#ifndef __UM_PTRACE_I386_H
-#define __UM_PTRACE_I386_H
-
-#define HOST_AUDIT_ARCH AUDIT_ARCH_I386
-
-#include "linux/compiler.h"
-#include "asm/ptrace-generic.h"
-
-#define user_mode(r) UPT_IS_USER(&(r)->regs)
-
-/*
- * Forward declaration to avoid including sysdep/tls.h, which causes a
- * circular include, and compilation failures.
- */
-struct user_desc;
-
-extern int ptrace_get_thread_area(struct task_struct *child, int idx,
-                                  struct user_desc __user *user_desc);
-
-extern int ptrace_set_thread_area(struct task_struct *child, int idx,
-                                  struct user_desc __user *user_desc);
-
-#endif
diff --git a/arch/x86/um/asm/ptrace_64.h b/arch/x86/um/asm/ptrace_64.h
deleted file mode 100644
index ea7bff3..0000000
--- a/arch/x86/um/asm/ptrace_64.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2003 PathScale, Inc.
- *
- * Licensed under the GPL
- */
-
-#ifndef __UM_PTRACE_X86_64_H
-#define __UM_PTRACE_X86_64_H
-
-#include "linux/compiler.h"
-#include "asm/errno.h"
-
-#define __FRAME_OFFSETS /* Needed to get the R* macros */
-#include "asm/ptrace-generic.h"
-
-#define HOST_AUDIT_ARCH AUDIT_ARCH_X86_64
-
-#define PT_REGS_R8(r) UPT_R8(&(r)->regs)
-#define PT_REGS_R9(r) UPT_R9(&(r)->regs)
-#define PT_REGS_R10(r) UPT_R10(&(r)->regs)
-#define PT_REGS_R11(r) UPT_R11(&(r)->regs)
-#define PT_REGS_R12(r) UPT_R12(&(r)->regs)
-#define PT_REGS_R13(r) UPT_R13(&(r)->regs)
-#define PT_REGS_R14(r) UPT_R14(&(r)->regs)
-#define PT_REGS_R15(r) UPT_R15(&(r)->regs)
-
-/* XXX */
-#define user_mode(r) UPT_IS_USER(&(r)->regs)
-
-struct user_desc;
-
-static inline int ptrace_get_thread_area(struct task_struct *child, int idx,
-                                         struct user_desc __user *user_desc)
-{
-        return -ENOSYS;
-}
-
-static inline int ptrace_set_thread_area(struct task_struct *child, int idx,
-                                         struct user_desc __user *user_desc)
-{
-        return -ENOSYS;
-}
-
-extern long arch_prctl(struct task_struct *task, int code,
-		       unsigned long __user *addr);
-#endif
diff --git a/arch/x86/um/bugs_32.c b/arch/x86/um/bugs_32.c
index 17d88cf..33daff4 100644
--- a/arch/x86/um/bugs_32.c
+++ b/arch/x86/um/bugs_32.c
@@ -4,9 +4,9 @@
  */
 
 #include <signal.h>
-#include "kern_util.h"
-#include "longjmp.h"
-#include "sysdep/ptrace.h"
+#include <kern_util.h>
+#include <longjmp.h>
+#include <sysdep/ptrace.h>
 #include <generated/asm-offsets.h>
 
 /* Set during early boot */
diff --git a/arch/x86/um/bugs_64.c b/arch/x86/um/bugs_64.c
index 44e02ba..8cc8256 100644
--- a/arch/x86/um/bugs_64.c
+++ b/arch/x86/um/bugs_64.c
@@ -4,7 +4,7 @@
  * Licensed under the GPL
  */
 
-#include "sysdep/ptrace.h"
+#include <sysdep/ptrace.h>
 
 void arch_check_bugs(void)
 {
diff --git a/arch/x86/um/fault.c b/arch/x86/um/fault.c
index d670f68..8784ab3 100644
--- a/arch/x86/um/fault.c
+++ b/arch/x86/um/fault.c
@@ -3,7 +3,7 @@
  * Licensed under the GPL
  */
 
-#include "sysdep/ptrace.h"
+#include <sysdep/ptrace.h>
 
 /* These two are from asm-um/uaccess.h and linux/module.h, check them. */
 struct exception_table_entry
diff --git a/arch/x86/um/ldt.c b/arch/x86/um/ldt.c
index 26b0e39..8e08176 100644
--- a/arch/x86/um/ldt.c
+++ b/arch/x86/um/ldt.c
@@ -7,11 +7,11 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <asm/unistd.h>
-#include "os.h"
-#include "proc_mm.h"
-#include "skas.h"
-#include "skas_ptrace.h"
-#include "sysdep/tls.h"
+#include <os.h>
+#include <proc_mm.h>
+#include <skas.h>
+#include <skas_ptrace.h>
+#include <sysdep/tls.h>
 
 extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
 
diff --git a/arch/x86/um/mem_64.c b/arch/x86/um/mem_64.c
index 5465187..c6492e7 100644
--- a/arch/x86/um/mem_64.c
+++ b/arch/x86/um/mem_64.c
@@ -1,6 +1,6 @@
-#include "linux/mm.h"
-#include "asm/page.h"
-#include "asm/mman.h"
+#include <linux/mm.h>
+#include <asm/page.h>
+#include <asm/mman.h>
 
 const char *arch_vma_name(struct vm_area_struct *vma)
 {
diff --git a/arch/x86/um/os-Linux/registers.c b/arch/x86/um/os-Linux/registers.c
index 0cdbb86..41bfe84 100644
--- a/arch/x86/um/os-Linux/registers.c
+++ b/arch/x86/um/os-Linux/registers.c
@@ -9,8 +9,8 @@
 #ifdef __i386__
 #include <sys/user.h>
 #endif
-#include "longjmp.h"
-#include "sysdep/ptrace_user.h"
+#include <longjmp.h>
+#include <sysdep/ptrace_user.h>
 
 int save_fp_registers(int pid, unsigned long *fp_regs)
 {
diff --git a/arch/x86/um/os-Linux/task_size.c b/arch/x86/um/os-Linux/task_size.c
index efb16c5..8502ad3 100644
--- a/arch/x86/um/os-Linux/task_size.c
+++ b/arch/x86/um/os-Linux/task_size.c
@@ -2,7 +2,7 @@
 #include <stdlib.h>
 #include <signal.h>
 #include <sys/mman.h>
-#include "longjmp.h"
+#include <longjmp.h>
 
 #ifdef __i386__
 
diff --git a/arch/x86/um/os-Linux/tls.c b/arch/x86/um/os-Linux/tls.c
index 82276b6..9d94b3b 100644
--- a/arch/x86/um/os-Linux/tls.c
+++ b/arch/x86/um/os-Linux/tls.c
@@ -5,7 +5,7 @@
 #include <sys/syscall.h>
 #include <unistd.h>
 
-#include "sysdep/tls.h"
+#include <sysdep/tls.h>
 
 #ifndef PTRACE_GET_THREAD_AREA
 #define PTRACE_GET_THREAD_AREA 25
diff --git a/arch/x86/um/ptrace_32.c b/arch/x86/um/ptrace_32.c
index 3b949daa..ce3dd4f 100644
--- a/arch/x86/um/ptrace_32.c
+++ b/arch/x86/um/ptrace_32.c
@@ -3,10 +3,10 @@
  * Licensed under the GPL
  */
 
-#include "linux/mm.h"
-#include "linux/sched.h"
-#include "asm/uaccess.h"
-#include "skas.h"
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <asm/uaccess.h>
+#include <skas.h>
 
 extern int arch_switch_tls(struct task_struct *to);
 
diff --git a/arch/x86/um/ptrace_user.c b/arch/x86/um/ptrace_user.c
index 3960ca1..617885b 100644
--- a/arch/x86/um/ptrace_user.c
+++ b/arch/x86/um/ptrace_user.c
@@ -4,7 +4,7 @@
  */
 
 #include <errno.h>
-#include "ptrace_user.h"
+#include <ptrace_user.h>
 
 int ptrace_getregs(long pid, unsigned long *regs_out)
 {
diff --git a/arch/x86/um/shared/sysdep/ptrace.h b/arch/x86/um/shared/sysdep/ptrace.h
index 6ce2d76..eb93569 100644
--- a/arch/x86/um/shared/sysdep/ptrace.h
+++ b/arch/x86/um/shared/sysdep/ptrace.h
@@ -2,7 +2,7 @@
 #define __SYSDEP_X86_PTRACE_H
 
 #include <generated/user_constants.h>
-#include "sysdep/faultinfo.h"
+#include <sysdep/faultinfo.h>
 
 #define MAX_REG_OFFSET (UM_FRAME_SIZE)
 #define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long))
diff --git a/arch/x86/um/shared/sysdep/stub.h b/arch/x86/um/shared/sysdep/stub.h
index bd161e3..3f55e5b 100644
--- a/arch/x86/um/shared/sysdep/stub.h
+++ b/arch/x86/um/shared/sysdep/stub.h
@@ -1,8 +1,8 @@
 #include <asm/unistd.h>
 #include <sys/mman.h>
 #include <signal.h>
-#include "as-layout.h"
-#include "stub-data.h"
+#include <as-layout.h>
+#include <stub-data.h>
 
 #ifdef __i386__
 #include "stub_32.h"
diff --git a/arch/x86/um/shared/sysdep/syscalls_32.h b/arch/x86/um/shared/sysdep/syscalls_32.h
index 05cb796..8436079 100644
--- a/arch/x86/um/shared/sysdep/syscalls_32.h
+++ b/arch/x86/um/shared/sysdep/syscalls_32.h
@@ -3,8 +3,8 @@
  * Licensed under the GPL
  */
 
-#include "asm/unistd.h"
-#include "sysdep/ptrace.h"
+#include <asm/unistd.h>
+#include <sysdep/ptrace.h>
 
 typedef long syscall_handler_t(struct pt_regs);
 
diff --git a/arch/x86/um/signal.c b/arch/x86/um/signal.c
index ba7363e..bdaa08c 100644
--- a/arch/x86/um/signal.c
+++ b/arch/x86/um/signal.c
@@ -11,8 +11,8 @@
 #include <asm/unistd.h>
 #include <asm/uaccess.h>
 #include <asm/ucontext.h>
-#include "frame_kern.h"
-#include "skas.h"
+#include <frame_kern.h>
+#include <skas.h>
 
 #ifdef CONFIG_X86_32
 
diff --git a/arch/x86/um/stub_32.S b/arch/x86/um/stub_32.S
index 54a36ec..b972649 100644
--- a/arch/x86/um/stub_32.S
+++ b/arch/x86/um/stub_32.S
@@ -1,4 +1,4 @@
-#include "as-layout.h"
+#include <as-layout.h>
 
 	.globl syscall_stub
 .section .__syscall_stub, "ax"
diff --git a/arch/x86/um/stub_64.S b/arch/x86/um/stub_64.S
index 20e4a96..7160b20 100644
--- a/arch/x86/um/stub_64.S
+++ b/arch/x86/um/stub_64.S
@@ -1,4 +1,4 @@
-#include "as-layout.h"
+#include <as-layout.h>
 
 	.globl syscall_stub
 .section .__syscall_stub, "ax"
diff --git a/arch/x86/um/stub_segv.c b/arch/x86/um/stub_segv.c
index b7450bd..1518d28 100644
--- a/arch/x86/um/stub_segv.c
+++ b/arch/x86/um/stub_segv.c
@@ -3,9 +3,9 @@
  * Licensed under the GPL
  */
 
-#include "sysdep/stub.h"
-#include "sysdep/faultinfo.h"
-#include "sysdep/mcontext.h"
+#include <sysdep/stub.h>
+#include <sysdep/faultinfo.h>
+#include <sysdep/mcontext.h>
 
 void __attribute__ ((__section__ (".__syscall_stub")))
 stub_segv_handler(int sig, siginfo_t *info, void *p)
diff --git a/arch/x86/um/sys_call_table_32.c b/arch/x86/um/sys_call_table_32.c
index b5408ce..232e605 100644
--- a/arch/x86/um/sys_call_table_32.c
+++ b/arch/x86/um/sys_call_table_32.c
@@ -25,7 +25,6 @@
 #define old_mmap sys_old_mmap
 
 #define ptregs_fork sys_fork
-#define ptregs_execve sys_execve
 #define ptregs_iopl sys_iopl
 #define ptregs_vm86old sys_vm86old
 #define ptregs_clone i386_clone
diff --git a/arch/x86/um/sysrq_32.c b/arch/x86/um/sysrq_32.c
index 2d5cc51..c9bee5b 100644
--- a/arch/x86/um/sysrq_32.c
+++ b/arch/x86/um/sysrq_32.c
@@ -3,12 +3,12 @@
  * Licensed under the GPL
  */
 
-#include "linux/kernel.h"
-#include "linux/smp.h"
-#include "linux/sched.h"
-#include "linux/kallsyms.h"
-#include "asm/ptrace.h"
-#include "sysrq.h"
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/sched.h>
+#include <linux/kallsyms.h>
+#include <asm/ptrace.h>
+#include <asm/sysrq.h>
 
 /* This is declared by <linux/sched.h> */
 void show_regs(struct pt_regs *regs)
diff --git a/arch/x86/um/sysrq_64.c b/arch/x86/um/sysrq_64.c
index 08258f1..a0e7fb1 100644
--- a/arch/x86/um/sysrq_64.c
+++ b/arch/x86/um/sysrq_64.c
@@ -10,7 +10,7 @@
 #include <linux/utsname.h>
 #include <asm/current.h>
 #include <asm/ptrace.h>
-#include "sysrq.h"
+#include <asm/sysrq.h>
 
 void __show_regs(struct pt_regs *regs)
 {
diff --git a/arch/x86/um/tls_32.c b/arch/x86/um/tls_32.c
index baba84f..5f5feff 100644
--- a/arch/x86/um/tls_32.c
+++ b/arch/x86/um/tls_32.c
@@ -3,12 +3,12 @@
  * Licensed under the GPL
  */
 
-#include "linux/percpu.h"
-#include "linux/sched.h"
-#include "asm/uaccess.h"
-#include "os.h"
-#include "skas.h"
-#include "sysdep/tls.h"
+#include <linux/percpu.h>
+#include <linux/sched.h>
+#include <asm/uaccess.h>
+#include <os.h>
+#include <skas.h>
+#include <sysdep/tls.h>
 
 /*
  * If needed we can detect when it's uninitialized.
diff --git a/arch/x86/um/tls_64.c b/arch/x86/um/tls_64.c
index f7ba462..d22363c 100644
--- a/arch/x86/um/tls_64.c
+++ b/arch/x86/um/tls_64.c
@@ -1,4 +1,4 @@
-#include "linux/sched.h"
+#include <linux/sched.h>
 
 void clear_flushed_tls(struct task_struct *task)
 {
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 5a16824..fd28d86 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -2451,8 +2451,7 @@
 
 	prot = __pgprot(pgprot_val(prot) | _PAGE_IOMAP);
 
-	BUG_ON(!((vma->vm_flags & (VM_PFNMAP | VM_RESERVED | VM_IO)) ==
-				(VM_PFNMAP | VM_RESERVED | VM_IO)));
+	BUG_ON(!((vma->vm_flags & (VM_PFNMAP | VM_IO)) == (VM_PFNMAP | VM_IO)));
 
 	rmd.mfn = mfn;
 	rmd.prot = prot;
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 744f5ee..cdcb48a 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -11,6 +11,9 @@
 	select HAVE_GENERIC_HARDIRQS
 	select GENERIC_IRQ_SHOW
 	select GENERIC_CPU_DEVICES
+	select MODULES_USE_ELF_RELA
+	select GENERIC_PCI_IOMAP
+	select ARCH_WANT_OPTIONAL_GPIOLIB
 	help
 	  Xtensa processors are 32-bit RISC machines designed by Tensilica
 	  primarily for embedded systems.  These processors are both
@@ -35,7 +38,7 @@
 	def_bool n
 
 config NO_IOPORT
-	def_bool y
+	def_bool n
 
 config HZ
 	int
@@ -142,6 +145,7 @@
 config XTENSA_PLATFORM_S6105
 	bool "S6105"
 	select SERIAL_CONSOLE
+	select NO_IOPORT
 
 endchoice
 
@@ -205,23 +209,6 @@
 
 source "fs/Kconfig"
 
-menu "Xtensa initrd options"
-	depends on BLK_DEV_INITRD
-
-config EMBEDDED_RAMDISK
-	bool "Embed root filesystem ramdisk into the kernel"
-
-config EMBEDDED_RAMDISK_IMAGE
-	string "Filename of gzipped ramdisk image"
-	depends on EMBEDDED_RAMDISK
-	default "ramdisk.gz"
-	help
-	  This is the filename of the ramdisk image to be built into the
-	  kernel.  Relative pathnames are relative to arch/xtensa/boot/ramdisk/.
-	  The ramdisk image is not part of the kernel distribution; you must
-	  provide one yourself.
-endmenu
-
 source "arch/xtensa/Kconfig.debug"
 
 source "security/Kconfig"
diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile
index f973754..bb5ba61 100644
--- a/arch/xtensa/Makefile
+++ b/arch/xtensa/Makefile
@@ -21,6 +21,18 @@
 VARIANT = $(variant-y)
 export VARIANT
 
+# Test for cross compiling
+
+ifneq ($(VARIANT),)
+  COMPILE_ARCH = $(shell uname -m)
+
+  ifneq ($(COMPILE_ARCH), xtensa)
+    ifndef CROSS_COMPILE
+      CROSS_COMPILE = xtensa_$(VARIANT)-
+    endif
+  endif
+endif
+
 # Platform configuration
 
 platform-$(CONFIG_XTENSA_PLATFORM_XT2000)	:= xt2000
@@ -31,7 +43,7 @@
 export PLATFORM
 
 # temporarily until string.h is fixed
-KBUILD_CFLAGS += -ffreestanding
+KBUILD_CFLAGS += -ffreestanding -D__linux__
 
 KBUILD_CFLAGS += -pipe -mlongcalls
 
@@ -48,24 +60,6 @@
 
 KBUILD_DEFCONFIG := iss_defconfig
 
-# ramdisk/initrd support
-# You need a compressed ramdisk image, named ramdisk.gz in
-# arch/xtensa/boot/ramdisk
-
-core-$(CONFIG_EMBEDDED_RAMDISK)	+= arch/xtensa/boot/ramdisk/
-
-# Test for cross compiling
-
-ifneq ($(VARIANT),)
-  COMPILE_ARCH = $(shell uname -m)
-
-  ifneq ($(COMPILE_ARCH), xtensa)
-    ifndef CROSS_COMPILE
-      CROSS_COMPILE = xtensa_$(VARIANT)-
-    endif
-  endif
-endif
-
 # Only build variant and/or platform if it includes a Makefile
 
 buildvar := $(shell test -e $(srctree)/arch/xtensa/variants/$(VARIANT)/Makefile && echo arch/xtensa/variants/$(VARIANT)/)
@@ -87,7 +81,7 @@
 
 bzImage : zImage
 
-zImage zImage.initrd: vmlinux
+zImage: vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) $@
 
 define archhelp
diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile
index 70fd145..4018f89 100644
--- a/arch/xtensa/boot/Makefile
+++ b/arch/xtensa/boot/Makefile
@@ -25,7 +25,7 @@
 bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf
 
 
-zImage zImage.initrd Image Image.initrd: $(bootdir-y)
+zImage Image: $(bootdir-y)
 
 $(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) \
 	      $(addprefix $(obj)/,$(host-progs))
diff --git a/arch/xtensa/boot/boot-elf/Makefile b/arch/xtensa/boot/boot-elf/Makefile
index 08e8814..f10992b 100644
--- a/arch/xtensa/boot/boot-elf/Makefile
+++ b/arch/xtensa/boot/boot-elf/Makefile
@@ -20,9 +20,11 @@
 
 OBJS		:= $(addprefix $(obj)/,$(boot-y))
 
-Image:	vmlinux $(OBJS) arch/$(ARCH)/boot/boot-elf/boot.lds
+vmlinux.tmp: vmlinux
 	$(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \
-		vmlinux vmlinux.tmp
+		$^ $@
+
+Image:	vmlinux.tmp $(OBJS) arch/$(ARCH)/boot/boot-elf/boot.lds
 	$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
 		--add-section image=vmlinux.tmp \
 		--set-section-flags image=contents,alloc,load,load,data \
@@ -30,24 +32,6 @@
 	$(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \
 		-T arch/$(ARCH)/boot/boot-elf/boot.lds \
 		-o arch/$(ARCH)/boot/$@.elf $@.tmp
-	rm -f $@.tmp vmlinux.tmp
-
-Image.initrd:	vmlinux $(OBJS)
-	$(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \
-		--add-section .initrd=arch/$(ARCH)/boot/ramdisk \
-		--set-section-flags .initrd=contents,alloc,load,load,data \
-		vmlinux vmlinux.tmp
-	$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
-		--add-section image=vmlinux.tmp \
-		--set-section-flags image=contents,alloc,load,load,data \
-		$(OBJS) $@.tmp
-	$(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \
-		-T $(srctree)/arch/$(ARCH)/boot/boot-elf/boot.ld \
-		-o arch/$(ARCH)/boot/$@.elf $@.tmp
-	rm -f $@.tmp vmlinux.tmp
-
 
 zImage:	Image
 
-zImage.initrd:	Image.initrd
-
diff --git a/arch/xtensa/boot/boot-elf/boot.lds.S b/arch/xtensa/boot/boot-elf/boot.lds.S
index 4e53b74..7b646e0 100644
--- a/arch/xtensa/boot/boot-elf/boot.lds.S
+++ b/arch/xtensa/boot/boot-elf/boot.lds.S
@@ -33,13 +33,6 @@
 
 	__reloc_end = . ;
 
-	.initrd ALIGN(0x10) :
-	{
-		boot_initrd_start = . ;
-		*(.initrd)
-		boot_initrd_end = .;
-	}
-
 	. = ALIGN(0x10);
 	__image_load = . ;
 	.image 0xd0001000:
diff --git a/arch/xtensa/boot/boot-redboot/Makefile b/arch/xtensa/boot/boot-redboot/Makefile
index 872029b..25a78c6 100644
--- a/arch/xtensa/boot/boot-redboot/Makefile
+++ b/arch/xtensa/boot/boot-redboot/Makefile
@@ -21,15 +21,17 @@
 
 LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
 
-zImage: vmlinux $(OBJS) $(LIBS)
+vmlinux.tmp: vmlinux
 	$(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \
-		vmlinux vmlinux.tmp
-	gzip -vf9 vmlinux.tmp
+		$^ $@
+
+vmlinux.tmp.gz: vmlinux.tmp
+	$(GZIP) $(GZIP_FLAGS) $^ > $@
+
+zImage: vmlinux.tmp.gz $(OBJS) $(LIBS)
 	$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
 		--add-section image=vmlinux.tmp.gz \
 		--set-section-flags image=contents,alloc,load,load,data \
 		$(OBJS) $@.tmp
 	$(LD) $(LD_ARGS) -o $@.elf $@.tmp $(LIBS) -L/xtensa-elf/lib $(LIBGCC)
 	$(OBJCOPY) -S -O binary $@.elf arch/$(ARCH)/boot/$@.redboot
-	rm -f $@.tmp $@.elf vmlinux.tmp.gz
-
diff --git a/arch/xtensa/boot/boot-redboot/boot.ld b/arch/xtensa/boot/boot-redboot/boot.ld
index 774db20..5bbcaf9 100644
--- a/arch/xtensa/boot/boot-redboot/boot.ld
+++ b/arch/xtensa/boot/boot-redboot/boot.ld
@@ -31,13 +31,6 @@
 
 	__reloc_end = . ;
 
-	.initrd ALIGN(0x10) :
-	{
-		boot_initrd_start = . ;
-		*(.initrd)
-		boot_initrd_end = .;
-	}
-
 	. = ALIGN(0x10);
 	__image_load = . ;
 	.image 0xd0001000: AT(__image_load)
diff --git a/arch/xtensa/boot/boot-redboot/bootstrap.S b/arch/xtensa/boot/boot-redboot/bootstrap.S
index 5582e8c..4c316cd 100644
--- a/arch/xtensa/boot/boot-redboot/bootstrap.S
+++ b/arch/xtensa/boot/boot-redboot/bootstrap.S
@@ -226,17 +226,7 @@
 
 	isync
 
-	movi	a5, __start
-	movi	a3, boot_initrd_start
-	movi	a4, boot_initrd_end
-	sub	a3, a3, a5
-	sub	a4, a4, a5
-	add	a3, a0, a3
-	add	a4, a0, a4
-
 	# a2  Boot parameter list
-	# a3  initrd_start (virtual load address)
-	# a4  initrd_end   (virtual load address)
 
 	movi	a0, _image_start
 	jx	a0
diff --git a/arch/xtensa/boot/ramdisk/Makefile b/arch/xtensa/boot/ramdisk/Makefile
deleted file mode 100644
index b12f763..0000000
--- a/arch/xtensa/boot/ramdisk/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Makefile for a ramdisk image
-#
-
-BIG_ENDIAN	:= $(shell echo -e "\#ifdef __XTENSA_EL__\nint little;\n\#else\nint big;\n\#endif" | $(CC) -E -|grep -c big)
-
-ifeq ($(BIG_ENDIAN),1)
-OBJCOPY_ARGS    := -O elf32-xtensa-be
-else
-OBJCOPY_ARGS    := -O elf32-xtensa-le
-endif
-
-obj-y = ramdisk.o
-
-RAMDISK_IMAGE = arch/$(ARCH)/boot/ramdisk/$(CONFIG_EMBEDDED_RAMDISK_IMAGE)
-
-arch/$(ARCH)/boot/ramdisk/ramdisk.o:
-	$(Q)echo -e "dummy:" | $(AS) -o $@;
-	$(Q)$(OBJCOPY) $(OBJCOPY_ARGS)					    \
-		--add-section .initrd=$(RAMDISK_IMAGE)			    \
-		--set-section-flags .initrd=contents,alloc,load,load,data   \
-		arch/$(ARCH)/boot/ramdisk/ramdisk.o $@
-
diff --git a/arch/xtensa/configs/s6105_defconfig b/arch/xtensa/configs/s6105_defconfig
index 550e8ed..eaf1b8f 100644
--- a/arch/xtensa/configs/s6105_defconfig
+++ b/arch/xtensa/configs/s6105_defconfig
@@ -541,11 +541,6 @@
 # CONFIG_DLM is not set
 
 #
-# Xtensa initrd options
-#
-# CONFIG_EMBEDDED_RAMDISK is not set
-
-#
 # Kernel hacking
 #
 CONFIG_PRINTK_TIME=y
diff --git a/arch/xtensa/include/asm/Kbuild b/arch/xtensa/include/asm/Kbuild
index c68e168..fccd81e 100644
--- a/arch/xtensa/include/asm/Kbuild
+++ b/arch/xtensa/include/asm/Kbuild
@@ -1 +1,4 @@
 include include/asm-generic/Kbuild.asm
+
+generic-y += clkdev.h
+generic-y += exec.h
diff --git a/arch/xtensa/include/asm/exec.h b/arch/xtensa/include/asm/exec.h
deleted file mode 100644
index af949e2..0000000
--- a/arch/xtensa/include/asm/exec.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * 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.
- *
- * Copyright (C) 2001 - 2005 Tensilica Inc.
- */
-
-#ifndef _XTENSA_EXEC_H
-#define _XTENSA_EXEC_H
-
-#define arch_align_stack(x) (x)
-
-#endif /* _XTENSA_EXEC_H */
diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h
index 4beb43c..e6be5b9 100644
--- a/arch/xtensa/include/asm/io.h
+++ b/arch/xtensa/include/asm/io.h
@@ -25,184 +25,54 @@
 #define XCHAL_KIO_SIZE		0x10000000
 
 #define IOADDR(x)		(XCHAL_KIO_BYPASS_VADDR + (x))
+#define IO_SPACE_LIMIT ~0
 
+#ifdef CONFIG_MMU
 /*
- * swap functions to change byte order from little-endian to big-endian and
- * vice versa.
- */
-
-static inline unsigned short _swapw (unsigned short v)
-{
-	return (v << 8) | (v >> 8);
-}
-
-static inline unsigned int _swapl (unsigned int v)
-{
-	return (v << 24) | ((v & 0xff00) << 8) | ((v >> 8) & 0xff00) | (v >> 24);
-}
-
-/*
- * Change virtual addresses to physical addresses and vv.
- * These are trivial on the 1:1 Linux/Xtensa mapping
- */
-
-static inline unsigned long virt_to_phys(volatile void * address)
-{
-	return __pa(address);
-}
-
-static inline void * phys_to_virt(unsigned long address)
-{
-	return __va(address);
-}
-
-/*
- * virt_to_bus and bus_to_virt are deprecated.
- */
-
-#define virt_to_bus(x)	virt_to_phys(x)
-#define bus_to_virt(x)	phys_to_virt(x)
-
-/*
- * Return the virtual (cached) address for the specified bus memory.
+ * Return the virtual address for the specified bus memory.
  * Note that we currently don't support any address outside the KIO segment.
  */
-
-static inline void *ioremap(unsigned long offset, unsigned long size)
+static inline void __iomem *ioremap_nocache(unsigned long offset,
+		unsigned long size)
 {
-#ifdef CONFIG_MMU
 	if (offset >= XCHAL_KIO_PADDR
-	    && offset < XCHAL_KIO_PADDR + XCHAL_KIO_SIZE)
+	    && offset - XCHAL_KIO_PADDR < XCHAL_KIO_SIZE)
 		return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_BYPASS_VADDR);
 	else
 		BUG();
-#else
-	return (void *)offset;
-#endif
 }
 
-static inline void *ioremap_nocache(unsigned long offset, unsigned long size)
+static inline void __iomem *ioremap_cache(unsigned long offset,
+		unsigned long size)
 {
-#ifdef CONFIG_MMU
 	if (offset >= XCHAL_KIO_PADDR
-	    && offset < XCHAL_KIO_PADDR + XCHAL_KIO_SIZE)
+	    && offset - XCHAL_KIO_PADDR < XCHAL_KIO_SIZE)
 		return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_CACHED_VADDR);
 	else
 		BUG();
-#else
-	return (void *)offset;
-#endif
 }
 
-static inline void iounmap(void *addr)
+#define ioremap_wc ioremap_nocache
+
+static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
+{
+	return ioremap_nocache(offset, size);
+}
+
+static inline void iounmap(volatile void __iomem *addr)
 {
 }
+#endif /* CONFIG_MMU */
 
 /*
  * Generic I/O
  */
-
-#define readb(addr) \
-	({ unsigned char __v = (*(volatile unsigned char *)(addr)); __v; })
-#define readw(addr) \
-	({ unsigned short __v = (*(volatile unsigned short *)(addr)); __v; })
-#define readl(addr) \
-	({ unsigned int __v = (*(volatile unsigned int *)(addr)); __v; })
-#define writeb(b, addr) (void)((*(volatile unsigned char *)(addr)) = (b))
-#define writew(b, addr) (void)((*(volatile unsigned short *)(addr)) = (b))
-#define writel(b, addr) (void)((*(volatile unsigned int *)(addr)) = (b))
-
-static inline __u8 __raw_readb(const volatile void __iomem *addr)
-{
-          return *(__force volatile __u8 *)(addr);
-}
-static inline __u16 __raw_readw(const volatile void __iomem *addr)
-{
-          return *(__force volatile __u16 *)(addr);
-}
-static inline __u32 __raw_readl(const volatile void __iomem *addr)
-{
-          return *(__force volatile __u32 *)(addr);
-}
-static inline void __raw_writeb(__u8 b, volatile void __iomem *addr)
-{
-          *(__force volatile __u8 *)(addr) = b;
-}
-static inline void __raw_writew(__u16 b, volatile void __iomem *addr)
-{
-          *(__force volatile __u16 *)(addr) = b;
-}
-static inline void __raw_writel(__u32 b, volatile void __iomem *addr)
-{
-          *(__force volatile __u32 *)(addr) = b;
-}
-
-/* These are the definitions for the x86 IO instructions
- * inb/inw/inl/outb/outw/outl, the "string" versions
- * insb/insw/insl/outsb/outsw/outsl, and the "pausing" versions
- * inb_p/inw_p/...
- * The macros don't do byte-swapping.
- */
-
-#define inb(port)		readb((u8 *)((port)))
-#define outb(val, port)		writeb((val),(u8 *)((unsigned long)(port)))
-#define inw(port)		readw((u16 *)((port)))
-#define outw(val, port)		writew((val),(u16 *)((unsigned long)(port)))
-#define inl(port)		readl((u32 *)((port)))
-#define outl(val, port)		writel((val),(u32 *)((unsigned long)(port)))
-
-#define inb_p(port)		inb((port))
-#define outb_p(val, port)	outb((val), (port))
-#define inw_p(port)		inw((port))
-#define outw_p(val, port)	outw((val), (port))
-#define inl_p(port)		inl((port))
-#define outl_p(val, port)	outl((val), (port))
-
-extern void insb (unsigned long port, void *dst, unsigned long count);
-extern void insw (unsigned long port, void *dst, unsigned long count);
-extern void insl (unsigned long port, void *dst, unsigned long count);
-extern void outsb (unsigned long port, const void *src, unsigned long count);
-extern void outsw (unsigned long port, const void *src, unsigned long count);
-extern void outsl (unsigned long port, const void *src, unsigned long count);
-
-#define IO_SPACE_LIMIT ~0
-
-#define memset_io(a,b,c)       memset((void *)(a),(b),(c))
-#define memcpy_fromio(a,b,c)   memcpy((a),(void *)(b),(c))
-#define memcpy_toio(a,b,c)      memcpy((void *)(a),(b),(c))
-
-/* At this point the Xtensa doesn't provide byte swap instructions */
-
-#ifdef __XTENSA_EB__
-# define in_8(addr) (*(u8*)(addr))
-# define in_le16(addr) _swapw(*(u16*)(addr))
-# define in_le32(addr) _swapl(*(u32*)(addr))
-# define out_8(b, addr) *(u8*)(addr) = (b)
-# define out_le16(b, addr) *(u16*)(addr) = _swapw(b)
-# define out_le32(b, addr) *(u32*)(addr) = _swapl(b)
-#elif defined(__XTENSA_EL__)
-# define in_8(addr)  (*(u8*)(addr))
-# define in_le16(addr) (*(u16*)(addr))
-# define in_le32(addr) (*(u32*)(addr))
-# define out_8(b, addr) *(u8*)(addr) = (b)
-# define out_le16(b, addr) *(u16*)(addr) = (b)
-# define out_le32(b, addr) *(u32*)(addr) = (b)
-#else
-# error processor byte order undefined!
-#endif
-
-
-/*
- * Convert a physical pointer to a virtual kernel pointer for /dev/mem access
- */
-#define xlate_dev_mem_ptr(p)    __va(p)
-
-/*
- * Convert a virtual cached pointer to an uncached pointer
- */
-#define xlate_dev_kmem_ptr(p)   p
-
+#define readb_relaxed readb
+#define readw_relaxed readw
+#define readl_relaxed readl
 
 #endif	/* __KERNEL__ */
 
+#include <asm-generic/io.h>
+
 #endif	/* _XTENSA_IO_H */
diff --git a/arch/xtensa/include/asm/ioctls.h b/arch/xtensa/include/asm/ioctls.h
index fd1d136..2aa4cd9 100644
--- a/arch/xtensa/include/asm/ioctls.h
+++ b/arch/xtensa/include/asm/ioctls.h
@@ -71,8 +71,8 @@
 #define TIOCSSOFTCAR	_IOW('T', 26, unsigned int)
 #define TIOCLINUX	_IOW('T', 28, char)
 #define TIOCCONS	_IO('T', 29)
-#define TIOCGSERIAL	_IOR('T', 30, struct serial_struct)
-#define TIOCSSERIAL	_IOW('T', 31, struct serial_struct)
+#define TIOCGSERIAL	0x803C541E	/*_IOR('T', 30, struct serial_struct)*/
+#define TIOCSSERIAL	0x403C541F	/*_IOW('T', 31, struct serial_struct)*/
 #define TIOCPKT		_IOW('T', 32, int)
 # define TIOCPKT_DATA		 0
 # define TIOCPKT_FLUSHREAD	 1
diff --git a/arch/xtensa/include/asm/regs.h b/arch/xtensa/include/asm/regs.h
index d4baed2..a3075b1 100644
--- a/arch/xtensa/include/asm/regs.h
+++ b/arch/xtensa/include/asm/regs.h
@@ -66,7 +66,7 @@
 #define ICOUNTLEVEL	237
 #define EXCVADDR	238
 #define CCOMPARE	240
-#define MISC		244
+#define MISC_SR		244
 
 /*  Special names for read-only and write-only interrupt registers.  */
 
diff --git a/arch/xtensa/include/asm/thread_info.h b/arch/xtensa/include/asm/thread_info.h
index 81abfd5..9481004 100644
--- a/arch/xtensa/include/asm/thread_info.h
+++ b/arch/xtensa/include/asm/thread_info.h
@@ -128,19 +128,14 @@
 #define TIF_SIGPENDING		1	/* signal pending */
 #define TIF_NEED_RESCHED	2	/* rescheduling necessary */
 #define TIF_SINGLESTEP		3	/* restore singlestep on return to user mode */
-#define TIF_IRET		4	/* return with iret */
 #define TIF_MEMDIE		5	/* is terminating due to OOM killer */
 #define TIF_RESTORE_SIGMASK	6	/* restore signal mask in do_signal() */
 #define TIF_NOTIFY_RESUME	7	/* callback before returning to user */
-#define TIF_POLLING_NRFLAG	16	/* true if poll_idle() is polling TIF_NEED_RESCHED */
 
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
 #define _TIF_SINGLESTEP		(1<<TIF_SINGLESTEP)
-#define _TIF_IRET		(1<<TIF_IRET)
-#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
-#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
 
 #define _TIF_WORK_MASK		0x0000FFFE	/* work to do on interrupt/exception return */
 #define _TIF_ALLWORK_MASK	0x0000FFFF	/* work to do on any return to u-space */
diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile
index 59fc3fe..f36cef5 100644
--- a/arch/xtensa/kernel/Makefile
+++ b/arch/xtensa/kernel/Makefile
@@ -6,7 +6,7 @@
 
 obj-y := align.o entry.o irq.o coprocessor.o process.o ptrace.o \
 	 setup.o signal.o syscall.o time.o traps.o vectors.o platform.o  \
-	 pci-dma.o io.o
+	 pci-dma.o
 
 obj-$(CONFIG_KGDB) += xtensa-stub.o
 obj-$(CONFIG_PCI) += pci.o
@@ -24,6 +24,7 @@
 # Replicate rules in scripts/Makefile.build
 
 sed-y = -e 's/\*(\(\.[a-z]*it\|\.ref\|\)\.text)/*(\1.literal \1.text)/g'    \
+	-e 's/\.text\.unlikely/.literal.unlikely .text.unlikely/g' \
 	-e 's/\*(\(\.text\.[a-z]*\))/*(\1.literal \1)/g'
 
 quiet_cmd__cpp_lds_S = LDS     $@
diff --git a/arch/xtensa/kernel/io.c b/arch/xtensa/kernel/io.c
deleted file mode 100644
index 5b65269..0000000
--- a/arch/xtensa/kernel/io.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * arch/xtensa/io.c
- *
- * IO primitives
- *
- * 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.
- *
- * Copied from sparc.
- *
- * Chris Zankel <chris@zankel.net>
- *
- */
-
-#include <asm/io.h>
-#include <asm/byteorder.h>
-
-void outsb(unsigned long addr, const void *src, unsigned long count) {
-        while (count) {
-                count -= 1;
-                writeb(*(const char *)src, addr);
-                src += 1;
-                addr += 1;
-        }
-}
-
-void outsw(unsigned long addr, const void *src, unsigned long count) {
-        while (count) {
-                count -= 2;
-                writew(*(const short *)src, addr);
-                src += 2;
-                addr += 2;
-        }
-}
-
-void outsl(unsigned long addr, const void *src, unsigned long count) {
-        while (count) {
-                count -= 4;
-                writel(*(const long *)src, addr);
-                src += 4;
-                addr += 4;
-        }
-}
-
-void insb(unsigned long addr, void *dst, unsigned long count) {
-        while (count) {
-                count -= 1;
-                *(unsigned char *)dst = readb(addr);
-                dst += 1;
-                addr += 1;
-        }
-}
-
-void insw(unsigned long addr, void *dst, unsigned long count) {
-        while (count) {
-                count -= 2;
-                *(unsigned short *)dst = readw(addr);
-                dst += 2;
-                addr += 2;
-        }
-}
-
-void insl(unsigned long addr, void *dst, unsigned long count) {
-        while (count) {
-                count -= 4;
-                /*
-                 * XXX I am sure we are in for an unaligned trap here.
-                 */
-                *(unsigned long *)dst = readl(addr);
-                dst += 4;
-                addr += 4;
-        }
-}
diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c
index 4340ee0..98e77c3 100644
--- a/arch/xtensa/kernel/irq.c
+++ b/arch/xtensa/kernel/irq.c
@@ -84,12 +84,12 @@
 static void xtensa_irq_enable(struct irq_data *d)
 {
 	variant_irq_enable(d->irq);
-	xtensa_irq_unmask(d->irq);
+	xtensa_irq_unmask(d);
 }
 
 static void xtensa_irq_disable(struct irq_data *d)
 {
-	xtensa_irq_mask(d->irq);
+	xtensa_irq_mask(d);
 	variant_irq_disable(d->irq);
 }
 
diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c
index 2783fda..2d9cc6d 100644
--- a/arch/xtensa/kernel/pci-dma.c
+++ b/arch/xtensa/kernel/pci-dma.c
@@ -21,6 +21,7 @@
 #include <linux/string.h>
 #include <linux/pci.h>
 #include <linux/gfp.h>
+#include <linux/module.h>
 #include <asm/io.h>
 #include <asm/cacheflush.h>
 
@@ -62,6 +63,7 @@
 
 	return (void*)uncached;
 }
+EXPORT_SYMBOL(dma_alloc_coherent);
 
 void dma_free_coherent(struct device *hwdev, size_t size,
 			 void *vaddr, dma_addr_t dma_handle)
@@ -73,6 +75,7 @@
 
 	free_pages(addr, get_order(size));
 }
+EXPORT_SYMBOL(dma_free_coherent);
 
 
 void consistent_sync(void *vaddr, size_t size, int direction)
@@ -92,3 +95,4 @@
 		break;
 	}
 }
+EXPORT_SYMBOL(consistent_sync);
diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c
index 54354de..126c188 100644
--- a/arch/xtensa/kernel/pci.c
+++ b/arch/xtensa/kernel/pci.c
@@ -333,7 +333,7 @@
 	int prot = pgprot_val(vma->vm_page_prot);
 
 	/* Set to write-through */
-	prot &= ~_PAGE_NO_CACHE;
+	prot = (prot & _PAGE_CA_MASK) | _PAGE_CA_WT;
 #if 0
 	if (!write_combine)
 		prot |= _PAGE_WRITETHRU;
diff --git a/arch/xtensa/kernel/platform.c b/arch/xtensa/kernel/platform.c
index 1b91a97..97230e4 100644
--- a/arch/xtensa/kernel/platform.c
+++ b/arch/xtensa/kernel/platform.c
@@ -40,8 +40,8 @@
 #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
 _F(void, calibrate_ccount, (void),
 {
-  printk ("ERROR: Cannot calibrate cpu frequency! Assuming 100MHz.\n");
-  ccount_per_jiffy = 100 * (1000000UL/HZ);
+	pr_err("ERROR: Cannot calibrate cpu frequency! Assuming 10MHz.\n");
+	ccount_per_jiffy = 10 * (1000000UL/HZ);
 });
 #endif
 
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
index 17e746f..270360d 100644
--- a/arch/xtensa/kernel/setup.c
+++ b/arch/xtensa/kernel/setup.c
@@ -60,8 +60,6 @@
 #ifdef CONFIG_BLK_DEV_INITRD
 extern void *initrd_start;
 extern void *initrd_end;
-extern void *__initrd_start;
-extern void *__initrd_end;
 int initrd_is_mapped = 0;
 extern int initrd_below_start_ok;
 #endif
@@ -79,10 +77,6 @@
 
 sysmem_info_t __initdata sysmem;
 
-#ifdef CONFIG_BLK_DEV_INITRD
-int initrd_is_mapped;
-#endif
-
 #ifdef CONFIG_MMU
 extern void init_mmu(void);
 #else
@@ -197,12 +191,6 @@
 
 void __init init_arch(bp_tag_t *bp_start)
 {
-
-#ifdef CONFIG_BLK_DEV_INITRD
-	initrd_start = &__initrd_start;
-	initrd_end = &__initrd_end;
-#endif
-
 	sysmem.nr_banks = 0;
 
 #ifdef CONFIG_CMDLINE_BOOL
diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c
index efe4e85..63c566f 100644
--- a/arch/xtensa/kernel/signal.c
+++ b/arch/xtensa/kernel/signal.c
@@ -19,7 +19,6 @@
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/personality.h>
-#include <linux/freezer.h>
 #include <linux/tracehook.h>
 
 #include <asm/ucontext.h>
@@ -527,9 +526,6 @@
 
 void do_notify_resume(struct pt_regs *regs)
 {
-	if (!user_mode(regs))
-		return;
-
 	if (test_thread_flag(TIF_SIGPENDING))
 		do_signal(regs);
 
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S
index ee2e208..255154f 100644
--- a/arch/xtensa/kernel/vmlinux.lds.S
+++ b/arch/xtensa/kernel/vmlinux.lds.S
@@ -222,11 +222,6 @@
   . = ALIGN(0x10);
   .bootstrap : { *(.bootstrap.literal .bootstrap.text .bootstrap.data) }
 
-  . = ALIGN(0x1000);
-  __initrd_start = .;
-  .initrd : { *(.initrd) }
-  __initrd_end = .;
-
   .ResetVector.text XCHAL_RESET_VECTOR_VADDR :
   {
     *(.ResetVector.text)
diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c
index c9a7c5b..a8b9f1f 100644
--- a/arch/xtensa/kernel/xtensa_ksyms.c
+++ b/arch/xtensa/kernel/xtensa_ksyms.c
@@ -39,8 +39,12 @@
 EXPORT_SYMBOL(memset);
 EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(memmove);
+EXPORT_SYMBOL(__strncpy_user);
+EXPORT_SYMBOL(clear_page);
+EXPORT_SYMBOL(copy_page);
 
 EXPORT_SYMBOL(kernel_thread);
+EXPORT_SYMBOL(empty_zero_page);
 
 /*
  * gcc internal math functions
@@ -56,6 +60,7 @@
 extern unsigned int __umodsi3(unsigned int, unsigned int);
 extern unsigned long long __umoddi3(unsigned long long, unsigned long long);
 extern unsigned long long __udivdi3(unsigned long long, unsigned long long);
+extern int __ucmpdi2(int, int);
 
 EXPORT_SYMBOL(__ashldi3);
 EXPORT_SYMBOL(__ashrdi3);
@@ -68,11 +73,31 @@
 EXPORT_SYMBOL(__umodsi3);
 EXPORT_SYMBOL(__udivdi3);
 EXPORT_SYMBOL(__umoddi3);
+EXPORT_SYMBOL(__ucmpdi2);
+
+void __xtensa_libgcc_window_spill(void)
+{
+	BUG();
+}
+EXPORT_SYMBOL(__xtensa_libgcc_window_spill);
+
+unsigned long __sync_fetch_and_and_4(unsigned long *p, unsigned long v)
+{
+	BUG();
+}
+EXPORT_SYMBOL(__sync_fetch_and_and_4);
+
+unsigned long __sync_fetch_and_or_4(unsigned long *p, unsigned long v)
+{
+	BUG();
+}
+EXPORT_SYMBOL(__sync_fetch_and_or_4);
 
 #ifdef CONFIG_NET
 /*
  * Networking support
  */
+EXPORT_SYMBOL(csum_partial);
 EXPORT_SYMBOL(csum_partial_copy_generic);
 #endif /* CONFIG_NET */
 
diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c
index 5a74c53..2c2f710 100644
--- a/arch/xtensa/mm/fault.c
+++ b/arch/xtensa/mm/fault.c
@@ -126,6 +126,7 @@
 			current->min_flt++;
 		if (fault & VM_FAULT_RETRY) {
 			flags &= ~FAULT_FLAG_ALLOW_RETRY;
+			flags |= FAULT_FLAG_TRIED;
 
 			 /* No need to up_read(&mm->mmap_sem) as we would
 			 * have already released it in __lock_page_or_retry
diff --git a/arch/xtensa/platforms/iss/Makefile b/arch/xtensa/platforms/iss/Makefile
index af96e31..b7d1a5c 100644
--- a/arch/xtensa/platforms/iss/Makefile
+++ b/arch/xtensa/platforms/iss/Makefile
@@ -4,5 +4,5 @@
 # "prom monitor" library routines under Linux.
 #
 
-obj-y			= io.o console.o setup.o network.o
-
+obj-y			= console.o setup.o
+obj-$(CONFIG_NET)	+= network.o
diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c
index 2cd3d3a..8ab47ed 100644
--- a/arch/xtensa/platforms/iss/console.c
+++ b/arch/xtensa/platforms/iss/console.c
@@ -33,7 +33,7 @@
 #endif
 
 #define SERIAL_MAX_NUM_LINES 1
-#define SERIAL_TIMER_VALUE (20 * HZ)
+#define SERIAL_TIMER_VALUE (HZ / 10)
 
 static struct tty_driver *serial_driver;
 static struct tty_port serial_port;
@@ -41,19 +41,6 @@
 
 static DEFINE_SPINLOCK(timer_lock);
 
-int errno;
-
-static int __simc (int a, int b, int c, int d, int e, int f) __attribute__((__noinline__));
-static int __simc (int a, int b, int c, int d, int e, int f)
-{
-	int ret;
-	__asm__ __volatile__ ("simcall\n"
-			"mov %0, a2\n"
-			"mov %1, a3\n" : "=a" (ret), "=a" (errno)
-			: : "a2", "a3");
-	return ret;
-}
-
 static char *serial_version = "0.1";
 static char *serial_name = "ISS serial driver";
 
diff --git a/arch/xtensa/platforms/iss/include/platform/serial.h b/arch/xtensa/platforms/iss/include/platform/serial.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/arch/xtensa/platforms/iss/include/platform/serial.h
diff --git a/arch/xtensa/platforms/iss/include/platform/simcall.h b/arch/xtensa/platforms/iss/include/platform/simcall.h
index b7952c0..8c43bfea 100644
--- a/arch/xtensa/platforms/iss/include/platform/simcall.h
+++ b/arch/xtensa/platforms/iss/include/platform/simcall.h
@@ -57,6 +57,59 @@
 #define  XTISS_SELECT_ONE_WRITE   2
 #define  XTISS_SELECT_ONE_EXCEPT  3
 
+static int errno;
+
+static inline int __simc(int a, int b, int c, int d, int e, int f)
+{
+	int ret;
+	register int a1 asm("a2") = a;
+	register int b1 asm("a3") = b;
+	register int c1 asm("a4") = c;
+	register int d1 asm("a5") = d;
+	register int e1 asm("a6") = e;
+	register int f1 asm("a7") = f;
+	__asm__ __volatile__ (
+			"simcall\n"
+			"mov %0, a2\n"
+			"mov %1, a3\n"
+			: "=a" (ret), "=a" (errno), "+r"(a1), "+r"(b1)
+			: "r"(c1), "r"(d1), "r"(e1), "r"(f1)
+			: );
+	return ret;
+}
+
+static inline int simc_open(char *file, int flags, int mode)
+{
+	return __simc(SYS_open, (int) file, flags, mode, 0, 0);
+}
+
+static inline int simc_close(int fd)
+{
+	return __simc(SYS_close, fd, 0, 0, 0, 0);
+}
+
+static inline int simc_ioctl(int fd, int request, void *arg)
+{
+	return __simc(SYS_ioctl, fd, request, (int) arg, 0, 0);
+}
+
+static inline int simc_read(int fd, void *buf, size_t count)
+{
+	return __simc(SYS_read, fd, (int) buf, count, 0, 0);
+}
+
+static inline int simc_write(int fd, void *buf, size_t count)
+{
+	return __simc(SYS_write, fd, (int) buf, count, 0, 0);
+}
+
+static inline int simc_poll(int fd)
+{
+	struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
+
+	return __simc(SYS_select_one, fd, XTISS_SELECT_ONE_READ, (int)&tv,
+			0, 0);
+}
 
 #endif /* _XTENSA_PLATFORM_ISS_SIMCALL_H */
 
diff --git a/arch/xtensa/platforms/iss/io.c b/arch/xtensa/platforms/iss/io.c
deleted file mode 100644
index 571d0b2..0000000
--- a/arch/xtensa/platforms/iss/io.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/* This file isn't really needed right now. */
-
-#if 0
-
-#include <asm/io.h>
-#include <platform/platform-iss/simcall.h>
-
-extern int __simc ();
-
-
-char iss_serial_getc()
-{
-  char c;
-  __simc( SYS_read, 0, &c, 1 );
-  return c;
-}
-
-void iss_serial_putc( char c )
-{
-  __simc( SYS_write, 1, &c, 1 );
-}
-
-void iss_serial_puts( char *s )
-{
-  if( s != 0 && *s != 0 )
-    __simc( SYS_write, 1, s, strlen(s) );
-}
-
-/*#error Need I/O ports to specific hardware!*/
-
-#endif
-
diff --git a/arch/xtensa/platforms/iss/network.c b/arch/xtensa/platforms/iss/network.c
index 7dde244..7d0fea6 100644
--- a/arch/xtensa/platforms/iss/network.c
+++ b/arch/xtensa/platforms/iss/network.c
@@ -101,55 +101,6 @@
 
 };
 
-/* ======================= ISS SIMCALL INTERFACE =========================== */
-
-/* Note: __simc must _not_ be declared inline! */
-
-static int errno;
-
-static int __simc (int a, int b, int c, int d, int e, int f) __attribute__((__noinline__));
-static int __simc (int a, int b, int c, int d, int e, int f)
-{
-	int ret;
-	__asm__ __volatile__ ("simcall\n"
-	    		      "mov %0, a2\n"
-			      "mov %1, a3\n" : "=a" (ret), "=a" (errno)
-			      : : "a2", "a3");
-	return ret;
-}
-
-static int inline simc_open(char *file, int flags, int mode)
-{
-	return __simc(SYS_open, (int) file, flags, mode, 0, 0);
-}
-
-static int inline simc_close(int fd)
-{
-	return __simc(SYS_close, fd, 0, 0, 0, 0);
-}
-
-static int inline simc_ioctl(int fd, int request, void *arg)
-{
-	return __simc(SYS_ioctl, fd, request, (int) arg, 0, 0);
-}
-
-static int inline simc_read(int fd, void *buf, size_t count)
-{
-	return __simc(SYS_read, fd, (int) buf, count, 0, 0);
-}
-
-static int inline simc_write(int fd, void *buf, size_t count)
-{
-	return __simc(SYS_write, fd, (int) buf, count, 0, 0);
-}
-
-static int inline simc_poll(int fd)
-{
-	struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
-
-	return __simc(SYS_select_one, fd, XTISS_SELECT_ONE_READ, (int)&tv,0,0);
-}
-
 /* ================================ HELPERS ================================ */
 
 
diff --git a/arch/xtensa/platforms/iss/setup.c b/arch/xtensa/platforms/iss/setup.c
index f60c8cf..927acf3 100644
--- a/arch/xtensa/platforms/iss/setup.c
+++ b/arch/xtensa/platforms/iss/setup.c
@@ -38,16 +38,22 @@
 
 }
 
+#ifdef CONFIG_PCI
+void platform_pcibios_init(void)
+{
+}
+#endif
+
 void platform_halt(void)
 {
-	printk (" ** Called platform_halt(), looping forever! **\n");
-	while (1);
+	pr_info(" ** Called platform_halt() **\n");
+	__asm__ __volatile__("movi a2, 1\nsimcall\n");
 }
 
 void platform_power_off(void)
 {
-	printk (" ** Called platform_power_off(), looping forever! **\n");
-	while (1);
+	pr_info(" ** Called platform_power_off() **\n");
+	__asm__ __volatile__("movi a2, 1\nsimcall\n");
 }
 void platform_restart(void)
 {
diff --git a/block/blk-core.c b/block/blk-core.c
index d2da641..a33870b 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -606,8 +606,8 @@
 	/*
 	 * A queue starts its life with bypass turned on to avoid
 	 * unnecessary bypass on/off overhead and nasty surprises during
-	 * init.  The initial bypass will be finished at the end of
-	 * blk_init_allocated_queue().
+	 * init.  The initial bypass will be finished when the queue is
+	 * registered by blk_register_queue().
 	 */
 	q->bypass_depth = 1;
 	__set_bit(QUEUE_FLAG_BYPASS, &q->queue_flags);
@@ -694,7 +694,7 @@
 	q->request_fn		= rfn;
 	q->prep_rq_fn		= NULL;
 	q->unprep_rq_fn		= NULL;
-	q->queue_flags		= QUEUE_FLAG_DEFAULT;
+	q->queue_flags		|= QUEUE_FLAG_DEFAULT;
 
 	/* Override internal queue lock with supplied lock pointer */
 	if (lock)
@@ -710,11 +710,6 @@
 	/* init elevator */
 	if (elevator_init(q, NULL))
 		return NULL;
-
-	blk_queue_congestion_threshold(q);
-
-	/* all done, end the initial bypass */
-	blk_queue_bypass_end(q);
 	return q;
 }
 EXPORT_SYMBOL(blk_init_allocated_queue);
@@ -1657,8 +1652,8 @@
 		goto end_io;
 	}
 
-	if (unlikely(!(bio->bi_rw & REQ_DISCARD) &&
-		     nr_sectors > queue_max_hw_sectors(q))) {
+	if (likely(bio_is_rw(bio) &&
+		   nr_sectors > queue_max_hw_sectors(q))) {
 		printk(KERN_ERR "bio too big device %s (%u > %u)\n",
 		       bdevname(bio->bi_bdev, b),
 		       bio_sectors(bio),
@@ -1699,8 +1694,12 @@
 
 	if ((bio->bi_rw & REQ_DISCARD) &&
 	    (!blk_queue_discard(q) ||
-	     ((bio->bi_rw & REQ_SECURE) &&
-	      !blk_queue_secdiscard(q)))) {
+	     ((bio->bi_rw & REQ_SECURE) && !blk_queue_secdiscard(q)))) {
+		err = -EOPNOTSUPP;
+		goto end_io;
+	}
+
+	if (bio->bi_rw & REQ_WRITE_SAME && !bdev_write_same(bio->bi_bdev)) {
 		err = -EOPNOTSUPP;
 		goto end_io;
 	}
@@ -1810,15 +1809,20 @@
  */
 void submit_bio(int rw, struct bio *bio)
 {
-	int count = bio_sectors(bio);
-
 	bio->bi_rw |= rw;
 
 	/*
 	 * If it's a regular read/write or a barrier with data attached,
 	 * go through the normal accounting stuff before submission.
 	 */
-	if (bio_has_data(bio) && !(rw & REQ_DISCARD)) {
+	if (bio_has_data(bio)) {
+		unsigned int count;
+
+		if (unlikely(rw & REQ_WRITE_SAME))
+			count = bdev_logical_block_size(bio->bi_bdev) >> 9;
+		else
+			count = bio_sectors(bio);
+
 		if (rw & WRITE) {
 			count_vm_events(PGPGOUT, count);
 		} else {
@@ -1864,11 +1868,10 @@
  */
 int blk_rq_check_limits(struct request_queue *q, struct request *rq)
 {
-	if (rq->cmd_flags & REQ_DISCARD)
+	if (!rq_mergeable(rq))
 		return 0;
 
-	if (blk_rq_sectors(rq) > queue_max_sectors(q) ||
-	    blk_rq_bytes(rq) > queue_max_hw_sectors(q) << 9) {
+	if (blk_rq_sectors(rq) > blk_queue_get_max_sectors(q, rq->cmd_flags)) {
 		printk(KERN_ERR "%s: over max size limit.\n", __func__);
 		return -EIO;
 	}
@@ -2340,7 +2343,7 @@
 	req->buffer = bio_data(req->bio);
 
 	/* update sector only for requests with clear definition of sector */
-	if (req->cmd_type == REQ_TYPE_FS || (req->cmd_flags & REQ_DISCARD))
+	if (req->cmd_type == REQ_TYPE_FS)
 		req->__sector += total_bytes >> 9;
 
 	/* mixed attributes always follow the first bio */
@@ -2781,16 +2784,10 @@
 	blk_rq_init(NULL, rq);
 
 	__rq_for_each_bio(bio_src, rq_src) {
-		bio = bio_alloc_bioset(gfp_mask, bio_src->bi_max_vecs, bs);
+		bio = bio_clone_bioset(bio_src, gfp_mask, bs);
 		if (!bio)
 			goto free_and_out;
 
-		__bio_clone(bio, bio_src);
-
-		if (bio_integrity(bio_src) &&
-		    bio_integrity_clone(bio, bio_src, gfp_mask, bs))
-			goto free_and_out;
-
 		if (bio_ctr && bio_ctr(bio, bio_src, data))
 			goto free_and_out;
 
@@ -2807,7 +2804,7 @@
 
 free_and_out:
 	if (bio)
-		bio_free(bio, bs);
+		bio_put(bio);
 	blk_rq_unprep_clone(rq);
 
 	return -ENOMEM;
diff --git a/block/blk-lib.c b/block/blk-lib.c
index 19cc761..9373b58 100644
--- a/block/blk-lib.c
+++ b/block/blk-lib.c
@@ -130,6 +130,80 @@
 EXPORT_SYMBOL(blkdev_issue_discard);
 
 /**
+ * blkdev_issue_write_same - queue a write same operation
+ * @bdev:	target blockdev
+ * @sector:	start sector
+ * @nr_sects:	number of sectors to write
+ * @gfp_mask:	memory allocation flags (for bio_alloc)
+ * @page:	page containing data to write
+ *
+ * Description:
+ *    Issue a write same request for the sectors in question.
+ */
+int blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
+			    sector_t nr_sects, gfp_t gfp_mask,
+			    struct page *page)
+{
+	DECLARE_COMPLETION_ONSTACK(wait);
+	struct request_queue *q = bdev_get_queue(bdev);
+	unsigned int max_write_same_sectors;
+	struct bio_batch bb;
+	struct bio *bio;
+	int ret = 0;
+
+	if (!q)
+		return -ENXIO;
+
+	max_write_same_sectors = q->limits.max_write_same_sectors;
+
+	if (max_write_same_sectors == 0)
+		return -EOPNOTSUPP;
+
+	atomic_set(&bb.done, 1);
+	bb.flags = 1 << BIO_UPTODATE;
+	bb.wait = &wait;
+
+	while (nr_sects) {
+		bio = bio_alloc(gfp_mask, 1);
+		if (!bio) {
+			ret = -ENOMEM;
+			break;
+		}
+
+		bio->bi_sector = sector;
+		bio->bi_end_io = bio_batch_end_io;
+		bio->bi_bdev = bdev;
+		bio->bi_private = &bb;
+		bio->bi_vcnt = 1;
+		bio->bi_io_vec->bv_page = page;
+		bio->bi_io_vec->bv_offset = 0;
+		bio->bi_io_vec->bv_len = bdev_logical_block_size(bdev);
+
+		if (nr_sects > max_write_same_sectors) {
+			bio->bi_size = max_write_same_sectors << 9;
+			nr_sects -= max_write_same_sectors;
+			sector += max_write_same_sectors;
+		} else {
+			bio->bi_size = nr_sects << 9;
+			nr_sects = 0;
+		}
+
+		atomic_inc(&bb.done);
+		submit_bio(REQ_WRITE | REQ_WRITE_SAME, bio);
+	}
+
+	/* Wait for bios in-flight */
+	if (!atomic_dec_and_test(&bb.done))
+		wait_for_completion(&wait);
+
+	if (!test_bit(BIO_UPTODATE, &bb.flags))
+		ret = -ENOTSUPP;
+
+	return ret;
+}
+EXPORT_SYMBOL(blkdev_issue_write_same);
+
+/**
  * blkdev_issue_zeroout - generate number of zero filed write bios
  * @bdev:	blockdev to issue
  * @sector:	start sector
@@ -140,7 +214,7 @@
  *  Generate and issue number of bios with zerofiled pages.
  */
 
-int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
+int __blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
 			sector_t nr_sects, gfp_t gfp_mask)
 {
 	int ret;
@@ -190,4 +264,32 @@
 
 	return ret;
 }
+
+/**
+ * blkdev_issue_zeroout - zero-fill a block range
+ * @bdev:	blockdev to write
+ * @sector:	start sector
+ * @nr_sects:	number of sectors to write
+ * @gfp_mask:	memory allocation flags (for bio_alloc)
+ *
+ * Description:
+ *  Generate and issue number of bios with zerofiled pages.
+ */
+
+int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
+			 sector_t nr_sects, gfp_t gfp_mask)
+{
+	if (bdev_write_same(bdev)) {
+		unsigned char bdn[BDEVNAME_SIZE];
+
+		if (!blkdev_issue_write_same(bdev, sector, nr_sects, gfp_mask,
+					     ZERO_PAGE(0)))
+			return 0;
+
+		bdevname(bdev, bdn);
+		pr_err("%s: WRITE SAME failed. Manually zeroing.\n", bdn);
+	}
+
+	return __blkdev_issue_zeroout(bdev, sector, nr_sects, gfp_mask);
+}
 EXPORT_SYMBOL(blkdev_issue_zeroout);
diff --git a/block/blk-merge.c b/block/blk-merge.c
index e76279e..936a110 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -275,14 +275,8 @@
 int ll_back_merge_fn(struct request_queue *q, struct request *req,
 		     struct bio *bio)
 {
-	unsigned short max_sectors;
-
-	if (unlikely(req->cmd_type == REQ_TYPE_BLOCK_PC))
-		max_sectors = queue_max_hw_sectors(q);
-	else
-		max_sectors = queue_max_sectors(q);
-
-	if (blk_rq_sectors(req) + bio_sectors(bio) > max_sectors) {
+	if (blk_rq_sectors(req) + bio_sectors(bio) >
+	    blk_rq_get_max_sectors(req)) {
 		req->cmd_flags |= REQ_NOMERGE;
 		if (req == q->last_merge)
 			q->last_merge = NULL;
@@ -299,15 +293,8 @@
 int ll_front_merge_fn(struct request_queue *q, struct request *req,
 		      struct bio *bio)
 {
-	unsigned short max_sectors;
-
-	if (unlikely(req->cmd_type == REQ_TYPE_BLOCK_PC))
-		max_sectors = queue_max_hw_sectors(q);
-	else
-		max_sectors = queue_max_sectors(q);
-
-
-	if (blk_rq_sectors(req) + bio_sectors(bio) > max_sectors) {
+	if (blk_rq_sectors(req) + bio_sectors(bio) >
+	    blk_rq_get_max_sectors(req)) {
 		req->cmd_flags |= REQ_NOMERGE;
 		if (req == q->last_merge)
 			q->last_merge = NULL;
@@ -338,7 +325,8 @@
 	/*
 	 * Will it become too large?
 	 */
-	if ((blk_rq_sectors(req) + blk_rq_sectors(next)) > queue_max_sectors(q))
+	if ((blk_rq_sectors(req) + blk_rq_sectors(next)) >
+	    blk_rq_get_max_sectors(req))
 		return 0;
 
 	total_phys_segments = req->nr_phys_segments + next->nr_phys_segments;
@@ -417,16 +405,7 @@
 	if (!rq_mergeable(req) || !rq_mergeable(next))
 		return 0;
 
-	/*
-	 * Don't merge file system requests and discard requests
-	 */
-	if ((req->cmd_flags & REQ_DISCARD) != (next->cmd_flags & REQ_DISCARD))
-		return 0;
-
-	/*
-	 * Don't merge discard requests and secure discard requests
-	 */
-	if ((req->cmd_flags & REQ_SECURE) != (next->cmd_flags & REQ_SECURE))
+	if (!blk_check_merge_flags(req->cmd_flags, next->cmd_flags))
 		return 0;
 
 	/*
@@ -440,6 +419,10 @@
 	    || next->special)
 		return 0;
 
+	if (req->cmd_flags & REQ_WRITE_SAME &&
+	    !blk_write_same_mergeable(req->bio, next->bio))
+		return 0;
+
 	/*
 	 * If we are allowed to merge, then append bio list
 	 * from next to rq and release next. merge_requests_fn
@@ -521,15 +504,10 @@
 
 bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
 {
-	if (!rq_mergeable(rq))
+	if (!rq_mergeable(rq) || !bio_mergeable(bio))
 		return false;
 
-	/* don't merge file system requests and discard requests */
-	if ((bio->bi_rw & REQ_DISCARD) != (rq->bio->bi_rw & REQ_DISCARD))
-		return false;
-
-	/* don't merge discard requests and secure discard requests */
-	if ((bio->bi_rw & REQ_SECURE) != (rq->bio->bi_rw & REQ_SECURE))
+	if (!blk_check_merge_flags(rq->cmd_flags, bio->bi_rw))
 		return false;
 
 	/* different data direction or already started, don't merge */
@@ -544,6 +522,11 @@
 	if (bio_integrity(bio) != blk_integrity_rq(rq))
 		return false;
 
+	/* must be using the same buffer */
+	if (rq->cmd_flags & REQ_WRITE_SAME &&
+	    !blk_write_same_mergeable(rq->bio, bio))
+		return false;
+
 	return true;
 }
 
diff --git a/block/blk-settings.c b/block/blk-settings.c
index 565a678..779bb76 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -113,6 +113,7 @@
 	lim->seg_boundary_mask = BLK_SEG_BOUNDARY_MASK;
 	lim->max_segment_size = BLK_MAX_SEGMENT_SIZE;
 	lim->max_sectors = lim->max_hw_sectors = BLK_SAFE_MAX_SECTORS;
+	lim->max_write_same_sectors = 0;
 	lim->max_discard_sectors = 0;
 	lim->discard_granularity = 0;
 	lim->discard_alignment = 0;
@@ -144,6 +145,7 @@
 	lim->max_segments = USHRT_MAX;
 	lim->max_hw_sectors = UINT_MAX;
 	lim->max_sectors = UINT_MAX;
+	lim->max_write_same_sectors = UINT_MAX;
 }
 EXPORT_SYMBOL(blk_set_stacking_limits);
 
@@ -286,6 +288,18 @@
 EXPORT_SYMBOL(blk_queue_max_discard_sectors);
 
 /**
+ * blk_queue_max_write_same_sectors - set max sectors for a single write same
+ * @q:  the request queue for the device
+ * @max_write_same_sectors: maximum number of sectors to write per command
+ **/
+void blk_queue_max_write_same_sectors(struct request_queue *q,
+				      unsigned int max_write_same_sectors)
+{
+	q->limits.max_write_same_sectors = max_write_same_sectors;
+}
+EXPORT_SYMBOL(blk_queue_max_write_same_sectors);
+
+/**
  * blk_queue_max_segments - set max hw segments for a request for this queue
  * @q:  the request queue for the device
  * @max_segments:  max number of segments
@@ -510,6 +524,8 @@
 
 	t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors);
 	t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors);
+	t->max_write_same_sectors = min(t->max_write_same_sectors,
+					b->max_write_same_sectors);
 	t->bounce_pfn = min_not_zero(t->bounce_pfn, b->bounce_pfn);
 
 	t->seg_boundary_mask = min_not_zero(t->seg_boundary_mask,
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 9628b29..ce62046 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -26,9 +26,15 @@
 static ssize_t
 queue_var_store(unsigned long *var, const char *page, size_t count)
 {
-	char *p = (char *) page;
+	int err;
+	unsigned long v;
 
-	*var = simple_strtoul(p, &p, 10);
+	err = strict_strtoul(page, 10, &v);
+	if (err || v > UINT_MAX)
+		return -EINVAL;
+
+	*var = v;
+
 	return count;
 }
 
@@ -48,6 +54,9 @@
 		return -EINVAL;
 
 	ret = queue_var_store(&nr, page, count);
+	if (ret < 0)
+		return ret;
+
 	if (nr < BLKDEV_MIN_RQ)
 		nr = BLKDEV_MIN_RQ;
 
@@ -102,6 +111,9 @@
 	unsigned long ra_kb;
 	ssize_t ret = queue_var_store(&ra_kb, page, count);
 
+	if (ret < 0)
+		return ret;
+
 	q->backing_dev_info.ra_pages = ra_kb >> (PAGE_CACHE_SHIFT - 10);
 
 	return ret;
@@ -168,6 +180,13 @@
 	return queue_var_show(queue_discard_zeroes_data(q), page);
 }
 
+static ssize_t queue_write_same_max_show(struct request_queue *q, char *page)
+{
+	return sprintf(page, "%llu\n",
+		(unsigned long long)q->limits.max_write_same_sectors << 9);
+}
+
+
 static ssize_t
 queue_max_sectors_store(struct request_queue *q, const char *page, size_t count)
 {
@@ -176,6 +195,9 @@
 			page_kb = 1 << (PAGE_CACHE_SHIFT - 10);
 	ssize_t ret = queue_var_store(&max_sectors_kb, page, count);
 
+	if (ret < 0)
+		return ret;
+
 	if (max_sectors_kb > max_hw_sectors_kb || max_sectors_kb < page_kb)
 		return -EINVAL;
 
@@ -236,6 +258,9 @@
 	unsigned long nm;
 	ssize_t ret = queue_var_store(&nm, page, count);
 
+	if (ret < 0)
+		return ret;
+
 	spin_lock_irq(q->queue_lock);
 	queue_flag_clear(QUEUE_FLAG_NOMERGES, q);
 	queue_flag_clear(QUEUE_FLAG_NOXMERGES, q);
@@ -264,6 +289,9 @@
 	unsigned long val;
 
 	ret = queue_var_store(&val, page, count);
+	if (ret < 0)
+		return ret;
+
 	spin_lock_irq(q->queue_lock);
 	if (val == 2) {
 		queue_flag_set(QUEUE_FLAG_SAME_COMP, q);
@@ -364,6 +392,11 @@
 	.show = queue_discard_zeroes_data_show,
 };
 
+static struct queue_sysfs_entry queue_write_same_max_entry = {
+	.attr = {.name = "write_same_max_bytes", .mode = S_IRUGO },
+	.show = queue_write_same_max_show,
+};
+
 static struct queue_sysfs_entry queue_nonrot_entry = {
 	.attr = {.name = "rotational", .mode = S_IRUGO | S_IWUSR },
 	.show = queue_show_nonrot,
@@ -411,6 +444,7 @@
 	&queue_discard_granularity_entry.attr,
 	&queue_discard_max_entry.attr,
 	&queue_discard_zeroes_data_entry.attr,
+	&queue_write_same_max_entry.attr,
 	&queue_nonrot_entry.attr,
 	&queue_nomerges_entry.attr,
 	&queue_rq_affinity_entry.attr,
@@ -527,6 +561,12 @@
 	if (WARN_ON(!q))
 		return -ENXIO;
 
+	/*
+	 * Initialization must be complete by now.  Finish the initial
+	 * bypass from queue allocation.
+	 */
+	blk_queue_bypass_end(q);
+
 	ret = blk_trace_init_sysfs(dev);
 	if (ret)
 		return ret;
diff --git a/block/blk-tag.c b/block/blk-tag.c
index 4af6f5c..cc345e1 100644
--- a/block/blk-tag.c
+++ b/block/blk-tag.c
@@ -186,7 +186,8 @@
 		tags = __blk_queue_init_tags(q, depth);
 
 		if (!tags)
-			goto fail;
+			return -ENOMEM;
+
 	} else if (q->queue_tags) {
 		rc = blk_queue_resize_tags(q, depth);
 		if (rc)
@@ -203,9 +204,6 @@
 	queue_flag_set_unlocked(QUEUE_FLAG_QUEUED, q);
 	INIT_LIST_HEAD(&q->tag_busy_list);
 	return 0;
-fail:
-	kfree(tags);
-	return -ENOMEM;
 }
 EXPORT_SYMBOL(blk_queue_init_tags);
 
diff --git a/block/blk.h b/block/blk.h
index 2a0ea32..ca51543 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -171,14 +171,13 @@
  *
  *	a) it's attached to a gendisk, and
  *	b) the queue had IO stats enabled when this request was started, and
- *	c) it's a file system request or a discard request
+ *	c) it's a file system request
  */
 static inline int blk_do_io_stat(struct request *rq)
 {
 	return rq->rq_disk &&
 	       (rq->cmd_flags & REQ_IO_STAT) &&
-	       (rq->cmd_type == REQ_TYPE_FS ||
-	        (rq->cmd_flags & REQ_DISCARD));
+		(rq->cmd_type == REQ_TYPE_FS);
 }
 
 /*
diff --git a/block/elevator.c b/block/elevator.c
index 6a55d41..9b1d42b 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -562,8 +562,7 @@
 
 	if (rq->cmd_flags & REQ_SOFTBARRIER) {
 		/* barriers are scheduling boundary, update end_sector */
-		if (rq->cmd_type == REQ_TYPE_FS ||
-		    (rq->cmd_flags & REQ_DISCARD)) {
+		if (rq->cmd_type == REQ_TYPE_FS) {
 			q->end_sector = rq_end_sector(rq);
 			q->boundary_rq = rq;
 		}
@@ -605,8 +604,7 @@
 		if (elv_attempt_insert_merge(q, rq))
 			break;
 	case ELEVATOR_INSERT_SORT:
-		BUG_ON(rq->cmd_type != REQ_TYPE_FS &&
-		       !(rq->cmd_flags & REQ_DISCARD));
+		BUG_ON(rq->cmd_type != REQ_TYPE_FS);
 		rq->cmd_flags |= REQ_SORTED;
 		q->nr_sorted++;
 		if (rq_mergeable(rq)) {
diff --git a/block/ioctl.c b/block/ioctl.c
index 4a85096..a31d91d9b 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -185,6 +185,22 @@
 	return blkdev_issue_discard(bdev, start, len, GFP_KERNEL, flags);
 }
 
+static int blk_ioctl_zeroout(struct block_device *bdev, uint64_t start,
+			     uint64_t len)
+{
+	if (start & 511)
+		return -EINVAL;
+	if (len & 511)
+		return -EINVAL;
+	start >>= 9;
+	len >>= 9;
+
+	if (start + len > (i_size_read(bdev->bd_inode) >> 9))
+		return -EINVAL;
+
+	return blkdev_issue_zeroout(bdev, start, len, GFP_KERNEL);
+}
+
 static int put_ushort(unsigned long arg, unsigned short val)
 {
 	return put_user(val, (unsigned short __user *)arg);
@@ -300,6 +316,17 @@
 		return blk_ioctl_discard(bdev, range[0], range[1],
 					 cmd == BLKSECDISCARD);
 	}
+	case BLKZEROOUT: {
+		uint64_t range[2];
+
+		if (!(mode & FMODE_WRITE))
+			return -EBADF;
+
+		if (copy_from_user(range, (void __user *)arg, sizeof(range)))
+			return -EFAULT;
+
+		return blk_ioctl_zeroout(bdev, range[0], range[1]);
+	}
 
 	case HDIO_GETGEO: {
 		struct hd_geometry geo;
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile
index 0a1b343..7f1d407 100644
--- a/drivers/acpi/acpica/Makefile
+++ b/drivers/acpi/acpica/Makefile
@@ -158,5 +158,6 @@
 	utresrc.o	\
 	utstate.o	\
 	utxface.o	\
+	utxfinit.o	\
 	utxferror.o	\
 	utxfmutex.o
diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h
index 5de4ec7..d902d31 100644
--- a/drivers/acpi/acpica/achware.h
+++ b/drivers/acpi/acpica/achware.h
@@ -110,8 +110,7 @@
 /*
  * hwgpe - GPE support
  */
-u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info,
-			     struct acpi_gpe_register_info *gpe_register_info);
+u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info);
 
 acpi_status
 acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action);
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index cc80fe1..c816ee6 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -707,15 +707,18 @@
 	u8                              disasm_opcode;  /* Subtype used for disassembly */\
 	char                            aml_op_name[16])	/* Op name (debug only) */
 
-#define ACPI_DASM_BUFFER                0x00
-#define ACPI_DASM_RESOURCE              0x01
-#define ACPI_DASM_STRING                0x02
-#define ACPI_DASM_UNICODE               0x03
-#define ACPI_DASM_EISAID                0x04
-#define ACPI_DASM_MATCHOP               0x05
-#define ACPI_DASM_LNOT_PREFIX           0x06
-#define ACPI_DASM_LNOT_SUFFIX           0x07
-#define ACPI_DASM_IGNORE                0x08
+/* Flags for disasm_flags field above */
+
+#define ACPI_DASM_BUFFER                0x00	/* Buffer is a simple data buffer */
+#define ACPI_DASM_RESOURCE              0x01	/* Buffer is a Resource Descriptor */
+#define ACPI_DASM_STRING                0x02	/* Buffer is a ASCII string */
+#define ACPI_DASM_UNICODE               0x03	/* Buffer is a Unicode string */
+#define ACPI_DASM_PLD_METHOD            0x04	/* Buffer is a _PLD method bit-packed buffer */
+#define ACPI_DASM_EISAID                0x05	/* Integer is an EISAID */
+#define ACPI_DASM_MATCHOP               0x06	/* Parent opcode is a Match() operator */
+#define ACPI_DASM_LNOT_PREFIX           0x07	/* Start of a Lnot_equal (etc.) pair of opcodes */
+#define ACPI_DASM_LNOT_SUFFIX           0x08	/* End  of a Lnot_equal (etc.) pair of opcodes */
+#define ACPI_DASM_IGNORE                0x09	/* Not used at this time */
 
 /*
  * Generic operation (for example:  If, While, Store)
@@ -932,6 +935,7 @@
 #define ACPI_OSI_WIN_VISTA_SP1          0x09
 #define ACPI_OSI_WIN_VISTA_SP2          0x0A
 #define ACPI_OSI_WIN_7                  0x0B
+#define ACPI_OSI_WIN_8                  0x0C
 
 #define ACPI_ALWAYS_ILLEGAL             0x00
 
@@ -1024,6 +1028,7 @@
  ****************************************************************************/
 
 struct acpi_db_method_info {
+	acpi_handle method;
 	acpi_handle main_thread_gate;
 	acpi_handle thread_complete_gate;
 	acpi_thread_id *threads;
diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h
index 832b619..a7f68c4 100644
--- a/drivers/acpi/acpica/acmacros.h
+++ b/drivers/acpi/acpica/acmacros.h
@@ -277,10 +277,33 @@
 
 /* Bitfields within ACPI registers */
 
-#define ACPI_REGISTER_PREPARE_BITS(val, pos, mask)      ((val << pos) & mask)
-#define ACPI_REGISTER_INSERT_VALUE(reg, pos, mask, val)  reg = (reg & (~(mask))) | ACPI_REGISTER_PREPARE_BITS(val, pos, mask)
+#define ACPI_REGISTER_PREPARE_BITS(val, pos, mask) \
+	((val << pos) & mask)
 
-#define ACPI_INSERT_BITS(target, mask, source)          target = ((target & (~(mask))) | (source & mask))
+#define ACPI_REGISTER_INSERT_VALUE(reg, pos, mask, val) \
+	reg = (reg & (~(mask))) | ACPI_REGISTER_PREPARE_BITS(val, pos, mask)
+
+#define ACPI_INSERT_BITS(target, mask, source) \
+	target = ((target & (~(mask))) | (source & mask))
+
+/* Generic bitfield macros and masks */
+
+#define ACPI_GET_BITS(source_ptr, position, mask) \
+	((*source_ptr >> position) & mask)
+
+#define ACPI_SET_BITS(target_ptr, position, mask, value) \
+	(*target_ptr |= ((value & mask) << position))
+
+#define ACPI_1BIT_MASK      0x00000001
+#define ACPI_2BIT_MASK      0x00000003
+#define ACPI_3BIT_MASK      0x00000007
+#define ACPI_4BIT_MASK      0x0000000F
+#define ACPI_5BIT_MASK      0x0000001F
+#define ACPI_6BIT_MASK      0x0000003F
+#define ACPI_7BIT_MASK      0x0000007F
+#define ACPI_8BIT_MASK      0x000000FF
+#define ACPI_16BIT_MASK     0x0000FFFF
+#define ACPI_24BIT_MASK     0x00FFFFFF
 
 /*
  * An object of type struct acpi_namespace_node can appear in some contexts
diff --git a/drivers/acpi/acpica/dswload.c b/drivers/acpi/acpica/dswload.c
index 552aa3a..5575100 100644
--- a/drivers/acpi/acpica/dswload.c
+++ b/drivers/acpi/acpica/dswload.c
@@ -230,6 +230,20 @@
 			walk_state->scope_info->common.value = ACPI_TYPE_ANY;
 			break;
 
+		case ACPI_TYPE_METHOD:
+
+			/*
+			 * Allow scope change to root during execution of module-level
+			 * code. Root is typed METHOD during this time.
+			 */
+			if ((node == acpi_gbl_root_node) &&
+			    (walk_state->
+			     parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
+				break;
+			}
+
+			/*lint -fallthrough */
+
 		default:
 
 			/* All other types are an error */
diff --git a/drivers/acpi/acpica/dswload2.c b/drivers/acpi/acpica/dswload2.c
index ae71477..89c0114 100644
--- a/drivers/acpi/acpica/dswload2.c
+++ b/drivers/acpi/acpica/dswload2.c
@@ -230,6 +230,20 @@
 			walk_state->scope_info->common.value = ACPI_TYPE_ANY;
 			break;
 
+		case ACPI_TYPE_METHOD:
+
+			/*
+			 * Allow scope change to root during execution of module-level
+			 * code. Root is typed METHOD during this time.
+			 */
+			if ((node == acpi_gbl_root_node) &&
+			    (walk_state->
+			     parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
+				break;
+			}
+
+			/*lint -fallthrough */
+
 		default:
 
 			/* All other types are an error */
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c
index afbd5cb..ef0193d 100644
--- a/drivers/acpi/acpica/evgpe.c
+++ b/drivers/acpi/acpica/evgpe.c
@@ -80,8 +80,7 @@
 		return_ACPI_STATUS(AE_NOT_EXIST);
 	}
 
-	register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info,
-						gpe_register_info);
+	register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
 
 	/* Clear the run bit up front */
 
@@ -379,6 +378,18 @@
 			 */
 			if (!(gpe_register_info->enable_for_run |
 			      gpe_register_info->enable_for_wake)) {
+				ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
+						  "Ignore disabled registers for GPE%02X-GPE%02X: "
+						  "RunEnable=%02X, WakeEnable=%02X\n",
+						  gpe_register_info->
+						  base_gpe_number,
+						  gpe_register_info->
+						  base_gpe_number +
+						  (ACPI_GPE_REGISTER_WIDTH - 1),
+						  gpe_register_info->
+						  enable_for_run,
+						  gpe_register_info->
+						  enable_for_wake));
 				continue;
 			}
 
@@ -401,9 +412,14 @@
 			}
 
 			ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
-					  "Read GPE Register at GPE%02X: Status=%02X, Enable=%02X\n",
+					  "Read registers for GPE%02X-GPE%02X: Status=%02X, Enable=%02X, "
+					  "RunEnable=%02X, WakeEnable=%02X\n",
 					  gpe_register_info->base_gpe_number,
-					  status_reg, enable_reg));
+					  gpe_register_info->base_gpe_number +
+					  (ACPI_GPE_REGISTER_WIDTH - 1),
+					  status_reg, enable_reg,
+					  gpe_register_info->enable_for_run,
+					  gpe_register_info->enable_for_wake));
 
 			/* Check if there is anything active at all in this register */
 
diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c
index 6affbdb..87c5f23 100644
--- a/drivers/acpi/acpica/evxfgpe.c
+++ b/drivers/acpi/acpica/evxfgpe.c
@@ -357,8 +357,7 @@
 		goto unlock_and_exit;
 	}
 
-	register_bit =
-	    acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
+	register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
 
 	/* Perform the action */
 
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c
index 25bd28c..db40765 100644
--- a/drivers/acpi/acpica/hwgpe.c
+++ b/drivers/acpi/acpica/hwgpe.c
@@ -60,7 +60,6 @@
  * FUNCTION:	acpi_hw_get_gpe_register_bit
  *
  * PARAMETERS:	gpe_event_info	    - Info block for the GPE
- *		gpe_register_info   - Info block for the GPE register
  *
  * RETURN:	Register mask with a one in the GPE bit position
  *
@@ -69,11 +68,10 @@
  *
  ******************************************************************************/
 
-u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info,
-			     struct acpi_gpe_register_info *gpe_register_info)
+u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info)
 {
 	return (u32)1 << (gpe_event_info->gpe_number -
-				gpe_register_info->base_gpe_number);
+		 gpe_event_info->register_info->base_gpe_number);
 }
 
 /******************************************************************************
@@ -115,8 +113,7 @@
 
 	/* Set or clear just the bit that corresponds to this GPE */
 
-	register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info,
-						gpe_register_info);
+	register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
 	switch (action) {
 	case ACPI_GPE_CONDITIONAL_ENABLE:
 
@@ -178,8 +175,7 @@
 	 * Write a one to the appropriate bit in the status register to
 	 * clear this GPE.
 	 */
-	register_bit =
-	    acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info);
+	register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
 
 	status = acpi_hw_write(register_bit,
 			       &gpe_register_info->status_address);
@@ -222,8 +218,7 @@
 
 	/* Get the register bitmask for this GPE */
 
-	register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info,
-						gpe_register_info);
+	register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
 
 	/* GPE currently enabled? (enabled for runtime?) */
 
diff --git a/drivers/acpi/acpica/hwxfsleep.c b/drivers/acpi/acpica/hwxfsleep.c
index 1f165a7..0ff1ece 100644
--- a/drivers/acpi/acpica/hwxfsleep.c
+++ b/drivers/acpi/acpica/hwxfsleep.c
@@ -381,7 +381,6 @@
  * FUNCTION:    acpi_leave_sleep_state_prep
  *
  * PARAMETERS:  sleep_state         - Which sleep state we are exiting
- *              flags               - ACPI_EXECUTE_BFS to run optional method
  *
  * RETURN:      Status
  *
diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c
index 7ee4e6ae..2526aaf 100644
--- a/drivers/acpi/acpica/nsdump.c
+++ b/drivers/acpi/acpica/nsdump.c
@@ -264,7 +264,7 @@
 		switch (type) {
 		case ACPI_TYPE_PROCESSOR:
 
-			acpi_os_printf("ID %X Len %.4X Addr %p\n",
+			acpi_os_printf("ID %02X Len %02X Addr %p\n",
 				       obj_desc->processor.proc_id,
 				       obj_desc->processor.length,
 				       ACPI_CAST_PTR(void,
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index 74f97d7..70f9d78 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -350,6 +350,7 @@
 acpi_status acpi_tb_resize_root_table_list(void)
 {
 	struct acpi_table_desc *tables;
+	u32 table_count;
 
 	ACPI_FUNCTION_TRACE(tb_resize_root_table_list);
 
@@ -363,8 +364,13 @@
 
 	/* Increase the Table Array size */
 
-	tables = ACPI_ALLOCATE_ZEROED(((acpi_size) acpi_gbl_root_table_list.
-				       max_table_count +
+	if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
+		table_count = acpi_gbl_root_table_list.max_table_count;
+	} else {
+		table_count = acpi_gbl_root_table_list.current_table_count;
+	}
+
+	tables = ACPI_ALLOCATE_ZEROED(((acpi_size) table_count +
 				       ACPI_ROOT_TABLE_SIZE_INCREMENT) *
 				      sizeof(struct acpi_table_desc));
 	if (!tables) {
@@ -377,8 +383,8 @@
 
 	if (acpi_gbl_root_table_list.tables) {
 		ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables,
-			    (acpi_size) acpi_gbl_root_table_list.
-			    max_table_count * sizeof(struct acpi_table_desc));
+			    (acpi_size) table_count *
+			    sizeof(struct acpi_table_desc));
 
 		if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) {
 			ACPI_FREE(acpi_gbl_root_table_list.tables);
@@ -386,9 +392,9 @@
 	}
 
 	acpi_gbl_root_table_list.tables = tables;
-	acpi_gbl_root_table_list.max_table_count +=
-	    ACPI_ROOT_TABLE_SIZE_INCREMENT;
-	acpi_gbl_root_table_list.flags |= (u8)ACPI_ROOT_ORIGIN_ALLOCATED;
+	acpi_gbl_root_table_list.max_table_count =
+	    table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT;
+	acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
 
 	return_ACPI_STATUS(AE_OK);
 }
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
index 29e51bc..2110126 100644
--- a/drivers/acpi/acpica/tbxface.c
+++ b/drivers/acpi/acpica/tbxface.c
@@ -159,14 +159,12 @@
  * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the
  *              root list from the previously provided scratch area. Should
  *              be called once dynamic memory allocation is available in the
- *              kernel
+ *              kernel.
  *
  ******************************************************************************/
 acpi_status acpi_reallocate_root_table(void)
 {
-	struct acpi_table_desc *tables;
-	acpi_size new_size;
-	acpi_size current_size;
+	acpi_status status;
 
 	ACPI_FUNCTION_TRACE(acpi_reallocate_root_table);
 
@@ -178,39 +176,10 @@
 		return_ACPI_STATUS(AE_SUPPORT);
 	}
 
-	/*
-	 * Get the current size of the root table and add the default
-	 * increment to create the new table size.
-	 */
-	current_size = (acpi_size)
-	    acpi_gbl_root_table_list.current_table_count *
-	    sizeof(struct acpi_table_desc);
+	acpi_gbl_root_table_list.flags |= ACPI_ROOT_ALLOW_RESIZE;
 
-	new_size = current_size +
-	    (ACPI_ROOT_TABLE_SIZE_INCREMENT * sizeof(struct acpi_table_desc));
-
-	/* Create new array and copy the old array */
-
-	tables = ACPI_ALLOCATE_ZEROED(new_size);
-	if (!tables) {
-		return_ACPI_STATUS(AE_NO_MEMORY);
-	}
-
-	ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, current_size);
-
-	/*
-	 * Update the root table descriptor. The new size will be the current
-	 * number of tables plus the increment, independent of the reserved
-	 * size of the original table list.
-	 */
-	acpi_gbl_root_table_list.tables = tables;
-	acpi_gbl_root_table_list.max_table_count =
-	    acpi_gbl_root_table_list.current_table_count +
-	    ACPI_ROOT_TABLE_SIZE_INCREMENT;
-	acpi_gbl_root_table_list.flags =
-	    ACPI_ROOT_ORIGIN_ALLOCATED | ACPI_ROOT_ALLOW_RESIZE;
-
-	return_ACPI_STATUS(AE_OK);
+	status = acpi_tb_resize_root_table_list();
+	return_ACPI_STATUS(status);
 }
 
 /*******************************************************************************
diff --git a/drivers/acpi/acpica/utosi.c b/drivers/acpi/acpica/utosi.c
index 34ef0bd..676285d 100644
--- a/drivers/acpi/acpica/utosi.c
+++ b/drivers/acpi/acpica/utosi.c
@@ -73,6 +73,7 @@
 	{"Windows 2006 SP1", NULL, 0, ACPI_OSI_WIN_VISTA_SP1},	/* Windows Vista SP1 - Added 09/2009 */
 	{"Windows 2006 SP2", NULL, 0, ACPI_OSI_WIN_VISTA_SP2},	/* Windows Vista SP2 - Added 09/2010 */
 	{"Windows 2009", NULL, 0, ACPI_OSI_WIN_7},	/* Windows 7 and Server 2008 R2 - Added 09/2009 */
+	{"Windows 2012", NULL, 0, ACPI_OSI_WIN_8},	/* Windows 8 and Server 2012 - Added 08/2012 */
 
 	/* Feature Group Strings */
 
diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c
index 534179f..b09632b 100644
--- a/drivers/acpi/acpica/utxface.c
+++ b/drivers/acpi/acpica/utxface.c
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Module Name: utxface - External interfaces for "global" ACPI functions
+ * Module Name: utxface - External interfaces, miscellaneous utility functions
  *
  *****************************************************************************/
 
@@ -53,271 +53,6 @@
 #define _COMPONENT          ACPI_UTILITIES
 ACPI_MODULE_NAME("utxface")
 
-#ifndef ACPI_ASL_COMPILER
-/*******************************************************************************
- *
- * FUNCTION:    acpi_initialize_subsystem
- *
- * PARAMETERS:  None
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Initializes all global variables.  This is the first function
- *              called, so any early initialization belongs here.
- *
- ******************************************************************************/
-acpi_status __init acpi_initialize_subsystem(void)
-{
-	acpi_status status;
-
-	ACPI_FUNCTION_TRACE(acpi_initialize_subsystem);
-
-	acpi_gbl_startup_flags = ACPI_SUBSYSTEM_INITIALIZE;
-	ACPI_DEBUG_EXEC(acpi_ut_init_stack_ptr_trace());
-
-	/* Initialize the OS-Dependent layer */
-
-	status = acpi_os_initialize();
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status, "During OSL initialization"));
-		return_ACPI_STATUS(status);
-	}
-
-	/* Initialize all globals used by the subsystem */
-
-	status = acpi_ut_init_globals();
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status,
-				"During initialization of globals"));
-		return_ACPI_STATUS(status);
-	}
-
-	/* Create the default mutex objects */
-
-	status = acpi_ut_mutex_initialize();
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status,
-				"During Global Mutex creation"));
-		return_ACPI_STATUS(status);
-	}
-
-	/*
-	 * Initialize the namespace manager and
-	 * the root of the namespace tree
-	 */
-	status = acpi_ns_root_initialize();
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status,
-				"During Namespace initialization"));
-		return_ACPI_STATUS(status);
-	}
-
-	/* Initialize the global OSI interfaces list with the static names */
-
-	status = acpi_ut_initialize_interfaces();
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status,
-				"During OSI interfaces initialization"));
-		return_ACPI_STATUS(status);
-	}
-
-	/* If configured, initialize the AML debugger */
-
-	ACPI_DEBUGGER_EXEC(status = acpi_db_initialize());
-	return_ACPI_STATUS(status);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_enable_subsystem
- *
- * PARAMETERS:  flags           - Init/enable Options
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Completes the subsystem initialization including hardware.
- *              Puts system into ACPI mode if it isn't already.
- *
- ******************************************************************************/
-acpi_status acpi_enable_subsystem(u32 flags)
-{
-	acpi_status status = AE_OK;
-
-	ACPI_FUNCTION_TRACE(acpi_enable_subsystem);
-
-#if (!ACPI_REDUCED_HARDWARE)
-
-	/* Enable ACPI mode */
-
-	if (!(flags & ACPI_NO_ACPI_ENABLE)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-				  "[Init] Going into ACPI mode\n"));
-
-		acpi_gbl_original_mode = acpi_hw_get_mode();
-
-		status = acpi_enable();
-		if (ACPI_FAILURE(status)) {
-			ACPI_WARNING((AE_INFO, "AcpiEnable failed"));
-			return_ACPI_STATUS(status);
-		}
-	}
-
-	/*
-	 * Obtain a permanent mapping for the FACS. This is required for the
-	 * Global Lock and the Firmware Waking Vector
-	 */
-	status = acpi_tb_initialize_facs();
-	if (ACPI_FAILURE(status)) {
-		ACPI_WARNING((AE_INFO, "Could not map the FACS table"));
-		return_ACPI_STATUS(status);
-	}
-#endif				/* !ACPI_REDUCED_HARDWARE */
-
-	/*
-	 * Install the default op_region handlers. These are installed unless
-	 * other handlers have already been installed via the
-	 * install_address_space_handler interface.
-	 */
-	if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-				  "[Init] Installing default address space handlers\n"));
-
-		status = acpi_ev_install_region_handlers();
-		if (ACPI_FAILURE(status)) {
-			return_ACPI_STATUS(status);
-		}
-	}
-#if (!ACPI_REDUCED_HARDWARE)
-	/*
-	 * Initialize ACPI Event handling (Fixed and General Purpose)
-	 *
-	 * Note1: We must have the hardware and events initialized before we can
-	 * execute any control methods safely. Any control method can require
-	 * ACPI hardware support, so the hardware must be fully initialized before
-	 * any method execution!
-	 *
-	 * Note2: Fixed events are initialized and enabled here. GPEs are
-	 * initialized, but cannot be enabled until after the hardware is
-	 * completely initialized (SCI and global_lock activated)
-	 */
-	if (!(flags & ACPI_NO_EVENT_INIT)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-				  "[Init] Initializing ACPI events\n"));
-
-		status = acpi_ev_initialize_events();
-		if (ACPI_FAILURE(status)) {
-			return_ACPI_STATUS(status);
-		}
-	}
-
-	/*
-	 * Install the SCI handler and Global Lock handler. This completes the
-	 * hardware initialization.
-	 */
-	if (!(flags & ACPI_NO_HANDLER_INIT)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-				  "[Init] Installing SCI/GL handlers\n"));
-
-		status = acpi_ev_install_xrupt_handlers();
-		if (ACPI_FAILURE(status)) {
-			return_ACPI_STATUS(status);
-		}
-	}
-#endif				/* !ACPI_REDUCED_HARDWARE */
-
-	return_ACPI_STATUS(status);
-}
-
-ACPI_EXPORT_SYMBOL(acpi_enable_subsystem)
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_initialize_objects
- *
- * PARAMETERS:  flags           - Init/enable Options
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Completes namespace initialization by initializing device
- *              objects and executing AML code for Regions, buffers, etc.
- *
- ******************************************************************************/
-acpi_status acpi_initialize_objects(u32 flags)
-{
-	acpi_status status = AE_OK;
-
-	ACPI_FUNCTION_TRACE(acpi_initialize_objects);
-
-	/*
-	 * Run all _REG methods
-	 *
-	 * Note: Any objects accessed by the _REG methods will be automatically
-	 * initialized, even if they contain executable AML (see the call to
-	 * acpi_ns_initialize_objects below).
-	 */
-	if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-				  "[Init] Executing _REG OpRegion methods\n"));
-
-		status = acpi_ev_initialize_op_regions();
-		if (ACPI_FAILURE(status)) {
-			return_ACPI_STATUS(status);
-		}
-	}
-
-	/*
-	 * Execute any module-level code that was detected during the table load
-	 * phase. Although illegal since ACPI 2.0, there are many machines that
-	 * contain this type of code. Each block of detected executable AML code
-	 * outside of any control method is wrapped with a temporary control
-	 * method object and placed on a global list. The methods on this list
-	 * are executed below.
-	 */
-	acpi_ns_exec_module_code_list();
-
-	/*
-	 * Initialize the objects that remain uninitialized. This runs the
-	 * executable AML that may be part of the declaration of these objects:
-	 * operation_regions, buffer_fields, Buffers, and Packages.
-	 */
-	if (!(flags & ACPI_NO_OBJECT_INIT)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-				  "[Init] Completing Initialization of ACPI Objects\n"));
-
-		status = acpi_ns_initialize_objects();
-		if (ACPI_FAILURE(status)) {
-			return_ACPI_STATUS(status);
-		}
-	}
-
-	/*
-	 * Initialize all device objects in the namespace. This runs the device
-	 * _STA and _INI methods.
-	 */
-	if (!(flags & ACPI_NO_DEVICE_INIT)) {
-		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-				  "[Init] Initializing ACPI Devices\n"));
-
-		status = acpi_ns_initialize_devices();
-		if (ACPI_FAILURE(status)) {
-			return_ACPI_STATUS(status);
-		}
-	}
-
-	/*
-	 * Empty the caches (delete the cached objects) on the assumption that
-	 * the table load filled them up more than they will be at runtime --
-	 * thus wasting non-paged memory.
-	 */
-	status = acpi_purge_cached_objects();
-
-	acpi_gbl_startup_flags |= ACPI_INITIALIZED_OK;
-	return_ACPI_STATUS(status);
-}
-
-ACPI_EXPORT_SYMBOL(acpi_initialize_objects)
-
-#endif
 /*******************************************************************************
  *
  * FUNCTION:    acpi_terminate
@@ -683,3 +418,90 @@
 
 ACPI_EXPORT_SYMBOL(acpi_check_address_range)
 #endif				/* !ACPI_ASL_COMPILER */
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_decode_pld_buffer
+ *
+ * PARAMETERS:  in_buffer           - Buffer returned by _PLD method
+ *              length              - Length of the in_buffer
+ *              return_buffer       - Where the decode buffer is returned
+ *
+ * RETURN:      Status and the decoded _PLD buffer. User must deallocate
+ *              the buffer via ACPI_FREE.
+ *
+ * DESCRIPTION: Decode the bit-packed buffer returned by the _PLD method into
+ *              a local struct that is much more useful to an ACPI driver.
+ *
+ ******************************************************************************/
+acpi_status
+acpi_decode_pld_buffer(u8 *in_buffer,
+		       acpi_size length, struct acpi_pld_info ** return_buffer)
+{
+	struct acpi_pld_info *pld_info;
+	u32 *buffer = ACPI_CAST_PTR(u32, in_buffer);
+	u32 dword;
+
+	/* Parameter validation */
+
+	if (!in_buffer || !return_buffer || (length < 16)) {
+		return (AE_BAD_PARAMETER);
+	}
+
+	pld_info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pld_info));
+	if (!pld_info) {
+		return (AE_NO_MEMORY);
+	}
+
+	/* First 32-bit DWord */
+
+	ACPI_MOVE_32_TO_32(&dword, &buffer[0]);
+	pld_info->revision = ACPI_PLD_GET_REVISION(&dword);
+	pld_info->ignore_color = ACPI_PLD_GET_IGNORE_COLOR(&dword);
+	pld_info->color = ACPI_PLD_GET_COLOR(&dword);
+
+	/* Second 32-bit DWord */
+
+	ACPI_MOVE_32_TO_32(&dword, &buffer[1]);
+	pld_info->width = ACPI_PLD_GET_WIDTH(&dword);
+	pld_info->height = ACPI_PLD_GET_HEIGHT(&dword);
+
+	/* Third 32-bit DWord */
+
+	ACPI_MOVE_32_TO_32(&dword, &buffer[2]);
+	pld_info->user_visible = ACPI_PLD_GET_USER_VISIBLE(&dword);
+	pld_info->dock = ACPI_PLD_GET_DOCK(&dword);
+	pld_info->lid = ACPI_PLD_GET_LID(&dword);
+	pld_info->panel = ACPI_PLD_GET_PANEL(&dword);
+	pld_info->vertical_position = ACPI_PLD_GET_VERTICAL(&dword);
+	pld_info->horizontal_position = ACPI_PLD_GET_HORIZONTAL(&dword);
+	pld_info->shape = ACPI_PLD_GET_SHAPE(&dword);
+	pld_info->group_orientation = ACPI_PLD_GET_ORIENTATION(&dword);
+	pld_info->group_token = ACPI_PLD_GET_TOKEN(&dword);
+	pld_info->group_position = ACPI_PLD_GET_POSITION(&dword);
+	pld_info->bay = ACPI_PLD_GET_BAY(&dword);
+
+	/* Fourth 32-bit DWord */
+
+	ACPI_MOVE_32_TO_32(&dword, &buffer[3]);
+	pld_info->ejectable = ACPI_PLD_GET_EJECTABLE(&dword);
+	pld_info->ospm_eject_required = ACPI_PLD_GET_OSPM_EJECT(&dword);
+	pld_info->cabinet_number = ACPI_PLD_GET_CABINET(&dword);
+	pld_info->card_cage_number = ACPI_PLD_GET_CARD_CAGE(&dword);
+	pld_info->reference = ACPI_PLD_GET_REFERENCE(&dword);
+	pld_info->rotation = ACPI_PLD_GET_ROTATION(&dword);
+	pld_info->order = ACPI_PLD_GET_ORDER(&dword);
+
+	if (length >= ACPI_PLD_BUFFER_SIZE) {
+
+		/* Fifth 32-bit DWord (Revision 2 of _PLD) */
+
+		ACPI_MOVE_32_TO_32(&dword, &buffer[4]);
+		pld_info->vertical_offset = ACPI_PLD_GET_VERT_OFFSET(&dword);
+		pld_info->horizontal_offset = ACPI_PLD_GET_HORIZ_OFFSET(&dword);
+	}
+
+	*return_buffer = pld_info;
+	return (AE_OK);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_decode_pld_buffer)
diff --git a/drivers/acpi/acpica/utxfinit.c b/drivers/acpi/acpica/utxfinit.c
new file mode 100644
index 0000000..14f5236
--- /dev/null
+++ b/drivers/acpi/acpica/utxfinit.c
@@ -0,0 +1,317 @@
+/******************************************************************************
+ *
+ * Module Name: utxfinit - External interfaces for ACPICA initialization
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <linux/export.h>
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "acevents.h"
+#include "acnamesp.h"
+#include "acdebug.h"
+#include "actables.h"
+
+#define _COMPONENT          ACPI_UTILITIES
+ACPI_MODULE_NAME("utxfinit")
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_initialize_subsystem
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Initializes all global variables. This is the first function
+ *              called, so any early initialization belongs here.
+ *
+ ******************************************************************************/
+acpi_status acpi_initialize_subsystem(void)
+{
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE(acpi_initialize_subsystem);
+
+	acpi_gbl_startup_flags = ACPI_SUBSYSTEM_INITIALIZE;
+	ACPI_DEBUG_EXEC(acpi_ut_init_stack_ptr_trace());
+
+	/* Initialize the OS-Dependent layer */
+
+	status = acpi_os_initialize();
+	if (ACPI_FAILURE(status)) {
+		ACPI_EXCEPTION((AE_INFO, status, "During OSL initialization"));
+		return_ACPI_STATUS(status);
+	}
+
+	/* Initialize all globals used by the subsystem */
+
+	status = acpi_ut_init_globals();
+	if (ACPI_FAILURE(status)) {
+		ACPI_EXCEPTION((AE_INFO, status,
+				"During initialization of globals"));
+		return_ACPI_STATUS(status);
+	}
+
+	/* Create the default mutex objects */
+
+	status = acpi_ut_mutex_initialize();
+	if (ACPI_FAILURE(status)) {
+		ACPI_EXCEPTION((AE_INFO, status,
+				"During Global Mutex creation"));
+		return_ACPI_STATUS(status);
+	}
+
+	/*
+	 * Initialize the namespace manager and
+	 * the root of the namespace tree
+	 */
+	status = acpi_ns_root_initialize();
+	if (ACPI_FAILURE(status)) {
+		ACPI_EXCEPTION((AE_INFO, status,
+				"During Namespace initialization"));
+		return_ACPI_STATUS(status);
+	}
+
+	/* Initialize the global OSI interfaces list with the static names */
+
+	status = acpi_ut_initialize_interfaces();
+	if (ACPI_FAILURE(status)) {
+		ACPI_EXCEPTION((AE_INFO, status,
+				"During OSI interfaces initialization"));
+		return_ACPI_STATUS(status);
+	}
+
+	/* If configured, initialize the AML debugger */
+
+	ACPI_DEBUGGER_EXEC(status = acpi_db_initialize());
+	return_ACPI_STATUS(status);
+}
+ACPI_EXPORT_SYMBOL(acpi_initialize_subsystem)
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_enable_subsystem
+ *
+ * PARAMETERS:  flags               - Init/enable Options
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Completes the subsystem initialization including hardware.
+ *              Puts system into ACPI mode if it isn't already.
+ *
+ ******************************************************************************/
+acpi_status acpi_enable_subsystem(u32 flags)
+{
+	acpi_status status = AE_OK;
+
+	ACPI_FUNCTION_TRACE(acpi_enable_subsystem);
+
+#if (!ACPI_REDUCED_HARDWARE)
+
+	/* Enable ACPI mode */
+
+	if (!(flags & ACPI_NO_ACPI_ENABLE)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+				  "[Init] Going into ACPI mode\n"));
+
+		acpi_gbl_original_mode = acpi_hw_get_mode();
+
+		status = acpi_enable();
+		if (ACPI_FAILURE(status)) {
+			ACPI_WARNING((AE_INFO, "AcpiEnable failed"));
+			return_ACPI_STATUS(status);
+		}
+	}
+
+	/*
+	 * Obtain a permanent mapping for the FACS. This is required for the
+	 * Global Lock and the Firmware Waking Vector
+	 */
+	status = acpi_tb_initialize_facs();
+	if (ACPI_FAILURE(status)) {
+		ACPI_WARNING((AE_INFO, "Could not map the FACS table"));
+		return_ACPI_STATUS(status);
+	}
+#endif				/* !ACPI_REDUCED_HARDWARE */
+
+	/*
+	 * Install the default op_region handlers. These are installed unless
+	 * other handlers have already been installed via the
+	 * install_address_space_handler interface.
+	 */
+	if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+				  "[Init] Installing default address space handlers\n"));
+
+		status = acpi_ev_install_region_handlers();
+		if (ACPI_FAILURE(status)) {
+			return_ACPI_STATUS(status);
+		}
+	}
+#if (!ACPI_REDUCED_HARDWARE)
+	/*
+	 * Initialize ACPI Event handling (Fixed and General Purpose)
+	 *
+	 * Note1: We must have the hardware and events initialized before we can
+	 * execute any control methods safely. Any control method can require
+	 * ACPI hardware support, so the hardware must be fully initialized before
+	 * any method execution!
+	 *
+	 * Note2: Fixed events are initialized and enabled here. GPEs are
+	 * initialized, but cannot be enabled until after the hardware is
+	 * completely initialized (SCI and global_lock activated) and the various
+	 * initialization control methods are run (_REG, _STA, _INI) on the
+	 * entire namespace.
+	 */
+	if (!(flags & ACPI_NO_EVENT_INIT)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+				  "[Init] Initializing ACPI events\n"));
+
+		status = acpi_ev_initialize_events();
+		if (ACPI_FAILURE(status)) {
+			return_ACPI_STATUS(status);
+		}
+	}
+
+	/*
+	 * Install the SCI handler and Global Lock handler. This completes the
+	 * hardware initialization.
+	 */
+	if (!(flags & ACPI_NO_HANDLER_INIT)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+				  "[Init] Installing SCI/GL handlers\n"));
+
+		status = acpi_ev_install_xrupt_handlers();
+		if (ACPI_FAILURE(status)) {
+			return_ACPI_STATUS(status);
+		}
+	}
+#endif				/* !ACPI_REDUCED_HARDWARE */
+
+	return_ACPI_STATUS(status);
+}
+ACPI_EXPORT_SYMBOL(acpi_enable_subsystem)
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_initialize_objects
+ *
+ * PARAMETERS:  flags               - Init/enable Options
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Completes namespace initialization by initializing device
+ *              objects and executing AML code for Regions, buffers, etc.
+ *
+ ******************************************************************************/
+acpi_status acpi_initialize_objects(u32 flags)
+{
+	acpi_status status = AE_OK;
+
+	ACPI_FUNCTION_TRACE(acpi_initialize_objects);
+
+	/*
+	 * Run all _REG methods
+	 *
+	 * Note: Any objects accessed by the _REG methods will be automatically
+	 * initialized, even if they contain executable AML (see the call to
+	 * acpi_ns_initialize_objects below).
+	 */
+	if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+				  "[Init] Executing _REG OpRegion methods\n"));
+
+		status = acpi_ev_initialize_op_regions();
+		if (ACPI_FAILURE(status)) {
+			return_ACPI_STATUS(status);
+		}
+	}
+
+	/*
+	 * Execute any module-level code that was detected during the table load
+	 * phase. Although illegal since ACPI 2.0, there are many machines that
+	 * contain this type of code. Each block of detected executable AML code
+	 * outside of any control method is wrapped with a temporary control
+	 * method object and placed on a global list. The methods on this list
+	 * are executed below.
+	 */
+	acpi_ns_exec_module_code_list();
+
+	/*
+	 * Initialize the objects that remain uninitialized. This runs the
+	 * executable AML that may be part of the declaration of these objects:
+	 * operation_regions, buffer_fields, Buffers, and Packages.
+	 */
+	if (!(flags & ACPI_NO_OBJECT_INIT)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+				  "[Init] Completing Initialization of ACPI Objects\n"));
+
+		status = acpi_ns_initialize_objects();
+		if (ACPI_FAILURE(status)) {
+			return_ACPI_STATUS(status);
+		}
+	}
+
+	/*
+	 * Initialize all device objects in the namespace. This runs the device
+	 * _STA and _INI methods.
+	 */
+	if (!(flags & ACPI_NO_DEVICE_INIT)) {
+		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+				  "[Init] Initializing ACPI Devices\n"));
+
+		status = acpi_ns_initialize_devices();
+		if (ACPI_FAILURE(status)) {
+			return_ACPI_STATUS(status);
+		}
+	}
+
+	/*
+	 * Empty the caches (delete the cached objects) on the assumption that
+	 * the table load filled them up more than they will be at runtime --
+	 * thus wasting non-paged memory.
+	 */
+	status = acpi_purge_cached_objects();
+
+	acpi_gbl_startup_flags |= ACPI_INITIALIZED_OK;
+	return_ACPI_STATUS(status);
+}
+ACPI_EXPORT_SYMBOL(acpi_initialize_objects)
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index e059695..d59175e 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -994,8 +994,6 @@
 	status = acpi_ec_ecdt_probe();
 	/* Ignore result. Not having an ECDT is not fatal. */
 
-	acpi_bus_osc_support();
-
 	status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION);
 	if (ACPI_FAILURE(status)) {
 		printk(KERN_ERR PREFIX "Unable to initialize ACPI objects\n");
@@ -1003,6 +1001,12 @@
 	}
 
 	/*
+	 * _OSC method may exist in module level code,
+	 * so it must be run after ACPI_FULL_INITIALIZATION
+	 */
+	acpi_bus_osc_support();
+
+	/*
 	 * _PDC control method may load dynamic SSDT tables,
 	 * and we need to install the table handler before that.
 	 */
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 314a3b8..f0d936b 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -450,15 +450,4 @@
 	return 0;
 }
 
-static int __init acpi_button_init(void)
-{
-	return acpi_bus_register_driver(&acpi_button_driver);
-}
-
-static void __exit acpi_button_exit(void)
-{
-	acpi_bus_unregister_driver(&acpi_button_driver);
-}
-
-module_init(acpi_button_init);
-module_exit(acpi_button_exit);
+module_acpi_driver(acpi_button_driver);
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index bc36a47..3bd6a54 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -212,24 +212,4 @@
 }
 #endif
 
-static int __init acpi_fan_init(void)
-{
-	int result = 0;
-
-	result = acpi_bus_register_driver(&acpi_fan_driver);
-	if (result < 0)
-		return -ENODEV;
-
-	return 0;
-}
-
-static void __exit acpi_fan_exit(void)
-{
-
-	acpi_bus_unregister_driver(&acpi_fan_driver);
-
-	return;
-}
-
-module_init(acpi_fan_init);
-module_exit(acpi_fan_exit);
+module_acpi_driver(acpi_fan_driver);
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 243ee85..d1a2d74 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -25,6 +25,8 @@
 static LIST_HEAD(bus_type_list);
 static DECLARE_RWSEM(bus_type_sem);
 
+#define PHYSICAL_NODE_STRING "physical_node"
+
 int register_acpi_bus_type(struct acpi_bus_type *type)
 {
 	if (acpi_disabled)
@@ -124,84 +126,119 @@
 
 EXPORT_SYMBOL(acpi_get_child);
 
-/* Link ACPI devices with physical devices */
-static void acpi_glue_data_handler(acpi_handle handle,
-				   void *context)
-{
-	/* we provide an empty handler */
-}
-
-/* Note: a success call will increase reference count by one */
-struct device *acpi_get_physical_device(acpi_handle handle)
-{
-	acpi_status status;
-	struct device *dev;
-
-	status = acpi_get_data(handle, acpi_glue_data_handler, (void **)&dev);
-	if (ACPI_SUCCESS(status))
-		return get_device(dev);
-	return NULL;
-}
-
-EXPORT_SYMBOL(acpi_get_physical_device);
-
 static int acpi_bind_one(struct device *dev, acpi_handle handle)
 {
 	struct acpi_device *acpi_dev;
 	acpi_status status;
+	struct acpi_device_physical_node *physical_node;
+	char physical_node_name[sizeof(PHYSICAL_NODE_STRING) + 2];
+	int retval = -EINVAL;
 
 	if (dev->archdata.acpi_handle) {
 		dev_warn(dev, "Drivers changed 'acpi_handle'\n");
 		return -EINVAL;
 	}
+
 	get_device(dev);
-	status = acpi_attach_data(handle, acpi_glue_data_handler, dev);
-	if (ACPI_FAILURE(status)) {
-		put_device(dev);
-		return -EINVAL;
+	status = acpi_bus_get_device(handle, &acpi_dev);
+	if (ACPI_FAILURE(status))
+		goto err;
+
+	physical_node = kzalloc(sizeof(struct acpi_device_physical_node),
+		GFP_KERNEL);
+	if (!physical_node) {
+		retval = -ENOMEM;
+		goto err;
 	}
+
+	mutex_lock(&acpi_dev->physical_node_lock);
+	/* allocate physical node id according to physical_node_id_bitmap */
+	physical_node->node_id =
+		find_first_zero_bit(acpi_dev->physical_node_id_bitmap,
+		ACPI_MAX_PHYSICAL_NODE);
+	if (physical_node->node_id >= ACPI_MAX_PHYSICAL_NODE) {
+		retval = -ENOSPC;
+		mutex_unlock(&acpi_dev->physical_node_lock);
+		goto err;
+	}
+
+	set_bit(physical_node->node_id, acpi_dev->physical_node_id_bitmap);
+	physical_node->dev = dev;
+	list_add_tail(&physical_node->node, &acpi_dev->physical_node_list);
+	acpi_dev->physical_node_count++;
+	mutex_unlock(&acpi_dev->physical_node_lock);
+
 	dev->archdata.acpi_handle = handle;
 
-	status = acpi_bus_get_device(handle, &acpi_dev);
-	if (!ACPI_FAILURE(status)) {
-		int ret;
+	if (!physical_node->node_id)
+		strcpy(physical_node_name, PHYSICAL_NODE_STRING);
+	else
+		sprintf(physical_node_name,
+			"physical_node%d", physical_node->node_id);
+	retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
+			physical_node_name);
+	retval = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj,
+		"firmware_node");
 
-		ret = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj,
-				"firmware_node");
-		ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj,
-				"physical_node");
-		if (acpi_dev->wakeup.flags.valid)
-			device_set_wakeup_capable(dev, true);
-	}
+	if (acpi_dev->wakeup.flags.valid)
+		device_set_wakeup_capable(dev, true);
 
 	return 0;
+
+ err:
+	put_device(dev);
+	return retval;
 }
 
 static int acpi_unbind_one(struct device *dev)
 {
+	struct acpi_device_physical_node *entry;
+	struct acpi_device *acpi_dev;
+	acpi_status status;
+	struct list_head *node, *next;
+
 	if (!dev->archdata.acpi_handle)
 		return 0;
-	if (dev == acpi_get_physical_device(dev->archdata.acpi_handle)) {
-		struct acpi_device *acpi_dev;
 
-		/* acpi_get_physical_device increase refcnt by one */
-		put_device(dev);
+	status = acpi_bus_get_device(dev->archdata.acpi_handle,
+		&acpi_dev);
+	if (ACPI_FAILURE(status))
+		goto err;
 
-		if (!acpi_bus_get_device(dev->archdata.acpi_handle,
-					&acpi_dev)) {
-			sysfs_remove_link(&dev->kobj, "firmware_node");
-			sysfs_remove_link(&acpi_dev->dev.kobj, "physical_node");
-		}
+	mutex_lock(&acpi_dev->physical_node_lock);
+	list_for_each_safe(node, next, &acpi_dev->physical_node_list) {
+		char physical_node_name[sizeof(PHYSICAL_NODE_STRING) + 2];
 
-		acpi_detach_data(dev->archdata.acpi_handle,
-				 acpi_glue_data_handler);
+		entry = list_entry(node, struct acpi_device_physical_node,
+			node);
+		if (entry->dev != dev)
+			continue;
+
+		list_del(node);
+		clear_bit(entry->node_id, acpi_dev->physical_node_id_bitmap);
+
+		acpi_dev->physical_node_count--;
+
+		if (!entry->node_id)
+			strcpy(physical_node_name, PHYSICAL_NODE_STRING);
+		else
+			sprintf(physical_node_name,
+				"physical_node%d", entry->node_id);
+
+		sysfs_remove_link(&acpi_dev->dev.kobj, physical_node_name);
+		sysfs_remove_link(&dev->kobj, "firmware_node");
 		dev->archdata.acpi_handle = NULL;
 		/* acpi_bind_one increase refcnt by one */
 		put_device(dev);
-	} else {
-		dev_err(dev, "Oops, 'acpi_handle' corrupt\n");
+		kfree(entry);
 	}
+	mutex_unlock(&acpi_dev->physical_node_lock);
+
 	return 0;
+
+err:
+	dev_err(dev, "Oops, 'acpi_handle' corrupt\n");
+	return -EINVAL;
 }
 
 static int acpi_platform_notify(struct device *dev)
diff --git a/drivers/acpi/hed.c b/drivers/acpi/hed.c
index d0c1967..20a0f2c 100644
--- a/drivers/acpi/hed.c
+++ b/drivers/acpi/hed.c
@@ -86,25 +86,7 @@
 		.notify = acpi_hed_notify,
 	},
 };
-
-static int __init acpi_hed_init(void)
-{
-	if (acpi_disabled)
-		return -ENODEV;
-
-	if (acpi_bus_register_driver(&acpi_hed_driver) < 0)
-		return -ENODEV;
-
-	return 0;
-}
-
-static void __exit acpi_hed_exit(void)
-{
-	acpi_bus_unregister_driver(&acpi_hed_driver);
-}
-
-module_init(acpi_hed_init);
-module_exit(acpi_hed_exit);
+module_acpi_driver(acpi_hed_driver);
 
 ACPI_MODULE_NAME("hed");
 MODULE_AUTHOR("Huang Ying");
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c
index 251c7b62..27adb09 100644
--- a/drivers/acpi/proc.c
+++ b/drivers/acpi/proc.c
@@ -302,26 +302,41 @@
 	list_for_each_safe(node, next, &acpi_wakeup_device_list) {
 		struct acpi_device *dev =
 		    container_of(node, struct acpi_device, wakeup_list);
-		struct device *ldev;
+		struct acpi_device_physical_node *entry;
 
 		if (!dev->wakeup.flags.valid)
 			continue;
 
-		ldev = acpi_get_physical_device(dev->handle);
-		seq_printf(seq, "%s\t  S%d\t%c%-8s  ",
+		seq_printf(seq, "%s\t  S%d\t",
 			   dev->pnp.bus_id,
-			   (u32) dev->wakeup.sleep_state,
-			   dev->wakeup.flags.run_wake ? '*' : ' ',
-			   (device_may_wakeup(&dev->dev)
-			     || (ldev && device_may_wakeup(ldev))) ?
-			       "enabled" : "disabled");
-		if (ldev)
-			seq_printf(seq, "%s:%s",
-				   ldev->bus ? ldev->bus->name : "no-bus",
-				   dev_name(ldev));
-		seq_printf(seq, "\n");
-		put_device(ldev);
+			   (u32) dev->wakeup.sleep_state);
 
+		if (!dev->physical_node_count)
+			seq_printf(seq, "%c%-8s\n",
+				dev->wakeup.flags.run_wake ?
+				'*' : ' ', "disabled");
+		else {
+			struct device *ldev;
+			list_for_each_entry(entry, &dev->physical_node_list,
+					node) {
+				ldev = get_device(entry->dev);
+				if (!ldev)
+					continue;
+
+				if (&entry->node !=
+						dev->physical_node_list.next)
+					seq_printf(seq, "\t\t");
+
+				seq_printf(seq, "%c%-8s  %s:%s\n",
+					dev->wakeup.flags.run_wake ? '*' : ' ',
+					(device_may_wakeup(&dev->dev) ||
+					(ldev && device_may_wakeup(ldev))) ?
+					"enabled" : "disabled",
+					ldev->bus ? ldev->bus->name :
+					"no-bus", dev_name(ldev));
+				put_device(ldev);
+			}
+		}
 	}
 	mutex_unlock(&acpi_device_lock);
 	return 0;
@@ -329,12 +344,14 @@
 
 static void physical_device_enable_wakeup(struct acpi_device *adev)
 {
-	struct device *dev = acpi_get_physical_device(adev->handle);
+	struct acpi_device_physical_node *entry;
 
-	if (dev && device_can_wakeup(dev)) {
-		bool enable = !device_may_wakeup(dev);
-		device_set_wakeup_enable(dev, enable);
-	}
+	list_for_each_entry(entry,
+		&adev->physical_node_list, node)
+		if (entry->dev && device_can_wakeup(entry->dev)) {
+			bool enable = !device_may_wakeup(entry->dev);
+			device_set_wakeup_enable(entry->dev, enable);
+		}
 }
 
 static ssize_t
diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c
index f8d2a47..cf6129a 100644
--- a/drivers/acpi/sbshc.c
+++ b/drivers/acpi/sbshc.c
@@ -310,23 +310,7 @@
 	return 0;
 }
 
-static int __init acpi_smb_hc_init(void)
-{
-	int result;
-
-	result = acpi_bus_register_driver(&acpi_smb_hc_driver);
-	if (result < 0)
-		return -ENODEV;
-	return 0;
-}
-
-static void __exit acpi_smb_hc_exit(void)
-{
-	acpi_bus_unregister_driver(&acpi_smb_hc_driver);
-}
-
-module_init(acpi_smb_hc_init);
-module_exit(acpi_smb_hc_exit);
+module_acpi_driver(acpi_smb_hc_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Alexey Starikovskiy");
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index d1ecca2..1fcb867 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -10,6 +10,7 @@
 #include <linux/signal.h>
 #include <linux/kthread.h>
 #include <linux/dmi.h>
+#include <linux/nls.h>
 
 #include <acpi/acpi_drivers.h>
 
@@ -232,8 +233,35 @@
 }
 static DEVICE_ATTR(path, 0444, acpi_device_path_show, NULL);
 
+/* sysfs file that shows description text from the ACPI _STR method */
+static ssize_t description_show(struct device *dev,
+				struct device_attribute *attr,
+				char *buf) {
+	struct acpi_device *acpi_dev = to_acpi_device(dev);
+	int result;
+
+	if (acpi_dev->pnp.str_obj == NULL)
+		return 0;
+
+	/*
+	 * The _STR object contains a Unicode identifier for a device.
+	 * We need to convert to utf-8 so it can be displayed.
+	 */
+	result = utf16s_to_utf8s(
+		(wchar_t *)acpi_dev->pnp.str_obj->buffer.pointer,
+		acpi_dev->pnp.str_obj->buffer.length,
+		UTF16_LITTLE_ENDIAN, buf,
+		PAGE_SIZE);
+
+	buf[result++] = '\n';
+
+	return result;
+}
+static DEVICE_ATTR(description, 0444, description_show, NULL);
+
 static int acpi_device_setup_files(struct acpi_device *dev)
 {
+	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
 	acpi_status status;
 	acpi_handle temp;
 	int result = 0;
@@ -257,6 +285,21 @@
 			goto end;
 	}
 
+	/*
+	 * If device has _STR, 'description' file is created
+	 */
+	status = acpi_get_handle(dev->handle, "_STR", &temp);
+	if (ACPI_SUCCESS(status)) {
+		status = acpi_evaluate_object(dev->handle, "_STR",
+					NULL, &buffer);
+		if (ACPI_FAILURE(status))
+			buffer.pointer = NULL;
+		dev->pnp.str_obj = buffer.pointer;
+		result = device_create_file(&dev->dev, &dev_attr_description);
+		if (result)
+			goto end;
+	}
+
         /*
          * If device has _EJ0, 'eject' file is created that is used to trigger
          * hot-removal function from userland.
@@ -274,8 +317,15 @@
 	acpi_handle temp;
 
 	/*
-	 * If device has _EJ0, 'eject' file is created that is used to trigger
-	 * hot-removal function from userland.
+	 * If device has _STR, remove 'description' file
+	 */
+	status = acpi_get_handle(dev->handle, "_STR", &temp);
+	if (ACPI_SUCCESS(status)) {
+		kfree(dev->pnp.str_obj);
+		device_remove_file(&dev->dev, &dev_attr_description);
+	}
+	/*
+	 * If device has _EJ0, remove 'eject' file.
 	 */
 	status = acpi_get_handle(dev->handle, "_EJ0", &temp);
 	if (ACPI_SUCCESS(status))
@@ -481,6 +531,8 @@
 	INIT_LIST_HEAD(&device->children);
 	INIT_LIST_HEAD(&device->node);
 	INIT_LIST_HEAD(&device->wakeup_list);
+	INIT_LIST_HEAD(&device->physical_node_list);
+	mutex_init(&device->physical_node_lock);
 
 	new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL);
 	if (!new_bus_id) {
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index f336bca7..2572d97 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -240,10 +240,17 @@
 	       table_end) {
 		if (entry->type == entry_id
 		    && (!max_entries || count++ < max_entries))
-			if (handler(entry, table_end)) {
-				early_acpi_os_unmap_memory((char *)table_header, tbl_size);
-				return -EINVAL;
-			}
+			if (handler(entry, table_end))
+				goto err;
+
+		/*
+		 * If entry->length is 0, break from this loop to avoid
+		 * infinite loop.
+		 */
+		if (entry->length == 0) {
+			pr_err(PREFIX "[%4.4s:0x%02x] Invalid zero length\n", id, entry_id);
+			goto err;
+		}
 
 		entry = (struct acpi_subtable_header *)
 		    ((unsigned long)entry + entry->length);
@@ -255,6 +262,9 @@
 
 	early_acpi_os_unmap_memory((char *)table_header, tbl_size);
 	return count;
+err:
+	early_acpi_os_unmap_memory((char *)table_header, tbl_size);
+	return -EINVAL;
 }
 
 int __init
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
index 3e87c9c..462f7e3 100644
--- a/drivers/acpi/utils.c
+++ b/drivers/acpi/utils.c
@@ -384,7 +384,7 @@
 EXPORT_SYMBOL(acpi_evaluate_reference);
 
 acpi_status
-acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld *pld)
+acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld)
 {
 	acpi_status status;
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -400,13 +400,16 @@
 	if (!output || output->type != ACPI_TYPE_PACKAGE
 	    || !output->package.count
 	    || output->package.elements[0].type != ACPI_TYPE_BUFFER
-	    || output->package.elements[0].buffer.length > sizeof(*pld)) {
+	    || output->package.elements[0].buffer.length < ACPI_PLD_REV1_BUFFER_SIZE) {
 		status = AE_TYPE;
 		goto out;
 	}
 
-	memcpy(pld, output->package.elements[0].buffer.pointer,
-	       output->package.elements[0].buffer.length);
+	status = acpi_decode_pld_buffer(
+			output->package.elements[0].buffer.pointer,
+			output->package.elements[0].buffer.length,
+			pld);
+
 out:
 	kfree(buffer.pointer);
 	return status;
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 7dda4f7..86c8821 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -248,26 +248,23 @@
 static int
 memory_block_action(unsigned long phys_index, unsigned long action)
 {
-	unsigned long start_pfn, start_paddr;
+	unsigned long start_pfn;
 	unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block;
 	struct page *first_page;
 	int ret;
 
 	first_page = pfn_to_page(phys_index << PFN_SECTION_SHIFT);
+	start_pfn = page_to_pfn(first_page);
 
 	switch (action) {
 		case MEM_ONLINE:
-			start_pfn = page_to_pfn(first_page);
-
 			if (!pages_correctly_reserved(start_pfn, nr_pages))
 				return -EBUSY;
 
 			ret = online_pages(start_pfn, nr_pages);
 			break;
 		case MEM_OFFLINE:
-			start_paddr = page_to_pfn(first_page) << PAGE_SHIFT;
-			ret = remove_memory(start_paddr,
-					    nr_pages << PAGE_SHIFT);
+			ret = offline_pages(start_pfn, nr_pages);
 			break;
 		default:
 			WARN(1, KERN_WARNING "%s(%ld, %ld) unknown action: "
@@ -278,13 +275,11 @@
 	return ret;
 }
 
-static int memory_block_change_state(struct memory_block *mem,
+static int __memory_block_change_state(struct memory_block *mem,
 		unsigned long to_state, unsigned long from_state_req)
 {
 	int ret = 0;
 
-	mutex_lock(&mem->state_mutex);
-
 	if (mem->state != from_state_req) {
 		ret = -EINVAL;
 		goto out;
@@ -312,10 +307,20 @@
 		break;
 	}
 out:
-	mutex_unlock(&mem->state_mutex);
 	return ret;
 }
 
+static int memory_block_change_state(struct memory_block *mem,
+		unsigned long to_state, unsigned long from_state_req)
+{
+	int ret;
+
+	mutex_lock(&mem->state_mutex);
+	ret = __memory_block_change_state(mem, to_state, from_state_req);
+	mutex_unlock(&mem->state_mutex);
+
+	return ret;
+}
 static ssize_t
 store_mem_state(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
@@ -656,6 +661,21 @@
 }
 
 /*
+ * offline one memory block. If the memory block has been offlined, do nothing.
+ */
+int offline_memory_block(struct memory_block *mem)
+{
+	int ret = 0;
+
+	mutex_lock(&mem->state_mutex);
+	if (mem->state != MEM_OFFLINE)
+		ret = __memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE);
+	mutex_unlock(&mem->state_mutex);
+
+	return ret;
+}
+
+/*
  * Initialize the sysfs support for memory devices...
  */
 int __init memory_dev_init(void)
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index f93a032..f55683a 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -162,23 +162,12 @@
 	.release = drbd_release,
 };
 
-static void bio_destructor_drbd(struct bio *bio)
-{
-	bio_free(bio, drbd_md_io_bio_set);
-}
-
 struct bio *bio_alloc_drbd(gfp_t gfp_mask)
 {
-	struct bio *bio;
-
 	if (!drbd_md_io_bio_set)
 		return bio_alloc(gfp_mask, 1);
 
-	bio = bio_alloc_bioset(gfp_mask, 1, drbd_md_io_bio_set);
-	if (!bio)
-		return NULL;
-	bio->bi_destructor = bio_destructor_drbd;
-	return bio;
+	return bio_alloc_bioset(gfp_mask, 1, drbd_md_io_bio_set);
 }
 
 #ifdef __CHECKER__
diff --git a/drivers/block/osdblk.c b/drivers/block/osdblk.c
index 87311eb..1bbc681 100644
--- a/drivers/block/osdblk.c
+++ b/drivers/block/osdblk.c
@@ -266,11 +266,10 @@
 	struct bio *tmp, *new_chain = NULL, *tail = NULL;
 
 	while (old_chain) {
-		tmp = bio_kmalloc(gfpmask, old_chain->bi_max_vecs);
+		tmp = bio_clone_kmalloc(old_chain, gfpmask);
 		if (!tmp)
 			goto err_out;
 
-		__bio_clone(tmp, old_chain);
 		tmp->bi_bdev = NULL;
 		gfpmask &= ~__GFP_WAIT;
 		tmp->bi_next = NULL;
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index ba66e44..2e7de7a 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -522,38 +522,6 @@
 	}
 }
 
-static void pkt_bio_destructor(struct bio *bio)
-{
-	kfree(bio->bi_io_vec);
-	kfree(bio);
-}
-
-static struct bio *pkt_bio_alloc(int nr_iovecs)
-{
-	struct bio_vec *bvl = NULL;
-	struct bio *bio;
-
-	bio = kmalloc(sizeof(struct bio), GFP_KERNEL);
-	if (!bio)
-		goto no_bio;
-	bio_init(bio);
-
-	bvl = kcalloc(nr_iovecs, sizeof(struct bio_vec), GFP_KERNEL);
-	if (!bvl)
-		goto no_bvl;
-
-	bio->bi_max_vecs = nr_iovecs;
-	bio->bi_io_vec = bvl;
-	bio->bi_destructor = pkt_bio_destructor;
-
-	return bio;
-
- no_bvl:
-	kfree(bio);
- no_bio:
-	return NULL;
-}
-
 /*
  * Allocate a packet_data struct
  */
@@ -567,7 +535,7 @@
 		goto no_pkt;
 
 	pkt->frames = frames;
-	pkt->w_bio = pkt_bio_alloc(frames);
+	pkt->w_bio = bio_kmalloc(GFP_KERNEL, frames);
 	if (!pkt->w_bio)
 		goto no_bio;
 
@@ -581,9 +549,10 @@
 	bio_list_init(&pkt->orig_bios);
 
 	for (i = 0; i < frames; i++) {
-		struct bio *bio = pkt_bio_alloc(1);
+		struct bio *bio = bio_kmalloc(GFP_KERNEL, 1);
 		if (!bio)
 			goto no_rd_bio;
+
 		pkt->r_bios[i] = bio;
 	}
 
@@ -1111,21 +1080,17 @@
 	 * Schedule reads for missing parts of the packet.
 	 */
 	for (f = 0; f < pkt->frames; f++) {
-		struct bio_vec *vec;
-
 		int p, offset;
+
 		if (written[f])
 			continue;
+
 		bio = pkt->r_bios[f];
-		vec = bio->bi_io_vec;
-		bio_init(bio);
-		bio->bi_max_vecs = 1;
+		bio_reset(bio);
 		bio->bi_sector = pkt->sector + f * (CD_FRAMESIZE >> 9);
 		bio->bi_bdev = pd->bdev;
 		bio->bi_end_io = pkt_end_io_read;
 		bio->bi_private = pkt;
-		bio->bi_io_vec = vec;
-		bio->bi_destructor = pkt_bio_destructor;
 
 		p = (f * CD_FRAMESIZE) / PAGE_SIZE;
 		offset = (f * CD_FRAMESIZE) % PAGE_SIZE;
@@ -1418,14 +1383,11 @@
 	}
 
 	/* Start the write request */
-	bio_init(pkt->w_bio);
-	pkt->w_bio->bi_max_vecs = PACKET_MAX_SIZE;
+	bio_reset(pkt->w_bio);
 	pkt->w_bio->bi_sector = pkt->sector;
 	pkt->w_bio->bi_bdev = pd->bdev;
 	pkt->w_bio->bi_end_io = pkt_end_io_packet_write;
 	pkt->w_bio->bi_private = pkt;
-	pkt->w_bio->bi_io_vec = bvec;
-	pkt->w_bio->bi_destructor = pkt_bio_destructor;
 	for (f = 0; f < pkt->frames; f++)
 		if (!bio_add_page(pkt->w_bio, bvec[f].bv_page, CD_FRAMESIZE, bvec[f].bv_offset))
 			BUG();
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index 54a55f0..bb3d9be 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -41,6 +41,8 @@
 
 #include "rbd_types.h"
 
+#define RBD_DEBUG	/* Activate rbd_assert() calls */
+
 /*
  * The basic unit of block I/O is a sector.  It is interpreted in a
  * number of contexts in Linux (blk, bio, genhd), but the default is
@@ -50,16 +52,24 @@
 #define	SECTOR_SHIFT	9
 #define	SECTOR_SIZE	(1ULL << SECTOR_SHIFT)
 
+/* It might be useful to have this defined elsewhere too */
+
+#define	U64_MAX	((u64) (~0ULL))
+
 #define RBD_DRV_NAME "rbd"
 #define RBD_DRV_NAME_LONG "rbd (rados block device)"
 
 #define RBD_MINORS_PER_MAJOR	256		/* max minors per blkdev */
 
 #define RBD_MAX_SNAP_NAME_LEN	32
+#define RBD_MAX_SNAP_COUNT	510	/* allows max snapc to fit in 4KB */
 #define RBD_MAX_OPT_LEN		1024
 
 #define RBD_SNAP_HEAD_NAME	"-"
 
+#define RBD_IMAGE_ID_LEN_MAX	64
+#define RBD_OBJ_PREFIX_LEN_MAX	64
+
 /*
  * An RBD device name will be "rbd#", where the "rbd" comes from
  * RBD_DRV_NAME above, and # is a unique integer identifier.
@@ -69,21 +79,22 @@
 #define DEV_NAME_LEN		32
 #define MAX_INT_FORMAT_WIDTH	((5 * sizeof (int)) / 2 + 1)
 
-#define RBD_NOTIFY_TIMEOUT_DEFAULT 10
+#define RBD_READ_ONLY_DEFAULT		false
 
 /*
  * block device image metadata (in-memory version)
  */
 struct rbd_image_header {
-	u64 image_size;
+	/* These four fields never change for a given rbd image */
 	char *object_prefix;
+	u64 features;
 	__u8 obj_order;
 	__u8 crypt_type;
 	__u8 comp_type;
-	struct ceph_snap_context *snapc;
-	size_t snap_names_len;
-	u32 total_snaps;
 
+	/* The remaining fields need to be updated occasionally */
+	u64 image_size;
+	struct ceph_snap_context *snapc;
 	char *snap_names;
 	u64 *snap_sizes;
 
@@ -91,7 +102,7 @@
 };
 
 struct rbd_options {
-	int	notify_timeout;
+	bool	read_only;
 };
 
 /*
@@ -99,7 +110,6 @@
  */
 struct rbd_client {
 	struct ceph_client	*client;
-	struct rbd_options	*rbd_opts;
 	struct kref		kref;
 	struct list_head	node;
 };
@@ -141,6 +151,16 @@
 	u64			size;
 	struct list_head	node;
 	u64			id;
+	u64			features;
+};
+
+struct rbd_mapping {
+	char                    *snap_name;
+	u64                     snap_id;
+	u64                     size;
+	u64                     features;
+	bool                    snap_exists;
+	bool			read_only;
 };
 
 /*
@@ -151,8 +171,9 @@
 
 	int			major;		/* blkdev assigned major */
 	struct gendisk		*disk;		/* blkdev's gendisk and rq */
-	struct request_queue	*q;
 
+	u32			image_format;	/* Either 1 or 2 */
+	struct rbd_options	rbd_opts;
 	struct rbd_client	*rbd_client;
 
 	char			name[DEV_NAME_LEN]; /* blkdev name, e.g. rbd3 */
@@ -160,6 +181,8 @@
 	spinlock_t		lock;		/* queue lock */
 
 	struct rbd_image_header	header;
+	char			*image_id;
+	size_t			image_id_len;
 	char			*image_name;
 	size_t			image_name_len;
 	char			*header_name;
@@ -171,13 +194,8 @@
 
 	/* protects updating the header */
 	struct rw_semaphore     header_rwsem;
-	/* name of the snapshot this device reads from */
-	char                    *snap_name;
-	/* id of the snapshot this device reads from */
-	u64                     snap_id;	/* current snapshot id */
-	/* whether the snap_id this device reads from still exists */
-	bool                    snap_exists;
-	int                     read_only;
+
+	struct rbd_mapping	mapping;
 
 	struct list_head	node;
 
@@ -196,12 +214,10 @@
 static LIST_HEAD(rbd_client_list);		/* clients */
 static DEFINE_SPINLOCK(rbd_client_list_lock);
 
-static int __rbd_init_snaps_header(struct rbd_device *rbd_dev);
+static int rbd_dev_snaps_update(struct rbd_device *rbd_dev);
+static int rbd_dev_snaps_register(struct rbd_device *rbd_dev);
+
 static void rbd_dev_release(struct device *dev);
-static ssize_t rbd_snap_add(struct device *dev,
-			    struct device_attribute *attr,
-			    const char *buf,
-			    size_t count);
 static void __rbd_remove_snap_dev(struct rbd_snap *snap);
 
 static ssize_t rbd_add(struct bus_type *bus, const char *buf,
@@ -229,6 +245,18 @@
 	.release =      rbd_root_dev_release,
 };
 
+#ifdef RBD_DEBUG
+#define rbd_assert(expr)						\
+		if (unlikely(!(expr))) {				\
+			printk(KERN_ERR "\nAssertion failure in %s() "	\
+						"at line %d:\n\n"	\
+					"\trbd_assert(%s);\n\n",	\
+					__func__, __LINE__, #expr);	\
+			BUG();						\
+		}
+#else /* !RBD_DEBUG */
+#  define rbd_assert(expr)	((void) 0)
+#endif /* !RBD_DEBUG */
 
 static struct device *rbd_get_dev(struct rbd_device *rbd_dev)
 {
@@ -246,11 +274,11 @@
 {
 	struct rbd_device *rbd_dev = bdev->bd_disk->private_data;
 
-	if ((mode & FMODE_WRITE) && rbd_dev->read_only)
+	if ((mode & FMODE_WRITE) && rbd_dev->mapping.read_only)
 		return -EROFS;
 
 	rbd_get_dev(rbd_dev);
-	set_device_ro(bdev, rbd_dev->read_only);
+	set_device_ro(bdev, rbd_dev->mapping.read_only);
 
 	return 0;
 }
@@ -274,8 +302,7 @@
  * Initialize an rbd client instance.
  * We own *ceph_opts.
  */
-static struct rbd_client *rbd_client_create(struct ceph_options *ceph_opts,
-					    struct rbd_options *rbd_opts)
+static struct rbd_client *rbd_client_create(struct ceph_options *ceph_opts)
 {
 	struct rbd_client *rbdc;
 	int ret = -ENOMEM;
@@ -299,8 +326,6 @@
 	if (ret < 0)
 		goto out_err;
 
-	rbdc->rbd_opts = rbd_opts;
-
 	spin_lock(&rbd_client_list_lock);
 	list_add_tail(&rbdc->node, &rbd_client_list);
 	spin_unlock(&rbd_client_list_lock);
@@ -322,36 +347,52 @@
 }
 
 /*
- * Find a ceph client with specific addr and configuration.
+ * Find a ceph client with specific addr and configuration.  If
+ * found, bump its reference count.
  */
-static struct rbd_client *__rbd_client_find(struct ceph_options *ceph_opts)
+static struct rbd_client *rbd_client_find(struct ceph_options *ceph_opts)
 {
 	struct rbd_client *client_node;
+	bool found = false;
 
 	if (ceph_opts->flags & CEPH_OPT_NOSHARE)
 		return NULL;
 
-	list_for_each_entry(client_node, &rbd_client_list, node)
-		if (!ceph_compare_options(ceph_opts, client_node->client))
-			return client_node;
-	return NULL;
+	spin_lock(&rbd_client_list_lock);
+	list_for_each_entry(client_node, &rbd_client_list, node) {
+		if (!ceph_compare_options(ceph_opts, client_node->client)) {
+			kref_get(&client_node->kref);
+			found = true;
+			break;
+		}
+	}
+	spin_unlock(&rbd_client_list_lock);
+
+	return found ? client_node : NULL;
 }
 
 /*
  * mount options
  */
 enum {
-	Opt_notify_timeout,
 	Opt_last_int,
 	/* int args above */
 	Opt_last_string,
 	/* string args above */
+	Opt_read_only,
+	Opt_read_write,
+	/* Boolean args above */
+	Opt_last_bool,
 };
 
 static match_table_t rbd_opts_tokens = {
-	{Opt_notify_timeout, "notify_timeout=%d"},
 	/* int args above */
 	/* string args above */
+	{Opt_read_only, "mapping.read_only"},
+	{Opt_read_only, "ro"},		/* Alternate spelling */
+	{Opt_read_write, "read_write"},
+	{Opt_read_write, "rw"},		/* Alternate spelling */
+	/* Boolean args above */
 	{-1, NULL}
 };
 
@@ -376,16 +417,22 @@
 	} else if (token > Opt_last_int && token < Opt_last_string) {
 		dout("got string token %d val %s\n", token,
 		     argstr[0].from);
+	} else if (token > Opt_last_string && token < Opt_last_bool) {
+		dout("got Boolean token %d\n", token);
 	} else {
 		dout("got token %d\n", token);
 	}
 
 	switch (token) {
-	case Opt_notify_timeout:
-		rbd_opts->notify_timeout = intval;
+	case Opt_read_only:
+		rbd_opts->read_only = true;
+		break;
+	case Opt_read_write:
+		rbd_opts->read_only = false;
 		break;
 	default:
-		BUG_ON(token);
+		rbd_assert(false);
+		break;
 	}
 	return 0;
 }
@@ -394,48 +441,33 @@
  * Get a ceph client with specific addr and configuration, if one does
  * not exist create it.
  */
-static struct rbd_client *rbd_get_client(const char *mon_addr,
-					 size_t mon_addr_len,
-					 char *options)
+static int rbd_get_client(struct rbd_device *rbd_dev, const char *mon_addr,
+				size_t mon_addr_len, char *options)
 {
-	struct rbd_client *rbdc;
+	struct rbd_options *rbd_opts = &rbd_dev->rbd_opts;
 	struct ceph_options *ceph_opts;
-	struct rbd_options *rbd_opts;
+	struct rbd_client *rbdc;
 
-	rbd_opts = kzalloc(sizeof(*rbd_opts), GFP_KERNEL);
-	if (!rbd_opts)
-		return ERR_PTR(-ENOMEM);
-
-	rbd_opts->notify_timeout = RBD_NOTIFY_TIMEOUT_DEFAULT;
+	rbd_opts->read_only = RBD_READ_ONLY_DEFAULT;
 
 	ceph_opts = ceph_parse_options(options, mon_addr,
 					mon_addr + mon_addr_len,
 					parse_rbd_opts_token, rbd_opts);
-	if (IS_ERR(ceph_opts)) {
-		kfree(rbd_opts);
-		return ERR_CAST(ceph_opts);
-	}
+	if (IS_ERR(ceph_opts))
+		return PTR_ERR(ceph_opts);
 
-	spin_lock(&rbd_client_list_lock);
-	rbdc = __rbd_client_find(ceph_opts);
+	rbdc = rbd_client_find(ceph_opts);
 	if (rbdc) {
 		/* using an existing client */
-		kref_get(&rbdc->kref);
-		spin_unlock(&rbd_client_list_lock);
-
 		ceph_destroy_options(ceph_opts);
-		kfree(rbd_opts);
-
-		return rbdc;
+	} else {
+		rbdc = rbd_client_create(ceph_opts);
+		if (IS_ERR(rbdc))
+			return PTR_ERR(rbdc);
 	}
-	spin_unlock(&rbd_client_list_lock);
+	rbd_dev->rbd_client = rbdc;
 
-	rbdc = rbd_client_create(ceph_opts, rbd_opts);
-
-	if (IS_ERR(rbdc))
-		kfree(rbd_opts);
-
-	return rbdc;
+	return 0;
 }
 
 /*
@@ -453,7 +485,6 @@
 	spin_unlock(&rbd_client_list_lock);
 
 	ceph_destroy_client(rbdc->client);
-	kfree(rbdc->rbd_opts);
 	kfree(rbdc);
 }
 
@@ -479,10 +510,38 @@
 	kfree(coll);
 }
 
+static bool rbd_image_format_valid(u32 image_format)
+{
+	return image_format == 1 || image_format == 2;
+}
+
 static bool rbd_dev_ondisk_valid(struct rbd_image_header_ondisk *ondisk)
 {
-	return !memcmp(&ondisk->text,
-			RBD_HEADER_TEXT, sizeof (RBD_HEADER_TEXT));
+	size_t size;
+	u32 snap_count;
+
+	/* The header has to start with the magic rbd header text */
+	if (memcmp(&ondisk->text, RBD_HEADER_TEXT, sizeof (RBD_HEADER_TEXT)))
+		return false;
+
+	/*
+	 * The size of a snapshot header has to fit in a size_t, and
+	 * that limits the number of snapshots.
+	 */
+	snap_count = le32_to_cpu(ondisk->snap_count);
+	size = SIZE_MAX - sizeof (struct ceph_snap_context);
+	if (snap_count > size / sizeof (__le64))
+		return false;
+
+	/*
+	 * Not only that, but the size of the entire the snapshot
+	 * header must also be representable in a size_t.
+	 */
+	size -= snap_count * sizeof (__le64);
+	if ((u64) size < le64_to_cpu(ondisk->snap_names_len))
+		return false;
+
+	return true;
 }
 
 /*
@@ -490,179 +549,203 @@
  * header.
  */
 static int rbd_header_from_disk(struct rbd_image_header *header,
-				 struct rbd_image_header_ondisk *ondisk,
-				 u32 allocated_snaps)
+				 struct rbd_image_header_ondisk *ondisk)
 {
 	u32 snap_count;
+	size_t len;
+	size_t size;
+	u32 i;
 
-	if (!rbd_dev_ondisk_valid(ondisk))
-		return -ENXIO;
+	memset(header, 0, sizeof (*header));
 
 	snap_count = le32_to_cpu(ondisk->snap_count);
-	if (snap_count > (SIZE_MAX - sizeof(struct ceph_snap_context))
-				 / sizeof (u64))
-		return -EINVAL;
-	header->snapc = kmalloc(sizeof(struct ceph_snap_context) +
-				snap_count * sizeof(u64),
-				GFP_KERNEL);
-	if (!header->snapc)
+
+	len = strnlen(ondisk->object_prefix, sizeof (ondisk->object_prefix));
+	header->object_prefix = kmalloc(len + 1, GFP_KERNEL);
+	if (!header->object_prefix)
 		return -ENOMEM;
+	memcpy(header->object_prefix, ondisk->object_prefix, len);
+	header->object_prefix[len] = '\0';
 
 	if (snap_count) {
-		header->snap_names_len = le64_to_cpu(ondisk->snap_names_len);
-		header->snap_names = kmalloc(header->snap_names_len,
-					     GFP_KERNEL);
+		u64 snap_names_len = le64_to_cpu(ondisk->snap_names_len);
+
+		/* Save a copy of the snapshot names */
+
+		if (snap_names_len > (u64) SIZE_MAX)
+			return -EIO;
+		header->snap_names = kmalloc(snap_names_len, GFP_KERNEL);
 		if (!header->snap_names)
-			goto err_snapc;
-		header->snap_sizes = kmalloc(snap_count * sizeof(u64),
-					     GFP_KERNEL);
+			goto out_err;
+		/*
+		 * Note that rbd_dev_v1_header_read() guarantees
+		 * the ondisk buffer we're working with has
+		 * snap_names_len bytes beyond the end of the
+		 * snapshot id array, this memcpy() is safe.
+		 */
+		memcpy(header->snap_names, &ondisk->snaps[snap_count],
+			snap_names_len);
+
+		/* Record each snapshot's size */
+
+		size = snap_count * sizeof (*header->snap_sizes);
+		header->snap_sizes = kmalloc(size, GFP_KERNEL);
 		if (!header->snap_sizes)
-			goto err_names;
+			goto out_err;
+		for (i = 0; i < snap_count; i++)
+			header->snap_sizes[i] =
+				le64_to_cpu(ondisk->snaps[i].image_size);
 	} else {
 		WARN_ON(ondisk->snap_names_len);
-		header->snap_names_len = 0;
 		header->snap_names = NULL;
 		header->snap_sizes = NULL;
 	}
 
-	header->object_prefix = kmalloc(sizeof (ondisk->block_name) + 1,
-					GFP_KERNEL);
-	if (!header->object_prefix)
-		goto err_sizes;
-
-	memcpy(header->object_prefix, ondisk->block_name,
-	       sizeof(ondisk->block_name));
-	header->object_prefix[sizeof (ondisk->block_name)] = '\0';
-
-	header->image_size = le64_to_cpu(ondisk->image_size);
+	header->features = 0;	/* No features support in v1 images */
 	header->obj_order = ondisk->options.order;
 	header->crypt_type = ondisk->options.crypt_type;
 	header->comp_type = ondisk->options.comp_type;
 
+	/* Allocate and fill in the snapshot context */
+
+	header->image_size = le64_to_cpu(ondisk->image_size);
+	size = sizeof (struct ceph_snap_context);
+	size += snap_count * sizeof (header->snapc->snaps[0]);
+	header->snapc = kzalloc(size, GFP_KERNEL);
+	if (!header->snapc)
+		goto out_err;
+
 	atomic_set(&header->snapc->nref, 1);
 	header->snapc->seq = le64_to_cpu(ondisk->snap_seq);
 	header->snapc->num_snaps = snap_count;
-	header->total_snaps = snap_count;
-
-	if (snap_count && allocated_snaps == snap_count) {
-		int i;
-
-		for (i = 0; i < snap_count; i++) {
-			header->snapc->snaps[i] =
-				le64_to_cpu(ondisk->snaps[i].id);
-			header->snap_sizes[i] =
-				le64_to_cpu(ondisk->snaps[i].image_size);
-		}
-
-		/* copy snapshot names */
-		memcpy(header->snap_names, &ondisk->snaps[snap_count],
-			header->snap_names_len);
-	}
+	for (i = 0; i < snap_count; i++)
+		header->snapc->snaps[i] =
+			le64_to_cpu(ondisk->snaps[i].id);
 
 	return 0;
 
-err_sizes:
+out_err:
 	kfree(header->snap_sizes);
 	header->snap_sizes = NULL;
-err_names:
 	kfree(header->snap_names);
 	header->snap_names = NULL;
-err_snapc:
-	kfree(header->snapc);
-	header->snapc = NULL;
+	kfree(header->object_prefix);
+	header->object_prefix = NULL;
 
 	return -ENOMEM;
 }
 
-static int snap_by_name(struct rbd_image_header *header, const char *snap_name,
-			u64 *seq, u64 *size)
+static int snap_by_name(struct rbd_device *rbd_dev, const char *snap_name)
 {
-	int i;
-	char *p = header->snap_names;
 
-	for (i = 0; i < header->total_snaps; i++) {
-		if (!strcmp(snap_name, p)) {
+	struct rbd_snap *snap;
 
-			/* Found it.  Pass back its id and/or size */
+	list_for_each_entry(snap, &rbd_dev->snaps, node) {
+		if (!strcmp(snap_name, snap->name)) {
+			rbd_dev->mapping.snap_id = snap->id;
+			rbd_dev->mapping.size = snap->size;
+			rbd_dev->mapping.features = snap->features;
 
-			if (seq)
-				*seq = header->snapc->snaps[i];
-			if (size)
-				*size = header->snap_sizes[i];
-			return i;
+			return 0;
 		}
-		p += strlen(p) + 1;	/* Skip ahead to the next name */
 	}
+
 	return -ENOENT;
 }
 
-static int rbd_header_set_snap(struct rbd_device *rbd_dev, u64 *size)
+static int rbd_dev_set_mapping(struct rbd_device *rbd_dev, char *snap_name)
 {
 	int ret;
 
-	down_write(&rbd_dev->header_rwsem);
-
-	if (!memcmp(rbd_dev->snap_name, RBD_SNAP_HEAD_NAME,
+	if (!memcmp(snap_name, RBD_SNAP_HEAD_NAME,
 		    sizeof (RBD_SNAP_HEAD_NAME))) {
-		rbd_dev->snap_id = CEPH_NOSNAP;
-		rbd_dev->snap_exists = false;
-		rbd_dev->read_only = 0;
-		if (size)
-			*size = rbd_dev->header.image_size;
+		rbd_dev->mapping.snap_id = CEPH_NOSNAP;
+		rbd_dev->mapping.size = rbd_dev->header.image_size;
+		rbd_dev->mapping.features = rbd_dev->header.features;
+		rbd_dev->mapping.snap_exists = false;
+		rbd_dev->mapping.read_only = rbd_dev->rbd_opts.read_only;
+		ret = 0;
 	} else {
-		u64 snap_id = 0;
-
-		ret = snap_by_name(&rbd_dev->header, rbd_dev->snap_name,
-					&snap_id, size);
+		ret = snap_by_name(rbd_dev, snap_name);
 		if (ret < 0)
 			goto done;
-		rbd_dev->snap_id = snap_id;
-		rbd_dev->snap_exists = true;
-		rbd_dev->read_only = 1;
+		rbd_dev->mapping.snap_exists = true;
+		rbd_dev->mapping.read_only = true;
 	}
-
-	ret = 0;
+	rbd_dev->mapping.snap_name = snap_name;
 done:
-	up_write(&rbd_dev->header_rwsem);
 	return ret;
 }
 
 static void rbd_header_free(struct rbd_image_header *header)
 {
 	kfree(header->object_prefix);
+	header->object_prefix = NULL;
 	kfree(header->snap_sizes);
+	header->snap_sizes = NULL;
 	kfree(header->snap_names);
+	header->snap_names = NULL;
 	ceph_put_snap_context(header->snapc);
+	header->snapc = NULL;
 }
 
-/*
- * get the actual striped segment name, offset and length
- */
-static u64 rbd_get_segment(struct rbd_image_header *header,
-			   const char *object_prefix,
-			   u64 ofs, u64 len,
-			   char *seg_name, u64 *segofs)
+static char *rbd_segment_name(struct rbd_device *rbd_dev, u64 offset)
 {
-	u64 seg = ofs >> header->obj_order;
+	char *name;
+	u64 segment;
+	int ret;
 
-	if (seg_name)
-		snprintf(seg_name, RBD_MAX_SEG_NAME_LEN,
-			 "%s.%012llx", object_prefix, seg);
+	name = kmalloc(RBD_MAX_SEG_NAME_LEN + 1, GFP_NOIO);
+	if (!name)
+		return NULL;
+	segment = offset >> rbd_dev->header.obj_order;
+	ret = snprintf(name, RBD_MAX_SEG_NAME_LEN, "%s.%012llx",
+			rbd_dev->header.object_prefix, segment);
+	if (ret < 0 || ret >= RBD_MAX_SEG_NAME_LEN) {
+		pr_err("error formatting segment name for #%llu (%d)\n",
+			segment, ret);
+		kfree(name);
+		name = NULL;
+	}
 
-	ofs = ofs & ((1 << header->obj_order) - 1);
-	len = min_t(u64, len, (1 << header->obj_order) - ofs);
+	return name;
+}
 
-	if (segofs)
-		*segofs = ofs;
+static u64 rbd_segment_offset(struct rbd_device *rbd_dev, u64 offset)
+{
+	u64 segment_size = (u64) 1 << rbd_dev->header.obj_order;
 
-	return len;
+	return offset & (segment_size - 1);
+}
+
+static u64 rbd_segment_length(struct rbd_device *rbd_dev,
+				u64 offset, u64 length)
+{
+	u64 segment_size = (u64) 1 << rbd_dev->header.obj_order;
+
+	offset &= segment_size - 1;
+
+	rbd_assert(length <= U64_MAX - offset);
+	if (offset + length > segment_size)
+		length = segment_size - offset;
+
+	return length;
 }
 
 static int rbd_get_num_segments(struct rbd_image_header *header,
 				u64 ofs, u64 len)
 {
-	u64 start_seg = ofs >> header->obj_order;
-	u64 end_seg = (ofs + len - 1) >> header->obj_order;
+	u64 start_seg;
+	u64 end_seg;
+
+	if (!len)
+		return 0;
+	if (len - 1 > U64_MAX - ofs)
+		return -ERANGE;
+
+	start_seg = ofs >> header->obj_order;
+	end_seg = (ofs + len - 1) >> header->obj_order;
+
 	return end_seg - start_seg + 1;
 }
 
@@ -724,7 +807,9 @@
 				   struct bio_pair **bp,
 				   int len, gfp_t gfpmask)
 {
-	struct bio *tmp, *old_chain = *old, *new_chain = NULL, *tail = NULL;
+	struct bio *old_chain = *old;
+	struct bio *new_chain = NULL;
+	struct bio *tail;
 	int total = 0;
 
 	if (*bp) {
@@ -733,9 +818,12 @@
 	}
 
 	while (old_chain && (total < len)) {
+		struct bio *tmp;
+
 		tmp = bio_kmalloc(gfpmask, old_chain->bi_max_vecs);
 		if (!tmp)
 			goto err_out;
+		gfpmask &= ~__GFP_WAIT;	/* can't wait after the first */
 
 		if (total + old_chain->bi_size > len) {
 			struct bio_pair *bp;
@@ -763,24 +851,18 @@
 		}
 
 		tmp->bi_bdev = NULL;
-		gfpmask &= ~__GFP_WAIT;
 		tmp->bi_next = NULL;
-
-		if (!new_chain) {
-			new_chain = tail = tmp;
-		} else {
+		if (new_chain)
 			tail->bi_next = tmp;
-			tail = tmp;
-		}
+		else
+			new_chain = tmp;
+		tail = tmp;
 		old_chain = old_chain->bi_next;
 
 		total += tmp->bi_size;
 	}
 
-	BUG_ON(total < len);
-
-	if (tail)
-		tail->bi_next = NULL;
+	rbd_assert(total == len);
 
 	*old = old_chain;
 
@@ -938,8 +1020,9 @@
 	layout->fl_stripe_count = cpu_to_le32(1);
 	layout->fl_object_size = cpu_to_le32(1 << RBD_MAX_OBJ_ORDER);
 	layout->fl_pg_pool = cpu_to_le32(rbd_dev->pool_id);
-	ceph_calc_raw_layout(osdc, layout, snapid, ofs, &len, &bno,
-				req, ops);
+	ret = ceph_calc_raw_layout(osdc, layout, snapid, ofs, &len, &bno,
+				   req, ops);
+	rbd_assert(ret == 0);
 
 	ceph_osdc_build_request(req, ofs, &len,
 				ops,
@@ -1030,8 +1113,8 @@
 			   int flags,
 			   struct ceph_osd_req_op *ops,
 			   const char *object_name,
-			   u64 ofs, u64 len,
-			   char *buf,
+			   u64 ofs, u64 inbound_size,
+			   char *inbound,
 			   struct ceph_osd_request **linger_req,
 			   u64 *ver)
 {
@@ -1039,15 +1122,15 @@
 	struct page **pages;
 	int num_pages;
 
-	BUG_ON(ops == NULL);
+	rbd_assert(ops != NULL);
 
-	num_pages = calc_pages_for(ofs , len);
+	num_pages = calc_pages_for(ofs, inbound_size);
 	pages = ceph_alloc_page_vector(num_pages, GFP_KERNEL);
 	if (IS_ERR(pages))
 		return PTR_ERR(pages);
 
 	ret = rbd_do_request(NULL, rbd_dev, snapc, snapid,
-			  object_name, ofs, len, NULL,
+			  object_name, ofs, inbound_size, NULL,
 			  pages, num_pages,
 			  flags,
 			  ops,
@@ -1057,8 +1140,8 @@
 	if (ret < 0)
 		goto done;
 
-	if ((flags & CEPH_OSD_FLAG_READ) && buf)
-		ret = ceph_copy_from_page_vector(pages, buf, ofs, ret);
+	if ((flags & CEPH_OSD_FLAG_READ) && inbound)
+		ret = ceph_copy_from_page_vector(pages, inbound, ofs, ret);
 
 done:
 	ceph_release_page_vector(pages, num_pages);
@@ -1085,14 +1168,11 @@
 	struct ceph_osd_req_op *ops;
 	u32 payload_len;
 
-	seg_name = kmalloc(RBD_MAX_SEG_NAME_LEN + 1, GFP_NOIO);
+	seg_name = rbd_segment_name(rbd_dev, ofs);
 	if (!seg_name)
 		return -ENOMEM;
-
-	seg_len = rbd_get_segment(&rbd_dev->header,
-				  rbd_dev->header.object_prefix,
-				  ofs, len,
-				  seg_name, &seg_ofs);
+	seg_len = rbd_segment_length(rbd_dev, ofs, len);
+	seg_ofs = rbd_segment_offset(rbd_dev, ofs);
 
 	payload_len = (flags & CEPH_OSD_FLAG_WRITE ? seg_len : 0);
 
@@ -1104,7 +1184,7 @@
 	/* we've taken care of segment sizes earlier when we
 	   cloned the bios. We should never have a segment
 	   truncated at this point */
-	BUG_ON(seg_len < len);
+	rbd_assert(seg_len == len);
 
 	ret = rbd_do_request(rq, rbd_dev, snapc, snapid,
 			     seg_name, seg_ofs, seg_len,
@@ -1306,89 +1386,36 @@
 	return ret;
 }
 
-struct rbd_notify_info {
-	struct rbd_device *rbd_dev;
-};
-
-static void rbd_notify_cb(u64 ver, u64 notify_id, u8 opcode, void *data)
-{
-	struct rbd_device *rbd_dev = (struct rbd_device *)data;
-	if (!rbd_dev)
-		return;
-
-	dout("rbd_notify_cb %s notify_id=%llu opcode=%u\n",
-			rbd_dev->header_name, (unsigned long long) notify_id,
-			(unsigned int) opcode);
-}
-
 /*
- * Request sync osd notify
- */
-static int rbd_req_sync_notify(struct rbd_device *rbd_dev)
-{
-	struct ceph_osd_req_op *ops;
-	struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc;
-	struct ceph_osd_event *event;
-	struct rbd_notify_info info;
-	int payload_len = sizeof(u32) + sizeof(u32);
-	int ret;
-
-	ops = rbd_create_rw_ops(1, CEPH_OSD_OP_NOTIFY, payload_len);
-	if (!ops)
-		return -ENOMEM;
-
-	info.rbd_dev = rbd_dev;
-
-	ret = ceph_osdc_create_event(osdc, rbd_notify_cb, 1,
-				     (void *)&info, &event);
-	if (ret < 0)
-		goto fail;
-
-	ops[0].watch.ver = 1;
-	ops[0].watch.flag = 1;
-	ops[0].watch.cookie = event->cookie;
-	ops[0].watch.prot_ver = RADOS_NOTIFY_VER;
-	ops[0].watch.timeout = 12;
-
-	ret = rbd_req_sync_op(rbd_dev, NULL,
-			       CEPH_NOSNAP,
-			       CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK,
-			       ops,
-			       rbd_dev->header_name,
-			       0, 0, NULL, NULL, NULL);
-	if (ret < 0)
-		goto fail_event;
-
-	ret = ceph_osdc_wait_event(event, CEPH_OSD_TIMEOUT_DEFAULT);
-	dout("ceph_osdc_wait_event returned %d\n", ret);
-	rbd_destroy_ops(ops);
-	return 0;
-
-fail_event:
-	ceph_osdc_cancel_event(event);
-fail:
-	rbd_destroy_ops(ops);
-	return ret;
-}
-
-/*
- * Request sync osd read
+ * Synchronous osd object method call
  */
 static int rbd_req_sync_exec(struct rbd_device *rbd_dev,
 			     const char *object_name,
 			     const char *class_name,
 			     const char *method_name,
-			     const char *data,
-			     int len,
+			     const char *outbound,
+			     size_t outbound_size,
+			     char *inbound,
+			     size_t inbound_size,
+			     int flags,
 			     u64 *ver)
 {
 	struct ceph_osd_req_op *ops;
 	int class_name_len = strlen(class_name);
 	int method_name_len = strlen(method_name);
+	int payload_size;
 	int ret;
 
-	ops = rbd_create_rw_ops(1, CEPH_OSD_OP_CALL,
-				    class_name_len + method_name_len + len);
+	/*
+	 * Any input parameters required by the method we're calling
+	 * will be sent along with the class and method names as
+	 * part of the message payload.  That data and its size are
+	 * supplied via the indata and indata_len fields (named from
+	 * the perspective of the server side) in the OSD request
+	 * operation.
+	 */
+	payload_size = class_name_len + method_name_len + outbound_size;
+	ops = rbd_create_rw_ops(1, CEPH_OSD_OP_CALL, payload_size);
 	if (!ops)
 		return -ENOMEM;
 
@@ -1397,14 +1424,14 @@
 	ops[0].cls.method_name = method_name;
 	ops[0].cls.method_len = (__u8) method_name_len;
 	ops[0].cls.argc = 0;
-	ops[0].cls.indata = data;
-	ops[0].cls.indata_len = len;
+	ops[0].cls.indata = outbound;
+	ops[0].cls.indata_len = outbound_size;
 
 	ret = rbd_req_sync_op(rbd_dev, NULL,
 			       CEPH_NOSNAP,
-			       CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK,
-			       ops,
-			       object_name, 0, 0, NULL, NULL, ver);
+			       flags, ops,
+			       object_name, 0, inbound_size, inbound,
+			       NULL, ver);
 
 	rbd_destroy_ops(ops);
 
@@ -1446,10 +1473,6 @@
 		struct rbd_req_coll *coll;
 		struct ceph_snap_context *snapc;
 
-		/* peek at request from block layer */
-		if (!rq)
-			break;
-
 		dout("fetched request\n");
 
 		/* filter out block requests we don't understand */
@@ -1464,7 +1487,7 @@
 		size = blk_rq_bytes(rq);
 		ofs = blk_rq_pos(rq) * SECTOR_SIZE;
 		rq_bio = rq->bio;
-		if (do_write && rbd_dev->read_only) {
+		if (do_write && rbd_dev->mapping.read_only) {
 			__blk_end_request_all(rq, -EROFS);
 			continue;
 		}
@@ -1473,7 +1496,8 @@
 
 		down_read(&rbd_dev->header_rwsem);
 
-		if (rbd_dev->snap_id != CEPH_NOSNAP && !rbd_dev->snap_exists) {
+		if (rbd_dev->mapping.snap_id != CEPH_NOSNAP &&
+				!rbd_dev->mapping.snap_exists) {
 			up_read(&rbd_dev->header_rwsem);
 			dout("request for non-existent snapshot");
 			spin_lock_irq(q->queue_lock);
@@ -1490,6 +1514,12 @@
 		     size, (unsigned long long) blk_rq_pos(rq) * SECTOR_SIZE);
 
 		num_segs = rbd_get_num_segments(&rbd_dev->header, ofs, size);
+		if (num_segs <= 0) {
+			spin_lock_irq(q->queue_lock);
+			__blk_end_request_all(rq, num_segs);
+			ceph_put_snap_context(snapc);
+			continue;
+		}
 		coll = rbd_alloc_coll(num_segs);
 		if (!coll) {
 			spin_lock_irq(q->queue_lock);
@@ -1501,10 +1531,7 @@
 		do {
 			/* a bio clone to be passed down to OSD req */
 			dout("rq->bio->bi_vcnt=%hu\n", rq->bio->bi_vcnt);
-			op_size = rbd_get_segment(&rbd_dev->header,
-						  rbd_dev->header.object_prefix,
-						  ofs, size,
-						  NULL, NULL);
+			op_size = rbd_segment_length(rbd_dev, ofs, size);
 			kref_get(&coll->kref);
 			bio = bio_chain_clone(&rq_bio, &next_bio, &bp,
 					      op_size, GFP_ATOMIC);
@@ -1524,7 +1551,7 @@
 					      coll, cur_seg);
 			else
 				rbd_req_read(rq, rbd_dev,
-					     rbd_dev->snap_id,
+					     rbd_dev->mapping.snap_id,
 					     ofs,
 					     op_size, bio,
 					     coll, cur_seg);
@@ -1580,8 +1607,6 @@
 	if (!disk)
 		return;
 
-	rbd_header_free(&rbd_dev->header);
-
 	if (disk->flags & GENHD_FL_UP)
 		del_gendisk(disk);
 	if (disk->queue)
@@ -1590,105 +1615,96 @@
 }
 
 /*
- * reload the ondisk the header 
+ * Read the complete header for the given rbd device.
+ *
+ * Returns a pointer to a dynamically-allocated buffer containing
+ * the complete and validated header.  Caller can pass the address
+ * of a variable that will be filled in with the version of the
+ * header object at the time it was read.
+ *
+ * Returns a pointer-coded errno if a failure occurs.
+ */
+static struct rbd_image_header_ondisk *
+rbd_dev_v1_header_read(struct rbd_device *rbd_dev, u64 *version)
+{
+	struct rbd_image_header_ondisk *ondisk = NULL;
+	u32 snap_count = 0;
+	u64 names_size = 0;
+	u32 want_count;
+	int ret;
+
+	/*
+	 * The complete header will include an array of its 64-bit
+	 * snapshot ids, followed by the names of those snapshots as
+	 * a contiguous block of NUL-terminated strings.  Note that
+	 * the number of snapshots could change by the time we read
+	 * it in, in which case we re-read it.
+	 */
+	do {
+		size_t size;
+
+		kfree(ondisk);
+
+		size = sizeof (*ondisk);
+		size += snap_count * sizeof (struct rbd_image_snap_ondisk);
+		size += names_size;
+		ondisk = kmalloc(size, GFP_KERNEL);
+		if (!ondisk)
+			return ERR_PTR(-ENOMEM);
+
+		ret = rbd_req_sync_read(rbd_dev, CEPH_NOSNAP,
+				       rbd_dev->header_name,
+				       0, size,
+				       (char *) ondisk, version);
+
+		if (ret < 0)
+			goto out_err;
+		if (WARN_ON((size_t) ret < size)) {
+			ret = -ENXIO;
+			pr_warning("short header read for image %s"
+					" (want %zd got %d)\n",
+				rbd_dev->image_name, size, ret);
+			goto out_err;
+		}
+		if (!rbd_dev_ondisk_valid(ondisk)) {
+			ret = -ENXIO;
+			pr_warning("invalid header for image %s\n",
+				rbd_dev->image_name);
+			goto out_err;
+		}
+
+		names_size = le64_to_cpu(ondisk->snap_names_len);
+		want_count = snap_count;
+		snap_count = le32_to_cpu(ondisk->snap_count);
+	} while (snap_count != want_count);
+
+	return ondisk;
+
+out_err:
+	kfree(ondisk);
+
+	return ERR_PTR(ret);
+}
+
+/*
+ * reload the ondisk the header
  */
 static int rbd_read_header(struct rbd_device *rbd_dev,
 			   struct rbd_image_header *header)
 {
-	ssize_t rc;
-	struct rbd_image_header_ondisk *dh;
-	u32 snap_count = 0;
-	u64 ver;
-	size_t len;
-
-	/*
-	 * First reads the fixed-size header to determine the number
-	 * of snapshots, then re-reads it, along with all snapshot
-	 * records as well as their stored names.
-	 */
-	len = sizeof (*dh);
-	while (1) {
-		dh = kmalloc(len, GFP_KERNEL);
-		if (!dh)
-			return -ENOMEM;
-
-		rc = rbd_req_sync_read(rbd_dev,
-				       CEPH_NOSNAP,
-				       rbd_dev->header_name,
-				       0, len,
-				       (char *)dh, &ver);
-		if (rc < 0)
-			goto out_dh;
-
-		rc = rbd_header_from_disk(header, dh, snap_count);
-		if (rc < 0) {
-			if (rc == -ENXIO)
-				pr_warning("unrecognized header format"
-					   " for image %s\n",
-					   rbd_dev->image_name);
-			goto out_dh;
-		}
-
-		if (snap_count == header->total_snaps)
-			break;
-
-		snap_count = header->total_snaps;
-		len = sizeof (*dh) +
-			snap_count * sizeof(struct rbd_image_snap_ondisk) +
-			header->snap_names_len;
-
-		rbd_header_free(header);
-		kfree(dh);
-	}
-	header->obj_version = ver;
-
-out_dh:
-	kfree(dh);
-	return rc;
-}
-
-/*
- * create a snapshot
- */
-static int rbd_header_add_snap(struct rbd_device *rbd_dev,
-			       const char *snap_name,
-			       gfp_t gfp_flags)
-{
-	int name_len = strlen(snap_name);
-	u64 new_snapid;
+	struct rbd_image_header_ondisk *ondisk;
+	u64 ver = 0;
 	int ret;
-	void *data, *p, *e;
-	struct ceph_mon_client *monc;
 
-	/* we should create a snapshot only if we're pointing at the head */
-	if (rbd_dev->snap_id != CEPH_NOSNAP)
-		return -EINVAL;
+	ondisk = rbd_dev_v1_header_read(rbd_dev, &ver);
+	if (IS_ERR(ondisk))
+		return PTR_ERR(ondisk);
+	ret = rbd_header_from_disk(header, ondisk);
+	if (ret >= 0)
+		header->obj_version = ver;
+	kfree(ondisk);
 
-	monc = &rbd_dev->rbd_client->client->monc;
-	ret = ceph_monc_create_snapid(monc, rbd_dev->pool_id, &new_snapid);
-	dout("created snapid=%llu\n", (unsigned long long) new_snapid);
-	if (ret < 0)
-		return ret;
-
-	data = kmalloc(name_len + 16, gfp_flags);
-	if (!data)
-		return -ENOMEM;
-
-	p = data;
-	e = data + name_len + 16;
-
-	ceph_encode_string_safe(&p, e, snap_name, name_len, bad);
-	ceph_encode_64_safe(&p, e, new_snapid, bad);
-
-	ret = rbd_req_sync_exec(rbd_dev, rbd_dev->header_name,
-				"rbd", "snap_add",
-				data, p - data, NULL);
-
-	kfree(data);
-
-	return ret < 0 ? ret : 0;
-bad:
-	return -ERANGE;
+	return ret;
 }
 
 static void __rbd_remove_all_snaps(struct rbd_device *rbd_dev)
@@ -1715,11 +1731,15 @@
 	down_write(&rbd_dev->header_rwsem);
 
 	/* resized? */
-	if (rbd_dev->snap_id == CEPH_NOSNAP) {
+	if (rbd_dev->mapping.snap_id == CEPH_NOSNAP) {
 		sector_t size = (sector_t) h.image_size / SECTOR_SIZE;
 
-		dout("setting size to %llu sectors", (unsigned long long) size);
-		set_capacity(rbd_dev->disk, size);
+		if (size != (sector_t) rbd_dev->mapping.size) {
+			dout("setting size to %llu sectors",
+				(unsigned long long) size);
+			rbd_dev->mapping.size = (u64) size;
+			set_capacity(rbd_dev->disk, size);
+		}
 	}
 
 	/* rbd_dev->header.object_prefix shouldn't change */
@@ -1732,16 +1752,16 @@
 		*hver = h.obj_version;
 	rbd_dev->header.obj_version = h.obj_version;
 	rbd_dev->header.image_size = h.image_size;
-	rbd_dev->header.total_snaps = h.total_snaps;
 	rbd_dev->header.snapc = h.snapc;
 	rbd_dev->header.snap_names = h.snap_names;
-	rbd_dev->header.snap_names_len = h.snap_names_len;
 	rbd_dev->header.snap_sizes = h.snap_sizes;
 	/* Free the extra copy of the object prefix */
 	WARN_ON(strcmp(rbd_dev->header.object_prefix, h.object_prefix));
 	kfree(h.object_prefix);
 
-	ret = __rbd_init_snaps_header(rbd_dev);
+	ret = rbd_dev_snaps_update(rbd_dev);
+	if (!ret)
+		ret = rbd_dev_snaps_register(rbd_dev);
 
 	up_write(&rbd_dev->header_rwsem);
 
@@ -1763,29 +1783,12 @@
 {
 	struct gendisk *disk;
 	struct request_queue *q;
-	int rc;
 	u64 segment_size;
-	u64 total_size = 0;
-
-	/* contact OSD, request size info about the object being mapped */
-	rc = rbd_read_header(rbd_dev, &rbd_dev->header);
-	if (rc)
-		return rc;
-
-	/* no need to lock here, as rbd_dev is not registered yet */
-	rc = __rbd_init_snaps_header(rbd_dev);
-	if (rc)
-		return rc;
-
-	rc = rbd_header_set_snap(rbd_dev, &total_size);
-	if (rc)
-		return rc;
 
 	/* create gendisk info */
-	rc = -ENOMEM;
 	disk = alloc_disk(RBD_MINORS_PER_MAJOR);
 	if (!disk)
-		goto out;
+		return -ENOMEM;
 
 	snprintf(disk->disk_name, sizeof(disk->disk_name), RBD_DRV_NAME "%d",
 		 rbd_dev->dev_id);
@@ -1795,7 +1798,6 @@
 	disk->private_data = rbd_dev;
 
 	/* init rq */
-	rc = -ENOMEM;
 	q = blk_init_queue(rbd_rq_fn, &rbd_dev->lock);
 	if (!q)
 		goto out_disk;
@@ -1816,20 +1818,14 @@
 	q->queuedata = rbd_dev;
 
 	rbd_dev->disk = disk;
-	rbd_dev->q = q;
 
-	/* finally, announce the disk to the world */
-	set_capacity(disk, total_size / SECTOR_SIZE);
-	add_disk(disk);
+	set_capacity(rbd_dev->disk, rbd_dev->mapping.size / SECTOR_SIZE);
 
-	pr_info("%s: added with size 0x%llx\n",
-		disk->disk_name, (unsigned long long)total_size);
 	return 0;
-
 out_disk:
 	put_disk(disk);
-out:
-	return rc;
+
+	return -ENOMEM;
 }
 
 /*
@@ -1854,6 +1850,19 @@
 	return sprintf(buf, "%llu\n", (unsigned long long) size * SECTOR_SIZE);
 }
 
+/*
+ * Note this shows the features for whatever's mapped, which is not
+ * necessarily the base image.
+ */
+static ssize_t rbd_features_show(struct device *dev,
+			     struct device_attribute *attr, char *buf)
+{
+	struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
+
+	return sprintf(buf, "0x%016llx\n",
+			(unsigned long long) rbd_dev->mapping.features);
+}
+
 static ssize_t rbd_major_show(struct device *dev,
 			      struct device_attribute *attr, char *buf)
 {
@@ -1895,13 +1904,25 @@
 	return sprintf(buf, "%s\n", rbd_dev->image_name);
 }
 
+static ssize_t rbd_image_id_show(struct device *dev,
+			     struct device_attribute *attr, char *buf)
+{
+	struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
+
+	return sprintf(buf, "%s\n", rbd_dev->image_id);
+}
+
+/*
+ * Shows the name of the currently-mapped snapshot (or
+ * RBD_SNAP_HEAD_NAME for the base image).
+ */
 static ssize_t rbd_snap_show(struct device *dev,
 			     struct device_attribute *attr,
 			     char *buf)
 {
 	struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
 
-	return sprintf(buf, "%s\n", rbd_dev->snap_name);
+	return sprintf(buf, "%s\n", rbd_dev->mapping.snap_name);
 }
 
 static ssize_t rbd_image_refresh(struct device *dev,
@@ -1918,25 +1939,27 @@
 }
 
 static DEVICE_ATTR(size, S_IRUGO, rbd_size_show, NULL);
+static DEVICE_ATTR(features, S_IRUGO, rbd_features_show, NULL);
 static DEVICE_ATTR(major, S_IRUGO, rbd_major_show, NULL);
 static DEVICE_ATTR(client_id, S_IRUGO, rbd_client_id_show, NULL);
 static DEVICE_ATTR(pool, S_IRUGO, rbd_pool_show, NULL);
 static DEVICE_ATTR(pool_id, S_IRUGO, rbd_pool_id_show, NULL);
 static DEVICE_ATTR(name, S_IRUGO, rbd_name_show, NULL);
+static DEVICE_ATTR(image_id, S_IRUGO, rbd_image_id_show, NULL);
 static DEVICE_ATTR(refresh, S_IWUSR, NULL, rbd_image_refresh);
 static DEVICE_ATTR(current_snap, S_IRUGO, rbd_snap_show, NULL);
-static DEVICE_ATTR(create_snap, S_IWUSR, NULL, rbd_snap_add);
 
 static struct attribute *rbd_attrs[] = {
 	&dev_attr_size.attr,
+	&dev_attr_features.attr,
 	&dev_attr_major.attr,
 	&dev_attr_client_id.attr,
 	&dev_attr_pool.attr,
 	&dev_attr_pool_id.attr,
 	&dev_attr_name.attr,
+	&dev_attr_image_id.attr,
 	&dev_attr_current_snap.attr,
 	&dev_attr_refresh.attr,
-	&dev_attr_create_snap.attr,
 	NULL
 };
 
@@ -1982,12 +2005,24 @@
 	return sprintf(buf, "%llu\n", (unsigned long long)snap->id);
 }
 
+static ssize_t rbd_snap_features_show(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	struct rbd_snap *snap = container_of(dev, struct rbd_snap, dev);
+
+	return sprintf(buf, "0x%016llx\n",
+			(unsigned long long) snap->features);
+}
+
 static DEVICE_ATTR(snap_size, S_IRUGO, rbd_snap_size_show, NULL);
 static DEVICE_ATTR(snap_id, S_IRUGO, rbd_snap_id_show, NULL);
+static DEVICE_ATTR(snap_features, S_IRUGO, rbd_snap_features_show, NULL);
 
 static struct attribute *rbd_snap_attrs[] = {
 	&dev_attr_snap_size.attr,
 	&dev_attr_snap_id.attr,
+	&dev_attr_snap_features.attr,
 	NULL,
 };
 
@@ -2012,10 +2047,21 @@
 	.release	= rbd_snap_dev_release,
 };
 
+static bool rbd_snap_registered(struct rbd_snap *snap)
+{
+	bool ret = snap->dev.type == &rbd_snap_device_type;
+	bool reg = device_is_registered(&snap->dev);
+
+	rbd_assert(!ret ^ reg);
+
+	return ret;
+}
+
 static void __rbd_remove_snap_dev(struct rbd_snap *snap)
 {
 	list_del(&snap->node);
-	device_unregister(&snap->dev);
+	if (device_is_registered(&snap->dev))
+		device_unregister(&snap->dev);
 }
 
 static int rbd_register_snap_dev(struct rbd_snap *snap,
@@ -2028,13 +2074,17 @@
 	dev->parent = parent;
 	dev->release = rbd_snap_dev_release;
 	dev_set_name(dev, "snap_%s", snap->name);
+	dout("%s: registering device for snapshot %s\n", __func__, snap->name);
+
 	ret = device_register(dev);
 
 	return ret;
 }
 
 static struct rbd_snap *__rbd_add_snap_dev(struct rbd_device *rbd_dev,
-					      int i, const char *name)
+						const char *snap_name,
+						u64 snap_id, u64 snap_size,
+						u64 snap_features)
 {
 	struct rbd_snap *snap;
 	int ret;
@@ -2044,17 +2094,13 @@
 		return ERR_PTR(-ENOMEM);
 
 	ret = -ENOMEM;
-	snap->name = kstrdup(name, GFP_KERNEL);
+	snap->name = kstrdup(snap_name, GFP_KERNEL);
 	if (!snap->name)
 		goto err;
 
-	snap->size = rbd_dev->header.snap_sizes[i];
-	snap->id = rbd_dev->header.snapc->snaps[i];
-	if (device_is_registered(&rbd_dev->dev)) {
-		ret = rbd_register_snap_dev(snap, &rbd_dev->dev);
-		if (ret < 0)
-			goto err;
-	}
+	snap->id = snap_id;
+	snap->size = snap_size;
+	snap->features = snap_features;
 
 	return snap;
 
@@ -2065,128 +2111,439 @@
 	return ERR_PTR(ret);
 }
 
-/*
- * search for the previous snap in a null delimited string list
- */
-const char *rbd_prev_snap_name(const char *name, const char *start)
+static char *rbd_dev_v1_snap_info(struct rbd_device *rbd_dev, u32 which,
+		u64 *snap_size, u64 *snap_features)
 {
-	if (name < start + 2)
-		return NULL;
+	char *snap_name;
 
-	name -= 2;
-	while (*name) {
-		if (name == start)
-			return start;
-		name--;
-	}
-	return name + 1;
+	rbd_assert(which < rbd_dev->header.snapc->num_snaps);
+
+	*snap_size = rbd_dev->header.snap_sizes[which];
+	*snap_features = 0;	/* No features for v1 */
+
+	/* Skip over names until we find the one we are looking for */
+
+	snap_name = rbd_dev->header.snap_names;
+	while (which--)
+		snap_name += strlen(snap_name) + 1;
+
+	return snap_name;
 }
 
 /*
- * compare the old list of snapshots that we have to what's in the header
- * and update it accordingly. Note that the header holds the snapshots
- * in a reverse order (from newest to oldest) and we need to go from
- * older to new so that we don't get a duplicate snap name when
- * doing the process (e.g., removed snapshot and recreated a new
- * one with the same name.
+ * Get the size and object order for an image snapshot, or if
+ * snap_id is CEPH_NOSNAP, gets this information for the base
+ * image.
  */
-static int __rbd_init_snaps_header(struct rbd_device *rbd_dev)
+static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id,
+				u8 *order, u64 *snap_size)
 {
-	const char *name, *first_name;
-	int i = rbd_dev->header.total_snaps;
-	struct rbd_snap *snap, *old_snap = NULL;
-	struct list_head *p, *n;
+	__le64 snapid = cpu_to_le64(snap_id);
+	int ret;
+	struct {
+		u8 order;
+		__le64 size;
+	} __attribute__ ((packed)) size_buf = { 0 };
 
-	first_name = rbd_dev->header.snap_names;
-	name = first_name + rbd_dev->header.snap_names_len;
+	ret = rbd_req_sync_exec(rbd_dev, rbd_dev->header_name,
+				"rbd", "get_size",
+				(char *) &snapid, sizeof (snapid),
+				(char *) &size_buf, sizeof (size_buf),
+				CEPH_OSD_FLAG_READ, NULL);
+	dout("%s: rbd_req_sync_exec returned %d\n", __func__, ret);
+	if (ret < 0)
+		return ret;
 
-	list_for_each_prev_safe(p, n, &rbd_dev->snaps) {
-		u64 cur_id;
+	*order = size_buf.order;
+	*snap_size = le64_to_cpu(size_buf.size);
 
-		old_snap = list_entry(p, struct rbd_snap, node);
-
-		if (i)
-			cur_id = rbd_dev->header.snapc->snaps[i - 1];
-
-		if (!i || old_snap->id < cur_id) {
-			/*
-			 * old_snap->id was skipped, thus was
-			 * removed.  If this rbd_dev is mapped to
-			 * the removed snapshot, record that it no
-			 * longer exists, to prevent further I/O.
-			 */
-			if (rbd_dev->snap_id == old_snap->id)
-				rbd_dev->snap_exists = false;
-			__rbd_remove_snap_dev(old_snap);
-			continue;
-		}
-		if (old_snap->id == cur_id) {
-			/* we have this snapshot already */
-			i--;
-			name = rbd_prev_snap_name(name, first_name);
-			continue;
-		}
-		for (; i > 0;
-		     i--, name = rbd_prev_snap_name(name, first_name)) {
-			if (!name) {
-				WARN_ON(1);
-				return -EINVAL;
-			}
-			cur_id = rbd_dev->header.snapc->snaps[i];
-			/* snapshot removal? handle it above */
-			if (cur_id >= old_snap->id)
-				break;
-			/* a new snapshot */
-			snap = __rbd_add_snap_dev(rbd_dev, i - 1, name);
-			if (IS_ERR(snap))
-				return PTR_ERR(snap);
-
-			/* note that we add it backward so using n and not p */
-			list_add(&snap->node, n);
-			p = &snap->node;
-		}
-	}
-	/* we're done going over the old snap list, just add what's left */
-	for (; i > 0; i--) {
-		name = rbd_prev_snap_name(name, first_name);
-		if (!name) {
-			WARN_ON(1);
-			return -EINVAL;
-		}
-		snap = __rbd_add_snap_dev(rbd_dev, i - 1, name);
-		if (IS_ERR(snap))
-			return PTR_ERR(snap);
-		list_add(&snap->node, &rbd_dev->snaps);
-	}
+	dout("  snap_id 0x%016llx order = %u, snap_size = %llu\n",
+		(unsigned long long) snap_id, (unsigned int) *order,
+		(unsigned long long) *snap_size);
 
 	return 0;
 }
 
+static int rbd_dev_v2_image_size(struct rbd_device *rbd_dev)
+{
+	return _rbd_dev_v2_snap_size(rbd_dev, CEPH_NOSNAP,
+					&rbd_dev->header.obj_order,
+					&rbd_dev->header.image_size);
+}
+
+static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev)
+{
+	void *reply_buf;
+	int ret;
+	void *p;
+
+	reply_buf = kzalloc(RBD_OBJ_PREFIX_LEN_MAX, GFP_KERNEL);
+	if (!reply_buf)
+		return -ENOMEM;
+
+	ret = rbd_req_sync_exec(rbd_dev, rbd_dev->header_name,
+				"rbd", "get_object_prefix",
+				NULL, 0,
+				reply_buf, RBD_OBJ_PREFIX_LEN_MAX,
+				CEPH_OSD_FLAG_READ, NULL);
+	dout("%s: rbd_req_sync_exec returned %d\n", __func__, ret);
+	if (ret < 0)
+		goto out;
+
+	p = reply_buf;
+	rbd_dev->header.object_prefix = ceph_extract_encoded_string(&p,
+						p + RBD_OBJ_PREFIX_LEN_MAX,
+						NULL, GFP_NOIO);
+
+	if (IS_ERR(rbd_dev->header.object_prefix)) {
+		ret = PTR_ERR(rbd_dev->header.object_prefix);
+		rbd_dev->header.object_prefix = NULL;
+	} else {
+		dout("  object_prefix = %s\n", rbd_dev->header.object_prefix);
+	}
+
+out:
+	kfree(reply_buf);
+
+	return ret;
+}
+
+static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id,
+		u64 *snap_features)
+{
+	__le64 snapid = cpu_to_le64(snap_id);
+	struct {
+		__le64 features;
+		__le64 incompat;
+	} features_buf = { 0 };
+	int ret;
+
+	ret = rbd_req_sync_exec(rbd_dev, rbd_dev->header_name,
+				"rbd", "get_features",
+				(char *) &snapid, sizeof (snapid),
+				(char *) &features_buf, sizeof (features_buf),
+				CEPH_OSD_FLAG_READ, NULL);
+	dout("%s: rbd_req_sync_exec returned %d\n", __func__, ret);
+	if (ret < 0)
+		return ret;
+	*snap_features = le64_to_cpu(features_buf.features);
+
+	dout("  snap_id 0x%016llx features = 0x%016llx incompat = 0x%016llx\n",
+		(unsigned long long) snap_id,
+		(unsigned long long) *snap_features,
+		(unsigned long long) le64_to_cpu(features_buf.incompat));
+
+	return 0;
+}
+
+static int rbd_dev_v2_features(struct rbd_device *rbd_dev)
+{
+	return _rbd_dev_v2_snap_features(rbd_dev, CEPH_NOSNAP,
+						&rbd_dev->header.features);
+}
+
+static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev, u64 *ver)
+{
+	size_t size;
+	int ret;
+	void *reply_buf;
+	void *p;
+	void *end;
+	u64 seq;
+	u32 snap_count;
+	struct ceph_snap_context *snapc;
+	u32 i;
+
+	/*
+	 * We'll need room for the seq value (maximum snapshot id),
+	 * snapshot count, and array of that many snapshot ids.
+	 * For now we have a fixed upper limit on the number we're
+	 * prepared to receive.
+	 */
+	size = sizeof (__le64) + sizeof (__le32) +
+			RBD_MAX_SNAP_COUNT * sizeof (__le64);
+	reply_buf = kzalloc(size, GFP_KERNEL);
+	if (!reply_buf)
+		return -ENOMEM;
+
+	ret = rbd_req_sync_exec(rbd_dev, rbd_dev->header_name,
+				"rbd", "get_snapcontext",
+				NULL, 0,
+				reply_buf, size,
+				CEPH_OSD_FLAG_READ, ver);
+	dout("%s: rbd_req_sync_exec returned %d\n", __func__, ret);
+	if (ret < 0)
+		goto out;
+
+	ret = -ERANGE;
+	p = reply_buf;
+	end = (char *) reply_buf + size;
+	ceph_decode_64_safe(&p, end, seq, out);
+	ceph_decode_32_safe(&p, end, snap_count, out);
+
+	/*
+	 * Make sure the reported number of snapshot ids wouldn't go
+	 * beyond the end of our buffer.  But before checking that,
+	 * make sure the computed size of the snapshot context we
+	 * allocate is representable in a size_t.
+	 */
+	if (snap_count > (SIZE_MAX - sizeof (struct ceph_snap_context))
+				 / sizeof (u64)) {
+		ret = -EINVAL;
+		goto out;
+	}
+	if (!ceph_has_room(&p, end, snap_count * sizeof (__le64)))
+		goto out;
+
+	size = sizeof (struct ceph_snap_context) +
+				snap_count * sizeof (snapc->snaps[0]);
+	snapc = kmalloc(size, GFP_KERNEL);
+	if (!snapc) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	atomic_set(&snapc->nref, 1);
+	snapc->seq = seq;
+	snapc->num_snaps = snap_count;
+	for (i = 0; i < snap_count; i++)
+		snapc->snaps[i] = ceph_decode_64(&p);
+
+	rbd_dev->header.snapc = snapc;
+
+	dout("  snap context seq = %llu, snap_count = %u\n",
+		(unsigned long long) seq, (unsigned int) snap_count);
+
+out:
+	kfree(reply_buf);
+
+	return 0;
+}
+
+static char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev, u32 which)
+{
+	size_t size;
+	void *reply_buf;
+	__le64 snap_id;
+	int ret;
+	void *p;
+	void *end;
+	size_t snap_name_len;
+	char *snap_name;
+
+	size = sizeof (__le32) + RBD_MAX_SNAP_NAME_LEN;
+	reply_buf = kmalloc(size, GFP_KERNEL);
+	if (!reply_buf)
+		return ERR_PTR(-ENOMEM);
+
+	snap_id = cpu_to_le64(rbd_dev->header.snapc->snaps[which]);
+	ret = rbd_req_sync_exec(rbd_dev, rbd_dev->header_name,
+				"rbd", "get_snapshot_name",
+				(char *) &snap_id, sizeof (snap_id),
+				reply_buf, size,
+				CEPH_OSD_FLAG_READ, NULL);
+	dout("%s: rbd_req_sync_exec returned %d\n", __func__, ret);
+	if (ret < 0)
+		goto out;
+
+	p = reply_buf;
+	end = (char *) reply_buf + size;
+	snap_name_len = 0;
+	snap_name = ceph_extract_encoded_string(&p, end, &snap_name_len,
+				GFP_KERNEL);
+	if (IS_ERR(snap_name)) {
+		ret = PTR_ERR(snap_name);
+		goto out;
+	} else {
+		dout("  snap_id 0x%016llx snap_name = %s\n",
+			(unsigned long long) le64_to_cpu(snap_id), snap_name);
+	}
+	kfree(reply_buf);
+
+	return snap_name;
+out:
+	kfree(reply_buf);
+
+	return ERR_PTR(ret);
+}
+
+static char *rbd_dev_v2_snap_info(struct rbd_device *rbd_dev, u32 which,
+		u64 *snap_size, u64 *snap_features)
+{
+	__le64 snap_id;
+	u8 order;
+	int ret;
+
+	snap_id = rbd_dev->header.snapc->snaps[which];
+	ret = _rbd_dev_v2_snap_size(rbd_dev, snap_id, &order, snap_size);
+	if (ret)
+		return ERR_PTR(ret);
+	ret = _rbd_dev_v2_snap_features(rbd_dev, snap_id, snap_features);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return rbd_dev_v2_snap_name(rbd_dev, which);
+}
+
+static char *rbd_dev_snap_info(struct rbd_device *rbd_dev, u32 which,
+		u64 *snap_size, u64 *snap_features)
+{
+	if (rbd_dev->image_format == 1)
+		return rbd_dev_v1_snap_info(rbd_dev, which,
+					snap_size, snap_features);
+	if (rbd_dev->image_format == 2)
+		return rbd_dev_v2_snap_info(rbd_dev, which,
+					snap_size, snap_features);
+	return ERR_PTR(-EINVAL);
+}
+
+/*
+ * Scan the rbd device's current snapshot list and compare it to the
+ * newly-received snapshot context.  Remove any existing snapshots
+ * not present in the new snapshot context.  Add a new snapshot for
+ * any snaphots in the snapshot context not in the current list.
+ * And verify there are no changes to snapshots we already know
+ * about.
+ *
+ * Assumes the snapshots in the snapshot context are sorted by
+ * snapshot id, highest id first.  (Snapshots in the rbd_dev's list
+ * are also maintained in that order.)
+ */
+static int rbd_dev_snaps_update(struct rbd_device *rbd_dev)
+{
+	struct ceph_snap_context *snapc = rbd_dev->header.snapc;
+	const u32 snap_count = snapc->num_snaps;
+	struct list_head *head = &rbd_dev->snaps;
+	struct list_head *links = head->next;
+	u32 index = 0;
+
+	dout("%s: snap count is %u\n", __func__, (unsigned int) snap_count);
+	while (index < snap_count || links != head) {
+		u64 snap_id;
+		struct rbd_snap *snap;
+		char *snap_name;
+		u64 snap_size = 0;
+		u64 snap_features = 0;
+
+		snap_id = index < snap_count ? snapc->snaps[index]
+					     : CEPH_NOSNAP;
+		snap = links != head ? list_entry(links, struct rbd_snap, node)
+				     : NULL;
+		rbd_assert(!snap || snap->id != CEPH_NOSNAP);
+
+		if (snap_id == CEPH_NOSNAP || (snap && snap->id > snap_id)) {
+			struct list_head *next = links->next;
+
+			/* Existing snapshot not in the new snap context */
+
+			if (rbd_dev->mapping.snap_id == snap->id)
+				rbd_dev->mapping.snap_exists = false;
+			__rbd_remove_snap_dev(snap);
+			dout("%ssnap id %llu has been removed\n",
+				rbd_dev->mapping.snap_id == snap->id ?
+								"mapped " : "",
+				(unsigned long long) snap->id);
+
+			/* Done with this list entry; advance */
+
+			links = next;
+			continue;
+		}
+
+		snap_name = rbd_dev_snap_info(rbd_dev, index,
+					&snap_size, &snap_features);
+		if (IS_ERR(snap_name))
+			return PTR_ERR(snap_name);
+
+		dout("entry %u: snap_id = %llu\n", (unsigned int) snap_count,
+			(unsigned long long) snap_id);
+		if (!snap || (snap_id != CEPH_NOSNAP && snap->id < snap_id)) {
+			struct rbd_snap *new_snap;
+
+			/* We haven't seen this snapshot before */
+
+			new_snap = __rbd_add_snap_dev(rbd_dev, snap_name,
+					snap_id, snap_size, snap_features);
+			if (IS_ERR(new_snap)) {
+				int err = PTR_ERR(new_snap);
+
+				dout("  failed to add dev, error %d\n", err);
+
+				return err;
+			}
+
+			/* New goes before existing, or at end of list */
+
+			dout("  added dev%s\n", snap ? "" : " at end\n");
+			if (snap)
+				list_add_tail(&new_snap->node, &snap->node);
+			else
+				list_add_tail(&new_snap->node, head);
+		} else {
+			/* Already have this one */
+
+			dout("  already present\n");
+
+			rbd_assert(snap->size == snap_size);
+			rbd_assert(!strcmp(snap->name, snap_name));
+			rbd_assert(snap->features == snap_features);
+
+			/* Done with this list entry; advance */
+
+			links = links->next;
+		}
+
+		/* Advance to the next entry in the snapshot context */
+
+		index++;
+	}
+	dout("%s: done\n", __func__);
+
+	return 0;
+}
+
+/*
+ * Scan the list of snapshots and register the devices for any that
+ * have not already been registered.
+ */
+static int rbd_dev_snaps_register(struct rbd_device *rbd_dev)
+{
+	struct rbd_snap *snap;
+	int ret = 0;
+
+	dout("%s called\n", __func__);
+	if (WARN_ON(!device_is_registered(&rbd_dev->dev)))
+		return -EIO;
+
+	list_for_each_entry(snap, &rbd_dev->snaps, node) {
+		if (!rbd_snap_registered(snap)) {
+			ret = rbd_register_snap_dev(snap, &rbd_dev->dev);
+			if (ret < 0)
+				break;
+		}
+	}
+	dout("%s: returning %d\n", __func__, ret);
+
+	return ret;
+}
+
 static int rbd_bus_add_dev(struct rbd_device *rbd_dev)
 {
-	int ret;
 	struct device *dev;
-	struct rbd_snap *snap;
+	int ret;
 
 	mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
-	dev = &rbd_dev->dev;
 
+	dev = &rbd_dev->dev;
 	dev->bus = &rbd_bus_type;
 	dev->type = &rbd_device_type;
 	dev->parent = &rbd_root_dev;
 	dev->release = rbd_dev_release;
 	dev_set_name(dev, "%d", rbd_dev->dev_id);
 	ret = device_register(dev);
-	if (ret < 0)
-		goto out;
 
-	list_for_each_entry(snap, &rbd_dev->snaps, node) {
-		ret = rbd_register_snap_dev(snap, &rbd_dev->dev);
-		if (ret < 0)
-			break;
-	}
-out:
 	mutex_unlock(&ctl_mutex);
+
 	return ret;
 }
 
@@ -2211,33 +2568,37 @@
 	return ret;
 }
 
-static atomic64_t rbd_id_max = ATOMIC64_INIT(0);
+static atomic64_t rbd_dev_id_max = ATOMIC64_INIT(0);
 
 /*
  * Get a unique rbd identifier for the given new rbd_dev, and add
  * the rbd_dev to the global list.  The minimum rbd id is 1.
  */
-static void rbd_id_get(struct rbd_device *rbd_dev)
+static void rbd_dev_id_get(struct rbd_device *rbd_dev)
 {
-	rbd_dev->dev_id = atomic64_inc_return(&rbd_id_max);
+	rbd_dev->dev_id = atomic64_inc_return(&rbd_dev_id_max);
 
 	spin_lock(&rbd_dev_list_lock);
 	list_add_tail(&rbd_dev->node, &rbd_dev_list);
 	spin_unlock(&rbd_dev_list_lock);
+	dout("rbd_dev %p given dev id %llu\n", rbd_dev,
+		(unsigned long long) rbd_dev->dev_id);
 }
 
 /*
  * Remove an rbd_dev from the global list, and record that its
  * identifier is no longer in use.
  */
-static void rbd_id_put(struct rbd_device *rbd_dev)
+static void rbd_dev_id_put(struct rbd_device *rbd_dev)
 {
 	struct list_head *tmp;
 	int rbd_id = rbd_dev->dev_id;
 	int max_id;
 
-	BUG_ON(rbd_id < 1);
+	rbd_assert(rbd_id > 0);
 
+	dout("rbd_dev %p released dev id %llu\n", rbd_dev,
+		(unsigned long long) rbd_dev->dev_id);
 	spin_lock(&rbd_dev_list_lock);
 	list_del_init(&rbd_dev->node);
 
@@ -2245,7 +2606,7 @@
 	 * If the id being "put" is not the current maximum, there
 	 * is nothing special we need to do.
 	 */
-	if (rbd_id != atomic64_read(&rbd_id_max)) {
+	if (rbd_id != atomic64_read(&rbd_dev_id_max)) {
 		spin_unlock(&rbd_dev_list_lock);
 		return;
 	}
@@ -2266,12 +2627,13 @@
 	spin_unlock(&rbd_dev_list_lock);
 
 	/*
-	 * The max id could have been updated by rbd_id_get(), in
+	 * The max id could have been updated by rbd_dev_id_get(), in
 	 * which case it now accurately reflects the new maximum.
 	 * Be careful not to overwrite the maximum value in that
 	 * case.
 	 */
-	atomic64_cmpxchg(&rbd_id_max, rbd_id, max_id);
+	atomic64_cmpxchg(&rbd_dev_id_max, rbd_id, max_id);
+	dout("  max dev id has been reset\n");
 }
 
 /*
@@ -2360,28 +2722,31 @@
 }
 
 /*
- * This fills in the pool_name, image_name, image_name_len, snap_name,
- * rbd_dev, rbd_md_name, and name fields of the given rbd_dev, based
- * on the list of monitor addresses and other options provided via
- * /sys/bus/rbd/add.
+ * This fills in the pool_name, image_name, image_name_len, rbd_dev,
+ * rbd_md_name, and name fields of the given rbd_dev, based on the
+ * list of monitor addresses and other options provided via
+ * /sys/bus/rbd/add.  Returns a pointer to a dynamically-allocated
+ * copy of the snapshot name to map if successful, or a
+ * pointer-coded error otherwise.
  *
  * Note: rbd_dev is assumed to have been initially zero-filled.
  */
-static int rbd_add_parse_args(struct rbd_device *rbd_dev,
-			      const char *buf,
-			      const char **mon_addrs,
-			      size_t *mon_addrs_size,
-			      char *options,
-			     size_t options_size)
+static char *rbd_add_parse_args(struct rbd_device *rbd_dev,
+				const char *buf,
+				const char **mon_addrs,
+				size_t *mon_addrs_size,
+				char *options,
+				size_t options_size)
 {
 	size_t len;
-	int ret;
+	char *err_ptr = ERR_PTR(-EINVAL);
+	char *snap_name;
 
 	/* The first four tokens are required */
 
 	len = next_token(&buf);
 	if (!len)
-		return -EINVAL;
+		return err_ptr;
 	*mon_addrs_size = len + 1;
 	*mon_addrs = buf;
 
@@ -2389,9 +2754,9 @@
 
 	len = copy_token(&buf, options, options_size);
 	if (!len || len >= options_size)
-		return -EINVAL;
+		return err_ptr;
 
-	ret = -ENOMEM;
+	err_ptr = ERR_PTR(-ENOMEM);
 	rbd_dev->pool_name = dup_token(&buf, NULL);
 	if (!rbd_dev->pool_name)
 		goto out_err;
@@ -2400,41 +2765,227 @@
 	if (!rbd_dev->image_name)
 		goto out_err;
 
-	/* Create the name of the header object */
-
-	rbd_dev->header_name = kmalloc(rbd_dev->image_name_len
-						+ sizeof (RBD_SUFFIX),
-					GFP_KERNEL);
-	if (!rbd_dev->header_name)
+	/* Snapshot name is optional */
+	len = next_token(&buf);
+	if (!len) {
+		buf = RBD_SNAP_HEAD_NAME; /* No snapshot supplied */
+		len = sizeof (RBD_SNAP_HEAD_NAME) - 1;
+	}
+	snap_name = kmalloc(len + 1, GFP_KERNEL);
+	if (!snap_name)
 		goto out_err;
-	sprintf(rbd_dev->header_name, "%s%s", rbd_dev->image_name, RBD_SUFFIX);
+	memcpy(snap_name, buf, len);
+	*(snap_name + len) = '\0';
+
+dout("    SNAP_NAME is <%s>, len is %zd\n", snap_name, len);
+
+	return snap_name;
+
+out_err:
+	kfree(rbd_dev->image_name);
+	rbd_dev->image_name = NULL;
+	rbd_dev->image_name_len = 0;
+	kfree(rbd_dev->pool_name);
+	rbd_dev->pool_name = NULL;
+
+	return err_ptr;
+}
+
+/*
+ * An rbd format 2 image has a unique identifier, distinct from the
+ * name given to it by the user.  Internally, that identifier is
+ * what's used to specify the names of objects related to the image.
+ *
+ * A special "rbd id" object is used to map an rbd image name to its
+ * id.  If that object doesn't exist, then there is no v2 rbd image
+ * with the supplied name.
+ *
+ * This function will record the given rbd_dev's image_id field if
+ * it can be determined, and in that case will return 0.  If any
+ * errors occur a negative errno will be returned and the rbd_dev's
+ * image_id field will be unchanged (and should be NULL).
+ */
+static int rbd_dev_image_id(struct rbd_device *rbd_dev)
+{
+	int ret;
+	size_t size;
+	char *object_name;
+	void *response;
+	void *p;
 
 	/*
-	 * The snapshot name is optional.  If none is is supplied,
-	 * we use the default value.
+	 * First, see if the format 2 image id file exists, and if
+	 * so, get the image's persistent id from it.
 	 */
-	rbd_dev->snap_name = dup_token(&buf, &len);
-	if (!rbd_dev->snap_name)
-		goto out_err;
-	if (!len) {
-		/* Replace the empty name with the default */
-		kfree(rbd_dev->snap_name);
-		rbd_dev->snap_name
-			= kmalloc(sizeof (RBD_SNAP_HEAD_NAME), GFP_KERNEL);
-		if (!rbd_dev->snap_name)
-			goto out_err;
+	size = sizeof (RBD_ID_PREFIX) + rbd_dev->image_name_len;
+	object_name = kmalloc(size, GFP_NOIO);
+	if (!object_name)
+		return -ENOMEM;
+	sprintf(object_name, "%s%s", RBD_ID_PREFIX, rbd_dev->image_name);
+	dout("rbd id object name is %s\n", object_name);
 
-		memcpy(rbd_dev->snap_name, RBD_SNAP_HEAD_NAME,
-			sizeof (RBD_SNAP_HEAD_NAME));
+	/* Response will be an encoded string, which includes a length */
+
+	size = sizeof (__le32) + RBD_IMAGE_ID_LEN_MAX;
+	response = kzalloc(size, GFP_NOIO);
+	if (!response) {
+		ret = -ENOMEM;
+		goto out;
 	}
 
+	ret = rbd_req_sync_exec(rbd_dev, object_name,
+				"rbd", "get_id",
+				NULL, 0,
+				response, RBD_IMAGE_ID_LEN_MAX,
+				CEPH_OSD_FLAG_READ, NULL);
+	dout("%s: rbd_req_sync_exec returned %d\n", __func__, ret);
+	if (ret < 0)
+		goto out;
+
+	p = response;
+	rbd_dev->image_id = ceph_extract_encoded_string(&p,
+						p + RBD_IMAGE_ID_LEN_MAX,
+						&rbd_dev->image_id_len,
+						GFP_NOIO);
+	if (IS_ERR(rbd_dev->image_id)) {
+		ret = PTR_ERR(rbd_dev->image_id);
+		rbd_dev->image_id = NULL;
+	} else {
+		dout("image_id is %s\n", rbd_dev->image_id);
+	}
+out:
+	kfree(response);
+	kfree(object_name);
+
+	return ret;
+}
+
+static int rbd_dev_v1_probe(struct rbd_device *rbd_dev)
+{
+	int ret;
+	size_t size;
+
+	/* Version 1 images have no id; empty string is used */
+
+	rbd_dev->image_id = kstrdup("", GFP_KERNEL);
+	if (!rbd_dev->image_id)
+		return -ENOMEM;
+	rbd_dev->image_id_len = 0;
+
+	/* Record the header object name for this rbd image. */
+
+	size = rbd_dev->image_name_len + sizeof (RBD_SUFFIX);
+	rbd_dev->header_name = kmalloc(size, GFP_KERNEL);
+	if (!rbd_dev->header_name) {
+		ret = -ENOMEM;
+		goto out_err;
+	}
+	sprintf(rbd_dev->header_name, "%s%s", rbd_dev->image_name, RBD_SUFFIX);
+
+	/* Populate rbd image metadata */
+
+	ret = rbd_read_header(rbd_dev, &rbd_dev->header);
+	if (ret < 0)
+		goto out_err;
+	rbd_dev->image_format = 1;
+
+	dout("discovered version 1 image, header name is %s\n",
+		rbd_dev->header_name);
+
 	return 0;
 
 out_err:
 	kfree(rbd_dev->header_name);
-	kfree(rbd_dev->image_name);
-	kfree(rbd_dev->pool_name);
-	rbd_dev->pool_name = NULL;
+	rbd_dev->header_name = NULL;
+	kfree(rbd_dev->image_id);
+	rbd_dev->image_id = NULL;
+
+	return ret;
+}
+
+static int rbd_dev_v2_probe(struct rbd_device *rbd_dev)
+{
+	size_t size;
+	int ret;
+	u64 ver = 0;
+
+	/*
+	 * Image id was filled in by the caller.  Record the header
+	 * object name for this rbd image.
+	 */
+	size = sizeof (RBD_HEADER_PREFIX) + rbd_dev->image_id_len;
+	rbd_dev->header_name = kmalloc(size, GFP_KERNEL);
+	if (!rbd_dev->header_name)
+		return -ENOMEM;
+	sprintf(rbd_dev->header_name, "%s%s",
+			RBD_HEADER_PREFIX, rbd_dev->image_id);
+
+	/* Get the size and object order for the image */
+
+	ret = rbd_dev_v2_image_size(rbd_dev);
+	if (ret < 0)
+		goto out_err;
+
+	/* Get the object prefix (a.k.a. block_name) for the image */
+
+	ret = rbd_dev_v2_object_prefix(rbd_dev);
+	if (ret < 0)
+		goto out_err;
+
+	/* Get the features for the image */
+
+	ret = rbd_dev_v2_features(rbd_dev);
+	if (ret < 0)
+		goto out_err;
+
+	/* crypto and compression type aren't (yet) supported for v2 images */
+
+	rbd_dev->header.crypt_type = 0;
+	rbd_dev->header.comp_type = 0;
+
+	/* Get the snapshot context, plus the header version */
+
+	ret = rbd_dev_v2_snap_context(rbd_dev, &ver);
+	if (ret)
+		goto out_err;
+	rbd_dev->header.obj_version = ver;
+
+	rbd_dev->image_format = 2;
+
+	dout("discovered version 2 image, header name is %s\n",
+		rbd_dev->header_name);
+
+	return -ENOTSUPP;
+out_err:
+	kfree(rbd_dev->header_name);
+	rbd_dev->header_name = NULL;
+	kfree(rbd_dev->header.object_prefix);
+	rbd_dev->header.object_prefix = NULL;
+
+	return ret;
+}
+
+/*
+ * Probe for the existence of the header object for the given rbd
+ * device.  For format 2 images this includes determining the image
+ * id.
+ */
+static int rbd_dev_probe(struct rbd_device *rbd_dev)
+{
+	int ret;
+
+	/*
+	 * Get the id from the image id object.  If it's not a
+	 * format 2 image, we'll get ENOENT back, and we'll assume
+	 * it's a format 1 image.
+	 */
+	ret = rbd_dev_image_id(rbd_dev);
+	if (ret)
+		ret = rbd_dev_v1_probe(rbd_dev);
+	else
+		ret = rbd_dev_v2_probe(rbd_dev);
+	if (ret)
+		dout("probe failed, returning %d\n", ret);
 
 	return ret;
 }
@@ -2449,16 +3000,17 @@
 	size_t mon_addrs_size = 0;
 	struct ceph_osd_client *osdc;
 	int rc = -ENOMEM;
+	char *snap_name;
 
 	if (!try_module_get(THIS_MODULE))
 		return -ENODEV;
 
 	options = kmalloc(count, GFP_KERNEL);
 	if (!options)
-		goto err_nomem;
+		goto err_out_mem;
 	rbd_dev = kzalloc(sizeof(*rbd_dev), GFP_KERNEL);
 	if (!rbd_dev)
-		goto err_nomem;
+		goto err_out_mem;
 
 	/* static rbd_device initialization */
 	spin_lock_init(&rbd_dev->lock);
@@ -2466,27 +3018,18 @@
 	INIT_LIST_HEAD(&rbd_dev->snaps);
 	init_rwsem(&rbd_dev->header_rwsem);
 
-	/* generate unique id: find highest unique id, add one */
-	rbd_id_get(rbd_dev);
-
-	/* Fill in the device name, now that we have its id. */
-	BUILD_BUG_ON(DEV_NAME_LEN
-			< sizeof (RBD_DRV_NAME) + MAX_INT_FORMAT_WIDTH);
-	sprintf(rbd_dev->name, "%s%d", RBD_DRV_NAME, rbd_dev->dev_id);
-
 	/* parse add command */
-	rc = rbd_add_parse_args(rbd_dev, buf, &mon_addrs, &mon_addrs_size,
-				options, count);
-	if (rc)
-		goto err_put_id;
-
-	rbd_dev->rbd_client = rbd_get_client(mon_addrs, mon_addrs_size - 1,
-						options);
-	if (IS_ERR(rbd_dev->rbd_client)) {
-		rc = PTR_ERR(rbd_dev->rbd_client);
-		goto err_put_id;
+	snap_name = rbd_add_parse_args(rbd_dev, buf,
+				&mon_addrs, &mon_addrs_size, options, count);
+	if (IS_ERR(snap_name)) {
+		rc = PTR_ERR(snap_name);
+		goto err_out_mem;
 	}
 
+	rc = rbd_get_client(rbd_dev, mon_addrs, mon_addrs_size - 1, options);
+	if (rc < 0)
+		goto err_out_args;
+
 	/* pick the pool */
 	osdc = &rbd_dev->rbd_client->client->osdc;
 	rc = ceph_pg_poolid_by_name(osdc->osdmap, rbd_dev->pool_name);
@@ -2494,23 +3037,53 @@
 		goto err_out_client;
 	rbd_dev->pool_id = rc;
 
-	/* register our block device */
-	rc = register_blkdev(0, rbd_dev->name);
+	rc = rbd_dev_probe(rbd_dev);
 	if (rc < 0)
 		goto err_out_client;
+	rbd_assert(rbd_image_format_valid(rbd_dev->image_format));
+
+	/* no need to lock here, as rbd_dev is not registered yet */
+	rc = rbd_dev_snaps_update(rbd_dev);
+	if (rc)
+		goto err_out_header;
+
+	rc = rbd_dev_set_mapping(rbd_dev, snap_name);
+	if (rc)
+		goto err_out_header;
+
+	/* generate unique id: find highest unique id, add one */
+	rbd_dev_id_get(rbd_dev);
+
+	/* Fill in the device name, now that we have its id. */
+	BUILD_BUG_ON(DEV_NAME_LEN
+			< sizeof (RBD_DRV_NAME) + MAX_INT_FORMAT_WIDTH);
+	sprintf(rbd_dev->name, "%s%d", RBD_DRV_NAME, rbd_dev->dev_id);
+
+	/* Get our block major device number. */
+
+	rc = register_blkdev(0, rbd_dev->name);
+	if (rc < 0)
+		goto err_out_id;
 	rbd_dev->major = rc;
 
+	/* Set up the blkdev mapping. */
+
+	rc = rbd_init_disk(rbd_dev);
+	if (rc)
+		goto err_out_blkdev;
+
 	rc = rbd_bus_add_dev(rbd_dev);
 	if (rc)
-		goto err_out_blkdev;
+		goto err_out_disk;
 
 	/*
 	 * At this point cleanup in the event of an error is the job
 	 * of the sysfs code (initiated by rbd_bus_del_dev()).
-	 *
-	 * Set up and announce blkdev mapping.
 	 */
-	rc = rbd_init_disk(rbd_dev);
+
+	down_write(&rbd_dev->header_rwsem);
+	rc = rbd_dev_snaps_register(rbd_dev);
+	up_write(&rbd_dev->header_rwsem);
 	if (rc)
 		goto err_out_bus;
 
@@ -2518,6 +3091,13 @@
 	if (rc)
 		goto err_out_bus;
 
+	/* Everything's ready.  Announce the disk to the world. */
+
+	add_disk(rbd_dev->disk);
+
+	pr_info("%s: added with size 0x%llx\n", rbd_dev->disk->disk_name,
+		(unsigned long long) rbd_dev->mapping.size);
+
 	return count;
 
 err_out_bus:
@@ -2527,19 +3107,23 @@
 	kfree(options);
 	return rc;
 
+err_out_disk:
+	rbd_free_disk(rbd_dev);
 err_out_blkdev:
 	unregister_blkdev(rbd_dev->major, rbd_dev->name);
+err_out_id:
+	rbd_dev_id_put(rbd_dev);
+err_out_header:
+	rbd_header_free(&rbd_dev->header);
 err_out_client:
+	kfree(rbd_dev->header_name);
 	rbd_put_client(rbd_dev);
-err_put_id:
-	if (rbd_dev->pool_name) {
-		kfree(rbd_dev->snap_name);
-		kfree(rbd_dev->header_name);
-		kfree(rbd_dev->image_name);
-		kfree(rbd_dev->pool_name);
-	}
-	rbd_id_put(rbd_dev);
-err_nomem:
+	kfree(rbd_dev->image_id);
+err_out_args:
+	kfree(rbd_dev->mapping.snap_name);
+	kfree(rbd_dev->image_name);
+	kfree(rbd_dev->pool_name);
+err_out_mem:
 	kfree(rbd_dev);
 	kfree(options);
 
@@ -2585,12 +3169,16 @@
 	rbd_free_disk(rbd_dev);
 	unregister_blkdev(rbd_dev->major, rbd_dev->name);
 
+	/* release allocated disk header fields */
+	rbd_header_free(&rbd_dev->header);
+
 	/* done with the id, and with the rbd_dev */
-	kfree(rbd_dev->snap_name);
+	kfree(rbd_dev->mapping.snap_name);
+	kfree(rbd_dev->image_id);
 	kfree(rbd_dev->header_name);
 	kfree(rbd_dev->pool_name);
 	kfree(rbd_dev->image_name);
-	rbd_id_put(rbd_dev);
+	rbd_dev_id_put(rbd_dev);
 	kfree(rbd_dev);
 
 	/* release module ref */
@@ -2628,47 +3216,7 @@
 
 done:
 	mutex_unlock(&ctl_mutex);
-	return ret;
-}
 
-static ssize_t rbd_snap_add(struct device *dev,
-			    struct device_attribute *attr,
-			    const char *buf,
-			    size_t count)
-{
-	struct rbd_device *rbd_dev = dev_to_rbd_dev(dev);
-	int ret;
-	char *name = kmalloc(count + 1, GFP_KERNEL);
-	if (!name)
-		return -ENOMEM;
-
-	snprintf(name, count, "%s", buf);
-
-	mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
-
-	ret = rbd_header_add_snap(rbd_dev,
-				  name, GFP_KERNEL);
-	if (ret < 0)
-		goto err_unlock;
-
-	ret = __rbd_refresh_header(rbd_dev, NULL);
-	if (ret < 0)
-		goto err_unlock;
-
-	/* shouldn't hold ctl_mutex when notifying.. notify might
-	   trigger a watch callback that would need to get that mutex */
-	mutex_unlock(&ctl_mutex);
-
-	/* make a best effort, don't error if failed */
-	rbd_req_sync_notify(rbd_dev);
-
-	ret = count;
-	kfree(name);
-	return ret;
-
-err_unlock:
-	mutex_unlock(&ctl_mutex);
-	kfree(name);
 	return ret;
 }
 
diff --git a/drivers/block/rbd_types.h b/drivers/block/rbd_types.h
index 0924e9e..cbe77fa 100644
--- a/drivers/block/rbd_types.h
+++ b/drivers/block/rbd_types.h
@@ -15,15 +15,30 @@
 
 #include <linux/types.h>
 
+/* For format version 2, rbd image 'foo' consists of objects
+ *   rbd_id.foo		- id of image
+ *   rbd_header.<id>	- image metadata
+ *   rbd_data.<id>.0000000000000000
+ *   rbd_data.<id>.0000000000000001
+ *   ...		- data
+ * Clients do not access header data directly in rbd format 2.
+ */
+
+#define RBD_HEADER_PREFIX      "rbd_header."
+#define RBD_DATA_PREFIX        "rbd_data."
+#define RBD_ID_PREFIX          "rbd_id."
+
 /*
- * rbd image 'foo' consists of objects
- *   foo.rbd      - image metadata
- *   foo.00000000
- *   foo.00000001
- *   ...          - data
+ * For format version 1, rbd image 'foo' consists of objects
+ *   foo.rbd		- image metadata
+ *   rb.<idhi>.<idlo>.00000000
+ *   rb.<idhi>.<idlo>.00000001
+ *   ...		- data
+ * There is no notion of a persistent image id in rbd format 1.
  */
 
 #define RBD_SUFFIX		".rbd"
+
 #define RBD_DIRECTORY           "rbd_directory"
 #define RBD_INFO                "rbd_info"
 
@@ -47,7 +62,7 @@
 
 struct rbd_image_header_ondisk {
 	char text[40];
-	char block_name[24];
+	char object_prefix[24];
 	char signature[4];
 	char version[8];
 	struct {
diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c
index 0c7d340..f74e892 100644
--- a/drivers/char/mbcs.c
+++ b/drivers/char/mbcs.c
@@ -507,7 +507,7 @@
 
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 
-	/* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */
+	/* Remap-pfn-range will mark the range VM_IO */
 	if (remap_pfn_range(vma,
 			    vma->vm_start,
 			    __pa(soft->gscr_addr) >> PAGE_SHIFT,
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index e5eedfa..0537903 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -322,7 +322,7 @@
 
 	vma->vm_ops = &mmap_mem_ops;
 
-	/* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */
+	/* Remap-pfn-range will mark the range VM_IO */
 	if (remap_pfn_range(vma,
 			    vma->vm_start,
 			    vma->vm_pgoff,
diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c
index 845f97f..e1f60f9 100644
--- a/drivers/char/mspec.c
+++ b/drivers/char/mspec.c
@@ -286,7 +286,7 @@
 	atomic_set(&vdata->refcnt, 1);
 	vma->vm_private_data = vdata;
 
-	vma->vm_flags |= (VM_IO | VM_RESERVED | VM_PFNMAP | VM_DONTEXPAND);
+	vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
 	if (vdata->type == MSPEC_FETCHOP || vdata->type == MSPEC_UNCACHED)
 		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 	vma->vm_ops = &mspec_vm_ops;
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index 54a3a6d..0bb207e 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -285,7 +285,7 @@
 
 static const struct file_operations raw_fops = {
 	.read		= do_sync_read,
-	.aio_read	= generic_file_aio_read,
+	.aio_read	= blkdev_aio_read,
 	.write		= do_sync_write,
 	.aio_write	= blkdev_aio_write,
 	.fsync		= blkdev_fsync,
diff --git a/drivers/cpufreq/omap-cpufreq.c b/drivers/cpufreq/omap-cpufreq.c
index 65f8e9a..1f3417a 100644
--- a/drivers/cpufreq/omap-cpufreq.c
+++ b/drivers/cpufreq/omap-cpufreq.c
@@ -30,20 +30,12 @@
 #include <asm/smp_plat.h>
 #include <asm/cpu.h>
 
-#include <plat/clock.h>
-#include <plat/omap-pm.h>
-#include <plat/common.h>
-#include <plat/omap_device.h>
-
-#include <mach/hardware.h>
-
 /* OPP tolerance in percentage */
 #define	OPP_TOLERANCE	4
 
 static struct cpufreq_frequency_table *freq_table;
 static atomic_t freq_table_users = ATOMIC_INIT(0);
 static struct clk *mpu_clk;
-static char *mpu_clk_name;
 static struct device *mpu_dev;
 static struct regulator *mpu_reg;
 
@@ -108,6 +100,14 @@
 	}
 
 	freq = freqs.new * 1000;
+	ret = clk_round_rate(mpu_clk, freq);
+	if (IS_ERR_VALUE(ret)) {
+		dev_warn(mpu_dev,
+			 "CPUfreq: Cannot find matching frequency for %lu\n",
+			 freq);
+		return ret;
+	}
+	freq = ret;
 
 	if (mpu_reg) {
 		opp = opp_find_freq_ceil(mpu_dev, &freq);
@@ -172,7 +172,7 @@
 {
 	int result = 0;
 
-	mpu_clk = clk_get(NULL, mpu_clk_name);
+	mpu_clk = clk_get(NULL, "cpufreq_ck");
 	if (IS_ERR(mpu_clk))
 		return PTR_ERR(mpu_clk);
 
@@ -253,22 +253,10 @@
 
 static int __init omap_cpufreq_init(void)
 {
-	if (cpu_is_omap24xx())
-		mpu_clk_name = "virt_prcm_set";
-	else if (cpu_is_omap34xx())
-		mpu_clk_name = "dpll1_ck";
-	else if (cpu_is_omap44xx())
-		mpu_clk_name = "dpll_mpu_ck";
-
-	if (!mpu_clk_name) {
-		pr_err("%s: unsupported Silicon?\n", __func__);
-		return -EINVAL;
-	}
-
-	mpu_dev = omap_device_get_by_hwmod_name("mpu");
-	if (IS_ERR(mpu_dev)) {
+	mpu_dev = get_cpu_device(0);
+	if (!mpu_dev) {
 		pr_warning("%s: unable to get the mpu device\n", __func__);
-		return PTR_ERR(mpu_dev);
+		return -EINVAL;
 	}
 
 	mpu_reg = regulator_get(mpu_dev, "vcc");
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index d06ea29..677cd6e 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -208,6 +208,16 @@
 	help
 	  Enable support for the CSR SiRFprimaII DMA engine.
 
+config TI_EDMA
+	tristate "TI EDMA support"
+	depends on ARCH_DAVINCI
+	select DMA_ENGINE
+	select DMA_VIRTUAL_CHANNELS
+	default n
+	help
+	  Enable support for the TI EDMA controller. This DMA
+	  engine is found on TI DaVinci and AM33xx parts.
+
 config ARCH_HAS_ASYNC_TX_FIND_CHANNEL
 	bool
 
@@ -292,6 +302,13 @@
 	select DMA_ENGINE
 	select DMA_VIRTUAL_CHANNELS
 
+config MMP_PDMA
+	bool "MMP PDMA support"
+	depends on (ARCH_MMP || ARCH_PXA)
+	select DMA_ENGINE
+	help
+	  Support the MMP PDMA engine for PXA and MMP platfrom.
+
 config DMA_ENGINE
 	bool
 
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 4cf6b12..7428fea 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -23,6 +23,7 @@
 obj-$(CONFIG_MXS_DMA) += mxs-dma.o
 obj-$(CONFIG_TIMB_DMA) += timb_dma.o
 obj-$(CONFIG_SIRF_DMA) += sirf-dma.o
+obj-$(CONFIG_TI_EDMA) += edma.o
 obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o
 obj-$(CONFIG_TEGRA20_APB_DMA) += tegra20-apb-dma.o
 obj-$(CONFIG_PL330_DMA) += pl330.o
@@ -32,3 +33,4 @@
 obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o
 obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o
 obj-$(CONFIG_DMA_OMAP) += omap-dma.o
+obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 6fbeebb..d1cc579 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -1892,6 +1892,7 @@
 	pl08x->pd = dev_get_platdata(&adev->dev);
 	if (!pl08x->pd) {
 		dev_err(&adev->dev, "no platform data supplied\n");
+		ret = -EINVAL;
 		goto out_no_platdata;
 	}
 
@@ -1943,6 +1944,7 @@
 		dev_err(&adev->dev, "%s failed to allocate "
 			"physical channel holders\n",
 			__func__);
+		ret = -ENOMEM;
 		goto out_no_phychans;
 	}
 
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c
index 17d6958..13a02f4 100644
--- a/drivers/dma/at_hdmac.c
+++ b/drivers/dma/at_hdmac.c
@@ -852,12 +852,13 @@
  * @buf_len: total number of bytes for the entire buffer
  * @period_len: number of bytes for each period
  * @direction: transfer direction, to or from device
+ * @flags: tx descriptor status flags
  * @context: transfer context (ignored)
  */
 static struct dma_async_tx_descriptor *
 atc_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
 		size_t period_len, enum dma_transfer_direction direction,
-		void *context)
+		unsigned long flags, void *context)
 {
 	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
 	struct at_dma_slave	*atslave = chan->private;
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index d3c5a5a..c4b0eb3c 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -36,12 +36,22 @@
  * which does not support descriptor writeback.
  */
 
+static inline unsigned int dwc_get_dms(struct dw_dma_slave *slave)
+{
+	return slave ? slave->dst_master : 0;
+}
+
+static inline unsigned int dwc_get_sms(struct dw_dma_slave *slave)
+{
+	return slave ? slave->src_master : 1;
+}
+
 #define DWC_DEFAULT_CTLLO(_chan) ({				\
 		struct dw_dma_slave *__slave = (_chan->private);	\
 		struct dw_dma_chan *_dwc = to_dw_dma_chan(_chan);	\
 		struct dma_slave_config	*_sconfig = &_dwc->dma_sconfig;	\
-		int _dms = __slave ? __slave->dst_master : 0;	\
-		int _sms = __slave ? __slave->src_master : 1;	\
+		int _dms = dwc_get_dms(__slave);		\
+		int _sms = dwc_get_sms(__slave);		\
 		u8 _smsize = __slave ? _sconfig->src_maxburst :	\
 			DW_DMA_MSIZE_16;			\
 		u8 _dmsize = __slave ? _sconfig->dst_maxburst :	\
@@ -56,16 +66,6 @@
 	})
 
 /*
- * This is configuration-dependent and usually a funny size like 4095.
- *
- * Note that this is a transfer count, i.e. if we transfer 32-bit
- * words, we can do 16380 bytes per descriptor.
- *
- * This parameter is also system-specific.
- */
-#define DWC_MAX_COUNT	4095U
-
-/*
  * Number of descriptors to allocate for each channel. This should be
  * made configurable somehow; preferably, the clients (at least the
  * ones using slave transfers) should be able to give us a hint.
@@ -177,6 +177,11 @@
 
 		cfghi = dws->cfg_hi;
 		cfglo |= dws->cfg_lo & ~DWC_CFGL_CH_PRIOR_MASK;
+	} else {
+		if (dwc->dma_sconfig.direction == DMA_MEM_TO_DEV)
+			cfghi = DWC_CFGH_DST_PER(dwc->dma_sconfig.slave_id);
+		else if (dwc->dma_sconfig.direction == DMA_DEV_TO_MEM)
+			cfghi = DWC_CFGH_SRC_PER(dwc->dma_sconfig.slave_id);
 	}
 
 	channel_writel(dwc, CFG_LO, cfglo);
@@ -206,7 +211,7 @@
 	return 0;
 }
 
-static void dwc_dump_chan_regs(struct dw_dma_chan *dwc)
+static inline void dwc_dump_chan_regs(struct dw_dma_chan *dwc)
 {
 	dev_err(chan2dev(&dwc->chan),
 		"  SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n",
@@ -227,10 +232,29 @@
 
 /*----------------------------------------------------------------------*/
 
+/* Perform single block transfer */
+static inline void dwc_do_single_block(struct dw_dma_chan *dwc,
+				       struct dw_desc *desc)
+{
+	struct dw_dma	*dw = to_dw_dma(dwc->chan.device);
+	u32		ctllo;
+
+	/* Software emulation of LLP mode relies on interrupts to continue
+	 * multi block transfer. */
+	ctllo = desc->lli.ctllo | DWC_CTLL_INT_EN;
+
+	channel_writel(dwc, SAR, desc->lli.sar);
+	channel_writel(dwc, DAR, desc->lli.dar);
+	channel_writel(dwc, CTL_LO, ctllo);
+	channel_writel(dwc, CTL_HI, desc->lli.ctlhi);
+	channel_set_bit(dw, CH_EN, dwc->mask);
+}
+
 /* Called with dwc->lock held and bh disabled */
 static void dwc_dostart(struct dw_dma_chan *dwc, struct dw_desc *first)
 {
 	struct dw_dma	*dw = to_dw_dma(dwc->chan.device);
+	unsigned long	was_soft_llp;
 
 	/* ASSERT:  channel is idle */
 	if (dma_readl(dw, CH_EN) & dwc->mask) {
@@ -242,6 +266,26 @@
 		return;
 	}
 
+	if (dwc->nollp) {
+		was_soft_llp = test_and_set_bit(DW_DMA_IS_SOFT_LLP,
+						&dwc->flags);
+		if (was_soft_llp) {
+			dev_err(chan2dev(&dwc->chan),
+				"BUG: Attempted to start new LLP transfer "
+				"inside ongoing one\n");
+			return;
+		}
+
+		dwc_initialize(dwc);
+
+		dwc->tx_list = &first->tx_list;
+		dwc->tx_node_active = first->tx_list.next;
+
+		dwc_do_single_block(dwc, first);
+
+		return;
+	}
+
 	dwc_initialize(dwc);
 
 	channel_writel(dwc, LLP, first->txd.phys);
@@ -553,8 +597,36 @@
 			dwc_handle_cyclic(dw, dwc, status_err, status_xfer);
 		else if (status_err & (1 << i))
 			dwc_handle_error(dw, dwc);
-		else if (status_xfer & (1 << i))
+		else if (status_xfer & (1 << i)) {
+			unsigned long flags;
+
+			spin_lock_irqsave(&dwc->lock, flags);
+			if (test_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags)) {
+				if (dwc->tx_node_active != dwc->tx_list) {
+					struct dw_desc *desc =
+						list_entry(dwc->tx_node_active,
+							   struct dw_desc,
+							   desc_node);
+
+					dma_writel(dw, CLEAR.XFER, dwc->mask);
+
+					/* move pointer to next descriptor */
+					dwc->tx_node_active =
+						dwc->tx_node_active->next;
+
+					dwc_do_single_block(dwc, desc);
+
+					spin_unlock_irqrestore(&dwc->lock, flags);
+					continue;
+				} else {
+					/* we are done here */
+					clear_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags);
+				}
+			}
+			spin_unlock_irqrestore(&dwc->lock, flags);
+
 			dwc_scan_descriptors(dw, dwc);
+		}
 	}
 
 	/*
@@ -636,6 +708,7 @@
 		size_t len, unsigned long flags)
 {
 	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
+	struct dw_dma_slave	*dws = chan->private;
 	struct dw_desc		*desc;
 	struct dw_desc		*first;
 	struct dw_desc		*prev;
@@ -643,6 +716,7 @@
 	size_t			offset;
 	unsigned int		src_width;
 	unsigned int		dst_width;
+	unsigned int		data_width;
 	u32			ctllo;
 
 	dev_vdbg(chan2dev(chan),
@@ -655,7 +729,11 @@
 		return NULL;
 	}
 
-	src_width = dst_width = dwc_fast_fls(src | dest | len);
+	data_width = min_t(unsigned int, dwc->dw->data_width[dwc_get_sms(dws)],
+					 dwc->dw->data_width[dwc_get_dms(dws)]);
+
+	src_width = dst_width = min_t(unsigned int, data_width,
+				      dwc_fast_fls(src | dest | len));
 
 	ctllo = DWC_DEFAULT_CTLLO(chan)
 			| DWC_CTLL_DST_WIDTH(dst_width)
@@ -667,7 +745,7 @@
 
 	for (offset = 0; offset < len; offset += xfer_count << src_width) {
 		xfer_count = min_t(size_t, (len - offset) >> src_width,
-				DWC_MAX_COUNT);
+					   dwc->block_size);
 
 		desc = dwc_desc_get(dwc);
 		if (!desc)
@@ -725,6 +803,7 @@
 	dma_addr_t		reg;
 	unsigned int		reg_width;
 	unsigned int		mem_width;
+	unsigned int		data_width;
 	unsigned int		i;
 	struct scatterlist	*sg;
 	size_t			total_len = 0;
@@ -748,6 +827,8 @@
 		ctllo |= sconfig->device_fc ? DWC_CTLL_FC(DW_DMA_FC_P_M2P) :
 			DWC_CTLL_FC(DW_DMA_FC_D_M2P);
 
+		data_width = dwc->dw->data_width[dwc_get_sms(dws)];
+
 		for_each_sg(sgl, sg, sg_len, i) {
 			struct dw_desc	*desc;
 			u32		len, dlen, mem;
@@ -755,7 +836,8 @@
 			mem = sg_dma_address(sg);
 			len = sg_dma_len(sg);
 
-			mem_width = dwc_fast_fls(mem | len);
+			mem_width = min_t(unsigned int,
+					  data_width, dwc_fast_fls(mem | len));
 
 slave_sg_todev_fill_desc:
 			desc = dwc_desc_get(dwc);
@@ -768,8 +850,8 @@
 			desc->lli.sar = mem;
 			desc->lli.dar = reg;
 			desc->lli.ctllo = ctllo | DWC_CTLL_SRC_WIDTH(mem_width);
-			if ((len >> mem_width) > DWC_MAX_COUNT) {
-				dlen = DWC_MAX_COUNT << mem_width;
+			if ((len >> mem_width) > dwc->block_size) {
+				dlen = dwc->block_size << mem_width;
 				mem += dlen;
 				len -= dlen;
 			} else {
@@ -808,6 +890,8 @@
 		ctllo |= sconfig->device_fc ? DWC_CTLL_FC(DW_DMA_FC_P_P2M) :
 			DWC_CTLL_FC(DW_DMA_FC_D_P2M);
 
+		data_width = dwc->dw->data_width[dwc_get_dms(dws)];
+
 		for_each_sg(sgl, sg, sg_len, i) {
 			struct dw_desc	*desc;
 			u32		len, dlen, mem;
@@ -815,7 +899,8 @@
 			mem = sg_dma_address(sg);
 			len = sg_dma_len(sg);
 
-			mem_width = dwc_fast_fls(mem | len);
+			mem_width = min_t(unsigned int,
+					  data_width, dwc_fast_fls(mem | len));
 
 slave_sg_fromdev_fill_desc:
 			desc = dwc_desc_get(dwc);
@@ -828,8 +913,8 @@
 			desc->lli.sar = reg;
 			desc->lli.dar = mem;
 			desc->lli.ctllo = ctllo | DWC_CTLL_DST_WIDTH(mem_width);
-			if ((len >> reg_width) > DWC_MAX_COUNT) {
-				dlen = DWC_MAX_COUNT << reg_width;
+			if ((len >> reg_width) > dwc->block_size) {
+				dlen = dwc->block_size << reg_width;
 				mem += dlen;
 				len -= dlen;
 			} else {
@@ -945,6 +1030,8 @@
 	} else if (cmd == DMA_TERMINATE_ALL) {
 		spin_lock_irqsave(&dwc->lock, flags);
 
+		clear_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags);
+
 		dwc_chan_disable(dw, dwc);
 
 		dwc->paused = false;
@@ -1187,6 +1274,13 @@
 	unsigned long			flags;
 
 	spin_lock_irqsave(&dwc->lock, flags);
+	if (dwc->nollp) {
+		spin_unlock_irqrestore(&dwc->lock, flags);
+		dev_dbg(chan2dev(&dwc->chan),
+				"channel doesn't support LLP transfers\n");
+		return ERR_PTR(-EINVAL);
+	}
+
 	if (!list_empty(&dwc->queue) || !list_empty(&dwc->active_list)) {
 		spin_unlock_irqrestore(&dwc->lock, flags);
 		dev_dbg(chan2dev(&dwc->chan),
@@ -1212,7 +1306,7 @@
 	periods = buf_len / period_len;
 
 	/* Check for too big/unaligned periods and unaligned DMA buffer. */
-	if (period_len > (DWC_MAX_COUNT << reg_width))
+	if (period_len > (dwc->block_size << reg_width))
 		goto out_err;
 	if (unlikely(period_len & ((1 << reg_width) - 1)))
 		goto out_err;
@@ -1374,6 +1468,11 @@
 	struct resource		*io;
 	struct dw_dma		*dw;
 	size_t			size;
+	void __iomem		*regs;
+	bool			autocfg;
+	unsigned int		dw_params;
+	unsigned int		nr_channels;
+	unsigned int		max_blk_size = 0;
 	int			irq;
 	int			err;
 	int			i;
@@ -1390,32 +1489,46 @@
 	if (irq < 0)
 		return irq;
 
-	size = sizeof(struct dw_dma);
-	size += pdata->nr_channels * sizeof(struct dw_dma_chan);
-	dw = kzalloc(size, GFP_KERNEL);
+	regs = devm_request_and_ioremap(&pdev->dev, io);
+	if (!regs)
+		return -EBUSY;
+
+	dw_params = dma_read_byaddr(regs, DW_PARAMS);
+	autocfg = dw_params >> DW_PARAMS_EN & 0x1;
+
+	if (autocfg)
+		nr_channels = (dw_params >> DW_PARAMS_NR_CHAN & 0x7) + 1;
+	else
+		nr_channels = pdata->nr_channels;
+
+	size = sizeof(struct dw_dma) + nr_channels * sizeof(struct dw_dma_chan);
+	dw = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
 	if (!dw)
 		return -ENOMEM;
 
-	if (!request_mem_region(io->start, DW_REGLEN, pdev->dev.driver->name)) {
-		err = -EBUSY;
-		goto err_kfree;
-	}
-
-	dw->regs = ioremap(io->start, DW_REGLEN);
-	if (!dw->regs) {
-		err = -ENOMEM;
-		goto err_release_r;
-	}
-
-	dw->clk = clk_get(&pdev->dev, "hclk");
-	if (IS_ERR(dw->clk)) {
-		err = PTR_ERR(dw->clk);
-		goto err_clk;
-	}
+	dw->clk = devm_clk_get(&pdev->dev, "hclk");
+	if (IS_ERR(dw->clk))
+		return PTR_ERR(dw->clk);
 	clk_prepare_enable(dw->clk);
 
+	dw->regs = regs;
+
+	/* get hardware configuration parameters */
+	if (autocfg) {
+		max_blk_size = dma_readl(dw, MAX_BLK_SIZE);
+
+		dw->nr_masters = (dw_params >> DW_PARAMS_NR_MASTER & 3) + 1;
+		for (i = 0; i < dw->nr_masters; i++) {
+			dw->data_width[i] =
+				(dw_params >> DW_PARAMS_DATA_WIDTH(i) & 3) + 2;
+		}
+	} else {
+		dw->nr_masters = pdata->nr_masters;
+		memcpy(dw->data_width, pdata->data_width, 4);
+	}
+
 	/* Calculate all channel mask before DMA setup */
-	dw->all_chan_mask = (1 << pdata->nr_channels) - 1;
+	dw->all_chan_mask = (1 << nr_channels) - 1;
 
 	/* force dma off, just in case */
 	dw_dma_off(dw);
@@ -1423,17 +1536,19 @@
 	/* disable BLOCK interrupts as well */
 	channel_clear_bit(dw, MASK.BLOCK, dw->all_chan_mask);
 
-	err = request_irq(irq, dw_dma_interrupt, 0, "dw_dmac", dw);
+	err = devm_request_irq(&pdev->dev, irq, dw_dma_interrupt, 0,
+			       "dw_dmac", dw);
 	if (err)
-		goto err_irq;
+		return err;
 
 	platform_set_drvdata(pdev, dw);
 
 	tasklet_init(&dw->tasklet, dw_dma_tasklet, (unsigned long)dw);
 
 	INIT_LIST_HEAD(&dw->dma.channels);
-	for (i = 0; i < pdata->nr_channels; i++) {
+	for (i = 0; i < nr_channels; i++) {
 		struct dw_dma_chan	*dwc = &dw->chan[i];
+		int			r = nr_channels - i - 1;
 
 		dwc->chan.device = &dw->dma;
 		dma_cookie_init(&dwc->chan);
@@ -1445,7 +1560,7 @@
 
 		/* 7 is highest priority & 0 is lowest. */
 		if (pdata->chan_priority == CHAN_PRIORITY_ASCENDING)
-			dwc->priority = pdata->nr_channels - i - 1;
+			dwc->priority = r;
 		else
 			dwc->priority = i;
 
@@ -1458,6 +1573,32 @@
 		INIT_LIST_HEAD(&dwc->free_list);
 
 		channel_clear_bit(dw, CH_EN, dwc->mask);
+
+		dwc->dw = dw;
+
+		/* hardware configuration */
+		if (autocfg) {
+			unsigned int dwc_params;
+
+			dwc_params = dma_read_byaddr(regs + r * sizeof(u32),
+						     DWC_PARAMS);
+
+			/* Decode maximum block size for given channel. The
+			 * stored 4 bit value represents blocks from 0x00 for 3
+			 * up to 0x0a for 4095. */
+			dwc->block_size =
+				(4 << ((max_blk_size >> 4 * i) & 0xf)) - 1;
+			dwc->nollp =
+				(dwc_params >> DWC_PARAMS_MBLK_EN & 0x1) == 0;
+		} else {
+			dwc->block_size = pdata->block_size;
+
+			/* Check if channel supports multi block transfer */
+			channel_writel(dwc, LLP, 0xfffffffc);
+			dwc->nollp =
+				(channel_readl(dwc, LLP) & 0xfffffffc) == 0;
+			channel_writel(dwc, LLP, 0);
+		}
 	}
 
 	/* Clear all interrupts on all channels. */
@@ -1486,35 +1627,21 @@
 	dma_writel(dw, CFG, DW_CFG_DMA_EN);
 
 	printk(KERN_INFO "%s: DesignWare DMA Controller, %d channels\n",
-			dev_name(&pdev->dev), pdata->nr_channels);
+			dev_name(&pdev->dev), nr_channels);
 
 	dma_async_device_register(&dw->dma);
 
 	return 0;
-
-err_irq:
-	clk_disable_unprepare(dw->clk);
-	clk_put(dw->clk);
-err_clk:
-	iounmap(dw->regs);
-	dw->regs = NULL;
-err_release_r:
-	release_resource(io);
-err_kfree:
-	kfree(dw);
-	return err;
 }
 
 static int __devexit dw_remove(struct platform_device *pdev)
 {
 	struct dw_dma		*dw = platform_get_drvdata(pdev);
 	struct dw_dma_chan	*dwc, *_dwc;
-	struct resource		*io;
 
 	dw_dma_off(dw);
 	dma_async_device_unregister(&dw->dma);
 
-	free_irq(platform_get_irq(pdev, 0), dw);
 	tasklet_kill(&dw->tasklet);
 
 	list_for_each_entry_safe(dwc, _dwc, &dw->dma.channels,
@@ -1523,17 +1650,6 @@
 		channel_clear_bit(dw, CH_EN, dwc->mask);
 	}
 
-	clk_disable_unprepare(dw->clk);
-	clk_put(dw->clk);
-
-	iounmap(dw->regs);
-	dw->regs = NULL;
-
-	io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	release_mem_region(io->start, DW_REGLEN);
-
-	kfree(dw);
-
 	return 0;
 }
 
diff --git a/drivers/dma/dw_dmac_regs.h b/drivers/dma/dw_dmac_regs.h
index 50830be..ff39fa6 100644
--- a/drivers/dma/dw_dmac_regs.h
+++ b/drivers/dma/dw_dmac_regs.h
@@ -82,9 +82,39 @@
 	DW_REG(ID);
 	DW_REG(TEST);
 
+	/* reserved */
+	DW_REG(__reserved0);
+	DW_REG(__reserved1);
+
 	/* optional encoded params, 0x3c8..0x3f7 */
+	u32	__reserved;
+
+	/* per-channel configuration registers */
+	u32	DWC_PARAMS[DW_DMA_MAX_NR_CHANNELS];
+	u32	MULTI_BLK_TYPE;
+	u32	MAX_BLK_SIZE;
+
+	/* top-level parameters */
+	u32	DW_PARAMS;
 };
 
+/* To access the registers in early stage of probe */
+#define dma_read_byaddr(addr, name) \
+	readl((addr) + offsetof(struct dw_dma_regs, name))
+
+/* Bitfields in DW_PARAMS */
+#define DW_PARAMS_NR_CHAN	8		/* number of channels */
+#define DW_PARAMS_NR_MASTER	11		/* number of AHB masters */
+#define DW_PARAMS_DATA_WIDTH(n)	(15 + 2 * (n))
+#define DW_PARAMS_DATA_WIDTH1	15		/* master 1 data width */
+#define DW_PARAMS_DATA_WIDTH2	17		/* master 2 data width */
+#define DW_PARAMS_DATA_WIDTH3	19		/* master 3 data width */
+#define DW_PARAMS_DATA_WIDTH4	21		/* master 4 data width */
+#define DW_PARAMS_EN		28		/* encoded parameters */
+
+/* Bitfields in DWC_PARAMS */
+#define DWC_PARAMS_MBLK_EN	11		/* multi block transfer */
+
 /* Bitfields in CTL_LO */
 #define DWC_CTLL_INT_EN		(1 << 0)	/* irqs enabled? */
 #define DWC_CTLL_DST_WIDTH(n)	((n)<<1)	/* bytes per element */
@@ -140,10 +170,9 @@
 /* Bitfields in CFG */
 #define DW_CFG_DMA_EN		(1 << 0)
 
-#define DW_REGLEN		0x400
-
 enum dw_dmac_flags {
 	DW_DMA_IS_CYCLIC = 0,
+	DW_DMA_IS_SOFT_LLP = 1,
 };
 
 struct dw_dma_chan {
@@ -154,6 +183,10 @@
 	bool			paused;
 	bool			initialized;
 
+	/* software emulation of the LLP transfers */
+	struct list_head	*tx_list;
+	struct list_head	*tx_node_active;
+
 	spinlock_t		lock;
 
 	/* these other elements are all protected by lock */
@@ -165,8 +198,15 @@
 
 	unsigned int		descs_allocated;
 
+	/* hardware configuration */
+	unsigned int		block_size;
+	bool			nollp;
+
 	/* configuration passed via DMA_SLAVE_CONFIG */
 	struct dma_slave_config dma_sconfig;
+
+	/* backlink to dw_dma */
+	struct dw_dma		*dw;
 };
 
 static inline struct dw_dma_chan_regs __iomem *
@@ -193,6 +233,10 @@
 
 	u8			all_chan_mask;
 
+	/* hardware configuration */
+	unsigned char		nr_masters;
+	unsigned char		data_width[4];
+
 	struct dw_dma_chan	chan[0];
 };
 
diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c
new file mode 100644
index 0000000..05aea3c
--- /dev/null
+++ b/drivers/dma/edma.c
@@ -0,0 +1,671 @@
+/*
+ * TI EDMA DMA engine driver
+ *
+ * Copyright 2012 Texas Instruments
+ *
+ * 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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include <mach/edma.h>
+
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+/*
+ * This will go away when the private EDMA API is folded
+ * into this driver and the platform device(s) are
+ * instantiated in the arch code. We can only get away
+ * with this simplification because DA8XX may not be built
+ * in the same kernel image with other DaVinci parts. This
+ * avoids having to sprinkle dmaengine driver platform devices
+ * and data throughout all the existing board files.
+ */
+#ifdef CONFIG_ARCH_DAVINCI_DA8XX
+#define EDMA_CTLRS	2
+#define EDMA_CHANS	32
+#else
+#define EDMA_CTLRS	1
+#define EDMA_CHANS	64
+#endif /* CONFIG_ARCH_DAVINCI_DA8XX */
+
+/* Max of 16 segments per channel to conserve PaRAM slots */
+#define MAX_NR_SG		16
+#define EDMA_MAX_SLOTS		MAX_NR_SG
+#define EDMA_DESCRIPTORS	16
+
+struct edma_desc {
+	struct virt_dma_desc		vdesc;
+	struct list_head		node;
+	int				absync;
+	int				pset_nr;
+	struct edmacc_param		pset[0];
+};
+
+struct edma_cc;
+
+struct edma_chan {
+	struct virt_dma_chan		vchan;
+	struct list_head		node;
+	struct edma_desc		*edesc;
+	struct edma_cc			*ecc;
+	int				ch_num;
+	bool				alloced;
+	int				slot[EDMA_MAX_SLOTS];
+	dma_addr_t			addr;
+	int				addr_width;
+	int				maxburst;
+};
+
+struct edma_cc {
+	int				ctlr;
+	struct dma_device		dma_slave;
+	struct edma_chan		slave_chans[EDMA_CHANS];
+	int				num_slave_chans;
+	int				dummy_slot;
+};
+
+static inline struct edma_cc *to_edma_cc(struct dma_device *d)
+{
+	return container_of(d, struct edma_cc, dma_slave);
+}
+
+static inline struct edma_chan *to_edma_chan(struct dma_chan *c)
+{
+	return container_of(c, struct edma_chan, vchan.chan);
+}
+
+static inline struct edma_desc
+*to_edma_desc(struct dma_async_tx_descriptor *tx)
+{
+	return container_of(tx, struct edma_desc, vdesc.tx);
+}
+
+static void edma_desc_free(struct virt_dma_desc *vdesc)
+{
+	kfree(container_of(vdesc, struct edma_desc, vdesc));
+}
+
+/* Dispatch a queued descriptor to the controller (caller holds lock) */
+static void edma_execute(struct edma_chan *echan)
+{
+	struct virt_dma_desc *vdesc = vchan_next_desc(&echan->vchan);
+	struct edma_desc *edesc;
+	int i;
+
+	if (!vdesc) {
+		echan->edesc = NULL;
+		return;
+	}
+
+	list_del(&vdesc->node);
+
+	echan->edesc = edesc = to_edma_desc(&vdesc->tx);
+
+	/* Write descriptor PaRAM set(s) */
+	for (i = 0; i < edesc->pset_nr; i++) {
+		edma_write_slot(echan->slot[i], &edesc->pset[i]);
+		dev_dbg(echan->vchan.chan.device->dev,
+			"\n pset[%d]:\n"
+			"  chnum\t%d\n"
+			"  slot\t%d\n"
+			"  opt\t%08x\n"
+			"  src\t%08x\n"
+			"  dst\t%08x\n"
+			"  abcnt\t%08x\n"
+			"  ccnt\t%08x\n"
+			"  bidx\t%08x\n"
+			"  cidx\t%08x\n"
+			"  lkrld\t%08x\n",
+			i, echan->ch_num, echan->slot[i],
+			edesc->pset[i].opt,
+			edesc->pset[i].src,
+			edesc->pset[i].dst,
+			edesc->pset[i].a_b_cnt,
+			edesc->pset[i].ccnt,
+			edesc->pset[i].src_dst_bidx,
+			edesc->pset[i].src_dst_cidx,
+			edesc->pset[i].link_bcntrld);
+		/* Link to the previous slot if not the last set */
+		if (i != (edesc->pset_nr - 1))
+			edma_link(echan->slot[i], echan->slot[i+1]);
+		/* Final pset links to the dummy pset */
+		else
+			edma_link(echan->slot[i], echan->ecc->dummy_slot);
+	}
+
+	edma_start(echan->ch_num);
+}
+
+static int edma_terminate_all(struct edma_chan *echan)
+{
+	unsigned long flags;
+	LIST_HEAD(head);
+
+	spin_lock_irqsave(&echan->vchan.lock, flags);
+
+	/*
+	 * Stop DMA activity: we assume the callback will not be called
+	 * after edma_dma() returns (even if it does, it will see
+	 * echan->edesc is NULL and exit.)
+	 */
+	if (echan->edesc) {
+		echan->edesc = NULL;
+		edma_stop(echan->ch_num);
+	}
+
+	vchan_get_all_descriptors(&echan->vchan, &head);
+	spin_unlock_irqrestore(&echan->vchan.lock, flags);
+	vchan_dma_desc_free_list(&echan->vchan, &head);
+
+	return 0;
+}
+
+
+static int edma_slave_config(struct edma_chan *echan,
+	struct dma_slave_config *config)
+{
+	if ((config->src_addr_width > DMA_SLAVE_BUSWIDTH_4_BYTES) ||
+	    (config->dst_addr_width > DMA_SLAVE_BUSWIDTH_4_BYTES))
+		return -EINVAL;
+
+	if (config->direction == DMA_MEM_TO_DEV) {
+		if (config->dst_addr)
+			echan->addr = config->dst_addr;
+		if (config->dst_addr_width)
+			echan->addr_width = config->dst_addr_width;
+		if (config->dst_maxburst)
+			echan->maxburst = config->dst_maxburst;
+	} else if (config->direction == DMA_DEV_TO_MEM) {
+		if (config->src_addr)
+			echan->addr = config->src_addr;
+		if (config->src_addr_width)
+			echan->addr_width = config->src_addr_width;
+		if (config->src_maxburst)
+			echan->maxburst = config->src_maxburst;
+	}
+
+	return 0;
+}
+
+static int edma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
+			unsigned long arg)
+{
+	int ret = 0;
+	struct dma_slave_config *config;
+	struct edma_chan *echan = to_edma_chan(chan);
+
+	switch (cmd) {
+	case DMA_TERMINATE_ALL:
+		edma_terminate_all(echan);
+		break;
+	case DMA_SLAVE_CONFIG:
+		config = (struct dma_slave_config *)arg;
+		ret = edma_slave_config(echan, config);
+		break;
+	default:
+		ret = -ENOSYS;
+	}
+
+	return ret;
+}
+
+static struct dma_async_tx_descriptor *edma_prep_slave_sg(
+	struct dma_chan *chan, struct scatterlist *sgl,
+	unsigned int sg_len, enum dma_transfer_direction direction,
+	unsigned long tx_flags, void *context)
+{
+	struct edma_chan *echan = to_edma_chan(chan);
+	struct device *dev = chan->device->dev;
+	struct edma_desc *edesc;
+	struct scatterlist *sg;
+	int i;
+	int acnt, bcnt, ccnt, src, dst, cidx;
+	int src_bidx, dst_bidx, src_cidx, dst_cidx;
+
+	if (unlikely(!echan || !sgl || !sg_len))
+		return NULL;
+
+	if (echan->addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) {
+		dev_err(dev, "Undefined slave buswidth\n");
+		return NULL;
+	}
+
+	if (sg_len > MAX_NR_SG) {
+		dev_err(dev, "Exceeded max SG segments %d > %d\n",
+			sg_len, MAX_NR_SG);
+		return NULL;
+	}
+
+	edesc = kzalloc(sizeof(*edesc) + sg_len *
+		sizeof(edesc->pset[0]), GFP_ATOMIC);
+	if (!edesc) {
+		dev_dbg(dev, "Failed to allocate a descriptor\n");
+		return NULL;
+	}
+
+	edesc->pset_nr = sg_len;
+
+	for_each_sg(sgl, sg, sg_len, i) {
+		/* Allocate a PaRAM slot, if needed */
+		if (echan->slot[i] < 0) {
+			echan->slot[i] =
+				edma_alloc_slot(EDMA_CTLR(echan->ch_num),
+						EDMA_SLOT_ANY);
+			if (echan->slot[i] < 0) {
+				dev_err(dev, "Failed to allocate slot\n");
+				return NULL;
+			}
+		}
+
+		acnt = echan->addr_width;
+
+		/*
+		 * If the maxburst is equal to the fifo width, use
+		 * A-synced transfers. This allows for large contiguous
+		 * buffer transfers using only one PaRAM set.
+		 */
+		if (echan->maxburst == 1) {
+			edesc->absync = false;
+			ccnt = sg_dma_len(sg) / acnt / (SZ_64K - 1);
+			bcnt = sg_dma_len(sg) / acnt - ccnt * (SZ_64K - 1);
+			if (bcnt)
+				ccnt++;
+			else
+				bcnt = SZ_64K - 1;
+			cidx = acnt;
+		/*
+		 * If maxburst is greater than the fifo address_width,
+		 * use AB-synced transfers where A count is the fifo
+		 * address_width and B count is the maxburst. In this
+		 * case, we are limited to transfers of C count frames
+		 * of (address_width * maxburst) where C count is limited
+		 * to SZ_64K-1. This places an upper bound on the length
+		 * of an SG segment that can be handled.
+		 */
+		} else {
+			edesc->absync = true;
+			bcnt = echan->maxburst;
+			ccnt = sg_dma_len(sg) / (acnt * bcnt);
+			if (ccnt > (SZ_64K - 1)) {
+				dev_err(dev, "Exceeded max SG segment size\n");
+				return NULL;
+			}
+			cidx = acnt * bcnt;
+		}
+
+		if (direction == DMA_MEM_TO_DEV) {
+			src = sg_dma_address(sg);
+			dst = echan->addr;
+			src_bidx = acnt;
+			src_cidx = cidx;
+			dst_bidx = 0;
+			dst_cidx = 0;
+		} else {
+			src = echan->addr;
+			dst = sg_dma_address(sg);
+			src_bidx = 0;
+			src_cidx = 0;
+			dst_bidx = acnt;
+			dst_cidx = cidx;
+		}
+
+		edesc->pset[i].opt = EDMA_TCC(EDMA_CHAN_SLOT(echan->ch_num));
+		/* Configure A or AB synchronized transfers */
+		if (edesc->absync)
+			edesc->pset[i].opt |= SYNCDIM;
+		/* If this is the last set, enable completion interrupt flag */
+		if (i == sg_len - 1)
+			edesc->pset[i].opt |= TCINTEN;
+
+		edesc->pset[i].src = src;
+		edesc->pset[i].dst = dst;
+
+		edesc->pset[i].src_dst_bidx = (dst_bidx << 16) | src_bidx;
+		edesc->pset[i].src_dst_cidx = (dst_cidx << 16) | src_cidx;
+
+		edesc->pset[i].a_b_cnt = bcnt << 16 | acnt;
+		edesc->pset[i].ccnt = ccnt;
+		edesc->pset[i].link_bcntrld = 0xffffffff;
+
+	}
+
+	return vchan_tx_prep(&echan->vchan, &edesc->vdesc, tx_flags);
+}
+
+static void edma_callback(unsigned ch_num, u16 ch_status, void *data)
+{
+	struct edma_chan *echan = data;
+	struct device *dev = echan->vchan.chan.device->dev;
+	struct edma_desc *edesc;
+	unsigned long flags;
+
+	/* Stop the channel */
+	edma_stop(echan->ch_num);
+
+	switch (ch_status) {
+	case DMA_COMPLETE:
+		dev_dbg(dev, "transfer complete on channel %d\n", ch_num);
+
+		spin_lock_irqsave(&echan->vchan.lock, flags);
+
+		edesc = echan->edesc;
+		if (edesc) {
+			edma_execute(echan);
+			vchan_cookie_complete(&edesc->vdesc);
+		}
+
+		spin_unlock_irqrestore(&echan->vchan.lock, flags);
+
+		break;
+	case DMA_CC_ERROR:
+		dev_dbg(dev, "transfer error on channel %d\n", ch_num);
+		break;
+	default:
+		break;
+	}
+}
+
+/* Alloc channel resources */
+static int edma_alloc_chan_resources(struct dma_chan *chan)
+{
+	struct edma_chan *echan = to_edma_chan(chan);
+	struct device *dev = chan->device->dev;
+	int ret;
+	int a_ch_num;
+	LIST_HEAD(descs);
+
+	a_ch_num = edma_alloc_channel(echan->ch_num, edma_callback,
+					chan, EVENTQ_DEFAULT);
+
+	if (a_ch_num < 0) {
+		ret = -ENODEV;
+		goto err_no_chan;
+	}
+
+	if (a_ch_num != echan->ch_num) {
+		dev_err(dev, "failed to allocate requested channel %u:%u\n",
+			EDMA_CTLR(echan->ch_num),
+			EDMA_CHAN_SLOT(echan->ch_num));
+		ret = -ENODEV;
+		goto err_wrong_chan;
+	}
+
+	echan->alloced = true;
+	echan->slot[0] = echan->ch_num;
+
+	dev_info(dev, "allocated channel for %u:%u\n",
+		 EDMA_CTLR(echan->ch_num), EDMA_CHAN_SLOT(echan->ch_num));
+
+	return 0;
+
+err_wrong_chan:
+	edma_free_channel(a_ch_num);
+err_no_chan:
+	return ret;
+}
+
+/* Free channel resources */
+static void edma_free_chan_resources(struct dma_chan *chan)
+{
+	struct edma_chan *echan = to_edma_chan(chan);
+	struct device *dev = chan->device->dev;
+	int i;
+
+	/* Terminate transfers */
+	edma_stop(echan->ch_num);
+
+	vchan_free_chan_resources(&echan->vchan);
+
+	/* Free EDMA PaRAM slots */
+	for (i = 1; i < EDMA_MAX_SLOTS; i++) {
+		if (echan->slot[i] >= 0) {
+			edma_free_slot(echan->slot[i]);
+			echan->slot[i] = -1;
+		}
+	}
+
+	/* Free EDMA channel */
+	if (echan->alloced) {
+		edma_free_channel(echan->ch_num);
+		echan->alloced = false;
+	}
+
+	dev_info(dev, "freeing channel for %u\n", echan->ch_num);
+}
+
+/* Send pending descriptor to hardware */
+static void edma_issue_pending(struct dma_chan *chan)
+{
+	struct edma_chan *echan = to_edma_chan(chan);
+	unsigned long flags;
+
+	spin_lock_irqsave(&echan->vchan.lock, flags);
+	if (vchan_issue_pending(&echan->vchan) && !echan->edesc)
+		edma_execute(echan);
+	spin_unlock_irqrestore(&echan->vchan.lock, flags);
+}
+
+static size_t edma_desc_size(struct edma_desc *edesc)
+{
+	int i;
+	size_t size;
+
+	if (edesc->absync)
+		for (size = i = 0; i < edesc->pset_nr; i++)
+			size += (edesc->pset[i].a_b_cnt & 0xffff) *
+				(edesc->pset[i].a_b_cnt >> 16) *
+				 edesc->pset[i].ccnt;
+	else
+		size = (edesc->pset[0].a_b_cnt & 0xffff) *
+			(edesc->pset[0].a_b_cnt >> 16) +
+			(edesc->pset[0].a_b_cnt & 0xffff) *
+			(SZ_64K - 1) * edesc->pset[0].ccnt;
+
+	return size;
+}
+
+/* Check request completion status */
+static enum dma_status edma_tx_status(struct dma_chan *chan,
+				      dma_cookie_t cookie,
+				      struct dma_tx_state *txstate)
+{
+	struct edma_chan *echan = to_edma_chan(chan);
+	struct virt_dma_desc *vdesc;
+	enum dma_status ret;
+	unsigned long flags;
+
+	ret = dma_cookie_status(chan, cookie, txstate);
+	if (ret == DMA_SUCCESS || !txstate)
+		return ret;
+
+	spin_lock_irqsave(&echan->vchan.lock, flags);
+	vdesc = vchan_find_desc(&echan->vchan, cookie);
+	if (vdesc) {
+		txstate->residue = edma_desc_size(to_edma_desc(&vdesc->tx));
+	} else if (echan->edesc && echan->edesc->vdesc.tx.cookie == cookie) {
+		struct edma_desc *edesc = echan->edesc;
+		txstate->residue = edma_desc_size(edesc);
+	} else {
+		txstate->residue = 0;
+	}
+	spin_unlock_irqrestore(&echan->vchan.lock, flags);
+
+	return ret;
+}
+
+static void __init edma_chan_init(struct edma_cc *ecc,
+				  struct dma_device *dma,
+				  struct edma_chan *echans)
+{
+	int i, j;
+
+	for (i = 0; i < EDMA_CHANS; i++) {
+		struct edma_chan *echan = &echans[i];
+		echan->ch_num = EDMA_CTLR_CHAN(ecc->ctlr, i);
+		echan->ecc = ecc;
+		echan->vchan.desc_free = edma_desc_free;
+
+		vchan_init(&echan->vchan, dma);
+
+		INIT_LIST_HEAD(&echan->node);
+		for (j = 0; j < EDMA_MAX_SLOTS; j++)
+			echan->slot[j] = -1;
+	}
+}
+
+static void edma_dma_init(struct edma_cc *ecc, struct dma_device *dma,
+			  struct device *dev)
+{
+	dma->device_prep_slave_sg = edma_prep_slave_sg;
+	dma->device_alloc_chan_resources = edma_alloc_chan_resources;
+	dma->device_free_chan_resources = edma_free_chan_resources;
+	dma->device_issue_pending = edma_issue_pending;
+	dma->device_tx_status = edma_tx_status;
+	dma->device_control = edma_control;
+	dma->dev = dev;
+
+	INIT_LIST_HEAD(&dma->channels);
+}
+
+static int __devinit edma_probe(struct platform_device *pdev)
+{
+	struct edma_cc *ecc;
+	int ret;
+
+	ecc = devm_kzalloc(&pdev->dev, sizeof(*ecc), GFP_KERNEL);
+	if (!ecc) {
+		dev_err(&pdev->dev, "Can't allocate controller\n");
+		return -ENOMEM;
+	}
+
+	ecc->ctlr = pdev->id;
+	ecc->dummy_slot = edma_alloc_slot(ecc->ctlr, EDMA_SLOT_ANY);
+	if (ecc->dummy_slot < 0) {
+		dev_err(&pdev->dev, "Can't allocate PaRAM dummy slot\n");
+		return -EIO;
+	}
+
+	dma_cap_zero(ecc->dma_slave.cap_mask);
+	dma_cap_set(DMA_SLAVE, ecc->dma_slave.cap_mask);
+
+	edma_dma_init(ecc, &ecc->dma_slave, &pdev->dev);
+
+	edma_chan_init(ecc, &ecc->dma_slave, ecc->slave_chans);
+
+	ret = dma_async_device_register(&ecc->dma_slave);
+	if (ret)
+		goto err_reg1;
+
+	platform_set_drvdata(pdev, ecc);
+
+	dev_info(&pdev->dev, "TI EDMA DMA engine driver\n");
+
+	return 0;
+
+err_reg1:
+	edma_free_slot(ecc->dummy_slot);
+	return ret;
+}
+
+static int __devexit edma_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct edma_cc *ecc = dev_get_drvdata(dev);
+
+	dma_async_device_unregister(&ecc->dma_slave);
+	edma_free_slot(ecc->dummy_slot);
+
+	return 0;
+}
+
+static struct platform_driver edma_driver = {
+	.probe		= edma_probe,
+	.remove		= __devexit_p(edma_remove),
+	.driver = {
+		.name = "edma-dma-engine",
+		.owner = THIS_MODULE,
+	},
+};
+
+bool edma_filter_fn(struct dma_chan *chan, void *param)
+{
+	if (chan->device->dev->driver == &edma_driver.driver) {
+		struct edma_chan *echan = to_edma_chan(chan);
+		unsigned ch_req = *(unsigned *)param;
+		return ch_req == echan->ch_num;
+	}
+	return false;
+}
+EXPORT_SYMBOL(edma_filter_fn);
+
+static struct platform_device *pdev0, *pdev1;
+
+static const struct platform_device_info edma_dev_info0 = {
+	.name = "edma-dma-engine",
+	.id = 0,
+	.dma_mask = DMA_BIT_MASK(32),
+};
+
+static const struct platform_device_info edma_dev_info1 = {
+	.name = "edma-dma-engine",
+	.id = 1,
+	.dma_mask = DMA_BIT_MASK(32),
+};
+
+static int edma_init(void)
+{
+	int ret = platform_driver_register(&edma_driver);
+
+	if (ret == 0) {
+		pdev0 = platform_device_register_full(&edma_dev_info0);
+		if (IS_ERR(pdev0)) {
+			platform_driver_unregister(&edma_driver);
+			ret = PTR_ERR(pdev0);
+			goto out;
+		}
+	}
+
+	if (EDMA_CTLRS == 2) {
+		pdev1 = platform_device_register_full(&edma_dev_info1);
+		if (IS_ERR(pdev1)) {
+			platform_driver_unregister(&edma_driver);
+			platform_device_unregister(pdev0);
+			ret = PTR_ERR(pdev1);
+		}
+	}
+
+out:
+	return ret;
+}
+subsys_initcall(edma_init);
+
+static void __exit edma_exit(void)
+{
+	platform_device_unregister(pdev0);
+	if (pdev1)
+		platform_device_unregister(pdev1);
+	platform_driver_unregister(&edma_driver);
+}
+module_exit(edma_exit);
+
+MODULE_AUTHOR("Matt Porter <mporter@ti.com>");
+MODULE_DESCRIPTION("TI EDMA DMA engine driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c
index 64256f6..bcfde40 100644
--- a/drivers/dma/ep93xx_dma.c
+++ b/drivers/dma/ep93xx_dma.c
@@ -1120,6 +1120,7 @@
  * @buf_len: length of the buffer (in bytes)
  * @period_len: length of a single period
  * @dir: direction of the operation
+ * @flags: tx descriptor status flags
  * @context: operation context (ignored)
  *
  * Prepares a descriptor for cyclic DMA operation. This means that once the
@@ -1133,7 +1134,8 @@
 static struct dma_async_tx_descriptor *
 ep93xx_dma_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t dma_addr,
 			   size_t buf_len, size_t period_len,
-			   enum dma_transfer_direction dir, void *context)
+			   enum dma_transfer_direction dir, unsigned long flags,
+			   void *context)
 {
 	struct ep93xx_dma_chan *edmac = to_ep93xx_dma_chan(chan);
 	struct ep93xx_dma_desc *desc, *first;
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c
index 2a3fab2..f11b5b2 100644
--- a/drivers/dma/imx-dma.c
+++ b/drivers/dma/imx-dma.c
@@ -801,7 +801,7 @@
 static struct dma_async_tx_descriptor *imxdma_prep_dma_cyclic(
 		struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len,
 		size_t period_len, enum dma_transfer_direction direction,
-		void *context)
+		unsigned long flags, void *context)
 {
 	struct imxdma_channel *imxdmac = to_imxdma_chan(chan);
 	struct imxdma_engine *imxdma = imxdmac->imxdma;
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 1b781d6..c099ca0 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -1012,7 +1012,7 @@
 static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic(
 		struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len,
 		size_t period_len, enum dma_transfer_direction direction,
-		void *context)
+		unsigned long flags, void *context)
 {
 	struct sdma_channel *sdmac = to_sdma_chan(chan);
 	struct sdma_engine *sdma = sdmac->sdma;
diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c
index 8689576..b9d6678 100644
--- a/drivers/dma/ioat/dma_v2.c
+++ b/drivers/dma/ioat/dma_v2.c
@@ -434,12 +434,11 @@
 		return NULL;
 	memset(hw, 0, sizeof(*hw));
 
-	desc = kmem_cache_alloc(ioat2_cache, flags);
+	desc = kmem_cache_zalloc(ioat2_cache, flags);
 	if (!desc) {
 		pci_pool_free(dma->dma_pool, hw, phys);
 		return NULL;
 	}
-	memset(desc, 0, sizeof(*desc));
 
 	dma_async_tx_descriptor_init(&desc->txd, chan);
 	desc->txd.tx_submit = ioat2_tx_submit_unlock;
diff --git a/drivers/dma/ioat/pci.c b/drivers/dma/ioat/pci.c
index 5e3a40f..c057306 100644
--- a/drivers/dma/ioat/pci.c
+++ b/drivers/dma/ioat/pci.c
@@ -40,6 +40,17 @@
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_AUTHOR("Intel Corporation");
 
+#define PCI_DEVICE_ID_INTEL_IOAT_IVB0	0x0e20
+#define PCI_DEVICE_ID_INTEL_IOAT_IVB1	0x0e21
+#define PCI_DEVICE_ID_INTEL_IOAT_IVB2	0x0e22
+#define PCI_DEVICE_ID_INTEL_IOAT_IVB3	0x0e23
+#define PCI_DEVICE_ID_INTEL_IOAT_IVB4	0x0e24
+#define PCI_DEVICE_ID_INTEL_IOAT_IVB5	0x0e25
+#define PCI_DEVICE_ID_INTEL_IOAT_IVB6	0x0e26
+#define PCI_DEVICE_ID_INTEL_IOAT_IVB7	0x0e27
+#define PCI_DEVICE_ID_INTEL_IOAT_IVB8	0x0e2e
+#define PCI_DEVICE_ID_INTEL_IOAT_IVB9	0x0e2f
+
 static struct pci_device_id ioat_pci_tbl[] = {
 	/* I/OAT v1 platforms */
 	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT) },
@@ -83,6 +94,17 @@
 	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB8) },
 	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB9) },
 
+	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB0) },
+	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB1) },
+	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB2) },
+	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB3) },
+	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB4) },
+	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB5) },
+	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB6) },
+	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB7) },
+	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB8) },
+	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_IVB9) },
+
 	{ 0, }
 };
 MODULE_DEVICE_TABLE(pci, ioat_pci_tbl);
diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c
new file mode 100644
index 0000000..14da1f4
--- /dev/null
+++ b/drivers/dma/mmp_pdma.c
@@ -0,0 +1,875 @@
+/*
+ * Copyright 2012 Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+#include <linux/dmaengine.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/platform_data/mmp_dma.h>
+#include <linux/dmapool.h>
+#include <linux/of_device.h>
+#include <linux/of.h>
+
+#include "dmaengine.h"
+
+#define DCSR		0x0000
+#define DALGN		0x00a0
+#define DINT		0x00f0
+#define DDADR		0x0200
+#define DSADR		0x0204
+#define DTADR		0x0208
+#define DCMD		0x020c
+
+#define DCSR_RUN	(1 << 31)	/* Run Bit (read / write) */
+#define DCSR_NODESC	(1 << 30)	/* No-Descriptor Fetch (read / write) */
+#define DCSR_STOPIRQEN	(1 << 29)	/* Stop Interrupt Enable (read / write) */
+#define DCSR_REQPEND	(1 << 8)	/* Request Pending (read-only) */
+#define DCSR_STOPSTATE	(1 << 3)	/* Stop State (read-only) */
+#define DCSR_ENDINTR	(1 << 2)	/* End Interrupt (read / write) */
+#define DCSR_STARTINTR	(1 << 1)	/* Start Interrupt (read / write) */
+#define DCSR_BUSERR	(1 << 0)	/* Bus Error Interrupt (read / write) */
+
+#define DCSR_EORIRQEN	(1 << 28)       /* End of Receive Interrupt Enable (R/W) */
+#define DCSR_EORJMPEN	(1 << 27)       /* Jump to next descriptor on EOR */
+#define DCSR_EORSTOPEN	(1 << 26)       /* STOP on an EOR */
+#define DCSR_SETCMPST	(1 << 25)       /* Set Descriptor Compare Status */
+#define DCSR_CLRCMPST	(1 << 24)       /* Clear Descriptor Compare Status */
+#define DCSR_CMPST	(1 << 10)       /* The Descriptor Compare Status */
+#define DCSR_EORINTR	(1 << 9)        /* The end of Receive */
+
+#define DRCMR_MAPVLD	(1 << 7)	/* Map Valid (read / write) */
+#define DRCMR_CHLNUM	0x1f		/* mask for Channel Number (read / write) */
+
+#define DDADR_DESCADDR	0xfffffff0	/* Address of next descriptor (mask) */
+#define DDADR_STOP	(1 << 0)	/* Stop (read / write) */
+
+#define DCMD_INCSRCADDR	(1 << 31)	/* Source Address Increment Setting. */
+#define DCMD_INCTRGADDR	(1 << 30)	/* Target Address Increment Setting. */
+#define DCMD_FLOWSRC	(1 << 29)	/* Flow Control by the source. */
+#define DCMD_FLOWTRG	(1 << 28)	/* Flow Control by the target. */
+#define DCMD_STARTIRQEN	(1 << 22)	/* Start Interrupt Enable */
+#define DCMD_ENDIRQEN	(1 << 21)	/* End Interrupt Enable */
+#define DCMD_ENDIAN	(1 << 18)	/* Device Endian-ness. */
+#define DCMD_BURST8	(1 << 16)	/* 8 byte burst */
+#define DCMD_BURST16	(2 << 16)	/* 16 byte burst */
+#define DCMD_BURST32	(3 << 16)	/* 32 byte burst */
+#define DCMD_WIDTH1	(1 << 14)	/* 1 byte width */
+#define DCMD_WIDTH2	(2 << 14)	/* 2 byte width (HalfWord) */
+#define DCMD_WIDTH4	(3 << 14)	/* 4 byte width (Word) */
+#define DCMD_LENGTH	0x01fff		/* length mask (max = 8K - 1) */
+
+#define PDMA_ALIGNMENT		3
+#define PDMA_MAX_DESC_BYTES	0x1000
+
+struct mmp_pdma_desc_hw {
+	u32 ddadr;	/* Points to the next descriptor + flags */
+	u32 dsadr;	/* DSADR value for the current transfer */
+	u32 dtadr;	/* DTADR value for the current transfer */
+	u32 dcmd;	/* DCMD value for the current transfer */
+} __aligned(32);
+
+struct mmp_pdma_desc_sw {
+	struct mmp_pdma_desc_hw desc;
+	struct list_head node;
+	struct list_head tx_list;
+	struct dma_async_tx_descriptor async_tx;
+};
+
+struct mmp_pdma_phy;
+
+struct mmp_pdma_chan {
+	struct device *dev;
+	struct dma_chan chan;
+	struct dma_async_tx_descriptor desc;
+	struct mmp_pdma_phy *phy;
+	enum dma_transfer_direction dir;
+
+	/* channel's basic info */
+	struct tasklet_struct tasklet;
+	u32 dcmd;
+	u32 drcmr;
+	u32 dev_addr;
+
+	/* list for desc */
+	spinlock_t desc_lock;		/* Descriptor list lock */
+	struct list_head chain_pending;	/* Link descriptors queue for pending */
+	struct list_head chain_running;	/* Link descriptors queue for running */
+	bool idle;			/* channel statue machine */
+
+	struct dma_pool *desc_pool;	/* Descriptors pool */
+};
+
+struct mmp_pdma_phy {
+	int idx;
+	void __iomem *base;
+	struct mmp_pdma_chan *vchan;
+};
+
+struct mmp_pdma_device {
+	int				dma_channels;
+	void __iomem			*base;
+	struct device			*dev;
+	struct dma_device		device;
+	struct mmp_pdma_phy		*phy;
+};
+
+#define tx_to_mmp_pdma_desc(tx) container_of(tx, struct mmp_pdma_desc_sw, async_tx)
+#define to_mmp_pdma_desc(lh) container_of(lh, struct mmp_pdma_desc_sw, node)
+#define to_mmp_pdma_chan(dchan) container_of(dchan, struct mmp_pdma_chan, chan)
+#define to_mmp_pdma_dev(dmadev) container_of(dmadev, struct mmp_pdma_device, device)
+
+static void set_desc(struct mmp_pdma_phy *phy, dma_addr_t addr)
+{
+	u32 reg = (phy->idx << 4) + DDADR;
+
+	writel(addr, phy->base + reg);
+}
+
+static void enable_chan(struct mmp_pdma_phy *phy)
+{
+	u32 reg;
+
+	if (!phy->vchan)
+		return;
+
+	reg = phy->vchan->drcmr;
+	reg = (((reg) < 64) ? 0x0100 : 0x1100) + (((reg) & 0x3f) << 2);
+	writel(DRCMR_MAPVLD | phy->idx, phy->base + reg);
+
+	reg = (phy->idx << 2) + DCSR;
+	writel(readl(phy->base + reg) | DCSR_RUN,
+					phy->base + reg);
+}
+
+static void disable_chan(struct mmp_pdma_phy *phy)
+{
+	u32 reg;
+
+	if (phy) {
+		reg = (phy->idx << 2) + DCSR;
+		writel(readl(phy->base + reg) & ~DCSR_RUN,
+						phy->base + reg);
+	}
+}
+
+static int clear_chan_irq(struct mmp_pdma_phy *phy)
+{
+	u32 dcsr;
+	u32 dint = readl(phy->base + DINT);
+	u32 reg = (phy->idx << 2) + DCSR;
+
+	if (dint & BIT(phy->idx)) {
+		/* clear irq */
+		dcsr = readl(phy->base + reg);
+		writel(dcsr, phy->base + reg);
+		if ((dcsr & DCSR_BUSERR) && (phy->vchan))
+			dev_warn(phy->vchan->dev, "DCSR_BUSERR\n");
+		return 0;
+	}
+	return -EAGAIN;
+}
+
+static irqreturn_t mmp_pdma_chan_handler(int irq, void *dev_id)
+{
+	struct mmp_pdma_phy *phy = dev_id;
+
+	if (clear_chan_irq(phy) == 0) {
+		tasklet_schedule(&phy->vchan->tasklet);
+		return IRQ_HANDLED;
+	} else
+		return IRQ_NONE;
+}
+
+static irqreturn_t mmp_pdma_int_handler(int irq, void *dev_id)
+{
+	struct mmp_pdma_device *pdev = dev_id;
+	struct mmp_pdma_phy *phy;
+	u32 dint = readl(pdev->base + DINT);
+	int i, ret;
+	int irq_num = 0;
+
+	while (dint) {
+		i = __ffs(dint);
+		dint &= (dint - 1);
+		phy = &pdev->phy[i];
+		ret = mmp_pdma_chan_handler(irq, phy);
+		if (ret == IRQ_HANDLED)
+			irq_num++;
+	}
+
+	if (irq_num)
+		return IRQ_HANDLED;
+	else
+		return IRQ_NONE;
+}
+
+/* lookup free phy channel as descending priority */
+static struct mmp_pdma_phy *lookup_phy(struct mmp_pdma_chan *pchan)
+{
+	int prio, i;
+	struct mmp_pdma_device *pdev = to_mmp_pdma_dev(pchan->chan.device);
+	struct mmp_pdma_phy *phy;
+
+	/*
+	 * dma channel priorities
+	 * ch 0 - 3,  16 - 19  <--> (0)
+	 * ch 4 - 7,  20 - 23  <--> (1)
+	 * ch 8 - 11, 24 - 27  <--> (2)
+	 * ch 12 - 15, 28 - 31  <--> (3)
+	 */
+	for (prio = 0; prio <= (((pdev->dma_channels - 1) & 0xf) >> 2); prio++) {
+		for (i = 0; i < pdev->dma_channels; i++) {
+			if (prio != ((i & 0xf) >> 2))
+				continue;
+			phy = &pdev->phy[i];
+			if (!phy->vchan) {
+				phy->vchan = pchan;
+				return phy;
+			}
+		}
+	}
+
+	return NULL;
+}
+
+/* desc->tx_list ==> pending list */
+static void append_pending_queue(struct mmp_pdma_chan *chan,
+					struct mmp_pdma_desc_sw *desc)
+{
+	struct mmp_pdma_desc_sw *tail =
+				to_mmp_pdma_desc(chan->chain_pending.prev);
+
+	if (list_empty(&chan->chain_pending))
+		goto out_splice;
+
+	/* one irq per queue, even appended */
+	tail->desc.ddadr = desc->async_tx.phys;
+	tail->desc.dcmd &= ~DCMD_ENDIRQEN;
+
+	/* softly link to pending list */
+out_splice:
+	list_splice_tail_init(&desc->tx_list, &chan->chain_pending);
+}
+
+/**
+ * start_pending_queue - transfer any pending transactions
+ * pending list ==> running list
+ */
+static void start_pending_queue(struct mmp_pdma_chan *chan)
+{
+	struct mmp_pdma_desc_sw *desc;
+
+	/* still in running, irq will start the pending list */
+	if (!chan->idle) {
+		dev_dbg(chan->dev, "DMA controller still busy\n");
+		return;
+	}
+
+	if (list_empty(&chan->chain_pending)) {
+		/* chance to re-fetch phy channel with higher prio */
+		if (chan->phy) {
+			chan->phy->vchan = NULL;
+			chan->phy = NULL;
+		}
+		dev_dbg(chan->dev, "no pending list\n");
+		return;
+	}
+
+	if (!chan->phy) {
+		chan->phy = lookup_phy(chan);
+		if (!chan->phy) {
+			dev_dbg(chan->dev, "no free dma channel\n");
+			return;
+		}
+	}
+
+	/*
+	 * pending -> running
+	 * reintilize pending list
+	 */
+	desc = list_first_entry(&chan->chain_pending,
+				struct mmp_pdma_desc_sw, node);
+	list_splice_tail_init(&chan->chain_pending, &chan->chain_running);
+
+	/*
+	 * Program the descriptor's address into the DMA controller,
+	 * then start the DMA transaction
+	 */
+	set_desc(chan->phy, desc->async_tx.phys);
+	enable_chan(chan->phy);
+	chan->idle = false;
+}
+
+
+/* desc->tx_list ==> pending list */
+static dma_cookie_t mmp_pdma_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+	struct mmp_pdma_chan *chan = to_mmp_pdma_chan(tx->chan);
+	struct mmp_pdma_desc_sw *desc = tx_to_mmp_pdma_desc(tx);
+	struct mmp_pdma_desc_sw *child;
+	unsigned long flags;
+	dma_cookie_t cookie = -EBUSY;
+
+	spin_lock_irqsave(&chan->desc_lock, flags);
+
+	list_for_each_entry(child, &desc->tx_list, node) {
+		cookie = dma_cookie_assign(&child->async_tx);
+	}
+
+	append_pending_queue(chan, desc);
+
+	spin_unlock_irqrestore(&chan->desc_lock, flags);
+
+	return cookie;
+}
+
+struct mmp_pdma_desc_sw *mmp_pdma_alloc_descriptor(struct mmp_pdma_chan *chan)
+{
+	struct mmp_pdma_desc_sw *desc;
+	dma_addr_t pdesc;
+
+	desc = dma_pool_alloc(chan->desc_pool, GFP_ATOMIC, &pdesc);
+	if (!desc) {
+		dev_err(chan->dev, "out of memory for link descriptor\n");
+		return NULL;
+	}
+
+	memset(desc, 0, sizeof(*desc));
+	INIT_LIST_HEAD(&desc->tx_list);
+	dma_async_tx_descriptor_init(&desc->async_tx, &chan->chan);
+	/* each desc has submit */
+	desc->async_tx.tx_submit = mmp_pdma_tx_submit;
+	desc->async_tx.phys = pdesc;
+
+	return desc;
+}
+
+/**
+ * mmp_pdma_alloc_chan_resources - Allocate resources for DMA channel.
+ *
+ * This function will create a dma pool for descriptor allocation.
+ * Request irq only when channel is requested
+ * Return - The number of allocated descriptors.
+ */
+
+static int mmp_pdma_alloc_chan_resources(struct dma_chan *dchan)
+{
+	struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan);
+
+	if (chan->desc_pool)
+		return 1;
+
+	chan->desc_pool =
+		dma_pool_create(dev_name(&dchan->dev->device), chan->dev,
+				  sizeof(struct mmp_pdma_desc_sw),
+				  __alignof__(struct mmp_pdma_desc_sw), 0);
+	if (!chan->desc_pool) {
+		dev_err(chan->dev, "unable to allocate descriptor pool\n");
+		return -ENOMEM;
+	}
+	if (chan->phy) {
+		chan->phy->vchan = NULL;
+		chan->phy = NULL;
+	}
+	chan->idle = true;
+	chan->dev_addr = 0;
+	return 1;
+}
+
+static void mmp_pdma_free_desc_list(struct mmp_pdma_chan *chan,
+				  struct list_head *list)
+{
+	struct mmp_pdma_desc_sw *desc, *_desc;
+
+	list_for_each_entry_safe(desc, _desc, list, node) {
+		list_del(&desc->node);
+		dma_pool_free(chan->desc_pool, desc, desc->async_tx.phys);
+	}
+}
+
+static void mmp_pdma_free_chan_resources(struct dma_chan *dchan)
+{
+	struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan);
+	unsigned long flags;
+
+	spin_lock_irqsave(&chan->desc_lock, flags);
+	mmp_pdma_free_desc_list(chan, &chan->chain_pending);
+	mmp_pdma_free_desc_list(chan, &chan->chain_running);
+	spin_unlock_irqrestore(&chan->desc_lock, flags);
+
+	dma_pool_destroy(chan->desc_pool);
+	chan->desc_pool = NULL;
+	chan->idle = true;
+	chan->dev_addr = 0;
+	if (chan->phy) {
+		chan->phy->vchan = NULL;
+		chan->phy = NULL;
+	}
+	return;
+}
+
+static struct dma_async_tx_descriptor *
+mmp_pdma_prep_memcpy(struct dma_chan *dchan,
+	dma_addr_t dma_dst, dma_addr_t dma_src,
+	size_t len, unsigned long flags)
+{
+	struct mmp_pdma_chan *chan;
+	struct mmp_pdma_desc_sw *first = NULL, *prev = NULL, *new;
+	size_t copy = 0;
+
+	if (!dchan)
+		return NULL;
+
+	if (!len)
+		return NULL;
+
+	chan = to_mmp_pdma_chan(dchan);
+
+	if (!chan->dir) {
+		chan->dir = DMA_MEM_TO_MEM;
+		chan->dcmd = DCMD_INCTRGADDR | DCMD_INCSRCADDR;
+		chan->dcmd |= DCMD_BURST32;
+	}
+
+	do {
+		/* Allocate the link descriptor from DMA pool */
+		new = mmp_pdma_alloc_descriptor(chan);
+		if (!new) {
+			dev_err(chan->dev, "no memory for desc\n");
+			goto fail;
+		}
+
+		copy = min_t(size_t, len, PDMA_MAX_DESC_BYTES);
+
+		new->desc.dcmd = chan->dcmd | (DCMD_LENGTH & copy);
+		new->desc.dsadr = dma_src;
+		new->desc.dtadr = dma_dst;
+
+		if (!first)
+			first = new;
+		else
+			prev->desc.ddadr = new->async_tx.phys;
+
+		new->async_tx.cookie = 0;
+		async_tx_ack(&new->async_tx);
+
+		prev = new;
+		len -= copy;
+
+		if (chan->dir == DMA_MEM_TO_DEV) {
+			dma_src += copy;
+		} else if (chan->dir == DMA_DEV_TO_MEM) {
+			dma_dst += copy;
+		} else if (chan->dir == DMA_MEM_TO_MEM) {
+			dma_src += copy;
+			dma_dst += copy;
+		}
+
+		/* Insert the link descriptor to the LD ring */
+		list_add_tail(&new->node, &first->tx_list);
+	} while (len);
+
+	first->async_tx.flags = flags; /* client is in control of this ack */
+	first->async_tx.cookie = -EBUSY;
+
+	/* last desc and fire IRQ */
+	new->desc.ddadr = DDADR_STOP;
+	new->desc.dcmd |= DCMD_ENDIRQEN;
+
+	return &first->async_tx;
+
+fail:
+	if (first)
+		mmp_pdma_free_desc_list(chan, &first->tx_list);
+	return NULL;
+}
+
+static struct dma_async_tx_descriptor *
+mmp_pdma_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl,
+			 unsigned int sg_len, enum dma_transfer_direction dir,
+			 unsigned long flags, void *context)
+{
+	struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan);
+	struct mmp_pdma_desc_sw *first = NULL, *prev = NULL, *new = NULL;
+	size_t len, avail;
+	struct scatterlist *sg;
+	dma_addr_t addr;
+	int i;
+
+	if ((sgl == NULL) || (sg_len == 0))
+		return NULL;
+
+	for_each_sg(sgl, sg, sg_len, i) {
+		addr = sg_dma_address(sg);
+		avail = sg_dma_len(sgl);
+
+		do {
+			len = min_t(size_t, avail, PDMA_MAX_DESC_BYTES);
+
+			/* allocate and populate the descriptor */
+			new = mmp_pdma_alloc_descriptor(chan);
+			if (!new) {
+				dev_err(chan->dev, "no memory for desc\n");
+				goto fail;
+			}
+
+			new->desc.dcmd = chan->dcmd | (DCMD_LENGTH & len);
+			if (dir == DMA_MEM_TO_DEV) {
+				new->desc.dsadr = addr;
+				new->desc.dtadr = chan->dev_addr;
+			} else {
+				new->desc.dsadr = chan->dev_addr;
+				new->desc.dtadr = addr;
+			}
+
+			if (!first)
+				first = new;
+			else
+				prev->desc.ddadr = new->async_tx.phys;
+
+			new->async_tx.cookie = 0;
+			async_tx_ack(&new->async_tx);
+			prev = new;
+
+			/* Insert the link descriptor to the LD ring */
+			list_add_tail(&new->node, &first->tx_list);
+
+			/* update metadata */
+			addr += len;
+			avail -= len;
+		} while (avail);
+	}
+
+	first->async_tx.cookie = -EBUSY;
+	first->async_tx.flags = flags;
+
+	/* last desc and fire IRQ */
+	new->desc.ddadr = DDADR_STOP;
+	new->desc.dcmd |= DCMD_ENDIRQEN;
+
+	return &first->async_tx;
+
+fail:
+	if (first)
+		mmp_pdma_free_desc_list(chan, &first->tx_list);
+	return NULL;
+}
+
+static int mmp_pdma_control(struct dma_chan *dchan, enum dma_ctrl_cmd cmd,
+		unsigned long arg)
+{
+	struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan);
+	struct dma_slave_config *cfg = (void *)arg;
+	unsigned long flags;
+	int ret = 0;
+	u32 maxburst = 0, addr = 0;
+	enum dma_slave_buswidth width = DMA_SLAVE_BUSWIDTH_UNDEFINED;
+
+	if (!dchan)
+		return -EINVAL;
+
+	switch (cmd) {
+	case DMA_TERMINATE_ALL:
+		disable_chan(chan->phy);
+		if (chan->phy) {
+			chan->phy->vchan = NULL;
+			chan->phy = NULL;
+		}
+		spin_lock_irqsave(&chan->desc_lock, flags);
+		mmp_pdma_free_desc_list(chan, &chan->chain_pending);
+		mmp_pdma_free_desc_list(chan, &chan->chain_running);
+		spin_unlock_irqrestore(&chan->desc_lock, flags);
+		chan->idle = true;
+		break;
+	case DMA_SLAVE_CONFIG:
+		if (cfg->direction == DMA_DEV_TO_MEM) {
+			chan->dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC;
+			maxburst = cfg->src_maxburst;
+			width = cfg->src_addr_width;
+			addr = cfg->src_addr;
+		} else if (cfg->direction == DMA_MEM_TO_DEV) {
+			chan->dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG;
+			maxburst = cfg->dst_maxburst;
+			width = cfg->dst_addr_width;
+			addr = cfg->dst_addr;
+		}
+
+		if (width == DMA_SLAVE_BUSWIDTH_1_BYTE)
+			chan->dcmd |= DCMD_WIDTH1;
+		else if (width == DMA_SLAVE_BUSWIDTH_2_BYTES)
+			chan->dcmd |= DCMD_WIDTH2;
+		else if (width == DMA_SLAVE_BUSWIDTH_4_BYTES)
+			chan->dcmd |= DCMD_WIDTH4;
+
+		if (maxburst == 8)
+			chan->dcmd |= DCMD_BURST8;
+		else if (maxburst == 16)
+			chan->dcmd |= DCMD_BURST16;
+		else if (maxburst == 32)
+			chan->dcmd |= DCMD_BURST32;
+
+		if (cfg) {
+			chan->dir = cfg->direction;
+			chan->drcmr = cfg->slave_id;
+		}
+		chan->dev_addr = addr;
+		break;
+	default:
+		return -ENOSYS;
+	}
+
+	return ret;
+}
+
+static enum dma_status mmp_pdma_tx_status(struct dma_chan *dchan,
+			dma_cookie_t cookie, struct dma_tx_state *txstate)
+{
+	struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan);
+	enum dma_status ret;
+	unsigned long flags;
+
+	spin_lock_irqsave(&chan->desc_lock, flags);
+	ret = dma_cookie_status(dchan, cookie, txstate);
+	spin_unlock_irqrestore(&chan->desc_lock, flags);
+
+	return ret;
+}
+
+/**
+ * mmp_pdma_issue_pending - Issue the DMA start command
+ * pending list ==> running list
+ */
+static void mmp_pdma_issue_pending(struct dma_chan *dchan)
+{
+	struct mmp_pdma_chan *chan = to_mmp_pdma_chan(dchan);
+	unsigned long flags;
+
+	spin_lock_irqsave(&chan->desc_lock, flags);
+	start_pending_queue(chan);
+	spin_unlock_irqrestore(&chan->desc_lock, flags);
+}
+
+/*
+ * dma_do_tasklet
+ * Do call back
+ * Start pending list
+ */
+static void dma_do_tasklet(unsigned long data)
+{
+	struct mmp_pdma_chan *chan = (struct mmp_pdma_chan *)data;
+	struct mmp_pdma_desc_sw *desc, *_desc;
+	LIST_HEAD(chain_cleanup);
+	unsigned long flags;
+
+	/* submit pending list; callback for each desc; free desc */
+
+	spin_lock_irqsave(&chan->desc_lock, flags);
+
+	/* update the cookie if we have some descriptors to cleanup */
+	if (!list_empty(&chan->chain_running)) {
+		dma_cookie_t cookie;
+
+		desc = to_mmp_pdma_desc(chan->chain_running.prev);
+		cookie = desc->async_tx.cookie;
+		dma_cookie_complete(&desc->async_tx);
+
+		dev_dbg(chan->dev, "completed_cookie=%d\n", cookie);
+	}
+
+	/*
+	 * move the descriptors to a temporary list so we can drop the lock
+	 * during the entire cleanup operation
+	 */
+	list_splice_tail_init(&chan->chain_running, &chain_cleanup);
+
+	/* the hardware is now idle and ready for more */
+	chan->idle = true;
+
+	/* Start any pending transactions automatically */
+	start_pending_queue(chan);
+	spin_unlock_irqrestore(&chan->desc_lock, flags);
+
+	/* Run the callback for each descriptor, in order */
+	list_for_each_entry_safe(desc, _desc, &chain_cleanup, node) {
+		struct dma_async_tx_descriptor *txd = &desc->async_tx;
+
+		/* Remove from the list of transactions */
+		list_del(&desc->node);
+		/* Run the link descriptor callback function */
+		if (txd->callback)
+			txd->callback(txd->callback_param);
+
+		dma_pool_free(chan->desc_pool, desc, txd->phys);
+	}
+}
+
+static int __devexit mmp_pdma_remove(struct platform_device *op)
+{
+	struct mmp_pdma_device *pdev = platform_get_drvdata(op);
+
+	dma_async_device_unregister(&pdev->device);
+	return 0;
+}
+
+static int __devinit mmp_pdma_chan_init(struct mmp_pdma_device *pdev,
+							int idx, int irq)
+{
+	struct mmp_pdma_phy *phy  = &pdev->phy[idx];
+	struct mmp_pdma_chan *chan;
+	int ret;
+
+	chan = devm_kzalloc(pdev->dev,
+			sizeof(struct mmp_pdma_chan), GFP_KERNEL);
+	if (chan == NULL)
+		return -ENOMEM;
+
+	phy->idx = idx;
+	phy->base = pdev->base;
+
+	if (irq) {
+		ret = devm_request_irq(pdev->dev, irq,
+			mmp_pdma_chan_handler, IRQF_DISABLED, "pdma", phy);
+		if (ret) {
+			dev_err(pdev->dev, "channel request irq fail!\n");
+			return ret;
+		}
+	}
+
+	spin_lock_init(&chan->desc_lock);
+	chan->dev = pdev->dev;
+	chan->chan.device = &pdev->device;
+	tasklet_init(&chan->tasklet, dma_do_tasklet, (unsigned long)chan);
+	INIT_LIST_HEAD(&chan->chain_pending);
+	INIT_LIST_HEAD(&chan->chain_running);
+
+	/* register virt channel to dma engine */
+	list_add_tail(&chan->chan.device_node,
+			&pdev->device.channels);
+
+	return 0;
+}
+
+static struct of_device_id mmp_pdma_dt_ids[] = {
+	{ .compatible = "marvell,pdma-1.0", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, mmp_pdma_dt_ids);
+
+static int __devinit mmp_pdma_probe(struct platform_device *op)
+{
+	struct mmp_pdma_device *pdev;
+	const struct of_device_id *of_id;
+	struct mmp_dma_platdata *pdata = dev_get_platdata(&op->dev);
+	struct resource *iores;
+	int i, ret, irq = 0;
+	int dma_channels = 0, irq_num = 0;
+
+	pdev = devm_kzalloc(&op->dev, sizeof(*pdev), GFP_KERNEL);
+	if (!pdev)
+		return -ENOMEM;
+	pdev->dev = &op->dev;
+
+	iores = platform_get_resource(op, IORESOURCE_MEM, 0);
+	if (!iores)
+		return -EINVAL;
+
+	pdev->base = devm_request_and_ioremap(pdev->dev, iores);
+	if (!pdev->base)
+		return -EADDRNOTAVAIL;
+
+	of_id = of_match_device(mmp_pdma_dt_ids, pdev->dev);
+	if (of_id)
+		of_property_read_u32(pdev->dev->of_node,
+				"#dma-channels", &dma_channels);
+	else if (pdata && pdata->dma_channels)
+		dma_channels = pdata->dma_channels;
+	else
+		dma_channels = 32;	/* default 32 channel */
+	pdev->dma_channels = dma_channels;
+
+	for (i = 0; i < dma_channels; i++) {
+		if (platform_get_irq(op, i) > 0)
+			irq_num++;
+	}
+
+	pdev->phy = devm_kzalloc(pdev->dev,
+		dma_channels * sizeof(struct mmp_pdma_chan), GFP_KERNEL);
+	if (pdev->phy == NULL)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&pdev->device.channels);
+
+	if (irq_num != dma_channels) {
+		/* all chan share one irq, demux inside */
+		irq = platform_get_irq(op, 0);
+		ret = devm_request_irq(pdev->dev, irq,
+			mmp_pdma_int_handler, IRQF_DISABLED, "pdma", pdev);
+		if (ret)
+			return ret;
+	}
+
+	for (i = 0; i < dma_channels; i++) {
+		irq = (irq_num != dma_channels) ? 0 : platform_get_irq(op, i);
+		ret = mmp_pdma_chan_init(pdev, i, irq);
+		if (ret)
+			return ret;
+	}
+
+	dma_cap_set(DMA_SLAVE, pdev->device.cap_mask);
+	dma_cap_set(DMA_MEMCPY, pdev->device.cap_mask);
+	dma_cap_set(DMA_SLAVE, pdev->device.cap_mask);
+	pdev->device.dev = &op->dev;
+	pdev->device.device_alloc_chan_resources = mmp_pdma_alloc_chan_resources;
+	pdev->device.device_free_chan_resources = mmp_pdma_free_chan_resources;
+	pdev->device.device_tx_status = mmp_pdma_tx_status;
+	pdev->device.device_prep_dma_memcpy = mmp_pdma_prep_memcpy;
+	pdev->device.device_prep_slave_sg = mmp_pdma_prep_slave_sg;
+	pdev->device.device_issue_pending = mmp_pdma_issue_pending;
+	pdev->device.device_control = mmp_pdma_control;
+	pdev->device.copy_align = PDMA_ALIGNMENT;
+
+	if (pdev->dev->coherent_dma_mask)
+		dma_set_mask(pdev->dev, pdev->dev->coherent_dma_mask);
+	else
+		dma_set_mask(pdev->dev, DMA_BIT_MASK(64));
+
+	ret = dma_async_device_register(&pdev->device);
+	if (ret) {
+		dev_err(pdev->device.dev, "unable to register\n");
+		return ret;
+	}
+
+	dev_info(pdev->device.dev, "initialized\n");
+	return 0;
+}
+
+static const struct platform_device_id mmp_pdma_id_table[] = {
+	{ "mmp-pdma", },
+	{ },
+};
+
+static struct platform_driver mmp_pdma_driver = {
+	.driver		= {
+		.name	= "mmp-pdma",
+		.owner  = THIS_MODULE,
+		.of_match_table = mmp_pdma_dt_ids,
+	},
+	.id_table	= mmp_pdma_id_table,
+	.probe		= mmp_pdma_probe,
+	.remove		= __devexit_p(mmp_pdma_remove),
+};
+
+module_platform_driver(mmp_pdma_driver);
+
+MODULE_DESCRIPTION("MARVELL MMP Periphera DMA Driver");
+MODULE_AUTHOR("Marvell International Ltd.");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/dma/mmp_tdma.c b/drivers/dma/mmp_tdma.c
index 07fa486..f3e8d71 100644
--- a/drivers/dma/mmp_tdma.c
+++ b/drivers/dma/mmp_tdma.c
@@ -20,6 +20,7 @@
 #include <linux/device.h>
 #include <mach/regs-icu.h>
 #include <linux/platform_data/dma-mmp_tdma.h>
+#include <linux/of_device.h>
 
 #include "dmaengine.h"
 
@@ -127,7 +128,6 @@
 	void __iomem			*base;
 	struct dma_device		device;
 	struct mmp_tdma_chan		*tdmac[TDMA_CHANNEL_NUM];
-	int				irq;
 };
 
 #define to_mmp_tdma_chan(dchan) container_of(dchan, struct mmp_tdma_chan, chan)
@@ -358,7 +358,7 @@
 static struct dma_async_tx_descriptor *mmp_tdma_prep_dma_cyclic(
 		struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len,
 		size_t period_len, enum dma_transfer_direction direction,
-		void *context)
+		unsigned long flags, void *context)
 {
 	struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan);
 	struct mmp_tdma_desc *desc;
@@ -492,7 +492,7 @@
 		return -ENOMEM;
 	}
 	if (irq)
-		tdmac->irq = irq + idx;
+		tdmac->irq = irq;
 	tdmac->dev	   = tdev->dev;
 	tdmac->chan.device = &tdev->device;
 	tdmac->idx	   = idx;
@@ -505,34 +505,43 @@
 	/* add the channel to tdma_chan list */
 	list_add_tail(&tdmac->chan.device_node,
 			&tdev->device.channels);
-
 	return 0;
 }
 
+static struct of_device_id mmp_tdma_dt_ids[] = {
+	{ .compatible = "marvell,adma-1.0", .data = (void *)MMP_AUD_TDMA},
+	{ .compatible = "marvell,pxa910-squ", .data = (void *)PXA910_SQU},
+	{}
+};
+MODULE_DEVICE_TABLE(of, mmp_tdma_dt_ids);
+
 static int __devinit mmp_tdma_probe(struct platform_device *pdev)
 {
-	const struct platform_device_id *id = platform_get_device_id(pdev);
-	enum mmp_tdma_type type = id->driver_data;
+	enum mmp_tdma_type type;
+	const struct of_device_id *of_id;
 	struct mmp_tdma_device *tdev;
 	struct resource *iores;
 	int i, ret;
-	int irq = 0;
+	int irq = 0, irq_num = 0;
 	int chan_num = TDMA_CHANNEL_NUM;
 
+	of_id = of_match_device(mmp_tdma_dt_ids, &pdev->dev);
+	if (of_id)
+		type = (enum mmp_tdma_type) of_id->data;
+	else
+		type = platform_get_device_id(pdev)->driver_data;
+
 	/* always have couple channels */
 	tdev = devm_kzalloc(&pdev->dev, sizeof(*tdev), GFP_KERNEL);
 	if (!tdev)
 		return -ENOMEM;
 
 	tdev->dev = &pdev->dev;
-	iores = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!iores)
-		return -EINVAL;
 
-	if (resource_size(iores) != chan_num)
-		tdev->irq = iores->start;
-	else
-		irq = iores->start;
+	for (i = 0; i < chan_num; i++) {
+		if (platform_get_irq(pdev, i) > 0)
+			irq_num++;
+	}
 
 	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!iores)
@@ -542,25 +551,26 @@
 	if (!tdev->base)
 		return -EADDRNOTAVAIL;
 
-	if (tdev->irq) {
-		ret = devm_request_irq(&pdev->dev, tdev->irq,
+	INIT_LIST_HEAD(&tdev->device.channels);
+
+	if (irq_num != chan_num) {
+		irq = platform_get_irq(pdev, 0);
+		ret = devm_request_irq(&pdev->dev, irq,
 			mmp_tdma_int_handler, IRQF_DISABLED, "tdma", tdev);
 		if (ret)
 			return ret;
 	}
 
+	/* initialize channel parameters */
+	for (i = 0; i < chan_num; i++) {
+		irq = (irq_num != chan_num) ? 0 : platform_get_irq(pdev, i);
+		ret = mmp_tdma_chan_init(tdev, i, irq, type);
+		if (ret)
+			return ret;
+	}
+
 	dma_cap_set(DMA_SLAVE, tdev->device.cap_mask);
 	dma_cap_set(DMA_CYCLIC, tdev->device.cap_mask);
-
-	INIT_LIST_HEAD(&tdev->device.channels);
-
-	/* initialize channel parameters */
-	for (i = 0; i < chan_num; i++) {
-		ret = mmp_tdma_chan_init(tdev, i, irq, type);
-		if (ret)
-			return ret;
-	}
-
 	tdev->device.dev = &pdev->dev;
 	tdev->device.device_alloc_chan_resources =
 					mmp_tdma_alloc_chan_resources;
@@ -595,6 +605,7 @@
 	.driver		= {
 		.name	= "mmp-tdma",
 		.owner  = THIS_MODULE,
+		.of_match_table = mmp_tdma_dt_ids,
 	},
 	.id_table	= mmp_tdma_id_table,
 	.probe		= mmp_tdma_probe,
diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index 7f41b25..9f02e79 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -101,7 +101,8 @@
 	u32		pio_words[MXS_PIO_WORDS];
 };
 
-#define NUM_CCW	(int)(PAGE_SIZE / sizeof(struct mxs_dma_ccw))
+#define CCW_BLOCK_SIZE	(4 * PAGE_SIZE)
+#define NUM_CCW	(int)(CCW_BLOCK_SIZE / sizeof(struct mxs_dma_ccw))
 
 struct mxs_dma_chan {
 	struct mxs_dma_engine		*mxs_dma;
@@ -354,14 +355,15 @@
 
 	mxs_chan->chan_irq = data->chan_irq;
 
-	mxs_chan->ccw = dma_alloc_coherent(mxs_dma->dma_device.dev, PAGE_SIZE,
-				&mxs_chan->ccw_phys, GFP_KERNEL);
+	mxs_chan->ccw = dma_alloc_coherent(mxs_dma->dma_device.dev,
+				CCW_BLOCK_SIZE, &mxs_chan->ccw_phys,
+				GFP_KERNEL);
 	if (!mxs_chan->ccw) {
 		ret = -ENOMEM;
 		goto err_alloc;
 	}
 
-	memset(mxs_chan->ccw, 0, PAGE_SIZE);
+	memset(mxs_chan->ccw, 0, CCW_BLOCK_SIZE);
 
 	if (mxs_chan->chan_irq != NO_IRQ) {
 		ret = request_irq(mxs_chan->chan_irq, mxs_dma_int_handler,
@@ -387,7 +389,7 @@
 err_clk:
 	free_irq(mxs_chan->chan_irq, mxs_dma);
 err_irq:
-	dma_free_coherent(mxs_dma->dma_device.dev, PAGE_SIZE,
+	dma_free_coherent(mxs_dma->dma_device.dev, CCW_BLOCK_SIZE,
 			mxs_chan->ccw, mxs_chan->ccw_phys);
 err_alloc:
 	return ret;
@@ -402,7 +404,7 @@
 
 	free_irq(mxs_chan->chan_irq, mxs_dma);
 
-	dma_free_coherent(mxs_dma->dma_device.dev, PAGE_SIZE,
+	dma_free_coherent(mxs_dma->dma_device.dev, CCW_BLOCK_SIZE,
 			mxs_chan->ccw, mxs_chan->ccw_phys);
 
 	clk_disable_unprepare(mxs_dma->clk);
@@ -531,7 +533,7 @@
 static struct dma_async_tx_descriptor *mxs_dma_prep_dma_cyclic(
 		struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len,
 		size_t period_len, enum dma_transfer_direction direction,
-		void *context)
+		unsigned long flags, void *context)
 {
 	struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
 	struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 2e16627..bb2d8e7 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -36,6 +36,7 @@
 	struct dma_slave_config	cfg;
 	unsigned dma_sig;
 	bool cyclic;
+	bool paused;
 
 	int dma_ch;
 	struct omap_desc *desc;
@@ -367,7 +368,8 @@
 
 static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
 	struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
-	size_t period_len, enum dma_transfer_direction dir, void *context)
+	size_t period_len, enum dma_transfer_direction dir, unsigned long flags,
+	void *context)
 {
 	struct omap_chan *c = to_omap_dma_chan(chan);
 	enum dma_slave_buswidth dev_width;
@@ -415,7 +417,10 @@
 	d->dev_addr = dev_addr;
 	d->fi = burst;
 	d->es = es;
-	d->sync_mode = OMAP_DMA_SYNC_PACKET;
+	if (burst)
+		d->sync_mode = OMAP_DMA_SYNC_PACKET;
+	else
+		d->sync_mode = OMAP_DMA_SYNC_ELEMENT;
 	d->sync_type = sync_type;
 	d->periph_port = OMAP_DMA_PORT_MPUI;
 	d->sg[0].addr = buf_addr;
@@ -426,7 +431,10 @@
 	if (!c->cyclic) {
 		c->cyclic = true;
 		omap_dma_link_lch(c->dma_ch, c->dma_ch);
-		omap_enable_dma_irq(c->dma_ch, OMAP_DMA_FRAME_IRQ);
+
+		if (flags & DMA_PREP_INTERRUPT)
+			omap_enable_dma_irq(c->dma_ch, OMAP_DMA_FRAME_IRQ);
+
 		omap_disable_dma_irq(c->dma_ch, OMAP_DMA_BLOCK_IRQ);
 	}
 
@@ -435,7 +443,7 @@
 		omap_set_dma_dest_burst_mode(c->dma_ch, OMAP_DMA_DATA_BURST_16);
 	}
 
-	return vchan_tx_prep(&c->vc, &d->vd, DMA_CTRL_ACK | DMA_PREP_INTERRUPT);
+	return vchan_tx_prep(&c->vc, &d->vd, flags);
 }
 
 static int omap_dma_slave_config(struct omap_chan *c, struct dma_slave_config *cfg)
@@ -469,11 +477,14 @@
 	 */
 	if (c->desc) {
 		c->desc = NULL;
-		omap_stop_dma(c->dma_ch);
+		/* Avoid stopping the dma twice */
+		if (!c->paused)
+			omap_stop_dma(c->dma_ch);
 	}
 
 	if (c->cyclic) {
 		c->cyclic = false;
+		c->paused = false;
 		omap_dma_unlink_lch(c->dma_ch, c->dma_ch);
 	}
 
@@ -486,14 +497,30 @@
 
 static int omap_dma_pause(struct omap_chan *c)
 {
-	/* FIXME: not supported by platform private API */
-	return -EINVAL;
+	/* Pause/Resume only allowed with cyclic mode */
+	if (!c->cyclic)
+		return -EINVAL;
+
+	if (!c->paused) {
+		omap_stop_dma(c->dma_ch);
+		c->paused = true;
+	}
+
+	return 0;
 }
 
 static int omap_dma_resume(struct omap_chan *c)
 {
-	/* FIXME: not supported by platform private API */
-	return -EINVAL;
+	/* Pause/Resume only allowed with cyclic mode */
+	if (!c->cyclic)
+		return -EINVAL;
+
+	if (c->paused) {
+		omap_start_dma(c->dma_ch);
+		c->paused = false;
+	}
+
+	return 0;
 }
 
 static int omap_dma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 5d3bbcd..665668b 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -23,7 +23,6 @@
 #include <linux/dmaengine.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/pl330.h>
-#include <linux/pm_runtime.h>
 #include <linux/scatterlist.h>
 #include <linux/of.h>
 
@@ -586,8 +585,6 @@
 
 	/* Peripheral channels connected to this DMAC */
 	struct dma_pl330_chan *peripherals; /* keep at end */
-
-	struct clk *clk;
 };
 
 struct dma_pl330_desc {
@@ -2395,7 +2392,7 @@
 	pch->pl330_chid = pl330_request_channel(&pdmac->pif);
 	if (!pch->pl330_chid) {
 		spin_unlock_irqrestore(&pch->lock, flags);
-		return 0;
+		return -ENOMEM;
 	}
 
 	tasklet_init(&pch->task, pl330_tasklet, (unsigned long) pch);
@@ -2685,7 +2682,7 @@
 static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
 		struct dma_chan *chan, dma_addr_t dma_addr, size_t len,
 		size_t period_len, enum dma_transfer_direction direction,
-		void *context)
+		unsigned long flags, void *context)
 {
 	struct dma_pl330_desc *desc;
 	struct dma_pl330_chan *pch = to_pchan(chan);
@@ -2889,29 +2886,17 @@
 		goto probe_err1;
 	}
 
-	pdmac->clk = clk_get(&adev->dev, "dma");
-	if (IS_ERR(pdmac->clk)) {
-		dev_err(&adev->dev, "Cannot get operation clock.\n");
-		ret = -EINVAL;
-		goto probe_err2;
-	}
-
 	amba_set_drvdata(adev, pdmac);
 
-#ifndef CONFIG_PM_RUNTIME
-	/* enable dma clk */
-	clk_enable(pdmac->clk);
-#endif
-
 	irq = adev->irq[0];
 	ret = request_irq(irq, pl330_irq_handler, 0,
 			dev_name(&adev->dev), pi);
 	if (ret)
-		goto probe_err3;
+		goto probe_err2;
 
 	ret = pl330_add(pi);
 	if (ret)
-		goto probe_err4;
+		goto probe_err3;
 
 	INIT_LIST_HEAD(&pdmac->desc_pool);
 	spin_lock_init(&pdmac->pool_lock);
@@ -2933,7 +2918,7 @@
 	if (!pdmac->peripherals) {
 		ret = -ENOMEM;
 		dev_err(&adev->dev, "unable to allocate pdmac->peripherals\n");
-		goto probe_err5;
+		goto probe_err4;
 	}
 
 	for (i = 0; i < num_chan; i++) {
@@ -2961,6 +2946,7 @@
 		if (pi->pcfg.num_peri) {
 			dma_cap_set(DMA_SLAVE, pd->cap_mask);
 			dma_cap_set(DMA_CYCLIC, pd->cap_mask);
+			dma_cap_set(DMA_PRIVATE, pd->cap_mask);
 		}
 	}
 
@@ -2976,7 +2962,7 @@
 	ret = dma_async_device_register(pd);
 	if (ret) {
 		dev_err(&adev->dev, "unable to register DMAC\n");
-		goto probe_err5;
+		goto probe_err4;
 	}
 
 	dev_info(&adev->dev,
@@ -2989,15 +2975,10 @@
 
 	return 0;
 
-probe_err5:
-	pl330_del(pi);
 probe_err4:
-	free_irq(irq, pi);
+	pl330_del(pi);
 probe_err3:
-#ifndef CONFIG_PM_RUNTIME
-	clk_disable(pdmac->clk);
-#endif
-	clk_put(pdmac->clk);
+	free_irq(irq, pi);
 probe_err2:
 	iounmap(pi->base);
 probe_err1:
@@ -3044,10 +3025,6 @@
 	res = &adev->res;
 	release_mem_region(res->start, resource_size(res));
 
-#ifndef CONFIG_PM_RUNTIME
-	clk_disable(pdmac->clk);
-#endif
-
 	kfree(pdmac);
 
 	return 0;
@@ -3063,49 +3040,10 @@
 
 MODULE_DEVICE_TABLE(amba, pl330_ids);
 
-#ifdef CONFIG_PM_RUNTIME
-static int pl330_runtime_suspend(struct device *dev)
-{
-	struct dma_pl330_dmac *pdmac = dev_get_drvdata(dev);
-
-	if (!pdmac) {
-		dev_err(dev, "failed to get dmac\n");
-		return -ENODEV;
-	}
-
-	clk_disable(pdmac->clk);
-
-	return 0;
-}
-
-static int pl330_runtime_resume(struct device *dev)
-{
-	struct dma_pl330_dmac *pdmac = dev_get_drvdata(dev);
-
-	if (!pdmac) {
-		dev_err(dev, "failed to get dmac\n");
-		return -ENODEV;
-	}
-
-	clk_enable(pdmac->clk);
-
-	return 0;
-}
-#else
-#define pl330_runtime_suspend	NULL
-#define pl330_runtime_resume	NULL
-#endif /* CONFIG_PM_RUNTIME */
-
-static const struct dev_pm_ops pl330_pm_ops = {
-	.runtime_suspend = pl330_runtime_suspend,
-	.runtime_resume = pl330_runtime_resume,
-};
-
 static struct amba_driver pl330_driver = {
 	.drv = {
 		.owner = THIS_MODULE,
 		.name = "dma-pl330",
-		.pm = &pl330_pm_ops,
 	},
 	.id_table = pl330_ids,
 	.probe = pl330_probe,
diff --git a/drivers/dma/sa11x0-dma.c b/drivers/dma/sa11x0-dma.c
index f5a7360..b893159 100644
--- a/drivers/dma/sa11x0-dma.c
+++ b/drivers/dma/sa11x0-dma.c
@@ -614,7 +614,7 @@
 
 static struct dma_async_tx_descriptor *sa11x0_dma_prep_dma_cyclic(
 	struct dma_chan *chan, dma_addr_t addr, size_t size, size_t period,
-	enum dma_transfer_direction dir, void *context)
+	enum dma_transfer_direction dir, unsigned long flags, void *context)
 {
 	struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
 	struct sa11x0_dma_desc *txd;
diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c
index 434ad31..64385cd 100644
--- a/drivers/dma/sirf-dma.c
+++ b/drivers/dma/sirf-dma.c
@@ -489,7 +489,7 @@
 static struct dma_async_tx_descriptor *
 sirfsoc_dma_prep_cyclic(struct dma_chan *chan, dma_addr_t addr,
 	size_t buf_len, size_t period_len,
-	enum dma_transfer_direction direction, void *context)
+	enum dma_transfer_direction direction, unsigned long flags, void *context)
 {
 	struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan);
 	struct sirfsoc_dma_desc *sdesc = NULL;
@@ -570,21 +570,19 @@
 
 	if (of_property_read_u32(dn, "cell-index", &id)) {
 		dev_err(dev, "Fail to get DMAC index\n");
-		ret = -ENODEV;
-		goto free_mem;
+		return -ENODEV;
 	}
 
 	sdma->irq = irq_of_parse_and_map(dn, 0);
 	if (sdma->irq == NO_IRQ) {
 		dev_err(dev, "Error mapping IRQ!\n");
-		ret = -EINVAL;
-		goto free_mem;
+		return -EINVAL;
 	}
 
 	ret = of_address_to_resource(dn, 0, &res);
 	if (ret) {
 		dev_err(dev, "Error parsing memory region!\n");
-		goto free_mem;
+		goto irq_dispose;
 	}
 
 	regs_start = res.start;
@@ -597,12 +595,11 @@
 		goto irq_dispose;
 	}
 
-	ret = devm_request_irq(dev, sdma->irq, &sirfsoc_dma_irq, 0, DRV_NAME,
-		sdma);
+	ret = request_irq(sdma->irq, &sirfsoc_dma_irq, 0, DRV_NAME, sdma);
 	if (ret) {
 		dev_err(dev, "Error requesting IRQ!\n");
 		ret = -EINVAL;
-		goto unmap_mem;
+		goto irq_dispose;
 	}
 
 	dma = &sdma->dma;
@@ -652,13 +649,9 @@
 	return 0;
 
 free_irq:
-	devm_free_irq(dev, sdma->irq, sdma);
+	free_irq(sdma->irq, sdma);
 irq_dispose:
 	irq_dispose_mapping(sdma->irq);
-unmap_mem:
-	iounmap(sdma->base);
-free_mem:
-	devm_kfree(dev, sdma);
 	return ret;
 }
 
@@ -668,10 +661,8 @@
 	struct sirfsoc_dma *sdma = dev_get_drvdata(dev);
 
 	dma_async_device_unregister(&sdma->dma);
-	devm_free_irq(dev, sdma->irq, sdma);
+	free_irq(sdma->irq, sdma);
 	irq_dispose_mapping(sdma->irq);
-	iounmap(sdma->base);
-	devm_kfree(dev, sdma);
 	return 0;
 }
 
diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c
index 000d309..ae55091 100644
--- a/drivers/dma/ste_dma40.c
+++ b/drivers/dma/ste_dma40.c
@@ -2347,7 +2347,8 @@
 static struct dma_async_tx_descriptor *
 dma40_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t dma_addr,
 		     size_t buf_len, size_t period_len,
-		     enum dma_transfer_direction direction, void *context)
+		     enum dma_transfer_direction direction, unsigned long flags,
+		     void *context)
 {
 	unsigned int periods = buf_len / period_len;
 	struct dma_async_tx_descriptor *txd;
@@ -2920,19 +2921,23 @@
 	struct d40_base *base = NULL;
 	int num_log_chans = 0;
 	int num_phy_chans;
+	int clk_ret = -EINVAL;
 	int i;
 	u32 pid;
 	u32 cid;
 	u8 rev;
 
 	clk = clk_get(&pdev->dev, NULL);
-
 	if (IS_ERR(clk)) {
 		d40_err(&pdev->dev, "No matching clock found\n");
 		goto failure;
 	}
 
-	clk_enable(clk);
+	clk_ret = clk_prepare_enable(clk);
+	if (clk_ret) {
+		d40_err(&pdev->dev, "Failed to prepare/enable clock\n");
+		goto failure;
+	}
 
 	/* Get IO for DMAC base address */
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "base");
@@ -3062,10 +3067,10 @@
 	return base;
 
 failure:
-	if (!IS_ERR(clk)) {
-		clk_disable(clk);
+	if (!clk_ret)
+		clk_disable_unprepare(clk);
+	if (!IS_ERR(clk))
 		clk_put(clk);
-	}
 	if (virtbase)
 		iounmap(virtbase);
 	if (res)
diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c
index 4708467..528c62d 100644
--- a/drivers/dma/tegra20-apb-dma.c
+++ b/drivers/dma/tegra20-apb-dma.c
@@ -169,6 +169,7 @@
 /* tegra_dma_channel: Channel specific information */
 struct tegra_dma_channel {
 	struct dma_chan		dma_chan;
+	char			name[30];
 	bool			config_init;
 	int			id;
 	int			irq;
@@ -475,8 +476,7 @@
 	while (!list_empty(&tdc->pending_sg_req)) {
 		sgreq = list_first_entry(&tdc->pending_sg_req,
 						typeof(*sgreq), node);
-		list_del(&sgreq->node);
-		list_add_tail(&sgreq->node, &tdc->free_sg_req);
+		list_move_tail(&sgreq->node, &tdc->free_sg_req);
 		if (sgreq->last_sg) {
 			dma_desc = sgreq->dma_desc;
 			dma_desc->dma_status = DMA_ERROR;
@@ -570,8 +570,7 @@
 
 	/* If not last req then put at end of pending list */
 	if (!list_is_last(&sgreq->node, &tdc->pending_sg_req)) {
-		list_del(&sgreq->node);
-		list_add_tail(&sgreq->node, &tdc->pending_sg_req);
+		list_move_tail(&sgreq->node, &tdc->pending_sg_req);
 		sgreq->configured = false;
 		st = handle_continuous_head_request(tdc, sgreq, to_terminate);
 		if (!st)
@@ -990,7 +989,7 @@
 struct dma_async_tx_descriptor *tegra_dma_prep_dma_cyclic(
 	struct dma_chan *dc, dma_addr_t buf_addr, size_t buf_len,
 	size_t period_len, enum dma_transfer_direction direction,
-	void *context)
+	unsigned long flags, void *context)
 {
 	struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc);
 	struct tegra_dma_desc *dma_desc = NULL;
@@ -1284,7 +1283,6 @@
 	INIT_LIST_HEAD(&tdma->dma_dev.channels);
 	for (i = 0; i < cdata->nr_channels; i++) {
 		struct tegra_dma_channel *tdc = &tdma->channels[i];
-		char irq_name[30];
 
 		tdc->chan_base_offset = TEGRA_APBDMA_CHANNEL_BASE_ADD_OFFSET +
 					i * TEGRA_APBDMA_CHANNEL_REGISTER_SIZE;
@@ -1296,9 +1294,9 @@
 			goto err_irq;
 		}
 		tdc->irq = res->start;
-		snprintf(irq_name, sizeof(irq_name), "apbdma.%d", i);
+		snprintf(tdc->name, sizeof(tdc->name), "apbdma.%d", i);
 		ret = devm_request_irq(&pdev->dev, tdc->irq,
-				tegra_dma_isr, 0, irq_name, tdc);
+				tegra_dma_isr, 0, tdc->name, tdc);
 		if (ret) {
 			dev_err(&pdev->dev,
 				"request_irq failed with err %d channel %d\n",
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index 2783f69..f8d2287 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -473,8 +473,8 @@
 	client->bus_reset_closure = a->bus_reset_closure;
 	if (a->bus_reset != 0) {
 		fill_bus_reset_event(&bus_reset, client);
-		ret = copy_to_user(u64_to_uptr(a->bus_reset),
-				   &bus_reset, sizeof(bus_reset));
+		/* unaligned size of bus_reset is 36 bytes */
+		ret = copy_to_user(u64_to_uptr(a->bus_reset), &bus_reset, 36);
 	}
 	if (ret == 0 && list_empty(&client->link))
 		list_add_tail(&client->link, &client->device->client_list);
diff --git a/drivers/gpio/gpio-stp-xway.c b/drivers/gpio/gpio-stp-xway.c
index e35096b..8bead0b 100644
--- a/drivers/gpio/gpio-stp-xway.c
+++ b/drivers/gpio/gpio-stp-xway.c
@@ -82,7 +82,7 @@
 	struct gpio_chip gc;
 	void __iomem *virt;
 	u32 edge;	/* rising or falling edge triggered shift register */
-	u16 shadow;	/* shadow the shift registers state */
+	u32 shadow;	/* shadow the shift registers state */
 	u8 groups;	/* we can drive 1-3 groups of 8bit each */
 	u8 dsl;		/* the 2 LSBs can be driven by the dsl core */
 	u8 phy1;	/* 3 bits can be driven by phy1 */
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 5dda07c..fadcd44 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -395,13 +395,14 @@
  * \param adapter : i2c device adaptor
  * \return 1 on success
  */
-static bool
+bool
 drm_probe_ddc(struct i2c_adapter *adapter)
 {
 	unsigned char out;
 
 	return (drm_do_probe_ddc_edid(adapter, &out, 0, 1) == 0);
 }
+EXPORT_SYMBOL(drm_probe_ddc);
 
 /**
  * drm_get_edid - get EDID data, if available
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 92177d5..24efae4 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -706,7 +706,7 @@
 		goto out_unlock;
 	}
 
-	vma->vm_flags |= VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTEXPAND;
+	vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
 	vma->vm_ops = obj->dev->driver->gem_vm_ops;
 	vma->vm_private_data = map->handle;
 	vma->vm_page_prot =  pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c
index 23a824e..db7bd29 100644
--- a/drivers/gpu/drm/drm_vm.c
+++ b/drivers/gpu/drm/drm_vm.c
@@ -514,8 +514,7 @@
 
 	vma->vm_ops = &drm_vm_dma_ops;
 
-	vma->vm_flags |= VM_RESERVED;	/* Don't swap */
-	vma->vm_flags |= VM_DONTEXPAND;
+	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 
 	drm_vm_open_locked(dev, vma);
 	return 0;
@@ -643,21 +642,16 @@
 	case _DRM_SHM:
 		vma->vm_ops = &drm_vm_shm_ops;
 		vma->vm_private_data = (void *)map;
-		/* Don't let this area swap.  Change when
-		   DRM_KERNEL advisory is supported. */
-		vma->vm_flags |= VM_RESERVED;
 		break;
 	case _DRM_SCATTER_GATHER:
 		vma->vm_ops = &drm_vm_sg_ops;
 		vma->vm_private_data = (void *)map;
-		vma->vm_flags |= VM_RESERVED;
 		vma->vm_page_prot = drm_dma_prot(map->type, vma);
 		break;
 	default:
 		return -EINVAL;	/* This should never happen. */
 	}
-	vma->vm_flags |= VM_RESERVED;	/* Don't swap */
-	vma->vm_flags |= VM_DONTEXPAND;
+	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 
 	drm_vm_open_locked(dev, vma);
 	return 0;
diff --git a/drivers/gpu/drm/exynos/exynos_ddc.c b/drivers/gpu/drm/exynos/exynos_ddc.c
index 961a180..37e6ec7 100644
--- a/drivers/gpu/drm/exynos/exynos_ddc.c
+++ b/drivers/gpu/drm/exynos/exynos_ddc.c
@@ -26,29 +26,41 @@
 {
 	hdmi_attach_ddc_client(client);
 
-	dev_info(&client->adapter->dev, "attached s5p_ddc "
-		"into i2c adapter successfully\n");
+	dev_info(&client->adapter->dev,
+		"attached %s into i2c adapter successfully\n",
+		client->name);
 
 	return 0;
 }
 
 static int s5p_ddc_remove(struct i2c_client *client)
 {
-	dev_info(&client->adapter->dev, "detached s5p_ddc "
-		"from i2c adapter successfully\n");
+	dev_info(&client->adapter->dev,
+		"detached %s from i2c adapter successfully\n",
+		client->name);
 
 	return 0;
 }
 
 static struct i2c_device_id ddc_idtable[] = {
 	{"s5p_ddc", 0},
+	{"exynos5-hdmiddc", 0},
 	{ },
 };
 
+static struct of_device_id hdmiddc_match_types[] = {
+	{
+		.compatible = "samsung,exynos5-hdmiddc",
+	}, {
+		/* end node */
+	}
+};
+
 struct i2c_driver ddc_driver = {
 	.driver = {
-		.name = "s5p_ddc",
+		.name = "exynos-hdmiddc",
 		.owner = THIS_MODULE,
+		.of_match_table = hdmiddc_match_types,
 	},
 	.id_table	= ddc_idtable,
 	.probe		= s5p_ddc_probe,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c b/drivers/gpu/drm/exynos/exynos_drm_connector.c
index c2b1b14..18c2718 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_connector.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c
@@ -40,6 +40,7 @@
 	struct drm_connector	drm_connector;
 	uint32_t		encoder_id;
 	struct exynos_drm_manager *manager;
+	uint32_t		dpms;
 };
 
 /* convert exynos_video_timings to drm_display_mode */
@@ -149,8 +150,12 @@
 		count = drm_add_edid_modes(connector, edid);
 		kfree(edid);
 	} else {
-		struct drm_display_mode *mode = drm_mode_create(connector->dev);
 		struct exynos_drm_panel_info *panel;
+		struct drm_display_mode *mode = drm_mode_create(connector->dev);
+		if (!mode) {
+			DRM_ERROR("failed to create a new display mode.\n");
+			return 0;
+		}
 
 		if (display_ops->get_panel)
 			panel = display_ops->get_panel(manager->dev);
@@ -194,8 +199,7 @@
 	return ret;
 }
 
-static struct drm_encoder *exynos_drm_best_encoder(
-						struct drm_connector *connector)
+struct drm_encoder *exynos_drm_best_encoder(struct drm_connector *connector)
 {
 	struct drm_device *dev = connector->dev;
 	struct exynos_drm_connector *exynos_connector =
@@ -224,6 +228,43 @@
 	.best_encoder	= exynos_drm_best_encoder,
 };
 
+void exynos_drm_display_power(struct drm_connector *connector, int mode)
+{
+	struct drm_encoder *encoder = exynos_drm_best_encoder(connector);
+	struct exynos_drm_connector *exynos_connector;
+	struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder);
+	struct exynos_drm_display_ops *display_ops = manager->display_ops;
+
+	exynos_connector = to_exynos_connector(connector);
+
+	if (exynos_connector->dpms == mode) {
+		DRM_DEBUG_KMS("desired dpms mode is same as previous one.\n");
+		return;
+	}
+
+	if (display_ops && display_ops->power_on)
+		display_ops->power_on(manager->dev, mode);
+
+	exynos_connector->dpms = mode;
+}
+
+static void exynos_drm_connector_dpms(struct drm_connector *connector,
+					int mode)
+{
+	DRM_DEBUG_KMS("%s\n", __FILE__);
+
+	/*
+	 * in case that drm_crtc_helper_set_mode() is called,
+	 * encoder/crtc->funcs->dpms() will be just returned
+	 * because they already were DRM_MODE_DPMS_ON so only
+	 * exynos_drm_display_power() will be called.
+	 */
+	drm_helper_connector_dpms(connector, mode);
+
+	exynos_drm_display_power(connector, mode);
+
+}
+
 static int exynos_drm_connector_fill_modes(struct drm_connector *connector,
 				unsigned int max_width, unsigned int max_height)
 {
@@ -283,7 +324,7 @@
 }
 
 static struct drm_connector_funcs exynos_connector_funcs = {
-	.dpms		= drm_helper_connector_dpms,
+	.dpms		= exynos_drm_connector_dpms,
 	.fill_modes	= exynos_drm_connector_fill_modes,
 	.detect		= exynos_drm_connector_detect,
 	.destroy	= exynos_drm_connector_destroy,
@@ -332,6 +373,7 @@
 
 	exynos_connector->encoder_id = encoder->base.id;
 	exynos_connector->manager = manager;
+	exynos_connector->dpms = DRM_MODE_DPMS_OFF;
 	connector->encoder = encoder;
 
 	err = drm_mode_connector_attach_encoder(connector, encoder);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.h b/drivers/gpu/drm/exynos/exynos_drm_connector.h
index 1c7b2b5..22f6cc4 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_connector.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_connector.h
@@ -31,4 +31,8 @@
 struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,
 						   struct drm_encoder *encoder);
 
+struct drm_encoder *exynos_drm_best_encoder(struct drm_connector *connector);
+
+void exynos_drm_display_power(struct drm_connector *connector, int mode);
+
 #endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c
index 19bdf0a..94026ad 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_core.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_core.c
@@ -34,33 +34,15 @@
 
 static LIST_HEAD(exynos_drm_subdrv_list);
 
-static int exynos_drm_subdrv_probe(struct drm_device *dev,
+static int exynos_drm_create_enc_conn(struct drm_device *dev,
 					struct exynos_drm_subdrv *subdrv)
 {
 	struct drm_encoder *encoder;
 	struct drm_connector *connector;
+	int ret;
 
 	DRM_DEBUG_DRIVER("%s\n", __FILE__);
 
-	if (subdrv->probe) {
-		int ret;
-
-		/*
-		 * this probe callback would be called by sub driver
-		 * after setting of all resources to this sub driver,
-		 * such as clock, irq and register map are done or by load()
-		 * of exynos drm driver.
-		 *
-		 * P.S. note that this driver is considered for modularization.
-		 */
-		ret = subdrv->probe(dev, subdrv->dev);
-		if (ret)
-			return ret;
-	}
-
-	if (!subdrv->manager)
-		return 0;
-
 	subdrv->manager->dev = subdrv->dev;
 
 	/* create and initialize a encoder for this sub driver. */
@@ -78,24 +60,22 @@
 	connector = exynos_drm_connector_create(dev, encoder);
 	if (!connector) {
 		DRM_ERROR("failed to create connector\n");
-		encoder->funcs->destroy(encoder);
-		return -EFAULT;
+		ret = -EFAULT;
+		goto err_destroy_encoder;
 	}
 
 	subdrv->encoder = encoder;
 	subdrv->connector = connector;
 
 	return 0;
+
+err_destroy_encoder:
+	encoder->funcs->destroy(encoder);
+	return ret;
 }
 
-static void exynos_drm_subdrv_remove(struct drm_device *dev,
-				      struct exynos_drm_subdrv *subdrv)
+static void exynos_drm_destroy_enc_conn(struct exynos_drm_subdrv *subdrv)
 {
-	DRM_DEBUG_DRIVER("%s\n", __FILE__);
-
-	if (subdrv->remove)
-		subdrv->remove(dev);
-
 	if (subdrv->encoder) {
 		struct drm_encoder *encoder = subdrv->encoder;
 		encoder->funcs->destroy(encoder);
@@ -109,9 +89,43 @@
 	}
 }
 
+static int exynos_drm_subdrv_probe(struct drm_device *dev,
+					struct exynos_drm_subdrv *subdrv)
+{
+	if (subdrv->probe) {
+		int ret;
+
+		subdrv->drm_dev = dev;
+
+		/*
+		 * this probe callback would be called by sub driver
+		 * after setting of all resources to this sub driver,
+		 * such as clock, irq and register map are done or by load()
+		 * of exynos drm driver.
+		 *
+		 * P.S. note that this driver is considered for modularization.
+		 */
+		ret = subdrv->probe(dev, subdrv->dev);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static void exynos_drm_subdrv_remove(struct drm_device *dev,
+				      struct exynos_drm_subdrv *subdrv)
+{
+	DRM_DEBUG_DRIVER("%s\n", __FILE__);
+
+	if (subdrv->remove)
+		subdrv->remove(dev, subdrv->dev);
+}
+
 int exynos_drm_device_register(struct drm_device *dev)
 {
 	struct exynos_drm_subdrv *subdrv, *n;
+	unsigned int fine_cnt = 0;
 	int err;
 
 	DRM_DEBUG_DRIVER("%s\n", __FILE__);
@@ -120,14 +134,36 @@
 		return -EINVAL;
 
 	list_for_each_entry_safe(subdrv, n, &exynos_drm_subdrv_list, list) {
-		subdrv->drm_dev = dev;
 		err = exynos_drm_subdrv_probe(dev, subdrv);
 		if (err) {
 			DRM_DEBUG("exynos drm subdrv probe failed.\n");
 			list_del(&subdrv->list);
+			continue;
 		}
+
+		/*
+		 * if manager is null then it means that this sub driver
+		 * doesn't need encoder and connector.
+		 */
+		if (!subdrv->manager) {
+			fine_cnt++;
+			continue;
+		}
+
+		err = exynos_drm_create_enc_conn(dev, subdrv);
+		if (err) {
+			DRM_DEBUG("failed to create encoder and connector.\n");
+			exynos_drm_subdrv_remove(dev, subdrv);
+			list_del(&subdrv->list);
+			continue;
+		}
+
+		fine_cnt++;
 	}
 
+	if (!fine_cnt)
+		return -EINVAL;
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(exynos_drm_device_register);
@@ -143,8 +179,10 @@
 		return -EINVAL;
 	}
 
-	list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list)
+	list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) {
 		exynos_drm_subdrv_remove(dev, subdrv);
+		exynos_drm_destroy_enc_conn(subdrv);
+	}
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index df1e34f0..fce245f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -66,7 +66,6 @@
 
 static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
 {
-	struct drm_device *dev = crtc->dev;
 	struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
 
 	DRM_DEBUG_KMS("crtc[%d] mode[%d]\n", crtc->base.id, mode);
@@ -76,12 +75,8 @@
 		return;
 	}
 
-	mutex_lock(&dev->struct_mutex);
-
 	exynos_drm_fn_encoder(crtc, &mode, exynos_drm_encoder_crtc_dpms);
 	exynos_crtc->dpms = mode;
-
-	mutex_unlock(&dev->struct_mutex);
 }
 
 static void exynos_drm_crtc_prepare(struct drm_crtc *crtc)
@@ -97,6 +92,7 @@
 
 	DRM_DEBUG_KMS("%s\n", __FILE__);
 
+	exynos_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
 	exynos_plane_commit(exynos_crtc->plane);
 	exynos_plane_dpms(exynos_crtc->plane, DRM_MODE_DPMS_ON);
 }
@@ -126,8 +122,6 @@
 
 	DRM_DEBUG_KMS("%s\n", __FILE__);
 
-	exynos_drm_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
-
 	/*
 	 * copy the mode data adjusted by mode_fixup() into crtc->mode
 	 * so that hardware can be seet to proper mode.
@@ -161,6 +155,12 @@
 
 	DRM_DEBUG_KMS("%s\n", __FILE__);
 
+	/* when framebuffer changing is requested, crtc's dpms should be on */
+	if (exynos_crtc->dpms > DRM_MODE_DPMS_ON) {
+		DRM_ERROR("failed framebuffer changing request.\n");
+		return -EPERM;
+	}
+
 	crtc_w = crtc->fb->width - x;
 	crtc_h = crtc->fb->height - y;
 
@@ -213,6 +213,12 @@
 
 	DRM_DEBUG_KMS("%s\n", __FILE__);
 
+	/* when the page flip is requested, crtc's dpms should be on */
+	if (exynos_crtc->dpms > DRM_MODE_DPMS_ON) {
+		DRM_ERROR("failed page flip request.\n");
+		return -EINVAL;
+	}
+
 	mutex_lock(&dev->struct_mutex);
 
 	if (event) {
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index a4ab98b..a342310 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -36,6 +36,20 @@
 #define MAX_FB_BUFFER	4
 #define DEFAULT_ZPOS	-1
 
+#define _wait_for(COND, MS) ({ \
+	unsigned long timeout__ = jiffies + msecs_to_jiffies(MS);	\
+	int ret__ = 0;							\
+	while (!(COND)) {						\
+		if (time_after(jiffies, timeout__)) {			\
+			ret__ = -ETIMEDOUT;				\
+			break;						\
+		}							\
+	}								\
+	ret__;								\
+})
+
+#define wait_for(COND, MS) _wait_for(COND, MS)
+
 struct drm_device;
 struct exynos_drm_overlay;
 struct drm_connector;
@@ -60,6 +74,8 @@
  * @commit: apply hardware specific overlay data to registers.
  * @enable: enable hardware specific overlay.
  * @disable: disable hardware specific overlay.
+ * @wait_for_vblank: wait for vblank interrupt to make sure that
+ *	hardware overlay is disabled.
  */
 struct exynos_drm_overlay_ops {
 	void (*mode_set)(struct device *subdrv_dev,
@@ -67,6 +83,7 @@
 	void (*commit)(struct device *subdrv_dev, int zpos);
 	void (*enable)(struct device *subdrv_dev, int zpos);
 	void (*disable)(struct device *subdrv_dev, int zpos);
+	void (*wait_for_vblank)(struct device *subdrv_dev);
 };
 
 /*
@@ -265,7 +282,7 @@
 	struct exynos_drm_manager *manager;
 
 	int (*probe)(struct drm_device *drm_dev, struct device *dev);
-	void (*remove)(struct drm_device *dev);
+	void (*remove)(struct drm_device *drm_dev, struct device *dev);
 	int (*open)(struct drm_device *drm_dev, struct device *dev,
 			struct drm_file *file);
 	void (*close)(struct drm_device *drm_dev, struct device *dev,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
index 39bd8ab..e51503f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
@@ -31,6 +31,7 @@
 
 #include "exynos_drm_drv.h"
 #include "exynos_drm_encoder.h"
+#include "exynos_drm_connector.h"
 
 #define to_exynos_encoder(x)	container_of(x, struct exynos_drm_encoder,\
 				drm_encoder)
@@ -44,26 +45,23 @@
  * @dpms: store the encoder dpms value.
  */
 struct exynos_drm_encoder {
+	struct drm_crtc			*old_crtc;
 	struct drm_encoder		drm_encoder;
 	struct exynos_drm_manager	*manager;
 	int dpms;
 };
 
-static void exynos_drm_display_power(struct drm_encoder *encoder, int mode)
+static void exynos_drm_connector_power(struct drm_encoder *encoder, int mode)
 {
 	struct drm_device *dev = encoder->dev;
 	struct drm_connector *connector;
-	struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder);
 
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-		if (connector->encoder == encoder) {
-			struct exynos_drm_display_ops *display_ops =
-							manager->display_ops;
-
+		if (exynos_drm_best_encoder(connector) == encoder) {
 			DRM_DEBUG_KMS("connector[%d] dpms[%d]\n",
 					connector->base.id, mode);
-			if (display_ops && display_ops->power_on)
-				display_ops->power_on(manager->dev, mode);
+
+			exynos_drm_display_power(connector, mode);
 		}
 	}
 }
@@ -88,13 +86,13 @@
 	case DRM_MODE_DPMS_ON:
 		if (manager_ops && manager_ops->apply)
 			manager_ops->apply(manager->dev);
-		exynos_drm_display_power(encoder, mode);
+		exynos_drm_connector_power(encoder, mode);
 		exynos_encoder->dpms = mode;
 		break;
 	case DRM_MODE_DPMS_STANDBY:
 	case DRM_MODE_DPMS_SUSPEND:
 	case DRM_MODE_DPMS_OFF:
-		exynos_drm_display_power(encoder, mode);
+		exynos_drm_connector_power(encoder, mode);
 		exynos_encoder->dpms = mode;
 		break;
 	default:
@@ -127,24 +125,74 @@
 	return true;
 }
 
+static void disable_plane_to_crtc(struct drm_device *dev,
+						struct drm_crtc *old_crtc,
+						struct drm_crtc *new_crtc)
+{
+	struct drm_plane *plane;
+
+	/*
+	 * if old_crtc isn't same as encoder->crtc then it means that
+	 * user changed crtc id to another one so the plane to old_crtc
+	 * should be disabled and plane->crtc should be set to new_crtc
+	 * (encoder->crtc)
+	 */
+	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+		if (plane->crtc == old_crtc) {
+			/*
+			 * do not change below call order.
+			 *
+			 * plane->funcs->disable_plane call checks
+			 * if encoder->crtc is same as plane->crtc and if same
+			 * then overlay_ops->disable callback will be called
+			 * to diasble current hw overlay so plane->crtc should
+			 * have new_crtc because new_crtc was set to
+			 * encoder->crtc in advance.
+			 */
+			plane->crtc = new_crtc;
+			plane->funcs->disable_plane(plane);
+		}
+	}
+}
+
 static void exynos_drm_encoder_mode_set(struct drm_encoder *encoder,
 					 struct drm_display_mode *mode,
 					 struct drm_display_mode *adjusted_mode)
 {
 	struct drm_device *dev = encoder->dev;
 	struct drm_connector *connector;
-	struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder);
-	struct exynos_drm_manager_ops *manager_ops = manager->ops;
+	struct exynos_drm_manager *manager;
+	struct exynos_drm_manager_ops *manager_ops;
 
 	DRM_DEBUG_KMS("%s\n", __FILE__);
 
-	exynos_drm_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
-
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-		if (connector->encoder == encoder)
+		if (connector->encoder == encoder) {
+			struct exynos_drm_encoder *exynos_encoder;
+
+			exynos_encoder = to_exynos_encoder(encoder);
+
+			if (exynos_encoder->old_crtc != encoder->crtc &&
+					exynos_encoder->old_crtc) {
+
+				/*
+				 * disable a plane to old crtc and change
+				 * crtc of the plane to new one.
+				 */
+				disable_plane_to_crtc(dev,
+						exynos_encoder->old_crtc,
+						encoder->crtc);
+			}
+
+			manager = exynos_drm_get_manager(encoder);
+			manager_ops = manager->ops;
+
 			if (manager_ops && manager_ops->mode_set)
 				manager_ops->mode_set(manager->dev,
 							adjusted_mode);
+
+			exynos_encoder->old_crtc = encoder->crtc;
+		}
 	}
 }
 
@@ -166,12 +214,27 @@
 		manager_ops->commit(manager->dev);
 }
 
+static void exynos_drm_encoder_disable(struct drm_encoder *encoder)
+{
+	struct drm_plane *plane;
+	struct drm_device *dev = encoder->dev;
+
+	exynos_drm_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
+
+	/* all planes connected to this encoder should be also disabled. */
+	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+		if (plane->crtc == encoder->crtc)
+			plane->funcs->disable_plane(plane);
+	}
+}
+
 static struct drm_encoder_helper_funcs exynos_encoder_helper_funcs = {
 	.dpms		= exynos_drm_encoder_dpms,
 	.mode_fixup	= exynos_drm_encoder_mode_fixup,
 	.mode_set	= exynos_drm_encoder_mode_set,
 	.prepare	= exynos_drm_encoder_prepare,
 	.commit		= exynos_drm_encoder_commit,
+	.disable	= exynos_drm_encoder_disable,
 };
 
 static void exynos_drm_encoder_destroy(struct drm_encoder *encoder)
@@ -338,6 +401,19 @@
 		manager_ops->dpms(manager->dev, mode);
 
 	/*
+	 * set current mode to new one so that data aren't updated into
+	 * registers by drm_helper_connector_dpms two times.
+	 *
+	 * in case that drm_crtc_helper_set_mode() is called,
+	 * overlay_ops->commit() and manager_ops->commit() callbacks
+	 * can be called two times, first at drm_crtc_helper_set_mode()
+	 * and second at drm_helper_connector_dpms().
+	 * so with this setting, when drm_helper_connector_dpms() is called
+	 * encoder->funcs->dpms() will be ignored.
+	 */
+	exynos_encoder->dpms = mode;
+
+	/*
 	 * if this condition is ok then it means that the crtc is already
 	 * detached from encoder and last function for detaching is properly
 	 * done, so clear pipe from manager to prevent repeated call.
@@ -422,4 +498,14 @@
 
 	if (overlay_ops && overlay_ops->disable)
 		overlay_ops->disable(manager->dev, zpos);
+
+	/*
+	 * wait for vblank interrupt
+	 * - this makes sure that hardware overlay is disabled to avoid
+	 * for the dma accesses to memory after gem buffer was released
+	 * because the setting for disabling the overlay will be updated
+	 * at vsync.
+	 */
+	if (overlay_ops->wait_for_vblank)
+		overlay_ops->wait_for_vblank(manager->dev);
 }
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c
index 53afcc5..4ef4cd3 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
@@ -41,10 +41,12 @@
  * exynos specific framebuffer structure.
  *
  * @fb: drm framebuffer obejct.
+ * @buf_cnt: a buffer count to drm framebuffer.
  * @exynos_gem_obj: array of exynos specific gem object containing a gem object.
  */
 struct exynos_drm_fb {
 	struct drm_framebuffer		fb;
+	unsigned int			buf_cnt;
 	struct exynos_drm_gem_obj	*exynos_gem_obj[MAX_FB_BUFFER];
 };
 
@@ -101,6 +103,25 @@
 	.dirty		= exynos_drm_fb_dirty,
 };
 
+void exynos_drm_fb_set_buf_cnt(struct drm_framebuffer *fb,
+						unsigned int cnt)
+{
+	struct exynos_drm_fb *exynos_fb;
+
+	exynos_fb = to_exynos_fb(fb);
+
+	exynos_fb->buf_cnt = cnt;
+}
+
+unsigned int exynos_drm_fb_get_buf_cnt(struct drm_framebuffer *fb)
+{
+	struct exynos_drm_fb *exynos_fb;
+
+	exynos_fb = to_exynos_fb(fb);
+
+	return exynos_fb->buf_cnt;
+}
+
 struct drm_framebuffer *
 exynos_drm_framebuffer_init(struct drm_device *dev,
 			    struct drm_mode_fb_cmd2 *mode_cmd,
@@ -127,6 +148,43 @@
 	return &exynos_fb->fb;
 }
 
+static u32 exynos_drm_format_num_buffers(struct drm_mode_fb_cmd2 *mode_cmd)
+{
+	unsigned int cnt = 0;
+
+	if (mode_cmd->pixel_format != DRM_FORMAT_NV12)
+		return drm_format_num_planes(mode_cmd->pixel_format);
+
+	while (cnt != MAX_FB_BUFFER) {
+		if (!mode_cmd->handles[cnt])
+			break;
+		cnt++;
+	}
+
+	/*
+	 * check if NV12 or NV12M.
+	 *
+	 * NV12
+	 * handles[0] = base1, offsets[0] = 0
+	 * handles[1] = base1, offsets[1] = Y_size
+	 *
+	 * NV12M
+	 * handles[0] = base1, offsets[0] = 0
+	 * handles[1] = base2, offsets[1] = 0
+	 */
+	if (cnt == 2) {
+		/*
+		 * in case of NV12 format, offsets[1] is not 0 and
+		 * handles[0] is same as handles[1].
+		 */
+		if (mode_cmd->offsets[1] &&
+			mode_cmd->handles[0] == mode_cmd->handles[1])
+			cnt = 1;
+	}
+
+	return cnt;
+}
+
 static struct drm_framebuffer *
 exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
 		      struct drm_mode_fb_cmd2 *mode_cmd)
@@ -134,7 +192,6 @@
 	struct drm_gem_object *obj;
 	struct drm_framebuffer *fb;
 	struct exynos_drm_fb *exynos_fb;
-	int nr;
 	int i;
 
 	DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -152,9 +209,11 @@
 	}
 
 	exynos_fb = to_exynos_fb(fb);
-	nr = exynos_drm_format_num_buffers(fb->pixel_format);
+	exynos_fb->buf_cnt = exynos_drm_format_num_buffers(mode_cmd);
 
-	for (i = 1; i < nr; i++) {
+	DRM_DEBUG_KMS("buf_cnt = %d\n", exynos_fb->buf_cnt);
+
+	for (i = 1; i < exynos_fb->buf_cnt; i++) {
 		obj = drm_gem_object_lookup(dev, file_priv,
 				mode_cmd->handles[i]);
 		if (!obj) {
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.h b/drivers/gpu/drm/exynos/exynos_drm_fb.h
index 5082375..96262e5 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.h
@@ -28,19 +28,6 @@
 #ifndef _EXYNOS_DRM_FB_H_
 #define _EXYNOS_DRM_FB_H
 
-static inline int exynos_drm_format_num_buffers(uint32_t format)
-{
-	switch (format) {
-	case DRM_FORMAT_NV12:
-	case DRM_FORMAT_NV12MT:
-		return 2;
-	case DRM_FORMAT_YUV420:
-		return 3;
-	default:
-		return 1;
-	}
-}
-
 struct drm_framebuffer *
 exynos_drm_framebuffer_init(struct drm_device *dev,
 			    struct drm_mode_fb_cmd2 *mode_cmd,
@@ -52,4 +39,11 @@
 
 void exynos_drm_mode_config_init(struct drm_device *dev);
 
+/* set a buffer count to drm framebuffer. */
+void exynos_drm_fb_set_buf_cnt(struct drm_framebuffer *fb,
+						unsigned int cnt);
+
+/* get a buffer count to drm framebuffer. */
+unsigned int exynos_drm_fb_get_buf_cnt(struct drm_framebuffer *fb);
+
 #endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index bd4ff63..67eb6ba 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -79,6 +79,9 @@
 		return -EFAULT;
 	}
 
+	/* buffer count to framebuffer always is 1 at booting time. */
+	exynos_drm_fb_set_buf_cnt(fb, 1);
+
 	offset = fbi->var.xoffset * (fb->bits_per_pixel >> 3);
 	offset += fbi->var.yoffset * fb->pitches[0];
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 58d50e3..130a2b5 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -19,8 +19,8 @@
 #include <linux/clk.h>
 #include <linux/pm_runtime.h>
 
+#include <video/samsung_fimd.h>
 #include <drm/exynos_drm.h>
-#include <plat/regs-fb-v4.h>
 
 #include "exynos_drm_drv.h"
 #include "exynos_drm_fbdev.h"
@@ -57,6 +57,18 @@
 
 #define get_fimd_context(dev)	platform_get_drvdata(to_platform_device(dev))
 
+struct fimd_driver_data {
+	unsigned int timing_base;
+};
+
+struct fimd_driver_data exynos4_fimd_driver_data = {
+	.timing_base = 0x0,
+};
+
+struct fimd_driver_data exynos5_fimd_driver_data = {
+	.timing_base = 0x20000,
+};
+
 struct fimd_win_data {
 	unsigned int		offset_x;
 	unsigned int		offset_y;
@@ -91,6 +103,13 @@
 	struct exynos_drm_panel_info *panel;
 };
 
+static inline struct fimd_driver_data *drm_fimd_get_driver_data(
+	struct platform_device *pdev)
+{
+	return (struct fimd_driver_data *)
+		platform_get_device_id(pdev)->driver_data;
+}
+
 static bool fimd_display_is_connected(struct device *dev)
 {
 	DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -194,32 +213,35 @@
 	struct fimd_context *ctx = get_fimd_context(dev);
 	struct exynos_drm_panel_info *panel = ctx->panel;
 	struct fb_videomode *timing = &panel->timing;
+	struct fimd_driver_data *driver_data;
+	struct platform_device *pdev = to_platform_device(dev);
 	u32 val;
 
+	driver_data = drm_fimd_get_driver_data(pdev);
 	if (ctx->suspended)
 		return;
 
 	DRM_DEBUG_KMS("%s\n", __FILE__);
 
 	/* setup polarity values from machine code. */
-	writel(ctx->vidcon1, ctx->regs + VIDCON1);
+	writel(ctx->vidcon1, ctx->regs + driver_data->timing_base + VIDCON1);
 
 	/* setup vertical timing values. */
 	val = VIDTCON0_VBPD(timing->upper_margin - 1) |
 	       VIDTCON0_VFPD(timing->lower_margin - 1) |
 	       VIDTCON0_VSPW(timing->vsync_len - 1);
-	writel(val, ctx->regs + VIDTCON0);
+	writel(val, ctx->regs + driver_data->timing_base + VIDTCON0);
 
 	/* setup horizontal timing values.  */
 	val = VIDTCON1_HBPD(timing->left_margin - 1) |
 	       VIDTCON1_HFPD(timing->right_margin - 1) |
 	       VIDTCON1_HSPW(timing->hsync_len - 1);
-	writel(val, ctx->regs + VIDTCON1);
+	writel(val, ctx->regs + driver_data->timing_base + VIDTCON1);
 
 	/* setup horizontal and vertical display size. */
 	val = VIDTCON2_LINEVAL(timing->yres - 1) |
 	       VIDTCON2_HOZVAL(timing->xres - 1);
-	writel(val, ctx->regs + VIDTCON2);
+	writel(val, ctx->regs + driver_data->timing_base + VIDTCON2);
 
 	/* setup clock source, clock divider, enable dma. */
 	val = ctx->vidcon0;
@@ -570,10 +592,22 @@
 	win_data->enabled = false;
 }
 
+static void fimd_wait_for_vblank(struct device *dev)
+{
+	struct fimd_context *ctx = get_fimd_context(dev);
+	int ret;
+
+	ret = wait_for((__raw_readl(ctx->regs + VIDCON1) &
+					VIDCON1_VSTATUS_VSYNC), 50);
+	if (ret < 0)
+		DRM_DEBUG_KMS("vblank wait timed out.\n");
+}
+
 static struct exynos_drm_overlay_ops fimd_overlay_ops = {
 	.mode_set = fimd_win_mode_set,
 	.commit = fimd_win_commit,
 	.disable = fimd_win_disable,
+	.wait_for_vblank = fimd_wait_for_vblank,
 };
 
 static struct exynos_drm_manager fimd_manager = {
@@ -678,7 +712,7 @@
 	return 0;
 }
 
-static void fimd_subdrv_remove(struct drm_device *drm_dev)
+static void fimd_subdrv_remove(struct drm_device *drm_dev, struct device *dev)
 {
 	DRM_DEBUG_KMS("%s\n", __FILE__);
 
@@ -747,16 +781,10 @@
 	writel(val, ctx->regs + SHADOWCON);
 }
 
-static int fimd_power_on(struct fimd_context *ctx, bool enable)
+static int fimd_clock(struct fimd_context *ctx, bool enable)
 {
-	struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
-	struct device *dev = subdrv->dev;
-
 	DRM_DEBUG_KMS("%s\n", __FILE__);
 
-	if (enable != false && enable != true)
-		return -EINVAL;
-
 	if (enable) {
 		int ret;
 
@@ -769,18 +797,31 @@
 			clk_disable(ctx->bus_clk);
 			return ret;
 		}
+	} else {
+		clk_disable(ctx->lcd_clk);
+		clk_disable(ctx->bus_clk);
+	}
+
+	return 0;
+}
+
+static int fimd_activate(struct fimd_context *ctx, bool enable)
+{
+	if (enable) {
+		int ret;
+		struct device *dev = ctx->subdrv.dev;
+
+		ret = fimd_clock(ctx, true);
+		if (ret < 0)
+			return ret;
 
 		ctx->suspended = false;
 
 		/* if vblank was enabled status, enable it again. */
 		if (test_and_clear_bit(0, &ctx->irq_flags))
 			fimd_enable_vblank(dev);
-
-		fimd_apply(dev);
 	} else {
-		clk_disable(ctx->lcd_clk);
-		clk_disable(ctx->bus_clk);
-
+		fimd_clock(ctx, false);
 		ctx->suspended = true;
 	}
 
@@ -930,15 +971,15 @@
 {
 	struct fimd_context *ctx = get_fimd_context(dev);
 
-	if (pm_runtime_suspended(dev))
-		return 0;
-
 	/*
 	 * do not use pm_runtime_suspend(). if pm_runtime_suspend() is
 	 * called here, an error would be returned by that interface
 	 * because the usage_count of pm runtime is more than 1.
 	 */
-	return fimd_power_on(ctx, false);
+	if (!pm_runtime_suspended(dev))
+		return fimd_activate(ctx, false);
+
+	return 0;
 }
 
 static int fimd_resume(struct device *dev)
@@ -950,8 +991,21 @@
 	 * of pm runtime would still be 1 so in this case, fimd driver
 	 * should be on directly not drawing on pm runtime interface.
 	 */
-	if (!pm_runtime_suspended(dev))
-		return fimd_power_on(ctx, true);
+	if (pm_runtime_suspended(dev)) {
+		int ret;
+
+		ret = fimd_activate(ctx, true);
+		if (ret < 0)
+			return ret;
+
+		/*
+		 * in case of dpms on(standby), fimd_apply function will
+		 * be called by encoder's dpms callback to update fimd's
+		 * registers but in case of sleep wakeup, it's not.
+		 * so fimd_apply function should be called at here.
+		 */
+		fimd_apply(dev);
+	}
 
 	return 0;
 }
@@ -964,7 +1018,7 @@
 
 	DRM_DEBUG_KMS("%s\n", __FILE__);
 
-	return fimd_power_on(ctx, false);
+	return fimd_activate(ctx, false);
 }
 
 static int fimd_runtime_resume(struct device *dev)
@@ -973,10 +1027,22 @@
 
 	DRM_DEBUG_KMS("%s\n", __FILE__);
 
-	return fimd_power_on(ctx, true);
+	return fimd_activate(ctx, true);
 }
 #endif
 
+static struct platform_device_id fimd_driver_ids[] = {
+	{
+		.name		= "exynos4-fb",
+		.driver_data	= (unsigned long)&exynos4_fimd_driver_data,
+	}, {
+		.name		= "exynos5-fb",
+		.driver_data	= (unsigned long)&exynos5_fimd_driver_data,
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(platform, fimd_driver_ids);
+
 static const struct dev_pm_ops fimd_pm_ops = {
 	SET_SYSTEM_SLEEP_PM_OPS(fimd_suspend, fimd_resume)
 	SET_RUNTIME_PM_OPS(fimd_runtime_suspend, fimd_runtime_resume, NULL)
@@ -985,6 +1051,7 @@
 struct platform_driver fimd_driver = {
 	.probe		= fimd_probe,
 	.remove		= __devexit_p(fimd_remove),
+	.id_table       = fimd_driver_ids,
 	.driver		= {
 		.name	= "exynos4-fb",
 		.owner	= THIS_MODULE,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index bc2a2e9..f7aab24 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -122,6 +122,7 @@
 	struct list_head	list;
 	struct list_head	run_cmdlist;
 	struct list_head	event_list;
+	pid_t			pid;
 	struct completion	complete;
 	int			async;
 };
@@ -164,8 +165,7 @@
 		return -ENOMEM;
 	}
 
-	node = kcalloc(G2D_CMDLIST_NUM, G2D_CMDLIST_NUM * sizeof(*node),
-			GFP_KERNEL);
+	node = kcalloc(G2D_CMDLIST_NUM, sizeof(*node), GFP_KERNEL);
 	if (!node) {
 		dev_err(dev, "failed to allocate memory\n");
 		ret = -ENOMEM;
@@ -679,6 +679,7 @@
 	}
 
 	mutex_lock(&g2d->runqueue_mutex);
+	runqueue_node->pid = current->pid;
 	list_add_tail(&runqueue_node->list, &g2d->runqueue);
 	if (!g2d->runqueue_node)
 		g2d_exec_runqueue(g2d);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index fcdbe46..d254556 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -500,7 +500,7 @@
 
 	DRM_DEBUG_KMS("%s\n", __FILE__);
 
-	vma->vm_flags |= (VM_IO | VM_RESERVED);
+	vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
 
 	update_vm_cache_attr(exynos_gem_obj, vma);
 
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
index c3d3a5e..c3b9e2b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
@@ -29,6 +29,11 @@
 #define get_ctx_from_subdrv(subdrv)	container_of(subdrv,\
 					struct drm_hdmi_context, subdrv);
 
+/* Common hdmi subdrv needs to access the hdmi and mixer though context.
+* These should be initialied by the repective drivers */
+static struct exynos_drm_hdmi_context *hdmi_ctx;
+static struct exynos_drm_hdmi_context *mixer_ctx;
+
 /* these callback points shoud be set by specific drivers. */
 static struct exynos_hdmi_ops *hdmi_ops;
 static struct exynos_mixer_ops *mixer_ops;
@@ -41,6 +46,18 @@
 	bool	enabled[MIXER_WIN_NR];
 };
 
+void exynos_hdmi_drv_attach(struct exynos_drm_hdmi_context *ctx)
+{
+	if (ctx)
+		hdmi_ctx = ctx;
+}
+
+void exynos_mixer_drv_attach(struct exynos_drm_hdmi_context *ctx)
+{
+	if (ctx)
+		mixer_ctx = ctx;
+}
+
 void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops)
 {
 	DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -274,10 +291,21 @@
 	ctx->enabled[win] = false;
 }
 
+static void drm_mixer_wait_for_vblank(struct device *subdrv_dev)
+{
+	struct drm_hdmi_context *ctx = to_context(subdrv_dev);
+
+	DRM_DEBUG_KMS("%s\n", __FILE__);
+
+	if (mixer_ops && mixer_ops->wait_for_vblank)
+		mixer_ops->wait_for_vblank(ctx->mixer_ctx->ctx);
+}
+
 static struct exynos_drm_overlay_ops drm_hdmi_overlay_ops = {
 	.mode_set = drm_mixer_mode_set,
 	.commit = drm_mixer_commit,
 	.disable = drm_mixer_disable,
+	.wait_for_vblank = drm_mixer_wait_for_vblank,
 };
 
 static struct exynos_drm_manager hdmi_manager = {
@@ -292,46 +320,30 @@
 {
 	struct exynos_drm_subdrv *subdrv = to_subdrv(dev);
 	struct drm_hdmi_context *ctx;
-	struct platform_device *pdev = to_platform_device(dev);
-	struct exynos_drm_common_hdmi_pd *pd;
 
 	DRM_DEBUG_KMS("%s\n", __FILE__);
 
-	pd = pdev->dev.platform_data;
-
-	if (!pd) {
-		DRM_DEBUG_KMS("platform data is null.\n");
+	if (!hdmi_ctx) {
+		DRM_ERROR("hdmi context not initialized.\n");
 		return -EFAULT;
 	}
 
-	if (!pd->hdmi_dev) {
-		DRM_DEBUG_KMS("hdmi device is null.\n");
-		return -EFAULT;
-	}
-
-	if (!pd->mixer_dev) {
-		DRM_DEBUG_KMS("mixer device is null.\n");
+	if (!mixer_ctx) {
+		DRM_ERROR("mixer context not initialized.\n");
 		return -EFAULT;
 	}
 
 	ctx = get_ctx_from_subdrv(subdrv);
 
-	ctx->hdmi_ctx = (struct exynos_drm_hdmi_context *)
-				to_context(pd->hdmi_dev);
-	if (!ctx->hdmi_ctx) {
-		DRM_DEBUG_KMS("hdmi context is null.\n");
+	if (!ctx) {
+		DRM_ERROR("no drm hdmi context.\n");
 		return -EFAULT;
 	}
 
+	ctx->hdmi_ctx = hdmi_ctx;
+	ctx->mixer_ctx = mixer_ctx;
+
 	ctx->hdmi_ctx->drm_dev = drm_dev;
-
-	ctx->mixer_ctx = (struct exynos_drm_hdmi_context *)
-				to_context(pd->mixer_dev);
-	if (!ctx->mixer_ctx) {
-		DRM_DEBUG_KMS("mixer context is null.\n");
-		return -EFAULT;
-	}
-
 	ctx->mixer_ctx->drm_dev = drm_dev;
 
 	return 0;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
index a91c420..2da5ffd 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
@@ -67,11 +67,14 @@
 	void (*dpms)(void *ctx, int mode);
 
 	/* overlay */
+	void (*wait_for_vblank)(void *ctx);
 	void (*win_mode_set)(void *ctx, struct exynos_drm_overlay *overlay);
 	void (*win_commit)(void *ctx, int zpos);
 	void (*win_disable)(void *ctx, int zpos);
 };
 
+void exynos_hdmi_drv_attach(struct exynos_drm_hdmi_context *ctx);
+void exynos_mixer_drv_attach(struct exynos_drm_hdmi_context *ctx);
 void exynos_hdmi_ops_register(struct exynos_hdmi_ops *ops);
 void exynos_mixer_ops_register(struct exynos_mixer_ops *ops);
 #endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index 03b472b..60b877a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -32,6 +32,42 @@
 	DRM_FORMAT_NV12MT,
 };
 
+/*
+ * This function is to get X or Y size shown via screen. This needs length and
+ * start position of CRTC.
+ *
+ *      <--- length --->
+ * CRTC ----------------
+ *      ^ start        ^ end
+ *
+ * There are six cases from a to b.
+ *
+ *             <----- SCREEN ----->
+ *             0                 last
+ *   ----------|------------------|----------
+ * CRTCs
+ * a -------
+ *        b -------
+ *        c --------------------------
+ *                 d --------
+ *                           e -------
+ *                                  f -------
+ */
+static int exynos_plane_get_size(int start, unsigned length, unsigned last)
+{
+	int end = start + length;
+	int size = 0;
+
+	if (start <= 0) {
+		if (end > 0)
+			size = min_t(unsigned, end, last);
+	} else if (start <= last) {
+		size = min_t(unsigned, last - start, length);
+	}
+
+	return size;
+}
+
 int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
 			  struct drm_framebuffer *fb, int crtc_x, int crtc_y,
 			  unsigned int crtc_w, unsigned int crtc_h,
@@ -47,7 +83,7 @@
 
 	DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
 
-	nr = exynos_drm_format_num_buffers(fb->pixel_format);
+	nr = exynos_drm_fb_get_buf_cnt(fb);
 	for (i = 0; i < nr; i++) {
 		struct exynos_drm_gem_buf *buffer = exynos_drm_fb_buffer(fb, i);
 
@@ -64,8 +100,24 @@
 				(unsigned long)overlay->dma_addr[i]);
 	}
 
-	actual_w = min((unsigned)(crtc->mode.hdisplay - crtc_x), crtc_w);
-	actual_h = min((unsigned)(crtc->mode.vdisplay - crtc_y), crtc_h);
+	actual_w = exynos_plane_get_size(crtc_x, crtc_w, crtc->mode.hdisplay);
+	actual_h = exynos_plane_get_size(crtc_y, crtc_h, crtc->mode.vdisplay);
+
+	if (crtc_x < 0) {
+		if (actual_w)
+			src_x -= crtc_x;
+		else
+			src_x += crtc_w;
+		crtc_x = 0;
+	}
+
+	if (crtc_y < 0) {
+		if (actual_h)
+			src_y -= crtc_y;
+		else
+			src_y += crtc_h;
+		crtc_y = 0;
+	}
 
 	/* set drm framebuffer data. */
 	overlay->fb_x = src_x;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
index 8fe431a..e4b8a8f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -56,6 +56,7 @@
 	unsigned int			connected;
 	bool				vblank_on;
 	bool				suspended;
+	bool				direct_vblank;
 	struct work_struct		work;
 	struct mutex			lock;
 };
@@ -224,6 +225,15 @@
 	if (!test_and_set_bit(0, &ctx->irq_flags))
 		ctx->vblank_on = true;
 
+	ctx->direct_vblank = true;
+
+	/*
+	 * in case of page flip request, vidi_finish_pageflip function
+	 * will not be called because direct_vblank is true and then
+	 * that function will be called by overlay_ops->commit callback
+	 */
+	schedule_work(&ctx->work);
+
 	return 0;
 }
 
@@ -425,7 +435,17 @@
 	/* refresh rate is about 50Hz. */
 	usleep_range(16000, 20000);
 
-	drm_handle_vblank(subdrv->drm_dev, manager->pipe);
+	mutex_lock(&ctx->lock);
+
+	if (ctx->direct_vblank) {
+		drm_handle_vblank(subdrv->drm_dev, manager->pipe);
+		ctx->direct_vblank = false;
+		mutex_unlock(&ctx->lock);
+		return;
+	}
+
+	mutex_unlock(&ctx->lock);
+
 	vidi_finish_pageflip(subdrv->drm_dev, manager->pipe);
 }
 
@@ -453,7 +473,7 @@
 	return 0;
 }
 
-static void vidi_subdrv_remove(struct drm_device *drm_dev)
+static void vidi_subdrv_remove(struct drm_device *drm_dev, struct device *dev)
 {
 	DRM_DEBUG_KMS("%s\n", __FILE__);
 
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index e1c5395..2c115f8 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -32,6 +32,9 @@
 #include <linux/pm_runtime.h>
 #include <linux/clk.h>
 #include <linux/regulator/consumer.h>
+#include <linux/io.h>
+#include <linux/of_gpio.h>
+#include <plat/gpio-cfg.h>
 
 #include <drm/exynos_drm.h>
 
@@ -40,10 +43,18 @@
 
 #include "exynos_hdmi.h"
 
+#include <linux/gpio.h>
+#include <media/s5p_hdmi.h>
+
 #define MAX_WIDTH		1920
 #define MAX_HEIGHT		1080
 #define get_hdmi_context(dev)	platform_get_drvdata(to_platform_device(dev))
 
+enum hdmi_type {
+	HDMI_TYPE13,
+	HDMI_TYPE14,
+};
+
 struct hdmi_resources {
 	struct clk			*hdmi;
 	struct clk			*sclk_hdmi;
@@ -59,13 +70,12 @@
 	struct drm_device		*drm_dev;
 	bool				hpd;
 	bool				powered;
-	bool				is_v13;
 	bool				dvi_mode;
 	struct mutex			hdmi_mutex;
 
 	void __iomem			*regs;
-	unsigned int			external_irq;
-	unsigned int			internal_irq;
+	int				external_irq;
+	int				internal_irq;
 
 	struct i2c_client		*ddc_port;
 	struct i2c_client		*hdmiphy_port;
@@ -76,8 +86,9 @@
 	struct hdmi_resources		res;
 	void				*parent_ctx;
 
-	void				(*cfg_hpd)(bool external);
-	int				(*get_hpd)(void);
+	int				hpd_gpio;
+
+	enum hdmi_type			type;
 };
 
 /* HDMI Version 1.3 */
@@ -1209,7 +1220,7 @@
 
 static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix)
 {
-	if (hdata->is_v13)
+	if (hdata->type == HDMI_TYPE13)
 		hdmi_v13_regs_dump(hdata, prefix);
 	else
 		hdmi_v14_regs_dump(hdata, prefix);
@@ -1250,7 +1261,7 @@
 static int hdmi_conf_index(struct hdmi_context *hdata,
 			   struct drm_display_mode *mode)
 {
-	if (hdata->is_v13)
+	if (hdata->type == HDMI_TYPE13)
 		return hdmi_v13_conf_index(mode);
 
 	return hdmi_v14_conf_index(mode);
@@ -1346,7 +1357,7 @@
 			check_timing->yres, check_timing->refresh,
 			check_timing->vmode);
 
-	if (hdata->is_v13)
+	if (hdata->type == HDMI_TYPE13)
 		return hdmi_v13_check_timing(check_timing);
 	else
 		return hdmi_v14_check_timing(check_timing);
@@ -1412,7 +1423,7 @@
 	hdmi_reg_writeb(hdata, HDMI_ACR_CTS1, acr[2]);
 	hdmi_reg_writeb(hdata, HDMI_ACR_CTS2, acr[1]);
 
-	if (hdata->is_v13)
+	if (hdata->type == HDMI_TYPE13)
 		hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 4);
 	else
 		hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
@@ -1516,7 +1527,7 @@
 {
 	u32 reg;
 
-	if (hdata->is_v13)
+	if (hdata->type == HDMI_TYPE13)
 		reg = HDMI_V13_CORE_RSTOUT;
 	else
 		reg = HDMI_CORE_RSTOUT;
@@ -1530,12 +1541,9 @@
 
 static void hdmi_conf_init(struct hdmi_context *hdata)
 {
-	/* enable HPD interrupts */
+	/* disable HPD interrupts */
 	hdmi_reg_writemask(hdata, HDMI_INTC_CON, 0, HDMI_INTC_EN_GLOBAL |
 		HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
-	mdelay(10);
-	hdmi_reg_writemask(hdata, HDMI_INTC_CON, ~0, HDMI_INTC_EN_GLOBAL |
-		HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
 
 	/* choose HDMI mode */
 	hdmi_reg_writemask(hdata, HDMI_MODE_SEL,
@@ -1551,7 +1559,7 @@
 				HDMI_VID_PREAMBLE_DIS | HDMI_GUARD_BAND_DIS);
 	}
 
-	if (hdata->is_v13) {
+	if (hdata->type == HDMI_TYPE13) {
 		/* choose bluescreen (fecal) color */
 		hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
 		hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
@@ -1833,7 +1841,7 @@
 
 static void hdmi_timing_apply(struct hdmi_context *hdata)
 {
-	if (hdata->is_v13)
+	if (hdata->type == HDMI_TYPE13)
 		hdmi_v13_timing_apply(hdata);
 	else
 		hdmi_v14_timing_apply(hdata);
@@ -1855,7 +1863,7 @@
 	if (hdata->hdmiphy_port)
 		i2c_master_send(hdata->hdmiphy_port, buffer, 2);
 
-	if (hdata->is_v13)
+	if (hdata->type == HDMI_TYPE13)
 		reg = HDMI_V13_PHY_RSTOUT;
 	else
 		reg = HDMI_PHY_RSTOUT;
@@ -1882,7 +1890,7 @@
 	}
 
 	/* pixel clock */
-	if (hdata->is_v13)
+	if (hdata->type == HDMI_TYPE13)
 		hdmiphy_data = hdmi_v13_confs[hdata->cur_conf].hdmiphy_data;
 	else
 		hdmiphy_data = hdmi_confs[hdata->cur_conf].hdmiphy_data;
@@ -1950,7 +1958,7 @@
 
 	drm_mode_set_crtcinfo(adjusted_mode, 0);
 
-	if (hdata->is_v13)
+	if (hdata->type == HDMI_TYPE13)
 		index = hdmi_v13_conf_index(adjusted_mode);
 	else
 		index = hdmi_v14_conf_index(adjusted_mode);
@@ -1964,7 +1972,7 @@
 	 * to adjusted_mode.
 	 */
 	list_for_each_entry(m, &connector->modes, head) {
-		if (hdata->is_v13)
+		if (hdata->type == HDMI_TYPE13)
 			index = hdmi_v13_conf_index(m);
 		else
 			index = hdmi_v14_conf_index(m);
@@ -2024,8 +2032,6 @@
 
 	hdata->powered = true;
 
-	if (hdata->cfg_hpd)
-		hdata->cfg_hpd(true);
 	mutex_unlock(&hdata->hdmi_mutex);
 
 	pm_runtime_get_sync(hdata->dev);
@@ -2061,8 +2067,6 @@
 	pm_runtime_put_sync(hdata->dev);
 
 	mutex_lock(&hdata->hdmi_mutex);
-	if (hdata->cfg_hpd)
-		hdata->cfg_hpd(false);
 
 	hdata->powered = false;
 
@@ -2110,17 +2114,13 @@
 	struct exynos_drm_hdmi_context *ctx = arg;
 	struct hdmi_context *hdata = ctx->ctx;
 
-	if (!hdata->get_hpd)
-		goto out;
-
 	mutex_lock(&hdata->hdmi_mutex);
-	hdata->hpd = hdata->get_hpd();
+	hdata->hpd = gpio_get_value(hdata->hpd_gpio);
 	mutex_unlock(&hdata->hdmi_mutex);
 
 	if (ctx->drm_dev)
 		drm_helper_hpd_irq_event(ctx->drm_dev);
 
-out:
 	return IRQ_HANDLED;
 }
 
@@ -2143,18 +2143,9 @@
 			HDMI_INTC_FLAG_HPD_PLUG);
 	}
 
-	mutex_lock(&hdata->hdmi_mutex);
-	hdata->hpd = hdmi_reg_read(hdata, HDMI_HPD_STATUS);
-	if (hdata->powered && hdata->hpd) {
-		mutex_unlock(&hdata->hdmi_mutex);
-		goto out;
-	}
-	mutex_unlock(&hdata->hdmi_mutex);
-
 	if (ctx->drm_dev)
 		drm_helper_hpd_irq_event(ctx->drm_dev);
 
-out:
 	return IRQ_HANDLED;
 }
 
@@ -2262,18 +2253,89 @@
 		hdmi_hdmiphy = hdmiphy;
 }
 
+#ifdef CONFIG_OF
+static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
+					(struct device *dev)
+{
+	struct device_node *np = dev->of_node;
+	struct s5p_hdmi_platform_data *pd;
+	enum of_gpio_flags flags;
+	u32 value;
+
+	pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
+	if (!pd) {
+		DRM_ERROR("memory allocation for pdata failed\n");
+		goto err_data;
+	}
+
+	if (!of_find_property(np, "hpd-gpio", &value)) {
+		DRM_ERROR("no hpd gpio property found\n");
+		goto err_data;
+	}
+
+	pd->hpd_gpio = of_get_named_gpio_flags(np, "hpd-gpio", 0, &flags);
+
+	return pd;
+
+err_data:
+	return NULL;
+}
+#else
+static struct s5p_hdmi_platform_data *drm_hdmi_dt_parse_pdata
+					(struct device *dev)
+{
+	return NULL;
+}
+#endif
+
+static struct platform_device_id hdmi_driver_types[] = {
+	{
+		.name		= "s5pv210-hdmi",
+		.driver_data    = HDMI_TYPE13,
+	}, {
+		.name		= "exynos4-hdmi",
+		.driver_data    = HDMI_TYPE13,
+	}, {
+		.name		= "exynos4-hdmi14",
+		.driver_data	= HDMI_TYPE14,
+	}, {
+		.name		= "exynos5-hdmi",
+		.driver_data	= HDMI_TYPE14,
+	}, {
+		/* end node */
+	}
+};
+
+static struct of_device_id hdmi_match_types[] = {
+	{
+		.compatible = "samsung,exynos5-hdmi",
+		.data	= (void	*)HDMI_TYPE14,
+	}, {
+		/* end node */
+	}
+};
+
 static int __devinit hdmi_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct exynos_drm_hdmi_context *drm_hdmi_ctx;
 	struct hdmi_context *hdata;
-	struct exynos_drm_hdmi_pdata *pdata;
+	struct s5p_hdmi_platform_data *pdata;
 	struct resource *res;
 	int ret;
 
 	DRM_DEBUG_KMS("[%d]\n", __LINE__);
 
-	pdata = pdev->dev.platform_data;
+	if (pdev->dev.of_node) {
+		pdata = drm_hdmi_dt_parse_pdata(dev);
+		if (IS_ERR(pdata)) {
+			DRM_ERROR("failed to parse dt\n");
+			return PTR_ERR(pdata);
+		}
+	} else {
+		pdata = pdev->dev.platform_data;
+	}
+
 	if (!pdata) {
 		DRM_ERROR("no platform data specified\n");
 		return -EINVAL;
@@ -2300,18 +2362,33 @@
 
 	platform_set_drvdata(pdev, drm_hdmi_ctx);
 
-	hdata->is_v13 = pdata->is_v13;
-	hdata->cfg_hpd = pdata->cfg_hpd;
-	hdata->get_hpd = pdata->get_hpd;
+	if (dev->of_node) {
+		const struct of_device_id *match;
+		match = of_match_node(of_match_ptr(hdmi_match_types),
+					pdev->dev.of_node);
+		hdata->type = (enum hdmi_type)match->data;
+	} else {
+		hdata->type = (enum hdmi_type)platform_get_device_id
+					(pdev)->driver_data;
+	}
+
+	hdata->hpd_gpio = pdata->hpd_gpio;
 	hdata->dev = dev;
 
 	ret = hdmi_resources_init(hdata);
+
 	if (ret) {
 		ret = -EINVAL;
+		DRM_ERROR("hdmi_resources_init failed\n");
 		goto err_data;
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		DRM_ERROR("failed to find registers\n");
+		ret = -ENOENT;
+		goto err_resource;
+	}
 
 	hdata->regs = devm_request_and_ioremap(&pdev->dev, res);
 	if (!hdata->regs) {
@@ -2320,11 +2397,17 @@
 		goto err_resource;
 	}
 
+	ret = gpio_request(hdata->hpd_gpio, "HPD");
+	if (ret) {
+		DRM_ERROR("failed to request HPD gpio\n");
+		goto err_resource;
+	}
+
 	/* DDC i2c driver */
 	if (i2c_add_driver(&ddc_driver)) {
 		DRM_ERROR("failed to register ddc i2c driver\n");
 		ret = -ENOENT;
-		goto err_resource;
+		goto err_gpio;
 	}
 
 	hdata->ddc_port = hdmi_ddc;
@@ -2338,32 +2421,31 @@
 
 	hdata->hdmiphy_port = hdmi_hdmiphy;
 
-	hdata->external_irq = platform_get_irq_byname(pdev, "external_irq");
+	hdata->external_irq = gpio_to_irq(hdata->hpd_gpio);
 	if (hdata->external_irq < 0) {
-		DRM_ERROR("failed to get platform irq\n");
+		DRM_ERROR("failed to get GPIO external irq\n");
 		ret = hdata->external_irq;
 		goto err_hdmiphy;
 	}
 
-	hdata->internal_irq = platform_get_irq_byname(pdev, "internal_irq");
+	hdata->internal_irq = platform_get_irq(pdev, 0);
 	if (hdata->internal_irq < 0) {
 		DRM_ERROR("failed to get platform internal irq\n");
 		ret = hdata->internal_irq;
 		goto err_hdmiphy;
 	}
 
+	hdata->hpd = gpio_get_value(hdata->hpd_gpio);
+
 	ret = request_threaded_irq(hdata->external_irq, NULL,
 			hdmi_external_irq_thread, IRQF_TRIGGER_RISING |
 			IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 			"hdmi_external", drm_hdmi_ctx);
 	if (ret) {
-		DRM_ERROR("failed to register hdmi internal interrupt\n");
+		DRM_ERROR("failed to register hdmi external interrupt\n");
 		goto err_hdmiphy;
 	}
 
-	if (hdata->cfg_hpd)
-		hdata->cfg_hpd(false);
-
 	ret = request_threaded_irq(hdata->internal_irq, NULL,
 			hdmi_internal_irq_thread, IRQF_ONESHOT,
 			"hdmi_internal", drm_hdmi_ctx);
@@ -2372,6 +2454,9 @@
 		goto err_free_irq;
 	}
 
+	/* Attach HDMI Driver to common hdmi. */
+	exynos_hdmi_drv_attach(drm_hdmi_ctx);
+
 	/* register specific callbacks to common hdmi. */
 	exynos_hdmi_ops_register(&hdmi_ops);
 
@@ -2385,6 +2470,8 @@
 	i2c_del_driver(&hdmiphy_driver);
 err_ddc:
 	i2c_del_driver(&ddc_driver);
+err_gpio:
+	gpio_free(hdata->hpd_gpio);
 err_resource:
 	hdmi_resources_cleanup(hdata);
 err_data:
@@ -2402,6 +2489,9 @@
 	pm_runtime_disable(dev);
 
 	free_irq(hdata->internal_irq, hdata);
+	free_irq(hdata->external_irq, hdata);
+
+	gpio_free(hdata->hpd_gpio);
 
 	hdmi_resources_cleanup(hdata);
 
@@ -2447,9 +2537,11 @@
 struct platform_driver hdmi_driver = {
 	.probe		= hdmi_probe,
 	.remove		= __devexit_p(hdmi_remove),
+	.id_table = hdmi_driver_types,
 	.driver		= {
-		.name	= "exynos4-hdmi",
+		.name	= "exynos-hdmi",
 		.owner	= THIS_MODULE,
 		.pm	= &hdmi_pm_ops,
+		.of_match_table = hdmi_match_types,
 	},
 };
diff --git a/drivers/gpu/drm/exynos/exynos_hdmiphy.c b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
index 0a8162b..27d1720 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmiphy.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmiphy.c
@@ -42,13 +42,23 @@
 
 static const struct i2c_device_id hdmiphy_id[] = {
 	{ "s5p_hdmiphy", 0 },
+	{ "exynos5-hdmiphy", 0 },
 	{ },
 };
 
+static struct of_device_id hdmiphy_match_types[] = {
+	{
+		.compatible = "samsung,exynos5-hdmiphy",
+	}, {
+		/* end node */
+	}
+};
+
 struct i2c_driver hdmiphy_driver = {
 	.driver = {
-		.name	= "s5p-hdmiphy",
+		.name	= "exynos-hdmiphy",
 		.owner	= THIS_MODULE,
+		.of_match_table = hdmiphy_match_types,
 	},
 	.id_table = hdmiphy_id,
 	.probe		= hdmiphy_probe,
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index e6098f2..614b2e9 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -73,16 +73,28 @@
 	struct clk		*sclk_dac;
 };
 
+enum mixer_version_id {
+	MXR_VER_0_0_0_16,
+	MXR_VER_16_0_33_0,
+};
+
 struct mixer_context {
 	struct device		*dev;
 	int			pipe;
 	bool			interlace;
 	bool			powered;
+	bool			vp_enabled;
 	u32			int_en;
 
 	struct mutex		mixer_mutex;
 	struct mixer_resources	mixer_res;
 	struct hdmi_win_data	win_data[MIXER_WIN_NR];
+	enum mixer_version_id	mxr_ver;
+};
+
+struct mixer_drv_data {
+	enum mixer_version_id	version;
+	bool					is_vp_enabled;
 };
 
 static const u8 filter_y_horiz_tap8[] = {
@@ -251,7 +263,8 @@
 	mixer_reg_writemask(res, MXR_STATUS, enable ?
 			MXR_STATUS_SYNC_ENABLE : 0, MXR_STATUS_SYNC_ENABLE);
 
-	vp_reg_write(res, VP_SHADOW_UPDATE, enable ?
+	if (ctx->vp_enabled)
+		vp_reg_write(res, VP_SHADOW_UPDATE, enable ?
 			VP_SHADOW_UPDATE_ENABLE : 0);
 }
 
@@ -333,8 +346,11 @@
 		mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP1_ENABLE);
 		break;
 	case 2:
-		vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON);
-		mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_VP_ENABLE);
+		if (ctx->vp_enabled) {
+			vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON);
+			mixer_reg_writemask(res, MXR_CFG, val,
+				MXR_CFG_VP_ENABLE);
+		}
 		break;
 	}
 }
@@ -465,6 +481,18 @@
 	vp_regs_dump(ctx);
 }
 
+static void mixer_layer_update(struct mixer_context *ctx)
+{
+	struct mixer_resources *res = &ctx->mixer_res;
+	u32 val;
+
+	val = mixer_reg_read(res, MXR_CFG);
+
+	/* allow one update per vsync only */
+	if (!(val & MXR_CFG_LAYER_UPDATE_COUNT_MASK))
+		mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE);
+}
+
 static void mixer_graph_buffer(struct mixer_context *ctx, int win)
 {
 	struct mixer_resources *res = &ctx->mixer_res;
@@ -545,6 +573,11 @@
 	mixer_cfg_scan(ctx, win_data->mode_height);
 	mixer_cfg_rgb_fmt(ctx, win_data->mode_height);
 	mixer_cfg_layer(ctx, win, true);
+
+	/* layer update mandatory for mixer 16.0.33.0 */
+	if (ctx->mxr_ver == MXR_VER_16_0_33_0)
+		mixer_layer_update(ctx);
+
 	mixer_run(ctx);
 
 	mixer_vsync_set_update(ctx, true);
@@ -592,7 +625,8 @@
 	 */
 	val = MXR_LAYER_CFG_GRP1_VAL(3);
 	val |= MXR_LAYER_CFG_GRP0_VAL(2);
-	val |= MXR_LAYER_CFG_VP_VAL(1);
+	if (ctx->vp_enabled)
+		val |= MXR_LAYER_CFG_VP_VAL(1);
 	mixer_reg_write(res, MXR_LAYER_CFG, val);
 
 	/* setting background color */
@@ -615,14 +649,17 @@
 	val = MXR_GRP_CFG_ALPHA_VAL(0);
 	mixer_reg_write(res, MXR_VIDEO_CFG, val);
 
-	/* configuration of Video Processor Registers */
-	vp_win_reset(ctx);
-	vp_default_filter(res);
+	if (ctx->vp_enabled) {
+		/* configuration of Video Processor Registers */
+		vp_win_reset(ctx);
+		vp_default_filter(res);
+	}
 
 	/* disable all layers */
 	mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP0_ENABLE);
 	mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP1_ENABLE);
-	mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE);
+	if (ctx->vp_enabled)
+		mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE);
 
 	mixer_vsync_set_update(ctx, true);
 	spin_unlock_irqrestore(&res->reg_slock, flags);
@@ -645,8 +682,10 @@
 	pm_runtime_get_sync(ctx->dev);
 
 	clk_enable(res->mixer);
-	clk_enable(res->vp);
-	clk_enable(res->sclk_mixer);
+	if (ctx->vp_enabled) {
+		clk_enable(res->vp);
+		clk_enable(res->sclk_mixer);
+	}
 
 	mixer_reg_write(res, MXR_INT_EN, ctx->int_en);
 	mixer_win_reset(ctx);
@@ -666,8 +705,10 @@
 	ctx->int_en = mixer_reg_read(res, MXR_INT_EN);
 
 	clk_disable(res->mixer);
-	clk_disable(res->vp);
-	clk_disable(res->sclk_mixer);
+	if (ctx->vp_enabled) {
+		clk_disable(res->vp);
+		clk_disable(res->sclk_mixer);
+	}
 
 	pm_runtime_put_sync(ctx->dev);
 
@@ -726,6 +767,18 @@
 	}
 }
 
+static void mixer_wait_for_vblank(void *ctx)
+{
+	struct mixer_context *mixer_ctx = ctx;
+	struct mixer_resources *res = &mixer_ctx->mixer_res;
+	int ret;
+
+	ret = wait_for((mixer_reg_read(res, MXR_INT_STATUS) &
+				MXR_INT_STATUS_VSYNC), 50);
+	if (ret < 0)
+		DRM_DEBUG_KMS("vblank wait timed out.\n");
+}
+
 static void mixer_win_mode_set(void *ctx,
 			      struct exynos_drm_overlay *overlay)
 {
@@ -788,7 +841,7 @@
 
 	DRM_DEBUG_KMS("[%d] %s, win: %d\n", __LINE__, __func__, win);
 
-	if (win > 1)
+	if (win > 1 && mixer_ctx->vp_enabled)
 		vp_video_buffer(mixer_ctx, win);
 	else
 		mixer_graph_buffer(mixer_ctx, win);
@@ -818,6 +871,7 @@
 	.dpms			= mixer_dpms,
 
 	/* overlay */
+	.wait_for_vblank	= mixer_wait_for_vblank,
 	.win_mode_set		= mixer_win_mode_set,
 	.win_commit		= mixer_win_commit,
 	.win_disable		= mixer_win_disable,
@@ -923,39 +977,20 @@
 		ret = -ENODEV;
 		goto fail;
 	}
-	mixer_res->vp = clk_get(dev, "vp");
-	if (IS_ERR_OR_NULL(mixer_res->vp)) {
-		dev_err(dev, "failed to get clock 'vp'\n");
-		ret = -ENODEV;
-		goto fail;
-	}
-	mixer_res->sclk_mixer = clk_get(dev, "sclk_mixer");
-	if (IS_ERR_OR_NULL(mixer_res->sclk_mixer)) {
-		dev_err(dev, "failed to get clock 'sclk_mixer'\n");
-		ret = -ENODEV;
-		goto fail;
-	}
+
 	mixer_res->sclk_hdmi = clk_get(dev, "sclk_hdmi");
 	if (IS_ERR_OR_NULL(mixer_res->sclk_hdmi)) {
 		dev_err(dev, "failed to get clock 'sclk_hdmi'\n");
 		ret = -ENODEV;
 		goto fail;
 	}
-	mixer_res->sclk_dac = clk_get(dev, "sclk_dac");
-	if (IS_ERR_OR_NULL(mixer_res->sclk_dac)) {
-		dev_err(dev, "failed to get clock 'sclk_dac'\n");
-		ret = -ENODEV;
-		goto fail;
-	}
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mxr");
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (res == NULL) {
 		dev_err(dev, "get memory resource failed.\n");
 		ret = -ENXIO;
 		goto fail;
 	}
 
-	clk_set_parent(mixer_res->sclk_mixer, mixer_res->sclk_hdmi);
-
 	mixer_res->mixer_regs = devm_ioremap(&pdev->dev, res->start,
 							resource_size(res));
 	if (mixer_res->mixer_regs == NULL) {
@@ -964,22 +999,7 @@
 		goto fail;
 	}
 
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vp");
-	if (res == NULL) {
-		dev_err(dev, "get memory resource failed.\n");
-		ret = -ENXIO;
-		goto fail;
-	}
-
-	mixer_res->vp_regs = devm_ioremap(&pdev->dev, res->start,
-							resource_size(res));
-	if (mixer_res->vp_regs == NULL) {
-		dev_err(dev, "register mapping failed.\n");
-		ret = -ENXIO;
-		goto fail;
-	}
-
-	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq");
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (res == NULL) {
 		dev_err(dev, "get interrupt resource failed.\n");
 		ret = -ENXIO;
@@ -997,24 +1017,108 @@
 	return 0;
 
 fail:
-	if (!IS_ERR_OR_NULL(mixer_res->sclk_dac))
-		clk_put(mixer_res->sclk_dac);
 	if (!IS_ERR_OR_NULL(mixer_res->sclk_hdmi))
 		clk_put(mixer_res->sclk_hdmi);
-	if (!IS_ERR_OR_NULL(mixer_res->sclk_mixer))
-		clk_put(mixer_res->sclk_mixer);
-	if (!IS_ERR_OR_NULL(mixer_res->vp))
-		clk_put(mixer_res->vp);
 	if (!IS_ERR_OR_NULL(mixer_res->mixer))
 		clk_put(mixer_res->mixer);
 	return ret;
 }
 
+static int __devinit vp_resources_init(struct exynos_drm_hdmi_context *ctx,
+				 struct platform_device *pdev)
+{
+	struct mixer_context *mixer_ctx = ctx->ctx;
+	struct device *dev = &pdev->dev;
+	struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
+	struct resource *res;
+	int ret;
+
+	mixer_res->vp = clk_get(dev, "vp");
+	if (IS_ERR_OR_NULL(mixer_res->vp)) {
+		dev_err(dev, "failed to get clock 'vp'\n");
+		ret = -ENODEV;
+		goto fail;
+	}
+	mixer_res->sclk_mixer = clk_get(dev, "sclk_mixer");
+	if (IS_ERR_OR_NULL(mixer_res->sclk_mixer)) {
+		dev_err(dev, "failed to get clock 'sclk_mixer'\n");
+		ret = -ENODEV;
+		goto fail;
+	}
+	mixer_res->sclk_dac = clk_get(dev, "sclk_dac");
+	if (IS_ERR_OR_NULL(mixer_res->sclk_dac)) {
+		dev_err(dev, "failed to get clock 'sclk_dac'\n");
+		ret = -ENODEV;
+		goto fail;
+	}
+
+	if (mixer_res->sclk_hdmi)
+		clk_set_parent(mixer_res->sclk_mixer, mixer_res->sclk_hdmi);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (res == NULL) {
+		dev_err(dev, "get memory resource failed.\n");
+		ret = -ENXIO;
+		goto fail;
+	}
+
+	mixer_res->vp_regs = devm_ioremap(&pdev->dev, res->start,
+							resource_size(res));
+	if (mixer_res->vp_regs == NULL) {
+		dev_err(dev, "register mapping failed.\n");
+		ret = -ENXIO;
+		goto fail;
+	}
+
+	return 0;
+
+fail:
+	if (!IS_ERR_OR_NULL(mixer_res->sclk_dac))
+		clk_put(mixer_res->sclk_dac);
+	if (!IS_ERR_OR_NULL(mixer_res->sclk_mixer))
+		clk_put(mixer_res->sclk_mixer);
+	if (!IS_ERR_OR_NULL(mixer_res->vp))
+		clk_put(mixer_res->vp);
+	return ret;
+}
+
+static struct mixer_drv_data exynos5_mxr_drv_data = {
+	.version = MXR_VER_16_0_33_0,
+	.is_vp_enabled = 0,
+};
+
+static struct mixer_drv_data exynos4_mxr_drv_data = {
+	.version = MXR_VER_0_0_0_16,
+	.is_vp_enabled = 1,
+};
+
+static struct platform_device_id mixer_driver_types[] = {
+	{
+		.name		= "s5p-mixer",
+		.driver_data	= (unsigned long)&exynos4_mxr_drv_data,
+	}, {
+		.name		= "exynos5-mixer",
+		.driver_data	= (unsigned long)&exynos5_mxr_drv_data,
+	}, {
+		/* end node */
+	}
+};
+
+static struct of_device_id mixer_match_types[] = {
+	{
+		.compatible = "samsung,exynos5-mixer",
+		.data	= &exynos5_mxr_drv_data,
+	}, {
+		/* end node */
+	}
+};
+
 static int __devinit mixer_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct exynos_drm_hdmi_context *drm_hdmi_ctx;
 	struct mixer_context *ctx;
+	struct mixer_drv_data *drv;
 	int ret;
 
 	dev_info(dev, "probe start\n");
@@ -1034,15 +1138,41 @@
 
 	mutex_init(&ctx->mixer_mutex);
 
+	if (dev->of_node) {
+		const struct of_device_id *match;
+		match = of_match_node(of_match_ptr(mixer_match_types),
+							  pdev->dev.of_node);
+		drv = match->data;
+	} else {
+		drv = (struct mixer_drv_data *)
+			platform_get_device_id(pdev)->driver_data;
+	}
+
 	ctx->dev = &pdev->dev;
 	drm_hdmi_ctx->ctx = (void *)ctx;
+	ctx->vp_enabled = drv->is_vp_enabled;
+	ctx->mxr_ver = drv->version;
 
 	platform_set_drvdata(pdev, drm_hdmi_ctx);
 
 	/* acquire resources: regs, irqs, clocks */
 	ret = mixer_resources_init(drm_hdmi_ctx, pdev);
-	if (ret)
+	if (ret) {
+		DRM_ERROR("mixer_resources_init failed\n");
 		goto fail;
+	}
+
+	if (ctx->vp_enabled) {
+		/* acquire vp resources: regs, irqs, clocks */
+		ret = vp_resources_init(drm_hdmi_ctx, pdev);
+		if (ret) {
+			DRM_ERROR("vp_resources_init failed\n");
+			goto fail;
+		}
+	}
+
+	/* attach mixer driver to common hdmi. */
+	exynos_mixer_drv_attach(drm_hdmi_ctx);
 
 	/* register specific callback point to common hdmi. */
 	exynos_mixer_ops_register(&mixer_ops);
@@ -1082,10 +1212,12 @@
 
 struct platform_driver mixer_driver = {
 	.driver = {
-		.name = "s5p-mixer",
+		.name = "exynos-mixer",
 		.owner = THIS_MODULE,
 		.pm = &mixer_pm_ops,
+		.of_match_table = mixer_match_types,
 	},
 	.probe = mixer_probe,
 	.remove = __devexit_p(mixer_remove),
+	.id_table	= mixer_driver_types,
 };
diff --git a/drivers/gpu/drm/exynos/regs-mixer.h b/drivers/gpu/drm/exynos/regs-mixer.h
index fd2f4d1..5d8dbc0 100644
--- a/drivers/gpu/drm/exynos/regs-mixer.h
+++ b/drivers/gpu/drm/exynos/regs-mixer.h
@@ -69,6 +69,7 @@
 	(((val) << (low_bit)) & MXR_MASK(high_bit, low_bit))
 
 /* bits for MXR_STATUS */
+#define MXR_STATUS_SOFT_RESET		(1 << 8)
 #define MXR_STATUS_16_BURST		(1 << 7)
 #define MXR_STATUS_BURST_MASK		(1 << 7)
 #define MXR_STATUS_BIG_ENDIAN		(1 << 3)
@@ -77,6 +78,8 @@
 #define MXR_STATUS_REG_RUN		(1 << 0)
 
 /* bits for MXR_CFG */
+#define MXR_CFG_LAYER_UPDATE		(1 << 31)
+#define MXR_CFG_LAYER_UPDATE_COUNT_MASK (3 << 29)
 #define MXR_CFG_RGB601_0_255		(0 << 9)
 #define MXR_CFG_RGB601_16_235		(1 << 9)
 #define MXR_CFG_RGB709_0_255		(2 << 9)
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
index 884ba73..afded54 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -178,8 +178,7 @@
 	 */
 	vma->vm_ops = &psbfb_vm_ops;
 	vma->vm_private_data = (void *)psbfb;
-	vma->vm_flags |= VM_RESERVED | VM_IO |
-					VM_MIXEDMAP | VM_DONTEXPAND;
+	vma->vm_flags |= VM_IO | VM_MIXEDMAP | VM_DONTEXPAND | VM_DONTDUMP;
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index e957f37..19dbdd7 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1399,10 +1399,16 @@
 	case 0:
 	case -ERESTARTSYS:
 	case -EINTR:
+	case -EBUSY:
+		/*
+		 * EBUSY is ok: this just means that another thread
+		 * already did the job.
+		 */
 		return VM_FAULT_NOPAGE;
 	case -ENOMEM:
 		return VM_FAULT_OOM;
 	default:
+		WARN_ON_ONCE(ret);
 		return VM_FAULT_SIGBUS;
 	}
 }
@@ -3217,10 +3223,6 @@
 	enum i915_cache_level level;
 	int ret;
 
-	ret = i915_mutex_lock_interruptible(dev);
-	if (ret)
-		return ret;
-
 	switch (args->caching) {
 	case I915_CACHING_NONE:
 		level = I915_CACHE_NONE;
@@ -3232,6 +3234,10 @@
 		return -EINVAL;
 	}
 
+	ret = i915_mutex_lock_interruptible(dev);
+	if (ret)
+		return ret;
+
 	obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
 	if (&obj->base == NULL) {
 		ret = -ENOENT;
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 1eb48fa..05ed42f 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -328,7 +328,7 @@
 	 * itlb_before_ctx_switch.
 	 */
 	if (IS_GEN6(ring->dev) && ring->itlb_before_ctx_switch) {
-		ret = ring->flush(ring, 0, 0);
+		ret = ring->flush(ring, I915_GEM_GPU_DOMAINS, 0);
 		if (ret)
 			return ret;
 	}
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index 3208650..cedbfd7 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -91,7 +91,10 @@
 	uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
 	uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
 
-	if (INTEL_INFO(dev)->gen >= 6) {
+	if (IS_VALLEYVIEW(dev)) {
+		swizzle_x = I915_BIT_6_SWIZZLE_NONE;
+		swizzle_y = I915_BIT_6_SWIZZLE_NONE;
+	} else if (INTEL_INFO(dev)->gen >= 6) {
 		uint32_t dimm_c0, dimm_c1;
 		dimm_c0 = I915_READ(MAD_DIMM_C0);
 		dimm_c1 = I915_READ(MAD_DIMM_C1);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 4e98883..32e1bda 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -697,12 +697,12 @@
 			intel_opregion_gse_intr(dev);
 
 		for (i = 0; i < 3; i++) {
+			if (de_iir & (DE_PIPEA_VBLANK_IVB << (5 * i)))
+				drm_handle_vblank(dev, i);
 			if (de_iir & (DE_PLANEA_FLIP_DONE_IVB << (5 * i))) {
 				intel_prepare_page_flip(dev, i);
 				intel_finish_page_flip_plane(dev, i);
 			}
-			if (de_iir & (DE_PIPEA_VBLANK_IVB << (5 * i)))
-				drm_handle_vblank(dev, i);
 		}
 
 		/* check event from PCH */
@@ -784,6 +784,12 @@
 	if (de_iir & DE_GSE)
 		intel_opregion_gse_intr(dev);
 
+	if (de_iir & DE_PIPEA_VBLANK)
+		drm_handle_vblank(dev, 0);
+
+	if (de_iir & DE_PIPEB_VBLANK)
+		drm_handle_vblank(dev, 1);
+
 	if (de_iir & DE_PLANEA_FLIP_DONE) {
 		intel_prepare_page_flip(dev, 0);
 		intel_finish_page_flip_plane(dev, 0);
@@ -794,12 +800,6 @@
 		intel_finish_page_flip_plane(dev, 1);
 	}
 
-	if (de_iir & DE_PIPEA_VBLANK)
-		drm_handle_vblank(dev, 0);
-
-	if (de_iir & DE_PIPEB_VBLANK)
-		drm_handle_vblank(dev, 1);
-
 	/* check event from PCH */
 	if (de_iir & DE_PCH_EVENT) {
 		if (pch_iir & hotplug_mask)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 7637824c..64c1be0 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -527,6 +527,9 @@
 # define VS_TIMER_DISPATCH				(1 << 6)
 # define MI_FLUSH_ENABLE				(1 << 12)
 
+#define GEN6_GT_MODE	0x20d0
+#define   GEN6_GT_MODE_HI	(1 << 9)
+
 #define GFX_MODE	0x02520
 #define GFX_MODE_GEN7	0x0229c
 #define RING_MODE_GEN7(ring)	((ring)->mmio_base+0x29c)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index e3c0265..2b6ce9b 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2806,13 +2806,34 @@
 	udelay(100);
 }
 
+static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned long flags;
+	bool pending;
+
+	if (atomic_read(&dev_priv->mm.wedged))
+		return false;
+
+	spin_lock_irqsave(&dev->event_lock, flags);
+	pending = to_intel_crtc(crtc)->unpin_work != NULL;
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+
+	return pending;
+}
+
 static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 
 	if (crtc->fb == NULL)
 		return;
 
+	wait_event(dev_priv->pending_flip_queue,
+		   !intel_crtc_has_pending_flip(crtc));
+
 	mutex_lock(&dev->struct_mutex);
 	intel_finish_fb(crtc->fb);
 	mutex_unlock(&dev->struct_mutex);
@@ -4370,7 +4391,7 @@
 	/* default to 8bpc */
 	pipeconf &= ~(PIPECONF_BPP_MASK | PIPECONF_DITHER_EN);
 	if (is_dp) {
-		if (mode->private_flags & INTEL_MODE_DP_FORCE_6BPC) {
+		if (adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC) {
 			pipeconf |= PIPECONF_BPP_6 |
 				    PIPECONF_DITHER_EN |
 				    PIPECONF_DITHER_TYPE_SP;
@@ -4802,7 +4823,8 @@
 		target_clock = adjusted_mode->clock;
 
 	/* determine panel color depth */
-	dither = intel_choose_pipe_bpp_dither(crtc, fb, &pipe_bpp, mode);
+	dither = intel_choose_pipe_bpp_dither(crtc, fb, &pipe_bpp,
+					      adjusted_mode);
 	if (is_lvds && dev_priv->lvds_dither)
 		dither = true;
 
@@ -6159,15 +6181,13 @@
 	struct intel_unpin_work *work;
 	struct drm_i915_gem_object *obj;
 	struct drm_pending_vblank_event *e;
-	struct timeval tnow, tvbl;
+	struct timeval tvbl;
 	unsigned long flags;
 
 	/* Ignore early vblank irqs */
 	if (intel_crtc == NULL)
 		return;
 
-	do_gettimeofday(&tnow);
-
 	spin_lock_irqsave(&dev->event_lock, flags);
 	work = intel_crtc->unpin_work;
 	if (work == NULL || !work->pending) {
@@ -6181,25 +6201,6 @@
 		e = work->event;
 		e->event.sequence = drm_vblank_count_and_time(dev, intel_crtc->pipe, &tvbl);
 
-		/* Called before vblank count and timestamps have
-		 * been updated for the vblank interval of flip
-		 * completion? Need to increment vblank count and
-		 * add one videorefresh duration to returned timestamp
-		 * to account for this. We assume this happened if we
-		 * get called over 0.9 frame durations after the last
-		 * timestamped vblank.
-		 *
-		 * This calculation can not be used with vrefresh rates
-		 * below 5Hz (10Hz to be on the safe side) without
-		 * promoting to 64 integers.
-		 */
-		if (10 * (timeval_to_ns(&tnow) - timeval_to_ns(&tvbl)) >
-		    9 * crtc->framedur_ns) {
-			e->event.sequence++;
-			tvbl = ns_to_timeval(timeval_to_ns(&tvbl) +
-					     crtc->framedur_ns);
-		}
-
 		e->event.tv_sec = tvbl.tv_sec;
 		e->event.tv_usec = tvbl.tv_usec;
 
@@ -6216,9 +6217,8 @@
 
 	atomic_clear_mask(1 << intel_crtc->plane,
 			  &obj->pending_flip.counter);
-	if (atomic_read(&obj->pending_flip) == 0)
-		wake_up(&dev_priv->pending_flip_queue);
 
+	wake_up(&dev_priv->pending_flip_queue);
 	schedule_work(&work->work);
 
 	trace_i915_flip_complete(intel_crtc->plane, work->pending_flip_obj);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 6c8746c..d1e8ddb 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -36,6 +36,7 @@
 #include <drm/i915_drm.h>
 #include "i915_drv.h"
 
+#define DP_RECEIVER_CAP_SIZE	0xf
 #define DP_LINK_STATUS_SIZE	6
 #define DP_LINK_CHECK_TIMEOUT	(10 * 1000)
 
@@ -1796,8 +1797,7 @@
 			if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
 				break;
 		if (i == intel_dp->lane_count && voltage_tries == 5) {
-			++loop_tries;
-			if (loop_tries == 5) {
+			if (++loop_tries == 5) {
 				DRM_DEBUG_KMS("too many full retries, give up\n");
 				break;
 			}
@@ -1807,15 +1807,11 @@
 		}
 
 		/* Check to see if we've tried the same voltage 5 times */
-		if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
-			++voltage_tries;
-			if (voltage_tries == 5) {
-				DRM_DEBUG_KMS("too many voltage retries, give up\n");
-				break;
-			}
-		} else
+		if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) != voltage) {
+			voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
 			voltage_tries = 0;
-		voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
+		} else
+			++voltage_tries;
 
 		/* Compute new intel_dp->train_set as requested by target */
 		intel_get_adjust_train(intel_dp, link_status);
@@ -1963,12 +1959,25 @@
 intel_dp_get_dpcd(struct intel_dp *intel_dp)
 {
 	if (intel_dp_aux_native_read_retry(intel_dp, 0x000, intel_dp->dpcd,
-					   sizeof(intel_dp->dpcd)) &&
-	    (intel_dp->dpcd[DP_DPCD_REV] != 0)) {
-		return true;
-	}
+					   sizeof(intel_dp->dpcd)) == 0)
+		return false; /* aux transfer failed */
 
-	return false;
+	if (intel_dp->dpcd[DP_DPCD_REV] == 0)
+		return false; /* DPCD not present */
+
+	if (!(intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] &
+	      DP_DWN_STRM_PORT_PRESENT))
+		return true; /* native DP sink */
+
+	if (intel_dp->dpcd[DP_DPCD_REV] == 0x10)
+		return true; /* no per-port downstream info */
+
+	if (intel_dp_aux_native_read_retry(intel_dp, DP_DOWNSTREAM_PORT_0,
+					   intel_dp->downstream_ports,
+					   DP_MAX_DOWNSTREAM_PORTS) == 0)
+		return false; /* downstream port status fetch failed */
+
+	return true;
 }
 
 static void
@@ -2068,11 +2077,43 @@
 	}
 }
 
+/* XXX this is probably wrong for multiple downstream ports */
 static enum drm_connector_status
 intel_dp_detect_dpcd(struct intel_dp *intel_dp)
 {
-	if (intel_dp_get_dpcd(intel_dp))
+	uint8_t *dpcd = intel_dp->dpcd;
+	bool hpd;
+	uint8_t type;
+
+	if (!intel_dp_get_dpcd(intel_dp))
+		return connector_status_disconnected;
+
+	/* if there's no downstream port, we're done */
+	if (!(dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT))
 		return connector_status_connected;
+
+	/* If we're HPD-aware, SINK_COUNT changes dynamically */
+	hpd = !!(intel_dp->downstream_ports[0] & DP_DS_PORT_HPD);
+	if (hpd) {
+		uint8_t reg;
+		if (!intel_dp_aux_native_read_retry(intel_dp, DP_SINK_COUNT,
+						    &reg, 1))
+			return connector_status_unknown;
+		return DP_GET_SINK_COUNT(reg) ? connector_status_connected
+					      : connector_status_disconnected;
+	}
+
+	/* If no HPD, poke DDC gently */
+	if (drm_probe_ddc(&intel_dp->adapter))
+		return connector_status_connected;
+
+	/* Well we tried, say unknown for unreliable port types */
+	type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK;
+	if (type == DP_DS_PORT_TYPE_VGA || type == DP_DS_PORT_TYPE_NON_EDID)
+		return connector_status_unknown;
+
+	/* Anything else is out of spec, warn and ignore */
+	DRM_DEBUG_KMS("Broken DP branch device, ignoring\n");
 	return connector_status_disconnected;
 }
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 05cc7c3..fe71425 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -332,6 +332,7 @@
 };
 
 #define DP_RECEIVER_CAP_SIZE		0xf
+#define DP_MAX_DOWNSTREAM_PORTS		0x10
 #define DP_LINK_CONFIGURATION_SIZE	9
 
 struct intel_dp {
@@ -346,6 +347,7 @@
 	uint8_t link_bw;
 	uint8_t lane_count;
 	uint8_t dpcd[DP_RECEIVER_CAP_SIZE];
+	uint8_t downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
 	struct i2c_adapter adapter;
 	struct i2c_algo_dp_aux_data algo;
 	bool is_pch_edp;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index d69f8f4..b3b4b6c 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3474,6 +3474,11 @@
 			   DISPPLANE_TRICKLE_FEED_DISABLE);
 		intel_flush_display_plane(dev_priv, pipe);
 	}
+
+	/* The default value should be 0x200 according to docs, but the two
+	 * platforms I checked have a 0 for this. (Maybe BIOS overrides?) */
+	I915_WRITE(GEN6_GT_MODE, _MASKED_BIT_DISABLE(0xffff));
+	I915_WRITE(GEN6_GT_MODE, _MASKED_BIT_ENABLE(GEN6_GT_MODE_HI));
 }
 
 static void gen7_setup_fixed_func_scheduler(struct drm_i915_private *dev_priv)
diff --git a/drivers/gpu/drm/nouveau/core/core/parent.c b/drivers/gpu/drm/nouveau/core/core/parent.c
index a1ea034..db7c549 100644
--- a/drivers/gpu/drm/nouveau/core/core/parent.c
+++ b/drivers/gpu/drm/nouveau/core/core/parent.c
@@ -101,23 +101,6 @@
 	return 0;
 }
 
-int
-_nouveau_parent_ctor(struct nouveau_object *parent,
-		     struct nouveau_object *engine,
-		     struct nouveau_oclass *oclass, void *data, u32 size,
-		     struct nouveau_object **pobject)
-{
-	struct nouveau_parent *object;
-	int ret;
-
-	ret = nouveau_parent_create(parent, engine, oclass, 0, NULL, 0, &object);
-	*pobject = nv_object(object);
-	if (ret)
-		return ret;
-
-	return 0;
-}
-
 void
 nouveau_parent_destroy(struct nouveau_parent *parent)
 {
diff --git a/drivers/gpu/drm/nouveau/core/include/core/parent.h b/drivers/gpu/drm/nouveau/core/include/core/parent.h
index d3aa251..3c2e940 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/parent.h
+++ b/drivers/gpu/drm/nouveau/core/include/core/parent.h
@@ -50,9 +50,6 @@
 			    int size, void **);
 void nouveau_parent_destroy(struct nouveau_parent *);
 
-int  _nouveau_parent_ctor(struct nouveau_object *, struct nouveau_object *,
-			  struct nouveau_oclass *, void *, u32,
-			  struct nouveau_object **);
 void _nouveau_parent_dtor(struct nouveau_object *);
 #define _nouveau_parent_init _nouveau_object_init
 #define _nouveau_parent_fini _nouveau_object_fini
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/timer.h b/drivers/gpu/drm/nouveau/core/include/subdev/timer.h
index 49bff90..c24ec8a 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/timer.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/timer.h
@@ -26,7 +26,7 @@
 struct nouveau_timer {
 	struct nouveau_subdev base;
 	u64  (*read)(struct nouveau_timer *);
-	void (*alarm)(struct nouveau_timer *, u32 time, struct nouveau_alarm *);
+	void (*alarm)(struct nouveau_timer *, u64 time, struct nouveau_alarm *);
 };
 
 static inline struct nouveau_timer *
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
index 2fbb6df..dcb5c2b 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
@@ -185,23 +185,22 @@
 nouveau_bios_shadow_acpi(struct nouveau_bios *bios)
 {
 	struct pci_dev *pdev = nv_device(bios)->pdev;
-	int cnt = 65536 / 4096;
-	int ret;
+	int ret, cnt, i;
+	u8  data[3];
 
 	if (!nouveau_acpi_rom_supported(pdev))
 		return;
 
-	bios->data = kmalloc(65536, GFP_KERNEL);
 	bios->size = 0;
-	if (!bios->data)
-		return;
+	if (nouveau_acpi_get_bios_chunk(data, 0, 3) == 3)
+		bios->size = data[2] * 512;
 
-	while (cnt--) {
-		ret = nouveau_acpi_get_bios_chunk(bios->data, bios->size, 4096);
-		if (ret != 4096)
-			return;
-
-		bios->size += 4096;
+	bios->data = kmalloc(bios->size, GFP_KERNEL);
+	for (i = 0; bios->data && i < bios->size; i += cnt) {
+		cnt = min((bios->size - i), (u32)4096);
+		ret = nouveau_acpi_get_bios_chunk(bios->data, i, cnt);
+		if (ret != cnt)
+			break;
 	}
 }
 
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c
index fd181fb..f4147f6 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c
@@ -90,6 +90,7 @@
 		return ret;
 
 	priv->base.pll_set = nv50_clock_pll_set;
+	priv->base.pll_calc = nv04_clock_pll_calc;
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c
index f87a7a3..9360ddd 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nv50.c
@@ -92,7 +92,7 @@
 		if (nv_rd32(therm, 0xc040) & 0x800000) {
 			/* Use the HOST clock (100 MHz)
 			* Where does this constant(2.4) comes from? */
-			pwm_clock = (100000000 >> pwm_div) / 10 / 24;
+			pwm_clock = (100000000 >> pwm_div) * 10 / 24;
 		} else {
 			/* Where does this constant(20) comes from? */
 			pwm_clock = (crystal * 1000) >> pwm_div;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c
index 49976be..c26ca9b 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c
@@ -85,7 +85,7 @@
 }
 
 static void
-nv04_timer_alarm(struct nouveau_timer *ptimer, u32 time,
+nv04_timer_alarm(struct nouveau_timer *ptimer, u64 time,
 		 struct nouveau_alarm *alarm)
 {
 	struct nv04_timer_priv *priv = (void *)ptimer;
diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c
index a877813..3ba72db 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_vm.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c
@@ -285,7 +285,7 @@
 	 */
 
 	vma->vm_private_data = bo;
-	vma->vm_flags |= VM_RESERVED | VM_IO | VM_MIXEDMAP | VM_DONTEXPAND;
+	vma->vm_flags |= VM_IO | VM_MIXEDMAP | VM_DONTEXPAND | VM_DONTDUMP;
 	return 0;
 out_unref:
 	ttm_bo_unref(&bo);
@@ -300,7 +300,7 @@
 
 	vma->vm_ops = &ttm_bo_vm_ops;
 	vma->vm_private_data = ttm_bo_reference(bo);
-	vma->vm_flags |= VM_RESERVED | VM_IO | VM_MIXEDMAP | VM_DONTEXPAND;
+	vma->vm_flags |= VM_IO | VM_MIXEDMAP | VM_DONTEXPAND;
 	return 0;
 }
 EXPORT_SYMBOL(ttm_fbdev_mmap);
diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c
index 67df842..69a2b16 100644
--- a/drivers/gpu/drm/udl/udl_fb.c
+++ b/drivers/gpu/drm/udl/udl_fb.c
@@ -243,7 +243,7 @@
 			size = 0;
 	}
 
-	vma->vm_flags |= VM_RESERVED;	/* avoid to swap out this VMA */
+	/* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
 	return 0;
 }
 
diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c
index 23ab3c4..1672e2a 100644
--- a/drivers/hwmon/acpi_power_meter.c
+++ b/drivers/hwmon/acpi_power_meter.c
@@ -29,6 +29,7 @@
 #include <linux/kdev_t.h>
 #include <linux/sched.h>
 #include <linux/time.h>
+#include <linux/err.h>
 #include <acpi/acpi_drivers.h>
 #include <acpi/acpi_bus.h>
 
diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c
index 8b24d1a..dafa477 100644
--- a/drivers/hwmon/adm9240.c
+++ b/drivers/hwmon/adm9240.c
@@ -50,6 +50,7 @@
 #include <linux/hwmon-vid.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
+#include <linux/jiffies.h>
 
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
diff --git a/drivers/hwmon/adt7411.c b/drivers/hwmon/adt7411.c
index fe72c69..517f185 100644
--- a/drivers/hwmon/adt7411.c
+++ b/drivers/hwmon/adt7411.c
@@ -15,7 +15,6 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/err.h>
-#include <linux/delay.h>
 #include <linux/mutex.h>
 #include <linux/jiffies.h>
 #include <linux/i2c.h>
diff --git a/drivers/hwmon/adt7462.c b/drivers/hwmon/adt7462.c
index baee482..98a7d81 100644
--- a/drivers/hwmon/adt7462.c
+++ b/drivers/hwmon/adt7462.c
@@ -26,7 +26,6 @@
 #include <linux/hwmon-sysfs.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
-#include <linux/delay.h>
 #include <linux/log2.h>
 #include <linux/slab.h>
 
diff --git a/drivers/hwmon/adt7475.c b/drivers/hwmon/adt7475.c
index 861c756..989e54c 100644
--- a/drivers/hwmon/adt7475.c
+++ b/drivers/hwmon/adt7475.c
@@ -20,6 +20,7 @@
 #include <linux/hwmon-sysfs.h>
 #include <linux/hwmon-vid.h>
 #include <linux/err.h>
+#include <linux/jiffies.h>
 
 /* Indexes for the sysfs hooks */
 
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index 8f3f6f2..b41baff 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -43,6 +43,7 @@
 #include <linux/leds.h>
 #include <linux/hwmon.h>
 #include <linux/workqueue.h>
+#include <linux/err.h>
 
 /* data port used by Apple SMC */
 #define APPLESMC_DATA_PORT	0x300
diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c
index cccb0e9..56dbcfb 100644
--- a/drivers/hwmon/asus_atk0110.c
+++ b/drivers/hwmon/asus_atk0110.c
@@ -14,6 +14,8 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/dmi.h>
+#include <linux/jiffies.h>
+#include <linux/err.h>
 
 #include <acpi/acpi.h>
 #include <acpi/acpixf.h>
diff --git a/drivers/hwmon/da9052-hwmon.c b/drivers/hwmon/da9052-hwmon.c
index fc65f2d..b8d01c5 100644
--- a/drivers/hwmon/da9052-hwmon.c
+++ b/drivers/hwmon/da9052-hwmon.c
@@ -12,7 +12,6 @@
  *
  */
 
-#include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c
index 68ab94b..142e1cb 100644
--- a/drivers/hwmon/emc1403.c
+++ b/drivers/hwmon/emc1403.c
@@ -33,6 +33,7 @@
 #include <linux/err.h>
 #include <linux/sysfs.h>
 #include <linux/mutex.h>
+#include <linux/jiffies.h>
 
 #define THERMAL_PID_REG		0xfd
 #define THERMAL_SMSC_ID_REG	0xfe
diff --git a/drivers/hwmon/emc6w201.c b/drivers/hwmon/emc6w201.c
index ada12a9..a98c917 100644
--- a/drivers/hwmon/emc6w201.c
+++ b/drivers/hwmon/emc6w201.c
@@ -18,7 +18,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/jiffies.h>
diff --git a/drivers/hwmon/hih6130.c b/drivers/hwmon/hih6130.c
index e8ee75f..9a675ef 100644
--- a/drivers/hwmon/hih6130.c
+++ b/drivers/hwmon/hih6130.c
@@ -33,6 +33,7 @@
 #include <linux/mutex.h>
 #include <linux/device.h>
 #include <linux/delay.h>
+#include <linux/jiffies.h>
 
 /**
  * struct hih6130 - HIH-6130 device specific data
diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c
index a18882c..46141ab 100644
--- a/drivers/hwmon/i5k_amb.c
+++ b/drivers/hwmon/i5k_amb.c
@@ -21,12 +21,10 @@
  */
 
 #include <linux/module.h>
-#include <linux/jiffies.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
-#include <linux/delay.h>
 #include <linux/log2.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c
index 37f17e0..a14f634 100644
--- a/drivers/hwmon/ibmaem.c
+++ b/drivers/hwmon/ibmaem.c
@@ -36,6 +36,7 @@
 #include <linux/platform_device.h>
 #include <linux/math64.h>
 #include <linux/time.h>
+#include <linux/err.h>
 
 #define REFRESH_INTERVAL	(HZ)
 #define IPMI_TIMEOUT		(30 * HZ)
diff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c
index 41dbf81..b622a93 100644
--- a/drivers/hwmon/ibmpex.c
+++ b/drivers/hwmon/ibmpex.c
@@ -26,6 +26,7 @@
 #include <linux/jiffies.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
+#include <linux/err.h>
 
 #define REFRESH_INTERVAL	(2 * HZ)
 #define DRVNAME			"ibmpex"
diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c
index 70717d4..2b72634 100644
--- a/drivers/hwmon/ina2xx.c
+++ b/drivers/hwmon/ina2xx.c
@@ -33,6 +33,7 @@
 #include <linux/i2c.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
+#include <linux/jiffies.h>
 
 #include <linux/platform_data/ina2xx.h>
 
diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c
index 49a69c5..e8c7fb0 100644
--- a/drivers/hwmon/k8temp.c
+++ b/drivers/hwmon/k8temp.c
@@ -22,7 +22,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/jiffies.h>
diff --git a/drivers/hwmon/lineage-pem.c b/drivers/hwmon/lineage-pem.c
index bd75d24..41df29f 100644
--- a/drivers/hwmon/lineage-pem.c
+++ b/drivers/hwmon/lineage-pem.c
@@ -29,6 +29,7 @@
 #include <linux/i2c.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
+#include <linux/jiffies.h>
 
 /*
  * This driver supports various Lineage Compact Power Line DC/DC and AC/DC
diff --git a/drivers/hwmon/lm92.c b/drivers/hwmon/lm92.c
index 2282d77..71626f3 100644
--- a/drivers/hwmon/lm92.c
+++ b/drivers/hwmon/lm92.c
@@ -48,6 +48,7 @@
 #include <linux/hwmon-sysfs.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
+#include <linux/jiffies.h>
 
 /*
  * The LM92 and MAX6635 have 2 two-state pins for address selection,
diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c
index c3d4255..1a003f7 100644
--- a/drivers/hwmon/lm93.c
+++ b/drivers/hwmon/lm93.c
@@ -47,6 +47,7 @@
 #include <linux/hwmon-vid.h>
 #include <linux/err.h>
 #include <linux/delay.h>
+#include <linux/jiffies.h>
 
 /* LM93 REGISTER ADDRESSES */
 
diff --git a/drivers/hwmon/ltc4151.c b/drivers/hwmon/ltc4151.c
index 8496baa..4319a94 100644
--- a/drivers/hwmon/ltc4151.c
+++ b/drivers/hwmon/ltc4151.c
@@ -36,6 +36,7 @@
 #include <linux/i2c.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
+#include <linux/jiffies.h>
 
 /* chip registers */
 #define LTC4151_SENSE_H	0x00
diff --git a/drivers/hwmon/ltc4215.c b/drivers/hwmon/ltc4215.c
index 98b3d04f..e887610 100644
--- a/drivers/hwmon/ltc4215.c
+++ b/drivers/hwmon/ltc4215.c
@@ -19,6 +19,7 @@
 #include <linux/i2c.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
+#include <linux/jiffies.h>
 
 /* Here are names of the chip's registers (a.k.a. commands) */
 enum ltc4215_cmd {
diff --git a/drivers/hwmon/ltc4245.c b/drivers/hwmon/ltc4245.c
index 52075914..3653f79 100644
--- a/drivers/hwmon/ltc4245.c
+++ b/drivers/hwmon/ltc4245.c
@@ -21,6 +21,7 @@
 #include <linux/i2c.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
+#include <linux/jiffies.h>
 #include <linux/i2c/ltc4245.h>
 
 /* Here are names of the chip's registers (a.k.a. commands) */
diff --git a/drivers/hwmon/ltc4261.c b/drivers/hwmon/ltc4261.c
index 77476a5..84a2d28 100644
--- a/drivers/hwmon/ltc4261.c
+++ b/drivers/hwmon/ltc4261.c
@@ -33,6 +33,7 @@
 #include <linux/i2c.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
+#include <linux/jiffies.h>
 
 /* chip registers */
 #define LTC4261_STATUS	0x00	/* readonly */
diff --git a/drivers/hwmon/max16065.c b/drivers/hwmon/max16065.c
index 019427d..e0019c6 100644
--- a/drivers/hwmon/max16065.c
+++ b/drivers/hwmon/max16065.c
@@ -22,7 +22,6 @@
 #include <linux/i2c.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
-#include <linux/delay.h>
 #include <linux/jiffies.h>
 
 enum chips { max16065, max16066, max16067, max16068, max16070, max16071 };
diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c
index 6c11ec2..445e5d4 100644
--- a/drivers/hwmon/max1619.c
+++ b/drivers/hwmon/max1619.c
@@ -1,7 +1,7 @@
 /*
  * max1619.c - Part of lm_sensors, Linux kernel modules for hardware
  *             monitoring
- * Copyright (C) 2003-2004 Alexey Fisher <fishor@mail.ru>
+ * Copyright (C) 2003-2004 Oleksij Rempel <bug-track@fisher-privat.net>
  *                         Jean Delvare <khali@linux-fr.org>
  *
  * Based on the lm90 driver. The MAX1619 is a sensor chip made by Maxim.
@@ -357,7 +357,7 @@
 
 module_i2c_driver(max1619_driver);
 
-MODULE_AUTHOR("Alexey Fisher <fishor@mail.ru> and "
+MODULE_AUTHOR("Oleksij Rempel <bug-track@fisher-privat.net> and "
 	"Jean Delvare <khali@linux-fr.org>");
 MODULE_DESCRIPTION("MAX1619 sensor driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/max6642.c b/drivers/hwmon/max6642.c
index bf236c0..223461a 100644
--- a/drivers/hwmon/max6642.c
+++ b/drivers/hwmon/max6642.c
@@ -7,7 +7,7 @@
  * Derived from:
  *
  *  Based on the max1619 driver.
- *  Copyright (C) 2003-2004 Alexey Fisher <fishor@mail.ru>
+ *  Copyright (C) 2003-2004 Oleksij Rempel <bug-track@fisher-privat.net>
  *                          Jean Delvare <khali@linux-fr.org>
  *
  * The MAX6642 is a sensor chip made by Maxim.
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index 29b319d..7d19b1b 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -26,7 +26,7 @@
 #include <linux/i2c.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
-#include <linux/delay.h>
+#include <linux/jiffies.h>
 #include <linux/i2c/pmbus.h>
 #include "pmbus.h"
 
diff --git a/drivers/hwmon/s3c-hwmon.c b/drivers/hwmon/s3c-hwmon.c
index fe11b95..bcecd02 100644
--- a/drivers/hwmon/s3c-hwmon.c
+++ b/drivers/hwmon/s3c-hwmon.c
@@ -22,7 +22,6 @@
 
 #include <linux/module.h>
 #include <linux/slab.h>
-#include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/init.h>
 #include <linux/err.h>
diff --git a/drivers/hwmon/sht21.c b/drivers/hwmon/sht21.c
index c2565d0..5f675469 100644
--- a/drivers/hwmon/sht21.c
+++ b/drivers/hwmon/sht21.c
@@ -29,6 +29,7 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/device.h>
+#include <linux/jiffies.h>
 
 /* I2C command bytes */
 #define SHT21_TRIG_T_MEASUREMENT_HM  0xe3
diff --git a/drivers/hwmon/smm665.c b/drivers/hwmon/smm665.c
index cbc51fb..d9e1b7d 100644
--- a/drivers/hwmon/smm665.c
+++ b/drivers/hwmon/smm665.c
@@ -24,6 +24,7 @@
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 #include <linux/delay.h>
+#include <linux/jiffies.h>
 
 /* Internal reference voltage (VREF, x 1000 */
 #define SMM665_VREF_ADC_X1000	1250
diff --git a/drivers/hwmon/thmc50.c b/drivers/hwmon/thmc50.c
index 080c263..3c2c48d 100644
--- a/drivers/hwmon/thmc50.c
+++ b/drivers/hwmon/thmc50.c
@@ -28,6 +28,7 @@
 #include <linux/hwmon-sysfs.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
+#include <linux/jiffies.h>
 
 MODULE_LICENSE("GPL");
 
diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c
index 4e1ff82..b8777e5 100644
--- a/drivers/hwmon/tmp102.c
+++ b/drivers/hwmon/tmp102.c
@@ -26,6 +26,7 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/device.h>
+#include <linux/jiffies.h>
 
 #define	DRIVER_NAME "tmp102"
 
diff --git a/drivers/hwmon/ultra45_env.c b/drivers/hwmon/ultra45_env.c
index c315c59..44136bb 100644
--- a/drivers/hwmon/ultra45_env.c
+++ b/drivers/hwmon/ultra45_env.c
@@ -12,6 +12,7 @@
 #include <linux/io.h>
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
 
 #define DRV_MODULE_VERSION	"0.1"
 
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c
index 93ea81a..39ab7bc 100644
--- a/drivers/hwmon/w83791d.c
+++ b/drivers/hwmon/w83791d.c
@@ -41,6 +41,7 @@
 #include <linux/hwmon-sysfs.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
+#include <linux/jiffies.h>
 
 #define NUMBER_OF_VIN		10
 #define NUMBER_OF_FANIN		5
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c
index 06d6f56..0536452 100644
--- a/drivers/hwmon/w83792d.c
+++ b/drivers/hwmon/w83792d.c
@@ -44,6 +44,7 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/sysfs.h>
+#include <linux/jiffies.h>
 
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c
index 4fc47e06..99799fd 100644
--- a/drivers/hwmon/w83793.c
+++ b/drivers/hwmon/w83793.c
@@ -46,6 +46,7 @@
 #include <linux/kref.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
+#include <linux/jiffies.h>
 
 /* Default values */
 #define WATCHDOG_TIMEOUT 2	/* 2 minute default timeout */
diff --git a/drivers/hwmon/w83795.c b/drivers/hwmon/w83795.c
index b813c64..55a4f48 100644
--- a/drivers/hwmon/w83795.c
+++ b/drivers/hwmon/w83795.c
@@ -34,7 +34,7 @@
 #include <linux/hwmon-sysfs.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
-#include <linux/delay.h>
+#include <linux/jiffies.h>
 
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = {
diff --git a/drivers/hwmon/w83l786ng.c b/drivers/hwmon/w83l786ng.c
index c99c8a0..f0e8286 100644
--- a/drivers/hwmon/w83l786ng.c
+++ b/drivers/hwmon/w83l786ng.c
@@ -33,6 +33,7 @@
 #include <linux/hwmon-sysfs.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
+#include <linux/jiffies.h>
 
 /* Addresses to scan */
 static const unsigned short normal_i2c[] = { 0x2e, 0x2f, I2C_CLIENT_END };
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index 5a3bb3d..2f8c76b 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -4,7 +4,7 @@
 
 menuconfig I2C
 	tristate "I2C support"
-	depends on HAS_IOMEM
+	depends on !S390
 	select RT_MUTEXES
 	---help---
 	  I2C (pronounce: I-squared-C) is a slow serial bus protocol used in
@@ -49,6 +49,7 @@
 
 config I2C_MUX
 	tristate "I2C bus multiplexing support"
+	depends on HAS_IOMEM
 	help
 	  Say Y here if you want the I2C core to support the ability to
 	  handle multiplexed I2C bus topologies, by presenting each
@@ -86,6 +87,19 @@
 source drivers/i2c/algos/Kconfig
 source drivers/i2c/busses/Kconfig
 
+config I2C_STUB
+	tristate "I2C/SMBus Test Stub"
+	depends on EXPERIMENTAL && m
+	default 'n'
+	help
+	  This module may be useful to developers of SMBus client drivers,
+	  especially for certain kinds of sensor chips.
+
+	  If you do build this module, be sure to read the notes and warnings
+	  in <file:Documentation/i2c/i2c-stub>.
+
+	  If you don't know what to do here, definitely say N.
+
 config I2C_DEBUG_CORE
 	bool "I2C Core debugging messages"
 	help
@@ -103,6 +117,7 @@
 
 config I2C_DEBUG_BUS
 	bool "I2C Bus debugging messages"
+	depends on HAS_IOMEM
 	help
 	  Say Y here if you want the I2C bus drivers to produce a bunch of
 	  debug messages to the system log.  Select this if you are having
diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c
index 6f5f98d..f892a42 100644
--- a/drivers/i2c/algos/i2c-algo-pca.c
+++ b/drivers/i2c/algos/i2c-algo-pca.c
@@ -46,14 +46,19 @@
 #define pca_set_con(adap, val) pca_outw(adap, I2C_PCA_CON, val)
 #define pca_get_con(adap) pca_inw(adap, I2C_PCA_CON)
 #define pca_wait(adap) adap->wait_for_completion(adap->data)
-#define pca_reset(adap) adap->reset_chip(adap->data)
 
-static void pca9665_reset(void *pd)
+static void pca_reset(struct i2c_algo_pca_data *adap)
 {
-	struct i2c_algo_pca_data *adap = pd;
-	pca_outw(adap, I2C_PCA_INDPTR, I2C_PCA_IPRESET);
-	pca_outw(adap, I2C_PCA_IND, 0xA5);
-	pca_outw(adap, I2C_PCA_IND, 0x5A);
+	if (adap->chip == I2C_PCA_CHIP_9665) {
+		/* Ignore the reset function from the module,
+		 * we can use the parallel bus reset.
+		 */
+		pca_outw(adap, I2C_PCA_INDPTR, I2C_PCA_IPRESET);
+		pca_outw(adap, I2C_PCA_IND, 0xA5);
+		pca_outw(adap, I2C_PCA_IND, 0x5A);
+	} else {
+		adap->reset_chip(adap->data);
+	}
 }
 
 /*
@@ -378,11 +383,12 @@
 	pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IADR);
 	if (pca_inw(pca_data, I2C_PCA_IND) == 0xAA) {
 		printk(KERN_INFO "%s: PCA9665 detected.\n", adap->name);
-		return I2C_PCA_CHIP_9665;
+		pca_data->chip = I2C_PCA_CHIP_9665;
 	} else {
 		printk(KERN_INFO "%s: PCA9564 detected.\n", adap->name);
-		return I2C_PCA_CHIP_9564;
+		pca_data->chip = I2C_PCA_CHIP_9564;
 	}
+	return pca_data->chip;
 }
 
 static int pca_init(struct i2c_adapter *adap)
@@ -456,11 +462,6 @@
 		 */
 		int raise_fall_time;
 
-		/* Ignore the reset function from the module,
-		 * we can use the parallel bus reset
-		 */
-		pca_data->reset_chip = pca9665_reset;
-
 		if (pca_data->i2c_clock > 1265800) {
 			printk(KERN_WARNING "%s: I2C clock speed too high."
 				" Using 1265.8kHz.\n", adap->name);
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 42d9fdd..65dd599 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -3,6 +3,7 @@
 #
 
 menu "I2C Hardware Bus support"
+	depends on HAS_IOMEM
 
 comment "PC SMBus host controller drivers"
 	depends on PCI
@@ -80,6 +81,7 @@
 	tristate "Intel 82801 (ICH/PCH)"
 	depends on PCI
 	select CHECK_SIGNATURE if X86 && DMI
+	select GPIOLIB if I2C_MUX
 	help
 	  If you say yes to this option, support will be included for the Intel
 	  801 family of mainboard I2C interfaces.  Specifically, the following
@@ -224,7 +226,7 @@
 	  will be called i2c-via.
 
 config I2C_VIAPRO
-	tristate "VIA VT82C596/82C686/82xx and CX700/VX8xx"
+	tristate "VIA VT82C596/82C686/82xx and CX700/VX8xx/VX900"
 	depends on PCI
 	help
 	  If you say yes to this option, support will be included for the VIA
@@ -240,6 +242,7 @@
 	    CX700
 	    VX800/VX820
 	    VX855/VX875
+	    VX900
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-viapro.
@@ -291,18 +294,21 @@
 
 config I2C_AT91
 	tristate "Atmel AT91 I2C Two-Wire interface (TWI)"
-	depends on ARCH_AT91 && EXPERIMENTAL && BROKEN
+	depends on ARCH_AT91 && EXPERIMENTAL
 	help
 	  This supports the use of the I2C interface on Atmel AT91
 	  processors.
 
-	  This driver is BROKEN because the controller which it uses
-	  will easily trigger RX overrun and TX underrun errors.  Using
-	  low I2C clock rates may partially work around those issues
-	  on some systems.  Another serious problem is that there is no
-	  documented way to issue repeated START conditions, as needed
+	  A serious problem is that there is no documented way to issue
+	  repeated START conditions for more than two messages, as needed
 	  to support combined I2C messages.  Use the i2c-gpio driver
-	  unless your system can cope with those limitations.
+	  unless your system can cope with this limitation.
+
+	  Caution! at91rm9200, at91sam9261, at91sam9260, at91sam9263 devices
+	  don't have clock stretching in transmission mode. For that reason,
+	  you can encounter underrun issues causing premature stop sendings if
+	  the latency to fill the transmission register is too long. If you
+	  are facing this situation, use the i2c-gpio driver.
 
 config I2C_AU1550
 	tristate "Au1550/Au1200/Au1300 SMBus interface"
@@ -715,6 +721,16 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-xlr.
 
+config I2C_RCAR
+	tristate "Renesas R-Car I2C Controller"
+	depends on ARCH_SHMOBILE && I2C
+	help
+	  If you say yes to this option, support will be included for the
+	  R-Car I2C controller.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-rcar.
+
 comment "External I2C/SMBus adapter drivers"
 
 config I2C_DIOLAN_U2C
@@ -849,19 +865,6 @@
 	help
 	  Supports the SiByte SOC on-chip I2C interfaces (2 channels).
 
-config I2C_STUB
-	tristate "I2C/SMBus Test Stub"
-	depends on EXPERIMENTAL && m
-	default 'n'
-	help
-	  This module may be useful to developers of SMBus client drivers,
-	  especially for certain kinds of sensor chips.
-
-	  If you do build this module, be sure to read the notes and warnings
-	  in <file:Documentation/i2c/i2c-stub>.
-
-	  If you don't know what to do here, definitely say N.
-
 config SCx200_I2C
 	tristate "NatSemi SCx200 I2C using GPIO pins (DEPRECATED)"
 	depends on SCx200_GPIO
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 37c4182..2d33d62 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -71,6 +71,7 @@
 obj-$(CONFIG_I2C_OCTEON)	+= i2c-octeon.o
 obj-$(CONFIG_I2C_XILINX)	+= i2c-xiic.o
 obj-$(CONFIG_I2C_XLR)		+= i2c-xlr.o
+obj-$(CONFIG_I2C_RCAR)		+= i2c-rcar.o
 
 # External I2C/SMBus adapter drivers
 obj-$(CONFIG_I2C_DIOLAN_U2C)	+= i2c-diolan-u2c.o
diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
index e24484b..aa59a25 100644
--- a/drivers/i2c/busses/i2c-at91.c
+++ b/drivers/i2c/busses/i2c-at91.c
@@ -1,315 +1,554 @@
 /*
-    i2c Support for Atmel's AT91 Two-Wire Interface (TWI)
-
-    Copyright (C) 2004 Rick Bronson
-    Converted to 2.6 by Andrew Victor <andrew@sanpeople.com>
-
-    Borrowed heavily from original work by:
-    Copyright (C) 2000 Philip Edelbrock <phil@stimpy.netroedge.com>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-*/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <mach/at91_twi.h>
-#include <mach/board.h>
-#include <mach/cpu.h>
-
-#define TWI_CLOCK		100000		/* Hz. max 400 Kbits/sec */
-
-
-static struct clk *twi_clk;
-static void __iomem *twi_base;
-
-#define at91_twi_read(reg)		__raw_readl(twi_base + (reg))
-#define at91_twi_write(reg, val)	__raw_writel((val), twi_base + (reg))
-
-
-/*
- * Initialize the TWI hardware registers.
- */
-static void __devinit at91_twi_hwinit(void)
-{
-	unsigned long cdiv, ckdiv;
-
-	at91_twi_write(AT91_TWI_IDR, 0xffffffff);	/* Disable all interrupts */
-	at91_twi_write(AT91_TWI_CR, AT91_TWI_SWRST);	/* Reset peripheral */
-	at91_twi_write(AT91_TWI_CR, AT91_TWI_MSEN);	/* Set Master mode */
-
-	/* Calcuate clock dividers */
-	cdiv = (clk_get_rate(twi_clk) / (2 * TWI_CLOCK)) - 3;
-	cdiv = cdiv + 1;	/* round up */
-	ckdiv = 0;
-	while (cdiv > 255) {
-		ckdiv++;
-		cdiv = cdiv >> 1;
-	}
-
-	if (cpu_is_at91rm9200()) {			/* AT91RM9200 Errata #22 */
-		if (ckdiv > 5) {
-			printk(KERN_ERR "AT91 I2C: Invalid TWI_CLOCK value!\n");
-			ckdiv = 5;
-		}
-	}
-
-	at91_twi_write(AT91_TWI_CWGR, (ckdiv << 16) | (cdiv << 8) | cdiv);
-}
-
-/*
- * Poll the i2c status register until the specified bit is set.
- * Returns 0 if timed out (100 msec).
- */
-static short at91_poll_status(unsigned long bit)
-{
-	int loop_cntr = 10000;
-
-	do {
-		udelay(10);
-	} while (!(at91_twi_read(AT91_TWI_SR) & bit) && (--loop_cntr > 0));
-
-	return (loop_cntr > 0);
-}
-
-static int xfer_read(struct i2c_adapter *adap, unsigned char *buf, int length)
-{
-	/* Send Start */
-	at91_twi_write(AT91_TWI_CR, AT91_TWI_START);
-
-	/* Read data */
-	while (length--) {
-		if (!length)	/* need to send Stop before reading last byte */
-			at91_twi_write(AT91_TWI_CR, AT91_TWI_STOP);
-		if (!at91_poll_status(AT91_TWI_RXRDY)) {
-			dev_dbg(&adap->dev, "RXRDY timeout\n");
-			return -ETIMEDOUT;
-		}
-		*buf++ = (at91_twi_read(AT91_TWI_RHR) & 0xff);
-	}
-
-	return 0;
-}
-
-static int xfer_write(struct i2c_adapter *adap, unsigned char *buf, int length)
-{
-	/* Load first byte into transmitter */
-	at91_twi_write(AT91_TWI_THR, *buf++);
-
-	/* Send Start */
-	at91_twi_write(AT91_TWI_CR, AT91_TWI_START);
-
-	do {
-		if (!at91_poll_status(AT91_TWI_TXRDY)) {
-			dev_dbg(&adap->dev, "TXRDY timeout\n");
-			return -ETIMEDOUT;
-		}
-
-		length--;	/* byte was transmitted */
-
-		if (length > 0)		/* more data to send? */
-			at91_twi_write(AT91_TWI_THR, *buf++);
-	} while (length);
-
-	/* Send Stop */
-	at91_twi_write(AT91_TWI_CR, AT91_TWI_STOP);
-
-	return 0;
-}
-
-/*
- * Generic i2c master transfer entrypoint.
+ *  i2c Support for Atmel's AT91 Two-Wire Interface (TWI)
  *
- * Note: We do not use Atmel's feature of storing the "internal device address".
- * Instead the "internal device address" has to be written using a separate
- * i2c message.
- * http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2004-September/024411.html
+ *  Copyright (C) 2011 Weinmann Medical GmbH
+ *  Author: Nikolaus Voss <n.voss@weinmann.de>
+ *
+ *  Evolved from original work by:
+ *  Copyright (C) 2004 Rick Bronson
+ *  Converted to 2.6 by Andrew Victor <andrew@sanpeople.com>
+ *
+ *  Borrowed heavily from original work by:
+ *  Copyright (C) 2000 Philip Edelbrock <phil@stimpy.netroedge.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
  */
-static int at91_xfer(struct i2c_adapter *adap, struct i2c_msg *pmsg, int num)
+
+#include <linux/clk.h>
+#include <linux/completion.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_i2c.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define TWI_CLK_HZ		100000			/* max 400 Kbits/s */
+#define AT91_I2C_TIMEOUT	msecs_to_jiffies(100)	/* transfer timeout */
+
+/* AT91 TWI register definitions */
+#define	AT91_TWI_CR		0x0000	/* Control Register */
+#define	AT91_TWI_START		0x0001	/* Send a Start Condition */
+#define	AT91_TWI_STOP		0x0002	/* Send a Stop Condition */
+#define	AT91_TWI_MSEN		0x0004	/* Master Transfer Enable */
+#define	AT91_TWI_SVDIS		0x0020	/* Slave Transfer Disable */
+#define	AT91_TWI_SWRST		0x0080	/* Software Reset */
+
+#define	AT91_TWI_MMR		0x0004	/* Master Mode Register */
+#define	AT91_TWI_IADRSZ_1	0x0100	/* Internal Device Address Size */
+#define	AT91_TWI_MREAD		0x1000	/* Master Read Direction */
+
+#define	AT91_TWI_IADR		0x000c	/* Internal Address Register */
+
+#define	AT91_TWI_CWGR		0x0010	/* Clock Waveform Generator Reg */
+
+#define	AT91_TWI_SR		0x0020	/* Status Register */
+#define	AT91_TWI_TXCOMP		0x0001	/* Transmission Complete */
+#define	AT91_TWI_RXRDY		0x0002	/* Receive Holding Register Ready */
+#define	AT91_TWI_TXRDY		0x0004	/* Transmit Holding Register Ready */
+
+#define	AT91_TWI_OVRE		0x0040	/* Overrun Error */
+#define	AT91_TWI_UNRE		0x0080	/* Underrun Error */
+#define	AT91_TWI_NACK		0x0100	/* Not Acknowledged */
+
+#define	AT91_TWI_IER		0x0024	/* Interrupt Enable Register */
+#define	AT91_TWI_IDR		0x0028	/* Interrupt Disable Register */
+#define	AT91_TWI_IMR		0x002c	/* Interrupt Mask Register */
+#define	AT91_TWI_RHR		0x0030	/* Receive Holding Register */
+#define	AT91_TWI_THR		0x0034	/* Transmit Holding Register */
+
+struct at91_twi_pdata {
+	unsigned	clk_max_div;
+	unsigned	clk_offset;
+	bool		has_unre_flag;
+};
+
+struct at91_twi_dev {
+	struct device		*dev;
+	void __iomem		*base;
+	struct completion	cmd_complete;
+	struct clk		*clk;
+	u8			*buf;
+	size_t			buf_len;
+	struct i2c_msg		*msg;
+	int			irq;
+	unsigned		transfer_status;
+	struct i2c_adapter	adapter;
+	unsigned		twi_cwgr_reg;
+	struct at91_twi_pdata	*pdata;
+};
+
+static unsigned at91_twi_read(struct at91_twi_dev *dev, unsigned reg)
 {
-	int i, ret;
+	return readl_relaxed(dev->base + reg);
+}
+
+static void at91_twi_write(struct at91_twi_dev *dev, unsigned reg, unsigned val)
+{
+	writel_relaxed(val, dev->base + reg);
+}
+
+static void at91_disable_twi_interrupts(struct at91_twi_dev *dev)
+{
+	at91_twi_write(dev, AT91_TWI_IDR,
+		       AT91_TWI_TXCOMP | AT91_TWI_RXRDY | AT91_TWI_TXRDY);
+}
+
+static void at91_init_twi_bus(struct at91_twi_dev *dev)
+{
+	at91_disable_twi_interrupts(dev);
+	at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_SWRST);
+	at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_MSEN);
+	at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_SVDIS);
+	at91_twi_write(dev, AT91_TWI_CWGR, dev->twi_cwgr_reg);
+}
+
+/*
+ * Calculate symmetric clock as stated in datasheet:
+ * twi_clk = F_MAIN / (2 * (cdiv * (1 << ckdiv) + offset))
+ */
+static void __devinit at91_calc_twi_clock(struct at91_twi_dev *dev, int twi_clk)
+{
+	int ckdiv, cdiv, div;
+	struct at91_twi_pdata *pdata = dev->pdata;
+	int offset = pdata->clk_offset;
+	int max_ckdiv = pdata->clk_max_div;
+
+	div = max(0, (int)DIV_ROUND_UP(clk_get_rate(dev->clk),
+				       2 * twi_clk) - offset);
+	ckdiv = fls(div >> 8);
+	cdiv = div >> ckdiv;
+
+	if (ckdiv > max_ckdiv) {
+		dev_warn(dev->dev, "%d exceeds ckdiv max value which is %d.\n",
+			 ckdiv, max_ckdiv);
+		ckdiv = max_ckdiv;
+		cdiv = 255;
+	}
+
+	dev->twi_cwgr_reg = (ckdiv << 16) | (cdiv << 8) | cdiv;
+	dev_dbg(dev->dev, "cdiv %d ckdiv %d\n", cdiv, ckdiv);
+}
+
+static void at91_twi_write_next_byte(struct at91_twi_dev *dev)
+{
+	if (dev->buf_len <= 0)
+		return;
+
+	at91_twi_write(dev, AT91_TWI_THR, *dev->buf);
+
+	/* send stop when last byte has been written */
+	if (--dev->buf_len == 0)
+		at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_STOP);
+
+	dev_dbg(dev->dev, "wrote 0x%x, to go %d\n", *dev->buf, dev->buf_len);
+
+	++dev->buf;
+}
+
+static void at91_twi_read_next_byte(struct at91_twi_dev *dev)
+{
+	if (dev->buf_len <= 0)
+		return;
+
+	*dev->buf = at91_twi_read(dev, AT91_TWI_RHR) & 0xff;
+	--dev->buf_len;
+
+	/* handle I2C_SMBUS_BLOCK_DATA */
+	if (unlikely(dev->msg->flags & I2C_M_RECV_LEN)) {
+		dev->msg->flags &= ~I2C_M_RECV_LEN;
+		dev->buf_len += *dev->buf;
+		dev->msg->len = dev->buf_len + 1;
+		dev_dbg(dev->dev, "received block length %d\n", dev->buf_len);
+	}
+
+	/* send stop if second but last byte has been read */
+	if (dev->buf_len == 1)
+		at91_twi_write(dev, AT91_TWI_CR, AT91_TWI_STOP);
+
+	dev_dbg(dev->dev, "read 0x%x, to go %d\n", *dev->buf, dev->buf_len);
+
+	++dev->buf;
+}
+
+static irqreturn_t atmel_twi_interrupt(int irq, void *dev_id)
+{
+	struct at91_twi_dev *dev = dev_id;
+	const unsigned status = at91_twi_read(dev, AT91_TWI_SR);
+	const unsigned irqstatus = status & at91_twi_read(dev, AT91_TWI_IMR);
+
+	if (!irqstatus)
+		return IRQ_NONE;
+	else if (irqstatus & AT91_TWI_RXRDY)
+		at91_twi_read_next_byte(dev);
+	else if (irqstatus & AT91_TWI_TXRDY)
+		at91_twi_write_next_byte(dev);
+
+	/* catch error flags */
+	dev->transfer_status |= status;
+
+	if (irqstatus & AT91_TWI_TXCOMP) {
+		at91_disable_twi_interrupts(dev);
+		complete(&dev->cmd_complete);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int at91_do_twi_transfer(struct at91_twi_dev *dev)
+{
+	int ret;
+	bool has_unre_flag = dev->pdata->has_unre_flag;
+
+	dev_dbg(dev->dev, "transfer: %s %d bytes.\n",
+		(dev->msg->flags & I2C_M_RD) ? "read" : "write", dev->buf_len);
+
+	INIT_COMPLETION(dev->cmd_complete);
+	dev->transfer_status = 0;
+	if (dev->msg->flags & I2C_M_RD) {
+		unsigned start_flags = AT91_TWI_START;
+
+		if (at91_twi_read(dev, AT91_TWI_SR) & AT91_TWI_RXRDY) {
+			dev_err(dev->dev, "RXRDY still set!");
+			at91_twi_read(dev, AT91_TWI_RHR);
+		}
+
+		/* if only one byte is to be read, immediately stop transfer */
+		if (dev->buf_len <= 1 && !(dev->msg->flags & I2C_M_RECV_LEN))
+			start_flags |= AT91_TWI_STOP;
+		at91_twi_write(dev, AT91_TWI_CR, start_flags);
+		at91_twi_write(dev, AT91_TWI_IER,
+			       AT91_TWI_TXCOMP | AT91_TWI_RXRDY);
+	} else {
+		at91_twi_write_next_byte(dev);
+		at91_twi_write(dev, AT91_TWI_IER,
+			       AT91_TWI_TXCOMP | AT91_TWI_TXRDY);
+	}
+
+	ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
+							dev->adapter.timeout);
+	if (ret == 0) {
+		dev_err(dev->dev, "controller timed out\n");
+		at91_init_twi_bus(dev);
+		return -ETIMEDOUT;
+	}
+	if (dev->transfer_status & AT91_TWI_NACK) {
+		dev_dbg(dev->dev, "received nack\n");
+		return -EREMOTEIO;
+	}
+	if (dev->transfer_status & AT91_TWI_OVRE) {
+		dev_err(dev->dev, "overrun while reading\n");
+		return -EIO;
+	}
+	if (has_unre_flag && dev->transfer_status & AT91_TWI_UNRE) {
+		dev_err(dev->dev, "underrun while writing\n");
+		return -EIO;
+	}
+	dev_dbg(dev->dev, "transfer complete\n");
+
+	return 0;
+}
+
+static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num)
+{
+	struct at91_twi_dev *dev = i2c_get_adapdata(adap);
+	int ret;
+	unsigned int_addr_flag = 0;
+	struct i2c_msg *m_start = msg;
 
 	dev_dbg(&adap->dev, "at91_xfer: processing %d messages:\n", num);
 
-	for (i = 0; i < num; i++) {
-		dev_dbg(&adap->dev, " #%d: %sing %d byte%s %s 0x%02x\n", i,
-			pmsg->flags & I2C_M_RD ? "read" : "writ",
-			pmsg->len, pmsg->len > 1 ? "s" : "",
-			pmsg->flags & I2C_M_RD ? "from" : "to",	pmsg->addr);
+	/*
+	 * The hardware can handle at most two messages concatenated by a
+	 * repeated start via it's internal address feature.
+	 */
+	if (num > 2) {
+		dev_err(dev->dev,
+			"cannot handle more than two concatenated messages.\n");
+		return 0;
+	} else if (num == 2) {
+		int internal_address = 0;
+		int i;
 
-		at91_twi_write(AT91_TWI_MMR, (pmsg->addr << 16)
-			| ((pmsg->flags & I2C_M_RD) ? AT91_TWI_MREAD : 0));
-
-		if (pmsg->len && pmsg->buf) {	/* sanity check */
-			if (pmsg->flags & I2C_M_RD)
-				ret = xfer_read(adap, pmsg->buf, pmsg->len);
-			else
-				ret = xfer_write(adap, pmsg->buf, pmsg->len);
-
-			if (ret)
-				return ret;
-
-			/* Wait until transfer is finished */
-			if (!at91_poll_status(AT91_TWI_TXCOMP)) {
-				dev_dbg(&adap->dev, "TXCOMP timeout\n");
-				return -ETIMEDOUT;
-			}
+		if (msg->flags & I2C_M_RD) {
+			dev_err(dev->dev, "first transfer must be write.\n");
+			return -EINVAL;
 		}
-		dev_dbg(&adap->dev, "transfer complete\n");
-		pmsg++;		/* next message */
+		if (msg->len > 3) {
+			dev_err(dev->dev, "first message size must be <= 3.\n");
+			return -EINVAL;
+		}
+
+		/* 1st msg is put into the internal address, start with 2nd */
+		m_start = &msg[1];
+		for (i = 0; i < msg->len; ++i) {
+			const unsigned addr = msg->buf[msg->len - 1 - i];
+
+			internal_address |= addr << (8 * i);
+			int_addr_flag += AT91_TWI_IADRSZ_1;
+		}
+		at91_twi_write(dev, AT91_TWI_IADR, internal_address);
 	}
-	return i;
+
+	at91_twi_write(dev, AT91_TWI_MMR, (m_start->addr << 16) | int_addr_flag
+		       | ((m_start->flags & I2C_M_RD) ? AT91_TWI_MREAD : 0));
+
+	dev->buf_len = m_start->len;
+	dev->buf = m_start->buf;
+	dev->msg = m_start;
+
+	ret = at91_do_twi_transfer(dev);
+
+	return (ret < 0) ? ret : num;
 }
 
-/*
- * Return list of supported functionality.
- */
-static u32 at91_func(struct i2c_adapter *adapter)
+static u32 at91_twi_func(struct i2c_adapter *adapter)
 {
-	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL
+		| I2C_FUNC_SMBUS_READ_BLOCK_DATA;
 }
 
-static struct i2c_algorithm at91_algorithm = {
-	.master_xfer	= at91_xfer,
-	.functionality	= at91_func,
+static struct i2c_algorithm at91_twi_algorithm = {
+	.master_xfer	= at91_twi_xfer,
+	.functionality	= at91_twi_func,
 };
 
-/*
- * Main initialization routine.
- */
-static int __devinit at91_i2c_probe(struct platform_device *pdev)
+static struct at91_twi_pdata at91rm9200_config = {
+	.clk_max_div = 5,
+	.clk_offset = 3,
+	.has_unre_flag = true,
+};
+
+static struct at91_twi_pdata at91sam9261_config = {
+	.clk_max_div = 5,
+	.clk_offset = 4,
+	.has_unre_flag = false,
+};
+
+static struct at91_twi_pdata at91sam9260_config = {
+	.clk_max_div = 7,
+	.clk_offset = 4,
+	.has_unre_flag = false,
+};
+
+static struct at91_twi_pdata at91sam9g20_config = {
+	.clk_max_div = 7,
+	.clk_offset = 4,
+	.has_unre_flag = false,
+};
+
+static struct at91_twi_pdata at91sam9g10_config = {
+	.clk_max_div = 7,
+	.clk_offset = 4,
+	.has_unre_flag = false,
+};
+
+static struct at91_twi_pdata at91sam9x5_config = {
+	.clk_max_div = 7,
+	.clk_offset = 4,
+	.has_unre_flag = false,
+};
+
+static const struct platform_device_id at91_twi_devtypes[] = {
+	{
+		.name = "i2c-at91rm9200",
+		.driver_data = (unsigned long) &at91rm9200_config,
+	}, {
+		.name = "i2c-at91sam9261",
+		.driver_data = (unsigned long) &at91sam9261_config,
+	}, {
+		.name = "i2c-at91sam9260",
+		.driver_data = (unsigned long) &at91sam9260_config,
+	}, {
+		.name = "i2c-at91sam9g20",
+		.driver_data = (unsigned long) &at91sam9g20_config,
+	}, {
+		.name = "i2c-at91sam9g10",
+		.driver_data = (unsigned long) &at91sam9g10_config,
+	}, {
+		/* sentinel */
+	}
+};
+
+#if defined(CONFIG_OF)
+static const struct of_device_id atmel_twi_dt_ids[] = {
+	{
+		.compatible = "atmel,at91sam9260-i2c",
+		.data = &at91sam9260_config,
+	} , {
+		.compatible = "atmel,at91sam9g20-i2c",
+		.data = &at91sam9g20_config,
+	} , {
+		.compatible = "atmel,at91sam9g10-i2c",
+		.data = &at91sam9g10_config,
+	}, {
+		.compatible = "atmel,at91sam9x5-i2c",
+		.data = &at91sam9x5_config,
+	}, {
+		/* sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(of, atmel_twi_dt_ids);
+#else
+#define atmel_twi_dt_ids NULL
+#endif
+
+static struct at91_twi_pdata * __devinit at91_twi_get_driver_data(
+					struct platform_device *pdev)
 {
-	struct i2c_adapter *adapter;
-	struct resource *res;
-	int rc;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res)
-		return -ENXIO;
-
-	if (!request_mem_region(res->start, resource_size(res), "at91_i2c"))
-		return -EBUSY;
-
-	twi_base = ioremap(res->start, resource_size(res));
-	if (!twi_base) {
-		rc = -ENOMEM;
-		goto fail0;
+	if (pdev->dev.of_node) {
+		const struct of_device_id *match;
+		match = of_match_node(atmel_twi_dt_ids, pdev->dev.of_node);
+		if (!match)
+			return NULL;
+		return match->data;
 	}
-
-	twi_clk = clk_get(NULL, "twi_clk");
-	if (IS_ERR(twi_clk)) {
-		dev_err(&pdev->dev, "no clock defined\n");
-		rc = -ENODEV;
-		goto fail1;
-	}
-
-	adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
-	if (adapter == NULL) {
-		dev_err(&pdev->dev, "can't allocate inteface!\n");
-		rc = -ENOMEM;
-		goto fail2;
-	}
-	snprintf(adapter->name, sizeof(adapter->name), "AT91");
-	adapter->algo = &at91_algorithm;
-	adapter->class = I2C_CLASS_HWMON;
-	adapter->dev.parent = &pdev->dev;
-	/* adapter->id == 0 ... only one TWI controller for now */
-
-	platform_set_drvdata(pdev, adapter);
-
-	clk_enable(twi_clk);		/* enable peripheral clock */
-	at91_twi_hwinit();		/* initialize TWI controller */
-
-	rc = i2c_add_numbered_adapter(adapter);
-	if (rc) {
-		dev_err(&pdev->dev, "Adapter %s registration failed\n",
-				adapter->name);
-		goto fail3;
-	}
-
-	dev_info(&pdev->dev, "AT91 i2c bus driver.\n");
-	return 0;
-
-fail3:
-	platform_set_drvdata(pdev, NULL);
-	kfree(adapter);
-	clk_disable(twi_clk);
-fail2:
-	clk_put(twi_clk);
-fail1:
-	iounmap(twi_base);
-fail0:
-	release_mem_region(res->start, resource_size(res));
-
-	return rc;
+	return (struct at91_twi_pdata *) platform_get_device_id(pdev)->driver_data;
 }
 
-static int __devexit at91_i2c_remove(struct platform_device *pdev)
+static int __devinit at91_twi_probe(struct platform_device *pdev)
 {
-	struct i2c_adapter *adapter = platform_get_drvdata(pdev);
-	struct resource *res;
+	struct at91_twi_dev *dev;
+	struct resource *mem;
 	int rc;
 
-	rc = i2c_del_adapter(adapter);
-	platform_set_drvdata(pdev, NULL);
+	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
+	if (!dev)
+		return -ENOMEM;
+	init_completion(&dev->cmd_complete);
+	dev->dev = &pdev->dev;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	iounmap(twi_base);
-	release_mem_region(res->start, resource_size(res));
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!mem)
+		return -ENODEV;
 
-	clk_disable(twi_clk);		/* disable peripheral clock */
-	clk_put(twi_clk);
+	dev->pdata = at91_twi_get_driver_data(pdev);
+	if (!dev->pdata)
+		return -ENODEV;
+
+	dev->base = devm_request_and_ioremap(&pdev->dev, mem);
+	if (!dev->base)
+		return -EBUSY;
+
+	dev->irq = platform_get_irq(pdev, 0);
+	if (dev->irq < 0)
+		return dev->irq;
+
+	rc = devm_request_irq(&pdev->dev, dev->irq, atmel_twi_interrupt, 0,
+			 dev_name(dev->dev), dev);
+	if (rc) {
+		dev_err(dev->dev, "Cannot get irq %d: %d\n", dev->irq, rc);
+		return rc;
+	}
+
+	platform_set_drvdata(pdev, dev);
+
+	dev->clk = devm_clk_get(dev->dev, NULL);
+	if (IS_ERR(dev->clk)) {
+		dev_err(dev->dev, "no clock defined\n");
+		return -ENODEV;
+	}
+	clk_prepare_enable(dev->clk);
+
+	at91_calc_twi_clock(dev, TWI_CLK_HZ);
+	at91_init_twi_bus(dev);
+
+	snprintf(dev->adapter.name, sizeof(dev->adapter.name), "AT91");
+	i2c_set_adapdata(&dev->adapter, dev);
+	dev->adapter.owner = THIS_MODULE;
+	dev->adapter.class = I2C_CLASS_HWMON;
+	dev->adapter.algo = &at91_twi_algorithm;
+	dev->adapter.dev.parent = dev->dev;
+	dev->adapter.nr = pdev->id;
+	dev->adapter.timeout = AT91_I2C_TIMEOUT;
+	dev->adapter.dev.of_node = pdev->dev.of_node;
+
+	rc = i2c_add_numbered_adapter(&dev->adapter);
+	if (rc) {
+		dev_err(dev->dev, "Adapter %s registration failed\n",
+			dev->adapter.name);
+		clk_disable_unprepare(dev->clk);
+		return rc;
+	}
+
+	of_i2c_register_devices(&dev->adapter);
+
+	dev_info(dev->dev, "AT91 i2c bus driver.\n");
+	return 0;
+}
+
+static int __devexit at91_twi_remove(struct platform_device *pdev)
+{
+	struct at91_twi_dev *dev = platform_get_drvdata(pdev);
+	int rc;
+
+	rc = i2c_del_adapter(&dev->adapter);
+	clk_disable_unprepare(dev->clk);
 
 	return rc;
 }
 
 #ifdef CONFIG_PM
 
-/* NOTE: could save a few mA by keeping clock off outside of at91_xfer... */
-
-static int at91_i2c_suspend(struct device *dev)
+static int at91_twi_runtime_suspend(struct device *dev)
 {
-	clk_disable(twi_clk);
+	struct at91_twi_dev *twi_dev = dev_get_drvdata(dev);
+
+	clk_disable(twi_dev->clk);
+
 	return 0;
 }
 
-static int at91_i2c_resume(struct device *dev)
+static int at91_twi_runtime_resume(struct device *dev)
 {
-	return clk_enable(twi_clk);
+	struct at91_twi_dev *twi_dev = dev_get_drvdata(dev);
+
+	return clk_enable(twi_dev->clk);
 }
 
-static SIMPLE_DEV_PM_OPS(at91_i2c_pm, at91_i2c_suspend, at91_i2c_resume);
-#define AT91_I2C_PM	(&at91_i2c_pm)
+static const struct dev_pm_ops at91_twi_pm = {
+	.runtime_suspend	= at91_twi_runtime_suspend,
+	.runtime_resume		= at91_twi_runtime_resume,
+};
 
+#define at91_twi_pm_ops (&at91_twi_pm)
 #else
-#define AT91_I2C_PM	NULL
+#define at91_twi_pm_ops NULL
 #endif
 
-static struct platform_driver at91_i2c_driver = {
-	.probe		= at91_i2c_probe,
-	.remove		= __devexit_p(at91_i2c_remove),
+static struct platform_driver at91_twi_driver = {
+	.probe		= at91_twi_probe,
+	.remove		= __devexit_p(at91_twi_remove),
+	.id_table	= at91_twi_devtypes,
 	.driver		= {
 		.name	= "at91_i2c",
 		.owner	= THIS_MODULE,
-		.pm	= AT91_I2C_PM,
+		.of_match_table = atmel_twi_dt_ids,
+		.pm	= at91_twi_pm_ops,
 	},
 };
 
-module_platform_driver(at91_i2c_driver);
+static int __init at91_twi_init(void)
+{
+	return platform_driver_register(&at91_twi_driver);
+}
 
-MODULE_AUTHOR("Rick Bronson");
+static void __exit at91_twi_exit(void)
+{
+	platform_driver_unregister(&at91_twi_driver);
+}
+
+subsys_initcall(at91_twi_init);
+module_exit(at91_twi_exit);
+
+MODULE_AUTHOR("Nikolaus Voss <n.voss@weinmann.de>");
 MODULE_DESCRIPTION("I2C (TWI) driver for Atmel AT91");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:at91_i2c");
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index 79a2542..6a0a553 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -38,6 +38,8 @@
 #include <linux/slab.h>
 #include <linux/cpufreq.h>
 #include <linux/gpio.h>
+#include <linux/of_i2c.h>
+#include <linux/of_device.h>
 
 #include <mach/hardware.h>
 #include <linux/platform_data/i2c-davinci.h>
@@ -114,6 +116,7 @@
 	struct completion	xfr_complete;
 	struct notifier_block	freq_transition;
 #endif
+	struct davinci_i2c_platform_data *pdata;
 };
 
 /* default platform data to use if not supplied in the platform_device */
@@ -155,7 +158,7 @@
 static void i2c_recover_bus(struct davinci_i2c_dev *dev)
 {
 	u32 flag = 0;
-	struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
+	struct davinci_i2c_platform_data *pdata = dev->pdata;
 
 	dev_err(dev->dev, "initiating i2c bus recovery\n");
 	/* Send NACK to the slave */
@@ -163,8 +166,7 @@
 	flag |=  DAVINCI_I2C_MDR_NACK;
 	/* write the data into mode register */
 	davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
-	if (pdata)
-		generic_i2c_clock_pulse(pdata->scl_pin);
+	generic_i2c_clock_pulse(pdata->scl_pin);
 	/* Send STOP */
 	flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
 	flag |= DAVINCI_I2C_MDR_STP;
@@ -187,7 +189,7 @@
 
 static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev)
 {
-	struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
+	struct davinci_i2c_platform_data *pdata = dev->pdata;
 	u16 psc;
 	u32 clk;
 	u32 d;
@@ -235,10 +237,7 @@
  */
 static int i2c_davinci_init(struct davinci_i2c_dev *dev)
 {
-	struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
-
-	if (!pdata)
-		pdata = &davinci_i2c_platform_data_default;
+	struct davinci_i2c_platform_data *pdata = dev->pdata;
 
 	/* put I2C into reset */
 	davinci_i2c_reset_ctrl(dev, 0);
@@ -260,6 +259,7 @@
 	dev_dbg(dev->dev, "bus_freq = %dkHz, bus_delay = %d\n",
 		pdata->bus_freq, pdata->bus_delay);
 
+
 	/* Take the I2C module out of reset: */
 	davinci_i2c_reset_ctrl(dev, 1);
 
@@ -308,13 +308,11 @@
 i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
 {
 	struct davinci_i2c_dev *dev = i2c_get_adapdata(adap);
-	struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
+	struct davinci_i2c_platform_data *pdata = dev->pdata;
 	u32 flag;
 	u16 w;
 	int r;
 
-	if (!pdata)
-		pdata = &davinci_i2c_platform_data_default;
 	/* Introduce a delay, required for some boards (e.g Davinci EVM) */
 	if (pdata->bus_delay)
 		udelay(pdata->bus_delay);
@@ -635,6 +633,12 @@
 	.functionality	= i2c_davinci_func,
 };
 
+static const struct of_device_id davinci_i2c_of_match[] = {
+	{.compatible = "ti,davinci-i2c", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, davinci_i2c_of_match);
+
 static int davinci_i2c_probe(struct platform_device *pdev)
 {
 	struct davinci_i2c_dev *dev;
@@ -674,14 +678,33 @@
 #endif
 	dev->dev = get_device(&pdev->dev);
 	dev->irq = irq->start;
+	dev->pdata = dev->dev->platform_data;
 	platform_set_drvdata(pdev, dev);
 
+	if (!dev->pdata && pdev->dev.of_node) {
+		u32 prop;
+
+		dev->pdata = devm_kzalloc(&pdev->dev,
+			sizeof(struct davinci_i2c_platform_data), GFP_KERNEL);
+		if (!dev->pdata) {
+			r = -ENOMEM;
+			goto err_free_mem;
+		}
+		memcpy(dev->pdata, &davinci_i2c_platform_data_default,
+			sizeof(struct davinci_i2c_platform_data));
+		if (!of_property_read_u32(pdev->dev.of_node, "clock-frequency",
+			&prop))
+			dev->pdata->bus_freq = prop / 1000;
+	} else if (!dev->pdata) {
+		dev->pdata = &davinci_i2c_platform_data_default;
+	}
+
 	dev->clk = clk_get(&pdev->dev, NULL);
 	if (IS_ERR(dev->clk)) {
 		r = -ENODEV;
 		goto err_free_mem;
 	}
-	clk_enable(dev->clk);
+	clk_prepare_enable(dev->clk);
 
 	dev->base = ioremap(mem->start, resource_size(mem));
 	if (!dev->base) {
@@ -711,6 +734,7 @@
 	adap->algo = &i2c_davinci_algo;
 	adap->dev.parent = &pdev->dev;
 	adap->timeout = DAVINCI_I2C_TIMEOUT;
+	adap->dev.of_node = pdev->dev.of_node;
 
 	adap->nr = pdev->id;
 	r = i2c_add_numbered_adapter(adap);
@@ -718,6 +742,7 @@
 		dev_err(&pdev->dev, "failure adding adapter\n");
 		goto err_free_irq;
 	}
+	of_i2c_register_devices(adap);
 
 	return 0;
 
@@ -726,7 +751,7 @@
 err_unuse_clocks:
 	iounmap(dev->base);
 err_mem_ioremap:
-	clk_disable(dev->clk);
+	clk_disable_unprepare(dev->clk);
 	clk_put(dev->clk);
 	dev->clk = NULL;
 err_free_mem:
@@ -750,7 +775,7 @@
 	i2c_del_adapter(&dev->adapter);
 	put_device(&pdev->dev);
 
-	clk_disable(dev->clk);
+	clk_disable_unprepare(dev->clk);
 	clk_put(dev->clk);
 	dev->clk = NULL;
 
@@ -772,7 +797,7 @@
 
 	/* put I2C into reset */
 	davinci_i2c_reset_ctrl(i2c_dev, 0);
-	clk_disable(i2c_dev->clk);
+	clk_disable_unprepare(i2c_dev->clk);
 
 	return 0;
 }
@@ -782,7 +807,7 @@
 	struct platform_device *pdev = to_platform_device(dev);
 	struct davinci_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
 
-	clk_enable(i2c_dev->clk);
+	clk_prepare_enable(i2c_dev->clk);
 	/* take I2C out of reset */
 	davinci_i2c_reset_ctrl(i2c_dev, 1);
 
@@ -809,6 +834,7 @@
 		.name	= "i2c_davinci",
 		.owner	= THIS_MODULE,
 		.pm	= davinci_i2c_pm_ops,
+		.of_match_table = of_match_ptr(davinci_i2c_of_match),
 	},
 };
 
diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c
index 7b8ebbe..cbba7db 100644
--- a/drivers/i2c/busses/i2c-designware-core.c
+++ b/drivers/i2c/busses/i2c-designware-core.c
@@ -370,7 +370,7 @@
  * messages into the tx buffer.  Even if the size of i2c_msg data is
  * longer than the size of the tx buffer, it handles everything.
  */
-void
+static void
 i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
 {
 	struct i2c_msg *msgs = dev->msgs;
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 33e9b0c..3779315 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -80,6 +80,13 @@
 #include <linux/dmi.h>
 #include <linux/slab.h>
 #include <linux/wait.h>
+#include <linux/err.h>
+
+#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE
+#include <linux/gpio.h>
+#include <linux/i2c-mux-gpio.h>
+#include <linux/platform_device.h>
+#endif
 
 /* I801 SMBus address offsets */
 #define SMBHSTSTS(p)	(0 + (p)->smba)
@@ -158,6 +165,15 @@
 #define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS	0x8c22
 #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS	0x9c22
 
+struct i801_mux_config {
+	char *gpio_chip;
+	unsigned values[3];
+	int n_values;
+	unsigned classes[3];
+	unsigned gpios[2];		/* Relative to gpio_chip->base */
+	int n_gpios;
+};
+
 struct i801_priv {
 	struct i2c_adapter adapter;
 	unsigned long smba;
@@ -175,6 +191,11 @@
 	int count;
 	int len;
 	u8 *data;
+
+#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE
+	const struct i801_mux_config *mux_drvdata;
+	struct platform_device *mux_pdev;
+#endif
 };
 
 static struct pci_driver i801_driver;
@@ -900,6 +921,165 @@
 static void __devinit i801_probe_optional_slaves(struct i801_priv *priv) {}
 #endif	/* CONFIG_X86 && CONFIG_DMI */
 
+#if defined CONFIG_I2C_MUX || defined CONFIG_I2C_MUX_MODULE
+static struct i801_mux_config i801_mux_config_asus_z8_d12 = {
+	.gpio_chip = "gpio_ich",
+	.values = { 0x02, 0x03 },
+	.n_values = 2,
+	.classes = { I2C_CLASS_SPD, I2C_CLASS_SPD },
+	.gpios = { 52, 53 },
+	.n_gpios = 2,
+};
+
+static struct i801_mux_config i801_mux_config_asus_z8_d18 = {
+	.gpio_chip = "gpio_ich",
+	.values = { 0x02, 0x03, 0x01 },
+	.n_values = 3,
+	.classes = { I2C_CLASS_SPD, I2C_CLASS_SPD, I2C_CLASS_SPD },
+	.gpios = { 52, 53 },
+	.n_gpios = 2,
+};
+
+static struct dmi_system_id __devinitdata mux_dmi_table[] = {
+	{
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+			DMI_MATCH(DMI_BOARD_NAME, "Z8NA-D6(C)"),
+		},
+		.driver_data = &i801_mux_config_asus_z8_d12,
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+			DMI_MATCH(DMI_BOARD_NAME, "Z8P(N)E-D12(X)"),
+		},
+		.driver_data = &i801_mux_config_asus_z8_d12,
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+			DMI_MATCH(DMI_BOARD_NAME, "Z8NH-D12"),
+		},
+		.driver_data = &i801_mux_config_asus_z8_d12,
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+			DMI_MATCH(DMI_BOARD_NAME, "Z8PH-D12/IFB"),
+		},
+		.driver_data = &i801_mux_config_asus_z8_d12,
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+			DMI_MATCH(DMI_BOARD_NAME, "Z8NR-D12"),
+		},
+		.driver_data = &i801_mux_config_asus_z8_d12,
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+			DMI_MATCH(DMI_BOARD_NAME, "Z8P(N)H-D12"),
+		},
+		.driver_data = &i801_mux_config_asus_z8_d12,
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+			DMI_MATCH(DMI_BOARD_NAME, "Z8PG-D18"),
+		},
+		.driver_data = &i801_mux_config_asus_z8_d18,
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+			DMI_MATCH(DMI_BOARD_NAME, "Z8PE-D18"),
+		},
+		.driver_data = &i801_mux_config_asus_z8_d18,
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+			DMI_MATCH(DMI_BOARD_NAME, "Z8PS-D12"),
+		},
+		.driver_data = &i801_mux_config_asus_z8_d12,
+	},
+	{ }
+};
+
+/* Setup multiplexing if needed */
+static int __devinit i801_add_mux(struct i801_priv *priv)
+{
+	struct device *dev = &priv->adapter.dev;
+	const struct i801_mux_config *mux_config;
+	struct i2c_mux_gpio_platform_data gpio_data;
+	int err;
+
+	if (!priv->mux_drvdata)
+		return 0;
+	mux_config = priv->mux_drvdata;
+
+	/* Prepare the platform data */
+	memset(&gpio_data, 0, sizeof(struct i2c_mux_gpio_platform_data));
+	gpio_data.parent = priv->adapter.nr;
+	gpio_data.values = mux_config->values;
+	gpio_data.n_values = mux_config->n_values;
+	gpio_data.classes = mux_config->classes;
+	gpio_data.gpio_chip = mux_config->gpio_chip;
+	gpio_data.gpios = mux_config->gpios;
+	gpio_data.n_gpios = mux_config->n_gpios;
+	gpio_data.idle = I2C_MUX_GPIO_NO_IDLE;
+
+	/* Register the mux device */
+	priv->mux_pdev = platform_device_register_data(dev, "i2c-mux-gpio",
+				PLATFORM_DEVID_AUTO, &gpio_data,
+				sizeof(struct i2c_mux_gpio_platform_data));
+	if (IS_ERR(priv->mux_pdev)) {
+		err = PTR_ERR(priv->mux_pdev);
+		priv->mux_pdev = NULL;
+		dev_err(dev, "Failed to register i2c-mux-gpio device\n");
+		return err;
+	}
+
+	return 0;
+}
+
+static void __devexit i801_del_mux(struct i801_priv *priv)
+{
+	if (priv->mux_pdev)
+		platform_device_unregister(priv->mux_pdev);
+}
+
+static unsigned int __devinit i801_get_adapter_class(struct i801_priv *priv)
+{
+	const struct dmi_system_id *id;
+	const struct i801_mux_config *mux_config;
+	unsigned int class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
+	int i;
+
+	id = dmi_first_match(mux_dmi_table);
+	if (id) {
+		/* Remove from branch classes from trunk */
+		mux_config = id->driver_data;
+		for (i = 0; i < mux_config->n_values; i++)
+			class &= ~mux_config->classes[i];
+
+		/* Remember for later */
+		priv->mux_drvdata = mux_config;
+	}
+
+	return class;
+}
+#else
+static inline int i801_add_mux(struct i801_priv *priv) { return 0; }
+static inline void i801_del_mux(struct i801_priv *priv) { }
+
+static inline unsigned int i801_get_adapter_class(struct i801_priv *priv)
+{
+	return I2C_CLASS_HWMON | I2C_CLASS_SPD;
+}
+#endif
+
 static int __devinit i801_probe(struct pci_dev *dev,
 				const struct pci_device_id *id)
 {
@@ -913,7 +1093,7 @@
 
 	i2c_set_adapdata(&priv->adapter, priv);
 	priv->adapter.owner = THIS_MODULE;
-	priv->adapter.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
+	priv->adapter.class = i801_get_adapter_class(priv);
 	priv->adapter.algo = &smbus_algorithm;
 
 	priv->pci_dev = dev;
@@ -1033,6 +1213,8 @@
 	}
 
 	i801_probe_optional_slaves(priv);
+	/* We ignore errors - multiplexing is optional */
+	i801_add_mux(priv);
 
 	pci_set_drvdata(dev, priv);
 
@@ -1052,6 +1234,7 @@
 {
 	struct i801_priv *priv = pci_get_drvdata(dev);
 
+	i801_del_mux(priv);
 	i2c_del_adapter(&priv->adapter);
 	pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg);
 
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index b7907ba..2ef162d 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -272,9 +272,9 @@
 
 	/* dev_dbg() can't be used, because adapter is not yet registered */
 #ifdef CONFIG_I2C_DEBUG_BUS
-	printk(KERN_DEBUG "I2C: <%s> I2C_CLK=%d, REQ DIV=%d\n",
+	dev_dbg(&i2c_imx->adapter.dev, "<%s> I2C_CLK=%d, REQ DIV=%d\n",
 		__func__, i2c_clk_rate, div);
-	printk(KERN_DEBUG "I2C: <%s> IFDR[IC]=0x%x, REAL DIV=%d\n",
+	dev_dbg(&i2c_imx->adapter.dev, "<%s> IFDR[IC]=0x%x, REAL DIV=%d\n",
 		__func__, i2c_clk_div[i][1], i2c_clk_div[i][0]);
 #endif
 }
@@ -564,7 +564,7 @@
 		resource_size(res), res->start);
 	dev_dbg(&i2c_imx->adapter.dev, "adapter name: \"%s\"\n",
 		i2c_imx->adapter.name);
-	dev_dbg(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n");
+	dev_info(&i2c_imx->adapter.dev, "IMX I2C adapter registered\n");
 
 	return 0;   /* Return OK */
 }
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index 57f7703..ca86430 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -576,7 +576,23 @@
 			    mpc_write(i2c, pmsg->addr, pmsg->buf, pmsg->len, i);
 		}
 	}
-	mpc_i2c_stop(i2c);
+	mpc_i2c_stop(i2c); /* Initiate STOP */
+	orig_jiffies = jiffies;
+	/* Wait until STOP is seen, allow up to 1 s */
+	while (readb(i2c->base + MPC_I2C_SR) & CSR_MBB) {
+		if (time_after(jiffies, orig_jiffies + HZ)) {
+			u8 status = readb(i2c->base + MPC_I2C_SR);
+
+			dev_dbg(i2c->dev, "timeout\n");
+			if ((status & (CSR_MCF | CSR_MBB | CSR_RXAK)) != 0) {
+				writeb(status & ~CSR_MAL,
+				       i2c->base + MPC_I2C_SR);
+				mpc_i2c_fixup(i2c);
+			}
+			return -EIO;
+		}
+		cond_resched();
+	}
 	return (ret < 0) ? ret : num;
 }
 
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c
index 51f05b8..1f58197 100644
--- a/drivers/i2c/busses/i2c-mxs.c
+++ b/drivers/i2c/busses/i2c-mxs.c
@@ -7,8 +7,6 @@
  *
  * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
  *
- * TODO: add dma-support if platform-support for it is available
- *
  * 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
@@ -31,9 +29,16 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_i2c.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/fsl/mxs-dma.h>
 
 #define DRIVER_NAME "mxs-i2c"
 
+static bool use_pioqueue;
+module_param(use_pioqueue, bool, 0);
+MODULE_PARM_DESC(use_pioqueue, "Use PIOQUEUE mode for transfer instead of DMA");
+
 #define MXS_I2C_CTRL0		(0x00)
 #define MXS_I2C_CTRL0_SET	(0x04)
 
@@ -146,6 +151,16 @@
 	u32 cmd_err;
 	struct i2c_adapter adapter;
 	const struct mxs_i2c_speed_config *speed;
+
+	/* DMA support components */
+	bool				dma_mode;
+	int				dma_channel;
+	struct dma_chan         	*dmach;
+	struct mxs_dma_data		dma_data;
+	uint32_t			pio_data[2];
+	uint32_t			addr_data;
+	struct scatterlist		sg_io[2];
+	bool				dma_read;
 };
 
 static void mxs_i2c_reset(struct mxs_i2c_dev *i2c)
@@ -157,7 +172,11 @@
 	writel(i2c->speed->timing2, i2c->regs + MXS_I2C_TIMING2);
 
 	writel(MXS_I2C_IRQ_MASK << 8, i2c->regs + MXS_I2C_CTRL1_SET);
-	writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE,
+	if (i2c->dma_mode)
+		writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE,
+			i2c->regs + MXS_I2C_QUEUECTRL_CLR);
+	else
+		writel(MXS_I2C_QUEUECTRL_PIO_QUEUE_MODE,
 			i2c->regs + MXS_I2C_QUEUECTRL_SET);
 }
 
@@ -248,6 +267,150 @@
 	return 0;
 }
 
+static void mxs_i2c_dma_finish(struct mxs_i2c_dev *i2c)
+{
+	if (i2c->dma_read) {
+		dma_unmap_sg(i2c->dev, &i2c->sg_io[0], 1, DMA_TO_DEVICE);
+		dma_unmap_sg(i2c->dev, &i2c->sg_io[1], 1, DMA_FROM_DEVICE);
+	} else {
+		dma_unmap_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE);
+	}
+}
+
+static void mxs_i2c_dma_irq_callback(void *param)
+{
+	struct mxs_i2c_dev *i2c = param;
+
+	complete(&i2c->cmd_complete);
+	mxs_i2c_dma_finish(i2c);
+}
+
+static int mxs_i2c_dma_setup_xfer(struct i2c_adapter *adap,
+			struct i2c_msg *msg, uint32_t flags)
+{
+	struct dma_async_tx_descriptor *desc;
+	struct mxs_i2c_dev *i2c = i2c_get_adapdata(adap);
+
+	if (msg->flags & I2C_M_RD) {
+		i2c->dma_read = 1;
+		i2c->addr_data = (msg->addr << 1) | I2C_SMBUS_READ;
+
+		/*
+		 * SELECT command.
+		 */
+
+		/* Queue the PIO register write transfer. */
+		i2c->pio_data[0] = MXS_CMD_I2C_SELECT;
+		desc = dmaengine_prep_slave_sg(i2c->dmach,
+					(struct scatterlist *)&i2c->pio_data[0],
+					1, DMA_TRANS_NONE, 0);
+		if (!desc) {
+			dev_err(i2c->dev,
+				"Failed to get PIO reg. write descriptor.\n");
+			goto select_init_pio_fail;
+		}
+
+		/* Queue the DMA data transfer. */
+		sg_init_one(&i2c->sg_io[0], &i2c->addr_data, 1);
+		dma_map_sg(i2c->dev, &i2c->sg_io[0], 1, DMA_TO_DEVICE);
+		desc = dmaengine_prep_slave_sg(i2c->dmach, &i2c->sg_io[0], 1,
+					DMA_MEM_TO_DEV,
+					DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+		if (!desc) {
+			dev_err(i2c->dev,
+				"Failed to get DMA data write descriptor.\n");
+			goto select_init_dma_fail;
+		}
+
+		/*
+		 * READ command.
+		 */
+
+		/* Queue the PIO register write transfer. */
+		i2c->pio_data[1] = flags | MXS_CMD_I2C_READ |
+				MXS_I2C_CTRL0_XFER_COUNT(msg->len);
+		desc = dmaengine_prep_slave_sg(i2c->dmach,
+					(struct scatterlist *)&i2c->pio_data[1],
+					1, DMA_TRANS_NONE, DMA_PREP_INTERRUPT);
+		if (!desc) {
+			dev_err(i2c->dev,
+				"Failed to get PIO reg. write descriptor.\n");
+			goto select_init_dma_fail;
+		}
+
+		/* Queue the DMA data transfer. */
+		sg_init_one(&i2c->sg_io[1], msg->buf, msg->len);
+		dma_map_sg(i2c->dev, &i2c->sg_io[1], 1, DMA_FROM_DEVICE);
+		desc = dmaengine_prep_slave_sg(i2c->dmach, &i2c->sg_io[1], 1,
+					DMA_DEV_TO_MEM,
+					DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+		if (!desc) {
+			dev_err(i2c->dev,
+				"Failed to get DMA data write descriptor.\n");
+			goto read_init_dma_fail;
+		}
+	} else {
+		i2c->dma_read = 0;
+		i2c->addr_data = (msg->addr << 1) | I2C_SMBUS_WRITE;
+
+		/*
+		 * WRITE command.
+		 */
+
+		/* Queue the PIO register write transfer. */
+		i2c->pio_data[0] = flags | MXS_CMD_I2C_WRITE |
+				MXS_I2C_CTRL0_XFER_COUNT(msg->len + 1);
+		desc = dmaengine_prep_slave_sg(i2c->dmach,
+					(struct scatterlist *)&i2c->pio_data[0],
+					1, DMA_TRANS_NONE, 0);
+		if (!desc) {
+			dev_err(i2c->dev,
+				"Failed to get PIO reg. write descriptor.\n");
+			goto write_init_pio_fail;
+		}
+
+		/* Queue the DMA data transfer. */
+		sg_init_table(i2c->sg_io, 2);
+		sg_set_buf(&i2c->sg_io[0], &i2c->addr_data, 1);
+		sg_set_buf(&i2c->sg_io[1], msg->buf, msg->len);
+		dma_map_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE);
+		desc = dmaengine_prep_slave_sg(i2c->dmach, i2c->sg_io, 2,
+					DMA_MEM_TO_DEV,
+					DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+		if (!desc) {
+			dev_err(i2c->dev,
+				"Failed to get DMA data write descriptor.\n");
+			goto write_init_dma_fail;
+		}
+	}
+
+	/*
+	 * The last descriptor must have this callback,
+	 * to finish the DMA transaction.
+	 */
+	desc->callback = mxs_i2c_dma_irq_callback;
+	desc->callback_param = i2c;
+
+	/* Start the transfer. */
+	dmaengine_submit(desc);
+	dma_async_issue_pending(i2c->dmach);
+	return 0;
+
+/* Read failpath. */
+read_init_dma_fail:
+	dma_unmap_sg(i2c->dev, &i2c->sg_io[1], 1, DMA_FROM_DEVICE);
+select_init_dma_fail:
+	dma_unmap_sg(i2c->dev, &i2c->sg_io[0], 1, DMA_TO_DEVICE);
+select_init_pio_fail:
+	return -EINVAL;
+
+/* Write failpath. */
+write_init_dma_fail:
+	dma_unmap_sg(i2c->dev, i2c->sg_io, 2, DMA_TO_DEVICE);
+write_init_pio_fail:
+	return -EINVAL;
+}
+
 /*
  * Low level master read/write transaction.
  */
@@ -258,6 +421,8 @@
 	int ret;
 	int flags;
 
+	flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0;
+
 	dev_dbg(i2c->dev, "addr: 0x%04x, len: %d, flags: 0x%x, stop: %d\n",
 		msg->addr, msg->len, msg->flags, stop);
 
@@ -267,23 +432,29 @@
 	init_completion(&i2c->cmd_complete);
 	i2c->cmd_err = 0;
 
-	flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0;
+	if (i2c->dma_mode) {
+		ret = mxs_i2c_dma_setup_xfer(adap, msg, flags);
+		if (ret)
+			return ret;
+	} else {
+		if (msg->flags & I2C_M_RD) {
+			mxs_i2c_pioq_setup_read(i2c, msg->addr,
+						msg->len, flags);
+		} else {
+			mxs_i2c_pioq_setup_write(i2c, msg->addr, msg->buf,
+						msg->len, flags);
+		}
 
-	if (msg->flags & I2C_M_RD)
-		mxs_i2c_pioq_setup_read(i2c, msg->addr, msg->len, flags);
-	else
-		mxs_i2c_pioq_setup_write(i2c, msg->addr, msg->buf, msg->len,
-					flags);
-
-	writel(MXS_I2C_QUEUECTRL_QUEUE_RUN,
+		writel(MXS_I2C_QUEUECTRL_QUEUE_RUN,
 			i2c->regs + MXS_I2C_QUEUECTRL_SET);
+	}
 
 	ret = wait_for_completion_timeout(&i2c->cmd_complete,
 						msecs_to_jiffies(1000));
 	if (ret == 0)
 		goto timeout;
 
-	if ((!i2c->cmd_err) && (msg->flags & I2C_M_RD)) {
+	if (!i2c->dma_mode && !i2c->cmd_err && (msg->flags & I2C_M_RD)) {
 		ret = mxs_i2c_finish_read(i2c, msg->buf, msg->len);
 		if (ret)
 			goto timeout;
@@ -301,6 +472,8 @@
 
 timeout:
 	dev_dbg(i2c->dev, "Timeout!\n");
+	if (i2c->dma_mode)
+		mxs_i2c_dma_finish(i2c);
 	mxs_i2c_reset(i2c);
 	return -ETIMEDOUT;
 }
@@ -342,11 +515,13 @@
 		/* MXS_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ is only for slaves */
 		i2c->cmd_err = -EIO;
 
-	is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) &
-		MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0;
+	if (!i2c->dma_mode) {
+		is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) &
+			MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0;
 
-	if (is_last_cmd || i2c->cmd_err)
-		complete(&i2c->cmd_complete);
+		if (is_last_cmd || i2c->cmd_err)
+			complete(&i2c->cmd_complete);
+	}
 
 	writel(stat, i2c->regs + MXS_I2C_CTRL1_CLR);
 
@@ -358,6 +533,21 @@
 	.functionality = mxs_i2c_func,
 };
 
+static bool mxs_i2c_dma_filter(struct dma_chan *chan, void *param)
+{
+	struct mxs_i2c_dev *i2c = param;
+
+	if (!mxs_dma_is_apbx(chan))
+		return false;
+
+	if (chan->chan_id != i2c->dma_channel)
+		return false;
+
+	chan->private = &i2c->dma_data;
+
+	return true;
+}
+
 static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c)
 {
 	uint32_t speed;
@@ -365,6 +555,26 @@
 	struct device_node *node = dev->of_node;
 	int ret;
 
+	/*
+	 * The MXS I2C DMA mode is prefered and enabled by default.
+	 * The PIO mode is still supported, but should be used only
+	 * for debuging purposes etc.
+	 */
+	i2c->dma_mode = !use_pioqueue;
+	if (!i2c->dma_mode)
+		dev_info(dev, "Using PIOQUEUE mode for I2C transfers!\n");
+
+	/*
+	 * TODO: This is a temporary solution and should be changed
+	 * to use generic DMA binding later when the helpers get in.
+	 */
+	ret = of_property_read_u32(node, "fsl,i2c-dma-channel",
+				   &i2c->dma_channel);
+	if (ret) {
+		dev_warn(dev, "Failed to get DMA channel, using PIOQUEUE!\n");
+		i2c->dma_mode = 0;
+	}
+
 	ret = of_property_read_u32(node, "clock-frequency", &speed);
 	if (ret)
 		dev_warn(dev, "No I2C speed selected, using 100kHz\n");
@@ -384,7 +594,8 @@
 	struct pinctrl *pinctrl;
 	struct resource *res;
 	resource_size_t res_size;
-	int err, irq;
+	int err, irq, dmairq;
+	dma_cap_mask_t mask;
 
 	pinctrl = devm_pinctrl_get_select_default(dev);
 	if (IS_ERR(pinctrl))
@@ -395,7 +606,10 @@
 		return -ENOMEM;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res)
+	irq = platform_get_irq(pdev, 0);
+	dmairq = platform_get_irq(pdev, 1);
+
+	if (!res || irq < 0 || dmairq < 0)
 		return -ENOENT;
 
 	res_size = resource_size(res);
@@ -406,10 +620,6 @@
 	if (!i2c->regs)
 		return -EBUSY;
 
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0)
-		return irq;
-
 	err = devm_request_irq(dev, irq, mxs_i2c_isr, 0, dev_name(dev), i2c);
 	if (err)
 		return err;
@@ -423,6 +633,18 @@
 			return err;
 	}
 
+	/* Setup the DMA */
+	if (i2c->dma_mode) {
+		dma_cap_zero(mask);
+		dma_cap_set(DMA_SLAVE, mask);
+		i2c->dma_data.chan_irq = dmairq;
+		i2c->dmach = dma_request_channel(mask, mxs_i2c_dma_filter, i2c);
+		if (!i2c->dmach) {
+			dev_err(dev, "Failed to request dma\n");
+			return -ENODEV;
+		}
+	}
+
 	platform_set_drvdata(pdev, i2c);
 
 	/* Do reset to enforce correct startup after pinmuxing */
@@ -458,6 +680,9 @@
 	if (ret)
 		return -EBUSY;
 
+	if (i2c->dmach)
+		dma_release_channel(i2c->dmach);
+
 	writel(MXS_I2C_CTRL0_SFTRST, i2c->regs + MXS_I2C_CTRL0_SET);
 
 	platform_set_drvdata(pdev, NULL);
diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index 61b00ed..698d7ac 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -22,9 +22,10 @@
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
-#include <linux/regulator/consumer.h>
 #include <linux/pm_runtime.h>
 #include <linux/platform_data/i2c-nomadik.h>
+#include <linux/of.h>
+#include <linux/of_i2c.h>
 
 #define DRIVER_NAME "nmk-i2c"
 
@@ -146,7 +147,6 @@
  * @stop: stop condition.
  * @xfer_complete: acknowledge completion for a I2C message.
  * @result: controller propogated result.
- * @regulator: pointer to i2c regulator.
  * @busy: Busy doing transfer.
  */
 struct nmk_i2c_dev {
@@ -160,7 +160,6 @@
 	int				stop;
 	struct completion		xfer_complete;
 	int				result;
-	struct regulator		*regulator;
 	bool				busy;
 };
 
@@ -643,8 +642,6 @@
 
 	dev->busy = true;
 
-	if (dev->regulator)
-		regulator_enable(dev->regulator);
 	pm_runtime_get_sync(&dev->adev->dev);
 
 	clk_enable(dev->clk);
@@ -676,8 +673,6 @@
 out:
 	clk_disable(dev->clk);
 	pm_runtime_put_sync(&dev->adev->dev);
-	if (dev->regulator)
-		regulator_disable(dev->regulator);
 
 	dev->busy = false;
 
@@ -920,18 +915,42 @@
 	.sm             = I2C_FREQ_MODE_FAST,
 };
 
+static void nmk_i2c_of_probe(struct device_node *np,
+			struct nmk_i2c_controller *pdata)
+{
+	of_property_read_u32(np, "clock-frequency", &pdata->clk_freq);
+
+	/* This driver only supports 'standard' and 'fast' modes of operation. */
+	if (pdata->clk_freq <= 100000)
+		pdata->sm = I2C_FREQ_MODE_STANDARD;
+	else
+		pdata->sm = I2C_FREQ_MODE_FAST;
+}
+
 static atomic_t adapter_id = ATOMIC_INIT(0);
 
 static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
 {
 	int ret = 0;
 	struct nmk_i2c_controller *pdata = adev->dev.platform_data;
+	struct device_node *np = adev->dev.of_node;
 	struct nmk_i2c_dev	*dev;
 	struct i2c_adapter *adap;
 
-	if (!pdata)
-		/* No i2c configuration found, using the default. */
-		pdata = &u8500_i2c;
+	if (!pdata) {
+		if (np) {
+			pdata = devm_kzalloc(&adev->dev, sizeof(*pdata), GFP_KERNEL);
+			if (!pdata) {
+				ret = -ENOMEM;
+				goto err_no_mem;
+			}
+			/* Provide the default configuration as a base. */
+			memcpy(pdata, &u8500_i2c, sizeof(struct nmk_i2c_controller));
+			nmk_i2c_of_probe(np, pdata);
+		} else
+			/* No i2c configuration found, using the default. */
+			pdata = &u8500_i2c;
+	}
 
 	dev = kzalloc(sizeof(struct nmk_i2c_dev), GFP_KERNEL);
 	if (!dev) {
@@ -957,12 +976,6 @@
 		goto err_irq;
 	}
 
-	dev->regulator = regulator_get(&adev->dev, "v-i2c");
-	if (IS_ERR(dev->regulator)) {
-		dev_warn(&adev->dev, "could not get i2c regulator\n");
-		dev->regulator = NULL;
-	}
-
 	pm_suspend_ignore_children(&adev->dev, true);
 
 	dev->clk = clk_get(&adev->dev, NULL);
@@ -973,6 +986,7 @@
 	}
 
 	adap = &dev->adap;
+	adap->dev.of_node = np;
 	adap->dev.parent = &adev->dev;
 	adap->owner	= THIS_MODULE;
 	adap->class	= I2C_CLASS_HWMON | I2C_CLASS_SPD;
@@ -1002,6 +1016,8 @@
 		goto err_add_adap;
 	}
 
+	of_i2c_register_devices(adap);
+
 	pm_runtime_put(&adev->dev);
 
 	return 0;
@@ -1009,8 +1025,6 @@
  err_add_adap:
 	clk_put(dev->clk);
  err_no_clk:
-	if (dev->regulator)
-		regulator_put(dev->regulator);
 	free_irq(dev->irq, dev);
  err_irq:
 	iounmap(dev->virtbase);
@@ -1038,8 +1052,6 @@
 	if (res)
 		release_mem_region(res->start, resource_size(res));
 	clk_put(dev->clk);
-	if (dev->regulator)
-		regulator_put(dev->regulator);
 	pm_runtime_disable(&adev->dev);
 	amba_set_drvdata(adev, NULL);
 	kfree(dev);
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index a0e49f6..db31eae 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -43,6 +43,7 @@
 #include <linux/slab.h>
 #include <linux/i2c-omap.h>
 #include <linux/pm_runtime.h>
+#include <linux/pm_qos.h>
 
 /* I2C controller revisions */
 #define OMAP_I2C_OMAP1_REV_2		0x20
@@ -55,6 +56,9 @@
 /* timeout waiting for the controller to respond */
 #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000))
 
+/* timeout for pm runtime autosuspend */
+#define OMAP_I2C_PM_TIMEOUT		1000	/* ms */
+
 /* For OMAP3 I2C_IV has changed to I2C_WE (wakeup enable) */
 enum {
 	OMAP_I2C_REV_REG = 0,
@@ -176,15 +180,15 @@
 #define I2C_OMAP_ERRATA_I462		(1 << 1)
 
 struct omap_i2c_dev {
+	spinlock_t		lock;		/* IRQ synchronization */
 	struct device		*dev;
 	void __iomem		*base;		/* virtual */
 	int			irq;
 	int			reg_shift;      /* bit shift for I2C register addresses */
 	struct completion	cmd_complete;
 	struct resource		*ioarea;
-	u32			latency;	/* maximum mpu wkup latency */
-	void			(*set_mpu_wkup_lat)(struct device *dev,
-						    long latency);
+	u32			latency;	/* maximum MPU wkup latency */
+	struct pm_qos_request	pm_qos_request;
 	u32			speed;		/* Speed of bus in kHz */
 	u32			dtrev;		/* extra revision from DT */
 	u32			flags;
@@ -193,12 +197,14 @@
 	u8			*regs;
 	size_t			buf_len;
 	struct i2c_adapter	adapter;
+	u8			threshold;
 	u8			fifo_size;	/* use as flag and value
 						 * fifo_size==0 implies no fifo
 						 * if set, should be trsh+1
 						 */
 	u8			rev;
 	unsigned		b_hw:1;		/* bad h/w fixes */
+	unsigned		receiver:1;	/* true when we're in receiver mode */
 	u16			iestate;	/* Saved interrupt register */
 	u16			pscstate;
 	u16			scllstate;
@@ -417,13 +423,6 @@
 	omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll);
 	omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh);
 
-	if (dev->fifo_size) {
-		/* Note: setup required fifo size - 1. RTRSH and XTRSH */
-		buf = (dev->fifo_size - 1) << 8 | OMAP_I2C_BUF_RXFIF_CLR |
-			(dev->fifo_size - 1) | OMAP_I2C_BUF_TXFIF_CLR;
-		omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf);
-	}
-
 	/* Take the I2C module out of reset: */
 	omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
 
@@ -461,6 +460,43 @@
 	return 0;
 }
 
+static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx)
+{
+	u16		buf;
+
+	if (dev->flags & OMAP_I2C_FLAG_NO_FIFO)
+		return;
+
+	/*
+	 * Set up notification threshold based on message size. We're doing
+	 * this to try and avoid draining feature as much as possible. Whenever
+	 * we have big messages to transfer (bigger than our total fifo size)
+	 * then we might use draining feature to transfer the remaining bytes.
+	 */
+
+	dev->threshold = clamp(size, (u8) 1, dev->fifo_size);
+
+	buf = omap_i2c_read_reg(dev, OMAP_I2C_BUF_REG);
+
+	if (is_rx) {
+		/* Clear RX Threshold */
+		buf &= ~(0x3f << 8);
+		buf |= ((dev->threshold - 1) << 8) | OMAP_I2C_BUF_RXFIF_CLR;
+	} else {
+		/* Clear TX Threshold */
+		buf &= ~0x3f;
+		buf |= (dev->threshold - 1) | OMAP_I2C_BUF_TXFIF_CLR;
+	}
+
+	omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf);
+
+	if (dev->rev < OMAP_I2C_REV_ON_3630_4430)
+		dev->b_hw = 1; /* Enable hardware fixes */
+
+	/* calculate wakeup latency constraint for MPU */
+	dev->latency = (1000000 * dev->threshold) / (1000 * dev->speed / 8);
+}
+
 /*
  * Low level master read/write transaction.
  */
@@ -477,6 +513,9 @@
 	if (msg->len == 0)
 		return -EINVAL;
 
+	dev->receiver = !!(msg->flags & I2C_M_RD);
+	omap_i2c_resize_fifo(dev, msg->len, dev->receiver);
+
 	omap_i2c_write_reg(dev, OMAP_I2C_SA_REG, msg->addr);
 
 	/* REVISIT: Could the STB bit of I2C_CON be used with probing? */
@@ -590,8 +629,16 @@
 	if (r < 0)
 		goto out;
 
-	if (dev->set_mpu_wkup_lat != NULL)
-		dev->set_mpu_wkup_lat(dev->dev, dev->latency);
+	/*
+	 * When waiting for completion of a i2c transfer, we need to
+	 * set a wake up latency constraint for the MPU. This is to
+	 * ensure quick enough wakeup from idle, when transfer
+	 * completes.
+	 */
+	if (dev->latency)
+		pm_qos_add_request(&dev->pm_qos_request,
+				   PM_QOS_CPU_DMA_LATENCY,
+				   dev->latency);
 
 	for (i = 0; i < num; i++) {
 		r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1)));
@@ -599,15 +646,16 @@
 			break;
 	}
 
-	if (dev->set_mpu_wkup_lat != NULL)
-		dev->set_mpu_wkup_lat(dev->dev, -1);
+	if (dev->latency)
+		pm_qos_remove_request(&dev->pm_qos_request);
 
 	if (r == 0)
 		r = num;
 
 	omap_i2c_wait_for_bb(dev);
 out:
-	pm_runtime_put(dev->dev);
+	pm_runtime_mark_last_busy(dev->dev);
+	pm_runtime_put_autosuspend(dev->dev);
 	return r;
 }
 
@@ -725,186 +773,252 @@
  * data to DATA_REG. Otherwise some data bytes can be lost while transferring
  * them from the memory to the I2C interface.
  */
-static int errata_omap3_i462(struct omap_i2c_dev *dev, u16 *stat, int *err)
+static int errata_omap3_i462(struct omap_i2c_dev *dev)
 {
 	unsigned long timeout = 10000;
+	u16 stat;
 
-	while (--timeout && !(*stat & OMAP_I2C_STAT_XUDF)) {
-		if (*stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
-			omap_i2c_ack_stat(dev, *stat & (OMAP_I2C_STAT_XRDY |
+	do {
+		stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
+		if (stat & OMAP_I2C_STAT_XUDF)
+			break;
+
+		if (stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
+			omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY |
 							OMAP_I2C_STAT_XDR));
-			return -ETIMEDOUT;
+			if (stat & OMAP_I2C_STAT_NACK) {
+				dev->cmd_err |= OMAP_I2C_STAT_NACK;
+				omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK);
+			}
+
+			if (stat & OMAP_I2C_STAT_AL) {
+				dev_err(dev->dev, "Arbitration lost\n");
+				dev->cmd_err |= OMAP_I2C_STAT_AL;
+				omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK);
+			}
+
+			return -EIO;
 		}
 
 		cpu_relax();
-		*stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
-	}
+	} while (--timeout);
 
 	if (!timeout) {
 		dev_err(dev->dev, "timeout waiting on XUDF bit\n");
 		return 0;
 	}
 
-	*err |= OMAP_I2C_STAT_XUDF;
+	return 0;
+}
+
+static void omap_i2c_receive_data(struct omap_i2c_dev *dev, u8 num_bytes,
+		bool is_rdr)
+{
+	u16		w;
+
+	while (num_bytes--) {
+		w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
+		*dev->buf++ = w;
+		dev->buf_len--;
+
+		/*
+		 * Data reg in 2430, omap3 and
+		 * omap4 is 8 bit wide
+		 */
+		if (dev->flags & OMAP_I2C_FLAG_16BIT_DATA_REG) {
+			*dev->buf++ = w >> 8;
+			dev->buf_len--;
+		}
+	}
+}
+
+static int omap_i2c_transmit_data(struct omap_i2c_dev *dev, u8 num_bytes,
+		bool is_xdr)
+{
+	u16		w;
+
+	while (num_bytes--) {
+		w = *dev->buf++;
+		dev->buf_len--;
+
+		/*
+		 * Data reg in 2430, omap3 and
+		 * omap4 is 8 bit wide
+		 */
+		if (dev->flags & OMAP_I2C_FLAG_16BIT_DATA_REG) {
+			w |= *dev->buf++ << 8;
+			dev->buf_len--;
+		}
+
+		if (dev->errata & I2C_OMAP_ERRATA_I462) {
+			int ret;
+
+			ret = errata_omap3_i462(dev);
+			if (ret < 0)
+				return ret;
+		}
+
+		omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
+	}
+
 	return 0;
 }
 
 static irqreturn_t
-omap_i2c_isr(int this_irq, void *dev_id)
+omap_i2c_isr(int irq, void *dev_id)
 {
 	struct omap_i2c_dev *dev = dev_id;
+	irqreturn_t ret = IRQ_HANDLED;
+	u16 mask;
+	u16 stat;
+
+	spin_lock(&dev->lock);
+	mask = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
+	stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
+
+	if (stat & mask)
+		ret = IRQ_WAKE_THREAD;
+
+	spin_unlock(&dev->lock);
+
+	return ret;
+}
+
+static irqreturn_t
+omap_i2c_isr_thread(int this_irq, void *dev_id)
+{
+	struct omap_i2c_dev *dev = dev_id;
+	unsigned long flags;
 	u16 bits;
-	u16 stat, w;
-	int err, count = 0;
+	u16 stat;
+	int err = 0, count = 0;
 
-	if (pm_runtime_suspended(dev->dev))
-		return IRQ_NONE;
+	spin_lock_irqsave(&dev->lock, flags);
+	do {
+		bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
+		stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
+		stat &= bits;
 
-	bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
-	while ((stat = (omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG))) & bits) {
+		/* If we're in receiver mode, ignore XDR/XRDY */
+		if (dev->receiver)
+			stat &= ~(OMAP_I2C_STAT_XDR | OMAP_I2C_STAT_XRDY);
+		else
+			stat &= ~(OMAP_I2C_STAT_RDR | OMAP_I2C_STAT_RRDY);
+
+		if (!stat) {
+			/* my work here is done */
+			goto out;
+		}
+
 		dev_dbg(dev->dev, "IRQ (ISR = 0x%04x)\n", stat);
 		if (count++ == 100) {
 			dev_warn(dev->dev, "Too much work in one IRQ\n");
 			break;
 		}
 
-		err = 0;
-complete:
-		/*
-		 * Ack the stat in one go, but [R/X]DR and [R/X]RDY should be
-		 * acked after the data operation is complete.
-		 * Ref: TRM SWPU114Q Figure 18-31
-		 */
-		omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat &
-				~(OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR |
-				OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));
-
-		if (stat & OMAP_I2C_STAT_NACK)
+		if (stat & OMAP_I2C_STAT_NACK) {
 			err |= OMAP_I2C_STAT_NACK;
+			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK);
+			break;
+		}
 
 		if (stat & OMAP_I2C_STAT_AL) {
 			dev_err(dev->dev, "Arbitration lost\n");
 			err |= OMAP_I2C_STAT_AL;
+			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_AL);
+			break;
 		}
+
 		/*
 		 * ProDB0017052: Clear ARDY bit twice
 		 */
 		if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK |
 					OMAP_I2C_STAT_AL)) {
-			omap_i2c_ack_stat(dev, stat &
-				(OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR |
-				OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR |
-				OMAP_I2C_STAT_ARDY));
-			omap_i2c_complete_cmd(dev, err);
-			return IRQ_HANDLED;
+			omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY |
+						OMAP_I2C_STAT_RDR |
+						OMAP_I2C_STAT_XRDY |
+						OMAP_I2C_STAT_XDR |
+						OMAP_I2C_STAT_ARDY));
+			break;
 		}
-		if (stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) {
+
+		if (stat & OMAP_I2C_STAT_RDR) {
 			u8 num_bytes = 1;
 
+			if (dev->fifo_size)
+				num_bytes = dev->buf_len;
+
+			omap_i2c_receive_data(dev, num_bytes, true);
+
 			if (dev->errata & I2C_OMAP_ERRATA_I207)
 				i2c_omap_errata_i207(dev, stat);
 
-			if (dev->fifo_size) {
-				if (stat & OMAP_I2C_STAT_RRDY)
-					num_bytes = dev->fifo_size;
-				else    /* read RXSTAT on RDR interrupt */
-					num_bytes = (omap_i2c_read_reg(dev,
-							OMAP_I2C_BUFSTAT_REG)
-							>> 8) & 0x3F;
-			}
-			while (num_bytes) {
-				num_bytes--;
-				w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
-				if (dev->buf_len) {
-					*dev->buf++ = w;
-					dev->buf_len--;
-					/*
-					 * Data reg in 2430, omap3 and
-					 * omap4 is 8 bit wide
-					 */
-					if (dev->flags &
-						 OMAP_I2C_FLAG_16BIT_DATA_REG) {
-						if (dev->buf_len) {
-							*dev->buf++ = w >> 8;
-							dev->buf_len--;
-						}
-					}
-				} else {
-					if (stat & OMAP_I2C_STAT_RRDY)
-						dev_err(dev->dev,
-							"RRDY IRQ while no data"
-								" requested\n");
-					if (stat & OMAP_I2C_STAT_RDR)
-						dev_err(dev->dev,
-							"RDR IRQ while no data"
-								" requested\n");
-					break;
-				}
-			}
-			omap_i2c_ack_stat(dev,
-				stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR));
-			continue;
+			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RDR);
+			break;
 		}
-		if (stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)) {
+
+		if (stat & OMAP_I2C_STAT_RRDY) {
 			u8 num_bytes = 1;
-			if (dev->fifo_size) {
-				if (stat & OMAP_I2C_STAT_XRDY)
-					num_bytes = dev->fifo_size;
-				else    /* read TXSTAT on XDR interrupt */
-					num_bytes = omap_i2c_read_reg(dev,
-							OMAP_I2C_BUFSTAT_REG)
-							& 0x3F;
-			}
-			while (num_bytes) {
-				num_bytes--;
-				w = 0;
-				if (dev->buf_len) {
-					w = *dev->buf++;
-					dev->buf_len--;
-					/*
-					 * Data reg in 2430, omap3 and
-					 * omap4 is 8 bit wide
-					 */
-					if (dev->flags &
-						 OMAP_I2C_FLAG_16BIT_DATA_REG) {
-						if (dev->buf_len) {
-							w |= *dev->buf++ << 8;
-							dev->buf_len--;
-						}
-					}
-				} else {
-					if (stat & OMAP_I2C_STAT_XRDY)
-						dev_err(dev->dev,
-							"XRDY IRQ while no "
-							"data to send\n");
-					if (stat & OMAP_I2C_STAT_XDR)
-						dev_err(dev->dev,
-							"XDR IRQ while no "
-							"data to send\n");
-					break;
-				}
 
-				if ((dev->errata & I2C_OMAP_ERRATA_I462) &&
-				    errata_omap3_i462(dev, &stat, &err))
-					goto complete;
+			if (dev->threshold)
+				num_bytes = dev->threshold;
 
-				omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
-			}
-			omap_i2c_ack_stat(dev,
-				stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));
+			omap_i2c_receive_data(dev, num_bytes, false);
+			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RRDY);
 			continue;
 		}
+
+		if (stat & OMAP_I2C_STAT_XDR) {
+			u8 num_bytes = 1;
+			int ret;
+
+			if (dev->fifo_size)
+				num_bytes = dev->buf_len;
+
+			ret = omap_i2c_transmit_data(dev, num_bytes, true);
+			if (ret < 0)
+				break;
+
+			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XDR);
+			break;
+		}
+
+		if (stat & OMAP_I2C_STAT_XRDY) {
+			u8 num_bytes = 1;
+			int ret;
+
+			if (dev->threshold)
+				num_bytes = dev->threshold;
+
+			ret = omap_i2c_transmit_data(dev, num_bytes, false);
+			if (ret < 0)
+				break;
+
+			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XRDY);
+			continue;
+		}
+
 		if (stat & OMAP_I2C_STAT_ROVR) {
 			dev_err(dev->dev, "Receive overrun\n");
-			dev->cmd_err |= OMAP_I2C_STAT_ROVR;
+			err |= OMAP_I2C_STAT_ROVR;
+			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_ROVR);
+			break;
 		}
+
 		if (stat & OMAP_I2C_STAT_XUDF) {
 			dev_err(dev->dev, "Transmit underflow\n");
-			dev->cmd_err |= OMAP_I2C_STAT_XUDF;
+			err |= OMAP_I2C_STAT_XUDF;
+			omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XUDF);
+			break;
 		}
-	}
+	} while (stat);
 
-	return count ? IRQ_HANDLED : IRQ_NONE;
+	omap_i2c_complete_cmd(dev, err);
+
+out:
+	spin_unlock_irqrestore(&dev->lock, flags);
+
+	return IRQ_HANDLED;
 }
 
 static const struct i2c_algorithm omap_i2c_algo = {
@@ -943,12 +1057,12 @@
 {
 	struct omap_i2c_dev	*dev;
 	struct i2c_adapter	*adap;
-	struct resource		*mem, *irq, *ioarea;
+	struct resource		*mem;
 	const struct omap_i2c_bus_platform_data *pdata =
 		pdev->dev.platform_data;
 	struct device_node	*node = pdev->dev.of_node;
 	const struct of_device_id *match;
-	irq_handler_t isr;
+	int irq;
 	int r;
 
 	/* NOTE: driver uses the static register mapping */
@@ -957,23 +1071,23 @@
 		dev_err(&pdev->dev, "no mem resource?\n");
 		return -ENODEV;
 	}
-	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!irq) {
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
 		dev_err(&pdev->dev, "no irq resource?\n");
-		return -ENODEV;
+		return irq;
 	}
 
-	ioarea = request_mem_region(mem->start, resource_size(mem),
-			pdev->name);
-	if (!ioarea) {
-		dev_err(&pdev->dev, "I2C region already claimed\n");
-		return -EBUSY;
-	}
-
-	dev = kzalloc(sizeof(struct omap_i2c_dev), GFP_KERNEL);
+	dev = devm_kzalloc(&pdev->dev, sizeof(struct omap_i2c_dev), GFP_KERNEL);
 	if (!dev) {
-		r = -ENOMEM;
-		goto err_release_region;
+		dev_err(&pdev->dev, "Menory allocation failed\n");
+		return -ENOMEM;
+	}
+
+	dev->base = devm_request_and_ioremap(&pdev->dev, mem);
+	if (!dev->base) {
+		dev_err(&pdev->dev, "I2C region already claimed\n");
+		return -ENOMEM;
 	}
 
 	match = of_match_device(of_match_ptr(omap_i2c_of_match), &pdev->dev);
@@ -990,17 +1104,13 @@
 	} else if (pdata != NULL) {
 		dev->speed = pdata->clkrate;
 		dev->flags = pdata->flags;
-		dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
 		dev->dtrev = pdata->rev;
 	}
 
 	dev->dev = &pdev->dev;
-	dev->irq = irq->start;
-	dev->base = ioremap(mem->start, resource_size(mem));
-	if (!dev->base) {
-		r = -ENOMEM;
-		goto err_free_mem;
-	}
+	dev->irq = irq;
+
+	spin_lock_init(&dev->lock);
 
 	platform_set_drvdata(pdev, dev);
 	init_completion(&dev->cmd_complete);
@@ -1013,6 +1123,9 @@
 		dev->regs = (u8 *)reg_map_ip_v1;
 
 	pm_runtime_enable(dev->dev);
+	pm_runtime_set_autosuspend_delay(dev->dev, OMAP_I2C_PM_TIMEOUT);
+	pm_runtime_use_autosuspend(dev->dev);
+
 	r = pm_runtime_get_sync(dev->dev);
 	if (IS_ERR_VALUE(r))
 		goto err_free_mem;
@@ -1042,32 +1155,31 @@
 
 		dev->fifo_size = (dev->fifo_size / 2);
 
-		if (dev->rev >= OMAP_I2C_REV_ON_3630_4430)
-			dev->b_hw = 0; /* Disable hardware fixes */
-		else
+		if (dev->rev < OMAP_I2C_REV_ON_3630_4430)
 			dev->b_hw = 1; /* Enable hardware fixes */
 
 		/* calculate wakeup latency constraint for MPU */
-		if (dev->set_mpu_wkup_lat != NULL)
-			dev->latency = (1000000 * dev->fifo_size) /
-				       (1000 * dev->speed / 8);
+		dev->latency = (1000000 * dev->fifo_size) /
+			       (1000 * dev->speed / 8);
 	}
 
 	/* reset ASAP, clearing any IRQs */
 	omap_i2c_init(dev);
 
-	isr = (dev->rev < OMAP_I2C_OMAP1_REV_2) ? omap_i2c_omap1_isr :
-								   omap_i2c_isr;
-	r = request_irq(dev->irq, isr, IRQF_NO_SUSPEND, pdev->name, dev);
+	if (dev->rev < OMAP_I2C_OMAP1_REV_2)
+		r = devm_request_irq(&pdev->dev, dev->irq, omap_i2c_omap1_isr,
+				IRQF_NO_SUSPEND, pdev->name, dev);
+	else
+		r = devm_request_threaded_irq(&pdev->dev, dev->irq,
+				omap_i2c_isr, omap_i2c_isr_thread,
+				IRQF_NO_SUSPEND | IRQF_ONESHOT,
+				pdev->name, dev);
 
 	if (r) {
 		dev_err(dev->dev, "failure requesting irq %i\n", dev->irq);
 		goto err_unuse_clocks;
 	}
 
-	dev_info(dev->dev, "bus %d rev%d.%d.%d at %d kHz\n", pdev->id,
-		 dev->dtrev, dev->rev >> 4, dev->rev & 0xf, dev->speed);
-
 	adap = &dev->adapter;
 	i2c_set_adapdata(adap, dev);
 	adap->owner = THIS_MODULE;
@@ -1082,27 +1194,25 @@
 	r = i2c_add_numbered_adapter(adap);
 	if (r) {
 		dev_err(dev->dev, "failure adding adapter\n");
-		goto err_free_irq;
+		goto err_unuse_clocks;
 	}
 
+	dev_info(dev->dev, "bus %d rev%d.%d.%d at %d kHz\n", adap->nr,
+		 dev->dtrev, dev->rev >> 4, dev->rev & 0xf, dev->speed);
+
 	of_i2c_register_devices(adap);
 
-	pm_runtime_put(dev->dev);
+	pm_runtime_mark_last_busy(dev->dev);
+	pm_runtime_put_autosuspend(dev->dev);
 
 	return 0;
 
-err_free_irq:
-	free_irq(dev->irq, dev);
 err_unuse_clocks:
 	omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
 	pm_runtime_put(dev->dev);
-	iounmap(dev->base);
 	pm_runtime_disable(&pdev->dev);
 err_free_mem:
 	platform_set_drvdata(pdev, NULL);
-	kfree(dev);
-err_release_region:
-	release_mem_region(mem->start, resource_size(mem));
 
 	return r;
 }
@@ -1110,12 +1220,10 @@
 static int __devexit omap_i2c_remove(struct platform_device *pdev)
 {
 	struct omap_i2c_dev	*dev = platform_get_drvdata(pdev);
-	struct resource		*mem;
 	int ret;
 
 	platform_set_drvdata(pdev, NULL);
 
-	free_irq(dev->irq, dev);
 	i2c_del_adapter(&dev->adapter);
 	ret = pm_runtime_get_sync(&pdev->dev);
 	if (IS_ERR_VALUE(ret))
@@ -1124,10 +1232,6 @@
 	omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
 	pm_runtime_put(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
-	iounmap(dev->base);
-	kfree(dev);
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	release_mem_region(mem->start, resource_size(mem));
 	return 0;
 }
 
diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c
index 2456568..81d8878 100644
--- a/drivers/i2c/busses/i2c-parport.c
+++ b/drivers/i2c/busses/i2c-parport.c
@@ -151,7 +151,7 @@
 
 /* ----- I2c and parallel port call-back functions and structures --------- */
 
-void i2c_parport_irq(void *data)
+static void i2c_parport_irq(void *data)
 {
 	struct i2c_par *adapter = data;
 	struct i2c_client *ara = adapter->ara;
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index ef511df..8bbd6ec 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -37,6 +37,7 @@
 #include <linux/stddef.h>
 #include <linux/ioport.h>
 #include <linux/i2c.h>
+#include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/dmi.h>
 #include <linux/acpi.h>
diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c
new file mode 100644
index 0000000..f9399d1
--- /dev/null
+++ b/drivers/i2c/busses/i2c-rcar.c
@@ -0,0 +1,709 @@
+/*
+ *  drivers/i2c/busses/i2c-rcar.c
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * This file is based on the drivers/i2c/busses/i2c-sh7760.c
+ * (c) 2005-2008 MSC Vertriebsges.m.b.H, Manuel Lauss <mlau@msc-ge.com>
+ *
+ * This file used out-of-tree driver i2c-rcar.c
+ * Copyright (C) 2011-2012 Renesas Electronics Corporation
+ *
+ * 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
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/i2c/i2c-rcar.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+/* register offsets */
+#define ICSCR	0x00	/* slave ctrl */
+#define ICMCR	0x04	/* master ctrl */
+#define ICSSR	0x08	/* slave status */
+#define ICMSR	0x0C	/* master status */
+#define ICSIER	0x10	/* slave irq enable */
+#define ICMIER	0x14	/* master irq enable */
+#define ICCCR	0x18	/* clock dividers */
+#define ICSAR	0x1C	/* slave address */
+#define ICMAR	0x20	/* master address */
+#define ICRXTX	0x24	/* data port */
+
+/* ICMCR */
+#define MDBS	(1 << 7)	/* non-fifo mode switch */
+#define FSCL	(1 << 6)	/* override SCL pin */
+#define FSDA	(1 << 5)	/* override SDA pin */
+#define OBPC	(1 << 4)	/* override pins */
+#define MIE	(1 << 3)	/* master if enable */
+#define TSBE	(1 << 2)
+#define FSB	(1 << 1)	/* force stop bit */
+#define ESG	(1 << 0)	/* en startbit gen */
+
+/* ICMSR */
+#define MNR	(1 << 6)	/* nack received */
+#define MAL	(1 << 5)	/* arbitration lost */
+#define MST	(1 << 4)	/* sent a stop */
+#define MDE	(1 << 3)
+#define MDT	(1 << 2)
+#define MDR	(1 << 1)
+#define MAT	(1 << 0)	/* slave addr xfer done */
+
+/* ICMIE */
+#define MNRE	(1 << 6)	/* nack irq en */
+#define MALE	(1 << 5)	/* arblos irq en */
+#define MSTE	(1 << 4)	/* stop irq en */
+#define MDEE	(1 << 3)
+#define MDTE	(1 << 2)
+#define MDRE	(1 << 1)
+#define MATE	(1 << 0)	/* address sent irq en */
+
+
+enum {
+	RCAR_BUS_PHASE_ADDR,
+	RCAR_BUS_PHASE_DATA,
+	RCAR_BUS_PHASE_STOP,
+};
+
+enum {
+	RCAR_IRQ_CLOSE,
+	RCAR_IRQ_OPEN_FOR_SEND,
+	RCAR_IRQ_OPEN_FOR_RECV,
+	RCAR_IRQ_OPEN_FOR_STOP,
+};
+
+/*
+ * flags
+ */
+#define ID_LAST_MSG	(1 << 0)
+#define ID_IOERROR	(1 << 1)
+#define ID_DONE		(1 << 2)
+#define ID_ARBLOST	(1 << 3)
+#define ID_NACK		(1 << 4)
+
+struct rcar_i2c_priv {
+	void __iomem *io;
+	struct i2c_adapter adap;
+	struct i2c_msg	*msg;
+
+	spinlock_t lock;
+	wait_queue_head_t wait;
+
+	int pos;
+	int irq;
+	u32 icccr;
+	u32 flags;
+};
+
+#define rcar_i2c_priv_to_dev(p)		((p)->adap.dev.parent)
+#define rcar_i2c_is_recv(p)		((p)->msg->flags & I2C_M_RD)
+
+#define rcar_i2c_flags_set(p, f)	((p)->flags |= (f))
+#define rcar_i2c_flags_has(p, f)	((p)->flags & (f))
+
+#define LOOP_TIMEOUT	1024
+
+/*
+ *		basic functions
+ */
+static void rcar_i2c_write(struct rcar_i2c_priv *priv, int reg, u32 val)
+{
+	writel(val, priv->io + reg);
+}
+
+static u32 rcar_i2c_read(struct rcar_i2c_priv *priv, int reg)
+{
+	return readl(priv->io + reg);
+}
+
+static void rcar_i2c_init(struct rcar_i2c_priv *priv)
+{
+	/*
+	 * reset slave mode.
+	 * slave mode is not used on this driver
+	 */
+	rcar_i2c_write(priv, ICSIER, 0);
+	rcar_i2c_write(priv, ICSAR, 0);
+	rcar_i2c_write(priv, ICSCR, 0);
+	rcar_i2c_write(priv, ICSSR, 0);
+
+	/* reset master mode */
+	rcar_i2c_write(priv, ICMIER, 0);
+	rcar_i2c_write(priv, ICMCR, 0);
+	rcar_i2c_write(priv, ICMSR, 0);
+	rcar_i2c_write(priv, ICMAR, 0);
+}
+
+static void rcar_i2c_irq_mask(struct rcar_i2c_priv *priv, int open)
+{
+	u32 val = MNRE | MALE | MSTE | MATE; /* default */
+
+	switch (open) {
+	case RCAR_IRQ_OPEN_FOR_SEND:
+		val |= MDEE; /* default + send */
+		break;
+	case RCAR_IRQ_OPEN_FOR_RECV:
+		val |= MDRE; /* default + read */
+		break;
+	case RCAR_IRQ_OPEN_FOR_STOP:
+		val = MSTE; /* stop irq only */
+		break;
+	case RCAR_IRQ_CLOSE:
+	default:
+		val = 0; /* all close */
+		break;
+	}
+	rcar_i2c_write(priv, ICMIER, val);
+}
+
+static void rcar_i2c_set_addr(struct rcar_i2c_priv *priv, u32 recv)
+{
+	rcar_i2c_write(priv, ICMAR, (priv->msg->addr << 1) | recv);
+}
+
+/*
+ *		bus control functions
+ */
+static int rcar_i2c_bus_barrier(struct rcar_i2c_priv *priv)
+{
+	int i;
+
+	for (i = 0; i < LOOP_TIMEOUT; i++) {
+		/* make sure that bus is not busy */
+		if (!(rcar_i2c_read(priv, ICMCR) & FSDA))
+			return 0;
+		udelay(1);
+	}
+
+	return -EBUSY;
+}
+
+static void rcar_i2c_bus_phase(struct rcar_i2c_priv *priv, int phase)
+{
+	switch (phase) {
+	case RCAR_BUS_PHASE_ADDR:
+		rcar_i2c_write(priv, ICMCR, MDBS | MIE | ESG);
+		break;
+	case RCAR_BUS_PHASE_DATA:
+		rcar_i2c_write(priv, ICMCR, MDBS | MIE);
+		break;
+	case RCAR_BUS_PHASE_STOP:
+		rcar_i2c_write(priv, ICMCR, MDBS | MIE | FSB);
+		break;
+	}
+}
+
+/*
+ *		clock function
+ */
+static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv,
+				    u32 bus_speed,
+				    struct device *dev)
+{
+	struct clk *clkp = clk_get(NULL, "peripheral_clk");
+	u32 scgd, cdf;
+	u32 round, ick;
+	u32 scl;
+
+	if (!clkp) {
+		dev_err(dev, "there is no peripheral_clk\n");
+		return -EIO;
+	}
+
+	/*
+	 * calculate SCL clock
+	 * see
+	 *	ICCCR
+	 *
+	 * ick	= clkp / (1 + CDF)
+	 * SCL	= ick / (20 + SCGD * 8 + F[(ticf + tr + intd) * ick])
+	 *
+	 * ick  : I2C internal clock < 20 MHz
+	 * ticf : I2C SCL falling time  =  35 ns here
+	 * tr   : I2C SCL rising  time  = 200 ns here
+	 * intd : LSI internal delay    =  50 ns here
+	 * clkp : peripheral_clk
+	 * F[]  : integer up-valuation
+	 */
+	for (cdf = 0; cdf < 4; cdf++) {
+		ick = clk_get_rate(clkp) / (1 + cdf);
+		if (ick < 20000000)
+			goto ick_find;
+	}
+	dev_err(dev, "there is no best CDF\n");
+	return -EIO;
+
+ick_find:
+	/*
+	 * it is impossible to calculate large scale
+	 * number on u32. separate it
+	 *
+	 * F[(ticf + tr + intd) * ick]
+	 *  = F[(35 + 200 + 50)ns * ick]
+	 *  = F[285 * ick / 1000000000]
+	 *  = F[(ick / 1000000) * 285 / 1000]
+	 */
+	round = (ick + 500000) / 1000000 * 285;
+	round = (round + 500) / 1000;
+
+	/*
+	 * SCL	= ick / (20 + SCGD * 8 + F[(ticf + tr + intd) * ick])
+	 *
+	 * Calculation result (= SCL) should be less than
+	 * bus_speed for hardware safety
+	 */
+	for (scgd = 0; scgd < 0x40; scgd++) {
+		scl = ick / (20 + (scgd * 8) + round);
+		if (scl <= bus_speed)
+			goto scgd_find;
+	}
+	dev_err(dev, "it is impossible to calculate best SCL\n");
+	return -EIO;
+
+scgd_find:
+	dev_dbg(dev, "clk %d/%d(%lu), round %u, CDF:0x%x, SCGD: 0x%x\n",
+		scl, bus_speed, clk_get_rate(clkp), round, cdf, scgd);
+
+	/*
+	 * keep icccr value
+	 */
+	priv->icccr = (scgd << 2 | cdf);
+
+	return 0;
+}
+
+static void rcar_i2c_clock_start(struct rcar_i2c_priv *priv)
+{
+	rcar_i2c_write(priv, ICCCR, priv->icccr);
+}
+
+/*
+ *		status functions
+ */
+static u32 rcar_i2c_status_get(struct rcar_i2c_priv *priv)
+{
+	return rcar_i2c_read(priv, ICMSR);
+}
+
+#define rcar_i2c_status_clear(priv) rcar_i2c_status_bit_clear(priv, 0xffffffff)
+static void rcar_i2c_status_bit_clear(struct rcar_i2c_priv *priv, u32 bit)
+{
+	rcar_i2c_write(priv, ICMSR, ~bit);
+}
+
+/*
+ *		recv/send functions
+ */
+static int rcar_i2c_recv(struct rcar_i2c_priv *priv)
+{
+	rcar_i2c_set_addr(priv, 1);
+	rcar_i2c_status_clear(priv);
+	rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_ADDR);
+	rcar_i2c_irq_mask(priv, RCAR_IRQ_OPEN_FOR_RECV);
+
+	return 0;
+}
+
+static int rcar_i2c_send(struct rcar_i2c_priv *priv)
+{
+	int ret;
+
+	/*
+	 * It should check bus status when send case
+	 */
+	ret = rcar_i2c_bus_barrier(priv);
+	if (ret < 0)
+		return ret;
+
+	rcar_i2c_set_addr(priv, 0);
+	rcar_i2c_status_clear(priv);
+	rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_ADDR);
+	rcar_i2c_irq_mask(priv, RCAR_IRQ_OPEN_FOR_SEND);
+
+	return 0;
+}
+
+#define rcar_i2c_send_restart(priv) rcar_i2c_status_bit_clear(priv, (MAT | MDE))
+#define rcar_i2c_recv_restart(priv) rcar_i2c_status_bit_clear(priv, (MAT | MDR))
+
+/*
+ *		interrupt functions
+ */
+static int rcar_i2c_irq_send(struct rcar_i2c_priv *priv, u32 msr)
+{
+	struct i2c_msg *msg = priv->msg;
+
+	/*
+	 * FIXME
+	 * sometimes, unknown interrupt happened.
+	 * Do nothing
+	 */
+	if (!(msr & MDE))
+		return 0;
+
+	/*
+	 * If address transfer phase finished,
+	 * goto data phase.
+	 */
+	if (msr & MAT)
+		rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_DATA);
+
+	if (priv->pos < msg->len) {
+		/*
+		 * Prepare next data to ICRXTX register.
+		 * This data will go to _SHIFT_ register.
+		 *
+		 *    *
+		 * [ICRXTX] -> [SHIFT] -> [I2C bus]
+		 */
+		rcar_i2c_write(priv, ICRXTX, msg->buf[priv->pos]);
+		priv->pos++;
+
+	} else {
+		/*
+		 * The last data was pushed to ICRXTX on _PREV_ empty irq.
+		 * It is on _SHIFT_ register, and will sent to I2C bus.
+		 *
+		 *		  *
+		 * [ICRXTX] -> [SHIFT] -> [I2C bus]
+		 */
+
+		if (priv->flags & ID_LAST_MSG)
+			/*
+			 * If current msg is the _LAST_ msg,
+			 * prepare stop condition here.
+			 * ID_DONE will be set on STOP irq.
+			 */
+			rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_STOP);
+		else
+			/*
+			 * If current msg is _NOT_ last msg,
+			 * it doesn't call stop phase.
+			 * thus, there is no STOP irq.
+			 * return ID_DONE here.
+			 */
+			return ID_DONE;
+	}
+
+	rcar_i2c_send_restart(priv);
+
+	return 0;
+}
+
+static int rcar_i2c_irq_recv(struct rcar_i2c_priv *priv, u32 msr)
+{
+	struct i2c_msg *msg = priv->msg;
+
+	/*
+	 * FIXME
+	 * sometimes, unknown interrupt happened.
+	 * Do nothing
+	 */
+	if (!(msr & MDR))
+		return 0;
+
+	if (msr & MAT) {
+		/*
+		 * Address transfer phase finished,
+		 * but, there is no data at this point.
+		 * Do nothing.
+		 */
+	} else if (priv->pos < msg->len) {
+		/*
+		 * get received data
+		 */
+		msg->buf[priv->pos] = rcar_i2c_read(priv, ICRXTX);
+		priv->pos++;
+	}
+
+	/*
+	 * If next received data is the _LAST_,
+	 * go to STOP phase,
+	 * otherwise, go to DATA phase.
+	 */
+	if (priv->pos + 1 >= msg->len)
+		rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_STOP);
+	else
+		rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_DATA);
+
+	rcar_i2c_recv_restart(priv);
+
+	return 0;
+}
+
+static irqreturn_t rcar_i2c_irq(int irq, void *ptr)
+{
+	struct rcar_i2c_priv *priv = ptr;
+	struct device *dev = rcar_i2c_priv_to_dev(priv);
+	u32 msr;
+
+	/*-------------- spin lock -----------------*/
+	spin_lock(&priv->lock);
+
+	msr = rcar_i2c_status_get(priv);
+
+	/*
+	 * Arbitration lost
+	 */
+	if (msr & MAL) {
+		/*
+		 * CAUTION
+		 *
+		 * When arbitration lost, device become _slave_ mode.
+		 */
+		dev_dbg(dev, "Arbitration Lost\n");
+		rcar_i2c_flags_set(priv, (ID_DONE | ID_ARBLOST));
+		goto out;
+	}
+
+	/*
+	 * Stop
+	 */
+	if (msr & MST) {
+		dev_dbg(dev, "Stop\n");
+		rcar_i2c_flags_set(priv, ID_DONE);
+		goto out;
+	}
+
+	/*
+	 * Nack
+	 */
+	if (msr & MNR) {
+		dev_dbg(dev, "Nack\n");
+
+		/* go to stop phase */
+		rcar_i2c_bus_phase(priv, RCAR_BUS_PHASE_STOP);
+		rcar_i2c_irq_mask(priv, RCAR_IRQ_OPEN_FOR_STOP);
+		rcar_i2c_flags_set(priv, ID_NACK);
+		goto out;
+	}
+
+	/*
+	 * recv/send
+	 */
+	if (rcar_i2c_is_recv(priv))
+		rcar_i2c_flags_set(priv, rcar_i2c_irq_recv(priv, msr));
+	else
+		rcar_i2c_flags_set(priv, rcar_i2c_irq_send(priv, msr));
+
+out:
+	if (rcar_i2c_flags_has(priv, ID_DONE)) {
+		rcar_i2c_irq_mask(priv, RCAR_IRQ_CLOSE);
+		rcar_i2c_status_clear(priv);
+		wake_up(&priv->wait);
+	}
+
+	spin_unlock(&priv->lock);
+	/*-------------- spin unlock -----------------*/
+
+	return IRQ_HANDLED;
+}
+
+static int rcar_i2c_master_xfer(struct i2c_adapter *adap,
+				struct i2c_msg *msgs,
+				int num)
+{
+	struct rcar_i2c_priv *priv = i2c_get_adapdata(adap);
+	struct device *dev = rcar_i2c_priv_to_dev(priv);
+	unsigned long flags;
+	int i, ret, timeout;
+
+	pm_runtime_get_sync(dev);
+
+	/*-------------- spin lock -----------------*/
+	spin_lock_irqsave(&priv->lock, flags);
+
+	rcar_i2c_init(priv);
+	rcar_i2c_clock_start(priv);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+	/*-------------- spin unlock -----------------*/
+
+	ret = -EINVAL;
+	for (i = 0; i < num; i++) {
+		/*-------------- spin lock -----------------*/
+		spin_lock_irqsave(&priv->lock, flags);
+
+		/* init each data */
+		priv->msg	= &msgs[i];
+		priv->pos	= 0;
+		priv->flags	= 0;
+		if (priv->msg == &msgs[num - 1])
+			rcar_i2c_flags_set(priv, ID_LAST_MSG);
+
+		/* start send/recv */
+		if (rcar_i2c_is_recv(priv))
+			ret = rcar_i2c_recv(priv);
+		else
+			ret = rcar_i2c_send(priv);
+
+		spin_unlock_irqrestore(&priv->lock, flags);
+		/*-------------- spin unlock -----------------*/
+
+		if (ret < 0)
+			break;
+
+		/*
+		 * wait result
+		 */
+		timeout = wait_event_timeout(priv->wait,
+					     rcar_i2c_flags_has(priv, ID_DONE),
+					     5 * HZ);
+		if (!timeout) {
+			ret = -ETIMEDOUT;
+			break;
+		}
+
+		/*
+		 * error handling
+		 */
+		if (rcar_i2c_flags_has(priv, ID_NACK)) {
+			ret = -EREMOTEIO;
+			break;
+		}
+
+		if (rcar_i2c_flags_has(priv, ID_ARBLOST)) {
+			ret = -EAGAIN;
+			break;
+		}
+
+		if (rcar_i2c_flags_has(priv, ID_IOERROR)) {
+			ret = -EIO;
+			break;
+		}
+
+		ret = i + 1; /* The number of transfer */
+	}
+
+	pm_runtime_put(dev);
+
+	if (ret < 0)
+		dev_err(dev, "error %d : %x\n", ret, priv->flags);
+
+	return ret;
+}
+
+static u32 rcar_i2c_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm rcar_i2c_algo = {
+	.master_xfer	= rcar_i2c_master_xfer,
+	.functionality	= rcar_i2c_func,
+};
+
+static int __devinit rcar_i2c_probe(struct platform_device *pdev)
+{
+	struct i2c_rcar_platform_data *pdata = pdev->dev.platform_data;
+	struct rcar_i2c_priv *priv;
+	struct i2c_adapter *adap;
+	struct resource *res;
+	struct device *dev = &pdev->dev;
+	u32 bus_speed;
+	int ret;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "no mmio resources\n");
+		return -ENODEV;
+	}
+
+	priv = devm_kzalloc(dev, sizeof(struct rcar_i2c_priv), GFP_KERNEL);
+	if (!priv) {
+		dev_err(dev, "no mem for private data\n");
+		return -ENOMEM;
+	}
+
+	bus_speed = 100000; /* default 100 kHz */
+	if (pdata && pdata->bus_speed)
+		bus_speed = pdata->bus_speed;
+	ret = rcar_i2c_clock_calculate(priv, bus_speed, dev);
+	if (ret < 0)
+		return ret;
+
+	priv->io = devm_ioremap(dev, res->start, resource_size(res));
+	if (!priv->io) {
+		dev_err(dev, "cannot ioremap\n");
+		return -ENODEV;
+	}
+
+	priv->irq = platform_get_irq(pdev, 0);
+	init_waitqueue_head(&priv->wait);
+	spin_lock_init(&priv->lock);
+
+	adap			= &priv->adap;
+	adap->nr		= pdev->id;
+	adap->algo		= &rcar_i2c_algo;
+	adap->class		= I2C_CLASS_HWMON | I2C_CLASS_SPD;
+	adap->retries		= 3;
+	adap->dev.parent	= dev;
+	i2c_set_adapdata(adap, priv);
+	strlcpy(adap->name, pdev->name, sizeof(adap->name));
+
+	ret = devm_request_irq(dev, priv->irq, rcar_i2c_irq, 0,
+			       dev_name(dev), priv);
+	if (ret < 0) {
+		dev_err(dev, "cannot get irq %d\n", priv->irq);
+		return ret;
+	}
+
+	ret = i2c_add_numbered_adapter(adap);
+	if (ret < 0) {
+		dev_err(dev, "reg adap failed: %d\n", ret);
+		return ret;
+	}
+
+	pm_runtime_enable(dev);
+	platform_set_drvdata(pdev, priv);
+
+	dev_info(dev, "probed\n");
+
+	return 0;
+}
+
+static int __devexit rcar_i2c_remove(struct platform_device *pdev)
+{
+	struct rcar_i2c_priv *priv = platform_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+
+	i2c_del_adapter(&priv->adap);
+	pm_runtime_disable(dev);
+
+	return 0;
+}
+
+static struct platform_driver rcar_i2c_drv = {
+	.driver	= {
+		.name	= "i2c-rcar",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= rcar_i2c_probe,
+	.remove		= __devexit_p(rcar_i2c_remove),
+};
+
+module_platform_driver(rcar_i2c_drv);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Renesas R-Car I2C bus driver");
+MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 4d07dea..3e0335f1 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -601,14 +601,14 @@
 	int ret;
 
 	pm_runtime_get_sync(&adap->dev);
-	clk_enable(i2c->clk);
+	clk_prepare_enable(i2c->clk);
 
 	for (retry = 0; retry < adap->retries; retry++) {
 
 		ret = s3c24xx_i2c_doxfer(i2c, msgs, num);
 
 		if (ret != -EAGAIN) {
-			clk_disable(i2c->clk);
+			clk_disable_unprepare(i2c->clk);
 			pm_runtime_put(&adap->dev);
 			return ret;
 		}
@@ -618,7 +618,7 @@
 		udelay(100);
 	}
 
-	clk_disable(i2c->clk);
+	clk_disable_unprepare(i2c->clk);
 	pm_runtime_put(&adap->dev);
 	return -EREMOTEIO;
 }
@@ -977,7 +977,7 @@
 
 	dev_dbg(&pdev->dev, "clock source %p\n", i2c->clk);
 
-	clk_enable(i2c->clk);
+	clk_prepare_enable(i2c->clk);
 
 	/* map the registers */
 
@@ -1065,7 +1065,7 @@
 	pm_runtime_enable(&i2c->adap.dev);
 
 	dev_info(&pdev->dev, "%s: S3C I2C adapter\n", dev_name(&i2c->adap.dev));
-	clk_disable(i2c->clk);
+	clk_disable_unprepare(i2c->clk);
 	return 0;
 
  err_cpufreq:
@@ -1082,7 +1082,7 @@
 	kfree(i2c->ioarea);
 
  err_clk:
-	clk_disable(i2c->clk);
+	clk_disable_unprepare(i2c->clk);
 	clk_put(i2c->clk);
 
  err_noclk:
@@ -1106,7 +1106,7 @@
 	i2c_del_adapter(&i2c->adap);
 	free_irq(i2c->irq, i2c);
 
-	clk_disable(i2c->clk);
+	clk_disable_unprepare(i2c->clk);
 	clk_put(i2c->clk);
 
 	iounmap(i2c->regs);
@@ -1135,9 +1135,9 @@
 	struct s3c24xx_i2c *i2c = platform_get_drvdata(pdev);
 
 	i2c->suspended = 0;
-	clk_enable(i2c->clk);
+	clk_prepare_enable(i2c->clk);
 	s3c24xx_i2c_init(i2c);
-	clk_disable(i2c->clk);
+	clk_disable_unprepare(i2c->clk);
 
 	return 0;
 }
diff --git a/drivers/i2c/busses/i2c-scmi.c b/drivers/i2c/busses/i2c-scmi.c
index 388cbdc..6aafa3d 100644
--- a/drivers/i2c/busses/i2c-scmi.c
+++ b/drivers/i2c/busses/i2c-scmi.c
@@ -426,19 +426,7 @@
 		.remove = acpi_smbus_cmi_remove,
 	},
 };
-
-static int __init acpi_smbus_cmi_init(void)
-{
-	return acpi_bus_register_driver(&acpi_smbus_cmi_driver);
-}
-
-static void __exit acpi_smbus_cmi_exit(void)
-{
-	acpi_bus_unregister_driver(&acpi_smbus_cmi_driver);
-}
-
-module_init(acpi_smbus_cmi_init);
-module_exit(acpi_smbus_cmi_exit);
+module_acpi_driver(acpi_smbus_cmi_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Crane Cai <crane.cai@amd.com>");
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
index 333011c..271c9a2 100644
--- a/drivers/i2c/busses/i2c-viapro.c
+++ b/drivers/i2c/busses/i2c-viapro.c
@@ -401,6 +401,7 @@
 	case PCI_DEVICE_ID_VIA_CX700:
 	case PCI_DEVICE_ID_VIA_VX800:
 	case PCI_DEVICE_ID_VIA_VX855:
+	case PCI_DEVICE_ID_VIA_VX900:
 	case PCI_DEVICE_ID_VIA_8251:
 	case PCI_DEVICE_ID_VIA_8237:
 	case PCI_DEVICE_ID_VIA_8237A:
@@ -470,6 +471,8 @@
 	  .driver_data = SMBBA3 },
 	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855),
 	  .driver_data = SMBBA3 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX900),
+	  .driver_data = SMBBA3 },
 	{ 0, }
 };
 
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c
index 2eacb77..08aab57 100644
--- a/drivers/i2c/busses/scx200_acb.c
+++ b/drivers/i2c/busses/scx200_acb.c
@@ -23,6 +23,8 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
@@ -37,8 +39,6 @@
 
 #include <linux/scx200.h>
 
-#define NAME "scx200_acb"
-
 MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
 MODULE_DESCRIPTION("NatSemi SCx200 ACCESS.bus Driver");
 MODULE_ALIAS("platform:cs5535-smb");
@@ -398,7 +398,7 @@
 	outb(0x70, ACBCTL2);
 
 	if (inb(ACBCTL2) != 0x70) {
-		pr_debug(NAME ": ACBCTL2 readback failed\n");
+		pr_debug("ACBCTL2 readback failed\n");
 		return -ENXIO;
 	}
 
@@ -406,8 +406,7 @@
 
 	val = inb(ACBCTL1);
 	if (val) {
-		pr_debug(NAME ": disabled, but ACBCTL1=0x%02x\n",
-			val);
+		pr_debug("disabled, but ACBCTL1=0x%02x\n", val);
 		return -ENXIO;
 	}
 
@@ -417,8 +416,8 @@
 
 	val = inb(ACBCTL1);
 	if ((val & ACBCTL1_NMINTE) != ACBCTL1_NMINTE) {
-		pr_debug(NAME ": enabled, but NMINTE won't be set, "
-			 "ACBCTL1=0x%02x\n", val);
+		pr_debug("enabled, but NMINTE won't be set, ACBCTL1=0x%02x\n",
+			 val);
 		return -ENXIO;
 	}
 
@@ -433,7 +432,7 @@
 
 	iface = kzalloc(sizeof(*iface), GFP_KERNEL);
 	if (!iface) {
-		printk(KERN_ERR NAME ": can't allocate memory\n");
+		pr_err("can't allocate memory\n");
 		return NULL;
 	}
 
@@ -459,14 +458,14 @@
 
 	rc = scx200_acb_probe(iface);
 	if (rc) {
-		printk(KERN_WARNING NAME ": probe failed\n");
+		pr_warn("probe failed\n");
 		return rc;
 	}
 
 	scx200_acb_reset(iface);
 
 	if (i2c_add_adapter(adapter) < 0) {
-		printk(KERN_ERR NAME ": failed to register\n");
+		pr_err("failed to register\n");
 		return -ENODEV;
 	}
 
@@ -493,8 +492,7 @@
 		return NULL;
 
 	if (!request_region(base, 8, iface->adapter.name)) {
-		printk(KERN_ERR NAME ": can't allocate io 0x%lx-0x%lx\n",
-		       base, base + 8 - 1);
+		pr_err("can't allocate io 0x%lx-0x%lx\n", base, base + 8 - 1);
 		goto errout_free;
 	}
 
@@ -583,7 +581,7 @@
 
 static int __init scx200_acb_init(void)
 {
-	pr_debug(NAME ": NatSemi SCx200 ACCESS.bus Driver\n");
+	pr_debug("NatSemi SCx200 ACCESS.bus Driver\n");
 
 	/* First scan for ISA-based devices */
 	scx200_scan_isa();	/* XXX: should we care about errors? */
diff --git a/drivers/i2c/busses/scx200_i2c.c b/drivers/i2c/busses/scx200_i2c.c
index 7ee0d50..ae1258b 100644
--- a/drivers/i2c/busses/scx200_i2c.c
+++ b/drivers/i2c/busses/scx200_i2c.c
@@ -21,6 +21,8 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.		     
 */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
@@ -31,8 +33,6 @@
 
 #include <linux/scx200_gpio.h>
 
-#define NAME "scx200_i2c"
-
 MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>");
 MODULE_DESCRIPTION("NatSemi SCx200 I2C Driver");
 MODULE_LICENSE("GPL");
@@ -88,17 +88,17 @@
 
 static int scx200_i2c_init(void)
 {
-	pr_debug(NAME ": NatSemi SCx200 I2C Driver\n");
+	pr_debug("NatSemi SCx200 I2C Driver\n");
 
 	if (!scx200_gpio_present()) {
-		printk(KERN_ERR NAME ": no SCx200 gpio pins available\n");
+		pr_err("no SCx200 gpio pins available\n");
 		return -ENODEV;
 	}
 
-	pr_debug(NAME ": SCL=GPIO%02u, SDA=GPIO%02u\n", scl, sda);
+	pr_debug("SCL=GPIO%02u, SDA=GPIO%02u\n", scl, sda);
 
 	if (scl == -1 || sda == -1 || scl == sda) {
-		printk(KERN_ERR NAME ": scl and sda must be specified\n");
+		pr_err("scl and sda must be specified\n");
 		return -EINVAL;
 	}
 
@@ -107,8 +107,7 @@
 	scx200_gpio_configure(sda, ~2, 5);
 
 	if (i2c_bit_add_bus(&scx200_i2c_ops) < 0) {
-		printk(KERN_ERR NAME ": adapter %s registration failed\n", 
-		       scx200_i2c_ops.name);
+		pr_err("adapter %s registration failed\n", scx200_i2c_ops.name);
 		return -ENODEV;
 	}
 	
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 2421d95..a7edf98 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -1989,12 +1989,22 @@
 	unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3];
 	unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2];
 	int num = read_write == I2C_SMBUS_READ ? 2 : 1;
-	struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 },
-	                          { addr, flags | I2C_M_RD, 0, msgbuf1 }
-	                        };
 	int i;
 	u8 partial_pec = 0;
 	int status;
+	struct i2c_msg msg[2] = {
+		{
+			.addr = addr,
+			.flags = flags,
+			.len = 1,
+			.buf = msgbuf0,
+		}, {
+			.addr = addr,
+			.flags = flags | I2C_M_RD,
+			.len = 0,
+			.buf = msgbuf1,
+		},
+	};
 
 	msgbuf0[0] = command;
 	switch (size) {
diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c
index 1038c38..d94e0ce 100644
--- a/drivers/i2c/i2c-mux.c
+++ b/drivers/i2c/i2c-mux.c
@@ -88,9 +88,23 @@
 	return parent->algo->functionality(parent);
 }
 
+/* Return all parent classes, merged */
+static unsigned int i2c_mux_parent_classes(struct i2c_adapter *parent)
+{
+	unsigned int class = 0;
+
+	do {
+		class |= parent->class;
+		parent = i2c_parent_is_i2c_adapter(parent);
+	} while (parent);
+
+	return class;
+}
+
 struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent,
 				struct device *mux_dev,
 				void *mux_priv, u32 force_nr, u32 chan_id,
+				unsigned int class,
 				int (*select) (struct i2c_adapter *,
 					       void *, u32),
 				int (*deselect) (struct i2c_adapter *,
@@ -127,6 +141,14 @@
 	priv->adap.algo_data = priv;
 	priv->adap.dev.parent = &parent->dev;
 
+	/* Sanity check on class */
+	if (i2c_mux_parent_classes(parent) & class)
+		dev_err(&parent->dev,
+			"Segment %d behind mux can't share classes with ancestors\n",
+			chan_id);
+	else
+		priv->adap.class = class;
+
 	/*
 	 * Try to populate the mux adapter's of_node, expands to
 	 * nothing if !CONFIG_OF.
diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c
index df3e0bf..92cdd23 100644
--- a/drivers/i2c/i2c-smbus.c
+++ b/drivers/i2c/i2c-smbus.c
@@ -142,7 +142,8 @@
 	struct i2c_adapter *adapter = ara->adapter;
 	int res;
 
-	alert = kzalloc(sizeof(struct i2c_smbus_alert), GFP_KERNEL);
+	alert = devm_kzalloc(&ara->dev, sizeof(struct i2c_smbus_alert),
+			     GFP_KERNEL);
 	if (!alert)
 		return -ENOMEM;
 
@@ -154,10 +155,8 @@
 	if (setup->irq > 0) {
 		res = devm_request_irq(&ara->dev, setup->irq, smbalert_irq,
 				       0, "smbus_alert", alert);
-		if (res) {
-			kfree(alert);
+		if (res)
 			return res;
-		}
 	}
 
 	i2c_set_clientdata(ara, alert);
@@ -167,14 +166,12 @@
 	return 0;
 }
 
-/* IRQ resource is managed so it is freed automatically */
+/* IRQ and memory resources are managed so they are freed automatically */
 static int smbalert_remove(struct i2c_client *ara)
 {
 	struct i2c_smbus_alert *alert = i2c_get_clientdata(ara);
 
 	cancel_work_sync(&alert->alert);
-
-	kfree(alert);
 	return 0;
 }
 
diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c
index 68b1f8e..566a675 100644
--- a/drivers/i2c/muxes/i2c-mux-gpio.c
+++ b/drivers/i2c/muxes/i2c-mux-gpio.c
@@ -21,6 +21,7 @@
 	struct i2c_adapter *parent;
 	struct i2c_adapter **adap; /* child busses */
 	struct i2c_mux_gpio_platform_data data;
+	unsigned gpio_base;
 };
 
 static void i2c_mux_gpio_set(const struct gpiomux *mux, unsigned val)
@@ -28,7 +29,8 @@
 	int i;
 
 	for (i = 0; i < mux->data.n_gpios; i++)
-		gpio_set_value(mux->data.gpios[i], val & (1 << i));
+		gpio_set_value(mux->gpio_base + mux->data.gpios[i],
+			       val & (1 << i));
 }
 
 static int i2c_mux_gpio_select(struct i2c_adapter *adap, void *data, u32 chan)
@@ -49,13 +51,19 @@
 	return 0;
 }
 
+static int __devinit match_gpio_chip_by_label(struct gpio_chip *chip,
+					      void *data)
+{
+	return !strcmp(chip->label, data);
+}
+
 static int __devinit i2c_mux_gpio_probe(struct platform_device *pdev)
 {
 	struct gpiomux *mux;
 	struct i2c_mux_gpio_platform_data *pdata;
 	struct i2c_adapter *parent;
 	int (*deselect) (struct i2c_adapter *, void *, u32);
-	unsigned initial_state;
+	unsigned initial_state, gpio_base;
 	int i, ret;
 
 	pdata = pdev->dev.platform_data;
@@ -64,6 +72,23 @@
 		return -ENODEV;
 	}
 
+	/*
+	 * If a GPIO chip name is provided, the GPIO pin numbers provided are
+	 * relative to its base GPIO number. Otherwise they are absolute.
+	 */
+	if (pdata->gpio_chip) {
+		struct gpio_chip *gpio;
+
+		gpio = gpiochip_find(pdata->gpio_chip,
+				     match_gpio_chip_by_label);
+		if (!gpio)
+			return -EPROBE_DEFER;
+
+		gpio_base = gpio->base;
+	} else {
+		gpio_base = 0;
+	}
+
 	parent = i2c_get_adapter(pdata->parent);
 	if (!parent) {
 		dev_err(&pdev->dev, "Parent adapter (%d) not found\n",
@@ -71,7 +96,7 @@
 		return -ENODEV;
 	}
 
-	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+	mux = devm_kzalloc(&pdev->dev, sizeof(*mux), GFP_KERNEL);
 	if (!mux) {
 		ret = -ENOMEM;
 		goto alloc_failed;
@@ -79,11 +104,13 @@
 
 	mux->parent = parent;
 	mux->data = *pdata;
-	mux->adap = kzalloc(sizeof(struct i2c_adapter *) * pdata->n_values,
-			    GFP_KERNEL);
+	mux->gpio_base = gpio_base;
+	mux->adap = devm_kzalloc(&pdev->dev,
+				 sizeof(*mux->adap) * pdata->n_values,
+				 GFP_KERNEL);
 	if (!mux->adap) {
 		ret = -ENOMEM;
-		goto alloc_failed2;
+		goto alloc_failed;
 	}
 
 	if (pdata->idle != I2C_MUX_GPIO_NO_IDLE) {
@@ -95,17 +122,19 @@
 	}
 
 	for (i = 0; i < pdata->n_gpios; i++) {
-		ret = gpio_request(pdata->gpios[i], "i2c-mux-gpio");
+		ret = gpio_request(gpio_base + pdata->gpios[i], "i2c-mux-gpio");
 		if (ret)
 			goto err_request_gpio;
-		gpio_direction_output(pdata->gpios[i],
+		gpio_direction_output(gpio_base + pdata->gpios[i],
 				      initial_state & (1 << i));
 	}
 
 	for (i = 0; i < pdata->n_values; i++) {
 		u32 nr = pdata->base_nr ? (pdata->base_nr + i) : 0;
+		unsigned int class = pdata->classes ? pdata->classes[i] : 0;
 
-		mux->adap[i] = i2c_add_mux_adapter(parent, &pdev->dev, mux, nr, i,
+		mux->adap[i] = i2c_add_mux_adapter(parent, &pdev->dev, mux, nr,
+						   i, class,
 						   i2c_mux_gpio_select, deselect);
 		if (!mux->adap[i]) {
 			ret = -ENODEV;
@@ -127,10 +156,7 @@
 	i = pdata->n_gpios;
 err_request_gpio:
 	for (; i > 0; i--)
-		gpio_free(pdata->gpios[i - 1]);
-	kfree(mux->adap);
-alloc_failed2:
-	kfree(mux);
+		gpio_free(gpio_base + pdata->gpios[i - 1]);
 alloc_failed:
 	i2c_put_adapter(parent);
 
@@ -146,12 +172,10 @@
 		i2c_del_mux_adapter(mux->adap[i]);
 
 	for (i = 0; i < mux->data.n_gpios; i++)
-		gpio_free(mux->data.gpios[i]);
+		gpio_free(mux->gpio_base + mux->data.gpios[i]);
 
 	platform_set_drvdata(pdev, NULL);
 	i2c_put_adapter(mux->parent);
-	kfree(mux->adap);
-	kfree(mux);
 
 	return 0;
 }
diff --git a/drivers/i2c/muxes/i2c-mux-pca9541.c b/drivers/i2c/muxes/i2c-mux-pca9541.c
index f8f72f3..f3b8f9a 100644
--- a/drivers/i2c/muxes/i2c-mux-pca9541.c
+++ b/drivers/i2c/muxes/i2c-mux-pca9541.c
@@ -354,7 +354,7 @@
 	if (pdata)
 		force = pdata->modes[0].adap_id;
 	data->mux_adap = i2c_add_mux_adapter(adap, &client->dev, client,
-					     force, 0,
+					     force, 0, 0,
 					     pca9541_select_chan,
 					     pca9541_release_chan);
 
diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
index f2dfe0d..8e43872 100644
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
@@ -186,7 +186,7 @@
 {
 	struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
 	struct pca954x_platform_data *pdata = client->dev.platform_data;
-	int num, force;
+	int num, force, class;
 	struct pca954x *data;
 	int ret = -ENODEV;
 
@@ -216,18 +216,20 @@
 	/* Now create an adapter for each channel */
 	for (num = 0; num < chips[data->type].nchans; num++) {
 		force = 0;			  /* dynamic adap number */
+		class = 0;			  /* no class by default */
 		if (pdata) {
-			if (num < pdata->num_modes)
+			if (num < pdata->num_modes) {
 				/* force static number */
 				force = pdata->modes[num].adap_id;
-			else
+				class = pdata->modes[num].class;
+			} else
 				/* discard unconfigured channels */
 				break;
 		}
 
 		data->virt_adaps[num] =
 			i2c_add_mux_adapter(adap, &client->dev, client,
-				force, num, pca954x_select_chan,
+				force, num, class, pca954x_select_chan,
 				(pdata && pdata->modes[num].deselect_on_exit)
 					? pca954x_deselect_mux : NULL);
 
diff --git a/drivers/i2c/muxes/i2c-mux-pinctrl.c b/drivers/i2c/muxes/i2c-mux-pinctrl.c
index 46a6697..5f097f3 100644
--- a/drivers/i2c/muxes/i2c-mux-pinctrl.c
+++ b/drivers/i2c/muxes/i2c-mux-pinctrl.c
@@ -221,7 +221,7 @@
 				(mux->pdata->base_bus_num + i) : 0;
 
 		mux->busses[i] = i2c_add_mux_adapter(mux->parent, &pdev->dev,
-						     mux, bus, i,
+						     mux, bus, i, 0,
 						     i2c_mux_pinctrl_select,
 						     deselect);
 		if (!mux->busses[i]) {
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index e872617..b0f6b4c 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -413,6 +413,7 @@
 	ICPU(0x2a, idle_cpu_snb),
 	ICPU(0x2d, idle_cpu_snb),
 	ICPU(0x3a, idle_cpu_ivb),
+	ICPU(0x3e, idle_cpu_ivb),
 	{}
 };
 MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids);
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 1983adc..a7568c3 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -3498,7 +3498,8 @@
 }
 
 static const struct ibnl_client_cbs cma_cb_table[] = {
-	[RDMA_NL_RDMA_CM_ID_STATS] = { .dump = cma_get_id_stats },
+	[RDMA_NL_RDMA_CM_ID_STATS] = { .dump = cma_get_id_stats,
+				       .module = THIS_MODULE },
 };
 
 static int __init cma_init(void)
diff --git a/drivers/infiniband/core/netlink.c b/drivers/infiniband/core/netlink.c
index fe10a94..da06abd 100644
--- a/drivers/infiniband/core/netlink.c
+++ b/drivers/infiniband/core/netlink.c
@@ -154,6 +154,7 @@
 			{
 				struct netlink_dump_control c = {
 					.dump = client->cb_table[op].dump,
+					.module = client->cb_table[op].module,
 				};
 				return netlink_dump_start(nls, skb, nlh, &c);
 			}
diff --git a/drivers/infiniband/hw/ehca/ehca_uverbs.c b/drivers/infiniband/hw/ehca/ehca_uverbs.c
index 45ee89b..1a1d5d9 100644
--- a/drivers/infiniband/hw/ehca/ehca_uverbs.c
+++ b/drivers/infiniband/hw/ehca/ehca_uverbs.c
@@ -117,7 +117,7 @@
 	physical = galpas->user.fw_handle;
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 	ehca_gen_dbg("vsize=%llx physical=%llx", vsize, physical);
-	/* VM_IO | VM_RESERVED are set by remap_pfn_range() */
+	/* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
 	ret = remap_4k_pfn(vma, vma->vm_start, physical >> EHCA_PAGESHIFT,
 			   vma->vm_page_prot);
 	if (unlikely(ret)) {
@@ -139,7 +139,7 @@
 	u64 start, ofs;
 	struct page *page;
 
-	vma->vm_flags |= VM_RESERVED;
+	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 	start = vma->vm_start;
 	for (ofs = 0; ofs < queue->queue_length; ofs += PAGE_SIZE) {
 		u64 virt_addr = (u64)ipz_qeit_calc(queue, ofs);
diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c
index 736d9ed..3eb7e45 100644
--- a/drivers/infiniband/hw/ipath/ipath_file_ops.c
+++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c
@@ -1225,7 +1225,7 @@
 
 	vma->vm_pgoff = (unsigned long) addr >> PAGE_SHIFT;
 	vma->vm_ops = &ipath_file_vm_ops;
-	vma->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
+	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 	ret = 1;
 
 bail:
diff --git a/drivers/infiniband/hw/qib/qib_file_ops.c b/drivers/infiniband/hw/qib/qib_file_ops.c
index faa44cb..959a5c4 100644
--- a/drivers/infiniband/hw/qib/qib_file_ops.c
+++ b/drivers/infiniband/hw/qib/qib_file_ops.c
@@ -971,7 +971,7 @@
 
 	vma->vm_pgoff = (unsigned long) addr >> PAGE_SHIFT;
 	vma->vm_ops = &qib_file_vm_ops;
-	vma->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
+	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 	ret = 1;
 
 bail:
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
index 9e1449f..cf23c46 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
@@ -3564,16 +3564,6 @@
 	return srpt_get_cmd_state(ioctx);
 }
 
-static u16 srpt_set_fabric_sense_len(struct se_cmd *cmd, u32 sense_length)
-{
-	return 0;
-}
-
-static u16 srpt_get_fabric_sense_len(void)
-{
-	return 0;
-}
-
 /**
  * srpt_parse_i_port_id() - Parse an initiator port ID.
  * @name: ASCII representation of a 128-bit initiator port ID.
@@ -3953,8 +3943,6 @@
 	.queue_data_in			= srpt_queue_response,
 	.queue_status			= srpt_queue_status,
 	.queue_tm_rsp			= srpt_queue_response,
-	.get_fabric_sense_len		= srpt_get_fabric_sense_len,
-	.set_fabric_sense_len		= srpt_set_fabric_sense_len,
 	/*
 	 * Setup function pointers for generic logic in
 	 * target_core_fabric_configfs.c
diff --git a/drivers/input/misc/atlas_btns.c b/drivers/input/misc/atlas_btns.c
index 601f737..26f1313 100644
--- a/drivers/input/misc/atlas_btns.c
+++ b/drivers/input/misc/atlas_btns.c
@@ -151,22 +151,7 @@
 		.remove	= atlas_acpi_button_remove,
 	},
 };
-
-static int __init atlas_acpi_init(void)
-{
-	if (acpi_disabled)
-		return -ENODEV;
-
-	return acpi_bus_register_driver(&atlas_acpi_driver);
-}
-
-static void __exit atlas_acpi_exit(void)
-{
-	acpi_bus_unregister_driver(&atlas_acpi_driver);
-}
-
-module_init(atlas_acpi_init);
-module_exit(atlas_acpi_exit);
+module_acpi_driver(atlas_acpi_driver);
 
 MODULE_AUTHOR("Jaya Kumar");
 MODULE_LICENSE("GPL");
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 9f69b56..e39f9db 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -42,7 +42,7 @@
 	select PCI_PRI
 	select PCI_PASID
 	select IOMMU_API
-	depends on X86_64 && PCI && ACPI
+	depends on X86_64 && PCI && ACPI && X86_IO_APIC
 	---help---
 	  With this option you can enable support for AMD IOMMU hardware in
 	  your system. An IOMMU is a hardware component which provides
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index e89daf1..55074cb 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -31,6 +31,12 @@
 #include <linux/amd-iommu.h>
 #include <linux/notifier.h>
 #include <linux/export.h>
+#include <linux/irq.h>
+#include <linux/msi.h>
+#include <asm/irq_remapping.h>
+#include <asm/io_apic.h>
+#include <asm/apic.h>
+#include <asm/hw_irq.h>
 #include <asm/msidef.h>
 #include <asm/proto.h>
 #include <asm/iommu.h>
@@ -39,6 +45,7 @@
 
 #include "amd_iommu_proto.h"
 #include "amd_iommu_types.h"
+#include "irq_remapping.h"
 
 #define CMD_SET_TYPE(cmd, t) ((cmd)->data[1] |= ((t) << 28))
 
@@ -72,6 +79,9 @@
 static LIST_HEAD(dev_data_list);
 static DEFINE_SPINLOCK(dev_data_list_lock);
 
+LIST_HEAD(ioapic_map);
+LIST_HEAD(hpet_map);
+
 /*
  * Domain for untranslated devices - only allocated
  * if iommu=pt passed on kernel cmd line.
@@ -92,6 +102,8 @@
 	u32 data[4];
 };
 
+struct kmem_cache *amd_iommu_irq_cache;
+
 static void update_domain(struct protection_domain *domain);
 static int __init alloc_passthrough_domain(void);
 
@@ -686,7 +698,7 @@
 
 		/*
 		 * Release iommu->lock because ppr-handling might need to
-		 * re-aquire it
+		 * re-acquire it
 		 */
 		spin_unlock_irqrestore(&iommu->lock, flags);
 
@@ -804,7 +816,7 @@
 	CMD_SET_TYPE(cmd, CMD_INV_IOMMU_PAGES);
 	if (s) /* size bit - we flush more than one 4kb page */
 		cmd->data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK;
-	if (pde) /* PDE bit - we wan't flush everything not only the PTEs */
+	if (pde) /* PDE bit - we want to flush everything, not only the PTEs */
 		cmd->data[2] |= CMD_INV_IOMMU_PAGES_PDE_MASK;
 }
 
@@ -899,6 +911,13 @@
 	CMD_SET_TYPE(cmd, CMD_INV_ALL);
 }
 
+static void build_inv_irt(struct iommu_cmd *cmd, u16 devid)
+{
+	memset(cmd, 0, sizeof(*cmd));
+	cmd->data[0] = devid;
+	CMD_SET_TYPE(cmd, CMD_INV_IRT);
+}
+
 /*
  * Writes the command to the IOMMUs command buffer and informs the
  * hardware about the new command.
@@ -1020,12 +1039,32 @@
 	iommu_completion_wait(iommu);
 }
 
+static void iommu_flush_irt(struct amd_iommu *iommu, u16 devid)
+{
+	struct iommu_cmd cmd;
+
+	build_inv_irt(&cmd, devid);
+
+	iommu_queue_command(iommu, &cmd);
+}
+
+static void iommu_flush_irt_all(struct amd_iommu *iommu)
+{
+	u32 devid;
+
+	for (devid = 0; devid <= MAX_DEV_TABLE_ENTRIES; devid++)
+		iommu_flush_irt(iommu, devid);
+
+	iommu_completion_wait(iommu);
+}
+
 void iommu_flush_all_caches(struct amd_iommu *iommu)
 {
 	if (iommu_feature(iommu, FEATURE_IA)) {
 		iommu_flush_all(iommu);
 	} else {
 		iommu_flush_dte_all(iommu);
+		iommu_flush_irt_all(iommu);
 		iommu_flush_tlb_all(iommu);
 	}
 }
@@ -2155,7 +2194,7 @@
 }
 
 /*
- * If a device is not yet associated with a domain, this function does
+ * If a device is not yet associated with a domain, this function
  * assigns it visible for the hardware
  */
 static int attach_device(struct device *dev,
@@ -2405,7 +2444,7 @@
 	if (domain != NULL)
 		return domain;
 
-	/* Device not bount yet - bind it */
+	/* Device not bound yet - bind it */
 	dma_dom = find_protection_domain(devid);
 	if (!dma_dom)
 		dma_dom = amd_iommu_rlookup_table[devid]->default_dom;
@@ -2944,7 +2983,7 @@
 			alloc_passthrough_domain();
 			dev_data->passthrough = true;
 			attach_device(&dev->dev, pt_domain);
-			pr_info("AMD-Vi: Using passthough domain for device %s\n",
+			pr_info("AMD-Vi: Using passthrough domain for device %s\n",
 				dev_name(&dev->dev));
 		}
 
@@ -3316,6 +3355,8 @@
 	switch (cap) {
 	case IOMMU_CAP_CACHE_COHERENCY:
 		return 1;
+	case IOMMU_CAP_INTR_REMAP:
+		return irq_remapping_enabled;
 	}
 
 	return 0;
@@ -3743,3 +3784,466 @@
 	return 0;
 }
 EXPORT_SYMBOL(amd_iommu_device_info);
+
+#ifdef CONFIG_IRQ_REMAP
+
+/*****************************************************************************
+ *
+ * Interrupt Remapping Implementation
+ *
+ *****************************************************************************/
+
+union irte {
+	u32 val;
+	struct {
+		u32 valid	: 1,
+		    no_fault	: 1,
+		    int_type	: 3,
+		    rq_eoi	: 1,
+		    dm		: 1,
+		    rsvd_1	: 1,
+		    destination	: 8,
+		    vector	: 8,
+		    rsvd_2	: 8;
+	} fields;
+};
+
+#define DTE_IRQ_PHYS_ADDR_MASK	(((1ULL << 45)-1) << 6)
+#define DTE_IRQ_REMAP_INTCTL    (2ULL << 60)
+#define DTE_IRQ_TABLE_LEN       (8ULL << 1)
+#define DTE_IRQ_REMAP_ENABLE    1ULL
+
+static void set_dte_irq_entry(u16 devid, struct irq_remap_table *table)
+{
+	u64 dte;
+
+	dte	= amd_iommu_dev_table[devid].data[2];
+	dte	&= ~DTE_IRQ_PHYS_ADDR_MASK;
+	dte	|= virt_to_phys(table->table);
+	dte	|= DTE_IRQ_REMAP_INTCTL;
+	dte	|= DTE_IRQ_TABLE_LEN;
+	dte	|= DTE_IRQ_REMAP_ENABLE;
+
+	amd_iommu_dev_table[devid].data[2] = dte;
+}
+
+#define IRTE_ALLOCATED (~1U)
+
+static struct irq_remap_table *get_irq_table(u16 devid, bool ioapic)
+{
+	struct irq_remap_table *table = NULL;
+	struct amd_iommu *iommu;
+	unsigned long flags;
+	u16 alias;
+
+	write_lock_irqsave(&amd_iommu_devtable_lock, flags);
+
+	iommu = amd_iommu_rlookup_table[devid];
+	if (!iommu)
+		goto out_unlock;
+
+	table = irq_lookup_table[devid];
+	if (table)
+		goto out;
+
+	alias = amd_iommu_alias_table[devid];
+	table = irq_lookup_table[alias];
+	if (table) {
+		irq_lookup_table[devid] = table;
+		set_dte_irq_entry(devid, table);
+		iommu_flush_dte(iommu, devid);
+		goto out;
+	}
+
+	/* Nothing there yet, allocate new irq remapping table */
+	table = kzalloc(sizeof(*table), GFP_ATOMIC);
+	if (!table)
+		goto out;
+
+	if (ioapic)
+		/* Keep the first 32 indexes free for IOAPIC interrupts */
+		table->min_index = 32;
+
+	table->table = kmem_cache_alloc(amd_iommu_irq_cache, GFP_ATOMIC);
+	if (!table->table) {
+		kfree(table);
+		table = NULL;
+		goto out;
+	}
+
+	memset(table->table, 0, MAX_IRQS_PER_TABLE * sizeof(u32));
+
+	if (ioapic) {
+		int i;
+
+		for (i = 0; i < 32; ++i)
+			table->table[i] = IRTE_ALLOCATED;
+	}
+
+	irq_lookup_table[devid] = table;
+	set_dte_irq_entry(devid, table);
+	iommu_flush_dte(iommu, devid);
+	if (devid != alias) {
+		irq_lookup_table[alias] = table;
+		set_dte_irq_entry(devid, table);
+		iommu_flush_dte(iommu, alias);
+	}
+
+out:
+	iommu_completion_wait(iommu);
+
+out_unlock:
+	write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
+
+	return table;
+}
+
+static int alloc_irq_index(struct irq_cfg *cfg, u16 devid, int count)
+{
+	struct irq_remap_table *table;
+	unsigned long flags;
+	int index, c;
+
+	table = get_irq_table(devid, false);
+	if (!table)
+		return -ENODEV;
+
+	spin_lock_irqsave(&table->lock, flags);
+
+	/* Scan table for free entries */
+	for (c = 0, index = table->min_index;
+	     index < MAX_IRQS_PER_TABLE;
+	     ++index) {
+		if (table->table[index] == 0)
+			c += 1;
+		else
+			c = 0;
+
+		if (c == count)	{
+			struct irq_2_iommu *irte_info;
+
+			for (; c != 0; --c)
+				table->table[index - c + 1] = IRTE_ALLOCATED;
+
+			index -= count - 1;
+
+			irte_info             = &cfg->irq_2_iommu;
+			irte_info->sub_handle = devid;
+			irte_info->irte_index = index;
+			irte_info->iommu      = (void *)cfg;
+
+			goto out;
+		}
+	}
+
+	index = -ENOSPC;
+
+out:
+	spin_unlock_irqrestore(&table->lock, flags);
+
+	return index;
+}
+
+static int get_irte(u16 devid, int index, union irte *irte)
+{
+	struct irq_remap_table *table;
+	unsigned long flags;
+
+	table = get_irq_table(devid, false);
+	if (!table)
+		return -ENOMEM;
+
+	spin_lock_irqsave(&table->lock, flags);
+	irte->val = table->table[index];
+	spin_unlock_irqrestore(&table->lock, flags);
+
+	return 0;
+}
+
+static int modify_irte(u16 devid, int index, union irte irte)
+{
+	struct irq_remap_table *table;
+	struct amd_iommu *iommu;
+	unsigned long flags;
+
+	iommu = amd_iommu_rlookup_table[devid];
+	if (iommu == NULL)
+		return -EINVAL;
+
+	table = get_irq_table(devid, false);
+	if (!table)
+		return -ENOMEM;
+
+	spin_lock_irqsave(&table->lock, flags);
+	table->table[index] = irte.val;
+	spin_unlock_irqrestore(&table->lock, flags);
+
+	iommu_flush_irt(iommu, devid);
+	iommu_completion_wait(iommu);
+
+	return 0;
+}
+
+static void free_irte(u16 devid, int index)
+{
+	struct irq_remap_table *table;
+	struct amd_iommu *iommu;
+	unsigned long flags;
+
+	iommu = amd_iommu_rlookup_table[devid];
+	if (iommu == NULL)
+		return;
+
+	table = get_irq_table(devid, false);
+	if (!table)
+		return;
+
+	spin_lock_irqsave(&table->lock, flags);
+	table->table[index] = 0;
+	spin_unlock_irqrestore(&table->lock, flags);
+
+	iommu_flush_irt(iommu, devid);
+	iommu_completion_wait(iommu);
+}
+
+static int setup_ioapic_entry(int irq, struct IO_APIC_route_entry *entry,
+			      unsigned int destination, int vector,
+			      struct io_apic_irq_attr *attr)
+{
+	struct irq_remap_table *table;
+	struct irq_2_iommu *irte_info;
+	struct irq_cfg *cfg;
+	union irte irte;
+	int ioapic_id;
+	int index;
+	int devid;
+	int ret;
+
+	cfg = irq_get_chip_data(irq);
+	if (!cfg)
+		return -EINVAL;
+
+	irte_info = &cfg->irq_2_iommu;
+	ioapic_id = mpc_ioapic_id(attr->ioapic);
+	devid     = get_ioapic_devid(ioapic_id);
+
+	if (devid < 0)
+		return devid;
+
+	table = get_irq_table(devid, true);
+	if (table == NULL)
+		return -ENOMEM;
+
+	index = attr->ioapic_pin;
+
+	/* Setup IRQ remapping info */
+	irte_info->sub_handle = devid;
+	irte_info->irte_index = index;
+	irte_info->iommu      = (void *)cfg;
+
+	/* Setup IRTE for IOMMU */
+	irte.val		= 0;
+	irte.fields.vector      = vector;
+	irte.fields.int_type    = apic->irq_delivery_mode;
+	irte.fields.destination = destination;
+	irte.fields.dm          = apic->irq_dest_mode;
+	irte.fields.valid       = 1;
+
+	ret = modify_irte(devid, index, irte);
+	if (ret)
+		return ret;
+
+	/* Setup IOAPIC entry */
+	memset(entry, 0, sizeof(*entry));
+
+	entry->vector        = index;
+	entry->mask          = 0;
+	entry->trigger       = attr->trigger;
+	entry->polarity      = attr->polarity;
+
+	/*
+	 * Mask level triggered irqs.
+	 */
+	if (attr->trigger)
+		entry->mask = 1;
+
+	return 0;
+}
+
+static int set_affinity(struct irq_data *data, const struct cpumask *mask,
+			bool force)
+{
+	struct irq_2_iommu *irte_info;
+	unsigned int dest, irq;
+	struct irq_cfg *cfg;
+	union irte irte;
+	int err;
+
+	if (!config_enabled(CONFIG_SMP))
+		return -1;
+
+	cfg       = data->chip_data;
+	irq       = data->irq;
+	irte_info = &cfg->irq_2_iommu;
+
+	if (!cpumask_intersects(mask, cpu_online_mask))
+		return -EINVAL;
+
+	if (get_irte(irte_info->sub_handle, irte_info->irte_index, &irte))
+		return -EBUSY;
+
+	if (assign_irq_vector(irq, cfg, mask))
+		return -EBUSY;
+
+	err = apic->cpu_mask_to_apicid_and(cfg->domain, mask, &dest);
+	if (err) {
+		if (assign_irq_vector(irq, cfg, data->affinity))
+			pr_err("AMD-Vi: Failed to recover vector for irq %d\n", irq);
+		return err;
+	}
+
+	irte.fields.vector      = cfg->vector;
+	irte.fields.destination = dest;
+
+	modify_irte(irte_info->sub_handle, irte_info->irte_index, irte);
+
+	if (cfg->move_in_progress)
+		send_cleanup_vector(cfg);
+
+	cpumask_copy(data->affinity, mask);
+
+	return 0;
+}
+
+static int free_irq(int irq)
+{
+	struct irq_2_iommu *irte_info;
+	struct irq_cfg *cfg;
+
+	cfg = irq_get_chip_data(irq);
+	if (!cfg)
+		return -EINVAL;
+
+	irte_info = &cfg->irq_2_iommu;
+
+	free_irte(irte_info->sub_handle, irte_info->irte_index);
+
+	return 0;
+}
+
+static void compose_msi_msg(struct pci_dev *pdev,
+			    unsigned int irq, unsigned int dest,
+			    struct msi_msg *msg, u8 hpet_id)
+{
+	struct irq_2_iommu *irte_info;
+	struct irq_cfg *cfg;
+	union irte irte;
+
+	cfg = irq_get_chip_data(irq);
+	if (!cfg)
+		return;
+
+	irte_info = &cfg->irq_2_iommu;
+
+	irte.val		= 0;
+	irte.fields.vector	= cfg->vector;
+	irte.fields.int_type    = apic->irq_delivery_mode;
+	irte.fields.destination	= dest;
+	irte.fields.dm		= apic->irq_dest_mode;
+	irte.fields.valid	= 1;
+
+	modify_irte(irte_info->sub_handle, irte_info->irte_index, irte);
+
+	msg->address_hi = MSI_ADDR_BASE_HI;
+	msg->address_lo = MSI_ADDR_BASE_LO;
+	msg->data       = irte_info->irte_index;
+}
+
+static int msi_alloc_irq(struct pci_dev *pdev, int irq, int nvec)
+{
+	struct irq_cfg *cfg;
+	int index;
+	u16 devid;
+
+	if (!pdev)
+		return -EINVAL;
+
+	cfg = irq_get_chip_data(irq);
+	if (!cfg)
+		return -EINVAL;
+
+	devid = get_device_id(&pdev->dev);
+	index = alloc_irq_index(cfg, devid, nvec);
+
+	return index < 0 ? MAX_IRQS_PER_TABLE : index;
+}
+
+static int msi_setup_irq(struct pci_dev *pdev, unsigned int irq,
+			 int index, int offset)
+{
+	struct irq_2_iommu *irte_info;
+	struct irq_cfg *cfg;
+	u16 devid;
+
+	if (!pdev)
+		return -EINVAL;
+
+	cfg = irq_get_chip_data(irq);
+	if (!cfg)
+		return -EINVAL;
+
+	if (index >= MAX_IRQS_PER_TABLE)
+		return 0;
+
+	devid		= get_device_id(&pdev->dev);
+	irte_info	= &cfg->irq_2_iommu;
+
+	irte_info->sub_handle = devid;
+	irte_info->irte_index = index + offset;
+	irte_info->iommu      = (void *)cfg;
+
+	return 0;
+}
+
+static int setup_hpet_msi(unsigned int irq, unsigned int id)
+{
+	struct irq_2_iommu *irte_info;
+	struct irq_cfg *cfg;
+	int index, devid;
+
+	cfg = irq_get_chip_data(irq);
+	if (!cfg)
+		return -EINVAL;
+
+	irte_info = &cfg->irq_2_iommu;
+	devid     = get_hpet_devid(id);
+	if (devid < 0)
+		return devid;
+
+	index = alloc_irq_index(cfg, devid, 1);
+	if (index < 0)
+		return index;
+
+	irte_info->sub_handle = devid;
+	irte_info->irte_index = index;
+	irte_info->iommu      = (void *)cfg;
+
+	return 0;
+}
+
+struct irq_remap_ops amd_iommu_irq_ops = {
+	.supported		= amd_iommu_supported,
+	.prepare		= amd_iommu_prepare,
+	.enable			= amd_iommu_enable,
+	.disable		= amd_iommu_disable,
+	.reenable		= amd_iommu_reenable,
+	.enable_faulting	= amd_iommu_enable_faulting,
+	.setup_ioapic_entry	= setup_ioapic_entry,
+	.set_affinity		= set_affinity,
+	.free_irq		= free_irq,
+	.compose_msi_msg	= compose_msi_msg,
+	.msi_alloc_irq		= msi_alloc_irq,
+	.msi_setup_irq		= msi_setup_irq,
+	.setup_hpet_msi		= setup_hpet_msi,
+};
+#endif
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 18a89b7..18b0d99 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -26,16 +26,18 @@
 #include <linux/msi.h>
 #include <linux/amd-iommu.h>
 #include <linux/export.h>
-#include <linux/acpi.h>
 #include <acpi/acpi.h>
 #include <asm/pci-direct.h>
 #include <asm/iommu.h>
 #include <asm/gart.h>
 #include <asm/x86_init.h>
 #include <asm/iommu_table.h>
+#include <asm/io_apic.h>
+#include <asm/irq_remapping.h>
 
 #include "amd_iommu_proto.h"
 #include "amd_iommu_types.h"
+#include "irq_remapping.h"
 
 /*
  * definitions for the ACPI scanning code
@@ -55,6 +57,10 @@
 #define IVHD_DEV_ALIAS_RANGE            0x43
 #define IVHD_DEV_EXT_SELECT             0x46
 #define IVHD_DEV_EXT_SELECT_RANGE       0x47
+#define IVHD_DEV_SPECIAL		0x48
+
+#define IVHD_SPECIAL_IOAPIC		1
+#define IVHD_SPECIAL_HPET		2
 
 #define IVHD_FLAG_HT_TUN_EN_MASK        0x01
 #define IVHD_FLAG_PASSPW_EN_MASK        0x02
@@ -123,6 +129,7 @@
 } __attribute__((packed));
 
 bool amd_iommu_dump;
+bool amd_iommu_irq_remap __read_mostly;
 
 static bool amd_iommu_detected;
 static bool __initdata amd_iommu_disabled;
@@ -178,7 +185,13 @@
 struct amd_iommu **amd_iommu_rlookup_table;
 
 /*
- * AMD IOMMU allows up to 2^16 differend protection domains. This is a bitmap
+ * This table is used to find the irq remapping table for a given device id
+ * quickly.
+ */
+struct irq_remap_table **irq_lookup_table;
+
+/*
+ * AMD IOMMU allows up to 2^16 different protection domains. This is a bitmap
  * to know which ones are already in use.
  */
 unsigned long *amd_iommu_pd_alloc_bitmap;
@@ -478,7 +491,7 @@
 
 /****************************************************************************
  *
- * The following functions belong the the code path which parses the ACPI table
+ * The following functions belong to the code path which parses the ACPI table
  * the second time. In this ACPI parsing iteration we allocate IOMMU specific
  * data structures, initialize the device/alias/rlookup table and also
  * basically initialize the hardware.
@@ -690,8 +703,33 @@
 	set_iommu_for_device(iommu, devid);
 }
 
+static int add_special_device(u8 type, u8 id, u16 devid)
+{
+	struct devid_map *entry;
+	struct list_head *list;
+
+	if (type != IVHD_SPECIAL_IOAPIC && type != IVHD_SPECIAL_HPET)
+		return -EINVAL;
+
+	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry)
+		return -ENOMEM;
+
+	entry->id    = id;
+	entry->devid = devid;
+
+	if (type == IVHD_SPECIAL_IOAPIC)
+		list = &ioapic_map;
+	else
+		list = &hpet_map;
+
+	list_add_tail(&entry->list, list);
+
+	return 0;
+}
+
 /*
- * Reads the device exclusion range from ACPI and initialize IOMMU with
+ * Reads the device exclusion range from ACPI and initializes the IOMMU with
  * it
  */
 static void __init set_device_exclusion_range(u16 devid, struct ivmd_header *m)
@@ -717,7 +755,7 @@
  * Takes a pointer to an AMD IOMMU entry in the ACPI table and
  * initializes the hardware and our data structures with it.
  */
-static void __init init_iommu_from_acpi(struct amd_iommu *iommu,
+static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
 					struct ivhd_header *h)
 {
 	u8 *p = (u8 *)h;
@@ -867,12 +905,43 @@
 							flags, ext_flags);
 			}
 			break;
+		case IVHD_DEV_SPECIAL: {
+			u8 handle, type;
+			const char *var;
+			u16 devid;
+			int ret;
+
+			handle = e->ext & 0xff;
+			devid  = (e->ext >>  8) & 0xffff;
+			type   = (e->ext >> 24) & 0xff;
+
+			if (type == IVHD_SPECIAL_IOAPIC)
+				var = "IOAPIC";
+			else if (type == IVHD_SPECIAL_HPET)
+				var = "HPET";
+			else
+				var = "UNKNOWN";
+
+			DUMP_printk("  DEV_SPECIAL(%s[%d])\t\tdevid: %02x:%02x.%x\n",
+				    var, (int)handle,
+				    PCI_BUS(devid),
+				    PCI_SLOT(devid),
+				    PCI_FUNC(devid));
+
+			set_dev_entry_from_acpi(iommu, devid, e->flags, 0);
+			ret = add_special_device(type, handle, devid);
+			if (ret)
+				return ret;
+			break;
+		}
 		default:
 			break;
 		}
 
 		p += ivhd_entry_length(p);
 	}
+
+	return 0;
 }
 
 /* Initializes the device->iommu mapping for the driver */
@@ -912,6 +981,8 @@
  */
 static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
 {
+	int ret;
+
 	spin_lock_init(&iommu->lock);
 
 	/* Add IOMMU to internal data structures */
@@ -947,7 +1018,16 @@
 
 	iommu->int_enabled = false;
 
-	init_iommu_from_acpi(iommu, h);
+	ret = init_iommu_from_acpi(iommu, h);
+	if (ret)
+		return ret;
+
+	/*
+	 * Make sure IOMMU is not considered to translate itself. The IVRS
+	 * table tells us so, but this is a lie!
+	 */
+	amd_iommu_rlookup_table[iommu->devid] = NULL;
+
 	init_iommu_devices(iommu);
 
 	return 0;
@@ -1115,9 +1195,11 @@
 				if (iommu_feature(iommu, (1ULL << i)))
 					pr_cont(" %s", feat_str[i]);
 			}
-		}
 		pr_cont("\n");
+		}
 	}
+	if (irq_remapping_enabled)
+		pr_info("AMD-Vi: Interrupt remapping enabled\n");
 }
 
 static int __init amd_iommu_init_pci(void)
@@ -1141,7 +1223,7 @@
 /****************************************************************************
  *
  * The following functions initialize the MSI interrupts for all IOMMUs
- * in the system. Its a bit challenging because there could be multiple
+ * in the system. It's a bit challenging because there could be multiple
  * IOMMUs per PCI BDF but we can call pci_enable_msi(x) only once per
  * pci_dev.
  *
@@ -1199,7 +1281,7 @@
  *
  * The next functions belong to the third pass of parsing the ACPI
  * table. In this last pass the memory mapping requirements are
- * gathered (like exclusion and unity mapping reanges).
+ * gathered (like exclusion and unity mapping ranges).
  *
  ****************************************************************************/
 
@@ -1308,7 +1390,7 @@
  * Init the device table to not allow DMA access for devices and
  * suppress all page faults
  */
-static void init_device_table(void)
+static void init_device_table_dma(void)
 {
 	u32 devid;
 
@@ -1318,6 +1400,27 @@
 	}
 }
 
+static void __init uninit_device_table_dma(void)
+{
+	u32 devid;
+
+	for (devid = 0; devid <= amd_iommu_last_bdf; ++devid) {
+		amd_iommu_dev_table[devid].data[0] = 0ULL;
+		amd_iommu_dev_table[devid].data[1] = 0ULL;
+	}
+}
+
+static void init_device_table(void)
+{
+	u32 devid;
+
+	if (!amd_iommu_irq_remap)
+		return;
+
+	for (devid = 0; devid <= amd_iommu_last_bdf; ++devid)
+		set_dev_entry_bit(devid, DEV_ENTRY_IRQ_TBL_EN);
+}
+
 static void iommu_init_flags(struct amd_iommu *iommu)
 {
 	iommu->acpi_flags & IVHD_FLAG_HT_TUN_EN_MASK ?
@@ -1466,10 +1569,14 @@
 
 static void __init free_on_init_error(void)
 {
-	amd_iommu_uninit_devices();
+	free_pages((unsigned long)irq_lookup_table,
+		   get_order(rlookup_table_size));
 
-	free_pages((unsigned long)amd_iommu_pd_alloc_bitmap,
-		   get_order(MAX_DOMAIN_ID/8));
+	if (amd_iommu_irq_cache) {
+		kmem_cache_destroy(amd_iommu_irq_cache);
+		amd_iommu_irq_cache = NULL;
+
+	}
 
 	free_pages((unsigned long)amd_iommu_rlookup_table,
 		   get_order(rlookup_table_size));
@@ -1482,8 +1589,6 @@
 
 	free_iommu_all();
 
-	free_unity_maps();
-
 #ifdef CONFIG_GART_IOMMU
 	/*
 	 * We failed to initialize the AMD IOMMU - try fallback to GART
@@ -1494,6 +1599,33 @@
 #endif
 }
 
+static bool __init check_ioapic_information(void)
+{
+	int idx;
+
+	for (idx = 0; idx < nr_ioapics; idx++) {
+		int id = mpc_ioapic_id(idx);
+
+		if (get_ioapic_devid(id) < 0) {
+			pr_err(FW_BUG "AMD-Vi: IO-APIC[%d] not in IVRS table\n", id);
+			pr_err("AMD-Vi: Disabling interrupt remapping due to BIOS Bug\n");
+			return false;
+		}
+	}
+
+	return true;
+}
+
+static void __init free_dma_resources(void)
+{
+	amd_iommu_uninit_devices();
+
+	free_pages((unsigned long)amd_iommu_pd_alloc_bitmap,
+		   get_order(MAX_DOMAIN_ID/8));
+
+	free_unity_maps();
+}
+
 /*
  * This is the hardware init function for AMD IOMMU in the system.
  * This function is called either from amd_iommu_init or from the interrupt
@@ -1580,9 +1712,6 @@
 	if (amd_iommu_pd_alloc_bitmap == NULL)
 		goto out;
 
-	/* init the device table */
-	init_device_table();
-
 	/*
 	 * let all alias entries point to itself
 	 */
@@ -1605,10 +1734,35 @@
 	if (ret)
 		goto out;
 
+	if (amd_iommu_irq_remap)
+		amd_iommu_irq_remap = check_ioapic_information();
+
+	if (amd_iommu_irq_remap) {
+		/*
+		 * Interrupt remapping enabled, create kmem_cache for the
+		 * remapping tables.
+		 */
+		amd_iommu_irq_cache = kmem_cache_create("irq_remap_cache",
+				MAX_IRQS_PER_TABLE * sizeof(u32),
+				IRQ_TABLE_ALIGNMENT,
+				0, NULL);
+		if (!amd_iommu_irq_cache)
+			goto out;
+
+		irq_lookup_table = (void *)__get_free_pages(
+				GFP_KERNEL | __GFP_ZERO,
+				get_order(rlookup_table_size));
+		if (!irq_lookup_table)
+			goto out;
+	}
+
 	ret = init_memory_definitions(ivrs_base);
 	if (ret)
 		goto out;
 
+	/* init the device table */
+	init_device_table();
+
 out:
 	/* Don't leak any ACPI memory */
 	early_acpi_os_unmap_memory((char __iomem *)ivrs_base, ivrs_size);
@@ -1652,13 +1806,22 @@
 	/* Make sure ACS will be enabled during PCI probe */
 	pci_request_acs();
 
+	if (!disable_irq_remap)
+		amd_iommu_irq_remap = true;
+
 	return true;
 }
 
 static int amd_iommu_init_dma(void)
 {
+	struct amd_iommu *iommu;
 	int ret;
 
+	init_device_table_dma();
+
+	for_each_iommu(iommu)
+		iommu_flush_all_caches(iommu);
+
 	if (iommu_pass_through)
 		ret = amd_iommu_init_passthrough();
 	else
@@ -1749,7 +1912,48 @@
 	return ret;
 }
 
+#ifdef CONFIG_IRQ_REMAP
+int __init amd_iommu_prepare(void)
+{
+	return iommu_go_to_state(IOMMU_ACPI_FINISHED);
+}
 
+int __init amd_iommu_supported(void)
+{
+	return amd_iommu_irq_remap ? 1 : 0;
+}
+
+int __init amd_iommu_enable(void)
+{
+	int ret;
+
+	ret = iommu_go_to_state(IOMMU_ENABLED);
+	if (ret)
+		return ret;
+
+	irq_remapping_enabled = 1;
+
+	return 0;
+}
+
+void amd_iommu_disable(void)
+{
+	amd_iommu_suspend();
+}
+
+int amd_iommu_reenable(int mode)
+{
+	amd_iommu_resume();
+
+	return 0;
+}
+
+int __init amd_iommu_enable_faulting(void)
+{
+	/* We enable MSI later when PCI is initialized */
+	return 0;
+}
+#endif
 
 /*
  * This is the core init function for AMD IOMMU hardware in the system.
@@ -1762,8 +1966,17 @@
 
 	ret = iommu_go_to_state(IOMMU_INITIALIZED);
 	if (ret) {
-		disable_iommus();
-		free_on_init_error();
+		free_dma_resources();
+		if (!irq_remapping_enabled) {
+			disable_iommus();
+			free_on_init_error();
+		} else {
+			struct amd_iommu *iommu;
+
+			uninit_device_table_dma();
+			for_each_iommu(iommu)
+				iommu_flush_all_caches(iommu);
+		}
 	}
 
 	return ret;
diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h
index 1a7f41c..c294961 100644
--- a/drivers/iommu/amd_iommu_proto.h
+++ b/drivers/iommu/amd_iommu_proto.h
@@ -32,6 +32,14 @@
 extern void amd_iommu_init_notifier(void);
 extern void amd_iommu_init_api(void);
 
+/* Needed for interrupt remapping */
+extern int amd_iommu_supported(void);
+extern int amd_iommu_prepare(void);
+extern int amd_iommu_enable(void);
+extern void amd_iommu_disable(void);
+extern int amd_iommu_reenable(int);
+extern int amd_iommu_enable_faulting(void);
+
 /* IOMMUv2 specific functions */
 struct iommu_domain;
 
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index d0dab86..c9aa3d0 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -152,6 +152,7 @@
 #define CMD_INV_DEV_ENTRY       0x02
 #define CMD_INV_IOMMU_PAGES	0x03
 #define CMD_INV_IOTLB_PAGES	0x04
+#define CMD_INV_IRT		0x05
 #define CMD_COMPLETE_PPR	0x07
 #define CMD_INV_ALL		0x08
 
@@ -175,6 +176,7 @@
 #define DEV_ENTRY_EX            0x67
 #define DEV_ENTRY_SYSMGT1       0x68
 #define DEV_ENTRY_SYSMGT2       0x69
+#define DEV_ENTRY_IRQ_TBL_EN	0x80
 #define DEV_ENTRY_INIT_PASS     0xb8
 #define DEV_ENTRY_EINT_PASS     0xb9
 #define DEV_ENTRY_NMI_PASS      0xba
@@ -183,6 +185,8 @@
 #define DEV_ENTRY_MODE_MASK	0x07
 #define DEV_ENTRY_MODE_SHIFT	0x09
 
+#define MAX_DEV_TABLE_ENTRIES	0xffff
+
 /* constants to configure the command buffer */
 #define CMD_BUFFER_SIZE    8192
 #define CMD_BUFFER_UNINITIALIZED 1
@@ -255,7 +259,7 @@
 #define PAGE_SIZE_ALIGN(address, pagesize) \
 		((address) & ~((pagesize) - 1))
 /*
- * Creates an IOMMU PTE for an address an a given pagesize
+ * Creates an IOMMU PTE for an address and a given pagesize
  * The PTE has no permission bits set
  * Pagesize is expected to be a power-of-two larger than 4096
  */
@@ -334,6 +338,23 @@
 /* Only true if all IOMMUs support device IOTLBs */
 extern bool amd_iommu_iotlb_sup;
 
+#define MAX_IRQS_PER_TABLE	256
+#define IRQ_TABLE_ALIGNMENT	128
+
+struct irq_remap_table {
+	spinlock_t lock;
+	unsigned min_index;
+	u32 *table;
+};
+
+extern struct irq_remap_table **irq_lookup_table;
+
+/* Interrupt remapping feature used? */
+extern bool amd_iommu_irq_remap;
+
+/* kmem_cache to get tables with 128 byte alignement */
+extern struct kmem_cache *amd_iommu_irq_cache;
+
 /*
  * Make iterating over all IOMMUs easier
  */
@@ -404,7 +425,7 @@
 	struct list_head dev_data_list;	  /* For global dev_data_list */
 	struct iommu_dev_data *alias_data;/* The alias dev_data */
 	struct protection_domain *domain; /* Domain the device is bound to */
-	atomic_t bind;			  /* Domain attach reverent count */
+	atomic_t bind;			  /* Domain attach reference count */
 	u16 devid;			  /* PCI Device ID */
 	bool iommu_v2;			  /* Device can make use of IOMMUv2 */
 	bool passthrough;		  /* Default for device is pt_domain */
@@ -565,6 +586,16 @@
 	u32 stored_l2[0x83];
 };
 
+struct devid_map {
+	struct list_head list;
+	u8 id;
+	u16 devid;
+};
+
+/* Map HPET and IOAPIC ids to the devid used by the IOMMU */
+extern struct list_head ioapic_map;
+extern struct list_head hpet_map;
+
 /*
  * List with all IOMMUs in the system. This list is not locked because it is
  * only written and read at driver initialization or suspend time
@@ -678,6 +709,30 @@
 	return (((u16)bus) << 8) | devfn;
 }
 
+static inline int get_ioapic_devid(int id)
+{
+	struct devid_map *entry;
+
+	list_for_each_entry(entry, &ioapic_map, list) {
+		if (entry->id == id)
+			return entry->devid;
+	}
+
+	return -EINVAL;
+}
+
+static inline int get_hpet_devid(int id)
+{
+	struct devid_map *entry;
+
+	list_for_each_entry(entry, &hpet_map, list) {
+		if (entry->id == id)
+			return entry->devid;
+	}
+
+	return -EINVAL;
+}
+
 #ifdef CONFIG_AMD_IOMMU_STATS
 
 struct __iommu_counter {
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
index 80bad32..7fe44f8 100644
--- a/drivers/iommu/exynos-iommu.c
+++ b/drivers/iommu/exynos-iommu.c
@@ -840,8 +840,7 @@
 	if (__exynos_sysmmu_disable(data)) {
 		dev_dbg(dev, "%s: Detached IOMMU with pgtable %#lx\n",
 					__func__, __pa(priv->pgtable));
-		list_del(&data->node);
-		INIT_LIST_HEAD(&data->node);
+		list_del_init(&data->node);
 
 	} else {
 		dev_dbg(dev, "%s: Detaching IOMMU with pgtable %#lx delayed",
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index db820d7..d4a4cd4 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -589,7 +589,9 @@
 {
 	int i;
 
-	domain->iommu_coherency = 1;
+	i = find_first_bit(domain->iommu_bmp, g_num_of_iommus);
+
+	domain->iommu_coherency = i < g_num_of_iommus ? 1 : 0;
 
 	for_each_set_bit(i, domain->iommu_bmp, g_num_of_iommus) {
 		if (!ecap_coherent(g_iommus[i]->ecap)) {
diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
index 151690d..faf85d6 100644
--- a/drivers/iommu/irq_remapping.c
+++ b/drivers/iommu/irq_remapping.c
@@ -51,6 +51,11 @@
 void __init setup_irq_remapping_ops(void)
 {
 	remap_ops = &intel_irq_remap_ops;
+
+#ifdef CONFIG_AMD_IOMMU
+	if (amd_iommu_irq_ops.prepare() == 0)
+		remap_ops = &amd_iommu_irq_ops;
+#endif
 }
 
 int irq_remapping_supported(void)
diff --git a/drivers/iommu/irq_remapping.h b/drivers/iommu/irq_remapping.h
index b12974c..95363ac 100644
--- a/drivers/iommu/irq_remapping.h
+++ b/drivers/iommu/irq_remapping.h
@@ -82,6 +82,12 @@
 };
 
 extern struct irq_remap_ops intel_irq_remap_ops;
+extern struct irq_remap_ops amd_iommu_irq_ops;
+
+#else  /* CONFIG_IRQ_REMAP */
+
+#define irq_remapping_enabled 0
+#define disable_irq_remap     1
 
 #endif /* CONFIG_IRQ_REMAP */
 
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c
index 2a4bb36..0b4d62e 100644
--- a/drivers/iommu/tegra-smmu.c
+++ b/drivers/iommu/tegra-smmu.c
@@ -32,14 +32,55 @@
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_iommu.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
 
 #include <asm/page.h>
 #include <asm/cacheflush.h>
 
 #include <mach/iomap.h>
-#include <mach/smmu.h>
 #include <mach/tegra-ahb.h>
 
+enum smmu_hwgrp {
+	HWGRP_AFI,
+	HWGRP_AVPC,
+	HWGRP_DC,
+	HWGRP_DCB,
+	HWGRP_EPP,
+	HWGRP_G2,
+	HWGRP_HC,
+	HWGRP_HDA,
+	HWGRP_ISP,
+	HWGRP_MPE,
+	HWGRP_NV,
+	HWGRP_NV2,
+	HWGRP_PPCS,
+	HWGRP_SATA,
+	HWGRP_VDE,
+	HWGRP_VI,
+
+	HWGRP_COUNT,
+
+	HWGRP_END = ~0,
+};
+
+#define HWG_AFI		(1 << HWGRP_AFI)
+#define HWG_AVPC	(1 << HWGRP_AVPC)
+#define HWG_DC		(1 << HWGRP_DC)
+#define HWG_DCB		(1 << HWGRP_DCB)
+#define HWG_EPP		(1 << HWGRP_EPP)
+#define HWG_G2		(1 << HWGRP_G2)
+#define HWG_HC		(1 << HWGRP_HC)
+#define HWG_HDA		(1 << HWGRP_HDA)
+#define HWG_ISP		(1 << HWGRP_ISP)
+#define HWG_MPE		(1 << HWGRP_MPE)
+#define HWG_NV		(1 << HWGRP_NV)
+#define HWG_NV2		(1 << HWGRP_NV2)
+#define HWG_PPCS	(1 << HWGRP_PPCS)
+#define HWG_SATA	(1 << HWGRP_SATA)
+#define HWG_VDE		(1 << HWGRP_VDE)
+#define HWG_VI		(1 << HWGRP_VI)
+
 /* bitmap of the page sizes currently supported */
 #define SMMU_IOMMU_PGSIZES	(SZ_4K)
 
@@ -47,16 +88,29 @@
 #define SMMU_CONFIG_DISABLE			0
 #define SMMU_CONFIG_ENABLE			1
 
-#define SMMU_TLB_CONFIG				0x14
-#define SMMU_TLB_CONFIG_STATS__MASK		(1 << 31)
-#define SMMU_TLB_CONFIG_STATS__ENABLE		(1 << 31)
+/* REVISIT: To support multiple MCs */
+enum {
+	_MC = 0,
+};
+
+enum {
+	_TLB = 0,
+	_PTC,
+};
+
+#define SMMU_CACHE_CONFIG_BASE			0x14
+#define __SMMU_CACHE_CONFIG(mc, cache)		(SMMU_CACHE_CONFIG_BASE + 4 * cache)
+#define SMMU_CACHE_CONFIG(cache)		__SMMU_CACHE_CONFIG(_MC, cache)
+
+#define SMMU_CACHE_CONFIG_STATS_SHIFT		31
+#define SMMU_CACHE_CONFIG_STATS_ENABLE		(1 << SMMU_CACHE_CONFIG_STATS_SHIFT)
+#define SMMU_CACHE_CONFIG_STATS_TEST_SHIFT	30
+#define SMMU_CACHE_CONFIG_STATS_TEST		(1 << SMMU_CACHE_CONFIG_STATS_TEST_SHIFT)
+
 #define SMMU_TLB_CONFIG_HIT_UNDER_MISS__ENABLE	(1 << 29)
 #define SMMU_TLB_CONFIG_ACTIVE_LINES__VALUE	0x10
 #define SMMU_TLB_CONFIG_RESET_VAL		0x20000010
 
-#define SMMU_PTC_CONFIG				0x18
-#define SMMU_PTC_CONFIG_STATS__MASK		(1 << 31)
-#define SMMU_PTC_CONFIG_STATS__ENABLE		(1 << 31)
 #define SMMU_PTC_CONFIG_CACHE__ENABLE		(1 << 29)
 #define SMMU_PTC_CONFIG_INDEX_MAP__PATTERN	0x3f
 #define SMMU_PTC_CONFIG_RESET_VAL		0x2000003f
@@ -86,10 +140,10 @@
 
 #define SMMU_ASID_SECURITY			0x38
 
-#define SMMU_STATS_TLB_HIT_COUNT		0x1f0
-#define SMMU_STATS_TLB_MISS_COUNT		0x1f4
-#define SMMU_STATS_PTC_HIT_COUNT		0x1f8
-#define SMMU_STATS_PTC_MISS_COUNT		0x1fc
+#define SMMU_STATS_CACHE_COUNT_BASE		0x1f0
+
+#define SMMU_STATS_CACHE_COUNT(mc, cache, hitmiss)		\
+	(SMMU_STATS_CACHE_COUNT_BASE + 8 * cache + 4 * hitmiss)
 
 #define SMMU_TRANSLATION_ENABLE_0		0x228
 #define SMMU_TRANSLATION_ENABLE_1		0x22c
@@ -231,6 +285,12 @@
 	spinlock_t		client_lock; /* for client list */
 };
 
+struct smmu_debugfs_info {
+	struct smmu_device *smmu;
+	int mc;
+	int cache;
+};
+
 /*
  * Per SMMU device - IOMMU device
  */
@@ -251,6 +311,9 @@
 	unsigned long translation_enable_2;
 	unsigned long asid_security;
 
+	struct dentry *debugfs_root;
+	struct smmu_debugfs_info *debugfs_info;
+
 	struct device_node *ahb;
 
 	int		num_as;
@@ -412,8 +475,8 @@
 	smmu_write(smmu, smmu->translation_enable_1, SMMU_TRANSLATION_ENABLE_1);
 	smmu_write(smmu, smmu->translation_enable_2, SMMU_TRANSLATION_ENABLE_2);
 	smmu_write(smmu, smmu->asid_security, SMMU_ASID_SECURITY);
-	smmu_write(smmu, SMMU_TLB_CONFIG_RESET_VAL, SMMU_TLB_CONFIG);
-	smmu_write(smmu, SMMU_PTC_CONFIG_RESET_VAL, SMMU_PTC_CONFIG);
+	smmu_write(smmu, SMMU_TLB_CONFIG_RESET_VAL, SMMU_CACHE_CONFIG(_TLB));
+	smmu_write(smmu, SMMU_PTC_CONFIG_RESET_VAL, SMMU_CACHE_CONFIG(_PTC));
 
 	smmu_flush_regs(smmu, 1);
 
@@ -895,6 +958,175 @@
 	.pgsize_bitmap	= SMMU_IOMMU_PGSIZES,
 };
 
+/* Should be in the order of enum */
+static const char * const smmu_debugfs_mc[] = { "mc", };
+static const char * const smmu_debugfs_cache[] = {  "tlb", "ptc", };
+
+static ssize_t smmu_debugfs_stats_write(struct file *file,
+					const char __user *buffer,
+					size_t count, loff_t *pos)
+{
+	struct smmu_debugfs_info *info;
+	struct smmu_device *smmu;
+	struct dentry *dent;
+	int i;
+	enum {
+		_OFF = 0,
+		_ON,
+		_RESET,
+	};
+	const char * const command[] = {
+		[_OFF]		= "off",
+		[_ON]		= "on",
+		[_RESET]	= "reset",
+	};
+	char str[] = "reset";
+	u32 val;
+	size_t offs;
+
+	count = min_t(size_t, count, sizeof(str));
+	if (copy_from_user(str, buffer, count))
+		return -EINVAL;
+
+	for (i = 0; i < ARRAY_SIZE(command); i++)
+		if (strncmp(str, command[i],
+			    strlen(command[i])) == 0)
+			break;
+
+	if (i == ARRAY_SIZE(command))
+		return -EINVAL;
+
+	dent = file->f_dentry;
+	info = dent->d_inode->i_private;
+	smmu = info->smmu;
+
+	offs = SMMU_CACHE_CONFIG(info->cache);
+	val = smmu_read(smmu, offs);
+	switch (i) {
+	case _OFF:
+		val &= ~SMMU_CACHE_CONFIG_STATS_ENABLE;
+		val &= ~SMMU_CACHE_CONFIG_STATS_TEST;
+		smmu_write(smmu, val, offs);
+		break;
+	case _ON:
+		val |= SMMU_CACHE_CONFIG_STATS_ENABLE;
+		val &= ~SMMU_CACHE_CONFIG_STATS_TEST;
+		smmu_write(smmu, val, offs);
+		break;
+	case _RESET:
+		val |= SMMU_CACHE_CONFIG_STATS_TEST;
+		smmu_write(smmu, val, offs);
+		val &= ~SMMU_CACHE_CONFIG_STATS_TEST;
+		smmu_write(smmu, val, offs);
+		break;
+	default:
+		BUG();
+		break;
+	}
+
+	dev_dbg(smmu->dev, "%s() %08x, %08x @%08x\n", __func__,
+		val, smmu_read(smmu, offs), offs);
+
+	return count;
+}
+
+static int smmu_debugfs_stats_show(struct seq_file *s, void *v)
+{
+	struct smmu_debugfs_info *info;
+	struct smmu_device *smmu;
+	struct dentry *dent;
+	int i;
+	const char * const stats[] = { "hit", "miss", };
+
+	dent = d_find_alias(s->private);
+	info = dent->d_inode->i_private;
+	smmu = info->smmu;
+
+	for (i = 0; i < ARRAY_SIZE(stats); i++) {
+		u32 val;
+		size_t offs;
+
+		offs = SMMU_STATS_CACHE_COUNT(info->mc, info->cache, i);
+		val = smmu_read(smmu, offs);
+		seq_printf(s, "%s:%08x ", stats[i], val);
+
+		dev_dbg(smmu->dev, "%s() %s %08x @%08x\n", __func__,
+			stats[i], val, offs);
+	}
+	seq_printf(s, "\n");
+
+	return 0;
+}
+
+static int smmu_debugfs_stats_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, smmu_debugfs_stats_show, inode);
+}
+
+static const struct file_operations smmu_debugfs_stats_fops = {
+	.open		= smmu_debugfs_stats_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= smmu_debugfs_stats_write,
+};
+
+static void smmu_debugfs_delete(struct smmu_device *smmu)
+{
+	debugfs_remove_recursive(smmu->debugfs_root);
+	kfree(smmu->debugfs_info);
+}
+
+static void smmu_debugfs_create(struct smmu_device *smmu)
+{
+	int i;
+	size_t bytes;
+	struct dentry *root;
+
+	bytes = ARRAY_SIZE(smmu_debugfs_mc) * ARRAY_SIZE(smmu_debugfs_cache) *
+		sizeof(*smmu->debugfs_info);
+	smmu->debugfs_info = kmalloc(bytes, GFP_KERNEL);
+	if (!smmu->debugfs_info)
+		return;
+
+	root = debugfs_create_dir(dev_name(smmu->dev), NULL);
+	if (!root)
+		goto err_out;
+	smmu->debugfs_root = root;
+
+	for (i = 0; i < ARRAY_SIZE(smmu_debugfs_mc); i++) {
+		int j;
+		struct dentry *mc;
+
+		mc = debugfs_create_dir(smmu_debugfs_mc[i], root);
+		if (!mc)
+			goto err_out;
+
+		for (j = 0; j < ARRAY_SIZE(smmu_debugfs_cache); j++) {
+			struct dentry *cache;
+			struct smmu_debugfs_info *info;
+
+			info = smmu->debugfs_info;
+			info += i * ARRAY_SIZE(smmu_debugfs_mc) + j;
+			info->smmu = smmu;
+			info->mc = i;
+			info->cache = j;
+
+			cache = debugfs_create_file(smmu_debugfs_cache[j],
+						    S_IWUGO | S_IRUGO, mc,
+						    (void *)info,
+						    &smmu_debugfs_stats_fops);
+			if (!cache)
+				goto err_out;
+		}
+	}
+
+	return;
+
+err_out:
+	smmu_debugfs_delete(smmu);
+}
+
 static int tegra_smmu_suspend(struct device *dev)
 {
 	struct smmu_device *smmu = dev_get_drvdata(dev);
@@ -999,6 +1231,7 @@
 	if (!smmu->avp_vector_page)
 		return -ENOMEM;
 
+	smmu_debugfs_create(smmu);
 	smmu_handle = smmu;
 	return 0;
 }
@@ -1008,6 +1241,8 @@
 	struct smmu_device *smmu = platform_get_drvdata(pdev);
 	int i;
 
+	smmu_debugfs_delete(smmu);
+
 	smmu_write(smmu, SMMU_CONFIG_DISABLE, SMMU_CONFIG);
 	for (i = 0; i < smmu->num_as; i++)
 		free_pdir(&smmu->as[i]);
diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig
index 452fde9..70ecd0c 100644
--- a/drivers/isdn/hisax/Kconfig
+++ b/drivers/isdn/hisax/Kconfig
@@ -109,7 +109,7 @@
 
 config HISAX_TELESPCI
 	bool "Teles PCI"
-	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
+	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN)))
 	help
 	  This enables HiSax support for the Teles PCI.
 	  See <file:Documentation/isdn/README.HiSax> on how to configure it.
@@ -237,7 +237,7 @@
 
 config HISAX_NETJET
 	bool "NETjet card"
-	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
+	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN)))
 	help
 	  This enables HiSax support for the NetJet from Traverse
 	  Technologies.
@@ -248,7 +248,7 @@
 
 config HISAX_NETJET_U
 	bool "NETspider U card"
-	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
+	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN)))
 	help
 	  This enables HiSax support for the Netspider U interface ISDN card
 	  from Traverse Technologies.
@@ -316,7 +316,7 @@
 
 config HISAX_HFC_PCI
 	bool "HFC PCI-Bus cards"
-	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
+	depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN)))
 	help
 	  This enables HiSax support for the HFC-S PCI 2BDS0 based cards.
 
@@ -341,7 +341,7 @@
 
 config HISAX_ENTERNOW_PCI
 	bool "Formula-n enter:now PCI card"
-	depends on HISAX_NETJET && PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV))
+	depends on HISAX_NETJET && PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN)))
 	help
 	  This enables HiSax support for the Formula-n enter:now PCI
 	  ISDN card.
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 16578d3..f508def 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -63,6 +63,17 @@
 	  hardware-accelerated blinking with maximum on and off periods of 9.8
 	  and 77 seconds respectively.
 
+config LEDS_LM3642
+	tristate "LED support for LM3642 Chip"
+	depends on LEDS_CLASS && I2C
+	select REGMAP_I2C
+	help
+	  This option enables support for LEDs connected to LM3642.
+	  The LM3642 is a 4MHz fixed-frequency synchronous boost
+	  converter plus 1.5A constant current driver for a high-current
+	  white LED.
+
+
 config LEDS_LOCOMO
 	tristate "LED Support for Locomo device"
 	depends on LEDS_CLASS
@@ -192,11 +203,12 @@
 	  programming the engines.
 
 config LEDS_LP5523
-	tristate "LED Support for N.S. LP5523 LED driver chip"
+	tristate "LED Support for TI/National LP5523/55231 LED driver chip"
 	depends on LEDS_CLASS && I2C
 	help
-	  If you say yes here you get support for the National Semiconductor
-	  LP5523 LED driver. It is 9 channel chip with programmable engines.
+	  If you say yes here you get support for TI/National Semiconductor
+	  LP5523/55231 LED driver.
+	  It is 9 channel chip with programmable engines.
 	  Driver provides direct control via LED class and interface for
 	  programming the engines.
 
@@ -422,13 +434,13 @@
 	  This option enables support for on-chip LED drivers on
 	  MAXIM MAX8997 PMIC.
 
-config LEDS_LM3556
-	tristate "LED support for LM3556 Chip"
+config LEDS_LM355x
+	tristate "LED support for LM355x Chips, LM3554 and LM3556"
 	depends on LEDS_CLASS && I2C
 	select REGMAP_I2C
 	help
-	  This option enables support for LEDs connected to LM3556.
-	  LM3556 includes Torch, Flash and Indicator functions.
+	  This option enables support for LEDs connected to LM355x.
+	  LM355x includes Torch, Flash and Indicator functions.
 
 config LEDS_OT200
 	tristate "LED support for the Bachmann OT200"
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index a9b627c..3fb9641 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -11,6 +11,7 @@
 obj-$(CONFIG_LEDS_LOCOMO)		+= leds-locomo.o
 obj-$(CONFIG_LEDS_LM3530)		+= leds-lm3530.o
 obj-$(CONFIG_LEDS_LM3533)		+= leds-lm3533.o
+obj-$(CONFIG_LEDS_LM3642)		+= leds-lm3642.o
 obj-$(CONFIG_LEDS_MIKROTIK_RB532)	+= leds-rb532.o
 obj-$(CONFIG_LEDS_S3C24XX)		+= leds-s3c24xx.o
 obj-$(CONFIG_LEDS_NET48XX)		+= leds-net48xx.o
@@ -48,7 +49,7 @@
 obj-$(CONFIG_LEDS_ASIC3)		+= leds-asic3.o
 obj-$(CONFIG_LEDS_RENESAS_TPU)		+= leds-renesas-tpu.o
 obj-$(CONFIG_LEDS_MAX8997)		+= leds-max8997.o
-obj-$(CONFIG_LEDS_LM3556)		+= leds-lm3556.o
+obj-$(CONFIG_LEDS_LM355x)		+= leds-lm355x.o
 obj-$(CONFIG_LEDS_BLINKM)		+= leds-blinkm.o
 
 # LED SPI Drivers
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
index c599095..48cce18 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -124,6 +124,16 @@
 	mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay));
 }
 
+static void set_brightness_delayed(struct work_struct *ws)
+{
+	struct led_classdev *led_cdev =
+		container_of(ws, struct led_classdev, set_brightness_work);
+
+	led_stop_software_blink(led_cdev);
+
+	__led_set_brightness(led_cdev, led_cdev->delayed_set_value);
+}
+
 /**
  * led_classdev_suspend - suspend an led_classdev.
  * @led_cdev: the led_classdev to suspend.
@@ -191,6 +201,8 @@
 
 	led_update_brightness(led_cdev);
 
+	INIT_WORK(&led_cdev->set_brightness_work, set_brightness_delayed);
+
 	init_timer(&led_cdev->blink_timer);
 	led_cdev->blink_timer.function = led_timer_function;
 	led_cdev->blink_timer.data = (unsigned long)led_cdev;
@@ -221,7 +233,10 @@
 	up_write(&led_cdev->trigger_lock);
 #endif
 
+	cancel_work_sync(&led_cdev->set_brightness_work);
+
 	/* Stop blinking */
+	led_stop_software_blink(led_cdev);
 	led_set_brightness(led_cdev, LED_OFF);
 
 	device_unregister(led_cdev->dev);
diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c
index 2ab05af..ce8921a 100644
--- a/drivers/leds/led-core.c
+++ b/drivers/leds/led-core.c
@@ -103,13 +103,23 @@
 }
 EXPORT_SYMBOL(led_blink_set_oneshot);
 
-void led_set_brightness(struct led_classdev *led_cdev,
-			enum led_brightness brightness)
+void led_stop_software_blink(struct led_classdev *led_cdev)
 {
-	/* stop and clear soft-blink timer */
 	del_timer_sync(&led_cdev->blink_timer);
 	led_cdev->blink_delay_on = 0;
 	led_cdev->blink_delay_off = 0;
+}
+EXPORT_SYMBOL_GPL(led_stop_software_blink);
+
+void led_set_brightness(struct led_classdev *led_cdev,
+			enum led_brightness brightness)
+{
+	/* delay brightness setting if need to stop soft-blink timer */
+	if (led_cdev->blink_delay_on || led_cdev->blink_delay_off) {
+		led_cdev->delayed_set_value = brightness;
+		schedule_work(&led_cdev->set_brightness_work);
+		return;
+	}
 
 	__led_set_brightness(led_cdev, brightness);
 }
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index 363975b..262eb41 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -102,6 +102,12 @@
 void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
 {
 	unsigned long flags;
+	char *event = NULL;
+	char *envp[2];
+	const char *name;
+
+	name = trig ? trig->name : "none";
+	event = kasprintf(GFP_KERNEL, "TRIGGER=%s", name);
 
 	/* Remove any existing trigger */
 	if (led_cdev->trigger) {
@@ -109,6 +115,8 @@
 		list_del(&led_cdev->trig_list);
 		write_unlock_irqrestore(&led_cdev->trigger->leddev_list_lock,
 			flags);
+		cancel_work_sync(&led_cdev->set_brightness_work);
+		led_stop_software_blink(led_cdev);
 		if (led_cdev->trigger->deactivate)
 			led_cdev->trigger->deactivate(led_cdev);
 		led_cdev->trigger = NULL;
@@ -122,6 +130,13 @@
 		if (trig->activate)
 			trig->activate(led_cdev);
 	}
+
+	if (event) {
+		envp[0] = event;
+		envp[1] = NULL;
+		kobject_uevent_env(&led_cdev->dev->kobj, KOBJ_CHANGE, envp);
+		kfree(event);
+	}
 }
 EXPORT_SYMBOL_GPL(led_trigger_set);
 
@@ -224,7 +239,7 @@
 		struct led_classdev *led_cdev;
 
 		led_cdev = list_entry(entry, struct led_classdev, trig_list);
-		__led_set_brightness(led_cdev, brightness);
+		led_set_brightness(led_cdev, brightness);
 	}
 	read_unlock(&trig->leddev_list_lock);
 }
diff --git a/drivers/leds/leds-clevo-mail.c b/drivers/leds/leds-clevo-mail.c
index 1ed1677..e024b0b 100644
--- a/drivers/leds/leds-clevo-mail.c
+++ b/drivers/leds/leds-clevo-mail.c
@@ -31,7 +31,7 @@
 }
 
 /*
- * struct mail_led_whitelist - List of known good models
+ * struct clevo_mail_led_dmi_table - List of known good models
  *
  * Contains the known good models this driver is compatible with.
  * When adding a new model try to be as strict as possible. This
@@ -39,7 +39,7 @@
  * detected as working, but in reality it is not) as low as
  * possible.
  */
-static struct dmi_system_id __initdata mail_led_whitelist[] = {
+static struct dmi_system_id __initdata clevo_mail_led_dmi_table[] = {
 	{
 		.callback = clevo_mail_led_dmi_callback,
 		.ident = "Clevo D410J",
@@ -59,11 +59,10 @@
 	},
 	{
 		.callback = clevo_mail_led_dmi_callback,
-		.ident = "Positivo Mobile",
+		.ident = "Clevo M5x0V",
 		.matches = {
 			DMI_MATCH(DMI_BOARD_VENDOR, "CLEVO Co. "),
 			DMI_MATCH(DMI_BOARD_NAME, "M5X0V "),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Positivo Mobile"),
 			DMI_MATCH(DMI_PRODUCT_VERSION, "VT6198")
 		}
 	},
@@ -89,6 +88,7 @@
 	},
 	{ }
 };
+MODULE_DEVICE_TABLE(dmi, clevo_mail_led_dmi_table);
 
 static void clevo_mail_led_set(struct led_classdev *led_cdev,
 				enum led_brightness value)
@@ -180,7 +180,7 @@
 
 	/* Check with the help of DMI if we are running on supported hardware */
 	if (!nodetect) {
-		count = dmi_check_system(mail_led_whitelist);
+		count = dmi_check_system(clevo_mail_led_dmi_table);
 	} else {
 		count = 1;
 		printk(KERN_ERR KBUILD_MODNAME ": Skipping DMI detection. "
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index c032b21..087d1e6 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -20,6 +20,7 @@
 #include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/module.h>
+#include <linux/pinctrl/consumer.h>
 
 struct gpio_led_data {
 	struct led_classdev cdev;
@@ -170,11 +171,10 @@
 {
 	struct device_node *np = pdev->dev.of_node, *child;
 	struct gpio_leds_priv *priv;
-	int count = 0, ret;
+	int count, ret;
 
 	/* count LEDs in this device, so we know how much to allocate */
-	for_each_child_of_node(np, child)
-		count++;
+	count = of_get_child_count(np);
 	if (!count)
 		return NULL;
 
@@ -228,7 +228,6 @@
 {
 	return NULL;
 }
-#define of_gpio_leds_match NULL
 #endif /* CONFIG_OF_GPIO */
 
 
@@ -236,8 +235,14 @@
 {
 	struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
 	struct gpio_leds_priv *priv;
+	struct pinctrl *pinctrl;
 	int i, ret = 0;
 
+	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+	if (IS_ERR(pinctrl))
+		dev_warn(&pdev->dev,
+			"pins are not configured from the driver\n");
+
 	if (pdata && pdata->num_leds) {
 		priv = devm_kzalloc(&pdev->dev,
 				sizeof_gpio_leds_priv(pdata->num_leds),
@@ -270,13 +275,13 @@
 
 static int __devexit gpio_led_remove(struct platform_device *pdev)
 {
-	struct gpio_leds_priv *priv = dev_get_drvdata(&pdev->dev);
+	struct gpio_leds_priv *priv = platform_get_drvdata(pdev);
 	int i;
 
 	for (i = 0; i < priv->num_leds; i++)
 		delete_gpio_led(&priv->leds[i]);
 
-	dev_set_drvdata(&pdev->dev, NULL);
+	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
@@ -287,7 +292,7 @@
 	.driver		= {
 		.name	= "leds-gpio",
 		.owner	= THIS_MODULE,
-		.of_match_table = of_gpio_leds_match,
+		.of_match_table = of_match_ptr(of_gpio_leds_match),
 	},
 };
 
diff --git a/drivers/leds/leds-lm3530.c b/drivers/leds/leds-lm3530.c
index 23637bd..b26306f 100644
--- a/drivers/leds/leds-lm3530.c
+++ b/drivers/leds/leds-lm3530.c
@@ -150,7 +150,7 @@
 		if (sysfs_streq(str, mode_map[i].mode))
 			return mode_map[i].mode_val;
 
-	return -1;
+	return -EINVAL;
 }
 
 static void lm3530_als_configure(struct lm3530_platform_data *pdata,
@@ -358,7 +358,7 @@
 	mode = lm3530_get_mode_from_str(buf);
 	if (mode < 0) {
 		dev_err(dev, "Invalid mode\n");
-		return -EINVAL;
+		return mode;
 	}
 
 	drvdata->mode = mode;
@@ -416,7 +416,7 @@
 
 	i2c_set_clientdata(client, drvdata);
 
-	drvdata->regulator = regulator_get(&client->dev, "vin");
+	drvdata->regulator = devm_regulator_get(&client->dev, "vin");
 	if (IS_ERR(drvdata->regulator)) {
 		dev_err(&client->dev, "regulator get failed\n");
 		err = PTR_ERR(drvdata->regulator);
@@ -429,15 +429,13 @@
 		if (err < 0) {
 			dev_err(&client->dev,
 				"Register Init failed: %d\n", err);
-			err = -ENODEV;
-			goto err_reg_init;
+			return err;
 		}
 	}
 	err = led_classdev_register(&client->dev, &drvdata->led_dev);
 	if (err < 0) {
 		dev_err(&client->dev, "Register led class failed: %d\n", err);
-		err = -ENODEV;
-		goto err_class_register;
+		return err;
 	}
 
 	err = device_create_file(drvdata->led_dev.dev, &dev_attr_mode);
@@ -451,9 +449,6 @@
 
 err_create_file:
 	led_classdev_unregister(&drvdata->led_dev);
-err_class_register:
-err_reg_init:
-	regulator_put(drvdata->regulator);
 	return err;
 }
 
@@ -465,7 +460,6 @@
 
 	if (drvdata->enable)
 		regulator_disable(drvdata->regulator);
-	regulator_put(drvdata->regulator);
 	led_classdev_unregister(&drvdata->led_dev);
 	return 0;
 }
diff --git a/drivers/leds/leds-lm3556.c b/drivers/leds/leds-lm3556.c
deleted file mode 100644
index 3062abd..0000000
--- a/drivers/leds/leds-lm3556.c
+++ /dev/null
@@ -1,512 +0,0 @@
-/*
- * Simple driver for Texas Instruments LM3556 LED Flash driver chip (Rev0x03)
- * Copyright (C) 2012 Texas Instruments
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Please refer Documentation/leds/leds-lm3556.txt file.
- */
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/leds.h>
-#include <linux/slab.h>
-#include <linux/platform_device.h>
-#include <linux/fs.h>
-#include <linux/regmap.h>
-#include <linux/platform_data/leds-lm3556.h>
-
-#define REG_FILT_TIME			(0x0)
-#define REG_IVFM_MODE			(0x1)
-#define REG_NTC				(0x2)
-#define REG_INDIC_TIME			(0x3)
-#define REG_INDIC_BLINK			(0x4)
-#define REG_INDIC_PERIOD		(0x5)
-#define REG_TORCH_TIME			(0x6)
-#define REG_CONF			(0x7)
-#define REG_FLASH			(0x8)
-#define REG_I_CTRL			(0x9)
-#define REG_ENABLE			(0xA)
-#define REG_FLAG			(0xB)
-#define REG_MAX				(0xB)
-
-#define IVFM_FILTER_TIME_SHIFT		(3)
-#define UVLO_EN_SHIFT			(7)
-#define HYSTERSIS_SHIFT			(5)
-#define IVM_D_TH_SHIFT			(2)
-#define IVFM_ADJ_MODE_SHIFT		(0)
-#define NTC_EVENT_LVL_SHIFT		(5)
-#define NTC_TRIP_TH_SHIFT		(2)
-#define NTC_BIAS_I_LVL_SHIFT		(0)
-#define INDIC_RAMP_UP_TIME_SHIFT	(3)
-#define INDIC_RAMP_DN_TIME_SHIFT	(0)
-#define INDIC_N_BLANK_SHIFT		(4)
-#define INDIC_PULSE_TIME_SHIFT		(0)
-#define INDIC_N_PERIOD_SHIFT		(0)
-#define TORCH_RAMP_UP_TIME_SHIFT	(3)
-#define TORCH_RAMP_DN_TIME_SHIFT	(0)
-#define STROBE_USUAGE_SHIFT		(7)
-#define STROBE_PIN_POLARITY_SHIFT	(6)
-#define TORCH_PIN_POLARITY_SHIFT	(5)
-#define TX_PIN_POLARITY_SHIFT		(4)
-#define TX_EVENT_LVL_SHIFT		(3)
-#define IVFM_EN_SHIFT			(2)
-#define NTC_MODE_SHIFT			(1)
-#define INDIC_MODE_SHIFT		(0)
-#define INDUCTOR_I_LIMIT_SHIFT		(6)
-#define FLASH_RAMP_TIME_SHIFT		(3)
-#define FLASH_TOUT_TIME_SHIFT		(0)
-#define TORCH_I_SHIFT			(4)
-#define FLASH_I_SHIFT			(0)
-#define NTC_EN_SHIFT			(7)
-#define TX_PIN_EN_SHIFT			(6)
-#define STROBE_PIN_EN_SHIFT		(5)
-#define TORCH_PIN_EN_SHIFT		(4)
-#define PRECHG_MODE_EN_SHIFT		(3)
-#define PASS_MODE_ONLY_EN_SHIFT		(2)
-#define MODE_BITS_SHIFT			(0)
-
-#define IVFM_FILTER_TIME_MASK		(0x3)
-#define UVLO_EN_MASK			(0x1)
-#define HYSTERSIS_MASK			(0x3)
-#define IVM_D_TH_MASK			(0x7)
-#define IVFM_ADJ_MODE_MASK		(0x3)
-#define NTC_EVENT_LVL_MASK		(0x1)
-#define NTC_TRIP_TH_MASK		(0x7)
-#define NTC_BIAS_I_LVL_MASK		(0x3)
-#define INDIC_RAMP_UP_TIME_MASK		(0x7)
-#define INDIC_RAMP_DN_TIME_MASK		(0x7)
-#define INDIC_N_BLANK_MASK		(0x7)
-#define INDIC_PULSE_TIME_MASK		(0x7)
-#define INDIC_N_PERIOD_MASK		(0x7)
-#define TORCH_RAMP_UP_TIME_MASK		(0x7)
-#define TORCH_RAMP_DN_TIME_MASK		(0x7)
-#define STROBE_USUAGE_MASK		(0x1)
-#define STROBE_PIN_POLARITY_MASK	(0x1)
-#define TORCH_PIN_POLARITY_MASK		(0x1)
-#define TX_PIN_POLARITY_MASK		(0x1)
-#define TX_EVENT_LVL_MASK		(0x1)
-#define IVFM_EN_MASK			(0x1)
-#define NTC_MODE_MASK			(0x1)
-#define INDIC_MODE_MASK			(0x1)
-#define INDUCTOR_I_LIMIT_MASK		(0x3)
-#define FLASH_RAMP_TIME_MASK		(0x7)
-#define FLASH_TOUT_TIME_MASK		(0x7)
-#define TORCH_I_MASK			(0x7)
-#define FLASH_I_MASK			(0xF)
-#define NTC_EN_MASK			(0x1)
-#define TX_PIN_EN_MASK			(0x1)
-#define STROBE_PIN_EN_MASK		(0x1)
-#define TORCH_PIN_EN_MASK		(0x1)
-#define PRECHG_MODE_EN_MASK		(0x1)
-#define PASS_MODE_ONLY_EN_MASK		(0x1)
-#define MODE_BITS_MASK			(0x13)
-#define EX_PIN_CONTROL_MASK		(0xF1)
-#define EX_PIN_ENABLE_MASK		(0x70)
-
-enum lm3556_indic_pulse_time {
-	PULSE_TIME_0_MS = 0,
-	PULSE_TIME_32_MS,
-	PULSE_TIME_64_MS,
-	PULSE_TIME_92_MS,
-	PULSE_TIME_128_MS,
-	PULSE_TIME_160_MS,
-	PULSE_TIME_196_MS,
-	PULSE_TIME_224_MS,
-	PULSE_TIME_256_MS,
-	PULSE_TIME_288_MS,
-	PULSE_TIME_320_MS,
-	PULSE_TIME_352_MS,
-	PULSE_TIME_384_MS,
-	PULSE_TIME_416_MS,
-	PULSE_TIME_448_MS,
-	PULSE_TIME_480_MS,
-};
-
-enum lm3556_indic_n_blank {
-	INDIC_N_BLANK_0 = 0,
-	INDIC_N_BLANK_1,
-	INDIC_N_BLANK_2,
-	INDIC_N_BLANK_3,
-	INDIC_N_BLANK_4,
-	INDIC_N_BLANK_5,
-	INDIC_N_BLANK_6,
-	INDIC_N_BLANK_7,
-	INDIC_N_BLANK_8,
-	INDIC_N_BLANK_9,
-	INDIC_N_BLANK_10,
-	INDIC_N_BLANK_11,
-	INDIC_N_BLANK_12,
-	INDIC_N_BLANK_13,
-	INDIC_N_BLANK_14,
-	INDIC_N_BLANK_15,
-};
-
-enum lm3556_indic_period {
-	INDIC_PERIOD_0 = 0,
-	INDIC_PERIOD_1,
-	INDIC_PERIOD_2,
-	INDIC_PERIOD_3,
-	INDIC_PERIOD_4,
-	INDIC_PERIOD_5,
-	INDIC_PERIOD_6,
-	INDIC_PERIOD_7,
-};
-
-enum lm3556_mode {
-	MODES_STASNDBY = 0,
-	MODES_INDIC,
-	MODES_TORCH,
-	MODES_FLASH
-};
-
-#define INDIC_PATTERN_SIZE 4
-
-struct indicator {
-	u8 blinking;
-	u8 period_cnt;
-};
-
-struct lm3556_chip_data {
-	struct device *dev;
-
-	struct led_classdev cdev_flash;
-	struct led_classdev cdev_torch;
-	struct led_classdev cdev_indicator;
-
-	struct lm3556_platform_data *pdata;
-	struct regmap *regmap;
-	struct mutex lock;
-
-	unsigned int last_flag;
-};
-
-/* indicator pattern */
-static struct indicator indicator_pattern[INDIC_PATTERN_SIZE] = {
-	[0] = {(INDIC_N_BLANK_1 << INDIC_N_BLANK_SHIFT)
-	       | PULSE_TIME_32_MS, INDIC_PERIOD_1},
-	[1] = {(INDIC_N_BLANK_15 << INDIC_N_BLANK_SHIFT)
-	       | PULSE_TIME_32_MS, INDIC_PERIOD_2},
-	[2] = {(INDIC_N_BLANK_10 << INDIC_N_BLANK_SHIFT)
-	       | PULSE_TIME_32_MS, INDIC_PERIOD_4},
-	[3] = {(INDIC_N_BLANK_5 << INDIC_N_BLANK_SHIFT)
-	       | PULSE_TIME_32_MS, INDIC_PERIOD_7},
-};
-
-/* chip initialize */
-static int __devinit lm3556_chip_init(struct lm3556_chip_data *chip)
-{
-	unsigned int reg_val;
-	int ret;
-	struct lm3556_platform_data *pdata = chip->pdata;
-
-	/* set config register */
-	ret = regmap_read(chip->regmap, REG_CONF, &reg_val);
-	if (ret < 0) {
-		dev_err(chip->dev, "Failed to read REG_CONF Register\n");
-		goto out;
-	}
-
-	reg_val &= (~EX_PIN_CONTROL_MASK);
-	reg_val |= ((pdata->torch_pin_polarity & 0x01)
-		    << TORCH_PIN_POLARITY_SHIFT);
-	reg_val |= ((pdata->strobe_usuage & 0x01) << STROBE_USUAGE_SHIFT);
-	reg_val |= ((pdata->strobe_pin_polarity & 0x01)
-		    << STROBE_PIN_POLARITY_SHIFT);
-	reg_val |= ((pdata->tx_pin_polarity & 0x01) << TX_PIN_POLARITY_SHIFT);
-	reg_val |= ((pdata->indicator_mode & 0x01) << INDIC_MODE_SHIFT);
-
-	ret = regmap_write(chip->regmap, REG_CONF, reg_val);
-	if (ret < 0) {
-		dev_err(chip->dev, "Failed to write REG_CONF Regisgter\n");
-		goto out;
-	}
-
-	/* set enable register */
-	ret = regmap_read(chip->regmap, REG_ENABLE, &reg_val);
-	if (ret < 0) {
-		dev_err(chip->dev, "Failed to read REG_ENABLE Register\n");
-		goto out;
-	}
-
-	reg_val &= (~EX_PIN_ENABLE_MASK);
-	reg_val |= ((pdata->torch_pin_en & 0x01) << TORCH_PIN_EN_SHIFT);
-	reg_val |= ((pdata->strobe_pin_en & 0x01) << STROBE_PIN_EN_SHIFT);
-	reg_val |= ((pdata->tx_pin_en & 0x01) << TX_PIN_EN_SHIFT);
-
-	ret = regmap_write(chip->regmap, REG_ENABLE, reg_val);
-	if (ret < 0) {
-		dev_err(chip->dev, "Failed to write REG_ENABLE Regisgter\n");
-		goto out;
-	}
-
-out:
-	return ret;
-}
-
-/* chip control */
-static int lm3556_control(struct lm3556_chip_data *chip,
-			  u8 brightness, enum lm3556_mode opmode)
-{
-	int ret;
-	struct lm3556_platform_data *pdata = chip->pdata;
-
-	ret = regmap_read(chip->regmap, REG_FLAG, &chip->last_flag);
-	if (ret < 0) {
-		dev_err(chip->dev, "Failed to read REG_FLAG Register\n");
-		goto out;
-	}
-
-	if (chip->last_flag)
-		dev_info(chip->dev, "Last FLAG is 0x%x\n", chip->last_flag);
-
-	/* brightness 0 means off-state */
-	if (!brightness)
-		opmode = MODES_STASNDBY;
-
-	switch (opmode) {
-	case MODES_TORCH:
-		ret = regmap_update_bits(chip->regmap, REG_I_CTRL,
-					 TORCH_I_MASK << TORCH_I_SHIFT,
-					 (brightness - 1) << TORCH_I_SHIFT);
-
-		if (pdata->torch_pin_en)
-			opmode |= (TORCH_PIN_EN_MASK << TORCH_PIN_EN_SHIFT);
-		break;
-
-	case MODES_FLASH:
-		ret = regmap_update_bits(chip->regmap, REG_I_CTRL,
-					 FLASH_I_MASK << FLASH_I_SHIFT,
-					 (brightness - 1) << FLASH_I_SHIFT);
-		break;
-
-	case MODES_INDIC:
-		ret = regmap_update_bits(chip->regmap, REG_I_CTRL,
-					 TORCH_I_MASK << TORCH_I_SHIFT,
-					 (brightness - 1) << TORCH_I_SHIFT);
-		break;
-
-	case MODES_STASNDBY:
-		if (pdata->torch_pin_en)
-			opmode |= (TORCH_PIN_EN_MASK << TORCH_PIN_EN_SHIFT);
-		break;
-
-	default:
-		return ret;
-	}
-	if (ret < 0) {
-		dev_err(chip->dev, "Failed to write REG_I_CTRL Register\n");
-		goto out;
-	}
-	ret = regmap_update_bits(chip->regmap, REG_ENABLE,
-				 MODE_BITS_MASK << MODE_BITS_SHIFT,
-				 opmode << MODE_BITS_SHIFT);
-
-out:
-	return ret;
-}
-
-/* torch */
-static void lm3556_torch_brightness_set(struct led_classdev *cdev,
-					enum led_brightness brightness)
-{
-	struct lm3556_chip_data *chip =
-	    container_of(cdev, struct lm3556_chip_data, cdev_torch);
-
-	mutex_lock(&chip->lock);
-	lm3556_control(chip, brightness, MODES_TORCH);
-	mutex_unlock(&chip->lock);
-}
-
-/* flash */
-static void lm3556_strobe_brightness_set(struct led_classdev *cdev,
-					 enum led_brightness brightness)
-{
-	struct lm3556_chip_data *chip =
-	    container_of(cdev, struct lm3556_chip_data, cdev_flash);
-
-	mutex_lock(&chip->lock);
-	lm3556_control(chip, brightness, MODES_FLASH);
-	mutex_unlock(&chip->lock);
-}
-
-/* indicator */
-static void lm3556_indicator_brightness_set(struct led_classdev *cdev,
-					    enum led_brightness brightness)
-{
-	struct lm3556_chip_data *chip =
-	    container_of(cdev, struct lm3556_chip_data, cdev_indicator);
-
-	mutex_lock(&chip->lock);
-	lm3556_control(chip, brightness, MODES_INDIC);
-	mutex_unlock(&chip->lock);
-}
-
-/* indicator pattern */
-static ssize_t lm3556_indicator_pattern_store(struct device *dev,
-					      struct device_attribute *devAttr,
-					      const char *buf, size_t size)
-{
-	ssize_t ret;
-	struct led_classdev *led_cdev = dev_get_drvdata(dev);
-	struct lm3556_chip_data *chip =
-	    container_of(led_cdev, struct lm3556_chip_data, cdev_indicator);
-	unsigned int state;
-
-	ret = kstrtouint(buf, 10, &state);
-	if (ret)
-		goto out;
-	if (state > INDIC_PATTERN_SIZE - 1)
-		state = INDIC_PATTERN_SIZE - 1;
-
-	ret = regmap_write(chip->regmap, REG_INDIC_BLINK,
-			   indicator_pattern[state].blinking);
-	if (ret < 0) {
-		dev_err(chip->dev, "Failed to write REG_ENABLE Regisgter\n");
-		goto out;
-	}
-
-	ret = regmap_write(chip->regmap, REG_INDIC_PERIOD,
-			   indicator_pattern[state].period_cnt);
-	if (ret < 0) {
-		dev_err(chip->dev, "Failed to write REG_ENABLE Regisgter\n");
-		goto out;
-	}
-
-	return size;
-out:
-	dev_err(chip->dev, "Indicator pattern doesn't saved\n");
-	return size;
-}
-
-static DEVICE_ATTR(pattern, 0666, NULL, lm3556_indicator_pattern_store);
-
-static const struct regmap_config lm3556_regmap = {
-	.reg_bits = 8,
-	.val_bits = 8,
-	.max_register = REG_MAX,
-};
-
-/* module initialize */
-static int __devinit lm3556_probe(struct i2c_client *client,
-				  const struct i2c_device_id *id)
-{
-	struct lm3556_platform_data *pdata = client->dev.platform_data;
-	struct lm3556_chip_data *chip;
-
-	int err;
-
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
-		dev_err(&client->dev, "i2c functionality check fail.\n");
-		return -EOPNOTSUPP;
-	}
-
-	if (pdata == NULL) {
-		dev_err(&client->dev, "Needs Platform Data.\n");
-		return -ENODATA;
-	}
-
-	chip =
-	    devm_kzalloc(&client->dev, sizeof(struct lm3556_chip_data),
-			 GFP_KERNEL);
-	if (!chip)
-		return -ENOMEM;
-
-	chip->dev = &client->dev;
-	chip->pdata = pdata;
-
-	chip->regmap = devm_regmap_init_i2c(client, &lm3556_regmap);
-	if (IS_ERR(chip->regmap)) {
-		err = PTR_ERR(chip->regmap);
-		dev_err(&client->dev, "Failed to allocate register map: %d\n",
-			err);
-		return err;
-	}
-
-	mutex_init(&chip->lock);
-	i2c_set_clientdata(client, chip);
-
-	err = lm3556_chip_init(chip);
-	if (err < 0)
-		goto err_out;
-
-	/* flash */
-	chip->cdev_flash.name = "flash";
-	chip->cdev_flash.max_brightness = 16;
-	chip->cdev_flash.brightness_set = lm3556_strobe_brightness_set;
-	err = led_classdev_register((struct device *)
-				    &client->dev, &chip->cdev_flash);
-	if (err < 0)
-		goto err_out;
-	/* torch */
-	chip->cdev_torch.name = "torch";
-	chip->cdev_torch.max_brightness = 8;
-	chip->cdev_torch.brightness_set = lm3556_torch_brightness_set;
-	err = led_classdev_register((struct device *)
-				    &client->dev, &chip->cdev_torch);
-	if (err < 0)
-		goto err_create_torch_file;
-	/* indicator */
-	chip->cdev_indicator.name = "indicator";
-	chip->cdev_indicator.max_brightness = 8;
-	chip->cdev_indicator.brightness_set = lm3556_indicator_brightness_set;
-	err = led_classdev_register((struct device *)
-				    &client->dev, &chip->cdev_indicator);
-	if (err < 0)
-		goto err_create_indicator_file;
-
-	err = device_create_file(chip->cdev_indicator.dev, &dev_attr_pattern);
-	if (err < 0)
-		goto err_create_pattern_file;
-
-	dev_info(&client->dev, "LM3556 is initialized\n");
-	return 0;
-
-err_create_pattern_file:
-	led_classdev_unregister(&chip->cdev_indicator);
-err_create_indicator_file:
-	led_classdev_unregister(&chip->cdev_torch);
-err_create_torch_file:
-	led_classdev_unregister(&chip->cdev_flash);
-err_out:
-	return err;
-}
-
-static int __devexit lm3556_remove(struct i2c_client *client)
-{
-	struct lm3556_chip_data *chip = i2c_get_clientdata(client);
-
-	device_remove_file(chip->cdev_indicator.dev, &dev_attr_pattern);
-	led_classdev_unregister(&chip->cdev_indicator);
-	led_classdev_unregister(&chip->cdev_torch);
-	led_classdev_unregister(&chip->cdev_flash);
-	regmap_write(chip->regmap, REG_ENABLE, 0);
-	return 0;
-}
-
-static const struct i2c_device_id lm3556_id[] = {
-	{LM3556_NAME, 0},
-	{}
-};
-
-MODULE_DEVICE_TABLE(i2c, lm3556_id);
-
-static struct i2c_driver lm3556_i2c_driver = {
-	.driver = {
-		   .name = LM3556_NAME,
-		   .owner = THIS_MODULE,
-		   .pm = NULL,
-		   },
-	.probe = lm3556_probe,
-	.remove = __devexit_p(lm3556_remove),
-	.id_table = lm3556_id,
-};
-
-module_i2c_driver(lm3556_i2c_driver);
-
-MODULE_DESCRIPTION("Texas Instruments Flash Lighting driver for LM3556");
-MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>");
-MODULE_AUTHOR("G.Shark Jeong <gshark.jeong@gmail.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/leds/leds-lm355x.c b/drivers/leds/leds-lm355x.c
new file mode 100644
index 0000000..065ec01
--- /dev/null
+++ b/drivers/leds/leds-lm355x.c
@@ -0,0 +1,572 @@
+/*
+* Simple driver for Texas Instruments LM355x LED Flash driver chip
+* Copyright (C) 2012 Texas Instruments
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/fs.h>
+#include <linux/regmap.h>
+#include <linux/workqueue.h>
+#include <linux/platform_data/leds-lm355x.h>
+
+enum lm355x_type {
+	CHIP_LM3554 = 0,
+	CHIP_LM3556,
+};
+
+enum lm355x_regs {
+	REG_FLAG = 0,
+	REG_TORCH_CFG,
+	REG_TORCH_CTRL,
+	REG_STROBE_CFG,
+	REG_FLASH_CTRL,
+	REG_INDI_CFG,
+	REG_INDI_CTRL,
+	REG_OPMODE,
+	REG_MAX,
+};
+
+/* operation mode */
+enum lm355x_mode {
+	MODE_SHDN = 0,
+	MODE_INDIC,
+	MODE_TORCH,
+	MODE_FLASH
+};
+
+/* register map info. */
+struct lm355x_reg_data {
+	u8 regno;
+	u8 mask;
+	u8 shift;
+};
+
+struct lm355x_chip_data {
+	struct device *dev;
+	enum lm355x_type type;
+
+	struct led_classdev cdev_flash;
+	struct led_classdev cdev_torch;
+	struct led_classdev cdev_indicator;
+
+	struct work_struct work_flash;
+	struct work_struct work_torch;
+	struct work_struct work_indicator;
+
+	u8 br_flash;
+	u8 br_torch;
+	u8 br_indicator;
+
+	struct lm355x_platform_data *pdata;
+	struct regmap *regmap;
+	struct mutex lock;
+
+	unsigned int last_flag;
+	struct lm355x_reg_data *regs;
+};
+
+/* specific indicator function for lm3556 */
+enum lm3556_indic_pulse_time {
+	PULSE_TIME_0_MS = 0,
+	PULSE_TIME_32_MS,
+	PULSE_TIME_64_MS,
+	PULSE_TIME_92_MS,
+	PULSE_TIME_128_MS,
+	PULSE_TIME_160_MS,
+	PULSE_TIME_196_MS,
+	PULSE_TIME_224_MS,
+	PULSE_TIME_256_MS,
+	PULSE_TIME_288_MS,
+	PULSE_TIME_320_MS,
+	PULSE_TIME_352_MS,
+	PULSE_TIME_384_MS,
+	PULSE_TIME_416_MS,
+	PULSE_TIME_448_MS,
+	PULSE_TIME_480_MS,
+};
+
+enum lm3556_indic_n_blank {
+	INDIC_N_BLANK_0 = 0,
+	INDIC_N_BLANK_1,
+	INDIC_N_BLANK_2,
+	INDIC_N_BLANK_3,
+	INDIC_N_BLANK_4,
+	INDIC_N_BLANK_5,
+	INDIC_N_BLANK_6,
+	INDIC_N_BLANK_7,
+	INDIC_N_BLANK_8,
+	INDIC_N_BLANK_9,
+	INDIC_N_BLANK_10,
+	INDIC_N_BLANK_11,
+	INDIC_N_BLANK_12,
+	INDIC_N_BLANK_13,
+	INDIC_N_BLANK_14,
+	INDIC_N_BLANK_15,
+};
+
+enum lm3556_indic_period {
+	INDIC_PERIOD_0 = 0,
+	INDIC_PERIOD_1,
+	INDIC_PERIOD_2,
+	INDIC_PERIOD_3,
+	INDIC_PERIOD_4,
+	INDIC_PERIOD_5,
+	INDIC_PERIOD_6,
+	INDIC_PERIOD_7,
+};
+
+#define INDIC_PATTERN_SIZE 4
+
+struct indicator {
+	u8 blinking;
+	u8 period_cnt;
+};
+
+/* indicator pattern data only for lm3556 */
+static struct indicator indicator_pattern[INDIC_PATTERN_SIZE] = {
+	[0] = {(INDIC_N_BLANK_1 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_1},
+	[1] = {(INDIC_N_BLANK_15 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_2},
+	[2] = {(INDIC_N_BLANK_10 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_4},
+	[3] = {(INDIC_N_BLANK_5 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_7},
+};
+
+static struct lm355x_reg_data lm3554_regs[REG_MAX] = {
+	[REG_FLAG] = {0xD0, 0xBF, 0},
+	[REG_TORCH_CFG] = {0xE0, 0x80, 7},
+	[REG_TORCH_CTRL] = {0xA0, 0x38, 3},
+	[REG_STROBE_CFG] = {0xE0, 0x04, 2},
+	[REG_FLASH_CTRL] = {0xB0, 0x78, 3},
+	[REG_INDI_CFG] = {0xE0, 0x08, 3},
+	[REG_INDI_CTRL] = {0xA0, 0xC0, 6},
+	[REG_OPMODE] = {0xA0, 0x03, 0},
+};
+
+static struct lm355x_reg_data lm3556_regs[REG_MAX] = {
+	[REG_FLAG] = {0x0B, 0xFF, 0},
+	[REG_TORCH_CFG] = {0x0A, 0x10, 4},
+	[REG_TORCH_CTRL] = {0x09, 0x70, 4},
+	[REG_STROBE_CFG] = {0x0A, 0x20, 5},
+	[REG_FLASH_CTRL] = {0x09, 0x0F, 0},
+	[REG_INDI_CFG] = {0xFF, 0xFF, 0},
+	[REG_INDI_CTRL] = {0x09, 0x70, 4},
+	[REG_OPMODE] = {0x0A, 0x03, 0},
+};
+
+static char lm355x_name[][I2C_NAME_SIZE] = {
+	[CHIP_LM3554] = LM3554_NAME,
+	[CHIP_LM3556] = LM3556_NAME,
+};
+
+/* chip initialize */
+static int __devinit lm355x_chip_init(struct lm355x_chip_data *chip)
+{
+	int ret;
+	unsigned int reg_val;
+	struct lm355x_platform_data *pdata = chip->pdata;
+
+	/* input and output pins configuration */
+	switch (chip->type) {
+	case CHIP_LM3554:
+		reg_val = pdata->pin_tx2 | pdata->ntc_pin;
+		ret = regmap_update_bits(chip->regmap, 0xE0, 0x28, reg_val);
+		if (ret < 0)
+			goto out;
+		reg_val = pdata->pass_mode;
+		ret = regmap_update_bits(chip->regmap, 0xA0, 0x04, reg_val);
+		if (ret < 0)
+			goto out;
+		break;
+
+	case CHIP_LM3556:
+		reg_val = pdata->pin_tx2 | pdata->ntc_pin | pdata->pass_mode;
+		ret = regmap_update_bits(chip->regmap, 0x0A, 0xC4, reg_val);
+		if (ret < 0)
+			goto out;
+		break;
+	default:
+		return -ENODATA;
+	}
+
+	return ret;
+out:
+	dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
+	return ret;
+}
+
+/* chip control */
+static void lm355x_control(struct lm355x_chip_data *chip,
+			   u8 brightness, enum lm355x_mode opmode)
+{
+	int ret;
+	unsigned int reg_val;
+	struct lm355x_platform_data *pdata = chip->pdata;
+	struct lm355x_reg_data *preg = chip->regs;
+
+	ret = regmap_read(chip->regmap, preg[REG_FLAG].regno, &chip->last_flag);
+	if (ret < 0)
+		goto out;
+	if (chip->last_flag & preg[REG_FLAG].mask)
+		dev_info(chip->dev, "%s Last FLAG is 0x%x\n",
+			 lm355x_name[chip->type],
+			 chip->last_flag & preg[REG_FLAG].mask);
+	/* brightness 0 means shutdown */
+	if (!brightness)
+		opmode = MODE_SHDN;
+
+	switch (opmode) {
+	case MODE_TORCH:
+		ret =
+		    regmap_update_bits(chip->regmap, preg[REG_TORCH_CTRL].regno,
+				       preg[REG_TORCH_CTRL].mask,
+				       (brightness - 1)
+				       << preg[REG_TORCH_CTRL].shift);
+		if (ret < 0)
+			goto out;
+
+		if (pdata->pin_tx1 != LM355x_PIN_TORCH_DISABLE) {
+			ret =
+			    regmap_update_bits(chip->regmap,
+					       preg[REG_TORCH_CFG].regno,
+					       preg[REG_TORCH_CFG].mask,
+					       0x01 <<
+					       preg[REG_TORCH_CFG].shift);
+			if (ret < 0)
+				goto out;
+			opmode = MODE_SHDN;
+			dev_info(chip->dev,
+				 "torch brt is set - ext. torch pin mode\n");
+		}
+		break;
+
+	case MODE_FLASH:
+
+		ret =
+		    regmap_update_bits(chip->regmap, preg[REG_FLASH_CTRL].regno,
+				       preg[REG_FLASH_CTRL].mask,
+				       (brightness - 1)
+				       << preg[REG_FLASH_CTRL].shift);
+		if (ret < 0)
+			goto out;
+
+		if (pdata->pin_strobe != LM355x_PIN_STROBE_DISABLE) {
+			if (chip->type == CHIP_LM3554)
+				reg_val = 0x00;
+			else
+				reg_val = 0x01;
+			ret =
+			    regmap_update_bits(chip->regmap,
+					       preg[REG_STROBE_CFG].regno,
+					       preg[REG_STROBE_CFG].mask,
+					       reg_val <<
+					       preg[REG_STROBE_CFG].shift);
+			if (ret < 0)
+				goto out;
+			opmode = MODE_SHDN;
+			dev_info(chip->dev,
+				 "flash brt is set - ext. strobe pin mode\n");
+		}
+		break;
+
+	case MODE_INDIC:
+		ret =
+		    regmap_update_bits(chip->regmap, preg[REG_INDI_CTRL].regno,
+				       preg[REG_INDI_CTRL].mask,
+				       (brightness - 1)
+				       << preg[REG_INDI_CTRL].shift);
+		if (ret < 0)
+			goto out;
+
+		if (pdata->pin_tx2 != LM355x_PIN_TX_DISABLE) {
+			ret =
+			    regmap_update_bits(chip->regmap,
+					       preg[REG_INDI_CFG].regno,
+					       preg[REG_INDI_CFG].mask,
+					       0x01 <<
+					       preg[REG_INDI_CFG].shift);
+			if (ret < 0)
+				goto out;
+			opmode = MODE_SHDN;
+		}
+		break;
+	case MODE_SHDN:
+		break;
+	default:
+		return;
+	}
+	/* operation mode control */
+	ret = regmap_update_bits(chip->regmap, preg[REG_OPMODE].regno,
+				 preg[REG_OPMODE].mask,
+				 opmode << preg[REG_OPMODE].shift);
+	if (ret < 0)
+		goto out;
+	return;
+out:
+	dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
+	return;
+}
+
+/* torch */
+static void lm355x_deferred_torch_brightness_set(struct work_struct *work)
+{
+	struct lm355x_chip_data *chip =
+	    container_of(work, struct lm355x_chip_data, work_torch);
+
+	mutex_lock(&chip->lock);
+	lm355x_control(chip, chip->br_torch, MODE_TORCH);
+	mutex_unlock(&chip->lock);
+}
+
+static void lm355x_torch_brightness_set(struct led_classdev *cdev,
+					enum led_brightness brightness)
+{
+	struct lm355x_chip_data *chip =
+	    container_of(cdev, struct lm355x_chip_data, cdev_torch);
+
+	chip->br_torch = brightness;
+	schedule_work(&chip->work_torch);
+}
+
+/* flash */
+static void lm355x_deferred_strobe_brightness_set(struct work_struct *work)
+{
+	struct lm355x_chip_data *chip =
+	    container_of(work, struct lm355x_chip_data, work_flash);
+
+	mutex_lock(&chip->lock);
+	lm355x_control(chip, chip->br_flash, MODE_FLASH);
+	mutex_unlock(&chip->lock);
+}
+
+static void lm355x_strobe_brightness_set(struct led_classdev *cdev,
+					 enum led_brightness brightness)
+{
+	struct lm355x_chip_data *chip =
+	    container_of(cdev, struct lm355x_chip_data, cdev_flash);
+
+	chip->br_flash = brightness;
+	schedule_work(&chip->work_flash);
+}
+
+/* indicator */
+static void lm355x_deferred_indicator_brightness_set(struct work_struct *work)
+{
+	struct lm355x_chip_data *chip =
+	    container_of(work, struct lm355x_chip_data, work_indicator);
+
+	mutex_lock(&chip->lock);
+	lm355x_control(chip, chip->br_indicator, MODE_INDIC);
+	mutex_unlock(&chip->lock);
+}
+
+static void lm355x_indicator_brightness_set(struct led_classdev *cdev,
+					    enum led_brightness brightness)
+{
+	struct lm355x_chip_data *chip =
+	    container_of(cdev, struct lm355x_chip_data, cdev_indicator);
+
+	chip->br_indicator = brightness;
+	schedule_work(&chip->work_indicator);
+}
+
+/* indicator pattern only for lm3556*/
+static ssize_t lm3556_indicator_pattern_store(struct device *dev,
+					      struct device_attribute *devAttr,
+					      const char *buf, size_t size)
+{
+	ssize_t ret;
+	struct led_classdev *led_cdev = dev_get_drvdata(dev);
+	struct lm355x_chip_data *chip =
+	    container_of(led_cdev, struct lm355x_chip_data, cdev_indicator);
+	unsigned int state;
+
+	ret = kstrtouint(buf, 10, &state);
+	if (ret)
+		goto out;
+	if (state > INDIC_PATTERN_SIZE - 1)
+		state = INDIC_PATTERN_SIZE - 1;
+
+	ret = regmap_write(chip->regmap, 0x04,
+			   indicator_pattern[state].blinking);
+	if (ret < 0)
+		goto out;
+
+	ret = regmap_write(chip->regmap, 0x05,
+			   indicator_pattern[state].period_cnt);
+	if (ret < 0)
+		goto out;
+
+	return size;
+out:
+	dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
+	return size;
+}
+
+static DEVICE_ATTR(pattern, 0666, NULL, lm3556_indicator_pattern_store);
+
+static const struct regmap_config lm355x_regmap = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = 0xFF,
+};
+
+/* module initialize */
+static int __devinit lm355x_probe(struct i2c_client *client,
+				  const struct i2c_device_id *id)
+{
+	struct lm355x_platform_data *pdata = client->dev.platform_data;
+	struct lm355x_chip_data *chip;
+
+	int err;
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		dev_err(&client->dev, "i2c functionality check fail.\n");
+		return -EOPNOTSUPP;
+	}
+
+	if (pdata == NULL) {
+		dev_err(&client->dev, "needs Platform Data.\n");
+		return -ENODATA;
+	}
+
+	chip = devm_kzalloc(&client->dev,
+			    sizeof(struct lm355x_chip_data), GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	chip->dev = &client->dev;
+	chip->type = id->driver_data;
+	switch (id->driver_data) {
+	case CHIP_LM3554:
+		chip->regs = lm3554_regs;
+		break;
+	case CHIP_LM3556:
+		chip->regs = lm3556_regs;
+		break;
+	default:
+		return -ENOSYS;
+	}
+	chip->pdata = pdata;
+
+	chip->regmap = devm_regmap_init_i2c(client, &lm355x_regmap);
+	if (IS_ERR(chip->regmap)) {
+		err = PTR_ERR(chip->regmap);
+		dev_err(&client->dev,
+			"Failed to allocate register map: %d\n", err);
+		return err;
+	}
+
+	mutex_init(&chip->lock);
+	i2c_set_clientdata(client, chip);
+
+	err = lm355x_chip_init(chip);
+	if (err < 0)
+		goto err_out;
+
+	/* flash */
+	INIT_WORK(&chip->work_flash, lm355x_deferred_strobe_brightness_set);
+	chip->cdev_flash.name = "flash";
+	chip->cdev_flash.max_brightness = 16;
+	chip->cdev_flash.brightness_set = lm355x_strobe_brightness_set;
+	err = led_classdev_register((struct device *)
+				    &client->dev, &chip->cdev_flash);
+	if (err < 0)
+		goto err_out;
+	/* torch */
+	INIT_WORK(&chip->work_torch, lm355x_deferred_torch_brightness_set);
+	chip->cdev_torch.name = "torch";
+	chip->cdev_torch.max_brightness = 8;
+	chip->cdev_torch.brightness_set = lm355x_torch_brightness_set;
+	err = led_classdev_register((struct device *)
+				    &client->dev, &chip->cdev_torch);
+	if (err < 0)
+		goto err_create_torch_file;
+	/* indicator */
+	INIT_WORK(&chip->work_indicator,
+		  lm355x_deferred_indicator_brightness_set);
+	chip->cdev_indicator.name = "indicator";
+	if (id->driver_data == CHIP_LM3554)
+		chip->cdev_indicator.max_brightness = 4;
+	else
+		chip->cdev_indicator.max_brightness = 8;
+	chip->cdev_indicator.brightness_set = lm355x_indicator_brightness_set;
+	err = led_classdev_register((struct device *)
+				    &client->dev, &chip->cdev_indicator);
+	if (err < 0)
+		goto err_create_indicator_file;
+	/* indicator pattern control only for LM3554 */
+	if (id->driver_data == CHIP_LM3556) {
+		err =
+		    device_create_file(chip->cdev_indicator.dev,
+				       &dev_attr_pattern);
+		if (err < 0)
+			goto err_create_pattern_file;
+	}
+
+	dev_info(&client->dev, "%s is initialized\n",
+		 lm355x_name[id->driver_data]);
+	return 0;
+
+err_create_pattern_file:
+	led_classdev_unregister(&chip->cdev_indicator);
+err_create_indicator_file:
+	led_classdev_unregister(&chip->cdev_torch);
+err_create_torch_file:
+	led_classdev_unregister(&chip->cdev_flash);
+err_out:
+	return err;
+}
+
+static int __devexit lm355x_remove(struct i2c_client *client)
+{
+	struct lm355x_chip_data *chip = i2c_get_clientdata(client);
+	struct lm355x_reg_data *preg = chip->regs;
+
+	regmap_write(chip->regmap, preg[REG_OPMODE].regno, 0);
+	if (chip->type == CHIP_LM3556)
+		device_remove_file(chip->cdev_indicator.dev, &dev_attr_pattern);
+	led_classdev_unregister(&chip->cdev_indicator);
+	flush_work(&chip->work_indicator);
+	led_classdev_unregister(&chip->cdev_torch);
+	flush_work(&chip->work_torch);
+	led_classdev_unregister(&chip->cdev_flash);
+	flush_work(&chip->work_flash);
+	dev_info(&client->dev, "%s is removed\n", lm355x_name[chip->type]);
+
+	return 0;
+}
+
+static const struct i2c_device_id lm355x_id[] = {
+	{LM3554_NAME, CHIP_LM3554},
+	{LM3556_NAME, CHIP_LM3556},
+	{}
+};
+
+MODULE_DEVICE_TABLE(i2c, lm355x_id);
+
+static struct i2c_driver lm355x_i2c_driver = {
+	.driver = {
+		   .name = LM355x_NAME,
+		   .owner = THIS_MODULE,
+		   .pm = NULL,
+		   },
+	.probe = lm355x_probe,
+	.remove = __devexit_p(lm355x_remove),
+	.id_table = lm355x_id,
+};
+
+module_i2c_driver(lm355x_i2c_driver);
+
+MODULE_DESCRIPTION("Texas Instruments Flash Lighting driver for LM355x");
+MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>");
+MODULE_AUTHOR("G.Shark Jeong <gshark.jeong@gmail.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/leds/leds-lm3642.c b/drivers/leds/leds-lm3642.c
new file mode 100644
index 0000000..3285006
--- /dev/null
+++ b/drivers/leds/leds-lm3642.c
@@ -0,0 +1,462 @@
+/*
+* Simple driver for Texas Instruments LM3642 LED Flash driver chip
+* Copyright (C) 2012 Texas Instruments
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+*/
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/leds.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/fs.h>
+#include <linux/regmap.h>
+#include <linux/workqueue.h>
+#include <linux/platform_data/leds-lm3642.h>
+
+#define	REG_FILT_TIME			(0x0)
+#define	REG_IVFM_MODE			(0x1)
+#define	REG_TORCH_TIME			(0x6)
+#define	REG_FLASH			(0x8)
+#define	REG_I_CTRL			(0x9)
+#define	REG_ENABLE			(0xA)
+#define	REG_FLAG			(0xB)
+#define	REG_MAX				(0xB)
+
+#define	UVLO_EN_SHIFT			(7)
+#define	IVM_D_TH_SHIFT			(2)
+#define	TORCH_RAMP_UP_TIME_SHIFT	(3)
+#define	TORCH_RAMP_DN_TIME_SHIFT	(0)
+#define	INDUCTOR_I_LIMIT_SHIFT		(6)
+#define	FLASH_RAMP_TIME_SHIFT		(3)
+#define	FLASH_TOUT_TIME_SHIFT		(0)
+#define	TORCH_I_SHIFT			(4)
+#define	FLASH_I_SHIFT			(0)
+#define	IVFM_SHIFT			(7)
+#define	TX_PIN_EN_SHIFT			(6)
+#define	STROBE_PIN_EN_SHIFT		(5)
+#define	TORCH_PIN_EN_SHIFT		(4)
+#define	MODE_BITS_SHIFT			(0)
+
+#define	UVLO_EN_MASK			(0x1)
+#define	IVM_D_TH_MASK			(0x7)
+#define	TORCH_RAMP_UP_TIME_MASK		(0x7)
+#define	TORCH_RAMP_DN_TIME_MASK		(0x7)
+#define	INDUCTOR_I_LIMIT_MASK		(0x1)
+#define	FLASH_RAMP_TIME_MASK		(0x7)
+#define	FLASH_TOUT_TIME_MASK		(0x7)
+#define	TORCH_I_MASK			(0x7)
+#define	FLASH_I_MASK			(0xF)
+#define	IVFM_MASK			(0x1)
+#define	TX_PIN_EN_MASK			(0x1)
+#define	STROBE_PIN_EN_MASK		(0x1)
+#define	TORCH_PIN_EN_MASK		(0x1)
+#define	MODE_BITS_MASK			(0x73)
+#define EX_PIN_CONTROL_MASK		(0x71)
+#define EX_PIN_ENABLE_MASK		(0x70)
+
+enum lm3642_mode {
+	MODES_STASNDBY = 0,
+	MODES_INDIC,
+	MODES_TORCH,
+	MODES_FLASH
+};
+
+struct lm3642_chip_data {
+	struct device *dev;
+
+	struct led_classdev cdev_flash;
+	struct led_classdev cdev_torch;
+	struct led_classdev cdev_indicator;
+
+	struct work_struct work_flash;
+	struct work_struct work_torch;
+	struct work_struct work_indicator;
+
+	u8 br_flash;
+	u8 br_torch;
+	u8 br_indicator;
+
+	enum lm3642_torch_pin_enable torch_pin;
+	enum lm3642_strobe_pin_enable strobe_pin;
+	enum lm3642_tx_pin_enable tx_pin;
+
+	struct lm3642_platform_data *pdata;
+	struct regmap *regmap;
+	struct mutex lock;
+
+	unsigned int last_flag;
+};
+
+/* chip initialize */
+static int __devinit lm3642_chip_init(struct lm3642_chip_data *chip)
+{
+	int ret;
+	struct lm3642_platform_data *pdata = chip->pdata;
+
+	/* set enable register */
+	ret = regmap_update_bits(chip->regmap, REG_ENABLE, EX_PIN_ENABLE_MASK,
+				 pdata->tx_pin);
+	if (ret < 0)
+		dev_err(chip->dev, "Failed to update REG_ENABLE Register\n");
+	return ret;
+}
+
+/* chip control */
+static int lm3642_control(struct lm3642_chip_data *chip,
+			  u8 brightness, enum lm3642_mode opmode)
+{
+	int ret;
+
+	ret = regmap_read(chip->regmap, REG_FLAG, &chip->last_flag);
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to read REG_FLAG Register\n");
+		goto out;
+	}
+
+	if (chip->last_flag)
+		dev_info(chip->dev, "Last FLAG is 0x%x\n", chip->last_flag);
+
+	/* brightness 0 means off-state */
+	if (!brightness)
+		opmode = MODES_STASNDBY;
+
+	switch (opmode) {
+	case MODES_TORCH:
+		ret = regmap_update_bits(chip->regmap, REG_I_CTRL,
+					 TORCH_I_MASK << TORCH_I_SHIFT,
+					 (brightness - 1) << TORCH_I_SHIFT);
+
+		if (chip->torch_pin)
+			opmode |= (TORCH_PIN_EN_MASK << TORCH_PIN_EN_SHIFT);
+		break;
+
+	case MODES_FLASH:
+		ret = regmap_update_bits(chip->regmap, REG_I_CTRL,
+					 FLASH_I_MASK << FLASH_I_SHIFT,
+					 (brightness - 1) << FLASH_I_SHIFT);
+
+		if (chip->strobe_pin)
+			opmode |= (STROBE_PIN_EN_MASK << STROBE_PIN_EN_SHIFT);
+		break;
+
+	case MODES_INDIC:
+		ret = regmap_update_bits(chip->regmap, REG_I_CTRL,
+					 TORCH_I_MASK << TORCH_I_SHIFT,
+					 (brightness - 1) << TORCH_I_SHIFT);
+		break;
+
+	case MODES_STASNDBY:
+
+		break;
+
+	default:
+		return ret;
+	}
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to write REG_I_CTRL Register\n");
+		goto out;
+	}
+
+	if (chip->tx_pin)
+		opmode |= (TX_PIN_EN_MASK << TX_PIN_EN_SHIFT);
+
+	ret = regmap_update_bits(chip->regmap, REG_ENABLE,
+				 MODE_BITS_MASK << MODE_BITS_SHIFT,
+				 opmode << MODE_BITS_SHIFT);
+out:
+	return ret;
+}
+
+/* torch */
+
+/* torch pin config for lm3642*/
+static ssize_t lm3642_torch_pin_store(struct device *dev,
+				      struct device_attribute *devAttr,
+				      const char *buf, size_t size)
+{
+	ssize_t ret;
+	struct led_classdev *led_cdev = dev_get_drvdata(dev);
+	struct lm3642_chip_data *chip =
+	    container_of(led_cdev, struct lm3642_chip_data, cdev_indicator);
+	unsigned int state;
+
+	ret = kstrtouint(buf, 10, &state);
+	if (ret)
+		goto out_strtoint;
+	if (state != 0)
+		state = 0x01 << TORCH_PIN_EN_SHIFT;
+
+	chip->torch_pin = state;
+	ret = regmap_update_bits(chip->regmap, REG_ENABLE,
+				 TORCH_PIN_EN_MASK << TORCH_PIN_EN_SHIFT,
+				 state);
+	if (ret < 0)
+		goto out;
+
+	return size;
+out:
+	dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
+	return size;
+out_strtoint:
+	dev_err(chip->dev, "%s: fail to change str to int\n", __func__);
+	return size;
+}
+
+static DEVICE_ATTR(torch_pin, 0666, NULL, lm3642_torch_pin_store);
+
+static void lm3642_deferred_torch_brightness_set(struct work_struct *work)
+{
+	struct lm3642_chip_data *chip =
+	    container_of(work, struct lm3642_chip_data, work_torch);
+
+	mutex_lock(&chip->lock);
+	lm3642_control(chip, chip->br_torch, MODES_TORCH);
+	mutex_unlock(&chip->lock);
+}
+
+static void lm3642_torch_brightness_set(struct led_classdev *cdev,
+					enum led_brightness brightness)
+{
+	struct lm3642_chip_data *chip =
+	    container_of(cdev, struct lm3642_chip_data, cdev_torch);
+
+	chip->br_torch = brightness;
+	schedule_work(&chip->work_torch);
+}
+
+/* flash */
+
+/* strobe pin config for lm3642*/
+static ssize_t lm3642_strobe_pin_store(struct device *dev,
+				       struct device_attribute *devAttr,
+				       const char *buf, size_t size)
+{
+	ssize_t ret;
+	struct led_classdev *led_cdev = dev_get_drvdata(dev);
+	struct lm3642_chip_data *chip =
+	    container_of(led_cdev, struct lm3642_chip_data, cdev_indicator);
+	unsigned int state;
+
+	ret = kstrtouint(buf, 10, &state);
+	if (ret)
+		goto out_strtoint;
+	if (state != 0)
+		state = 0x01 << STROBE_PIN_EN_SHIFT;
+
+	chip->strobe_pin = state;
+	ret = regmap_update_bits(chip->regmap, REG_ENABLE,
+				 STROBE_PIN_EN_MASK << STROBE_PIN_EN_SHIFT,
+				 state);
+	if (ret < 0)
+		goto out;
+
+	return size;
+out:
+	dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
+	return size;
+out_strtoint:
+	dev_err(chip->dev, "%s: fail to change str to int\n", __func__);
+	return size;
+}
+
+static DEVICE_ATTR(strobe_pin, 0666, NULL, lm3642_strobe_pin_store);
+
+static void lm3642_deferred_strobe_brightness_set(struct work_struct *work)
+{
+	struct lm3642_chip_data *chip =
+	    container_of(work, struct lm3642_chip_data, work_flash);
+
+	mutex_lock(&chip->lock);
+	lm3642_control(chip, chip->br_flash, MODES_FLASH);
+	mutex_unlock(&chip->lock);
+}
+
+static void lm3642_strobe_brightness_set(struct led_classdev *cdev,
+					 enum led_brightness brightness)
+{
+	struct lm3642_chip_data *chip =
+	    container_of(cdev, struct lm3642_chip_data, cdev_flash);
+
+	chip->br_flash = brightness;
+	schedule_work(&chip->work_flash);
+}
+
+/* indicator */
+static void lm3642_deferred_indicator_brightness_set(struct work_struct *work)
+{
+	struct lm3642_chip_data *chip =
+	    container_of(work, struct lm3642_chip_data, work_indicator);
+
+	mutex_lock(&chip->lock);
+	lm3642_control(chip, chip->br_indicator, MODES_INDIC);
+	mutex_unlock(&chip->lock);
+}
+
+static void lm3642_indicator_brightness_set(struct led_classdev *cdev,
+					    enum led_brightness brightness)
+{
+	struct lm3642_chip_data *chip =
+	    container_of(cdev, struct lm3642_chip_data, cdev_indicator);
+
+	chip->br_indicator = brightness;
+	schedule_work(&chip->work_indicator);
+}
+
+static const struct regmap_config lm3642_regmap = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = REG_MAX,
+};
+
+static int __devinit lm3642_probe(struct i2c_client *client,
+				  const struct i2c_device_id *id)
+{
+	struct lm3642_platform_data *pdata = client->dev.platform_data;
+	struct lm3642_chip_data *chip;
+
+	int err;
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		dev_err(&client->dev, "i2c functionality check fail.\n");
+		return -EOPNOTSUPP;
+	}
+
+	if (pdata == NULL) {
+		dev_err(&client->dev, "needs Platform Data.\n");
+		return -ENODATA;
+	}
+
+	chip = devm_kzalloc(&client->dev,
+			    sizeof(struct lm3642_chip_data), GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	chip->dev = &client->dev;
+	chip->pdata = pdata;
+
+	chip->tx_pin = pdata->tx_pin;
+	chip->torch_pin = pdata->torch_pin;
+	chip->strobe_pin = pdata->strobe_pin;
+
+	chip->regmap = devm_regmap_init_i2c(client, &lm3642_regmap);
+	if (IS_ERR(chip->regmap)) {
+		err = PTR_ERR(chip->regmap);
+		dev_err(&client->dev, "Failed to allocate register map: %d\n",
+			err);
+		return err;
+	}
+
+	mutex_init(&chip->lock);
+	i2c_set_clientdata(client, chip);
+
+	err = lm3642_chip_init(chip);
+	if (err < 0)
+		goto err_out;
+
+	/* flash */
+	INIT_WORK(&chip->work_flash, lm3642_deferred_strobe_brightness_set);
+	chip->cdev_flash.name = "flash";
+	chip->cdev_flash.max_brightness = 16;
+	chip->cdev_flash.brightness_set = lm3642_strobe_brightness_set;
+	err = led_classdev_register((struct device *)
+				    &client->dev, &chip->cdev_flash);
+	if (err < 0) {
+		dev_err(chip->dev, "failed to register flash\n");
+		goto err_out;
+	}
+	err = device_create_file(chip->cdev_flash.dev, &dev_attr_strobe_pin);
+	if (err < 0) {
+		dev_err(chip->dev, "failed to create strobe-pin file\n");
+		goto err_create_flash_pin_file;
+	}
+
+	/* torch */
+	INIT_WORK(&chip->work_torch, lm3642_deferred_torch_brightness_set);
+	chip->cdev_torch.name = "torch";
+	chip->cdev_torch.max_brightness = 8;
+	chip->cdev_torch.brightness_set = lm3642_torch_brightness_set;
+	err = led_classdev_register((struct device *)
+				    &client->dev, &chip->cdev_torch);
+	if (err < 0) {
+		dev_err(chip->dev, "failed to register torch\n");
+		goto err_create_torch_file;
+	}
+	err = device_create_file(chip->cdev_torch.dev, &dev_attr_torch_pin);
+	if (err < 0) {
+		dev_err(chip->dev, "failed to create torch-pin file\n");
+		goto err_create_torch_pin_file;
+	}
+
+	/* indicator */
+	INIT_WORK(&chip->work_indicator,
+		  lm3642_deferred_indicator_brightness_set);
+	chip->cdev_indicator.name = "indicator";
+	chip->cdev_indicator.max_brightness = 8;
+	chip->cdev_indicator.brightness_set = lm3642_indicator_brightness_set;
+	err = led_classdev_register((struct device *)
+				    &client->dev, &chip->cdev_indicator);
+	if (err < 0) {
+		dev_err(chip->dev, "failed to register indicator\n");
+		goto err_create_indicator_file;
+	}
+
+	dev_info(&client->dev, "LM3642 is initialized\n");
+	return 0;
+
+err_create_indicator_file:
+	device_remove_file(chip->cdev_torch.dev, &dev_attr_torch_pin);
+err_create_torch_pin_file:
+	led_classdev_unregister(&chip->cdev_torch);
+err_create_torch_file:
+	device_remove_file(chip->cdev_flash.dev, &dev_attr_strobe_pin);
+err_create_flash_pin_file:
+	led_classdev_unregister(&chip->cdev_flash);
+err_out:
+	return err;
+}
+
+static int __devexit lm3642_remove(struct i2c_client *client)
+{
+	struct lm3642_chip_data *chip = i2c_get_clientdata(client);
+
+	led_classdev_unregister(&chip->cdev_indicator);
+	flush_work(&chip->work_indicator);
+	device_remove_file(chip->cdev_torch.dev, &dev_attr_torch_pin);
+	led_classdev_unregister(&chip->cdev_torch);
+	flush_work(&chip->work_torch);
+	device_remove_file(chip->cdev_flash.dev, &dev_attr_strobe_pin);
+	led_classdev_unregister(&chip->cdev_flash);
+	flush_work(&chip->work_flash);
+	regmap_write(chip->regmap, REG_ENABLE, 0);
+	return 0;
+}
+
+static const struct i2c_device_id lm3642_id[] = {
+	{LM3642_NAME, 0},
+	{}
+};
+
+MODULE_DEVICE_TABLE(i2c, lm3642_id);
+
+static struct i2c_driver lm3642_i2c_driver = {
+	.driver = {
+		   .name = LM3642_NAME,
+		   .owner = THIS_MODULE,
+		   .pm = NULL,
+		   },
+	.probe = lm3642_probe,
+	.remove = __devexit_p(lm3642_remove),
+	.id_table = lm3642_id,
+};
+
+module_i2c_driver(lm3642_i2c_driver);
+
+MODULE_DESCRIPTION("Texas Instruments Flash Lighting driver for LM3642");
+MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>");
+MODULE_AUTHOR("G.Shark Jeong <gshark.jeong@gmail.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c
index fbc12ac..97994ff 100644
--- a/drivers/leds/leds-lp5523.c
+++ b/drivers/leds/leds-lp5523.c
@@ -104,6 +104,11 @@
 #define LED_ACTIVE(mux, led)		(!!(mux & (0x0001 << led)))
 #define SHIFT_MASK(id)			(((id) - 1) * 2)
 
+enum lp5523_chip_id {
+	LP5523,
+	LP55231,
+};
+
 struct lp5523_engine {
 	int		id;
 	u8		mode;
@@ -150,7 +155,7 @@
 			    leds[led->id]);
 }
 
-static int lp5523_set_mode(struct lp5523_engine *engine, u8 mode);
+static void lp5523_set_mode(struct lp5523_engine *engine, u8 mode);
 static int lp5523_set_engine_mode(struct lp5523_engine *engine, u8 mode);
 static int lp5523_load_program(struct lp5523_engine *engine, const u8 *pattern);
 
@@ -177,7 +182,7 @@
 	int ret;
 	u8 buf;
 
-	ret = lp5523_write(client, LP5523_REG_ENABLE, 0x40);
+	ret = lp5523_write(client, LP5523_REG_ENABLE, LP5523_ENABLE);
 	if (ret)
 		return ret;
 	ret = lp5523_read(client, LP5523_REG_ENABLE, &buf);
@@ -338,7 +343,8 @@
 {
 	int i;
 	u16 tmp_mux = 0;
-	len = len < LP5523_LEDS ? len : LP5523_LEDS;
+
+	len = min_t(int, len, LP5523_LEDS);
 	for (i = 0; i < len; i++) {
 		switch (buf[i]) {
 		case '1':
@@ -546,6 +552,9 @@
 	unsigned cmd;
 	u8 pattern[LP5523_PROGRAM_LENGTH] = {0};
 
+	if (engine->mode != LP5523_CMD_LOAD)
+		return -EINVAL;
+
 	while ((offset < len - 1) && (i < LP5523_PROGRAM_LENGTH)) {
 		/* separate sscanfs because length is working only for %s */
 		ret = sscanf(buf + offset, "%2s%n ", c, &nrchars);
@@ -563,12 +572,7 @@
 		goto fail;
 
 	mutex_lock(&chip->lock);
-
-	if (engine->mode == LP5523_CMD_LOAD)
-		ret = lp5523_load_program(engine, pattern);
-	else
-		ret = -EINVAL;
-
+	ret = lp5523_load_program(engine, pattern);
 	mutex_unlock(&chip->lock);
 
 	if (ret) {
@@ -755,6 +759,7 @@
 	&dev_attr_engine2_leds.attr,
 	&dev_attr_engine3_load.attr,
 	&dev_attr_engine3_leds.attr,
+	NULL,
 };
 
 static const struct attribute_group lp5523_group = {
@@ -789,26 +794,28 @@
 /*--------------------------------------------------------------*/
 /*			Set chip operating mode			*/
 /*--------------------------------------------------------------*/
-static int lp5523_set_mode(struct lp5523_engine *engine, u8 mode)
+static void lp5523_set_mode(struct lp5523_engine *engine, u8 mode)
 {
-	int ret = 0;
-
 	/* if in that mode already do nothing, except for run */
 	if (mode == engine->mode && mode != LP5523_CMD_RUN)
-		return 0;
+		return;
 
-	if (mode == LP5523_CMD_RUN) {
-		ret = lp5523_run_program(engine);
-	} else if (mode == LP5523_CMD_LOAD) {
+	switch (mode) {
+	case LP5523_CMD_RUN:
+		lp5523_run_program(engine);
+		break;
+	case LP5523_CMD_LOAD:
 		lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED);
 		lp5523_set_engine_mode(engine, LP5523_CMD_LOAD);
-	} else if (mode == LP5523_CMD_DISABLED) {
+		break;
+	case LP5523_CMD_DISABLED:
 		lp5523_set_engine_mode(engine, LP5523_CMD_DISABLED);
+		break;
+	default:
+		return;
 	}
 
 	engine->mode = mode;
-
-	return ret;
 }
 
 /*--------------------------------------------------------------*/
@@ -827,7 +834,8 @@
 }
 
 static int __devinit lp5523_init_led(struct lp5523_led *led, struct device *dev,
-			   int chan, struct lp5523_platform_data *pdata)
+			   int chan, struct lp5523_platform_data *pdata,
+			   const char *chip_name)
 {
 	char name[32];
 	int res;
@@ -846,10 +854,14 @@
 			return -EINVAL;
 		}
 
-		snprintf(name, sizeof(name), "%s:channel%d",
-			pdata->label ?: "lp5523", chan);
+		if (pdata->led_config[chan].name) {
+			led->cdev.name = pdata->led_config[chan].name;
+		} else {
+			snprintf(name, sizeof(name), "%s:channel%d",
+				pdata->label ? : chip_name, chan);
+			led->cdev.name = name;
+		}
 
-		led->cdev.name = name;
 		led->cdev.brightness_set = lp5523_set_brightness;
 		res = led_classdev_register(dev, &led->cdev);
 		if (res < 0) {
@@ -917,7 +929,7 @@
 	if (ret)
 		goto fail1;
 
-	dev_info(&client->dev, "LP5523 Programmable led chip found\n");
+	dev_info(&client->dev, "%s Programmable led chip found\n", id->name);
 
 	/* Initialize engines */
 	for (i = 0; i < ARRAY_SIZE(chip->engines); i++) {
@@ -945,7 +957,8 @@
 		INIT_WORK(&chip->leds[led].brightness_work,
 			lp5523_led_brightness_work);
 
-		ret = lp5523_init_led(&chip->leds[led], &client->dev, i, pdata);
+		ret = lp5523_init_led(&chip->leds[led], &client->dev, i, pdata,
+				id->name);
 		if (ret) {
 			dev_err(&client->dev, "error initializing leds\n");
 			goto fail2;
@@ -970,7 +983,7 @@
 fail2:
 	for (i = 0; i < chip->num_leds; i++) {
 		led_classdev_unregister(&chip->leds[i].cdev);
-		cancel_work_sync(&chip->leds[i].brightness_work);
+		flush_work(&chip->leds[i].brightness_work);
 	}
 fail1:
 	if (pdata->enable)
@@ -985,11 +998,14 @@
 	struct lp5523_chip *chip = i2c_get_clientdata(client);
 	int i;
 
+	/* Disable engine mode */
+	lp5523_write(client, LP5523_REG_OP_MODE, LP5523_CMD_DISABLED);
+
 	lp5523_unregister_sysfs(client);
 
 	for (i = 0; i < chip->num_leds; i++) {
 		led_classdev_unregister(&chip->leds[i].cdev);
-		cancel_work_sync(&chip->leds[i].brightness_work);
+		flush_work(&chip->leds[i].brightness_work);
 	}
 
 	if (chip->pdata->enable)
@@ -1000,7 +1016,8 @@
 }
 
 static const struct i2c_device_id lp5523_id[] = {
-	{ "lp5523", 0 },
+	{ "lp5523",  LP5523 },
+	{ "lp55231", LP55231 },
 	{ }
 };
 
@@ -1008,7 +1025,7 @@
 
 static struct i2c_driver lp5523_driver = {
 	.driver = {
-		.name	= "lp5523",
+		.name	= "lp5523x",
 	},
 	.probe		= lp5523_probe,
 	.remove		= lp5523_remove,
diff --git a/drivers/leds/leds-pca9633.c b/drivers/leds/leds-pca9633.c
index edcd706..2f2f9c4 100644
--- a/drivers/leds/leds-pca9633.c
+++ b/drivers/leds/leds-pca9633.c
@@ -22,6 +22,7 @@
 #include <linux/i2c.h>
 #include <linux/workqueue.h>
 #include <linux/slab.h>
+#include <linux/platform_data/leds-pca9633.h>
 
 /* LED select registers determine the source that drives LED outputs */
 #define PCA9633_LED_OFF		0x0	/* LED driver off */
@@ -96,13 +97,13 @@
 					const struct i2c_device_id *id)
 {
 	struct pca9633_led *pca9633;
-	struct led_platform_data *pdata;
+	struct pca9633_platform_data *pdata;
 	int i, err;
 
 	pdata = client->dev.platform_data;
 
 	if (pdata) {
-		if (pdata->num_leds <= 0 || pdata->num_leds > 4) {
+		if (pdata->leds.num_leds <= 0 || pdata->leds.num_leds > 4) {
 			dev_err(&client->dev, "board info must claim at most 4 LEDs");
 			return -EINVAL;
 		}
@@ -119,14 +120,14 @@
 		pca9633[i].led_num = i;
 
 		/* Platform data can specify LED names and default triggers */
-		if (pdata && i < pdata->num_leds) {
-			if (pdata->leds[i].name)
+		if (pdata && i < pdata->leds.num_leds) {
+			if (pdata->leds.leds[i].name)
 				snprintf(pca9633[i].name,
 					 sizeof(pca9633[i].name), "pca9633:%s",
-					 pdata->leds[i].name);
-			if (pdata->leds[i].default_trigger)
+					 pdata->leds.leds[i].name);
+			if (pdata->leds.leds[i].default_trigger)
 				pca9633[i].led_cdev.default_trigger =
-					pdata->leds[i].default_trigger;
+					pdata->leds.leds[i].default_trigger;
 		} else {
 			snprintf(pca9633[i].name, sizeof(pca9633[i].name),
 				 "pca9633:%d", i);
@@ -145,6 +146,10 @@
 	/* Disable LED all-call address and set normal mode */
 	i2c_smbus_write_byte_data(client, PCA9633_MODE1, 0x00);
 
+	/* Configure output: open-drain or totem pole (push-pull) */
+	if (pdata && pdata->outdrv == PCA9633_OPEN_DRAIN)
+		i2c_smbus_write_byte_data(client, PCA9633_MODE2, 0x01);
+
 	/* Turn off LEDs */
 	i2c_smbus_write_byte_data(client, PCA9633_LEDOUT, 0x00);
 
diff --git a/drivers/leds/leds-wm8350.c b/drivers/leds/leds-wm8350.c
index 4c62113..88f23f8 100644
--- a/drivers/leds/leds-wm8350.c
+++ b/drivers/leds/leds-wm8350.c
@@ -201,7 +201,7 @@
 	struct regulator *isink, *dcdc;
 	struct wm8350_led *led;
 	struct wm8350_led_platform_data *pdata = pdev->dev.platform_data;
-	int ret, i;
+	int i;
 
 	if (pdata == NULL) {
 		dev_err(&pdev->dev, "no platform data\n");
@@ -214,24 +214,21 @@
 		return -EINVAL;
 	}
 
-	isink = regulator_get(&pdev->dev, "led_isink");
+	isink = devm_regulator_get(&pdev->dev, "led_isink");
 	if (IS_ERR(isink)) {
 		printk(KERN_ERR "%s: can't get ISINK\n", __func__);
 		return PTR_ERR(isink);
 	}
 
-	dcdc = regulator_get(&pdev->dev, "led_vcc");
+	dcdc = devm_regulator_get(&pdev->dev, "led_vcc");
 	if (IS_ERR(dcdc)) {
 		printk(KERN_ERR "%s: can't get DCDC\n", __func__);
-		ret = PTR_ERR(dcdc);
-		goto err_isink;
+		return PTR_ERR(dcdc);
 	}
 
 	led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL);
-	if (led == NULL) {
-		ret = -ENOMEM;
-		goto err_dcdc;
-	}
+	if (led == NULL)
+		return -ENOMEM;
 
 	led->cdev.brightness_set = wm8350_led_set;
 	led->cdev.default_trigger = pdata->default_trigger;
@@ -257,17 +254,7 @@
 	led->value = LED_OFF;
 	platform_set_drvdata(pdev, led);
 
-	ret = led_classdev_register(&pdev->dev, &led->cdev);
-	if (ret < 0)
-		goto err_dcdc;
-
-	return 0;
-
- err_dcdc:
-	regulator_put(dcdc);
- err_isink:
-	regulator_put(isink);
-	return ret;
+	return led_classdev_register(&pdev->dev, &led->cdev);
 }
 
 static int wm8350_led_remove(struct platform_device *pdev)
@@ -277,8 +264,6 @@
 	led_classdev_unregister(&led->cdev);
 	flush_work(&led->work);
 	wm8350_led_disable(led);
-	regulator_put(led->dcdc);
-	regulator_put(led->isink);
 	return 0;
 }
 
diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h
index d02acd4..4c50365 100644
--- a/drivers/leds/leds.h
+++ b/drivers/leds/leds.h
@@ -32,6 +32,8 @@
 	return led_cdev->brightness;
 }
 
+void led_stop_software_blink(struct led_classdev *led_cdev);
+
 extern struct rw_semaphore leds_list_lock;
 extern struct list_head leds_list;
 
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 664743d..bbf459b 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -798,14 +798,6 @@
 	return 0;
 }
 
-static void dm_crypt_bio_destructor(struct bio *bio)
-{
-	struct dm_crypt_io *io = bio->bi_private;
-	struct crypt_config *cc = io->cc;
-
-	bio_free(bio, cc->bs);
-}
-
 /*
  * Generate a new unfragmented bio with the given size
  * This should never violate the device limitations
@@ -974,7 +966,6 @@
 	clone->bi_end_io  = crypt_endio;
 	clone->bi_bdev    = cc->dev->bdev;
 	clone->bi_rw      = io->base_bio->bi_rw;
-	clone->bi_destructor = dm_crypt_bio_destructor;
 }
 
 static int kcryptd_io_read(struct dm_crypt_io *io, gfp_t gfp)
@@ -988,19 +979,14 @@
 	 * copy the required bvecs because we need the original
 	 * one in order to decrypt the whole bio data *afterwards*.
 	 */
-	clone = bio_alloc_bioset(gfp, bio_segments(base_bio), cc->bs);
+	clone = bio_clone_bioset(base_bio, gfp, cc->bs);
 	if (!clone)
 		return 1;
 
 	crypt_inc_pending(io);
 
 	clone_init(io, clone);
-	clone->bi_idx = 0;
-	clone->bi_vcnt = bio_segments(base_bio);
-	clone->bi_size = base_bio->bi_size;
 	clone->bi_sector = cc->start + io->sector;
-	memcpy(clone->bi_io_vec, bio_iovec(base_bio),
-	       sizeof(struct bio_vec) * clone->bi_vcnt);
 
 	generic_make_request(clone);
 	return 0;
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
index ea5dd28..1c46f97 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -249,16 +249,6 @@
 	dp->context_ptr = data;
 }
 
-static void dm_bio_destructor(struct bio *bio)
-{
-	unsigned region;
-	struct io *io;
-
-	retrieve_io_and_region_from_bio(bio, &io, &region);
-
-	bio_free(bio, io->client->bios);
-}
-
 /*
  * Functions for getting the pages from kernel memory.
  */
@@ -317,7 +307,6 @@
 		bio->bi_sector = where->sector + (where->count - remaining);
 		bio->bi_bdev = where->bdev;
 		bio->bi_end_io = endio;
-		bio->bi_destructor = dm_bio_destructor;
 		store_io_and_region_in_bio(bio, io, region);
 
 		if (rw & REQ_DISCARD) {
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 67ffa39..66ceaff 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -86,12 +86,17 @@
 };
 
 /*
- * For request-based dm.
- * One of these is allocated per bio.
+ * For request-based dm - the bio clones we allocate are embedded in these
+ * structs.
+ *
+ * We allocate these with bio_alloc_bioset, using the front_pad parameter when
+ * the bioset is created - this means the bio has to come at the end of the
+ * struct.
  */
 struct dm_rq_clone_bio_info {
 	struct bio *orig;
 	struct dm_rq_target_io *tio;
+	struct bio clone;
 };
 
 union map_info *dm_get_mapinfo(struct bio *bio)
@@ -211,6 +216,11 @@
 static struct kmem_cache *_io_cache;
 static struct kmem_cache *_tio_cache;
 static struct kmem_cache *_rq_tio_cache;
+
+/*
+ * Unused now, and needs to be deleted. But since io_pool is overloaded and it's
+ * still used for _io_cache, I'm leaving this for a later cleanup
+ */
 static struct kmem_cache *_rq_bio_info_cache;
 
 static int __init local_init(void)
@@ -467,16 +477,6 @@
 	mempool_free(tio, tio->md->tio_pool);
 }
 
-static struct dm_rq_clone_bio_info *alloc_bio_info(struct mapped_device *md)
-{
-	return mempool_alloc(md->io_pool, GFP_ATOMIC);
-}
-
-static void free_bio_info(struct dm_rq_clone_bio_info *info)
-{
-	mempool_free(info, info->tio->md->io_pool);
-}
-
 static int md_in_flight(struct mapped_device *md)
 {
 	return atomic_read(&md->pending[READ]) +
@@ -681,11 +681,6 @@
 		}
 	}
 
-	/*
-	 * Store md for cleanup instead of tio which is about to get freed.
-	 */
-	bio->bi_private = md->bs;
-
 	free_tio(md, tio);
 	bio_put(bio);
 	dec_pending(io, error);
@@ -1036,11 +1031,6 @@
 		/* error the io and bail out, or requeue it if needed */
 		md = tio->io->md;
 		dec_pending(tio->io, r);
-		/*
-		 * Store bio_set for cleanup.
-		 */
-		clone->bi_end_io = NULL;
-		clone->bi_private = md->bs;
 		bio_put(clone);
 		free_tio(md, tio);
 	} else if (r) {
@@ -1059,13 +1049,6 @@
 	unsigned short idx;
 };
 
-static void dm_bio_destructor(struct bio *bio)
-{
-	struct bio_set *bs = bio->bi_private;
-
-	bio_free(bio, bs);
-}
-
 /*
  * Creates a little bio that just does part of a bvec.
  */
@@ -1077,7 +1060,6 @@
 	struct bio_vec *bv = bio->bi_io_vec + idx;
 
 	clone = bio_alloc_bioset(GFP_NOIO, 1, bs);
-	clone->bi_destructor = dm_bio_destructor;
 	*clone->bi_io_vec = *bv;
 
 	clone->bi_sector = sector;
@@ -1090,7 +1072,7 @@
 	clone->bi_flags |= 1 << BIO_CLONED;
 
 	if (bio_integrity(bio)) {
-		bio_integrity_clone(clone, bio, GFP_NOIO, bs);
+		bio_integrity_clone(clone, bio, GFP_NOIO);
 		bio_integrity_trim(clone,
 				   bio_sector_offset(bio, idx, offset), len);
 	}
@@ -1109,7 +1091,6 @@
 
 	clone = bio_alloc_bioset(GFP_NOIO, bio->bi_max_vecs, bs);
 	__bio_clone(clone, bio);
-	clone->bi_destructor = dm_bio_destructor;
 	clone->bi_sector = sector;
 	clone->bi_idx = idx;
 	clone->bi_vcnt = idx + bv_count;
@@ -1117,7 +1098,7 @@
 	clone->bi_flags &= ~(1 << BIO_SEG_VALID);
 
 	if (bio_integrity(bio)) {
-		bio_integrity_clone(clone, bio, GFP_NOIO, bs);
+		bio_integrity_clone(clone, bio, GFP_NOIO);
 
 		if (idx != bio->bi_idx || clone->bi_size < bio->bi_size)
 			bio_integrity_trim(clone,
@@ -1152,9 +1133,8 @@
 	 * ci->bio->bi_max_vecs is BIO_INLINE_VECS anyway, for both flush
 	 * and discard, so no need for concern about wasted bvec allocations.
 	 */
-	clone = bio_alloc_bioset(GFP_NOIO, ci->bio->bi_max_vecs, ci->md->bs);
-	__bio_clone(clone, ci->bio);
-	clone->bi_destructor = dm_bio_destructor;
+	clone = bio_clone_bioset(ci->bio, GFP_NOIO, ci->md->bs);
+
 	if (len) {
 		clone->bi_sector = ci->sector;
 		clone->bi_size = to_bytes(len);
@@ -1484,30 +1464,17 @@
 }
 EXPORT_SYMBOL_GPL(dm_dispatch_request);
 
-static void dm_rq_bio_destructor(struct bio *bio)
-{
-	struct dm_rq_clone_bio_info *info = bio->bi_private;
-	struct mapped_device *md = info->tio->md;
-
-	free_bio_info(info);
-	bio_free(bio, md->bs);
-}
-
 static int dm_rq_bio_constructor(struct bio *bio, struct bio *bio_orig,
 				 void *data)
 {
 	struct dm_rq_target_io *tio = data;
-	struct mapped_device *md = tio->md;
-	struct dm_rq_clone_bio_info *info = alloc_bio_info(md);
-
-	if (!info)
-		return -ENOMEM;
+	struct dm_rq_clone_bio_info *info =
+		container_of(bio, struct dm_rq_clone_bio_info, clone);
 
 	info->orig = bio_orig;
 	info->tio = tio;
 	bio->bi_end_io = end_clone_bio;
 	bio->bi_private = info;
-	bio->bi_destructor = dm_rq_bio_destructor;
 
 	return 0;
 }
@@ -2771,7 +2738,10 @@
 	if (!pools->tio_pool)
 		goto free_io_pool_and_out;
 
-	pools->bs = bioset_create(pool_size, 0);
+	pools->bs = (type == DM_TYPE_BIO_BASED) ?
+		bioset_create(pool_size, 0) :
+		bioset_create(pool_size,
+			      offsetof(struct dm_rq_clone_bio_info, clone));
 	if (!pools->bs)
 		goto free_tio_pool_and_out;
 
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 308e87b..95c8801 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -155,32 +155,17 @@
  * like bio_clone, but with a local bio set
  */
 
-static void mddev_bio_destructor(struct bio *bio)
-{
-	struct mddev *mddev, **mddevp;
-
-	mddevp = (void*)bio;
-	mddev = mddevp[-1];
-
-	bio_free(bio, mddev->bio_set);
-}
-
 struct bio *bio_alloc_mddev(gfp_t gfp_mask, int nr_iovecs,
 			    struct mddev *mddev)
 {
 	struct bio *b;
-	struct mddev **mddevp;
 
 	if (!mddev || !mddev->bio_set)
 		return bio_alloc(gfp_mask, nr_iovecs);
 
-	b = bio_alloc_bioset(gfp_mask, nr_iovecs,
-			     mddev->bio_set);
+	b = bio_alloc_bioset(gfp_mask, nr_iovecs, mddev->bio_set);
 	if (!b)
 		return NULL;
-	mddevp = (void*)b;
-	mddevp[-1] = mddev;
-	b->bi_destructor = mddev_bio_destructor;
 	return b;
 }
 EXPORT_SYMBOL_GPL(bio_alloc_mddev);
@@ -188,32 +173,10 @@
 struct bio *bio_clone_mddev(struct bio *bio, gfp_t gfp_mask,
 			    struct mddev *mddev)
 {
-	struct bio *b;
-	struct mddev **mddevp;
-
 	if (!mddev || !mddev->bio_set)
 		return bio_clone(bio, gfp_mask);
 
-	b = bio_alloc_bioset(gfp_mask, bio->bi_max_vecs,
-			     mddev->bio_set);
-	if (!b)
-		return NULL;
-	mddevp = (void*)b;
-	mddevp[-1] = mddev;
-	b->bi_destructor = mddev_bio_destructor;
-	__bio_clone(b, bio);
-	if (bio_integrity(bio)) {
-		int ret;
-
-		ret = bio_integrity_clone(b, bio, gfp_mask, mddev->bio_set);
-
-		if (ret < 0) {
-			bio_put(b);
-			return NULL;
-		}
-	}
-
-	return b;
+	return bio_clone_bioset(bio, gfp_mask, mddev->bio_set);
 }
 EXPORT_SYMBOL_GPL(bio_clone_mddev);
 
@@ -5006,8 +4969,7 @@
 	}
 
 	if (mddev->bio_set == NULL)
-		mddev->bio_set = bioset_create(BIO_POOL_SIZE,
-					       sizeof(struct mddev *));
+		mddev->bio_set = bioset_create(BIO_POOL_SIZE, 0);
 
 	spin_lock(&pers_lock);
 	pers = find_pers(mddev->level, mddev->clevel);
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index de63a1f..a9e4fa9 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -422,6 +422,7 @@
 	if (md_check_no_bitmap(mddev))
 		return -EINVAL;
 	blk_queue_max_hw_sectors(mddev->queue, mddev->chunk_sectors);
+	blk_queue_max_write_same_sectors(mddev->queue, mddev->chunk_sectors);
 
 	/* if private is not null, we are here after takeover */
 	if (mddev->private == NULL) {
diff --git a/drivers/media/pci/meye/meye.c b/drivers/media/pci/meye/meye.c
index 7bc7752..e5a76da 100644
--- a/drivers/media/pci/meye/meye.c
+++ b/drivers/media/pci/meye/meye.c
@@ -1647,7 +1647,7 @@
 
 	vma->vm_ops = &meye_vm_ops;
 	vma->vm_flags &= ~VM_IO;	/* not I/O memory */
-	vma->vm_flags |= VM_RESERVED;	/* avoid to swap out this VMA */
+	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 	vma->vm_private_data = (void *) (offset / gbufsize);
 	meye_vm_open(vma);
 
diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
index 66ac21d..a3b1a34 100644
--- a/drivers/media/platform/omap/omap_vout.c
+++ b/drivers/media/platform/omap/omap_vout.c
@@ -455,11 +455,15 @@
 
 	win = &vout->win;
 	for (i = 0; i < ovid->num_overlays; i++) {
+		struct omap_dss_device *dssdev;
+
 		ovl = ovid->overlays[i];
-		if (!ovl->manager || !ovl->manager->device)
+		dssdev = ovl->get_device(ovl);
+
+		if (!dssdev)
 			return -EINVAL;
 
-		timing = &ovl->manager->device->panel.timings;
+		timing = &dssdev->panel.timings;
 
 		outw = win->w.width;
 		outh = win->w.height;
@@ -516,8 +520,11 @@
 	struct omapvideo_info *ovid = &vout->vid_info;
 
 	for (i = 0; i < ovid->num_overlays; i++) {
+		struct omap_dss_device *dssdev;
+
 		ovl = ovid->overlays[i];
-		if (!ovl->manager || !ovl->manager->device)
+		dssdev = ovl->get_device(ovl);
+		if (!dssdev)
 			return -EINVAL;
 		ovl->manager->apply(ovl->manager);
 	}
@@ -580,12 +587,14 @@
 
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
-	/* get the display device attached to the overlay */
-	if (!ovl->manager || !ovl->manager->device)
-		return;
 
 	mgr_id = ovl->manager->id;
-	cur_display = ovl->manager->device;
+
+	/* get the display device attached to the overlay */
+	cur_display = ovl->get_device(ovl);
+
+	if (!cur_display)
+		return;
 
 	spin_lock(&vout->vbq_lock);
 	do_gettimeofday(&timevalue);
@@ -911,7 +920,7 @@
 
 	q->bufs[i]->baddr = vma->vm_start;
 
-	vma->vm_flags |= VM_RESERVED;
+	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 	vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
 	vma->vm_ops = &omap_vout_vm_ops;
 	vma->vm_private_data = (void *) vout;
@@ -949,7 +958,9 @@
 	/* Disable all the overlay managers connected with this interface */
 	for (i = 0; i < ovid->num_overlays; i++) {
 		struct omap_overlay *ovl = ovid->overlays[i];
-		if (ovl->manager && ovl->manager->device)
+		struct omap_dss_device *dssdev = ovl->get_device(ovl);
+
+		if (dssdev)
 			ovl->disable(ovl);
 	}
 	/* Turn off the pipeline */
@@ -1082,14 +1093,17 @@
 	struct omapvideo_info *ovid;
 	struct omap_video_timings *timing;
 	struct omap_vout_device *vout = fh;
+	struct omap_dss_device *dssdev;
 
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
-
-	if (!ovl->manager || !ovl->manager->device)
-		return -EINVAL;
 	/* get the display device attached to the overlay */
-	timing = &ovl->manager->device->panel.timings;
+	dssdev = ovl->get_device(ovl);
+
+	if (!dssdev)
+		return -EINVAL;
+
+	timing = &dssdev->panel.timings;
 
 	vout->fbuf.fmt.height = timing->y_res;
 	vout->fbuf.fmt.width = timing->x_res;
@@ -1106,6 +1120,7 @@
 	struct omapvideo_info *ovid;
 	struct omap_video_timings *timing;
 	struct omap_vout_device *vout = fh;
+	struct omap_dss_device *dssdev;
 
 	if (vout->streaming)
 		return -EBUSY;
@@ -1114,13 +1129,14 @@
 
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
+	dssdev = ovl->get_device(ovl);
 
 	/* get the display device attached to the overlay */
-	if (!ovl->manager || !ovl->manager->device) {
+	if (!dssdev) {
 		ret = -EINVAL;
 		goto s_fmt_vid_out_exit;
 	}
-	timing = &ovl->manager->device->panel.timings;
+	timing = &dssdev->panel.timings;
 
 	/* We dont support RGB24-packed mode if vrfb rotation
 	 * is enabled*/
@@ -1299,6 +1315,7 @@
 	struct omapvideo_info *ovid;
 	struct omap_overlay *ovl;
 	struct omap_video_timings *timing;
+	struct omap_dss_device *dssdev;
 
 	if (vout->streaming)
 		return -EBUSY;
@@ -1306,13 +1323,15 @@
 	mutex_lock(&vout->lock);
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
+	/* get the display device attached to the overlay */
+	dssdev = ovl->get_device(ovl);
 
-	if (!ovl->manager || !ovl->manager->device) {
+	if (!dssdev) {
 		ret = -EINVAL;
 		goto s_crop_err;
 	}
-	/* get the display device attached to the overlay */
-	timing = &ovl->manager->device->panel.timings;
+
+	timing = &dssdev->panel.timings;
 
 	if (is_rotation_90_or_270(vout)) {
 		vout->fbuf.fmt.height = timing->x_res;
@@ -1668,7 +1687,7 @@
 	for (j = 0; j < ovid->num_overlays; j++) {
 		struct omap_overlay *ovl = ovid->overlays[j];
 
-		if (ovl->manager && ovl->manager->device) {
+		if (ovl->get_device(ovl)) {
 			struct omap_overlay_info info;
 			ovl->get_overlay_info(ovl, &info);
 			info.paddr = addr;
@@ -1691,8 +1710,9 @@
 
 	for (j = 0; j < ovid->num_overlays; j++) {
 		struct omap_overlay *ovl = ovid->overlays[j];
+		struct omap_dss_device *dssdev = ovl->get_device(ovl);
 
-		if (ovl->manager && ovl->manager->device) {
+		if (dssdev) {
 			ret = ovl->enable(ovl);
 			if (ret)
 				goto streamon_err1;
@@ -1727,8 +1747,9 @@
 
 	for (j = 0; j < ovid->num_overlays; j++) {
 		struct omap_overlay *ovl = ovid->overlays[j];
+		struct omap_dss_device *dssdev = ovl->get_device(ovl);
 
-		if (ovl->manager && ovl->manager->device)
+		if (dssdev)
 			ovl->disable(ovl);
 	}
 
@@ -1891,8 +1912,8 @@
 	struct video_device *vfd;
 	struct v4l2_pix_format *pix;
 	struct v4l2_control *control;
-	struct omap_dss_device *display =
-		vout->vid_info.overlays[0]->manager->device;
+	struct omap_overlay *ovl = vout->vid_info.overlays[0];
+	struct omap_dss_device *display = ovl->get_device(ovl);
 
 	/* set the default pix */
 	pix = &vout->pix;
@@ -2207,8 +2228,10 @@
 	 */
 	for (i = 1; i < vid_dev->num_overlays; i++) {
 		ovl = omap_dss_get_overlay(i);
-		if (ovl->manager && ovl->manager->device) {
-			def_display = ovl->manager->device;
+		dssdev = ovl->get_device(ovl);
+
+		if (dssdev) {
+			def_display = dssdev;
 		} else {
 			dev_warn(&pdev->dev, "cannot find display\n");
 			def_display = NULL;
@@ -2255,8 +2278,10 @@
 	for (i = 1; i < vid_dev->num_overlays; i++) {
 		def_display = NULL;
 		ovl = omap_dss_get_overlay(i);
-		if (ovl->manager && ovl->manager->device)
-			def_display = ovl->manager->device;
+		dssdev = ovl->get_device(ovl);
+
+		if (dssdev)
+			def_display = dssdev;
 
 		if (def_display && def_display->driver)
 			def_display->driver->disable(def_display);
diff --git a/drivers/media/platform/vino.c b/drivers/media/platform/vino.c
index 790d96c..70b0bf4 100644
--- a/drivers/media/platform/vino.c
+++ b/drivers/media/platform/vino.c
@@ -3950,7 +3950,7 @@
 
 	fb->map_count = 1;
 
-	vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
+	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 	vma->vm_flags &= ~VM_IO;
 	vma->vm_private_data = fb;
 	vma->vm_file = file;
diff --git a/drivers/media/usb/sn9c102/sn9c102_core.c b/drivers/media/usb/sn9c102/sn9c102_core.c
index 19ea780..5bfc8e2 100644
--- a/drivers/media/usb/sn9c102/sn9c102_core.c
+++ b/drivers/media/usb/sn9c102/sn9c102_core.c
@@ -2126,8 +2126,7 @@
 		return -EINVAL;
 	}
 
-	vma->vm_flags |= VM_IO;
-	vma->vm_flags |= VM_RESERVED;
+	vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
 
 	pos = cam->frame[i].bufmem;
 	while (size > 0) { /* size is page-aligned */
diff --git a/drivers/media/usb/usbvision/usbvision-video.c b/drivers/media/usb/usbvision/usbvision-video.c
index f67018e..5c36a57 100644
--- a/drivers/media/usb/usbvision/usbvision-video.c
+++ b/drivers/media/usb/usbvision/usbvision-video.c
@@ -1108,8 +1108,7 @@
 	}
 
 	/* VM_IO is eventually going to replace PageReserved altogether */
-	vma->vm_flags |= VM_IO;
-	vma->vm_flags |= VM_RESERVED;	/* avoid to swap out this VMA */
+	vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
 
 	pos = usbvision->frame[i].data;
 	while (size > 0) {
diff --git a/drivers/media/v4l2-core/videobuf-dma-sg.c b/drivers/media/v4l2-core/videobuf-dma-sg.c
index f300dea..828e7c1 100644
--- a/drivers/media/v4l2-core/videobuf-dma-sg.c
+++ b/drivers/media/v4l2-core/videobuf-dma-sg.c
@@ -582,7 +582,7 @@
 	map->count    = 1;
 	map->q        = q;
 	vma->vm_ops   = &videobuf_vm_ops;
-	vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
+	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 	vma->vm_flags &= ~VM_IO; /* using shared anonymous pages */
 	vma->vm_private_data = map;
 	dprintk(1, "mmap %p: q=%p %08lx-%08lx pgoff %08lx bufs %d-%d\n",
diff --git a/drivers/media/v4l2-core/videobuf-vmalloc.c b/drivers/media/v4l2-core/videobuf-vmalloc.c
index df14258..2ff7fcc 100644
--- a/drivers/media/v4l2-core/videobuf-vmalloc.c
+++ b/drivers/media/v4l2-core/videobuf-vmalloc.c
@@ -270,7 +270,7 @@
 	}
 
 	vma->vm_ops          = &videobuf_vm_ops;
-	vma->vm_flags       |= VM_DONTEXPAND | VM_RESERVED;
+	vma->vm_flags       |= VM_DONTEXPAND | VM_DONTDUMP;
 	vma->vm_private_data = map;
 
 	dprintk(1, "mmap %p: q=%p %08lx-%08lx (%lx) pgoff %08lx buf %d\n",
diff --git a/drivers/media/v4l2-core/videobuf2-memops.c b/drivers/media/v4l2-core/videobuf2-memops.c
index 504cd4c..051ea35 100644
--- a/drivers/media/v4l2-core/videobuf2-memops.c
+++ b/drivers/media/v4l2-core/videobuf2-memops.c
@@ -163,7 +163,7 @@
 		return ret;
 	}
 
-	vma->vm_flags		|= VM_DONTEXPAND | VM_RESERVED;
+	vma->vm_flags		|= VM_DONTEXPAND | VM_DONTDUMP;
 	vma->vm_private_data	= priv;
 	vma->vm_ops		= vm_ops;
 
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 99c7335..b151b7c 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -60,16 +60,6 @@
 	  purposes including software controlled power-efficient backlights
 	  on LCD displays, motor control, and waveform generation.
 
-config AB8500_PWM
-	bool "AB8500 PWM support"
-	depends on AB8500_CORE && ARCH_U8500
-	select HAVE_PWM
-	depends on !PWM
-	help
-	  This driver exports functions to enable/disble/config/free Pulse
-	  Width Modulation in the Analog Baseband Chip AB8500.
-	  It is used by led and backlight driver to control the intensity.
-
 config ATMEL_TCLIB
 	bool "Atmel AT32/AT91 Timer/Counter Library"
 	depends on (AVR32 || ARCH_AT91)
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index b88df7a..2129377 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -44,7 +44,6 @@
 obj-$(CONFIG_ARM_CHARLCD)	+= arm-charlcd.o
 obj-$(CONFIG_PCH_PHUB)		+= pch_phub.o
 obj-y				+= ti-st/
-obj-$(CONFIG_AB8500_PWM)	+= ab8500-pwm.o
 obj-y				+= lis3lv02d/
 obj-y				+= carma/
 obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
diff --git a/drivers/misc/ab8500-pwm.c b/drivers/misc/ab8500-pwm.c
deleted file mode 100644
index d7a9aa1..0000000
--- a/drivers/misc/ab8500-pwm.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) ST-Ericsson SA 2010
- *
- * Author: Arun R Murthy <arun.murthy@stericsson.com>
- * License terms: GNU General Public License (GPL) version 2
- */
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/pwm.h>
-#include <linux/mfd/abx500.h>
-#include <linux/mfd/abx500/ab8500.h>
-#include <linux/module.h>
-
-/*
- * PWM Out generators
- * Bank: 0x10
- */
-#define AB8500_PWM_OUT_CTRL1_REG	0x60
-#define AB8500_PWM_OUT_CTRL2_REG	0x61
-#define AB8500_PWM_OUT_CTRL7_REG	0x66
-
-/* backlight driver constants */
-#define ENABLE_PWM			1
-#define DISABLE_PWM			0
-
-struct pwm_device {
-	struct device *dev;
-	struct list_head node;
-	const char *label;
-	unsigned int pwm_id;
-};
-
-static LIST_HEAD(pwm_list);
-
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
-{
-	int ret = 0;
-	unsigned int higher_val, lower_val;
-	u8 reg;
-
-	/*
-	 * get the first 8 bits that are be written to
-	 * AB8500_PWM_OUT_CTRL1_REG[0:7]
-	 */
-	lower_val = duty_ns & 0x00FF;
-	/*
-	 * get bits [9:10] that are to be written to
-	 * AB8500_PWM_OUT_CTRL2_REG[0:1]
-	 */
-	higher_val = ((duty_ns & 0x0300) >> 8);
-
-	reg = AB8500_PWM_OUT_CTRL1_REG + ((pwm->pwm_id - 1) * 2);
-
-	ret = abx500_set_register_interruptible(pwm->dev, AB8500_MISC,
-			reg, (u8)lower_val);
-	if (ret < 0)
-		return ret;
-	ret = abx500_set_register_interruptible(pwm->dev, AB8500_MISC,
-			(reg + 1), (u8)higher_val);
-
-	return ret;
-}
-EXPORT_SYMBOL(pwm_config);
-
-int pwm_enable(struct pwm_device *pwm)
-{
-	int ret;
-
-	ret = abx500_mask_and_set_register_interruptible(pwm->dev,
-				AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG,
-				1 << (pwm->pwm_id-1), ENABLE_PWM);
-	if (ret < 0)
-		dev_err(pwm->dev, "%s: Failed to disable PWM, Error %d\n",
-							pwm->label, ret);
-	return ret;
-}
-EXPORT_SYMBOL(pwm_enable);
-
-void pwm_disable(struct pwm_device *pwm)
-{
-	int ret;
-
-	ret = abx500_mask_and_set_register_interruptible(pwm->dev,
-				AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG,
-				1 << (pwm->pwm_id-1), DISABLE_PWM);
-	if (ret < 0)
-		dev_err(pwm->dev, "%s: Failed to disable PWM, Error %d\n",
-							pwm->label, ret);
-	return;
-}
-EXPORT_SYMBOL(pwm_disable);
-
-struct pwm_device *pwm_request(int pwm_id, const char *label)
-{
-	struct pwm_device *pwm;
-
-	list_for_each_entry(pwm, &pwm_list, node) {
-		if (pwm->pwm_id == pwm_id) {
-			pwm->label = label;
-			pwm->pwm_id = pwm_id;
-			return pwm;
-		}
-	}
-
-	return ERR_PTR(-ENOENT);
-}
-EXPORT_SYMBOL(pwm_request);
-
-void pwm_free(struct pwm_device *pwm)
-{
-	pwm_disable(pwm);
-}
-EXPORT_SYMBOL(pwm_free);
-
-static int __devinit ab8500_pwm_probe(struct platform_device *pdev)
-{
-	struct pwm_device *pwm;
-	/*
-	 * Nothing to be done in probe, this is required to get the
-	 * device which is required for ab8500 read and write
-	 */
-	pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
-	if (pwm == NULL) {
-		dev_err(&pdev->dev, "failed to allocate memory\n");
-		return -ENOMEM;
-	}
-	pwm->dev = &pdev->dev;
-	pwm->pwm_id = pdev->id;
-	list_add_tail(&pwm->node, &pwm_list);
-	platform_set_drvdata(pdev, pwm);
-	dev_dbg(pwm->dev, "pwm probe successful\n");
-	return 0;
-}
-
-static int __devexit ab8500_pwm_remove(struct platform_device *pdev)
-{
-	struct pwm_device *pwm = platform_get_drvdata(pdev);
-	list_del(&pwm->node);
-	dev_dbg(&pdev->dev, "pwm driver removed\n");
-	kfree(pwm);
-	return 0;
-}
-
-static struct platform_driver ab8500_pwm_driver = {
-	.driver = {
-		.name = "ab8500-pwm",
-		.owner = THIS_MODULE,
-	},
-	.probe = ab8500_pwm_probe,
-	.remove = __devexit_p(ab8500_pwm_remove),
-};
-
-static int __init ab8500_pwm_init(void)
-{
-	return platform_driver_register(&ab8500_pwm_driver);
-}
-
-static void __exit ab8500_pwm_exit(void)
-{
-	platform_driver_unregister(&ab8500_pwm_driver);
-}
-
-subsys_initcall(ab8500_pwm_init);
-module_exit(ab8500_pwm_exit);
-MODULE_AUTHOR("Arun MURTHY <arun.murthy@stericsson.com>");
-MODULE_DESCRIPTION("AB8500 Pulse Width Modulation Driver");
-MODULE_ALIAS("platform:ab8500-pwm");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/misc/carma/carma-fpga.c b/drivers/misc/carma/carma-fpga.c
index 0c43297..8835eab 100644
--- a/drivers/misc/carma/carma-fpga.c
+++ b/drivers/misc/carma/carma-fpga.c
@@ -1243,8 +1243,6 @@
 		return -EINVAL;
 	}
 
-	/* IO memory (stop cacheing) */
-	vma->vm_flags |= VM_IO | VM_RESERVED;
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 
 	return io_remap_pfn_range(vma, vma->vm_start, addr, vsize,
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c
index ecafa4b..492c8ca 100644
--- a/drivers/misc/sgi-gru/grufile.c
+++ b/drivers/misc/sgi-gru/grufile.c
@@ -108,9 +108,8 @@
 				vma->vm_end & (GRU_GSEG_PAGESIZE - 1))
 		return -EINVAL;
 
-	vma->vm_flags |=
-	    (VM_IO | VM_DONTCOPY | VM_LOCKED | VM_DONTEXPAND | VM_PFNMAP |
-			VM_RESERVED);
+	vma->vm_flags |= VM_IO | VM_PFNMAP | VM_LOCKED |
+			 VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP;
 	vma->vm_page_prot = PAGE_SHARED;
 	vma->vm_ops = &gru_vm_ops;
 
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 8ac5246..06c42cf 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -26,6 +26,7 @@
 #include <linux/suspend.h>
 #include <linux/fault-inject.h>
 #include <linux/random.h>
+#include <linux/slab.h>
 
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
@@ -41,6 +42,12 @@
 #include "sd_ops.h"
 #include "sdio_ops.h"
 
+/*
+ * Background operations can take a long time, depending on the housekeeping
+ * operations the card has to perform.
+ */
+#define MMC_BKOPS_MAX_TIMEOUT	(4 * 60 * 1000) /* max time to wait in ms */
+
 static struct workqueue_struct *workqueue;
 static const unsigned freqs[] = { 400000, 300000, 200000, 100000 };
 
@@ -245,6 +252,70 @@
 	host->ops->request(host, mrq);
 }
 
+/**
+ *	mmc_start_bkops - start BKOPS for supported cards
+ *	@card: MMC card to start BKOPS
+ *	@form_exception: A flag to indicate if this function was
+ *			 called due to an exception raised by the card
+ *
+ *	Start background operations whenever requested.
+ *	When the urgent BKOPS bit is set in a R1 command response
+ *	then background operations should be started immediately.
+*/
+void mmc_start_bkops(struct mmc_card *card, bool from_exception)
+{
+	int err;
+	int timeout;
+	bool use_busy_signal;
+
+	BUG_ON(!card);
+
+	if (!card->ext_csd.bkops_en || mmc_card_doing_bkops(card))
+		return;
+
+	err = mmc_read_bkops_status(card);
+	if (err) {
+		pr_err("%s: Failed to read bkops status: %d\n",
+		       mmc_hostname(card->host), err);
+		return;
+	}
+
+	if (!card->ext_csd.raw_bkops_status)
+		return;
+
+	if (card->ext_csd.raw_bkops_status < EXT_CSD_BKOPS_LEVEL_2 &&
+	    from_exception)
+		return;
+
+	mmc_claim_host(card->host);
+	if (card->ext_csd.raw_bkops_status >= EXT_CSD_BKOPS_LEVEL_2) {
+		timeout = MMC_BKOPS_MAX_TIMEOUT;
+		use_busy_signal = true;
+	} else {
+		timeout = 0;
+		use_busy_signal = false;
+	}
+
+	err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+			EXT_CSD_BKOPS_START, 1, timeout, use_busy_signal);
+	if (err) {
+		pr_warn("%s: Error %d starting bkops\n",
+			mmc_hostname(card->host), err);
+		goto out;
+	}
+
+	/*
+	 * For urgent bkops status (LEVEL_2 and more)
+	 * bkops executed synchronously, otherwise
+	 * the operation is in progress
+	 */
+	if (!use_busy_signal)
+		mmc_card_set_doing_bkops(card);
+out:
+	mmc_release_host(card->host);
+}
+EXPORT_SYMBOL(mmc_start_bkops);
+
 static void mmc_wait_done(struct mmc_request *mrq)
 {
 	complete(&mrq->completion);
@@ -354,6 +425,14 @@
 	if (host->areq) {
 		mmc_wait_for_req_done(host, host->areq->mrq);
 		err = host->areq->err_check(host->card, host->areq);
+		/*
+		 * Check BKOPS urgency for each R1 response
+		 */
+		if (host->card && mmc_card_mmc(host->card) &&
+		    ((mmc_resp_type(host->areq->mrq->cmd) == MMC_RSP_R1) ||
+		     (mmc_resp_type(host->areq->mrq->cmd) == MMC_RSP_R1B)) &&
+		    (host->areq->mrq->cmd->resp[0] & R1_EXCEPTION_EVENT))
+			mmc_start_bkops(host->card, true);
 	}
 
 	if (!err && areq)
@@ -398,7 +477,7 @@
  *	@card: the MMC card associated with the HPI transfer
  *
  *	Issued High Priority Interrupt, and check for card status
- *	util out-of prg-state.
+ *	until out-of prg-state.
  */
 int mmc_interrupt_hpi(struct mmc_card *card)
 {
@@ -424,8 +503,9 @@
 	case R1_STATE_IDLE:
 	case R1_STATE_READY:
 	case R1_STATE_STBY:
+	case R1_STATE_TRAN:
 		/*
-		 * In idle states, HPI is not needed and the caller
+		 * In idle and transfer states, HPI is not needed and the caller
 		 * can issue the next intended command immediately
 		 */
 		goto out;
@@ -489,6 +569,64 @@
 EXPORT_SYMBOL(mmc_wait_for_cmd);
 
 /**
+ *	mmc_stop_bkops - stop ongoing BKOPS
+ *	@card: MMC card to check BKOPS
+ *
+ *	Send HPI command to stop ongoing background operations to
+ *	allow rapid servicing of foreground operations, e.g. read/
+ *	writes. Wait until the card comes out of the programming state
+ *	to avoid errors in servicing read/write requests.
+ */
+int mmc_stop_bkops(struct mmc_card *card)
+{
+	int err = 0;
+
+	BUG_ON(!card);
+	err = mmc_interrupt_hpi(card);
+
+	/*
+	 * If err is EINVAL, we can't issue an HPI.
+	 * It should complete the BKOPS.
+	 */
+	if (!err || (err == -EINVAL)) {
+		mmc_card_clr_doing_bkops(card);
+		err = 0;
+	}
+
+	return err;
+}
+EXPORT_SYMBOL(mmc_stop_bkops);
+
+int mmc_read_bkops_status(struct mmc_card *card)
+{
+	int err;
+	u8 *ext_csd;
+
+	/*
+	 * In future work, we should consider storing the entire ext_csd.
+	 */
+	ext_csd = kmalloc(512, GFP_KERNEL);
+	if (!ext_csd) {
+		pr_err("%s: could not allocate buffer to receive the ext_csd.\n",
+		       mmc_hostname(card->host));
+		return -ENOMEM;
+	}
+
+	mmc_claim_host(card->host);
+	err = mmc_send_ext_csd(card, ext_csd);
+	mmc_release_host(card->host);
+	if (err)
+		goto out;
+
+	card->ext_csd.raw_bkops_status = ext_csd[EXT_CSD_BKOPS_STATUS];
+	card->ext_csd.raw_exception_status = ext_csd[EXT_CSD_EXP_EVENTS_STATUS];
+out:
+	kfree(ext_csd);
+	return err;
+}
+EXPORT_SYMBOL(mmc_read_bkops_status);
+
+/**
  *	mmc_set_data_timeout - set the timeout for a data command
  *	@data: data phase for command
  *	@card: the MMC card associated with the data transfer
@@ -975,7 +1113,8 @@
 		int		tmp;
 		int		voltage;
 
-		/* REVISIT mmc_vddrange_to_ocrmask() may have set some
+		/*
+		 * REVISIT mmc_vddrange_to_ocrmask() may have set some
 		 * bits this regulator doesn't quite support ... don't
 		 * be too picky, most cards and regulators are OK with
 		 * a 0.1V range goof (it's a small error percentage).
@@ -989,12 +1128,13 @@
 			max_uV = min_uV + 100 * 1000;
 		}
 
-		/* avoid needless changes to this voltage; the regulator
-		 * might not allow this operation
+		/*
+		 * If we're using a fixed/static regulator, don't call
+		 * regulator_set_voltage; it would fail.
 		 */
 		voltage = regulator_get_voltage(supply);
 
-		if (mmc->caps2 & MMC_CAP2_BROKEN_VOLTAGE)
+		if (regulator_count_voltages(supply) == 1)
 			min_uV = max_uV = voltage;
 
 		if (voltage < 0)
@@ -1133,48 +1273,6 @@
 	mmc_host_clk_release(host);
 }
 
-static void mmc_poweroff_notify(struct mmc_host *host)
-{
-	struct mmc_card *card;
-	unsigned int timeout;
-	unsigned int notify_type = EXT_CSD_NO_POWER_NOTIFICATION;
-	int err = 0;
-
-	card = host->card;
-	mmc_claim_host(host);
-
-	/*
-	 * Send power notify command only if card
-	 * is mmc and notify state is powered ON
-	 */
-	if (card && mmc_card_mmc(card) &&
-	    (card->poweroff_notify_state == MMC_POWERED_ON)) {
-
-		if (host->power_notify_type == MMC_HOST_PW_NOTIFY_SHORT) {
-			notify_type = EXT_CSD_POWER_OFF_SHORT;
-			timeout = card->ext_csd.generic_cmd6_time;
-			card->poweroff_notify_state = MMC_POWEROFF_SHORT;
-		} else {
-			notify_type = EXT_CSD_POWER_OFF_LONG;
-			timeout = card->ext_csd.power_off_longtime;
-			card->poweroff_notify_state = MMC_POWEROFF_LONG;
-		}
-
-		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-				 EXT_CSD_POWER_OFF_NOTIFICATION,
-				 notify_type, timeout);
-
-		if (err && err != -EBADMSG)
-			pr_err("Device failed to respond within %d poweroff "
-			       "time. Forcefully powering down the device\n",
-			       timeout);
-
-		/* Set the card state to no notification after the poweroff */
-		card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION;
-	}
-	mmc_release_host(host);
-}
-
 /*
  * Apply power to the MMC stack.  This is a two-stage process.
  * First, we enable power to the card without the clock running.
@@ -1237,8 +1335,6 @@
 
 void mmc_power_off(struct mmc_host *host)
 {
-	int err = 0;
-
 	if (host->ios.power_mode == MMC_POWER_OFF)
 		return;
 
@@ -1247,22 +1343,6 @@
 	host->ios.clock = 0;
 	host->ios.vdd = 0;
 
-	/*
-	 * For eMMC 4.5 device send AWAKE command before
-	 * POWER_OFF_NOTIFY command, because in sleep state
-	 * eMMC 4.5 devices respond to only RESET and AWAKE cmd
-	 */
-	if (host->card && mmc_card_is_sleep(host->card) &&
-	    host->bus_ops->resume) {
-		err = host->bus_ops->resume(host);
-
-		if (!err)
-			mmc_poweroff_notify(host);
-		else
-			pr_warning("%s: error %d during resume "
-				   "(continue with poweroff sequence)\n",
-				   mmc_hostname(host), err);
-	}
 
 	/*
 	 * Reset ocr mask to be the highest possible voltage supported for
@@ -2052,6 +2132,11 @@
 	if (host->rescan_disable)
 		return;
 
+	/* If there is a non-removable card registered, only scan once */
+	if ((host->caps & MMC_CAP_NONREMOVABLE) && host->rescan_entered)
+		return;
+	host->rescan_entered = 1;
+
 	mmc_bus_get(host);
 
 	/*
@@ -2327,9 +2412,14 @@
 
 	mmc_bus_get(host);
 	if (host->bus_ops && !host->bus_dead) {
-
-		if (host->bus_ops->suspend)
+		if (host->bus_ops->suspend) {
+			if (mmc_card_doing_bkops(host->card)) {
+				err = mmc_stop_bkops(host->card);
+				if (err)
+					goto out;
+			}
 			err = host->bus_ops->suspend(host);
+		}
 
 		if (err == -ENOSYS || !host->bus_ops->resume) {
 			/*
@@ -2411,15 +2501,24 @@
 	struct mmc_host *host = container_of(
 		notify_block, struct mmc_host, pm_notify);
 	unsigned long flags;
-
+	int err = 0;
 
 	switch (mode) {
 	case PM_HIBERNATION_PREPARE:
 	case PM_SUSPEND_PREPARE:
+		if (host->card && mmc_card_mmc(host->card) &&
+		    mmc_card_doing_bkops(host->card)) {
+			err = mmc_stop_bkops(host->card);
+			if (err) {
+				pr_err("%s: didn't stop bkops\n",
+					mmc_hostname(host));
+				return err;
+			}
+			mmc_card_clr_doing_bkops(host->card);
+		}
 
 		spin_lock_irqsave(&host->lock, flags);
 		host->rescan_disable = 1;
-		host->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
 		spin_unlock_irqrestore(&host->lock, flags);
 		cancel_delayed_work_sync(&host->detect);
 
@@ -2443,7 +2542,6 @@
 
 		spin_lock_irqsave(&host->lock, flags);
 		host->rescan_disable = 0;
-		host->power_notify_type = MMC_HOST_PW_NOTIFY_LONG;
 		spin_unlock_irqrestore(&host->lock, flags);
 		mmc_detect_change(host, 0);
 
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
index 9ab5b17..d96c643 100644
--- a/drivers/mmc/core/debugfs.c
+++ b/drivers/mmc/core/debugfs.c
@@ -281,7 +281,7 @@
 	if (err)
 		goto out_free;
 
-	for (i = 511; i >= 0; i--)
+	for (i = 0; i < 512; i++)
 		n += sprintf(buf + n, "%02x", ext_csd[i]);
 	n += sprintf(buf + n, "\n");
 	BUG_ON(n != EXT_CSD_STR_LEN);
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 396b258..7cc4638 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -463,6 +463,17 @@
 	}
 
 	if (card->ext_csd.rev >= 5) {
+		/* check whether the eMMC card supports BKOPS */
+		if (ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1) {
+			card->ext_csd.bkops = 1;
+			card->ext_csd.bkops_en = ext_csd[EXT_CSD_BKOPS_EN];
+			card->ext_csd.raw_bkops_status =
+				ext_csd[EXT_CSD_BKOPS_STATUS];
+			if (!card->ext_csd.bkops_en)
+				pr_info("%s: BKOPS_EN bit is not set\n",
+					mmc_hostname(card->host));
+		}
+
 		/* check whether the eMMC card supports HPI */
 		if (ext_csd[EXT_CSD_HPI_FEATURES] & 0x1) {
 			card->ext_csd.hpi = 1;
@@ -996,7 +1007,7 @@
 		 * so check for success and update the flag
 		 */
 		if (!err)
-			card->poweroff_notify_state = MMC_POWERED_ON;
+			card->ext_csd.power_off_notification = EXT_CSD_POWER_ON;
 	}
 
 	/*
@@ -1262,6 +1273,35 @@
 	return err;
 }
 
+static int mmc_can_poweroff_notify(const struct mmc_card *card)
+{
+	return card &&
+		mmc_card_mmc(card) &&
+		(card->ext_csd.power_off_notification == EXT_CSD_POWER_ON);
+}
+
+static int mmc_poweroff_notify(struct mmc_card *card, unsigned int notify_type)
+{
+	unsigned int timeout = card->ext_csd.generic_cmd6_time;
+	int err;
+
+	/* Use EXT_CSD_POWER_OFF_SHORT as default notification type. */
+	if (notify_type == EXT_CSD_POWER_OFF_LONG)
+		timeout = card->ext_csd.power_off_longtime;
+
+	err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+			 EXT_CSD_POWER_OFF_NOTIFICATION,
+			 notify_type, timeout);
+	if (err)
+		pr_err("%s: Power Off Notification timed out, %u\n",
+		       mmc_hostname(card->host), timeout);
+
+	/* Disable the power off notification after the switch operation. */
+	card->ext_csd.power_off_notification = EXT_CSD_NO_POWER_NOTIFICATION;
+
+	return err;
+}
+
 /*
  * Host is being removed. Free up the current card.
  */
@@ -1322,11 +1362,11 @@
 	BUG_ON(!host->card);
 
 	mmc_claim_host(host);
-	if (mmc_card_can_sleep(host)) {
+	if (mmc_can_poweroff_notify(host->card))
+		err = mmc_poweroff_notify(host->card, EXT_CSD_POWER_OFF_SHORT);
+	else if (mmc_card_can_sleep(host))
 		err = mmc_card_sleep(host);
-		if (!err)
-			mmc_card_set_sleep(host->card);
-	} else if (!mmc_host_is_spi(host))
+	else if (!mmc_host_is_spi(host))
 		err = mmc_deselect_cards(host);
 	host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
 	mmc_release_host(host);
@@ -1348,11 +1388,7 @@
 	BUG_ON(!host->card);
 
 	mmc_claim_host(host);
-	if (mmc_card_is_sleep(host->card)) {
-		err = mmc_card_awake(host);
-		mmc_card_clr_sleep(host->card);
-	} else
-		err = mmc_init_card(host, host->ocr, host->card);
+	err = mmc_init_card(host, host->ocr, host->card);
 	mmc_release_host(host);
 
 	return err;
@@ -1363,7 +1399,6 @@
 	int ret;
 
 	host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
-	mmc_card_clr_sleep(host->card);
 	mmc_claim_host(host);
 	ret = mmc_init_card(host, host->ocr, host->card);
 	mmc_release_host(host);
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index 0ed2cc5..a0e1720 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -230,6 +230,10 @@
 	return 0;
 }
 
+/*
+ * NOTE: void *buf, caller for the buf is required to use DMA-capable
+ * buffer or on-stack buffer (with some overhead in callee).
+ */
 static int
 mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host,
 		u32 opcode, void *buf, unsigned len)
@@ -239,13 +243,19 @@
 	struct mmc_data data = {0};
 	struct scatterlist sg;
 	void *data_buf;
+	int is_on_stack;
 
-	/* dma onto stack is unsafe/nonportable, but callers to this
-	 * routine normally provide temporary on-stack buffers ...
-	 */
-	data_buf = kmalloc(len, GFP_KERNEL);
-	if (data_buf == NULL)
-		return -ENOMEM;
+	is_on_stack = object_is_on_stack(buf);
+	if (is_on_stack) {
+		/*
+		 * dma onto stack is unsafe/nonportable, but callers to this
+		 * routine normally provide temporary on-stack buffers ...
+		 */
+		data_buf = kmalloc(len, GFP_KERNEL);
+		if (!data_buf)
+			return -ENOMEM;
+	} else
+		data_buf = buf;
 
 	mrq.cmd = &cmd;
 	mrq.data = &data;
@@ -280,8 +290,10 @@
 
 	mmc_wait_for_req(host, &mrq);
 
-	memcpy(buf, data_buf, len);
-	kfree(data_buf);
+	if (is_on_stack) {
+		memcpy(buf, data_buf, len);
+		kfree(data_buf);
+	}
 
 	if (cmd.error)
 		return cmd.error;
@@ -294,24 +306,32 @@
 int mmc_send_csd(struct mmc_card *card, u32 *csd)
 {
 	int ret, i;
+	u32 *csd_tmp;
 
 	if (!mmc_host_is_spi(card->host))
 		return mmc_send_cxd_native(card->host, card->rca << 16,
 				csd, MMC_SEND_CSD);
 
-	ret = mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd, 16);
+	csd_tmp = kmalloc(16, GFP_KERNEL);
+	if (!csd_tmp)
+		return -ENOMEM;
+
+	ret = mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd_tmp, 16);
 	if (ret)
-		return ret;
+		goto err;
 
 	for (i = 0;i < 4;i++)
-		csd[i] = be32_to_cpu(csd[i]);
+		csd[i] = be32_to_cpu(csd_tmp[i]);
 
-	return 0;
+err:
+	kfree(csd_tmp);
+	return ret;
 }
 
 int mmc_send_cid(struct mmc_host *host, u32 *cid)
 {
 	int ret, i;
+	u32 *cid_tmp;
 
 	if (!mmc_host_is_spi(host)) {
 		if (!host->card)
@@ -320,14 +340,20 @@
 				cid, MMC_SEND_CID);
 	}
 
-	ret = mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid, 16);
+	cid_tmp = kmalloc(16, GFP_KERNEL);
+	if (!cid_tmp)
+		return -ENOMEM;
+
+	ret = mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid_tmp, 16);
 	if (ret)
-		return ret;
+		goto err;
 
 	for (i = 0;i < 4;i++)
-		cid[i] = be32_to_cpu(cid[i]);
+		cid[i] = be32_to_cpu(cid_tmp[i]);
 
-	return 0;
+err:
+	kfree(cid_tmp);
+	return ret;
 }
 
 int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd)
@@ -367,18 +393,19 @@
 }
 
 /**
- *	mmc_switch - modify EXT_CSD register
+ *	__mmc_switch - modify EXT_CSD register
  *	@card: the MMC card associated with the data transfer
  *	@set: cmd set values
  *	@index: EXT_CSD register index
  *	@value: value to program into EXT_CSD register
  *	@timeout_ms: timeout (ms) for operation performed by register write,
  *                   timeout of zero implies maximum possible timeout
+ *	@use_busy_signal: use the busy signal as response type
  *
  *	Modifies the EXT_CSD register for selected card.
  */
-int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
-	       unsigned int timeout_ms)
+int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
+	       unsigned int timeout_ms, bool use_busy_signal)
 {
 	int err;
 	struct mmc_command cmd = {0};
@@ -392,13 +419,23 @@
 		  (index << 16) |
 		  (value << 8) |
 		  set;
-	cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
+	cmd.flags = MMC_CMD_AC;
+	if (use_busy_signal)
+		cmd.flags |= MMC_RSP_SPI_R1B | MMC_RSP_R1B;
+	else
+		cmd.flags |= MMC_RSP_SPI_R1 | MMC_RSP_R1;
+
+
 	cmd.cmd_timeout_ms = timeout_ms;
 
 	err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
 	if (err)
 		return err;
 
+	/* No need to check card status in case of unblocking command */
+	if (!use_busy_signal)
+		return 0;
+
 	/* Must check status to be sure of no errors */
 	do {
 		err = mmc_send_status(card, &status);
@@ -423,6 +460,13 @@
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(__mmc_switch);
+
+int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
+		unsigned int timeout_ms)
+{
+	return __mmc_switch(card, set, index, value, timeout_ms, true);
+}
 EXPORT_SYMBOL_GPL(mmc_switch);
 
 int mmc_send_status(struct mmc_card *card, u32 *status)
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c
index 236842e..6bf6879 100644
--- a/drivers/mmc/core/sdio_bus.c
+++ b/drivers/mmc/core/sdio_bus.c
@@ -193,14 +193,7 @@
 }
 
 #ifdef CONFIG_PM
-
-static int pm_no_operation(struct device *dev)
-{
-	return 0;
-}
-
 static const struct dev_pm_ops sdio_bus_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(pm_no_operation, pm_no_operation)
 	SET_RUNTIME_PM_OPS(
 		pm_generic_runtime_suspend,
 		pm_generic_runtime_resume,
diff --git a/drivers/mmc/core/slot-gpio.c b/drivers/mmc/core/slot-gpio.c
index 0582429..08c6b3d 100644
--- a/drivers/mmc/core/slot-gpio.c
+++ b/drivers/mmc/core/slot-gpio.c
@@ -100,7 +100,13 @@
 
 	ctx = host->slot.handler_priv;
 
-	return gpio_request_one(gpio, GPIOF_DIR_IN, ctx->ro_label);
+	ret = gpio_request_one(gpio, GPIOF_DIR_IN, ctx->ro_label);
+	if (ret < 0)
+		return ret;
+
+	ctx->ro_gpio = gpio;
+
+	return 0;
 }
 EXPORT_SYMBOL(mmc_gpio_request_ro);
 
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index aa131b3..9bf10e7 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -540,6 +540,15 @@
 
 	  If unsure, say Y.
 
+config MMC_DW_EXYNOS
+	tristate "Exynos specific extentions for Synopsys DW Memory Card Interface"
+	depends on MMC_DW
+	select MMC_DW_PLTFM
+	help
+	  This selects support for Samsung Exynos SoC specific extensions to the
+	  Synopsys DesignWare Memory Card Interface driver. Select this option
+	  for platforms based on Exynos4 and Exynos5 SoC's.
+
 config MMC_DW_PCI
 	tristate "Synopsys Designware MCI support on PCI bus"
 	depends on MMC_DW && PCI
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 8922b06..17ad0a7 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -39,6 +39,7 @@
 obj-$(CONFIG_SDH_BFIN)		+= bfin_sdh.o
 obj-$(CONFIG_MMC_DW)		+= dw_mmc.o
 obj-$(CONFIG_MMC_DW_PLTFM)	+= dw_mmc-pltfm.o
+obj-$(CONFIG_MMC_DW_EXYNOS)	+= dw_mmc-exynos.o
 obj-$(CONFIG_MMC_DW_PCI)	+= dw_mmc-pci.o
 obj-$(CONFIG_MMC_SH_MMCIF)	+= sh_mmcif.o
 obj-$(CONFIG_MMC_JZ4740)	+= jz4740_mmc.o
diff --git a/drivers/mmc/host/atmel-mci-regs.h b/drivers/mmc/host/atmel-mci-regs.h
index ab56f7d..c97001e 100644
--- a/drivers/mmc/host/atmel-mci-regs.h
+++ b/drivers/mmc/host/atmel-mci-regs.h
@@ -140,6 +140,13 @@
 #define atmci_writel(port,reg,value)			\
 	__raw_writel((value), (port)->regs + reg)
 
+/* On AVR chips the Peripheral DMA Controller is not connected to MCI. */
+#ifdef CONFIG_AVR32
+#	define ATMCI_PDC_CONNECTED	0
+#else
+#	define ATMCI_PDC_CONNECTED	1
+#endif
+
 /*
  * Fix sconfig's burst size according to atmel MCI. We need to convert them as:
  * 1 -> 0, 4 -> 1, 8 -> 2, 16 -> 3.
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index 852d5fb..ddf096e 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -19,6 +19,9 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
 #include <linux/platform_device.h>
 #include <linux/scatterlist.h>
 #include <linux/seq_file.h>
@@ -71,7 +74,7 @@
 };
 
 struct atmel_mci_caps {
-	bool    has_dma;
+	bool    has_dma_conf_reg;
 	bool    has_pdc;
 	bool    has_cfg_reg;
 	bool    has_cstor_reg;
@@ -418,7 +421,7 @@
 	atmci_show_status_reg(s, "SR", buf[ATMCI_SR / 4]);
 	atmci_show_status_reg(s, "IMR", buf[ATMCI_IMR / 4]);
 
-	if (host->caps.has_dma) {
+	if (host->caps.has_dma_conf_reg) {
 		u32 val;
 
 		val = buf[ATMCI_DMA / 4];
@@ -500,6 +503,70 @@
 	dev_err(&mmc->class_dev, "failed to initialize debugfs for slot\n");
 }
 
+#if defined(CONFIG_OF)
+static const struct of_device_id atmci_dt_ids[] = {
+	{ .compatible = "atmel,hsmci" },
+	{ /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, atmci_dt_ids);
+
+static struct mci_platform_data __devinit*
+atmci_of_init(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct device_node *cnp;
+	struct mci_platform_data *pdata;
+	u32 slot_id;
+
+	if (!np) {
+		dev_err(&pdev->dev, "device node not found\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		dev_err(&pdev->dev, "could not allocate memory for pdata\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	for_each_child_of_node(np, cnp) {
+		if (of_property_read_u32(cnp, "reg", &slot_id)) {
+			dev_warn(&pdev->dev, "reg property is missing for %s\n",
+				 cnp->full_name);
+			continue;
+		}
+
+		if (slot_id >= ATMCI_MAX_NR_SLOTS) {
+			dev_warn(&pdev->dev, "can't have more than %d slots\n",
+			         ATMCI_MAX_NR_SLOTS);
+			break;
+		}
+
+		if (of_property_read_u32(cnp, "bus-width",
+		                         &pdata->slot[slot_id].bus_width))
+			pdata->slot[slot_id].bus_width = 1;
+
+		pdata->slot[slot_id].detect_pin =
+			of_get_named_gpio(cnp, "cd-gpios", 0);
+
+		pdata->slot[slot_id].detect_is_active_high =
+			of_property_read_bool(cnp, "cd-inverted");
+
+		pdata->slot[slot_id].wp_pin =
+			of_get_named_gpio(cnp, "wp-gpios", 0);
+	}
+
+	return pdata;
+}
+#else /* CONFIG_OF */
+static inline struct mci_platform_data*
+atmci_of_init(struct platform_device *dev)
+{
+	return ERR_PTR(-EINVAL);
+}
+#endif
+
 static inline unsigned int atmci_get_version(struct atmel_mci *host)
 {
 	return atmci_readl(host, ATMCI_VERSION) & 0x00000fff;
@@ -774,7 +841,7 @@
 
 	dev_vdbg(&host->pdev->dev, "DMA complete\n");
 
-	if (host->caps.has_dma)
+	if (host->caps.has_dma_conf_reg)
 		/* Disable DMA hardware handshaking on MCI */
 		atmci_writel(host, ATMCI_DMA, atmci_readl(host, ATMCI_DMA) & ~ATMCI_DMAEN);
 
@@ -961,7 +1028,9 @@
 		maxburst = atmci_convert_chksize(host->dma_conf.dst_maxburst);
 	}
 
-	atmci_writel(host, ATMCI_DMA, ATMCI_DMA_CHKSIZE(maxburst) | ATMCI_DMAEN);
+	if (host->caps.has_dma_conf_reg)
+		atmci_writel(host, ATMCI_DMA, ATMCI_DMA_CHKSIZE(maxburst) |
+			ATMCI_DMAEN);
 
 	sglen = dma_map_sg(chan->device->dev, data->sg,
 			data->sg_len, direction);
@@ -2046,6 +2115,13 @@
 	slot->sdc_reg = sdc_reg;
 	slot->sdio_irq = sdio_irq;
 
+	dev_dbg(&mmc->class_dev,
+	        "slot[%u]: bus_width=%u, detect_pin=%d, "
+		"detect_is_active_high=%s, wp_pin=%d\n",
+		id, slot_data->bus_width, slot_data->detect_pin,
+		slot_data->detect_is_active_high ? "true" : "false",
+		slot_data->wp_pin);
+
 	mmc->ops = &atmci_ops;
 	mmc->f_min = DIV_ROUND_UP(host->bus_hz, 512);
 	mmc->f_max = host->bus_hz / 2;
@@ -2169,7 +2245,10 @@
 
 	pdata = host->pdev->dev.platform_data;
 
-	if (pdata && find_slave_dev(pdata->dma_slave)) {
+	if (!pdata)
+		return false;
+
+	if (pdata->dma_slave && find_slave_dev(pdata->dma_slave)) {
 		dma_cap_mask_t mask;
 
 		/* Try to grab a DMA channel */
@@ -2210,8 +2289,8 @@
 	dev_info(&host->pdev->dev,
 			"version: 0x%x\n", version);
 
-	host->caps.has_dma = 0;
-	host->caps.has_pdc = 1;
+	host->caps.has_dma_conf_reg = 0;
+	host->caps.has_pdc = ATMCI_PDC_CONNECTED;
 	host->caps.has_cfg_reg = 0;
 	host->caps.has_cstor_reg = 0;
 	host->caps.has_highspeed = 0;
@@ -2228,12 +2307,7 @@
 		host->caps.has_odd_clk_div = 1;
 	case 0x400:
 	case 0x300:
-#ifdef CONFIG_AT_HDMAC
-		host->caps.has_dma = 1;
-#else
-		dev_info(&host->pdev->dev,
-			"has dma capability but dma engine is not selected, then use pio\n");
-#endif
+		host->caps.has_dma_conf_reg = 1;
 		host->caps.has_pdc = 0;
 		host->caps.has_cfg_reg = 1;
 		host->caps.has_cstor_reg = 1;
@@ -2268,8 +2342,14 @@
 	if (!regs)
 		return -ENXIO;
 	pdata = pdev->dev.platform_data;
-	if (!pdata)
-		return -ENXIO;
+	if (!pdata) {
+		pdata = atmci_of_init(pdev);
+		if (IS_ERR(pdata)) {
+			dev_err(&pdev->dev, "platform data not available\n");
+			return PTR_ERR(pdata);
+		}
+	}
+
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0)
 		return irq;
@@ -2308,7 +2388,7 @@
 
 	/* Get MCI capabilities and set operations according to it */
 	atmci_get_cap(host);
-	if (host->caps.has_dma && atmci_configure_dma(host)) {
+	if (atmci_configure_dma(host)) {
 		host->prepare_data = &atmci_prepare_data_dma;
 		host->submit_data = &atmci_submit_data_dma;
 		host->stop_transfer = &atmci_stop_transfer_dma;
@@ -2487,6 +2567,7 @@
 	.driver		= {
 		.name		= "atmel_mci",
 		.pm		= ATMCI_PM_OPS,
+		.of_match_table	= of_match_ptr(atmci_dt_ids),
 	},
 };
 
diff --git a/drivers/mmc/host/bfin_sdh.c b/drivers/mmc/host/bfin_sdh.c
index a17dd73..b9b463e 100644
--- a/drivers/mmc/host/bfin_sdh.c
+++ b/drivers/mmc/host/bfin_sdh.c
@@ -24,9 +24,7 @@
 #include <asm/portmux.h>
 #include <asm/bfin_sdh.h>
 
-#if defined(CONFIG_BF51x)
-#define bfin_read_SDH_PWR_CTL		bfin_read_RSI_PWR_CTL
-#define bfin_write_SDH_PWR_CTL		bfin_write_RSI_PWR_CTL
+#if defined(CONFIG_BF51x) || defined(__ADSPBF60x__)
 #define bfin_read_SDH_CLK_CTL		bfin_read_RSI_CLK_CTL
 #define bfin_write_SDH_CLK_CTL		bfin_write_RSI_CLK_CTL
 #define bfin_write_SDH_ARGUMENT		bfin_write_RSI_ARGUMENT
@@ -45,8 +43,16 @@
 #define bfin_write_SDH_E_STATUS		bfin_write_RSI_E_STATUS
 #define bfin_read_SDH_STATUS		bfin_read_RSI_STATUS
 #define bfin_write_SDH_MASK0		bfin_write_RSI_MASK0
+#define bfin_write_SDH_E_MASK		bfin_write_RSI_E_MASK
 #define bfin_read_SDH_CFG		bfin_read_RSI_CFG
 #define bfin_write_SDH_CFG		bfin_write_RSI_CFG
+# if defined(__ADSPBF60x__)
+#  define bfin_read_SDH_BLK_SIZE	bfin_read_RSI_BLKSZ
+#  define bfin_write_SDH_BLK_SIZE	bfin_write_RSI_BLKSZ
+# else
+#  define bfin_read_SDH_PWR_CTL		bfin_read_RSI_PWR_CTL
+#  define bfin_write_SDH_PWR_CTL	bfin_write_RSI_PWR_CTL
+# endif
 #endif
 
 struct sdh_host {
@@ -62,6 +68,7 @@
 	dma_addr_t		sg_dma;
 	int			dma_len;
 
+	unsigned long		sclk;
 	unsigned int		imask;
 	unsigned int		power_mode;
 	unsigned int		clk_div;
@@ -127,11 +134,15 @@
 	/* Only supports power-of-2 block size */
 	if (data->blksz & (data->blksz - 1))
 		return -EINVAL;
+#ifndef RSI_BLKSZ
 	data_ctl |= ((ffs(data->blksz) - 1) << 4);
+#else
+        bfin_write_SDH_BLK_SIZE(data->blksz);
+#endif
 
 	bfin_write_SDH_DATA_CTL(data_ctl);
 	/* the time of a host clock period in ns */
-	cycle_ns = 1000000000 / (get_sclk() / (2 * (host->clk_div + 1)));
+	cycle_ns = 1000000000 / (host->sclk / (2 * (host->clk_div + 1)));
 	timeout = data->timeout_ns / cycle_ns;
 	timeout += data->timeout_clks;
 	bfin_write_SDH_DATA_TIMER(timeout);
@@ -145,8 +156,13 @@
 
 	sdh_enable_stat_irq(host, (DAT_CRC_FAIL | DAT_TIME_OUT | DAT_END));
 	host->dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma_dir);
-#if defined(CONFIG_BF54x)
-	dma_cfg |= DMAFLOW_ARRAY | NDSIZE_5 | RESTART | WDSIZE_32 | DMAEN;
+#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x)
+	dma_cfg |= DMAFLOW_ARRAY | RESTART | WDSIZE_32 | DMAEN;
+# ifdef RSI_BLKSZ
+	dma_cfg |= PSIZE_32 | NDSIZE_3;
+# else
+	dma_cfg |= NDSIZE_5;
+# endif
 	{
 		struct scatterlist *sg;
 		int i;
@@ -156,7 +172,7 @@
 			host->sg_cpu[i].x_count = sg_dma_len(sg) / 4;
 			host->sg_cpu[i].x_modify = 4;
 			dev_dbg(mmc_dev(host->mmc), "%d: start_addr:0x%lx, "
-				"cfg:0x%x, x_count:0x%x, x_modify:0x%x\n",
+				"cfg:0x%lx, x_count:0x%lx, x_modify:0x%lx\n",
 				i, host->sg_cpu[i].start_addr,
 				host->sg_cpu[i].cfg, host->sg_cpu[i].x_count,
 				host->sg_cpu[i].x_modify);
@@ -172,6 +188,7 @@
 	set_dma_curr_desc_addr(host->dma_ch, (unsigned long *)host->sg_dma);
 	set_dma_x_count(host->dma_ch, 0);
 	set_dma_x_modify(host->dma_ch, 0);
+	SSYNC();
 	set_dma_config(host->dma_ch, dma_cfg);
 #elif defined(CONFIG_BF51x)
 	/* RSI DMA doesn't work in array mode */
@@ -179,6 +196,7 @@
 	set_dma_start_addr(host->dma_ch, sg_dma_address(&data->sg[0]));
 	set_dma_x_count(host->dma_ch, length / 4);
 	set_dma_x_modify(host->dma_ch, 4);
+	SSYNC();
 	set_dma_config(host->dma_ch, dma_cfg);
 #endif
 	bfin_write_SDH_DATA_CTL(bfin_read_SDH_DATA_CTL() | DTX_DMA_E | DTX_E);
@@ -296,7 +314,6 @@
 	else
 		data->bytes_xfered = 0;
 
-	sdh_disable_stat_irq(host, DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL | RX_OVERRUN | TX_UNDERRUN);
 	bfin_write_SDH_STATUS_CLR(DAT_END_STAT | DAT_TIMEOUT_STAT | \
 			DAT_CRC_FAIL_STAT | DAT_BLK_END_STAT | RX_OVERRUN | TX_UNDERRUN);
 	bfin_write_SDH_DATA_CTL(0);
@@ -321,74 +338,115 @@
 	dev_dbg(mmc_dev(host->mmc), "%s enter, mrp:%p, cmd:%p\n", __func__, mrq, mrq->cmd);
 	WARN_ON(host->mrq != NULL);
 
+	spin_lock(&host->lock);
 	host->mrq = mrq;
 	host->data = mrq->data;
 
 	if (mrq->data && mrq->data->flags & MMC_DATA_READ) {
 		ret = sdh_setup_data(host, mrq->data);
 		if (ret)
-			return;
+			goto data_err;
 	}
 
 	sdh_start_cmd(host, mrq->cmd);
+data_err:
+	spin_unlock(&host->lock);
 }
 
 static void sdh_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
 	struct sdh_host *host;
-	unsigned long flags;
 	u16 clk_ctl = 0;
+#ifndef RSI_BLKSZ
 	u16 pwr_ctl = 0;
+#endif
 	u16 cfg;
 	host = mmc_priv(mmc);
 
-	spin_lock_irqsave(&host->lock, flags);
-	if (ios->clock) {
-		unsigned long  sys_clk, ios_clk;
+	spin_lock(&host->lock);
+
+	cfg = bfin_read_SDH_CFG();
+	cfg |= MWE;
+	switch (ios->bus_width) {
+	case MMC_BUS_WIDTH_4:
+#ifndef RSI_BLKSZ
+		cfg &= ~PD_SDDAT3;
+#endif
+		cfg |= PUP_SDDAT3;
+		/* Enable 4 bit SDIO */
+		cfg |= SD4E;
+		clk_ctl |= WIDE_BUS_4;
+		break;
+	case MMC_BUS_WIDTH_8:
+#ifndef RSI_BLKSZ
+		cfg &= ~PD_SDDAT3;
+#endif
+		cfg |= PUP_SDDAT3;
+		/* Disable 4 bit SDIO */
+		cfg &= ~SD4E;
+		clk_ctl |= BYTE_BUS_8;
+		break;
+	default:
+		cfg &= ~PUP_SDDAT3;
+		/* Disable 4 bit SDIO */
+		cfg &= ~SD4E;
+	}
+
+	host->power_mode = ios->power_mode;
+#ifndef RSI_BLKSZ
+	if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) {
+		pwr_ctl |= ROD_CTL;
+# ifndef CONFIG_SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND
+		pwr_ctl |= SD_CMD_OD;
+# endif
+	}
+
+	if (ios->power_mode != MMC_POWER_OFF)
+		pwr_ctl |= PWR_ON;
+	else
+		pwr_ctl &= ~PWR_ON;
+
+	bfin_write_SDH_PWR_CTL(pwr_ctl);
+#else
+# ifndef CONFIG_SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND
+	if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
+		cfg |= SD_CMD_OD;
+	else
+		cfg &= ~SD_CMD_OD;
+# endif
+
+
+	if (ios->power_mode != MMC_POWER_OFF)
+		cfg |= PWR_ON;
+	else
+		cfg &= ~PWR_ON;
+
+	bfin_write_SDH_CFG(cfg);
+#endif
+	SSYNC();
+
+	if (ios->power_mode == MMC_POWER_ON && ios->clock) {
 		unsigned char clk_div;
-		ios_clk = 2 * ios->clock;
-		sys_clk = get_sclk();
-		clk_div = sys_clk / ios_clk;
-		if (sys_clk % ios_clk == 0)
-			clk_div -= 1;
+		clk_div = (get_sclk() / ios->clock - 1) / 2;
 		clk_div = min_t(unsigned char, clk_div, 0xFF);
 		clk_ctl |= clk_div;
 		clk_ctl |= CLK_E;
 		host->clk_div = clk_div;
+		bfin_write_SDH_CLK_CTL(clk_ctl);
+
 	} else
 		sdh_stop_clock(host);
 
-	if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
-#ifdef CONFIG_SDH_BFIN_MISSING_CMD_PULLUP_WORKAROUND
-		pwr_ctl |= ROD_CTL;
-#else
-		pwr_ctl |= SD_CMD_OD | ROD_CTL;
-#endif
-
-	if (ios->bus_width == MMC_BUS_WIDTH_4) {
-		cfg = bfin_read_SDH_CFG();
-		cfg &= ~PD_SDDAT3;
-		cfg |= PUP_SDDAT3;
-		/* Enable 4 bit SDIO */
-		cfg |= (SD4E | MWE);
-		bfin_write_SDH_CFG(cfg);
-		clk_ctl |= WIDE_BUS;
-	} else {
-		cfg = bfin_read_SDH_CFG();
-		cfg |= MWE;
-		bfin_write_SDH_CFG(cfg);
-	}
-
-	bfin_write_SDH_CLK_CTL(clk_ctl);
-
-	host->power_mode = ios->power_mode;
+	/* set up sdh interrupt mask*/
 	if (ios->power_mode == MMC_POWER_ON)
-		pwr_ctl |= PWR_ON;
-
-	bfin_write_SDH_PWR_CTL(pwr_ctl);
+		bfin_write_SDH_MASK0(DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL |
+			RX_OVERRUN | TX_UNDERRUN | CMD_SENT | CMD_RESP_END |
+			CMD_TIME_OUT | CMD_CRC_FAIL);
+	else
+		bfin_write_SDH_MASK0(0);
 	SSYNC();
 
-	spin_unlock_irqrestore(&host->lock, flags);
+	spin_unlock(&host->lock);
 
 	dev_dbg(mmc_dev(host->mmc), "SDH: clk_div = 0x%x actual clock:%ld expected clock:%d\n",
 		host->clk_div,
@@ -405,7 +463,7 @@
 {
 	struct sdh_host *host = devid;
 
-	dev_dbg(mmc_dev(host->mmc), "%s enter, irq_stat: 0x%04x\n", __func__,
+	dev_dbg(mmc_dev(host->mmc), "%s enter, irq_stat: 0x%04lx\n", __func__,
 		get_dma_curr_irqstat(host->dma_ch));
 	clear_dma_irqstat(host->dma_ch);
 	SSYNC();
@@ -420,6 +478,9 @@
 	int handled = 0;
 
 	dev_dbg(mmc_dev(host->mmc), "%s enter\n", __func__);
+
+	spin_lock(&host->lock);
+
 	status = bfin_read_SDH_E_STATUS();
 	if (status & SD_CARD_DET) {
 		mmc_detect_change(host->mmc, 0);
@@ -437,11 +498,30 @@
 	if (status & (DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL | RX_OVERRUN | TX_UNDERRUN))
 		handled |= sdh_data_done(host, status);
 
+	spin_unlock(&host->lock);
+
 	dev_dbg(mmc_dev(host->mmc), "%s exit\n\n", __func__);
 
 	return IRQ_RETVAL(handled);
 }
 
+static void sdh_reset(void)
+{
+#if defined(CONFIG_BF54x)
+	/* Secure Digital Host shares DMA with Nand controller */
+	bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() | 0x1);
+#endif
+
+	bfin_write_SDH_CFG(bfin_read_SDH_CFG() | CLKS_EN);
+	SSYNC();
+
+	/* Disable card inserting detection pin. set MMC_CAP_NEEDS_POLL, and
+	 * mmc stack will do the detection.
+	 */
+	bfin_write_SDH_CFG((bfin_read_SDH_CFG() & 0x1F) | (PUP_SDDAT | PUP_SDDAT3));
+	SSYNC();
+}
+
 static int __devinit sdh_probe(struct platform_device *pdev)
 {
 	struct mmc_host *mmc;
@@ -462,8 +542,16 @@
 	}
 
 	mmc->ops = &sdh_ops;
-	mmc->max_segs = 32;
+#if defined(CONFIG_BF51x)
+	mmc->max_segs = 1;
+#else
+	mmc->max_segs = PAGE_SIZE / sizeof(struct dma_desc_array);
+#endif
+#ifdef RSI_BLKSZ
+	mmc->max_seg_size = -1;
+#else
 	mmc->max_seg_size = 1 << 16;
+#endif
 	mmc->max_blk_size = 1 << 11;
 	mmc->max_blk_count = 1 << 11;
 	mmc->max_req_size = PAGE_SIZE;
@@ -473,6 +561,7 @@
 	mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_NEEDS_POLL;
 	host = mmc_priv(mmc);
 	host->mmc = mmc;
+	host->sclk = get_sclk();
 
 	spin_lock_init(&host->lock);
 	host->irq = drv_data->irq_int0;
@@ -497,7 +586,6 @@
 	}
 
 	platform_set_drvdata(pdev, mmc);
-	mmc_add_host(mmc);
 
 	ret = request_irq(host->irq, sdh_stat_irq, 0, "SDH Status IRQ", host);
 	if (ret) {
@@ -510,20 +598,10 @@
 		dev_err(&pdev->dev, "unable to request peripheral pins\n");
 		goto out4;
 	}
-#if defined(CONFIG_BF54x)
-	/* Secure Digital Host shares DMA with Nand controller */
-	bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() | 0x1);
-#endif
 
-	bfin_write_SDH_CFG(bfin_read_SDH_CFG() | CLKS_EN);
-	SSYNC();
+	sdh_reset();
 
-	/* Disable card inserting detection pin. set MMC_CAP_NEES_POLL, and
-	 * mmc stack will do the detection.
-	 */
-	bfin_write_SDH_CFG((bfin_read_SDH_CFG() & 0x1F) | (PUP_SDDAT | PUP_SDDAT3));
-	SSYNC();
-
+	mmc_add_host(mmc);
 	return 0;
 
 out4:
@@ -571,7 +649,6 @@
 	if (mmc)
 		ret = mmc_suspend_host(mmc);
 
-	bfin_write_SDH_PWR_CTL(bfin_read_SDH_PWR_CTL() & ~PWR_ON);
 	peripheral_free_list(drv_data->pin_req);
 
 	return ret;
@@ -589,16 +666,7 @@
 		return ret;
 	}
 
-	bfin_write_SDH_PWR_CTL(bfin_read_SDH_PWR_CTL() | PWR_ON);
-#if defined(CONFIG_BF54x)
-	/* Secure Digital Host shares DMA with Nand controller */
-	bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() | 0x1);
-#endif
-	bfin_write_SDH_CFG(bfin_read_SDH_CFG() | CLKS_EN);
-	SSYNC();
-
-	bfin_write_SDH_CFG((bfin_read_SDH_CFG() & 0x1F) | (PUP_SDDAT | PUP_SDDAT3));
-	SSYNC();
+	sdh_reset();
 
 	if (mmc)
 		ret = mmc_resume_host(mmc);
diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c
index 3dfd347..2063677 100644
--- a/drivers/mmc/host/davinci_mmc.c
+++ b/drivers/mmc/host/davinci_mmc.c
@@ -30,11 +30,12 @@
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/delay.h>
+#include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
+#include <linux/edma.h>
 #include <linux/mmc/mmc.h>
 
 #include <linux/platform_data/mmc-davinci.h>
-#include <mach/edma.h>
 
 /*
  * Register Definitions
@@ -200,21 +201,13 @@
 	u32 bytes_left;
 
 	u32 rxdma, txdma;
+	struct dma_chan *dma_tx;
+	struct dma_chan *dma_rx;
 	bool use_dma;
 	bool do_dma;
 	bool sdio_int;
 	bool active_request;
 
-	/* Scatterlist DMA uses one or more parameter RAM entries:
-	 * the main one (associated with rxdma or txdma) plus zero or
-	 * more links.  The entries for a given transfer differ only
-	 * by memory buffer (address, length) and link field.
-	 */
-	struct edmacc_param	tx_template;
-	struct edmacc_param	rx_template;
-	unsigned		n_link;
-	u32			links[MAX_NR_SG - 1];
-
 	/* For PIO we walk scatterlists one segment at a time. */
 	unsigned int		sg_len;
 	struct scatterlist *sg;
@@ -410,153 +403,74 @@
 
 static void davinci_abort_dma(struct mmc_davinci_host *host)
 {
-	int sync_dev;
+	struct dma_chan *sync_dev;
 
 	if (host->data_dir == DAVINCI_MMC_DATADIR_READ)
-		sync_dev = host->rxdma;
+		sync_dev = host->dma_rx;
 	else
-		sync_dev = host->txdma;
+		sync_dev = host->dma_tx;
 
-	edma_stop(sync_dev);
-	edma_clean_channel(sync_dev);
+	dmaengine_terminate_all(sync_dev);
 }
 
-static void
-mmc_davinci_xfer_done(struct mmc_davinci_host *host, struct mmc_data *data);
-
-static void mmc_davinci_dma_cb(unsigned channel, u16 ch_status, void *data)
-{
-	if (DMA_COMPLETE != ch_status) {
-		struct mmc_davinci_host *host = data;
-
-		/* Currently means:  DMA Event Missed, or "null" transfer
-		 * request was seen.  In the future, TC errors (like bad
-		 * addresses) might be presented too.
-		 */
-		dev_warn(mmc_dev(host->mmc), "DMA %s error\n",
-			(host->data->flags & MMC_DATA_WRITE)
-				? "write" : "read");
-		host->data->error = -EIO;
-		mmc_davinci_xfer_done(host, host->data);
-	}
-}
-
-/* Set up tx or rx template, to be modified and updated later */
-static void __init mmc_davinci_dma_setup(struct mmc_davinci_host *host,
-		bool tx, struct edmacc_param *template)
-{
-	unsigned	sync_dev;
-	const u16	acnt = 4;
-	const u16	bcnt = rw_threshold >> 2;
-	const u16	ccnt = 0;
-	u32		src_port = 0;
-	u32		dst_port = 0;
-	s16		src_bidx, dst_bidx;
-	s16		src_cidx, dst_cidx;
-
-	/*
-	 * A-B Sync transfer:  each DMA request is for one "frame" of
-	 * rw_threshold bytes, broken into "acnt"-size chunks repeated
-	 * "bcnt" times.  Each segment needs "ccnt" such frames; since
-	 * we tell the block layer our mmc->max_seg_size limit, we can
-	 * trust (later) that it's within bounds.
-	 *
-	 * The FIFOs are read/written in 4-byte chunks (acnt == 4) and
-	 * EDMA will optimize memory operations to use larger bursts.
-	 */
-	if (tx) {
-		sync_dev = host->txdma;
-
-		/* src_prt, ccnt, and link to be set up later */
-		src_bidx = acnt;
-		src_cidx = acnt * bcnt;
-
-		dst_port = host->mem_res->start + DAVINCI_MMCDXR;
-		dst_bidx = 0;
-		dst_cidx = 0;
-	} else {
-		sync_dev = host->rxdma;
-
-		src_port = host->mem_res->start + DAVINCI_MMCDRR;
-		src_bidx = 0;
-		src_cidx = 0;
-
-		/* dst_prt, ccnt, and link to be set up later */
-		dst_bidx = acnt;
-		dst_cidx = acnt * bcnt;
-	}
-
-	/*
-	 * We can't use FIFO mode for the FIFOs because MMC FIFO addresses
-	 * are not 256-bit (32-byte) aligned.  So we use INCR, and the W8BIT
-	 * parameter is ignored.
-	 */
-	edma_set_src(sync_dev, src_port, INCR, W8BIT);
-	edma_set_dest(sync_dev, dst_port, INCR, W8BIT);
-
-	edma_set_src_index(sync_dev, src_bidx, src_cidx);
-	edma_set_dest_index(sync_dev, dst_bidx, dst_cidx);
-
-	edma_set_transfer_params(sync_dev, acnt, bcnt, ccnt, 8, ABSYNC);
-
-	edma_read_slot(sync_dev, template);
-
-	/* don't bother with irqs or chaining */
-	template->opt |= EDMA_CHAN_SLOT(sync_dev) << 12;
-}
-
-static void mmc_davinci_send_dma_request(struct mmc_davinci_host *host,
+static int mmc_davinci_send_dma_request(struct mmc_davinci_host *host,
 		struct mmc_data *data)
 {
-	struct edmacc_param	*template;
-	int			channel, slot;
-	unsigned		link;
-	struct scatterlist	*sg;
-	unsigned		sg_len;
-	unsigned		bytes_left = host->bytes_left;
-	const unsigned		shift = ffs(rw_threshold) - 1;
+	struct dma_chan *chan;
+	struct dma_async_tx_descriptor *desc;
+	int ret = 0;
 
 	if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE) {
-		template = &host->tx_template;
-		channel = host->txdma;
+		struct dma_slave_config dma_tx_conf = {
+			.direction = DMA_MEM_TO_DEV,
+			.dst_addr = host->mem_res->start + DAVINCI_MMCDXR,
+			.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
+			.dst_maxburst =
+				rw_threshold / DMA_SLAVE_BUSWIDTH_4_BYTES,
+		};
+		chan = host->dma_tx;
+		dmaengine_slave_config(host->dma_tx, &dma_tx_conf);
+
+		desc = dmaengine_prep_slave_sg(host->dma_tx,
+				data->sg,
+				host->sg_len,
+				DMA_MEM_TO_DEV,
+				DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+		if (!desc) {
+			dev_dbg(mmc_dev(host->mmc),
+				"failed to allocate DMA TX descriptor");
+			ret = -1;
+			goto out;
+		}
 	} else {
-		template = &host->rx_template;
-		channel = host->rxdma;
+		struct dma_slave_config dma_rx_conf = {
+			.direction = DMA_DEV_TO_MEM,
+			.src_addr = host->mem_res->start + DAVINCI_MMCDRR,
+			.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
+			.src_maxburst =
+				rw_threshold / DMA_SLAVE_BUSWIDTH_4_BYTES,
+		};
+		chan = host->dma_rx;
+		dmaengine_slave_config(host->dma_rx, &dma_rx_conf);
+
+		desc = dmaengine_prep_slave_sg(host->dma_rx,
+				data->sg,
+				host->sg_len,
+				DMA_DEV_TO_MEM,
+				DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+		if (!desc) {
+			dev_dbg(mmc_dev(host->mmc),
+				"failed to allocate DMA RX descriptor");
+			ret = -1;
+			goto out;
+		}
 	}
 
-	/* We know sg_len and ccnt will never be out of range because
-	 * we told the mmc layer which in turn tells the block layer
-	 * to ensure that it only hands us one scatterlist segment
-	 * per EDMA PARAM entry.  Update the PARAM
-	 * entries needed for each segment of this scatterlist.
-	 */
-	for (slot = channel, link = 0, sg = data->sg, sg_len = host->sg_len;
-			sg_len-- != 0 && bytes_left;
-			sg = sg_next(sg), slot = host->links[link++]) {
-		u32		buf = sg_dma_address(sg);
-		unsigned	count = sg_dma_len(sg);
+	dmaengine_submit(desc);
+	dma_async_issue_pending(chan);
 
-		template->link_bcntrld = sg_len
-				? (EDMA_CHAN_SLOT(host->links[link]) << 5)
-				: 0xffff;
-
-		if (count > bytes_left)
-			count = bytes_left;
-		bytes_left -= count;
-
-		if (host->data_dir == DAVINCI_MMC_DATADIR_WRITE)
-			template->src = buf;
-		else
-			template->dst = buf;
-		template->ccnt = count >> shift;
-
-		edma_write_slot(slot, template);
-	}
-
-	if (host->version == MMC_CTLR_VERSION_2)
-		edma_clear_event(channel);
-
-	edma_start(channel);
+out:
+	return ret;
 }
 
 static int mmc_davinci_start_dma_transfer(struct mmc_davinci_host *host,
@@ -564,6 +478,7 @@
 {
 	int i;
 	int mask = rw_threshold - 1;
+	int ret = 0;
 
 	host->sg_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
 				((data->flags & MMC_DATA_WRITE)
@@ -583,70 +498,48 @@
 	}
 
 	host->do_dma = 1;
-	mmc_davinci_send_dma_request(host, data);
+	ret = mmc_davinci_send_dma_request(host, data);
 
-	return 0;
+	return ret;
 }
 
 static void __init_or_module
 davinci_release_dma_channels(struct mmc_davinci_host *host)
 {
-	unsigned	i;
-
 	if (!host->use_dma)
 		return;
 
-	for (i = 0; i < host->n_link; i++)
-		edma_free_slot(host->links[i]);
-
-	edma_free_channel(host->txdma);
-	edma_free_channel(host->rxdma);
+	dma_release_channel(host->dma_tx);
+	dma_release_channel(host->dma_rx);
 }
 
 static int __init davinci_acquire_dma_channels(struct mmc_davinci_host *host)
 {
-	u32 link_size;
-	int r, i;
+	int r;
+	dma_cap_mask_t mask;
 
-	/* Acquire master DMA write channel */
-	r = edma_alloc_channel(host->txdma, mmc_davinci_dma_cb, host,
-			EVENTQ_DEFAULT);
-	if (r < 0) {
-		dev_warn(mmc_dev(host->mmc), "alloc %s channel err %d\n",
-				"tx", r);
-		return r;
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+
+	host->dma_tx =
+		dma_request_channel(mask, edma_filter_fn, &host->txdma);
+	if (!host->dma_tx) {
+		dev_err(mmc_dev(host->mmc), "Can't get dma_tx channel\n");
+		return -ENODEV;
 	}
-	mmc_davinci_dma_setup(host, true, &host->tx_template);
 
-	/* Acquire master DMA read channel */
-	r = edma_alloc_channel(host->rxdma, mmc_davinci_dma_cb, host,
-			EVENTQ_DEFAULT);
-	if (r < 0) {
-		dev_warn(mmc_dev(host->mmc), "alloc %s channel err %d\n",
-				"rx", r);
+	host->dma_rx =
+		dma_request_channel(mask, edma_filter_fn, &host->rxdma);
+	if (!host->dma_rx) {
+		dev_err(mmc_dev(host->mmc), "Can't get dma_rx channel\n");
+		r = -ENODEV;
 		goto free_master_write;
 	}
-	mmc_davinci_dma_setup(host, false, &host->rx_template);
-
-	/* Allocate parameter RAM slots, which will later be bound to a
-	 * channel as needed to handle a scatterlist.
-	 */
-	link_size = min_t(unsigned, host->nr_sg, ARRAY_SIZE(host->links));
-	for (i = 0; i < link_size; i++) {
-		r = edma_alloc_slot(EDMA_CTLR(host->txdma), EDMA_SLOT_ANY);
-		if (r < 0) {
-			dev_dbg(mmc_dev(host->mmc), "dma PaRAM alloc --> %d\n",
-				r);
-			break;
-		}
-		host->links[i] = r;
-	}
-	host->n_link = i;
 
 	return 0;
 
 free_master_write:
-	edma_free_channel(host->txdma);
+	dma_release_channel(host->dma_tx);
 
 	return r;
 }
@@ -1359,7 +1252,7 @@
 	 * Each hw_seg uses one EDMA parameter RAM slot, always one
 	 * channel and then usually some linked slots.
 	 */
-	mmc->max_segs		= 1 + host->n_link;
+	mmc->max_segs		= MAX_NR_SG;
 
 	/* EDMA limit per hw segment (one or two MBytes) */
 	mmc->max_seg_size	= MAX_CCNT * rw_threshold;
diff --git a/drivers/mmc/host/dw_mmc-exynos.c b/drivers/mmc/host/dw_mmc-exynos.c
new file mode 100644
index 0000000..660bbc5
--- /dev/null
+++ b/drivers/mmc/host/dw_mmc-exynos.c
@@ -0,0 +1,253 @@
+/*
+ * Exynos Specific Extensions for Synopsys DW Multimedia Card Interface driver
+ *
+ * Copyright (C) 2012, Samsung Electronics Co., Ltd.
+ *
+ * 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/platform_device.h>
+#include <linux/clk.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/dw_mmc.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+
+#include "dw_mmc.h"
+#include "dw_mmc-pltfm.h"
+
+#define NUM_PINS(x)			(x + 2)
+
+#define SDMMC_CLKSEL			0x09C
+#define SDMMC_CLKSEL_CCLK_SAMPLE(x)	(((x) & 7) << 0)
+#define SDMMC_CLKSEL_CCLK_DRIVE(x)	(((x) & 7) << 16)
+#define SDMMC_CLKSEL_CCLK_DIVIDER(x)	(((x) & 7) << 24)
+#define SDMMC_CLKSEL_GET_DRV_WD3(x)	(((x) >> 16) & 0x7)
+#define SDMMC_CLKSEL_TIMING(x, y, z)	(SDMMC_CLKSEL_CCLK_SAMPLE(x) |	\
+					SDMMC_CLKSEL_CCLK_DRIVE(y) |	\
+					SDMMC_CLKSEL_CCLK_DIVIDER(z))
+
+#define SDMMC_CMD_USE_HOLD_REG		BIT(29)
+
+#define EXYNOS4210_FIXED_CIU_CLK_DIV	2
+#define EXYNOS4412_FIXED_CIU_CLK_DIV	4
+
+/* Variations in Exynos specific dw-mshc controller */
+enum dw_mci_exynos_type {
+	DW_MCI_TYPE_EXYNOS4210,
+	DW_MCI_TYPE_EXYNOS4412,
+	DW_MCI_TYPE_EXYNOS5250,
+};
+
+/* Exynos implementation specific driver private data */
+struct dw_mci_exynos_priv_data {
+	enum dw_mci_exynos_type		ctrl_type;
+	u8				ciu_div;
+	u32				sdr_timing;
+	u32				ddr_timing;
+};
+
+static struct dw_mci_exynos_compatible {
+	char				*compatible;
+	enum dw_mci_exynos_type		ctrl_type;
+} exynos_compat[] = {
+	{
+		.compatible	= "samsung,exynos4210-dw-mshc",
+		.ctrl_type	= DW_MCI_TYPE_EXYNOS4210,
+	}, {
+		.compatible	= "samsung,exynos4412-dw-mshc",
+		.ctrl_type	= DW_MCI_TYPE_EXYNOS4412,
+	}, {
+		.compatible	= "samsung,exynos5250-dw-mshc",
+		.ctrl_type	= DW_MCI_TYPE_EXYNOS5250,
+	},
+};
+
+static int dw_mci_exynos_priv_init(struct dw_mci *host)
+{
+	struct dw_mci_exynos_priv_data *priv;
+	int idx;
+
+	priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv) {
+		dev_err(host->dev, "mem alloc failed for private data\n");
+		return -ENOMEM;
+	}
+
+	for (idx = 0; idx < ARRAY_SIZE(exynos_compat); idx++) {
+		if (of_device_is_compatible(host->dev->of_node,
+					exynos_compat[idx].compatible))
+			priv->ctrl_type = exynos_compat[idx].ctrl_type;
+	}
+
+	host->priv = priv;
+	return 0;
+}
+
+static int dw_mci_exynos_setup_clock(struct dw_mci *host)
+{
+	struct dw_mci_exynos_priv_data *priv = host->priv;
+
+	if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS5250)
+		host->bus_hz /= (priv->ciu_div + 1);
+	else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4412)
+		host->bus_hz /= EXYNOS4412_FIXED_CIU_CLK_DIV;
+	else if (priv->ctrl_type == DW_MCI_TYPE_EXYNOS4210)
+		host->bus_hz /= EXYNOS4210_FIXED_CIU_CLK_DIV;
+
+	return 0;
+}
+
+static void dw_mci_exynos_prepare_command(struct dw_mci *host, u32 *cmdr)
+{
+	/*
+	 * Exynos4412 and Exynos5250 extends the use of CMD register with the
+	 * use of bit 29 (which is reserved on standard MSHC controllers) for
+	 * optionally bypassing the HOLD register for command and data. The
+	 * HOLD register should be bypassed in case there is no phase shift
+	 * applied on CMD/DATA that is sent to the card.
+	 */
+	if (SDMMC_CLKSEL_GET_DRV_WD3(mci_readl(host, CLKSEL)))
+		*cmdr |= SDMMC_CMD_USE_HOLD_REG;
+}
+
+static void dw_mci_exynos_set_ios(struct dw_mci *host, struct mmc_ios *ios)
+{
+	struct dw_mci_exynos_priv_data *priv = host->priv;
+
+	if (ios->timing == MMC_TIMING_UHS_DDR50)
+		mci_writel(host, CLKSEL, priv->ddr_timing);
+	else
+		mci_writel(host, CLKSEL, priv->sdr_timing);
+}
+
+static int dw_mci_exynos_parse_dt(struct dw_mci *host)
+{
+	struct dw_mci_exynos_priv_data *priv = host->priv;
+	struct device_node *np = host->dev->of_node;
+	u32 timing[2];
+	u32 div = 0;
+	int ret;
+
+	of_property_read_u32(np, "samsung,dw-mshc-ciu-div", &div);
+	priv->ciu_div = div;
+
+	ret = of_property_read_u32_array(np,
+			"samsung,dw-mshc-sdr-timing", timing, 2);
+	if (ret)
+		return ret;
+
+	priv->sdr_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], div);
+
+	ret = of_property_read_u32_array(np,
+			"samsung,dw-mshc-ddr-timing", timing, 2);
+	if (ret)
+		return ret;
+
+	priv->ddr_timing = SDMMC_CLKSEL_TIMING(timing[0], timing[1], div);
+	return 0;
+}
+
+static int dw_mci_exynos_setup_bus(struct dw_mci *host,
+				struct device_node *slot_np, u8 bus_width)
+{
+	int idx, gpio, ret;
+
+	if (!slot_np)
+		return -EINVAL;
+
+	/* cmd + clock + bus-width pins */
+	for (idx = 0; idx < NUM_PINS(bus_width); idx++) {
+		gpio = of_get_gpio(slot_np, idx);
+		if (!gpio_is_valid(gpio)) {
+			dev_err(host->dev, "invalid gpio: %d\n", gpio);
+			return -EINVAL;
+		}
+
+		ret = devm_gpio_request(host->dev, gpio, "dw-mci-bus");
+		if (ret) {
+			dev_err(host->dev, "gpio [%d] request failed\n", gpio);
+			return -EBUSY;
+		}
+	}
+
+	gpio = of_get_named_gpio(slot_np, "wp-gpios", 0);
+	if (gpio_is_valid(gpio)) {
+		if (devm_gpio_request(host->dev, gpio, "dw-mci-wp"))
+			dev_info(host->dev, "gpio [%d] request failed\n",
+						gpio);
+	} else {
+		dev_info(host->dev, "wp gpio not available");
+		host->pdata->quirks |= DW_MCI_QUIRK_NO_WRITE_PROTECT;
+	}
+
+	if (host->pdata->quirks & DW_MCI_QUIRK_BROKEN_CARD_DETECTION)
+		return 0;
+
+	gpio = of_get_named_gpio(slot_np, "samsung,cd-pinmux-gpio", 0);
+	if (gpio_is_valid(gpio)) {
+		if (devm_gpio_request(host->dev, gpio, "dw-mci-cd"))
+			dev_err(host->dev, "gpio [%d] request failed\n", gpio);
+	} else {
+		dev_info(host->dev, "cd gpio not available");
+	}
+
+	return 0;
+}
+
+/* Exynos5250 controller specific capabilities */
+static unsigned long exynos5250_dwmmc_caps[4] = {
+	MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR |
+		MMC_CAP_8_BIT_DATA | MMC_CAP_CMD23,
+	MMC_CAP_CMD23,
+	MMC_CAP_CMD23,
+	MMC_CAP_CMD23,
+};
+
+static struct dw_mci_drv_data exynos5250_drv_data = {
+	.caps			= exynos5250_dwmmc_caps,
+	.init			= dw_mci_exynos_priv_init,
+	.setup_clock		= dw_mci_exynos_setup_clock,
+	.prepare_command	= dw_mci_exynos_prepare_command,
+	.set_ios		= dw_mci_exynos_set_ios,
+	.parse_dt		= dw_mci_exynos_parse_dt,
+	.setup_bus		= dw_mci_exynos_setup_bus,
+};
+
+static const struct of_device_id dw_mci_exynos_match[] = {
+	{ .compatible = "samsung,exynos5250-dw-mshc",
+			.data = (void *)&exynos5250_drv_data, },
+	{},
+};
+MODULE_DEVICE_TABLE(of, dw_mci_pltfm_match);
+
+int dw_mci_exynos_probe(struct platform_device *pdev)
+{
+	struct dw_mci_drv_data *drv_data;
+	const struct of_device_id *match;
+
+	match = of_match_node(dw_mci_exynos_match, pdev->dev.of_node);
+	drv_data = match->data;
+	return dw_mci_pltfm_register(pdev, drv_data);
+}
+
+static struct platform_driver dw_mci_exynos_pltfm_driver = {
+	.probe		= dw_mci_exynos_probe,
+	.remove		= __exit_p(dw_mci_pltfm_remove),
+	.driver		= {
+		.name		= "dwmmc_exynos",
+		.of_match_table	= of_match_ptr(dw_mci_exynos_match),
+		.pm		= &dw_mci_pltfm_pmops,
+	},
+};
+
+module_platform_driver(dw_mci_exynos_pltfm_driver);
+
+MODULE_DESCRIPTION("Samsung Specific DW-MSHC Driver Extension");
+MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:dwmmc-exynos");
diff --git a/drivers/mmc/host/dw_mmc-pci.c b/drivers/mmc/host/dw_mmc-pci.c
index dc0d25a..edb37e9 100644
--- a/drivers/mmc/host/dw_mmc-pci.c
+++ b/drivers/mmc/host/dw_mmc-pci.c
@@ -59,7 +59,7 @@
 
 	host->irq = pdev->irq;
 	host->irq_flags = IRQF_SHARED;
-	host->dev = pdev->dev;
+	host->dev = &pdev->dev;
 	host->pdata = &pci_board_data;
 
 	host->regs = pci_iomap(pdev, PCI_BAR_NO, COMPLETE_BAR);
@@ -140,18 +140,7 @@
 	},
 };
 
-static int __init dw_mci_init(void)
-{
-	return pci_register_driver(&dw_mci_pci_driver);
-}
-
-static void __exit dw_mci_exit(void)
-{
-	pci_unregister_driver(&dw_mci_pci_driver);
-}
-
-module_init(dw_mci_init);
-module_exit(dw_mci_exit);
+module_pci_driver(dw_mci_pci_driver);
 
 MODULE_DESCRIPTION("DW Multimedia Card PCI Interface driver");
 MODULE_AUTHOR("Shashidhar Hiremath <shashidharh@vayavyalabs.com>");
diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
index 92ec3eb..c960ca7 100644
--- a/drivers/mmc/host/dw_mmc-pltfm.c
+++ b/drivers/mmc/host/dw_mmc-pltfm.c
@@ -19,59 +19,63 @@
 #include <linux/mmc/host.h>
 #include <linux/mmc/mmc.h>
 #include <linux/mmc/dw_mmc.h>
+#include <linux/of.h>
+
 #include "dw_mmc.h"
 
-static int dw_mci_pltfm_probe(struct platform_device *pdev)
+int dw_mci_pltfm_register(struct platform_device *pdev,
+				struct dw_mci_drv_data *drv_data)
 {
 	struct dw_mci *host;
 	struct resource	*regs;
 	int ret;
 
-	host = kzalloc(sizeof(struct dw_mci), GFP_KERNEL);
+	host = devm_kzalloc(&pdev->dev, sizeof(struct dw_mci), GFP_KERNEL);
 	if (!host)
 		return -ENOMEM;
 
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!regs) {
-		ret = -ENXIO;
-		goto err_free;
-	}
+	if (!regs)
+		return -ENXIO;
 
 	host->irq = platform_get_irq(pdev, 0);
-	if (host->irq < 0) {
-		ret = host->irq;
-		goto err_free;
-	}
+	if (host->irq < 0)
+		return host->irq;
 
-	host->dev = pdev->dev;
+	host->drv_data = drv_data;
+	host->dev = &pdev->dev;
 	host->irq_flags = 0;
 	host->pdata = pdev->dev.platform_data;
-	ret = -ENOMEM;
-	host->regs = ioremap(regs->start, resource_size(regs));
+	host->regs = devm_request_and_ioremap(&pdev->dev, regs);
 	if (!host->regs)
-		goto err_free;
+		return -ENOMEM;
+
+	if (host->drv_data->init) {
+		ret = host->drv_data->init(host);
+		if (ret)
+			return ret;
+	}
+
 	platform_set_drvdata(pdev, host);
 	ret = dw_mci_probe(host);
-	if (ret)
-		goto err_out;
-	return ret;
-err_out:
-	iounmap(host->regs);
-err_free:
-	kfree(host);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(dw_mci_pltfm_register);
 
-static int __exit dw_mci_pltfm_remove(struct platform_device *pdev)
+static int __devinit dw_mci_pltfm_probe(struct platform_device *pdev)
+{
+	return dw_mci_pltfm_register(pdev, NULL);
+}
+
+static int __devexit dw_mci_pltfm_remove(struct platform_device *pdev)
 {
 	struct dw_mci *host = platform_get_drvdata(pdev);
 
 	platform_set_drvdata(pdev, NULL);
 	dw_mci_remove(host);
-	iounmap(host->regs);
-	kfree(host);
 	return 0;
 }
+EXPORT_SYMBOL_GPL(dw_mci_pltfm_remove);
 
 #ifdef CONFIG_PM_SLEEP
 /*
@@ -105,12 +109,20 @@
 #define dw_mci_pltfm_resume	NULL
 #endif /* CONFIG_PM_SLEEP */
 
-static SIMPLE_DEV_PM_OPS(dw_mci_pltfm_pmops, dw_mci_pltfm_suspend, dw_mci_pltfm_resume);
+SIMPLE_DEV_PM_OPS(dw_mci_pltfm_pmops, dw_mci_pltfm_suspend, dw_mci_pltfm_resume);
+EXPORT_SYMBOL_GPL(dw_mci_pltfm_pmops);
+
+static const struct of_device_id dw_mci_pltfm_match[] = {
+	{ .compatible = "snps,dw-mshc", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, dw_mci_pltfm_match);
 
 static struct platform_driver dw_mci_pltfm_driver = {
 	.remove		= __exit_p(dw_mci_pltfm_remove),
 	.driver		= {
 		.name		= "dw_mmc",
+		.of_match_table	= of_match_ptr(dw_mci_pltfm_match),
 		.pm		= &dw_mci_pltfm_pmops,
 	},
 };
diff --git a/drivers/mmc/host/dw_mmc-pltfm.h b/drivers/mmc/host/dw_mmc-pltfm.h
new file mode 100644
index 0000000..301f245
--- /dev/null
+++ b/drivers/mmc/host/dw_mmc-pltfm.h
@@ -0,0 +1,20 @@
+/*
+ * Synopsys DesignWare Multimedia Card Interface Platform driver
+ *
+ * Copyright (C) 2012, Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ */
+
+#ifndef _DW_MMC_PLTFM_H_
+#define _DW_MMC_PLTFM_H_
+
+extern int dw_mci_pltfm_register(struct platform_device *pdev,
+				struct dw_mci_drv_data *drv_data);
+extern int __devexit dw_mci_pltfm_remove(struct platform_device *pdev);
+extern const struct dev_pm_ops dw_mci_pltfm_pmops;
+
+#endif /* _DW_MMC_PLTFM_H_ */
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index af40d22..c2828f3 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -33,6 +33,7 @@
 #include <linux/bitops.h>
 #include <linux/regulator/consumer.h>
 #include <linux/workqueue.h>
+#include <linux/of.h>
 
 #include "dw_mmc.h"
 
@@ -230,6 +231,7 @@
 static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd)
 {
 	struct mmc_data	*data;
+	struct dw_mci_slot *slot = mmc_priv(mmc);
 	u32 cmdr;
 	cmd->error = -EINPROGRESS;
 
@@ -259,6 +261,9 @@
 			cmdr |= SDMMC_CMD_DAT_WR;
 	}
 
+	if (slot->host->drv_data->prepare_command)
+		slot->host->drv_data->prepare_command(slot->host, &cmdr);
+
 	return cmdr;
 }
 
@@ -266,7 +271,7 @@
 				 struct mmc_command *cmd, u32 cmd_flags)
 {
 	host->cmd = cmd;
-	dev_vdbg(&host->dev,
+	dev_vdbg(host->dev,
 		 "start command: ARGR=0x%08x CMDR=0x%08x\n",
 		 cmd->arg, cmd_flags);
 
@@ -308,7 +313,7 @@
 
 	if (data)
 		if (!data->host_cookie)
-			dma_unmap_sg(&host->dev,
+			dma_unmap_sg(host->dev,
 				     data->sg,
 				     data->sg_len,
 				     dw_mci_get_dma_dir(data));
@@ -334,7 +339,7 @@
 {
 	struct mmc_data *data = host->data;
 
-	dev_vdbg(&host->dev, "DMA complete\n");
+	dev_vdbg(host->dev, "DMA complete\n");
 
 	host->dma_ops->cleanup(host);
 
@@ -405,23 +410,11 @@
 static int dw_mci_idmac_init(struct dw_mci *host)
 {
 	struct idmac_desc *p;
-	int i, dma_support;
+	int i;
 
 	/* Number of descriptors in the ring buffer */
 	host->ring_size = PAGE_SIZE / sizeof(struct idmac_desc);
 
-	/* Check if Hardware Configuration Register has support for DMA */
-	dma_support = (mci_readl(host, HCON) >> 16) & 0x3;
-
-	if (!dma_support || dma_support > 2) {
-		dev_err(&host->dev,
-			"Host Controller does not support IDMA Tx.\n");
-		host->dma_ops = NULL;
-		return -ENODEV;
-	}
-
-	dev_info(&host->dev, "Using internal DMA controller.\n");
-
 	/* Forward link the descriptor list */
 	for (i = 0, p = host->sg_cpu; i < host->ring_size - 1; i++, p++)
 		p->des3 = host->sg_dma + (sizeof(struct idmac_desc) * (i + 1));
@@ -476,7 +469,7 @@
 			return -EINVAL;
 	}
 
-	sg_len = dma_map_sg(&host->dev,
+	sg_len = dma_map_sg(host->dev,
 			    data->sg,
 			    data->sg_len,
 			    dw_mci_get_dma_dir(data));
@@ -519,7 +512,7 @@
 		return;
 
 	if (data->host_cookie)
-		dma_unmap_sg(&slot->host->dev,
+		dma_unmap_sg(slot->host->dev,
 			     data->sg,
 			     data->sg_len,
 			     dw_mci_get_dma_dir(data));
@@ -545,7 +538,7 @@
 
 	host->using_dma = 1;
 
-	dev_vdbg(&host->dev,
+	dev_vdbg(host->dev,
 		 "sd sg_cpu: %#lx sg_dma: %#lx sg_len: %d\n",
 		 (unsigned long)host->sg_cpu, (unsigned long)host->sg_dma,
 		 sg_len);
@@ -814,6 +807,9 @@
 		slot->clock = ios->clock;
 	}
 
+	if (slot->host->drv_data->set_ios)
+		slot->host->drv_data->set_ios(slot->host, ios);
+
 	switch (ios->power_mode) {
 	case MMC_POWER_UP:
 		set_bit(DW_MMC_CARD_NEED_INIT, &slot->flags);
@@ -830,7 +826,9 @@
 	struct dw_mci_board *brd = slot->host->pdata;
 
 	/* Use platform get_ro function, else try on board write protect */
-	if (brd->get_ro)
+	if (brd->quirks & DW_MCI_QUIRK_NO_WRITE_PROTECT)
+		read_only = 0;
+	else if (brd->get_ro)
 		read_only = brd->get_ro(slot->id);
 	else
 		read_only =
@@ -939,12 +937,12 @@
 		slot = list_entry(host->queue.next,
 				  struct dw_mci_slot, queue_node);
 		list_del(&slot->queue_node);
-		dev_vdbg(&host->dev, "list not empty: %s is next\n",
+		dev_vdbg(host->dev, "list not empty: %s is next\n",
 			 mmc_hostname(slot->mmc));
 		host->state = STATE_SENDING_CMD;
 		dw_mci_start_request(host, slot);
 	} else {
-		dev_vdbg(&host->dev, "list empty\n");
+		dev_vdbg(host->dev, "list empty\n");
 		host->state = STATE_IDLE;
 	}
 
@@ -1083,7 +1081,7 @@
 					data->bytes_xfered = 0;
 					data->error = -ETIMEDOUT;
 				} else {
-					dev_err(&host->dev,
+					dev_err(host->dev,
 						"data FIFO error "
 						"(status=%08x)\n",
 						status);
@@ -1767,12 +1765,60 @@
 	}
 }
 
-static int __init dw_mci_init_slot(struct dw_mci *host, unsigned int id)
+#ifdef CONFIG_OF
+/* given a slot id, find out the device node representing that slot */
+static struct device_node *dw_mci_of_find_slot_node(struct device *dev, u8 slot)
+{
+	struct device_node *np;
+	const __be32 *addr;
+	int len;
+
+	if (!dev || !dev->of_node)
+		return NULL;
+
+	for_each_child_of_node(dev->of_node, np) {
+		addr = of_get_property(np, "reg", &len);
+		if (!addr || (len < sizeof(int)))
+			continue;
+		if (be32_to_cpup(addr) == slot)
+			return np;
+	}
+	return NULL;
+}
+
+/* find out bus-width for a given slot */
+static u32 dw_mci_of_get_bus_wd(struct device *dev, u8 slot)
+{
+	struct device_node *np = dw_mci_of_find_slot_node(dev, slot);
+	u32 bus_wd = 1;
+
+	if (!np)
+		return 1;
+
+	if (of_property_read_u32(np, "bus-width", &bus_wd))
+		dev_err(dev, "bus-width property not found, assuming width"
+			       " as 1\n");
+	return bus_wd;
+}
+#else /* CONFIG_OF */
+static u32 dw_mci_of_get_bus_wd(struct device *dev, u8 slot)
+{
+	return 1;
+}
+static struct device_node *dw_mci_of_find_slot_node(struct device *dev, u8 slot)
+{
+	return NULL;
+}
+#endif /* CONFIG_OF */
+
+static int dw_mci_init_slot(struct dw_mci *host, unsigned int id)
 {
 	struct mmc_host *mmc;
 	struct dw_mci_slot *slot;
+	int ctrl_id, ret;
+	u8 bus_width;
 
-	mmc = mmc_alloc_host(sizeof(struct dw_mci_slot), &host->dev);
+	mmc = mmc_alloc_host(sizeof(struct dw_mci_slot), host->dev);
 	if (!mmc)
 		return -ENOMEM;
 
@@ -1780,6 +1826,7 @@
 	slot->id = id;
 	slot->mmc = mmc;
 	slot->host = host;
+	host->slot[id] = slot;
 
 	mmc->ops = &dw_mci_ops;
 	mmc->f_min = DIV_ROUND_UP(host->bus_hz, 510);
@@ -1800,21 +1847,44 @@
 	if (host->pdata->caps)
 		mmc->caps = host->pdata->caps;
 
+	if (host->dev->of_node) {
+		ctrl_id = of_alias_get_id(host->dev->of_node, "mshc");
+		if (ctrl_id < 0)
+			ctrl_id = 0;
+	} else {
+		ctrl_id = to_platform_device(host->dev)->id;
+	}
+	if (host->drv_data && host->drv_data->caps)
+		mmc->caps |= host->drv_data->caps[ctrl_id];
+
 	if (host->pdata->caps2)
 		mmc->caps2 = host->pdata->caps2;
 
 	if (host->pdata->get_bus_wd)
-		if (host->pdata->get_bus_wd(slot->id) >= 4)
-			mmc->caps |= MMC_CAP_4_BIT_DATA;
+		bus_width = host->pdata->get_bus_wd(slot->id);
+	else if (host->dev->of_node)
+		bus_width = dw_mci_of_get_bus_wd(host->dev, slot->id);
+	else
+		bus_width = 1;
+
+	if (host->drv_data->setup_bus) {
+		struct device_node *slot_np;
+		slot_np = dw_mci_of_find_slot_node(host->dev, slot->id);
+		ret = host->drv_data->setup_bus(host, slot_np, bus_width);
+		if (ret)
+			goto err_setup_bus;
+	}
+
+	switch (bus_width) {
+	case 8:
+		mmc->caps |= MMC_CAP_8_BIT_DATA;
+	case 4:
+		mmc->caps |= MMC_CAP_4_BIT_DATA;
+	}
 
 	if (host->pdata->quirks & DW_MCI_QUIRK_HIGHSPEED)
 		mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
 
-	if (mmc->caps2 & MMC_CAP2_POWEROFF_NOTIFY)
-		mmc->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
-	else
-		mmc->power_notify_type = MMC_HOST_PW_NOTIFY_NONE;
-
 	if (host->pdata->blk_settings) {
 		mmc->max_segs = host->pdata->blk_settings->max_segs;
 		mmc->max_blk_size = host->pdata->blk_settings->max_blk_size;
@@ -1850,7 +1920,6 @@
 	else
 		clear_bit(DW_MMC_CARD_PRESENT, &slot->flags);
 
-	host->slot[id] = slot;
 	mmc_add_host(mmc);
 
 #if defined(CONFIG_DEBUG_FS)
@@ -1867,6 +1936,10 @@
 	queue_work(host->card_workqueue, &host->card_work);
 
 	return 0;
+
+err_setup_bus:
+	mmc_free_host(mmc);
+	return -EINVAL;
 }
 
 static void dw_mci_cleanup_slot(struct dw_mci_slot *slot, unsigned int id)
@@ -1884,10 +1957,10 @@
 static void dw_mci_init_dma(struct dw_mci *host)
 {
 	/* Alloc memory for sg translation */
-	host->sg_cpu = dma_alloc_coherent(&host->dev, PAGE_SIZE,
+	host->sg_cpu = dma_alloc_coherent(host->dev, PAGE_SIZE,
 					  &host->sg_dma, GFP_KERNEL);
 	if (!host->sg_cpu) {
-		dev_err(&host->dev, "%s: could not alloc DMA memory\n",
+		dev_err(host->dev, "%s: could not alloc DMA memory\n",
 			__func__);
 		goto no_dma;
 	}
@@ -1895,6 +1968,7 @@
 	/* Determine which DMA interface to use */
 #ifdef CONFIG_MMC_DW_IDMAC
 	host->dma_ops = &dw_mci_idmac_ops;
+	dev_info(&host->dev, "Using internal DMA controller.\n");
 #endif
 
 	if (!host->dma_ops)
@@ -1903,12 +1977,12 @@
 	if (host->dma_ops->init && host->dma_ops->start &&
 	    host->dma_ops->stop && host->dma_ops->cleanup) {
 		if (host->dma_ops->init(host)) {
-			dev_err(&host->dev, "%s: Unable to initialize "
+			dev_err(host->dev, "%s: Unable to initialize "
 				"DMA Controller.\n", __func__);
 			goto no_dma;
 		}
 	} else {
-		dev_err(&host->dev, "DMA initialization not found.\n");
+		dev_err(host->dev, "DMA initialization not found.\n");
 		goto no_dma;
 	}
 
@@ -1916,7 +1990,7 @@
 	return;
 
 no_dma:
-	dev_info(&host->dev, "Using PIO mode.\n");
+	dev_info(host->dev, "Using PIO mode.\n");
 	host->use_dma = 0;
 	return;
 }
@@ -1942,30 +2016,133 @@
 	return false;
 }
 
+#ifdef CONFIG_OF
+static struct dw_mci_of_quirks {
+	char *quirk;
+	int id;
+} of_quirks[] = {
+	{
+		.quirk	= "supports-highspeed",
+		.id	= DW_MCI_QUIRK_HIGHSPEED,
+	}, {
+		.quirk	= "broken-cd",
+		.id	= DW_MCI_QUIRK_BROKEN_CARD_DETECTION,
+	},
+};
+
+static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
+{
+	struct dw_mci_board *pdata;
+	struct device *dev = host->dev;
+	struct device_node *np = dev->of_node;
+	int idx, ret;
+
+	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		dev_err(dev, "could not allocate memory for pdata\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	/* find out number of slots supported */
+	if (of_property_read_u32(dev->of_node, "num-slots",
+				&pdata->num_slots)) {
+		dev_info(dev, "num-slots property not found, "
+				"assuming 1 slot is available\n");
+		pdata->num_slots = 1;
+	}
+
+	/* get quirks */
+	for (idx = 0; idx < ARRAY_SIZE(of_quirks); idx++)
+		if (of_get_property(np, of_quirks[idx].quirk, NULL))
+			pdata->quirks |= of_quirks[idx].id;
+
+	if (of_property_read_u32(np, "fifo-depth", &pdata->fifo_depth))
+		dev_info(dev, "fifo-depth property not found, using "
+				"value of FIFOTH register as default\n");
+
+	of_property_read_u32(np, "card-detect-delay", &pdata->detect_delay_ms);
+
+	if (host->drv_data->parse_dt) {
+		ret = host->drv_data->parse_dt(host);
+		if (ret)
+			return ERR_PTR(ret);
+	}
+
+	return pdata;
+}
+
+#else /* CONFIG_OF */
+static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
+{
+	return ERR_PTR(-EINVAL);
+}
+#endif /* CONFIG_OF */
+
 int dw_mci_probe(struct dw_mci *host)
 {
 	int width, i, ret = 0;
 	u32 fifo_size;
+	int init_slots = 0;
 
-	if (!host->pdata || !host->pdata->init) {
-		dev_err(&host->dev,
-			"Platform data must supply init function\n");
-		return -ENODEV;
+	if (!host->pdata) {
+		host->pdata = dw_mci_parse_dt(host);
+		if (IS_ERR(host->pdata)) {
+			dev_err(host->dev, "platform data not available\n");
+			return -EINVAL;
+		}
 	}
 
 	if (!host->pdata->select_slot && host->pdata->num_slots > 1) {
-		dev_err(&host->dev,
+		dev_err(host->dev,
 			"Platform data must supply select_slot function\n");
 		return -ENODEV;
 	}
 
-	if (!host->pdata->bus_hz) {
-		dev_err(&host->dev,
-			"Platform data must supply bus speed\n");
-		return -ENODEV;
+	host->biu_clk = clk_get(host->dev, "biu");
+	if (IS_ERR(host->biu_clk)) {
+		dev_dbg(host->dev, "biu clock not available\n");
+	} else {
+		ret = clk_prepare_enable(host->biu_clk);
+		if (ret) {
+			dev_err(host->dev, "failed to enable biu clock\n");
+			clk_put(host->biu_clk);
+			return ret;
+		}
 	}
 
-	host->bus_hz = host->pdata->bus_hz;
+	host->ciu_clk = clk_get(host->dev, "ciu");
+	if (IS_ERR(host->ciu_clk)) {
+		dev_dbg(host->dev, "ciu clock not available\n");
+	} else {
+		ret = clk_prepare_enable(host->ciu_clk);
+		if (ret) {
+			dev_err(host->dev, "failed to enable ciu clock\n");
+			clk_put(host->ciu_clk);
+			goto err_clk_biu;
+		}
+	}
+
+	if (IS_ERR(host->ciu_clk))
+		host->bus_hz = host->pdata->bus_hz;
+	else
+		host->bus_hz = clk_get_rate(host->ciu_clk);
+
+	if (host->drv_data->setup_clock) {
+		ret = host->drv_data->setup_clock(host);
+		if (ret) {
+			dev_err(host->dev,
+				"implementation specific clock setup failed\n");
+			goto err_clk_ciu;
+		}
+	}
+
+	if (!host->bus_hz) {
+		dev_err(host->dev,
+			"Platform data must supply bus speed\n");
+		ret = -ENODEV;
+		goto err_clk_ciu;
+	}
+
 	host->quirks = host->pdata->quirks;
 
 	spin_lock_init(&host->lock);
@@ -1998,7 +2175,7 @@
 	}
 
 	/* Reset all blocks */
-	if (!mci_wait_reset(&host->dev, host))
+	if (!mci_wait_reset(host->dev, host))
 		return -ENODEV;
 
 	host->dma_ops = host->pdata->dma_ops;
@@ -2054,10 +2231,18 @@
 	/* We need at least one slot to succeed */
 	for (i = 0; i < host->num_slots; i++) {
 		ret = dw_mci_init_slot(host, i);
-		if (ret) {
-			ret = -ENODEV;
-			goto err_init_slot;
-		}
+		if (ret)
+			dev_dbg(host->dev, "slot %d init failed\n", i);
+		else
+			init_slots++;
+	}
+
+	if (init_slots) {
+		dev_info(host->dev, "%d slots initialized\n", init_slots);
+	} else {
+		dev_dbg(host->dev, "attempted to initialize %d slots, "
+					"but failed on all\n", host->num_slots);
+		goto err_init_slot;
 	}
 
 	/*
@@ -2065,7 +2250,7 @@
 	 * Need to check the version-id and set data-offset for DATA register.
 	 */
 	host->verid = SDMMC_GET_VERID(mci_readl(host, VERID));
-	dev_info(&host->dev, "Version ID is %04x\n", host->verid);
+	dev_info(host->dev, "Version ID is %04x\n", host->verid);
 
 	if (host->verid < DW_MMC_240A)
 		host->data_offset = DATA_OFFSET;
@@ -2082,22 +2267,16 @@
 		   DW_MCI_ERROR_FLAGS | SDMMC_INT_CD);
 	mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */
 
-	dev_info(&host->dev, "DW MMC controller at irq %d, "
+	dev_info(host->dev, "DW MMC controller at irq %d, "
 		 "%d bit host data width, "
 		 "%u deep fifo\n",
 		 host->irq, width, fifo_size);
 	if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO)
-		dev_info(&host->dev, "Internal DMAC interrupt fix enabled.\n");
+		dev_info(host->dev, "Internal DMAC interrupt fix enabled.\n");
 
 	return 0;
 
 err_init_slot:
-	/* De-init any initialized slots */
-	while (i > 0) {
-		if (host->slot[i])
-			dw_mci_cleanup_slot(host->slot[i], i);
-		i--;
-	}
 	free_irq(host->irq, host);
 
 err_workqueue:
@@ -2106,13 +2285,24 @@
 err_dmaunmap:
 	if (host->use_dma && host->dma_ops->exit)
 		host->dma_ops->exit(host);
-	dma_free_coherent(&host->dev, PAGE_SIZE,
+	dma_free_coherent(host->dev, PAGE_SIZE,
 			  host->sg_cpu, host->sg_dma);
 
 	if (host->vmmc) {
 		regulator_disable(host->vmmc);
 		regulator_put(host->vmmc);
 	}
+
+err_clk_ciu:
+	if (!IS_ERR(host->ciu_clk)) {
+		clk_disable_unprepare(host->ciu_clk);
+		clk_put(host->ciu_clk);
+	}
+err_clk_biu:
+	if (!IS_ERR(host->biu_clk)) {
+		clk_disable_unprepare(host->biu_clk);
+		clk_put(host->biu_clk);
+	}
 	return ret;
 }
 EXPORT_SYMBOL(dw_mci_probe);
@@ -2125,7 +2315,7 @@
 	mci_writel(host, INTMASK, 0); /* disable all mmc interrupt first */
 
 	for (i = 0; i < host->num_slots; i++) {
-		dev_dbg(&host->dev, "remove slot %d\n", i);
+		dev_dbg(host->dev, "remove slot %d\n", i);
 		if (host->slot[i])
 			dw_mci_cleanup_slot(host->slot[i], i);
 	}
@@ -2136,7 +2326,7 @@
 
 	free_irq(host->irq, host);
 	destroy_workqueue(host->card_workqueue);
-	dma_free_coherent(&host->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
+	dma_free_coherent(host->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
 
 	if (host->use_dma && host->dma_ops->exit)
 		host->dma_ops->exit(host);
@@ -2146,6 +2336,12 @@
 		regulator_put(host->vmmc);
 	}
 
+	if (!IS_ERR(host->ciu_clk))
+		clk_disable_unprepare(host->ciu_clk);
+	if (!IS_ERR(host->biu_clk))
+		clk_disable_unprepare(host->biu_clk);
+	clk_put(host->ciu_clk);
+	clk_put(host->biu_clk);
 }
 EXPORT_SYMBOL(dw_mci_remove);
 
@@ -2188,7 +2384,7 @@
 	if (host->vmmc)
 		regulator_enable(host->vmmc);
 
-	if (!mci_wait_reset(&host->dev, host)) {
+	if (!mci_wait_reset(host->dev, host)) {
 		ret = -ENODEV;
 		return ret;
 	}
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index 15c27e1..53b8fd9 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -182,4 +182,28 @@
 extern int dw_mci_resume(struct dw_mci *host);
 #endif
 
+/**
+ * dw_mci driver data - dw-mshc implementation specific driver data.
+ * @caps: mmc subsystem specified capabilities of the controller(s).
+ * @init: early implementation specific initialization.
+ * @setup_clock: implementation specific clock configuration.
+ * @prepare_command: handle CMD register extensions.
+ * @set_ios: handle bus specific extensions.
+ * @parse_dt: parse implementation specific device tree properties.
+ * @setup_bus: initialize io-interface
+ *
+ * Provide controller implementation specific extensions. The usage of this
+ * data structure is fully optional and usage of each member in this structure
+ * is optional as well.
+ */
+struct dw_mci_drv_data {
+	unsigned long	*caps;
+	int		(*init)(struct dw_mci *host);
+	int		(*setup_clock)(struct dw_mci *host);
+	void		(*prepare_command)(struct dw_mci *host, u32 *cmdr);
+	void		(*set_ios)(struct dw_mci *host, struct mmc_ios *ios);
+	int		(*parse_dt)(struct dw_mci *host);
+	int		(*setup_bus)(struct dw_mci *host,
+				struct device_node *slot_np, u8 bus_width);
+};
 #endif /* _DW_MMC_H_ */
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 273306c..a600eab 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -1532,20 +1532,7 @@
 	.remove =	__devexit_p(mmc_spi_remove),
 };
 
-
-static int __init mmc_spi_init(void)
-{
-	return spi_register_driver(&mmc_spi_driver);
-}
-module_init(mmc_spi_init);
-
-
-static void __exit mmc_spi_exit(void)
-{
-	spi_unregister_driver(&mmc_spi_driver);
-}
-module_exit(mmc_spi_exit);
-
+module_spi_driver(mmc_spi_driver);
 
 MODULE_AUTHOR("Mike Lavender, David Brownell, "
 		"Hans-Peter Nilsson, Jan Nikitenko");
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 50ff19a..edc3e9b 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -1309,14 +1309,10 @@
 		goto host_free;
 	}
 
-	ret = clk_prepare(host->clk);
+	ret = clk_prepare_enable(host->clk);
 	if (ret)
 		goto clk_free;
 
-	ret = clk_enable(host->clk);
-	if (ret)
-		goto clk_unprep;
-
 	host->plat = plat;
 	host->variant = variant;
 	host->mclk = clk_get_rate(host->clk);
@@ -1515,9 +1511,7 @@
  err_gpio_cd:
 	iounmap(host->base);
  clk_disable:
-	clk_disable(host->clk);
- clk_unprep:
-	clk_unprepare(host->clk);
+	clk_disable_unprepare(host->clk);
  clk_free:
 	clk_put(host->clk);
  host_free:
@@ -1564,8 +1558,7 @@
 			gpio_free(host->gpio_cd);
 
 		iounmap(host->base);
-		clk_disable(host->clk);
-		clk_unprepare(host->clk);
+		clk_disable_unprepare(host->clk);
 		clk_put(host->clk);
 
 		if (host->vcc)
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index 7b1161d..565c2e4 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -44,6 +44,7 @@
 #include <mach/hardware.h>
 
 #define DRIVER_NAME "mxc-mmc"
+#define MXCMCI_TIMEOUT_MS 10000
 
 #define MMC_REG_STR_STP_CLK		0x00
 #define MMC_REG_STATUS			0x04
@@ -150,6 +151,8 @@
 	int			dmareq;
 	struct dma_slave_config dma_slave_config;
 	struct imx_dma_data	dma_data;
+
+	struct timer_list	watchdog;
 };
 
 static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios);
@@ -271,9 +274,32 @@
 	dmaengine_submit(host->desc);
 	dma_async_issue_pending(host->dma);
 
+	mod_timer(&host->watchdog, jiffies + msecs_to_jiffies(MXCMCI_TIMEOUT_MS));
+
 	return 0;
 }
 
+static void mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat);
+static void mxcmci_data_done(struct mxcmci_host *host, unsigned int stat);
+
+static void mxcmci_dma_callback(void *data)
+{
+	struct mxcmci_host *host = data;
+	u32 stat;
+
+	del_timer(&host->watchdog);
+
+	stat = readl(host->base + MMC_REG_STATUS);
+	writel(stat & ~STATUS_DATA_TRANS_DONE, host->base + MMC_REG_STATUS);
+
+	dev_dbg(mmc_dev(host->mmc), "%s: 0x%08x\n", __func__, stat);
+
+	if (stat & STATUS_READ_OP_DONE)
+		writel(STATUS_READ_OP_DONE, host->base + MMC_REG_STATUS);
+
+	mxcmci_data_done(host, stat);
+}
+
 static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd,
 		unsigned int cmdat)
 {
@@ -305,8 +331,14 @@
 
 	int_cntr = INT_END_CMD_RES_EN;
 
-	if (mxcmci_use_dma(host))
-		int_cntr |= INT_READ_OP_EN | INT_WRITE_OP_DONE_EN;
+	if (mxcmci_use_dma(host)) {
+		if (host->dma_dir == DMA_FROM_DEVICE) {
+			host->desc->callback = mxcmci_dma_callback;
+			host->desc->callback_param = host;
+		} else {
+			int_cntr |= INT_WRITE_OP_DONE_EN;
+		}
+	}
 
 	spin_lock_irqsave(&host->lock, flags);
 	if (host->use_sdio)
@@ -345,11 +377,9 @@
 	struct mmc_data *data = host->data;
 	int data_error;
 
-	if (mxcmci_use_dma(host)) {
-		dmaengine_terminate_all(host->dma);
+	if (mxcmci_use_dma(host))
 		dma_unmap_sg(host->dma->device->dev, data->sg, data->sg_len,
 				host->dma_dir);
-	}
 
 	if (stat & STATUS_ERR_MASK) {
 		dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n",
@@ -624,8 +654,10 @@
 		mxcmci_cmd_done(host, stat);
 
 	if (mxcmci_use_dma(host) &&
-		  (stat & (STATUS_DATA_TRANS_DONE | STATUS_WRITE_OP_DONE)))
+		  (stat & (STATUS_DATA_TRANS_DONE | STATUS_WRITE_OP_DONE))) {
+		del_timer(&host->watchdog);
 		mxcmci_data_done(host, stat);
+	}
 
 	if (host->default_irq_mask &&
 		  (stat & (STATUS_CARD_INSERTION | STATUS_CARD_REMOVAL)))
@@ -836,6 +868,34 @@
 	return true;
 }
 
+static void mxcmci_watchdog(unsigned long data)
+{
+	struct mmc_host *mmc = (struct mmc_host *)data;
+	struct mxcmci_host *host = mmc_priv(mmc);
+	struct mmc_request *req = host->req;
+	unsigned int stat = readl(host->base + MMC_REG_STATUS);
+
+	if (host->dma_dir == DMA_FROM_DEVICE) {
+		dmaengine_terminate_all(host->dma);
+		dev_err(mmc_dev(host->mmc),
+			"%s: read time out (status = 0x%08x)\n",
+			__func__, stat);
+	} else {
+		dev_err(mmc_dev(host->mmc),
+			"%s: write time out (status = 0x%08x)\n",
+			__func__, stat);
+		mxcmci_softreset(host);
+	}
+
+	/* Mark transfer as erroneus and inform the upper layers */
+
+	host->data->error = -ETIMEDOUT;
+	host->req = NULL;
+	host->cmd = NULL;
+	host->data = NULL;
+	mmc_request_done(host->mmc, req);
+}
+
 static const struct mmc_host_ops mxcmci_ops = {
 	.request		= mxcmci_request,
 	.set_ios		= mxcmci_set_ios,
@@ -968,6 +1028,10 @@
 
 	mmc_add_host(mmc);
 
+	init_timer(&host->watchdog);
+	host->watchdog.function = &mxcmci_watchdog;
+	host->watchdog.data = (unsigned long)mmc;
+
 	return 0;
 
 out_free_irq:
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index c6259a8..48ad361 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -27,16 +27,10 @@
 #include <linux/mmc/card.h>
 #include <linux/clk.h>
 #include <linux/scatterlist.h>
-#include <linux/i2c/tps65010.h>
 #include <linux/slab.h>
 
-#include <asm/io.h>
-#include <asm/irq.h>
-
 #include <plat/mmc.h>
-#include <asm/gpio.h>
 #include <plat/dma.h>
-#include <plat/fpga.h>
 
 #define	OMAP_MMC_REG_CMD	0x00
 #define	OMAP_MMC_REG_ARGL	0x01
@@ -105,7 +99,6 @@
 	u16			saved_con;
 	u16			bus_mode;
 	unsigned int		fclk_freq;
-	unsigned		powered:1;
 
 	struct tasklet_struct	cover_tasklet;
 	struct timer_list       cover_timer;
@@ -137,7 +130,6 @@
 	unsigned int		phys_base;
 	int			irq;
 	unsigned char		bus_mode;
-	unsigned char		hw_bus_mode;
 	unsigned int		reg_shift;
 
 	struct work_struct	cmd_abort_work;
@@ -695,22 +687,29 @@
 	host->buffer += nwords;
 }
 
-static inline void mmc_omap_report_irq(u16 status)
+#ifdef CONFIG_MMC_DEBUG
+static void mmc_omap_report_irq(struct mmc_omap_host *host, u16 status)
 {
 	static const char *mmc_omap_status_bits[] = {
 		"EOC", "CD", "CB", "BRS", "EOFB", "DTO", "DCRC", "CTO",
 		"CCRC", "CRW", "AF", "AE", "OCRB", "CIRQ", "CERR"
 	};
-	int i, c = 0;
+	int i;
+	char res[64], *buf = res;
+
+	buf += sprintf(buf, "MMC IRQ 0x%x:", status);
 
 	for (i = 0; i < ARRAY_SIZE(mmc_omap_status_bits); i++)
-		if (status & (1 << i)) {
-			if (c)
-				printk(" ");
-			printk("%s", mmc_omap_status_bits[i]);
-			c++;
-		}
+		if (status & (1 << i))
+			buf += sprintf(buf, " %s", mmc_omap_status_bits[i]);
+	dev_vdbg(mmc_dev(host->mmc), "%s\n", res);
 }
+#else
+static void mmc_omap_report_irq(struct mmc_omap_host *host, u16 status)
+{
+}
+#endif
+
 
 static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
 {
@@ -744,12 +743,10 @@
 			cmd = host->cmd->opcode;
 		else
 			cmd = -1;
-#ifdef CONFIG_MMC_DEBUG
 		dev_dbg(mmc_dev(host->mmc), "MMC IRQ %04x (CMD %d): ",
 			status, cmd);
-		mmc_omap_report_irq(status);
-		printk("\n");
-#endif
+		mmc_omap_report_irq(host, status);
+
 		if (host->total_bytes_left) {
 			if ((status & OMAP_MMC_STAT_A_FULL) ||
 			    (status & OMAP_MMC_STAT_END_OF_DATA))
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 38adc33..54bfd0c 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -35,7 +35,6 @@
 #include <linux/mmc/core.h>
 #include <linux/mmc/mmc.h>
 #include <linux/io.h>
-#include <linux/semaphore.h>
 #include <linux/gpio.h>
 #include <linux/regulator/consumer.h>
 #include <linux/pm_runtime.h>
@@ -44,7 +43,6 @@
 #include <plat/cpu.h>
 
 /* OMAP HSMMC Host Controller Registers */
-#define OMAP_HSMMC_SYSCONFIG	0x0010
 #define OMAP_HSMMC_SYSSTATUS	0x0014
 #define OMAP_HSMMC_CON		0x002C
 #define OMAP_HSMMC_BLK		0x0104
@@ -161,8 +159,6 @@
 	unsigned int		dma_sg_idx;
 	unsigned char		bus_mode;
 	unsigned char		power_mode;
-	u32			*buffer;
-	u32			bytesleft;
 	int			suspended;
 	int			irq;
 	int			use_dma, dma_ch;
@@ -171,7 +167,6 @@
 	int			slot_id;
 	int			response_busy;
 	int			context_loss;
-	int			vdd;
 	int			protect_card;
 	int			reqs_blocked;
 	int			use_reg;
@@ -300,12 +295,12 @@
 	struct regulator *reg;
 	int ocr_value = 0;
 
-	mmc_slot(host).set_power = omap_hsmmc_set_power;
-
 	reg = regulator_get(host->dev, "vmmc");
 	if (IS_ERR(reg)) {
 		dev_dbg(host->dev, "vmmc regulator missing\n");
+		return PTR_ERR(reg);
 	} else {
+		mmc_slot(host).set_power = omap_hsmmc_set_power;
 		host->vcc = reg;
 		ocr_value = mmc_regulator_get_ocrmask(reg);
 		if (!mmc_slot(host).ocr_mask) {
@@ -495,7 +490,7 @@
 	unsigned long regval;
 	unsigned long timeout;
 
-	dev_dbg(mmc_dev(host->mmc), "Set clock to %uHz\n", ios->clock);
+	dev_vdbg(mmc_dev(host->mmc), "Set clock to %uHz\n", ios->clock);
 
 	omap_hsmmc_stop_clock(host);
 
@@ -579,21 +574,8 @@
 	if (host->context_loss == context_loss)
 		return 1;
 
-	/* Wait for hardware reset */
-	timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
-	while ((OMAP_HSMMC_READ(host->base, SYSSTATUS) & RESETDONE) != RESETDONE
-		&& time_before(jiffies, timeout))
-		;
-
-	/* Do software reset */
-	OMAP_HSMMC_WRITE(host->base, SYSCONFIG, SOFTRESET);
-	timeout = jiffies + msecs_to_jiffies(MMC_TIMEOUT_MS);
-	while ((OMAP_HSMMC_READ(host->base, SYSSTATUS) & RESETDONE) != RESETDONE
-		&& time_before(jiffies, timeout))
-		;
-
-	OMAP_HSMMC_WRITE(host->base, SYSCONFIG,
-			OMAP_HSMMC_READ(host->base, SYSCONFIG) | AUTOIDLE);
+	if (!OMAP_HSMMC_READ(host->base, SYSSTATUS) & RESETDONE)
+		return 1;
 
 	if (host->pdata->controller_flags & OMAP_HSMMC_SUPPORTS_DUAL_VOLT) {
 		if (host->power_mode != MMC_POWER_OFF &&
@@ -745,7 +727,7 @@
 {
 	int cmdreg = 0, resptype = 0, cmdtype = 0;
 
-	dev_dbg(mmc_dev(host->mmc), "%s: CMD%d, argument 0x%08x\n",
+	dev_vdbg(mmc_dev(host->mmc), "%s: CMD%d, argument 0x%08x\n",
 		mmc_hostname(host->mmc), cmd->opcode, cmd->arg);
 	host->cmd = cmd;
 
@@ -934,7 +916,7 @@
 			buf += len;
 		}
 
-	dev_dbg(mmc_dev(host->mmc), "%s\n", res);
+	dev_vdbg(mmc_dev(host->mmc), "%s\n", res);
 }
 #else
 static inline void omap_hsmmc_dbg_report_irq(struct omap_hsmmc_host *host,
@@ -981,72 +963,40 @@
 			__func__);
 }
 
+static void hsmmc_command_incomplete(struct omap_hsmmc_host *host, int err)
+{
+	omap_hsmmc_reset_controller_fsm(host, SRC);
+	host->cmd->error = err;
+
+	if (host->data) {
+		omap_hsmmc_reset_controller_fsm(host, SRD);
+		omap_hsmmc_dma_cleanup(host, err);
+	}
+
+}
+
 static void omap_hsmmc_do_irq(struct omap_hsmmc_host *host, int status)
 {
 	struct mmc_data *data;
 	int end_cmd = 0, end_trans = 0;
 
-	if (!host->req_in_progress) {
-		do {
-			OMAP_HSMMC_WRITE(host->base, STAT, status);
-			/* Flush posted write */
-			status = OMAP_HSMMC_READ(host->base, STAT);
-		} while (status & INT_EN_MASK);
-		return;
-	}
-
 	data = host->data;
-	dev_dbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status);
+	dev_vdbg(mmc_dev(host->mmc), "IRQ Status is %x\n", status);
 
 	if (status & ERR) {
 		omap_hsmmc_dbg_report_irq(host, status);
-		if ((status & CMD_TIMEOUT) ||
-			(status & CMD_CRC)) {
-			if (host->cmd) {
-				if (status & CMD_TIMEOUT) {
-					omap_hsmmc_reset_controller_fsm(host,
-									SRC);
-					host->cmd->error = -ETIMEDOUT;
-				} else {
-					host->cmd->error = -EILSEQ;
-				}
-				end_cmd = 1;
-			}
-			if (host->data || host->response_busy) {
-				if (host->data)
-					omap_hsmmc_dma_cleanup(host,
-								-ETIMEDOUT);
-				host->response_busy = 0;
-				omap_hsmmc_reset_controller_fsm(host, SRD);
-			}
-		}
-		if ((status & DATA_TIMEOUT) ||
-			(status & DATA_CRC)) {
-			if (host->data || host->response_busy) {
-				int err = (status & DATA_TIMEOUT) ?
-						-ETIMEDOUT : -EILSEQ;
+		if (status & (CMD_TIMEOUT | DATA_TIMEOUT))
+			hsmmc_command_incomplete(host, -ETIMEDOUT);
+		else if (status & (CMD_CRC | DATA_CRC))
+			hsmmc_command_incomplete(host, -EILSEQ);
 
-				if (host->data)
-					omap_hsmmc_dma_cleanup(host, err);
-				else
-					host->mrq->cmd->error = err;
-				host->response_busy = 0;
-				omap_hsmmc_reset_controller_fsm(host, SRD);
-				end_trans = 1;
-			}
-		}
-		if (status & CARD_ERR) {
-			dev_dbg(mmc_dev(host->mmc),
-				"Ignoring card err CMD%d\n", host->cmd->opcode);
-			if (host->cmd)
-				end_cmd = 1;
-			if (host->data)
-				end_trans = 1;
+		end_cmd = 1;
+		if (host->data || host->response_busy) {
+			end_trans = 1;
+			host->response_busy = 0;
 		}
 	}
 
-	OMAP_HSMMC_WRITE(host->base, STAT, status);
-
 	if (end_cmd || ((status & CC) && host->cmd))
 		omap_hsmmc_cmd_done(host, host->cmd);
 	if ((end_trans || (status & TC)) && host->mrq)
@@ -1062,11 +1012,13 @@
 	int status;
 
 	status = OMAP_HSMMC_READ(host->base, STAT);
-	do {
+	while (status & INT_EN_MASK && host->req_in_progress) {
 		omap_hsmmc_do_irq(host, status);
+
 		/* Flush posted write */
+		OMAP_HSMMC_WRITE(host->base, STAT, status);
 		status = OMAP_HSMMC_READ(host->base, STAT);
-	} while (status & INT_EN_MASK);
+	}
 
 	return IRQ_HANDLED;
 }
@@ -1501,12 +1453,10 @@
 		case MMC_POWER_OFF:
 			mmc_slot(host).set_power(host->dev, host->slot_id,
 						 0, 0);
-			host->vdd = 0;
 			break;
 		case MMC_POWER_UP:
 			mmc_slot(host).set_power(host->dev, host->slot_id,
 						 1, ios->vdd);
-			host->vdd = ios->vdd;
 			break;
 		case MMC_POWER_ON:
 			do_send_init_stream = 1;
@@ -1598,10 +1548,6 @@
 	value = OMAP_HSMMC_READ(host->base, CAPA);
 	OMAP_HSMMC_WRITE(host->base, CAPA, value | capa);
 
-	/* Set the controller to AUTO IDLE mode */
-	value = OMAP_HSMMC_READ(host->base, SYSCONFIG);
-	OMAP_HSMMC_WRITE(host->base, SYSCONFIG, value | AUTOIDLE);
-
 	/* Set SD bus power bit */
 	set_sd_bus_power(host);
 }
@@ -1659,8 +1605,6 @@
 
 	pm_runtime_get_sync(host->dev);
 
-	seq_printf(s, "SYSCONFIG:\t0x%08x\n",
-			OMAP_HSMMC_READ(host->base, SYSCONFIG));
 	seq_printf(s, "CON:\t\t0x%08x\n",
 			OMAP_HSMMC_READ(host->base, CON));
 	seq_printf(s, "HCTL:\t\t0x%08x\n",
@@ -2105,8 +2049,7 @@
 	if (ret) {
 		host->suspended = 0;
 		if (host->pdata->resume) {
-			ret = host->pdata->resume(dev, host->slot_id);
-			if (ret)
+			if (host->pdata->resume(dev, host->slot_id))
 				dev_dbg(dev, "Unmask interrupt failed\n");
 		}
 		goto err;
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index ca3915d..3f9d6d5 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -30,6 +30,9 @@
 #include <linux/regulator/consumer.h>
 #include <linux/gpio.h>
 #include <linux/gfp.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/of_device.h>
 
 #include <asm/sizes.h>
 
@@ -573,6 +576,50 @@
 	return IRQ_HANDLED;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id pxa_mmc_dt_ids[] = {
+        { .compatible = "marvell,pxa-mmc" },
+        { }
+};
+
+MODULE_DEVICE_TABLE(of, pxa_mmc_dt_ids);
+
+static int __devinit pxamci_of_init(struct platform_device *pdev)
+{
+        struct device_node *np = pdev->dev.of_node;
+        struct pxamci_platform_data *pdata;
+        u32 tmp;
+
+        if (!np)
+                return 0;
+
+        pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+        if (!pdata)
+                return -ENOMEM;
+
+	pdata->gpio_card_detect =
+		of_get_named_gpio(np, "cd-gpios", 0);
+	pdata->gpio_card_ro =
+		of_get_named_gpio(np, "wp-gpios", 0);
+
+	/* pxa-mmc specific */
+	pdata->gpio_power =
+		of_get_named_gpio(np, "pxa-mmc,gpio-power", 0);
+
+	if (of_property_read_u32(np, "pxa-mmc,detect-delay-ms", &tmp) == 0)
+		pdata->detect_delay_ms = tmp;
+
+        pdev->dev.platform_data = pdata;
+
+        return 0;
+}
+#else
+static int __devinit pxamci_of_init(struct platform_device *pdev)
+{
+        return 0;
+}
+#endif
+
 static int pxamci_probe(struct platform_device *pdev)
 {
 	struct mmc_host *mmc;
@@ -580,6 +627,10 @@
 	struct resource *r, *dmarx, *dmatx;
 	int ret, irq, gpio_cd = -1, gpio_ro = -1, gpio_power = -1;
 
+	ret = pxamci_of_init(pdev);
+	if (ret)
+		return ret;
+
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	irq = platform_get_irq(pdev, 0);
 	if (!r || irq < 0)
@@ -866,6 +917,7 @@
 	.driver		= {
 		.name	= DRIVER_NAME,
 		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(pxa_mmc_dt_ids),
 #ifdef CONFIG_PM
 		.pm	= &pxamci_pm_ops,
 #endif
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c
index a6e53a1..90140eb 100644
--- a/drivers/mmc/host/sdhci-dove.c
+++ b/drivers/mmc/host/sdhci-dove.c
@@ -24,6 +24,7 @@
 #include <linux/err.h>
 #include <linux/module.h>
 #include <linux/mmc/host.h>
+#include <linux/of.h>
 
 #include "sdhci-pltfm.h"
 
@@ -126,11 +127,18 @@
 	return sdhci_pltfm_unregister(pdev);
 }
 
+static const struct of_device_id sdhci_dove_of_match_table[] __devinitdata = {
+	{ .compatible = "marvell,dove-sdhci", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, sdhci_dove_of_match_table);
+
 static struct platform_driver sdhci_dove_driver = {
 	.driver		= {
 		.name	= "sdhci-dove",
 		.owner	= THIS_MODULE,
 		.pm	= SDHCI_PLTFM_PMOPS,
+		.of_match_table = of_match_ptr(sdhci_dove_of_match_table),
 	},
 	.probe		= sdhci_dove_probe,
 	.remove		= __devexit_p(sdhci_dove_remove),
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index f8eb1fb..ae5fcbf 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -21,6 +21,32 @@
 #include "sdhci-pltfm.h"
 #include "sdhci-esdhc.h"
 
+#define VENDOR_V_22	0x12
+static u32 esdhc_readl(struct sdhci_host *host, int reg)
+{
+	u32 ret;
+
+	ret = in_be32(host->ioaddr + reg);
+	/*
+	 * The bit of ADMA flag in eSDHC is not compatible with standard
+	 * SDHC register, so set fake flag SDHCI_CAN_DO_ADMA2 when ADMA is
+	 * supported by eSDHC.
+	 * And for many FSL eSDHC controller, the reset value of field
+	 * SDHCI_CAN_DO_ADMA1 is one, but some of them can't support ADMA,
+	 * only these vendor version is greater than 2.2/0x12 support ADMA.
+	 * For FSL eSDHC, must aligned 4-byte, so use 0xFC to read the
+	 * the verdor version number, oxFE is SDHCI_HOST_VERSION.
+	 */
+	if ((reg == SDHCI_CAPABILITIES) && (ret & SDHCI_CAN_DO_ADMA1)) {
+		u32 tmp = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS);
+		tmp = (tmp & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT;
+		if (tmp > VENDOR_V_22)
+			ret |= SDHCI_CAN_DO_ADMA2;
+	}
+
+	return ret;
+}
+
 static u16 esdhc_readw(struct sdhci_host *host, int reg)
 {
 	u16 ret;
@@ -144,7 +170,7 @@
 #endif
 
 static struct sdhci_ops sdhci_esdhc_ops = {
-	.read_l = sdhci_be32bs_readl,
+	.read_l = esdhc_readl,
 	.read_w = esdhc_readw,
 	.read_b = esdhc_readb,
 	.write_l = sdhci_be32bs_writel,
@@ -161,9 +187,13 @@
 };
 
 static struct sdhci_pltfm_data sdhci_esdhc_pdata = {
-	/* card detection could be handled via GPIO */
+	/*
+	 * card detection could be handled via GPIO
+	 * eSDHC cannot support End Attribute in NOP ADMA descriptor
+	 */
 	.quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION
-		| SDHCI_QUIRK_NO_CARD_NO_RESET,
+		| SDHCI_QUIRK_NO_CARD_NO_RESET
+		| SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
 	.ops = &sdhci_esdhc_ops,
 };
 
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 9722d43..4bb74b0 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -1476,24 +1476,7 @@
 	},
 };
 
-/*****************************************************************************\
- *                                                                           *
- * Driver init/exit                                                          *
- *                                                                           *
-\*****************************************************************************/
-
-static int __init sdhci_drv_init(void)
-{
-	return pci_register_driver(&sdhci_driver);
-}
-
-static void __exit sdhci_drv_exit(void)
-{
-	pci_unregister_driver(&sdhci_driver);
-}
-
-module_init(sdhci_drv_init);
-module_exit(sdhci_drv_exit);
+module_pci_driver(sdhci_driver);
 
 MODULE_AUTHOR("Pierre Ossman <pierre@ossman.eu>");
 MODULE_DESCRIPTION("Secure Digital Host Controller Interface PCI driver");
diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c
index d9a4ef4..65551a9 100644
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -75,6 +75,9 @@
 		if (sdhci_of_wp_inverted(np))
 			host->quirks |= SDHCI_QUIRK_INVERTED_WRITE_PROTECT;
 
+		if (of_get_property(np, "broken-cd", NULL))
+			host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION;
+
 		if (of_device_is_compatible(np, "fsl,p2020-rev1-esdhc"))
 			host->quirks |= SDHCI_QUIRK_BROKEN_DMA;
 
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index b6ee885..8e63a9c 100644
--- a/drivers/mmc/host/sdhci-pxav2.c
+++ b/drivers/mmc/host/sdhci-pxav2.c
@@ -197,7 +197,7 @@
 		goto err_clk_get;
 	}
 	pltfm_host->clk = clk;
-	clk_enable(clk);
+	clk_prepare_enable(clk);
 
 	host->quirks = SDHCI_QUIRK_BROKEN_ADMA
 		| SDHCI_QUIRK_BROKEN_TIMEOUT_VAL
@@ -239,7 +239,7 @@
 	return 0;
 
 err_add_host:
-	clk_disable(clk);
+	clk_disable_unprepare(clk);
 	clk_put(clk);
 err_clk_get:
 	sdhci_pltfm_free(pdev);
@@ -255,7 +255,7 @@
 
 	sdhci_remove_host(host, 1);
 
-	clk_disable(pltfm_host->clk);
+	clk_disable_unprepare(pltfm_host->clk);
 	clk_put(pltfm_host->clk);
 	sdhci_pltfm_free(pdev);
 	kfree(pxa);
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 07fe383..e918a2b 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -24,12 +24,14 @@
 #include <linux/gpio.h>
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
+#include <linux/mmc/slot-gpio.h>
 #include <linux/platform_data/pxa_sdhci.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/of_gpio.h>
 
 #include "sdhci.h"
 #include "sdhci-pltfm.h"
@@ -182,6 +184,7 @@
 	struct device_node *np = dev->of_node;
 	u32 bus_width;
 	u32 clk_delay_cycles;
+	enum of_gpio_flags gpio_flags;
 
 	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
 	if (!pdata)
@@ -198,6 +201,10 @@
 	if (clk_delay_cycles > 0)
 		pdata->clk_delay_cycles = clk_delay_cycles;
 
+	pdata->ext_cd_gpio = of_get_named_gpio_flags(np, "cd-gpios", 0, &gpio_flags);
+	if (gpio_flags != OF_GPIO_ACTIVE_LOW)
+		pdata->host_caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
+
 	return pdata;
 }
 #else
@@ -231,14 +238,14 @@
 	pltfm_host = sdhci_priv(host);
 	pltfm_host->priv = pxa;
 
-	clk = clk_get(dev, "PXA-SDHCLK");
+	clk = clk_get(dev, NULL);
 	if (IS_ERR(clk)) {
 		dev_err(dev, "failed to get io clock\n");
 		ret = PTR_ERR(clk);
 		goto err_clk_get;
 	}
 	pltfm_host->clk = clk;
-	clk_enable(clk);
+	clk_prepare_enable(clk);
 
 	host->quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL
 		| SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC
@@ -266,12 +273,25 @@
 			host->quirks |= pdata->quirks;
 		if (pdata->host_caps)
 			host->mmc->caps |= pdata->host_caps;
+		if (pdata->host_caps2)
+			host->mmc->caps2 |= pdata->host_caps2;
 		if (pdata->pm_caps)
 			host->mmc->pm_caps |= pdata->pm_caps;
+
+		if (gpio_is_valid(pdata->ext_cd_gpio)) {
+			ret = mmc_gpio_request_cd(host->mmc, pdata->ext_cd_gpio);
+			if (ret) {
+				dev_err(mmc_dev(host->mmc),
+					"failed to allocate card detect gpio\n");
+				goto err_cd_req;
+			}
+		}
 	}
 
 	host->ops = &pxav3_sdhci_ops;
 
+	sdhci_get_of_property(pdev);
+
 	ret = sdhci_add_host(host);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to add host\n");
@@ -283,8 +303,10 @@
 	return 0;
 
 err_add_host:
-	clk_disable(clk);
+	clk_disable_unprepare(clk);
 	clk_put(clk);
+	mmc_gpio_free_cd(host->mmc);
+err_cd_req:
 err_clk_get:
 	sdhci_pltfm_free(pdev);
 	kfree(pxa);
@@ -296,11 +318,16 @@
 	struct sdhci_host *host = platform_get_drvdata(pdev);
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct sdhci_pxa *pxa = pltfm_host->priv;
+	struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data;
 
 	sdhci_remove_host(host, 1);
 
-	clk_disable(pltfm_host->clk);
+	clk_disable_unprepare(pltfm_host->clk);
 	clk_put(pltfm_host->clk);
+
+	if (gpio_is_valid(pdata->ext_cd_gpio))
+		mmc_gpio_free_cd(host->mmc);
+
 	sdhci_pltfm_free(pdev);
 	kfree(pxa);
 
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index a50c205..2903949 100644
--- a/drivers/mmc/host/sdhci-s3c.c
+++ b/drivers/mmc/host/sdhci-s3c.c
@@ -34,6 +34,9 @@
 
 #define MAX_BUS_CLK	(4)
 
+/* Number of gpio's used is max data bus width + command and clock lines */
+#define NUM_GPIOS(x)	(x + 2)
+
 /**
  * struct sdhci_s3c - S3C SDHCI instance
  * @host: The SDHCI host created
@@ -41,6 +44,7 @@
  * @ioarea: The resource created when we claimed the IO area.
  * @pdata: The platform data for this controller.
  * @cur_clk: The index of the current bus clock.
+ * @gpios: List of gpio numbers parsed from device tree.
  * @clk_io: The clock for the internal bus interface.
  * @clk_bus: The clocks that are available for the SD/MMC bus clock.
  */
@@ -52,6 +56,7 @@
 	unsigned int		cur_clk;
 	int			ext_cd_irq;
 	int			ext_cd_gpio;
+	int			*gpios;
 
 	struct clk		*clk_io;
 	struct clk		*clk_bus[MAX_BUS_CLK];
@@ -166,7 +171,7 @@
 	dev_dbg(&ourhost->pdev->dev, "clk %d: rate %ld, want %d, got %ld\n",
 		src, rate, wanted, rate / div);
 
-	return (wanted - (rate / div));
+	return wanted - (rate / div);
 }
 
 /**
@@ -203,10 +208,12 @@
 		 best_src, clock, best);
 
 	/* select the new clock source */
-
 	if (ourhost->cur_clk != best_src) {
 		struct clk *clk = ourhost->clk_bus[best_src];
 
+		clk_enable(clk);
+		clk_disable(ourhost->clk_bus[ourhost->cur_clk]);
+
 		/* turn clock off to card before changing clock source */
 		writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);
 
@@ -288,6 +295,7 @@
 static void sdhci_cmu_set_clock(struct sdhci_host *host, unsigned int clock)
 {
 	struct sdhci_s3c *ourhost = to_s3c(host);
+	struct device *dev = &ourhost->pdev->dev;
 	unsigned long timeout;
 	u16 clk = 0;
 
@@ -309,8 +317,8 @@
 	while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
 		& SDHCI_CLOCK_INT_STABLE)) {
 		if (timeout == 0) {
-			printk(KERN_ERR "%s: Internal clock never "
-				"stabilised.\n", mmc_hostname(host->mmc));
+			dev_err(dev, "%s: Internal clock never stabilised.\n",
+				mmc_hostname(host->mmc));
 			return;
 		}
 		timeout--;
@@ -404,7 +412,9 @@
 		if (sc->ext_cd_irq &&
 		    request_threaded_irq(sc->ext_cd_irq, NULL,
 					 sdhci_s3c_gpio_card_detect_thread,
-					 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+					 IRQF_TRIGGER_RISING |
+					 IRQF_TRIGGER_FALLING |
+					 IRQF_ONESHOT,
 					 dev_name(dev), sc) == 0) {
 			int status = gpio_get_value(sc->ext_cd_gpio);
 			if (pdata->ext_cd_gpio_invert)
@@ -419,9 +429,121 @@
 	}
 }
 
+#ifdef CONFIG_OF
+static int __devinit sdhci_s3c_parse_dt(struct device *dev,
+		struct sdhci_host *host, struct s3c_sdhci_platdata *pdata)
+{
+	struct device_node *node = dev->of_node;
+	struct sdhci_s3c *ourhost = to_s3c(host);
+	u32 max_width;
+	int gpio, cnt, ret;
+
+	/* if the bus-width property is not specified, assume width as 1 */
+	if (of_property_read_u32(node, "bus-width", &max_width))
+		max_width = 1;
+	pdata->max_width = max_width;
+
+	ourhost->gpios = devm_kzalloc(dev, NUM_GPIOS(pdata->max_width) *
+				sizeof(int), GFP_KERNEL);
+	if (!ourhost->gpios)
+		return -ENOMEM;
+
+	/* get the card detection method */
+	if (of_get_property(node, "broken-cd", 0)) {
+		pdata->cd_type = S3C_SDHCI_CD_NONE;
+		goto setup_bus;
+	}
+
+	if (of_get_property(node, "non-removable", 0)) {
+		pdata->cd_type = S3C_SDHCI_CD_PERMANENT;
+		goto setup_bus;
+	}
+
+	gpio = of_get_named_gpio(node, "cd-gpios", 0);
+	if (gpio_is_valid(gpio)) {
+		pdata->cd_type = S3C_SDHCI_CD_GPIO;
+		goto found_cd;
+	} else if (gpio != -ENOENT) {
+		dev_err(dev, "invalid card detect gpio specified\n");
+		return -EINVAL;
+	}
+
+	gpio = of_get_named_gpio(node, "samsung,cd-pinmux-gpio", 0);
+	if (gpio_is_valid(gpio)) {
+		pdata->cd_type = S3C_SDHCI_CD_INTERNAL;
+		goto found_cd;
+	} else if (gpio != -ENOENT) {
+		dev_err(dev, "invalid card detect gpio specified\n");
+		return -EINVAL;
+	}
+
+	dev_info(dev, "assuming no card detect line available\n");
+	pdata->cd_type = S3C_SDHCI_CD_NONE;
+
+ found_cd:
+	if (pdata->cd_type == S3C_SDHCI_CD_GPIO) {
+		pdata->ext_cd_gpio = gpio;
+		ourhost->ext_cd_gpio = -1;
+		if (of_get_property(node, "cd-inverted", NULL))
+			pdata->ext_cd_gpio_invert = 1;
+	} else if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+		ret = gpio_request(gpio, "sdhci-cd");
+		if (ret) {
+			dev_err(dev, "card detect gpio request failed\n");
+			return -EINVAL;
+		}
+		ourhost->ext_cd_gpio = gpio;
+	}
+
+ setup_bus:
+	/* get the gpios for command, clock and data lines */
+	for (cnt = 0; cnt < NUM_GPIOS(pdata->max_width); cnt++) {
+		gpio = of_get_gpio(node, cnt);
+		if (!gpio_is_valid(gpio)) {
+			dev_err(dev, "invalid gpio[%d]\n", cnt);
+			goto err_free_dt_cd_gpio;
+		}
+		ourhost->gpios[cnt] = gpio;
+	}
+
+	for (cnt = 0; cnt < NUM_GPIOS(pdata->max_width); cnt++) {
+		ret = gpio_request(ourhost->gpios[cnt], "sdhci-gpio");
+		if (ret) {
+			dev_err(dev, "gpio[%d] request failed\n", cnt);
+			goto err_free_dt_gpios;
+		}
+	}
+
+	return 0;
+
+ err_free_dt_gpios:
+	while (--cnt >= 0)
+		gpio_free(ourhost->gpios[cnt]);
+ err_free_dt_cd_gpio:
+	if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL)
+		gpio_free(ourhost->ext_cd_gpio);
+	return -EINVAL;
+}
+#else
+static int __devinit sdhci_s3c_parse_dt(struct device *dev,
+		struct sdhci_host *host, struct s3c_sdhci_platdata *pdata)
+{
+	return -EINVAL;
+}
+#endif
+
+static const struct of_device_id sdhci_s3c_dt_match[];
+
 static inline struct sdhci_s3c_drv_data *sdhci_s3c_get_driver_data(
 			struct platform_device *pdev)
 {
+#ifdef CONFIG_OF
+	if (pdev->dev.of_node) {
+		const struct of_device_id *match;
+		match = of_match_node(sdhci_s3c_dt_match, pdev->dev.of_node);
+		return (struct sdhci_s3c_drv_data *)match->data;
+	}
+#endif
 	return (struct sdhci_s3c_drv_data *)
 			platform_get_device_id(pdev)->driver_data;
 }
@@ -436,7 +558,7 @@
 	struct resource *res;
 	int ret, irq, ptr, clks;
 
-	if (!pdev->dev.platform_data) {
+	if (!pdev->dev.platform_data && !pdev->dev.of_node) {
 		dev_err(dev, "no device data specified\n");
 		return -ENOENT;
 	}
@@ -452,21 +574,28 @@
 		dev_err(dev, "sdhci_alloc_host() failed\n");
 		return PTR_ERR(host);
 	}
+	sc = sdhci_priv(host);
 
 	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
 	if (!pdata) {
 		ret = -ENOMEM;
-		goto err_io_clk;
+		goto err_pdata;
 	}
-	memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata));
+
+	if (pdev->dev.of_node) {
+		ret = sdhci_s3c_parse_dt(&pdev->dev, host, pdata);
+		if (ret)
+			goto err_pdata;
+	} else {
+		memcpy(pdata, pdev->dev.platform_data, sizeof(*pdata));
+		sc->ext_cd_gpio = -1; /* invalid gpio number */
+	}
 
 	drv_data = sdhci_s3c_get_driver_data(pdev);
-	sc = sdhci_priv(host);
 
 	sc->host = host;
 	sc->pdev = pdev;
 	sc->pdata = pdata;
-	sc->ext_cd_gpio = -1; /* invalid gpio number */
 
 	platform_set_drvdata(pdev, host);
 
@@ -486,9 +615,8 @@
 
 		snprintf(name, 14, "mmc_busclk.%d", ptr);
 		clk = clk_get(dev, name);
-		if (IS_ERR(clk)) {
+		if (IS_ERR(clk))
 			continue;
-		}
 
 		clks++;
 		sc->clk_bus[ptr] = clk;
@@ -499,8 +627,6 @@
 		 */
 		sc->cur_clk = ptr;
 
-		clk_enable(clk);
-
 		dev_info(dev, "clock source %d: %s (%ld Hz)\n",
 			 ptr, name, clk_get_rate(clk));
 	}
@@ -511,6 +637,10 @@
 		goto err_no_busclks;
 	}
 
+#ifndef CONFIG_PM_RUNTIME
+	clk_enable(sc->clk_bus[sc->cur_clk]);
+#endif
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	host->ioaddr = devm_request_and_ioremap(&pdev->dev, res);
 	if (!host->ioaddr) {
@@ -616,12 +746,17 @@
 	    gpio_is_valid(pdata->ext_cd_gpio))
 		sdhci_s3c_setup_card_detect_gpio(sc);
 
+#ifdef CONFIG_PM_RUNTIME
+	clk_disable(sc->clk_io);
+#endif
 	return 0;
 
  err_req_regs:
+#ifndef CONFIG_PM_RUNTIME
+	clk_disable(sc->clk_bus[sc->cur_clk]);
+#endif
 	for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
 		if (sc->clk_bus[ptr]) {
-			clk_disable(sc->clk_bus[ptr]);
 			clk_put(sc->clk_bus[ptr]);
 		}
 	}
@@ -631,6 +766,12 @@
 	clk_put(sc->clk_io);
 
  err_io_clk:
+	for (ptr = 0; ptr < NUM_GPIOS(sc->pdata->max_width); ptr++)
+		gpio_free(sc->gpios[ptr]);
+	if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL)
+		gpio_free(sc->ext_cd_gpio);
+
+ err_pdata:
 	sdhci_free_host(host);
 
 	return ret;
@@ -638,9 +779,9 @@
 
 static int __devexit sdhci_s3c_remove(struct platform_device *pdev)
 {
-	struct s3c_sdhci_platdata *pdata = pdev->dev.platform_data;
 	struct sdhci_host *host =  platform_get_drvdata(pdev);
 	struct sdhci_s3c *sc = sdhci_priv(host);
+	struct s3c_sdhci_platdata *pdata = sc->pdata;
 	int ptr;
 
 	if (pdata->cd_type == S3C_SDHCI_CD_EXTERNAL && pdata->ext_cd_cleanup)
@@ -652,19 +793,30 @@
 	if (gpio_is_valid(sc->ext_cd_gpio))
 		gpio_free(sc->ext_cd_gpio);
 
+#ifdef CONFIG_PM_RUNTIME
+	clk_enable(sc->clk_io);
+#endif
 	sdhci_remove_host(host, 1);
 
+	pm_runtime_dont_use_autosuspend(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
-	for (ptr = 0; ptr < 3; ptr++) {
+#ifndef CONFIG_PM_RUNTIME
+	clk_disable(sc->clk_bus[sc->cur_clk]);
+#endif
+	for (ptr = 0; ptr < MAX_BUS_CLK; ptr++) {
 		if (sc->clk_bus[ptr]) {
-			clk_disable(sc->clk_bus[ptr]);
 			clk_put(sc->clk_bus[ptr]);
 		}
 	}
 	clk_disable(sc->clk_io);
 	clk_put(sc->clk_io);
 
+	if (pdev->dev.of_node) {
+		for (ptr = 0; ptr < NUM_GPIOS(sc->pdata->max_width); ptr++)
+			gpio_free(sc->gpios[ptr]);
+	}
+
 	sdhci_free_host(host);
 	platform_set_drvdata(pdev, NULL);
 
@@ -691,15 +843,28 @@
 static int sdhci_s3c_runtime_suspend(struct device *dev)
 {
 	struct sdhci_host *host = dev_get_drvdata(dev);
+	struct sdhci_s3c *ourhost = to_s3c(host);
+	struct clk *busclk = ourhost->clk_io;
+	int ret;
 
-	return sdhci_runtime_suspend_host(host);
+	ret = sdhci_runtime_suspend_host(host);
+
+	clk_disable(ourhost->clk_bus[ourhost->cur_clk]);
+	clk_disable(busclk);
+	return ret;
 }
 
 static int sdhci_s3c_runtime_resume(struct device *dev)
 {
 	struct sdhci_host *host = dev_get_drvdata(dev);
+	struct sdhci_s3c *ourhost = to_s3c(host);
+	struct clk *busclk = ourhost->clk_io;
+	int ret;
 
-	return sdhci_runtime_resume_host(host);
+	clk_enable(busclk);
+	clk_enable(ourhost->clk_bus[ourhost->cur_clk]);
+	ret = sdhci_runtime_resume_host(host);
+	return ret;
 }
 #endif
 
@@ -737,6 +902,16 @@
 };
 MODULE_DEVICE_TABLE(platform, sdhci_s3c_driver_ids);
 
+#ifdef CONFIG_OF
+static const struct of_device_id sdhci_s3c_dt_match[] = {
+	{ .compatible = "samsung,s3c6410-sdhci", },
+	{ .compatible = "samsung,exynos4210-sdhci",
+		.data = (void *)EXYNOS4_SDHCI_DRV_DATA },
+	{},
+};
+MODULE_DEVICE_TABLE(of, sdhci_s3c_dt_match);
+#endif
+
 static struct platform_driver sdhci_s3c_driver = {
 	.probe		= sdhci_s3c_probe,
 	.remove		= __devexit_p(sdhci_s3c_remove),
@@ -744,6 +919,7 @@
 	.driver		= {
 		.owner	= THIS_MODULE,
 		.name	= "s3c-sdhci",
+		.of_match_table = of_match_ptr(sdhci_s3c_dt_match),
 		.pm	= SDHCI_S3C_PMOPS,
 	},
 };
diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index 423da81..6be89c0 100644
--- a/drivers/mmc/host/sdhci-spear.c
+++ b/drivers/mmc/host/sdhci-spear.c
@@ -20,6 +20,8 @@
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
 #include <linux/slab.h>
@@ -68,8 +70,42 @@
 	return IRQ_HANDLED;
 }
 
+#ifdef CONFIG_OF
+static struct sdhci_plat_data * __devinit
+sdhci_probe_config_dt(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct sdhci_plat_data *pdata = NULL;
+	int cd_gpio;
+
+	cd_gpio = of_get_named_gpio(np, "cd-gpios", 0);
+	if (!gpio_is_valid(cd_gpio))
+		cd_gpio = -1;
+
+	/* If pdata is required */
+	if (cd_gpio != -1) {
+		pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+		if (!pdata) {
+			dev_err(&pdev->dev, "DT: kzalloc failed\n");
+			return ERR_PTR(-ENOMEM);
+		}
+	}
+
+	pdata->card_int_gpio = cd_gpio;
+
+	return pdata;
+}
+#else
+static struct sdhci_plat_data * __devinit
+sdhci_probe_config_dt(struct platform_device *pdev)
+{
+	return ERR_PTR(-ENOSYS);
+}
+#endif
+
 static int __devinit sdhci_probe(struct platform_device *pdev)
 {
+	struct device_node *np = pdev->dev.of_node;
 	struct sdhci_host *host;
 	struct resource *iomem;
 	struct spear_sdhci *sdhci;
@@ -104,14 +140,22 @@
 		goto err;
 	}
 
-	ret = clk_enable(sdhci->clk);
+	ret = clk_prepare_enable(sdhci->clk);
 	if (ret) {
 		dev_dbg(&pdev->dev, "Error enabling clock\n");
 		goto put_clk;
 	}
 
-	/* overwrite platform_data */
-	sdhci->data = dev_get_platdata(&pdev->dev);
+	if (np) {
+		sdhci->data = sdhci_probe_config_dt(pdev);
+		if (IS_ERR(sdhci->data)) {
+			dev_err(&pdev->dev, "DT: Failed to get pdata\n");
+			return -ENODEV;
+		}
+	} else {
+		sdhci->data = dev_get_platdata(&pdev->dev);
+	}
+
 	pdev->dev.platform_data = sdhci;
 
 	if (pdev->dev.parent)
@@ -216,7 +260,7 @@
 free_host:
 	sdhci_free_host(host);
 disable_clk:
-	clk_disable(sdhci->clk);
+	clk_disable_unprepare(sdhci->clk);
 put_clk:
 	clk_put(sdhci->clk);
 err:
@@ -238,7 +282,7 @@
 
 	sdhci_remove_host(host, dead);
 	sdhci_free_host(host);
-	clk_disable(sdhci->clk);
+	clk_disable_unprepare(sdhci->clk);
 	clk_put(sdhci->clk);
 
 	return 0;
@@ -253,7 +297,7 @@
 
 	ret = sdhci_suspend_host(host);
 	if (!ret)
-		clk_disable(sdhci->clk);
+		clk_disable_unprepare(sdhci->clk);
 
 	return ret;
 }
@@ -264,7 +308,7 @@
 	struct spear_sdhci *sdhci = dev_get_platdata(dev);
 	int ret;
 
-	ret = clk_enable(sdhci->clk);
+	ret = clk_prepare_enable(sdhci->clk);
 	if (ret) {
 		dev_dbg(dev, "Resume: Error enabling clock\n");
 		return ret;
@@ -276,11 +320,20 @@
 
 static SIMPLE_DEV_PM_OPS(sdhci_pm_ops, sdhci_suspend, sdhci_resume);
 
+#ifdef CONFIG_OF
+static const struct of_device_id sdhci_spear_id_table[] = {
+	{ .compatible = "st,spear300-sdhci" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, sdhci_spear_id_table);
+#endif
+
 static struct platform_driver sdhci_driver = {
 	.driver = {
 		.name	= "sdhci",
 		.owner	= THIS_MODULE,
 		.pm	= &sdhci_pm_ops,
+		.of_match_table = of_match_ptr(sdhci_spear_id_table),
 	},
 	.probe		= sdhci_probe,
 	.remove		= __devexit_p(sdhci_remove),
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index aa8c4de..f9eb916 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -256,10 +256,9 @@
 	int rc;
 
 	match = of_match_device(sdhci_tegra_dt_match, &pdev->dev);
-	if (match)
-		soc_data = match->data;
-	else
-		soc_data = &soc_data_tegra20;
+	if (!match)
+		return -EINVAL;
+	soc_data = match->data;
 
 	host = sdhci_pltfm_init(pdev, soc_data->pdata);
 	if (IS_ERR(host))
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 9a11dc3..7922adb 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -28,6 +28,7 @@
 #include <linux/mmc/mmc.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
+#include <linux/mmc/slot-gpio.h>
 
 #include "sdhci.h"
 
@@ -1293,6 +1294,13 @@
 		present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
 				SDHCI_CARD_PRESENT;
 
+	/* If we're using a cd-gpio, testing the presence bit might fail. */
+	if (!present) {
+		int ret = mmc_gpio_get_cd(host->mmc);
+		if (ret > 0)
+			present = true;
+	}
+
 	if (!present || host->flags & SDHCI_DEVICE_DEAD) {
 		host->mrq->cmd->error = -ENOMEDIUM;
 		tasklet_schedule(&host->finish_tasklet);
@@ -1597,57 +1605,65 @@
 	spin_unlock_irqrestore(&host->lock, flags);
 }
 
-static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
-						struct mmc_ios *ios)
+static int sdhci_do_3_3v_signal_voltage_switch(struct sdhci_host *host,
+						u16 ctrl)
 {
-	u8 pwr;
-	u16 clk, ctrl;
-	u32 present_state;
+	int ret;
 
-	/*
-	 * Signal Voltage Switching is only applicable for Host Controllers
-	 * v3.00 and above.
-	 */
-	if (host->version < SDHCI_SPEC_300)
-		return 0;
+	/* Set 1.8V Signal Enable in the Host Control2 register to 0 */
+	ctrl &= ~SDHCI_CTRL_VDD_180;
+	sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
 
-	/*
-	 * We first check whether the request is to set signalling voltage
-	 * to 3.3V. If so, we change the voltage to 3.3V and return quickly.
-	 */
-	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
-	if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
-		/* Set 1.8V Signal Enable in the Host Control2 register to 0 */
-		ctrl &= ~SDHCI_CTRL_VDD_180;
-		sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
-
-		/* Wait for 5ms */
-		usleep_range(5000, 5500);
-
-		/* 3.3V regulator output should be stable within 5 ms */
-		ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
-		if (!(ctrl & SDHCI_CTRL_VDD_180))
-			return 0;
-		else {
-			pr_info(DRIVER_NAME ": Switching to 3.3V "
-				"signalling voltage failed\n");
+	if (host->vqmmc) {
+		ret = regulator_set_voltage(host->vqmmc, 3300000, 3300000);
+		if (ret) {
+			pr_warning("%s: Switching to 3.3V signalling voltage "
+				   " failed\n", mmc_hostname(host->mmc));
 			return -EIO;
 		}
-	} else if (!(ctrl & SDHCI_CTRL_VDD_180) &&
-		  (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180)) {
-		/* Stop SDCLK */
-		clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
-		clk &= ~SDHCI_CLOCK_CARD_EN;
-		sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+	}
+	/* Wait for 5ms */
+	usleep_range(5000, 5500);
 
-		/* Check whether DAT[3:0] is 0000 */
-		present_state = sdhci_readl(host, SDHCI_PRESENT_STATE);
-		if (!((present_state & SDHCI_DATA_LVL_MASK) >>
-		       SDHCI_DATA_LVL_SHIFT)) {
-			/*
-			 * Enable 1.8V Signal Enable in the Host Control2
-			 * register
-			 */
+	/* 3.3V regulator output should be stable within 5 ms */
+	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+	if (!(ctrl & SDHCI_CTRL_VDD_180))
+		return 0;
+
+	pr_warning("%s: 3.3V regulator output did not became stable\n",
+		   mmc_hostname(host->mmc));
+
+	return -EIO;
+}
+
+static int sdhci_do_1_8v_signal_voltage_switch(struct sdhci_host *host,
+						u16 ctrl)
+{
+	u8 pwr;
+	u16 clk;
+	u32 present_state;
+	int ret;
+
+	/* Stop SDCLK */
+	clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
+	clk &= ~SDHCI_CLOCK_CARD_EN;
+	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+
+	/* Check whether DAT[3:0] is 0000 */
+	present_state = sdhci_readl(host, SDHCI_PRESENT_STATE);
+	if (!((present_state & SDHCI_DATA_LVL_MASK) >>
+	       SDHCI_DATA_LVL_SHIFT)) {
+		/*
+		 * Enable 1.8V Signal Enable in the Host Control2
+		 * register
+		 */
+		if (host->vqmmc)
+			ret = regulator_set_voltage(host->vqmmc,
+				1800000, 1800000);
+		else
+			ret = 0;
+
+		if (!ret) {
 			ctrl |= SDHCI_CTRL_VDD_180;
 			sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
 
@@ -1656,7 +1672,7 @@
 
 			ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
 			if (ctrl & SDHCI_CTRL_VDD_180) {
-				/* Provide SDCLK again and wait for 1ms*/
+				/* Provide SDCLK again and wait for 1ms */
 				clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
 				clk |= SDHCI_CLOCK_CARD_EN;
 				sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
@@ -1673,29 +1689,55 @@
 					return 0;
 			}
 		}
+	}
 
-		/*
-		 * If we are here, that means the switch to 1.8V signaling
-		 * failed. We power cycle the card, and retry initialization
-		 * sequence by setting S18R to 0.
-		 */
-		pwr = sdhci_readb(host, SDHCI_POWER_CONTROL);
-		pwr &= ~SDHCI_POWER_ON;
-		sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
-		if (host->vmmc)
-			regulator_disable(host->vmmc);
+	/*
+	 * If we are here, that means the switch to 1.8V signaling
+	 * failed. We power cycle the card, and retry initialization
+	 * sequence by setting S18R to 0.
+	 */
+	pwr = sdhci_readb(host, SDHCI_POWER_CONTROL);
+	pwr &= ~SDHCI_POWER_ON;
+	sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
+	if (host->vmmc)
+		regulator_disable(host->vmmc);
 
-		/* Wait for 1ms as per the spec */
-		usleep_range(1000, 1500);
-		pwr |= SDHCI_POWER_ON;
-		sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
-		if (host->vmmc)
-			regulator_enable(host->vmmc);
+	/* Wait for 1ms as per the spec */
+	usleep_range(1000, 1500);
+	pwr |= SDHCI_POWER_ON;
+	sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
+	if (host->vmmc)
+		regulator_enable(host->vmmc);
 
-		pr_info(DRIVER_NAME ": Switching to 1.8V signalling "
-			"voltage failed, retrying with S18R set to 0\n");
-		return -EAGAIN;
-	} else
+	pr_warning("%s: Switching to 1.8V signalling voltage failed, "
+		   "retrying with S18R set to 0\n", mmc_hostname(host->mmc));
+
+	return -EAGAIN;
+}
+
+static int sdhci_do_start_signal_voltage_switch(struct sdhci_host *host,
+						struct mmc_ios *ios)
+{
+	u16 ctrl;
+
+	/*
+	 * Signal Voltage Switching is only applicable for Host Controllers
+	 * v3.00 and above.
+	 */
+	if (host->version < SDHCI_SPEC_300)
+		return 0;
+
+	/*
+	 * We first check whether the request is to set signalling voltage
+	 * to 3.3V. If so, we change the voltage to 3.3V and return quickly.
+	 */
+	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+	if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330)
+		return sdhci_do_3_3v_signal_voltage_switch(host, ctrl);
+	else if (!(ctrl & SDHCI_CTRL_VDD_180) &&
+			(ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180))
+		return sdhci_do_1_8v_signal_voltage_switch(host, ctrl);
+	else
 		/* No signal voltage switch required */
 		return 0;
 }
@@ -2802,6 +2844,18 @@
 	    !(host->mmc->caps & MMC_CAP_NONREMOVABLE))
 		mmc->caps |= MMC_CAP_NEEDS_POLL;
 
+	/* If vqmmc regulator and no 1.8V signalling, then there's no UHS */
+	host->vqmmc = regulator_get(mmc_dev(mmc), "vqmmc");
+	if (IS_ERR(host->vqmmc)) {
+		pr_info("%s: no vqmmc regulator found\n", mmc_hostname(mmc));
+		host->vqmmc = NULL;
+	}
+	else if (regulator_is_supported_voltage(host->vqmmc, 1800000, 1800000))
+		regulator_enable(host->vqmmc);
+	else
+		caps[1] &= ~(SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 |
+		       SDHCI_SUPPORT_DDR50);
+
 	/* Any UHS-I mode in caps implies SDR12 and SDR25 support. */
 	if (caps[1] & (SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 |
 		       SDHCI_SUPPORT_DDR50))
@@ -2832,15 +2886,6 @@
 	if (caps[1] & SDHCI_DRIVER_TYPE_D)
 		mmc->caps |= MMC_CAP_DRIVER_TYPE_D;
 
-	/*
-	 * If Power Off Notify capability is enabled by the host,
-	 * set notify to short power off notify timeout value.
-	 */
-	if (mmc->caps2 & MMC_CAP2_POWEROFF_NOTIFY)
-		mmc->power_notify_type = MMC_HOST_PW_NOTIFY_SHORT;
-	else
-		mmc->power_notify_type = MMC_HOST_PW_NOTIFY_NONE;
-
 	/* Initial value for re-tuning timer count */
 	host->tuning_count = (caps[1] & SDHCI_RETUNING_TIMER_COUNT_MASK) >>
 			      SDHCI_RETUNING_TIMER_COUNT_SHIFT;
@@ -2862,7 +2907,8 @@
 	if (IS_ERR(host->vmmc)) {
 		pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc));
 		host->vmmc = NULL;
-	}
+	} else
+		regulator_enable(host->vmmc);
 
 #ifdef CONFIG_REGULATOR
 	if (host->vmmc) {
@@ -3119,8 +3165,15 @@
 	tasklet_kill(&host->card_tasklet);
 	tasklet_kill(&host->finish_tasklet);
 
-	if (host->vmmc)
+	if (host->vmmc) {
+		regulator_disable(host->vmmc);
 		regulator_put(host->vmmc);
+	}
+
+	if (host->vqmmc) {
+		regulator_disable(host->vqmmc);
+		regulator_put(host->vqmmc);
+	}
 
 	kfree(host->adma_desc);
 	kfree(host->align_buffer);
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index 5d81427..11d2bc3 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -1213,7 +1213,9 @@
 		sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_BUFRE);
 		sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MBUFRE);
 	} else if (state & INT_DTRANE) {
-		sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~INT_DTRANE);
+		sh_mmcif_writel(host->addr, MMCIF_CE_INT,
+			~(INT_CMD12DRE | INT_CMD12RBE |
+			  INT_CMD12CRE | INT_DTRANE));
 		sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MDTRANE);
 	} else if (state & INT_CMD12RBE) {
 		sh_mmcif_writel(host->addr, MMCIF_CE_INT,
@@ -1229,6 +1231,10 @@
 		host->sd_error = true;
 		dev_dbg(&host->pd->dev, "int err state = %08x\n", state);
 	}
+	if (host->state == STATE_IDLE) {
+		dev_info(&host->pd->dev, "Spurious IRQ status 0x%x", state);
+		return IRQ_HANDLED;
+	}
 	if (state & ~(INT_CMD12RBE | INT_CMD12CRE)) {
 		if (!host->dma_active)
 			return IRQ_WAKE_THREAD;
diff --git a/drivers/mmc/host/via-sdmmc.c b/drivers/mmc/host/via-sdmmc.c
index 4b83c43..f18bece 100644
--- a/drivers/mmc/host/via-sdmmc.c
+++ b/drivers/mmc/host/via-sdmmc.c
@@ -1337,21 +1337,7 @@
 	.resume = via_sd_resume,
 };
 
-static int __init via_sd_drv_init(void)
-{
-	pr_info(DRV_NAME ": VIA SD/MMC Card Reader driver "
-		"(C) 2008 VIA Technologies, Inc.\n");
-
-	return pci_register_driver(&via_sd_driver);
-}
-
-static void __exit via_sd_drv_exit(void)
-{
-	pci_unregister_driver(&via_sd_driver);
-}
-
-module_init(via_sd_drv_init);
-module_exit(via_sd_drv_exit);
+module_pci_driver(via_sd_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("VIA Technologies Inc.");
diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c
index 58eab9a..d5655a6 100644
--- a/drivers/mmc/host/vub300.c
+++ b/drivers/mmc/host/vub300.c
@@ -2358,9 +2358,9 @@
 	 * which is contained at the end of struct mmc
 	 */
 error4:
-	usb_free_urb(command_out_urb);
-error1:
 	usb_free_urb(command_res_urb);
+error1:
+	usb_free_urb(command_out_urb);
 error0:
 	return retval;
 }
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 27143e0..73fcbbe 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -148,6 +148,13 @@
 	  This provides partions parsing for BCM63xx devices with CFE
 	  bootloaders.
 
+config MTD_BCM47XX_PARTS
+	tristate "BCM47XX partitioning support"
+	depends on BCM47XX
+	help
+	  This provides partitions parser for devices based on BCM47xx
+	  boards.
+
 comment "User Modules And Translation Layers"
 
 config MTD_CHAR
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index f901354..18a38e5 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -12,6 +12,7 @@
 obj-$(CONFIG_MTD_AFS_PARTS)	+= afs.o
 obj-$(CONFIG_MTD_AR7_PARTS)	+= ar7part.o
 obj-$(CONFIG_MTD_BCM63XX_PARTS)	+= bcm63xxpart.o
+obj-$(CONFIG_MTD_BCM47XX_PARTS)	+= bcm47xxpart.o
 
 # 'Users' - code which presents functionality to userspace.
 obj-$(CONFIG_MTD_CHAR)		+= mtdchar.o
diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c
new file mode 100644
index 0000000..e06d782
--- /dev/null
+++ b/drivers/mtd/bcm47xxpart.c
@@ -0,0 +1,202 @@
+/*
+ * BCM47XX MTD partitioning
+ *
+ * Copyright © 2012 RafaÅ‚ MiÅ‚ecki <zajec5@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <asm/mach-bcm47xx/nvram.h>
+
+/* 10 parts were found on sflash on Netgear WNDR4500 */
+#define BCM47XXPART_MAX_PARTS		12
+
+/*
+ * Amount of bytes we read when analyzing each block of flash memory.
+ * Set it big enough to allow detecting partition and reading important data.
+ */
+#define BCM47XXPART_BYTES_TO_READ	0x404
+
+/* Magics */
+#define BOARD_DATA_MAGIC		0x5246504D	/* MPFR */
+#define POT_MAGIC1			0x54544f50	/* POTT */
+#define POT_MAGIC2			0x504f		/* OP */
+#define ML_MAGIC1			0x39685a42
+#define ML_MAGIC2			0x26594131
+#define TRX_MAGIC			0x30524448
+
+struct trx_header {
+	uint32_t magic;
+	uint32_t length;
+	uint32_t crc32;
+	uint16_t flags;
+	uint16_t version;
+	uint32_t offset[3];
+} __packed;
+
+static void bcm47xxpart_add_part(struct mtd_partition *part, char *name,
+				 u64 offset, uint32_t mask_flags)
+{
+	part->name = name;
+	part->offset = offset;
+	part->mask_flags = mask_flags;
+}
+
+static int bcm47xxpart_parse(struct mtd_info *master,
+			     struct mtd_partition **pparts,
+			     struct mtd_part_parser_data *data)
+{
+	struct mtd_partition *parts;
+	uint8_t i, curr_part = 0;
+	uint32_t *buf;
+	size_t bytes_read;
+	uint32_t offset;
+	uint32_t blocksize = 0x10000;
+	struct trx_header *trx;
+
+	/* Alloc */
+	parts = kzalloc(sizeof(struct mtd_partition) * BCM47XXPART_MAX_PARTS,
+			GFP_KERNEL);
+	buf = kzalloc(BCM47XXPART_BYTES_TO_READ, GFP_KERNEL);
+
+	/* Parse block by block looking for magics */
+	for (offset = 0; offset <= master->size - blocksize;
+	     offset += blocksize) {
+		/* Nothing more in higher memory */
+		if (offset >= 0x2000000)
+			break;
+
+		if (curr_part > BCM47XXPART_MAX_PARTS) {
+			pr_warn("Reached maximum number of partitions, scanning stopped!\n");
+			break;
+		}
+
+		/* Read beginning of the block */
+		if (mtd_read(master, offset, BCM47XXPART_BYTES_TO_READ,
+			     &bytes_read, (uint8_t *)buf) < 0) {
+			pr_err("mtd_read error while parsing (offset: 0x%X)!\n",
+			       offset);
+			continue;
+		}
+
+		/* CFE has small NVRAM at 0x400 */
+		if (buf[0x400 / 4] == NVRAM_HEADER) {
+			bcm47xxpart_add_part(&parts[curr_part++], "boot",
+					     offset, MTD_WRITEABLE);
+			continue;
+		}
+
+		/* Standard NVRAM */
+		if (buf[0x000 / 4] == NVRAM_HEADER) {
+			bcm47xxpart_add_part(&parts[curr_part++], "nvram",
+					     offset, 0);
+			continue;
+		}
+
+		/*
+		 * board_data starts with board_id which differs across boards,
+		 * but we can use 'MPFR' (hopefully) magic at 0x100
+		 */
+		if (buf[0x100 / 4] == BOARD_DATA_MAGIC) {
+			bcm47xxpart_add_part(&parts[curr_part++], "board_data",
+					     offset, MTD_WRITEABLE);
+			continue;
+		}
+
+		/* POT(TOP) */
+		if (buf[0x000 / 4] == POT_MAGIC1 &&
+		    (buf[0x004 / 4] & 0xFFFF) == POT_MAGIC2) {
+			bcm47xxpart_add_part(&parts[curr_part++], "POT", offset,
+					     MTD_WRITEABLE);
+			continue;
+		}
+
+		/* ML */
+		if (buf[0x010 / 4] == ML_MAGIC1 &&
+		    buf[0x014 / 4] == ML_MAGIC2) {
+			bcm47xxpart_add_part(&parts[curr_part++], "ML", offset,
+					     MTD_WRITEABLE);
+			continue;
+		}
+
+		/* TRX */
+		if (buf[0x000 / 4] == TRX_MAGIC) {
+			trx = (struct trx_header *)buf;
+
+			i = 0;
+			/* We have LZMA loader if offset[2] points to sth */
+			if (trx->offset[2]) {
+				bcm47xxpart_add_part(&parts[curr_part++],
+						     "loader",
+						     offset + trx->offset[i],
+						     0);
+				i++;
+			}
+
+			bcm47xxpart_add_part(&parts[curr_part++], "linux",
+					     offset + trx->offset[i], 0);
+			i++;
+
+			/*
+			 * Pure rootfs size is known and can be calculated as:
+			 * trx->length - trx->offset[i]. We don't fill it as
+			 * we want to have jffs2 (overlay) in the same mtd.
+			 */
+			bcm47xxpart_add_part(&parts[curr_part++], "rootfs",
+					     offset + trx->offset[i], 0);
+			i++;
+
+			/*
+			 * We have whole TRX scanned, skip to the next part. Use
+			 * roundown (not roundup), as the loop will increase
+			 * offset in next step.
+			 */
+			offset = rounddown(offset + trx->length, blocksize);
+			continue;
+		}
+	}
+	kfree(buf);
+
+	/*
+	 * Assume that partitions end at the beginning of the one they are
+	 * followed by.
+	 */
+	for (i = 0; i < curr_part - 1; i++)
+		parts[i].size = parts[i + 1].offset - parts[i].offset;
+	if (curr_part > 0)
+		parts[curr_part - 1].size =
+				master->size - parts[curr_part - 1].offset;
+
+	*pparts = parts;
+	return curr_part;
+};
+
+static struct mtd_part_parser bcm47xxpart_mtd_parser = {
+	.owner = THIS_MODULE,
+	.parse_fn = bcm47xxpart_parse,
+	.name = "bcm47xxpart",
+};
+
+static int __init bcm47xxpart_init(void)
+{
+	return register_mtd_parser(&bcm47xxpart_mtd_parser);
+}
+
+static void __exit bcm47xxpart_exit(void)
+{
+	deregister_mtd_parser(&bcm47xxpart_mtd_parser);
+}
+
+module_init(bcm47xxpart_init);
+module_exit(bcm47xxpart_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MTD partitioning for BCM47XX flash memories");
diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig
index b1e3c26..e469b01 100644
--- a/drivers/mtd/chips/Kconfig
+++ b/drivers/mtd/chips/Kconfig
@@ -43,9 +43,6 @@
 	prompt "Flash cmd/query data swapping"
 	depends on MTD_CFI_ADV_OPTIONS
 	default MTD_CFI_NOSWAP
-
-config MTD_CFI_NOSWAP
-	bool "NO"
 	---help---
 	  This option defines the way in which the CPU attempts to arrange
 	  data bits when writing the 'magic' commands to the chips. Saying
@@ -55,12 +52,8 @@
 	  Specific arrangements are possible with the BIG_ENDIAN_BYTE and
 	  LITTLE_ENDIAN_BYTE, if the bytes are reversed.
 
-	  If you have a LART, on which the data (and address) lines were
-	  connected in a fashion which ensured that the nets were as short
-	  as possible, resulting in a bit-shuffling which seems utterly
-	  random to the untrained eye, you need the LART_ENDIAN_BYTE option.
-
-	  Yes, there really exists something sicker than PDP-endian :)
+config MTD_CFI_NOSWAP
+	bool "NO"
 
 config MTD_CFI_BE_BYTE_SWAP
 	bool "BIG_ENDIAN_BYTE"
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index dbbd2ed..7751443 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -2043,7 +2043,7 @@
 {
 	struct cfi_private *cfi = map->fldrv_priv;
 	struct cfi_pri_intelext *extp = cfi->cmdset_priv;
-	int udelay;
+	int mdelay;
 	int ret;
 
 	adr += chip->start;
@@ -2072,9 +2072,17 @@
 	 * If Instant Individual Block Locking supported then no need
 	 * to delay.
 	 */
-	udelay = (!extp || !(extp->FeatureSupport & (1 << 5))) ? 1000000/HZ : 0;
+	/*
+	 * Unlocking may take up to 1.4 seconds on some Intel flashes. So
+	 * lets use a max of 1.5 seconds (1500ms) as timeout.
+	 *
+	 * See "Clear Block Lock-Bits Time" on page 40 in
+	 * "3 Volt Intel StrataFlash Memory" 28F128J3,28F640J3,28F320J3 manual
+	 * from February 2003
+	 */
+	mdelay = (!extp || !(extp->FeatureSupport & (1 << 5))) ? 1500 : 0;
 
-	ret = WAIT_TIMEOUT(map, chip, adr, udelay, udelay * 100);
+	ret = WAIT_TIMEOUT(map, chip, adr, mdelay, mdelay * 1000);
 	if (ret) {
 		map_write(map, CMD(0x70), adr);
 		chip->state = FL_STATUS;
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 22d0493..5ff5c4a 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -431,6 +431,68 @@
 	}
 }
 
+static int is_m29ew(struct cfi_private *cfi)
+{
+	if (cfi->mfr == CFI_MFR_INTEL &&
+	    ((cfi->device_type == CFI_DEVICETYPE_X8 && (cfi->id & 0xff) == 0x7e) ||
+	     (cfi->device_type == CFI_DEVICETYPE_X16 && cfi->id == 0x227e)))
+		return 1;
+	return 0;
+}
+
+/*
+ * From TN-13-07: Patching the Linux Kernel and U-Boot for M29 Flash, page 20:
+ * Some revisions of the M29EW suffer from erase suspend hang ups. In
+ * particular, it can occur when the sequence
+ * Erase Confirm -> Suspend -> Program -> Resume
+ * causes a lockup due to internal timing issues. The consequence is that the
+ * erase cannot be resumed without inserting a dummy command after programming
+ * and prior to resuming. [...] The work-around is to issue a dummy write cycle
+ * that writes an F0 command code before the RESUME command.
+ */
+static void cfi_fixup_m29ew_erase_suspend(struct map_info *map,
+					  unsigned long adr)
+{
+	struct cfi_private *cfi = map->fldrv_priv;
+	/* before resume, insert a dummy 0xF0 cycle for Micron M29EW devices */
+	if (is_m29ew(cfi))
+		map_write(map, CMD(0xF0), adr);
+}
+
+/*
+ * From TN-13-07: Patching the Linux Kernel and U-Boot for M29 Flash, page 22:
+ *
+ * Some revisions of the M29EW (for example, A1 and A2 step revisions)
+ * are affected by a problem that could cause a hang up when an ERASE SUSPEND
+ * command is issued after an ERASE RESUME operation without waiting for a
+ * minimum delay.  The result is that once the ERASE seems to be completed
+ * (no bits are toggling), the contents of the Flash memory block on which
+ * the erase was ongoing could be inconsistent with the expected values
+ * (typically, the array value is stuck to the 0xC0, 0xC4, 0x80, or 0x84
+ * values), causing a consequent failure of the ERASE operation.
+ * The occurrence of this issue could be high, especially when file system
+ * operations on the Flash are intensive.  As a result, it is recommended
+ * that a patch be applied.  Intensive file system operations can cause many
+ * calls to the garbage routine to free Flash space (also by erasing physical
+ * Flash blocks) and as a result, many consecutive SUSPEND and RESUME
+ * commands can occur.  The problem disappears when a delay is inserted after
+ * the RESUME command by using the udelay() function available in Linux.
+ * The DELAY value must be tuned based on the customer's platform.
+ * The maximum value that fixes the problem in all cases is 500us.
+ * But, in our experience, a delay of 30 µs to 50 µs is sufficient
+ * in most cases.
+ * We have chosen 500µs because this latency is acceptable.
+ */
+static void cfi_fixup_m29ew_delay_after_resume(struct cfi_private *cfi)
+{
+	/*
+	 * Resolving the Delay After Resume Issue see Micron TN-13-07
+	 * Worst case delay must be 500µs but 30-50µs should be ok as well
+	 */
+	if (is_m29ew(cfi))
+		cfi_udelay(500);
+}
+
 struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
 {
 	struct cfi_private *cfi = map->fldrv_priv;
@@ -776,7 +838,10 @@
 
 	switch(chip->oldstate) {
 	case FL_ERASING:
+		cfi_fixup_m29ew_erase_suspend(map,
+			chip->in_progress_block_addr);
 		map_write(map, cfi->sector_erase_cmd, chip->in_progress_block_addr);
+		cfi_fixup_m29ew_delay_after_resume(cfi);
 		chip->oldstate = FL_READY;
 		chip->state = FL_ERASING;
 		break;
@@ -916,6 +981,8 @@
 			/* Disallow XIP again */
 			local_irq_disable();
 
+			/* Correct Erase Suspend Hangups for M29EW */
+			cfi_fixup_m29ew_erase_suspend(map, adr);
 			/* Resume the write or erase operation */
 			map_write(map, cfi->sector_erase_cmd, adr);
 			chip->state = oldstate;
diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c
index 4558e0f..aed1b8a 100644
--- a/drivers/mtd/cmdlinepart.c
+++ b/drivers/mtd/cmdlinepart.c
@@ -39,11 +39,10 @@
 
 #include <linux/kernel.h>
 #include <linux/slab.h>
-
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
-#include <linux/bootmem.h>
 #include <linux/module.h>
+#include <linux/err.h>
 
 /* error message prefix */
 #define ERRP "mtd: "
@@ -72,7 +71,7 @@
 
 /* the command line passed to mtdpart_setup() */
 static char *cmdline;
-static int cmdline_parsed = 0;
+static int cmdline_parsed;
 
 /*
  * Parse one partition definition for an MTD. Since there can be many
@@ -83,15 +82,14 @@
  * syntax has been verified ok.
  */
 static struct mtd_partition * newpart(char *s,
-                                      char **retptr,
-                                      int *num_parts,
-                                      int this_part,
-                                      unsigned char **extra_mem_ptr,
-                                      int extra_mem_size)
+				      char **retptr,
+				      int *num_parts,
+				      int this_part,
+				      unsigned char **extra_mem_ptr,
+				      int extra_mem_size)
 {
 	struct mtd_partition *parts;
-	unsigned long size;
-	unsigned long offset = OFFSET_CONTINUOUS;
+	unsigned long size, offset = OFFSET_CONTINUOUS;
 	char *name;
 	int name_len;
 	unsigned char *extra_mem;
@@ -99,124 +97,106 @@
 	unsigned int mask_flags;
 
 	/* fetch the partition size */
-	if (*s == '-')
-	{	/* assign all remaining space to this partition */
+	if (*s == '-') {
+		/* assign all remaining space to this partition */
 		size = SIZE_REMAINING;
 		s++;
-	}
-	else
-	{
+	} else {
 		size = memparse(s, &s);
-		if (size < PAGE_SIZE)
-		{
+		if (size < PAGE_SIZE) {
 			printk(KERN_ERR ERRP "partition size too small (%lx)\n", size);
-			return NULL;
+			return ERR_PTR(-EINVAL);
 		}
 	}
 
 	/* fetch partition name and flags */
 	mask_flags = 0; /* this is going to be a regular partition */
 	delim = 0;
-        /* check for offset */
-        if (*s == '@')
-	{
-                s++;
-                offset = memparse(s, &s);
-        }
-        /* now look for name */
-	if (*s == '(')
-	{
-		delim = ')';
+
+	/* check for offset */
+	if (*s == '@') {
+		s++;
+		offset = memparse(s, &s);
 	}
 
-	if (delim)
-	{
+	/* now look for name */
+	if (*s == '(')
+		delim = ')';
+
+	if (delim) {
 		char *p;
 
-	    	name = ++s;
+		name = ++s;
 		p = strchr(name, delim);
-		if (!p)
-		{
+		if (!p) {
 			printk(KERN_ERR ERRP "no closing %c found in partition name\n", delim);
-			return NULL;
+			return ERR_PTR(-EINVAL);
 		}
 		name_len = p - name;
 		s = p + 1;
-	}
-	else
-	{
-	    	name = NULL;
+	} else {
+		name = NULL;
 		name_len = 13; /* Partition_000 */
 	}
 
 	/* record name length for memory allocation later */
 	extra_mem_size += name_len + 1;
 
-        /* test for options */
-        if (strncmp(s, "ro", 2) == 0)
-	{
+	/* test for options */
+	if (strncmp(s, "ro", 2) == 0) {
 		mask_flags |= MTD_WRITEABLE;
 		s += 2;
-        }
+	}
 
-        /* if lk is found do NOT unlock the MTD partition*/
-        if (strncmp(s, "lk", 2) == 0)
-	{
+	/* if lk is found do NOT unlock the MTD partition*/
+	if (strncmp(s, "lk", 2) == 0) {
 		mask_flags |= MTD_POWERUP_LOCK;
 		s += 2;
-        }
+	}
 
 	/* test if more partitions are following */
-	if (*s == ',')
-	{
-		if (size == SIZE_REMAINING)
-		{
+	if (*s == ',') {
+		if (size == SIZE_REMAINING) {
 			printk(KERN_ERR ERRP "no partitions allowed after a fill-up partition\n");
-			return NULL;
+			return ERR_PTR(-EINVAL);
 		}
 		/* more partitions follow, parse them */
 		parts = newpart(s + 1, &s, num_parts, this_part + 1,
 				&extra_mem, extra_mem_size);
-		if (!parts)
-			return NULL;
-	}
-	else
-	{	/* this is the last partition: allocate space for all */
+		if (IS_ERR(parts))
+			return parts;
+	} else {
+		/* this is the last partition: allocate space for all */
 		int alloc_size;
 
 		*num_parts = this_part + 1;
 		alloc_size = *num_parts * sizeof(struct mtd_partition) +
 			     extra_mem_size;
+
 		parts = kzalloc(alloc_size, GFP_KERNEL);
 		if (!parts)
-			return NULL;
+			return ERR_PTR(-ENOMEM);
 		extra_mem = (unsigned char *)(parts + *num_parts);
 	}
+
 	/* enter this partition (offset will be calculated later if it is zero at this point) */
 	parts[this_part].size = size;
 	parts[this_part].offset = offset;
 	parts[this_part].mask_flags = mask_flags;
 	if (name)
-	{
 		strlcpy(extra_mem, name, name_len + 1);
-	}
 	else
-	{
 		sprintf(extra_mem, "Partition_%03d", this_part);
-	}
 	parts[this_part].name = extra_mem;
 	extra_mem += name_len + 1;
 
 	dbg(("partition %d: name <%s>, offset %llx, size %llx, mask flags %x\n",
-	     this_part,
-	     parts[this_part].name,
-	     parts[this_part].offset,
-	     parts[this_part].size,
-	     parts[this_part].mask_flags));
+	     this_part, parts[this_part].name, parts[this_part].offset,
+	     parts[this_part].size, parts[this_part].mask_flags));
 
 	/* return (updated) pointer to extra_mem memory */
 	if (extra_mem_ptr)
-	  *extra_mem_ptr = extra_mem;
+		*extra_mem_ptr = extra_mem;
 
 	/* return (updated) pointer command line string */
 	*retptr = s;
@@ -236,16 +216,16 @@
 	{
 		struct cmdline_mtd_partition *this_mtd;
 		struct mtd_partition *parts;
-	    	int mtd_id_len;
-		int num_parts;
+		int mtd_id_len, num_parts;
 		char *p, *mtd_id;
 
-	    	mtd_id = s;
+		mtd_id = s;
+
 		/* fetch <mtd-id> */
-		if (!(p = strchr(s, ':')))
-		{
+		p = strchr(s, ':');
+		if (!p) {
 			printk(KERN_ERR ERRP "no mtd-id\n");
-			return 0;
+			return -EINVAL;
 		}
 		mtd_id_len = p - mtd_id;
 
@@ -262,8 +242,7 @@
 				(unsigned char**)&this_mtd, /* out: extra mem */
 				mtd_id_len + 1 + sizeof(*this_mtd) +
 				sizeof(void*)-1 /*alignment*/);
-		if(!parts)
-		{
+		if (IS_ERR(parts)) {
 			/*
 			 * An error occurred. We're either:
 			 * a) out of memory, or
@@ -271,12 +250,12 @@
 			 * Either way, this mtd is hosed and we're
 			 * unlikely to succeed in parsing any more
 			 */
-			 return 0;
+			 return PTR_ERR(parts);
 		 }
 
 		/* align this_mtd */
 		this_mtd = (struct cmdline_mtd_partition *)
-			ALIGN((unsigned long)this_mtd, sizeof(void*));
+				ALIGN((unsigned long)this_mtd, sizeof(void *));
 		/* enter results */
 		this_mtd->parts = parts;
 		this_mtd->num_parts = num_parts;
@@ -296,14 +275,14 @@
 			break;
 
 		/* does another spec follow? */
-		if (*s != ';')
-		{
+		if (*s != ';') {
 			printk(KERN_ERR ERRP "bad character after partition (%c)\n", *s);
-			return 0;
+			return -EINVAL;
 		}
 		s++;
 	}
-	return 1;
+
+	return 0;
 }
 
 /*
@@ -318,44 +297,58 @@
 				    struct mtd_part_parser_data *data)
 {
 	unsigned long offset;
-	int i;
+	int i, err;
 	struct cmdline_mtd_partition *part;
 	const char *mtd_id = master->name;
 
 	/* parse command line */
-	if (!cmdline_parsed)
-		mtdpart_setup_real(cmdline);
+	if (!cmdline_parsed) {
+		err = mtdpart_setup_real(cmdline);
+		if (err)
+			return err;
+	}
 
-	for(part = partitions; part; part = part->next)
-	{
-		if ((!mtd_id) || (!strcmp(part->mtd_id, mtd_id)))
-		{
-			for(i = 0, offset = 0; i < part->num_parts; i++)
-			{
+	for (part = partitions; part; part = part->next) {
+		if ((!mtd_id) || (!strcmp(part->mtd_id, mtd_id))) {
+			for (i = 0, offset = 0; i < part->num_parts; i++) {
 				if (part->parts[i].offset == OFFSET_CONTINUOUS)
-				  part->parts[i].offset = offset;
+					part->parts[i].offset = offset;
 				else
-				  offset = part->parts[i].offset;
+					offset = part->parts[i].offset;
+
 				if (part->parts[i].size == SIZE_REMAINING)
-				  part->parts[i].size = master->size - offset;
-				if (offset + part->parts[i].size > master->size)
-				{
+					part->parts[i].size = master->size - offset;
+
+				if (part->parts[i].size == 0) {
+					printk(KERN_WARNING ERRP
+					       "%s: skipping zero sized partition\n",
+					       part->mtd_id);
+					part->num_parts--;
+					memmove(&part->parts[i],
+						&part->parts[i + 1],
+						sizeof(*part->parts) * (part->num_parts - i));
+					continue;
+				}
+
+				if (offset + part->parts[i].size > master->size) {
 					printk(KERN_WARNING ERRP
 					       "%s: partitioning exceeds flash size, truncating\n",
 					       part->mtd_id);
 					part->parts[i].size = master->size - offset;
-					part->num_parts = i;
 				}
 				offset += part->parts[i].size;
 			}
+
 			*pparts = kmemdup(part->parts,
 					sizeof(*part->parts) * part->num_parts,
 					GFP_KERNEL);
 			if (!*pparts)
 				return -ENOMEM;
+
 			return part->num_parts;
 		}
 	}
+
 	return 0;
 }
 
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 4cdb2af..27f80cd 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -97,7 +97,7 @@
 	  doesn't support the JEDEC ID instruction.
 
 config M25PXX_USE_FAST_READ
-	bool "Use FAST_READ OPCode allowing SPI CLK <= 50MHz"
+	bool "Use FAST_READ OPCode allowing SPI CLK >= 50MHz"
 	depends on MTD_M25P80
 	default y
 	help
@@ -120,6 +120,14 @@
 	  Set up your spi devices with the right board-specific platform data,
 	  if you want to specify device partitioning.
 
+config MTD_BCM47XXSFLASH
+	tristate "R/O support for serial flash on BCMA bus"
+	depends on BCMA_SFLASH
+	help
+	  BCMA bus can have various flash memories attached, they are
+	  registered by bcma as platform devices. This enables driver for
+	  serial flash memories (only read-only mode is implemented).
+
 config MTD_SLRAM
 	tristate "Uncached system RAM"
 	help
diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile
index a4dd1d8..395733a 100644
--- a/drivers/mtd/devices/Makefile
+++ b/drivers/mtd/devices/Makefile
@@ -19,5 +19,6 @@
 obj-$(CONFIG_MTD_M25P80)	+= m25p80.o
 obj-$(CONFIG_MTD_SPEAR_SMI)	+= spear_smi.o
 obj-$(CONFIG_MTD_SST25L)	+= sst25l.o
+obj-$(CONFIG_MTD_BCM47XXSFLASH)	+= bcm47xxsflash.o
 
 CFLAGS_docg3.o			+= -I$(src)
\ No newline at end of file
diff --git a/drivers/mtd/devices/bcm47xxsflash.c b/drivers/mtd/devices/bcm47xxsflash.c
new file mode 100644
index 0000000..2dc5a6f
--- /dev/null
+++ b/drivers/mtd/devices/bcm47xxsflash.c
@@ -0,0 +1,105 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/mtd/mtd.h>
+#include <linux/platform_device.h>
+#include <linux/bcma/bcma.h>
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Serial flash driver for BCMA bus");
+
+static const char *probes[] = { "bcm47xxpart", NULL };
+
+static int bcm47xxsflash_read(struct mtd_info *mtd, loff_t from, size_t len,
+			      size_t *retlen, u_char *buf)
+{
+	struct bcma_sflash *sflash = mtd->priv;
+
+	/* Check address range */
+	if ((from + len) > mtd->size)
+		return -EINVAL;
+
+	memcpy_fromio(buf, (void __iomem *)KSEG0ADDR(sflash->window + from),
+		      len);
+
+	return len;
+}
+
+static void bcm47xxsflash_fill_mtd(struct bcma_sflash *sflash,
+				   struct mtd_info *mtd)
+{
+	mtd->priv = sflash;
+	mtd->name = "bcm47xxsflash";
+	mtd->owner = THIS_MODULE;
+	mtd->type = MTD_ROM;
+	mtd->size = sflash->size;
+	mtd->_read = bcm47xxsflash_read;
+
+	/* TODO: implement writing support and verify/change following code */
+	mtd->flags = MTD_CAP_ROM;
+	mtd->writebufsize = mtd->writesize = 1;
+}
+
+static int bcm47xxsflash_probe(struct platform_device *pdev)
+{
+	struct bcma_sflash *sflash = dev_get_platdata(&pdev->dev);
+	int err;
+
+	sflash->mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL);
+	if (!sflash->mtd) {
+		err = -ENOMEM;
+		goto out;
+	}
+	bcm47xxsflash_fill_mtd(sflash, sflash->mtd);
+
+	err = mtd_device_parse_register(sflash->mtd, probes, NULL, NULL, 0);
+	if (err) {
+		pr_err("Failed to register MTD device: %d\n", err);
+		goto err_dev_reg;
+	}
+
+	return 0;
+
+err_dev_reg:
+	kfree(sflash->mtd);
+out:
+	return err;
+}
+
+static int __devexit bcm47xxsflash_remove(struct platform_device *pdev)
+{
+	struct bcma_sflash *sflash = dev_get_platdata(&pdev->dev);
+
+	mtd_device_unregister(sflash->mtd);
+	kfree(sflash->mtd);
+
+	return 0;
+}
+
+static struct platform_driver bcma_sflash_driver = {
+	.remove = __devexit_p(bcm47xxsflash_remove),
+	.driver = {
+		.name = "bcma_sflash",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init bcm47xxsflash_init(void)
+{
+	int err;
+
+	err = platform_driver_probe(&bcma_sflash_driver, bcm47xxsflash_probe);
+	if (err)
+		pr_err("Failed to register BCMA serial flash driver: %d\n",
+		       err);
+
+	return err;
+}
+
+static void __exit bcm47xxsflash_exit(void)
+{
+	platform_driver_unregister(&bcma_sflash_driver);
+}
+
+module_init(bcm47xxsflash_init);
+module_exit(bcm47xxsflash_exit);
diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c
index 04eb2e4..4f2220a 100644
--- a/drivers/mtd/devices/doc2001plus.c
+++ b/drivers/mtd/devices/doc2001plus.c
@@ -659,23 +659,15 @@
 #ifdef ECC_DEBUG
 			printk("%s(%d): Millennium Plus ECC error (from=0x%x:\n",
 				__FILE__, __LINE__, (int)from);
-			printk("        syndrome= %02x:%02x:%02x:%02x:%02x:"
-				"%02x\n",
-				syndrome[0], syndrome[1], syndrome[2],
-				syndrome[3], syndrome[4], syndrome[5]);
-			printk("          eccbuf= %02x:%02x:%02x:%02x:%02x:"
-				"%02x\n",
-				eccbuf[0], eccbuf[1], eccbuf[2],
-				eccbuf[3], eccbuf[4], eccbuf[5]);
+			printk("        syndrome= %*phC\n", 6, syndrome);
+			printk("        eccbuf= %*phC\n", 6, eccbuf);
 #endif
 				ret = -EIO;
 		}
 	}
 
 #ifdef PSYCHO_DEBUG
-	printk("ECC DATA at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
-	       (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
-	       eccbuf[4], eccbuf[5]);
+	printk("ECC DATA at %lx: %*ph\n", (long)from, 6, eccbuf);
 #endif
 	/* disable the ECC engine */
 	WriteDOC(DOC_ECC_DIS, docptr , Mplus_ECCConf);
diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c
index f70854d..d34d83b 100644
--- a/drivers/mtd/devices/docg3.c
+++ b/drivers/mtd/devices/docg3.c
@@ -919,19 +919,13 @@
 		eccconf1 = doc_register_readb(docg3, DOC_ECCCONF1);
 
 		if (nboob >= DOC_LAYOUT_OOB_SIZE) {
-			doc_dbg("OOB - INFO: %02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-				oobbuf[0], oobbuf[1], oobbuf[2], oobbuf[3],
-				oobbuf[4], oobbuf[5], oobbuf[6]);
+			doc_dbg("OOB - INFO: %*phC\n", 7, oobbuf);
 			doc_dbg("OOB - HAMMING: %02x\n", oobbuf[7]);
-			doc_dbg("OOB - BCH_ECC: %02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-				oobbuf[8], oobbuf[9], oobbuf[10], oobbuf[11],
-				oobbuf[12], oobbuf[13], oobbuf[14]);
+			doc_dbg("OOB - BCH_ECC: %*phC\n", 7, oobbuf + 8);
 			doc_dbg("OOB - UNUSED: %02x\n", oobbuf[15]);
 		}
 		doc_dbg("ECC checks: ECCConf1=%x\n", eccconf1);
-		doc_dbg("ECC HW_ECC: %02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-			hwecc[0], hwecc[1], hwecc[2], hwecc[3], hwecc[4],
-			hwecc[5], hwecc[6]);
+		doc_dbg("ECC HW_ECC: %*phC\n", 7, hwecc);
 
 		ret = -EIO;
 		if (is_prot_seq_error(docg3))
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 5d0d68c..03838ba 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -633,11 +633,14 @@
 	{ "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) },
 	{ "at26df321",  INFO(0x1f4700, 0, 64 * 1024, 64, SECT_4K) },
 
+	{ "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) },
+
 	/* EON -- en25xxx */
 	{ "en25f32", INFO(0x1c3116, 0, 64 * 1024,  64, SECT_4K) },
 	{ "en25p32", INFO(0x1c2016, 0, 64 * 1024,  64, 0) },
 	{ "en25q32b", INFO(0x1c3016, 0, 64 * 1024,  64, 0) },
 	{ "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) },
+	{ "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) },
 
 	/* Everspin */
 	{ "mr25h256", CAT25_INFO(  32 * 1024, 1, 256, 2) },
@@ -646,6 +649,7 @@
 	{ "160s33b",  INFO(0x898911, 0, 64 * 1024,  32, 0) },
 	{ "320s33b",  INFO(0x898912, 0, 64 * 1024,  64, 0) },
 	{ "640s33b",  INFO(0x898913, 0, 64 * 1024, 128, 0) },
+	{ "n25q064",  INFO(0x20ba17, 0, 64 * 1024, 128, 0) },
 
 	/* Macronix */
 	{ "mx25l2005a",  INFO(0xc22012, 0, 64 * 1024,   4, SECT_4K) },
@@ -659,15 +663,15 @@
 	{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
 	{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
 
+	/* Micron */
+	{ "n25q128",  INFO(0x20ba18, 0, 64 * 1024, 256, 0) },
+	{ "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) },
+
 	/* Spansion -- single (large) sector size only, at least
 	 * for the chips listed here (without boot sectors).
 	 */
-	{ "s25sl004a",  INFO(0x010212,      0,  64 * 1024,   8, 0) },
-	{ "s25sl008a",  INFO(0x010213,      0,  64 * 1024,  16, 0) },
-	{ "s25sl016a",  INFO(0x010214,      0,  64 * 1024,  32, 0) },
-	{ "s25sl032a",  INFO(0x010215,      0,  64 * 1024,  64, 0) },
-	{ "s25sl032p",  INFO(0x010215, 0x4d00,  64 * 1024,  64, SECT_4K) },
-	{ "s25sl064a",  INFO(0x010216,      0,  64 * 1024, 128, 0) },
+	{ "s25sl032p",  INFO(0x010215, 0x4d00,  64 * 1024,  64, 0) },
+	{ "s25sl064p",  INFO(0x010216, 0x4d00,  64 * 1024, 128, 0) },
 	{ "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
 	{ "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, 0) },
 	{ "s25fl512s",  INFO(0x010220, 0x4d00, 256 * 1024, 256, 0) },
@@ -676,6 +680,11 @@
 	{ "s25sl12801", INFO(0x012018, 0x0301,  64 * 1024, 256, 0) },
 	{ "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024,  64, 0) },
 	{ "s25fl129p1", INFO(0x012018, 0x4d01,  64 * 1024, 256, 0) },
+	{ "s25sl004a",  INFO(0x010212,      0,  64 * 1024,   8, 0) },
+	{ "s25sl008a",  INFO(0x010213,      0,  64 * 1024,  16, 0) },
+	{ "s25sl016a",  INFO(0x010214,      0,  64 * 1024,  32, 0) },
+	{ "s25sl032a",  INFO(0x010215,      0,  64 * 1024,  64, 0) },
+	{ "s25sl064a",  INFO(0x010216,      0,  64 * 1024, 128, 0) },
 	{ "s25fl016k",  INFO(0xef4015,      0,  64 * 1024,  32, SECT_4K) },
 	{ "s25fl064k",  INFO(0xef4017,      0,  64 * 1024, 128, SECT_4K) },
 
@@ -699,6 +708,7 @@
 	{ "m25p32",  INFO(0x202016,  0,  64 * 1024,  64, 0) },
 	{ "m25p64",  INFO(0x202017,  0,  64 * 1024, 128, 0) },
 	{ "m25p128", INFO(0x202018,  0, 256 * 1024,  64, 0) },
+	{ "n25q032", INFO(0x20ba16,  0,  64 * 1024,  64, 0) },
 
 	{ "m25p05-nonjedec",  INFO(0, 0,  32 * 1024,   2, 0) },
 	{ "m25p10-nonjedec",  INFO(0, 0,  32 * 1024,   4, 0) },
@@ -714,6 +724,7 @@
 	{ "m45pe80", INFO(0x204014,  0, 64 * 1024,   16, 0) },
 	{ "m45pe16", INFO(0x204015,  0, 64 * 1024,   32, 0) },
 
+	{ "m25pe20", INFO(0x208012,  0, 64 * 1024,  4,       0) },
 	{ "m25pe80", INFO(0x208014,  0, 64 * 1024, 16,       0) },
 	{ "m25pe16", INFO(0x208015,  0, 64 * 1024, 32, SECT_4K) },
 
@@ -730,6 +741,7 @@
 	{ "w25x16", INFO(0xef3015, 0, 64 * 1024,  32, SECT_4K) },
 	{ "w25x32", INFO(0xef3016, 0, 64 * 1024,  64, SECT_4K) },
 	{ "w25q32", INFO(0xef4016, 0, 64 * 1024,  64, SECT_4K) },
+	{ "w25q32dw", INFO(0xef6016, 0, 64 * 1024,  64, SECT_4K) },
 	{ "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
 	{ "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
 	{ "w25q80", INFO(0xef5014, 0, 64 * 1024,  16, SECT_4K) },
diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c
index 6796036..dcc3c95 100644
--- a/drivers/mtd/devices/spear_smi.c
+++ b/drivers/mtd/devices/spear_smi.c
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/param.h>
 #include <linux/platform_device.h>
+#include <linux/pm.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/spear_smi.h>
@@ -240,8 +241,8 @@
 	/* copy dev->status (lower 16 bits) in order to release lock */
 	if (ret > 0)
 		ret = dev->status & 0xffff;
-	else
-		ret = -EIO;
+	else if (ret == 0)
+		ret = -ETIMEDOUT;
 
 	/* restore the ctrl regs state */
 	writel(ctrlreg1, dev->io_base + SMI_CR1);
@@ -269,16 +270,19 @@
 	finish = jiffies + timeout;
 	do {
 		status = spear_smi_read_sr(dev, bank);
-		if (status < 0)
-			continue; /* try till timeout */
-		else if (!(status & SR_WIP))
+		if (status < 0) {
+			if (status == -ETIMEDOUT)
+				continue; /* try till finish */
+			return status;
+		} else if (!(status & SR_WIP)) {
 			return 0;
+		}
 
 		cond_resched();
 	} while (!time_after_eq(jiffies, finish));
 
 	dev_err(&dev->pdev->dev, "smi controller is busy, timeout\n");
-	return status;
+	return -EBUSY;
 }
 
 /**
@@ -335,6 +339,9 @@
 	val = HOLD1 | BANK_EN | DSEL_TIME | (prescale << 8);
 
 	mutex_lock(&dev->lock);
+	/* clear all interrupt conditions */
+	writel(0, dev->io_base + SMI_SR);
+
 	writel(val, dev->io_base + SMI_CR1);
 	mutex_unlock(&dev->lock);
 }
@@ -391,11 +398,11 @@
 	writel(ctrlreg1, dev->io_base + SMI_CR1);
 	writel(0, dev->io_base + SMI_CR2);
 
-	if (ret <= 0) {
+	if (ret == 0) {
 		ret = -EIO;
 		dev_err(&dev->pdev->dev,
 			"smi controller failed on write enable\n");
-	} else {
+	} else if (ret > 0) {
 		/* check whether write mode status is set for required bank */
 		if (dev->status & (1 << (bank + WM_SHIFT)))
 			ret = 0;
@@ -462,10 +469,10 @@
 	ret = wait_event_interruptible_timeout(dev->cmd_complete,
 			dev->status & TFF, SMI_CMD_TIMEOUT);
 
-	if (ret <= 0) {
+	if (ret == 0) {
 		ret = -EIO;
 		dev_err(&dev->pdev->dev, "sector erase failed\n");
-	} else
+	} else if (ret > 0)
 		ret = 0; /* success */
 
 	/* restore ctrl regs */
@@ -820,7 +827,7 @@
 	if (!flash_info)
 		return -ENODEV;
 
-	flash = kzalloc(sizeof(*flash), GFP_ATOMIC);
+	flash = devm_kzalloc(&pdev->dev, sizeof(*flash), GFP_ATOMIC);
 	if (!flash)
 		return -ENOMEM;
 	flash->bank = bank;
@@ -831,15 +838,13 @@
 	flash_index = spear_smi_probe_flash(dev, bank);
 	if (flash_index < 0) {
 		dev_info(&dev->pdev->dev, "smi-nor%d not found\n", bank);
-		ret = flash_index;
-		goto err_probe;
+		return flash_index;
 	}
 	/* map the memory for nor flash chip */
-	flash->base_addr = ioremap(flash_info->mem_base, flash_info->size);
-	if (!flash->base_addr) {
-		ret = -EIO;
-		goto err_probe;
-	}
+	flash->base_addr = devm_ioremap(&pdev->dev, flash_info->mem_base,
+					flash_info->size);
+	if (!flash->base_addr)
+		return -EIO;
 
 	dev->flash[bank] = flash;
 	flash->mtd.priv = dev;
@@ -881,17 +886,10 @@
 					count);
 	if (ret) {
 		dev_err(&dev->pdev->dev, "Err MTD partition=%d\n", ret);
-		goto err_map;
+		return ret;
 	}
 
 	return 0;
-
-err_map:
-	iounmap(flash->base_addr);
-
-err_probe:
-	kfree(flash);
-	return ret;
 }
 
 /**
@@ -928,20 +926,13 @@
 		}
 	} else {
 		pdata = dev_get_platdata(&pdev->dev);
-		if (pdata < 0) {
+		if (!pdata) {
 			ret = -ENODEV;
 			dev_err(&pdev->dev, "no platform data\n");
 			goto err;
 		}
 	}
 
-	smi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!smi_base) {
-		ret = -ENODEV;
-		dev_err(&pdev->dev, "invalid smi base address\n");
-		goto err;
-	}
-
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
 		ret = -ENODEV;
@@ -949,32 +940,26 @@
 		goto err;
 	}
 
-	dev = kzalloc(sizeof(*dev), GFP_ATOMIC);
+	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_ATOMIC);
 	if (!dev) {
 		ret = -ENOMEM;
 		dev_err(&pdev->dev, "mem alloc fail\n");
 		goto err;
 	}
 
-	smi_base = request_mem_region(smi_base->start, resource_size(smi_base),
-			pdev->name);
-	if (!smi_base) {
-		ret = -EBUSY;
-		dev_err(&pdev->dev, "request mem region fail\n");
-		goto err_mem;
-	}
+	smi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
-	dev->io_base = ioremap(smi_base->start, resource_size(smi_base));
+	dev->io_base = devm_request_and_ioremap(&pdev->dev, smi_base);
 	if (!dev->io_base) {
 		ret = -EIO;
-		dev_err(&pdev->dev, "ioremap fail\n");
-		goto err_ioremap;
+		dev_err(&pdev->dev, "devm_request_and_ioremap fail\n");
+		goto err;
 	}
 
 	dev->pdev = pdev;
 	dev->clk_rate = pdata->clk_rate;
 
-	if (dev->clk_rate < 0 || dev->clk_rate > SMI_MAX_CLOCK_FREQ)
+	if (dev->clk_rate > SMI_MAX_CLOCK_FREQ)
 		dev->clk_rate = SMI_MAX_CLOCK_FREQ;
 
 	dev->num_flashes = pdata->num_flashes;
@@ -984,17 +969,18 @@
 		dev->num_flashes = MAX_NUM_FLASH_CHIP;
 	}
 
-	dev->clk = clk_get(&pdev->dev, NULL);
+	dev->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(dev->clk)) {
 		ret = PTR_ERR(dev->clk);
-		goto err_clk;
+		goto err;
 	}
 
 	ret = clk_prepare_enable(dev->clk);
 	if (ret)
-		goto err_clk_prepare_enable;
+		goto err;
 
-	ret = request_irq(irq, spear_smi_int_handler, 0, pdev->name, dev);
+	ret = devm_request_irq(&pdev->dev, irq, spear_smi_int_handler, 0,
+			       pdev->name, dev);
 	if (ret) {
 		dev_err(&dev->pdev->dev, "SMI IRQ allocation failed\n");
 		goto err_irq;
@@ -1017,18 +1003,9 @@
 	return 0;
 
 err_bank_setup:
-	free_irq(irq, dev);
 	platform_set_drvdata(pdev, NULL);
 err_irq:
 	clk_disable_unprepare(dev->clk);
-err_clk_prepare_enable:
-	clk_put(dev->clk);
-err_clk:
-	iounmap(dev->io_base);
-err_ioremap:
-	release_mem_region(smi_base->start, resource_size(smi_base));
-err_mem:
-	kfree(dev);
 err:
 	return ret;
 }
@@ -1042,11 +1019,8 @@
 static int __devexit spear_smi_remove(struct platform_device *pdev)
 {
 	struct spear_smi *dev;
-	struct spear_smi_plat_data *pdata;
 	struct spear_snor_flash *flash;
-	struct resource *smi_base;
-	int ret;
-	int i, irq;
+	int ret, i;
 
 	dev = platform_get_drvdata(pdev);
 	if (!dev) {
@@ -1054,8 +1028,6 @@
 		return -ENODEV;
 	}
 
-	pdata = dev_get_platdata(&pdev->dev);
-
 	/* clean up for all nor flash */
 	for (i = 0; i < dev->num_flashes; i++) {
 		flash = dev->flash[i];
@@ -1066,49 +1038,41 @@
 		ret = mtd_device_unregister(&flash->mtd);
 		if (ret)
 			dev_err(&pdev->dev, "error removing mtd\n");
-
-		iounmap(flash->base_addr);
-		kfree(flash);
 	}
 
-	irq = platform_get_irq(pdev, 0);
-	free_irq(irq, dev);
-
 	clk_disable_unprepare(dev->clk);
-	clk_put(dev->clk);
-	iounmap(dev->io_base);
-	kfree(dev);
-
-	smi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	release_mem_region(smi_base->start, resource_size(smi_base));
 	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
 
-int spear_smi_suspend(struct platform_device *pdev, pm_message_t state)
+#ifdef CONFIG_PM
+static int spear_smi_suspend(struct device *dev)
 {
-	struct spear_smi *dev = platform_get_drvdata(pdev);
+	struct spear_smi *sdev = dev_get_drvdata(dev);
 
-	if (dev && dev->clk)
-		clk_disable_unprepare(dev->clk);
+	if (sdev && sdev->clk)
+		clk_disable_unprepare(sdev->clk);
 
 	return 0;
 }
 
-int spear_smi_resume(struct platform_device *pdev)
+static int spear_smi_resume(struct device *dev)
 {
-	struct spear_smi *dev = platform_get_drvdata(pdev);
+	struct spear_smi *sdev = dev_get_drvdata(dev);
 	int ret = -EPERM;
 
-	if (dev && dev->clk)
-		ret = clk_prepare_enable(dev->clk);
+	if (sdev && sdev->clk)
+		ret = clk_prepare_enable(sdev->clk);
 
 	if (!ret)
-		spear_smi_hw_init(dev);
+		spear_smi_hw_init(sdev);
 	return ret;
 }
 
+static SIMPLE_DEV_PM_OPS(spear_smi_pm_ops, spear_smi_suspend, spear_smi_resume);
+#endif
+
 #ifdef CONFIG_OF
 static const struct of_device_id spear_smi_id_table[] = {
 	{ .compatible = "st,spear600-smi" },
@@ -1123,11 +1087,12 @@
 		.bus = &platform_bus_type,
 		.owner = THIS_MODULE,
 		.of_match_table = of_match_ptr(spear_smi_id_table),
+#ifdef CONFIG_PM
+		.pm = &spear_smi_pm_ops,
+#endif
 	},
 	.probe = spear_smi_probe,
 	.remove = __devexit_p(spear_smi_remove),
-	.suspend = spear_smi_suspend,
-	.resume = spear_smi_resume,
 };
 
 static int spear_smi_init(void)
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 5ba2458..2e47c2e 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -373,7 +373,7 @@
 	  have such a board, say 'Y'.
 
 config MTD_AUTCPU12
-	tristate "NV-RAM mapping AUTCPU12 board"
+	bool "NV-RAM mapping AUTCPU12 board"
 	depends on ARCH_AUTCPU12
 	help
 	  This enables access to the NV-RAM on autronix autcpu12 board.
@@ -443,22 +443,10 @@
 
 config MTD_UCLINUX
 	bool "Generic uClinux RAM/ROM filesystem support"
-	depends on MTD_RAM=y && !MMU
+	depends on MTD_RAM=y && (!MMU || COLDFIRE)
 	help
 	  Map driver to support image based filesystems for uClinux.
 
-config MTD_WRSBC8260
-	tristate "Map driver for WindRiver PowerQUICC II MPC82xx board"
-	depends on (SBC82xx || SBC8560)
-	select MTD_MAP_BANK_WIDTH_4
-	select MTD_MAP_BANK_WIDTH_1
-	select MTD_CFI_I1
-	select MTD_CFI_I4
-	help
-	  Map driver for WindRiver PowerQUICC II MPC82xx board. Drives
-	  all three flash regions on CS0, CS1 and CS6 if they are configured
-	  correctly by the boot loader.
-
 config MTD_DMV182
         tristate "Map driver for Dy-4 SVME/DMV-182 board."
         depends on DMV182
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 68a9a91..deb43e9 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -47,7 +47,6 @@
 obj-$(CONFIG_MTD_H720X)		+= h720x-flash.o
 obj-$(CONFIG_MTD_IXP4XX)	+= ixp4xx.o
 obj-$(CONFIG_MTD_IXP2000)	+= ixp2000.o
-obj-$(CONFIG_MTD_WRSBC8260)	+= wr_sbc82xx_flash.o
 obj-$(CONFIG_MTD_DMV182)	+= dmv182.o
 obj-$(CONFIG_MTD_PLATRAM)	+= plat-ram.o
 obj-$(CONFIG_MTD_INTEL_VR_NOR)	+= intel_vr_nor.o
diff --git a/drivers/mtd/maps/autcpu12-nvram.c b/drivers/mtd/maps/autcpu12-nvram.c
index e5bfd0e..76fb594 100644
--- a/drivers/mtd/maps/autcpu12-nvram.c
+++ b/drivers/mtd/maps/autcpu12-nvram.c
@@ -15,43 +15,54 @@
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
  */
+#include <linux/sizes.h>
 
-#include <linux/module.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/ioport.h>
 #include <linux/init.h>
-#include <asm/io.h>
-#include <asm/sizes.h>
-#include <mach/hardware.h>
-#include <mach/autcpu12.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
 
-
-static struct mtd_info *sram_mtd;
-
-struct map_info autcpu12_sram_map = {
-	.name = "SRAM",
-	.size = 32768,
-	.bankwidth = 4,
-	.phys = 0x12000000,
+struct autcpu12_nvram_priv {
+	struct mtd_info *mtd;
+	struct map_info map;
 };
 
-static int __init init_autcpu12_sram (void)
+static int __devinit autcpu12_nvram_probe(struct platform_device *pdev)
 {
-	int err, save0, save1;
+	map_word tmp, save0, save1;
+	struct resource *res;
+	struct autcpu12_nvram_priv *priv;
 
-	autcpu12_sram_map.virt = ioremap(0x12000000, SZ_128K);
-	if (!autcpu12_sram_map.virt) {
-		printk("Failed to ioremap autcpu12 NV-RAM space\n");
-		err = -EIO;
-		goto out;
+	priv = devm_kzalloc(&pdev->dev,
+			    sizeof(struct autcpu12_nvram_priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, priv);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "failed to get memory resource\n");
+		return -ENOENT;
 	}
-	simple_map_init(&autcpu_sram_map);
+
+	priv->map.bankwidth	= 4;
+	priv->map.phys		= res->start;
+	priv->map.size		= resource_size(res);
+	priv->map.virt		= devm_request_and_ioremap(&pdev->dev, res);
+	strcpy((char *)priv->map.name, res->name);
+	if (!priv->map.virt) {
+		dev_err(&pdev->dev, "failed to remap mem resource\n");
+		return -EBUSY;
+	}
+
+	simple_map_init(&priv->map);
 
 	/*
 	 * Check for 32K/128K
@@ -61,65 +72,59 @@
 	 * Read	and check result on ofs 0x0
 	 * Restore contents
 	 */
-	save0 = map_read32(&autcpu12_sram_map,0);
-	save1 = map_read32(&autcpu12_sram_map,0x10000);
-	map_write32(&autcpu12_sram_map,~save0,0x10000);
-	/* if we find this pattern on 0x0, we have 32K size
-	 * restore contents and exit
-	 */
-	if ( map_read32(&autcpu12_sram_map,0) != save0) {
-		map_write32(&autcpu12_sram_map,save0,0x0);
-		goto map;
-	}
-	/* We have a 128K found, restore 0x10000 and set size
-	 * to 128K
-	 */
-	map_write32(&autcpu12_sram_map,save1,0x10000);
-	autcpu12_sram_map.size = SZ_128K;
+	save0 = map_read(&priv->map, 0);
+	save1 = map_read(&priv->map, 0x10000);
+	tmp.x[0] = ~save0.x[0];
+	map_write(&priv->map, tmp, 0x10000);
+	tmp = map_read(&priv->map, 0);
+	/* if we find this pattern on 0x0, we have 32K size */
+	if (!map_word_equal(&priv->map, tmp, save0)) {
+		map_write(&priv->map, save0, 0x0);
+		priv->map.size = SZ_32K;
+	} else
+		map_write(&priv->map, save1, 0x10000);
 
-map:
-	sram_mtd = do_map_probe("map_ram", &autcpu12_sram_map);
-	if (!sram_mtd) {
-		printk("NV-RAM probe failed\n");
-		err = -ENXIO;
-		goto out_ioremap;
+	priv->mtd = do_map_probe("map_ram", &priv->map);
+	if (!priv->mtd) {
+		dev_err(&pdev->dev, "probing failed\n");
+		return -ENXIO;
 	}
 
-	sram_mtd->owner = THIS_MODULE;
-	sram_mtd->erasesize = 16;
-
-	if (mtd_device_register(sram_mtd, NULL, 0)) {
-		printk("NV-RAM device addition failed\n");
-		err = -ENOMEM;
-		goto out_probe;
+	priv->mtd->owner	= THIS_MODULE;
+	priv->mtd->erasesize	= 16;
+	priv->mtd->dev.parent	= &pdev->dev;
+	if (!mtd_device_register(priv->mtd, NULL, 0)) {
+		dev_info(&pdev->dev,
+			 "NV-RAM device size %ldKiB registered on AUTCPU12\n",
+			 priv->map.size / SZ_1K);
+		return 0;
 	}
 
-	printk("NV-RAM device size %ldKiB registered on AUTCPU12\n",autcpu12_sram_map.size/SZ_1K);
+	map_destroy(priv->mtd);
+	dev_err(&pdev->dev, "NV-RAM device addition failed\n");
+	return -ENOMEM;
+}
+
+static int __devexit autcpu12_nvram_remove(struct platform_device *pdev)
+{
+	struct autcpu12_nvram_priv *priv = platform_get_drvdata(pdev);
+
+	mtd_device_unregister(priv->mtd);
+	map_destroy(priv->mtd);
 
 	return 0;
-
-out_probe:
-	map_destroy(sram_mtd);
-	sram_mtd = 0;
-
-out_ioremap:
-	iounmap((void *)autcpu12_sram_map.virt);
-out:
-	return err;
 }
 
-static void __exit cleanup_autcpu12_maps(void)
-{
-	if (sram_mtd) {
-		mtd_device_unregister(sram_mtd);
-		map_destroy(sram_mtd);
-		iounmap((void *)autcpu12_sram_map.virt);
-	}
-}
-
-module_init(init_autcpu12_sram);
-module_exit(cleanup_autcpu12_maps);
+static struct platform_driver autcpu12_nvram_driver = {
+	.driver		= {
+		.name	= "autcpu12_nvram",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= autcpu12_nvram_probe,
+	.remove		= __devexit_p(autcpu12_nvram_remove),
+};
+module_platform_driver(autcpu12_nvram_driver);
 
 MODULE_AUTHOR("Thomas Gleixner");
-MODULE_DESCRIPTION("autcpu12 NV-RAM map driver");
+MODULE_DESCRIPTION("autcpu12 NVRAM map driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/maps/pci.c b/drivers/mtd/maps/pci.c
index f14ce0a..1c30c1a 100644
--- a/drivers/mtd/maps/pci.c
+++ b/drivers/mtd/maps/pci.c
@@ -43,26 +43,14 @@
 	struct map_pci_info *map = (struct map_pci_info *)_map;
 	map_word val;
 	val.x[0]= readb(map->base + map->translate(map, ofs));
-//	printk("read8 : %08lx => %02x\n", ofs, val.x[0]);
 	return val;
 }
 
-#if 0
-static map_word mtd_pci_read16(struct map_info *_map, unsigned long ofs)
-{
-	struct map_pci_info *map = (struct map_pci_info *)_map;
-	map_word val;
-	val.x[0] = readw(map->base + map->translate(map, ofs));
-//	printk("read16: %08lx => %04x\n", ofs, val.x[0]);
-	return val;
-}
-#endif
 static map_word mtd_pci_read32(struct map_info *_map, unsigned long ofs)
 {
 	struct map_pci_info *map = (struct map_pci_info *)_map;
 	map_word val;
 	val.x[0] = readl(map->base + map->translate(map, ofs));
-//	printk("read32: %08lx => %08x\n", ofs, val.x[0]);
 	return val;
 }
 
@@ -75,22 +63,12 @@
 static void mtd_pci_write8(struct map_info *_map, map_word val, unsigned long ofs)
 {
 	struct map_pci_info *map = (struct map_pci_info *)_map;
-//	printk("write8 : %08lx <= %02x\n", ofs, val.x[0]);
 	writeb(val.x[0], map->base + map->translate(map, ofs));
 }
 
-#if 0
-static void mtd_pci_write16(struct map_info *_map, map_word val, unsigned long ofs)
-{
-	struct map_pci_info *map = (struct map_pci_info *)_map;
-//	printk("write16: %08lx <= %04x\n", ofs, val.x[0]);
-	writew(val.x[0], map->base + map->translate(map, ofs));
-}
-#endif
 static void mtd_pci_write32(struct map_info *_map, map_word val, unsigned long ofs)
 {
 	struct map_pci_info *map = (struct map_pci_info *)_map;
-//	printk("write32: %08lx <= %08x\n", ofs, val.x[0]);
 	writel(val.x[0], map->base + map->translate(map, ofs));
 }
 
@@ -358,4 +336,3 @@
 MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
 MODULE_DESCRIPTION("Generic PCI map driver");
 MODULE_DEVICE_TABLE(pci, mtd_pci_ids);
-
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c
index 2e6fb68..6f19aca 100644
--- a/drivers/mtd/maps/physmap_of.c
+++ b/drivers/mtd/maps/physmap_of.c
@@ -169,6 +169,7 @@
 	struct mtd_info **mtd_list = NULL;
 	resource_size_t res_size;
 	struct mtd_part_parser_data ppdata;
+	bool map_indirect;
 
 	match = of_match_device(of_flash_match, &dev->dev);
 	if (!match)
@@ -192,6 +193,8 @@
 	}
 	count /= reg_tuple_size;
 
+	map_indirect = of_property_read_bool(dp, "no-unaligned-direct-access");
+
 	err = -ENOMEM;
 	info = kzalloc(sizeof(struct of_flash) +
 		       sizeof(struct of_flash_list) * count, GFP_KERNEL);
@@ -247,6 +250,17 @@
 
 		simple_map_init(&info->list[i].map);
 
+		/*
+		 * On some platforms (e.g. MPC5200) a direct 1:1 mapping
+		 * may cause problems with JFFS2 usage, as the local bus (LPB)
+		 * doesn't support unaligned accesses as implemented in the
+		 * JFFS2 code via memcpy(). By setting NO_XIP, the
+		 * flash will not be exposed directly to the MTD users
+		 * (e.g. JFFS2) any more.
+		 */
+		if (map_indirect)
+			info->list[i].map.phys = NO_XIP;
+
 		if (probe_type) {
 			info->list[i].mtd = do_map_probe(probe_type,
 							 &info->list[i].map);
diff --git a/drivers/mtd/maps/rbtx4939-flash.c b/drivers/mtd/maps/rbtx4939-flash.c
index 6f52e1f..49c3fe7 100644
--- a/drivers/mtd/maps/rbtx4939-flash.c
+++ b/drivers/mtd/maps/rbtx4939-flash.c
@@ -100,8 +100,6 @@
 		goto err_out;
 	}
 	info->mtd->owner = THIS_MODULE;
-	if (err)
-		goto err_out;
 	err = mtd_device_parse_register(info->mtd, NULL, NULL, pdata->parts,
 					pdata->nr_parts);
 
diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c
index c3bb304..299bf88 100644
--- a/drivers/mtd/maps/uclinux.c
+++ b/drivers/mtd/maps/uclinux.c
@@ -67,10 +67,16 @@
 	printk("uclinux[mtd]: RAM probe address=0x%x size=0x%x\n",
 	       	(int) mapp->phys, (int) mapp->size);
 
-	mapp->virt = ioremap_nocache(mapp->phys, mapp->size);
+	/*
+	 * The filesystem is guaranteed to be in direct mapped memory. It is
+	 * directly following the kernels own bss region. Following the same
+	 * mechanism used by architectures setting up traditional initrds we
+	 * use phys_to_virt to get the virtual address of its start.
+	 */
+	mapp->virt = phys_to_virt(mapp->phys);
 
 	if (mapp->virt == 0) {
-		printk("uclinux[mtd]: ioremap_nocache() failed\n");
+		printk("uclinux[mtd]: no virtual mapping?\n");
 		return(-EIO);
 	}
 
@@ -79,7 +85,6 @@
 	mtd = do_map_probe("map_ram", mapp);
 	if (!mtd) {
 		printk("uclinux[mtd]: failed to find a mapping?\n");
-		iounmap(mapp->virt);
 		return(-ENXIO);
 	}
 
@@ -102,10 +107,8 @@
 		map_destroy(uclinux_ram_mtdinfo);
 		uclinux_ram_mtdinfo = NULL;
 	}
-	if (uclinux_ram_map.virt) {
-		iounmap((void *) uclinux_ram_map.virt);
+	if (uclinux_ram_map.virt)
 		uclinux_ram_map.virt = 0;
-	}
 }
 
 /****************************************************************************/
diff --git a/drivers/mtd/maps/wr_sbc82xx_flash.c b/drivers/mtd/maps/wr_sbc82xx_flash.c
deleted file mode 100644
index e7534c8..0000000
--- a/drivers/mtd/maps/wr_sbc82xx_flash.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Map for flash chips on Wind River PowerQUICC II SBC82xx board.
- *
- * Copyright (C) 2004 Red Hat, Inc.
- *
- * Author: David Woodhouse <dwmw2@infradead.org>
- *
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <asm/io.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/immap_cpm2.h>
-
-static struct mtd_info *sbcmtd[3];
-
-struct map_info sbc82xx_flash_map[3] = {
-	{.name = "Boot flash"},
-	{.name = "Alternate boot flash"},
-	{.name = "User flash"}
-};
-
-static struct mtd_partition smallflash_parts[] = {
-	{
-		.name =		"space",
-		.size =		0x100000,
-		.offset =	0,
-	}, {
-		.name =		"bootloader",
-		.size =		MTDPART_SIZ_FULL,
-		.offset =	MTDPART_OFS_APPEND,
-	}
-};
-
-static struct mtd_partition bigflash_parts[] = {
-	{
-		.name =		"bootloader",
-		.size =		0x00100000,
-		.offset =	0,
-	}, {
-		.name =		"file system",
-		.size =		0x01f00000,
-		.offset =	MTDPART_OFS_APPEND,
-	}, {
-		.name =		"boot config",
-		.size =		0x00100000,
-		.offset =	MTDPART_OFS_APPEND,
-	}, {
-		.name =		"space",
-		.size =		0x01f00000,
-		.offset =	MTDPART_OFS_APPEND,
-	}
-};
-
-static const char *part_probes[] __initconst = {"cmdlinepart", "RedBoot", NULL};
-
-#define init_sbc82xx_one_flash(map, br, or)			\
-do {								\
-	(map).phys = (br & 1) ? (br & 0xffff8000) : 0;		\
-	(map).size = (br & 1) ? (~(or & 0xffff8000) + 1) : 0;	\
-	switch (br & 0x00001800) {				\
-	case 0x00000000:					\
-	case 0x00000800:	(map).bankwidth = 1;	break;	\
-	case 0x00001000:	(map).bankwidth = 2;	break;	\
-	case 0x00001800:	(map).bankwidth = 4;	break;	\
-	}							\
-} while (0);
-
-static int __init init_sbc82xx_flash(void)
-{
-	volatile memctl_cpm2_t *mc = &cpm2_immr->im_memctl;
-	int bigflash;
-	int i;
-
-#ifdef CONFIG_SBC8560
-	mc = ioremap(0xff700000 + 0x5000, sizeof(memctl_cpm2_t));
-#else
-	mc = &cpm2_immr->im_memctl;
-#endif
-
-	bigflash = 1;
-	if ((mc->memc_br0 & 0x00001800) == 0x00001800)
-		bigflash = 0;
-
-	init_sbc82xx_one_flash(sbc82xx_flash_map[0], mc->memc_br0, mc->memc_or0);
-	init_sbc82xx_one_flash(sbc82xx_flash_map[1], mc->memc_br6, mc->memc_or6);
-	init_sbc82xx_one_flash(sbc82xx_flash_map[2], mc->memc_br1, mc->memc_or1);
-
-#ifdef CONFIG_SBC8560
-	iounmap((void *) mc);
-#endif
-
-	for (i=0; i<3; i++) {
-		int8_t flashcs[3] = { 0, 6, 1 };
-		int nr_parts;
-		struct mtd_partition *defparts;
-
-		printk(KERN_NOTICE "PowerQUICC II %s (%ld MiB on CS%d",
-		       sbc82xx_flash_map[i].name,
-		       (sbc82xx_flash_map[i].size >> 20),
-		       flashcs[i]);
-		if (!sbc82xx_flash_map[i].phys) {
-			/* We know it can't be at zero. */
-			printk("): disabled by bootloader.\n");
-			continue;
-		}
-		printk(" at %08lx)\n",  sbc82xx_flash_map[i].phys);
-
-		sbc82xx_flash_map[i].virt = ioremap(sbc82xx_flash_map[i].phys,
-						    sbc82xx_flash_map[i].size);
-
-		if (!sbc82xx_flash_map[i].virt) {
-			printk("Failed to ioremap\n");
-			continue;
-		}
-
-		simple_map_init(&sbc82xx_flash_map[i]);
-
-		sbcmtd[i] = do_map_probe("cfi_probe", &sbc82xx_flash_map[i]);
-
-		if (!sbcmtd[i])
-			continue;
-
-		sbcmtd[i]->owner = THIS_MODULE;
-
-		/* No partitioning detected. Use default */
-		if (i == 2) {
-			defparts = NULL;
-			nr_parts = 0;
-		} else if (i == bigflash) {
-			defparts = bigflash_parts;
-			nr_parts = ARRAY_SIZE(bigflash_parts);
-		} else {
-			defparts = smallflash_parts;
-			nr_parts = ARRAY_SIZE(smallflash_parts);
-		}
-
-		mtd_device_parse_register(sbcmtd[i], part_probes, NULL,
-					  defparts, nr_parts);
-	}
-	return 0;
-}
-
-static void __exit cleanup_sbc82xx_flash(void)
-{
-	int i;
-
-	for (i=0; i<3; i++) {
-		if (!sbcmtd[i])
-			continue;
-
-		mtd_device_unregister(sbcmtd[i]);
-
-		map_destroy(sbcmtd[i]);
-
-		iounmap((void *)sbc82xx_flash_map[i].virt);
-		sbc82xx_flash_map[i].virt = 0;
-	}
-}
-
-module_init(init_sbc82xx_flash);
-module_exit(cleanup_sbc82xx_flash);
-
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-MODULE_DESCRIPTION("Flash map driver for WindRiver PowerQUICC II");
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index a6e7451..82c0616 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -1162,7 +1162,11 @@
 	resource_size_t start, off;
 	unsigned long len, vma_len;
 
-	if (mtd->type == MTD_RAM || mtd->type == MTD_ROM) {
+        /* This is broken because it assumes the MTD device is map-based
+	   and that mtd->priv is a valid struct map_info.  It should be
+	   replaced with something that uses the mtd_get_unmapped_area()
+	   operation properly. */
+	if (0 /*mtd->type == MTD_RAM || mtd->type == MTD_ROM*/) {
 		off = get_vm_offset(vma);
 		start = map->phys;
 		len = PAGE_ALIGN((start & ~PAGE_MASK) + map->size);
@@ -1182,7 +1186,7 @@
 			return -EINVAL;
 		if (set_vm_offset(vma, off) < 0)
 			return -EINVAL;
-		vma->vm_flags |= VM_IO | VM_RESERVED;
+		vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
 
 #ifdef pgprot_noncached
 		if (file->f_flags & O_DSYNC || off >= __pa(high_memory))
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 5757307..374c46d 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -858,6 +858,27 @@
 }
 EXPORT_SYMBOL_GPL(mtd_panic_write);
 
+int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
+{
+	int ret_code;
+	ops->retlen = ops->oobretlen = 0;
+	if (!mtd->_read_oob)
+		return -EOPNOTSUPP;
+	/*
+	 * In cases where ops->datbuf != NULL, mtd->_read_oob() has semantics
+	 * similar to mtd->_read(), returning a non-negative integer
+	 * representing max bitflips. In other cases, mtd->_read_oob() may
+	 * return -EUCLEAN. In all cases, perform similar logic to mtd_read().
+	 */
+	ret_code = mtd->_read_oob(mtd, from, ops);
+	if (unlikely(ret_code < 0))
+		return ret_code;
+	if (mtd->ecc_strength == 0)
+		return 0;	/* device lacks ecc */
+	return ret_code >= mtd->bitflip_threshold ? -EUCLEAN : 0;
+}
+EXPORT_SYMBOL_GPL(mtd_read_oob);
+
 /*
  * Method to access the protection register area, present in some flash
  * devices. The user data is one time programmable but the factory data is read
@@ -1056,8 +1077,7 @@
  * until the request succeeds or until the allocation size falls below
  * the system page size. This attempts to make sure it does not adversely
  * impact system performance, so when allocating more than one page, we
- * ask the memory allocator to avoid re-trying, swapping, writing back
- * or performing I/O.
+ * ask the memory allocator to avoid re-trying.
  *
  * Note, this function also makes sure that the allocated buffer is aligned to
  * the MTD device's min. I/O unit, i.e. the "mtd->writesize" value.
@@ -1071,8 +1091,7 @@
  */
 void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size)
 {
-	gfp_t flags = __GFP_NOWARN | __GFP_WAIT |
-		       __GFP_NORETRY | __GFP_NO_KSWAPD;
+	gfp_t flags = __GFP_NOWARN | __GFP_WAIT | __GFP_NORETRY;
 	size_t min_alloc = max_t(size_t, mtd->writesize, PAGE_SIZE);
 	void *kbuf;
 
diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c
index 438737a..f5b3f91 100644
--- a/drivers/mtd/mtdoops.c
+++ b/drivers/mtd/mtdoops.c
@@ -169,14 +169,7 @@
 			cxt->nextpage = 0;
 	}
 
-	while (1) {
-		ret = mtd_block_isbad(mtd, cxt->nextpage * record_size);
-		if (!ret)
-			break;
-		if (ret < 0) {
-			printk(KERN_ERR "mtdoops: block_isbad failed, aborting\n");
-			return;
-		}
+	while ((ret = mtd_block_isbad(mtd, cxt->nextpage * record_size)) > 0) {
 badblock:
 		printk(KERN_WARNING "mtdoops: bad block at %08lx\n",
 		       cxt->nextpage * record_size);
@@ -190,6 +183,11 @@
 		}
 	}
 
+	if (ret < 0) {
+		printk(KERN_ERR "mtdoops: mtd_block_isbad failed, aborting\n");
+		return;
+	}
+
 	for (j = 0, ret = -1; (j < 3) && (ret < 0); j++)
 		ret = mtdoops_erase_block(cxt, cxt->nextpage * record_size);
 
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 3a49e6d..70fa70a 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -711,6 +711,8 @@
  * partition parsers, specified in @types. However, if @types is %NULL, then
  * the default list of parsers is used. The default list contains only the
  * "cmdlinepart" and "ofpart" parsers ATM.
+ * Note: If there are more then one parser in @types, the kernel only takes the
+ * partitions parsed out by the first parser.
  *
  * This function may return:
  * o a negative error code in case of failure
@@ -735,11 +737,12 @@
 		if (!parser)
 			continue;
 		ret = (*parser->parse_fn)(master, pparts, data);
+		put_partition_parser(parser);
 		if (ret > 0) {
 			printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n",
 			       ret, parser->name, master->name);
+			break;
 		}
-		put_partition_parser(parser);
 	}
 	return ret;
 }
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 598cd0a..4883139 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -22,15 +22,6 @@
 
 if MTD_NAND
 
-config MTD_NAND_VERIFY_WRITE
-	bool "Verify NAND page writes"
-	help
-	  This adds an extra check when data is written to the flash. The
-	  NAND flash device internally checks only bits transitioning
-	  from 1 to 0. There is a rare possibility that even though the
-	  device thinks the write was successful, a bit could have been
-	  flipped accidentally due to device wear or something else.
-
 config MTD_NAND_BCH
 	tristate
 	select BCH
@@ -267,22 +258,6 @@
 	  when the is NAND chip selected or released, but will save
 	  approximately 5mA of power when there is nothing happening.
 
-config MTD_NAND_BCM_UMI
-	tristate "NAND Flash support for BCM Reference Boards"
-	depends on ARCH_BCMRING
-	help
-	  This enables the NAND flash controller on the BCM UMI block.
-
-	  No board specific support is done by this driver, each board
-	  must advertise a platform_device for the driver to attach.
-
-config MTD_NAND_BCM_UMI_HWCS
-	bool "BCM UMI NAND Hardware CS"
-	depends on MTD_NAND_BCM_UMI
-	help
-	  Enable the use of the BCM UMI block's internal CS using NAND.
-	  This should only be used if you know the external NAND CS can toggle.
-
 config MTD_NAND_DISKONCHIP
 	tristate "DiskOnChip 2000, Millennium and Millennium Plus (NAND reimplementation) (EXPERIMENTAL)"
 	depends on EXPERIMENTAL
@@ -356,7 +331,7 @@
 
 config MTD_NAND_DOCG4
 	tristate "Support for DiskOnChip G4 (EXPERIMENTAL)"
-	depends on EXPERIMENTAL
+	depends on EXPERIMENTAL && HAS_IOMEM
 	select BCH
 	select BITREVERSE
 	help
@@ -414,6 +389,28 @@
 	  This enables the driver for the NAND flash device found on
 	  PXA3xx processors
 
+config MTD_NAND_SLC_LPC32XX
+	tristate "NXP LPC32xx SLC Controller"
+	depends on ARCH_LPC32XX
+	help
+	  Enables support for NXP's LPC32XX SLC (i.e. for Single Level Cell
+	  chips) NAND controller. This is the default for the PHYTEC 3250
+	  reference board which contains a NAND256R3A2CZA6 chip.
+
+	  Please check the actual NAND chip connected and its support
+	  by the SLC NAND controller.
+
+config MTD_NAND_MLC_LPC32XX
+	tristate "NXP LPC32xx MLC Controller"
+	depends on ARCH_LPC32XX
+	help
+	  Uses the LPC32XX MLC (i.e. for Multi Level Cell chips) NAND
+	  controller. This is the default for the WORK92105 controller
+	  board.
+
+	  Please check the actual NAND chip connected and its support
+	  by the MLC NAND controller.
+
 config MTD_NAND_CM_X270
 	tristate "Support for NAND Flash on CM-X270 modules"
 	depends on MACH_ARMCORE
@@ -439,10 +436,10 @@
 	  MTD nand layer.
 
 config MTD_NAND_GPMI_NAND
-        bool "GPMI NAND Flash Controller driver"
+        tristate "GPMI NAND Flash Controller driver"
         depends on MTD_NAND && MXS_DMA
         help
-	 Enables NAND Flash support for IMX23 or IMX28.
+	 Enables NAND Flash support for IMX23, IMX28 or IMX6.
 	 The GPMI controller is very powerful, with the help of BCH
 	 module, it can do the hardware ECC. The GPMI supports several
 	 NAND flashs at the same time. The GPMI may conflicts with other
@@ -510,7 +507,7 @@
 
 config MTD_NAND_MXC
 	tristate "MXC NAND support"
-	depends on IMX_HAVE_PLATFORM_MXC_NAND
+	depends on ARCH_MXC
 	help
 	  This enables the driver for the NAND flash controller on the
 	  MXC processors.
@@ -567,4 +564,12 @@
 	  Enables support for NAND Flash chips on the ST Microelectronics
 	  Flexible Static Memory Controller (FSMC)
 
+config MTD_NAND_XWAY
+	tristate "Support for NAND on Lantiq XWAY SoC"
+	depends on LANTIQ && SOC_TYPE_XWAY
+	select MTD_NAND_PLATFORM
+	help
+	  Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached
+	  to the External Bus Unit (EBU).
+
 endif # MTD_NAND
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index d4b4d87..2cbd091 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -40,16 +40,18 @@
 obj-$(CONFIG_MTD_NAND_FSL_ELBC)		+= fsl_elbc_nand.o
 obj-$(CONFIG_MTD_NAND_FSL_IFC)		+= fsl_ifc_nand.o
 obj-$(CONFIG_MTD_NAND_FSL_UPM)		+= fsl_upm.o
+obj-$(CONFIG_MTD_NAND_SLC_LPC32XX)      += lpc32xx_slc.o
+obj-$(CONFIG_MTD_NAND_MLC_LPC32XX)      += lpc32xx_mlc.o
 obj-$(CONFIG_MTD_NAND_SH_FLCTL)		+= sh_flctl.o
 obj-$(CONFIG_MTD_NAND_MXC)		+= mxc_nand.o
 obj-$(CONFIG_MTD_NAND_SOCRATES)		+= socrates_nand.o
 obj-$(CONFIG_MTD_NAND_TXX9NDFMC)	+= txx9ndfmc.o
 obj-$(CONFIG_MTD_NAND_NUC900)		+= nuc900_nand.o
 obj-$(CONFIG_MTD_NAND_NOMADIK)		+= nomadik_nand.o
-obj-$(CONFIG_MTD_NAND_BCM_UMI)		+= bcm_umi_nand.o nand_bcm_umi.o
 obj-$(CONFIG_MTD_NAND_MPC5121_NFC)	+= mpc5121_nfc.o
 obj-$(CONFIG_MTD_NAND_RICOH)		+= r852.o
 obj-$(CONFIG_MTD_NAND_JZ4740)		+= jz4740_nand.o
 obj-$(CONFIG_MTD_NAND_GPMI_NAND)	+= gpmi-nand/
+obj-$(CONFIG_MTD_NAND_XWAY)		+= xway_nand.o
 
 nand-objs := nand_base.o nand_bbt.o
diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c
index a7040af..9e7723a 100644
--- a/drivers/mtd/nand/ams-delta.c
+++ b/drivers/mtd/nand/ams-delta.c
@@ -107,18 +107,6 @@
 		buf[i] = ams_delta_read_byte(mtd);
 }
 
-static int ams_delta_verify_buf(struct mtd_info *mtd, const u_char *buf,
-				int len)
-{
-	int i;
-
-	for (i=0; i<len; i++)
-		if (buf[i] != ams_delta_read_byte(mtd))
-			return -EFAULT;
-
-	return 0;
-}
-
 /*
  * Command control function
  *
@@ -237,7 +225,6 @@
 	this->read_byte = ams_delta_read_byte;
 	this->write_buf = ams_delta_write_buf;
 	this->read_buf = ams_delta_read_buf;
-	this->verify_buf = ams_delta_verify_buf;
 	this->cmd_ctrl = ams_delta_hwcontrol;
 	if (gpio_request(AMS_DELTA_GPIO_PIN_NAND_RB, "nand_rdy") == 0) {
 		this->dev_ready = ams_delta_nand_ready;
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index 97ac671..9144557 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -1,20 +1,22 @@
 /*
- *  Copyright (C) 2003 Rick Bronson
+ *  Copyright © 2003 Rick Bronson
  *
  *  Derived from drivers/mtd/nand/autcpu12.c
- *	 Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
+ *	 Copyright © 2001 Thomas Gleixner (gleixner@autronix.de)
  *
  *  Derived from drivers/mtd/spia.c
- *	 Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com)
+ *	 Copyright © 2000 Steven J. Hill (sjhill@cotw.com)
  *
  *
  *  Add Hardware ECC support for AT91SAM9260 / AT91SAM9263
- *     Richard Genoud (richard.genoud@gmail.com), Adeneo Copyright (C) 2007
+ *     Richard Genoud (richard.genoud@gmail.com), Adeneo Copyright © 2007
  *
  *     Derived from Das U-Boot source code
  *     		(u-boot-1.1.5/board/atmel/at91sam9263ek/nand.c)
- *     (C) Copyright 2006 ATMEL Rousset, Lacressonniere Nicolas
+ *     © Copyright 2006 ATMEL Rousset, Lacressonniere Nicolas
  *
+ *  Add Programmable Multibit ECC support for various AT91 SoC
+ *     © Copyright 2012 ATMEL, Hong Xu
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -93,8 +95,36 @@
 
 	struct completion	comp;
 	struct dma_chan		*dma_chan;
+
+	bool			has_pmecc;
+	u8			pmecc_corr_cap;
+	u16			pmecc_sector_size;
+	u32			pmecc_lookup_table_offset;
+
+	int			pmecc_bytes_per_sector;
+	int			pmecc_sector_number;
+	int			pmecc_degree;	/* Degree of remainders */
+	int			pmecc_cw_len;	/* Length of codeword */
+
+	void __iomem		*pmerrloc_base;
+	void __iomem		*pmecc_rom_base;
+
+	/* lookup table for alpha_to and index_of */
+	void __iomem		*pmecc_alpha_to;
+	void __iomem		*pmecc_index_of;
+
+	/* data for pmecc computation */
+	int16_t			*pmecc_partial_syn;
+	int16_t			*pmecc_si;
+	int16_t			*pmecc_smu;	/* Sigma table */
+	int16_t			*pmecc_lmu;	/* polynomal order */
+	int			*pmecc_mu;
+	int			*pmecc_dmu;
+	int			*pmecc_delta;
 };
 
+static struct nand_ecclayout atmel_pmecc_oobinfo;
+
 static int cpu_has_dma(void)
 {
 	return cpu_is_at91sam9rl() || cpu_is_at91sam9g45();
@@ -288,6 +318,703 @@
 }
 
 /*
+ * Return number of ecc bytes per sector according to sector size and
+ * correction capability
+ *
+ * Following table shows what at91 PMECC supported:
+ * Correction Capability	Sector_512_bytes	Sector_1024_bytes
+ * =====================	================	=================
+ *                2-bits                 4-bytes                  4-bytes
+ *                4-bits                 7-bytes                  7-bytes
+ *                8-bits                13-bytes                 14-bytes
+ *               12-bits                20-bytes                 21-bytes
+ *               24-bits                39-bytes                 42-bytes
+ */
+static int __devinit pmecc_get_ecc_bytes(int cap, int sector_size)
+{
+	int m = 12 + sector_size / 512;
+	return (m * cap + 7) / 8;
+}
+
+static void __devinit pmecc_config_ecc_layout(struct nand_ecclayout *layout,
+	int oobsize, int ecc_len)
+{
+	int i;
+
+	layout->eccbytes = ecc_len;
+
+	/* ECC will occupy the last ecc_len bytes continuously */
+	for (i = 0; i < ecc_len; i++)
+		layout->eccpos[i] = oobsize - ecc_len + i;
+
+	layout->oobfree[0].offset = 2;
+	layout->oobfree[0].length =
+		oobsize - ecc_len - layout->oobfree[0].offset;
+}
+
+static void __devinit __iomem *pmecc_get_alpha_to(struct atmel_nand_host *host)
+{
+	int table_size;
+
+	table_size = host->pmecc_sector_size == 512 ?
+		PMECC_LOOKUP_TABLE_SIZE_512 : PMECC_LOOKUP_TABLE_SIZE_1024;
+
+	return host->pmecc_rom_base + host->pmecc_lookup_table_offset +
+			table_size * sizeof(int16_t);
+}
+
+static void pmecc_data_free(struct atmel_nand_host *host)
+{
+	kfree(host->pmecc_partial_syn);
+	kfree(host->pmecc_si);
+	kfree(host->pmecc_lmu);
+	kfree(host->pmecc_smu);
+	kfree(host->pmecc_mu);
+	kfree(host->pmecc_dmu);
+	kfree(host->pmecc_delta);
+}
+
+static int __devinit pmecc_data_alloc(struct atmel_nand_host *host)
+{
+	const int cap = host->pmecc_corr_cap;
+
+	host->pmecc_partial_syn = kzalloc((2 * cap + 1) * sizeof(int16_t),
+					GFP_KERNEL);
+	host->pmecc_si = kzalloc((2 * cap + 1) * sizeof(int16_t), GFP_KERNEL);
+	host->pmecc_lmu = kzalloc((cap + 1) * sizeof(int16_t), GFP_KERNEL);
+	host->pmecc_smu = kzalloc((cap + 2) * (2 * cap + 1) * sizeof(int16_t),
+					GFP_KERNEL);
+	host->pmecc_mu = kzalloc((cap + 1) * sizeof(int), GFP_KERNEL);
+	host->pmecc_dmu = kzalloc((cap + 1) * sizeof(int), GFP_KERNEL);
+	host->pmecc_delta = kzalloc((cap + 1) * sizeof(int), GFP_KERNEL);
+
+	if (host->pmecc_partial_syn &&
+			host->pmecc_si &&
+			host->pmecc_lmu &&
+			host->pmecc_smu &&
+			host->pmecc_mu &&
+			host->pmecc_dmu &&
+			host->pmecc_delta)
+		return 0;
+
+	/* error happened */
+	pmecc_data_free(host);
+	return -ENOMEM;
+}
+
+static void pmecc_gen_syndrome(struct mtd_info *mtd, int sector)
+{
+	struct nand_chip *nand_chip = mtd->priv;
+	struct atmel_nand_host *host = nand_chip->priv;
+	int i;
+	uint32_t value;
+
+	/* Fill odd syndromes */
+	for (i = 0; i < host->pmecc_corr_cap; i++) {
+		value = pmecc_readl_rem_relaxed(host->ecc, sector, i / 2);
+		if (i & 1)
+			value >>= 16;
+		value &= 0xffff;
+		host->pmecc_partial_syn[(2 * i) + 1] = (int16_t)value;
+	}
+}
+
+static void pmecc_substitute(struct mtd_info *mtd)
+{
+	struct nand_chip *nand_chip = mtd->priv;
+	struct atmel_nand_host *host = nand_chip->priv;
+	int16_t __iomem *alpha_to = host->pmecc_alpha_to;
+	int16_t __iomem *index_of = host->pmecc_index_of;
+	int16_t *partial_syn = host->pmecc_partial_syn;
+	const int cap = host->pmecc_corr_cap;
+	int16_t *si;
+	int i, j;
+
+	/* si[] is a table that holds the current syndrome value,
+	 * an element of that table belongs to the field
+	 */
+	si = host->pmecc_si;
+
+	memset(&si[1], 0, sizeof(int16_t) * (2 * cap - 1));
+
+	/* Computation 2t syndromes based on S(x) */
+	/* Odd syndromes */
+	for (i = 1; i < 2 * cap; i += 2) {
+		for (j = 0; j < host->pmecc_degree; j++) {
+			if (partial_syn[i] & ((unsigned short)0x1 << j))
+				si[i] = readw_relaxed(alpha_to + i * j) ^ si[i];
+		}
+	}
+	/* Even syndrome = (Odd syndrome) ** 2 */
+	for (i = 2, j = 1; j <= cap; i = ++j << 1) {
+		if (si[j] == 0) {
+			si[i] = 0;
+		} else {
+			int16_t tmp;
+
+			tmp = readw_relaxed(index_of + si[j]);
+			tmp = (tmp * 2) % host->pmecc_cw_len;
+			si[i] = readw_relaxed(alpha_to + tmp);
+		}
+	}
+
+	return;
+}
+
+static void pmecc_get_sigma(struct mtd_info *mtd)
+{
+	struct nand_chip *nand_chip = mtd->priv;
+	struct atmel_nand_host *host = nand_chip->priv;
+
+	int16_t *lmu = host->pmecc_lmu;
+	int16_t *si = host->pmecc_si;
+	int *mu = host->pmecc_mu;
+	int *dmu = host->pmecc_dmu;	/* Discrepancy */
+	int *delta = host->pmecc_delta; /* Delta order */
+	int cw_len = host->pmecc_cw_len;
+	const int16_t cap = host->pmecc_corr_cap;
+	const int num = 2 * cap + 1;
+	int16_t __iomem	*index_of = host->pmecc_index_of;
+	int16_t __iomem	*alpha_to = host->pmecc_alpha_to;
+	int i, j, k;
+	uint32_t dmu_0_count, tmp;
+	int16_t *smu = host->pmecc_smu;
+
+	/* index of largest delta */
+	int ro;
+	int largest;
+	int diff;
+
+	dmu_0_count = 0;
+
+	/* First Row */
+
+	/* Mu */
+	mu[0] = -1;
+
+	memset(smu, 0, sizeof(int16_t) * num);
+	smu[0] = 1;
+
+	/* discrepancy set to 1 */
+	dmu[0] = 1;
+	/* polynom order set to 0 */
+	lmu[0] = 0;
+	delta[0] = (mu[0] * 2 - lmu[0]) >> 1;
+
+	/* Second Row */
+
+	/* Mu */
+	mu[1] = 0;
+	/* Sigma(x) set to 1 */
+	memset(&smu[num], 0, sizeof(int16_t) * num);
+	smu[num] = 1;
+
+	/* discrepancy set to S1 */
+	dmu[1] = si[1];
+
+	/* polynom order set to 0 */
+	lmu[1] = 0;
+
+	delta[1] = (mu[1] * 2 - lmu[1]) >> 1;
+
+	/* Init the Sigma(x) last row */
+	memset(&smu[(cap + 1) * num], 0, sizeof(int16_t) * num);
+
+	for (i = 1; i <= cap; i++) {
+		mu[i + 1] = i << 1;
+		/* Begin Computing Sigma (Mu+1) and L(mu) */
+		/* check if discrepancy is set to 0 */
+		if (dmu[i] == 0) {
+			dmu_0_count++;
+
+			tmp = ((cap - (lmu[i] >> 1) - 1) / 2);
+			if ((cap - (lmu[i] >> 1) - 1) & 0x1)
+				tmp += 2;
+			else
+				tmp += 1;
+
+			if (dmu_0_count == tmp) {
+				for (j = 0; j <= (lmu[i] >> 1) + 1; j++)
+					smu[(cap + 1) * num + j] =
+							smu[i * num + j];
+
+				lmu[cap + 1] = lmu[i];
+				return;
+			}
+
+			/* copy polynom */
+			for (j = 0; j <= lmu[i] >> 1; j++)
+				smu[(i + 1) * num + j] = smu[i * num + j];
+
+			/* copy previous polynom order to the next */
+			lmu[i + 1] = lmu[i];
+		} else {
+			ro = 0;
+			largest = -1;
+			/* find largest delta with dmu != 0 */
+			for (j = 0; j < i; j++) {
+				if ((dmu[j]) && (delta[j] > largest)) {
+					largest = delta[j];
+					ro = j;
+				}
+			}
+
+			/* compute difference */
+			diff = (mu[i] - mu[ro]);
+
+			/* Compute degree of the new smu polynomial */
+			if ((lmu[i] >> 1) > ((lmu[ro] >> 1) + diff))
+				lmu[i + 1] = lmu[i];
+			else
+				lmu[i + 1] = ((lmu[ro] >> 1) + diff) * 2;
+
+			/* Init smu[i+1] with 0 */
+			for (k = 0; k < num; k++)
+				smu[(i + 1) * num + k] = 0;
+
+			/* Compute smu[i+1] */
+			for (k = 0; k <= lmu[ro] >> 1; k++) {
+				int16_t a, b, c;
+
+				if (!(smu[ro * num + k] && dmu[i]))
+					continue;
+				a = readw_relaxed(index_of + dmu[i]);
+				b = readw_relaxed(index_of + dmu[ro]);
+				c = readw_relaxed(index_of + smu[ro * num + k]);
+				tmp = a + (cw_len - b) + c;
+				a = readw_relaxed(alpha_to + tmp % cw_len);
+				smu[(i + 1) * num + (k + diff)] = a;
+			}
+
+			for (k = 0; k <= lmu[i] >> 1; k++)
+				smu[(i + 1) * num + k] ^= smu[i * num + k];
+		}
+
+		/* End Computing Sigma (Mu+1) and L(mu) */
+		/* In either case compute delta */
+		delta[i + 1] = (mu[i + 1] * 2 - lmu[i + 1]) >> 1;
+
+		/* Do not compute discrepancy for the last iteration */
+		if (i >= cap)
+			continue;
+
+		for (k = 0; k <= (lmu[i + 1] >> 1); k++) {
+			tmp = 2 * (i - 1);
+			if (k == 0) {
+				dmu[i + 1] = si[tmp + 3];
+			} else if (smu[(i + 1) * num + k] && si[tmp + 3 - k]) {
+				int16_t a, b, c;
+				a = readw_relaxed(index_of +
+						smu[(i + 1) * num + k]);
+				b = si[2 * (i - 1) + 3 - k];
+				c = readw_relaxed(index_of + b);
+				tmp = a + c;
+				tmp %= cw_len;
+				dmu[i + 1] = readw_relaxed(alpha_to + tmp) ^
+					dmu[i + 1];
+			}
+		}
+	}
+
+	return;
+}
+
+static int pmecc_err_location(struct mtd_info *mtd)
+{
+	struct nand_chip *nand_chip = mtd->priv;
+	struct atmel_nand_host *host = nand_chip->priv;
+	unsigned long end_time;
+	const int cap = host->pmecc_corr_cap;
+	const int num = 2 * cap + 1;
+	int sector_size = host->pmecc_sector_size;
+	int err_nbr = 0;	/* number of error */
+	int roots_nbr;		/* number of roots */
+	int i;
+	uint32_t val;
+	int16_t *smu = host->pmecc_smu;
+
+	pmerrloc_writel(host->pmerrloc_base, ELDIS, PMERRLOC_DISABLE);
+
+	for (i = 0; i <= host->pmecc_lmu[cap + 1] >> 1; i++) {
+		pmerrloc_writel_sigma_relaxed(host->pmerrloc_base, i,
+				      smu[(cap + 1) * num + i]);
+		err_nbr++;
+	}
+
+	val = (err_nbr - 1) << 16;
+	if (sector_size == 1024)
+		val |= 1;
+
+	pmerrloc_writel(host->pmerrloc_base, ELCFG, val);
+	pmerrloc_writel(host->pmerrloc_base, ELEN,
+			sector_size * 8 + host->pmecc_degree * cap);
+
+	end_time = jiffies + msecs_to_jiffies(PMECC_MAX_TIMEOUT_MS);
+	while (!(pmerrloc_readl_relaxed(host->pmerrloc_base, ELISR)
+		 & PMERRLOC_CALC_DONE)) {
+		if (unlikely(time_after(jiffies, end_time))) {
+			dev_err(host->dev, "PMECC: Timeout to calculate error location.\n");
+			return -1;
+		}
+		cpu_relax();
+	}
+
+	roots_nbr = (pmerrloc_readl_relaxed(host->pmerrloc_base, ELISR)
+		& PMERRLOC_ERR_NUM_MASK) >> 8;
+	/* Number of roots == degree of smu hence <= cap */
+	if (roots_nbr == host->pmecc_lmu[cap + 1] >> 1)
+		return err_nbr - 1;
+
+	/* Number of roots does not match the degree of smu
+	 * unable to correct error */
+	return -1;
+}
+
+static void pmecc_correct_data(struct mtd_info *mtd, uint8_t *buf, uint8_t *ecc,
+		int sector_num, int extra_bytes, int err_nbr)
+{
+	struct nand_chip *nand_chip = mtd->priv;
+	struct atmel_nand_host *host = nand_chip->priv;
+	int i = 0;
+	int byte_pos, bit_pos, sector_size, pos;
+	uint32_t tmp;
+	uint8_t err_byte;
+
+	sector_size = host->pmecc_sector_size;
+
+	while (err_nbr) {
+		tmp = pmerrloc_readl_el_relaxed(host->pmerrloc_base, i) - 1;
+		byte_pos = tmp / 8;
+		bit_pos  = tmp % 8;
+
+		if (byte_pos >= (sector_size + extra_bytes))
+			BUG();	/* should never happen */
+
+		if (byte_pos < sector_size) {
+			err_byte = *(buf + byte_pos);
+			*(buf + byte_pos) ^= (1 << bit_pos);
+
+			pos = sector_num * host->pmecc_sector_size + byte_pos;
+			dev_info(host->dev, "Bit flip in data area, byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n",
+				pos, bit_pos, err_byte, *(buf + byte_pos));
+		} else {
+			/* Bit flip in OOB area */
+			tmp = sector_num * host->pmecc_bytes_per_sector
+					+ (byte_pos - sector_size);
+			err_byte = ecc[tmp];
+			ecc[tmp] ^= (1 << bit_pos);
+
+			pos = tmp + nand_chip->ecc.layout->eccpos[0];
+			dev_info(host->dev, "Bit flip in OOB, oob_byte_pos: %d, bit_pos: %d, 0x%02x -> 0x%02x\n",
+				pos, bit_pos, err_byte, ecc[tmp]);
+		}
+
+		i++;
+		err_nbr--;
+	}
+
+	return;
+}
+
+static int pmecc_correction(struct mtd_info *mtd, u32 pmecc_stat, uint8_t *buf,
+	u8 *ecc)
+{
+	struct nand_chip *nand_chip = mtd->priv;
+	struct atmel_nand_host *host = nand_chip->priv;
+	int i, err_nbr, eccbytes;
+	uint8_t *buf_pos;
+
+	eccbytes = nand_chip->ecc.bytes;
+	for (i = 0; i < eccbytes; i++)
+		if (ecc[i] != 0xff)
+			goto normal_check;
+	/* Erased page, return OK */
+	return 0;
+
+normal_check:
+	for (i = 0; i < host->pmecc_sector_number; i++) {
+		err_nbr = 0;
+		if (pmecc_stat & 0x1) {
+			buf_pos = buf + i * host->pmecc_sector_size;
+
+			pmecc_gen_syndrome(mtd, i);
+			pmecc_substitute(mtd);
+			pmecc_get_sigma(mtd);
+
+			err_nbr = pmecc_err_location(mtd);
+			if (err_nbr == -1) {
+				dev_err(host->dev, "PMECC: Too many errors\n");
+				mtd->ecc_stats.failed++;
+				return -EIO;
+			} else {
+				pmecc_correct_data(mtd, buf_pos, ecc, i,
+					host->pmecc_bytes_per_sector, err_nbr);
+				mtd->ecc_stats.corrected += err_nbr;
+			}
+		}
+		pmecc_stat >>= 1;
+	}
+
+	return 0;
+}
+
+static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,
+	struct nand_chip *chip, uint8_t *buf, int oob_required, int page)
+{
+	struct atmel_nand_host *host = chip->priv;
+	int eccsize = chip->ecc.size;
+	uint8_t *oob = chip->oob_poi;
+	uint32_t *eccpos = chip->ecc.layout->eccpos;
+	uint32_t stat;
+	unsigned long end_time;
+
+	pmecc_writel(host->ecc, CTRL, PMECC_CTRL_RST);
+	pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE);
+	pmecc_writel(host->ecc, CFG, (pmecc_readl_relaxed(host->ecc, CFG)
+		& ~PMECC_CFG_WRITE_OP) | PMECC_CFG_AUTO_ENABLE);
+
+	pmecc_writel(host->ecc, CTRL, PMECC_CTRL_ENABLE);
+	pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DATA);
+
+	chip->read_buf(mtd, buf, eccsize);
+	chip->read_buf(mtd, oob, mtd->oobsize);
+
+	end_time = jiffies + msecs_to_jiffies(PMECC_MAX_TIMEOUT_MS);
+	while ((pmecc_readl_relaxed(host->ecc, SR) & PMECC_SR_BUSY)) {
+		if (unlikely(time_after(jiffies, end_time))) {
+			dev_err(host->dev, "PMECC: Timeout to get error status.\n");
+			return -EIO;
+		}
+		cpu_relax();
+	}
+
+	stat = pmecc_readl_relaxed(host->ecc, ISR);
+	if (stat != 0)
+		if (pmecc_correction(mtd, stat, buf, &oob[eccpos[0]]) != 0)
+			return -EIO;
+
+	return 0;
+}
+
+static int atmel_nand_pmecc_write_page(struct mtd_info *mtd,
+		struct nand_chip *chip, const uint8_t *buf, int oob_required)
+{
+	struct atmel_nand_host *host = chip->priv;
+	uint32_t *eccpos = chip->ecc.layout->eccpos;
+	int i, j;
+	unsigned long end_time;
+
+	pmecc_writel(host->ecc, CTRL, PMECC_CTRL_RST);
+	pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE);
+
+	pmecc_writel(host->ecc, CFG, (pmecc_readl_relaxed(host->ecc, CFG) |
+		PMECC_CFG_WRITE_OP) & ~PMECC_CFG_AUTO_ENABLE);
+
+	pmecc_writel(host->ecc, CTRL, PMECC_CTRL_ENABLE);
+	pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DATA);
+
+	chip->write_buf(mtd, (u8 *)buf, mtd->writesize);
+
+	end_time = jiffies + msecs_to_jiffies(PMECC_MAX_TIMEOUT_MS);
+	while ((pmecc_readl_relaxed(host->ecc, SR) & PMECC_SR_BUSY)) {
+		if (unlikely(time_after(jiffies, end_time))) {
+			dev_err(host->dev, "PMECC: Timeout to get ECC value.\n");
+			return -EIO;
+		}
+		cpu_relax();
+	}
+
+	for (i = 0; i < host->pmecc_sector_number; i++) {
+		for (j = 0; j < host->pmecc_bytes_per_sector; j++) {
+			int pos;
+
+			pos = i * host->pmecc_bytes_per_sector + j;
+			chip->oob_poi[eccpos[pos]] =
+				pmecc_readb_ecc_relaxed(host->ecc, i, j);
+		}
+	}
+	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+	return 0;
+}
+
+static void atmel_pmecc_core_init(struct mtd_info *mtd)
+{
+	struct nand_chip *nand_chip = mtd->priv;
+	struct atmel_nand_host *host = nand_chip->priv;
+	uint32_t val = 0;
+	struct nand_ecclayout *ecc_layout;
+
+	pmecc_writel(host->ecc, CTRL, PMECC_CTRL_RST);
+	pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE);
+
+	switch (host->pmecc_corr_cap) {
+	case 2:
+		val = PMECC_CFG_BCH_ERR2;
+		break;
+	case 4:
+		val = PMECC_CFG_BCH_ERR4;
+		break;
+	case 8:
+		val = PMECC_CFG_BCH_ERR8;
+		break;
+	case 12:
+		val = PMECC_CFG_BCH_ERR12;
+		break;
+	case 24:
+		val = PMECC_CFG_BCH_ERR24;
+		break;
+	}
+
+	if (host->pmecc_sector_size == 512)
+		val |= PMECC_CFG_SECTOR512;
+	else if (host->pmecc_sector_size == 1024)
+		val |= PMECC_CFG_SECTOR1024;
+
+	switch (host->pmecc_sector_number) {
+	case 1:
+		val |= PMECC_CFG_PAGE_1SECTOR;
+		break;
+	case 2:
+		val |= PMECC_CFG_PAGE_2SECTORS;
+		break;
+	case 4:
+		val |= PMECC_CFG_PAGE_4SECTORS;
+		break;
+	case 8:
+		val |= PMECC_CFG_PAGE_8SECTORS;
+		break;
+	}
+
+	val |= (PMECC_CFG_READ_OP | PMECC_CFG_SPARE_DISABLE
+		| PMECC_CFG_AUTO_DISABLE);
+	pmecc_writel(host->ecc, CFG, val);
+
+	ecc_layout = nand_chip->ecc.layout;
+	pmecc_writel(host->ecc, SAREA, mtd->oobsize - 1);
+	pmecc_writel(host->ecc, SADDR, ecc_layout->eccpos[0]);
+	pmecc_writel(host->ecc, EADDR,
+			ecc_layout->eccpos[ecc_layout->eccbytes - 1]);
+	/* See datasheet about PMECC Clock Control Register */
+	pmecc_writel(host->ecc, CLK, 2);
+	pmecc_writel(host->ecc, IDR, 0xff);
+	pmecc_writel(host->ecc, CTRL, PMECC_CTRL_ENABLE);
+}
+
+static int __init atmel_pmecc_nand_init_params(struct platform_device *pdev,
+					 struct atmel_nand_host *host)
+{
+	struct mtd_info *mtd = &host->mtd;
+	struct nand_chip *nand_chip = &host->nand_chip;
+	struct resource *regs, *regs_pmerr, *regs_rom;
+	int cap, sector_size, err_no;
+
+	cap = host->pmecc_corr_cap;
+	sector_size = host->pmecc_sector_size;
+	dev_info(host->dev, "Initialize PMECC params, cap: %d, sector: %d\n",
+		 cap, sector_size);
+
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!regs) {
+		dev_warn(host->dev,
+			"Can't get I/O resource regs for PMECC controller, rolling back on software ECC\n");
+		nand_chip->ecc.mode = NAND_ECC_SOFT;
+		return 0;
+	}
+
+	host->ecc = ioremap(regs->start, resource_size(regs));
+	if (host->ecc == NULL) {
+		dev_err(host->dev, "ioremap failed\n");
+		err_no = -EIO;
+		goto err_pmecc_ioremap;
+	}
+
+	regs_pmerr = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+	regs_rom = platform_get_resource(pdev, IORESOURCE_MEM, 3);
+	if (regs_pmerr && regs_rom) {
+		host->pmerrloc_base = ioremap(regs_pmerr->start,
+			resource_size(regs_pmerr));
+		host->pmecc_rom_base = ioremap(regs_rom->start,
+			resource_size(regs_rom));
+	}
+
+	if (!host->pmerrloc_base || !host->pmecc_rom_base) {
+		dev_err(host->dev,
+			"Can not get I/O resource for PMECC ERRLOC controller or ROM!\n");
+		err_no = -EIO;
+		goto err_pmloc_ioremap;
+	}
+
+	/* ECC is calculated for the whole page (1 step) */
+	nand_chip->ecc.size = mtd->writesize;
+
+	/* set ECC page size and oob layout */
+	switch (mtd->writesize) {
+	case 2048:
+		host->pmecc_degree = PMECC_GF_DIMENSION_13;
+		host->pmecc_cw_len = (1 << host->pmecc_degree) - 1;
+		host->pmecc_sector_number = mtd->writesize / sector_size;
+		host->pmecc_bytes_per_sector = pmecc_get_ecc_bytes(
+			cap, sector_size);
+		host->pmecc_alpha_to = pmecc_get_alpha_to(host);
+		host->pmecc_index_of = host->pmecc_rom_base +
+			host->pmecc_lookup_table_offset;
+
+		nand_chip->ecc.steps = 1;
+		nand_chip->ecc.strength = cap;
+		nand_chip->ecc.bytes = host->pmecc_bytes_per_sector *
+				       host->pmecc_sector_number;
+		if (nand_chip->ecc.bytes > mtd->oobsize - 2) {
+			dev_err(host->dev, "No room for ECC bytes\n");
+			err_no = -EINVAL;
+			goto err_no_ecc_room;
+		}
+		pmecc_config_ecc_layout(&atmel_pmecc_oobinfo,
+					mtd->oobsize,
+					nand_chip->ecc.bytes);
+		nand_chip->ecc.layout = &atmel_pmecc_oobinfo;
+		break;
+	case 512:
+	case 1024:
+	case 4096:
+		/* TODO */
+		dev_warn(host->dev,
+			"Unsupported page size for PMECC, use Software ECC\n");
+	default:
+		/* page size not handled by HW ECC */
+		/* switching back to soft ECC */
+		nand_chip->ecc.mode = NAND_ECC_SOFT;
+		return 0;
+	}
+
+	/* Allocate data for PMECC computation */
+	err_no = pmecc_data_alloc(host);
+	if (err_no) {
+		dev_err(host->dev,
+				"Cannot allocate memory for PMECC computation!\n");
+		goto err_pmecc_data_alloc;
+	}
+
+	nand_chip->ecc.read_page = atmel_nand_pmecc_read_page;
+	nand_chip->ecc.write_page = atmel_nand_pmecc_write_page;
+
+	atmel_pmecc_core_init(mtd);
+
+	return 0;
+
+err_pmecc_data_alloc:
+err_no_ecc_room:
+err_pmloc_ioremap:
+	iounmap(host->ecc);
+	if (host->pmerrloc_base)
+		iounmap(host->pmerrloc_base);
+	if (host->pmecc_rom_base)
+		iounmap(host->pmecc_rom_base);
+err_pmecc_ioremap:
+	return err_no;
+}
+
+/*
  * Calculate HW ECC
  *
  * function called after a write
@@ -481,7 +1208,8 @@
 static int __devinit atmel_of_init_port(struct atmel_nand_host *host,
 					 struct device_node *np)
 {
-	u32 val;
+	u32 val, table_offset;
+	u32 offset[2];
 	int ecc_mode;
 	struct atmel_nand_data *board = &host->board;
 	enum of_gpio_flags flags;
@@ -517,6 +1245,50 @@
 	board->enable_pin = of_get_gpio(np, 1);
 	board->det_pin = of_get_gpio(np, 2);
 
+	host->has_pmecc = of_property_read_bool(np, "atmel,has-pmecc");
+
+	if (!(board->ecc_mode == NAND_ECC_HW) || !host->has_pmecc)
+		return 0;	/* Not using PMECC */
+
+	/* use PMECC, get correction capability, sector size and lookup
+	 * table offset.
+	 */
+	if (of_property_read_u32(np, "atmel,pmecc-cap", &val) != 0) {
+		dev_err(host->dev, "Cannot decide PMECC Capability\n");
+		return -EINVAL;
+	} else if ((val != 2) && (val != 4) && (val != 8) && (val != 12) &&
+	    (val != 24)) {
+		dev_err(host->dev,
+			"Unsupported PMECC correction capability: %d; should be 2, 4, 8, 12 or 24\n",
+			val);
+		return -EINVAL;
+	}
+	host->pmecc_corr_cap = (u8)val;
+
+	if (of_property_read_u32(np, "atmel,pmecc-sector-size", &val) != 0) {
+		dev_err(host->dev, "Cannot decide PMECC Sector Size\n");
+		return -EINVAL;
+	} else if ((val != 512) && (val != 1024)) {
+		dev_err(host->dev,
+			"Unsupported PMECC sector size: %d; should be 512 or 1024 bytes\n",
+			val);
+		return -EINVAL;
+	}
+	host->pmecc_sector_size = (u16)val;
+
+	if (of_property_read_u32_array(np, "atmel,pmecc-lookup-table-offset",
+			offset, 2) != 0) {
+		dev_err(host->dev, "Cannot get PMECC lookup table offset\n");
+		return -EINVAL;
+	}
+	table_offset = host->pmecc_sector_size == 512 ? offset[0] : offset[1];
+
+	if (!table_offset) {
+		dev_err(host->dev, "Invalid PMECC lookup table offset\n");
+		return -EINVAL;
+	}
+	host->pmecc_lookup_table_offset = table_offset;
+
 	return 0;
 }
 #else
@@ -527,6 +1299,66 @@
 }
 #endif
 
+static int __init atmel_hw_nand_init_params(struct platform_device *pdev,
+					 struct atmel_nand_host *host)
+{
+	struct mtd_info *mtd = &host->mtd;
+	struct nand_chip *nand_chip = &host->nand_chip;
+	struct resource		*regs;
+
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!regs) {
+		dev_err(host->dev,
+			"Can't get I/O resource regs, use software ECC\n");
+		nand_chip->ecc.mode = NAND_ECC_SOFT;
+		return 0;
+	}
+
+	host->ecc = ioremap(regs->start, resource_size(regs));
+	if (host->ecc == NULL) {
+		dev_err(host->dev, "ioremap failed\n");
+		return -EIO;
+	}
+
+	/* ECC is calculated for the whole page (1 step) */
+	nand_chip->ecc.size = mtd->writesize;
+
+	/* set ECC page size and oob layout */
+	switch (mtd->writesize) {
+	case 512:
+		nand_chip->ecc.layout = &atmel_oobinfo_small;
+		ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_528);
+		break;
+	case 1024:
+		nand_chip->ecc.layout = &atmel_oobinfo_large;
+		ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_1056);
+		break;
+	case 2048:
+		nand_chip->ecc.layout = &atmel_oobinfo_large;
+		ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_2112);
+		break;
+	case 4096:
+		nand_chip->ecc.layout = &atmel_oobinfo_large;
+		ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_4224);
+		break;
+	default:
+		/* page size not handled by HW ECC */
+		/* switching back to soft ECC */
+		nand_chip->ecc.mode = NAND_ECC_SOFT;
+		return 0;
+	}
+
+	/* set up for HW ECC */
+	nand_chip->ecc.calculate = atmel_nand_calculate;
+	nand_chip->ecc.correct = atmel_nand_correct;
+	nand_chip->ecc.hwctl = atmel_nand_hwctl;
+	nand_chip->ecc.read_page = atmel_nand_read_page;
+	nand_chip->ecc.bytes = 4;
+	nand_chip->ecc.strength = 1;
+
+	return 0;
+}
+
 /*
  * Probe for the NAND device.
  */
@@ -535,7 +1367,6 @@
 	struct atmel_nand_host *host;
 	struct mtd_info *mtd;
 	struct nand_chip *nand_chip;
-	struct resource *regs;
 	struct resource *mem;
 	struct mtd_part_parser_data ppdata = {};
 	int res;
@@ -568,7 +1399,7 @@
 	if (pdev->dev.of_node) {
 		res = atmel_of_init_port(host, pdev->dev.of_node);
 		if (res)
-			goto err_nand_ioremap;
+			goto err_ecc_ioremap;
 	} else {
 		memcpy(&host->board, pdev->dev.platform_data,
 		       sizeof(struct atmel_nand_data));
@@ -583,33 +1414,45 @@
 	nand_chip->IO_ADDR_W = host->io_base;
 	nand_chip->cmd_ctrl = atmel_nand_cmd_ctrl;
 
-	if (gpio_is_valid(host->board.rdy_pin))
-		nand_chip->dev_ready = atmel_nand_device_ready;
-
-	nand_chip->ecc.mode = host->board.ecc_mode;
-
-	regs = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-	if (!regs && nand_chip->ecc.mode == NAND_ECC_HW) {
-		printk(KERN_ERR "atmel_nand: can't get I/O resource "
-				"regs\nFalling back on software ECC\n");
-		nand_chip->ecc.mode = NAND_ECC_SOFT;
-	}
-
-	if (nand_chip->ecc.mode == NAND_ECC_HW) {
-		host->ecc = ioremap(regs->start, resource_size(regs));
-		if (host->ecc == NULL) {
-			printk(KERN_ERR "atmel_nand: ioremap failed\n");
-			res = -EIO;
+	if (gpio_is_valid(host->board.rdy_pin)) {
+		res = gpio_request(host->board.rdy_pin, "nand_rdy");
+		if (res < 0) {
+			dev_err(&pdev->dev,
+				"can't request rdy gpio %d\n",
+				host->board.rdy_pin);
 			goto err_ecc_ioremap;
 		}
-		nand_chip->ecc.calculate = atmel_nand_calculate;
-		nand_chip->ecc.correct = atmel_nand_correct;
-		nand_chip->ecc.hwctl = atmel_nand_hwctl;
-		nand_chip->ecc.read_page = atmel_nand_read_page;
-		nand_chip->ecc.bytes = 4;
-		nand_chip->ecc.strength = 1;
+
+		res = gpio_direction_input(host->board.rdy_pin);
+		if (res < 0) {
+			dev_err(&pdev->dev,
+				"can't request input direction rdy gpio %d\n",
+				host->board.rdy_pin);
+			goto err_ecc_ioremap;
+		}
+
+		nand_chip->dev_ready = atmel_nand_device_ready;
 	}
 
+	if (gpio_is_valid(host->board.enable_pin)) {
+		res = gpio_request(host->board.enable_pin, "nand_enable");
+		if (res < 0) {
+			dev_err(&pdev->dev,
+				"can't request enable gpio %d\n",
+				host->board.enable_pin);
+			goto err_ecc_ioremap;
+		}
+
+		res = gpio_direction_output(host->board.enable_pin, 1);
+		if (res < 0) {
+			dev_err(&pdev->dev,
+				"can't request output direction enable gpio %d\n",
+				host->board.enable_pin);
+			goto err_ecc_ioremap;
+		}
+	}
+
+	nand_chip->ecc.mode = host->board.ecc_mode;
 	nand_chip->chip_delay = 20;		/* 20us command delay time */
 
 	if (host->board.bus_width_16)	/* 16-bit bus width */
@@ -622,6 +1465,22 @@
 	atmel_nand_enable(host);
 
 	if (gpio_is_valid(host->board.det_pin)) {
+		res = gpio_request(host->board.det_pin, "nand_det");
+		if (res < 0) {
+			dev_err(&pdev->dev,
+				"can't request det gpio %d\n",
+				host->board.det_pin);
+			goto err_no_card;
+		}
+
+		res = gpio_direction_input(host->board.det_pin);
+		if (res < 0) {
+			dev_err(&pdev->dev,
+				"can't request input direction det gpio %d\n",
+				host->board.det_pin);
+			goto err_no_card;
+		}
+
 		if (gpio_get_value(host->board.det_pin)) {
 			printk(KERN_INFO "No SmartMedia card inserted.\n");
 			res = -ENXIO;
@@ -661,40 +1520,13 @@
 	}
 
 	if (nand_chip->ecc.mode == NAND_ECC_HW) {
-		/* ECC is calculated for the whole page (1 step) */
-		nand_chip->ecc.size = mtd->writesize;
+		if (host->has_pmecc)
+			res = atmel_pmecc_nand_init_params(pdev, host);
+		else
+			res = atmel_hw_nand_init_params(pdev, host);
 
-		/* set ECC page size and oob layout */
-		switch (mtd->writesize) {
-		case 512:
-			nand_chip->ecc.layout = &atmel_oobinfo_small;
-			ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_528);
-			break;
-		case 1024:
-			nand_chip->ecc.layout = &atmel_oobinfo_large;
-			ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_1056);
-			break;
-		case 2048:
-			nand_chip->ecc.layout = &atmel_oobinfo_large;
-			ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_2112);
-			break;
-		case 4096:
-			nand_chip->ecc.layout = &atmel_oobinfo_large;
-			ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_4224);
-			break;
-		default:
-			/* page size not handled by HW ECC */
-			/* switching back to soft ECC */
-			nand_chip->ecc.mode = NAND_ECC_SOFT;
-			nand_chip->ecc.calculate = NULL;
-			nand_chip->ecc.correct = NULL;
-			nand_chip->ecc.hwctl = NULL;
-			nand_chip->ecc.read_page = NULL;
-			nand_chip->ecc.postpad = 0;
-			nand_chip->ecc.prepad = 0;
-			nand_chip->ecc.bytes = 0;
-			break;
-		}
+		if (res != 0)
+			goto err_hw_ecc;
 	}
 
 	/* second phase scan */
@@ -711,14 +1543,23 @@
 		return res;
 
 err_scan_tail:
+	if (host->has_pmecc && host->nand_chip.ecc.mode == NAND_ECC_HW) {
+		pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE);
+		pmecc_data_free(host);
+	}
+	if (host->ecc)
+		iounmap(host->ecc);
+	if (host->pmerrloc_base)
+		iounmap(host->pmerrloc_base);
+	if (host->pmecc_rom_base)
+		iounmap(host->pmecc_rom_base);
+err_hw_ecc:
 err_scan_ident:
 err_no_card:
 	atmel_nand_disable(host);
 	platform_set_drvdata(pdev, NULL);
 	if (host->dma_chan)
 		dma_release_channel(host->dma_chan);
-	if (host->ecc)
-		iounmap(host->ecc);
 err_ecc_ioremap:
 	iounmap(host->io_base);
 err_nand_ioremap:
@@ -738,8 +1579,28 @@
 
 	atmel_nand_disable(host);
 
+	if (host->has_pmecc && host->nand_chip.ecc.mode == NAND_ECC_HW) {
+		pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE);
+		pmerrloc_writel(host->pmerrloc_base, ELDIS,
+				PMERRLOC_DISABLE);
+		pmecc_data_free(host);
+	}
+
+	if (gpio_is_valid(host->board.det_pin))
+		gpio_free(host->board.det_pin);
+
+	if (gpio_is_valid(host->board.enable_pin))
+		gpio_free(host->board.enable_pin);
+
+	if (gpio_is_valid(host->board.rdy_pin))
+		gpio_free(host->board.rdy_pin);
+
 	if (host->ecc)
 		iounmap(host->ecc);
+	if (host->pmecc_rom_base)
+		iounmap(host->pmecc_rom_base);
+	if (host->pmerrloc_base)
+		iounmap(host->pmerrloc_base);
 
 	if (host->dma_chan)
 		dma_release_channel(host->dma_chan);
diff --git a/drivers/mtd/nand/atmel_nand_ecc.h b/drivers/mtd/nand/atmel_nand_ecc.h
index 578c776..8a1e9a6 100644
--- a/drivers/mtd/nand/atmel_nand_ecc.h
+++ b/drivers/mtd/nand/atmel_nand_ecc.h
@@ -3,7 +3,7 @@
  * Based on AT91SAM9260 datasheet revision B.
  *
  * Copyright (C) 2007 Andrew Victor
- * Copyright (C) 2007 Atmel Corporation.
+ * Copyright (C) 2007 - 2012 Atmel Corporation.
  *
  * 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
@@ -36,4 +36,116 @@
 #define ATMEL_ECC_NPR		0x10			/* NParity register */
 #define		ATMEL_ECC_NPARITY	(0xffff << 0)		/* NParity */
 
+/* PMECC Register Definitions */
+#define ATMEL_PMECC_CFG			0x000	/* Configuration Register */
+#define		PMECC_CFG_BCH_ERR2		(0 << 0)
+#define		PMECC_CFG_BCH_ERR4		(1 << 0)
+#define		PMECC_CFG_BCH_ERR8		(2 << 0)
+#define		PMECC_CFG_BCH_ERR12		(3 << 0)
+#define		PMECC_CFG_BCH_ERR24		(4 << 0)
+
+#define		PMECC_CFG_SECTOR512		(0 << 4)
+#define		PMECC_CFG_SECTOR1024		(1 << 4)
+
+#define		PMECC_CFG_PAGE_1SECTOR		(0 << 8)
+#define		PMECC_CFG_PAGE_2SECTORS		(1 << 8)
+#define		PMECC_CFG_PAGE_4SECTORS		(2 << 8)
+#define		PMECC_CFG_PAGE_8SECTORS		(3 << 8)
+
+#define		PMECC_CFG_READ_OP		(0 << 12)
+#define		PMECC_CFG_WRITE_OP		(1 << 12)
+
+#define		PMECC_CFG_SPARE_ENABLE		(1 << 16)
+#define		PMECC_CFG_SPARE_DISABLE		(0 << 16)
+
+#define		PMECC_CFG_AUTO_ENABLE		(1 << 20)
+#define		PMECC_CFG_AUTO_DISABLE		(0 << 20)
+
+#define ATMEL_PMECC_SAREA		0x004	/* Spare area size */
+#define ATMEL_PMECC_SADDR		0x008	/* PMECC starting address */
+#define ATMEL_PMECC_EADDR		0x00c	/* PMECC ending address */
+#define ATMEL_PMECC_CLK			0x010	/* PMECC clock control */
+#define		PMECC_CLK_133MHZ		(2 << 0)
+
+#define ATMEL_PMECC_CTRL		0x014	/* PMECC control register */
+#define		PMECC_CTRL_RST			(1 << 0)
+#define		PMECC_CTRL_DATA			(1 << 1)
+#define		PMECC_CTRL_USER			(1 << 2)
+#define		PMECC_CTRL_ENABLE		(1 << 4)
+#define		PMECC_CTRL_DISABLE		(1 << 5)
+
+#define ATMEL_PMECC_SR			0x018	/* PMECC status register */
+#define		PMECC_SR_BUSY			(1 << 0)
+#define		PMECC_SR_ENABLE			(1 << 4)
+
+#define ATMEL_PMECC_IER			0x01c	/* PMECC interrupt enable */
+#define		PMECC_IER_ENABLE		(1 << 0)
+#define ATMEL_PMECC_IDR			0x020	/* PMECC interrupt disable */
+#define		PMECC_IER_DISABLE		(1 << 0)
+#define ATMEL_PMECC_IMR			0x024	/* PMECC interrupt mask */
+#define		PMECC_IER_MASK			(1 << 0)
+#define ATMEL_PMECC_ISR			0x028	/* PMECC interrupt status */
+#define ATMEL_PMECC_ECCx		0x040	/* PMECC ECC x */
+#define ATMEL_PMECC_REMx		0x240	/* PMECC REM x */
+
+/* PMERRLOC Register Definitions */
+#define ATMEL_PMERRLOC_ELCFG		0x000	/* Error location config */
+#define		PMERRLOC_ELCFG_SECTOR_512	(0 << 0)
+#define		PMERRLOC_ELCFG_SECTOR_1024	(1 << 0)
+#define		PMERRLOC_ELCFG_NUM_ERRORS(n)	((n) << 16)
+
+#define ATMEL_PMERRLOC_ELPRIM		0x004	/* Error location primitive */
+#define ATMEL_PMERRLOC_ELEN		0x008	/* Error location enable */
+#define ATMEL_PMERRLOC_ELDIS		0x00c	/* Error location disable */
+#define		PMERRLOC_DISABLE		(1 << 0)
+
+#define ATMEL_PMERRLOC_ELSR		0x010	/* Error location status */
+#define		PMERRLOC_ELSR_BUSY		(1 << 0)
+#define ATMEL_PMERRLOC_ELIER		0x014	/* Error location int enable */
+#define ATMEL_PMERRLOC_ELIDR		0x018	/* Error location int disable */
+#define ATMEL_PMERRLOC_ELIMR		0x01c	/* Error location int mask */
+#define ATMEL_PMERRLOC_ELISR		0x020	/* Error location int status */
+#define		PMERRLOC_ERR_NUM_MASK		(0x1f << 8)
+#define		PMERRLOC_CALC_DONE		(1 << 0)
+#define ATMEL_PMERRLOC_SIGMAx		0x028	/* Error location SIGMA x */
+#define ATMEL_PMERRLOC_ELx		0x08c	/* Error location x */
+
+/* Register access macros for PMECC */
+#define pmecc_readl_relaxed(addr, reg) \
+	readl_relaxed((addr) + ATMEL_PMECC_##reg)
+
+#define pmecc_writel(addr, reg, value) \
+	writel((value), (addr) + ATMEL_PMECC_##reg)
+
+#define pmecc_readb_ecc_relaxed(addr, sector, n) \
+	readb_relaxed((addr) + ATMEL_PMECC_ECCx + ((sector) * 0x40) + (n))
+
+#define pmecc_readl_rem_relaxed(addr, sector, n) \
+	readl_relaxed((addr) + ATMEL_PMECC_REMx + ((sector) * 0x40) + ((n) * 4))
+
+#define pmerrloc_readl_relaxed(addr, reg) \
+	readl_relaxed((addr) + ATMEL_PMERRLOC_##reg)
+
+#define pmerrloc_writel(addr, reg, value) \
+	writel((value), (addr) + ATMEL_PMERRLOC_##reg)
+
+#define pmerrloc_writel_sigma_relaxed(addr, n, value) \
+	writel_relaxed((value), (addr) + ATMEL_PMERRLOC_SIGMAx + ((n) * 4))
+
+#define pmerrloc_readl_sigma_relaxed(addr, n) \
+	readl_relaxed((addr) + ATMEL_PMERRLOC_SIGMAx + ((n) * 4))
+
+#define pmerrloc_readl_el_relaxed(addr, n) \
+	readl_relaxed((addr) + ATMEL_PMERRLOC_ELx + ((n) * 4))
+
+/* Galois field dimension */
+#define PMECC_GF_DIMENSION_13			13
+#define PMECC_GF_DIMENSION_14			14
+
+#define PMECC_LOOKUP_TABLE_SIZE_512		0x2000
+#define PMECC_LOOKUP_TABLE_SIZE_1024		0x4000
+
+/* Time out value for reading PMECC status register */
+#define PMECC_MAX_TIMEOUT_MS			100
+
 #endif
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c
index 9f609d2..5c47b20 100644
--- a/drivers/mtd/nand/au1550nd.c
+++ b/drivers/mtd/nand/au1550nd.c
@@ -141,28 +141,6 @@
 }
 
 /**
- * au_verify_buf -  Verify chip data against buffer
- * @mtd:	MTD device structure
- * @buf:	buffer containing the data to compare
- * @len:	number of bytes to compare
- *
- * verify function for 8bit buswidth
- */
-static int au_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
-{
-	int i;
-	struct nand_chip *this = mtd->priv;
-
-	for (i = 0; i < len; i++) {
-		if (buf[i] != readb(this->IO_ADDR_R))
-			return -EFAULT;
-		au_sync();
-	}
-
-	return 0;
-}
-
-/**
  * au_write_buf16 -  write buffer to chip
  * @mtd:	MTD device structure
  * @buf:	data buffer
@@ -205,29 +183,6 @@
 	}
 }
 
-/**
- * au_verify_buf16 -  Verify chip data against buffer
- * @mtd:	MTD device structure
- * @buf:	buffer containing the data to compare
- * @len:	number of bytes to compare
- *
- * verify function for 16bit buswidth
- */
-static int au_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len)
-{
-	int i;
-	struct nand_chip *this = mtd->priv;
-	u16 *p = (u16 *) buf;
-	len >>= 1;
-
-	for (i = 0; i < len; i++) {
-		if (p[i] != readw(this->IO_ADDR_R))
-			return -EFAULT;
-		au_sync();
-	}
-	return 0;
-}
-
 /* Select the chip by setting nCE to low */
 #define NAND_CTL_SETNCE		1
 /* Deselect the chip by setting nCE to high */
@@ -516,7 +471,6 @@
 	this->read_word = au_read_word;
 	this->write_buf = (pd->devwidth) ? au_write_buf16 : au_write_buf;
 	this->read_buf = (pd->devwidth) ? au_read_buf16 : au_read_buf;
-	this->verify_buf = (pd->devwidth) ? au_verify_buf16 : au_verify_buf;
 
 	ret = nand_scan(&ctx->info, 1);
 	if (ret) {
diff --git a/drivers/mtd/nand/bcm_umi_bch.c b/drivers/mtd/nand/bcm_umi_bch.c
deleted file mode 100644
index 5914bb3..0000000
--- a/drivers/mtd/nand/bcm_umi_bch.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/*****************************************************************************
-* Copyright 2004 - 2009 Broadcom Corporation.  All rights reserved.
-*
-* Unless you and Broadcom execute a separate written software license
-* agreement governing use of this software, this software is licensed to you
-* under the terms of the GNU General Public License version 2, available at
-* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
-*
-* Notwithstanding the above, under no circumstances may you combine this
-* software in any way with any other Broadcom software provided under a
-* license other than the GPL, without Broadcom's express prior written
-* consent.
-*****************************************************************************/
-
-/* ---- Include Files ---------------------------------------------------- */
-#include "nand_bcm_umi.h"
-
-/* ---- External Variable Declarations ----------------------------------- */
-/* ---- External Function Prototypes ------------------------------------- */
-/* ---- Public Variables ------------------------------------------------- */
-/* ---- Private Constants and Types -------------------------------------- */
-
-/* ---- Private Function Prototypes -------------------------------------- */
-static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd,
-	struct nand_chip *chip, uint8_t *buf, int oob_required, int page);
-static void bcm_umi_bch_write_page_hwecc(struct mtd_info *mtd,
-	struct nand_chip *chip, const uint8_t *buf, int oob_required);
-
-/* ---- Private Variables ------------------------------------------------ */
-
-/*
-** nand_hw_eccoob
-** New oob placement block for use with hardware ecc generation.
-*/
-static struct nand_ecclayout nand_hw_eccoob_512 = {
-	/* Reserve 5 for BI indicator */
-	.oobfree = {
-#if (NAND_ECC_NUM_BYTES > 3)
-		    {.offset = 0, .length = 2}
-#else
-		    {.offset = 0, .length = 5},
-		    {.offset = 6, .length = 7}
-#endif
-		    }
-};
-
-/*
-** We treat the OOB for a 2K page as if it were 4 512 byte oobs,
-** except the BI is at byte 0.
-*/
-static struct nand_ecclayout nand_hw_eccoob_2048 = {
-	/* Reserve 0 as BI indicator */
-	.oobfree = {
-#if (NAND_ECC_NUM_BYTES > 10)
-		    {.offset = 1, .length = 2},
-#elif (NAND_ECC_NUM_BYTES > 7)
-		    {.offset = 1, .length = 5},
-		    {.offset = 16, .length = 6},
-		    {.offset = 32, .length = 6},
-		    {.offset = 48, .length = 6}
-#else
-		    {.offset = 1, .length = 8},
-		    {.offset = 16, .length = 9},
-		    {.offset = 32, .length = 9},
-		    {.offset = 48, .length = 9}
-#endif
-		    }
-};
-
-/* We treat the OOB for a 4K page as if it were 8 512 byte oobs,
- * except the BI is at byte 0. */
-static struct nand_ecclayout nand_hw_eccoob_4096 = {
-	/* Reserve 0 as BI indicator */
-	.oobfree = {
-#if (NAND_ECC_NUM_BYTES > 10)
-		    {.offset = 1, .length = 2},
-		    {.offset = 16, .length = 3},
-		    {.offset = 32, .length = 3},
-		    {.offset = 48, .length = 3},
-		    {.offset = 64, .length = 3},
-		    {.offset = 80, .length = 3},
-		    {.offset = 96, .length = 3},
-		    {.offset = 112, .length = 3}
-#else
-		    {.offset = 1, .length = 5},
-		    {.offset = 16, .length = 6},
-		    {.offset = 32, .length = 6},
-		    {.offset = 48, .length = 6},
-		    {.offset = 64, .length = 6},
-		    {.offset = 80, .length = 6},
-		    {.offset = 96, .length = 6},
-		    {.offset = 112, .length = 6}
-#endif
-		    }
-};
-
-/* ---- Private Functions ------------------------------------------------ */
-/* ==== Public Functions ================================================= */
-
-/****************************************************************************
-*
-*  bcm_umi_bch_read_page_hwecc - hardware ecc based page read function
-*  @mtd:	mtd info structure
-*  @chip:	nand chip info structure
-*  @buf:	buffer to store read data
-*  @oob_required:	caller expects OOB data read to chip->oob_poi
-*
-***************************************************************************/
-static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd,
-				       struct nand_chip *chip, uint8_t * buf,
-				       int oob_required, int page)
-{
-	int sectorIdx = 0;
-	int eccsize = chip->ecc.size;
-	int eccsteps = chip->ecc.steps;
-	uint8_t *datap = buf;
-	uint8_t eccCalc[NAND_ECC_NUM_BYTES];
-	int sectorOobSize = mtd->oobsize / eccsteps;
-	int stat;
-	unsigned int max_bitflips = 0;
-
-	for (sectorIdx = 0; sectorIdx < eccsteps;
-			sectorIdx++, datap += eccsize) {
-		if (sectorIdx > 0) {
-			/* Seek to page location within sector */
-			chip->cmdfunc(mtd, NAND_CMD_RNDOUT, sectorIdx * eccsize,
-				      -1);
-		}
-
-		/* Enable hardware ECC before reading the buf */
-		nand_bcm_umi_bch_enable_read_hwecc();
-
-		/* Read in data */
-		bcm_umi_nand_read_buf(mtd, datap, eccsize);
-
-		/* Pause hardware ECC after reading the buf */
-		nand_bcm_umi_bch_pause_read_ecc_calc();
-
-		/* Read the OOB ECC */
-		chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
-			      mtd->writesize + sectorIdx * sectorOobSize, -1);
-		nand_bcm_umi_bch_read_oobEcc(mtd->writesize, eccCalc,
-					     NAND_ECC_NUM_BYTES,
-					     chip->oob_poi +
-					     sectorIdx * sectorOobSize);
-
-		/* Correct any ECC detected errors */
-		stat =
-		    nand_bcm_umi_bch_correct_page(datap, eccCalc,
-						  NAND_ECC_NUM_BYTES);
-
-		/* Update Stats */
-		if (stat < 0) {
-#if defined(NAND_BCM_UMI_DEBUG)
-			printk(KERN_WARNING "%s uncorr_err sectorIdx=%d\n",
-			       __func__, sectorIdx);
-			printk(KERN_WARNING
-			       "%s data %02x %02x %02x %02x "
-					 "%02x %02x %02x %02x\n",
-			       __func__, datap[0], datap[1], datap[2], datap[3],
-			       datap[4], datap[5], datap[6], datap[7]);
-			printk(KERN_WARNING
-			       "%s ecc  %02x %02x %02x %02x "
-					 "%02x %02x %02x %02x %02x %02x "
-					 "%02x %02x %02x\n",
-			       __func__, eccCalc[0], eccCalc[1], eccCalc[2],
-			       eccCalc[3], eccCalc[4], eccCalc[5], eccCalc[6],
-			       eccCalc[7], eccCalc[8], eccCalc[9], eccCalc[10],
-			       eccCalc[11], eccCalc[12]);
-			BUG();
-#endif
-			mtd->ecc_stats.failed++;
-		} else {
-#if defined(NAND_BCM_UMI_DEBUG)
-			if (stat > 0) {
-				printk(KERN_INFO
-				       "%s %d correctable_errors detected\n",
-				       __func__, stat);
-			}
-#endif
-			mtd->ecc_stats.corrected += stat;
-			max_bitflips = max_t(unsigned int, max_bitflips, stat);
-		}
-	}
-	return max_bitflips;
-}
-
-/****************************************************************************
-*
-*  bcm_umi_bch_write_page_hwecc - hardware ecc based page write function
-*  @mtd:	mtd info structure
-*  @chip:	nand chip info structure
-*  @buf:	data buffer
-*  @oob_required:	must write chip->oob_poi to OOB
-*
-***************************************************************************/
-static void bcm_umi_bch_write_page_hwecc(struct mtd_info *mtd,
-	struct nand_chip *chip, const uint8_t *buf, int oob_required)
-{
-	int sectorIdx = 0;
-	int eccsize = chip->ecc.size;
-	int eccsteps = chip->ecc.steps;
-	const uint8_t *datap = buf;
-	uint8_t *oobp = chip->oob_poi;
-	int sectorOobSize = mtd->oobsize / eccsteps;
-
-	for (sectorIdx = 0; sectorIdx < eccsteps;
-	     sectorIdx++, datap += eccsize, oobp += sectorOobSize) {
-		/* Enable hardware ECC before writing the buf */
-		nand_bcm_umi_bch_enable_write_hwecc();
-		bcm_umi_nand_write_buf(mtd, datap, eccsize);
-		nand_bcm_umi_bch_write_oobEcc(mtd->writesize, oobp,
-					      NAND_ECC_NUM_BYTES);
-	}
-
-	bcm_umi_nand_write_buf(mtd, chip->oob_poi, mtd->oobsize);
-}
diff --git a/drivers/mtd/nand/bcm_umi_nand.c b/drivers/mtd/nand/bcm_umi_nand.c
deleted file mode 100644
index d0d1bd4..0000000
--- a/drivers/mtd/nand/bcm_umi_nand.c
+++ /dev/null
@@ -1,555 +0,0 @@
-/*****************************************************************************
-* Copyright 2004 - 2009 Broadcom Corporation.  All rights reserved.
-*
-* Unless you and Broadcom execute a separate written software license
-* agreement governing use of this software, this software is licensed to you
-* under the terms of the GNU General Public License version 2, available at
-* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
-*
-* Notwithstanding the above, under no circumstances may you combine this
-* software in any way with any other Broadcom software provided under a
-* license other than the GPL, without Broadcom's express prior written
-* consent.
-*****************************************************************************/
-
-/* ---- Include Files ---------------------------------------------------- */
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/nand_ecc.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/mach-types.h>
-
-#include <mach/reg_nand.h>
-#include <mach/reg_umi.h>
-
-#include "nand_bcm_umi.h"
-
-#include <mach/memory_settings.h>
-
-#define USE_DMA 1
-#include <mach/dma.h>
-#include <linux/dma-mapping.h>
-#include <linux/completion.h>
-
-/* ---- External Variable Declarations ----------------------------------- */
-/* ---- External Function Prototypes ------------------------------------- */
-/* ---- Public Variables ------------------------------------------------- */
-/* ---- Private Constants and Types -------------------------------------- */
-static const __devinitconst char gBanner[] = KERN_INFO \
-	"BCM UMI MTD NAND Driver: 1.00\n";
-
-#if NAND_ECC_BCH
-static uint8_t scan_ff_pattern[] = { 0xff };
-
-static struct nand_bbt_descr largepage_bbt = {
-	.options = 0,
-	.offs = 0,
-	.len = 1,
-	.pattern = scan_ff_pattern
-};
-#endif
-
-/*
-** Preallocate a buffer to avoid having to do this every dma operation.
-** This is the size of the preallocated coherent DMA buffer.
-*/
-#if USE_DMA
-#define DMA_MIN_BUFLEN	512
-#define DMA_MAX_BUFLEN	PAGE_SIZE
-#define USE_DIRECT_IO(len)	(((len) < DMA_MIN_BUFLEN) || \
-	((len) > DMA_MAX_BUFLEN))
-
-/*
- * The current NAND data space goes from 0x80001900 to 0x80001FFF,
- * which is only 0x700 = 1792 bytes long. This is too small for 2K, 4K page
- * size NAND flash. Need to break the DMA down to multiple 1Ks.
- *
- * Need to make sure REG_NAND_DATA_PADDR + DMA_MAX_LEN < 0x80002000
- */
-#define DMA_MAX_LEN             1024
-
-#else /* !USE_DMA */
-#define DMA_MIN_BUFLEN          0
-#define DMA_MAX_BUFLEN          0
-#define USE_DIRECT_IO(len)      1
-#endif
-/* ---- Private Function Prototypes -------------------------------------- */
-static void bcm_umi_nand_read_buf(struct mtd_info *mtd, u_char * buf, int len);
-static void bcm_umi_nand_write_buf(struct mtd_info *mtd, const u_char * buf,
-				   int len);
-
-/* ---- Private Variables ------------------------------------------------ */
-static struct mtd_info *board_mtd;
-static void __iomem *bcm_umi_io_base;
-static void *virtPtr;
-static dma_addr_t physPtr;
-static struct completion nand_comp;
-
-/* ---- Private Functions ------------------------------------------------ */
-#if NAND_ECC_BCH
-#include "bcm_umi_bch.c"
-#else
-#include "bcm_umi_hamming.c"
-#endif
-
-#if USE_DMA
-
-/* Handler called when the DMA finishes. */
-static void nand_dma_handler(DMA_Device_t dev, int reason, void *userData)
-{
-	complete(&nand_comp);
-}
-
-static int nand_dma_init(void)
-{
-	int rc;
-
-	rc = dma_set_device_handler(DMA_DEVICE_NAND_MEM_TO_MEM,
-		nand_dma_handler, NULL);
-	if (rc != 0) {
-		printk(KERN_ERR "dma_set_device_handler failed: %d\n", rc);
-		return rc;
-	}
-
-	virtPtr =
-	    dma_alloc_coherent(NULL, DMA_MAX_BUFLEN, &physPtr, GFP_KERNEL);
-	if (virtPtr == NULL) {
-		printk(KERN_ERR "NAND - Failed to allocate memory for DMA buffer\n");
-		return -ENOMEM;
-	}
-
-	return 0;
-}
-
-static void nand_dma_term(void)
-{
-	if (virtPtr != NULL)
-		dma_free_coherent(NULL, DMA_MAX_BUFLEN, virtPtr, physPtr);
-}
-
-static void nand_dma_read(void *buf, int len)
-{
-	int offset = 0;
-	int tmp_len = 0;
-	int len_left = len;
-	DMA_Handle_t hndl;
-
-	if (virtPtr == NULL)
-		panic("nand_dma_read: virtPtr == NULL\n");
-
-	if ((void *)physPtr == NULL)
-		panic("nand_dma_read: physPtr == NULL\n");
-
-	hndl = dma_request_channel(DMA_DEVICE_NAND_MEM_TO_MEM);
-	if (hndl < 0) {
-		printk(KERN_ERR
-		       "nand_dma_read: unable to allocate dma channel: %d\n",
-		       (int)hndl);
-		panic("\n");
-	}
-
-	while (len_left > 0) {
-		if (len_left > DMA_MAX_LEN) {
-			tmp_len = DMA_MAX_LEN;
-			len_left -= DMA_MAX_LEN;
-		} else {
-			tmp_len = len_left;
-			len_left = 0;
-		}
-
-		init_completion(&nand_comp);
-		dma_transfer_mem_to_mem(hndl, REG_NAND_DATA_PADDR,
-					physPtr + offset, tmp_len);
-		wait_for_completion(&nand_comp);
-
-		offset += tmp_len;
-	}
-
-	dma_free_channel(hndl);
-
-	if (buf != NULL)
-		memcpy(buf, virtPtr, len);
-}
-
-static void nand_dma_write(const void *buf, int len)
-{
-	int offset = 0;
-	int tmp_len = 0;
-	int len_left = len;
-	DMA_Handle_t hndl;
-
-	if (buf == NULL)
-		panic("nand_dma_write: buf == NULL\n");
-
-	if (virtPtr == NULL)
-		panic("nand_dma_write: virtPtr == NULL\n");
-
-	if ((void *)physPtr == NULL)
-		panic("nand_dma_write: physPtr == NULL\n");
-
-	memcpy(virtPtr, buf, len);
-
-
-	hndl = dma_request_channel(DMA_DEVICE_NAND_MEM_TO_MEM);
-	if (hndl < 0) {
-		printk(KERN_ERR
-		       "nand_dma_write: unable to allocate dma channel: %d\n",
-		       (int)hndl);
-		panic("\n");
-	}
-
-	while (len_left > 0) {
-		if (len_left > DMA_MAX_LEN) {
-			tmp_len = DMA_MAX_LEN;
-			len_left -= DMA_MAX_LEN;
-		} else {
-			tmp_len = len_left;
-			len_left = 0;
-		}
-
-		init_completion(&nand_comp);
-		dma_transfer_mem_to_mem(hndl, physPtr + offset,
-					REG_NAND_DATA_PADDR, tmp_len);
-		wait_for_completion(&nand_comp);
-
-		offset += tmp_len;
-	}
-
-	dma_free_channel(hndl);
-}
-
-#endif
-
-static int nand_dev_ready(struct mtd_info *mtd)
-{
-	return nand_bcm_umi_dev_ready();
-}
-
-/****************************************************************************
-*
-*  bcm_umi_nand_inithw
-*
-*   This routine does the necessary hardware (board-specific)
-*   initializations.  This includes setting up the timings, etc.
-*
-***************************************************************************/
-int bcm_umi_nand_inithw(void)
-{
-	/* Configure nand timing parameters */
-	writel(readl(&REG_UMI_NAND_TCR) & ~0x7ffff, &REG_UMI_NAND_TCR);
-	writel(readl(&REG_UMI_NAND_TCR) | HW_CFG_NAND_TCR, &REG_UMI_NAND_TCR);
-
-#if !defined(CONFIG_MTD_NAND_BCM_UMI_HWCS)
-	/* enable software control of CS */
-	writel(readl(&REG_UMI_NAND_TCR) | REG_UMI_NAND_TCR_CS_SWCTRL, &REG_UMI_NAND_TCR);
-#endif
-
-	/* keep NAND chip select asserted */
-	writel(readl(&REG_UMI_NAND_RCSR) | REG_UMI_NAND_RCSR_CS_ASSERTED, &REG_UMI_NAND_RCSR);
-
-	writel(readl(&REG_UMI_NAND_TCR) & ~REG_UMI_NAND_TCR_WORD16, &REG_UMI_NAND_TCR);
-	/* enable writes to flash */
-	writel(readl(&REG_UMI_MMD_ICR) | REG_UMI_MMD_ICR_FLASH_WP, &REG_UMI_MMD_ICR);
-
-	writel(NAND_CMD_RESET, bcm_umi_io_base + REG_NAND_CMD_OFFSET);
-	nand_bcm_umi_wait_till_ready();
-
-#if NAND_ECC_BCH
-	nand_bcm_umi_bch_config_ecc(NAND_ECC_NUM_BYTES);
-#endif
-
-	return 0;
-}
-
-/* Used to turn latch the proper register for access. */
-static void bcm_umi_nand_hwcontrol(struct mtd_info *mtd, int cmd,
-				   unsigned int ctrl)
-{
-	/* send command to hardware */
-	struct nand_chip *chip = mtd->priv;
-	if (ctrl & NAND_CTRL_CHANGE) {
-		if (ctrl & NAND_CLE) {
-			chip->IO_ADDR_W = bcm_umi_io_base + REG_NAND_CMD_OFFSET;
-			goto CMD;
-		}
-		if (ctrl & NAND_ALE) {
-			chip->IO_ADDR_W =
-			    bcm_umi_io_base + REG_NAND_ADDR_OFFSET;
-			goto CMD;
-		}
-		chip->IO_ADDR_W = bcm_umi_io_base + REG_NAND_DATA8_OFFSET;
-	}
-
-CMD:
-	/* Send command to chip directly */
-	if (cmd != NAND_CMD_NONE)
-		writeb(cmd, chip->IO_ADDR_W);
-}
-
-static void bcm_umi_nand_write_buf(struct mtd_info *mtd, const u_char * buf,
-				   int len)
-{
-	if (USE_DIRECT_IO(len)) {
-		/* Do it the old way if the buffer is small or too large.
-		 * Probably quicker than starting and checking dma. */
-		int i;
-		struct nand_chip *this = mtd->priv;
-
-		for (i = 0; i < len; i++)
-			writeb(buf[i], this->IO_ADDR_W);
-	}
-#if USE_DMA
-	else
-		nand_dma_write(buf, len);
-#endif
-}
-
-static void bcm_umi_nand_read_buf(struct mtd_info *mtd, u_char * buf, int len)
-{
-	if (USE_DIRECT_IO(len)) {
-		int i;
-		struct nand_chip *this = mtd->priv;
-
-		for (i = 0; i < len; i++)
-			buf[i] = readb(this->IO_ADDR_R);
-	}
-#if USE_DMA
-	else
-		nand_dma_read(buf, len);
-#endif
-}
-
-static uint8_t readbackbuf[NAND_MAX_PAGESIZE];
-static int bcm_umi_nand_verify_buf(struct mtd_info *mtd, const u_char * buf,
-				   int len)
-{
-	/*
-	 * Try to readback page with ECC correction. This is necessary
-	 * for MLC parts which may have permanently stuck bits.
-	 */
-	struct nand_chip *chip = mtd->priv;
-	int ret = chip->ecc.read_page(mtd, chip, readbackbuf, 0, 0);
-	if (ret < 0)
-		return -EFAULT;
-	else {
-		if (memcmp(readbackbuf, buf, len) == 0)
-			return 0;
-
-		return -EFAULT;
-	}
-	return 0;
-}
-
-static int __devinit bcm_umi_nand_probe(struct platform_device *pdev)
-{
-	struct nand_chip *this;
-	struct resource *r;
-	int err = 0;
-
-	printk(gBanner);
-
-	/* Allocate memory for MTD device structure and private data */
-	board_mtd =
-	    kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip),
-		    GFP_KERNEL);
-	if (!board_mtd) {
-		printk(KERN_WARNING
-		       "Unable to allocate NAND MTD device structure.\n");
-		return -ENOMEM;
-	}
-
-	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
-	if (!r) {
-		err = -ENXIO;
-		goto out_free;
-	}
-
-	/* map physical address */
-	bcm_umi_io_base = ioremap(r->start, resource_size(r));
-
-	if (!bcm_umi_io_base) {
-		printk(KERN_ERR "ioremap to access BCM UMI NAND chip failed\n");
-		err = -EIO;
-		goto out_free;
-	}
-
-	/* Get pointer to private data */
-	this = (struct nand_chip *)(&board_mtd[1]);
-
-	/* Initialize structures */
-	memset((char *)board_mtd, 0, sizeof(struct mtd_info));
-	memset((char *)this, 0, sizeof(struct nand_chip));
-
-	/* Link the private data with the MTD structure */
-	board_mtd->priv = this;
-
-	/* Initialize the NAND hardware.  */
-	if (bcm_umi_nand_inithw() < 0) {
-		printk(KERN_ERR "BCM UMI NAND chip could not be initialized\n");
-		err = -EIO;
-		goto out_unmap;
-	}
-
-	/* Set address of NAND IO lines */
-	this->IO_ADDR_W = bcm_umi_io_base + REG_NAND_DATA8_OFFSET;
-	this->IO_ADDR_R = bcm_umi_io_base + REG_NAND_DATA8_OFFSET;
-
-	/* Set command delay time, see datasheet for correct value */
-	this->chip_delay = 0;
-	/* Assign the device ready function, if available */
-	this->dev_ready = nand_dev_ready;
-	this->options = 0;
-
-	this->write_buf = bcm_umi_nand_write_buf;
-	this->read_buf = bcm_umi_nand_read_buf;
-	this->verify_buf = bcm_umi_nand_verify_buf;
-
-	this->cmd_ctrl = bcm_umi_nand_hwcontrol;
-	this->ecc.mode = NAND_ECC_HW;
-	this->ecc.size = 512;
-	this->ecc.bytes = NAND_ECC_NUM_BYTES;
-#if NAND_ECC_BCH
-	this->ecc.read_page = bcm_umi_bch_read_page_hwecc;
-	this->ecc.write_page = bcm_umi_bch_write_page_hwecc;
-#else
-	this->ecc.correct = nand_correct_data512;
-	this->ecc.calculate = bcm_umi_hamming_get_hw_ecc;
-	this->ecc.hwctl = bcm_umi_hamming_enable_hwecc;
-#endif
-
-#if USE_DMA
-	err = nand_dma_init();
-	if (err != 0)
-		goto out_unmap;
-#endif
-
-	/* Figure out the size of the device that we have.
-	 * We need to do this to figure out which ECC
-	 * layout we'll be using.
-	 */
-
-	err = nand_scan_ident(board_mtd, 1, NULL);
-	if (err) {
-		printk(KERN_ERR "nand_scan failed: %d\n", err);
-		goto out_unmap;
-	}
-
-	/* Now that we know the nand size, we can setup the ECC layout */
-
-	switch (board_mtd->writesize) {	/* writesize is the pagesize */
-	case 4096:
-		this->ecc.layout = &nand_hw_eccoob_4096;
-		break;
-	case 2048:
-		this->ecc.layout = &nand_hw_eccoob_2048;
-		break;
-	case 512:
-		this->ecc.layout = &nand_hw_eccoob_512;
-		break;
-	default:
-		{
-			printk(KERN_ERR "NAND - Unrecognized pagesize: %d\n",
-					 board_mtd->writesize);
-			err = -EINVAL;
-			goto out_unmap;
-		}
-	}
-
-#if NAND_ECC_BCH
-	if (board_mtd->writesize > 512) {
-		if (this->bbt_options & NAND_BBT_USE_FLASH)
-			largepage_bbt.options = NAND_BBT_SCAN2NDPAGE;
-		this->badblock_pattern = &largepage_bbt;
-	}
-
-	this->ecc.strength = 8;
-
-#endif
-
-	/* Now finish off the scan, now that ecc.layout has been initialized. */
-
-	err = nand_scan_tail(board_mtd);
-	if (err) {
-		printk(KERN_ERR "nand_scan failed: %d\n", err);
-		goto out_unmap;
-	}
-
-	/* Register the partitions */
-	board_mtd->name = "bcm_umi-nand";
-	mtd_device_parse_register(board_mtd, NULL, NULL, NULL, 0);
-
-	/* Return happy */
-	return 0;
-out_unmap:
-	iounmap(bcm_umi_io_base);
-out_free:
-	kfree(board_mtd);
-	return err;
-}
-
-static int bcm_umi_nand_remove(struct platform_device *pdev)
-{
-#if USE_DMA
-	nand_dma_term();
-#endif
-
-	/* Release resources, unregister device */
-	nand_release(board_mtd);
-
-	/* unmap physical address */
-	iounmap(bcm_umi_io_base);
-
-	/* Free the MTD device structure */
-	kfree(board_mtd);
-
-	return 0;
-}
-
-#ifdef CONFIG_PM
-static int bcm_umi_nand_suspend(struct platform_device *pdev,
-				pm_message_t state)
-{
-	printk(KERN_ERR "MTD NAND suspend is being called\n");
-	return 0;
-}
-
-static int bcm_umi_nand_resume(struct platform_device *pdev)
-{
-	printk(KERN_ERR "MTD NAND resume is being called\n");
-	return 0;
-}
-#else
-#define bcm_umi_nand_suspend   NULL
-#define bcm_umi_nand_resume    NULL
-#endif
-
-static struct platform_driver nand_driver = {
-	.driver = {
-		   .name = "bcm-nand",
-		   .owner = THIS_MODULE,
-		   },
-	.probe = bcm_umi_nand_probe,
-	.remove = bcm_umi_nand_remove,
-	.suspend = bcm_umi_nand_suspend,
-	.resume = bcm_umi_nand_resume,
-};
-
-module_platform_driver(nand_driver);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Broadcom");
-MODULE_DESCRIPTION("BCM UMI MTD NAND driver");
diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c
index 3f1c185..ab0caa7 100644
--- a/drivers/mtd/nand/bf5xx_nand.c
+++ b/drivers/mtd/nand/bf5xx_nand.c
@@ -566,11 +566,13 @@
 	return 0;
 }
 
-static void bf5xx_nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
-		const uint8_t *buf, int oob_required)
+static int bf5xx_nand_write_page_raw(struct mtd_info *mtd,
+		struct nand_chip *chip,	const uint8_t *buf, int oob_required)
 {
 	bf5xx_nand_write_buf(mtd, buf, mtd->writesize);
 	bf5xx_nand_write_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+	return 0;
 }
 
 /*
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c
index f3f6cfe..2bb7170 100644
--- a/drivers/mtd/nand/cafe_nand.c
+++ b/drivers/mtd/nand/cafe_nand.c
@@ -377,7 +377,7 @@
  * @buf:	buffer to store read data
  * @oob_required:	caller expects OOB data read to chip->oob_poi
  *
- * The hw generator calculates the error syndrome automatically. Therefor
+ * The hw generator calculates the error syndrome automatically. Therefore
  * we need a special oob layout and handling.
  */
 static int cafe_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
@@ -520,7 +520,7 @@
 };
 
 
-static void cafe_nand_write_page_lowlevel(struct mtd_info *mtd,
+static int cafe_nand_write_page_lowlevel(struct mtd_info *mtd,
 					  struct nand_chip *chip,
 					  const uint8_t *buf, int oob_required)
 {
@@ -531,6 +531,8 @@
 
 	/* Set up ECC autogeneration */
 	cafe->ctl2 |= (1<<30);
+
+	return 0;
 }
 
 static int cafe_nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
@@ -542,9 +544,12 @@
 	chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
 
 	if (unlikely(raw))
-		chip->ecc.write_page_raw(mtd, chip, buf, oob_required);
+		status = chip->ecc.write_page_raw(mtd, chip, buf, oob_required);
 	else
-		chip->ecc.write_page(mtd, chip, buf, oob_required);
+		status = chip->ecc.write_page(mtd, chip, buf, oob_required);
+
+	if (status < 0)
+		return status;
 
 	/*
 	 * Cached progamming disabled for now, Not sure if its worth the
@@ -571,13 +576,6 @@
 		status = chip->waitfunc(mtd, chip);
 	}
 
-#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
-	/* Send command to read back the data */
-	chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
-
-	if (chip->verify_buf(mtd, buf, mtd->writesize))
-		return -EIO;
-#endif
 	return 0;
 }
 
diff --git a/drivers/mtd/nand/cmx270_nand.c b/drivers/mtd/nand/cmx270_nand.c
index 1024bfc..39b2ef8 100644
--- a/drivers/mtd/nand/cmx270_nand.c
+++ b/drivers/mtd/nand/cmx270_nand.c
@@ -76,18 +76,6 @@
 		*buf++ = readl(this->IO_ADDR_R) >> 16;
 }
 
-static int cmx270_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
-{
-	int i;
-	struct nand_chip *this = mtd->priv;
-
-	for (i=0; i<len; i++)
-		if (buf[i] != (u_char)(readl(this->IO_ADDR_R) >> 16))
-			return -EFAULT;
-
-	return 0;
-}
-
 static inline void nand_cs_on(void)
 {
 	gpio_set_value(GPIO_NAND_CS, 0);
@@ -209,7 +197,6 @@
 	this->read_byte = cmx270_read_byte;
 	this->read_buf = cmx270_read_buf;
 	this->write_buf = cmx270_write_buf;
-	this->verify_buf = cmx270_verify_buf;
 
 	/* Scan to find existence of the device */
 	if (nand_scan (cmx270_nand_mtd, 1)) {
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index f1deb1e..945047a 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -33,6 +33,7 @@
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/slab.h>
+#include <linux/of_device.h>
 
 #include <linux/platform_data/mtd-davinci.h>
 #include <linux/platform_data/mtd-davinci-aemif.h>
@@ -518,9 +519,75 @@
 	},
 };
 
+#if defined(CONFIG_OF)
+static const struct of_device_id davinci_nand_of_match[] = {
+	{.compatible = "ti,davinci-nand", },
+	{},
+}
+MODULE_DEVICE_TABLE(of, davinci_nand_of_match);
+
+static struct davinci_nand_pdata
+	*nand_davinci_get_pdata(struct platform_device *pdev)
+{
+	if (!pdev->dev.platform_data && pdev->dev.of_node) {
+		struct davinci_nand_pdata *pdata;
+		const char *mode;
+		u32 prop;
+		int len;
+
+		pdata =  devm_kzalloc(&pdev->dev,
+				sizeof(struct davinci_nand_pdata),
+				GFP_KERNEL);
+		pdev->dev.platform_data = pdata;
+		if (!pdata)
+			return NULL;
+		if (!of_property_read_u32(pdev->dev.of_node,
+			"ti,davinci-chipselect", &prop))
+			pdev->id = prop;
+		if (!of_property_read_u32(pdev->dev.of_node,
+			"ti,davinci-mask-ale", &prop))
+			pdata->mask_ale = prop;
+		if (!of_property_read_u32(pdev->dev.of_node,
+			"ti,davinci-mask-cle", &prop))
+			pdata->mask_cle = prop;
+		if (!of_property_read_u32(pdev->dev.of_node,
+			"ti,davinci-mask-chipsel", &prop))
+			pdata->mask_chipsel = prop;
+		if (!of_property_read_string(pdev->dev.of_node,
+			"ti,davinci-ecc-mode", &mode)) {
+			if (!strncmp("none", mode, 4))
+				pdata->ecc_mode = NAND_ECC_NONE;
+			if (!strncmp("soft", mode, 4))
+				pdata->ecc_mode = NAND_ECC_SOFT;
+			if (!strncmp("hw", mode, 2))
+				pdata->ecc_mode = NAND_ECC_HW;
+		}
+		if (!of_property_read_u32(pdev->dev.of_node,
+			"ti,davinci-ecc-bits", &prop))
+			pdata->ecc_bits = prop;
+		if (!of_property_read_u32(pdev->dev.of_node,
+			"ti,davinci-nand-buswidth", &prop))
+			if (prop == 16)
+				pdata->options |= NAND_BUSWIDTH_16;
+		if (of_find_property(pdev->dev.of_node,
+			"ti,davinci-nand-use-bbt", &len))
+			pdata->bbt_options = NAND_BBT_USE_FLASH;
+	}
+
+	return pdev->dev.platform_data;
+}
+#else
+#define davinci_nand_of_match NULL
+static struct davinci_nand_pdata
+	*nand_davinci_get_pdata(struct platform_device *pdev)
+{
+	return pdev->dev.platform_data;
+}
+#endif
+
 static int __init nand_davinci_probe(struct platform_device *pdev)
 {
-	struct davinci_nand_pdata	*pdata = pdev->dev.platform_data;
+	struct davinci_nand_pdata	*pdata;
 	struct davinci_nand_info	*info;
 	struct resource			*res1;
 	struct resource			*res2;
@@ -530,6 +597,7 @@
 	uint32_t			val;
 	nand_ecc_modes_t		ecc_mode;
 
+	pdata = nand_davinci_get_pdata(pdev);
 	/* insist on board-specific configuration */
 	if (!pdata)
 		return -ENODEV;
@@ -656,7 +724,7 @@
 		goto err_clk;
 	}
 
-	ret = clk_enable(info->clk);
+	ret = clk_prepare_enable(info->clk);
 	if (ret < 0) {
 		dev_dbg(&pdev->dev, "unable to enable AEMIF clock, err %d\n",
 			ret);
@@ -767,7 +835,7 @@
 
 err_scan:
 err_timing:
-	clk_disable(info->clk);
+	clk_disable_unprepare(info->clk);
 
 err_clk_enable:
 	clk_put(info->clk);
@@ -804,7 +872,7 @@
 
 	nand_release(&info->mtd);
 
-	clk_disable(info->clk);
+	clk_disable_unprepare(info->clk);
 	clk_put(info->clk);
 
 	kfree(info);
@@ -816,6 +884,8 @@
 	.remove		= __exit_p(nand_davinci_remove),
 	.driver		= {
 		.name	= "davinci_nand",
+		.owner	= THIS_MODULE,
+		.of_match_table = davinci_nand_of_match,
 	},
 };
 MODULE_ALIAS("platform:davinci_nand");
diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c
index 0650aaf..e706a23 100644
--- a/drivers/mtd/nand/denali.c
+++ b/drivers/mtd/nand/denali.c
@@ -1028,7 +1028,7 @@
 
 /* writes a page. user specifies type, and this function handles the
  * configuration details. */
-static void write_page(struct mtd_info *mtd, struct nand_chip *chip,
+static int write_page(struct mtd_info *mtd, struct nand_chip *chip,
 			const uint8_t *buf, bool raw_xfer)
 {
 	struct denali_nand_info *denali = mtd_to_denali(mtd);
@@ -1078,6 +1078,8 @@
 
 	denali_enable_dma(denali, false);
 	dma_sync_single_for_cpu(denali->dev, addr, size, DMA_TO_DEVICE);
+
+	return 0;
 }
 
 /* NAND core entry points */
@@ -1086,24 +1088,24 @@
  * writing a page with ECC or without is similar, all the work is done
  * by write_page above.
  * */
-static void denali_write_page(struct mtd_info *mtd, struct nand_chip *chip,
+static int denali_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 				const uint8_t *buf, int oob_required)
 {
 	/* for regular page writes, we let HW handle all the ECC
 	 * data written to the device. */
-	write_page(mtd, chip, buf, false);
+	return write_page(mtd, chip, buf, false);
 }
 
 /* This is the callback that the NAND core calls to write a page without ECC.
  * raw access is similar to ECC page writes, so all the work is done in the
  * write_page() function above.
  */
-static void denali_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+static int denali_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
 					const uint8_t *buf, int oob_required)
 {
 	/* for raw page writes, we want to disable ECC and simply write
 	   whatever data is in the buffer. */
-	write_page(mtd, chip, buf, true);
+	return write_page(mtd, chip, buf, true);
 }
 
 static int denali_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index e2ca067..256eb30 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -376,19 +376,6 @@
 	}
 }
 
-static int doc2000_verifybuf(struct mtd_info *mtd, const u_char *buf, int len)
-{
-	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = this->priv;
-	void __iomem *docptr = doc->virtadr;
-	int i;
-
-	for (i = 0; i < len; i++)
-		if (buf[i] != ReadDOC(docptr, 2k_CDSN_IO))
-			return -EFAULT;
-	return 0;
-}
-
 static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
 {
 	struct nand_chip *this = mtd->priv;
@@ -526,26 +513,6 @@
 	buf[i] = ReadDOC(docptr, LastDataRead);
 }
 
-static int doc2001_verifybuf(struct mtd_info *mtd, const u_char *buf, int len)
-{
-	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = this->priv;
-	void __iomem *docptr = doc->virtadr;
-	int i;
-
-	/* Start read pipeline */
-	ReadDOC(docptr, ReadPipeInit);
-
-	for (i = 0; i < len - 1; i++)
-		if (buf[i] != ReadDOC(docptr, Mil_CDSN_IO)) {
-			ReadDOC(docptr, LastDataRead);
-			return i;
-		}
-	if (buf[i] != ReadDOC(docptr, LastDataRead))
-		return i;
-	return 0;
-}
-
 static u_char doc2001plus_read_byte(struct mtd_info *mtd)
 {
 	struct nand_chip *this = mtd->priv;
@@ -610,33 +577,6 @@
 		printk("\n");
 }
 
-static int doc2001plus_verifybuf(struct mtd_info *mtd, const u_char *buf, int len)
-{
-	struct nand_chip *this = mtd->priv;
-	struct doc_priv *doc = this->priv;
-	void __iomem *docptr = doc->virtadr;
-	int i;
-
-	if (debug)
-		printk("verifybuf of %d bytes: ", len);
-
-	/* Start read pipeline */
-	ReadDOC(docptr, Mplus_ReadPipeInit);
-	ReadDOC(docptr, Mplus_ReadPipeInit);
-
-	for (i = 0; i < len - 2; i++)
-		if (buf[i] != ReadDOC(docptr, Mil_CDSN_IO)) {
-			ReadDOC(docptr, Mplus_LastDataRead);
-			ReadDOC(docptr, Mplus_LastDataRead);
-			return i;
-		}
-	if (buf[len - 2] != ReadDOC(docptr, Mplus_LastDataRead))
-		return len - 2;
-	if (buf[len - 1] != ReadDOC(docptr, Mplus_LastDataRead))
-		return len - 1;
-	return 0;
-}
-
 static void doc2001plus_select_chip(struct mtd_info *mtd, int chip)
 {
 	struct nand_chip *this = mtd->priv;
@@ -1432,7 +1372,6 @@
 	this->read_byte = doc2000_read_byte;
 	this->write_buf = doc2000_writebuf;
 	this->read_buf = doc2000_readbuf;
-	this->verify_buf = doc2000_verifybuf;
 	this->scan_bbt = nftl_scan_bbt;
 
 	doc->CDSNControl = CDSN_CTRL_FLASH_IO | CDSN_CTRL_ECC_IO;
@@ -1449,7 +1388,6 @@
 	this->read_byte = doc2001_read_byte;
 	this->write_buf = doc2001_writebuf;
 	this->read_buf = doc2001_readbuf;
-	this->verify_buf = doc2001_verifybuf;
 
 	ReadDOC(doc->virtadr, ChipID);
 	ReadDOC(doc->virtadr, ChipID);
@@ -1480,7 +1418,6 @@
 	this->read_byte = doc2001plus_read_byte;
 	this->write_buf = doc2001plus_writebuf;
 	this->read_buf = doc2001plus_readbuf;
-	this->verify_buf = doc2001plus_verifybuf;
 	this->scan_bbt = inftl_scan_bbt;
 	this->cmd_ctrl = NULL;
 	this->select_chip = doc2001plus_select_chip;
diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c
index a225e49..799da5d 100644
--- a/drivers/mtd/nand/docg4.c
+++ b/drivers/mtd/nand/docg4.c
@@ -378,9 +378,9 @@
 		 * bit flips(s) are not reported in stats.
 		 */
 
-		if (doc->oob_buf[15]) {
+		if (nand->oob_poi[15]) {
 			int bit, numsetbits = 0;
-			unsigned long written_flag = doc->oob_buf[15];
+			unsigned long written_flag = nand->oob_poi[15];
 			for_each_set_bit(bit, &written_flag, 8)
 				numsetbits++;
 			if (numsetbits > 4) { /* assume blank */
@@ -428,7 +428,7 @@
 		/* if error within oob area preceeding ecc bytes... */
 		if (errpos[i] > DOCG4_PAGE_SIZE * 8)
 			change_bit(errpos[i] - DOCG4_PAGE_SIZE * 8,
-				   (unsigned long *)doc->oob_buf);
+				   (unsigned long *)nand->oob_poi);
 
 		else    /* error in page data */
 			change_bit(errpos[i], (unsigned long *)buf);
@@ -748,18 +748,12 @@
 
 	docg4_read_buf(mtd, buf, DOCG4_PAGE_SIZE); /* read the page data */
 
-	/*
-	 * Diskonchips read oob immediately after a page read.  Mtd
-	 * infrastructure issues a separate command for reading oob after the
-	 * page is read.  So we save the oob bytes in a local buffer and just
-	 * copy it if the next command reads oob from the same page.
-	 */
-
+	/* this device always reads oob after page data */
 	/* first 14 oob bytes read from I/O reg */
-	docg4_read_buf(mtd, doc->oob_buf, 14);
+	docg4_read_buf(mtd, nand->oob_poi, 14);
 
 	/* last 2 read from another reg */
-	buf16 = (uint16_t *)(doc->oob_buf + 14);
+	buf16 = (uint16_t *)(nand->oob_poi + 14);
 	*buf16 = readw(docptr + DOCG4_MYSTERY_REG);
 
 	write_nop(docptr);
@@ -782,6 +776,8 @@
 	}
 
 	writew(0, docptr + DOC_DATAEND);
+	if (bits_corrected == -EBADMSG)	  /* uncorrectable errors */
+		return 0;
 	return bits_corrected;
 }
 
@@ -807,21 +803,6 @@
 
 	dev_dbg(doc->dev, "%s: page %x\n", __func__, page);
 
-	/*
-	 * Oob bytes are read as part of a normal page read.  If the previous
-	 * nand command was a read of the page whose oob is now being read, just
-	 * copy the oob bytes that we saved in a local buffer and avoid a
-	 * separate oob read.
-	 */
-	if (doc->last_command.command == NAND_CMD_READ0 &&
-	    doc->last_command.page == page) {
-		memcpy(nand->oob_poi, doc->oob_buf, 16);
-		return 0;
-	}
-
-	/*
-	 * Separate read of oob data only.
-	 */
 	docg4_command(mtd, NAND_CMD_READ0, nand->ecc.size, page);
 
 	writew(DOC_ECCCONF0_READ_MODE | DOCG4_OOB_SIZE, docptr + DOC_ECCCONF0);
@@ -898,7 +879,7 @@
 	write_nop(docptr);
 }
 
-static void write_page(struct mtd_info *mtd, struct nand_chip *nand,
+static int write_page(struct mtd_info *mtd, struct nand_chip *nand,
 		       const uint8_t *buf, bool use_ecc)
 {
 	struct docg4_priv *doc = nand->priv;
@@ -950,15 +931,17 @@
 	write_nop(docptr);
 	writew(0, docptr + DOC_DATAEND);
 	write_nop(docptr);
+
+	return 0;
 }
 
-static void docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
+static int docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
 				 const uint8_t *buf, int oob_required)
 {
 	return write_page(mtd, nand, buf, false);
 }
 
-static void docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand,
+static int docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand,
 			     const uint8_t *buf, int oob_required)
 {
 	return write_page(mtd, nand, buf, true);
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c
index 7842938..cc1480a 100644
--- a/drivers/mtd/nand/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/fsl_elbc_nand.c
@@ -614,41 +614,6 @@
 		        len, avail);
 }
 
-/*
- * Verify buffer against the FCM Controller Data Buffer
- */
-static int fsl_elbc_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
-{
-	struct nand_chip *chip = mtd->priv;
-	struct fsl_elbc_mtd *priv = chip->priv;
-	struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand;
-	int i;
-
-	if (len < 0) {
-		dev_err(priv->dev, "write_buf of %d bytes", len);
-		return -EINVAL;
-	}
-
-	if ((unsigned int)len >
-			elbc_fcm_ctrl->read_bytes - elbc_fcm_ctrl->index) {
-		dev_err(priv->dev,
-			"verify_buf beyond end of buffer "
-			"(%d requested, %u available)\n",
-			len, elbc_fcm_ctrl->read_bytes - elbc_fcm_ctrl->index);
-
-		elbc_fcm_ctrl->index = elbc_fcm_ctrl->read_bytes;
-		return -EINVAL;
-	}
-
-	for (i = 0; i < len; i++)
-		if (in_8(&elbc_fcm_ctrl->addr[elbc_fcm_ctrl->index + i])
-				!= buf[i])
-			break;
-
-	elbc_fcm_ctrl->index += len;
-	return i == len && elbc_fcm_ctrl->status == LTESR_CC ? 0 : -EIO;
-}
-
 /* This function is called after Program and Erase Operations to
  * check for success or failure.
  */
@@ -766,11 +731,13 @@
 /* ECC will be calculated automatically, and errors will be detected in
  * waitfunc.
  */
-static void fsl_elbc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
+static int fsl_elbc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 				const uint8_t *buf, int oob_required)
 {
 	fsl_elbc_write_buf(mtd, buf, mtd->writesize);
 	fsl_elbc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+	return 0;
 }
 
 static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
@@ -796,7 +763,6 @@
 	chip->read_byte = fsl_elbc_read_byte;
 	chip->write_buf = fsl_elbc_write_buf;
 	chip->read_buf = fsl_elbc_read_buf;
-	chip->verify_buf = fsl_elbc_verify_buf;
 	chip->select_chip = fsl_elbc_select_chip;
 	chip->cmdfunc = fsl_elbc_cmdfunc;
 	chip->waitfunc = fsl_elbc_wait;
@@ -805,7 +771,6 @@
 	chip->bbt_md = &bbt_mirror_descr;
 
 	/* set up nand options */
-	chip->options = NAND_NO_READRDY;
 	chip->bbt_options = NAND_BBT_USE_FLASH;
 
 	chip->controller = &elbc_fcm_ctrl->controller;
@@ -916,7 +881,8 @@
 	elbc_fcm_ctrl->chips[bank] = priv;
 	priv->bank = bank;
 	priv->ctrl = fsl_lbc_ctrl_dev;
-	priv->dev = dev;
+	priv->dev = &pdev->dev;
+	dev_set_drvdata(priv->dev, priv);
 
 	priv->vbase = ioremap(res.start, resource_size(&res));
 	if (!priv->vbase) {
@@ -963,11 +929,10 @@
 
 static int fsl_elbc_nand_remove(struct platform_device *pdev)
 {
-	int i;
 	struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = fsl_lbc_ctrl_dev->nand;
-	for (i = 0; i < MAX_BANKS; i++)
-		if (elbc_fcm_ctrl->chips[i])
-			fsl_elbc_chip_remove(elbc_fcm_ctrl->chips[i]);
+	struct fsl_elbc_mtd *priv = dev_get_drvdata(&pdev->dev);
+
+	fsl_elbc_chip_remove(priv);
 
 	mutex_lock(&fsl_elbc_nand_mutex);
 	elbc_fcm_ctrl->counter--;
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
index 01e2f2e..3551a99 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -194,7 +194,7 @@
 	struct nand_chip *chip = mtd->priv;
 	struct fsl_ifc_mtd *priv = chip->priv;
 	u8 __iomem *addr = priv->vbase + bufnum * (mtd->writesize * 2);
-	u32 __iomem *mainarea = (u32 *)addr;
+	u32 __iomem *mainarea = (u32 __iomem *)addr;
 	u8 __iomem *oob = addr + mtd->writesize;
 	int i;
 
@@ -592,8 +592,8 @@
 	 * next byte.
 	 */
 	if (ifc_nand_ctrl->index < ifc_nand_ctrl->read_bytes) {
-		data = in_be16((uint16_t *)&ifc_nand_ctrl->
-					addr[ifc_nand_ctrl->index]);
+		data = in_be16((uint16_t __iomem *)&ifc_nand_ctrl->
+			       addr[ifc_nand_ctrl->index]);
 		ifc_nand_ctrl->index += 2;
 		return (uint8_t) data;
 	}
@@ -628,46 +628,6 @@
 }
 
 /*
- * Verify buffer against the IFC Controller Data Buffer
- */
-static int fsl_ifc_verify_buf(struct mtd_info *mtd,
-			       const u_char *buf, int len)
-{
-	struct nand_chip *chip = mtd->priv;
-	struct fsl_ifc_mtd *priv = chip->priv;
-	struct fsl_ifc_ctrl *ctrl = priv->ctrl;
-	struct fsl_ifc_nand_ctrl *nctrl = ifc_nand_ctrl;
-	int i;
-
-	if (len < 0) {
-		dev_err(priv->dev, "%s: write_buf of %d bytes", __func__, len);
-		return -EINVAL;
-	}
-
-	if ((unsigned int)len > nctrl->read_bytes - nctrl->index) {
-		dev_err(priv->dev,
-			"%s: beyond end of buffer (%d requested, %u available)\n",
-			__func__, len, nctrl->read_bytes - nctrl->index);
-
-		nctrl->index = nctrl->read_bytes;
-		return -EINVAL;
-	}
-
-	for (i = 0; i < len; i++)
-		if (in_8(&nctrl->addr[nctrl->index + i]) != buf[i])
-			break;
-
-	nctrl->index += len;
-
-	if (i != len)
-		return -EIO;
-	if (ctrl->nand_stat != IFC_NAND_EVTER_STAT_OPC)
-		return -EIO;
-
-	return 0;
-}
-
-/*
  * This function is called after Program and Erase Operations to
  * check for success or failure.
  */
@@ -722,11 +682,13 @@
 /* ECC will be calculated automatically, and errors will be detected in
  * waitfunc.
  */
-static void fsl_ifc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
+static int fsl_ifc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 			       const uint8_t *buf, int oob_required)
 {
 	fsl_ifc_write_buf(mtd, buf, mtd->writesize);
 	fsl_ifc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+	return 0;
 }
 
 static int fsl_ifc_chip_init_tail(struct mtd_info *mtd)
@@ -844,7 +806,6 @@
 
 	chip->write_buf = fsl_ifc_write_buf;
 	chip->read_buf = fsl_ifc_read_buf;
-	chip->verify_buf = fsl_ifc_verify_buf;
 	chip->select_chip = fsl_ifc_select_chip;
 	chip->cmdfunc = fsl_ifc_cmdfunc;
 	chip->waitfunc = fsl_ifc_wait;
@@ -855,7 +816,6 @@
 	out_be32(&ifc->ifc_nand.ncfgr, 0x0);
 
 	/* set up nand options */
-	chip->options = NAND_NO_READRDY;
 	chip->bbt_options = NAND_BBT_USE_FLASH;
 
 
diff --git a/drivers/mtd/nand/gpio.c b/drivers/mtd/nand/gpio.c
index 27000a5..bc73bc5 100644
--- a/drivers/mtd/nand/gpio.c
+++ b/drivers/mtd/nand/gpio.c
@@ -100,23 +100,6 @@
 	readsb(this->IO_ADDR_R, buf, len);
 }
 
-static int gpio_nand_verifybuf(struct mtd_info *mtd, const u_char *buf, int len)
-{
-	struct nand_chip *this = mtd->priv;
-	unsigned char read, *p = (unsigned char *) buf;
-	int i, err = 0;
-
-	for (i = 0; i < len; i++) {
-		read = readb(this->IO_ADDR_R);
-		if (read != p[i]) {
-			pr_debug("%s: err at %d (read %04x vs %04x)\n",
-			       __func__, i, read, p[i]);
-			err = -EFAULT;
-		}
-	}
-	return err;
-}
-
 static void gpio_nand_writebuf16(struct mtd_info *mtd, const u_char *buf,
 				 int len)
 {
@@ -148,26 +131,6 @@
 	}
 }
 
-static int gpio_nand_verifybuf16(struct mtd_info *mtd, const u_char *buf,
-				 int len)
-{
-	struct nand_chip *this = mtd->priv;
-	unsigned short read, *p = (unsigned short *) buf;
-	int i, err = 0;
-	len >>= 1;
-
-	for (i = 0; i < len; i++) {
-		read = readw(this->IO_ADDR_R);
-		if (read != p[i]) {
-			pr_debug("%s: err at %d (read %04x vs %04x)\n",
-			       __func__, i, read, p[i]);
-			err = -EFAULT;
-		}
-	}
-	return err;
-}
-
-
 static int gpio_nand_devready(struct mtd_info *mtd)
 {
 	struct gpiomtd *gpiomtd = gpio_nand_getpriv(mtd);
@@ -391,11 +354,9 @@
 	if (this->options & NAND_BUSWIDTH_16) {
 		this->read_buf   = gpio_nand_readbuf16;
 		this->write_buf  = gpio_nand_writebuf16;
-		this->verify_buf = gpio_nand_verifybuf16;
 	} else {
 		this->read_buf   = gpio_nand_readbuf;
 		this->write_buf  = gpio_nand_writebuf;
-		this->verify_buf = gpio_nand_verifybuf;
 	}
 
 	/* set the mtd private data for the nand driver */
@@ -456,20 +417,7 @@
 	},
 };
 
-static int __init gpio_nand_init(void)
-{
-	printk(KERN_INFO "GPIO NAND driver, © 2004 Simtec Electronics\n");
-
-	return platform_driver_register(&gpio_nand_driver);
-}
-
-static void __exit gpio_nand_exit(void)
-{
-	platform_driver_unregister(&gpio_nand_driver);
-}
-
-module_init(gpio_nand_init);
-module_exit(gpio_nand_exit);
+module_platform_driver(gpio_nand_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
index a1f4332..3502acc 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
@@ -26,7 +26,7 @@
 #include "gpmi-regs.h"
 #include "bch-regs.h"
 
-struct timing_threshod timing_default_threshold = {
+static struct timing_threshod timing_default_threshold = {
 	.max_data_setup_cycles       = (BM_GPMI_TIMING0_DATA_SETUP >>
 						BP_GPMI_TIMING0_DATA_SETUP),
 	.internal_data_setup_in_ns   = 0,
@@ -124,12 +124,42 @@
 	return -ETIMEDOUT;
 }
 
+static int __gpmi_enable_clk(struct gpmi_nand_data *this, bool v)
+{
+	struct clk *clk;
+	int ret;
+	int i;
+
+	for (i = 0; i < GPMI_CLK_MAX; i++) {
+		clk = this->resources.clock[i];
+		if (!clk)
+			break;
+
+		if (v) {
+			ret = clk_prepare_enable(clk);
+			if (ret)
+				goto err_clk;
+		} else {
+			clk_disable_unprepare(clk);
+		}
+	}
+	return 0;
+
+err_clk:
+	for (; i > 0; i--)
+		clk_disable_unprepare(this->resources.clock[i - 1]);
+	return ret;
+}
+
+#define gpmi_enable_clk(x) __gpmi_enable_clk(x, true)
+#define gpmi_disable_clk(x) __gpmi_enable_clk(x, false)
+
 int gpmi_init(struct gpmi_nand_data *this)
 {
 	struct resources *r = &this->resources;
 	int ret;
 
-	ret = clk_prepare_enable(r->clock);
+	ret = gpmi_enable_clk(this);
 	if (ret)
 		goto err_out;
 	ret = gpmi_reset_block(r->gpmi_regs, false);
@@ -149,7 +179,7 @@
 	/* Select BCH ECC. */
 	writel(BM_GPMI_CTRL1_BCH_MODE, r->gpmi_regs + HW_GPMI_CTRL1_SET);
 
-	clk_disable_unprepare(r->clock);
+	gpmi_disable_clk(this);
 	return 0;
 err_out:
 	return ret;
@@ -205,7 +235,7 @@
 	ecc_strength  = bch_geo->ecc_strength >> 1;
 	page_size     = bch_geo->page_size;
 
-	ret = clk_prepare_enable(r->clock);
+	ret = gpmi_enable_clk(this);
 	if (ret)
 		goto err_out;
 
@@ -240,7 +270,7 @@
 	writel(BM_BCH_CTRL_COMPLETE_IRQ_EN,
 				r->bch_regs + HW_BCH_CTRL_SET);
 
-	clk_disable_unprepare(r->clock);
+	gpmi_disable_clk(this);
 	return 0;
 err_out:
 	return ret;
@@ -263,6 +293,7 @@
 					struct gpmi_nfc_hardware_timing *hw)
 {
 	struct timing_threshod *nfc = &timing_default_threshold;
+	struct resources *r = &this->resources;
 	struct nand_chip *nand = &this->nand;
 	struct nand_timing target = this->timing;
 	bool improved_timing_is_available;
@@ -302,8 +333,9 @@
 		(target.tRHOH_in_ns >= 0) ;
 
 	/* Inspect the clock. */
+	nfc->clock_frequency_in_hz = clk_get_rate(r->clock[0]);
 	clock_frequency_in_hz = nfc->clock_frequency_in_hz;
-	clock_period_in_ns    = 1000000000 / clock_frequency_in_hz;
+	clock_period_in_ns    = NSEC_PER_SEC / clock_frequency_in_hz;
 
 	/*
 	 * The NFC quantizes setup and hold parameters in terms of clock cycles.
@@ -698,17 +730,230 @@
 	hw->address_setup_in_cycles = address_setup_in_cycles;
 	hw->use_half_periods        = dll_use_half_periods;
 	hw->sample_delay_factor     = sample_delay_factor;
+	hw->device_busy_timeout     = GPMI_DEFAULT_BUSY_TIMEOUT;
+	hw->wrn_dly_sel             = BV_GPMI_CTRL1_WRN_DLY_SEL_4_TO_8NS;
 
 	/* Return success. */
 	return 0;
 }
 
+/*
+ * <1> Firstly, we should know what's the GPMI-clock means.
+ *     The GPMI-clock is the internal clock in the gpmi nand controller.
+ *     If you set 100MHz to gpmi nand controller, the GPMI-clock's period
+ *     is 10ns. Mark the GPMI-clock's period as GPMI-clock-period.
+ *
+ * <2> Secondly, we should know what's the frequency on the nand chip pins.
+ *     The frequency on the nand chip pins is derived from the GPMI-clock.
+ *     We can get it from the following equation:
+ *
+ *         F = G / (DS + DH)
+ *
+ *         F  : the frequency on the nand chip pins.
+ *         G  : the GPMI clock, such as 100MHz.
+ *         DS : GPMI_HW_GPMI_TIMING0:DATA_SETUP
+ *         DH : GPMI_HW_GPMI_TIMING0:DATA_HOLD
+ *
+ * <3> Thirdly, when the frequency on the nand chip pins is above 33MHz,
+ *     the nand EDO(extended Data Out) timing could be applied.
+ *     The GPMI implements a feedback read strobe to sample the read data.
+ *     The feedback read strobe can be delayed to support the nand EDO timing
+ *     where the read strobe may deasserts before the read data is valid, and
+ *     read data is valid for some time after read strobe.
+ *
+ *     The following figure illustrates some aspects of a NAND Flash read:
+ *
+ *                   |<---tREA---->|
+ *                   |             |
+ *                   |         |   |
+ *                   |<--tRP-->|   |
+ *                   |         |   |
+ *                  __          ___|__________________________________
+ *     RDN            \________/   |
+ *                                 |
+ *                                 /---------\
+ *     Read Data    --------------<           >---------
+ *                                 \---------/
+ *                                |     |
+ *                                |<-D->|
+ *     FeedbackRDN  ________             ____________
+ *                          \___________/
+ *
+ *          D stands for delay, set in the HW_GPMI_CTRL1:RDN_DELAY.
+ *
+ *
+ * <4> Now, we begin to describe how to compute the right RDN_DELAY.
+ *
+ *  4.1) From the aspect of the nand chip pins:
+ *        Delay = (tREA + C - tRP)               {1}
+ *
+ *        tREA : the maximum read access time. From the ONFI nand standards,
+ *               we know that tREA is 16ns in mode 5, tREA is 20ns is mode 4.
+ *               Please check it in : www.onfi.org
+ *        C    : a constant for adjust the delay. default is 4.
+ *        tRP  : the read pulse width.
+ *               Specified by the HW_GPMI_TIMING0:DATA_SETUP:
+ *                    tRP = (GPMI-clock-period) * DATA_SETUP
+ *
+ *  4.2) From the aspect of the GPMI nand controller:
+ *         Delay = RDN_DELAY * 0.125 * RP        {2}
+ *
+ *         RP   : the DLL reference period.
+ *            if (GPMI-clock-period > DLL_THRETHOLD)
+ *                   RP = GPMI-clock-period / 2;
+ *            else
+ *                   RP = GPMI-clock-period;
+ *
+ *            Set the HW_GPMI_CTRL1:HALF_PERIOD if GPMI-clock-period
+ *            is greater DLL_THRETHOLD. In other SOCs, the DLL_THRETHOLD
+ *            is 16ns, but in mx6q, we use 12ns.
+ *
+ *  4.3) since {1} equals {2}, we get:
+ *
+ *                    (tREA + 4 - tRP) * 8
+ *         RDN_DELAY = ---------------------     {3}
+ *                           RP
+ *
+ *  4.4) We only support the fastest asynchronous mode of ONFI nand.
+ *       For some ONFI nand, the mode 4 is the fastest mode;
+ *       while for some ONFI nand, the mode 5 is the fastest mode.
+ *       So we only support the mode 4 and mode 5. It is no need to
+ *       support other modes.
+ */
+static void gpmi_compute_edo_timing(struct gpmi_nand_data *this,
+			struct gpmi_nfc_hardware_timing *hw)
+{
+	struct resources *r = &this->resources;
+	unsigned long rate = clk_get_rate(r->clock[0]);
+	int mode = this->timing_mode;
+	int dll_threshold = 16; /* in ns */
+	unsigned long delay;
+	unsigned long clk_period;
+	int t_rea;
+	int c = 4;
+	int t_rp;
+	int rp;
+
+	/*
+	 * [1] for GPMI_HW_GPMI_TIMING0:
+	 *     The async mode requires 40MHz for mode 4, 50MHz for mode 5.
+	 *     The GPMI can support 100MHz at most. So if we want to
+	 *     get the 40MHz or 50MHz, we have to set DS=1, DH=1.
+	 *     Set the ADDRESS_SETUP to 0 in mode 4.
+	 */
+	hw->data_setup_in_cycles = 1;
+	hw->data_hold_in_cycles = 1;
+	hw->address_setup_in_cycles = ((mode == 5) ? 1 : 0);
+
+	/* [2] for GPMI_HW_GPMI_TIMING1 */
+	hw->device_busy_timeout = 0x9000;
+
+	/* [3] for GPMI_HW_GPMI_CTRL1 */
+	hw->wrn_dly_sel = BV_GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY;
+
+	if (GPMI_IS_MX6Q(this))
+		dll_threshold = 12;
+
+	/*
+	 * Enlarge 10 times for the numerator and denominator in {3}.
+	 * This make us to get more accurate result.
+	 */
+	clk_period = NSEC_PER_SEC / (rate / 10);
+	dll_threshold *= 10;
+	t_rea = ((mode == 5) ? 16 : 20) * 10;
+	c *= 10;
+
+	t_rp = clk_period * 1; /* DATA_SETUP is 1 */
+
+	if (clk_period > dll_threshold) {
+		hw->use_half_periods = 1;
+		rp = clk_period / 2;
+	} else {
+		hw->use_half_periods = 0;
+		rp = clk_period;
+	}
+
+	/*
+	 * Multiply the numerator with 10, we could do a round off:
+	 *      7.8 round up to 8; 7.4 round down to 7.
+	 */
+	delay  = (((t_rea + c - t_rp) * 8) * 10) / rp;
+	delay = (delay + 5) / 10;
+
+	hw->sample_delay_factor = delay;
+}
+
+static int enable_edo_mode(struct gpmi_nand_data *this, int mode)
+{
+	struct resources  *r = &this->resources;
+	struct nand_chip *nand = &this->nand;
+	struct mtd_info	 *mtd = &this->mtd;
+	uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {};
+	unsigned long rate;
+	int ret;
+
+	nand->select_chip(mtd, 0);
+
+	/* [1] send SET FEATURE commond to NAND */
+	feature[0] = mode;
+	ret = nand->onfi_set_features(mtd, nand,
+				ONFI_FEATURE_ADDR_TIMING_MODE, feature);
+	if (ret)
+		goto err_out;
+
+	/* [2] send GET FEATURE command to double-check the timing mode */
+	memset(feature, 0, ONFI_SUBFEATURE_PARAM_LEN);
+	ret = nand->onfi_get_features(mtd, nand,
+				ONFI_FEATURE_ADDR_TIMING_MODE, feature);
+	if (ret || feature[0] != mode)
+		goto err_out;
+
+	nand->select_chip(mtd, -1);
+
+	/* [3] set the main IO clock, 100MHz for mode 5, 80MHz for mode 4. */
+	rate = (mode == 5) ? 100000000 : 80000000;
+	clk_set_rate(r->clock[0], rate);
+
+	/* Let the gpmi_begin() re-compute the timing again. */
+	this->flags &= ~GPMI_TIMING_INIT_OK;
+
+	this->flags |= GPMI_ASYNC_EDO_ENABLED;
+	this->timing_mode = mode;
+	dev_info(this->dev, "enable the asynchronous EDO mode %d\n", mode);
+	return 0;
+
+err_out:
+	nand->select_chip(mtd, -1);
+	dev_err(this->dev, "mode:%d ,failed in set feature.\n", mode);
+	return -EINVAL;
+}
+
+int gpmi_extra_init(struct gpmi_nand_data *this)
+{
+	struct nand_chip *chip = &this->nand;
+
+	/* Enable the asynchronous EDO feature. */
+	if (GPMI_IS_MX6Q(this) && chip->onfi_version) {
+		int mode = onfi_get_async_timing_mode(chip);
+
+		/* We only support the timing mode 4 and mode 5. */
+		if (mode & ONFI_TIMING_MODE_5)
+			mode = 5;
+		else if (mode & ONFI_TIMING_MODE_4)
+			mode = 4;
+		else
+			return 0;
+
+		return enable_edo_mode(this, mode);
+	}
+	return 0;
+}
+
 /* Begin the I/O */
 void gpmi_begin(struct gpmi_nand_data *this)
 {
 	struct resources *r = &this->resources;
-	struct timing_threshod *nfc = &timing_default_threshold;
-	unsigned char  *gpmi_regs = r->gpmi_regs;
+	void __iomem *gpmi_regs = r->gpmi_regs;
 	unsigned int   clock_period_in_ns;
 	uint32_t       reg;
 	unsigned int   dll_wait_time_in_us;
@@ -716,60 +961,66 @@
 	int ret;
 
 	/* Enable the clock. */
-	ret = clk_prepare_enable(r->clock);
+	ret = gpmi_enable_clk(this);
 	if (ret) {
 		pr_err("We failed in enable the clk\n");
 		goto err_out;
 	}
 
-	/* set ready/busy timeout */
-	writel(0x500 << BP_GPMI_TIMING1_BUSY_TIMEOUT,
-		gpmi_regs + HW_GPMI_TIMING1);
+	/* Only initialize the timing once */
+	if (this->flags & GPMI_TIMING_INIT_OK)
+		return;
+	this->flags |= GPMI_TIMING_INIT_OK;
 
-	/* Get the timing information we need. */
-	nfc->clock_frequency_in_hz = clk_get_rate(r->clock);
-	clock_period_in_ns = 1000000000 / nfc->clock_frequency_in_hz;
+	if (this->flags & GPMI_ASYNC_EDO_ENABLED)
+		gpmi_compute_edo_timing(this, &hw);
+	else
+		gpmi_nfc_compute_hardware_timing(this, &hw);
 
-	gpmi_nfc_compute_hardware_timing(this, &hw);
-
-	/* Set up all the simple timing parameters. */
+	/* [1] Set HW_GPMI_TIMING0 */
 	reg = BF_GPMI_TIMING0_ADDRESS_SETUP(hw.address_setup_in_cycles) |
 		BF_GPMI_TIMING0_DATA_HOLD(hw.data_hold_in_cycles)         |
 		BF_GPMI_TIMING0_DATA_SETUP(hw.data_setup_in_cycles)       ;
 
 	writel(reg, gpmi_regs + HW_GPMI_TIMING0);
 
-	/*
-	 * DLL_ENABLE must be set to 0 when setting RDN_DELAY or HALF_PERIOD.
-	 */
+	/* [2] Set HW_GPMI_TIMING1 */
+	writel(BF_GPMI_TIMING1_BUSY_TIMEOUT(hw.device_busy_timeout),
+		gpmi_regs + HW_GPMI_TIMING1);
+
+	/* [3] The following code is to set the HW_GPMI_CTRL1. */
+
+	/* Set the WRN_DLY_SEL */
+	writel(BM_GPMI_CTRL1_WRN_DLY_SEL, gpmi_regs + HW_GPMI_CTRL1_CLR);
+	writel(BF_GPMI_CTRL1_WRN_DLY_SEL(hw.wrn_dly_sel),
+					gpmi_regs + HW_GPMI_CTRL1_SET);
+
+	/* DLL_ENABLE must be set to 0 when setting RDN_DELAY or HALF_PERIOD. */
 	writel(BM_GPMI_CTRL1_DLL_ENABLE, gpmi_regs + HW_GPMI_CTRL1_CLR);
 
 	/* Clear out the DLL control fields. */
-	writel(BM_GPMI_CTRL1_RDN_DELAY,   gpmi_regs + HW_GPMI_CTRL1_CLR);
-	writel(BM_GPMI_CTRL1_HALF_PERIOD, gpmi_regs + HW_GPMI_CTRL1_CLR);
+	reg = BM_GPMI_CTRL1_RDN_DELAY | BM_GPMI_CTRL1_HALF_PERIOD;
+	writel(reg, gpmi_regs + HW_GPMI_CTRL1_CLR);
 
 	/* If no sample delay is called for, return immediately. */
 	if (!hw.sample_delay_factor)
 		return;
 
-	/* Configure the HALF_PERIOD flag. */
-	if (hw.use_half_periods)
-		writel(BM_GPMI_CTRL1_HALF_PERIOD,
-						gpmi_regs + HW_GPMI_CTRL1_SET);
+	/* Set RDN_DELAY or HALF_PERIOD. */
+	reg = ((hw.use_half_periods) ? BM_GPMI_CTRL1_HALF_PERIOD : 0)
+		| BF_GPMI_CTRL1_RDN_DELAY(hw.sample_delay_factor);
 
-	/* Set the delay factor. */
-	writel(BF_GPMI_CTRL1_RDN_DELAY(hw.sample_delay_factor),
-						gpmi_regs + HW_GPMI_CTRL1_SET);
+	writel(reg, gpmi_regs + HW_GPMI_CTRL1_SET);
 
-	/* Enable the DLL. */
+	/* At last, we enable the DLL. */
 	writel(BM_GPMI_CTRL1_DLL_ENABLE, gpmi_regs + HW_GPMI_CTRL1_SET);
 
 	/*
 	 * After we enable the GPMI DLL, we have to wait 64 clock cycles before
-	 * we can use the GPMI.
-	 *
-	 * Calculate the amount of time we need to wait, in microseconds.
+	 * we can use the GPMI. Calculate the amount of time we need to wait,
+	 * in microseconds.
 	 */
+	clock_period_in_ns = NSEC_PER_SEC / clk_get_rate(r->clock[0]);
 	dll_wait_time_in_us = (clock_period_in_ns * 64) / 1000;
 
 	if (!dll_wait_time_in_us)
@@ -784,8 +1035,7 @@
 
 void gpmi_end(struct gpmi_nand_data *this)
 {
-	struct resources *r = &this->resources;
-	clk_disable_unprepare(r->clock);
+	gpmi_disable_clk(this);
 }
 
 /* Clears a BCH interrupt. */
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index a6cad5c..d79696b 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -18,6 +18,9 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/clk.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
@@ -27,6 +30,7 @@
 #include <linux/pinctrl/consumer.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/of_mtd.h>
 #include "gpmi-nand.h"
 
 /* add our owner bbt descriptor */
@@ -113,7 +117,7 @@
 	/* We use the same ECC strength for all chunks. */
 	geo->ecc_strength = get_ecc_strength(this);
 	if (!geo->ecc_strength) {
-		pr_err("We get a wrong ECC strength.\n");
+		pr_err("wrong ECC strength.\n");
 		return -EINVAL;
 	}
 
@@ -316,7 +320,7 @@
 	struct platform_device *pdev = this->pdev;
 	struct resources *res = &this->resources;
 	struct resource *r;
-	void *p;
+	void __iomem *p;
 
 	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name);
 	if (!r) {
@@ -423,8 +427,8 @@
 	struct platform_device *pdev = this->pdev;
 	struct resource *r_dma;
 	struct device_node *dn;
-	int dma_channel;
-	unsigned int ret;
+	u32 dma_channel;
+	int ret;
 	struct dma_chan *dma_chan;
 	dma_cap_mask_t mask;
 
@@ -464,9 +468,73 @@
 	return -EINVAL;
 }
 
+static void gpmi_put_clks(struct gpmi_nand_data *this)
+{
+	struct resources *r = &this->resources;
+	struct clk *clk;
+	int i;
+
+	for (i = 0; i < GPMI_CLK_MAX; i++) {
+		clk = r->clock[i];
+		if (clk) {
+			clk_put(clk);
+			r->clock[i] = NULL;
+		}
+	}
+}
+
+static char *extra_clks_for_mx6q[GPMI_CLK_MAX] = {
+	"gpmi_apb", "gpmi_bch", "gpmi_bch_apb", "per1_bch",
+};
+
+static int __devinit gpmi_get_clks(struct gpmi_nand_data *this)
+{
+	struct resources *r = &this->resources;
+	char **extra_clks = NULL;
+	struct clk *clk;
+	int i;
+
+	/* The main clock is stored in the first. */
+	r->clock[0] = clk_get(this->dev, "gpmi_io");
+	if (IS_ERR(r->clock[0]))
+		goto err_clock;
+
+	/* Get extra clocks */
+	if (GPMI_IS_MX6Q(this))
+		extra_clks = extra_clks_for_mx6q;
+	if (!extra_clks)
+		return 0;
+
+	for (i = 1; i < GPMI_CLK_MAX; i++) {
+		if (extra_clks[i - 1] == NULL)
+			break;
+
+		clk = clk_get(this->dev, extra_clks[i - 1]);
+		if (IS_ERR(clk))
+			goto err_clock;
+
+		r->clock[i] = clk;
+	}
+
+	if (GPMI_IS_MX6Q(this))
+		/*
+		 * Set the default value for the gpmi clock in mx6q:
+		 *
+		 * If you want to use the ONFI nand which is in the
+		 * Synchronous Mode, you should change the clock as you need.
+		 */
+		clk_set_rate(r->clock[0], 22000000);
+
+	return 0;
+
+err_clock:
+	dev_dbg(this->dev, "failed in finding the clocks.\n");
+	gpmi_put_clks(this);
+	return -ENOMEM;
+}
+
 static int __devinit acquire_resources(struct gpmi_nand_data *this)
 {
-	struct resources *res = &this->resources;
 	struct pinctrl *pinctrl;
 	int ret;
 
@@ -492,12 +560,9 @@
 		goto exit_pin;
 	}
 
-	res->clock = clk_get(&this->pdev->dev, NULL);
-	if (IS_ERR(res->clock)) {
-		pr_err("can not get the clock\n");
-		ret = -ENOENT;
+	ret = gpmi_get_clks(this);
+	if (ret)
 		goto exit_clock;
-	}
 	return 0;
 
 exit_clock:
@@ -512,9 +577,7 @@
 
 static void release_resources(struct gpmi_nand_data *this)
 {
-	struct resources *r = &this->resources;
-
-	clk_put(r->clock);
+	gpmi_put_clks(this);
 	release_register_block(this);
 	release_bch_irq(this);
 	release_dma_channels(this);
@@ -667,12 +730,12 @@
 	struct device *dev = this->dev;
 
 	/* [1] Allocate a command buffer. PAGE_SIZE is enough. */
-	this->cmd_buffer = kzalloc(PAGE_SIZE, GFP_DMA);
+	this->cmd_buffer = kzalloc(PAGE_SIZE, GFP_DMA | GFP_KERNEL);
 	if (this->cmd_buffer == NULL)
 		goto error_alloc;
 
 	/* [2] Allocate a read/write data buffer. PAGE_SIZE is enough. */
-	this->data_buffer_dma = kzalloc(PAGE_SIZE, GFP_DMA);
+	this->data_buffer_dma = kzalloc(PAGE_SIZE, GFP_DMA | GFP_KERNEL);
 	if (this->data_buffer_dma == NULL)
 		goto error_alloc;
 
@@ -930,7 +993,7 @@
 	return ret;
 }
 
-static void gpmi_ecc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
+static int gpmi_ecc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
 				const uint8_t *buf, int oob_required)
 {
 	struct gpmi_nand_data *this = chip->priv;
@@ -972,7 +1035,7 @@
 				&payload_virt, &payload_phys);
 		if (ret) {
 			pr_err("Inadequate payload DMA buffer\n");
-			return;
+			return 0;
 		}
 
 		ret = send_page_prepare(this,
@@ -1002,6 +1065,8 @@
 				nfc_geo->payload_size,
 				payload_virt, payload_phys);
 	}
+
+	return 0;
 }
 
 /*
@@ -1064,6 +1129,9 @@
  * ECC-based or raw view of the page is implicit in which function it calls
  * (there is a similar pair of ECC-based/raw functions for writing).
  *
+ * FIXME: The following paragraph is incorrect, now that there exist
+ * ecc.read_oob_raw and ecc.write_oob_raw functions.
+ *
  * Since MTD assumes the OOB is not covered by ECC, there is no pair of
  * ECC-based/raw functions for reading or or writing the OOB. The fact that the
  * caller wants an ECC-based or raw view of the page is not propagated down to
@@ -1190,7 +1258,6 @@
 	unsigned int search_area_size_in_strides;
 	unsigned int stride;
 	unsigned int page;
-	loff_t byte;
 	uint8_t *buffer = chip->buffers->databuf;
 	int saved_chip_number;
 	int found_an_ncb_fingerprint = false;
@@ -1207,9 +1274,8 @@
 	dev_dbg(dev, "Scanning for an NCB fingerprint...\n");
 
 	for (stride = 0; stride < search_area_size_in_strides; stride++) {
-		/* Compute the page and byte addresses. */
+		/* Compute the page addresses. */
 		page = stride * rom_geo->stride_size_in_pages;
-		byte = page   * mtd->writesize;
 
 		dev_dbg(dev, "Looking for a fingerprint in page 0x%x\n", page);
 
@@ -1251,7 +1317,6 @@
 	unsigned int block;
 	unsigned int stride;
 	unsigned int page;
-	loff_t       byte;
 	uint8_t      *buffer = chip->buffers->databuf;
 	int saved_chip_number;
 	int status;
@@ -1300,9 +1365,8 @@
 	/* Loop through the first search area, writing NCB fingerprints. */
 	dev_dbg(dev, "Writing NCB fingerprints...\n");
 	for (stride = 0; stride < search_area_size_in_strides; stride++) {
-		/* Compute the page and byte addresses. */
+		/* Compute the page addresses. */
 		page = stride * rom_geo->stride_size_in_pages;
-		byte = page   * mtd->writesize;
 
 		/* Write the first page of the current stride. */
 		dev_dbg(dev, "Writing an NCB fingerprint in page 0x%x\n", page);
@@ -1436,6 +1500,7 @@
 	/* Adjust the ECC strength according to the chip. */
 	this->nand.ecc.strength = this->bch_geometry.ecc_strength;
 	this->mtd.ecc_strength = this->bch_geometry.ecc_strength;
+	this->mtd.bitflip_threshold = this->bch_geometry.ecc_strength;
 
 	/* NAND boot init, depends on the gpmi_set_geometry(). */
 	return nand_boot_init(this);
@@ -1452,11 +1517,19 @@
 	if (ret)
 		return ret;
 
+	/*
+	 * Can we enable the extra features? such as EDO or Sync mode.
+	 *
+	 * We do not check the return value now. That's means if we fail in
+	 * enable the extra features, we still can run in the normal way.
+	 */
+	gpmi_extra_init(this);
+
 	/* use the default BBT implementation */
 	return nand_default_bbt(mtd);
 }
 
-void gpmi_nfc_exit(struct gpmi_nand_data *this)
+static void gpmi_nfc_exit(struct gpmi_nand_data *this)
 {
 	nand_release(&this->mtd);
 	gpmi_free_dma_buffer(this);
@@ -1497,6 +1570,8 @@
 	chip->ecc.size		= 1;
 	chip->ecc.strength	= 8;
 	chip->ecc.layout	= &gpmi_hw_ecclayout;
+	if (of_get_nand_on_flash_bbt(this->dev->of_node))
+		chip->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;
 
 	/* Allocate a temporary DMA buffer for reading ID in the nand_scan() */
 	this->bch_geometry.payload_size = 1024;
@@ -1579,6 +1654,8 @@
 	if (ret)
 		goto exit_nfc_init;
 
+	dev_info(this->dev, "driver registered.\n");
+
 	return 0;
 
 exit_nfc_init:
@@ -1586,10 +1663,12 @@
 exit_acquire_resources:
 	platform_set_drvdata(pdev, NULL);
 	kfree(this);
+	dev_err(this->dev, "driver registration failed: %d\n", ret);
+
 	return ret;
 }
 
-static int __exit gpmi_nand_remove(struct platform_device *pdev)
+static int __devexit gpmi_nand_remove(struct platform_device *pdev)
 {
 	struct gpmi_nand_data *this = platform_get_drvdata(pdev);
 
@@ -1606,29 +1685,10 @@
 		.of_match_table = gpmi_nand_id_table,
 	},
 	.probe   = gpmi_nand_probe,
-	.remove  = __exit_p(gpmi_nand_remove),
+	.remove  = __devexit_p(gpmi_nand_remove),
 	.id_table = gpmi_ids,
 };
-
-static int __init gpmi_nand_init(void)
-{
-	int err;
-
-	err = platform_driver_register(&gpmi_nand_driver);
-	if (err == 0)
-		printk(KERN_INFO "GPMI NAND driver registered. (IMX)\n");
-	else
-		pr_err("i.MX GPMI NAND driver registration failed\n");
-	return err;
-}
-
-static void __exit gpmi_nand_exit(void)
-{
-	platform_driver_unregister(&gpmi_nand_driver);
-}
-
-module_init(gpmi_nand_init);
-module_exit(gpmi_nand_exit);
+module_platform_driver(gpmi_nand_driver);
 
 MODULE_AUTHOR("Freescale Semiconductor, Inc.");
 MODULE_DESCRIPTION("i.MX GPMI NAND Flash Controller Driver");
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
index ce5daa1..7ac25c1 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
@@ -22,14 +22,15 @@
 #include <linux/dma-mapping.h>
 #include <linux/fsl/mxs-dma.h>
 
+#define GPMI_CLK_MAX 5 /* MX6Q needs five clocks */
 struct resources {
-	void          *gpmi_regs;
-	void          *bch_regs;
+	void __iomem  *gpmi_regs;
+	void __iomem  *bch_regs;
 	unsigned int  bch_low_interrupt;
 	unsigned int  bch_high_interrupt;
 	unsigned int  dma_low_channel;
 	unsigned int  dma_high_channel;
-	struct clk    *clock;
+	struct clk    *clock[GPMI_CLK_MAX];
 };
 
 /**
@@ -121,6 +122,11 @@
 };
 
 struct gpmi_nand_data {
+	/* flags */
+#define GPMI_ASYNC_EDO_ENABLED	(1 << 0)
+#define GPMI_TIMING_INIT_OK	(1 << 1)
+	int			flags;
+
 	/* System Interface */
 	struct device		*dev;
 	struct platform_device	*pdev;
@@ -131,6 +137,7 @@
 
 	/* Flash Hardware */
 	struct nand_timing	timing;
+	int			timing_mode;
 
 	/* BCH */
 	struct bch_geometry	bch_geometry;
@@ -188,16 +195,28 @@
  * @data_setup_in_cycles:      The data setup time, in cycles.
  * @data_hold_in_cycles:       The data hold time, in cycles.
  * @address_setup_in_cycles:   The address setup time, in cycles.
+ * @device_busy_timeout:       The timeout waiting for NAND Ready/Busy,
+ *                             this value is the number of cycles multiplied
+ *                             by 4096.
  * @use_half_periods:          Indicates the clock is running slowly, so the
  *                             NFC DLL should use half-periods.
  * @sample_delay_factor:       The sample delay factor.
+ * @wrn_dly_sel:               The delay on the GPMI write strobe.
  */
 struct gpmi_nfc_hardware_timing {
+	/* for HW_GPMI_TIMING0 */
 	uint8_t  data_setup_in_cycles;
 	uint8_t  data_hold_in_cycles;
 	uint8_t  address_setup_in_cycles;
+
+	/* for HW_GPMI_TIMING1 */
+	uint16_t device_busy_timeout;
+#define GPMI_DEFAULT_BUSY_TIMEOUT	0x500 /* default busy timeout value.*/
+
+	/* for HW_GPMI_CTRL1 */
 	bool     use_half_periods;
 	uint8_t  sample_delay_factor;
+	uint8_t  wrn_dly_sel;
 };
 
 /**
@@ -246,6 +265,7 @@
 
 /* GPMI-NAND helper function library */
 extern int gpmi_init(struct gpmi_nand_data *);
+extern int gpmi_extra_init(struct gpmi_nand_data *);
 extern void gpmi_clear_bch(struct gpmi_nand_data *);
 extern void gpmi_dump_info(struct gpmi_nand_data *);
 extern int bch_set_geometry(struct gpmi_nand_data *);
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-regs.h b/drivers/mtd/nand/gpmi-nand/gpmi-regs.h
index 8343124..53397cc 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-regs.h
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-regs.h
@@ -108,6 +108,15 @@
 #define HW_GPMI_CTRL1_CLR				0x00000068
 #define HW_GPMI_CTRL1_TOG				0x0000006c
 
+#define BP_GPMI_CTRL1_WRN_DLY_SEL			22
+#define BM_GPMI_CTRL1_WRN_DLY_SEL	(0x3 << BP_GPMI_CTRL1_WRN_DLY_SEL)
+#define BF_GPMI_CTRL1_WRN_DLY_SEL(v)  \
+	(((v) << BP_GPMI_CTRL1_WRN_DLY_SEL) & BM_GPMI_CTRL1_WRN_DLY_SEL)
+#define BV_GPMI_CTRL1_WRN_DLY_SEL_4_TO_8NS		0x0
+#define BV_GPMI_CTRL1_WRN_DLY_SEL_6_TO_10NS		0x1
+#define BV_GPMI_CTRL1_WRN_DLY_SEL_7_TO_12NS		0x2
+#define BV_GPMI_CTRL1_WRN_DLY_SEL_NO_DELAY		0x3
+
 #define BM_GPMI_CTRL1_BCH_MODE				(1 << 18)
 
 #define BP_GPMI_CTRL1_DLL_ENABLE			17
@@ -154,6 +163,9 @@
 
 #define HW_GPMI_TIMING1					0x00000080
 #define BP_GPMI_TIMING1_BUSY_TIMEOUT			16
+#define BM_GPMI_TIMING1_BUSY_TIMEOUT	(0xffff << BP_GPMI_TIMING1_BUSY_TIMEOUT)
+#define BF_GPMI_TIMING1_BUSY_TIMEOUT(v)		\
+	(((v) << BP_GPMI_TIMING1_BUSY_TIMEOUT) & BM_GPMI_TIMING1_BUSY_TIMEOUT)
 
 #define HW_GPMI_TIMING2					0x00000090
 #define HW_GPMI_DATA					0x000000a0
diff --git a/drivers/mtd/nand/lpc32xx_mlc.c b/drivers/mtd/nand/lpc32xx_mlc.c
new file mode 100644
index 0000000..c29b7ac
--- /dev/null
+++ b/drivers/mtd/nand/lpc32xx_mlc.c
@@ -0,0 +1,924 @@
+/*
+ * Driver for NAND MLC Controller in LPC32xx
+ *
+ * Author: Roland Stigge <stigge@antcom.de>
+ *
+ * Copyright © 2011 WORK Microwave GmbH
+ * Copyright © 2011, 2012 Roland Stigge
+ *
+ * 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.
+ *
+ *
+ * NAND Flash Controller Operation:
+ * - Read: Auto Decode
+ * - Write: Auto Encode
+ * - Tested Page Sizes: 2048, 4096
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+#include <linux/of.h>
+#include <linux/of_mtd.h>
+#include <linux/of_gpio.h>
+#include <linux/mtd/lpc32xx_mlc.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/mtd/nand_ecc.h>
+
+#define DRV_NAME "lpc32xx_mlc"
+
+/**********************************************************************
+* MLC NAND controller register offsets
+**********************************************************************/
+
+#define MLC_BUFF(x)			(x + 0x00000)
+#define MLC_DATA(x)			(x + 0x08000)
+#define MLC_CMD(x)			(x + 0x10000)
+#define MLC_ADDR(x)			(x + 0x10004)
+#define MLC_ECC_ENC_REG(x)		(x + 0x10008)
+#define MLC_ECC_DEC_REG(x)		(x + 0x1000C)
+#define MLC_ECC_AUTO_ENC_REG(x)		(x + 0x10010)
+#define MLC_ECC_AUTO_DEC_REG(x)		(x + 0x10014)
+#define MLC_RPR(x)			(x + 0x10018)
+#define MLC_WPR(x)			(x + 0x1001C)
+#define MLC_RUBP(x)			(x + 0x10020)
+#define MLC_ROBP(x)			(x + 0x10024)
+#define MLC_SW_WP_ADD_LOW(x)		(x + 0x10028)
+#define MLC_SW_WP_ADD_HIG(x)		(x + 0x1002C)
+#define MLC_ICR(x)			(x + 0x10030)
+#define MLC_TIME_REG(x)			(x + 0x10034)
+#define MLC_IRQ_MR(x)			(x + 0x10038)
+#define MLC_IRQ_SR(x)			(x + 0x1003C)
+#define MLC_LOCK_PR(x)			(x + 0x10044)
+#define MLC_ISR(x)			(x + 0x10048)
+#define MLC_CEH(x)			(x + 0x1004C)
+
+/**********************************************************************
+* MLC_CMD bit definitions
+**********************************************************************/
+#define MLCCMD_RESET			0xFF
+
+/**********************************************************************
+* MLC_ICR bit definitions
+**********************************************************************/
+#define MLCICR_WPROT			(1 << 3)
+#define MLCICR_LARGEBLOCK		(1 << 2)
+#define MLCICR_LONGADDR			(1 << 1)
+#define MLCICR_16BIT			(1 << 0)  /* unsupported by LPC32x0! */
+
+/**********************************************************************
+* MLC_TIME_REG bit definitions
+**********************************************************************/
+#define MLCTIMEREG_TCEA_DELAY(n)	(((n) & 0x03) << 24)
+#define MLCTIMEREG_BUSY_DELAY(n)	(((n) & 0x1F) << 19)
+#define MLCTIMEREG_NAND_TA(n)		(((n) & 0x07) << 16)
+#define MLCTIMEREG_RD_HIGH(n)		(((n) & 0x0F) << 12)
+#define MLCTIMEREG_RD_LOW(n)		(((n) & 0x0F) << 8)
+#define MLCTIMEREG_WR_HIGH(n)		(((n) & 0x0F) << 4)
+#define MLCTIMEREG_WR_LOW(n)		(((n) & 0x0F) << 0)
+
+/**********************************************************************
+* MLC_IRQ_MR and MLC_IRQ_SR bit definitions
+**********************************************************************/
+#define MLCIRQ_NAND_READY		(1 << 5)
+#define MLCIRQ_CONTROLLER_READY		(1 << 4)
+#define MLCIRQ_DECODE_FAILURE		(1 << 3)
+#define MLCIRQ_DECODE_ERROR		(1 << 2)
+#define MLCIRQ_ECC_READY		(1 << 1)
+#define MLCIRQ_WRPROT_FAULT		(1 << 0)
+
+/**********************************************************************
+* MLC_LOCK_PR bit definitions
+**********************************************************************/
+#define MLCLOCKPR_MAGIC			0xA25E
+
+/**********************************************************************
+* MLC_ISR bit definitions
+**********************************************************************/
+#define MLCISR_DECODER_FAILURE		(1 << 6)
+#define MLCISR_ERRORS			((1 << 4) | (1 << 5))
+#define MLCISR_ERRORS_DETECTED		(1 << 3)
+#define MLCISR_ECC_READY		(1 << 2)
+#define MLCISR_CONTROLLER_READY		(1 << 1)
+#define MLCISR_NAND_READY		(1 << 0)
+
+/**********************************************************************
+* MLC_CEH bit definitions
+**********************************************************************/
+#define MLCCEH_NORMAL			(1 << 0)
+
+struct lpc32xx_nand_cfg_mlc {
+	uint32_t tcea_delay;
+	uint32_t busy_delay;
+	uint32_t nand_ta;
+	uint32_t rd_high;
+	uint32_t rd_low;
+	uint32_t wr_high;
+	uint32_t wr_low;
+	int wp_gpio;
+	struct mtd_partition *parts;
+	unsigned num_parts;
+};
+
+static struct nand_ecclayout lpc32xx_nand_oob = {
+	.eccbytes = 40,
+	.eccpos = { 6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+		   22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+		   38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+		   54, 55, 56, 57, 58, 59, 60, 61, 62, 63 },
+	.oobfree = {
+		{ .offset = 0,
+		  .length = 6, },
+		{ .offset = 16,
+		  .length = 6, },
+		{ .offset = 32,
+		  .length = 6, },
+		{ .offset = 48,
+		  .length = 6, },
+		},
+};
+
+static struct nand_bbt_descr lpc32xx_nand_bbt = {
+	.options = NAND_BBT_ABSPAGE | NAND_BBT_2BIT | NAND_BBT_NO_OOB |
+		   NAND_BBT_WRITE,
+	.pages = { 524224, 0, 0, 0, 0, 0, 0, 0 },
+};
+
+static struct nand_bbt_descr lpc32xx_nand_bbt_mirror = {
+	.options = NAND_BBT_ABSPAGE | NAND_BBT_2BIT | NAND_BBT_NO_OOB |
+		   NAND_BBT_WRITE,
+	.pages = { 524160, 0, 0, 0, 0, 0, 0, 0 },
+};
+
+struct lpc32xx_nand_host {
+	struct nand_chip	nand_chip;
+	struct lpc32xx_mlc_platform_data *pdata;
+	struct clk		*clk;
+	struct mtd_info		mtd;
+	void __iomem		*io_base;
+	int			irq;
+	struct lpc32xx_nand_cfg_mlc	*ncfg;
+	struct completion       comp_nand;
+	struct completion       comp_controller;
+	uint32_t llptr;
+	/*
+	 * Physical addresses of ECC buffer, DMA data buffers, OOB data buffer
+	 */
+	dma_addr_t		oob_buf_phy;
+	/*
+	 * Virtual addresses of ECC buffer, DMA data buffers, OOB data buffer
+	 */
+	uint8_t			*oob_buf;
+	/* Physical address of DMA base address */
+	dma_addr_t		io_base_phy;
+
+	struct completion	comp_dma;
+	struct dma_chan		*dma_chan;
+	struct dma_slave_config	dma_slave_config;
+	struct scatterlist	sgl;
+	uint8_t			*dma_buf;
+	uint8_t			*dummy_buf;
+	int			mlcsubpages; /* number of 512bytes-subpages */
+};
+
+/*
+ * Activate/Deactivate DMA Operation:
+ *
+ * Using the PL080 DMA Controller for transferring the 512 byte subpages
+ * instead of doing readl() / writel() in a loop slows it down significantly.
+ * Measurements via getnstimeofday() upon 512 byte subpage reads reveal:
+ *
+ * - readl() of 128 x 32 bits in a loop: ~20us
+ * - DMA read of 512 bytes (32 bit, 4...128 words bursts): ~60us
+ * - DMA read of 512 bytes (32 bit, no bursts): ~100us
+ *
+ * This applies to the transfer itself. In the DMA case: only the
+ * wait_for_completion() (DMA setup _not_ included).
+ *
+ * Note that the 512 bytes subpage transfer is done directly from/to a
+ * FIFO/buffer inside the NAND controller. Most of the time (~400-800us for a
+ * 2048 bytes page) is spent waiting for the NAND IRQ, anyway. (The NAND
+ * controller transferring data between its internal buffer to/from the NAND
+ * chip.)
+ *
+ * Therefore, using the PL080 DMA is disabled by default, for now.
+ *
+ */
+static int use_dma;
+
+static void lpc32xx_nand_setup(struct lpc32xx_nand_host *host)
+{
+	uint32_t clkrate, tmp;
+
+	/* Reset MLC controller */
+	writel(MLCCMD_RESET, MLC_CMD(host->io_base));
+	udelay(1000);
+
+	/* Get base clock for MLC block */
+	clkrate = clk_get_rate(host->clk);
+	if (clkrate == 0)
+		clkrate = 104000000;
+
+	/* Unlock MLC_ICR
+	 * (among others, will be locked again automatically) */
+	writew(MLCLOCKPR_MAGIC, MLC_LOCK_PR(host->io_base));
+
+	/* Configure MLC Controller: Large Block, 5 Byte Address */
+	tmp = MLCICR_LARGEBLOCK | MLCICR_LONGADDR;
+	writel(tmp, MLC_ICR(host->io_base));
+
+	/* Unlock MLC_TIME_REG
+	 * (among others, will be locked again automatically) */
+	writew(MLCLOCKPR_MAGIC, MLC_LOCK_PR(host->io_base));
+
+	/* Compute clock setup values, see LPC and NAND manual */
+	tmp = 0;
+	tmp |= MLCTIMEREG_TCEA_DELAY(clkrate / host->ncfg->tcea_delay + 1);
+	tmp |= MLCTIMEREG_BUSY_DELAY(clkrate / host->ncfg->busy_delay + 1);
+	tmp |= MLCTIMEREG_NAND_TA(clkrate / host->ncfg->nand_ta + 1);
+	tmp |= MLCTIMEREG_RD_HIGH(clkrate / host->ncfg->rd_high + 1);
+	tmp |= MLCTIMEREG_RD_LOW(clkrate / host->ncfg->rd_low);
+	tmp |= MLCTIMEREG_WR_HIGH(clkrate / host->ncfg->wr_high + 1);
+	tmp |= MLCTIMEREG_WR_LOW(clkrate / host->ncfg->wr_low);
+	writel(tmp, MLC_TIME_REG(host->io_base));
+
+	/* Enable IRQ for CONTROLLER_READY and NAND_READY */
+	writeb(MLCIRQ_CONTROLLER_READY | MLCIRQ_NAND_READY,
+			MLC_IRQ_MR(host->io_base));
+
+	/* Normal nCE operation: nCE controlled by controller */
+	writel(MLCCEH_NORMAL, MLC_CEH(host->io_base));
+}
+
+/*
+ * Hardware specific access to control lines
+ */
+static void lpc32xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
+				  unsigned int ctrl)
+{
+	struct nand_chip *nand_chip = mtd->priv;
+	struct lpc32xx_nand_host *host = nand_chip->priv;
+
+	if (cmd != NAND_CMD_NONE) {
+		if (ctrl & NAND_CLE)
+			writel(cmd, MLC_CMD(host->io_base));
+		else
+			writel(cmd, MLC_ADDR(host->io_base));
+	}
+}
+
+/*
+ * Read Device Ready (NAND device _and_ controller ready)
+ */
+static int lpc32xx_nand_device_ready(struct mtd_info *mtd)
+{
+	struct nand_chip *nand_chip = mtd->priv;
+	struct lpc32xx_nand_host *host = nand_chip->priv;
+
+	if ((readb(MLC_ISR(host->io_base)) &
+	     (MLCISR_CONTROLLER_READY | MLCISR_NAND_READY)) ==
+	    (MLCISR_CONTROLLER_READY | MLCISR_NAND_READY))
+		return  1;
+
+	return 0;
+}
+
+static irqreturn_t lpc3xxx_nand_irq(int irq, struct lpc32xx_nand_host *host)
+{
+	uint8_t sr;
+
+	/* Clear interrupt flag by reading status */
+	sr = readb(MLC_IRQ_SR(host->io_base));
+	if (sr & MLCIRQ_NAND_READY)
+		complete(&host->comp_nand);
+	if (sr & MLCIRQ_CONTROLLER_READY)
+		complete(&host->comp_controller);
+
+	return IRQ_HANDLED;
+}
+
+static int lpc32xx_waitfunc_nand(struct mtd_info *mtd, struct nand_chip *chip)
+{
+	struct lpc32xx_nand_host *host = chip->priv;
+
+	if (readb(MLC_ISR(host->io_base)) & MLCISR_NAND_READY)
+		goto exit;
+
+	wait_for_completion(&host->comp_nand);
+
+	while (!(readb(MLC_ISR(host->io_base)) & MLCISR_NAND_READY)) {
+		/* Seems to be delayed sometimes by controller */
+		dev_dbg(&mtd->dev, "Warning: NAND not ready.\n");
+		cpu_relax();
+	}
+
+exit:
+	return NAND_STATUS_READY;
+}
+
+static int lpc32xx_waitfunc_controller(struct mtd_info *mtd,
+				       struct nand_chip *chip)
+{
+	struct lpc32xx_nand_host *host = chip->priv;
+
+	if (readb(MLC_ISR(host->io_base)) & MLCISR_CONTROLLER_READY)
+		goto exit;
+
+	wait_for_completion(&host->comp_controller);
+
+	while (!(readb(MLC_ISR(host->io_base)) &
+		 MLCISR_CONTROLLER_READY)) {
+		dev_dbg(&mtd->dev, "Warning: Controller not ready.\n");
+		cpu_relax();
+	}
+
+exit:
+	return NAND_STATUS_READY;
+}
+
+static int lpc32xx_waitfunc(struct mtd_info *mtd, struct nand_chip *chip)
+{
+	lpc32xx_waitfunc_nand(mtd, chip);
+	lpc32xx_waitfunc_controller(mtd, chip);
+
+	return NAND_STATUS_READY;
+}
+
+/*
+ * Enable NAND write protect
+ */
+static void lpc32xx_wp_enable(struct lpc32xx_nand_host *host)
+{
+	if (gpio_is_valid(host->ncfg->wp_gpio))
+		gpio_set_value(host->ncfg->wp_gpio, 0);
+}
+
+/*
+ * Disable NAND write protect
+ */
+static void lpc32xx_wp_disable(struct lpc32xx_nand_host *host)
+{
+	if (gpio_is_valid(host->ncfg->wp_gpio))
+		gpio_set_value(host->ncfg->wp_gpio, 1);
+}
+
+static void lpc32xx_dma_complete_func(void *completion)
+{
+	complete(completion);
+}
+
+static int lpc32xx_xmit_dma(struct mtd_info *mtd, void *mem, int len,
+			    enum dma_transfer_direction dir)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct lpc32xx_nand_host *host = chip->priv;
+	struct dma_async_tx_descriptor *desc;
+	int flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
+	int res;
+
+	sg_init_one(&host->sgl, mem, len);
+
+	res = dma_map_sg(host->dma_chan->device->dev, &host->sgl, 1,
+			 DMA_BIDIRECTIONAL);
+	if (res != 1) {
+		dev_err(mtd->dev.parent, "Failed to map sg list\n");
+		return -ENXIO;
+	}
+	desc = dmaengine_prep_slave_sg(host->dma_chan, &host->sgl, 1, dir,
+				       flags);
+	if (!desc) {
+		dev_err(mtd->dev.parent, "Failed to prepare slave sg\n");
+		goto out1;
+	}
+
+	init_completion(&host->comp_dma);
+	desc->callback = lpc32xx_dma_complete_func;
+	desc->callback_param = &host->comp_dma;
+
+	dmaengine_submit(desc);
+	dma_async_issue_pending(host->dma_chan);
+
+	wait_for_completion_timeout(&host->comp_dma, msecs_to_jiffies(1000));
+
+	dma_unmap_sg(host->dma_chan->device->dev, &host->sgl, 1,
+		     DMA_BIDIRECTIONAL);
+	return 0;
+out1:
+	dma_unmap_sg(host->dma_chan->device->dev, &host->sgl, 1,
+		     DMA_BIDIRECTIONAL);
+	return -ENXIO;
+}
+
+static int lpc32xx_read_page(struct mtd_info *mtd, struct nand_chip *chip,
+			     uint8_t *buf, int oob_required, int page)
+{
+	struct lpc32xx_nand_host *host = chip->priv;
+	int i, j;
+	uint8_t *oobbuf = chip->oob_poi;
+	uint32_t mlc_isr;
+	int res;
+	uint8_t *dma_buf;
+	bool dma_mapped;
+
+	if ((void *)buf <= high_memory) {
+		dma_buf = buf;
+		dma_mapped = true;
+	} else {
+		dma_buf = host->dma_buf;
+		dma_mapped = false;
+	}
+
+	/* Writing Command and Address */
+	chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
+
+	/* For all sub-pages */
+	for (i = 0; i < host->mlcsubpages; i++) {
+		/* Start Auto Decode Command */
+		writeb(0x00, MLC_ECC_AUTO_DEC_REG(host->io_base));
+
+		/* Wait for Controller Ready */
+		lpc32xx_waitfunc_controller(mtd, chip);
+
+		/* Check ECC Error status */
+		mlc_isr = readl(MLC_ISR(host->io_base));
+		if (mlc_isr & MLCISR_DECODER_FAILURE) {
+			mtd->ecc_stats.failed++;
+			dev_warn(&mtd->dev, "%s: DECODER_FAILURE\n", __func__);
+		} else if (mlc_isr & MLCISR_ERRORS_DETECTED) {
+			mtd->ecc_stats.corrected += ((mlc_isr >> 4) & 0x3) + 1;
+		}
+
+		/* Read 512 + 16 Bytes */
+		if (use_dma) {
+			res = lpc32xx_xmit_dma(mtd, dma_buf + i * 512, 512,
+					       DMA_DEV_TO_MEM);
+			if (res)
+				return res;
+		} else {
+			for (j = 0; j < (512 >> 2); j++) {
+				*((uint32_t *)(buf)) =
+					readl(MLC_BUFF(host->io_base));
+				buf += 4;
+			}
+		}
+		for (j = 0; j < (16 >> 2); j++) {
+			*((uint32_t *)(oobbuf)) =
+				readl(MLC_BUFF(host->io_base));
+			oobbuf += 4;
+		}
+	}
+
+	if (use_dma && !dma_mapped)
+		memcpy(buf, dma_buf, mtd->writesize);
+
+	return 0;
+}
+
+static int lpc32xx_write_page_lowlevel(struct mtd_info *mtd,
+				       struct nand_chip *chip,
+				       const uint8_t *buf, int oob_required)
+{
+	struct lpc32xx_nand_host *host = chip->priv;
+	const uint8_t *oobbuf = chip->oob_poi;
+	uint8_t *dma_buf = (uint8_t *)buf;
+	int res;
+	int i, j;
+
+	if (use_dma && (void *)buf >= high_memory) {
+		dma_buf = host->dma_buf;
+		memcpy(dma_buf, buf, mtd->writesize);
+	}
+
+	for (i = 0; i < host->mlcsubpages; i++) {
+		/* Start Encode */
+		writeb(0x00, MLC_ECC_ENC_REG(host->io_base));
+
+		/* Write 512 + 6 Bytes to Buffer */
+		if (use_dma) {
+			res = lpc32xx_xmit_dma(mtd, dma_buf + i * 512, 512,
+					       DMA_MEM_TO_DEV);
+			if (res)
+				return res;
+		} else {
+			for (j = 0; j < (512 >> 2); j++) {
+				writel(*((uint32_t *)(buf)),
+				       MLC_BUFF(host->io_base));
+				buf += 4;
+			}
+		}
+		writel(*((uint32_t *)(oobbuf)), MLC_BUFF(host->io_base));
+		oobbuf += 4;
+		writew(*((uint16_t *)(oobbuf)), MLC_BUFF(host->io_base));
+		oobbuf += 12;
+
+		/* Auto Encode w/ Bit 8 = 0 (see LPC MLC Controller manual) */
+		writeb(0x00, MLC_ECC_AUTO_ENC_REG(host->io_base));
+
+		/* Wait for Controller Ready */
+		lpc32xx_waitfunc_controller(mtd, chip);
+	}
+	return 0;
+}
+
+static int lpc32xx_write_page(struct mtd_info *mtd, struct nand_chip *chip,
+			      const uint8_t *buf, int oob_required, int page,
+			      int cached, int raw)
+{
+	int res;
+
+	chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
+	res = lpc32xx_write_page_lowlevel(mtd, chip, buf, oob_required);
+	chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
+	lpc32xx_waitfunc(mtd, chip);
+
+	return res;
+}
+
+static int lpc32xx_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
+			    int page)
+{
+	struct lpc32xx_nand_host *host = chip->priv;
+
+	/* Read whole page - necessary with MLC controller! */
+	lpc32xx_read_page(mtd, chip, host->dummy_buf, 1, page);
+
+	return 0;
+}
+
+static int lpc32xx_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
+			      int page)
+{
+	/* None, write_oob conflicts with the automatic LPC MLC ECC decoder! */
+	return 0;
+}
+
+/* Prepares MLC for transfers with H/W ECC enabled: always enabled anyway */
+static void lpc32xx_ecc_enable(struct mtd_info *mtd, int mode)
+{
+	/* Always enabled! */
+}
+
+static int lpc32xx_dma_setup(struct lpc32xx_nand_host *host)
+{
+	struct mtd_info *mtd = &host->mtd;
+	dma_cap_mask_t mask;
+
+	if (!host->pdata || !host->pdata->dma_filter) {
+		dev_err(mtd->dev.parent, "no DMA platform data\n");
+		return -ENOENT;
+	}
+
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+	host->dma_chan = dma_request_channel(mask, host->pdata->dma_filter,
+					     "nand-mlc");
+	if (!host->dma_chan) {
+		dev_err(mtd->dev.parent, "Failed to request DMA channel\n");
+		return -EBUSY;
+	}
+
+	/*
+	 * Set direction to a sensible value even if the dmaengine driver
+	 * should ignore it. With the default (DMA_MEM_TO_MEM), the amba-pl08x
+	 * driver criticizes it as "alien transfer direction".
+	 */
+	host->dma_slave_config.direction = DMA_DEV_TO_MEM;
+	host->dma_slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	host->dma_slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	host->dma_slave_config.src_maxburst = 128;
+	host->dma_slave_config.dst_maxburst = 128;
+	/* DMA controller does flow control: */
+	host->dma_slave_config.device_fc = false;
+	host->dma_slave_config.src_addr = MLC_BUFF(host->io_base_phy);
+	host->dma_slave_config.dst_addr = MLC_BUFF(host->io_base_phy);
+	if (dmaengine_slave_config(host->dma_chan, &host->dma_slave_config)) {
+		dev_err(mtd->dev.parent, "Failed to setup DMA slave\n");
+		goto out1;
+	}
+
+	return 0;
+out1:
+	dma_release_channel(host->dma_chan);
+	return -ENXIO;
+}
+
+static struct lpc32xx_nand_cfg_mlc *lpc32xx_parse_dt(struct device *dev)
+{
+	struct lpc32xx_nand_cfg_mlc *ncfg;
+	struct device_node *np = dev->of_node;
+
+	ncfg = devm_kzalloc(dev, sizeof(*ncfg), GFP_KERNEL);
+	if (!ncfg) {
+		dev_err(dev, "could not allocate memory for platform data\n");
+		return NULL;
+	}
+
+	of_property_read_u32(np, "nxp,tcea-delay", &ncfg->tcea_delay);
+	of_property_read_u32(np, "nxp,busy-delay", &ncfg->busy_delay);
+	of_property_read_u32(np, "nxp,nand-ta", &ncfg->nand_ta);
+	of_property_read_u32(np, "nxp,rd-high", &ncfg->rd_high);
+	of_property_read_u32(np, "nxp,rd-low", &ncfg->rd_low);
+	of_property_read_u32(np, "nxp,wr-high", &ncfg->wr_high);
+	of_property_read_u32(np, "nxp,wr-low", &ncfg->wr_low);
+
+	if (!ncfg->tcea_delay || !ncfg->busy_delay || !ncfg->nand_ta ||
+	    !ncfg->rd_high || !ncfg->rd_low || !ncfg->wr_high ||
+	    !ncfg->wr_low) {
+		dev_err(dev, "chip parameters not specified correctly\n");
+		return NULL;
+	}
+
+	ncfg->wp_gpio = of_get_named_gpio(np, "gpios", 0);
+
+	return ncfg;
+}
+
+/*
+ * Probe for NAND controller
+ */
+static int __devinit lpc32xx_nand_probe(struct platform_device *pdev)
+{
+	struct lpc32xx_nand_host *host;
+	struct mtd_info *mtd;
+	struct nand_chip *nand_chip;
+	struct resource *rc;
+	int res;
+	struct mtd_part_parser_data ppdata = {};
+
+	/* Allocate memory for the device structure (and zero it) */
+	host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
+	if (!host) {
+		dev_err(&pdev->dev, "failed to allocate device structure.\n");
+		return -ENOMEM;
+	}
+
+	rc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (rc == NULL) {
+		dev_err(&pdev->dev, "No memory resource found for device!\r\n");
+		return -ENXIO;
+	}
+
+	host->io_base = devm_request_and_ioremap(&pdev->dev, rc);
+	if (host->io_base == NULL) {
+		dev_err(&pdev->dev, "ioremap failed\n");
+		return -EIO;
+	}
+	host->io_base_phy = rc->start;
+
+	mtd = &host->mtd;
+	nand_chip = &host->nand_chip;
+	if (pdev->dev.of_node)
+		host->ncfg = lpc32xx_parse_dt(&pdev->dev);
+	if (!host->ncfg) {
+		dev_err(&pdev->dev,
+			"Missing or bad NAND config from device tree\n");
+		return -ENOENT;
+	}
+	if (host->ncfg->wp_gpio == -EPROBE_DEFER)
+		return -EPROBE_DEFER;
+	if (gpio_is_valid(host->ncfg->wp_gpio) &&
+			gpio_request(host->ncfg->wp_gpio, "NAND WP")) {
+		dev_err(&pdev->dev, "GPIO not available\n");
+		return -EBUSY;
+	}
+	lpc32xx_wp_disable(host);
+
+	host->pdata = pdev->dev.platform_data;
+
+	nand_chip->priv = host;		/* link the private data structures */
+	mtd->priv = nand_chip;
+	mtd->owner = THIS_MODULE;
+	mtd->dev.parent = &pdev->dev;
+
+	/* Get NAND clock */
+	host->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(host->clk)) {
+		dev_err(&pdev->dev, "Clock initialization failure\n");
+		res = -ENOENT;
+		goto err_exit1;
+	}
+	clk_enable(host->clk);
+
+	nand_chip->cmd_ctrl = lpc32xx_nand_cmd_ctrl;
+	nand_chip->dev_ready = lpc32xx_nand_device_ready;
+	nand_chip->chip_delay = 25; /* us */
+	nand_chip->IO_ADDR_R = MLC_DATA(host->io_base);
+	nand_chip->IO_ADDR_W = MLC_DATA(host->io_base);
+
+	/* Init NAND controller */
+	lpc32xx_nand_setup(host);
+
+	platform_set_drvdata(pdev, host);
+
+	/* Initialize function pointers */
+	nand_chip->ecc.hwctl = lpc32xx_ecc_enable;
+	nand_chip->ecc.read_page_raw = lpc32xx_read_page;
+	nand_chip->ecc.read_page = lpc32xx_read_page;
+	nand_chip->ecc.write_page_raw = lpc32xx_write_page_lowlevel;
+	nand_chip->ecc.write_page = lpc32xx_write_page_lowlevel;
+	nand_chip->ecc.write_oob = lpc32xx_write_oob;
+	nand_chip->ecc.read_oob = lpc32xx_read_oob;
+	nand_chip->ecc.strength = 4;
+	nand_chip->write_page = lpc32xx_write_page;
+	nand_chip->waitfunc = lpc32xx_waitfunc;
+
+	nand_chip->bbt_options = NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;
+	nand_chip->bbt_td = &lpc32xx_nand_bbt;
+	nand_chip->bbt_md = &lpc32xx_nand_bbt_mirror;
+
+	/* bitflip_threshold's default is defined as ecc_strength anyway.
+	 * Unfortunately, it is set only later at add_mtd_device(). Meanwhile
+	 * being 0, it causes bad block table scanning errors in
+	 * nand_scan_tail(), so preparing it here. */
+	mtd->bitflip_threshold = nand_chip->ecc.strength;
+
+	if (use_dma) {
+		res = lpc32xx_dma_setup(host);
+		if (res) {
+			res = -EIO;
+			goto err_exit2;
+		}
+	}
+
+	/*
+	 * Scan to find existance of the device and
+	 * Get the type of NAND device SMALL block or LARGE block
+	 */
+	if (nand_scan_ident(mtd, 1, NULL)) {
+		res = -ENXIO;
+		goto err_exit3;
+	}
+
+	host->dma_buf = devm_kzalloc(&pdev->dev, mtd->writesize, GFP_KERNEL);
+	if (!host->dma_buf) {
+		dev_err(&pdev->dev, "Error allocating dma_buf memory\n");
+		res = -ENOMEM;
+		goto err_exit3;
+	}
+
+	host->dummy_buf = devm_kzalloc(&pdev->dev, mtd->writesize, GFP_KERNEL);
+	if (!host->dummy_buf) {
+		dev_err(&pdev->dev, "Error allocating dummy_buf memory\n");
+		res = -ENOMEM;
+		goto err_exit3;
+	}
+
+	nand_chip->ecc.mode = NAND_ECC_HW;
+	nand_chip->ecc.size = mtd->writesize;
+	nand_chip->ecc.layout = &lpc32xx_nand_oob;
+	host->mlcsubpages = mtd->writesize / 512;
+
+	/* initially clear interrupt status */
+	readb(MLC_IRQ_SR(host->io_base));
+
+	init_completion(&host->comp_nand);
+	init_completion(&host->comp_controller);
+
+	host->irq = platform_get_irq(pdev, 0);
+	if ((host->irq < 0) || (host->irq >= NR_IRQS)) {
+		dev_err(&pdev->dev, "failed to get platform irq\n");
+		res = -EINVAL;
+		goto err_exit3;
+	}
+
+	if (request_irq(host->irq, (irq_handler_t)&lpc3xxx_nand_irq,
+			IRQF_TRIGGER_HIGH, DRV_NAME, host)) {
+		dev_err(&pdev->dev, "Error requesting NAND IRQ\n");
+		res = -ENXIO;
+		goto err_exit3;
+	}
+
+	/*
+	 * Fills out all the uninitialized function pointers with the defaults
+	 * And scans for a bad block table if appropriate.
+	 */
+	if (nand_scan_tail(mtd)) {
+		res = -ENXIO;
+		goto err_exit4;
+	}
+
+	mtd->name = DRV_NAME;
+
+	ppdata.of_node = pdev->dev.of_node;
+	res = mtd_device_parse_register(mtd, NULL, &ppdata, host->ncfg->parts,
+					host->ncfg->num_parts);
+	if (!res)
+		return res;
+
+	nand_release(mtd);
+
+err_exit4:
+	free_irq(host->irq, host);
+err_exit3:
+	if (use_dma)
+		dma_release_channel(host->dma_chan);
+err_exit2:
+	clk_disable(host->clk);
+	clk_put(host->clk);
+	platform_set_drvdata(pdev, NULL);
+err_exit1:
+	lpc32xx_wp_enable(host);
+	gpio_free(host->ncfg->wp_gpio);
+
+	return res;
+}
+
+/*
+ * Remove NAND device
+ */
+static int __devexit lpc32xx_nand_remove(struct platform_device *pdev)
+{
+	struct lpc32xx_nand_host *host = platform_get_drvdata(pdev);
+	struct mtd_info *mtd = &host->mtd;
+
+	nand_release(mtd);
+	free_irq(host->irq, host);
+	if (use_dma)
+		dma_release_channel(host->dma_chan);
+
+	clk_disable(host->clk);
+	clk_put(host->clk);
+	platform_set_drvdata(pdev, NULL);
+
+	lpc32xx_wp_enable(host);
+	gpio_free(host->ncfg->wp_gpio);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int lpc32xx_nand_resume(struct platform_device *pdev)
+{
+	struct lpc32xx_nand_host *host = platform_get_drvdata(pdev);
+
+	/* Re-enable NAND clock */
+	clk_enable(host->clk);
+
+	/* Fresh init of NAND controller */
+	lpc32xx_nand_setup(host);
+
+	/* Disable write protect */
+	lpc32xx_wp_disable(host);
+
+	return 0;
+}
+
+static int lpc32xx_nand_suspend(struct platform_device *pdev, pm_message_t pm)
+{
+	struct lpc32xx_nand_host *host = platform_get_drvdata(pdev);
+
+	/* Enable write protect for safety */
+	lpc32xx_wp_enable(host);
+
+	/* Disable clock */
+	clk_disable(host->clk);
+	return 0;
+}
+
+#else
+#define lpc32xx_nand_resume NULL
+#define lpc32xx_nand_suspend NULL
+#endif
+
+static const struct of_device_id lpc32xx_nand_match[] = {
+	{ .compatible = "nxp,lpc3220-mlc" },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, lpc32xx_nand_match);
+
+static struct platform_driver lpc32xx_nand_driver = {
+	.probe		= lpc32xx_nand_probe,
+	.remove		= __devexit_p(lpc32xx_nand_remove),
+	.resume		= lpc32xx_nand_resume,
+	.suspend	= lpc32xx_nand_suspend,
+	.driver		= {
+		.name	= DRV_NAME,
+		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(lpc32xx_nand_match),
+	},
+};
+
+module_platform_driver(lpc32xx_nand_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>");
+MODULE_DESCRIPTION("NAND driver for the NXP LPC32XX MLC controller");
diff --git a/drivers/mtd/nand/lpc32xx_slc.c b/drivers/mtd/nand/lpc32xx_slc.c
new file mode 100644
index 0000000..32409c4
--- /dev/null
+++ b/drivers/mtd/nand/lpc32xx_slc.c
@@ -0,0 +1,1039 @@
+/*
+ * NXP LPC32XX NAND SLC driver
+ *
+ * Authors:
+ *    Kevin Wells <kevin.wells@nxp.com>
+ *    Roland Stigge <stigge@antcom.de>
+ *
+ * Copyright © 2011 NXP Semiconductors
+ * Copyright © 2012 Roland Stigge
+ *
+ * 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/slab.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/of_mtd.h>
+#include <linux/of_gpio.h>
+#include <linux/mtd/lpc32xx_slc.h>
+
+#define LPC32XX_MODNAME		"lpc32xx-nand"
+
+/**********************************************************************
+* SLC NAND controller register offsets
+**********************************************************************/
+
+#define SLC_DATA(x)		(x + 0x000)
+#define SLC_ADDR(x)		(x + 0x004)
+#define SLC_CMD(x)		(x + 0x008)
+#define SLC_STOP(x)		(x + 0x00C)
+#define SLC_CTRL(x)		(x + 0x010)
+#define SLC_CFG(x)		(x + 0x014)
+#define SLC_STAT(x)		(x + 0x018)
+#define SLC_INT_STAT(x)		(x + 0x01C)
+#define SLC_IEN(x)		(x + 0x020)
+#define SLC_ISR(x)		(x + 0x024)
+#define SLC_ICR(x)		(x + 0x028)
+#define SLC_TAC(x)		(x + 0x02C)
+#define SLC_TC(x)		(x + 0x030)
+#define SLC_ECC(x)		(x + 0x034)
+#define SLC_DMA_DATA(x)		(x + 0x038)
+
+/**********************************************************************
+* slc_ctrl register definitions
+**********************************************************************/
+#define SLCCTRL_SW_RESET	(1 << 2) /* Reset the NAND controller bit */
+#define SLCCTRL_ECC_CLEAR	(1 << 1) /* Reset ECC bit */
+#define SLCCTRL_DMA_START	(1 << 0) /* Start DMA channel bit */
+
+/**********************************************************************
+* slc_cfg register definitions
+**********************************************************************/
+#define SLCCFG_CE_LOW		(1 << 5) /* Force CE low bit */
+#define SLCCFG_DMA_ECC		(1 << 4) /* Enable DMA ECC bit */
+#define SLCCFG_ECC_EN		(1 << 3) /* ECC enable bit */
+#define SLCCFG_DMA_BURST	(1 << 2) /* DMA burst bit */
+#define SLCCFG_DMA_DIR		(1 << 1) /* DMA write(0)/read(1) bit */
+#define SLCCFG_WIDTH		(1 << 0) /* External device width, 0=8bit */
+
+/**********************************************************************
+* slc_stat register definitions
+**********************************************************************/
+#define SLCSTAT_DMA_FIFO	(1 << 2) /* DMA FIFO has data bit */
+#define SLCSTAT_SLC_FIFO	(1 << 1) /* SLC FIFO has data bit */
+#define SLCSTAT_NAND_READY	(1 << 0) /* NAND device is ready bit */
+
+/**********************************************************************
+* slc_int_stat, slc_ien, slc_isr, and slc_icr register definitions
+**********************************************************************/
+#define SLCSTAT_INT_TC		(1 << 1) /* Transfer count bit */
+#define SLCSTAT_INT_RDY_EN	(1 << 0) /* Ready interrupt bit */
+
+/**********************************************************************
+* slc_tac register definitions
+**********************************************************************/
+/* Clock setting for RDY write sample wait time in 2*n clocks */
+#define SLCTAC_WDR(n)		(((n) & 0xF) << 28)
+/* Write pulse width in clock cycles, 1 to 16 clocks */
+#define SLCTAC_WWIDTH(n)	(((n) & 0xF) << 24)
+/* Write hold time of control and data signals, 1 to 16 clocks */
+#define SLCTAC_WHOLD(n)		(((n) & 0xF) << 20)
+/* Write setup time of control and data signals, 1 to 16 clocks */
+#define SLCTAC_WSETUP(n)	(((n) & 0xF) << 16)
+/* Clock setting for RDY read sample wait time in 2*n clocks */
+#define SLCTAC_RDR(n)		(((n) & 0xF) << 12)
+/* Read pulse width in clock cycles, 1 to 16 clocks */
+#define SLCTAC_RWIDTH(n)	(((n) & 0xF) << 8)
+/* Read hold time of control and data signals, 1 to 16 clocks */
+#define SLCTAC_RHOLD(n)		(((n) & 0xF) << 4)
+/* Read setup time of control and data signals, 1 to 16 clocks */
+#define SLCTAC_RSETUP(n)	(((n) & 0xF) << 0)
+
+/**********************************************************************
+* slc_ecc register definitions
+**********************************************************************/
+/* ECC line party fetch macro */
+#define SLCECC_TO_LINEPAR(n)	(((n) >> 6) & 0x7FFF)
+#define SLCECC_TO_COLPAR(n)	((n) & 0x3F)
+
+/*
+ * DMA requires storage space for the DMA local buffer and the hardware ECC
+ * storage area. The DMA local buffer is only used if DMA mapping fails
+ * during runtime.
+ */
+#define LPC32XX_DMA_DATA_SIZE		4096
+#define LPC32XX_ECC_SAVE_SIZE		((4096 / 256) * 4)
+
+/* Number of bytes used for ECC stored in NAND per 256 bytes */
+#define LPC32XX_SLC_DEV_ECC_BYTES	3
+
+/*
+ * If the NAND base clock frequency can't be fetched, this frequency will be
+ * used instead as the base. This rate is used to setup the timing registers
+ * used for NAND accesses.
+ */
+#define LPC32XX_DEF_BUS_RATE		133250000
+
+/* Milliseconds for DMA FIFO timeout (unlikely anyway) */
+#define LPC32XX_DMA_TIMEOUT		100
+
+/*
+ * NAND ECC Layout for small page NAND devices
+ * Note: For large and huge page devices, the default layouts are used
+ */
+static struct nand_ecclayout lpc32xx_nand_oob_16 = {
+	.eccbytes = 6,
+	.eccpos = {10, 11, 12, 13, 14, 15},
+	.oobfree = {
+		{ .offset = 0, .length = 4 },
+		{ .offset = 6, .length = 4 },
+	},
+};
+
+static u8 bbt_pattern[] = {'B', 'b', 't', '0' };
+static u8 mirror_pattern[] = {'1', 't', 'b', 'B' };
+
+/*
+ * Small page FLASH BBT descriptors, marker at offset 0, version at offset 6
+ * Note: Large page devices used the default layout
+ */
+static struct nand_bbt_descr bbt_smallpage_main_descr = {
+	.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
+		| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
+	.offs =	0,
+	.len = 4,
+	.veroffs = 6,
+	.maxblocks = 4,
+	.pattern = bbt_pattern
+};
+
+static struct nand_bbt_descr bbt_smallpage_mirror_descr = {
+	.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
+		| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
+	.offs =	0,
+	.len = 4,
+	.veroffs = 6,
+	.maxblocks = 4,
+	.pattern = mirror_pattern
+};
+
+/*
+ * NAND platform configuration structure
+ */
+struct lpc32xx_nand_cfg_slc {
+	uint32_t wdr_clks;
+	uint32_t wwidth;
+	uint32_t whold;
+	uint32_t wsetup;
+	uint32_t rdr_clks;
+	uint32_t rwidth;
+	uint32_t rhold;
+	uint32_t rsetup;
+	bool use_bbt;
+	int wp_gpio;
+	struct mtd_partition *parts;
+	unsigned num_parts;
+};
+
+struct lpc32xx_nand_host {
+	struct nand_chip	nand_chip;
+	struct lpc32xx_slc_platform_data *pdata;
+	struct clk		*clk;
+	struct mtd_info		mtd;
+	void __iomem		*io_base;
+	struct lpc32xx_nand_cfg_slc *ncfg;
+
+	struct completion	comp;
+	struct dma_chan		*dma_chan;
+	uint32_t		dma_buf_len;
+	struct dma_slave_config	dma_slave_config;
+	struct scatterlist	sgl;
+
+	/*
+	 * DMA and CPU addresses of ECC work area and data buffer
+	 */
+	uint32_t		*ecc_buf;
+	uint8_t			*data_buf;
+	dma_addr_t		io_base_dma;
+};
+
+static void lpc32xx_nand_setup(struct lpc32xx_nand_host *host)
+{
+	uint32_t clkrate, tmp;
+
+	/* Reset SLC controller */
+	writel(SLCCTRL_SW_RESET, SLC_CTRL(host->io_base));
+	udelay(1000);
+
+	/* Basic setup */
+	writel(0, SLC_CFG(host->io_base));
+	writel(0, SLC_IEN(host->io_base));
+	writel((SLCSTAT_INT_TC | SLCSTAT_INT_RDY_EN),
+		SLC_ICR(host->io_base));
+
+	/* Get base clock for SLC block */
+	clkrate = clk_get_rate(host->clk);
+	if (clkrate == 0)
+		clkrate = LPC32XX_DEF_BUS_RATE;
+
+	/* Compute clock setup values */
+	tmp = SLCTAC_WDR(host->ncfg->wdr_clks) |
+		SLCTAC_WWIDTH(1 + (clkrate / host->ncfg->wwidth)) |
+		SLCTAC_WHOLD(1 + (clkrate / host->ncfg->whold)) |
+		SLCTAC_WSETUP(1 + (clkrate / host->ncfg->wsetup)) |
+		SLCTAC_RDR(host->ncfg->rdr_clks) |
+		SLCTAC_RWIDTH(1 + (clkrate / host->ncfg->rwidth)) |
+		SLCTAC_RHOLD(1 + (clkrate / host->ncfg->rhold)) |
+		SLCTAC_RSETUP(1 + (clkrate / host->ncfg->rsetup));
+	writel(tmp, SLC_TAC(host->io_base));
+}
+
+/*
+ * Hardware specific access to control lines
+ */
+static void lpc32xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
+	unsigned int ctrl)
+{
+	uint32_t tmp;
+	struct nand_chip *chip = mtd->priv;
+	struct lpc32xx_nand_host *host = chip->priv;
+
+	/* Does CE state need to be changed? */
+	tmp = readl(SLC_CFG(host->io_base));
+	if (ctrl & NAND_NCE)
+		tmp |= SLCCFG_CE_LOW;
+	else
+		tmp &= ~SLCCFG_CE_LOW;
+	writel(tmp, SLC_CFG(host->io_base));
+
+	if (cmd != NAND_CMD_NONE) {
+		if (ctrl & NAND_CLE)
+			writel(cmd, SLC_CMD(host->io_base));
+		else
+			writel(cmd, SLC_ADDR(host->io_base));
+	}
+}
+
+/*
+ * Read the Device Ready pin
+ */
+static int lpc32xx_nand_device_ready(struct mtd_info *mtd)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct lpc32xx_nand_host *host = chip->priv;
+	int rdy = 0;
+
+	if ((readl(SLC_STAT(host->io_base)) & SLCSTAT_NAND_READY) != 0)
+		rdy = 1;
+
+	return rdy;
+}
+
+/*
+ * Enable NAND write protect
+ */
+static void lpc32xx_wp_enable(struct lpc32xx_nand_host *host)
+{
+	if (gpio_is_valid(host->ncfg->wp_gpio))
+		gpio_set_value(host->ncfg->wp_gpio, 0);
+}
+
+/*
+ * Disable NAND write protect
+ */
+static void lpc32xx_wp_disable(struct lpc32xx_nand_host *host)
+{
+	if (gpio_is_valid(host->ncfg->wp_gpio))
+		gpio_set_value(host->ncfg->wp_gpio, 1);
+}
+
+/*
+ * Prepares SLC for transfers with H/W ECC enabled
+ */
+static void lpc32xx_nand_ecc_enable(struct mtd_info *mtd, int mode)
+{
+	/* Hardware ECC is enabled automatically in hardware as needed */
+}
+
+/*
+ * Calculates the ECC for the data
+ */
+static int lpc32xx_nand_ecc_calculate(struct mtd_info *mtd,
+				      const unsigned char *buf,
+				      unsigned char *code)
+{
+	/*
+	 * ECC is calculated automatically in hardware during syndrome read
+	 * and write operations, so it doesn't need to be calculated here.
+	 */
+	return 0;
+}
+
+/*
+ * Read a single byte from NAND device
+ */
+static uint8_t lpc32xx_nand_read_byte(struct mtd_info *mtd)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct lpc32xx_nand_host *host = chip->priv;
+
+	return (uint8_t)readl(SLC_DATA(host->io_base));
+}
+
+/*
+ * Simple device read without ECC
+ */
+static void lpc32xx_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct lpc32xx_nand_host *host = chip->priv;
+
+	/* Direct device read with no ECC */
+	while (len-- > 0)
+		*buf++ = (uint8_t)readl(SLC_DATA(host->io_base));
+}
+
+/*
+ * Simple device write without ECC
+ */
+static void lpc32xx_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct lpc32xx_nand_host *host = chip->priv;
+
+	/* Direct device write with no ECC */
+	while (len-- > 0)
+		writel((uint32_t)*buf++, SLC_DATA(host->io_base));
+}
+
+/*
+ * Read the OOB data from the device without ECC using FIFO method
+ */
+static int lpc32xx_nand_read_oob_syndrome(struct mtd_info *mtd,
+					  struct nand_chip *chip, int page)
+{
+	chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
+	chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+	return 0;
+}
+
+/*
+ * Write the OOB data to the device without ECC using FIFO method
+ */
+static int lpc32xx_nand_write_oob_syndrome(struct mtd_info *mtd,
+	struct nand_chip *chip, int page)
+{
+	int status;
+
+	chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page);
+	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+	/* Send command to program the OOB data */
+	chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
+
+	status = chip->waitfunc(mtd, chip);
+
+	return status & NAND_STATUS_FAIL ? -EIO : 0;
+}
+
+/*
+ * Fills in the ECC fields in the OOB buffer with the hardware generated ECC
+ */
+static void lpc32xx_slc_ecc_copy(uint8_t *spare, const uint32_t *ecc, int count)
+{
+	int i;
+
+	for (i = 0; i < (count * 3); i += 3) {
+		uint32_t ce = ecc[i / 3];
+		ce = ~(ce << 2) & 0xFFFFFF;
+		spare[i + 2] = (uint8_t)(ce & 0xFF);
+		ce >>= 8;
+		spare[i + 1] = (uint8_t)(ce & 0xFF);
+		ce >>= 8;
+		spare[i] = (uint8_t)(ce & 0xFF);
+	}
+}
+
+static void lpc32xx_dma_complete_func(void *completion)
+{
+	complete(completion);
+}
+
+static int lpc32xx_xmit_dma(struct mtd_info *mtd, dma_addr_t dma,
+			    void *mem, int len, enum dma_transfer_direction dir)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct lpc32xx_nand_host *host = chip->priv;
+	struct dma_async_tx_descriptor *desc;
+	int flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
+	int res;
+
+	host->dma_slave_config.direction = dir;
+	host->dma_slave_config.src_addr = dma;
+	host->dma_slave_config.dst_addr = dma;
+	host->dma_slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	host->dma_slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	host->dma_slave_config.src_maxburst = 4;
+	host->dma_slave_config.dst_maxburst = 4;
+	/* DMA controller does flow control: */
+	host->dma_slave_config.device_fc = false;
+	if (dmaengine_slave_config(host->dma_chan, &host->dma_slave_config)) {
+		dev_err(mtd->dev.parent, "Failed to setup DMA slave\n");
+		return -ENXIO;
+	}
+
+	sg_init_one(&host->sgl, mem, len);
+
+	res = dma_map_sg(host->dma_chan->device->dev, &host->sgl, 1,
+			 DMA_BIDIRECTIONAL);
+	if (res != 1) {
+		dev_err(mtd->dev.parent, "Failed to map sg list\n");
+		return -ENXIO;
+	}
+	desc = dmaengine_prep_slave_sg(host->dma_chan, &host->sgl, 1, dir,
+				       flags);
+	if (!desc) {
+		dev_err(mtd->dev.parent, "Failed to prepare slave sg\n");
+		goto out1;
+	}
+
+	init_completion(&host->comp);
+	desc->callback = lpc32xx_dma_complete_func;
+	desc->callback_param = &host->comp;
+
+	dmaengine_submit(desc);
+	dma_async_issue_pending(host->dma_chan);
+
+	wait_for_completion_timeout(&host->comp, msecs_to_jiffies(1000));
+
+	dma_unmap_sg(host->dma_chan->device->dev, &host->sgl, 1,
+		     DMA_BIDIRECTIONAL);
+
+	return 0;
+out1:
+	dma_unmap_sg(host->dma_chan->device->dev, &host->sgl, 1,
+		     DMA_BIDIRECTIONAL);
+	return -ENXIO;
+}
+
+/*
+ * DMA read/write transfers with ECC support
+ */
+static int lpc32xx_xfer(struct mtd_info *mtd, uint8_t *buf, int eccsubpages,
+			int read)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct lpc32xx_nand_host *host = chip->priv;
+	int i, status = 0;
+	unsigned long timeout;
+	int res;
+	enum dma_transfer_direction dir =
+		read ? DMA_DEV_TO_MEM : DMA_MEM_TO_DEV;
+	uint8_t *dma_buf;
+	bool dma_mapped;
+
+	if ((void *)buf <= high_memory) {
+		dma_buf = buf;
+		dma_mapped = true;
+	} else {
+		dma_buf = host->data_buf;
+		dma_mapped = false;
+		if (!read)
+			memcpy(host->data_buf, buf, mtd->writesize);
+	}
+
+	if (read) {
+		writel(readl(SLC_CFG(host->io_base)) |
+		       SLCCFG_DMA_DIR | SLCCFG_ECC_EN | SLCCFG_DMA_ECC |
+		       SLCCFG_DMA_BURST, SLC_CFG(host->io_base));
+	} else {
+		writel((readl(SLC_CFG(host->io_base)) |
+			SLCCFG_ECC_EN | SLCCFG_DMA_ECC | SLCCFG_DMA_BURST) &
+		       ~SLCCFG_DMA_DIR,
+			SLC_CFG(host->io_base));
+	}
+
+	/* Clear initial ECC */
+	writel(SLCCTRL_ECC_CLEAR, SLC_CTRL(host->io_base));
+
+	/* Transfer size is data area only */
+	writel(mtd->writesize, SLC_TC(host->io_base));
+
+	/* Start transfer in the NAND controller */
+	writel(readl(SLC_CTRL(host->io_base)) | SLCCTRL_DMA_START,
+	       SLC_CTRL(host->io_base));
+
+	for (i = 0; i < chip->ecc.steps; i++) {
+		/* Data */
+		res = lpc32xx_xmit_dma(mtd, SLC_DMA_DATA(host->io_base_dma),
+				       dma_buf + i * chip->ecc.size,
+				       mtd->writesize / chip->ecc.steps, dir);
+		if (res)
+			return res;
+
+		/* Always _read_ ECC */
+		if (i == chip->ecc.steps - 1)
+			break;
+		if (!read) /* ECC availability delayed on write */
+			udelay(10);
+		res = lpc32xx_xmit_dma(mtd, SLC_ECC(host->io_base_dma),
+				       &host->ecc_buf[i], 4, DMA_DEV_TO_MEM);
+		if (res)
+			return res;
+	}
+
+	/*
+	 * According to NXP, the DMA can be finished here, but the NAND
+	 * controller may still have buffered data. After porting to using the
+	 * dmaengine DMA driver (amba-pl080), the condition (DMA_FIFO empty)
+	 * appears to be always true, according to tests. Keeping the check for
+	 * safety reasons for now.
+	 */
+	if (readl(SLC_STAT(host->io_base)) & SLCSTAT_DMA_FIFO) {
+		dev_warn(mtd->dev.parent, "FIFO not empty!\n");
+		timeout = jiffies + msecs_to_jiffies(LPC32XX_DMA_TIMEOUT);
+		while ((readl(SLC_STAT(host->io_base)) & SLCSTAT_DMA_FIFO) &&
+		       time_before(jiffies, timeout))
+			cpu_relax();
+		if (!time_before(jiffies, timeout)) {
+			dev_err(mtd->dev.parent, "FIFO held data too long\n");
+			status = -EIO;
+		}
+	}
+
+	/* Read last calculated ECC value */
+	if (!read)
+		udelay(10);
+	host->ecc_buf[chip->ecc.steps - 1] =
+		readl(SLC_ECC(host->io_base));
+
+	/* Flush DMA */
+	dmaengine_terminate_all(host->dma_chan);
+
+	if (readl(SLC_STAT(host->io_base)) & SLCSTAT_DMA_FIFO ||
+	    readl(SLC_TC(host->io_base))) {
+		/* Something is left in the FIFO, something is wrong */
+		dev_err(mtd->dev.parent, "DMA FIFO failure\n");
+		status = -EIO;
+	}
+
+	/* Stop DMA & HW ECC */
+	writel(readl(SLC_CTRL(host->io_base)) & ~SLCCTRL_DMA_START,
+	       SLC_CTRL(host->io_base));
+	writel(readl(SLC_CFG(host->io_base)) &
+	       ~(SLCCFG_DMA_DIR | SLCCFG_ECC_EN | SLCCFG_DMA_ECC |
+		 SLCCFG_DMA_BURST), SLC_CFG(host->io_base));
+
+	if (!dma_mapped && read)
+		memcpy(buf, host->data_buf, mtd->writesize);
+
+	return status;
+}
+
+/*
+ * Read the data and OOB data from the device, use ECC correction with the
+ * data, disable ECC for the OOB data
+ */
+static int lpc32xx_nand_read_page_syndrome(struct mtd_info *mtd,
+					   struct nand_chip *chip, uint8_t *buf,
+					   int oob_required, int page)
+{
+	struct lpc32xx_nand_host *host = chip->priv;
+	int stat, i, status;
+	uint8_t *oobecc, tmpecc[LPC32XX_ECC_SAVE_SIZE];
+
+	/* Issue read command */
+	chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
+
+	/* Read data and oob, calculate ECC */
+	status = lpc32xx_xfer(mtd, buf, chip->ecc.steps, 1);
+
+	/* Get OOB data */
+	chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+	/* Convert to stored ECC format */
+	lpc32xx_slc_ecc_copy(tmpecc, (uint32_t *) host->ecc_buf, chip->ecc.steps);
+
+	/* Pointer to ECC data retrieved from NAND spare area */
+	oobecc = chip->oob_poi + chip->ecc.layout->eccpos[0];
+
+	for (i = 0; i < chip->ecc.steps; i++) {
+		stat = chip->ecc.correct(mtd, buf, oobecc,
+					 &tmpecc[i * chip->ecc.bytes]);
+		if (stat < 0)
+			mtd->ecc_stats.failed++;
+		else
+			mtd->ecc_stats.corrected += stat;
+
+		buf += chip->ecc.size;
+		oobecc += chip->ecc.bytes;
+	}
+
+	return status;
+}
+
+/*
+ * Read the data and OOB data from the device, no ECC correction with the
+ * data or OOB data
+ */
+static int lpc32xx_nand_read_page_raw_syndrome(struct mtd_info *mtd,
+					       struct nand_chip *chip,
+					       uint8_t *buf, int oob_required,
+					       int page)
+{
+	/* Issue read command */
+	chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
+
+	/* Raw reads can just use the FIFO interface */
+	chip->read_buf(mtd, buf, chip->ecc.size * chip->ecc.steps);
+	chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+	return 0;
+}
+
+/*
+ * Write the data and OOB data to the device, use ECC with the data,
+ * disable ECC for the OOB data
+ */
+static int lpc32xx_nand_write_page_syndrome(struct mtd_info *mtd,
+					    struct nand_chip *chip,
+					    const uint8_t *buf, int oob_required)
+{
+	struct lpc32xx_nand_host *host = chip->priv;
+	uint8_t *pb = chip->oob_poi + chip->ecc.layout->eccpos[0];
+	int error;
+
+	/* Write data, calculate ECC on outbound data */
+	error = lpc32xx_xfer(mtd, (uint8_t *)buf, chip->ecc.steps, 0);
+	if (error)
+		return error;
+
+	/*
+	 * The calculated ECC needs some manual work done to it before
+	 * committing it to NAND. Process the calculated ECC and place
+	 * the resultant values directly into the OOB buffer. */
+	lpc32xx_slc_ecc_copy(pb, (uint32_t *)host->ecc_buf, chip->ecc.steps);
+
+	/* Write ECC data to device */
+	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+	return 0;
+}
+
+/*
+ * Write the data and OOB data to the device, no ECC correction with the
+ * data or OOB data
+ */
+static int lpc32xx_nand_write_page_raw_syndrome(struct mtd_info *mtd,
+						struct nand_chip *chip,
+						const uint8_t *buf,
+						int oob_required)
+{
+	/* Raw writes can just use the FIFO interface */
+	chip->write_buf(mtd, buf, chip->ecc.size * chip->ecc.steps);
+	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+	return 0;
+}
+
+static int lpc32xx_nand_dma_setup(struct lpc32xx_nand_host *host)
+{
+	struct mtd_info *mtd = &host->mtd;
+	dma_cap_mask_t mask;
+
+	if (!host->pdata || !host->pdata->dma_filter) {
+		dev_err(mtd->dev.parent, "no DMA platform data\n");
+		return -ENOENT;
+	}
+
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+	host->dma_chan = dma_request_channel(mask, host->pdata->dma_filter,
+					     "nand-slc");
+	if (!host->dma_chan) {
+		dev_err(mtd->dev.parent, "Failed to request DMA channel\n");
+		return -EBUSY;
+	}
+
+	return 0;
+}
+
+static struct lpc32xx_nand_cfg_slc *lpc32xx_parse_dt(struct device *dev)
+{
+	struct lpc32xx_nand_cfg_slc *ncfg;
+	struct device_node *np = dev->of_node;
+
+	ncfg = devm_kzalloc(dev, sizeof(*ncfg), GFP_KERNEL);
+	if (!ncfg) {
+		dev_err(dev, "could not allocate memory for NAND config\n");
+		return NULL;
+	}
+
+	of_property_read_u32(np, "nxp,wdr-clks", &ncfg->wdr_clks);
+	of_property_read_u32(np, "nxp,wwidth", &ncfg->wwidth);
+	of_property_read_u32(np, "nxp,whold", &ncfg->whold);
+	of_property_read_u32(np, "nxp,wsetup", &ncfg->wsetup);
+	of_property_read_u32(np, "nxp,rdr-clks", &ncfg->rdr_clks);
+	of_property_read_u32(np, "nxp,rwidth", &ncfg->rwidth);
+	of_property_read_u32(np, "nxp,rhold", &ncfg->rhold);
+	of_property_read_u32(np, "nxp,rsetup", &ncfg->rsetup);
+
+	if (!ncfg->wdr_clks || !ncfg->wwidth || !ncfg->whold ||
+	    !ncfg->wsetup || !ncfg->rdr_clks || !ncfg->rwidth ||
+	    !ncfg->rhold || !ncfg->rsetup) {
+		dev_err(dev, "chip parameters not specified correctly\n");
+		return NULL;
+	}
+
+	ncfg->use_bbt = of_get_nand_on_flash_bbt(np);
+	ncfg->wp_gpio = of_get_named_gpio(np, "gpios", 0);
+
+	return ncfg;
+}
+
+/*
+ * Probe for NAND controller
+ */
+static int __devinit lpc32xx_nand_probe(struct platform_device *pdev)
+{
+	struct lpc32xx_nand_host *host;
+	struct mtd_info *mtd;
+	struct nand_chip *chip;
+	struct resource *rc;
+	struct mtd_part_parser_data ppdata = {};
+	int res;
+
+	rc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (rc == NULL) {
+		dev_err(&pdev->dev, "No memory resource found for device\n");
+		return -EBUSY;
+	}
+
+	/* Allocate memory for the device structure (and zero it) */
+	host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
+	if (!host) {
+		dev_err(&pdev->dev, "failed to allocate device structure\n");
+		return -ENOMEM;
+	}
+	host->io_base_dma = rc->start;
+
+	host->io_base = devm_request_and_ioremap(&pdev->dev, rc);
+	if (host->io_base == NULL) {
+		dev_err(&pdev->dev, "ioremap failed\n");
+		return -ENOMEM;
+	}
+
+	if (pdev->dev.of_node)
+		host->ncfg = lpc32xx_parse_dt(&pdev->dev);
+	if (!host->ncfg) {
+		dev_err(&pdev->dev,
+			"Missing or bad NAND config from device tree\n");
+		return -ENOENT;
+	}
+	if (host->ncfg->wp_gpio == -EPROBE_DEFER)
+		return -EPROBE_DEFER;
+	if (gpio_is_valid(host->ncfg->wp_gpio) &&
+			gpio_request(host->ncfg->wp_gpio, "NAND WP")) {
+		dev_err(&pdev->dev, "GPIO not available\n");
+		return -EBUSY;
+	}
+	lpc32xx_wp_disable(host);
+
+	host->pdata = pdev->dev.platform_data;
+
+	mtd = &host->mtd;
+	chip = &host->nand_chip;
+	chip->priv = host;
+	mtd->priv = chip;
+	mtd->owner = THIS_MODULE;
+	mtd->dev.parent = &pdev->dev;
+
+	/* Get NAND clock */
+	host->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(host->clk)) {
+		dev_err(&pdev->dev, "Clock failure\n");
+		res = -ENOENT;
+		goto err_exit1;
+	}
+	clk_enable(host->clk);
+
+	/* Set NAND IO addresses and command/ready functions */
+	chip->IO_ADDR_R = SLC_DATA(host->io_base);
+	chip->IO_ADDR_W = SLC_DATA(host->io_base);
+	chip->cmd_ctrl = lpc32xx_nand_cmd_ctrl;
+	chip->dev_ready = lpc32xx_nand_device_ready;
+	chip->chip_delay = 20; /* 20us command delay time */
+
+	/* Init NAND controller */
+	lpc32xx_nand_setup(host);
+
+	platform_set_drvdata(pdev, host);
+
+	/* NAND callbacks for LPC32xx SLC hardware */
+	chip->ecc.mode = NAND_ECC_HW_SYNDROME;
+	chip->read_byte = lpc32xx_nand_read_byte;
+	chip->read_buf = lpc32xx_nand_read_buf;
+	chip->write_buf = lpc32xx_nand_write_buf;
+	chip->ecc.read_page_raw = lpc32xx_nand_read_page_raw_syndrome;
+	chip->ecc.read_page = lpc32xx_nand_read_page_syndrome;
+	chip->ecc.write_page_raw = lpc32xx_nand_write_page_raw_syndrome;
+	chip->ecc.write_page = lpc32xx_nand_write_page_syndrome;
+	chip->ecc.write_oob = lpc32xx_nand_write_oob_syndrome;
+	chip->ecc.read_oob = lpc32xx_nand_read_oob_syndrome;
+	chip->ecc.calculate = lpc32xx_nand_ecc_calculate;
+	chip->ecc.correct = nand_correct_data;
+	chip->ecc.strength = 1;
+	chip->ecc.hwctl = lpc32xx_nand_ecc_enable;
+
+	/* bitflip_threshold's default is defined as ecc_strength anyway.
+	 * Unfortunately, it is set only later at add_mtd_device(). Meanwhile
+	 * being 0, it causes bad block table scanning errors in
+	 * nand_scan_tail(), so preparing it here already. */
+	mtd->bitflip_threshold = chip->ecc.strength;
+
+	/*
+	 * Allocate a large enough buffer for a single huge page plus
+	 * extra space for the spare area and ECC storage area
+	 */
+	host->dma_buf_len = LPC32XX_DMA_DATA_SIZE + LPC32XX_ECC_SAVE_SIZE;
+	host->data_buf = devm_kzalloc(&pdev->dev, host->dma_buf_len,
+				      GFP_KERNEL);
+	if (host->data_buf == NULL) {
+		dev_err(&pdev->dev, "Error allocating memory\n");
+		res = -ENOMEM;
+		goto err_exit2;
+	}
+
+	res = lpc32xx_nand_dma_setup(host);
+	if (res) {
+		res = -EIO;
+		goto err_exit2;
+	}
+
+	/* Find NAND device */
+	if (nand_scan_ident(mtd, 1, NULL)) {
+		res = -ENXIO;
+		goto err_exit3;
+	}
+
+	/* OOB and ECC CPU and DMA work areas */
+	host->ecc_buf = (uint32_t *)(host->data_buf + LPC32XX_DMA_DATA_SIZE);
+
+	/*
+	 * Small page FLASH has a unique OOB layout, but large and huge
+	 * page FLASH use the standard layout. Small page FLASH uses a
+	 * custom BBT marker layout.
+	 */
+	if (mtd->writesize <= 512)
+		chip->ecc.layout = &lpc32xx_nand_oob_16;
+
+	/* These sizes remain the same regardless of page size */
+	chip->ecc.size = 256;
+	chip->ecc.bytes = LPC32XX_SLC_DEV_ECC_BYTES;
+	chip->ecc.prepad = chip->ecc.postpad = 0;
+
+	/* Avoid extra scan if using BBT, setup BBT support */
+	if (host->ncfg->use_bbt) {
+		chip->options |= NAND_SKIP_BBTSCAN;
+		chip->bbt_options |= NAND_BBT_USE_FLASH;
+
+		/*
+		 * Use a custom BBT marker setup for small page FLASH that
+		 * won't interfere with the ECC layout. Large and huge page
+		 * FLASH use the standard layout.
+		 */
+		if (mtd->writesize <= 512) {
+			chip->bbt_td = &bbt_smallpage_main_descr;
+			chip->bbt_md = &bbt_smallpage_mirror_descr;
+		}
+	}
+
+	/*
+	 * Fills out all the uninitialized function pointers with the defaults
+	 */
+	if (nand_scan_tail(mtd)) {
+		res = -ENXIO;
+		goto err_exit3;
+	}
+
+	/* Standard layout in FLASH for bad block tables */
+	if (host->ncfg->use_bbt) {
+		if (nand_default_bbt(mtd) < 0)
+			dev_err(&pdev->dev,
+			       "Error initializing default bad block tables\n");
+	}
+
+	mtd->name = "nxp_lpc3220_slc";
+	ppdata.of_node = pdev->dev.of_node;
+	res = mtd_device_parse_register(mtd, NULL, &ppdata, host->ncfg->parts,
+					host->ncfg->num_parts);
+	if (!res)
+		return res;
+
+	nand_release(mtd);
+
+err_exit3:
+	dma_release_channel(host->dma_chan);
+err_exit2:
+	clk_disable(host->clk);
+	clk_put(host->clk);
+	platform_set_drvdata(pdev, NULL);
+err_exit1:
+	lpc32xx_wp_enable(host);
+	gpio_free(host->ncfg->wp_gpio);
+
+	return res;
+}
+
+/*
+ * Remove NAND device.
+ */
+static int __devexit lpc32xx_nand_remove(struct platform_device *pdev)
+{
+	uint32_t tmp;
+	struct lpc32xx_nand_host *host = platform_get_drvdata(pdev);
+	struct mtd_info *mtd = &host->mtd;
+
+	nand_release(mtd);
+	dma_release_channel(host->dma_chan);
+
+	/* Force CE high */
+	tmp = readl(SLC_CTRL(host->io_base));
+	tmp &= ~SLCCFG_CE_LOW;
+	writel(tmp, SLC_CTRL(host->io_base));
+
+	clk_disable(host->clk);
+	clk_put(host->clk);
+	platform_set_drvdata(pdev, NULL);
+	lpc32xx_wp_enable(host);
+	gpio_free(host->ncfg->wp_gpio);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int lpc32xx_nand_resume(struct platform_device *pdev)
+{
+	struct lpc32xx_nand_host *host = platform_get_drvdata(pdev);
+
+	/* Re-enable NAND clock */
+	clk_enable(host->clk);
+
+	/* Fresh init of NAND controller */
+	lpc32xx_nand_setup(host);
+
+	/* Disable write protect */
+	lpc32xx_wp_disable(host);
+
+	return 0;
+}
+
+static int lpc32xx_nand_suspend(struct platform_device *pdev, pm_message_t pm)
+{
+	uint32_t tmp;
+	struct lpc32xx_nand_host *host = platform_get_drvdata(pdev);
+
+	/* Force CE high */
+	tmp = readl(SLC_CTRL(host->io_base));
+	tmp &= ~SLCCFG_CE_LOW;
+	writel(tmp, SLC_CTRL(host->io_base));
+
+	/* Enable write protect for safety */
+	lpc32xx_wp_enable(host);
+
+	/* Disable clock */
+	clk_disable(host->clk);
+
+	return 0;
+}
+
+#else
+#define lpc32xx_nand_resume NULL
+#define lpc32xx_nand_suspend NULL
+#endif
+
+static const struct of_device_id lpc32xx_nand_match[] = {
+	{ .compatible = "nxp,lpc3220-slc" },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, lpc32xx_nand_match);
+
+static struct platform_driver lpc32xx_nand_driver = {
+	.probe		= lpc32xx_nand_probe,
+	.remove		= __devexit_p(lpc32xx_nand_remove),
+	.resume		= lpc32xx_nand_resume,
+	.suspend	= lpc32xx_nand_suspend,
+	.driver		= {
+		.name	= LPC32XX_MODNAME,
+		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(lpc32xx_nand_match),
+	},
+};
+
+module_platform_driver(lpc32xx_nand_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kevin Wells <kevin.wells@nxp.com>");
+MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>");
+MODULE_DESCRIPTION("NAND driver for the NXP LPC32XX SLC controller");
diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/mpc5121_nfc.c
index c259c24..f776c85 100644
--- a/drivers/mtd/nand/mpc5121_nfc.c
+++ b/drivers/mtd/nand/mpc5121_nfc.c
@@ -506,27 +506,6 @@
 	mpc5121_nfc_buf_copy(mtd, (u_char *)buf, len, 1);
 }
 
-/* Compare buffer with NAND flash */
-static int mpc5121_nfc_verify_buf(struct mtd_info *mtd,
-						const u_char *buf, int len)
-{
-	u_char tmp[256];
-	uint bsize;
-
-	while (len) {
-		bsize = min(len, 256);
-		mpc5121_nfc_read_buf(mtd, tmp, bsize);
-
-		if (memcmp(buf, tmp, bsize))
-			return 1;
-
-		buf += bsize;
-		len -= bsize;
-	}
-
-	return 0;
-}
-
 /* Read byte from NFC buffers */
 static u8 mpc5121_nfc_read_byte(struct mtd_info *mtd)
 {
@@ -732,7 +711,6 @@
 	chip->read_word = mpc5121_nfc_read_word;
 	chip->read_buf = mpc5121_nfc_read_buf;
 	chip->write_buf = mpc5121_nfc_write_buf;
-	chip->verify_buf = mpc5121_nfc_verify_buf;
 	chip->select_chip = mpc5121_nfc_select_chip;
 	chip->bbt_options = NAND_BBT_USE_FLASH;
 	chip->ecc.mode = NAND_ECC_SOFT;
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 5683604..72e31d8 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -43,8 +43,8 @@
 
 #define nfc_is_v21()		(cpu_is_mx25() || cpu_is_mx35())
 #define nfc_is_v1()		(cpu_is_mx31() || cpu_is_mx27() || cpu_is_mx21())
-#define nfc_is_v3_2()		(cpu_is_mx51() || cpu_is_mx53())
-#define nfc_is_v3()		nfc_is_v3_2()
+#define nfc_is_v3_2a()		cpu_is_mx51()
+#define nfc_is_v3_2b()		cpu_is_mx53()
 
 /* Addresses for NFC registers */
 #define NFC_V1_V2_BUF_SIZE		(host->regs + 0x00)
@@ -122,7 +122,7 @@
 #define NFC_V3_CONFIG2_2CMD_PHASES		(1 << 4)
 #define NFC_V3_CONFIG2_NUM_ADDR_PHASE0		(1 << 5)
 #define NFC_V3_CONFIG2_ECC_MODE_8		(1 << 6)
-#define NFC_V3_CONFIG2_PPB(x)			(((x) & 0x3) << 7)
+#define NFC_V3_CONFIG2_PPB(x, shift)		(((x) & 0x3) << shift)
 #define NFC_V3_CONFIG2_NUM_ADDR_PHASE1(x)	(((x) & 0x3) << 12)
 #define NFC_V3_CONFIG2_INT_MSK			(1 << 15)
 #define NFC_V3_CONFIG2_ST_CMD(x)		(((x) & 0xff) << 24)
@@ -174,6 +174,7 @@
 	int spare_len;
 	int eccbytes;
 	int eccsize;
+	int ppb_shift;
 };
 
 struct mxc_nand_host {
@@ -745,14 +746,6 @@
 	host->buf_start += n;
 }
 
-/* Used by the upper layer to verify the data in NAND Flash
- * with the data in the buf. */
-static int mxc_nand_verify_buf(struct mtd_info *mtd,
-				const u_char *buf, int len)
-{
-	return -EFAULT;
-}
-
 /* This function is used by upper layer for select and
  * deselect of the NAND chip */
 static void mxc_nand_select_chip_v1_v3(struct mtd_info *mtd, int chip)
@@ -784,7 +777,7 @@
 	if (chip == -1) {
 		/* Disable the NFC clock */
 		if (host->clk_act) {
-			clk_disable(host->clk);
+			clk_disable_unprepare(host->clk);
 			host->clk_act = 0;
 		}
 		return;
@@ -792,7 +785,7 @@
 
 	if (!host->clk_act) {
 		/* Enable the NFC clock */
-		clk_enable(host->clk);
+		clk_prepare_enable(host->clk);
 		host->clk_act = 1;
 	}
 
@@ -1021,7 +1014,9 @@
 	}
 
 	if (mtd->writesize) {
-		config2 |= NFC_V3_CONFIG2_PPB(ffs(mtd->erasesize / mtd->writesize) - 6);
+		config2 |= NFC_V3_CONFIG2_PPB(
+				ffs(mtd->erasesize / mtd->writesize) - 6,
+				host->devtype_data->ppb_shift);
 		host->eccsize = get_eccsize(mtd);
 		if (host->eccsize == 8)
 			config2 |= NFC_V3_CONFIG2_ECC_MODE_8;
@@ -1234,7 +1229,7 @@
 	.eccsize = 0,
 };
 
-/* v3: i.MX51, i.MX53 */
+/* v3.2a: i.MX51 */
 static const struct mxc_nand_devtype_data imx51_nand_devtype_data = {
 	.preset = preset_v3,
 	.send_cmd = send_cmd_v3,
@@ -1258,6 +1253,34 @@
 	.spare_len = 64,
 	.eccbytes = 0,
 	.eccsize = 0,
+	.ppb_shift = 7,
+};
+
+/* v3.2b: i.MX53 */
+static const struct mxc_nand_devtype_data imx53_nand_devtype_data = {
+	.preset = preset_v3,
+	.send_cmd = send_cmd_v3,
+	.send_addr = send_addr_v3,
+	.send_page = send_page_v3,
+	.send_read_id = send_read_id_v3,
+	.get_dev_status = get_dev_status_v3,
+	.check_int = check_int_v3,
+	.irq_control = irq_control_v3,
+	.get_ecc_status = get_ecc_status_v3,
+	.ecclayout_512 = &nandv2_hw_eccoob_smallpage,
+	.ecclayout_2k = &nandv2_hw_eccoob_largepage,
+	.ecclayout_4k = &nandv2_hw_eccoob_smallpage, /* XXX: needs fix */
+	.select_chip = mxc_nand_select_chip_v1_v3,
+	.correct_data = mxc_nand_correct_data_v2_v3,
+	.irqpending_quirk = 0,
+	.needs_ip = 1,
+	.regs_offset = 0,
+	.spare0_offset = 0x1000,
+	.axi_offset = 0x1e00,
+	.spare_len = 64,
+	.eccbytes = 0,
+	.eccsize = 0,
+	.ppb_shift = 8,
 };
 
 #ifdef CONFIG_OF_MTD
@@ -1274,6 +1297,9 @@
 	}, {
 		.compatible = "fsl,imx51-nand",
 		.data = &imx51_nand_devtype_data,
+	}, {
+		.compatible = "fsl,imx53-nand",
+		.data = &imx53_nand_devtype_data,
 	},
 	{ /* sentinel */ }
 };
@@ -1327,15 +1353,17 @@
 			host->devtype_data = &imx27_nand_devtype_data;
 	} else if (nfc_is_v21()) {
 		host->devtype_data = &imx25_nand_devtype_data;
-	} else if (nfc_is_v3_2()) {
+	} else if (nfc_is_v3_2a()) {
 		host->devtype_data = &imx51_nand_devtype_data;
+	} else if (nfc_is_v3_2b()) {
+		host->devtype_data = &imx53_nand_devtype_data;
 	} else
 		BUG();
 
 	return 0;
 }
 
-static int __init mxcnd_probe(struct platform_device *pdev)
+static int __devinit mxcnd_probe(struct platform_device *pdev)
 {
 	struct nand_chip *this;
 	struct mtd_info *mtd;
@@ -1344,8 +1372,8 @@
 	int err = 0;
 
 	/* Allocate memory for MTD device structure and private data */
-	host = kzalloc(sizeof(struct mxc_nand_host) + NAND_MAX_PAGESIZE +
-			NAND_MAX_OOBSIZE, GFP_KERNEL);
+	host = devm_kzalloc(&pdev->dev, sizeof(struct mxc_nand_host) +
+			NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE, GFP_KERNEL);
 	if (!host)
 		return -ENOMEM;
 
@@ -1370,36 +1398,38 @@
 	this->read_word = mxc_nand_read_word;
 	this->write_buf = mxc_nand_write_buf;
 	this->read_buf = mxc_nand_read_buf;
-	this->verify_buf = mxc_nand_verify_buf;
 
-	host->clk = clk_get(&pdev->dev, "nfc");
-	if (IS_ERR(host->clk)) {
-		err = PTR_ERR(host->clk);
-		goto eclk;
-	}
-
-	clk_prepare_enable(host->clk);
-	host->clk_act = 1;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		err = -ENODEV;
-		goto eres;
-	}
-
-	host->base = ioremap(res->start, resource_size(res));
-	if (!host->base) {
-		err = -ENOMEM;
-		goto eres;
-	}
-
-	host->main_area0 = host->base;
+	host->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(host->clk))
+		return PTR_ERR(host->clk);
 
 	err = mxcnd_probe_dt(host);
 	if (err > 0)
 		err = mxcnd_probe_pdata(host);
 	if (err < 0)
-		goto eirq;
+		return err;
+
+	if (host->devtype_data->needs_ip) {
+		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+		if (!res)
+			return -ENODEV;
+		host->regs_ip = devm_request_and_ioremap(&pdev->dev, res);
+		if (!host->regs_ip)
+			return -ENOMEM;
+
+		res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	} else {
+		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	}
+
+	if (!res)
+		return -ENODEV;
+
+	host->base = devm_request_and_ioremap(&pdev->dev, res);
+	if (!host->base)
+		return -ENOMEM;
+
+	host->main_area0 = host->base;
 
 	if (host->devtype_data->regs_offset)
 		host->regs = host->base + host->devtype_data->regs_offset;
@@ -1414,19 +1444,6 @@
 	this->ecc.size = 512;
 	this->ecc.layout = host->devtype_data->ecclayout_512;
 
-	if (host->devtype_data->needs_ip) {
-		res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-		if (!res) {
-			err = -ENODEV;
-			goto eirq;
-		}
-		host->regs_ip = ioremap(res->start, resource_size(res));
-		if (!host->regs_ip) {
-			err = -ENOMEM;
-			goto eirq;
-		}
-	}
-
 	if (host->pdata.hw_ecc) {
 		this->ecc.calculate = mxc_nand_calculate_ecc;
 		this->ecc.hwctl = mxc_nand_enable_hwecc;
@@ -1458,9 +1475,13 @@
 	 */
 	host->devtype_data->irq_control(host, 0);
 
-	err = request_irq(host->irq, mxc_nfc_irq, IRQF_DISABLED, DRIVER_NAME, host);
+	err = devm_request_irq(&pdev->dev, host->irq, mxc_nfc_irq,
+			IRQF_DISABLED, DRIVER_NAME, host);
 	if (err)
-		goto eirq;
+		return err;
+
+	clk_prepare_enable(host->clk);
+	host->clk_act = 1;
 
 	/*
 	 * Now that we "own" the interrupt make sure the interrupt mask bit is
@@ -1512,15 +1533,7 @@
 	return 0;
 
 escan:
-	free_irq(host->irq, host);
-eirq:
-	if (host->regs_ip)
-		iounmap(host->regs_ip);
-	iounmap(host->base);
-eres:
-	clk_put(host->clk);
-eclk:
-	kfree(host);
+	clk_disable_unprepare(host->clk);
 
 	return err;
 }
@@ -1529,16 +1542,9 @@
 {
 	struct mxc_nand_host *host = platform_get_drvdata(pdev);
 
-	clk_put(host->clk);
-
 	platform_set_drvdata(pdev, NULL);
 
 	nand_release(&host->mtd);
-	free_irq(host->irq, host);
-	if (host->regs_ip)
-		iounmap(host->regs_ip);
-	iounmap(host->base);
-	kfree(host);
 
 	return 0;
 }
@@ -1549,22 +1555,10 @@
 		   .owner = THIS_MODULE,
 		   .of_match_table = of_match_ptr(mxcnd_dt_ids),
 	},
+	.probe = mxcnd_probe,
 	.remove = __devexit_p(mxcnd_remove),
 };
-
-static int __init mxc_nd_init(void)
-{
-	return platform_driver_probe(&mxcnd_driver, mxcnd_probe);
-}
-
-static void __exit mxc_nd_cleanup(void)
-{
-	/* Unregister the device structure */
-	platform_driver_unregister(&mxcnd_driver);
-}
-
-module_init(mxc_nd_init);
-module_exit(mxc_nd_cleanup);
+module_platform_driver(mxcnd_driver);
 
 MODULE_AUTHOR("Freescale Semiconductor, Inc.");
 MODULE_DESCRIPTION("MXC NAND MTD driver");
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index a11253a0..ec6841d 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -243,25 +243,6 @@
 }
 
 /**
- * nand_verify_buf - [DEFAULT] Verify chip data against buffer
- * @mtd: MTD device structure
- * @buf: buffer containing the data to compare
- * @len: number of bytes to compare
- *
- * Default verify function for 8bit buswidth.
- */
-static int nand_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
-{
-	int i;
-	struct nand_chip *chip = mtd->priv;
-
-	for (i = 0; i < len; i++)
-		if (buf[i] != readb(chip->IO_ADDR_R))
-			return -EFAULT;
-	return 0;
-}
-
-/**
  * nand_write_buf16 - [DEFAULT] write buffer to chip
  * @mtd: MTD device structure
  * @buf: data buffer
@@ -301,28 +282,6 @@
 }
 
 /**
- * nand_verify_buf16 - [DEFAULT] Verify chip data against buffer
- * @mtd: MTD device structure
- * @buf: buffer containing the data to compare
- * @len: number of bytes to compare
- *
- * Default verify function for 16bit buswidth.
- */
-static int nand_verify_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
-{
-	int i;
-	struct nand_chip *chip = mtd->priv;
-	u16 *p = (u16 *) buf;
-	len >>= 1;
-
-	for (i = 0; i < len; i++)
-		if (p[i] != readw(chip->IO_ADDR_R))
-			return -EFAULT;
-
-	return 0;
-}
-
-/**
  * nand_block_bad - [DEFAULT] Read bad block marker from the chip
  * @mtd: MTD device structure
  * @ofs: offset from device start
@@ -1525,7 +1484,8 @@
 				ret = chip->ecc.read_page_raw(mtd, chip, bufpoi,
 							      oob_required,
 							      page);
-			else if (!aligned && NAND_SUBPAGE_READ(chip) && !oob)
+			else if (!aligned && NAND_HAS_SUBPAGE_READ(chip) &&
+				 !oob)
 				ret = chip->ecc.read_subpage(mtd, chip,
 							col, bytes, bufpoi);
 			else
@@ -1542,7 +1502,7 @@
 
 			/* Transfer not aligned data */
 			if (!aligned) {
-				if (!NAND_SUBPAGE_READ(chip) && !oob &&
+				if (!NAND_HAS_SUBPAGE_READ(chip) && !oob &&
 				    !(mtd->ecc_stats.failed - stats.failed) &&
 				    (ops->mode != MTD_OPS_RAW)) {
 					chip->pagebuf = realpage;
@@ -1565,14 +1525,6 @@
 					oobreadlen -= toread;
 				}
 			}
-
-			if (!(chip->options & NAND_NO_READRDY)) {
-				/* Apply delay or wait for ready/busy pin */
-				if (!chip->dev_ready)
-					udelay(chip->chip_delay);
-				else
-					nand_wait_ready(mtd);
-			}
 		} else {
 			memcpy(buf, chip->buffers->databuf + col, bytes);
 			buf += bytes;
@@ -1633,7 +1585,7 @@
 	ops.len = len;
 	ops.datbuf = buf;
 	ops.oobbuf = NULL;
-	ops.mode = 0;
+	ops.mode = MTD_OPS_PLACE_OOB;
 	ret = nand_do_read_ops(mtd, from, &ops);
 	*retlen = ops.retlen;
 	nand_release_device(mtd);
@@ -1837,14 +1789,6 @@
 		len = min(len, readlen);
 		buf = nand_transfer_oob(chip, buf, ops, len);
 
-		if (!(chip->options & NAND_NO_READRDY)) {
-			/* Apply delay or wait for ready/busy pin */
-			if (!chip->dev_ready)
-				udelay(chip->chip_delay);
-			else
-				nand_wait_ready(mtd);
-		}
-
 		readlen -= len;
 		if (!readlen)
 			break;
@@ -1927,12 +1871,14 @@
  *
  * Not for syndrome calculating ECC controllers, which use a special oob layout.
  */
-static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+static int nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
 				const uint8_t *buf, int oob_required)
 {
 	chip->write_buf(mtd, buf, mtd->writesize);
 	if (oob_required)
 		chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+	return 0;
 }
 
 /**
@@ -1944,7 +1890,7 @@
  *
  * We need a special oob layout and handling even when ECC isn't checked.
  */
-static void nand_write_page_raw_syndrome(struct mtd_info *mtd,
+static int nand_write_page_raw_syndrome(struct mtd_info *mtd,
 					struct nand_chip *chip,
 					const uint8_t *buf, int oob_required)
 {
@@ -1974,6 +1920,8 @@
 	size = mtd->oobsize - (oob - chip->oob_poi);
 	if (size)
 		chip->write_buf(mtd, oob, size);
+
+	return 0;
 }
 /**
  * nand_write_page_swecc - [REPLACEABLE] software ECC based page write function
@@ -1982,7 +1930,7 @@
  * @buf: data buffer
  * @oob_required: must write chip->oob_poi to OOB
  */
-static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
+static int nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
 				  const uint8_t *buf, int oob_required)
 {
 	int i, eccsize = chip->ecc.size;
@@ -1999,7 +1947,7 @@
 	for (i = 0; i < chip->ecc.total; i++)
 		chip->oob_poi[eccpos[i]] = ecc_calc[i];
 
-	chip->ecc.write_page_raw(mtd, chip, buf, 1);
+	return chip->ecc.write_page_raw(mtd, chip, buf, 1);
 }
 
 /**
@@ -2009,7 +1957,7 @@
  * @buf: data buffer
  * @oob_required: must write chip->oob_poi to OOB
  */
-static void nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+static int nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 				  const uint8_t *buf, int oob_required)
 {
 	int i, eccsize = chip->ecc.size;
@@ -2029,6 +1977,8 @@
 		chip->oob_poi[eccpos[i]] = ecc_calc[i];
 
 	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+	return 0;
 }
 
 /**
@@ -2041,7 +1991,7 @@
  * The hw generator calculates the error syndrome automatically. Therefore we
  * need a special oob layout and handling.
  */
-static void nand_write_page_syndrome(struct mtd_info *mtd,
+static int nand_write_page_syndrome(struct mtd_info *mtd,
 				    struct nand_chip *chip,
 				    const uint8_t *buf, int oob_required)
 {
@@ -2075,6 +2025,8 @@
 	i = mtd->oobsize - (oob - chip->oob_poi);
 	if (i)
 		chip->write_buf(mtd, oob, i);
+
+	return 0;
 }
 
 /**
@@ -2096,9 +2048,12 @@
 	chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
 
 	if (unlikely(raw))
-		chip->ecc.write_page_raw(mtd, chip, buf, oob_required);
+		status = chip->ecc.write_page_raw(mtd, chip, buf, oob_required);
 	else
-		chip->ecc.write_page(mtd, chip, buf, oob_required);
+		status = chip->ecc.write_page(mtd, chip, buf, oob_required);
+
+	if (status < 0)
+		return status;
 
 	/*
 	 * Cached progamming disabled for now. Not sure if it's worth the
@@ -2125,16 +2080,6 @@
 		status = chip->waitfunc(mtd, chip);
 	}
 
-#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
-	/* Send command to read back the data */
-	chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
-
-	if (chip->verify_buf(mtd, buf, mtd->writesize))
-		return -EIO;
-
-	/* Make sure the next page prog is preceded by a status read */
-	chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
-#endif
 	return 0;
 }
 
@@ -2336,7 +2281,7 @@
 	ops.len = len;
 	ops.datbuf = (uint8_t *)buf;
 	ops.oobbuf = NULL;
-	ops.mode = 0;
+	ops.mode = MTD_OPS_PLACE_OOB;
 
 	ret = nand_do_write_ops(mtd, to, &ops);
 
@@ -2365,7 +2310,7 @@
 	ops.len = len;
 	ops.datbuf = (uint8_t *)buf;
 	ops.oobbuf = NULL;
-	ops.mode = 0;
+	ops.mode = MTD_OPS_PLACE_OOB;
 	ret = nand_do_write_ops(mtd, to, &ops);
 	*retlen = ops.retlen;
 	nand_release_device(mtd);
@@ -2755,6 +2700,50 @@
 }
 
 /**
+ * nand_onfi_set_features- [REPLACEABLE] set features for ONFI nand
+ * @mtd: MTD device structure
+ * @chip: nand chip info structure
+ * @addr: feature address.
+ * @subfeature_param: the subfeature parameters, a four bytes array.
+ */
+static int nand_onfi_set_features(struct mtd_info *mtd, struct nand_chip *chip,
+			int addr, uint8_t *subfeature_param)
+{
+	int status;
+
+	if (!chip->onfi_version)
+		return -EINVAL;
+
+	chip->cmdfunc(mtd, NAND_CMD_SET_FEATURES, addr, -1);
+	chip->write_buf(mtd, subfeature_param, ONFI_SUBFEATURE_PARAM_LEN);
+	status = chip->waitfunc(mtd, chip);
+	if (status & NAND_STATUS_FAIL)
+		return -EIO;
+	return 0;
+}
+
+/**
+ * nand_onfi_get_features- [REPLACEABLE] get features for ONFI nand
+ * @mtd: MTD device structure
+ * @chip: nand chip info structure
+ * @addr: feature address.
+ * @subfeature_param: the subfeature parameters, a four bytes array.
+ */
+static int nand_onfi_get_features(struct mtd_info *mtd, struct nand_chip *chip,
+			int addr, uint8_t *subfeature_param)
+{
+	if (!chip->onfi_version)
+		return -EINVAL;
+
+	/* clear the sub feature parameters */
+	memset(subfeature_param, 0, ONFI_SUBFEATURE_PARAM_LEN);
+
+	chip->cmdfunc(mtd, NAND_CMD_GET_FEATURES, addr, -1);
+	chip->read_buf(mtd, subfeature_param, ONFI_SUBFEATURE_PARAM_LEN);
+	return 0;
+}
+
+/**
  * nand_suspend - [MTD Interface] Suspend the NAND flash
  * @mtd: MTD device structure
  */
@@ -2809,8 +2798,6 @@
 		chip->write_buf = busw ? nand_write_buf16 : nand_write_buf;
 	if (!chip->read_buf)
 		chip->read_buf = busw ? nand_read_buf16 : nand_read_buf;
-	if (!chip->verify_buf)
-		chip->verify_buf = busw ? nand_verify_buf16 : nand_verify_buf;
 	if (!chip->scan_bbt)
 		chip->scan_bbt = nand_default_bbt;
 
@@ -2914,14 +2901,250 @@
 	if (le16_to_cpu(p->features) & 1)
 		*busw = NAND_BUSWIDTH_16;
 
-	chip->options &= ~NAND_CHIPOPTIONS_MSK;
-	chip->options |= NAND_NO_READRDY & NAND_CHIPOPTIONS_MSK;
-
 	pr_info("ONFI flash detected\n");
 	return 1;
 }
 
 /*
+ * nand_id_has_period - Check if an ID string has a given wraparound period
+ * @id_data: the ID string
+ * @arrlen: the length of the @id_data array
+ * @period: the period of repitition
+ *
+ * Check if an ID string is repeated within a given sequence of bytes at
+ * specific repetition interval period (e.g., {0x20,0x01,0x7F,0x20} has a
+ * period of 2). This is a helper function for nand_id_len(). Returns non-zero
+ * if the repetition has a period of @period; otherwise, returns zero.
+ */
+static int nand_id_has_period(u8 *id_data, int arrlen, int period)
+{
+	int i, j;
+	for (i = 0; i < period; i++)
+		for (j = i + period; j < arrlen; j += period)
+			if (id_data[i] != id_data[j])
+				return 0;
+	return 1;
+}
+
+/*
+ * nand_id_len - Get the length of an ID string returned by CMD_READID
+ * @id_data: the ID string
+ * @arrlen: the length of the @id_data array
+
+ * Returns the length of the ID string, according to known wraparound/trailing
+ * zero patterns. If no pattern exists, returns the length of the array.
+ */
+static int nand_id_len(u8 *id_data, int arrlen)
+{
+	int last_nonzero, period;
+
+	/* Find last non-zero byte */
+	for (last_nonzero = arrlen - 1; last_nonzero >= 0; last_nonzero--)
+		if (id_data[last_nonzero])
+			break;
+
+	/* All zeros */
+	if (last_nonzero < 0)
+		return 0;
+
+	/* Calculate wraparound period */
+	for (period = 1; period < arrlen; period++)
+		if (nand_id_has_period(id_data, arrlen, period))
+			break;
+
+	/* There's a repeated pattern */
+	if (period < arrlen)
+		return period;
+
+	/* There are trailing zeros */
+	if (last_nonzero < arrlen - 1)
+		return last_nonzero + 1;
+
+	/* No pattern detected */
+	return arrlen;
+}
+
+/*
+ * Many new NAND share similar device ID codes, which represent the size of the
+ * chip. The rest of the parameters must be decoded according to generic or
+ * manufacturer-specific "extended ID" decoding patterns.
+ */
+static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip,
+				u8 id_data[8], int *busw)
+{
+	int extid, id_len;
+	/* The 3rd id byte holds MLC / multichip data */
+	chip->cellinfo = id_data[2];
+	/* The 4th id byte is the important one */
+	extid = id_data[3];
+
+	id_len = nand_id_len(id_data, 8);
+
+	/*
+	 * Field definitions are in the following datasheets:
+	 * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
+	 * New style   (6 byte ID): Samsung K9GAG08U0F (p.44)
+	 * Hynix MLC   (6 byte ID): Hynix H27UBG8T2B (p.22)
+	 *
+	 * Check for ID length, cell type, and Hynix/Samsung ID to decide what
+	 * to do.
+	 */
+	if (id_len == 6 && id_data[0] == NAND_MFR_SAMSUNG) {
+		/* Calc pagesize */
+		mtd->writesize = 2048 << (extid & 0x03);
+		extid >>= 2;
+		/* Calc oobsize */
+		switch (((extid >> 2) & 0x04) | (extid & 0x03)) {
+		case 1:
+			mtd->oobsize = 128;
+			break;
+		case 2:
+			mtd->oobsize = 218;
+			break;
+		case 3:
+			mtd->oobsize = 400;
+			break;
+		case 4:
+			mtd->oobsize = 436;
+			break;
+		case 5:
+			mtd->oobsize = 512;
+			break;
+		case 6:
+		default: /* Other cases are "reserved" (unknown) */
+			mtd->oobsize = 640;
+			break;
+		}
+		extid >>= 2;
+		/* Calc blocksize */
+		mtd->erasesize = (128 * 1024) <<
+			(((extid >> 1) & 0x04) | (extid & 0x03));
+		*busw = 0;
+	} else if (id_len == 6 && id_data[0] == NAND_MFR_HYNIX &&
+			(chip->cellinfo & NAND_CI_CELLTYPE_MSK)) {
+		unsigned int tmp;
+
+		/* Calc pagesize */
+		mtd->writesize = 2048 << (extid & 0x03);
+		extid >>= 2;
+		/* Calc oobsize */
+		switch (((extid >> 2) & 0x04) | (extid & 0x03)) {
+		case 0:
+			mtd->oobsize = 128;
+			break;
+		case 1:
+			mtd->oobsize = 224;
+			break;
+		case 2:
+			mtd->oobsize = 448;
+			break;
+		case 3:
+			mtd->oobsize = 64;
+			break;
+		case 4:
+			mtd->oobsize = 32;
+			break;
+		case 5:
+			mtd->oobsize = 16;
+			break;
+		default:
+			mtd->oobsize = 640;
+			break;
+		}
+		extid >>= 2;
+		/* Calc blocksize */
+		tmp = ((extid >> 1) & 0x04) | (extid & 0x03);
+		if (tmp < 0x03)
+			mtd->erasesize = (128 * 1024) << tmp;
+		else if (tmp == 0x03)
+			mtd->erasesize = 768 * 1024;
+		else
+			mtd->erasesize = (64 * 1024) << tmp;
+		*busw = 0;
+	} else {
+		/* Calc pagesize */
+		mtd->writesize = 1024 << (extid & 0x03);
+		extid >>= 2;
+		/* Calc oobsize */
+		mtd->oobsize = (8 << (extid & 0x01)) *
+			(mtd->writesize >> 9);
+		extid >>= 2;
+		/* Calc blocksize. Blocksize is multiples of 64KiB */
+		mtd->erasesize = (64 * 1024) << (extid & 0x03);
+		extid >>= 2;
+		/* Get buswidth information */
+		*busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
+	}
+}
+
+/*
+ * Old devices have chip data hardcoded in the device ID table. nand_decode_id
+ * decodes a matching ID table entry and assigns the MTD size parameters for
+ * the chip.
+ */
+static void nand_decode_id(struct mtd_info *mtd, struct nand_chip *chip,
+				struct nand_flash_dev *type, u8 id_data[8],
+				int *busw)
+{
+	int maf_id = id_data[0];
+
+	mtd->erasesize = type->erasesize;
+	mtd->writesize = type->pagesize;
+	mtd->oobsize = mtd->writesize / 32;
+	*busw = type->options & NAND_BUSWIDTH_16;
+
+	/*
+	 * Check for Spansion/AMD ID + repeating 5th, 6th byte since
+	 * some Spansion chips have erasesize that conflicts with size
+	 * listed in nand_ids table.
+	 * Data sheet (5 byte ID): Spansion S30ML-P ORNAND (p.39)
+	 */
+	if (maf_id == NAND_MFR_AMD && id_data[4] != 0x00 && id_data[5] == 0x00
+			&& id_data[6] == 0x00 && id_data[7] == 0x00
+			&& mtd->writesize == 512) {
+		mtd->erasesize = 128 * 1024;
+		mtd->erasesize <<= ((id_data[3] & 0x03) << 1);
+	}
+}
+
+/*
+ * Set the bad block marker/indicator (BBM/BBI) patterns according to some
+ * heuristic patterns using various detected parameters (e.g., manufacturer,
+ * page size, cell-type information).
+ */
+static void nand_decode_bbm_options(struct mtd_info *mtd,
+				    struct nand_chip *chip, u8 id_data[8])
+{
+	int maf_id = id_data[0];
+
+	/* Set the bad block position */
+	if (mtd->writesize > 512 || (chip->options & NAND_BUSWIDTH_16))
+		chip->badblockpos = NAND_LARGE_BADBLOCK_POS;
+	else
+		chip->badblockpos = NAND_SMALL_BADBLOCK_POS;
+
+	/*
+	 * Bad block marker is stored in the last page of each block on Samsung
+	 * and Hynix MLC devices; stored in first two pages of each block on
+	 * Micron devices with 2KiB pages and on SLC Samsung, Hynix, Toshiba,
+	 * AMD/Spansion, and Macronix.  All others scan only the first page.
+	 */
+	if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
+			(maf_id == NAND_MFR_SAMSUNG ||
+			 maf_id == NAND_MFR_HYNIX))
+		chip->bbt_options |= NAND_BBT_SCANLASTPAGE;
+	else if ((!(chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
+				(maf_id == NAND_MFR_SAMSUNG ||
+				 maf_id == NAND_MFR_HYNIX ||
+				 maf_id == NAND_MFR_TOSHIBA ||
+				 maf_id == NAND_MFR_AMD ||
+				 maf_id == NAND_MFR_MACRONIX)) ||
+			(mtd->writesize == 2048 &&
+			 maf_id == NAND_MFR_MICRON))
+		chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
+}
+
+/*
  * Get the flash and manufacturer id and lookup if the type is supported.
  */
 static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
@@ -2932,7 +3155,6 @@
 {
 	int i, maf_idx;
 	u8 id_data[8];
-	int ret;
 
 	/* Select the device */
 	chip->select_chip(mtd, 0);
@@ -2959,7 +3181,8 @@
 
 	chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
 
-	for (i = 0; i < 2; i++)
+	/* Read entire ID string */
+	for (i = 0; i < 8; i++)
 		id_data[i] = chip->read_byte(mtd);
 
 	if (id_data[0] != *maf_id || id_data[1] != *dev_id) {
@@ -2979,18 +3202,10 @@
 	chip->onfi_version = 0;
 	if (!type->name || !type->pagesize) {
 		/* Check is chip is ONFI compliant */
-		ret = nand_flash_detect_onfi(mtd, chip, &busw);
-		if (ret)
+		if (nand_flash_detect_onfi(mtd, chip, &busw))
 			goto ident_done;
 	}
 
-	chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
-
-	/* Read entire ID string */
-
-	for (i = 0; i < 8; i++)
-		id_data[i] = chip->read_byte(mtd);
-
 	if (!type->name)
 		return ERR_PTR(-ENODEV);
 
@@ -3003,86 +3218,13 @@
 		/* Set the pagesize, oobsize, erasesize by the driver */
 		busw = chip->init_size(mtd, chip, id_data);
 	} else if (!type->pagesize) {
-		int extid;
-		/* The 3rd id byte holds MLC / multichip data */
-		chip->cellinfo = id_data[2];
-		/* The 4th id byte is the important one */
-		extid = id_data[3];
-
-		/*
-		 * Field definitions are in the following datasheets:
-		 * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
-		 * New style   (6 byte ID): Samsung K9GBG08U0M (p.40)
-		 *
-		 * Check for wraparound + Samsung ID + nonzero 6th byte
-		 * to decide what to do.
-		 */
-		if (id_data[0] == id_data[6] && id_data[1] == id_data[7] &&
-				id_data[0] == NAND_MFR_SAMSUNG &&
-				(chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
-				id_data[5] != 0x00) {
-			/* Calc pagesize */
-			mtd->writesize = 2048 << (extid & 0x03);
-			extid >>= 2;
-			/* Calc oobsize */
-			switch (extid & 0x03) {
-			case 1:
-				mtd->oobsize = 128;
-				break;
-			case 2:
-				mtd->oobsize = 218;
-				break;
-			case 3:
-				mtd->oobsize = 400;
-				break;
-			default:
-				mtd->oobsize = 436;
-				break;
-			}
-			extid >>= 2;
-			/* Calc blocksize */
-			mtd->erasesize = (128 * 1024) <<
-				(((extid >> 1) & 0x04) | (extid & 0x03));
-			busw = 0;
-		} else {
-			/* Calc pagesize */
-			mtd->writesize = 1024 << (extid & 0x03);
-			extid >>= 2;
-			/* Calc oobsize */
-			mtd->oobsize = (8 << (extid & 0x01)) *
-				(mtd->writesize >> 9);
-			extid >>= 2;
-			/* Calc blocksize. Blocksize is multiples of 64KiB */
-			mtd->erasesize = (64 * 1024) << (extid & 0x03);
-			extid >>= 2;
-			/* Get buswidth information */
-			busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
-		}
+		/* Decode parameters from extended ID */
+		nand_decode_ext_id(mtd, chip, id_data, &busw);
 	} else {
-		/*
-		 * Old devices have chip data hardcoded in the device id table.
-		 */
-		mtd->erasesize = type->erasesize;
-		mtd->writesize = type->pagesize;
-		mtd->oobsize = mtd->writesize / 32;
-		busw = type->options & NAND_BUSWIDTH_16;
-
-		/*
-		 * Check for Spansion/AMD ID + repeating 5th, 6th byte since
-		 * some Spansion chips have erasesize that conflicts with size
-		 * listed in nand_ids table.
-		 * Data sheet (5 byte ID): Spansion S30ML-P ORNAND (p.39)
-		 */
-		if (*maf_id == NAND_MFR_AMD && id_data[4] != 0x00 &&
-				id_data[5] == 0x00 && id_data[6] == 0x00 &&
-				id_data[7] == 0x00 && mtd->writesize == 512) {
-			mtd->erasesize = 128 * 1024;
-			mtd->erasesize <<= ((id_data[3] & 0x03) << 1);
-		}
+		nand_decode_id(mtd, chip, type, id_data, &busw);
 	}
-	/* Get chip options, preserve non chip based options */
-	chip->options &= ~NAND_CHIPOPTIONS_MSK;
-	chip->options |= type->options & NAND_CHIPOPTIONS_MSK;
+	/* Get chip options */
+	chip->options |= type->options;
 
 	/*
 	 * Check if chip is not a Samsung device. Do not clear the
@@ -3112,6 +3254,8 @@
 		return ERR_PTR(-EINVAL);
 	}
 
+	nand_decode_bbm_options(mtd, chip, id_data);
+
 	/* Calculate the address shift from the page size */
 	chip->page_shift = ffs(mtd->writesize) - 1;
 	/* Convert chipsize to number of pages per chip -1 */
@@ -3128,33 +3272,6 @@
 
 	chip->badblockbits = 8;
 
-	/* Set the bad block position */
-	if (mtd->writesize > 512 || (busw & NAND_BUSWIDTH_16))
-		chip->badblockpos = NAND_LARGE_BADBLOCK_POS;
-	else
-		chip->badblockpos = NAND_SMALL_BADBLOCK_POS;
-
-	/*
-	 * Bad block marker is stored in the last page of each block
-	 * on Samsung and Hynix MLC devices; stored in first two pages
-	 * of each block on Micron devices with 2KiB pages and on
-	 * SLC Samsung, Hynix, Toshiba, AMD/Spansion, and Macronix.
-	 * All others scan only the first page.
-	 */
-	if ((chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
-			(*maf_id == NAND_MFR_SAMSUNG ||
-			 *maf_id == NAND_MFR_HYNIX))
-		chip->bbt_options |= NAND_BBT_SCANLASTPAGE;
-	else if ((!(chip->cellinfo & NAND_CI_CELLTYPE_MSK) &&
-				(*maf_id == NAND_MFR_SAMSUNG ||
-				 *maf_id == NAND_MFR_HYNIX ||
-				 *maf_id == NAND_MFR_TOSHIBA ||
-				 *maf_id == NAND_MFR_AMD ||
-				 *maf_id == NAND_MFR_MACRONIX)) ||
-			(mtd->writesize == 2048 &&
-			 *maf_id == NAND_MFR_MICRON))
-		chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
-
 	/* Check for AND chips with 4 page planes */
 	if (chip->options & NAND_4PAGE_ARRAY)
 		chip->erase_cmd = multi_erase_cmd;
@@ -3284,6 +3401,12 @@
 	if (!chip->write_page)
 		chip->write_page = nand_write_page;
 
+	/* set for ONFI nand */
+	if (!chip->onfi_set_features)
+		chip->onfi_set_features = nand_onfi_set_features;
+	if (!chip->onfi_get_features)
+		chip->onfi_get_features = nand_onfi_get_features;
+
 	/*
 	 * Check ECC mode, default to software if 3byte/512byte hardware ECC is
 	 * selected and we have 256 byte pagesize fallback to software ECC
@@ -3477,6 +3600,10 @@
 	/* Invalidate the pagebuffer reference */
 	chip->pagebuf = -1;
 
+	/* Large page NAND with SOFT_ECC should support subpage reads */
+	if ((chip->ecc.mode == NAND_ECC_SOFT) && (chip->page_shift > 9))
+		chip->options |= NAND_SUBPAGE_READ;
+
 	/* Fill in remaining MTD driver data */
 	mtd->type = MTD_NANDFLASH;
 	mtd->flags = (chip->options & NAND_ROM) ? MTD_CAP_ROM :
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 30d1319..916d6e9 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -4,7 +4,7 @@
  *  Overview:
  *   Bad block table support for the NAND driver
  *
- *  Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
+ *  Copyright © 2004 Thomas Gleixner (tglx@linutronix.de)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -22,7 +22,7 @@
  * BBT on flash. If a BBT is found then the contents are read and the memory
  * based BBT is created. If a mirrored BBT is selected then the mirror is
  * searched too and the versions are compared. If the mirror has a greater
- * version number than the mirror BBT is used to build the memory based BBT.
+ * version number, then the mirror BBT is used to build the memory based BBT.
  * If the tables are not versioned, then we "or" the bad block information.
  * If one of the BBTs is out of date or does not exist it is (re)created.
  * If no BBT exists at all then the device is scanned for factory marked
@@ -62,21 +62,20 @@
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/mtd/mtd.h>
+#include <linux/mtd/bbm.h>
 #include <linux/mtd/nand.h>
 #include <linux/mtd/nand_ecc.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
 #include <linux/vmalloc.h>
 #include <linux/export.h>
+#include <linux/string.h>
 
 static int check_pattern_no_oob(uint8_t *buf, struct nand_bbt_descr *td)
 {
-	int ret;
-
-	ret = memcmp(buf, td->pattern, td->len);
-	if (!ret)
-		return ret;
-	return -1;
+	if (memcmp(buf, td->pattern, td->len))
+		return -1;
+	return 0;
 }
 
 /**
@@ -92,19 +91,16 @@
  */
 static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
 {
-	int i, end = 0;
+	int end = 0;
 	uint8_t *p = buf;
 
 	if (td->options & NAND_BBT_NO_OOB)
 		return check_pattern_no_oob(buf, td);
 
 	end = paglen + td->offs;
-	if (td->options & NAND_BBT_SCANEMPTY) {
-		for (i = 0; i < end; i++) {
-			if (p[i] != 0xff)
-				return -1;
-		}
-	}
+	if (td->options & NAND_BBT_SCANEMPTY)
+		if (memchr_inv(p, 0xff, end))
+			return -1;
 	p += end;
 
 	/* Compare the pattern */
@@ -114,10 +110,8 @@
 	if (td->options & NAND_BBT_SCANEMPTY) {
 		p += td->len;
 		end += td->len;
-		for (i = end; i < len; i++) {
-			if (*p++ != 0xff)
-				return -1;
-		}
+		if (memchr_inv(p, 0xff, len - end))
+			return -1;
 	}
 	return 0;
 }
@@ -133,14 +127,9 @@
  */
 static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td)
 {
-	int i;
-	uint8_t *p = buf;
-
 	/* Compare the pattern */
-	for (i = 0; i < td->len; i++) {
-		if (p[td->offs + i] != td->pattern[i])
-			return -1;
-	}
+	if (memcmp(buf + td->offs, td->pattern, td->len))
+		return -1;
 	return 0;
 }
 
@@ -288,7 +277,7 @@
 }
 
 /* BBT marker is in the first page, no OOB */
-static int scan_read_raw_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
+static int scan_read_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
 			 struct nand_bbt_descr *td)
 {
 	size_t retlen;
@@ -301,14 +290,24 @@
 	return mtd_read(mtd, offs, len, &retlen, buf);
 }
 
-/* Scan read raw data from flash */
-static int scan_read_raw_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
+/**
+ * scan_read_oob - [GENERIC] Scan data+OOB region to buffer
+ * @mtd: MTD device structure
+ * @buf: temporary buffer
+ * @offs: offset at which to scan
+ * @len: length of data region to read
+ *
+ * Scan read data from data+OOB. May traverse multiple pages, interleaving
+ * page,OOB,page,OOB,... in buf. Completes transfer and returns the "strongest"
+ * ECC condition (error or bitflip). May quit on the first (non-ECC) error.
+ */
+static int scan_read_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
 			 size_t len)
 {
 	struct mtd_oob_ops ops;
-	int res;
+	int res, ret = 0;
 
-	ops.mode = MTD_OPS_RAW;
+	ops.mode = MTD_OPS_PLACE_OOB;
 	ops.ooboffs = 0;
 	ops.ooblen = mtd->oobsize;
 
@@ -318,24 +317,27 @@
 		ops.oobbuf = buf + ops.len;
 
 		res = mtd_read_oob(mtd, offs, &ops);
-
-		if (res)
-			return res;
+		if (res) {
+			if (!mtd_is_bitflip_or_eccerr(res))
+				return res;
+			else if (mtd_is_eccerr(res) || !ret)
+				ret = res;
+		}
 
 		buf += mtd->oobsize + mtd->writesize;
 		len -= mtd->writesize;
 		offs += mtd->writesize;
 	}
-	return 0;
+	return ret;
 }
 
-static int scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
+static int scan_read(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
 			 size_t len, struct nand_bbt_descr *td)
 {
 	if (td->options & NAND_BBT_NO_OOB)
-		return scan_read_raw_data(mtd, buf, offs, td);
+		return scan_read_data(mtd, buf, offs, td);
 	else
-		return scan_read_raw_oob(mtd, buf, offs, len);
+		return scan_read_oob(mtd, buf, offs, len);
 }
 
 /* Scan write data with oob to flash */
@@ -373,14 +375,14 @@
  * Read the bad block table(s) for all chips starting at a given page. We
  * assume that the bbt bits are in consecutive order.
  */
-static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
-			 struct nand_bbt_descr *td, struct nand_bbt_descr *md)
+static void read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
+			  struct nand_bbt_descr *td, struct nand_bbt_descr *md)
 {
 	struct nand_chip *this = mtd->priv;
 
 	/* Read the primary version, if available */
 	if (td->options & NAND_BBT_VERSION) {
-		scan_read_raw(mtd, buf, (loff_t)td->pages[0] << this->page_shift,
+		scan_read(mtd, buf, (loff_t)td->pages[0] << this->page_shift,
 			      mtd->writesize, td);
 		td->version[0] = buf[bbt_get_ver_offs(mtd, td)];
 		pr_info("Bad block table at page %d, version 0x%02X\n",
@@ -389,28 +391,27 @@
 
 	/* Read the mirror version, if available */
 	if (md && (md->options & NAND_BBT_VERSION)) {
-		scan_read_raw(mtd, buf, (loff_t)md->pages[0] << this->page_shift,
-			      mtd->writesize, td);
+		scan_read(mtd, buf, (loff_t)md->pages[0] << this->page_shift,
+			      mtd->writesize, md);
 		md->version[0] = buf[bbt_get_ver_offs(mtd, md)];
 		pr_info("Bad block table at page %d, version 0x%02X\n",
 			 md->pages[0], md->version[0]);
 	}
-	return 1;
 }
 
 /* Scan a given block full */
 static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd,
 			   loff_t offs, uint8_t *buf, size_t readlen,
-			   int scanlen, int len)
+			   int scanlen, int numpages)
 {
 	int ret, j;
 
-	ret = scan_read_raw_oob(mtd, buf, offs, readlen);
+	ret = scan_read_oob(mtd, buf, offs, readlen);
 	/* Ignore ECC errors when checking for BBM */
 	if (ret && !mtd_is_bitflip_or_eccerr(ret))
 		return ret;
 
-	for (j = 0; j < len; j++, buf += scanlen) {
+	for (j = 0; j < numpages; j++, buf += scanlen) {
 		if (check_pattern(buf, scanlen, mtd->writesize, bd))
 			return 1;
 	}
@@ -419,7 +420,7 @@
 
 /* Scan a given block partially */
 static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
-			   loff_t offs, uint8_t *buf, int len)
+			   loff_t offs, uint8_t *buf, int numpages)
 {
 	struct mtd_oob_ops ops;
 	int j, ret;
@@ -430,7 +431,7 @@
 	ops.datbuf = NULL;
 	ops.mode = MTD_OPS_PLACE_OOB;
 
-	for (j = 0; j < len; j++) {
+	for (j = 0; j < numpages; j++) {
 		/*
 		 * Read the full oob until read_oob is fixed to handle single
 		 * byte reads for 16 bit buswidth.
@@ -463,7 +464,7 @@
 	struct nand_bbt_descr *bd, int chip)
 {
 	struct nand_chip *this = mtd->priv;
-	int i, numblocks, len, scanlen;
+	int i, numblocks, numpages, scanlen;
 	int startblock;
 	loff_t from;
 	size_t readlen;
@@ -471,11 +472,11 @@
 	pr_info("Scanning device for bad blocks\n");
 
 	if (bd->options & NAND_BBT_SCANALLPAGES)
-		len = 1 << (this->bbt_erase_shift - this->page_shift);
+		numpages = 1 << (this->bbt_erase_shift - this->page_shift);
 	else if (bd->options & NAND_BBT_SCAN2NDPAGE)
-		len = 2;
+		numpages = 2;
 	else
-		len = 1;
+		numpages = 1;
 
 	if (!(bd->options & NAND_BBT_SCANEMPTY)) {
 		/* We need only read few bytes from the OOB area */
@@ -484,7 +485,7 @@
 	} else {
 		/* Full page content should be read */
 		scanlen = mtd->writesize + mtd->oobsize;
-		readlen = len * mtd->writesize;
+		readlen = numpages * mtd->writesize;
 	}
 
 	if (chip == -1) {
@@ -508,7 +509,7 @@
 	}
 
 	if (this->bbt_options & NAND_BBT_SCANLASTPAGE)
-		from += mtd->erasesize - (mtd->writesize * len);
+		from += mtd->erasesize - (mtd->writesize * numpages);
 
 	for (i = startblock; i < numblocks;) {
 		int ret;
@@ -517,9 +518,9 @@
 
 		if (bd->options & NAND_BBT_SCANALLPAGES)
 			ret = scan_block_full(mtd, bd, from, buf, readlen,
-					      scanlen, len);
+					      scanlen, numpages);
 		else
-			ret = scan_block_fast(mtd, bd, from, buf, len);
+			ret = scan_block_fast(mtd, bd, from, buf, numpages);
 
 		if (ret < 0)
 			return ret;
@@ -594,7 +595,7 @@
 			loff_t offs = (loff_t)actblock << this->bbt_erase_shift;
 
 			/* Read first page */
-			scan_read_raw(mtd, buf, offs, mtd->writesize, td);
+			scan_read(mtd, buf, offs, mtd->writesize, td);
 			if (!check_pattern(buf, scanlen, mtd->writesize, td)) {
 				td->pages[i] = actblock << blocktopage;
 				if (td->options & NAND_BBT_VERSION) {
@@ -626,7 +627,9 @@
  *
  * Search and read the bad block table(s).
  */
-static int search_read_bbts(struct mtd_info *mtd, uint8_t * buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md)
+static void search_read_bbts(struct mtd_info *mtd, uint8_t *buf,
+			     struct nand_bbt_descr *td,
+			     struct nand_bbt_descr *md)
 {
 	/* Search the primary table */
 	search_bbt(mtd, buf, td);
@@ -634,9 +637,6 @@
 	/* Search the mirror table */
 	if (md)
 		search_bbt(mtd, buf, md);
-
-	/* Force result check */
-	return 1;
 }
 
 /**
@@ -1162,14 +1162,13 @@
 
 	/* Is the bbt at a given page? */
 	if (td->options & NAND_BBT_ABSPAGE) {
-		res = read_abs_bbts(mtd, buf, td, md);
+		read_abs_bbts(mtd, buf, td, md);
 	} else {
 		/* Search the bad block table using a pattern in oob */
-		res = search_read_bbts(mtd, buf, td, md);
+		search_read_bbts(mtd, buf, td, md);
 	}
 
-	if (res)
-		res = check_create(mtd, buf, bd);
+	res = check_create(mtd, buf, bd);
 
 	/* Prevent the bbt regions from erasing / writing */
 	mark_bbt_region(mtd, td);
@@ -1260,7 +1259,7 @@
 	.offs =	8,
 	.len = 4,
 	.veroffs = 12,
-	.maxblocks = 4,
+	.maxblocks = NAND_BBT_SCAN_MAXBLOCKS,
 	.pattern = bbt_pattern
 };
 
@@ -1270,27 +1269,27 @@
 	.offs =	8,
 	.len = 4,
 	.veroffs = 12,
-	.maxblocks = 4,
+	.maxblocks = NAND_BBT_SCAN_MAXBLOCKS,
 	.pattern = mirror_pattern
 };
 
-static struct nand_bbt_descr bbt_main_no_bbt_descr = {
+static struct nand_bbt_descr bbt_main_no_oob_descr = {
 	.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
 		| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP
 		| NAND_BBT_NO_OOB,
 	.len = 4,
 	.veroffs = 4,
-	.maxblocks = 4,
+	.maxblocks = NAND_BBT_SCAN_MAXBLOCKS,
 	.pattern = bbt_pattern
 };
 
-static struct nand_bbt_descr bbt_mirror_no_bbt_descr = {
+static struct nand_bbt_descr bbt_mirror_no_oob_descr = {
 	.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
 		| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP
 		| NAND_BBT_NO_OOB,
 	.len = 4,
 	.veroffs = 4,
-	.maxblocks = 4,
+	.maxblocks = NAND_BBT_SCAN_MAXBLOCKS,
 	.pattern = mirror_pattern
 };
 
@@ -1355,8 +1354,8 @@
 		/* Use the default pattern descriptors */
 		if (!this->bbt_td) {
 			if (this->bbt_options & NAND_BBT_NO_OOB) {
-				this->bbt_td = &bbt_main_no_bbt_descr;
-				this->bbt_md = &bbt_mirror_no_bbt_descr;
+				this->bbt_td = &bbt_main_no_oob_descr;
+				this->bbt_md = &bbt_mirror_no_oob_descr;
 			} else {
 				this->bbt_td = &bbt_main_descr;
 				this->bbt_md = &bbt_mirror_descr;
@@ -1406,3 +1405,4 @@
 
 EXPORT_SYMBOL(nand_scan_bbt);
 EXPORT_SYMBOL(nand_default_bbt);
+EXPORT_SYMBOL_GPL(nand_update_bbt);
diff --git a/drivers/mtd/nand/nand_bcm_umi.c b/drivers/mtd/nand/nand_bcm_umi.c
deleted file mode 100644
index 46a6bc9..0000000
--- a/drivers/mtd/nand/nand_bcm_umi.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/*****************************************************************************
-* Copyright 2004 - 2009 Broadcom Corporation.  All rights reserved.
-*
-* Unless you and Broadcom execute a separate written software license
-* agreement governing use of this software, this software is licensed to you
-* under the terms of the GNU General Public License version 2, available at
-* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
-*
-* Notwithstanding the above, under no circumstances may you combine this
-* software in any way with any other Broadcom software provided under a
-* license other than the GPL, without Broadcom's express prior written
-* consent.
-*****************************************************************************/
-
-/* ---- Include Files ---------------------------------------------------- */
-#include <mach/reg_umi.h>
-#include "nand_bcm_umi.h"
-#ifdef BOOT0_BUILD
-#include <uart.h>
-#endif
-
-/* ---- External Variable Declarations ----------------------------------- */
-/* ---- External Function Prototypes ------------------------------------- */
-/* ---- Public Variables ------------------------------------------------- */
-/* ---- Private Constants and Types -------------------------------------- */
-/* ---- Private Function Prototypes -------------------------------------- */
-/* ---- Private Variables ------------------------------------------------ */
-/* ---- Private Functions ------------------------------------------------ */
-
-#if NAND_ECC_BCH
-/****************************************************************************
-*  nand_bch_ecc_flip_bit - Routine to flip an errored bit
-*
-*  PURPOSE:
-*     This is a helper routine that flips the bit (0 -> 1 or 1 -> 0) of the
-*     errored bit specified
-*
-*  PARAMETERS:
-*     datap - Container that holds the 512 byte data
-*     errorLocation - Location of the bit that needs to be flipped
-*
-*  RETURNS:
-*     None
-****************************************************************************/
-static void nand_bcm_umi_bch_ecc_flip_bit(uint8_t *datap, int errorLocation)
-{
-	int locWithinAByte = (errorLocation & REG_UMI_BCH_ERR_LOC_BYTE) >> 0;
-	int locWithinAWord = (errorLocation & REG_UMI_BCH_ERR_LOC_WORD) >> 3;
-	int locWithinAPage = (errorLocation & REG_UMI_BCH_ERR_LOC_PAGE) >> 5;
-
-	uint8_t errorByte = 0;
-	uint8_t byteMask = 1 << locWithinAByte;
-
-	/* BCH uses big endian, need to change the location
-	 * bits to little endian */
-	locWithinAWord = 3 - locWithinAWord;
-
-	errorByte = datap[locWithinAPage * sizeof(uint32_t) + locWithinAWord];
-
-#ifdef BOOT0_BUILD
-	puthexs("\nECC Correct Offset: ",
-		locWithinAPage * sizeof(uint32_t) + locWithinAWord);
-	puthexs(" errorByte:", errorByte);
-	puthex8(" Bit: ", locWithinAByte);
-#endif
-
-	if (errorByte & byteMask) {
-		/* bit needs to be cleared */
-		errorByte &= ~byteMask;
-	} else {
-		/* bit needs to be set */
-		errorByte |= byteMask;
-	}
-
-	/* write back the value with the fixed bit */
-	datap[locWithinAPage * sizeof(uint32_t) + locWithinAWord] = errorByte;
-}
-
-/****************************************************************************
-*  nand_correct_page_bch - Routine to correct bit errors when reading NAND
-*
-*  PURPOSE:
-*     This routine reads the BCH registers to determine if there are any bit
-*     errors during the read of the last 512 bytes of data + ECC bytes.  If
-*     errors exists, the routine fixes it.
-*
-*  PARAMETERS:
-*     datap - Container that holds the 512 byte data
-*
-*  RETURNS:
-*     0 or greater = Number of errors corrected
-*                    (No errors are found or errors have been fixed)
-*    -1 = Error(s) cannot be fixed
-****************************************************************************/
-int nand_bcm_umi_bch_correct_page(uint8_t *datap, uint8_t *readEccData,
-				  int numEccBytes)
-{
-	int numErrors;
-	int errorLocation;
-	int idx;
-	uint32_t regValue;
-
-	/* wait for read ECC to be valid */
-	regValue = nand_bcm_umi_bch_poll_read_ecc_calc();
-
-	/*
-	 * read the control status register to determine if there
-	 * are error'ed bits
-	 * see if errors are correctible
-	 */
-	if ((regValue & REG_UMI_BCH_CTRL_STATUS_UNCORR_ERR) > 0) {
-		int i;
-
-		for (i = 0; i < numEccBytes; i++) {
-			if (readEccData[i] != 0xff) {
-				/* errors cannot be fixed, return -1 */
-				return -1;
-			}
-		}
-		/* If ECC is unprogrammed then we can't correct,
-		 * assume everything OK */
-		return 0;
-	}
-
-	if ((regValue & REG_UMI_BCH_CTRL_STATUS_CORR_ERR) == 0) {
-		/* no errors */
-		return 0;
-	}
-
-	/*
-	 * Fix errored bits by doing the following:
-	 * 1. Read the number of errors in the control and status register
-	 * 2. Read the error location registers that corresponds to the number
-	 *    of errors reported
-	 * 3. Invert the bit in the data
-	 */
-	numErrors = (regValue & REG_UMI_BCH_CTRL_STATUS_NB_CORR_ERROR) >> 20;
-
-	for (idx = 0; idx < numErrors; idx++) {
-		errorLocation =
-		    REG_UMI_BCH_ERR_LOC_ADDR(idx) & REG_UMI_BCH_ERR_LOC_MASK;
-
-		/* Flip bit */
-		nand_bcm_umi_bch_ecc_flip_bit(datap, errorLocation);
-	}
-	/* Errors corrected */
-	return numErrors;
-}
-#endif
diff --git a/drivers/mtd/nand/nand_bcm_umi.h b/drivers/mtd/nand/nand_bcm_umi.h
deleted file mode 100644
index d901866..0000000
--- a/drivers/mtd/nand/nand_bcm_umi.h
+++ /dev/null
@@ -1,336 +0,0 @@
-/*****************************************************************************
-* Copyright 2003 - 2009 Broadcom Corporation.  All rights reserved.
-*
-* Unless you and Broadcom execute a separate written software license
-* agreement governing use of this software, this software is licensed to you
-* under the terms of the GNU General Public License version 2, available at
-* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
-*
-* Notwithstanding the above, under no circumstances may you combine this
-* software in any way with any other Broadcom software provided under a
-* license other than the GPL, without Broadcom's express prior written
-* consent.
-*****************************************************************************/
-#ifndef NAND_BCM_UMI_H
-#define NAND_BCM_UMI_H
-
-/* ---- Include Files ---------------------------------------------------- */
-#include <mach/reg_umi.h>
-#include <mach/reg_nand.h>
-#include <mach/cfg_global.h>
-
-/* ---- Constants and Types ---------------------------------------------- */
-#if (CFG_GLOBAL_CHIP_FAMILY == CFG_GLOBAL_CHIP_FAMILY_BCMRING)
-#define NAND_ECC_BCH (CFG_GLOBAL_CHIP_REV > 0xA0)
-#else
-#define NAND_ECC_BCH 0
-#endif
-
-#define CFG_GLOBAL_NAND_ECC_BCH_NUM_BYTES	13
-
-#if NAND_ECC_BCH
-#ifdef BOOT0_BUILD
-#define NAND_ECC_NUM_BYTES 13
-#else
-#define NAND_ECC_NUM_BYTES CFG_GLOBAL_NAND_ECC_BCH_NUM_BYTES
-#endif
-#else
-#define NAND_ECC_NUM_BYTES 3
-#endif
-
-#define NAND_DATA_ACCESS_SIZE 512
-
-/* ---- Variable Externs ------------------------------------------ */
-/* ---- Function Prototypes --------------------------------------- */
-int nand_bcm_umi_bch_correct_page(uint8_t *datap, uint8_t *readEccData,
-				  int numEccBytes);
-
-/* Check in device is ready */
-static inline int nand_bcm_umi_dev_ready(void)
-{
-	return readl(&REG_UMI_NAND_RCSR) & REG_UMI_NAND_RCSR_RDY;
-}
-
-/* Wait until device is ready */
-static inline void nand_bcm_umi_wait_till_ready(void)
-{
-	while (nand_bcm_umi_dev_ready() == 0)
-		;
-}
-
-/* Enable Hamming ECC */
-static inline void nand_bcm_umi_hamming_enable_hwecc(void)
-{
-	/* disable and reset ECC, 512 byte page */
-	writel(readl(&REG_UMI_NAND_ECC_CSR) & ~(REG_UMI_NAND_ECC_CSR_ECC_ENABLE |
-		REG_UMI_NAND_ECC_CSR_256BYTE), &REG_UMI_NAND_ECC_CSR);
-	/* enable ECC */
-	writel(readl(&REG_UMI_NAND_ECC_CSR) | REG_UMI_NAND_ECC_CSR_ECC_ENABLE,
-		&REG_UMI_NAND_ECC_CSR);
-}
-
-#if NAND_ECC_BCH
-/* BCH ECC specifics */
-#define ECC_BITS_PER_CORRECTABLE_BIT 13
-
-/* Enable BCH Read ECC */
-static inline void nand_bcm_umi_bch_enable_read_hwecc(void)
-{
-	/* disable and reset ECC */
-	writel(REG_UMI_BCH_CTRL_STATUS_RD_ECC_VALID, &REG_UMI_BCH_CTRL_STATUS);
-	/* Turn on ECC */
-	writel(REG_UMI_BCH_CTRL_STATUS_ECC_RD_EN, &REG_UMI_BCH_CTRL_STATUS);
-}
-
-/* Enable BCH Write ECC */
-static inline void nand_bcm_umi_bch_enable_write_hwecc(void)
-{
-	/* disable and reset ECC */
-	writel(REG_UMI_BCH_CTRL_STATUS_WR_ECC_VALID, &REG_UMI_BCH_CTRL_STATUS);
-	/* Turn on ECC */
-	writel(REG_UMI_BCH_CTRL_STATUS_ECC_WR_EN, &REG_UMI_BCH_CTRL_STATUS);
-}
-
-/* Config number of BCH ECC bytes */
-static inline void nand_bcm_umi_bch_config_ecc(uint8_t numEccBytes)
-{
-	uint32_t nValue;
-	uint32_t tValue;
-	uint32_t kValue;
-	uint32_t numBits = numEccBytes * 8;
-
-	/* disable and reset ECC */
-	writel(REG_UMI_BCH_CTRL_STATUS_WR_ECC_VALID |
-	       REG_UMI_BCH_CTRL_STATUS_RD_ECC_VALID,
-	       &REG_UMI_BCH_CTRL_STATUS);
-
-	/* Every correctible bit requires 13 ECC bits */
-	tValue = (uint32_t) (numBits / ECC_BITS_PER_CORRECTABLE_BIT);
-
-	/* Total data in number of bits for generating and computing BCH ECC */
-	nValue = (NAND_DATA_ACCESS_SIZE + numEccBytes) * 8;
-
-	/* K parameter is used internally.  K = N - (T * 13) */
-	kValue = nValue - (tValue * ECC_BITS_PER_CORRECTABLE_BIT);
-
-	/* Write the settings */
-	writel(nValue, &REG_UMI_BCH_N);
-	writel(tValue, &REG_UMI_BCH_T);
-	writel(kValue, &REG_UMI_BCH_K);
-}
-
-/* Pause during ECC read calculation to skip bytes in OOB */
-static inline void nand_bcm_umi_bch_pause_read_ecc_calc(void)
-{
-	writel(REG_UMI_BCH_CTRL_STATUS_ECC_RD_EN | REG_UMI_BCH_CTRL_STATUS_PAUSE_ECC_DEC, &REG_UMI_BCH_CTRL_STATUS);
-}
-
-/* Resume during ECC read calculation after skipping bytes in OOB */
-static inline void nand_bcm_umi_bch_resume_read_ecc_calc(void)
-{
-	writel(REG_UMI_BCH_CTRL_STATUS_ECC_RD_EN, &REG_UMI_BCH_CTRL_STATUS);
-}
-
-/* Poll read ECC calc to check when hardware completes */
-static inline uint32_t nand_bcm_umi_bch_poll_read_ecc_calc(void)
-{
-	uint32_t regVal;
-
-	do {
-		/* wait for ECC to be valid */
-		regVal = readl(&REG_UMI_BCH_CTRL_STATUS);
-	} while ((regVal & REG_UMI_BCH_CTRL_STATUS_RD_ECC_VALID) == 0);
-
-	return regVal;
-}
-
-/* Poll write ECC calc to check when hardware completes */
-static inline void nand_bcm_umi_bch_poll_write_ecc_calc(void)
-{
-	/* wait for ECC to be valid */
-	while ((readl(&REG_UMI_BCH_CTRL_STATUS) & REG_UMI_BCH_CTRL_STATUS_WR_ECC_VALID)
-	       == 0)
-		;
-}
-
-/* Read the OOB and ECC, for kernel write OOB to a buffer */
-#if defined(__KERNEL__) && !defined(STANDALONE)
-static inline void nand_bcm_umi_bch_read_oobEcc(uint32_t pageSize,
-	uint8_t *eccCalc, int numEccBytes, uint8_t *oobp)
-#else
-static inline void nand_bcm_umi_bch_read_oobEcc(uint32_t pageSize,
-	uint8_t *eccCalc, int numEccBytes)
-#endif
-{
-	int eccPos = 0;
-	int numToRead = 16;	/* There are 16 bytes per sector in the OOB */
-
-	/* ECC is already paused when this function is called */
-	if (pageSize != NAND_DATA_ACCESS_SIZE) {
-		/* skip BI */
-#if defined(__KERNEL__) && !defined(STANDALONE)
-		*oobp++ = readb(&REG_NAND_DATA8);
-#else
-		readb(&REG_NAND_DATA8);
-#endif
-		numToRead--;
-	}
-
-	while (numToRead > numEccBytes) {
-		/* skip free oob region */
-#if defined(__KERNEL__) && !defined(STANDALONE)
-		*oobp++ = readb(&REG_NAND_DATA8);
-#else
-		readb(&REG_NAND_DATA8);
-#endif
-		numToRead--;
-	}
-
-	if (pageSize == NAND_DATA_ACCESS_SIZE) {
-		/* read ECC bytes before BI */
-		nand_bcm_umi_bch_resume_read_ecc_calc();
-
-		while (numToRead > 11) {
-#if defined(__KERNEL__) && !defined(STANDALONE)
-			*oobp = readb(&REG_NAND_DATA8);
-			eccCalc[eccPos++] = *oobp;
-			oobp++;
-#else
-			eccCalc[eccPos++] = readb(&REG_NAND_DATA8);
-#endif
-			numToRead--;
-		}
-
-		nand_bcm_umi_bch_pause_read_ecc_calc();
-
-		if (numToRead == 11) {
-			/* read BI */
-#if defined(__KERNEL__) && !defined(STANDALONE)
-			*oobp++ = readb(&REG_NAND_DATA8);
-#else
-			readb(&REG_NAND_DATA8);
-#endif
-			numToRead--;
-		}
-
-	}
-	/* read ECC bytes */
-	nand_bcm_umi_bch_resume_read_ecc_calc();
-	while (numToRead) {
-#if defined(__KERNEL__) && !defined(STANDALONE)
-		*oobp = readb(&REG_NAND_DATA8);
-		eccCalc[eccPos++] = *oobp;
-		oobp++;
-#else
-		eccCalc[eccPos++] = readb(&REG_NAND_DATA8);
-#endif
-		numToRead--;
-	}
-}
-
-/* Helper function to write ECC */
-static inline void NAND_BCM_UMI_ECC_WRITE(int numEccBytes, int eccBytePos,
-					  uint8_t *oobp, uint8_t eccVal)
-{
-	if (eccBytePos <= numEccBytes)
-		*oobp = eccVal;
-}
-
-/* Write OOB with ECC */
-static inline void nand_bcm_umi_bch_write_oobEcc(uint32_t pageSize,
-						 uint8_t *oobp, int numEccBytes)
-{
-	uint32_t eccVal = 0xffffffff;
-
-	/* wait for write ECC to be valid */
-	nand_bcm_umi_bch_poll_write_ecc_calc();
-
-	/*
-	 ** Get the hardware ecc from the 32-bit result registers.
-	 ** Read after 512 byte accesses. Format B3B2B1B0
-	 ** where B3 = ecc3, etc.
-	 */
-
-	if (pageSize == NAND_DATA_ACCESS_SIZE) {
-		/* Now fill in the ECC bytes */
-		if (numEccBytes >= 13)
-			eccVal = readl(&REG_UMI_BCH_WR_ECC_3);
-
-		/* Usually we skip CM in oob[0,1] */
-		NAND_BCM_UMI_ECC_WRITE(numEccBytes, 15, &oobp[0],
-			(eccVal >> 16) & 0xff);
-		NAND_BCM_UMI_ECC_WRITE(numEccBytes, 14, &oobp[1],
-			(eccVal >> 8) & 0xff);
-
-		/* Write ECC in oob[2,3,4] */
-		NAND_BCM_UMI_ECC_WRITE(numEccBytes, 13, &oobp[2],
-			eccVal & 0xff);	/* ECC 12 */
-
-		if (numEccBytes >= 9)
-			eccVal = readl(&REG_UMI_BCH_WR_ECC_2);
-
-		NAND_BCM_UMI_ECC_WRITE(numEccBytes, 12, &oobp[3],
-			(eccVal >> 24) & 0xff);	/* ECC11 */
-		NAND_BCM_UMI_ECC_WRITE(numEccBytes, 11, &oobp[4],
-			(eccVal >> 16) & 0xff);	/* ECC10 */
-
-		/* Always Skip BI in oob[5] */
-	} else {
-		/* Always Skip BI in oob[0] */
-
-		/* Now fill in the ECC bytes */
-		if (numEccBytes >= 13)
-			eccVal = readl(&REG_UMI_BCH_WR_ECC_3);
-
-		/* Usually skip CM in oob[1,2] */
-		NAND_BCM_UMI_ECC_WRITE(numEccBytes, 15, &oobp[1],
-			(eccVal >> 16) & 0xff);
-		NAND_BCM_UMI_ECC_WRITE(numEccBytes, 14, &oobp[2],
-			(eccVal >> 8) & 0xff);
-
-		/* Write ECC in oob[3-15] */
-		NAND_BCM_UMI_ECC_WRITE(numEccBytes, 13, &oobp[3],
-			eccVal & 0xff);	/* ECC12 */
-
-		if (numEccBytes >= 9)
-			eccVal = readl(&REG_UMI_BCH_WR_ECC_2);
-
-		NAND_BCM_UMI_ECC_WRITE(numEccBytes, 12, &oobp[4],
-			(eccVal >> 24) & 0xff);	/* ECC11 */
-		NAND_BCM_UMI_ECC_WRITE(numEccBytes, 11, &oobp[5],
-			(eccVal >> 16) & 0xff);	/* ECC10 */
-	}
-
-	/* Fill in the remainder of ECC locations */
-	NAND_BCM_UMI_ECC_WRITE(numEccBytes, 10, &oobp[6],
-		(eccVal >> 8) & 0xff);	/* ECC9 */
-	NAND_BCM_UMI_ECC_WRITE(numEccBytes, 9, &oobp[7],
-		eccVal & 0xff);	/* ECC8 */
-
-	if (numEccBytes >= 5)
-		eccVal = readl(&REG_UMI_BCH_WR_ECC_1);
-
-	NAND_BCM_UMI_ECC_WRITE(numEccBytes, 8, &oobp[8],
-		(eccVal >> 24) & 0xff);	/* ECC7 */
-	NAND_BCM_UMI_ECC_WRITE(numEccBytes, 7, &oobp[9],
-		(eccVal >> 16) & 0xff);	/* ECC6 */
-	NAND_BCM_UMI_ECC_WRITE(numEccBytes, 6, &oobp[10],
-		(eccVal >> 8) & 0xff);	/* ECC5 */
-	NAND_BCM_UMI_ECC_WRITE(numEccBytes, 5, &oobp[11],
-		eccVal & 0xff);	/* ECC4 */
-
-	if (numEccBytes >= 1)
-		eccVal = readl(&REG_UMI_BCH_WR_ECC_0);
-
-	NAND_BCM_UMI_ECC_WRITE(numEccBytes, 4, &oobp[12],
-		(eccVal >> 24) & 0xff);	/* ECC3 */
-	NAND_BCM_UMI_ECC_WRITE(numEccBytes, 3, &oobp[13],
-		(eccVal >> 16) & 0xff);	/* ECC2 */
-	NAND_BCM_UMI_ECC_WRITE(numEccBytes, 2, &oobp[14],
-		(eccVal >> 8) & 0xff);	/* ECC1 */
-	NAND_BCM_UMI_ECC_WRITE(numEccBytes, 1, &oobp[15],
-		eccVal & 0xff);	/* ECC0 */
-}
-#endif
-
-#endif /* NAND_BCM_UMI_H */
diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c
index 621b70b..e3aa274 100644
--- a/drivers/mtd/nand/nand_ids.c
+++ b/drivers/mtd/nand/nand_ids.c
@@ -70,7 +70,7 @@
 	 * These are the new chips with large page size. The pagesize and the
 	 * erasesize is determined from the extended id bytes
 	 */
-#define LP_OPTIONS (NAND_SAMSUNG_LP_OPTIONS | NAND_NO_READRDY)
+#define LP_OPTIONS NAND_SAMSUNG_LP_OPTIONS
 #define LP_OPTIONS16 (LP_OPTIONS | NAND_BUSWIDTH_16)
 
 	/* 512 Megabit */
@@ -157,7 +157,7 @@
 	 * writes possible, but not implemented now
 	 */
 	{"AND 128MiB 3,3V 8-bit",	0x01, 2048, 128, 0x4000,
-	 NAND_IS_AND | NAND_NO_READRDY | NAND_4PAGE_ARRAY | BBT_AUTO_REFRESH},
+	 NAND_IS_AND | NAND_4PAGE_ARRAY | BBT_AUTO_REFRESH},
 
 	{NULL,}
 };
@@ -174,8 +174,9 @@
 	{NAND_MFR_STMICRO, "ST Micro"},
 	{NAND_MFR_HYNIX, "Hynix"},
 	{NAND_MFR_MICRON, "Micron"},
-	{NAND_MFR_AMD, "AMD"},
+	{NAND_MFR_AMD, "AMD/Spansion"},
 	{NAND_MFR_MACRONIX, "Macronix"},
+	{NAND_MFR_EON, "Eon"},
 	{0x0, "Unknown"}
 };
 
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index cf0cd31..a932c48 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -447,8 +447,6 @@
 /* MTD structure for NAND controller */
 static struct mtd_info *nsmtd;
 
-static u_char ns_verify_buf[NS_LARGEST_PAGE_SIZE];
-
 /*
  * Allocate array of page pointers, create slab allocation for an array
  * and initialize the array by NULL pointers.
@@ -2189,19 +2187,6 @@
 	return;
 }
 
-static int ns_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
-{
-	ns_nand_read_buf(mtd, (u_char *)&ns_verify_buf[0], len);
-
-	if (!memcmp(buf, &ns_verify_buf[0], len)) {
-		NS_DBG("verify_buf: the buffer is OK\n");
-		return 0;
-	} else {
-		NS_DBG("verify_buf: the buffer is wrong\n");
-		return -EFAULT;
-	}
-}
-
 /*
  * Module initialization function
  */
@@ -2236,7 +2221,6 @@
 	chip->dev_ready  = ns_device_ready;
 	chip->write_buf  = ns_nand_write_buf;
 	chip->read_buf   = ns_nand_read_buf;
-	chip->verify_buf = ns_nand_verify_buf;
 	chip->read_word  = ns_nand_read_word;
 	chip->ecc.mode   = NAND_ECC_SOFT;
 	/* The NAND_SKIP_BBTSCAN option is necessary for 'overridesize' */
@@ -2333,6 +2317,7 @@
 		uint64_t new_size = (uint64_t)nsmtd->erasesize << overridesize;
 		if (new_size >> overridesize != nsmtd->erasesize) {
 			NS_ERR("overridesize is too big\n");
+			retval = -EINVAL;
 			goto err_exit;
 		}
 		/* N.B. This relies on nand_scan not doing anything with the size before we change it */
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
index 2b6f632..5fd3f01 100644
--- a/drivers/mtd/nand/ndfc.c
+++ b/drivers/mtd/nand/ndfc.c
@@ -140,18 +140,6 @@
 		out_be32(ndfc->ndfcbase + NDFC_DATA, *p++);
 }
 
-static int ndfc_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
-{
-	struct nand_chip *chip = mtd->priv;
-	struct ndfc_controller *ndfc = chip->priv;
-	uint32_t *p = (uint32_t *) buf;
-
-	for(;len > 0; len -= 4)
-		if (*p++ != in_be32(ndfc->ndfcbase + NDFC_DATA))
-			return -EFAULT;
-	return 0;
-}
-
 /*
  * Initialize chip structure
  */
@@ -172,7 +160,6 @@
 	chip->controller = &ndfc->ndfc_control;
 	chip->read_buf = ndfc_read_buf;
 	chip->write_buf = ndfc_write_buf;
-	chip->verify_buf = ndfc_verify_buf;
 	chip->ecc.correct = nand_correct_data;
 	chip->ecc.hwctl = ndfc_enable_hwecc;
 	chip->ecc.calculate = ndfc_calculate_ecc;
diff --git a/drivers/mtd/nand/nuc900_nand.c b/drivers/mtd/nand/nuc900_nand.c
index 8febe46..94dc46b 100644
--- a/drivers/mtd/nand/nuc900_nand.c
+++ b/drivers/mtd/nand/nuc900_nand.c
@@ -112,22 +112,6 @@
 		write_data_reg(nand, buf[i]);
 }
 
-static int nuc900_verify_buf(struct mtd_info *mtd,
-			     const unsigned char *buf, int len)
-{
-	int i;
-	struct nuc900_nand *nand;
-
-	nand = container_of(mtd, struct nuc900_nand, mtd);
-
-	for (i = 0; i < len; i++) {
-		if (buf[i] != (unsigned char)read_data_reg(nand))
-			return -EFAULT;
-	}
-
-	return 0;
-}
-
 static int nuc900_check_rb(struct nuc900_nand *nand)
 {
 	unsigned int val;
@@ -292,7 +276,6 @@
 	chip->read_byte		= nuc900_nand_read_byte;
 	chip->write_buf		= nuc900_nand_write_buf;
 	chip->read_buf		= nuc900_nand_read_buf;
-	chip->verify_buf	= nuc900_verify_buf;
 	chip->chip_delay	= 50;
 	chip->options		= 0;
 	chip->ecc.mode		= NAND_ECC_SOFT;
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index fc81112..5b31386 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -425,7 +425,7 @@
 }
 
 /*
- * omap_nand_dma_transfer: configer and start dma transfer
+ * omap_nand_dma_transfer: configure and start dma transfer
  * @mtd: MTD device structure
  * @addr: virtual address in RAM of source/destination
  * @len: number of data bytes to be transferred
@@ -546,7 +546,7 @@
 }
 
 /*
- * omap_nand_irq - GMPC irq handler
+ * omap_nand_irq - GPMC irq handler
  * @this_irq: gpmc irq number
  * @dev: omap_nand_info structure pointer is passed here
  */
@@ -698,27 +698,6 @@
 }
 
 /**
- * omap_verify_buf - Verify chip data against buffer
- * @mtd: MTD device structure
- * @buf: buffer containing the data to compare
- * @len: number of bytes to compare
- */
-static int omap_verify_buf(struct mtd_info *mtd, const u_char * buf, int len)
-{
-	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-							mtd);
-	u16 *p = (u16 *) buf;
-
-	len >>= 1;
-	while (len--) {
-		if (*p++ != cpu_to_le16(readw(info->nand.IO_ADDR_R)))
-			return -EFAULT;
-	}
-
-	return 0;
-}
-
-/**
  * gen_true_ecc - This function will generate true ECC value
  * @ecc_buf: buffer to store ecc code
  *
@@ -1326,8 +1305,8 @@
 
 	/*
 	 * If RDY/BSY line is connected to OMAP then use the omap ready
-	 * funcrtion and the generic nand_wait function which reads the status
-	 * register after monitoring the RDY/BSY line.Otherwise use a standard
+	 * function and the generic nand_wait function which reads the status
+	 * register after monitoring the RDY/BSY line. Otherwise use a standard
 	 * chip delay which is slightly more than tR (AC Timing) of the NAND
 	 * device and read status register until you get a failure or success
 	 */
@@ -1428,9 +1407,7 @@
 		goto out_release_mem_region;
 	}
 
-	info->nand.verify_buf = omap_verify_buf;
-
-	/* selsect the ecc type */
+	/* select the ecc type */
 	if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DEFAULT)
 		info->nand.ecc.mode = NAND_ECC_SOFT;
 	else if ((pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) ||
@@ -1536,7 +1513,8 @@
 	/* Release NAND device, its internal structures and partitions */
 	nand_release(&info->mtd);
 	iounmap(info->nand.IO_ADDR_R);
-	kfree(&info->mtd);
+	release_mem_region(info->phys_base, NAND_IO_SIZE);
+	kfree(info);
 	return 0;
 }
 
diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c
index 131b58a..aefaf8c 100644
--- a/drivers/mtd/nand/orion_nand.c
+++ b/drivers/mtd/nand/orion_nand.c
@@ -21,7 +21,6 @@
 #include <linux/err.h>
 #include <asm/io.h>
 #include <asm/sizes.h>
-#include <mach/hardware.h>
 #include <linux/platform_data/mtd-orion_nand.h>
 
 static void orion_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/plat_nand.c
index 1bcb520..a47ee68 100644
--- a/drivers/mtd/nand/plat_nand.c
+++ b/drivers/mtd/nand/plat_nand.c
@@ -37,6 +37,11 @@
 	const char **part_types;
 	int err = 0;
 
+	if (!pdata) {
+		dev_err(&pdev->dev, "platform_nand_data is missing\n");
+		return -EINVAL;
+	}
+
 	if (pdata->chip.nr_chips < 1) {
 		dev_err(&pdev->dev, "invalid number of chips specified\n");
 		return -EINVAL;
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index c452271..37ee75c 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -683,11 +683,13 @@
 	info->state = STATE_IDLE;
 }
 
-static void pxa3xx_nand_write_page_hwecc(struct mtd_info *mtd,
+static int pxa3xx_nand_write_page_hwecc(struct mtd_info *mtd,
 		struct nand_chip *chip, const uint8_t *buf, int oob_required)
 {
 	chip->write_buf(mtd, buf, mtd->writesize);
 	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+	return 0;
 }
 
 static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd,
@@ -771,12 +773,6 @@
 	info->buf_start += real_len;
 }
 
-static int pxa3xx_nand_verify_buf(struct mtd_info *mtd,
-		const uint8_t *buf, int len)
-{
-	return 0;
-}
-
 static void pxa3xx_nand_select_chip(struct mtd_info *mtd, int chip)
 {
 	return;
@@ -1007,7 +1003,6 @@
 	chip->ecc.size = host->page_size;
 	chip->ecc.strength = 1;
 
-	chip->options |= NAND_NO_READRDY;
 	if (host->reg_ndcr & NDCR_DWIDTH_M)
 		chip->options |= NAND_BUSWIDTH_16;
 
@@ -1070,7 +1065,6 @@
 		chip->read_byte		= pxa3xx_nand_read_byte;
 		chip->read_buf		= pxa3xx_nand_read_buf;
 		chip->write_buf		= pxa3xx_nand_write_buf;
-		chip->verify_buf	= pxa3xx_nand_verify_buf;
 	}
 
 	spin_lock_init(&chip->controller->lock);
diff --git a/drivers/mtd/nand/r852.c b/drivers/mtd/nand/r852.c
index 8cb6277..4495f85 100644
--- a/drivers/mtd/nand/r852.c
+++ b/drivers/mtd/nand/r852.c
@@ -309,27 +309,6 @@
 	return r852_read_reg(dev, R852_DATALINE);
 }
 
-
-/*
- * Readback the buffer to verify it
- */
-int r852_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
-{
-	struct r852_device *dev = r852_get_dev(mtd);
-
-	/* We can't be sure about anything here... */
-	if (dev->card_unstable)
-		return -1;
-
-	/* This will never happen, unless you wired up a nand chip
-		with > 512 bytes page size to the reader */
-	if (len > SM_SECTOR_SIZE)
-		return 0;
-
-	r852_read_buf(mtd, dev->tmp_buffer, len);
-	return memcmp(buf, dev->tmp_buffer, len);
-}
-
 /*
  * Control several chip lines & send commands
  */
@@ -882,7 +861,6 @@
 	chip->read_byte = r852_read_byte;
 	chip->read_buf = r852_read_buf;
 	chip->write_buf = r852_write_buf;
-	chip->verify_buf = r852_verify_buf;
 
 	/* ecc */
 	chip->ecc.mode = NAND_ECC_HW_SYNDROME;
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c
index d804061..295e4be 100644
--- a/drivers/mtd/nand/s3c2410.c
+++ b/drivers/mtd/nand/s3c2410.c
@@ -21,6 +21,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
+#define pr_fmt(fmt) "nand-s3c2410: " fmt
+
 #ifdef CONFIG_MTD_NAND_S3C2410_DEBUG
 #define DEBUG
 #endif
@@ -30,6 +32,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
+#include <linux/io.h>
 #include <linux/ioport.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
@@ -43,24 +46,9 @@
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/partitions.h>
 
-#include <asm/io.h>
-
 #include <plat/regs-nand.h>
 #include <linux/platform_data/mtd-nand-s3c2410.h>
 
-#ifdef CONFIG_MTD_NAND_S3C2410_HWECC
-static int hardware_ecc = 1;
-#else
-static int hardware_ecc = 0;
-#endif
-
-#ifdef CONFIG_MTD_NAND_S3C2410_CLKSTOP
-static const int clock_stop = 1;
-#else
-static const int clock_stop = 0;
-#endif
-
-
 /* new oob placement block for use with hardware ecc generation
  */
 
@@ -109,9 +97,8 @@
  * @mtds: An array of MTD instances on this controoler.
  * @platform: The platform data for this board.
  * @device: The platform device we bound to.
- * @area: The IO area resource that came from request_mem_region().
  * @clk: The clock resource for this controller.
- * @regs: The area mapped for the hardware registers described by @area.
+ * @regs: The area mapped for the hardware registers.
  * @sel_reg: Pointer to the register controlling the NAND selection.
  * @sel_bit: The bit in @sel_reg to select the NAND chip.
  * @mtd_count: The number of MTDs created from this controller.
@@ -128,7 +115,6 @@
 
 	/* device info */
 	struct device			*device;
-	struct resource			*area;
 	struct clk			*clk;
 	void __iomem			*regs;
 	void __iomem			*sel_reg;
@@ -169,7 +155,11 @@
 
 static inline int allow_clk_suspend(struct s3c2410_nand_info *info)
 {
-	return clock_stop;
+#ifdef CONFIG_MTD_NAND_S3C2410_CLKSTOP
+	return 1;
+#else
+	return 0;
+#endif
 }
 
 /**
@@ -215,7 +205,8 @@
 	pr_debug("result %d from %ld, %d\n", result, clk, wanted);
 
 	if (result > max) {
-		printk("%d ns is too big for current clock rate %ld\n", wanted, clk);
+		pr_err("%d ns is too big for current clock rate %ld\n",
+			wanted, clk);
 		return -1;
 	}
 
@@ -225,7 +216,7 @@
 	return result;
 }
 
-#define to_ns(ticks,clk) (((ticks) * NS_IN_KHZ) / (unsigned int)(clk))
+#define to_ns(ticks, clk) (((ticks) * NS_IN_KHZ) / (unsigned int)(clk))
 
 /* controller setup */
 
@@ -268,7 +259,8 @@
 	}
 
 	dev_info(info->device, "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n",
-	       tacls, to_ns(tacls, clkrate), twrph0, to_ns(twrph0, clkrate), twrph1, to_ns(twrph1, clkrate));
+		tacls, to_ns(tacls, clkrate), twrph0, to_ns(twrph0, clkrate),
+						twrph1, to_ns(twrph1, clkrate));
 
 	switch (info->cpu_type) {
 	case TYPE_S3C2410:
@@ -325,13 +317,13 @@
 	if (ret < 0)
 		return ret;
 
- 	switch (info->cpu_type) {
- 	case TYPE_S3C2410:
+	switch (info->cpu_type) {
+	case TYPE_S3C2410:
 	default:
 		break;
 
- 	case TYPE_S3C2440:
- 	case TYPE_S3C2412:
+	case TYPE_S3C2440:
+	case TYPE_S3C2412:
 		/* enable the controller and de-assert nFCE */
 
 		writel(S3C2440_NFCONT_ENABLE, info->regs + S3C2440_NFCONT);
@@ -450,6 +442,7 @@
 
 /* ECC handling functions */
 
+#ifdef CONFIG_MTD_NAND_S3C2410_HWECC
 static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat,
 				     u_char *read_ecc, u_char *calc_ecc)
 {
@@ -463,10 +456,8 @@
 	diff1 = read_ecc[1] ^ calc_ecc[1];
 	diff2 = read_ecc[2] ^ calc_ecc[2];
 
-	pr_debug("%s: rd %02x%02x%02x calc %02x%02x%02x diff %02x%02x%02x\n",
-		 __func__,
-		 read_ecc[0], read_ecc[1], read_ecc[2],
-		 calc_ecc[0], calc_ecc[1], calc_ecc[2],
+	pr_debug("%s: rd %*phN calc %*phN diff %02x%02x%02x\n",
+		 __func__, 3, read_ecc, 3, calc_ecc,
 		 diff0, diff1, diff2);
 
 	if (diff0 == 0 && diff1 == 0 && diff2 == 0)
@@ -546,7 +537,8 @@
 	unsigned long ctrl;
 
 	ctrl = readl(info->regs + S3C2440_NFCONT);
-	writel(ctrl | S3C2412_NFCONT_INIT_MAIN_ECC, info->regs + S3C2440_NFCONT);
+	writel(ctrl | S3C2412_NFCONT_INIT_MAIN_ECC,
+	       info->regs + S3C2440_NFCONT);
 }
 
 static void s3c2440_nand_enable_hwecc(struct mtd_info *mtd, int mode)
@@ -558,7 +550,8 @@
 	writel(ctrl | S3C2440_NFCONT_INITECC, info->regs + S3C2440_NFCONT);
 }
 
-static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
+static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
+				      u_char *ecc_code)
 {
 	struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
 
@@ -566,13 +559,13 @@
 	ecc_code[1] = readb(info->regs + S3C2410_NFECC + 1);
 	ecc_code[2] = readb(info->regs + S3C2410_NFECC + 2);
 
-	pr_debug("%s: returning ecc %02x%02x%02x\n", __func__,
-		 ecc_code[0], ecc_code[1], ecc_code[2]);
+	pr_debug("%s: returning ecc %*phN\n", __func__, 3, ecc_code);
 
 	return 0;
 }
 
-static int s3c2412_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
+static int s3c2412_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
+				      u_char *ecc_code)
 {
 	struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
 	unsigned long ecc = readl(info->regs + S3C2412_NFMECC0);
@@ -581,12 +574,13 @@
 	ecc_code[1] = ecc >> 8;
 	ecc_code[2] = ecc >> 16;
 
-	pr_debug("calculate_ecc: returning ecc %02x,%02x,%02x\n", ecc_code[0], ecc_code[1], ecc_code[2]);
+	pr_debug("%s: returning ecc %*phN\n", __func__, 3, ecc_code);
 
 	return 0;
 }
 
-static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
+static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
+				      u_char *ecc_code)
 {
 	struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
 	unsigned long ecc = readl(info->regs + S3C2440_NFMECC0);
@@ -599,6 +593,7 @@
 
 	return 0;
 }
+#endif
 
 /* over-ride the standard functions for a little more speed. We can
  * use read/write block to move the data buffers to/from the controller
@@ -625,13 +620,15 @@
 	}
 }
 
-static void s3c2410_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
+static void s3c2410_nand_write_buf(struct mtd_info *mtd, const u_char *buf,
+				   int len)
 {
 	struct nand_chip *this = mtd->priv;
 	writesb(this->IO_ADDR_W, buf, len);
 }
 
-static void s3c2440_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
+static void s3c2440_nand_write_buf(struct mtd_info *mtd, const u_char *buf,
+				   int len)
 {
 	struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
 
@@ -675,7 +672,8 @@
 					 CPUFREQ_TRANSITION_NOTIFIER);
 }
 
-static inline void s3c2410_nand_cpufreq_deregister(struct s3c2410_nand_info *info)
+static inline void
+s3c2410_nand_cpufreq_deregister(struct s3c2410_nand_info *info)
 {
 	cpufreq_unregister_notifier(&info->freq_transition,
 				    CPUFREQ_TRANSITION_NOTIFIER);
@@ -687,7 +685,8 @@
 	return 0;
 }
 
-static inline void s3c2410_nand_cpufreq_deregister(struct s3c2410_nand_info *info)
+static inline void
+s3c2410_nand_cpufreq_deregister(struct s3c2410_nand_info *info)
 {
 }
 #endif
@@ -717,29 +716,12 @@
 			pr_debug("releasing mtd %d (%p)\n", mtdno, ptr);
 			nand_release(&ptr->mtd);
 		}
-
-		kfree(info->mtds);
 	}
 
 	/* free the common resources */
 
-	if (!IS_ERR(info->clk)) {
+	if (!IS_ERR(info->clk))
 		s3c2410_nand_clk_set_state(info, CLOCK_DISABLE);
-		clk_put(info->clk);
-	}
-
-	if (info->regs != NULL) {
-		iounmap(info->regs);
-		info->regs = NULL;
-	}
-
-	if (info->area != NULL) {
-		release_resource(info->area);
-		kfree(info->area);
-		info->area = NULL;
-	}
-
-	kfree(info);
 
 	return 0;
 }
@@ -810,7 +792,7 @@
 			dev_info(info->device, "System booted from NAND\n");
 
 		break;
-  	}
+	}
 
 	chip->IO_ADDR_R = chip->IO_ADDR_W;
 
@@ -819,32 +801,31 @@
 	nmtd->mtd.owner    = THIS_MODULE;
 	nmtd->set	   = set;
 
-	if (hardware_ecc) {
+#ifdef CONFIG_MTD_NAND_S3C2410_HWECC
+	chip->ecc.calculate = s3c2410_nand_calculate_ecc;
+	chip->ecc.correct   = s3c2410_nand_correct_data;
+	chip->ecc.mode	    = NAND_ECC_HW;
+	chip->ecc.strength  = 1;
+
+	switch (info->cpu_type) {
+	case TYPE_S3C2410:
+		chip->ecc.hwctl	    = s3c2410_nand_enable_hwecc;
 		chip->ecc.calculate = s3c2410_nand_calculate_ecc;
-		chip->ecc.correct   = s3c2410_nand_correct_data;
-		chip->ecc.mode	    = NAND_ECC_HW;
-		chip->ecc.strength  = 1;
+		break;
 
-		switch (info->cpu_type) {
-		case TYPE_S3C2410:
-			chip->ecc.hwctl	    = s3c2410_nand_enable_hwecc;
-			chip->ecc.calculate = s3c2410_nand_calculate_ecc;
-			break;
+	case TYPE_S3C2412:
+		chip->ecc.hwctl     = s3c2412_nand_enable_hwecc;
+		chip->ecc.calculate = s3c2412_nand_calculate_ecc;
+		break;
 
-		case TYPE_S3C2412:
-  			chip->ecc.hwctl     = s3c2412_nand_enable_hwecc;
-  			chip->ecc.calculate = s3c2412_nand_calculate_ecc;
-			break;
-
-		case TYPE_S3C2440:
-  			chip->ecc.hwctl     = s3c2440_nand_enable_hwecc;
-  			chip->ecc.calculate = s3c2440_nand_calculate_ecc;
-			break;
-
-		}
-	} else {
-		chip->ecc.mode	    = NAND_ECC_SOFT;
+	case TYPE_S3C2440:
+		chip->ecc.hwctl     = s3c2440_nand_enable_hwecc;
+		chip->ecc.calculate = s3c2440_nand_calculate_ecc;
+		break;
 	}
+#else
+	chip->ecc.mode	    = NAND_ECC_SOFT;
+#endif
 
 	if (set->ecc_layout != NULL)
 		chip->ecc.layout = set->ecc_layout;
@@ -921,7 +902,7 @@
 static int s3c24xx_nand_probe(struct platform_device *pdev)
 {
 	struct s3c2410_platform_nand *plat = to_nand_plat(pdev);
-	enum s3c_cpu_type cpu_type; 
+	enum s3c_cpu_type cpu_type;
 	struct s3c2410_nand_info *info;
 	struct s3c2410_nand_mtd *nmtd;
 	struct s3c2410_nand_set *sets;
@@ -935,7 +916,7 @@
 
 	pr_debug("s3c2410_nand_probe(%p)\n", pdev);
 
-	info = kzalloc(sizeof(*info), GFP_KERNEL);
+	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
 	if (info == NULL) {
 		dev_err(&pdev->dev, "no memory for flash info\n");
 		err = -ENOMEM;
@@ -949,7 +930,7 @@
 
 	/* get the clock source and enable it */
 
-	info->clk = clk_get(&pdev->dev, "nand");
+	info->clk = devm_clk_get(&pdev->dev, "nand");
 	if (IS_ERR(info->clk)) {
 		dev_err(&pdev->dev, "failed to get clock\n");
 		err = -ENOENT;
@@ -961,22 +942,14 @@
 	/* allocate and map the resource */
 
 	/* currently we assume we have the one resource */
-	res  = pdev->resource;
+	res = pdev->resource;
 	size = resource_size(res);
 
-	info->area = request_mem_region(res->start, size, pdev->name);
+	info->device	= &pdev->dev;
+	info->platform	= plat;
+	info->cpu_type	= cpu_type;
 
-	if (info->area == NULL) {
-		dev_err(&pdev->dev, "cannot reserve register region\n");
-		err = -ENOENT;
-		goto exit_error;
-	}
-
-	info->device     = &pdev->dev;
-	info->platform   = plat;
-	info->regs       = ioremap(res->start, size);
-	info->cpu_type   = cpu_type;
-
+	info->regs	= devm_request_and_ioremap(&pdev->dev, res);
 	if (info->regs == NULL) {
 		dev_err(&pdev->dev, "cannot reserve register region\n");
 		err = -EIO;
@@ -999,7 +972,7 @@
 	/* allocate our information */
 
 	size = nr_sets * sizeof(*info->mtds);
-	info->mtds = kzalloc(size, GFP_KERNEL);
+	info->mtds = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
 	if (info->mtds == NULL) {
 		dev_err(&pdev->dev, "failed to allocate mtd storage\n");
 		err = -ENOMEM;
@@ -1011,7 +984,8 @@
 	nmtd = info->mtds;
 
 	for (setno = 0; setno < nr_sets; setno++, nmtd++) {
-		pr_debug("initialising set %d (%p, info %p)\n", setno, nmtd, info);
+		pr_debug("initialising set %d (%p, info %p)\n",
+			 setno, nmtd, info);
 
 		s3c2410_nand_init_chip(info, nmtd, sets);
 
@@ -1134,20 +1108,7 @@
 	},
 };
 
-static int __init s3c2410_nand_init(void)
-{
-	printk("S3C24XX NAND Driver, (c) 2004 Simtec Electronics\n");
-
-	return platform_driver_register(&s3c24xx_nand_driver);
-}
-
-static void __exit s3c2410_nand_exit(void)
-{
-	platform_driver_unregister(&s3c24xx_nand_driver);
-}
-
-module_init(s3c2410_nand_init);
-module_exit(s3c2410_nand_exit);
+module_platform_driver(s3c24xx_nand_driver);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index aa9b8a5..4fbfe96 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -24,10 +24,12 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
+#include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
+#include <linux/string.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
@@ -43,11 +45,17 @@
 };
 
 static struct nand_ecclayout flctl_4secc_oob_64 = {
-	.eccbytes = 10,
-	.eccpos = {48, 49, 50, 51, 52, 53, 54, 55, 56, 57},
+	.eccbytes = 4 * 10,
+	.eccpos = {
+		 6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+		22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+		38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+		54, 55, 56, 57, 58, 59, 60, 61, 62, 63 },
 	.oobfree = {
-		{.offset = 60,
-		. length = 4} },
+		{.offset =  2, .length = 4},
+		{.offset = 16, .length = 6},
+		{.offset = 32, .length = 6},
+		{.offset = 48, .length = 6} },
 };
 
 static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
@@ -61,15 +69,15 @@
 
 static struct nand_bbt_descr flctl_4secc_largepage = {
 	.options = NAND_BBT_SCAN2NDPAGE,
-	.offs = 58,
+	.offs = 0,
 	.len = 2,
 	.pattern = scan_ff_pattern,
 };
 
 static void empty_fifo(struct sh_flctl *flctl)
 {
-	writel(0x000c0000, FLINTDMACR(flctl));	/* FIFO Clear */
-	writel(0x00000000, FLINTDMACR(flctl));	/* Clear Error flags */
+	writel(flctl->flintdmacr_base | AC1CLR | AC0CLR, FLINTDMACR(flctl));
+	writel(flctl->flintdmacr_base, FLINTDMACR(flctl));
 }
 
 static void start_translation(struct sh_flctl *flctl)
@@ -158,27 +166,56 @@
 	timeout_error(flctl, __func__);
 }
 
-static int wait_recfifo_ready(struct sh_flctl *flctl, int sector_number)
+static enum flctl_ecc_res_t wait_recfifo_ready
+		(struct sh_flctl *flctl, int sector_number)
 {
 	uint32_t timeout = LOOP_TIMEOUT_MAX;
-	int checked[4];
 	void __iomem *ecc_reg[4];
 	int i;
+	int state = FL_SUCCESS;
 	uint32_t data, size;
 
-	memset(checked, 0, sizeof(checked));
-
+	/*
+	 * First this loops checks in FLDTCNTR if we are ready to read out the
+	 * oob data. This is the case if either all went fine without errors or
+	 * if the bottom part of the loop corrected the errors or marked them as
+	 * uncorrectable and the controller is given time to push the data into
+	 * the FIFO.
+	 */
 	while (timeout--) {
+		/* check if all is ok and we can read out the OOB */
 		size = readl(FLDTCNTR(flctl)) >> 24;
-		if (size & 0xFF)
-			return 0;	/* success */
+		if ((size & 0xFF) == 4)
+			return state;
 
-		if (readl(FL4ECCCR(flctl)) & _4ECCFA)
-			return 1;	/* can't correct */
-
-		udelay(1);
-		if (!(readl(FL4ECCCR(flctl)) & _4ECCEND))
+		/* check if a correction code has been calculated */
+		if (!(readl(FL4ECCCR(flctl)) & _4ECCEND)) {
+			/*
+			 * either we wait for the fifo to be filled or a
+			 * correction pattern is being generated
+			 */
+			udelay(1);
 			continue;
+		}
+
+		/* check for an uncorrectable error */
+		if (readl(FL4ECCCR(flctl)) & _4ECCFA) {
+			/* check if we face a non-empty page */
+			for (i = 0; i < 512; i++) {
+				if (flctl->done_buff[i] != 0xff) {
+					state = FL_ERROR; /* can't correct */
+					break;
+				}
+			}
+
+			if (state == FL_SUCCESS)
+				dev_dbg(&flctl->pdev->dev,
+				"reading empty sector %d, ecc error ignored\n",
+				sector_number);
+
+			writel(0, FL4ECCCR(flctl));
+			continue;
+		}
 
 		/* start error correction */
 		ecc_reg[0] = FL4ECCRESULT0(flctl);
@@ -187,28 +224,26 @@
 		ecc_reg[3] = FL4ECCRESULT3(flctl);
 
 		for (i = 0; i < 3; i++) {
+			uint8_t org;
+			int index;
+
 			data = readl(ecc_reg[i]);
-			if (data != INIT_FL4ECCRESULT_VAL && !checked[i]) {
-				uint8_t org;
-				int index;
 
-				if (flctl->page_size)
-					index = (512 * sector_number) +
-						(data >> 16);
-				else
-					index = data >> 16;
+			if (flctl->page_size)
+				index = (512 * sector_number) +
+					(data >> 16);
+			else
+				index = data >> 16;
 
-				org = flctl->done_buff[index];
-				flctl->done_buff[index] = org ^ (data & 0xFF);
-				checked[i] = 1;
-			}
+			org = flctl->done_buff[index];
+			flctl->done_buff[index] = org ^ (data & 0xFF);
 		}
-
+		state = FL_REPAIRABLE;
 		writel(0, FL4ECCCR(flctl));
 	}
 
 	timeout_error(flctl, __func__);
-	return 1;	/* timeout */
+	return FL_TIMEOUT;	/* timeout */
 }
 
 static void wait_wecfifo_ready(struct sh_flctl *flctl)
@@ -241,31 +276,33 @@
 {
 	int i, len_4align;
 	unsigned long *buf = (unsigned long *)&flctl->done_buff[offset];
-	void *fifo_addr = (void *)FLDTFIFO(flctl);
 
 	len_4align = (rlen + 3) / 4;
 
 	for (i = 0; i < len_4align; i++) {
 		wait_rfifo_ready(flctl);
-		buf[i] = readl(fifo_addr);
+		buf[i] = readl(FLDTFIFO(flctl));
 		buf[i] = be32_to_cpu(buf[i]);
 	}
 }
 
-static int read_ecfiforeg(struct sh_flctl *flctl, uint8_t *buff, int sector)
+static enum flctl_ecc_res_t read_ecfiforeg
+		(struct sh_flctl *flctl, uint8_t *buff, int sector)
 {
 	int i;
+	enum flctl_ecc_res_t res;
 	unsigned long *ecc_buf = (unsigned long *)buff;
-	void *fifo_addr = (void *)FLECFIFO(flctl);
 
-	for (i = 0; i < 4; i++) {
-		if (wait_recfifo_ready(flctl , sector))
-			return 1;
-		ecc_buf[i] = readl(fifo_addr);
-		ecc_buf[i] = be32_to_cpu(ecc_buf[i]);
+	res = wait_recfifo_ready(flctl , sector);
+
+	if (res != FL_ERROR) {
+		for (i = 0; i < 4; i++) {
+			ecc_buf[i] = readl(FLECFIFO(flctl));
+			ecc_buf[i] = be32_to_cpu(ecc_buf[i]);
+		}
 	}
 
-	return 0;
+	return res;
 }
 
 static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
@@ -281,6 +318,18 @@
 	}
 }
 
+static void write_ec_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
+{
+	int i, len_4align;
+	unsigned long *data = (unsigned long *)&flctl->done_buff[offset];
+
+	len_4align = (rlen + 3) / 4;
+	for (i = 0; i < len_4align; i++) {
+		wait_wecfifo_ready(flctl);
+		writel(cpu_to_be32(data[i]), FLECFIFO(flctl));
+	}
+}
+
 static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_val)
 {
 	struct sh_flctl *flctl = mtd_to_flctl(mtd);
@@ -346,73 +395,65 @@
 static int flctl_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 				uint8_t *buf, int oob_required, int page)
 {
-	int i, eccsize = chip->ecc.size;
-	int eccbytes = chip->ecc.bytes;
-	int eccsteps = chip->ecc.steps;
-	uint8_t *p = buf;
-	struct sh_flctl *flctl = mtd_to_flctl(mtd);
-
-	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
-		chip->read_buf(mtd, p, eccsize);
-
-	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
-		if (flctl->hwecc_cant_correct[i])
-			mtd->ecc_stats.failed++;
-		else
-			mtd->ecc_stats.corrected += 0; /* FIXME */
-	}
-
+	chip->read_buf(mtd, buf, mtd->writesize);
+	if (oob_required)
+		chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
 	return 0;
 }
 
-static void flctl_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+static int flctl_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
 				   const uint8_t *buf, int oob_required)
 {
-	int i, eccsize = chip->ecc.size;
-	int eccbytes = chip->ecc.bytes;
-	int eccsteps = chip->ecc.steps;
-	const uint8_t *p = buf;
-
-	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
-		chip->write_buf(mtd, p, eccsize);
+	chip->write_buf(mtd, buf, mtd->writesize);
+	chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
+	return 0;
 }
 
 static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr)
 {
 	struct sh_flctl *flctl = mtd_to_flctl(mtd);
 	int sector, page_sectors;
+	enum flctl_ecc_res_t ecc_result;
 
-	if (flctl->page_size)
-		page_sectors = 4;
-	else
-		page_sectors = 1;
-
-	writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE | _4ECCCORRECT,
-		 FLCMNCR(flctl));
+	page_sectors = flctl->page_size ? 4 : 1;
 
 	set_cmd_regs(mtd, NAND_CMD_READ0,
 		(NAND_CMD_READSTART << 8) | NAND_CMD_READ0);
 
+	writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE | _4ECCCORRECT,
+		 FLCMNCR(flctl));
+	writel(readl(FLCMDCR(flctl)) | page_sectors, FLCMDCR(flctl));
+	writel(page_addr << 2, FLADR(flctl));
+
+	empty_fifo(flctl);
+	start_translation(flctl);
+
 	for (sector = 0; sector < page_sectors; sector++) {
-		int ret;
-
-		empty_fifo(flctl);
-		writel(readl(FLCMDCR(flctl)) | 1, FLCMDCR(flctl));
-		writel(page_addr << 2 | sector, FLADR(flctl));
-
-		start_translation(flctl);
 		read_fiforeg(flctl, 512, 512 * sector);
 
-		ret = read_ecfiforeg(flctl,
+		ecc_result = read_ecfiforeg(flctl,
 			&flctl->done_buff[mtd->writesize + 16 * sector],
 			sector);
 
-		if (ret)
-			flctl->hwecc_cant_correct[sector] = 1;
-
-		writel(0x0, FL4ECCCR(flctl));
-		wait_completion(flctl);
+		switch (ecc_result) {
+		case FL_REPAIRABLE:
+			dev_info(&flctl->pdev->dev,
+				"applied ecc on page 0x%x", page_addr);
+			flctl->mtd.ecc_stats.corrected++;
+			break;
+		case FL_ERROR:
+			dev_warn(&flctl->pdev->dev,
+				"page 0x%x contains corrupted data\n",
+				page_addr);
+			flctl->mtd.ecc_stats.failed++;
+			break;
+		default:
+			;
+		}
 	}
+
+	wait_completion(flctl);
+
 	writel(readl(FLCMNCR(flctl)) & ~(ACM_SACCES_MODE | _4ECCCORRECT),
 			FLCMNCR(flctl));
 }
@@ -420,30 +461,20 @@
 static void execmd_read_oob(struct mtd_info *mtd, int page_addr)
 {
 	struct sh_flctl *flctl = mtd_to_flctl(mtd);
+	int page_sectors = flctl->page_size ? 4 : 1;
+	int i;
 
 	set_cmd_regs(mtd, NAND_CMD_READ0,
 		(NAND_CMD_READSTART << 8) | NAND_CMD_READ0);
 
 	empty_fifo(flctl);
-	if (flctl->page_size) {
-		int i;
-		/* In case that the page size is 2k */
-		for (i = 0; i < 16 * 3; i++)
-			flctl->done_buff[i] = 0xFF;
 
-		set_addr(mtd, 3 * 528 + 512, page_addr);
+	for (i = 0; i < page_sectors; i++) {
+		set_addr(mtd, (512 + 16) * i + 512 , page_addr);
 		writel(16, FLDTCNTR(flctl));
 
 		start_translation(flctl);
-		read_fiforeg(flctl, 16, 16 * 3);
-		wait_completion(flctl);
-	} else {
-		/* In case that the page size is 512b */
-		set_addr(mtd, 512, page_addr);
-		writel(16, FLDTCNTR(flctl));
-
-		start_translation(flctl);
-		read_fiforeg(flctl, 16, 0);
+		read_fiforeg(flctl, 16, 16 * i);
 		wait_completion(flctl);
 	}
 }
@@ -451,34 +482,26 @@
 static void execmd_write_page_sector(struct mtd_info *mtd)
 {
 	struct sh_flctl *flctl = mtd_to_flctl(mtd);
-	int i, page_addr = flctl->seqin_page_addr;
+	int page_addr = flctl->seqin_page_addr;
 	int sector, page_sectors;
 
-	if (flctl->page_size)
-		page_sectors = 4;
-	else
-		page_sectors = 1;
-
-	writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE, FLCMNCR(flctl));
+	page_sectors = flctl->page_size ? 4 : 1;
 
 	set_cmd_regs(mtd, NAND_CMD_PAGEPROG,
 			(NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN);
 
+	empty_fifo(flctl);
+	writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE, FLCMNCR(flctl));
+	writel(readl(FLCMDCR(flctl)) | page_sectors, FLCMDCR(flctl));
+	writel(page_addr << 2, FLADR(flctl));
+	start_translation(flctl);
+
 	for (sector = 0; sector < page_sectors; sector++) {
-		empty_fifo(flctl);
-		writel(readl(FLCMDCR(flctl)) | 1, FLCMDCR(flctl));
-		writel(page_addr << 2 | sector, FLADR(flctl));
-
-		start_translation(flctl);
 		write_fiforeg(flctl, 512, 512 * sector);
-
-		for (i = 0; i < 4; i++) {
-			wait_wecfifo_ready(flctl); /* wait for write ready */
-			writel(0xFFFFFFFF, FLECFIFO(flctl));
-		}
-		wait_completion(flctl);
+		write_ec_fiforeg(flctl, 16, mtd->writesize + 16 * sector);
 	}
 
+	wait_completion(flctl);
 	writel(readl(FLCMNCR(flctl)) & ~ACM_SACCES_MODE, FLCMNCR(flctl));
 }
 
@@ -488,18 +511,12 @@
 	int page_addr = flctl->seqin_page_addr;
 	int sector, page_sectors;
 
-	if (flctl->page_size) {
-		sector = 3;
-		page_sectors = 4;
-	} else {
-		sector = 0;
-		page_sectors = 1;
-	}
+	page_sectors = flctl->page_size ? 4 : 1;
 
 	set_cmd_regs(mtd, NAND_CMD_PAGEPROG,
 			(NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN);
 
-	for (; sector < page_sectors; sector++) {
+	for (sector = 0; sector < page_sectors; sector++) {
 		empty_fifo(flctl);
 		set_addr(mtd, sector * 528 + 512, page_addr);
 		writel(16, FLDTCNTR(flctl));	/* set read size */
@@ -731,10 +748,9 @@
 static void flctl_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 {
 	struct sh_flctl *flctl = mtd_to_flctl(mtd);
-	int i, index = flctl->index;
+	int index = flctl->index;
 
-	for (i = 0; i < len; i++)
-		flctl->done_buff[index + i] = buf[i];
+	memcpy(&flctl->done_buff[index], buf, len);
 	flctl->index += len;
 }
 
@@ -763,20 +779,11 @@
 
 static void flctl_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
 {
-	int i;
+	struct sh_flctl *flctl = mtd_to_flctl(mtd);
+	int index = flctl->index;
 
-	for (i = 0; i < len; i++)
-		buf[i] = flctl_read_byte(mtd);
-}
-
-static int flctl_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
-{
-	int i;
-
-	for (i = 0; i < len; i++)
-		if (buf[i] != flctl_read_byte(mtd))
-			return -EFAULT;
-	return 0;
+	memcpy(buf, &flctl->done_buff[index], len);
+	flctl->index += len;
 }
 
 static int flctl_chip_init_tail(struct mtd_info *mtd)
@@ -831,7 +838,7 @@
 		chip->ecc.mode = NAND_ECC_HW;
 
 		/* 4 symbols ECC enabled */
-		flctl->flcmncr_base |= _4ECCEN | ECCPOS2 | ECCPOS_02;
+		flctl->flcmncr_base |= _4ECCEN;
 	} else {
 		chip->ecc.mode = NAND_ECC_SOFT;
 	}
@@ -839,6 +846,16 @@
 	return 0;
 }
 
+static irqreturn_t flctl_handle_flste(int irq, void *dev_id)
+{
+	struct sh_flctl *flctl = dev_id;
+
+	dev_err(&flctl->pdev->dev, "flste irq: %x\n", readl(FLINTDMACR(flctl)));
+	writel(flctl->flintdmacr_base, FLINTDMACR(flctl));
+
+	return IRQ_HANDLED;
+}
+
 static int __devinit flctl_probe(struct platform_device *pdev)
 {
 	struct resource *res;
@@ -847,6 +864,7 @@
 	struct nand_chip *nand;
 	struct sh_flctl_platform_data *pdata;
 	int ret = -ENXIO;
+	int irq;
 
 	pdata = pdev->dev.platform_data;
 	if (pdata == NULL) {
@@ -872,14 +890,27 @@
 		goto err_iomap;
 	}
 
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "failed to get flste irq data\n");
+		goto err_flste;
+	}
+
+	ret = request_irq(irq, flctl_handle_flste, IRQF_SHARED, "flste", flctl);
+	if (ret) {
+		dev_err(&pdev->dev, "request interrupt failed.\n");
+		goto err_flste;
+	}
+
 	platform_set_drvdata(pdev, flctl);
 	flctl_mtd = &flctl->mtd;
 	nand = &flctl->chip;
 	flctl_mtd->priv = nand;
 	flctl->pdev = pdev;
-	flctl->flcmncr_base = pdata->flcmncr_val;
 	flctl->hwecc = pdata->has_hwecc;
 	flctl->holden = pdata->use_holden;
+	flctl->flcmncr_base = pdata->flcmncr_val;
+	flctl->flintdmacr_base = flctl->hwecc ? (STERINTE | ECERB) : STERINTE;
 
 	/* Set address of hardware control function */
 	/* 20 us command delay time */
@@ -888,7 +919,6 @@
 	nand->read_byte = flctl_read_byte;
 	nand->write_buf = flctl_write_buf;
 	nand->read_buf = flctl_read_buf;
-	nand->verify_buf = flctl_verify_buf;
 	nand->select_chip = flctl_select_chip;
 	nand->cmdfunc = flctl_cmdfunc;
 
@@ -918,6 +948,9 @@
 
 err_chip:
 	pm_runtime_disable(&pdev->dev);
+	free_irq(irq, flctl);
+err_flste:
+	iounmap(flctl->reg);
 err_iomap:
 	kfree(flctl);
 	return ret;
@@ -929,6 +962,8 @@
 
 	nand_release(&flctl->mtd);
 	pm_runtime_disable(&pdev->dev);
+	free_irq(platform_get_irq(pdev, 0), flctl);
+	iounmap(flctl->reg);
 	kfree(flctl);
 
 	return 0;
diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/socrates_nand.c
index e02b08b..f3f28fa 100644
--- a/drivers/mtd/nand/socrates_nand.c
+++ b/drivers/mtd/nand/socrates_nand.c
@@ -98,24 +98,6 @@
 	return word;
 }
 
-/**
- * socrates_nand_verify_buf -  Verify chip data against buffer
- * @mtd:	MTD device structure
- * @buf:	buffer containing the data to compare
- * @len:	number of bytes to compare
- */
-static int socrates_nand_verify_buf(struct mtd_info *mtd, const u8 *buf,
-		int len)
-{
-	int i;
-
-	for (i = 0; i < len; i++) {
-		if (buf[i] != socrates_nand_read_byte(mtd))
-			return -EFAULT;
-	}
-	return 0;
-}
-
 /*
  * Hardware specific access to control-lines
  */
@@ -201,7 +183,6 @@
 	nand_chip->read_word = socrates_nand_read_word;
 	nand_chip->write_buf = socrates_nand_write_buf;
 	nand_chip->read_buf = socrates_nand_read_buf;
-	nand_chip->verify_buf = socrates_nand_verify_buf;
 	nand_chip->dev_ready = socrates_nand_device_ready;
 
 	nand_chip->ecc.mode = NAND_ECC_SOFT;	/* enable ECC */
diff --git a/drivers/mtd/nand/tmio_nand.c b/drivers/mtd/nand/tmio_nand.c
index 5aa5180..508e9e0 100644
--- a/drivers/mtd/nand/tmio_nand.c
+++ b/drivers/mtd/nand/tmio_nand.c
@@ -256,18 +256,6 @@
 	tmio_ioread16_rep(tmio->fcr + FCR_DATA, buf, len >> 1);
 }
 
-static int
-tmio_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
-{
-	struct tmio_nand *tmio = mtd_to_tmio(mtd);
-	u16				*p = (u16 *) buf;
-
-	for (len >>= 1; len; len--)
-		if (*(p++) != tmio_ioread16(tmio->fcr + FCR_DATA))
-			return -EFAULT;
-	return 0;
-}
-
 static void tmio_nand_enable_hwecc(struct mtd_info *mtd, int mode)
 {
 	struct tmio_nand *tmio = mtd_to_tmio(mtd);
@@ -424,7 +412,6 @@
 	nand_chip->read_byte = tmio_nand_read_byte;
 	nand_chip->write_buf = tmio_nand_write_buf;
 	nand_chip->read_buf = tmio_nand_read_buf;
-	nand_chip->verify_buf = tmio_nand_verify_buf;
 
 	/* set eccmode using hardware ECC */
 	nand_chip->ecc.mode = NAND_ECC_HW;
diff --git a/drivers/mtd/nand/txx9ndfmc.c b/drivers/mtd/nand/txx9ndfmc.c
index 26398dcf..e3d7266 100644
--- a/drivers/mtd/nand/txx9ndfmc.c
+++ b/drivers/mtd/nand/txx9ndfmc.c
@@ -131,18 +131,6 @@
 		*buf++ = __raw_readl(ndfdtr);
 }
 
-static int txx9ndfmc_verify_buf(struct mtd_info *mtd, const uint8_t *buf,
-				int len)
-{
-	struct platform_device *dev = mtd_to_platdev(mtd);
-	void __iomem *ndfdtr = ndregaddr(dev, TXX9_NDFDTR);
-
-	while (len--)
-		if (*buf++ != (uint8_t)__raw_readl(ndfdtr))
-			return -EFAULT;
-	return 0;
-}
-
 static void txx9ndfmc_cmd_ctrl(struct mtd_info *mtd, int cmd,
 			       unsigned int ctrl)
 {
@@ -346,7 +334,6 @@
 		chip->read_byte = txx9ndfmc_read_byte;
 		chip->read_buf = txx9ndfmc_read_buf;
 		chip->write_buf = txx9ndfmc_write_buf;
-		chip->verify_buf = txx9ndfmc_verify_buf;
 		chip->cmd_ctrl = txx9ndfmc_cmd_ctrl;
 		chip->dev_ready = txx9ndfmc_dev_ready;
 		chip->ecc.calculate = txx9ndfmc_calculate_ecc;
diff --git a/drivers/mtd/nand/xway_nand.c b/drivers/mtd/nand/xway_nand.c
new file mode 100644
index 0000000..3f81dc8
--- /dev/null
+++ b/drivers/mtd/nand/xway_nand.c
@@ -0,0 +1,201 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright © 2012 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/mtd/nand.h>
+#include <linux/of_gpio.h>
+#include <linux/of_platform.h>
+
+#include <lantiq_soc.h>
+
+/* nand registers */
+#define EBU_ADDSEL1		0x24
+#define EBU_NAND_CON		0xB0
+#define EBU_NAND_WAIT		0xB4
+#define EBU_NAND_ECC0		0xB8
+#define EBU_NAND_ECC_AC		0xBC
+
+/* nand commands */
+#define NAND_CMD_ALE		(1 << 2)
+#define NAND_CMD_CLE		(1 << 3)
+#define NAND_CMD_CS		(1 << 4)
+#define NAND_WRITE_CMD_RESET	0xff
+#define NAND_WRITE_CMD		(NAND_CMD_CS | NAND_CMD_CLE)
+#define NAND_WRITE_ADDR		(NAND_CMD_CS | NAND_CMD_ALE)
+#define NAND_WRITE_DATA		(NAND_CMD_CS)
+#define NAND_READ_DATA		(NAND_CMD_CS)
+#define NAND_WAIT_WR_C		(1 << 3)
+#define NAND_WAIT_RD		(0x1)
+
+/* we need to tel the ebu which addr we mapped the nand to */
+#define ADDSEL1_MASK(x)		(x << 4)
+#define ADDSEL1_REGEN		1
+
+/* we need to tell the EBU that we have nand attached and set it up properly */
+#define BUSCON1_SETUP		(1 << 22)
+#define BUSCON1_BCGEN_RES	(0x3 << 12)
+#define BUSCON1_WAITWRC2	(2 << 8)
+#define BUSCON1_WAITRDC2	(2 << 6)
+#define BUSCON1_HOLDC1		(1 << 4)
+#define BUSCON1_RECOVC1		(1 << 2)
+#define BUSCON1_CMULT4		1
+
+#define NAND_CON_CE		(1 << 20)
+#define NAND_CON_OUT_CS1	(1 << 10)
+#define NAND_CON_IN_CS1		(1 << 8)
+#define NAND_CON_PRE_P		(1 << 7)
+#define NAND_CON_WP_P		(1 << 6)
+#define NAND_CON_SE_P		(1 << 5)
+#define NAND_CON_CS_P		(1 << 4)
+#define NAND_CON_CSMUX		(1 << 1)
+#define NAND_CON_NANDM		1
+
+static void xway_reset_chip(struct nand_chip *chip)
+{
+	unsigned long nandaddr = (unsigned long) chip->IO_ADDR_W;
+	unsigned long flags;
+
+	nandaddr &= ~NAND_WRITE_ADDR;
+	nandaddr |= NAND_WRITE_CMD;
+
+	/* finish with a reset */
+	spin_lock_irqsave(&ebu_lock, flags);
+	writeb(NAND_WRITE_CMD_RESET, (void __iomem *) nandaddr);
+	while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
+		;
+	spin_unlock_irqrestore(&ebu_lock, flags);
+}
+
+static void xway_select_chip(struct mtd_info *mtd, int chip)
+{
+
+	switch (chip) {
+	case -1:
+		ltq_ebu_w32_mask(NAND_CON_CE, 0, EBU_NAND_CON);
+		ltq_ebu_w32_mask(NAND_CON_NANDM, 0, EBU_NAND_CON);
+		break;
+	case 0:
+		ltq_ebu_w32_mask(0, NAND_CON_NANDM, EBU_NAND_CON);
+		ltq_ebu_w32_mask(0, NAND_CON_CE, EBU_NAND_CON);
+		break;
+	default:
+		BUG();
+	}
+}
+
+static void xway_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+	struct nand_chip *this = mtd->priv;
+	unsigned long nandaddr = (unsigned long) this->IO_ADDR_W;
+	unsigned long flags;
+
+	if (ctrl & NAND_CTRL_CHANGE) {
+		nandaddr &= ~(NAND_WRITE_CMD | NAND_WRITE_ADDR);
+		if (ctrl & NAND_CLE)
+			nandaddr |= NAND_WRITE_CMD;
+		else
+			nandaddr |= NAND_WRITE_ADDR;
+		this->IO_ADDR_W = (void __iomem *) nandaddr;
+	}
+
+	if (cmd != NAND_CMD_NONE) {
+		spin_lock_irqsave(&ebu_lock, flags);
+		writeb(cmd, this->IO_ADDR_W);
+		while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
+			;
+		spin_unlock_irqrestore(&ebu_lock, flags);
+	}
+}
+
+static int xway_dev_ready(struct mtd_info *mtd)
+{
+	return ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_RD;
+}
+
+static unsigned char xway_read_byte(struct mtd_info *mtd)
+{
+	struct nand_chip *this = mtd->priv;
+	unsigned long nandaddr = (unsigned long) this->IO_ADDR_R;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&ebu_lock, flags);
+	ret = ltq_r8((void __iomem *)(nandaddr + NAND_READ_DATA));
+	spin_unlock_irqrestore(&ebu_lock, flags);
+
+	return ret;
+}
+
+static int xway_nand_probe(struct platform_device *pdev)
+{
+	struct nand_chip *this = platform_get_drvdata(pdev);
+	unsigned long nandaddr = (unsigned long) this->IO_ADDR_W;
+	const __be32 *cs = of_get_property(pdev->dev.of_node,
+					"lantiq,cs", NULL);
+	u32 cs_flag = 0;
+
+	/* load our CS from the DT. Either we find a valid 1 or default to 0 */
+	if (cs && (*cs == 1))
+		cs_flag = NAND_CON_IN_CS1 | NAND_CON_OUT_CS1;
+
+	/* setup the EBU to run in NAND mode on our base addr */
+	ltq_ebu_w32(CPHYSADDR(nandaddr)
+		| ADDSEL1_MASK(3) | ADDSEL1_REGEN, EBU_ADDSEL1);
+
+	ltq_ebu_w32(BUSCON1_SETUP | BUSCON1_BCGEN_RES | BUSCON1_WAITWRC2
+		| BUSCON1_WAITRDC2 | BUSCON1_HOLDC1 | BUSCON1_RECOVC1
+		| BUSCON1_CMULT4, LTQ_EBU_BUSCON1);
+
+	ltq_ebu_w32(NAND_CON_NANDM | NAND_CON_CSMUX | NAND_CON_CS_P
+		| NAND_CON_SE_P | NAND_CON_WP_P | NAND_CON_PRE_P
+		| cs_flag, EBU_NAND_CON);
+
+	/* finish with a reset */
+	xway_reset_chip(this);
+
+	return 0;
+}
+
+/* allow users to override the partition in DT using the cmdline */
+static const char *part_probes[] = { "cmdlinepart", "ofpart", NULL };
+
+static struct platform_nand_data xway_nand_data = {
+	.chip = {
+		.nr_chips		= 1,
+		.chip_delay		= 30,
+		.part_probe_types	= part_probes,
+	},
+	.ctrl = {
+		.probe		= xway_nand_probe,
+		.cmd_ctrl	= xway_cmd_ctrl,
+		.dev_ready	= xway_dev_ready,
+		.select_chip	= xway_select_chip,
+		.read_byte	= xway_read_byte,
+	}
+};
+
+/*
+ * Try to find the node inside the DT. If it is available attach out
+ * platform_nand_data
+ */
+static int __init xway_register_nand(void)
+{
+	struct device_node *node;
+	struct platform_device *pdev;
+
+	node = of_find_compatible_node(NULL, NULL, "lantiq,nand-xway");
+	if (!node)
+		return -ENOENT;
+	pdev = of_find_device_by_node(node);
+	if (!pdev)
+		return -EINVAL;
+	pdev->dev.platform_data = &xway_nand_data;
+	of_node_put(node);
+	return 0;
+}
+
+subsys_initcall(xway_register_nand);
diff --git a/drivers/mtd/sm_ftl.c b/drivers/mtd/sm_ftl.c
index 9e2dfd5..8dd6ba5 100644
--- a/drivers/mtd/sm_ftl.c
+++ b/drivers/mtd/sm_ftl.c
@@ -346,7 +346,6 @@
 	ret = mtd_write_oob(mtd, sm_mkoffset(ftl, zone, block, boffset), &ops);
 
 	/* Now we assume that hardware will catch write bitflip errors */
-	/* If you are paranoid, use CONFIG_MTD_NAND_VERIFY_WRITE */
 
 	if (ret) {
 		dbg("write to block %d at zone %d, failed with error %d",
diff --git a/drivers/mtd/tests/Makefile b/drivers/mtd/tests/Makefile
index b44dcab..bd0065c0 100644
--- a/drivers/mtd/tests/Makefile
+++ b/drivers/mtd/tests/Makefile
@@ -6,3 +6,4 @@
 obj-$(CONFIG_MTD_TESTS) += mtd_subpagetest.o
 obj-$(CONFIG_MTD_TESTS) += mtd_torturetest.o
 obj-$(CONFIG_MTD_TESTS) += mtd_nandecctest.o
+obj-$(CONFIG_MTD_TESTS) += mtd_nandbiterrs.o
diff --git a/drivers/mtd/tests/mtd_nandbiterrs.c b/drivers/mtd/tests/mtd_nandbiterrs.c
new file mode 100644
index 0000000..cc8d62c
--- /dev/null
+++ b/drivers/mtd/tests/mtd_nandbiterrs.c
@@ -0,0 +1,460 @@
+/*
+ * Copyright © 2012 NetCommWireless
+ * Iwo Mergler <Iwo.Mergler@netcommwireless.com.au>
+ *
+ * Test for multi-bit error recovery on a NAND page This mostly tests the
+ * ECC controller / driver.
+ *
+ * There are two test modes:
+ *
+ *	0 - artificially inserting bit errors until the ECC fails
+ *	    This is the default method and fairly quick. It should
+ *	    be independent of the quality of the FLASH.
+ *
+ *	1 - re-writing the same pattern repeatedly until the ECC fails.
+ *	    This method relies on the physics of NAND FLASH to eventually
+ *	    generate '0' bits if '1' has been written sufficient times.
+ *	    Depending on the NAND, the first bit errors will appear after
+ *	    1000 or more writes and then will usually snowball, reaching the
+ *	    limits of the ECC quickly.
+ *
+ *	    The test stops after 10000 cycles, should your FLASH be
+ *	    exceptionally good and not generate bit errors before that. Try
+ *	    a different page in that case.
+ *
+ * Please note that neither of these tests will significantly 'use up' any
+ * FLASH endurance. Only a maximum of two erase operations will be performed.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; see the file COPYING. If not, write to the Free Software
+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/mtd/mtd.h>
+#include <linux/err.h>
+#include <linux/mtd/nand.h>
+#include <linux/slab.h>
+
+#define msg(FMT, VA...) pr_info("mtd_nandbiterrs: "FMT, ##VA)
+
+static int dev;
+module_param(dev, int, S_IRUGO);
+MODULE_PARM_DESC(dev, "MTD device number to use");
+
+static unsigned page_offset;
+module_param(page_offset, uint, S_IRUGO);
+MODULE_PARM_DESC(page_offset, "Page number relative to dev start");
+
+static unsigned seed;
+module_param(seed, uint, S_IRUGO);
+MODULE_PARM_DESC(seed, "Random seed");
+
+static int mode;
+module_param(mode, int, S_IRUGO);
+MODULE_PARM_DESC(mode, "0=incremental errors, 1=overwrite test");
+
+static unsigned max_overwrite = 10000;
+
+static loff_t   offset;     /* Offset of the page we're using. */
+static unsigned eraseblock; /* Eraseblock number for our page. */
+
+/* We assume that the ECC can correct up to a certain number
+ * of biterrors per subpage. */
+static unsigned subsize;  /* Size of subpages */
+static unsigned subcount; /* Number of subpages per page */
+
+static struct mtd_info *mtd;   /* MTD device */
+
+static uint8_t *wbuffer; /* One page write / compare buffer */
+static uint8_t *rbuffer; /* One page read buffer */
+
+/* 'random' bytes from known offsets */
+static uint8_t hash(unsigned offset)
+{
+	unsigned v = offset;
+	unsigned char c;
+	v ^= 0x7f7edfd3;
+	v = v ^ (v >> 3);
+	v = v ^ (v >> 5);
+	v = v ^ (v >> 13);
+	c = v & 0xFF;
+	/* Reverse bits of result. */
+	c = (c & 0x0F) << 4 | (c & 0xF0) >> 4;
+	c = (c & 0x33) << 2 | (c & 0xCC) >> 2;
+	c = (c & 0x55) << 1 | (c & 0xAA) >> 1;
+	return c;
+}
+
+static int erase_block(void)
+{
+	int err;
+	struct erase_info ei;
+	loff_t addr = eraseblock * mtd->erasesize;
+
+	msg("erase_block\n");
+
+	memset(&ei, 0, sizeof(struct erase_info));
+	ei.mtd  = mtd;
+	ei.addr = addr;
+	ei.len  = mtd->erasesize;
+
+	err = mtd_erase(mtd, &ei);
+	if (err || ei.state == MTD_ERASE_FAILED) {
+		msg("error %d while erasing\n", err);
+		if (!err)
+			err = -EIO;
+		return err;
+	}
+
+	return 0;
+}
+
+/* Writes wbuffer to page */
+static int write_page(int log)
+{
+	int err = 0;
+	size_t written;
+
+	if (log)
+		msg("write_page\n");
+
+	err = mtd_write(mtd, offset, mtd->writesize, &written, wbuffer);
+	if (err || written != mtd->writesize) {
+		msg("error: write failed at %#llx\n", (long long)offset);
+		if (!err)
+			err = -EIO;
+	}
+
+	return err;
+}
+
+/* Re-writes the data area while leaving the OOB alone. */
+static int rewrite_page(int log)
+{
+	int err = 0;
+	struct mtd_oob_ops ops;
+
+	if (log)
+		msg("rewrite page\n");
+
+	ops.mode      = MTD_OPS_RAW; /* No ECC */
+	ops.len       = mtd->writesize;
+	ops.retlen    = 0;
+	ops.ooblen    = 0;
+	ops.oobretlen = 0;
+	ops.ooboffs   = 0;
+	ops.datbuf    = wbuffer;
+	ops.oobbuf    = NULL;
+
+	err = mtd_write_oob(mtd, offset, &ops);
+	if (err || ops.retlen != mtd->writesize) {
+		msg("error: write_oob failed (%d)\n", err);
+		if (!err)
+			err = -EIO;
+	}
+
+	return err;
+}
+
+/* Reads page into rbuffer. Returns number of corrected bit errors (>=0)
+ * or error (<0) */
+static int read_page(int log)
+{
+	int err = 0;
+	size_t read;
+	struct mtd_ecc_stats oldstats;
+
+	if (log)
+		msg("read_page\n");
+
+	/* Saving last mtd stats */
+	memcpy(&oldstats, &mtd->ecc_stats, sizeof(oldstats));
+
+	err = mtd_read(mtd, offset, mtd->writesize, &read, rbuffer);
+	if (err == -EUCLEAN)
+		err = mtd->ecc_stats.corrected - oldstats.corrected;
+
+	if (err < 0 || read != mtd->writesize) {
+		msg("error: read failed at %#llx\n", (long long)offset);
+		if (err >= 0)
+			err = -EIO;
+	}
+
+	return err;
+}
+
+/* Verifies rbuffer against random sequence */
+static int verify_page(int log)
+{
+	unsigned i, errs = 0;
+
+	if (log)
+		msg("verify_page\n");
+
+	for (i = 0; i < mtd->writesize; i++) {
+		if (rbuffer[i] != hash(i+seed)) {
+			msg("Error: page offset %u, expected %02x, got %02x\n",
+				i, hash(i+seed), rbuffer[i]);
+			errs++;
+		}
+	}
+
+	if (errs)
+		return -EIO;
+	else
+		return 0;
+}
+
+#define CBIT(v, n) ((v) & (1 << (n)))
+#define BCLR(v, n) ((v) = (v) & ~(1 << (n)))
+
+/* Finds the first '1' bit in wbuffer starting at offset 'byte'
+ * and sets it to '0'. */
+static int insert_biterror(unsigned byte)
+{
+	int bit;
+
+	while (byte < mtd->writesize) {
+		for (bit = 7; bit >= 0; bit--) {
+			if (CBIT(wbuffer[byte], bit)) {
+				BCLR(wbuffer[byte], bit);
+				msg("Inserted biterror @ %u/%u\n", byte, bit);
+				return 0;
+			}
+		}
+		byte++;
+	}
+	msg("biterror: Failed to find a '1' bit\n");
+	return -EIO;
+}
+
+/* Writes 'random' data to page and then introduces deliberate bit
+ * errors into the page, while verifying each step. */
+static int incremental_errors_test(void)
+{
+	int err = 0;
+	unsigned i;
+	unsigned errs_per_subpage = 0;
+
+	msg("incremental biterrors test\n");
+
+	for (i = 0; i < mtd->writesize; i++)
+		wbuffer[i] = hash(i+seed);
+
+	err = write_page(1);
+	if (err)
+		goto exit;
+
+	while (1) {
+
+		err = rewrite_page(1);
+		if (err)
+			goto exit;
+
+		err = read_page(1);
+		if (err > 0)
+			msg("Read reported %d corrected bit errors\n", err);
+		if (err < 0) {
+			msg("After %d biterrors per subpage, read reported error %d\n",
+				errs_per_subpage, err);
+			err = 0;
+			goto exit;
+		}
+
+		err = verify_page(1);
+		if (err) {
+			msg("ECC failure, read data is incorrect despite read success\n");
+			goto exit;
+		}
+
+		msg("Successfully corrected %d bit errors per subpage\n",
+			errs_per_subpage);
+
+		for (i = 0; i < subcount; i++) {
+			err = insert_biterror(i * subsize);
+			if (err < 0)
+				goto exit;
+		}
+		errs_per_subpage++;
+	}
+
+exit:
+	return err;
+}
+
+
+/* Writes 'random' data to page and then re-writes that same data repeatedly.
+   This eventually develops bit errors (bits written as '1' will slowly become
+   '0'), which are corrected as far as the ECC is capable of. */
+static int overwrite_test(void)
+{
+	int err = 0;
+	unsigned i;
+	unsigned max_corrected = 0;
+	unsigned opno = 0;
+	/* We don't expect more than this many correctable bit errors per
+	 * page. */
+	#define MAXBITS 512
+	static unsigned bitstats[MAXBITS]; /* bit error histogram. */
+
+	memset(bitstats, 0, sizeof(bitstats));
+
+	msg("overwrite biterrors test\n");
+
+	for (i = 0; i < mtd->writesize; i++)
+		wbuffer[i] = hash(i+seed);
+
+	err = write_page(1);
+	if (err)
+		goto exit;
+
+	while (opno < max_overwrite) {
+
+		err = rewrite_page(0);
+		if (err)
+			break;
+
+		err = read_page(0);
+		if (err >= 0) {
+			if (err >= MAXBITS) {
+				msg("Implausible number of bit errors corrected\n");
+				err = -EIO;
+				break;
+			}
+			bitstats[err]++;
+			if (err > max_corrected) {
+				max_corrected = err;
+				msg("Read reported %d corrected bit errors\n",
+					err);
+			}
+		} else { /* err < 0 */
+			msg("Read reported error %d\n", err);
+			err = 0;
+			break;
+		}
+
+		err = verify_page(0);
+		if (err) {
+			bitstats[max_corrected] = opno;
+			msg("ECC failure, read data is incorrect despite read success\n");
+			break;
+		}
+
+		opno++;
+	}
+
+	/* At this point bitstats[0] contains the number of ops with no bit
+	 * errors, bitstats[1] the number of ops with 1 bit error, etc. */
+	msg("Bit error histogram (%d operations total):\n", opno);
+	for (i = 0; i < max_corrected; i++)
+		msg("Page reads with %3d corrected bit errors: %d\n",
+			i, bitstats[i]);
+
+exit:
+	return err;
+}
+
+static int __init mtd_nandbiterrs_init(void)
+{
+	int err = 0;
+
+	msg("\n");
+	msg("==================================================\n");
+	msg("MTD device: %d\n", dev);
+
+	mtd = get_mtd_device(NULL, dev);
+	if (IS_ERR(mtd)) {
+		err = PTR_ERR(mtd);
+		msg("error: cannot get MTD device\n");
+		goto exit_mtddev;
+	}
+
+	if (mtd->type != MTD_NANDFLASH) {
+		msg("this test requires NAND flash\n");
+		err = -ENODEV;
+		goto exit_nand;
+	}
+
+	msg("MTD device size %llu, eraseblock=%u, page=%u, oob=%u\n",
+		(unsigned long long)mtd->size, mtd->erasesize,
+		mtd->writesize, mtd->oobsize);
+
+	subsize  = mtd->writesize >> mtd->subpage_sft;
+	subcount = mtd->writesize / subsize;
+
+	msg("Device uses %d subpages of %d bytes\n", subcount, subsize);
+
+	offset     = page_offset * mtd->writesize;
+	eraseblock = mtd_div_by_eb(offset, mtd);
+
+	msg("Using page=%u, offset=%llu, eraseblock=%u\n",
+		page_offset, offset, eraseblock);
+
+	wbuffer = kmalloc(mtd->writesize, GFP_KERNEL);
+	if (!wbuffer) {
+		err = -ENOMEM;
+		goto exit_wbuffer;
+	}
+
+	rbuffer = kmalloc(mtd->writesize, GFP_KERNEL);
+	if (!rbuffer) {
+		err = -ENOMEM;
+		goto exit_rbuffer;
+	}
+
+	err = erase_block();
+	if (err)
+		goto exit_error;
+
+	if (mode == 0)
+		err = incremental_errors_test();
+	else
+		err = overwrite_test();
+
+	if (err)
+		goto exit_error;
+
+	/* We leave the block un-erased in case of test failure. */
+	err = erase_block();
+	if (err)
+		goto exit_error;
+
+	err = -EIO;
+	msg("finished successfully.\n");
+	msg("==================================================\n");
+
+exit_error:
+	kfree(rbuffer);
+exit_rbuffer:
+	kfree(wbuffer);
+exit_wbuffer:
+	/* Nothing */
+exit_nand:
+	put_mtd_device(mtd);
+exit_mtddev:
+	return err;
+}
+
+static void __exit mtd_nandbiterrs_exit(void)
+{
+	return;
+}
+
+module_init(mtd_nandbiterrs_init);
+module_exit(mtd_nandbiterrs_exit);
+
+MODULE_DESCRIPTION("NAND bit error recovery test");
+MODULE_AUTHOR("Iwo Mergler");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/tests/mtd_nandecctest.c b/drivers/mtd/tests/mtd_nandecctest.c
index 70d6d7d..b437fa4 100644
--- a/drivers/mtd/tests/mtd_nandecctest.c
+++ b/drivers/mtd/tests/mtd_nandecctest.c
@@ -4,60 +4,287 @@
 #include <linux/random.h>
 #include <linux/string.h>
 #include <linux/bitops.h>
-#include <linux/jiffies.h>
+#include <linux/slab.h>
 #include <linux/mtd/nand_ecc.h>
 
+/*
+ * Test the implementation for software ECC
+ *
+ * No actual MTD device is needed, So we don't need to warry about losing
+ * important data by human error.
+ *
+ * This covers possible patterns of corruption which can be reliably corrected
+ * or detected.
+ */
+
 #if defined(CONFIG_MTD_NAND) || defined(CONFIG_MTD_NAND_MODULE)
 
-static void inject_single_bit_error(void *data, size_t size)
-{
-	unsigned long offset = random32() % (size * BITS_PER_BYTE);
+struct nand_ecc_test {
+	const char *name;
+	void (*prepare)(void *, void *, void *, void *, const size_t);
+	int (*verify)(void *, void *, void *, const size_t);
+};
 
-	__change_bit(offset, data);
+/*
+ * The reason for this __change_bit_le() instead of __change_bit() is to inject
+ * bit error properly within the region which is not a multiple of
+ * sizeof(unsigned long) on big-endian systems
+ */
+#ifdef __LITTLE_ENDIAN
+#define __change_bit_le(nr, addr) __change_bit(nr, addr)
+#elif defined(__BIG_ENDIAN)
+#define __change_bit_le(nr, addr) \
+		__change_bit((nr) ^ ((BITS_PER_LONG - 1) & ~0x7), addr)
+#else
+#error "Unknown byte order"
+#endif
+
+static void single_bit_error_data(void *error_data, void *correct_data,
+				size_t size)
+{
+	unsigned int offset = random32() % (size * BITS_PER_BYTE);
+
+	memcpy(error_data, correct_data, size);
+	__change_bit_le(offset, error_data);
 }
 
-static unsigned char data[512];
-static unsigned char error_data[512];
-
-static int nand_ecc_test(const size_t size)
+static void double_bit_error_data(void *error_data, void *correct_data,
+				size_t size)
 {
-	unsigned char code[3];
-	unsigned char error_code[3];
-	char testname[30];
+	unsigned int offset[2];
 
-	BUG_ON(sizeof(data) < size);
+	offset[0] = random32() % (size * BITS_PER_BYTE);
+	do {
+		offset[1] = random32() % (size * BITS_PER_BYTE);
+	} while (offset[0] == offset[1]);
 
-	sprintf(testname, "nand-ecc-%zu", size);
+	memcpy(error_data, correct_data, size);
 
-	get_random_bytes(data, size);
+	__change_bit_le(offset[0], error_data);
+	__change_bit_le(offset[1], error_data);
+}
 
-	memcpy(error_data, data, size);
-	inject_single_bit_error(error_data, size);
+static unsigned int random_ecc_bit(size_t size)
+{
+	unsigned int offset = random32() % (3 * BITS_PER_BYTE);
 
-	__nand_calculate_ecc(data, size, code);
-	__nand_calculate_ecc(error_data, size, error_code);
-	__nand_correct_data(error_data, code, error_code, size);
-
-	if (!memcmp(data, error_data, size)) {
-		printk(KERN_INFO "mtd_nandecctest: ok - %s\n", testname);
-		return 0;
+	if (size == 256) {
+		/*
+		 * Don't inject a bit error into the insignificant bits (16th
+		 * and 17th bit) in ECC code for 256 byte data block
+		 */
+		while (offset == 16 || offset == 17)
+			offset = random32() % (3 * BITS_PER_BYTE);
 	}
 
-	printk(KERN_ERR "mtd_nandecctest: not ok - %s\n", testname);
+	return offset;
+}
 
-	printk(KERN_DEBUG "hexdump of data:\n");
-	print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 4,
-			data, size, false);
-	printk(KERN_DEBUG "hexdump of error data:\n");
-	print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 4,
+static void single_bit_error_ecc(void *error_ecc, void *correct_ecc,
+				size_t size)
+{
+	unsigned int offset = random_ecc_bit(size);
+
+	memcpy(error_ecc, correct_ecc, 3);
+	__change_bit_le(offset, error_ecc);
+}
+
+static void double_bit_error_ecc(void *error_ecc, void *correct_ecc,
+				size_t size)
+{
+	unsigned int offset[2];
+
+	offset[0] = random_ecc_bit(size);
+	do {
+		offset[1] = random_ecc_bit(size);
+	} while (offset[0] == offset[1]);
+
+	memcpy(error_ecc, correct_ecc, 3);
+	__change_bit_le(offset[0], error_ecc);
+	__change_bit_le(offset[1], error_ecc);
+}
+
+static void no_bit_error(void *error_data, void *error_ecc,
+		void *correct_data, void *correct_ecc, const size_t size)
+{
+	memcpy(error_data, correct_data, size);
+	memcpy(error_ecc, correct_ecc, 3);
+}
+
+static int no_bit_error_verify(void *error_data, void *error_ecc,
+				void *correct_data, const size_t size)
+{
+	unsigned char calc_ecc[3];
+	int ret;
+
+	__nand_calculate_ecc(error_data, size, calc_ecc);
+	ret = __nand_correct_data(error_data, error_ecc, calc_ecc, size);
+	if (ret == 0 && !memcmp(correct_data, error_data, size))
+		return 0;
+
+	return -EINVAL;
+}
+
+static void single_bit_error_in_data(void *error_data, void *error_ecc,
+		void *correct_data, void *correct_ecc, const size_t size)
+{
+	single_bit_error_data(error_data, correct_data, size);
+	memcpy(error_ecc, correct_ecc, 3);
+}
+
+static void single_bit_error_in_ecc(void *error_data, void *error_ecc,
+		void *correct_data, void *correct_ecc, const size_t size)
+{
+	memcpy(error_data, correct_data, size);
+	single_bit_error_ecc(error_ecc, correct_ecc, size);
+}
+
+static int single_bit_error_correct(void *error_data, void *error_ecc,
+				void *correct_data, const size_t size)
+{
+	unsigned char calc_ecc[3];
+	int ret;
+
+	__nand_calculate_ecc(error_data, size, calc_ecc);
+	ret = __nand_correct_data(error_data, error_ecc, calc_ecc, size);
+	if (ret == 1 && !memcmp(correct_data, error_data, size))
+		return 0;
+
+	return -EINVAL;
+}
+
+static void double_bit_error_in_data(void *error_data, void *error_ecc,
+		void *correct_data, void *correct_ecc, const size_t size)
+{
+	double_bit_error_data(error_data, correct_data, size);
+	memcpy(error_ecc, correct_ecc, 3);
+}
+
+static void single_bit_error_in_data_and_ecc(void *error_data, void *error_ecc,
+		void *correct_data, void *correct_ecc, const size_t size)
+{
+	single_bit_error_data(error_data, correct_data, size);
+	single_bit_error_ecc(error_ecc, correct_ecc, size);
+}
+
+static void double_bit_error_in_ecc(void *error_data, void *error_ecc,
+		void *correct_data, void *correct_ecc, const size_t size)
+{
+	memcpy(error_data, correct_data, size);
+	double_bit_error_ecc(error_ecc, correct_ecc, size);
+}
+
+static int double_bit_error_detect(void *error_data, void *error_ecc,
+				void *correct_data, const size_t size)
+{
+	unsigned char calc_ecc[3];
+	int ret;
+
+	__nand_calculate_ecc(error_data, size, calc_ecc);
+	ret = __nand_correct_data(error_data, error_ecc, calc_ecc, size);
+
+	return (ret == -1) ? 0 : -EINVAL;
+}
+
+static const struct nand_ecc_test nand_ecc_test[] = {
+	{
+		.name = "no-bit-error",
+		.prepare = no_bit_error,
+		.verify = no_bit_error_verify,
+	},
+	{
+		.name = "single-bit-error-in-data-correct",
+		.prepare = single_bit_error_in_data,
+		.verify = single_bit_error_correct,
+	},
+	{
+		.name = "single-bit-error-in-ecc-correct",
+		.prepare = single_bit_error_in_ecc,
+		.verify = single_bit_error_correct,
+	},
+	{
+		.name = "double-bit-error-in-data-detect",
+		.prepare = double_bit_error_in_data,
+		.verify = double_bit_error_detect,
+	},
+	{
+		.name = "single-bit-error-in-data-and-ecc-detect",
+		.prepare = single_bit_error_in_data_and_ecc,
+		.verify = double_bit_error_detect,
+	},
+	{
+		.name = "double-bit-error-in-ecc-detect",
+		.prepare = double_bit_error_in_ecc,
+		.verify = double_bit_error_detect,
+	},
+};
+
+static void dump_data_ecc(void *error_data, void *error_ecc, void *correct_data,
+			void *correct_ecc, const size_t size)
+{
+	pr_info("hexdump of error data:\n");
+	print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 4,
 			error_data, size, false);
+	print_hex_dump(KERN_INFO, "hexdump of error ecc: ",
+			DUMP_PREFIX_NONE, 16, 1, error_ecc, 3, false);
 
-	return -1;
+	pr_info("hexdump of correct data:\n");
+	print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 4,
+			correct_data, size, false);
+	print_hex_dump(KERN_INFO, "hexdump of correct ecc: ",
+			DUMP_PREFIX_NONE, 16, 1, correct_ecc, 3, false);
+}
+
+static int nand_ecc_test_run(const size_t size)
+{
+	int i;
+	int err = 0;
+	void *error_data;
+	void *error_ecc;
+	void *correct_data;
+	void *correct_ecc;
+
+	error_data = kmalloc(size, GFP_KERNEL);
+	error_ecc = kmalloc(3, GFP_KERNEL);
+	correct_data = kmalloc(size, GFP_KERNEL);
+	correct_ecc = kmalloc(3, GFP_KERNEL);
+
+	if (!error_data || !error_ecc || !correct_data || !correct_ecc) {
+		err = -ENOMEM;
+		goto error;
+	}
+
+	get_random_bytes(correct_data, size);
+	__nand_calculate_ecc(correct_data, size, correct_ecc);
+
+	for (i = 0; i < ARRAY_SIZE(nand_ecc_test); i++) {
+		nand_ecc_test[i].prepare(error_data, error_ecc,
+				correct_data, correct_ecc, size);
+		err = nand_ecc_test[i].verify(error_data, error_ecc,
+						correct_data, size);
+
+		if (err) {
+			pr_err("mtd_nandecctest: not ok - %s-%zd\n",
+				nand_ecc_test[i].name, size);
+			dump_data_ecc(error_data, error_ecc,
+				correct_data, correct_ecc, size);
+			break;
+		}
+		pr_info("mtd_nandecctest: ok - %s-%zd\n",
+			nand_ecc_test[i].name, size);
+	}
+error:
+	kfree(error_data);
+	kfree(error_ecc);
+	kfree(correct_data);
+	kfree(correct_ecc);
+
+	return err;
 }
 
 #else
 
-static int nand_ecc_test(const size_t size)
+static int nand_ecc_test_run(const size_t size)
 {
 	return 0;
 }
@@ -66,12 +293,13 @@
 
 static int __init ecc_test_init(void)
 {
-	srandom32(jiffies);
+	int err;
 
-	nand_ecc_test(256);
-	nand_ecc_test(512);
+	err = nand_ecc_test_run(256);
+	if (err)
+		return err;
 
-	return 0;
+	return nand_ecc_test_run(512);
 }
 
 static void __exit ecc_test_exit(void)
diff --git a/drivers/mtd/tests/mtd_speedtest.c b/drivers/mtd/tests/mtd_speedtest.c
index 2aec4f3..42b0f74 100644
--- a/drivers/mtd/tests/mtd_speedtest.c
+++ b/drivers/mtd/tests/mtd_speedtest.c
@@ -26,6 +26,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/slab.h>
 #include <linux/sched.h>
+#include <linux/random.h>
 
 #define PRINT_PREF KERN_INFO "mtd_speedtest: "
 
@@ -47,25 +48,13 @@
 static int pgcnt;
 static int goodebcnt;
 static struct timeval start, finish;
-static unsigned long next = 1;
-
-static inline unsigned int simple_rand(void)
-{
-	next = next * 1103515245 + 12345;
-	return (unsigned int)((next / 65536) % 32768);
-}
-
-static inline void simple_srand(unsigned long seed)
-{
-	next = seed;
-}
 
 static void set_random_data(unsigned char *buf, size_t len)
 {
 	size_t i;
 
 	for (i = 0; i < len; ++i)
-		buf[i] = simple_rand();
+		buf[i] = random32();
 }
 
 static int erase_eraseblock(int ebnum)
@@ -407,7 +396,6 @@
 		goto out;
 	}
 
-	simple_srand(1);
 	set_random_data(iobuf, mtd->erasesize);
 
 	err = scan_for_bad_eraseblocks();
diff --git a/drivers/mtd/tests/mtd_stresstest.c b/drivers/mtd/tests/mtd_stresstest.c
index 7b33f22..cb268ce 100644
--- a/drivers/mtd/tests/mtd_stresstest.c
+++ b/drivers/mtd/tests/mtd_stresstest.c
@@ -27,6 +27,7 @@
 #include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/vmalloc.h>
+#include <linux/random.h>
 
 #define PRINT_PREF KERN_INFO "mtd_stresstest: "
 
@@ -48,28 +49,13 @@
 static int bufsize;
 static int ebcnt;
 static int pgcnt;
-static unsigned long next = 1;
-
-static inline unsigned int simple_rand(void)
-{
-	next = next * 1103515245 + 12345;
-	return (unsigned int)((next / 65536) % 32768);
-}
-
-static inline void simple_srand(unsigned long seed)
-{
-	next = seed;
-}
 
 static int rand_eb(void)
 {
-	int eb;
+	unsigned int eb;
 
 again:
-	if (ebcnt < 32768)
-		eb = simple_rand();
-	else
-		eb = (simple_rand() << 15) | simple_rand();
+	eb = random32();
 	/* Read or write up 2 eraseblocks at a time - hence 'ebcnt - 1' */
 	eb %= (ebcnt - 1);
 	if (bbt[eb])
@@ -79,24 +65,18 @@
 
 static int rand_offs(void)
 {
-	int offs;
+	unsigned int offs;
 
-	if (bufsize < 32768)
-		offs = simple_rand();
-	else
-		offs = (simple_rand() << 15) | simple_rand();
+	offs = random32();
 	offs %= bufsize;
 	return offs;
 }
 
 static int rand_len(int offs)
 {
-	int len;
+	unsigned int len;
 
-	if (bufsize < 32768)
-		len = simple_rand();
-	else
-		len = (simple_rand() << 15) | simple_rand();
+	len = random32();
 	len %= (bufsize - offs);
 	return len;
 }
@@ -211,7 +191,7 @@
 
 static int do_operation(void)
 {
-	if (simple_rand() & 1)
+	if (random32() & 1)
 		return do_read();
 	else
 		return do_write();
@@ -302,9 +282,8 @@
 	}
 	for (i = 0; i < ebcnt; i++)
 		offsets[i] = mtd->erasesize;
-	simple_srand(current->pid);
 	for (i = 0; i < bufsize; i++)
-		writebuf[i] = simple_rand();
+		writebuf[i] = random32();
 
 	err = scan_for_bad_eraseblocks();
 	if (err)
diff --git a/drivers/mtd/ubi/Kconfig b/drivers/mtd/ubi/Kconfig
index 271a842..36663af 100644
--- a/drivers/mtd/ubi/Kconfig
+++ b/drivers/mtd/ubi/Kconfig
@@ -56,6 +56,27 @@
 
 	  Leave the default value if unsure.
 
+config MTD_UBI_FASTMAP
+	bool "UBI Fastmap (Experimental feature)"
+	default n
+	help
+	   Important: this feature is experimental so far and the on-flash
+	   format for fastmap may change in the next kernel versions
+
+	   Fastmap is a mechanism which allows attaching an UBI device
+	   in nearly constant time. Instead of scanning the whole MTD device it
+	   only has to locate a checkpoint (called fastmap) on the device.
+	   The on-flash fastmap contains all information needed to attach
+	   the device. Using fastmap makes only sense on large devices where
+	   attaching by scanning takes long. UBI will not automatically install
+	   a fastmap on old images, but you can set the UBI module parameter
+	   fm_autoconvert to 1 if you want so. Please note that fastmap-enabled
+	   images are still usable with UBI implementations without
+	   fastmap support. On typical flash devices the whole fastmap fits
+	   into one PEB. UBI will reserve PEBs to hold two fastmaps.
+
+	   If in doubt, say "N".
+
 config MTD_UBI_GLUEBI
 	tristate "MTD devices emulation driver (gluebi)"
 	help
diff --git a/drivers/mtd/ubi/Makefile b/drivers/mtd/ubi/Makefile
index a0803ac..b46b0c97 100644
--- a/drivers/mtd/ubi/Makefile
+++ b/drivers/mtd/ubi/Makefile
@@ -2,5 +2,6 @@
 
 ubi-y += vtbl.o vmt.o upd.o build.o cdev.o kapi.o eba.o io.o wl.o attach.o
 ubi-y += misc.o debug.o
+ubi-$(CONFIG_MTD_UBI_FASTMAP) += fastmap.o
 
 obj-$(CONFIG_MTD_UBI_GLUEBI) += gluebi.o
diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c
index f7adf53..fec406b 100644
--- a/drivers/mtd/ubi/attach.c
+++ b/drivers/mtd/ubi/attach.c
@@ -300,7 +300,7 @@
 }
 
 /**
- * compare_lebs - find out which logical eraseblock is newer.
+ * ubi_compare_lebs - find out which logical eraseblock is newer.
  * @ubi: UBI device description object
  * @aeb: first logical eraseblock to compare
  * @pnum: physical eraseblock number of the second logical eraseblock to
@@ -319,7 +319,7 @@
  *     o bit 2 is cleared: the older LEB is not corrupted;
  *     o bit 2 is set: the older LEB is corrupted.
  */
-static int compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb,
+int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb,
 			int pnum, const struct ubi_vid_hdr *vid_hdr)
 {
 	void *buf;
@@ -337,7 +337,7 @@
 		 * support these images anymore. Well, those images still work,
 		 * but only if no unclean reboots happened.
 		 */
-		ubi_err("unsupported on-flash UBI format\n");
+		ubi_err("unsupported on-flash UBI format");
 		return -EINVAL;
 	}
 
@@ -507,7 +507,7 @@
 		 * sequence numbers. We still can attach these images, unless
 		 * there is a need to distinguish between old and new
 		 * eraseblocks, in which case we'll refuse the image in
-		 * 'compare_lebs()'. In other words, we attach old clean
+		 * 'ubi_compare_lebs()'. In other words, we attach old clean
 		 * images, but refuse attaching old images with duplicated
 		 * logical eraseblocks because there was an unclean reboot.
 		 */
@@ -523,7 +523,7 @@
 		 * Now we have to drop the older one and preserve the newer
 		 * one.
 		 */
-		cmp_res = compare_lebs(ubi, aeb, pnum, vid_hdr);
+		cmp_res = ubi_compare_lebs(ubi, aeb, pnum, vid_hdr);
 		if (cmp_res < 0)
 			return cmp_res;
 
@@ -748,7 +748,7 @@
 /**
  * check_corruption - check the data area of PEB.
  * @ubi: UBI device description object
- * @vid_hrd: the (corrupted) VID header of this PEB
+ * @vid_hdr: the (corrupted) VID header of this PEB
  * @pnum: the physical eraseblock number to check
  *
  * This is a helper function which is used to distinguish between VID header
@@ -810,6 +810,8 @@
  * @ubi: UBI device description object
  * @ai: attaching information
  * @pnum: the physical eraseblock number
+ * @vid: The volume ID of the found volume will be stored in this pointer
+ * @sqnum: The sqnum of the found volume will be stored in this pointer
  *
  * This function reads UBI headers of PEB @pnum, checks them, and adds
  * information about this PEB to the corresponding list or RB-tree in the
@@ -817,10 +819,10 @@
  * successfully handled and a negative error code in case of failure.
  */
 static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai,
-		    int pnum)
+		    int pnum, int *vid, unsigned long long *sqnum)
 {
 	long long uninitialized_var(ec);
-	int err, bitflips = 0, vol_id, ec_err = 0;
+	int err, bitflips = 0, vol_id = -1, ec_err = 0;
 
 	dbg_bld("scan PEB %d", pnum);
 
@@ -991,14 +993,21 @@
 	}
 
 	vol_id = be32_to_cpu(vidh->vol_id);
+	if (vid)
+		*vid = vol_id;
+	if (sqnum)
+		*sqnum = be64_to_cpu(vidh->sqnum);
 	if (vol_id > UBI_MAX_VOLUMES && vol_id != UBI_LAYOUT_VOLUME_ID) {
 		int lnum = be32_to_cpu(vidh->lnum);
 
 		/* Unsupported internal volume */
 		switch (vidh->compat) {
 		case UBI_COMPAT_DELETE:
-			ubi_msg("\"delete\" compatible internal volume %d:%d found, will remove it",
-				vol_id, lnum);
+			if (vol_id != UBI_FM_SB_VOLUME_ID
+			    && vol_id != UBI_FM_DATA_VOLUME_ID) {
+				ubi_msg("\"delete\" compatible internal volume %d:%d found, will remove it",
+					vol_id, lnum);
+			}
 			err = add_to_list(ai, pnum, vol_id, lnum,
 					  ec, 1, &ai->erase);
 			if (err)
@@ -1121,155 +1130,6 @@
 }
 
 /**
- * scan_all - scan entire MTD device.
- * @ubi: UBI device description object
- *
- * This function does full scanning of an MTD device and returns complete
- * information about it in form of a "struct ubi_attach_info" object. In case
- * of failure, an error code is returned.
- */
-static struct ubi_attach_info *scan_all(struct ubi_device *ubi)
-{
-	int err, pnum;
-	struct rb_node *rb1, *rb2;
-	struct ubi_ainf_volume *av;
-	struct ubi_ainf_peb *aeb;
-	struct ubi_attach_info *ai;
-
-	ai = kzalloc(sizeof(struct ubi_attach_info), GFP_KERNEL);
-	if (!ai)
-		return ERR_PTR(-ENOMEM);
-
-	INIT_LIST_HEAD(&ai->corr);
-	INIT_LIST_HEAD(&ai->free);
-	INIT_LIST_HEAD(&ai->erase);
-	INIT_LIST_HEAD(&ai->alien);
-	ai->volumes = RB_ROOT;
-
-	err = -ENOMEM;
-	ai->aeb_slab_cache = kmem_cache_create("ubi_aeb_slab_cache",
-					       sizeof(struct ubi_ainf_peb),
-					       0, 0, NULL);
-	if (!ai->aeb_slab_cache)
-		goto out_ai;
-
-	ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
-	if (!ech)
-		goto out_ai;
-
-	vidh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL);
-	if (!vidh)
-		goto out_ech;
-
-	for (pnum = 0; pnum < ubi->peb_count; pnum++) {
-		cond_resched();
-
-		dbg_gen("process PEB %d", pnum);
-		err = scan_peb(ubi, ai, pnum);
-		if (err < 0)
-			goto out_vidh;
-	}
-
-	ubi_msg("scanning is finished");
-
-	/* Calculate mean erase counter */
-	if (ai->ec_count)
-		ai->mean_ec = div_u64(ai->ec_sum, ai->ec_count);
-
-	err = late_analysis(ubi, ai);
-	if (err)
-		goto out_vidh;
-
-	/*
-	 * In case of unknown erase counter we use the mean erase counter
-	 * value.
-	 */
-	ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) {
-		ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb)
-			if (aeb->ec == UBI_UNKNOWN)
-				aeb->ec = ai->mean_ec;
-	}
-
-	list_for_each_entry(aeb, &ai->free, u.list) {
-		if (aeb->ec == UBI_UNKNOWN)
-			aeb->ec = ai->mean_ec;
-	}
-
-	list_for_each_entry(aeb, &ai->corr, u.list)
-		if (aeb->ec == UBI_UNKNOWN)
-			aeb->ec = ai->mean_ec;
-
-	list_for_each_entry(aeb, &ai->erase, u.list)
-		if (aeb->ec == UBI_UNKNOWN)
-			aeb->ec = ai->mean_ec;
-
-	err = self_check_ai(ubi, ai);
-	if (err)
-		goto out_vidh;
-
-	ubi_free_vid_hdr(ubi, vidh);
-	kfree(ech);
-
-	return ai;
-
-out_vidh:
-	ubi_free_vid_hdr(ubi, vidh);
-out_ech:
-	kfree(ech);
-out_ai:
-	ubi_destroy_ai(ai);
-	return ERR_PTR(err);
-}
-
-/**
- * ubi_attach - attach an MTD device.
- * @ubi: UBI device descriptor
- *
- * This function returns zero in case of success and a negative error code in
- * case of failure.
- */
-int ubi_attach(struct ubi_device *ubi)
-{
-	int err;
-	struct ubi_attach_info *ai;
-
-	ai = scan_all(ubi);
-	if (IS_ERR(ai))
-		return PTR_ERR(ai);
-
-	ubi->bad_peb_count = ai->bad_peb_count;
-	ubi->good_peb_count = ubi->peb_count - ubi->bad_peb_count;
-	ubi->corr_peb_count = ai->corr_peb_count;
-	ubi->max_ec = ai->max_ec;
-	ubi->mean_ec = ai->mean_ec;
-	dbg_gen("max. sequence number:       %llu", ai->max_sqnum);
-
-	err = ubi_read_volume_table(ubi, ai);
-	if (err)
-		goto out_ai;
-
-	err = ubi_wl_init(ubi, ai);
-	if (err)
-		goto out_vtbl;
-
-	err = ubi_eba_init(ubi, ai);
-	if (err)
-		goto out_wl;
-
-	ubi_destroy_ai(ai);
-	return 0;
-
-out_wl:
-	ubi_wl_close(ubi);
-out_vtbl:
-	ubi_free_internal_volumes(ubi);
-	vfree(ubi->vtbl);
-out_ai:
-	ubi_destroy_ai(ai);
-	return err;
-}
-
-/**
  * destroy_av - free volume attaching information.
  * @av: volume attaching information
  * @ai: attaching information
@@ -1303,10 +1163,10 @@
 }
 
 /**
- * ubi_destroy_ai - destroy attaching information.
+ * destroy_ai - destroy attaching information.
  * @ai: attaching information
  */
-void ubi_destroy_ai(struct ubi_attach_info *ai)
+static void destroy_ai(struct ubi_attach_info *ai)
 {
 	struct ubi_ainf_peb *aeb, *aeb_tmp;
 	struct ubi_ainf_volume *av;
@@ -1358,6 +1218,276 @@
 }
 
 /**
+ * scan_all - scan entire MTD device.
+ * @ubi: UBI device description object
+ * @ai: attach info object
+ * @start: start scanning at this PEB
+ *
+ * This function does full scanning of an MTD device and returns complete
+ * information about it in form of a "struct ubi_attach_info" object. In case
+ * of failure, an error code is returned.
+ */
+static int scan_all(struct ubi_device *ubi, struct ubi_attach_info *ai,
+		    int start)
+{
+	int err, pnum;
+	struct rb_node *rb1, *rb2;
+	struct ubi_ainf_volume *av;
+	struct ubi_ainf_peb *aeb;
+
+	err = -ENOMEM;
+
+	ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
+	if (!ech)
+		return err;
+
+	vidh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL);
+	if (!vidh)
+		goto out_ech;
+
+	for (pnum = start; pnum < ubi->peb_count; pnum++) {
+		cond_resched();
+
+		dbg_gen("process PEB %d", pnum);
+		err = scan_peb(ubi, ai, pnum, NULL, NULL);
+		if (err < 0)
+			goto out_vidh;
+	}
+
+	ubi_msg("scanning is finished");
+
+	/* Calculate mean erase counter */
+	if (ai->ec_count)
+		ai->mean_ec = div_u64(ai->ec_sum, ai->ec_count);
+
+	err = late_analysis(ubi, ai);
+	if (err)
+		goto out_vidh;
+
+	/*
+	 * In case of unknown erase counter we use the mean erase counter
+	 * value.
+	 */
+	ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) {
+		ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb)
+			if (aeb->ec == UBI_UNKNOWN)
+				aeb->ec = ai->mean_ec;
+	}
+
+	list_for_each_entry(aeb, &ai->free, u.list) {
+		if (aeb->ec == UBI_UNKNOWN)
+			aeb->ec = ai->mean_ec;
+	}
+
+	list_for_each_entry(aeb, &ai->corr, u.list)
+		if (aeb->ec == UBI_UNKNOWN)
+			aeb->ec = ai->mean_ec;
+
+	list_for_each_entry(aeb, &ai->erase, u.list)
+		if (aeb->ec == UBI_UNKNOWN)
+			aeb->ec = ai->mean_ec;
+
+	err = self_check_ai(ubi, ai);
+	if (err)
+		goto out_vidh;
+
+	ubi_free_vid_hdr(ubi, vidh);
+	kfree(ech);
+
+	return 0;
+
+out_vidh:
+	ubi_free_vid_hdr(ubi, vidh);
+out_ech:
+	kfree(ech);
+	return err;
+}
+
+#ifdef CONFIG_MTD_UBI_FASTMAP
+
+/**
+ * scan_fastmap - try to find a fastmap and attach from it.
+ * @ubi: UBI device description object
+ * @ai: attach info object
+ *
+ * Returns 0 on success, negative return values indicate an internal
+ * error.
+ * UBI_NO_FASTMAP denotes that no fastmap was found.
+ * UBI_BAD_FASTMAP denotes that the found fastmap was invalid.
+ */
+static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info *ai)
+{
+	int err, pnum, fm_anchor = -1;
+	unsigned long long max_sqnum = 0;
+
+	err = -ENOMEM;
+
+	ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
+	if (!ech)
+		goto out;
+
+	vidh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL);
+	if (!vidh)
+		goto out_ech;
+
+	for (pnum = 0; pnum < UBI_FM_MAX_START; pnum++) {
+		int vol_id = -1;
+		unsigned long long sqnum = -1;
+		cond_resched();
+
+		dbg_gen("process PEB %d", pnum);
+		err = scan_peb(ubi, ai, pnum, &vol_id, &sqnum);
+		if (err < 0)
+			goto out_vidh;
+
+		if (vol_id == UBI_FM_SB_VOLUME_ID && sqnum > max_sqnum) {
+			max_sqnum = sqnum;
+			fm_anchor = pnum;
+		}
+	}
+
+	ubi_free_vid_hdr(ubi, vidh);
+	kfree(ech);
+
+	if (fm_anchor < 0)
+		return UBI_NO_FASTMAP;
+
+	return ubi_scan_fastmap(ubi, ai, fm_anchor);
+
+out_vidh:
+	ubi_free_vid_hdr(ubi, vidh);
+out_ech:
+	kfree(ech);
+out:
+	return err;
+}
+
+#endif
+
+static struct ubi_attach_info *alloc_ai(const char *slab_name)
+{
+	struct ubi_attach_info *ai;
+
+	ai = kzalloc(sizeof(struct ubi_attach_info), GFP_KERNEL);
+	if (!ai)
+		return ai;
+
+	INIT_LIST_HEAD(&ai->corr);
+	INIT_LIST_HEAD(&ai->free);
+	INIT_LIST_HEAD(&ai->erase);
+	INIT_LIST_HEAD(&ai->alien);
+	ai->volumes = RB_ROOT;
+	ai->aeb_slab_cache = kmem_cache_create(slab_name,
+					       sizeof(struct ubi_ainf_peb),
+					       0, 0, NULL);
+	if (!ai->aeb_slab_cache) {
+		kfree(ai);
+		ai = NULL;
+	}
+
+	return ai;
+}
+
+/**
+ * ubi_attach - attach an MTD device.
+ * @ubi: UBI device descriptor
+ * @force_scan: if set to non-zero attach by scanning
+ *
+ * This function returns zero in case of success and a negative error code in
+ * case of failure.
+ */
+int ubi_attach(struct ubi_device *ubi, int force_scan)
+{
+	int err;
+	struct ubi_attach_info *ai;
+
+	ai = alloc_ai("ubi_aeb_slab_cache");
+	if (!ai)
+		return -ENOMEM;
+
+#ifdef CONFIG_MTD_UBI_FASTMAP
+	/* On small flash devices we disable fastmap in any case. */
+	if ((int)mtd_div_by_eb(ubi->mtd->size, ubi->mtd) <= UBI_FM_MAX_START) {
+		ubi->fm_disabled = 1;
+		force_scan = 1;
+	}
+
+	if (force_scan)
+		err = scan_all(ubi, ai, 0);
+	else {
+		err = scan_fast(ubi, ai);
+		if (err > 0) {
+			if (err != UBI_NO_FASTMAP) {
+				destroy_ai(ai);
+				ai = alloc_ai("ubi_aeb_slab_cache2");
+				if (!ai)
+					return -ENOMEM;
+			}
+
+			err = scan_all(ubi, ai, UBI_FM_MAX_START);
+		}
+	}
+#else
+	err = scan_all(ubi, ai, 0);
+#endif
+	if (err)
+		goto out_ai;
+
+	ubi->bad_peb_count = ai->bad_peb_count;
+	ubi->good_peb_count = ubi->peb_count - ubi->bad_peb_count;
+	ubi->corr_peb_count = ai->corr_peb_count;
+	ubi->max_ec = ai->max_ec;
+	ubi->mean_ec = ai->mean_ec;
+	dbg_gen("max. sequence number:       %llu", ai->max_sqnum);
+
+	err = ubi_read_volume_table(ubi, ai);
+	if (err)
+		goto out_ai;
+
+	err = ubi_wl_init(ubi, ai);
+	if (err)
+		goto out_vtbl;
+
+	err = ubi_eba_init(ubi, ai);
+	if (err)
+		goto out_wl;
+
+#ifdef CONFIG_MTD_UBI_FASTMAP
+	if (ubi->fm && ubi->dbg->chk_gen) {
+		struct ubi_attach_info *scan_ai;
+
+		scan_ai = alloc_ai("ubi_ckh_aeb_slab_cache");
+		if (!scan_ai)
+			goto out_wl;
+
+		err = scan_all(ubi, scan_ai, 0);
+		if (err) {
+			destroy_ai(scan_ai);
+			goto out_wl;
+		}
+
+		err = self_check_eba(ubi, ai, scan_ai);
+		destroy_ai(scan_ai);
+
+		if (err)
+			goto out_wl;
+	}
+#endif
+
+	destroy_ai(ai);
+	return 0;
+
+out_wl:
+	ubi_wl_close(ubi);
+out_vtbl:
+	ubi_free_internal_volumes(ubi);
+	vfree(ubi->vtbl);
+out_ai:
+	destroy_ai(ai);
+	return err;
+}
+
+/**
  * self_check_ai - check the attaching information.
  * @ubi: UBI device description object
  * @ai: attaching information
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 3497703..344b4cb 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -76,7 +76,10 @@
 
 /* MTD devices specification parameters */
 static struct mtd_dev_param __initdata mtd_dev_param[UBI_MAX_DEVICES];
-
+#ifdef CONFIG_MTD_UBI_FASTMAP
+/* UBI module parameter to enable fastmap automatically on non-fastmap images */
+static bool fm_autoconvert;
+#endif
 /* Root UBI "class" object (corresponds to '/<sysfs>/class/ubi/') */
 struct class *ubi_class;
 
@@ -153,6 +156,19 @@
 
 	ubi_do_get_device_info(ubi, &nt.di);
 	ubi_do_get_volume_info(ubi, vol, &nt.vi);
+
+#ifdef CONFIG_MTD_UBI_FASTMAP
+	switch (ntype) {
+	case UBI_VOLUME_ADDED:
+	case UBI_VOLUME_REMOVED:
+	case UBI_VOLUME_RESIZED:
+	case UBI_VOLUME_RENAMED:
+		if (ubi_update_fastmap(ubi)) {
+			ubi_err("Unable to update fastmap!");
+			ubi_ro_mode(ubi);
+		}
+	}
+#endif
 	return blocking_notifier_call_chain(&ubi_notifiers, ntype, &nt);
 }
 
@@ -918,10 +934,40 @@
 	ubi->vid_hdr_offset = vid_hdr_offset;
 	ubi->autoresize_vol_id = -1;
 
+#ifdef CONFIG_MTD_UBI_FASTMAP
+	ubi->fm_pool.used = ubi->fm_pool.size = 0;
+	ubi->fm_wl_pool.used = ubi->fm_wl_pool.size = 0;
+
+	/*
+	 * fm_pool.max_size is 5% of the total number of PEBs but it's also
+	 * between UBI_FM_MAX_POOL_SIZE and UBI_FM_MIN_POOL_SIZE.
+	 */
+	ubi->fm_pool.max_size = min(((int)mtd_div_by_eb(ubi->mtd->size,
+		ubi->mtd) / 100) * 5, UBI_FM_MAX_POOL_SIZE);
+	if (ubi->fm_pool.max_size < UBI_FM_MIN_POOL_SIZE)
+		ubi->fm_pool.max_size = UBI_FM_MIN_POOL_SIZE;
+
+	ubi->fm_wl_pool.max_size = UBI_FM_WL_POOL_SIZE;
+	ubi->fm_disabled = !fm_autoconvert;
+
+	if (!ubi->fm_disabled && (int)mtd_div_by_eb(ubi->mtd->size, ubi->mtd)
+	    <= UBI_FM_MAX_START) {
+		ubi_err("More than %i PEBs are needed for fastmap, sorry.",
+			UBI_FM_MAX_START);
+		ubi->fm_disabled = 1;
+	}
+
+	ubi_msg("default fastmap pool size: %d", ubi->fm_pool.max_size);
+	ubi_msg("default fastmap WL pool size: %d", ubi->fm_wl_pool.max_size);
+#else
+	ubi->fm_disabled = 1;
+#endif
 	mutex_init(&ubi->buf_mutex);
 	mutex_init(&ubi->ckvol_mutex);
 	mutex_init(&ubi->device_mutex);
 	spin_lock_init(&ubi->volumes_lock);
+	mutex_init(&ubi->fm_mutex);
+	init_rwsem(&ubi->fm_sem);
 
 	ubi_msg("attaching mtd%d to ubi%d", mtd->index, ubi_num);
 
@@ -934,11 +980,17 @@
 	if (!ubi->peb_buf)
 		goto out_free;
 
+#ifdef CONFIG_MTD_UBI_FASTMAP
+	ubi->fm_size = ubi_calc_fm_size(ubi);
+	ubi->fm_buf = vzalloc(ubi->fm_size);
+	if (!ubi->fm_buf)
+		goto out_free;
+#endif
 	err = ubi_debugging_init_dev(ubi);
 	if (err)
 		goto out_free;
 
-	err = ubi_attach(ubi);
+	err = ubi_attach(ubi, 0);
 	if (err) {
 		ubi_err("failed to attach mtd%d, error %d", mtd->index, err);
 		goto out_debugging;
@@ -1012,6 +1064,7 @@
 	ubi_debugging_exit_dev(ubi);
 out_free:
 	vfree(ubi->peb_buf);
+	vfree(ubi->fm_buf);
 	if (ref)
 		put_device(&ubi->dev);
 	else
@@ -1061,7 +1114,11 @@
 	ubi_assert(ubi_num == ubi->ubi_num);
 	ubi_notify_all(ubi, UBI_VOLUME_REMOVED, NULL);
 	ubi_msg("detaching mtd%d from ubi%d", ubi->mtd->index, ubi_num);
-
+#ifdef CONFIG_MTD_UBI_FASTMAP
+	/* If we don't write a new fastmap at detach time we lose all
+	 * EC updates that have been made since the last written fastmap. */
+	ubi_update_fastmap(ubi);
+#endif
 	/*
 	 * Before freeing anything, we have to stop the background thread to
 	 * prevent it from doing anything on this device while we are freeing.
@@ -1077,12 +1134,14 @@
 
 	ubi_debugfs_exit_dev(ubi);
 	uif_close(ubi);
+
 	ubi_wl_close(ubi);
 	ubi_free_internal_volumes(ubi);
 	vfree(ubi->vtbl);
 	put_mtd_device(ubi->mtd);
 	ubi_debugging_exit_dev(ubi);
 	vfree(ubi->peb_buf);
+	vfree(ubi->fm_buf);
 	ubi_msg("mtd%d is detached from ubi%d", ubi->mtd->index, ubi->ubi_num);
 	put_device(&ubi->dev);
 	return 0;
@@ -1404,7 +1463,10 @@
 		      "Example 2: mtd=content,1984 mtd=4 - attach MTD device with name \"content\" using VID header offset 1984, and MTD device number 4 with default VID header offset.\n"
 		      "Example 3: mtd=/dev/mtd1,0,25 - attach MTD device /dev/mtd1 using default VID header offset and reserve 25*nand_size_in_blocks/1024 erase blocks for bad block handling.\n"
 		      "\t(e.g. if the NAND *chipset* has 4096 PEB, 100 will be reserved for this UBI device).");
-
+#ifdef CONFIG_MTD_UBI_FASTMAP
+module_param(fm_autoconvert, bool, 0644);
+MODULE_PARM_DESC(fm_autoconvert, "Set this parameter to enable fastmap automatically on images without a fastmap.");
+#endif
 MODULE_VERSION(__stringify(UBI_VERSION));
 MODULE_DESCRIPTION("UBI - Unsorted Block Images");
 MODULE_AUTHOR("Artem Bityutskiy");
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c
index a26d7d2..0e11671d 100644
--- a/drivers/mtd/ubi/eba.c
+++ b/drivers/mtd/ubi/eba.c
@@ -57,7 +57,7 @@
  * global sequence counter value. It also increases the global sequence
  * counter.
  */
-static unsigned long long next_sqnum(struct ubi_device *ubi)
+unsigned long long ubi_next_sqnum(struct ubi_device *ubi)
 {
 	unsigned long long sqnum;
 
@@ -340,7 +340,9 @@
 
 	dbg_eba("erase LEB %d:%d, PEB %d", vol_id, lnum, pnum);
 
+	down_read(&ubi->fm_sem);
 	vol->eba_tbl[lnum] = UBI_LEB_UNMAPPED;
+	up_read(&ubi->fm_sem);
 	err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 0);
 
 out_unlock:
@@ -521,7 +523,7 @@
 		goto out_put;
 	}
 
-	vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
+	vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
 	err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr);
 	if (err)
 		goto write_error;
@@ -548,7 +550,9 @@
 	mutex_unlock(&ubi->buf_mutex);
 	ubi_free_vid_hdr(ubi, vid_hdr);
 
+	down_read(&ubi->fm_sem);
 	vol->eba_tbl[lnum] = new_pnum;
+	up_read(&ubi->fm_sem);
 	ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1);
 
 	ubi_msg("data was successfully recovered");
@@ -632,7 +636,7 @@
 	}
 
 	vid_hdr->vol_type = UBI_VID_DYNAMIC;
-	vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
+	vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
 	vid_hdr->vol_id = cpu_to_be32(vol_id);
 	vid_hdr->lnum = cpu_to_be32(lnum);
 	vid_hdr->compat = ubi_get_compat(ubi, vol_id);
@@ -665,7 +669,9 @@
 		}
 	}
 
+	down_read(&ubi->fm_sem);
 	vol->eba_tbl[lnum] = pnum;
+	up_read(&ubi->fm_sem);
 
 	leb_write_unlock(ubi, vol_id, lnum);
 	ubi_free_vid_hdr(ubi, vid_hdr);
@@ -692,7 +698,7 @@
 		return err;
 	}
 
-	vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
+	vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
 	ubi_msg("try another PEB");
 	goto retry;
 }
@@ -745,7 +751,7 @@
 		return err;
 	}
 
-	vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
+	vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
 	vid_hdr->vol_id = cpu_to_be32(vol_id);
 	vid_hdr->lnum = cpu_to_be32(lnum);
 	vid_hdr->compat = ubi_get_compat(ubi, vol_id);
@@ -783,7 +789,9 @@
 	}
 
 	ubi_assert(vol->eba_tbl[lnum] < 0);
+	down_read(&ubi->fm_sem);
 	vol->eba_tbl[lnum] = pnum;
+	up_read(&ubi->fm_sem);
 
 	leb_write_unlock(ubi, vol_id, lnum);
 	ubi_free_vid_hdr(ubi, vid_hdr);
@@ -810,7 +818,7 @@
 		return err;
 	}
 
-	vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
+	vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
 	ubi_msg("try another PEB");
 	goto retry;
 }
@@ -862,7 +870,7 @@
 	if (err)
 		goto out_mutex;
 
-	vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
+	vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
 	vid_hdr->vol_id = cpu_to_be32(vol_id);
 	vid_hdr->lnum = cpu_to_be32(lnum);
 	vid_hdr->compat = ubi_get_compat(ubi, vol_id);
@@ -904,7 +912,9 @@
 			goto out_leb_unlock;
 	}
 
+	down_read(&ubi->fm_sem);
 	vol->eba_tbl[lnum] = pnum;
+	up_read(&ubi->fm_sem);
 
 out_leb_unlock:
 	leb_write_unlock(ubi, vol_id, lnum);
@@ -930,7 +940,7 @@
 		goto out_leb_unlock;
 	}
 
-	vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
+	vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
 	ubi_msg("try another PEB");
 	goto retry;
 }
@@ -1089,7 +1099,7 @@
 		vid_hdr->data_size = cpu_to_be32(data_size);
 		vid_hdr->data_crc = cpu_to_be32(crc);
 	}
-	vid_hdr->sqnum = cpu_to_be64(next_sqnum(ubi));
+	vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
 
 	err = ubi_io_write_vid_hdr(ubi, to, vid_hdr);
 	if (err) {
@@ -1151,7 +1161,9 @@
 	}
 
 	ubi_assert(vol->eba_tbl[lnum] == from);
+	down_read(&ubi->fm_sem);
 	vol->eba_tbl[lnum] = to;
+	up_read(&ubi->fm_sem);
 
 out_unlock_buf:
 	mutex_unlock(&ubi->buf_mutex);
@@ -1202,6 +1214,102 @@
 }
 
 /**
+ * self_check_eba - run a self check on the EBA table constructed by fastmap.
+ * @ubi: UBI device description object
+ * @ai_fastmap: UBI attach info object created by fastmap
+ * @ai_scan: UBI attach info object created by scanning
+ *
+ * Returns < 0 in case of an internal error, 0 otherwise.
+ * If a bad EBA table entry was found it will be printed out and
+ * ubi_assert() triggers.
+ */
+int self_check_eba(struct ubi_device *ubi, struct ubi_attach_info *ai_fastmap,
+		   struct ubi_attach_info *ai_scan)
+{
+	int i, j, num_volumes, ret = 0;
+	int **scan_eba, **fm_eba;
+	struct ubi_ainf_volume *av;
+	struct ubi_volume *vol;
+	struct ubi_ainf_peb *aeb;
+	struct rb_node *rb;
+
+	num_volumes = ubi->vtbl_slots + UBI_INT_VOL_COUNT;
+
+	scan_eba = kmalloc(sizeof(*scan_eba) * num_volumes, GFP_KERNEL);
+	if (!scan_eba)
+		return -ENOMEM;
+
+	fm_eba = kmalloc(sizeof(*fm_eba) * num_volumes, GFP_KERNEL);
+	if (!fm_eba) {
+		kfree(scan_eba);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < num_volumes; i++) {
+		vol = ubi->volumes[i];
+		if (!vol)
+			continue;
+
+		scan_eba[i] = kmalloc(vol->reserved_pebs * sizeof(**scan_eba),
+				      GFP_KERNEL);
+		if (!scan_eba[i]) {
+			ret = -ENOMEM;
+			goto out_free;
+		}
+
+		fm_eba[i] = kmalloc(vol->reserved_pebs * sizeof(**fm_eba),
+				    GFP_KERNEL);
+		if (!fm_eba[i]) {
+			ret = -ENOMEM;
+			goto out_free;
+		}
+
+		for (j = 0; j < vol->reserved_pebs; j++)
+			scan_eba[i][j] = fm_eba[i][j] = UBI_LEB_UNMAPPED;
+
+		av = ubi_find_av(ai_scan, idx2vol_id(ubi, i));
+		if (!av)
+			continue;
+
+		ubi_rb_for_each_entry(rb, aeb, &av->root, u.rb)
+			scan_eba[i][aeb->lnum] = aeb->pnum;
+
+		av = ubi_find_av(ai_fastmap, idx2vol_id(ubi, i));
+		if (!av)
+			continue;
+
+		ubi_rb_for_each_entry(rb, aeb, &av->root, u.rb)
+			fm_eba[i][aeb->lnum] = aeb->pnum;
+
+		for (j = 0; j < vol->reserved_pebs; j++) {
+			if (scan_eba[i][j] != fm_eba[i][j]) {
+				if (scan_eba[i][j] == UBI_LEB_UNMAPPED ||
+					fm_eba[i][j] == UBI_LEB_UNMAPPED)
+					continue;
+
+				ubi_err("LEB:%i:%i is PEB:%i instead of %i!",
+					vol->vol_id, i, fm_eba[i][j],
+					scan_eba[i][j]);
+				ubi_assert(0);
+			}
+		}
+	}
+
+out_free:
+	for (i = 0; i < num_volumes; i++) {
+		if (!ubi->volumes[i])
+			continue;
+
+		kfree(scan_eba[i]);
+		kfree(fm_eba[i]);
+	}
+
+	kfree(scan_eba);
+	kfree(fm_eba);
+	return ret;
+}
+
+/**
  * ubi_eba_init - initialize the EBA sub-system using attaching information.
  * @ubi: UBI device description object
  * @ai: attaching information
diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
new file mode 100644
index 0000000..1a5f53c
--- /dev/null
+++ b/drivers/mtd/ubi/fastmap.c
@@ -0,0 +1,1537 @@
+/*
+ * Copyright (c) 2012 Linutronix GmbH
+ * Author: Richard Weinberger <richard@nod.at>
+ *
+ * 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; version 2.
+ *
+ * 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/crc32.h>
+#include "ubi.h"
+
+/**
+ * ubi_calc_fm_size - calculates the fastmap size in bytes for an UBI device.
+ * @ubi: UBI device description object
+ */
+size_t ubi_calc_fm_size(struct ubi_device *ubi)
+{
+	size_t size;
+
+	size = sizeof(struct ubi_fm_hdr) + \
+		sizeof(struct ubi_fm_scan_pool) + \
+		sizeof(struct ubi_fm_scan_pool) + \
+		(ubi->peb_count * sizeof(struct ubi_fm_ec)) + \
+		(sizeof(struct ubi_fm_eba) + \
+		(ubi->peb_count * sizeof(__be32))) + \
+		sizeof(struct ubi_fm_volhdr) * UBI_MAX_VOLUMES;
+	return roundup(size, ubi->leb_size);
+}
+
+
+/**
+ * new_fm_vhdr - allocate a new volume header for fastmap usage.
+ * @ubi: UBI device description object
+ * @vol_id: the VID of the new header
+ *
+ * Returns a new struct ubi_vid_hdr on success.
+ * NULL indicates out of memory.
+ */
+static struct ubi_vid_hdr *new_fm_vhdr(struct ubi_device *ubi, int vol_id)
+{
+	struct ubi_vid_hdr *new;
+
+	new = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL);
+	if (!new)
+		goto out;
+
+	new->vol_type = UBI_VID_DYNAMIC;
+	new->vol_id = cpu_to_be32(vol_id);
+
+	/* UBI implementations without fastmap support have to delete the
+	 * fastmap.
+	 */
+	new->compat = UBI_COMPAT_DELETE;
+
+out:
+	return new;
+}
+
+/**
+ * add_aeb - create and add a attach erase block to a given list.
+ * @ai: UBI attach info object
+ * @list: the target list
+ * @pnum: PEB number of the new attach erase block
+ * @ec: erease counter of the new LEB
+ * @scrub: scrub this PEB after attaching
+ *
+ * Returns 0 on success, < 0 indicates an internal error.
+ */
+static int add_aeb(struct ubi_attach_info *ai, struct list_head *list,
+		   int pnum, int ec, int scrub)
+{
+	struct ubi_ainf_peb *aeb;
+
+	aeb = kmem_cache_alloc(ai->aeb_slab_cache, GFP_KERNEL);
+	if (!aeb)
+		return -ENOMEM;
+
+	aeb->pnum = pnum;
+	aeb->ec = ec;
+	aeb->lnum = -1;
+	aeb->scrub = scrub;
+	aeb->copy_flag = aeb->sqnum = 0;
+
+	ai->ec_sum += aeb->ec;
+	ai->ec_count++;
+
+	if (ai->max_ec < aeb->ec)
+		ai->max_ec = aeb->ec;
+
+	if (ai->min_ec > aeb->ec)
+		ai->min_ec = aeb->ec;
+
+	list_add_tail(&aeb->u.list, list);
+
+	return 0;
+}
+
+/**
+ * add_vol - create and add a new volume to ubi_attach_info.
+ * @ai: ubi_attach_info object
+ * @vol_id: VID of the new volume
+ * @used_ebs: number of used EBS
+ * @data_pad: data padding value of the new volume
+ * @vol_type: volume type
+ * @last_eb_bytes: number of bytes in the last LEB
+ *
+ * Returns the new struct ubi_ainf_volume on success.
+ * NULL indicates an error.
+ */
+static struct ubi_ainf_volume *add_vol(struct ubi_attach_info *ai, int vol_id,
+				       int used_ebs, int data_pad, u8 vol_type,
+				       int last_eb_bytes)
+{
+	struct ubi_ainf_volume *av;
+	struct rb_node **p = &ai->volumes.rb_node, *parent = NULL;
+
+	while (*p) {
+		parent = *p;
+		av = rb_entry(parent, struct ubi_ainf_volume, rb);
+
+		if (vol_id > av->vol_id)
+			p = &(*p)->rb_left;
+		else if (vol_id > av->vol_id)
+			p = &(*p)->rb_right;
+	}
+
+	av = kmalloc(sizeof(struct ubi_ainf_volume), GFP_KERNEL);
+	if (!av)
+		goto out;
+
+	av->highest_lnum = av->leb_count = 0;
+	av->vol_id = vol_id;
+	av->used_ebs = used_ebs;
+	av->data_pad = data_pad;
+	av->last_data_size = last_eb_bytes;
+	av->compat = 0;
+	av->vol_type = vol_type;
+	av->root = RB_ROOT;
+
+	dbg_bld("found volume (ID %i)", vol_id);
+
+	rb_link_node(&av->rb, parent, p);
+	rb_insert_color(&av->rb, &ai->volumes);
+
+out:
+	return av;
+}
+
+/**
+ * assign_aeb_to_av - assigns a SEB to a given ainf_volume and removes it
+ * from it's original list.
+ * @ai: ubi_attach_info object
+ * @aeb: the to be assigned SEB
+ * @av: target scan volume
+ */
+static void assign_aeb_to_av(struct ubi_attach_info *ai,
+			     struct ubi_ainf_peb *aeb,
+			     struct ubi_ainf_volume *av)
+{
+	struct ubi_ainf_peb *tmp_aeb;
+	struct rb_node **p = &ai->volumes.rb_node, *parent = NULL;
+
+	p = &av->root.rb_node;
+	while (*p) {
+		parent = *p;
+
+		tmp_aeb = rb_entry(parent, struct ubi_ainf_peb, u.rb);
+		if (aeb->lnum != tmp_aeb->lnum) {
+			if (aeb->lnum < tmp_aeb->lnum)
+				p = &(*p)->rb_left;
+			else
+				p = &(*p)->rb_right;
+
+			continue;
+		} else
+			break;
+	}
+
+	list_del(&aeb->u.list);
+	av->leb_count++;
+
+	rb_link_node(&aeb->u.rb, parent, p);
+	rb_insert_color(&aeb->u.rb, &av->root);
+}
+
+/**
+ * update_vol - inserts or updates a LEB which was found a pool.
+ * @ubi: the UBI device object
+ * @ai: attach info object
+ * @av: the volume this LEB belongs to
+ * @new_vh: the volume header derived from new_aeb
+ * @new_aeb: the AEB to be examined
+ *
+ * Returns 0 on success, < 0 indicates an internal error.
+ */
+static int update_vol(struct ubi_device *ubi, struct ubi_attach_info *ai,
+		      struct ubi_ainf_volume *av, struct ubi_vid_hdr *new_vh,
+		      struct ubi_ainf_peb *new_aeb)
+{
+	struct rb_node **p = &av->root.rb_node, *parent = NULL;
+	struct ubi_ainf_peb *aeb, *victim;
+	int cmp_res;
+
+	while (*p) {
+		parent = *p;
+		aeb = rb_entry(parent, struct ubi_ainf_peb, u.rb);
+
+		if (be32_to_cpu(new_vh->lnum) != aeb->lnum) {
+			if (be32_to_cpu(new_vh->lnum) < aeb->lnum)
+				p = &(*p)->rb_left;
+			else
+				p = &(*p)->rb_right;
+
+			continue;
+		}
+
+		/* This case can happen if the fastmap gets written
+		 * because of a volume change (creation, deletion, ..).
+		 * Then a PEB can be within the persistent EBA and the pool.
+		 */
+		if (aeb->pnum == new_aeb->pnum) {
+			ubi_assert(aeb->lnum == new_aeb->lnum);
+			kmem_cache_free(ai->aeb_slab_cache, new_aeb);
+
+			return 0;
+		}
+
+		cmp_res = ubi_compare_lebs(ubi, aeb, new_aeb->pnum, new_vh);
+		if (cmp_res < 0)
+			return cmp_res;
+
+		/* new_aeb is newer */
+		if (cmp_res & 1) {
+			victim = kmem_cache_alloc(ai->aeb_slab_cache,
+				GFP_KERNEL);
+			if (!victim)
+				return -ENOMEM;
+
+			victim->ec = aeb->ec;
+			victim->pnum = aeb->pnum;
+			list_add_tail(&victim->u.list, &ai->erase);
+
+			if (av->highest_lnum == be32_to_cpu(new_vh->lnum))
+				av->last_data_size = \
+					be32_to_cpu(new_vh->data_size);
+
+			dbg_bld("vol %i: AEB %i's PEB %i is the newer",
+				av->vol_id, aeb->lnum, new_aeb->pnum);
+
+			aeb->ec = new_aeb->ec;
+			aeb->pnum = new_aeb->pnum;
+			aeb->copy_flag = new_vh->copy_flag;
+			aeb->scrub = new_aeb->scrub;
+			kmem_cache_free(ai->aeb_slab_cache, new_aeb);
+
+		/* new_aeb is older */
+		} else {
+			dbg_bld("vol %i: AEB %i's PEB %i is old, dropping it",
+				av->vol_id, aeb->lnum, new_aeb->pnum);
+			list_add_tail(&new_aeb->u.list, &ai->erase);
+		}
+
+		return 0;
+	}
+	/* This LEB is new, let's add it to the volume */
+
+	if (av->highest_lnum <= be32_to_cpu(new_vh->lnum)) {
+		av->highest_lnum = be32_to_cpu(new_vh->lnum);
+		av->last_data_size = be32_to_cpu(new_vh->data_size);
+	}
+
+	if (av->vol_type == UBI_STATIC_VOLUME)
+		av->used_ebs = be32_to_cpu(new_vh->used_ebs);
+
+	av->leb_count++;
+
+	rb_link_node(&new_aeb->u.rb, parent, p);
+	rb_insert_color(&new_aeb->u.rb, &av->root);
+
+	return 0;
+}
+
+/**
+ * process_pool_aeb - we found a non-empty PEB in a pool.
+ * @ubi: UBI device object
+ * @ai: attach info object
+ * @new_vh: the volume header derived from new_aeb
+ * @new_aeb: the AEB to be examined
+ *
+ * Returns 0 on success, < 0 indicates an internal error.
+ */
+static int process_pool_aeb(struct ubi_device *ubi, struct ubi_attach_info *ai,
+			    struct ubi_vid_hdr *new_vh,
+			    struct ubi_ainf_peb *new_aeb)
+{
+	struct ubi_ainf_volume *av, *tmp_av = NULL;
+	struct rb_node **p = &ai->volumes.rb_node, *parent = NULL;
+	int found = 0;
+
+	if (be32_to_cpu(new_vh->vol_id) == UBI_FM_SB_VOLUME_ID ||
+		be32_to_cpu(new_vh->vol_id) == UBI_FM_DATA_VOLUME_ID) {
+		kmem_cache_free(ai->aeb_slab_cache, new_aeb);
+
+		return 0;
+	}
+
+	/* Find the volume this SEB belongs to */
+	while (*p) {
+		parent = *p;
+		tmp_av = rb_entry(parent, struct ubi_ainf_volume, rb);
+
+		if (be32_to_cpu(new_vh->vol_id) > tmp_av->vol_id)
+			p = &(*p)->rb_left;
+		else if (be32_to_cpu(new_vh->vol_id) < tmp_av->vol_id)
+			p = &(*p)->rb_right;
+		else {
+			found = 1;
+			break;
+		}
+	}
+
+	if (found)
+		av = tmp_av;
+	else {
+		ubi_err("orphaned volume in fastmap pool!");
+		return UBI_BAD_FASTMAP;
+	}
+
+	ubi_assert(be32_to_cpu(new_vh->vol_id) == av->vol_id);
+
+	return update_vol(ubi, ai, av, new_vh, new_aeb);
+}
+
+/**
+ * unmap_peb - unmap a PEB.
+ * If fastmap detects a free PEB in the pool it has to check whether
+ * this PEB has been unmapped after writing the fastmap.
+ *
+ * @ai: UBI attach info object
+ * @pnum: The PEB to be unmapped
+ */
+static void unmap_peb(struct ubi_attach_info *ai, int pnum)
+{
+	struct ubi_ainf_volume *av;
+	struct rb_node *node, *node2;
+	struct ubi_ainf_peb *aeb;
+
+	for (node = rb_first(&ai->volumes); node; node = rb_next(node)) {
+		av = rb_entry(node, struct ubi_ainf_volume, rb);
+
+		for (node2 = rb_first(&av->root); node2;
+		     node2 = rb_next(node2)) {
+			aeb = rb_entry(node2, struct ubi_ainf_peb, u.rb);
+			if (aeb->pnum == pnum) {
+				rb_erase(&aeb->u.rb, &av->root);
+				kmem_cache_free(ai->aeb_slab_cache, aeb);
+				return;
+			}
+		}
+	}
+}
+
+/**
+ * scan_pool - scans a pool for changed (no longer empty PEBs).
+ * @ubi: UBI device object
+ * @ai: attach info object
+ * @pebs: an array of all PEB numbers in the to be scanned pool
+ * @pool_size: size of the pool (number of entries in @pebs)
+ * @max_sqnum: pointer to the maximal sequence number
+ * @eba_orphans: list of PEBs which need to be scanned
+ * @free: list of PEBs which are most likely free (and go into @ai->free)
+ *
+ * Returns 0 on success, if the pool is unusable UBI_BAD_FASTMAP is returned.
+ * < 0 indicates an internal error.
+ */
+static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai,
+		     int *pebs, int pool_size, unsigned long long *max_sqnum,
+		     struct list_head *eba_orphans, struct list_head *free)
+{
+	struct ubi_vid_hdr *vh;
+	struct ubi_ec_hdr *ech;
+	struct ubi_ainf_peb *new_aeb, *tmp_aeb;
+	int i, pnum, err, found_orphan, ret = 0;
+
+	ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
+	if (!ech)
+		return -ENOMEM;
+
+	vh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL);
+	if (!vh) {
+		kfree(ech);
+		return -ENOMEM;
+	}
+
+	dbg_bld("scanning fastmap pool: size = %i", pool_size);
+
+	/*
+	 * Now scan all PEBs in the pool to find changes which have been made
+	 * after the creation of the fastmap
+	 */
+	for (i = 0; i < pool_size; i++) {
+		int scrub = 0;
+
+		pnum = be32_to_cpu(pebs[i]);
+
+		if (ubi_io_is_bad(ubi, pnum)) {
+			ubi_err("bad PEB in fastmap pool!");
+			ret = UBI_BAD_FASTMAP;
+			goto out;
+		}
+
+		err = ubi_io_read_ec_hdr(ubi, pnum, ech, 0);
+		if (err && err != UBI_IO_BITFLIPS) {
+			ubi_err("unable to read EC header! PEB:%i err:%i",
+				pnum, err);
+			ret = err > 0 ? UBI_BAD_FASTMAP : err;
+			goto out;
+		} else if (ret == UBI_IO_BITFLIPS)
+			scrub = 1;
+
+		if (be32_to_cpu(ech->image_seq) != ubi->image_seq) {
+			ubi_err("bad image seq: 0x%x, expected: 0x%x",
+				be32_to_cpu(ech->image_seq), ubi->image_seq);
+			err = UBI_BAD_FASTMAP;
+			goto out;
+		}
+
+		err = ubi_io_read_vid_hdr(ubi, pnum, vh, 0);
+		if (err == UBI_IO_FF || err == UBI_IO_FF_BITFLIPS) {
+			unsigned long long ec = be64_to_cpu(ech->ec);
+			unmap_peb(ai, pnum);
+			dbg_bld("Adding PEB to free: %i", pnum);
+			if (err == UBI_IO_FF_BITFLIPS)
+				add_aeb(ai, free, pnum, ec, 1);
+			else
+				add_aeb(ai, free, pnum, ec, 0);
+			continue;
+		} else if (err == 0 || err == UBI_IO_BITFLIPS) {
+			dbg_bld("Found non empty PEB:%i in pool", pnum);
+
+			if (err == UBI_IO_BITFLIPS)
+				scrub = 1;
+
+			found_orphan = 0;
+			list_for_each_entry(tmp_aeb, eba_orphans, u.list) {
+				if (tmp_aeb->pnum == pnum) {
+					found_orphan = 1;
+					break;
+				}
+			}
+			if (found_orphan) {
+				kmem_cache_free(ai->aeb_slab_cache, tmp_aeb);
+				list_del(&tmp_aeb->u.list);
+			}
+
+			new_aeb = kmem_cache_alloc(ai->aeb_slab_cache,
+						   GFP_KERNEL);
+			if (!new_aeb) {
+				ret = -ENOMEM;
+				goto out;
+			}
+
+			new_aeb->ec = be64_to_cpu(ech->ec);
+			new_aeb->pnum = pnum;
+			new_aeb->lnum = be32_to_cpu(vh->lnum);
+			new_aeb->sqnum = be64_to_cpu(vh->sqnum);
+			new_aeb->copy_flag = vh->copy_flag;
+			new_aeb->scrub = scrub;
+
+			if (*max_sqnum < new_aeb->sqnum)
+				*max_sqnum = new_aeb->sqnum;
+
+			err = process_pool_aeb(ubi, ai, vh, new_aeb);
+			if (err) {
+				ret = err > 0 ? UBI_BAD_FASTMAP : err;
+				goto out;
+			}
+		} else {
+			/* We are paranoid and fall back to scanning mode */
+			ubi_err("fastmap pool PEBs contains damaged PEBs!");
+			ret = err > 0 ? UBI_BAD_FASTMAP : err;
+			goto out;
+		}
+
+	}
+
+out:
+	ubi_free_vid_hdr(ubi, vh);
+	kfree(ech);
+	return ret;
+}
+
+/**
+ * count_fastmap_pebs - Counts the PEBs found by fastmap.
+ * @ai: The UBI attach info object
+ */
+static int count_fastmap_pebs(struct ubi_attach_info *ai)
+{
+	struct ubi_ainf_peb *aeb;
+	struct ubi_ainf_volume *av;
+	struct rb_node *rb1, *rb2;
+	int n = 0;
+
+	list_for_each_entry(aeb, &ai->erase, u.list)
+		n++;
+
+	list_for_each_entry(aeb, &ai->free, u.list)
+		n++;
+
+	 ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb)
+		ubi_rb_for_each_entry(rb2, aeb, &av->root, u.rb)
+			n++;
+
+	return n;
+}
+
+/**
+ * ubi_attach_fastmap - creates ubi_attach_info from a fastmap.
+ * @ubi: UBI device object
+ * @ai: UBI attach info object
+ * @fm: the fastmap to be attached
+ *
+ * Returns 0 on success, UBI_BAD_FASTMAP if the found fastmap was unusable.
+ * < 0 indicates an internal error.
+ */
+static int ubi_attach_fastmap(struct ubi_device *ubi,
+			      struct ubi_attach_info *ai,
+			      struct ubi_fastmap_layout *fm)
+{
+	struct list_head used, eba_orphans, free;
+	struct ubi_ainf_volume *av;
+	struct ubi_ainf_peb *aeb, *tmp_aeb, *_tmp_aeb;
+	struct ubi_ec_hdr *ech;
+	struct ubi_fm_sb *fmsb;
+	struct ubi_fm_hdr *fmhdr;
+	struct ubi_fm_scan_pool *fmpl1, *fmpl2;
+	struct ubi_fm_ec *fmec;
+	struct ubi_fm_volhdr *fmvhdr;
+	struct ubi_fm_eba *fm_eba;
+	int ret, i, j, pool_size, wl_pool_size;
+	size_t fm_pos = 0, fm_size = ubi->fm_size;
+	unsigned long long max_sqnum = 0;
+	void *fm_raw = ubi->fm_buf;
+
+	INIT_LIST_HEAD(&used);
+	INIT_LIST_HEAD(&free);
+	INIT_LIST_HEAD(&eba_orphans);
+	INIT_LIST_HEAD(&ai->corr);
+	INIT_LIST_HEAD(&ai->free);
+	INIT_LIST_HEAD(&ai->erase);
+	INIT_LIST_HEAD(&ai->alien);
+	ai->volumes = RB_ROOT;
+	ai->min_ec = UBI_MAX_ERASECOUNTER;
+
+	ai->aeb_slab_cache = kmem_cache_create("ubi_ainf_peb_slab",
+					       sizeof(struct ubi_ainf_peb),
+					       0, 0, NULL);
+	if (!ai->aeb_slab_cache) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	fmsb = (struct ubi_fm_sb *)(fm_raw);
+	ai->max_sqnum = fmsb->sqnum;
+	fm_pos += sizeof(struct ubi_fm_sb);
+	if (fm_pos >= fm_size)
+		goto fail_bad;
+
+	fmhdr = (struct ubi_fm_hdr *)(fm_raw + fm_pos);
+	fm_pos += sizeof(*fmhdr);
+	if (fm_pos >= fm_size)
+		goto fail_bad;
+
+	if (be32_to_cpu(fmhdr->magic) != UBI_FM_HDR_MAGIC) {
+		ubi_err("bad fastmap header magic: 0x%x, expected: 0x%x",
+			be32_to_cpu(fmhdr->magic), UBI_FM_HDR_MAGIC);
+		goto fail_bad;
+	}
+
+	fmpl1 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos);
+	fm_pos += sizeof(*fmpl1);
+	if (fm_pos >= fm_size)
+		goto fail_bad;
+	if (be32_to_cpu(fmpl1->magic) != UBI_FM_POOL_MAGIC) {
+		ubi_err("bad fastmap pool magic: 0x%x, expected: 0x%x",
+			be32_to_cpu(fmpl1->magic), UBI_FM_POOL_MAGIC);
+		goto fail_bad;
+	}
+
+	fmpl2 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos);
+	fm_pos += sizeof(*fmpl2);
+	if (fm_pos >= fm_size)
+		goto fail_bad;
+	if (be32_to_cpu(fmpl2->magic) != UBI_FM_POOL_MAGIC) {
+		ubi_err("bad fastmap pool magic: 0x%x, expected: 0x%x",
+			be32_to_cpu(fmpl2->magic), UBI_FM_POOL_MAGIC);
+		goto fail_bad;
+	}
+
+	pool_size = be16_to_cpu(fmpl1->size);
+	wl_pool_size = be16_to_cpu(fmpl2->size);
+	fm->max_pool_size = be16_to_cpu(fmpl1->max_size);
+	fm->max_wl_pool_size = be16_to_cpu(fmpl2->max_size);
+
+	if (pool_size > UBI_FM_MAX_POOL_SIZE || pool_size < 0) {
+		ubi_err("bad pool size: %i", pool_size);
+		goto fail_bad;
+	}
+
+	if (wl_pool_size > UBI_FM_MAX_POOL_SIZE || wl_pool_size < 0) {
+		ubi_err("bad WL pool size: %i", wl_pool_size);
+		goto fail_bad;
+	}
+
+
+	if (fm->max_pool_size > UBI_FM_MAX_POOL_SIZE ||
+	    fm->max_pool_size < 0) {
+		ubi_err("bad maximal pool size: %i", fm->max_pool_size);
+		goto fail_bad;
+	}
+
+	if (fm->max_wl_pool_size > UBI_FM_MAX_POOL_SIZE ||
+	    fm->max_wl_pool_size < 0) {
+		ubi_err("bad maximal WL pool size: %i", fm->max_wl_pool_size);
+		goto fail_bad;
+	}
+
+	/* read EC values from free list */
+	for (i = 0; i < be32_to_cpu(fmhdr->free_peb_count); i++) {
+		fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
+		fm_pos += sizeof(*fmec);
+		if (fm_pos >= fm_size)
+			goto fail_bad;
+
+		add_aeb(ai, &ai->free, be32_to_cpu(fmec->pnum),
+			be32_to_cpu(fmec->ec), 0);
+	}
+
+	/* read EC values from used list */
+	for (i = 0; i < be32_to_cpu(fmhdr->used_peb_count); i++) {
+		fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
+		fm_pos += sizeof(*fmec);
+		if (fm_pos >= fm_size)
+			goto fail_bad;
+
+		add_aeb(ai, &used, be32_to_cpu(fmec->pnum),
+			be32_to_cpu(fmec->ec), 0);
+	}
+
+	/* read EC values from scrub list */
+	for (i = 0; i < be32_to_cpu(fmhdr->scrub_peb_count); i++) {
+		fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
+		fm_pos += sizeof(*fmec);
+		if (fm_pos >= fm_size)
+			goto fail_bad;
+
+		add_aeb(ai, &used, be32_to_cpu(fmec->pnum),
+			be32_to_cpu(fmec->ec), 1);
+	}
+
+	/* read EC values from erase list */
+	for (i = 0; i < be32_to_cpu(fmhdr->erase_peb_count); i++) {
+		fmec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
+		fm_pos += sizeof(*fmec);
+		if (fm_pos >= fm_size)
+			goto fail_bad;
+
+		add_aeb(ai, &ai->erase, be32_to_cpu(fmec->pnum),
+			be32_to_cpu(fmec->ec), 1);
+	}
+
+	ai->mean_ec = div_u64(ai->ec_sum, ai->ec_count);
+	ai->bad_peb_count = be32_to_cpu(fmhdr->bad_peb_count);
+
+	/* Iterate over all volumes and read their EBA table */
+	for (i = 0; i < be32_to_cpu(fmhdr->vol_count); i++) {
+		fmvhdr = (struct ubi_fm_volhdr *)(fm_raw + fm_pos);
+		fm_pos += sizeof(*fmvhdr);
+		if (fm_pos >= fm_size)
+			goto fail_bad;
+
+		if (be32_to_cpu(fmvhdr->magic) != UBI_FM_VHDR_MAGIC) {
+			ubi_err("bad fastmap vol header magic: 0x%x, " \
+				"expected: 0x%x",
+				be32_to_cpu(fmvhdr->magic), UBI_FM_VHDR_MAGIC);
+			goto fail_bad;
+		}
+
+		av = add_vol(ai, be32_to_cpu(fmvhdr->vol_id),
+			     be32_to_cpu(fmvhdr->used_ebs),
+			     be32_to_cpu(fmvhdr->data_pad),
+			     fmvhdr->vol_type,
+			     be32_to_cpu(fmvhdr->last_eb_bytes));
+
+		if (!av)
+			goto fail_bad;
+
+		ai->vols_found++;
+		if (ai->highest_vol_id < be32_to_cpu(fmvhdr->vol_id))
+			ai->highest_vol_id = be32_to_cpu(fmvhdr->vol_id);
+
+		fm_eba = (struct ubi_fm_eba *)(fm_raw + fm_pos);
+		fm_pos += sizeof(*fm_eba);
+		fm_pos += (sizeof(__be32) * be32_to_cpu(fm_eba->reserved_pebs));
+		if (fm_pos >= fm_size)
+			goto fail_bad;
+
+		if (be32_to_cpu(fm_eba->magic) != UBI_FM_EBA_MAGIC) {
+			ubi_err("bad fastmap EBA header magic: 0x%x, " \
+				"expected: 0x%x",
+				be32_to_cpu(fm_eba->magic), UBI_FM_EBA_MAGIC);
+			goto fail_bad;
+		}
+
+		for (j = 0; j < be32_to_cpu(fm_eba->reserved_pebs); j++) {
+			int pnum = be32_to_cpu(fm_eba->pnum[j]);
+
+			if ((int)be32_to_cpu(fm_eba->pnum[j]) < 0)
+				continue;
+
+			aeb = NULL;
+			list_for_each_entry(tmp_aeb, &used, u.list) {
+				if (tmp_aeb->pnum == pnum)
+					aeb = tmp_aeb;
+			}
+
+			/* This can happen if a PEB is already in an EBA known
+			 * by this fastmap but the PEB itself is not in the used
+			 * list.
+			 * In this case the PEB can be within the fastmap pool
+			 * or while writing the fastmap it was in the protection
+			 * queue.
+			 */
+			if (!aeb) {
+				aeb = kmem_cache_alloc(ai->aeb_slab_cache,
+						       GFP_KERNEL);
+				if (!aeb) {
+					ret = -ENOMEM;
+
+					goto fail;
+				}
+
+				aeb->lnum = j;
+				aeb->pnum = be32_to_cpu(fm_eba->pnum[j]);
+				aeb->ec = -1;
+				aeb->scrub = aeb->copy_flag = aeb->sqnum = 0;
+				list_add_tail(&aeb->u.list, &eba_orphans);
+				continue;
+			}
+
+			aeb->lnum = j;
+
+			if (av->highest_lnum <= aeb->lnum)
+				av->highest_lnum = aeb->lnum;
+
+			assign_aeb_to_av(ai, aeb, av);
+
+			dbg_bld("inserting PEB:%i (LEB %i) to vol %i",
+				aeb->pnum, aeb->lnum, av->vol_id);
+		}
+
+		ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
+		if (!ech) {
+			ret = -ENOMEM;
+			goto fail;
+		}
+
+		list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &eba_orphans,
+					 u.list) {
+			int err;
+
+			if (ubi_io_is_bad(ubi, tmp_aeb->pnum)) {
+				ubi_err("bad PEB in fastmap EBA orphan list");
+				ret = UBI_BAD_FASTMAP;
+				kfree(ech);
+				goto fail;
+			}
+
+			err = ubi_io_read_ec_hdr(ubi, tmp_aeb->pnum, ech, 0);
+			if (err && err != UBI_IO_BITFLIPS) {
+				ubi_err("unable to read EC header! PEB:%i " \
+					"err:%i", tmp_aeb->pnum, err);
+				ret = err > 0 ? UBI_BAD_FASTMAP : err;
+				kfree(ech);
+
+				goto fail;
+			} else if (err == UBI_IO_BITFLIPS)
+				tmp_aeb->scrub = 1;
+
+			tmp_aeb->ec = be64_to_cpu(ech->ec);
+			assign_aeb_to_av(ai, tmp_aeb, av);
+		}
+
+		kfree(ech);
+	}
+
+	ret = scan_pool(ubi, ai, fmpl1->pebs, pool_size, &max_sqnum,
+			&eba_orphans, &free);
+	if (ret)
+		goto fail;
+
+	ret = scan_pool(ubi, ai, fmpl2->pebs, wl_pool_size, &max_sqnum,
+			&eba_orphans, &free);
+	if (ret)
+		goto fail;
+
+	if (max_sqnum > ai->max_sqnum)
+		ai->max_sqnum = max_sqnum;
+
+	list_for_each_entry_safe(tmp_aeb, _tmp_aeb, &free, u.list) {
+		list_del(&tmp_aeb->u.list);
+		list_add_tail(&tmp_aeb->u.list, &ai->free);
+	}
+
+	/*
+	 * If fastmap is leaking PEBs (must not happen), raise a
+	 * fat warning and fall back to scanning mode.
+	 * We do this here because in ubi_wl_init() it's too late
+	 * and we cannot fall back to scanning.
+	 */
+	if (WARN_ON(count_fastmap_pebs(ai) != ubi->peb_count -
+		    ai->bad_peb_count - fm->used_blocks))
+		goto fail_bad;
+
+	return 0;
+
+fail_bad:
+	ret = UBI_BAD_FASTMAP;
+fail:
+	return ret;
+}
+
+/**
+ * ubi_scan_fastmap - scan the fastmap.
+ * @ubi: UBI device object
+ * @ai: UBI attach info to be filled
+ * @fm_anchor: The fastmap starts at this PEB
+ *
+ * Returns 0 on success, UBI_NO_FASTMAP if no fastmap was found,
+ * UBI_BAD_FASTMAP if one was found but is not usable.
+ * < 0 indicates an internal error.
+ */
+int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai,
+		     int fm_anchor)
+{
+	struct ubi_fm_sb *fmsb, *fmsb2;
+	struct ubi_vid_hdr *vh;
+	struct ubi_ec_hdr *ech;
+	struct ubi_fastmap_layout *fm;
+	int i, used_blocks, pnum, ret = 0;
+	size_t fm_size;
+	__be32 crc, tmp_crc;
+	unsigned long long sqnum = 0;
+
+	mutex_lock(&ubi->fm_mutex);
+	memset(ubi->fm_buf, 0, ubi->fm_size);
+
+	fmsb = kmalloc(sizeof(*fmsb), GFP_KERNEL);
+	if (!fmsb) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	fm = kzalloc(sizeof(*fm), GFP_KERNEL);
+	if (!fm) {
+		ret = -ENOMEM;
+		kfree(fmsb);
+		goto out;
+	}
+
+	ret = ubi_io_read(ubi, fmsb, fm_anchor, ubi->leb_start, sizeof(*fmsb));
+	if (ret && ret != UBI_IO_BITFLIPS)
+		goto free_fm_sb;
+	else if (ret == UBI_IO_BITFLIPS)
+		fm->to_be_tortured[0] = 1;
+
+	if (be32_to_cpu(fmsb->magic) != UBI_FM_SB_MAGIC) {
+		ubi_err("bad super block magic: 0x%x, expected: 0x%x",
+			be32_to_cpu(fmsb->magic), UBI_FM_SB_MAGIC);
+		ret = UBI_BAD_FASTMAP;
+		goto free_fm_sb;
+	}
+
+	if (fmsb->version != UBI_FM_FMT_VERSION) {
+		ubi_err("bad fastmap version: %i, expected: %i",
+			fmsb->version, UBI_FM_FMT_VERSION);
+		ret = UBI_BAD_FASTMAP;
+		goto free_fm_sb;
+	}
+
+	used_blocks = be32_to_cpu(fmsb->used_blocks);
+	if (used_blocks > UBI_FM_MAX_BLOCKS || used_blocks < 1) {
+		ubi_err("number of fastmap blocks is invalid: %i", used_blocks);
+		ret = UBI_BAD_FASTMAP;
+		goto free_fm_sb;
+	}
+
+	fm_size = ubi->leb_size * used_blocks;
+	if (fm_size != ubi->fm_size) {
+		ubi_err("bad fastmap size: %zi, expected: %zi", fm_size,
+			ubi->fm_size);
+		ret = UBI_BAD_FASTMAP;
+		goto free_fm_sb;
+	}
+
+	ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
+	if (!ech) {
+		ret = -ENOMEM;
+		goto free_fm_sb;
+	}
+
+	vh = ubi_zalloc_vid_hdr(ubi, GFP_KERNEL);
+	if (!vh) {
+		ret = -ENOMEM;
+		goto free_hdr;
+	}
+
+	for (i = 0; i < used_blocks; i++) {
+		pnum = be32_to_cpu(fmsb->block_loc[i]);
+
+		if (ubi_io_is_bad(ubi, pnum)) {
+			ret = UBI_BAD_FASTMAP;
+			goto free_hdr;
+		}
+
+		ret = ubi_io_read_ec_hdr(ubi, pnum, ech, 0);
+		if (ret && ret != UBI_IO_BITFLIPS) {
+			ubi_err("unable to read fastmap block# %i EC (PEB: %i)",
+				i, pnum);
+			if (ret > 0)
+				ret = UBI_BAD_FASTMAP;
+			goto free_hdr;
+		} else if (ret == UBI_IO_BITFLIPS)
+			fm->to_be_tortured[i] = 1;
+
+		if (!ubi->image_seq)
+			ubi->image_seq = be32_to_cpu(ech->image_seq);
+
+		if (be32_to_cpu(ech->image_seq) != ubi->image_seq) {
+			ret = UBI_BAD_FASTMAP;
+			goto free_hdr;
+		}
+
+		ret = ubi_io_read_vid_hdr(ubi, pnum, vh, 0);
+		if (ret && ret != UBI_IO_BITFLIPS) {
+			ubi_err("unable to read fastmap block# %i (PEB: %i)",
+				i, pnum);
+			goto free_hdr;
+		}
+
+		if (i == 0) {
+			if (be32_to_cpu(vh->vol_id) != UBI_FM_SB_VOLUME_ID) {
+				ubi_err("bad fastmap anchor vol_id: 0x%x," \
+					" expected: 0x%x",
+					be32_to_cpu(vh->vol_id),
+					UBI_FM_SB_VOLUME_ID);
+				ret = UBI_BAD_FASTMAP;
+				goto free_hdr;
+			}
+		} else {
+			if (be32_to_cpu(vh->vol_id) != UBI_FM_DATA_VOLUME_ID) {
+				ubi_err("bad fastmap data vol_id: 0x%x," \
+					" expected: 0x%x",
+					be32_to_cpu(vh->vol_id),
+					UBI_FM_DATA_VOLUME_ID);
+				ret = UBI_BAD_FASTMAP;
+				goto free_hdr;
+			}
+		}
+
+		if (sqnum < be64_to_cpu(vh->sqnum))
+			sqnum = be64_to_cpu(vh->sqnum);
+
+		ret = ubi_io_read(ubi, ubi->fm_buf + (ubi->leb_size * i), pnum,
+				  ubi->leb_start, ubi->leb_size);
+		if (ret && ret != UBI_IO_BITFLIPS) {
+			ubi_err("unable to read fastmap block# %i (PEB: %i, " \
+				"err: %i)", i, pnum, ret);
+			goto free_hdr;
+		}
+	}
+
+	kfree(fmsb);
+	fmsb = NULL;
+
+	fmsb2 = (struct ubi_fm_sb *)(ubi->fm_buf);
+	tmp_crc = be32_to_cpu(fmsb2->data_crc);
+	fmsb2->data_crc = 0;
+	crc = crc32(UBI_CRC32_INIT, ubi->fm_buf, fm_size);
+	if (crc != tmp_crc) {
+		ubi_err("fastmap data CRC is invalid");
+		ubi_err("CRC should be: 0x%x, calc: 0x%x", tmp_crc, crc);
+		ret = UBI_BAD_FASTMAP;
+		goto free_hdr;
+	}
+
+	fmsb2->sqnum = sqnum;
+
+	fm->used_blocks = used_blocks;
+
+	ret = ubi_attach_fastmap(ubi, ai, fm);
+	if (ret) {
+		if (ret > 0)
+			ret = UBI_BAD_FASTMAP;
+		goto free_hdr;
+	}
+
+	for (i = 0; i < used_blocks; i++) {
+		struct ubi_wl_entry *e;
+
+		e = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
+		if (!e) {
+			while (i--)
+				kfree(fm->e[i]);
+
+			ret = -ENOMEM;
+			goto free_hdr;
+		}
+
+		e->pnum = be32_to_cpu(fmsb2->block_loc[i]);
+		e->ec = be32_to_cpu(fmsb2->block_ec[i]);
+		fm->e[i] = e;
+	}
+
+	ubi->fm = fm;
+	ubi->fm_pool.max_size = ubi->fm->max_pool_size;
+	ubi->fm_wl_pool.max_size = ubi->fm->max_wl_pool_size;
+	ubi_msg("attached by fastmap");
+	ubi_msg("fastmap pool size: %d", ubi->fm_pool.max_size);
+	ubi_msg("fastmap WL pool size: %d", ubi->fm_wl_pool.max_size);
+	ubi->fm_disabled = 0;
+
+	ubi_free_vid_hdr(ubi, vh);
+	kfree(ech);
+out:
+	mutex_unlock(&ubi->fm_mutex);
+	if (ret == UBI_BAD_FASTMAP)
+		ubi_err("Attach by fastmap failed, doing a full scan!");
+	return ret;
+
+free_hdr:
+	ubi_free_vid_hdr(ubi, vh);
+	kfree(ech);
+free_fm_sb:
+	kfree(fmsb);
+	kfree(fm);
+	goto out;
+}
+
+/**
+ * ubi_write_fastmap - writes a fastmap.
+ * @ubi: UBI device object
+ * @new_fm: the to be written fastmap
+ *
+ * Returns 0 on success, < 0 indicates an internal error.
+ */
+static int ubi_write_fastmap(struct ubi_device *ubi,
+			     struct ubi_fastmap_layout *new_fm)
+{
+	size_t fm_pos = 0;
+	void *fm_raw;
+	struct ubi_fm_sb *fmsb;
+	struct ubi_fm_hdr *fmh;
+	struct ubi_fm_scan_pool *fmpl1, *fmpl2;
+	struct ubi_fm_ec *fec;
+	struct ubi_fm_volhdr *fvh;
+	struct ubi_fm_eba *feba;
+	struct rb_node *node;
+	struct ubi_wl_entry *wl_e;
+	struct ubi_volume *vol;
+	struct ubi_vid_hdr *avhdr, *dvhdr;
+	struct ubi_work *ubi_wrk;
+	int ret, i, j, free_peb_count, used_peb_count, vol_count;
+	int scrub_peb_count, erase_peb_count;
+
+	fm_raw = ubi->fm_buf;
+	memset(ubi->fm_buf, 0, ubi->fm_size);
+
+	avhdr = new_fm_vhdr(ubi, UBI_FM_SB_VOLUME_ID);
+	if (!avhdr) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	dvhdr = new_fm_vhdr(ubi, UBI_FM_DATA_VOLUME_ID);
+	if (!dvhdr) {
+		ret = -ENOMEM;
+		goto out_kfree;
+	}
+
+	spin_lock(&ubi->volumes_lock);
+	spin_lock(&ubi->wl_lock);
+
+	fmsb = (struct ubi_fm_sb *)fm_raw;
+	fm_pos += sizeof(*fmsb);
+	ubi_assert(fm_pos <= ubi->fm_size);
+
+	fmh = (struct ubi_fm_hdr *)(fm_raw + fm_pos);
+	fm_pos += sizeof(*fmh);
+	ubi_assert(fm_pos <= ubi->fm_size);
+
+	fmsb->magic = cpu_to_be32(UBI_FM_SB_MAGIC);
+	fmsb->version = UBI_FM_FMT_VERSION;
+	fmsb->used_blocks = cpu_to_be32(new_fm->used_blocks);
+	/* the max sqnum will be filled in while *reading* the fastmap */
+	fmsb->sqnum = 0;
+
+	fmh->magic = cpu_to_be32(UBI_FM_HDR_MAGIC);
+	free_peb_count = 0;
+	used_peb_count = 0;
+	scrub_peb_count = 0;
+	erase_peb_count = 0;
+	vol_count = 0;
+
+	fmpl1 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos);
+	fm_pos += sizeof(*fmpl1);
+	fmpl1->magic = cpu_to_be32(UBI_FM_POOL_MAGIC);
+	fmpl1->size = cpu_to_be16(ubi->fm_pool.size);
+	fmpl1->max_size = cpu_to_be16(ubi->fm_pool.max_size);
+
+	for (i = 0; i < ubi->fm_pool.size; i++)
+		fmpl1->pebs[i] = cpu_to_be32(ubi->fm_pool.pebs[i]);
+
+	fmpl2 = (struct ubi_fm_scan_pool *)(fm_raw + fm_pos);
+	fm_pos += sizeof(*fmpl2);
+	fmpl2->magic = cpu_to_be32(UBI_FM_POOL_MAGIC);
+	fmpl2->size = cpu_to_be16(ubi->fm_wl_pool.size);
+	fmpl2->max_size = cpu_to_be16(ubi->fm_wl_pool.max_size);
+
+	for (i = 0; i < ubi->fm_wl_pool.size; i++)
+		fmpl2->pebs[i] = cpu_to_be32(ubi->fm_wl_pool.pebs[i]);
+
+	for (node = rb_first(&ubi->free); node; node = rb_next(node)) {
+		wl_e = rb_entry(node, struct ubi_wl_entry, u.rb);
+		fec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
+
+		fec->pnum = cpu_to_be32(wl_e->pnum);
+		fec->ec = cpu_to_be32(wl_e->ec);
+
+		free_peb_count++;
+		fm_pos += sizeof(*fec);
+		ubi_assert(fm_pos <= ubi->fm_size);
+	}
+	fmh->free_peb_count = cpu_to_be32(free_peb_count);
+
+	for (node = rb_first(&ubi->used); node; node = rb_next(node)) {
+		wl_e = rb_entry(node, struct ubi_wl_entry, u.rb);
+		fec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
+
+		fec->pnum = cpu_to_be32(wl_e->pnum);
+		fec->ec = cpu_to_be32(wl_e->ec);
+
+		used_peb_count++;
+		fm_pos += sizeof(*fec);
+		ubi_assert(fm_pos <= ubi->fm_size);
+	}
+	fmh->used_peb_count = cpu_to_be32(used_peb_count);
+
+	for (node = rb_first(&ubi->scrub); node; node = rb_next(node)) {
+		wl_e = rb_entry(node, struct ubi_wl_entry, u.rb);
+		fec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
+
+		fec->pnum = cpu_to_be32(wl_e->pnum);
+		fec->ec = cpu_to_be32(wl_e->ec);
+
+		scrub_peb_count++;
+		fm_pos += sizeof(*fec);
+		ubi_assert(fm_pos <= ubi->fm_size);
+	}
+	fmh->scrub_peb_count = cpu_to_be32(scrub_peb_count);
+
+
+	list_for_each_entry(ubi_wrk, &ubi->works, list) {
+		if (ubi_is_erase_work(ubi_wrk)) {
+			wl_e = ubi_wrk->e;
+			ubi_assert(wl_e);
+
+			fec = (struct ubi_fm_ec *)(fm_raw + fm_pos);
+
+			fec->pnum = cpu_to_be32(wl_e->pnum);
+			fec->ec = cpu_to_be32(wl_e->ec);
+
+			erase_peb_count++;
+			fm_pos += sizeof(*fec);
+			ubi_assert(fm_pos <= ubi->fm_size);
+		}
+	}
+	fmh->erase_peb_count = cpu_to_be32(erase_peb_count);
+
+	for (i = 0; i < UBI_MAX_VOLUMES + UBI_INT_VOL_COUNT; i++) {
+		vol = ubi->volumes[i];
+
+		if (!vol)
+			continue;
+
+		vol_count++;
+
+		fvh = (struct ubi_fm_volhdr *)(fm_raw + fm_pos);
+		fm_pos += sizeof(*fvh);
+		ubi_assert(fm_pos <= ubi->fm_size);
+
+		fvh->magic = cpu_to_be32(UBI_FM_VHDR_MAGIC);
+		fvh->vol_id = cpu_to_be32(vol->vol_id);
+		fvh->vol_type = vol->vol_type;
+		fvh->used_ebs = cpu_to_be32(vol->used_ebs);
+		fvh->data_pad = cpu_to_be32(vol->data_pad);
+		fvh->last_eb_bytes = cpu_to_be32(vol->last_eb_bytes);
+
+		ubi_assert(vol->vol_type == UBI_DYNAMIC_VOLUME ||
+			vol->vol_type == UBI_STATIC_VOLUME);
+
+		feba = (struct ubi_fm_eba *)(fm_raw + fm_pos);
+		fm_pos += sizeof(*feba) + (sizeof(__be32) * vol->reserved_pebs);
+		ubi_assert(fm_pos <= ubi->fm_size);
+
+		for (j = 0; j < vol->reserved_pebs; j++)
+			feba->pnum[j] = cpu_to_be32(vol->eba_tbl[j]);
+
+		feba->reserved_pebs = cpu_to_be32(j);
+		feba->magic = cpu_to_be32(UBI_FM_EBA_MAGIC);
+	}
+	fmh->vol_count = cpu_to_be32(vol_count);
+	fmh->bad_peb_count = cpu_to_be32(ubi->bad_peb_count);
+
+	avhdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
+	avhdr->lnum = 0;
+
+	spin_unlock(&ubi->wl_lock);
+	spin_unlock(&ubi->volumes_lock);
+
+	dbg_bld("writing fastmap SB to PEB %i", new_fm->e[0]->pnum);
+	ret = ubi_io_write_vid_hdr(ubi, new_fm->e[0]->pnum, avhdr);
+	if (ret) {
+		ubi_err("unable to write vid_hdr to fastmap SB!");
+		goto out_kfree;
+	}
+
+	for (i = 0; i < new_fm->used_blocks; i++) {
+		fmsb->block_loc[i] = cpu_to_be32(new_fm->e[i]->pnum);
+		fmsb->block_ec[i] = cpu_to_be32(new_fm->e[i]->ec);
+	}
+
+	fmsb->data_crc = 0;
+	fmsb->data_crc = cpu_to_be32(crc32(UBI_CRC32_INIT, fm_raw,
+					   ubi->fm_size));
+
+	for (i = 1; i < new_fm->used_blocks; i++) {
+		dvhdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
+		dvhdr->lnum = cpu_to_be32(i);
+		dbg_bld("writing fastmap data to PEB %i sqnum %llu",
+			new_fm->e[i]->pnum, be64_to_cpu(dvhdr->sqnum));
+		ret = ubi_io_write_vid_hdr(ubi, new_fm->e[i]->pnum, dvhdr);
+		if (ret) {
+			ubi_err("unable to write vid_hdr to PEB %i!",
+				new_fm->e[i]->pnum);
+			goto out_kfree;
+		}
+	}
+
+	for (i = 0; i < new_fm->used_blocks; i++) {
+		ret = ubi_io_write(ubi, fm_raw + (i * ubi->leb_size),
+			new_fm->e[i]->pnum, ubi->leb_start, ubi->leb_size);
+		if (ret) {
+			ubi_err("unable to write fastmap to PEB %i!",
+				new_fm->e[i]->pnum);
+			goto out_kfree;
+		}
+	}
+
+	ubi_assert(new_fm);
+	ubi->fm = new_fm;
+
+	dbg_bld("fastmap written!");
+
+out_kfree:
+	ubi_free_vid_hdr(ubi, avhdr);
+	ubi_free_vid_hdr(ubi, dvhdr);
+out:
+	return ret;
+}
+
+/**
+ * erase_block - Manually erase a PEB.
+ * @ubi: UBI device object
+ * @pnum: PEB to be erased
+ *
+ * Returns the new EC value on success, < 0 indicates an internal error.
+ */
+static int erase_block(struct ubi_device *ubi, int pnum)
+{
+	int ret;
+	struct ubi_ec_hdr *ec_hdr;
+	long long ec;
+
+	ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL);
+	if (!ec_hdr)
+		return -ENOMEM;
+
+	ret = ubi_io_read_ec_hdr(ubi, pnum, ec_hdr, 0);
+	if (ret < 0)
+		goto out;
+	else if (ret && ret != UBI_IO_BITFLIPS) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = ubi_io_sync_erase(ubi, pnum, 0);
+	if (ret < 0)
+		goto out;
+
+	ec = be64_to_cpu(ec_hdr->ec);
+	ec += ret;
+	if (ec > UBI_MAX_ERASECOUNTER) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ec_hdr->ec = cpu_to_be64(ec);
+	ret = ubi_io_write_ec_hdr(ubi, pnum, ec_hdr);
+	if (ret < 0)
+		goto out;
+
+	ret = ec;
+out:
+	kfree(ec_hdr);
+	return ret;
+}
+
+/**
+ * invalidate_fastmap - destroys a fastmap.
+ * @ubi: UBI device object
+ * @fm: the fastmap to be destroyed
+ *
+ * Returns 0 on success, < 0 indicates an internal error.
+ */
+static int invalidate_fastmap(struct ubi_device *ubi,
+			      struct ubi_fastmap_layout *fm)
+{
+	int ret, i;
+	struct ubi_vid_hdr *vh;
+
+	ret = erase_block(ubi, fm->e[0]->pnum);
+	if (ret < 0)
+		return ret;
+
+	vh = new_fm_vhdr(ubi, UBI_FM_SB_VOLUME_ID);
+	if (!vh)
+		return -ENOMEM;
+
+	/* deleting the current fastmap SB is not enough, an old SB may exist,
+	 * so create a (corrupted) SB such that fastmap will find it and fall
+	 * back to scanning mode in any case */
+	vh->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
+	ret = ubi_io_write_vid_hdr(ubi, fm->e[0]->pnum, vh);
+
+	for (i = 0; i < fm->used_blocks; i++)
+		ubi_wl_put_fm_peb(ubi, fm->e[i], i, fm->to_be_tortured[i]);
+
+	return ret;
+}
+
+/**
+ * ubi_update_fastmap - will be called by UBI if a volume changes or
+ * a fastmap pool becomes full.
+ * @ubi: UBI device object
+ *
+ * Returns 0 on success, < 0 indicates an internal error.
+ */
+int ubi_update_fastmap(struct ubi_device *ubi)
+{
+	int ret, i;
+	struct ubi_fastmap_layout *new_fm, *old_fm;
+	struct ubi_wl_entry *tmp_e;
+
+	mutex_lock(&ubi->fm_mutex);
+
+	ubi_refill_pools(ubi);
+
+	if (ubi->ro_mode || ubi->fm_disabled) {
+		mutex_unlock(&ubi->fm_mutex);
+		return 0;
+	}
+
+	ret = ubi_ensure_anchor_pebs(ubi);
+	if (ret) {
+		mutex_unlock(&ubi->fm_mutex);
+		return ret;
+	}
+
+	new_fm = kzalloc(sizeof(*new_fm), GFP_KERNEL);
+	if (!new_fm) {
+		mutex_unlock(&ubi->fm_mutex);
+		return -ENOMEM;
+	}
+
+	new_fm->used_blocks = ubi->fm_size / ubi->leb_size;
+
+	for (i = 0; i < new_fm->used_blocks; i++) {
+		new_fm->e[i] = kmem_cache_alloc(ubi_wl_entry_slab, GFP_KERNEL);
+		if (!new_fm->e[i]) {
+			while (i--)
+				kfree(new_fm->e[i]);
+
+			kfree(new_fm);
+			mutex_unlock(&ubi->fm_mutex);
+			return -ENOMEM;
+		}
+	}
+
+	old_fm = ubi->fm;
+	ubi->fm = NULL;
+
+	if (new_fm->used_blocks > UBI_FM_MAX_BLOCKS) {
+		ubi_err("fastmap too large");
+		ret = -ENOSPC;
+		goto err;
+	}
+
+	for (i = 1; i < new_fm->used_blocks; i++) {
+		spin_lock(&ubi->wl_lock);
+		tmp_e = ubi_wl_get_fm_peb(ubi, 0);
+		spin_unlock(&ubi->wl_lock);
+
+		if (!tmp_e && !old_fm) {
+			int j;
+			ubi_err("could not get any free erase block");
+
+			for (j = 1; j < i; j++)
+				ubi_wl_put_fm_peb(ubi, new_fm->e[j], j, 0);
+
+			ret = -ENOSPC;
+			goto err;
+		} else if (!tmp_e && old_fm) {
+			ret = erase_block(ubi, old_fm->e[i]->pnum);
+			if (ret < 0) {
+				int j;
+
+				for (j = 1; j < i; j++)
+					ubi_wl_put_fm_peb(ubi, new_fm->e[j],
+							  j, 0);
+
+				ubi_err("could not erase old fastmap PEB");
+				goto err;
+			}
+
+			new_fm->e[i]->pnum = old_fm->e[i]->pnum;
+			new_fm->e[i]->ec = old_fm->e[i]->ec;
+		} else {
+			new_fm->e[i]->pnum = tmp_e->pnum;
+			new_fm->e[i]->ec = tmp_e->ec;
+
+			if (old_fm)
+				ubi_wl_put_fm_peb(ubi, old_fm->e[i], i,
+						  old_fm->to_be_tortured[i]);
+		}
+	}
+
+	spin_lock(&ubi->wl_lock);
+	tmp_e = ubi_wl_get_fm_peb(ubi, 1);
+	spin_unlock(&ubi->wl_lock);
+
+	if (old_fm) {
+		/* no fresh anchor PEB was found, reuse the old one */
+		if (!tmp_e) {
+			ret = erase_block(ubi, old_fm->e[0]->pnum);
+			if (ret < 0) {
+				int i;
+				ubi_err("could not erase old anchor PEB");
+
+				for (i = 1; i < new_fm->used_blocks; i++)
+					ubi_wl_put_fm_peb(ubi, new_fm->e[i],
+							  i, 0);
+				goto err;
+			}
+
+			new_fm->e[0]->pnum = old_fm->e[0]->pnum;
+			new_fm->e[0]->ec = ret;
+		} else {
+			/* we've got a new anchor PEB, return the old one */
+			ubi_wl_put_fm_peb(ubi, old_fm->e[0], 0,
+					  old_fm->to_be_tortured[0]);
+
+			new_fm->e[0]->pnum = tmp_e->pnum;
+			new_fm->e[0]->ec = tmp_e->ec;
+		}
+	} else {
+		if (!tmp_e) {
+			int i;
+			ubi_err("could not find any anchor PEB");
+
+			for (i = 1; i < new_fm->used_blocks; i++)
+				ubi_wl_put_fm_peb(ubi, new_fm->e[i], i, 0);
+
+			ret = -ENOSPC;
+			goto err;
+		}
+
+		new_fm->e[0]->pnum = tmp_e->pnum;
+		new_fm->e[0]->ec = tmp_e->ec;
+	}
+
+	down_write(&ubi->work_sem);
+	down_write(&ubi->fm_sem);
+	ret = ubi_write_fastmap(ubi, new_fm);
+	up_write(&ubi->fm_sem);
+	up_write(&ubi->work_sem);
+
+	if (ret)
+		goto err;
+
+out_unlock:
+	mutex_unlock(&ubi->fm_mutex);
+	kfree(old_fm);
+	return ret;
+
+err:
+	kfree(new_fm);
+
+	ubi_warn("Unable to write new fastmap, err=%i", ret);
+
+	ret = 0;
+	if (old_fm) {
+		ret = invalidate_fastmap(ubi, old_fm);
+		if (ret < 0)
+			ubi_err("Unable to invalidiate current fastmap!");
+		else if (ret)
+			ret = 0;
+	}
+	goto out_unlock;
+}
diff --git a/drivers/mtd/ubi/ubi-media.h b/drivers/mtd/ubi/ubi-media.h
index 468ffbc..ac2b24d 100644
--- a/drivers/mtd/ubi/ubi-media.h
+++ b/drivers/mtd/ubi/ubi-media.h
@@ -375,4 +375,141 @@
 	__be32  crc;
 } __packed;
 
+/* UBI fastmap on-flash data structures */
+
+#define UBI_FM_SB_VOLUME_ID	(UBI_LAYOUT_VOLUME_ID + 1)
+#define UBI_FM_DATA_VOLUME_ID	(UBI_LAYOUT_VOLUME_ID + 2)
+
+/* fastmap on-flash data structure format version */
+#define UBI_FM_FMT_VERSION	1
+
+#define UBI_FM_SB_MAGIC		0x7B11D69F
+#define UBI_FM_HDR_MAGIC	0xD4B82EF7
+#define UBI_FM_VHDR_MAGIC	0xFA370ED1
+#define UBI_FM_POOL_MAGIC	0x67AF4D08
+#define UBI_FM_EBA_MAGIC	0xf0c040a8
+
+/* A fastmap supber block can be located between PEB 0 and
+ * UBI_FM_MAX_START */
+#define UBI_FM_MAX_START	64
+
+/* A fastmap can use up to UBI_FM_MAX_BLOCKS PEBs */
+#define UBI_FM_MAX_BLOCKS	32
+
+/* 5% of the total number of PEBs have to be scanned while attaching
+ * from a fastmap.
+ * But the size of this pool is limited to be between UBI_FM_MIN_POOL_SIZE and
+ * UBI_FM_MAX_POOL_SIZE */
+#define UBI_FM_MIN_POOL_SIZE	8
+#define UBI_FM_MAX_POOL_SIZE	256
+
+#define UBI_FM_WL_POOL_SIZE	25
+
+/**
+ * struct ubi_fm_sb - UBI fastmap super block
+ * @magic: fastmap super block magic number (%UBI_FM_SB_MAGIC)
+ * @version: format version of this fastmap
+ * @data_crc: CRC over the fastmap data
+ * @used_blocks: number of PEBs used by this fastmap
+ * @block_loc: an array containing the location of all PEBs of the fastmap
+ * @block_ec: the erase counter of each used PEB
+ * @sqnum: highest sequence number value at the time while taking the fastmap
+ *
+ */
+struct ubi_fm_sb {
+	__be32 magic;
+	__u8 version;
+	__u8 padding1[3];
+	__be32 data_crc;
+	__be32 used_blocks;
+	__be32 block_loc[UBI_FM_MAX_BLOCKS];
+	__be32 block_ec[UBI_FM_MAX_BLOCKS];
+	__be64 sqnum;
+	__u8 padding2[32];
+} __packed;
+
+/**
+ * struct ubi_fm_hdr - header of the fastmap data set
+ * @magic: fastmap header magic number (%UBI_FM_HDR_MAGIC)
+ * @free_peb_count: number of free PEBs known by this fastmap
+ * @used_peb_count: number of used PEBs known by this fastmap
+ * @scrub_peb_count: number of to be scrubbed PEBs known by this fastmap
+ * @bad_peb_count: number of bad PEBs known by this fastmap
+ * @erase_peb_count: number of bad PEBs which have to be erased
+ * @vol_count: number of UBI volumes known by this fastmap
+ */
+struct ubi_fm_hdr {
+	__be32 magic;
+	__be32 free_peb_count;
+	__be32 used_peb_count;
+	__be32 scrub_peb_count;
+	__be32 bad_peb_count;
+	__be32 erase_peb_count;
+	__be32 vol_count;
+	__u8 padding[4];
+} __packed;
+
+/* struct ubi_fm_hdr is followed by two struct ubi_fm_scan_pool */
+
+/**
+ * struct ubi_fm_scan_pool - Fastmap pool PEBs to be scanned while attaching
+ * @magic: pool magic numer (%UBI_FM_POOL_MAGIC)
+ * @size: current pool size
+ * @max_size: maximal pool size
+ * @pebs: an array containing the location of all PEBs in this pool
+ */
+struct ubi_fm_scan_pool {
+	__be32 magic;
+	__be16 size;
+	__be16 max_size;
+	__be32 pebs[UBI_FM_MAX_POOL_SIZE];
+	__be32 padding[4];
+} __packed;
+
+/* ubi_fm_scan_pool is followed by nfree+nused struct ubi_fm_ec records */
+
+/**
+ * struct ubi_fm_ec - stores the erase counter of a PEB
+ * @pnum: PEB number
+ * @ec: ec of this PEB
+ */
+struct ubi_fm_ec {
+	__be32 pnum;
+	__be32 ec;
+} __packed;
+
+/**
+ * struct ubi_fm_volhdr - Fastmap volume header
+ * it identifies the start of an eba table
+ * @magic: Fastmap volume header magic number (%UBI_FM_VHDR_MAGIC)
+ * @vol_id: volume id of the fastmapped volume
+ * @vol_type: type of the fastmapped volume
+ * @data_pad: data_pad value of the fastmapped volume
+ * @used_ebs: number of used LEBs within this volume
+ * @last_eb_bytes: number of bytes used in the last LEB
+ */
+struct ubi_fm_volhdr {
+	__be32 magic;
+	__be32 vol_id;
+	__u8 vol_type;
+	__u8 padding1[3];
+	__be32 data_pad;
+	__be32 used_ebs;
+	__be32 last_eb_bytes;
+	__u8 padding2[8];
+} __packed;
+
+/* struct ubi_fm_volhdr is followed by one struct ubi_fm_eba records */
+
+/**
+ * struct ubi_fm_eba - denotes an association beween a PEB and LEB
+ * @magic: EBA table magic number
+ * @reserved_pebs: number of table entries
+ * @pnum: PEB number of LEB (LEB is the index)
+ */
+struct ubi_fm_eba {
+	__be32 magic;
+	__be32 reserved_pebs;
+	__be32 pnum[0];
+} __packed;
 #endif /* !__UBI_MEDIA_H__ */
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index 383ee43..7d57469 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -133,6 +133,17 @@
 	MOVE_RETRY,
 };
 
+/*
+ * Return codes of the fastmap sub-system
+ *
+ * UBI_NO_FASTMAP: No fastmap super block was found
+ * UBI_BAD_FASTMAP: A fastmap was found but it's unusable
+ */
+enum {
+	UBI_NO_FASTMAP = 1,
+	UBI_BAD_FASTMAP,
+};
+
 /**
  * struct ubi_wl_entry - wear-leveling entry.
  * @u.rb: link in the corresponding (free/used) RB-tree
@@ -199,6 +210,41 @@
 struct ubi_volume_desc;
 
 /**
+ * struct ubi_fastmap_layout - in-memory fastmap data structure.
+ * @e: PEBs used by the current fastmap
+ * @to_be_tortured: if non-zero tortured this PEB
+ * @used_blocks: number of used PEBs
+ * @max_pool_size: maximal size of the user pool
+ * @max_wl_pool_size: maximal size of the pool used by the WL sub-system
+ */
+struct ubi_fastmap_layout {
+	struct ubi_wl_entry *e[UBI_FM_MAX_BLOCKS];
+	int to_be_tortured[UBI_FM_MAX_BLOCKS];
+	int used_blocks;
+	int max_pool_size;
+	int max_wl_pool_size;
+};
+
+/**
+ * struct ubi_fm_pool - in-memory fastmap pool
+ * @pebs: PEBs in this pool
+ * @used: number of used PEBs
+ * @size: total number of PEBs in this pool
+ * @max_size: maximal size of the pool
+ *
+ * A pool gets filled with up to max_size.
+ * If all PEBs within the pool are used a new fastmap will be written
+ * to the flash and the pool gets refilled with empty PEBs.
+ *
+ */
+struct ubi_fm_pool {
+	int pebs[UBI_FM_MAX_POOL_SIZE];
+	int used;
+	int size;
+	int max_size;
+};
+
+/**
  * struct ubi_volume - UBI volume description data structure.
  * @dev: device object to make use of the the Linux device model
  * @cdev: character device object to create character device
@@ -333,9 +379,21 @@
  * @ltree: the lock tree
  * @alc_mutex: serializes "atomic LEB change" operations
  *
+ * @fm_disabled: non-zero if fastmap is disabled (default)
+ * @fm: in-memory data structure of the currently used fastmap
+ * @fm_pool: in-memory data structure of the fastmap pool
+ * @fm_wl_pool: in-memory data structure of the fastmap pool used by the WL
+ *		sub-system
+ * @fm_mutex: serializes ubi_update_fastmap() and protects @fm_buf
+ * @fm_buf: vmalloc()'d buffer which holds the raw fastmap
+ * @fm_size: fastmap size in bytes
+ * @fm_sem: allows ubi_update_fastmap() to block EBA table changes
+ * @fm_work: fastmap work queue
+ *
  * @used: RB-tree of used physical eraseblocks
  * @erroneous: RB-tree of erroneous used physical eraseblocks
  * @free: RB-tree of free physical eraseblocks
+ * @free_count: Contains the number of elements in @free
  * @scrub: RB-tree of physical eraseblocks which need scrubbing
  * @pq: protection queue (contain physical eraseblocks which are temporarily
  *      protected from the wear-leveling worker)
@@ -426,10 +484,22 @@
 	struct rb_root ltree;
 	struct mutex alc_mutex;
 
+	/* Fastmap stuff */
+	int fm_disabled;
+	struct ubi_fastmap_layout *fm;
+	struct ubi_fm_pool fm_pool;
+	struct ubi_fm_pool fm_wl_pool;
+	struct rw_semaphore fm_sem;
+	struct mutex fm_mutex;
+	void *fm_buf;
+	size_t fm_size;
+	struct work_struct fm_work;
+
 	/* Wear-leveling sub-system's stuff */
 	struct rb_root used;
 	struct rb_root erroneous;
 	struct rb_root free;
+	int free_count;
 	struct rb_root scrub;
 	struct list_head pq[UBI_PROT_QUEUE_LEN];
 	int pq_head;
@@ -596,6 +666,32 @@
 	struct kmem_cache *aeb_slab_cache;
 };
 
+/**
+ * struct ubi_work - UBI work description data structure.
+ * @list: a link in the list of pending works
+ * @func: worker function
+ * @e: physical eraseblock to erase
+ * @vol_id: the volume ID on which this erasure is being performed
+ * @lnum: the logical eraseblock number
+ * @torture: if the physical eraseblock has to be tortured
+ * @anchor: produce a anchor PEB to by used by fastmap
+ *
+ * The @func pointer points to the worker function. If the @cancel argument is
+ * not zero, the worker has to free the resources and exit immediately. The
+ * worker has to return zero in case of success and a negative error code in
+ * case of failure.
+ */
+struct ubi_work {
+	struct list_head list;
+	int (*func)(struct ubi_device *ubi, struct ubi_work *wrk, int cancel);
+	/* The below fields are only relevant to erasure works */
+	struct ubi_wl_entry *e;
+	int vol_id;
+	int lnum;
+	int torture;
+	int anchor;
+};
+
 #include "debug.h"
 
 extern struct kmem_cache *ubi_wl_entry_slab;
@@ -606,7 +702,7 @@
 extern struct mutex ubi_devices_mutex;
 extern struct blocking_notifier_head ubi_notifiers;
 
-/* scan.c */
+/* attach.c */
 int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum,
 		  int ec, const struct ubi_vid_hdr *vid_hdr, int bitflips);
 struct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai,
@@ -614,7 +710,7 @@
 void ubi_remove_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av);
 struct ubi_ainf_peb *ubi_early_get_peb(struct ubi_device *ubi,
 				       struct ubi_attach_info *ai);
-int ubi_attach(struct ubi_device *ubi);
+int ubi_attach(struct ubi_device *ubi, int force_scan);
 void ubi_destroy_ai(struct ubi_attach_info *ai);
 
 /* vtbl.c */
@@ -664,6 +760,9 @@
 int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
 		     struct ubi_vid_hdr *vid_hdr);
 int ubi_eba_init(struct ubi_device *ubi, struct ubi_attach_info *ai);
+unsigned long long ubi_next_sqnum(struct ubi_device *ubi);
+int self_check_eba(struct ubi_device *ubi, struct ubi_attach_info *ai_fastmap,
+		   struct ubi_attach_info *ai_scan);
 
 /* wl.c */
 int ubi_wl_get_peb(struct ubi_device *ubi);
@@ -674,6 +773,12 @@
 int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai);
 void ubi_wl_close(struct ubi_device *ubi);
 int ubi_thread(void *u);
+struct ubi_wl_entry *ubi_wl_get_fm_peb(struct ubi_device *ubi, int anchor);
+int ubi_wl_put_fm_peb(struct ubi_device *ubi, struct ubi_wl_entry *used_e,
+		      int lnum, int torture);
+int ubi_is_erase_work(struct ubi_work *wrk);
+void ubi_refill_pools(struct ubi_device *ubi);
+int ubi_ensure_anchor_pebs(struct ubi_device *ubi);
 
 /* io.c */
 int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset,
@@ -711,6 +816,15 @@
 void ubi_do_get_device_info(struct ubi_device *ubi, struct ubi_device_info *di);
 void ubi_do_get_volume_info(struct ubi_device *ubi, struct ubi_volume *vol,
 			    struct ubi_volume_info *vi);
+/* scan.c */
+int ubi_compare_lebs(struct ubi_device *ubi, const struct ubi_ainf_peb *aeb,
+		      int pnum, const struct ubi_vid_hdr *vid_hdr);
+
+/* fastmap.c */
+size_t ubi_calc_fm_size(struct ubi_device *ubi);
+int ubi_update_fastmap(struct ubi_device *ubi);
+int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai,
+		     int fm_anchor);
 
 /*
  * ubi_rb_for_each_entry - walk an RB-tree.
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index 032fc57..da7b449 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -135,36 +135,48 @@
  */
 #define WL_MAX_FAILURES 32
 
-/**
- * struct ubi_work - UBI work description data structure.
- * @list: a link in the list of pending works
- * @func: worker function
- * @e: physical eraseblock to erase
- * @vol_id: the volume ID on which this erasure is being performed
- * @lnum: the logical eraseblock number
- * @torture: if the physical eraseblock has to be tortured
- *
- * The @func pointer points to the worker function. If the @cancel argument is
- * not zero, the worker has to free the resources and exit immediately. The
- * worker has to return zero in case of success and a negative error code in
- * case of failure.
- */
-struct ubi_work {
-	struct list_head list;
-	int (*func)(struct ubi_device *ubi, struct ubi_work *wrk, int cancel);
-	/* The below fields are only relevant to erasure works */
-	struct ubi_wl_entry *e;
-	int vol_id;
-	int lnum;
-	int torture;
-};
-
 static int self_check_ec(struct ubi_device *ubi, int pnum, int ec);
 static int self_check_in_wl_tree(const struct ubi_device *ubi,
 				 struct ubi_wl_entry *e, struct rb_root *root);
 static int self_check_in_pq(const struct ubi_device *ubi,
 			    struct ubi_wl_entry *e);
 
+#ifdef CONFIG_MTD_UBI_FASTMAP
+/**
+ * update_fastmap_work_fn - calls ubi_update_fastmap from a work queue
+ * @wrk: the work description object
+ */
+static void update_fastmap_work_fn(struct work_struct *wrk)
+{
+	struct ubi_device *ubi = container_of(wrk, struct ubi_device, fm_work);
+	ubi_update_fastmap(ubi);
+}
+
+/**
+ *  ubi_ubi_is_fm_block - returns 1 if a PEB is currently used in a fastmap.
+ *  @ubi: UBI device description object
+ *  @pnum: the to be checked PEB
+ */
+static int ubi_is_fm_block(struct ubi_device *ubi, int pnum)
+{
+	int i;
+
+	if (!ubi->fm)
+		return 0;
+
+	for (i = 0; i < ubi->fm->used_blocks; i++)
+		if (ubi->fm->e[i]->pnum == pnum)
+			return 1;
+
+	return 0;
+}
+#else
+static int ubi_is_fm_block(struct ubi_device *ubi, int pnum)
+{
+	return 0;
+}
+#endif
+
 /**
  * wl_tree_add - add a wear-leveling entry to a WL RB-tree.
  * @e: the wear-leveling entry to add
@@ -261,18 +273,16 @@
 {
 	int err;
 
-	spin_lock(&ubi->wl_lock);
 	while (!ubi->free.rb_node) {
 		spin_unlock(&ubi->wl_lock);
 
 		dbg_wl("do one work synchronously");
 		err = do_work(ubi);
-		if (err)
-			return err;
 
 		spin_lock(&ubi->wl_lock);
+		if (err)
+			return err;
 	}
-	spin_unlock(&ubi->wl_lock);
 
 	return 0;
 }
@@ -339,16 +349,18 @@
 
 /**
  * find_wl_entry - find wear-leveling entry closest to certain erase counter.
+ * @ubi: UBI device description object
  * @root: the RB-tree where to look for
  * @diff: maximum possible difference from the smallest erase counter
  *
  * This function looks for a wear leveling entry with erase counter closest to
  * min + @diff, where min is the smallest erase counter.
  */
-static struct ubi_wl_entry *find_wl_entry(struct rb_root *root, int diff)
+static struct ubi_wl_entry *find_wl_entry(struct ubi_device *ubi,
+					  struct rb_root *root, int diff)
 {
 	struct rb_node *p;
-	struct ubi_wl_entry *e;
+	struct ubi_wl_entry *e, *prev_e = NULL;
 	int max;
 
 	e = rb_entry(rb_first(root), struct ubi_wl_entry, u.rb);
@@ -363,35 +375,143 @@
 			p = p->rb_left;
 		else {
 			p = p->rb_right;
+			prev_e = e;
 			e = e1;
 		}
 	}
 
+	/* If no fastmap has been written and this WL entry can be used
+	 * as anchor PEB, hold it back and return the second best WL entry
+	 * such that fastmap can use the anchor PEB later. */
+	if (prev_e && !ubi->fm_disabled &&
+	    !ubi->fm && e->pnum < UBI_FM_MAX_START)
+		return prev_e;
+
 	return e;
 }
 
 /**
- * ubi_wl_get_peb - get a physical eraseblock.
+ * find_mean_wl_entry - find wear-leveling entry with medium erase counter.
+ * @ubi: UBI device description object
+ * @root: the RB-tree where to look for
+ *
+ * This function looks for a wear leveling entry with medium erase counter,
+ * but not greater or equivalent than the lowest erase counter plus
+ * %WL_FREE_MAX_DIFF/2.
+ */
+static struct ubi_wl_entry *find_mean_wl_entry(struct ubi_device *ubi,
+					       struct rb_root *root)
+{
+	struct ubi_wl_entry *e, *first, *last;
+
+	first = rb_entry(rb_first(root), struct ubi_wl_entry, u.rb);
+	last = rb_entry(rb_last(root), struct ubi_wl_entry, u.rb);
+
+	if (last->ec - first->ec < WL_FREE_MAX_DIFF) {
+		e = rb_entry(root->rb_node, struct ubi_wl_entry, u.rb);
+
+#ifdef CONFIG_MTD_UBI_FASTMAP
+		/* If no fastmap has been written and this WL entry can be used
+		 * as anchor PEB, hold it back and return the second best
+		 * WL entry such that fastmap can use the anchor PEB later. */
+		if (e && !ubi->fm_disabled && !ubi->fm &&
+		    e->pnum < UBI_FM_MAX_START)
+			e = rb_entry(rb_next(root->rb_node),
+				     struct ubi_wl_entry, u.rb);
+#endif
+	} else
+		e = find_wl_entry(ubi, root, WL_FREE_MAX_DIFF/2);
+
+	return e;
+}
+
+#ifdef CONFIG_MTD_UBI_FASTMAP
+/**
+ * find_anchor_wl_entry - find wear-leveling entry to used as anchor PEB.
+ * @root: the RB-tree where to look for
+ */
+static struct ubi_wl_entry *find_anchor_wl_entry(struct rb_root *root)
+{
+	struct rb_node *p;
+	struct ubi_wl_entry *e, *victim = NULL;
+	int max_ec = UBI_MAX_ERASECOUNTER;
+
+	ubi_rb_for_each_entry(p, e, root, u.rb) {
+		if (e->pnum < UBI_FM_MAX_START && e->ec < max_ec) {
+			victim = e;
+			max_ec = e->ec;
+		}
+	}
+
+	return victim;
+}
+
+static int anchor_pebs_avalible(struct rb_root *root)
+{
+	struct rb_node *p;
+	struct ubi_wl_entry *e;
+
+	ubi_rb_for_each_entry(p, e, root, u.rb)
+		if (e->pnum < UBI_FM_MAX_START)
+			return 1;
+
+	return 0;
+}
+
+/**
+ * ubi_wl_get_fm_peb - find a physical erase block with a given maximal number.
+ * @ubi: UBI device description object
+ * @anchor: This PEB will be used as anchor PEB by fastmap
+ *
+ * The function returns a physical erase block with a given maximal number
+ * and removes it from the wl subsystem.
+ * Must be called with wl_lock held!
+ */
+struct ubi_wl_entry *ubi_wl_get_fm_peb(struct ubi_device *ubi, int anchor)
+{
+	struct ubi_wl_entry *e = NULL;
+
+	if (!ubi->free.rb_node || (ubi->free_count - ubi->beb_rsvd_pebs < 1))
+		goto out;
+
+	if (anchor)
+		e = find_anchor_wl_entry(&ubi->free);
+	else
+		e = find_mean_wl_entry(ubi, &ubi->free);
+
+	if (!e)
+		goto out;
+
+	self_check_in_wl_tree(ubi, e, &ubi->free);
+
+	/* remove it from the free list,
+	 * the wl subsystem does no longer know this erase block */
+	rb_erase(&e->u.rb, &ubi->free);
+	ubi->free_count--;
+out:
+	return e;
+}
+#endif
+
+/**
+ * __wl_get_peb - get a physical eraseblock.
  * @ubi: UBI device description object
  *
  * This function returns a physical eraseblock in case of success and a
  * negative error code in case of failure. Might sleep.
  */
-int ubi_wl_get_peb(struct ubi_device *ubi)
+static int __wl_get_peb(struct ubi_device *ubi)
 {
 	int err;
-	struct ubi_wl_entry *e, *first, *last;
+	struct ubi_wl_entry *e;
 
 retry:
-	spin_lock(&ubi->wl_lock);
 	if (!ubi->free.rb_node) {
 		if (ubi->works_count == 0) {
-			ubi_assert(list_empty(&ubi->works));
 			ubi_err("no free eraseblocks");
-			spin_unlock(&ubi->wl_lock);
+			ubi_assert(list_empty(&ubi->works));
 			return -ENOSPC;
 		}
-		spin_unlock(&ubi->wl_lock);
 
 		err = produce_free_peb(ubi);
 		if (err < 0)
@@ -399,13 +519,11 @@
 		goto retry;
 	}
 
-	first = rb_entry(rb_first(&ubi->free), struct ubi_wl_entry, u.rb);
-	last = rb_entry(rb_last(&ubi->free), struct ubi_wl_entry, u.rb);
-
-	if (last->ec - first->ec < WL_FREE_MAX_DIFF)
-		e = rb_entry(ubi->free.rb_node, struct ubi_wl_entry, u.rb);
-	else
-		e = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF/2);
+	e = find_mean_wl_entry(ubi, &ubi->free);
+	if (!e) {
+		ubi_err("no free eraseblocks");
+		return -ENOSPC;
+	}
 
 	self_check_in_wl_tree(ubi, e, &ubi->free);
 
@@ -414,10 +532,14 @@
 	 * be protected from being moved for some time.
 	 */
 	rb_erase(&e->u.rb, &ubi->free);
+	ubi->free_count--;
 	dbg_wl("PEB %d EC %d", e->pnum, e->ec);
+#ifndef CONFIG_MTD_UBI_FASTMAP
+	/* We have to enqueue e only if fastmap is disabled,
+	 * is fastmap enabled prot_queue_add() will be called by
+	 * ubi_wl_get_peb() after removing e from the pool. */
 	prot_queue_add(ubi, e);
-	spin_unlock(&ubi->wl_lock);
-
+#endif
 	err = ubi_self_check_all_ff(ubi, e->pnum, ubi->vid_hdr_aloffset,
 				    ubi->peb_size - ubi->vid_hdr_aloffset);
 	if (err) {
@@ -428,6 +550,150 @@
 	return e->pnum;
 }
 
+#ifdef CONFIG_MTD_UBI_FASTMAP
+/**
+ * return_unused_pool_pebs - returns unused PEB to the free tree.
+ * @ubi: UBI device description object
+ * @pool: fastmap pool description object
+ */
+static void return_unused_pool_pebs(struct ubi_device *ubi,
+				    struct ubi_fm_pool *pool)
+{
+	int i;
+	struct ubi_wl_entry *e;
+
+	for (i = pool->used; i < pool->size; i++) {
+		e = ubi->lookuptbl[pool->pebs[i]];
+		wl_tree_add(e, &ubi->free);
+		ubi->free_count++;
+	}
+}
+
+/**
+ * refill_wl_pool - refills all the fastmap pool used by the
+ * WL sub-system.
+ * @ubi: UBI device description object
+ */
+static void refill_wl_pool(struct ubi_device *ubi)
+{
+	struct ubi_wl_entry *e;
+	struct ubi_fm_pool *pool = &ubi->fm_wl_pool;
+
+	return_unused_pool_pebs(ubi, pool);
+
+	for (pool->size = 0; pool->size < pool->max_size; pool->size++) {
+		if (!ubi->free.rb_node ||
+		   (ubi->free_count - ubi->beb_rsvd_pebs < 5))
+			break;
+
+		e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF);
+		self_check_in_wl_tree(ubi, e, &ubi->free);
+		rb_erase(&e->u.rb, &ubi->free);
+		ubi->free_count--;
+
+		pool->pebs[pool->size] = e->pnum;
+	}
+	pool->used = 0;
+}
+
+/**
+ * refill_wl_user_pool - refills all the fastmap pool used by ubi_wl_get_peb.
+ * @ubi: UBI device description object
+ */
+static void refill_wl_user_pool(struct ubi_device *ubi)
+{
+	struct ubi_fm_pool *pool = &ubi->fm_pool;
+
+	return_unused_pool_pebs(ubi, pool);
+
+	for (pool->size = 0; pool->size < pool->max_size; pool->size++) {
+		if (!ubi->free.rb_node ||
+		   (ubi->free_count - ubi->beb_rsvd_pebs < 1))
+			break;
+
+		pool->pebs[pool->size] = __wl_get_peb(ubi);
+		if (pool->pebs[pool->size] < 0)
+			break;
+	}
+	pool->used = 0;
+}
+
+/**
+ * ubi_refill_pools - refills all fastmap PEB pools.
+ * @ubi: UBI device description object
+ */
+void ubi_refill_pools(struct ubi_device *ubi)
+{
+	spin_lock(&ubi->wl_lock);
+	refill_wl_pool(ubi);
+	refill_wl_user_pool(ubi);
+	spin_unlock(&ubi->wl_lock);
+}
+
+/* ubi_wl_get_peb - works exaclty like __wl_get_peb but keeps track of
+ * the fastmap pool.
+ */
+int ubi_wl_get_peb(struct ubi_device *ubi)
+{
+	int ret;
+	struct ubi_fm_pool *pool = &ubi->fm_pool;
+	struct ubi_fm_pool *wl_pool = &ubi->fm_wl_pool;
+
+	if (!pool->size || !wl_pool->size || pool->used == pool->size ||
+	    wl_pool->used == wl_pool->size)
+		ubi_update_fastmap(ubi);
+
+	/* we got not a single free PEB */
+	if (!pool->size)
+		ret = -ENOSPC;
+	else {
+		spin_lock(&ubi->wl_lock);
+		ret = pool->pebs[pool->used++];
+		prot_queue_add(ubi, ubi->lookuptbl[ret]);
+		spin_unlock(&ubi->wl_lock);
+	}
+
+	return ret;
+}
+
+/* get_peb_for_wl - returns a PEB to be used internally by the WL sub-system.
+ *
+ * @ubi: UBI device description object
+ */
+static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi)
+{
+	struct ubi_fm_pool *pool = &ubi->fm_wl_pool;
+	int pnum;
+
+	if (pool->used == pool->size || !pool->size) {
+		/* We cannot update the fastmap here because this
+		 * function is called in atomic context.
+		 * Let's fail here and refill/update it as soon as possible. */
+		schedule_work(&ubi->fm_work);
+		return NULL;
+	} else {
+		pnum = pool->pebs[pool->used++];
+		return ubi->lookuptbl[pnum];
+	}
+}
+#else
+static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi)
+{
+	return find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF);
+}
+
+int ubi_wl_get_peb(struct ubi_device *ubi)
+{
+	int peb;
+
+	spin_lock(&ubi->wl_lock);
+	peb = __wl_get_peb(ubi);
+	spin_unlock(&ubi->wl_lock);
+
+	return peb;
+}
+#endif
+
 /**
  * prot_queue_del - remove a physical eraseblock from the protection queue.
  * @ubi: UBI device description object
@@ -558,14 +824,14 @@
 }
 
 /**
- * schedule_ubi_work - schedule a work.
+ * __schedule_ubi_work - schedule a work.
  * @ubi: UBI device description object
  * @wrk: the work to schedule
  *
  * This function adds a work defined by @wrk to the tail of the pending works
- * list.
+ * list. Can only be used of ubi->work_sem is already held in read mode!
  */
-static void schedule_ubi_work(struct ubi_device *ubi, struct ubi_work *wrk)
+static void __schedule_ubi_work(struct ubi_device *ubi, struct ubi_work *wrk)
 {
 	spin_lock(&ubi->wl_lock);
 	list_add_tail(&wrk->list, &ubi->works);
@@ -576,9 +842,35 @@
 	spin_unlock(&ubi->wl_lock);
 }
 
+/**
+ * schedule_ubi_work - schedule a work.
+ * @ubi: UBI device description object
+ * @wrk: the work to schedule
+ *
+ * This function adds a work defined by @wrk to the tail of the pending works
+ * list.
+ */
+static void schedule_ubi_work(struct ubi_device *ubi, struct ubi_work *wrk)
+{
+	down_read(&ubi->work_sem);
+	__schedule_ubi_work(ubi, wrk);
+	up_read(&ubi->work_sem);
+}
+
 static int erase_worker(struct ubi_device *ubi, struct ubi_work *wl_wrk,
 			int cancel);
 
+#ifdef CONFIG_MTD_UBI_FASTMAP
+/**
+ * ubi_is_erase_work - checks whether a work is erase work.
+ * @wrk: The work object to be checked
+ */
+int ubi_is_erase_work(struct ubi_work *wrk)
+{
+	return wrk->func == erase_worker;
+}
+#endif
+
 /**
  * schedule_erase - schedule an erase work.
  * @ubi: UBI device description object
@@ -595,6 +887,9 @@
 {
 	struct ubi_work *wl_wrk;
 
+	ubi_assert(e);
+	ubi_assert(!ubi_is_fm_block(ubi, e->pnum));
+
 	dbg_wl("schedule erasure of PEB %d, EC %d, torture %d",
 	       e->pnum, e->ec, torture);
 
@@ -613,6 +908,79 @@
 }
 
 /**
+ * do_sync_erase - run the erase worker synchronously.
+ * @ubi: UBI device description object
+ * @e: the WL entry of the physical eraseblock to erase
+ * @vol_id: the volume ID that last used this PEB
+ * @lnum: the last used logical eraseblock number for the PEB
+ * @torture: if the physical eraseblock has to be tortured
+ *
+ */
+static int do_sync_erase(struct ubi_device *ubi, struct ubi_wl_entry *e,
+			 int vol_id, int lnum, int torture)
+{
+	struct ubi_work *wl_wrk;
+
+	dbg_wl("sync erase of PEB %i", e->pnum);
+
+	wl_wrk = kmalloc(sizeof(struct ubi_work), GFP_NOFS);
+	if (!wl_wrk)
+		return -ENOMEM;
+
+	wl_wrk->e = e;
+	wl_wrk->vol_id = vol_id;
+	wl_wrk->lnum = lnum;
+	wl_wrk->torture = torture;
+
+	return erase_worker(ubi, wl_wrk, 0);
+}
+
+#ifdef CONFIG_MTD_UBI_FASTMAP
+/**
+ * ubi_wl_put_fm_peb - returns a PEB used in a fastmap to the wear-leveling
+ * sub-system.
+ * see: ubi_wl_put_peb()
+ *
+ * @ubi: UBI device description object
+ * @fm_e: physical eraseblock to return
+ * @lnum: the last used logical eraseblock number for the PEB
+ * @torture: if this physical eraseblock has to be tortured
+ */
+int ubi_wl_put_fm_peb(struct ubi_device *ubi, struct ubi_wl_entry *fm_e,
+		      int lnum, int torture)
+{
+	struct ubi_wl_entry *e;
+	int vol_id, pnum = fm_e->pnum;
+
+	dbg_wl("PEB %d", pnum);
+
+	ubi_assert(pnum >= 0);
+	ubi_assert(pnum < ubi->peb_count);
+
+	spin_lock(&ubi->wl_lock);
+	e = ubi->lookuptbl[pnum];
+
+	/* This can happen if we recovered from a fastmap the very
+	 * first time and writing now a new one. In this case the wl system
+	 * has never seen any PEB used by the original fastmap.
+	 */
+	if (!e) {
+		e = fm_e;
+		ubi_assert(e->ec >= 0);
+		ubi->lookuptbl[pnum] = e;
+	} else {
+		e->ec = fm_e->ec;
+		kfree(fm_e);
+	}
+
+	spin_unlock(&ubi->wl_lock);
+
+	vol_id = lnum ? UBI_FM_DATA_VOLUME_ID : UBI_FM_SB_VOLUME_ID;
+	return schedule_erase(ubi, e, vol_id, lnum, torture);
+}
+#endif
+
+/**
  * wear_leveling_worker - wear-leveling worker function.
  * @ubi: UBI device description object
  * @wrk: the work object
@@ -627,6 +995,9 @@
 {
 	int err, scrubbing = 0, torture = 0, protect = 0, erroneous = 0;
 	int vol_id = -1, uninitialized_var(lnum);
+#ifdef CONFIG_MTD_UBI_FASTMAP
+	int anchor = wrk->anchor;
+#endif
 	struct ubi_wl_entry *e1, *e2;
 	struct ubi_vid_hdr *vid_hdr;
 
@@ -660,14 +1031,35 @@
 		goto out_cancel;
 	}
 
+#ifdef CONFIG_MTD_UBI_FASTMAP
+	/* Check whether we need to produce an anchor PEB */
+	if (!anchor)
+		anchor = !anchor_pebs_avalible(&ubi->free);
+
+	if (anchor) {
+		e1 = find_anchor_wl_entry(&ubi->used);
+		if (!e1)
+			goto out_cancel;
+		e2 = get_peb_for_wl(ubi);
+		if (!e2)
+			goto out_cancel;
+
+		self_check_in_wl_tree(ubi, e1, &ubi->used);
+		rb_erase(&e1->u.rb, &ubi->used);
+		dbg_wl("anchor-move PEB %d to PEB %d", e1->pnum, e2->pnum);
+	} else if (!ubi->scrub.rb_node) {
+#else
 	if (!ubi->scrub.rb_node) {
+#endif
 		/*
 		 * Now pick the least worn-out used physical eraseblock and a
 		 * highly worn-out free physical eraseblock. If the erase
 		 * counters differ much enough, start wear-leveling.
 		 */
 		e1 = rb_entry(rb_first(&ubi->used), struct ubi_wl_entry, u.rb);
-		e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF);
+		e2 = get_peb_for_wl(ubi);
+		if (!e2)
+			goto out_cancel;
 
 		if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD)) {
 			dbg_wl("no WL needed: min used EC %d, max free EC %d",
@@ -682,14 +1074,15 @@
 		/* Perform scrubbing */
 		scrubbing = 1;
 		e1 = rb_entry(rb_first(&ubi->scrub), struct ubi_wl_entry, u.rb);
-		e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF);
+		e2 = get_peb_for_wl(ubi);
+		if (!e2)
+			goto out_cancel;
+
 		self_check_in_wl_tree(ubi, e1, &ubi->scrub);
 		rb_erase(&e1->u.rb, &ubi->scrub);
 		dbg_wl("scrub PEB %d to PEB %d", e1->pnum, e2->pnum);
 	}
 
-	self_check_in_wl_tree(ubi, e2, &ubi->free);
-	rb_erase(&e2->u.rb, &ubi->free);
 	ubi->move_from = e1;
 	ubi->move_to = e2;
 	spin_unlock(&ubi->wl_lock);
@@ -806,7 +1199,7 @@
 	ubi->move_to_put = ubi->wl_scheduled = 0;
 	spin_unlock(&ubi->wl_lock);
 
-	err = schedule_erase(ubi, e1, vol_id, lnum, 0);
+	err = do_sync_erase(ubi, e1, vol_id, lnum, 0);
 	if (err) {
 		kmem_cache_free(ubi_wl_entry_slab, e1);
 		if (e2)
@@ -821,7 +1214,7 @@
 		 */
 		dbg_wl("PEB %d (LEB %d:%d) was put meanwhile, erase",
 		       e2->pnum, vol_id, lnum);
-		err = schedule_erase(ubi, e2, vol_id, lnum, 0);
+		err = do_sync_erase(ubi, e2, vol_id, lnum, 0);
 		if (err) {
 			kmem_cache_free(ubi_wl_entry_slab, e2);
 			goto out_ro;
@@ -860,7 +1253,7 @@
 	spin_unlock(&ubi->wl_lock);
 
 	ubi_free_vid_hdr(ubi, vid_hdr);
-	err = schedule_erase(ubi, e2, vol_id, lnum, torture);
+	err = do_sync_erase(ubi, e2, vol_id, lnum, torture);
 	if (err) {
 		kmem_cache_free(ubi_wl_entry_slab, e2);
 		goto out_ro;
@@ -901,12 +1294,13 @@
 /**
  * ensure_wear_leveling - schedule wear-leveling if it is needed.
  * @ubi: UBI device description object
+ * @nested: set to non-zero if this function is called from UBI worker
  *
  * This function checks if it is time to start wear-leveling and schedules it
  * if yes. This function returns zero in case of success and a negative error
  * code in case of failure.
  */
-static int ensure_wear_leveling(struct ubi_device *ubi)
+static int ensure_wear_leveling(struct ubi_device *ubi, int nested)
 {
 	int err = 0;
 	struct ubi_wl_entry *e1;
@@ -934,7 +1328,7 @@
 		 * %UBI_WL_THRESHOLD.
 		 */
 		e1 = rb_entry(rb_first(&ubi->used), struct ubi_wl_entry, u.rb);
-		e2 = find_wl_entry(&ubi->free, WL_FREE_MAX_DIFF);
+		e2 = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF);
 
 		if (!(e2->ec - e1->ec >= UBI_WL_THRESHOLD))
 			goto out_unlock;
@@ -951,8 +1345,12 @@
 		goto out_cancel;
 	}
 
+	wrk->anchor = 0;
 	wrk->func = &wear_leveling_worker;
-	schedule_ubi_work(ubi, wrk);
+	if (nested)
+		__schedule_ubi_work(ubi, wrk);
+	else
+		schedule_ubi_work(ubi, wrk);
 	return err;
 
 out_cancel:
@@ -963,6 +1361,38 @@
 	return err;
 }
 
+#ifdef CONFIG_MTD_UBI_FASTMAP
+/**
+ * ubi_ensure_anchor_pebs - schedule wear-leveling to produce an anchor PEB.
+ * @ubi: UBI device description object
+ */
+int ubi_ensure_anchor_pebs(struct ubi_device *ubi)
+{
+	struct ubi_work *wrk;
+
+	spin_lock(&ubi->wl_lock);
+	if (ubi->wl_scheduled) {
+		spin_unlock(&ubi->wl_lock);
+		return 0;
+	}
+	ubi->wl_scheduled = 1;
+	spin_unlock(&ubi->wl_lock);
+
+	wrk = kmalloc(sizeof(struct ubi_work), GFP_NOFS);
+	if (!wrk) {
+		spin_lock(&ubi->wl_lock);
+		ubi->wl_scheduled = 0;
+		spin_unlock(&ubi->wl_lock);
+		return -ENOMEM;
+	}
+
+	wrk->anchor = 1;
+	wrk->func = &wear_leveling_worker;
+	schedule_ubi_work(ubi, wrk);
+	return 0;
+}
+#endif
+
 /**
  * erase_worker - physical eraseblock erase worker function.
  * @ubi: UBI device description object
@@ -993,6 +1423,8 @@
 	dbg_wl("erase PEB %d EC %d LEB %d:%d",
 	       pnum, e->ec, wl_wrk->vol_id, wl_wrk->lnum);
 
+	ubi_assert(!ubi_is_fm_block(ubi, e->pnum));
+
 	err = sync_erase(ubi, e, wl_wrk->torture);
 	if (!err) {
 		/* Fine, we've erased it successfully */
@@ -1000,6 +1432,7 @@
 
 		spin_lock(&ubi->wl_lock);
 		wl_tree_add(e, &ubi->free);
+		ubi->free_count++;
 		spin_unlock(&ubi->wl_lock);
 
 		/*
@@ -1009,7 +1442,7 @@
 		serve_prot_queue(ubi);
 
 		/* And take care about wear-leveling */
-		err = ensure_wear_leveling(ubi);
+		err = ensure_wear_leveling(ubi, 1);
 		return err;
 	}
 
@@ -1247,7 +1680,7 @@
 	 * Technically scrubbing is the same as wear-leveling, so it is done
 	 * by the WL worker.
 	 */
-	return ensure_wear_leveling(ubi);
+	return ensure_wear_leveling(ubi, 0);
 }
 
 /**
@@ -1428,7 +1861,7 @@
  */
 int ubi_wl_init(struct ubi_device *ubi, struct ubi_attach_info *ai)
 {
-	int err, i;
+	int err, i, reserved_pebs, found_pebs = 0;
 	struct rb_node *rb1, *rb2;
 	struct ubi_ainf_volume *av;
 	struct ubi_ainf_peb *aeb, *tmp;
@@ -1440,6 +1873,9 @@
 	init_rwsem(&ubi->work_sem);
 	ubi->max_ec = ai->max_ec;
 	INIT_LIST_HEAD(&ubi->works);
+#ifdef CONFIG_MTD_UBI_FASTMAP
+	INIT_WORK(&ubi->fm_work, update_fastmap_work_fn);
+#endif
 
 	sprintf(ubi->bgt_name, UBI_BGT_NAME_PATTERN, ubi->ubi_num);
 
@@ -1461,13 +1897,17 @@
 
 		e->pnum = aeb->pnum;
 		e->ec = aeb->ec;
+		ubi_assert(!ubi_is_fm_block(ubi, e->pnum));
 		ubi->lookuptbl[e->pnum] = e;
 		if (schedule_erase(ubi, e, aeb->vol_id, aeb->lnum, 0)) {
 			kmem_cache_free(ubi_wl_entry_slab, e);
 			goto out_free;
 		}
+
+		found_pebs++;
 	}
 
+	ubi->free_count = 0;
 	list_for_each_entry(aeb, &ai->free, u.list) {
 		cond_resched();
 
@@ -1478,8 +1918,14 @@
 		e->pnum = aeb->pnum;
 		e->ec = aeb->ec;
 		ubi_assert(e->ec >= 0);
+		ubi_assert(!ubi_is_fm_block(ubi, e->pnum));
+
 		wl_tree_add(e, &ubi->free);
+		ubi->free_count++;
+
 		ubi->lookuptbl[e->pnum] = e;
+
+		found_pebs++;
 	}
 
 	ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) {
@@ -1493,6 +1939,7 @@
 			e->pnum = aeb->pnum;
 			e->ec = aeb->ec;
 			ubi->lookuptbl[e->pnum] = e;
+
 			if (!aeb->scrub) {
 				dbg_wl("add PEB %d EC %d to the used tree",
 				       e->pnum, e->ec);
@@ -1502,22 +1949,38 @@
 				       e->pnum, e->ec);
 				wl_tree_add(e, &ubi->scrub);
 			}
+
+			found_pebs++;
 		}
 	}
 
-	if (ubi->avail_pebs < WL_RESERVED_PEBS) {
+	dbg_wl("found %i PEBs", found_pebs);
+
+	if (ubi->fm)
+		ubi_assert(ubi->good_peb_count == \
+			   found_pebs + ubi->fm->used_blocks);
+	else
+		ubi_assert(ubi->good_peb_count == found_pebs);
+
+	reserved_pebs = WL_RESERVED_PEBS;
+#ifdef CONFIG_MTD_UBI_FASTMAP
+	/* Reserve enough LEBs to store two fastmaps. */
+	reserved_pebs += (ubi->fm_size / ubi->leb_size) * 2;
+#endif
+
+	if (ubi->avail_pebs < reserved_pebs) {
 		ubi_err("no enough physical eraseblocks (%d, need %d)",
-			ubi->avail_pebs, WL_RESERVED_PEBS);
+			ubi->avail_pebs, reserved_pebs);
 		if (ubi->corr_peb_count)
 			ubi_err("%d PEBs are corrupted and not used",
 				ubi->corr_peb_count);
 		goto out_free;
 	}
-	ubi->avail_pebs -= WL_RESERVED_PEBS;
-	ubi->rsvd_pebs += WL_RESERVED_PEBS;
+	ubi->avail_pebs -= reserved_pebs;
+	ubi->rsvd_pebs += reserved_pebs;
 
 	/* Schedule wear-leveling if needed */
-	err = ensure_wear_leveling(ubi);
+	err = ensure_wear_leveling(ubi, 0);
 	if (err)
 		goto out_free;
 
@@ -1596,7 +2059,7 @@
 	}
 
 	read_ec = be64_to_cpu(ec_hdr->ec);
-	if (ec != read_ec) {
+	if (ec != read_ec && read_ec - ec > 1) {
 		ubi_err("self-check failed for PEB %d", pnum);
 		ubi_err("read EC is %lld, should be %d", read_ec, ec);
 		dump_stack();
diff --git a/drivers/net/ethernet/amd/amd8111e.c b/drivers/net/ethernet/amd/amd8111e.c
index 64d0d9c..3491d43 100644
--- a/drivers/net/ethernet/amd/amd8111e.c
+++ b/drivers/net/ethernet/amd/amd8111e.c
@@ -1845,6 +1845,7 @@
 	if((pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM))==0){
 		printk(KERN_ERR "amd8111e: No Power Management capability, "
 		       "exiting.\n");
+		err = -ENODEV;
 		goto err_free_reg;
 	}
 
@@ -1852,6 +1853,7 @@
 	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) < 0) {
 		printk(KERN_ERR "amd8111e: DMA not supported,"
 			"exiting.\n");
+		err = -ENODEV;
 		goto err_free_reg;
 	}
 
diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c
index 397596b..f195acf 100644
--- a/drivers/net/ethernet/amd/au1000_eth.c
+++ b/drivers/net/ethernet/amd/au1000_eth.c
@@ -1174,8 +1174,10 @@
 	snprintf(aup->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
 		pdev->name, aup->mac_id);
 	aup->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
-	if (aup->mii_bus->irq == NULL)
+	if (aup->mii_bus->irq == NULL) {
+		err = -ENOMEM;
 		goto err_out;
+	}
 
 	for (i = 0; i < PHY_MAX_ADDR; ++i)
 		aup->mii_bus->irq[i] = PHY_POLL;
@@ -1190,7 +1192,8 @@
 		goto err_mdiobus_reg;
 	}
 
-	if (au1000_mii_probe(dev) != 0)
+	err = au1000_mii_probe(dev);
+	if (err != 0)
 		goto err_out;
 
 	pDBfree = NULL;
@@ -1205,6 +1208,7 @@
 	}
 	aup->pDBfree = pDBfree;
 
+	err = -ENODEV;
 	for (i = 0; i < NUM_RX_DMA; i++) {
 		pDB = au1000_GetFreeDB(aup);
 		if (!pDB)
@@ -1213,6 +1217,8 @@
 		aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
 		aup->rx_db_inuse[i] = pDB;
 	}
+
+	err = -ENODEV;
 	for (i = 0; i < NUM_TX_DMA; i++) {
 		pDB = au1000_GetFreeDB(aup);
 		if (!pDB)
diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.h b/drivers/net/ethernet/broadcom/bcm63xx_enet.h
index 0e3048b..133d585 100644
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h
@@ -10,6 +10,7 @@
 #include <bcm63xx_regs.h>
 #include <bcm63xx_irq.h>
 #include <bcm63xx_io.h>
+#include <bcm63xx_iudma.h>
 
 /* default number of descriptor */
 #define BCMENET_DEF_RX_DESC	64
@@ -31,35 +32,6 @@
 #define BCMENET_MAX_MTU		2046
 
 /*
- * rx/tx dma descriptor
- */
-struct bcm_enet_desc {
-	u32 len_stat;
-	u32 address;
-};
-
-#define DMADESC_LENGTH_SHIFT	16
-#define DMADESC_LENGTH_MASK	(0xfff << DMADESC_LENGTH_SHIFT)
-#define DMADESC_OWNER_MASK	(1 << 15)
-#define DMADESC_EOP_MASK	(1 << 14)
-#define DMADESC_SOP_MASK	(1 << 13)
-#define DMADESC_ESOP_MASK	(DMADESC_EOP_MASK | DMADESC_SOP_MASK)
-#define DMADESC_WRAP_MASK	(1 << 12)
-
-#define DMADESC_UNDER_MASK	(1 << 9)
-#define DMADESC_APPEND_CRC	(1 << 8)
-#define DMADESC_OVSIZE_MASK	(1 << 4)
-#define DMADESC_RXER_MASK	(1 << 2)
-#define DMADESC_CRC_MASK	(1 << 1)
-#define DMADESC_OV_MASK		(1 << 0)
-#define DMADESC_ERR_MASK	(DMADESC_UNDER_MASK | \
-				DMADESC_OVSIZE_MASK | \
-				DMADESC_RXER_MASK | \
-				DMADESC_CRC_MASK | \
-				DMADESC_OV_MASK)
-
-
-/*
  * MIB Counters register definitions
 */
 #define ETH_MIB_TX_GD_OCTETS			0
diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c
index 2b4b4f5..16814b3 100644
--- a/drivers/net/ethernet/calxeda/xgmac.c
+++ b/drivers/net/ethernet/calxeda/xgmac.c
@@ -375,7 +375,6 @@
 	unsigned int tx_tail;
 
 	void __iomem *base;
-	struct sk_buff_head rx_recycle;
 	unsigned int dma_buf_sz;
 	dma_addr_t dma_rx_phy;
 	dma_addr_t dma_tx_phy;
@@ -672,9 +671,7 @@
 		p = priv->dma_rx + entry;
 
 		if (priv->rx_skbuff[entry] == NULL) {
-			skb = __skb_dequeue(&priv->rx_recycle);
-			if (skb == NULL)
-				skb = netdev_alloc_skb(priv->dev, priv->dma_buf_sz);
+			skb = netdev_alloc_skb(priv->dev, priv->dma_buf_sz);
 			if (unlikely(skb == NULL))
 				break;
 
@@ -887,17 +884,7 @@
 				       desc_get_buf_len(p), DMA_TO_DEVICE);
 		}
 
-		/*
-		 * If there's room in the queue (limit it to size)
-		 * we add this skb back into the pool,
-		 * if it's the right size.
-		 */
-		if ((skb_queue_len(&priv->rx_recycle) <
-			DMA_RX_RING_SZ) &&
-			skb_recycle_check(skb, priv->dma_buf_sz))
-			__skb_queue_head(&priv->rx_recycle, skb);
-		else
-			dev_kfree_skb(skb);
+		dev_kfree_skb(skb);
 	}
 
 	if (dma_ring_space(priv->tx_head, priv->tx_tail, DMA_TX_RING_SZ) >
@@ -1016,7 +1003,6 @@
 			dev->dev_addr);
 	}
 
-	skb_queue_head_init(&priv->rx_recycle);
 	memset(&priv->xstats, 0, sizeof(struct xgmac_extra_stats));
 
 	/* Initialize the XGMAC and descriptors */
@@ -1053,7 +1039,6 @@
 		napi_disable(&priv->napi);
 
 	writel(0, priv->base + XGMAC_DMA_INTR_ENA);
-	skb_queue_purge(&priv->rx_recycle);
 
 	/* Disable the MAC core */
 	xgmac_mac_disable(priv->base);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 31752b2..a4da893 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -696,6 +696,7 @@
 int get_vpd_params(struct adapter *adapter, struct vpd_params *p);
 int t4_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size);
 unsigned int t4_flash_cfg_addr(struct adapter *adapter);
+int t4_load_cfg(struct adapter *adapter, const u8 *cfg_data, unsigned int size);
 int t4_check_fw_version(struct adapter *adapter);
 int t4_prep_adapter(struct adapter *adapter);
 int t4_port_init(struct adapter *adap, int mbox, int pf, int vf);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 6b9f6bb..604f4f8 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -443,7 +443,10 @@
 module_param(dbfifo_int_thresh, int, 0644);
 MODULE_PARM_DESC(dbfifo_int_thresh, "doorbell fifo interrupt threshold");
 
-int dbfifo_drain_delay = 1000; /* usecs to sleep while draining the dbfifo */
+/*
+ * usecs to sleep while draining the dbfifo
+ */
+static int dbfifo_drain_delay = 1000;
 module_param(dbfifo_drain_delay, int, 0644);
 MODULE_PARM_DESC(dbfifo_drain_delay,
 		 "usecs to sleep while draining the dbfifo");
@@ -636,7 +639,7 @@
 static int request_msix_queue_irqs(struct adapter *adap)
 {
 	struct sge *s = &adap->sge;
-	int err, ethqidx, ofldqidx = 0, rdmaqidx = 0, msi = 2;
+	int err, ethqidx, ofldqidx = 0, rdmaqidx = 0, msi_index = 2;
 
 	err = request_irq(adap->msix_info[1].vec, t4_sge_intr_msix, 0,
 			  adap->msix_info[1].desc, &s->fw_evtq);
@@ -644,56 +647,60 @@
 		return err;
 
 	for_each_ethrxq(s, ethqidx) {
-		err = request_irq(adap->msix_info[msi].vec, t4_sge_intr_msix, 0,
-				  adap->msix_info[msi].desc,
+		err = request_irq(adap->msix_info[msi_index].vec,
+				  t4_sge_intr_msix, 0,
+				  adap->msix_info[msi_index].desc,
 				  &s->ethrxq[ethqidx].rspq);
 		if (err)
 			goto unwind;
-		msi++;
+		msi_index++;
 	}
 	for_each_ofldrxq(s, ofldqidx) {
-		err = request_irq(adap->msix_info[msi].vec, t4_sge_intr_msix, 0,
-				  adap->msix_info[msi].desc,
+		err = request_irq(adap->msix_info[msi_index].vec,
+				  t4_sge_intr_msix, 0,
+				  adap->msix_info[msi_index].desc,
 				  &s->ofldrxq[ofldqidx].rspq);
 		if (err)
 			goto unwind;
-		msi++;
+		msi_index++;
 	}
 	for_each_rdmarxq(s, rdmaqidx) {
-		err = request_irq(adap->msix_info[msi].vec, t4_sge_intr_msix, 0,
-				  adap->msix_info[msi].desc,
+		err = request_irq(adap->msix_info[msi_index].vec,
+				  t4_sge_intr_msix, 0,
+				  adap->msix_info[msi_index].desc,
 				  &s->rdmarxq[rdmaqidx].rspq);
 		if (err)
 			goto unwind;
-		msi++;
+		msi_index++;
 	}
 	return 0;
 
 unwind:
 	while (--rdmaqidx >= 0)
-		free_irq(adap->msix_info[--msi].vec,
+		free_irq(adap->msix_info[--msi_index].vec,
 			 &s->rdmarxq[rdmaqidx].rspq);
 	while (--ofldqidx >= 0)
-		free_irq(adap->msix_info[--msi].vec,
+		free_irq(adap->msix_info[--msi_index].vec,
 			 &s->ofldrxq[ofldqidx].rspq);
 	while (--ethqidx >= 0)
-		free_irq(adap->msix_info[--msi].vec, &s->ethrxq[ethqidx].rspq);
+		free_irq(adap->msix_info[--msi_index].vec,
+			 &s->ethrxq[ethqidx].rspq);
 	free_irq(adap->msix_info[1].vec, &s->fw_evtq);
 	return err;
 }
 
 static void free_msix_queue_irqs(struct adapter *adap)
 {
-	int i, msi = 2;
+	int i, msi_index = 2;
 	struct sge *s = &adap->sge;
 
 	free_irq(adap->msix_info[1].vec, &s->fw_evtq);
 	for_each_ethrxq(s, i)
-		free_irq(adap->msix_info[msi++].vec, &s->ethrxq[i].rspq);
+		free_irq(adap->msix_info[msi_index++].vec, &s->ethrxq[i].rspq);
 	for_each_ofldrxq(s, i)
-		free_irq(adap->msix_info[msi++].vec, &s->ofldrxq[i].rspq);
+		free_irq(adap->msix_info[msi_index++].vec, &s->ofldrxq[i].rspq);
 	for_each_rdmarxq(s, i)
-		free_irq(adap->msix_info[msi++].vec, &s->rdmarxq[i].rspq);
+		free_irq(adap->msix_info[msi_index++].vec, &s->rdmarxq[i].rspq);
 }
 
 /**
@@ -2535,9 +2542,8 @@
 
 	ret = t4_mem_win_read_len(adap, addr, (__be32 *)&indices, 8);
 	if (!ret) {
-		indices = be64_to_cpu(indices);
-		*cidx = (indices >> 25) & 0xffff;
-		*pidx = (indices >> 9) & 0xffff;
+		*cidx = (be64_to_cpu(indices) >> 25) & 0xffff;
+		*pidx = (be64_to_cpu(indices) >> 9) & 0xffff;
 	}
 	return ret;
 }
@@ -3634,10 +3640,10 @@
 	 * field selections will fit in the 36-bit budget.
 	 */
 	if (tp_vlan_pri_map != TP_VLAN_PRI_MAP_DEFAULT) {
-		int i, bits = 0;
+		int j, bits = 0;
 
-		for (i = TP_VLAN_PRI_MAP_FIRST; i <= TP_VLAN_PRI_MAP_LAST; i++)
-			switch (tp_vlan_pri_map & (1 << i)) {
+		for (j = TP_VLAN_PRI_MAP_FIRST; j <= TP_VLAN_PRI_MAP_LAST; j++)
+			switch (tp_vlan_pri_map & (1 << j)) {
 			case 0:
 				/* compressed filter field not enabled */
 				break;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index 137a244..32eec15 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -380,9 +380,11 @@
 	/* Collecting data 4 bytes at a time upto MEMWIN0_APERTURE */
 	for (i = 0; i < MEMWIN0_APERTURE; i = i+0x4) {
 		if (dir)
-			*data++ = t4_read_reg(adap, (MEMWIN0_BASE + i));
+			*data++ = (__force __be32) t4_read_reg(adap,
+							(MEMWIN0_BASE + i));
 		else
-			t4_write_reg(adap, (MEMWIN0_BASE + i), *data++);
+			t4_write_reg(adap, (MEMWIN0_BASE + i),
+				     (__force u32) *data++);
 	}
 
 	return 0;
@@ -417,7 +419,7 @@
 	if ((addr & 0x3) || (len & 0x3))
 		return -EINVAL;
 
-	data = vmalloc(MEMWIN0_APERTURE/sizeof(__be32));
+	data = vmalloc(MEMWIN0_APERTURE);
 	if (!data)
 		return -ENOMEM;
 
@@ -744,7 +746,7 @@
 		if (ret)
 			return ret;
 		if (byte_oriented)
-			*data = htonl(*data);
+			*data = (__force __u32) (htonl(*data));
 	}
 	return 0;
 }
@@ -992,7 +994,7 @@
 	int ret, addr;
 	unsigned int i;
 	u8 first_page[SF_PAGE_SIZE];
-	const u32 *p = (const u32 *)fw_data;
+	const __be32 *p = (const __be32 *)fw_data;
 	const struct fw_hdr *hdr = (const struct fw_hdr *)fw_data;
 	unsigned int sf_sec_size = adap->params.sf_size / adap->params.sf_nsec;
 	unsigned int fw_img_start = adap->params.sf_fw_start;
@@ -2315,7 +2317,8 @@
 	t4_read_reg(adap, PCIE_MEM_ACCESS_OFFSET);
 
 	for (i = 0; i < len; i += 4)
-		*data++ = t4_read_reg(adap, (MEMWIN0_BASE + off + i));
+		*data++ = (__force __be32) t4_read_reg(adap,
+						(MEMWIN0_BASE + off + i));
 
 	return 0;
 }
diff --git a/drivers/net/ethernet/dec/tulip/dmfe.c b/drivers/net/ethernet/dec/tulip/dmfe.c
index 4d6fe60..d23755e 100644
--- a/drivers/net/ethernet/dec/tulip/dmfe.c
+++ b/drivers/net/ethernet/dec/tulip/dmfe.c
@@ -446,13 +446,17 @@
 	/* Allocate Tx/Rx descriptor memory */
 	db->desc_pool_ptr = pci_alloc_consistent(pdev, sizeof(struct tx_desc) *
 			DESC_ALL_CNT + 0x20, &db->desc_pool_dma_ptr);
-	if (!db->desc_pool_ptr)
+	if (!db->desc_pool_ptr) {
+		err = -ENOMEM;
 		goto err_out_res;
+	}
 
 	db->buf_pool_ptr = pci_alloc_consistent(pdev, TX_BUF_ALLOC *
 			TX_DESC_CNT + 4, &db->buf_pool_dma_ptr);
-	if (!db->buf_pool_ptr)
+	if (!db->buf_pool_ptr) {
+		err = -ENOMEM;
 		goto err_out_free_desc;
+	}
 
 	db->first_tx_desc = (struct tx_desc *) db->desc_pool_ptr;
 	db->first_tx_desc_dma = db->desc_pool_dma_ptr;
@@ -462,8 +466,10 @@
 	db->chip_id = ent->driver_data;
 	/* IO type range. */
 	db->ioaddr = pci_iomap(pdev, 0, 0);
-	if (!db->ioaddr)
+	if (!db->ioaddr) {
+		err = -ENOMEM;
 		goto err_out_free_buf;
+	}
 
 	db->chip_revision = pdev->revision;
 	db->wol_mode = 0;
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index eb3f2cb..d1b6cc5 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -2129,8 +2129,11 @@
 		ue_hi = (ue_hi & ~ue_hi_mask);
 	}
 
-	if (ue_lo || ue_hi ||
-		sliport_status & SLIPORT_STATUS_ERR_MASK) {
+	/* On certain platforms BE hardware can indicate spurious UEs.
+	 * Allow the h/w to stop working completely in case of a real UE.
+	 * Hence not setting the hw_error for UE detection.
+	 */
+	if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
 		adapter->hw_error = true;
 		dev_err(&adapter->pdev->dev,
 			"Error detected in the card\n");
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index a1b52ec..1d03dcd 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -1765,7 +1765,6 @@
 			  sizeof(struct rxbd8) * priv->total_rx_ring_size,
 			  priv->tx_queue[0]->tx_bd_base,
 			  priv->tx_queue[0]->tx_bd_dma_base);
-	skb_queue_purge(&priv->rx_recycle);
 }
 
 void gfar_start(struct net_device *dev)
@@ -1943,8 +1942,6 @@
 
 	enable_napi(priv);
 
-	skb_queue_head_init(&priv->rx_recycle);
-
 	/* Initialize a bunch of registers */
 	init_registers(dev);
 
@@ -2533,16 +2530,7 @@
 
 		bytes_sent += skb->len;
 
-		/* If there's room in the queue (limit it to rx_buffer_size)
-		 * we add this skb back into the pool, if it's the right size
-		 */
-		if (skb_queue_len(&priv->rx_recycle) < rx_queue->rx_ring_size &&
-		    skb_recycle_check(skb, priv->rx_buffer_size +
-				      RXBUF_ALIGNMENT)) {
-			gfar_align_skb(skb);
-			skb_queue_head(&priv->rx_recycle, skb);
-		} else
-			dev_kfree_skb_any(skb);
+		dev_kfree_skb_any(skb);
 
 		tx_queue->tx_skbuff[skb_dirtytx] = NULL;
 
@@ -2608,7 +2596,7 @@
 static struct sk_buff *gfar_alloc_skb(struct net_device *dev)
 {
 	struct gfar_private *priv = netdev_priv(dev);
-	struct sk_buff *skb = NULL;
+	struct sk_buff *skb;
 
 	skb = netdev_alloc_skb(dev, priv->rx_buffer_size + RXBUF_ALIGNMENT);
 	if (!skb)
@@ -2621,14 +2609,7 @@
 
 struct sk_buff *gfar_new_skb(struct net_device *dev)
 {
-	struct gfar_private *priv = netdev_priv(dev);
-	struct sk_buff *skb = NULL;
-
-	skb = skb_dequeue(&priv->rx_recycle);
-	if (!skb)
-		skb = gfar_alloc_skb(dev);
-
-	return skb;
+	return gfar_alloc_skb(dev);
 }
 
 static inline void count_errors(unsigned short status, struct net_device *dev)
@@ -2787,7 +2768,7 @@
 			if (unlikely(!newskb))
 				newskb = skb;
 			else if (skb)
-				skb_queue_head(&priv->rx_recycle, skb);
+				dev_kfree_skb(skb);
 		} else {
 			/* Increment the number of packets */
 			rx_queue->stats.rx_packets++;
diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h
index 4141ef2..22eabc1 100644
--- a/drivers/net/ethernet/freescale/gianfar.h
+++ b/drivers/net/ethernet/freescale/gianfar.h
@@ -1080,8 +1080,6 @@
 
 	u32 cur_filer_idx;
 
-	struct sk_buff_head rx_recycle;
-
 	/* RX queue filer rule set*/
 	struct ethtool_rx_list rx_list;
 	struct mutex rx_queue_access;
diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
index 1642884..0a70bb5 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.c
+++ b/drivers/net/ethernet/freescale/ucc_geth.c
@@ -209,14 +209,12 @@
 static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth,
 		u8 __iomem *bd)
 {
-	struct sk_buff *skb = NULL;
+	struct sk_buff *skb;
 
-	skb = __skb_dequeue(&ugeth->rx_recycle);
+	skb = netdev_alloc_skb(ugeth->ndev,
+			       ugeth->ug_info->uf_info.max_rx_buf_length +
+			       UCC_GETH_RX_DATA_BUF_ALIGNMENT);
 	if (!skb)
-		skb = netdev_alloc_skb(ugeth->ndev,
-				      ugeth->ug_info->uf_info.max_rx_buf_length +
-				      UCC_GETH_RX_DATA_BUF_ALIGNMENT);
-	if (skb == NULL)
 		return NULL;
 
 	/* We need the data buffer to be aligned properly.  We will reserve
@@ -2020,8 +2018,6 @@
 		iounmap(ugeth->ug_regs);
 		ugeth->ug_regs = NULL;
 	}
-
-	skb_queue_purge(&ugeth->rx_recycle);
 }
 
 static void ucc_geth_set_multi(struct net_device *dev)
@@ -2230,8 +2226,6 @@
 		return -ENOMEM;
 	}
 
-	skb_queue_head_init(&ugeth->rx_recycle);
-
 	return 0;
 }
 
@@ -3274,12 +3268,7 @@
 			if (netif_msg_rx_err(ugeth))
 				ugeth_err("%s, %d: ERROR!!! skb - 0x%08x",
 					   __func__, __LINE__, (u32) skb);
-			if (skb) {
-				skb->data = skb->head + NET_SKB_PAD;
-				skb->len = 0;
-				skb_reset_tail_pointer(skb);
-				__skb_queue_head(&ugeth->rx_recycle, skb);
-			}
+			dev_kfree_skb(skb);
 
 			ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]] = NULL;
 			dev->stats.rx_dropped++;
@@ -3349,13 +3338,7 @@
 
 		dev->stats.tx_packets++;
 
-		if (skb_queue_len(&ugeth->rx_recycle) < RX_BD_RING_LEN &&
-			     skb_recycle_check(skb,
-				    ugeth->ug_info->uf_info.max_rx_buf_length +
-				    UCC_GETH_RX_DATA_BUF_ALIGNMENT))
-			__skb_queue_head(&ugeth->rx_recycle, skb);
-		else
-			dev_kfree_skb(skb);
+		dev_kfree_skb(skb);
 
 		ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]] = NULL;
 		ugeth->skb_dirtytx[txQ] =
diff --git a/drivers/net/ethernet/freescale/ucc_geth.h b/drivers/net/ethernet/freescale/ucc_geth.h
index f71b3e7..75f3371 100644
--- a/drivers/net/ethernet/freescale/ucc_geth.h
+++ b/drivers/net/ethernet/freescale/ucc_geth.h
@@ -1214,8 +1214,6 @@
 	/* index of the first skb which hasn't been transmitted yet. */
 	u16 skb_dirtytx[NUM_TX_QUEUES];
 
-	struct sk_buff_head rx_recycle;
-
 	struct ugeth_mii_info *mii_info;
 	struct phy_device *phydev;
 	phy_interface_t phy_interface;
diff --git a/drivers/net/ethernet/intel/e1000e/hw.h b/drivers/net/ethernet/intel/e1000e/hw.h
index ed5b409..d37bfd9 100644
--- a/drivers/net/ethernet/intel/e1000e/hw.h
+++ b/drivers/net/ethernet/intel/e1000e/hw.h
@@ -412,6 +412,8 @@
 #define E1000_DEV_ID_PCH2_LV_V			0x1503
 #define E1000_DEV_ID_PCH_LPT_I217_LM		0x153A
 #define E1000_DEV_ID_PCH_LPT_I217_V		0x153B
+#define E1000_DEV_ID_PCH_LPTLP_I218_LM		0x155A
+#define E1000_DEV_ID_PCH_LPTLP_I218_V		0x1559
 
 #define E1000_REVISION_4 4
 
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index fb659dd..de57a2b 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -6558,6 +6558,8 @@
 
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LPT_I217_LM), board_pch_lpt },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LPT_I217_V), board_pch_lpt },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LPTLP_I218_LM), board_pch_lpt },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LPTLP_I218_V), board_pch_lpt },
 
 	{ 0, 0, 0, 0, 0, 0, 0 }	/* terminate list */
 };
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 5bd2676..30efc9f 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -410,7 +410,7 @@
 #define IXGBE_TX_CTXTDESC(R, i)	    \
 	(&(((struct ixgbe_adv_tx_context_desc *)((R)->desc))[i]))
 
-#define IXGBE_MAX_JUMBO_FRAME_SIZE        16128
+#define IXGBE_MAX_JUMBO_FRAME_SIZE	9728 /* Maximum Supported Size 9.5KB */
 #ifdef IXGBE_FCOE
 /* Use 3K as the baby jumbo frame size for FCoE */
 #define IXGBE_FCOE_JUMBO_FRAME_SIZE       3072
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
index 383b4e1..4a9c9c2 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h
@@ -175,7 +175,7 @@
 #define IXGBEVF_TX_CTXTDESC(R, i)	    \
 	(&(((struct ixgbe_adv_tx_context_desc *)((R)->desc))[i]))
 
-#define IXGBE_MAX_JUMBO_FRAME_SIZE        16128
+#define IXGBE_MAX_JUMBO_FRAME_SIZE	9728 /* Maximum Supported Size 9.5KB */
 
 #define OTHER_VECTOR 1
 #define NON_Q_VECTORS (OTHER_VECTOR)
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index 0ee9bd4..de1ad50 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -1747,6 +1747,7 @@
  **/
 static int ixgbevf_set_interrupt_capability(struct ixgbevf_adapter *adapter)
 {
+	struct net_device *netdev = adapter->netdev;
 	int err = 0;
 	int vector, v_budget;
 
@@ -1775,6 +1776,12 @@
 
 	ixgbevf_acquire_msix_vectors(adapter, v_budget);
 
+	err = netif_set_real_num_tx_queues(netdev, adapter->num_tx_queues);
+	if (err)
+		goto out;
+
+	err = netif_set_real_num_rx_queues(netdev, adapter->num_rx_queues);
+
 out:
 	return err;
 }
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index 087b9e0..84c1326 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -412,7 +412,6 @@
 	u8 work_rx_refill;
 
 	int skb_size;
-	struct sk_buff_head rx_recycle;
 
 	/*
 	 * RX state.
@@ -673,9 +672,7 @@
 		struct rx_desc *rx_desc;
 		int size;
 
-		skb = __skb_dequeue(&mp->rx_recycle);
-		if (skb == NULL)
-			skb = netdev_alloc_skb(mp->dev, mp->skb_size);
+		skb = netdev_alloc_skb(mp->dev, mp->skb_size);
 
 		if (skb == NULL) {
 			mp->oom = 1;
@@ -989,14 +986,7 @@
 				       desc->byte_cnt, DMA_TO_DEVICE);
 		}
 
-		if (skb != NULL) {
-			if (skb_queue_len(&mp->rx_recycle) <
-					mp->rx_ring_size &&
-			    skb_recycle_check(skb, mp->skb_size))
-				__skb_queue_head(&mp->rx_recycle, skb);
-			else
-				dev_kfree_skb(skb);
-		}
+		dev_kfree_skb(skb);
 	}
 
 	__netif_tx_unlock(nq);
@@ -2349,8 +2339,6 @@
 
 	napi_enable(&mp->napi);
 
-	skb_queue_head_init(&mp->rx_recycle);
-
 	mp->int_mask = INT_EXT;
 
 	for (i = 0; i < mp->rxq_count; i++) {
@@ -2445,8 +2433,6 @@
 	mib_counters_update(mp);
 	del_timer_sync(&mp->mib_counters_timer);
 
-	skb_queue_purge(&mp->rx_recycle);
-
 	for (i = 0; i < mp->rxq_count; i++)
 		rxq_deinit(mp->rxq + i);
 	for (i = 0; i < mp->txq_count; i++)
diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c
index 5a30bf8..9b9c2ac 100644
--- a/drivers/net/ethernet/marvell/skge.c
+++ b/drivers/net/ethernet/marvell/skge.c
@@ -3189,7 +3189,7 @@
 	if (work_done < to_do) {
 		unsigned long flags;
 
-		napi_gro_flush(napi);
+		napi_gro_flush(napi, false);
 		spin_lock_irqsave(&hw->hw_lock, flags);
 		__napi_complete(napi);
 		hw->intr_mask |= napimask[skge->port];
@@ -3945,8 +3945,10 @@
 		skge_board_name(hw), hw->chip_rev);
 
 	dev = skge_devinit(hw, 0, using_dac);
-	if (!dev)
+	if (!dev) {
+		err = -ENOMEM;
 		goto err_out_led_off;
+	}
 
 	/* Some motherboards are broken and has zero in ROM. */
 	if (!is_valid_ether_addr(dev->dev_addr))
@@ -4153,6 +4155,13 @@
 			DMI_MATCH(DMI_BOARD_NAME, "nForce"),
 		},
 	},
+	{
+		.ident = "ASUS P5NSLI",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+			DMI_MATCH(DMI_BOARD_NAME, "P5NSLI")
+		},
+	},
 	{}
 };
 
diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
index 2b0748d..78946fe 100644
--- a/drivers/net/ethernet/marvell/sky2.c
+++ b/drivers/net/ethernet/marvell/sky2.c
@@ -4924,6 +4924,7 @@
 
 	if (~reg == 0) {
 		dev_err(&pdev->dev, "PCI configuration read error\n");
+		err = -EIO;
 		goto err_out;
 	}
 
@@ -4993,8 +4994,10 @@
 	hw->st_size = hw->ports * roundup_pow_of_two(3*RX_MAX_PENDING + TX_MAX_PENDING);
 	hw->st_le = pci_alloc_consistent(pdev, hw->st_size * sizeof(struct sky2_status_le),
 					 &hw->st_dma);
-	if (!hw->st_le)
+	if (!hw->st_le) {
+		err = -ENOMEM;
 		goto err_out_reset;
+	}
 
 	dev_info(&pdev->dev, "Yukon-2 %s chip revision %d\n",
 		 sky2_name(hw->chip_id, buf1, sizeof(buf1)), hw->chip_rev);
diff --git a/drivers/net/ethernet/natsemi/natsemi.c b/drivers/net/ethernet/natsemi/natsemi.c
index 5b61d12..dbaaa99 100644
--- a/drivers/net/ethernet/natsemi/natsemi.c
+++ b/drivers/net/ethernet/natsemi/natsemi.c
@@ -947,8 +947,8 @@
 	i = register_netdev(dev);
 	if (i)
 		goto err_register_netdev;
-
-	if (NATSEMI_CREATE_FILE(pdev, dspcfg_workaround))
+	i = NATSEMI_CREATE_FILE(pdev, dspcfg_workaround);
+	if (i)
 		goto err_create_file;
 
 	if (netif_msg_drv(np)) {
diff --git a/drivers/net/ethernet/natsemi/xtsonic.c b/drivers/net/ethernet/natsemi/xtsonic.c
index e01c0a0..7dfe883 100644
--- a/drivers/net/ethernet/natsemi/xtsonic.c
+++ b/drivers/net/ethernet/natsemi/xtsonic.c
@@ -205,6 +205,7 @@
 	if (lp->descriptors == NULL) {
 		printk(KERN_ERR "%s: couldn't alloc DMA memory for "
 				" descriptors.\n", dev_name(lp->device));
+		err = -ENOMEM;
 		goto out;
 	}
 
diff --git a/drivers/net/ethernet/octeon/octeon_mgmt.c b/drivers/net/ethernet/octeon/octeon_mgmt.c
index a688a2d..f97719c 100644
--- a/drivers/net/ethernet/octeon/octeon_mgmt.c
+++ b/drivers/net/ethernet/octeon/octeon_mgmt.c
@@ -3,13 +3,14 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2009 Cavium Networks
+ * Copyright (C) 2009-2012 Cavium, Inc
  */
 
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/etherdevice.h>
 #include <linux/capability.h>
+#include <linux/net_tstamp.h>
 #include <linux/interrupt.h>
 #include <linux/netdevice.h>
 #include <linux/spinlock.h>
@@ -33,8 +34,7 @@
 
 #define OCTEON_MGMT_NAPI_WEIGHT 16
 
-/*
- * Ring sizes that are powers of two allow for more efficient modulo
+/* Ring sizes that are powers of two allow for more efficient modulo
  * opertions.
  */
 #define OCTEON_MGMT_RX_RING_SIZE 512
@@ -93,6 +93,7 @@
 #define AGL_GMX_RX_ADR_CAM4		0x1a0
 #define AGL_GMX_RX_ADR_CAM5		0x1a8
 
+#define AGL_GMX_TX_CLK			0x208
 #define AGL_GMX_TX_STATS_CTL		0x268
 #define AGL_GMX_TX_CTL			0x270
 #define AGL_GMX_TX_STAT0		0x280
@@ -110,8 +111,10 @@
 	struct net_device *netdev;
 	u64 mix;
 	u64 agl;
+	u64 agl_prt_ctl;
 	int port;
 	int irq;
+	bool has_rx_tstamp;
 	u64 *tx_ring;
 	dma_addr_t tx_ring_handle;
 	unsigned int tx_next;
@@ -131,6 +134,7 @@
 	spinlock_t lock;
 	unsigned int last_duplex;
 	unsigned int last_link;
+	unsigned int last_speed;
 	struct device *dev;
 	struct napi_struct napi;
 	struct tasklet_struct tx_clean_tasklet;
@@ -140,6 +144,8 @@
 	resource_size_t mix_size;
 	resource_size_t agl_phys;
 	resource_size_t agl_size;
+	resource_size_t agl_prt_ctl_phys;
+	resource_size_t agl_prt_ctl_size;
 };
 
 static void octeon_mgmt_set_rx_irq(struct octeon_mgmt *p, int enable)
@@ -166,22 +172,22 @@
 	spin_unlock_irqrestore(&p->lock, flags);
 }
 
-static inline void octeon_mgmt_enable_rx_irq(struct octeon_mgmt *p)
+static void octeon_mgmt_enable_rx_irq(struct octeon_mgmt *p)
 {
 	octeon_mgmt_set_rx_irq(p, 1);
 }
 
-static inline void octeon_mgmt_disable_rx_irq(struct octeon_mgmt *p)
+static void octeon_mgmt_disable_rx_irq(struct octeon_mgmt *p)
 {
 	octeon_mgmt_set_rx_irq(p, 0);
 }
 
-static inline void octeon_mgmt_enable_tx_irq(struct octeon_mgmt *p)
+static void octeon_mgmt_enable_tx_irq(struct octeon_mgmt *p)
 {
 	octeon_mgmt_set_tx_irq(p, 1);
 }
 
-static inline void octeon_mgmt_disable_tx_irq(struct octeon_mgmt *p)
+static void octeon_mgmt_disable_tx_irq(struct octeon_mgmt *p)
 {
 	octeon_mgmt_set_tx_irq(p, 0);
 }
@@ -233,6 +239,28 @@
 	}
 }
 
+static ktime_t ptp_to_ktime(u64 ptptime)
+{
+	ktime_t ktimebase;
+	u64 ptpbase;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	/* Fill the icache with the code */
+	ktime_get_real();
+	/* Flush all pending operations */
+	mb();
+	/* Read the time and PTP clock as close together as
+	 * possible. It is important that this sequence take the same
+	 * amount of time to reduce jitter
+	 */
+	ktimebase = ktime_get_real();
+	ptpbase = cvmx_read_csr(CVMX_MIO_PTP_CLOCK_HI);
+	local_irq_restore(flags);
+
+	return ktime_sub_ns(ktimebase, ptpbase - ptptime);
+}
+
 static void octeon_mgmt_clean_tx_buffers(struct octeon_mgmt *p)
 {
 	union cvmx_mixx_orcnt mix_orcnt;
@@ -272,6 +300,20 @@
 
 		dma_unmap_single(p->dev, re.s.addr, re.s.len,
 				 DMA_TO_DEVICE);
+
+		/* Read the hardware TX timestamp if one was recorded */
+		if (unlikely(re.s.tstamp)) {
+			struct skb_shared_hwtstamps ts;
+			/* Read the timestamp */
+			u64 ns = cvmx_read_csr(CVMX_MIXX_TSTAMP(p->port));
+			/* Remove the timestamp from the FIFO */
+			cvmx_write_csr(CVMX_MIXX_TSCTL(p->port), 0);
+			/* Tell the kernel about the timestamp */
+			ts.syststamp = ptp_to_ktime(ns);
+			ts.hwtstamp = ns_to_ktime(ns);
+			skb_tstamp_tx(skb, &ts);
+		}
+
 		dev_kfree_skb_any(skb);
 		cleaned++;
 
@@ -372,14 +414,23 @@
 		/* A good packet, send it up. */
 		skb_put(skb, re.s.len);
 good:
+		/* Process the RX timestamp if it was recorded */
+		if (p->has_rx_tstamp) {
+			/* The first 8 bytes are the timestamp */
+			u64 ns = *(u64 *)skb->data;
+			struct skb_shared_hwtstamps *ts;
+			ts = skb_hwtstamps(skb);
+			ts->hwtstamp = ns_to_ktime(ns);
+			ts->syststamp = ptp_to_ktime(ns);
+			__skb_pull(skb, 8);
+		}
 		skb->protocol = eth_type_trans(skb, netdev);
 		netdev->stats.rx_packets++;
 		netdev->stats.rx_bytes += skb->len;
 		netif_receive_skb(skb);
 		rc = 0;
 	} else if (re.s.code == RING_ENTRY_CODE_MORE) {
-		/*
-		 * Packet split across skbs.  This can happen if we
+		/* Packet split across skbs.  This can happen if we
 		 * increase the MTU.  Buffers that are already in the
 		 * rx ring can then end up being too small.  As the rx
 		 * ring is refilled, buffers sized for the new MTU
@@ -409,8 +460,7 @@
 	} else {
 		/* Some other error, discard it. */
 		dev_kfree_skb_any(skb);
-		/*
-		 * Error statistics are accumulated in
+		/* Error statistics are accumulated in
 		 * octeon_mgmt_update_rx_stats.
 		 */
 	}
@@ -488,7 +538,7 @@
 	mix_ctl.s.reset = 1;
 	cvmx_write_csr(p->mix + MIX_CTL, mix_ctl.u64);
 	cvmx_read_csr(p->mix + MIX_CTL);
-	cvmx_wait(64);
+	octeon_io_clk_delay(64);
 
 	mix_bist.u64 = cvmx_read_csr(p->mix + MIX_BIST);
 	if (mix_bist.u64)
@@ -537,8 +587,7 @@
 		cam_mode = 0;
 		available_cam_entries = 8;
 	} else {
-		/*
-		 * One CAM entry for the primary address, leaves seven
+		/* One CAM entry for the primary address, leaves seven
 		 * for the secondary addresses.
 		 */
 		available_cam_entries = 7 - netdev->uc.count;
@@ -595,12 +644,10 @@
 
 static int octeon_mgmt_set_mac_address(struct net_device *netdev, void *addr)
 {
-	struct sockaddr *sa = addr;
+	int r = eth_mac_addr(netdev, addr);
 
-	if (!is_valid_ether_addr(sa->sa_data))
-		return -EADDRNOTAVAIL;
-
-	memcpy(netdev->dev_addr, sa->sa_data, ETH_ALEN);
+	if (r)
+		return r;
 
 	octeon_mgmt_set_rx_filtering(netdev);
 
@@ -612,8 +659,7 @@
 	struct octeon_mgmt *p = netdev_priv(netdev);
 	int size_without_fcs = new_mtu + OCTEON_MGMT_RX_HEADROOM;
 
-	/*
-	 * Limit the MTU to make sure the ethernet packets are between
+	/* Limit the MTU to make sure the ethernet packets are between
 	 * 64 bytes and 16383 bytes.
 	 */
 	if (size_without_fcs < 64 || size_without_fcs > 16383) {
@@ -656,53 +702,258 @@
 	return IRQ_HANDLED;
 }
 
+static int octeon_mgmt_ioctl_hwtstamp(struct net_device *netdev,
+				      struct ifreq *rq, int cmd)
+{
+	struct octeon_mgmt *p = netdev_priv(netdev);
+	struct hwtstamp_config config;
+	union cvmx_mio_ptp_clock_cfg ptp;
+	union cvmx_agl_gmx_rxx_frm_ctl rxx_frm_ctl;
+	bool have_hw_timestamps = false;
+
+	if (copy_from_user(&config, rq->ifr_data, sizeof(config)))
+		return -EFAULT;
+
+	if (config.flags) /* reserved for future extensions */
+		return -EINVAL;
+
+	/* Check the status of hardware for tiemstamps */
+	if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+		/* Get the current state of the PTP clock */
+		ptp.u64 = cvmx_read_csr(CVMX_MIO_PTP_CLOCK_CFG);
+		if (!ptp.s.ext_clk_en) {
+			/* The clock has not been configured to use an
+			 * external source.  Program it to use the main clock
+			 * reference.
+			 */
+			u64 clock_comp = (NSEC_PER_SEC << 32) /	octeon_get_io_clock_rate();
+			if (!ptp.s.ptp_en)
+				cvmx_write_csr(CVMX_MIO_PTP_CLOCK_COMP, clock_comp);
+			pr_info("PTP Clock: Using sclk reference at %lld Hz\n",
+				(NSEC_PER_SEC << 32) / clock_comp);
+		} else {
+			/* The clock is already programmed to use a GPIO */
+			u64 clock_comp = cvmx_read_csr(CVMX_MIO_PTP_CLOCK_COMP);
+			pr_info("PTP Clock: Using GPIO %d at %lld Hz\n",
+				ptp.s.ext_clk_in,
+				(NSEC_PER_SEC << 32) / clock_comp);
+		}
+
+		/* Enable the clock if it wasn't done already */
+		if (!ptp.s.ptp_en) {
+			ptp.s.ptp_en = 1;
+			cvmx_write_csr(CVMX_MIO_PTP_CLOCK_CFG, ptp.u64);
+		}
+		have_hw_timestamps = true;
+	}
+
+	if (!have_hw_timestamps)
+		return -EINVAL;
+
+	switch (config.tx_type) {
+	case HWTSTAMP_TX_OFF:
+	case HWTSTAMP_TX_ON:
+		break;
+	default:
+		return -ERANGE;
+	}
+
+	switch (config.rx_filter) {
+	case HWTSTAMP_FILTER_NONE:
+		p->has_rx_tstamp = false;
+		rxx_frm_ctl.u64 = cvmx_read_csr(p->agl + AGL_GMX_RX_FRM_CTL);
+		rxx_frm_ctl.s.ptp_mode = 0;
+		cvmx_write_csr(p->agl + AGL_GMX_RX_FRM_CTL, rxx_frm_ctl.u64);
+		break;
+	case HWTSTAMP_FILTER_ALL:
+	case HWTSTAMP_FILTER_SOME:
+	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
+	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
+	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
+	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
+	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
+	case HWTSTAMP_FILTER_PTP_V2_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
+		p->has_rx_tstamp = have_hw_timestamps;
+		config.rx_filter = HWTSTAMP_FILTER_ALL;
+		if (p->has_rx_tstamp) {
+			rxx_frm_ctl.u64 = cvmx_read_csr(p->agl + AGL_GMX_RX_FRM_CTL);
+			rxx_frm_ctl.s.ptp_mode = 1;
+			cvmx_write_csr(p->agl + AGL_GMX_RX_FRM_CTL, rxx_frm_ctl.u64);
+		}
+		break;
+	default:
+		return -ERANGE;
+	}
+
+	if (copy_to_user(rq->ifr_data, &config, sizeof(config)))
+		return -EFAULT;
+
+	return 0;
+}
+
 static int octeon_mgmt_ioctl(struct net_device *netdev,
 			     struct ifreq *rq, int cmd)
 {
 	struct octeon_mgmt *p = netdev_priv(netdev);
 
-	if (!netif_running(netdev))
+	switch (cmd) {
+	case SIOCSHWTSTAMP:
+		return octeon_mgmt_ioctl_hwtstamp(netdev, rq, cmd);
+	default:
+		if (p->phydev)
+			return phy_mii_ioctl(p->phydev, rq, cmd);
 		return -EINVAL;
+	}
+}
 
-	if (!p->phydev)
-		return -EINVAL;
+static void octeon_mgmt_disable_link(struct octeon_mgmt *p)
+{
+	union cvmx_agl_gmx_prtx_cfg prtx_cfg;
 
-	return phy_mii_ioctl(p->phydev, rq, cmd);
+	/* Disable GMX before we make any changes. */
+	prtx_cfg.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG);
+	prtx_cfg.s.en = 0;
+	prtx_cfg.s.tx_en = 0;
+	prtx_cfg.s.rx_en = 0;
+	cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, prtx_cfg.u64);
+
+	if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+		int i;
+		for (i = 0; i < 10; i++) {
+			prtx_cfg.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG);
+			if (prtx_cfg.s.tx_idle == 1 || prtx_cfg.s.rx_idle == 1)
+				break;
+			mdelay(1);
+			i++;
+		}
+	}
+}
+
+static void octeon_mgmt_enable_link(struct octeon_mgmt *p)
+{
+	union cvmx_agl_gmx_prtx_cfg prtx_cfg;
+
+	/* Restore the GMX enable state only if link is set */
+	prtx_cfg.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG);
+	prtx_cfg.s.tx_en = 1;
+	prtx_cfg.s.rx_en = 1;
+	prtx_cfg.s.en = 1;
+	cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, prtx_cfg.u64);
+}
+
+static void octeon_mgmt_update_link(struct octeon_mgmt *p)
+{
+	union cvmx_agl_gmx_prtx_cfg prtx_cfg;
+
+	prtx_cfg.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG);
+
+	if (!p->phydev->link)
+		prtx_cfg.s.duplex = 1;
+	else
+		prtx_cfg.s.duplex = p->phydev->duplex;
+
+	switch (p->phydev->speed) {
+	case 10:
+		prtx_cfg.s.speed = 0;
+		prtx_cfg.s.slottime = 0;
+
+		if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+			prtx_cfg.s.burst = 1;
+			prtx_cfg.s.speed_msb = 1;
+		}
+		break;
+	case 100:
+		prtx_cfg.s.speed = 0;
+		prtx_cfg.s.slottime = 0;
+
+		if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+			prtx_cfg.s.burst = 1;
+			prtx_cfg.s.speed_msb = 0;
+		}
+		break;
+	case 1000:
+		/* 1000 MBits is only supported on 6XXX chips */
+		if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+			prtx_cfg.s.speed = 1;
+			prtx_cfg.s.speed_msb = 0;
+			/* Only matters for half-duplex */
+			prtx_cfg.s.slottime = 1;
+			prtx_cfg.s.burst = p->phydev->duplex;
+		}
+		break;
+	case 0:  /* No link */
+	default:
+		break;
+	}
+
+	/* Write the new GMX setting with the port still disabled. */
+	cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, prtx_cfg.u64);
+
+	/* Read GMX CFG again to make sure the config is completed. */
+	prtx_cfg.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG);
+
+	if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+		union cvmx_agl_gmx_txx_clk agl_clk;
+		union cvmx_agl_prtx_ctl prtx_ctl;
+
+		prtx_ctl.u64 = cvmx_read_csr(p->agl_prt_ctl);
+		agl_clk.u64 = cvmx_read_csr(p->agl + AGL_GMX_TX_CLK);
+		/* MII (both speeds) and RGMII 1000 speed. */
+		agl_clk.s.clk_cnt = 1;
+		if (prtx_ctl.s.mode == 0) { /* RGMII mode */
+			if (p->phydev->speed == 10)
+				agl_clk.s.clk_cnt = 50;
+			else if (p->phydev->speed == 100)
+				agl_clk.s.clk_cnt = 5;
+		}
+		cvmx_write_csr(p->agl + AGL_GMX_TX_CLK, agl_clk.u64);
+	}
 }
 
 static void octeon_mgmt_adjust_link(struct net_device *netdev)
 {
 	struct octeon_mgmt *p = netdev_priv(netdev);
-	union cvmx_agl_gmx_prtx_cfg prtx_cfg;
 	unsigned long flags;
 	int link_changed = 0;
 
+	if (!p->phydev)
+		return;
+
 	spin_lock_irqsave(&p->lock, flags);
-	if (p->phydev->link) {
-		if (!p->last_link)
-			link_changed = 1;
-		if (p->last_duplex != p->phydev->duplex) {
-			p->last_duplex = p->phydev->duplex;
-			prtx_cfg.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG);
-			prtx_cfg.s.duplex = p->phydev->duplex;
-			cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, prtx_cfg.u64);
-		}
-	} else {
-		if (p->last_link)
-			link_changed = -1;
+
+
+	if (!p->phydev->link && p->last_link)
+		link_changed = -1;
+
+	if (p->phydev->link
+	    && (p->last_duplex != p->phydev->duplex
+		|| p->last_link != p->phydev->link
+		|| p->last_speed != p->phydev->speed)) {
+		octeon_mgmt_disable_link(p);
+		link_changed = 1;
+		octeon_mgmt_update_link(p);
+		octeon_mgmt_enable_link(p);
 	}
+
 	p->last_link = p->phydev->link;
+	p->last_speed = p->phydev->speed;
+	p->last_duplex = p->phydev->duplex;
+
 	spin_unlock_irqrestore(&p->lock, flags);
 
 	if (link_changed != 0) {
 		if (link_changed > 0) {
-			netif_carrier_on(netdev);
 			pr_info("%s: Link is up - %d/%s\n", netdev->name,
 				p->phydev->speed,
 				DUPLEX_FULL == p->phydev->duplex ?
 				"Full" : "Half");
 		} else {
-			netif_carrier_off(netdev);
 			pr_info("%s: Link is down\n", netdev->name);
 		}
 	}
@@ -723,9 +974,7 @@
 				   PHY_INTERFACE_MODE_MII);
 
 	if (!p->phydev)
-		return -1;
-
-	phy_start_aneg(p->phydev);
+		return -ENODEV;
 
 	return 0;
 }
@@ -733,12 +982,10 @@
 static int octeon_mgmt_open(struct net_device *netdev)
 {
 	struct octeon_mgmt *p = netdev_priv(netdev);
-	int port = p->port;
 	union cvmx_mixx_ctl mix_ctl;
 	union cvmx_agl_gmx_inf_mode agl_gmx_inf_mode;
 	union cvmx_mixx_oring1 oring1;
 	union cvmx_mixx_iring1 iring1;
-	union cvmx_agl_gmx_prtx_cfg prtx_cfg;
 	union cvmx_agl_gmx_rxx_frm_ctl rxx_frm_ctl;
 	union cvmx_mixx_irhwm mix_irhwm;
 	union cvmx_mixx_orhwm mix_orhwm;
@@ -785,9 +1032,30 @@
 		} while (mix_ctl.s.reset);
 	}
 
-	agl_gmx_inf_mode.u64 = 0;
-	agl_gmx_inf_mode.s.en = 1;
-	cvmx_write_csr(CVMX_AGL_GMX_INF_MODE, agl_gmx_inf_mode.u64);
+	if (OCTEON_IS_MODEL(OCTEON_CN5XXX)) {
+		agl_gmx_inf_mode.u64 = 0;
+		agl_gmx_inf_mode.s.en = 1;
+		cvmx_write_csr(CVMX_AGL_GMX_INF_MODE, agl_gmx_inf_mode.u64);
+	}
+	if (OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)
+		|| OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) {
+		/* Force compensation values, as they are not
+		 * determined properly by HW
+		 */
+		union cvmx_agl_gmx_drv_ctl drv_ctl;
+
+		drv_ctl.u64 = cvmx_read_csr(CVMX_AGL_GMX_DRV_CTL);
+		if (p->port) {
+			drv_ctl.s.byp_en1 = 1;
+			drv_ctl.s.nctl1 = 6;
+			drv_ctl.s.pctl1 = 6;
+		} else {
+			drv_ctl.s.byp_en = 1;
+			drv_ctl.s.nctl = 6;
+			drv_ctl.s.pctl = 6;
+		}
+		cvmx_write_csr(CVMX_AGL_GMX_DRV_CTL, drv_ctl.u64);
+	}
 
 	oring1.u64 = 0;
 	oring1.s.obase = p->tx_ring_handle >> 3;
@@ -799,18 +1067,12 @@
 	iring1.s.isize = OCTEON_MGMT_RX_RING_SIZE;
 	cvmx_write_csr(p->mix + MIX_IRING1, iring1.u64);
 
-	/* Disable packet I/O. */
-	prtx_cfg.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG);
-	prtx_cfg.s.en = 0;
-	cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, prtx_cfg.u64);
-
 	memcpy(sa.sa_data, netdev->dev_addr, ETH_ALEN);
 	octeon_mgmt_set_mac_address(netdev, &sa);
 
 	octeon_mgmt_change_mtu(netdev, netdev->mtu);
 
-	/*
-	 * Enable the port HW. Packets are not allowed until
+	/* Enable the port HW. Packets are not allowed until
 	 * cvmx_mgmt_port_enable() is called.
 	 */
 	mix_ctl.u64 = 0;
@@ -819,27 +1081,70 @@
 	mix_ctl.s.nbtarb = 0;       /* Arbitration mode */
 	/* MII CB-request FIFO programmable high watermark */
 	mix_ctl.s.mrq_hwm = 1;
+#ifdef __LITTLE_ENDIAN
+	mix_ctl.s.lendian = 1;
+#endif
 	cvmx_write_csr(p->mix + MIX_CTL, mix_ctl.u64);
 
-	if (OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)
-	    || OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) {
-		/*
-		 * Force compensation values, as they are not
-		 * determined properly by HW
-		 */
-		union cvmx_agl_gmx_drv_ctl drv_ctl;
+	/* Read the PHY to find the mode of the interface. */
+	if (octeon_mgmt_init_phy(netdev)) {
+		dev_err(p->dev, "Cannot initialize PHY on MIX%d.\n", p->port);
+		goto err_noirq;
+	}
 
-		drv_ctl.u64 = cvmx_read_csr(CVMX_AGL_GMX_DRV_CTL);
-		if (port) {
-			drv_ctl.s.byp_en1 = 1;
-			drv_ctl.s.nctl1 = 6;
-			drv_ctl.s.pctl1 = 6;
-		} else {
-			drv_ctl.s.byp_en = 1;
-			drv_ctl.s.nctl = 6;
-			drv_ctl.s.pctl = 6;
+	/* Set the mode of the interface, RGMII/MII. */
+	if (OCTEON_IS_MODEL(OCTEON_CN6XXX) && p->phydev) {
+		union cvmx_agl_prtx_ctl agl_prtx_ctl;
+		int rgmii_mode = (p->phydev->supported &
+				  (SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full)) != 0;
+
+		agl_prtx_ctl.u64 = cvmx_read_csr(p->agl_prt_ctl);
+		agl_prtx_ctl.s.mode = rgmii_mode ? 0 : 1;
+		cvmx_write_csr(p->agl_prt_ctl,	agl_prtx_ctl.u64);
+
+		/* MII clocks counts are based on the 125Mhz
+		 * reference, which has an 8nS period. So our delays
+		 * need to be multiplied by this factor.
+		 */
+#define NS_PER_PHY_CLK 8
+
+		/* Take the DLL and clock tree out of reset */
+		agl_prtx_ctl.u64 = cvmx_read_csr(p->agl_prt_ctl);
+		agl_prtx_ctl.s.clkrst = 0;
+		if (rgmii_mode) {
+			agl_prtx_ctl.s.dllrst = 0;
+			agl_prtx_ctl.s.clktx_byp = 0;
 		}
-		cvmx_write_csr(CVMX_AGL_GMX_DRV_CTL, drv_ctl.u64);
+		cvmx_write_csr(p->agl_prt_ctl,	agl_prtx_ctl.u64);
+		cvmx_read_csr(p->agl_prt_ctl); /* Force write out before wait */
+
+		/* Wait for the DLL to lock. External 125 MHz
+		 * reference clock must be stable at this point.
+		 */
+		ndelay(256 * NS_PER_PHY_CLK);
+
+		/* Enable the interface */
+		agl_prtx_ctl.u64 = cvmx_read_csr(p->agl_prt_ctl);
+		agl_prtx_ctl.s.enable = 1;
+		cvmx_write_csr(p->agl_prt_ctl, agl_prtx_ctl.u64);
+
+		/* Read the value back to force the previous write */
+		agl_prtx_ctl.u64 = cvmx_read_csr(p->agl_prt_ctl);
+
+		/* Enable the compensation controller */
+		agl_prtx_ctl.s.comp = 1;
+		agl_prtx_ctl.s.drv_byp = 0;
+		cvmx_write_csr(p->agl_prt_ctl,	agl_prtx_ctl.u64);
+		/* Force write out before wait. */
+		cvmx_read_csr(p->agl_prt_ctl);
+
+		/* For compensation state to lock. */
+		ndelay(1040 * NS_PER_PHY_CLK);
+
+		/* Some Ethernet switches cannot handle standard
+		 * Interframe Gap, increase to 16 bytes.
+		 */
+		cvmx_write_csr(CVMX_AGL_GMX_TX_IFG, 0x88);
 	}
 
 	octeon_mgmt_rx_fill_ring(netdev);
@@ -870,7 +1175,7 @@
 
 	/* Interrupt when we have 1 or more packets to clean.  */
 	mix_orhwm.u64 = 0;
-	mix_orhwm.s.orhwm = 1;
+	mix_orhwm.s.orhwm = 0;
 	cvmx_write_csr(p->mix + MIX_ORHWM, mix_orhwm.u64);
 
 	/* Enable receive and transmit interrupts */
@@ -879,13 +1184,12 @@
 	mix_intena.s.othena = 1;
 	cvmx_write_csr(p->mix + MIX_INTENA, mix_intena.u64);
 
-
 	/* Enable packet I/O. */
 
 	rxx_frm_ctl.u64 = 0;
+	rxx_frm_ctl.s.ptp_mode = p->has_rx_tstamp ? 1 : 0;
 	rxx_frm_ctl.s.pre_align = 1;
-	/*
-	 * When set, disables the length check for non-min sized pkts
+	/* When set, disables the length check for non-min sized pkts
 	 * with padding in the client data.
 	 */
 	rxx_frm_ctl.s.pad_len = 1;
@@ -903,33 +1207,26 @@
 	rxx_frm_ctl.s.ctl_drp = 1;
 	/* Strip off the preamble */
 	rxx_frm_ctl.s.pre_strp = 1;
-	/*
-	 * This port is configured to send PREAMBLE+SFD to begin every
+	/* This port is configured to send PREAMBLE+SFD to begin every
 	 * frame.  GMX checks that the PREAMBLE is sent correctly.
 	 */
 	rxx_frm_ctl.s.pre_chk = 1;
 	cvmx_write_csr(p->agl + AGL_GMX_RX_FRM_CTL, rxx_frm_ctl.u64);
 
-	/* Enable the AGL block */
-	agl_gmx_inf_mode.u64 = 0;
-	agl_gmx_inf_mode.s.en = 1;
-	cvmx_write_csr(CVMX_AGL_GMX_INF_MODE, agl_gmx_inf_mode.u64);
-
-	/* Configure the port duplex and enables */
-	prtx_cfg.u64 = cvmx_read_csr(p->agl + AGL_GMX_PRT_CFG);
-	prtx_cfg.s.tx_en = 1;
-	prtx_cfg.s.rx_en = 1;
-	prtx_cfg.s.en = 1;
-	p->last_duplex = 1;
-	prtx_cfg.s.duplex = p->last_duplex;
-	cvmx_write_csr(p->agl + AGL_GMX_PRT_CFG, prtx_cfg.u64);
+	/* Configure the port duplex, speed and enables */
+	octeon_mgmt_disable_link(p);
+	if (p->phydev)
+		octeon_mgmt_update_link(p);
+	octeon_mgmt_enable_link(p);
 
 	p->last_link = 0;
-	netif_carrier_off(netdev);
-
-	if (octeon_mgmt_init_phy(netdev)) {
-		dev_err(p->dev, "Cannot initialize PHY.\n");
-		goto err_noirq;
+	p->last_speed = 0;
+	/* PHY is not present in simulator. The carrier is enabled
+	 * while initializing the phy for simulator, leave it enabled.
+	 */
+	if (p->phydev) {
+		netif_carrier_off(netdev);
+		phy_start_aneg(p->phydev);
 	}
 
 	netif_wake_queue(netdev);
@@ -959,6 +1256,7 @@
 
 	if (p->phydev)
 		phy_disconnect(p->phydev);
+	p->phydev = NULL;
 
 	netif_carrier_off(netdev);
 
@@ -991,6 +1289,7 @@
 	int rv = NETDEV_TX_BUSY;
 
 	re.d64 = 0;
+	re.s.tstamp = ((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) != 0);
 	re.s.len = skb->len;
 	re.s.addr = dma_map_single(p->dev, skb->data,
 				   skb->len,
@@ -1031,6 +1330,7 @@
 	/* Ring the bell.  */
 	cvmx_write_csr(p->mix + MIX_ORING2, 1);
 
+	netdev->trans_start = jiffies;
 	rv = NETDEV_TX_OK;
 out:
 	octeon_mgmt_update_tx_stats(netdev);
@@ -1068,7 +1368,7 @@
 	if (p->phydev)
 		return phy_ethtool_gset(p->phydev, cmd);
 
-	return -EINVAL;
+	return -EOPNOTSUPP;
 }
 
 static int octeon_mgmt_set_settings(struct net_device *netdev,
@@ -1082,23 +1382,37 @@
 	if (p->phydev)
 		return phy_ethtool_sset(p->phydev, cmd);
 
-	return -EINVAL;
+	return -EOPNOTSUPP;
+}
+
+static int octeon_mgmt_nway_reset(struct net_device *dev)
+{
+	struct octeon_mgmt *p = netdev_priv(dev);
+
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	if (p->phydev)
+		return phy_start_aneg(p->phydev);
+
+	return -EOPNOTSUPP;
 }
 
 static const struct ethtool_ops octeon_mgmt_ethtool_ops = {
 	.get_drvinfo = octeon_mgmt_get_drvinfo,
-	.get_link = ethtool_op_get_link,
 	.get_settings = octeon_mgmt_get_settings,
-	.set_settings = octeon_mgmt_set_settings
+	.set_settings = octeon_mgmt_set_settings,
+	.nway_reset = octeon_mgmt_nway_reset,
+	.get_link = ethtool_op_get_link,
 };
 
 static const struct net_device_ops octeon_mgmt_ops = {
 	.ndo_open =			octeon_mgmt_open,
 	.ndo_stop =			octeon_mgmt_stop,
 	.ndo_start_xmit =		octeon_mgmt_xmit,
-	.ndo_set_rx_mode = 		octeon_mgmt_set_rx_filtering,
+	.ndo_set_rx_mode =		octeon_mgmt_set_rx_filtering,
 	.ndo_set_mac_address =		octeon_mgmt_set_mac_address,
-	.ndo_do_ioctl = 		octeon_mgmt_ioctl,
+	.ndo_do_ioctl =			octeon_mgmt_ioctl,
 	.ndo_change_mtu =		octeon_mgmt_change_mtu,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller =		octeon_mgmt_poll_controller,
@@ -1113,6 +1427,7 @@
 	const u8 *mac;
 	struct resource *res_mix;
 	struct resource *res_agl;
+	struct resource *res_agl_prt_ctl;
 	int len;
 	int result;
 
@@ -1120,6 +1435,8 @@
 	if (netdev == NULL)
 		return -ENOMEM;
 
+	SET_NETDEV_DEV(netdev, &pdev->dev);
+
 	dev_set_drvdata(&pdev->dev, netdev);
 	p = netdev_priv(netdev);
 	netif_napi_add(netdev, &p->napi, octeon_mgmt_napi_poll,
@@ -1127,6 +1444,7 @@
 
 	p->netdev = netdev;
 	p->dev = &pdev->dev;
+	p->has_rx_tstamp = false;
 
 	data = of_get_property(pdev->dev.of_node, "cell-index", &len);
 	if (data && len == sizeof(*data)) {
@@ -1159,10 +1477,19 @@
 		goto err;
 	}
 
+	res_agl_prt_ctl = platform_get_resource(pdev, IORESOURCE_MEM, 3);
+	if (res_agl_prt_ctl == NULL) {
+		dev_err(&pdev->dev, "no 'reg' resource\n");
+		result = -ENXIO;
+		goto err;
+	}
+
 	p->mix_phys = res_mix->start;
 	p->mix_size = resource_size(res_mix);
 	p->agl_phys = res_agl->start;
 	p->agl_size = resource_size(res_agl);
+	p->agl_prt_ctl_phys = res_agl_prt_ctl->start;
+	p->agl_prt_ctl_size = resource_size(res_agl_prt_ctl);
 
 
 	if (!devm_request_mem_region(&pdev->dev, p->mix_phys, p->mix_size,
@@ -1181,10 +1508,18 @@
 		goto err;
 	}
 
+	if (!devm_request_mem_region(&pdev->dev, p->agl_prt_ctl_phys,
+				     p->agl_prt_ctl_size, res_agl_prt_ctl->name)) {
+		result = -ENXIO;
+		dev_err(&pdev->dev, "request_mem_region (%s) failed\n",
+			res_agl_prt_ctl->name);
+		goto err;
+	}
 
 	p->mix = (u64)devm_ioremap(&pdev->dev, p->mix_phys, p->mix_size);
 	p->agl = (u64)devm_ioremap(&pdev->dev, p->agl_phys, p->agl_size);
-
+	p->agl_prt_ctl = (u64)devm_ioremap(&pdev->dev, p->agl_prt_ctl_phys,
+					   p->agl_prt_ctl_size);
 	spin_lock_init(&p->lock);
 
 	skb_queue_head_init(&p->tx_list);
@@ -1199,14 +1534,19 @@
 
 	mac = of_get_mac_address(pdev->dev.of_node);
 
-	if (mac)
-		memcpy(netdev->dev_addr, mac, 6);
+	if (mac && is_valid_ether_addr(mac)) {
+		memcpy(netdev->dev_addr, mac, ETH_ALEN);
+		netdev->addr_assign_type &= ~NET_ADDR_RANDOM;
+	} else {
+		eth_hw_addr_random(netdev);
+	}
 
 	p->phy_np = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0);
 
 	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(64);
 	pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
 
+	netif_carrier_off(netdev);
 	result = register_netdev(netdev);
 	if (result)
 		goto err;
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig b/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig
index 9730241..5296cc8 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/Kconfig
@@ -26,6 +26,9 @@
 config PCH_PTP
 	bool "PCH PTP clock support"
 	default n
+	depends on EXPERIMENTAL
+	select PPS
+	select PTP_1588_CLOCK
 	select PTP_1588_CLOCK_PCH
 	---help---
 	  Say Y here if you want to use Precision Time Protocol (PTP) in the
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 473ce13..24ad17e 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -1601,7 +1601,8 @@
 	adapter->netdev  = netdev;
 	adapter->pdev    = pdev;
 
-	if (qlcnic_alloc_adapter_resources(adapter))
+	err = qlcnic_alloc_adapter_resources(adapter);
+	if (err)
 		goto err_out_free_netdev;
 
 	adapter->dev_rst_time = jiffies;
diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
index 995d0cf..1c81825 100644
--- a/drivers/net/ethernet/realtek/8139cp.c
+++ b/drivers/net/ethernet/realtek/8139cp.c
@@ -563,7 +563,7 @@
 		if (cpr16(IntrStatus) & cp_rx_intr_mask)
 			goto rx_status_loop;
 
-		napi_gro_flush(napi);
+		napi_gro_flush(napi, false);
 		spin_lock_irqsave(&cp->lock, flags);
 		__napi_complete(napi);
 		cpw16_f(IntrMask, cp_intr_mask);
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index bad8f2e..c8bfea0 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -2438,6 +2438,7 @@
 		rtsu = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 		if (!rtsu) {
 			dev_err(&pdev->dev, "Not found TSU resource\n");
+			ret = -ENODEV;
 			goto out_release;
 		}
 		mdp->tsu_addr = ioremap(rtsu->start,
diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c
index 5b3dd02..0767043f 100644
--- a/drivers/net/ethernet/sfc/ptp.c
+++ b/drivers/net/ethernet/sfc/ptp.c
@@ -640,8 +640,7 @@
 			evt = list_entry(cursor, struct efx_ptp_event_rx,
 					 link);
 			if (time_after(jiffies, evt->expiry)) {
-				list_del(&evt->link);
-				list_add(&evt->link, &ptp->evt_free_list);
+				list_move(&evt->link, &ptp->evt_free_list);
 				netif_warn(efx, hw, efx->net_dev,
 					   "PTP rx event dropped\n");
 			}
@@ -684,8 +683,7 @@
 
 			match->state = PTP_PACKET_STATE_MATCHED;
 			rc = PTP_PACKET_STATE_MATCHED;
-			list_del(&evt->link);
-			list_add(&evt->link, &ptp->evt_free_list);
+			list_move(&evt->link, &ptp->evt_free_list);
 			break;
 		}
 	}
@@ -820,8 +818,7 @@
 	/* Drop any pending receive events */
 	spin_lock_bh(&efx->ptp_data->evt_lock);
 	list_for_each_safe(cursor, next, &efx->ptp_data->evt_list) {
-		list_del(cursor);
-		list_add(cursor, &efx->ptp_data->evt_free_list);
+		list_move(cursor, &efx->ptp_data->evt_free_list);
 	}
 	spin_unlock_bh(&efx->ptp_data->evt_lock);
 
diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c
index 203d9c6..fb9f6b3 100644
--- a/drivers/net/ethernet/sis/sis900.c
+++ b/drivers/net/ethernet/sis/sis900.c
@@ -478,8 +478,10 @@
 
 	/* IO region. */
 	ioaddr = pci_iomap(pci_dev, 0, 0);
-	if (!ioaddr)
+	if (!ioaddr) {
+		ret = -ENOMEM;
 		goto err_out_cleardev;
+	}
 
 	sis_priv = netdev_priv(net_dev);
 	sis_priv->ioaddr = ioaddr;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index e872e1d..7d51a65 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -50,7 +50,6 @@
 	unsigned int dirty_rx;
 	struct sk_buff **rx_skbuff;
 	dma_addr_t *rx_skbuff_dma;
-	struct sk_buff_head rx_recycle;
 
 	struct net_device *dev;
 	dma_addr_t dma_rx_phy;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 3be8833..c6cdbc4 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -747,18 +747,7 @@
 		priv->hw->ring->clean_desc3(p);
 
 		if (likely(skb != NULL)) {
-			/*
-			 * If there's room in the queue (limit it to size)
-			 * we add this skb back into the pool,
-			 * if it's the right size.
-			 */
-			if ((skb_queue_len(&priv->rx_recycle) <
-				priv->dma_rx_size) &&
-				skb_recycle_check(skb, priv->dma_buf_sz))
-				__skb_queue_head(&priv->rx_recycle, skb);
-			else
-				dev_kfree_skb(skb);
-
+			dev_kfree_skb(skb);
 			priv->tx_skbuff[entry] = NULL;
 		}
 
@@ -1169,7 +1158,6 @@
 	priv->eee_enabled = stmmac_eee_init(priv);
 
 	napi_enable(&priv->napi);
-	skb_queue_head_init(&priv->rx_recycle);
 	netif_start_queue(dev);
 
 	return 0;
@@ -1222,7 +1210,6 @@
 		kfree(priv->tm);
 #endif
 	napi_disable(&priv->napi);
-	skb_queue_purge(&priv->rx_recycle);
 
 	/* Free the IRQ lines */
 	free_irq(dev->irq, dev);
@@ -1388,10 +1375,7 @@
 		if (likely(priv->rx_skbuff[entry] == NULL)) {
 			struct sk_buff *skb;
 
-			skb = __skb_dequeue(&priv->rx_recycle);
-			if (skb == NULL)
-				skb = netdev_alloc_skb_ip_align(priv->dev,
-								bfsize);
+			skb = netdev_alloc_skb_ip_align(priv->dev, bfsize);
 
 			if (unlikely(skb == NULL))
 				break;
diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c
index 8419bf3..275b430 100644
--- a/drivers/net/ethernet/sun/niu.c
+++ b/drivers/net/ethernet/sun/niu.c
@@ -9788,6 +9788,7 @@
 
 	if (!pci_is_pcie(pdev)) {
 		dev_err(&pdev->dev, "Cannot find PCI Express capability, aborting\n");
+		err = -ENODEV;
 		goto err_out_free_res;
 	}
 
diff --git a/drivers/net/ethernet/sun/sungem.c b/drivers/net/ethernet/sun/sungem.c
index 9ae12d0..6c8695e 100644
--- a/drivers/net/ethernet/sun/sungem.c
+++ b/drivers/net/ethernet/sun/sungem.c
@@ -2963,7 +2963,8 @@
 		goto err_out_iounmap;
 	}
 
-	if (gem_get_device_address(gp))
+	err = gem_get_device_address(gp);
+	if (err)
 		goto err_out_free_consistent;
 
 	dev->netdev_ops = &gem_netdev_ops;
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c
index 30087ca..6e4d4b6 100644
--- a/drivers/net/irda/irtty-sir.c
+++ b/drivers/net/irda/irtty-sir.c
@@ -459,8 +459,10 @@
 
 	/* allocate private device info block */
 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-	if (!priv)
+	if (!priv) {
+		ret = -ENOMEM;
 		goto out_put;
+	}
 
 	priv->magic = IRTTY_MAGIC;
 	priv->tty = tty;
diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c
index 1a00b59..f07c340 100644
--- a/drivers/net/irda/mcs7780.c
+++ b/drivers/net/irda/mcs7780.c
@@ -920,8 +920,10 @@
 
 	ndev->netdev_ops = &mcs_netdev_ops;
 
-	if (!intf->cur_altsetting)
+	if (!intf->cur_altsetting) {
+		ret = -ENOMEM;
 		goto error2;
+	}
 
 	ret = mcs_find_endpoints(mcs, intf->cur_altsetting->endpoint,
 				 intf->cur_altsetting->desc.bNumEndpoints);
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
index 002a442..858de05 100644
--- a/drivers/net/irda/pxaficp_ir.c
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -846,8 +846,10 @@
 		goto err_mem_2;
 
 	dev = alloc_irdadev(sizeof(struct pxa_irda));
-	if (!dev)
+	if (!dev) {
+		err = -ENOMEM;
 		goto err_mem_3;
+	}
 
 	SET_NETDEV_DEV(dev, &pdev->dev);
 	si = netdev_priv(dev);
diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
index e250675..42fde9e 100644
--- a/drivers/net/irda/sa1100_ir.c
+++ b/drivers/net/irda/sa1100_ir.c
@@ -940,8 +940,10 @@
 		goto err_mem_3;
 
 	dev = alloc_irdadev(sizeof(struct sa1100_irda));
-	if (!dev)
+	if (!dev) {
+		err = -ENOMEM;
 		goto err_mem_4;
+	}
 
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
diff --git a/drivers/net/irda/sh_irda.c b/drivers/net/irda/sh_irda.c
index eb315b8..4b746d9 100644
--- a/drivers/net/irda/sh_irda.c
+++ b/drivers/net/irda/sh_irda.c
@@ -808,8 +808,8 @@
 		goto err_mem_4;
 
 	platform_set_drvdata(pdev, ndev);
-
-	if (request_irq(irq, sh_irda_irq, IRQF_DISABLED, "sh_irda", self)) {
+	err = request_irq(irq, sh_irda_irq, IRQF_DISABLED, "sh_irda", self);
+	if (err) {
 		dev_warn(&pdev->dev, "Unable to attach sh_irda interrupt\n");
 		goto err_mem_4;
 	}
diff --git a/drivers/net/irda/sh_sir.c b/drivers/net/irda/sh_sir.c
index 7951094..624ac19 100644
--- a/drivers/net/irda/sh_sir.c
+++ b/drivers/net/irda/sh_sir.c
@@ -741,6 +741,7 @@
 	self->clk = clk_get(&pdev->dev, clk_name);
 	if (IS_ERR(self->clk)) {
 		dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
+		err = -ENODEV;
 		goto err_mem_3;
 	}
 
@@ -760,8 +761,8 @@
 		goto err_mem_4;
 
 	platform_set_drvdata(pdev, ndev);
-
-	if (request_irq(irq, sh_sir_irq, IRQF_DISABLED, "sh_sir", self)) {
+	err = request_irq(irq, sh_sir_irq, IRQF_DISABLED, "sh_sir", self);
+	if (err) {
 		dev_warn(&pdev->dev, "Unable to attach sh_sir interrupt\n");
 		goto err_mem_4;
 	}
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 170eb41..c1ef300 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -26,6 +26,7 @@
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/of_device.h>
+#include <linux/of_mdio.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 51de9ed..8be9bf0 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -28,7 +28,6 @@
 #include <linux/igmp.h>
 #include <linux/etherdevice.h>
 #include <linux/if_ether.h>
-#include <linux/version.h>
 #include <linux/hash.h>
 #include <net/ip.h>
 #include <net/icmp.h>
@@ -1084,13 +1083,13 @@
 	if (nla_put_u32(skb, IFLA_VXLAN_ID, vxlan->vni))
 		goto nla_put_failure;
 
-	if (vxlan->gaddr && nla_put_u32(skb, IFLA_VXLAN_GROUP, vxlan->gaddr))
+	if (vxlan->gaddr && nla_put_be32(skb, IFLA_VXLAN_GROUP, vxlan->gaddr))
 		goto nla_put_failure;
 
 	if (vxlan->link && nla_put_u32(skb, IFLA_VXLAN_LINK, vxlan->link))
 		goto nla_put_failure;
 
-	if (vxlan->saddr && nla_put_u32(skb, IFLA_VXLAN_LOCAL, vxlan->saddr))
+	if (vxlan->saddr && nla_put_be32(skb, IFLA_VXLAN_LOCAL, vxlan->saddr))
 		goto nla_put_failure;
 
 	if (nla_put_u8(skb, IFLA_VXLAN_TTL, vxlan->ttl) ||
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index 1a62318..b627132 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -597,7 +597,7 @@
 	 * bottom half for the card.  Note the limitation of 64 cards.
 	 * That ought to be enough
 	 */
-	mask = 1 << card_index;
+	mask = (u64)1 << card_index;
 	*queue |= mask;
 	spin_unlock_irqrestore(&fst_work_q_lock, flags);
 }
diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
index f34b5b2..d93b2b6 100644
--- a/drivers/oprofile/buffer_sync.c
+++ b/drivers/oprofile/buffer_sync.c
@@ -216,7 +216,7 @@
 }
 
 
-/* Look up the dcookie for the task's first VM_EXECUTABLE mapping,
+/* Look up the dcookie for the task's mm->exe_file,
  * which corresponds loosely to "application name". This is
  * not strictly necessary but allows oprofile to associate
  * shared-library samples with particular applications
@@ -224,21 +224,10 @@
 static unsigned long get_exec_dcookie(struct mm_struct *mm)
 {
 	unsigned long cookie = NO_COOKIE;
-	struct vm_area_struct *vma;
 
-	if (!mm)
-		goto out;
+	if (mm && mm->exe_file)
+		cookie = fast_get_dcookie(&mm->exe_file->f_path);
 
-	for (vma = mm->mmap; vma; vma = vma->vm_next) {
-		if (!vma->vm_file)
-			continue;
-		if (!(vma->vm_flags & VM_EXECUTABLE))
-			continue;
-		cookie = fast_get_dcookie(&vma->vm_file->f_path);
-		break;
-	}
-
-out:
 	return cookie;
 }
 
diff --git a/drivers/parport/Kconfig b/drivers/parport/Kconfig
index d92185a..4b6e4e7 100644
--- a/drivers/parport/Kconfig
+++ b/drivers/parport/Kconfig
@@ -36,7 +36,7 @@
 config PARPORT_PC
 	tristate "PC-style hardware"
 	depends on (!SPARC64 || PCI) && !SPARC32 && !M32R && !FRV && \
-		(!M68K || ISA) && !MN10300 && !AVR32 && !BLACKFIN
+		(!M68K || ISA) && !MN10300 && !AVR32 && !BLACKFIN && !XTENSA
 	---help---
 	  You should say Y here if you have a PC-style parallel port. All
 	  IBM PC compatible computers and some Alphas have PC-style
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 33e3df9..7bf914d 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -68,10 +68,21 @@
 	help
 	  Say Y here to enable the imx6q pinctrl driver
 
+config PINCTRL_LANTIQ
+	bool
+	depends on LANTIQ
+	select PINMUX
+	select PINCONF
+
 config PINCTRL_PXA3xx
 	bool
 	select PINMUX
 
+config PINCTRL_FALCON
+	bool
+	depends on SOC_FALCON
+	depends on PINCTRL_LANTIQ
+
 config PINCTRL_MMP2
 	bool "MMP2 pin controller driver"
 	depends on ARCH_MMP
@@ -199,6 +210,11 @@
 
 source "drivers/pinctrl/spear/Kconfig"
 
+config PINCTRL_XWAY
+	bool
+	depends on SOC_TYPE_XWAY
+	depends on PINCTRL_LANTIQ
+
 endmenu
 
 endif
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index f162e01..f395ba5 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -16,6 +16,7 @@
 obj-$(CONFIG_PINCTRL_IMX53)	+= pinctrl-imx53.o
 obj-$(CONFIG_PINCTRL_IMX6Q)	+= pinctrl-imx6q.o
 obj-$(CONFIG_PINCTRL_PXA3xx)	+= pinctrl-pxa3xx.o
+obj-$(CONFIG_PINCTRL_FALCON)	+= pinctrl-falcon.o
 obj-$(CONFIG_PINCTRL_MMP2)	+= pinctrl-mmp2.o
 obj-$(CONFIG_PINCTRL_MXS)	+= pinctrl-mxs.o
 obj-$(CONFIG_PINCTRL_IMX23)	+= pinctrl-imx23.o
@@ -40,5 +41,7 @@
 obj-$(CONFIG_PINCTRL_KIRKWOOD)	+= pinctrl-kirkwood.o
 obj-$(CONFIG_PINCTRL_ARMADA_370) += pinctrl-armada-370.o
 obj-$(CONFIG_PINCTRL_ARMADA_XP)  += pinctrl-armada-xp.o
+obj-$(CONFIG_PINCTRL_XWAY)	+= pinctrl-xway.o
+obj-$(CONFIG_PINCTRL_LANTIQ)	+= pinctrl-lantiq.o
 
 obj-$(CONFIG_PLAT_SPEAR)	+= spear/
diff --git a/drivers/pinctrl/pinctrl-falcon.c b/drivers/pinctrl/pinctrl-falcon.c
new file mode 100644
index 0000000..ee73059
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-falcon.c
@@ -0,0 +1,468 @@
+/*
+ *  linux/drivers/pinctrl/pinmux-falcon.c
+ *  based on linux/drivers/pinctrl/pinmux-pxa910.c
+ *
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2012 Thomas Langer <thomas.langer@lantiq.com>
+ *  Copyright (C) 2012 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/export.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+
+#include "pinctrl-lantiq.h"
+
+#include <lantiq_soc.h>
+
+/* Multiplexer Control Register */
+#define LTQ_PADC_MUX(x)         (x * 0x4)
+/* Pull Up Enable Register */
+#define LTQ_PADC_PUEN		0x80
+/* Pull Down Enable Register */
+#define LTQ_PADC_PDEN		0x84
+/* Slew Rate Control Register */
+#define LTQ_PADC_SRC		0x88
+/* Drive Current Control Register */
+#define LTQ_PADC_DCC		0x8C
+/* Pad Control Availability Register */
+#define LTQ_PADC_AVAIL          0xF0
+
+#define pad_r32(p, reg)		ltq_r32(p + reg)
+#define pad_w32(p, val, reg)	ltq_w32(val, p + reg)
+#define pad_w32_mask(c, clear, set, reg) \
+		pad_w32(c, (pad_r32(c, reg) & ~(clear)) | (set), reg)
+
+#define pad_getbit(m, r, p)	(!!(ltq_r32(m + r) & (1 << p)))
+
+#define PORTS			5
+#define PINS			32
+#define PORT(x)                 (x / PINS)
+#define PORT_PIN(x)             (x % PINS)
+
+#define MFP_FALCON(a, f0, f1, f2, f3)		\
+{						\
+	.name = #a,				\
+	.pin = a,				\
+	.func = {				\
+		FALCON_MUX_##f0,		\
+		FALCON_MUX_##f1,		\
+		FALCON_MUX_##f2,		\
+		FALCON_MUX_##f3,		\
+	},					\
+}
+
+#define GRP_MUX(a, m, p)	\
+{				\
+	.name = a,		\
+	.mux = FALCON_MUX_##m,	\
+	.pins = p,		\
+	.npins = ARRAY_SIZE(p),	\
+}
+
+enum falcon_mux {
+	FALCON_MUX_GPIO = 0,
+	FALCON_MUX_RST,
+	FALCON_MUX_NTR,
+	FALCON_MUX_MDIO,
+	FALCON_MUX_LED,
+	FALCON_MUX_SPI,
+	FALCON_MUX_ASC,
+	FALCON_MUX_I2C,
+	FALCON_MUX_HOSTIF,
+	FALCON_MUX_SLIC,
+	FALCON_MUX_JTAG,
+	FALCON_MUX_PCM,
+	FALCON_MUX_MII,
+	FALCON_MUX_PHY,
+	FALCON_MUX_NONE = 0xffff,
+};
+
+static struct pinctrl_pin_desc falcon_pads[PORTS * PINS];
+static int pad_count[PORTS];
+
+static void lantiq_load_pin_desc(struct pinctrl_pin_desc *d, int bank, int len)
+{
+	int base = bank * PINS;
+	int i;
+
+	for (i = 0; i < len; i++) {
+		/* strlen("ioXYZ") + 1 = 6 */
+		char *name = kzalloc(6, GFP_KERNEL);
+		snprintf(name, 6, "io%d", base + i);
+		d[i].number = base + i;
+		d[i].name = name;
+	}
+	pad_count[bank] = len;
+}
+
+static struct ltq_mfp_pin falcon_mfp[] = {
+	/*	pin		f0	f1	f2	f3 */
+	MFP_FALCON(GPIO0,	RST,	GPIO,   NONE,   NONE),
+	MFP_FALCON(GPIO1,	GPIO,	GPIO,   NONE,   NONE),
+	MFP_FALCON(GPIO2,	GPIO,	GPIO,   NONE,   NONE),
+	MFP_FALCON(GPIO3,	GPIO,	GPIO,   NONE,   NONE),
+	MFP_FALCON(GPIO4,	NTR,	GPIO,   NONE,   NONE),
+	MFP_FALCON(GPIO5,	NTR,	GPIO,   NONE,   NONE),
+	MFP_FALCON(GPIO6,	RST,	GPIO,   NONE,   NONE),
+	MFP_FALCON(GPIO7,	MDIO,	GPIO,   NONE,   NONE),
+	MFP_FALCON(GPIO8,	MDIO,	GPIO,   NONE,   NONE),
+	MFP_FALCON(GPIO9,	LED,	GPIO,   NONE,   NONE),
+	MFP_FALCON(GPIO10,	LED,	GPIO,   NONE,   NONE),
+	MFP_FALCON(GPIO11,	LED,	GPIO,   NONE,   NONE),
+	MFP_FALCON(GPIO12,	LED,	GPIO,   NONE,   NONE),
+	MFP_FALCON(GPIO13,	LED,	GPIO,   NONE,   NONE),
+	MFP_FALCON(GPIO14,	LED,	GPIO,   NONE,   NONE),
+	MFP_FALCON(GPIO32,	ASC,	GPIO,   NONE,   NONE),
+	MFP_FALCON(GPIO33,	ASC,	GPIO,   NONE,   NONE),
+	MFP_FALCON(GPIO34,	SPI,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO35,	SPI,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO36,	SPI,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO37,	SPI,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO38,	SPI,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO39,	I2C,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO40,	I2C,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO41,	HOSTIF,	GPIO,	HOSTIF,	JTAG),
+	MFP_FALCON(GPIO42,	HOSTIF,	GPIO,	HOSTIF,	NONE),
+	MFP_FALCON(GPIO43,	SLIC,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO44,	SLIC,	GPIO,	PCM,	ASC),
+	MFP_FALCON(GPIO45,	SLIC,	GPIO,	PCM,	ASC),
+	MFP_FALCON(GPIO64,	MII,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO65,	MII,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO66,	MII,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO67,	MII,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO68,	MII,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO69,	MII,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO70,	MII,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO71,	MII,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO72,	MII,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO73,	MII,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO74,	MII,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO75,	MII,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO76,	MII,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO77,	MII,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO78,	MII,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO79,	MII,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO80,	MII,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO81,	MII,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO82,	MII,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO83,	MII,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO84,	MII,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO85,	MII,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO86,	MII,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO87,	MII,	GPIO,	NONE,	NONE),
+	MFP_FALCON(GPIO88,	PHY,	GPIO,	NONE,	NONE),
+};
+
+static const unsigned pins_por[] = {GPIO0};
+static const unsigned pins_ntr[] = {GPIO4};
+static const unsigned pins_ntr8k[] = {GPIO5};
+static const unsigned pins_hrst[] = {GPIO6};
+static const unsigned pins_mdio[] = {GPIO7, GPIO8};
+static const unsigned pins_bled[] = {GPIO7, GPIO10, GPIO11,
+					GPIO12, GPIO13, GPIO14};
+static const unsigned pins_asc0[] = {GPIO32, GPIO33};
+static const unsigned pins_spi[] = {GPIO34, GPIO35, GPIO36};
+static const unsigned pins_spi_cs0[] = {GPIO37};
+static const unsigned pins_spi_cs1[] = {GPIO38};
+static const unsigned pins_i2c[] = {GPIO39, GPIO40};
+static const unsigned pins_jtag[] = {GPIO41};
+static const unsigned pins_slic[] = {GPIO43, GPIO44, GPIO45};
+static const unsigned pins_pcm[] = {GPIO44, GPIO45};
+static const unsigned pins_asc1[] = {GPIO44, GPIO45};
+
+static struct ltq_pin_group falcon_grps[] = {
+	GRP_MUX("por", RST, pins_por),
+	GRP_MUX("ntr", NTR, pins_ntr),
+	GRP_MUX("ntr8k", NTR, pins_ntr8k),
+	GRP_MUX("hrst", RST, pins_hrst),
+	GRP_MUX("mdio", MDIO, pins_mdio),
+	GRP_MUX("bootled", LED, pins_bled),
+	GRP_MUX("asc0", ASC, pins_asc0),
+	GRP_MUX("spi", SPI, pins_spi),
+	GRP_MUX("spi cs0", SPI, pins_spi_cs0),
+	GRP_MUX("spi cs1", SPI, pins_spi_cs1),
+	GRP_MUX("i2c", I2C, pins_i2c),
+	GRP_MUX("jtag", JTAG, pins_jtag),
+	GRP_MUX("slic", SLIC, pins_slic),
+	GRP_MUX("pcm", PCM, pins_pcm),
+	GRP_MUX("asc1", ASC, pins_asc1),
+};
+
+static const char * const ltq_rst_grps[] = {"por", "hrst"};
+static const char * const ltq_ntr_grps[] = {"ntr", "ntr8k"};
+static const char * const ltq_mdio_grps[] = {"mdio"};
+static const char * const ltq_bled_grps[] = {"bootled"};
+static const char * const ltq_asc_grps[] = {"asc0", "asc1"};
+static const char * const ltq_spi_grps[] = {"spi", "spi cs0", "spi cs1"};
+static const char * const ltq_i2c_grps[] = {"i2c"};
+static const char * const ltq_jtag_grps[] = {"jtag"};
+static const char * const ltq_slic_grps[] = {"slic"};
+static const char * const ltq_pcm_grps[] = {"pcm"};
+
+static struct ltq_pmx_func falcon_funcs[] = {
+	{"rst",		ARRAY_AND_SIZE(ltq_rst_grps)},
+	{"ntr",		ARRAY_AND_SIZE(ltq_ntr_grps)},
+	{"mdio",	ARRAY_AND_SIZE(ltq_mdio_grps)},
+	{"led",		ARRAY_AND_SIZE(ltq_bled_grps)},
+	{"asc",		ARRAY_AND_SIZE(ltq_asc_grps)},
+	{"spi",		ARRAY_AND_SIZE(ltq_spi_grps)},
+	{"i2c",		ARRAY_AND_SIZE(ltq_i2c_grps)},
+	{"jtag",	ARRAY_AND_SIZE(ltq_jtag_grps)},
+	{"slic",	ARRAY_AND_SIZE(ltq_slic_grps)},
+	{"pcm",		ARRAY_AND_SIZE(ltq_pcm_grps)},
+};
+
+
+
+
+/* ---------  pinconf related code --------- */
+static int falcon_pinconf_group_get(struct pinctrl_dev *pctrldev,
+				unsigned group, unsigned long *config)
+{
+	return -ENOTSUPP;
+}
+
+static int falcon_pinconf_group_set(struct pinctrl_dev *pctrldev,
+				unsigned group, unsigned long config)
+{
+	return -ENOTSUPP;
+}
+
+static int falcon_pinconf_get(struct pinctrl_dev *pctrldev,
+				unsigned pin, unsigned long *config)
+{
+	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+	enum ltq_pinconf_param param = LTQ_PINCONF_UNPACK_PARAM(*config);
+	void __iomem *mem = info->membase[PORT(pin)];
+
+	switch (param) {
+	case LTQ_PINCONF_PARAM_DRIVE_CURRENT:
+		*config = LTQ_PINCONF_PACK(param,
+			!!pad_getbit(mem, LTQ_PADC_DCC, PORT_PIN(pin)));
+		break;
+
+	case LTQ_PINCONF_PARAM_SLEW_RATE:
+		*config = LTQ_PINCONF_PACK(param,
+			!!pad_getbit(mem, LTQ_PADC_SRC, PORT_PIN(pin)));
+		break;
+
+	case LTQ_PINCONF_PARAM_PULL:
+		if (pad_getbit(mem, LTQ_PADC_PDEN, PORT_PIN(pin)))
+			*config = LTQ_PINCONF_PACK(param, 1);
+		else if (pad_getbit(mem, LTQ_PADC_PUEN, PORT_PIN(pin)))
+			*config = LTQ_PINCONF_PACK(param, 2);
+		else
+			*config = LTQ_PINCONF_PACK(param, 0);
+
+		break;
+
+	default:
+		return -ENOTSUPP;
+	}
+
+	return 0;
+}
+
+static int falcon_pinconf_set(struct pinctrl_dev *pctrldev,
+			unsigned pin, unsigned long config)
+{
+	enum ltq_pinconf_param param = LTQ_PINCONF_UNPACK_PARAM(config);
+	int arg = LTQ_PINCONF_UNPACK_ARG(config);
+	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+	void __iomem *mem = info->membase[PORT(pin)];
+	u32 reg;
+
+	switch (param) {
+	case LTQ_PINCONF_PARAM_DRIVE_CURRENT:
+		reg = LTQ_PADC_DCC;
+		break;
+
+	case LTQ_PINCONF_PARAM_SLEW_RATE:
+		reg = LTQ_PADC_SRC;
+		break;
+
+	case LTQ_PINCONF_PARAM_PULL:
+		if (arg == 1)
+			reg = LTQ_PADC_PDEN;
+		else
+			reg = LTQ_PADC_PUEN;
+		break;
+
+	default:
+		pr_err("%s: Invalid config param %04x\n",
+		pinctrl_dev_get_name(pctrldev), param);
+		return -ENOTSUPP;
+	}
+
+	pad_w32(mem, BIT(PORT_PIN(pin)), reg);
+	if (!(pad_r32(mem, reg) & BIT(PORT_PIN(pin))))
+		return -ENOTSUPP;
+	return 0;
+}
+
+static void falcon_pinconf_dbg_show(struct pinctrl_dev *pctrldev,
+			struct seq_file *s, unsigned offset)
+{
+}
+
+static void falcon_pinconf_group_dbg_show(struct pinctrl_dev *pctrldev,
+			struct seq_file *s, unsigned selector)
+{
+}
+
+struct pinconf_ops falcon_pinconf_ops = {
+	.pin_config_get			= falcon_pinconf_get,
+	.pin_config_set			= falcon_pinconf_set,
+	.pin_config_group_get		= falcon_pinconf_group_get,
+	.pin_config_group_set		= falcon_pinconf_group_set,
+	.pin_config_dbg_show		= falcon_pinconf_dbg_show,
+	.pin_config_group_dbg_show	= falcon_pinconf_group_dbg_show,
+};
+
+static struct pinctrl_desc falcon_pctrl_desc = {
+	.owner		= THIS_MODULE,
+	.pins		= falcon_pads,
+	.confops	= &falcon_pinconf_ops,
+};
+
+static inline int falcon_mux_apply(struct pinctrl_dev *pctrldev,
+			int mfp, int mux)
+{
+	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+	int port = PORT(info->mfp[mfp].pin);
+
+	if ((port >= PORTS) || (!info->membase[port]))
+		return -ENODEV;
+
+	pad_w32(info->membase[port], mux,
+		LTQ_PADC_MUX(PORT_PIN(info->mfp[mfp].pin)));
+	return 0;
+}
+
+static const struct ltq_cfg_param falcon_cfg_params[] = {
+	{"lantiq,pull",			LTQ_PINCONF_PARAM_PULL},
+	{"lantiq,drive-current",	LTQ_PINCONF_PARAM_DRIVE_CURRENT},
+	{"lantiq,slew-rate",		LTQ_PINCONF_PARAM_SLEW_RATE},
+};
+
+static struct ltq_pinmux_info falcon_info = {
+	.desc		= &falcon_pctrl_desc,
+	.apply_mux	= falcon_mux_apply,
+};
+
+
+
+
+/* --------- register the pinctrl layer --------- */
+
+int pinctrl_falcon_get_range_size(int id)
+{
+	u32 avail;
+
+	if ((id >= PORTS) || (!falcon_info.membase[id]))
+		return -EINVAL;
+
+	avail = pad_r32(falcon_info.membase[id], LTQ_PADC_AVAIL);
+
+	return fls(avail);
+}
+
+void pinctrl_falcon_add_gpio_range(struct pinctrl_gpio_range *range)
+{
+	pinctrl_add_gpio_range(falcon_info.pctrl, range);
+}
+
+static int pinctrl_falcon_probe(struct platform_device *pdev)
+{
+	struct device_node *np;
+	int pad_count = 0;
+	int ret = 0;
+
+	/* load and remap the pad resources of the different banks */
+	for_each_compatible_node(np, NULL, "lantiq,pad-falcon") {
+		struct platform_device *ppdev = of_find_device_by_node(np);
+		const __be32 *bank = of_get_property(np, "lantiq,bank", NULL);
+		struct resource res;
+		u32 avail;
+		int pins;
+
+		if (!ppdev) {
+			dev_err(&pdev->dev, "failed to find pad pdev\n");
+			continue;
+		}
+		if (!bank || *bank >= PORTS)
+			continue;
+		if (of_address_to_resource(np, 0, &res))
+			continue;
+		falcon_info.clk[*bank] = clk_get(&ppdev->dev, NULL);
+		if (IS_ERR(falcon_info.clk[*bank])) {
+			dev_err(&ppdev->dev, "failed to get clock\n");
+			return PTR_ERR(falcon_info.clk[*bank]);
+		}
+		falcon_info.membase[*bank] =
+				devm_request_and_ioremap(&pdev->dev, &res);
+		if (!falcon_info.membase[*bank]) {
+			dev_err(&pdev->dev,
+				"Failed to remap memory for bank %d\n",
+				*bank);
+			return -ENOMEM;
+		}
+		avail = pad_r32(falcon_info.membase[*bank],
+					LTQ_PADC_AVAIL);
+		pins = fls(avail);
+		lantiq_load_pin_desc(&falcon_pads[pad_count], *bank, pins);
+		pad_count += pins;
+		clk_enable(falcon_info.clk[*bank]);
+		dev_dbg(&pdev->dev, "found %s with %d pads\n",
+				res.name, pins);
+	}
+	dev_dbg(&pdev->dev, "found a total of %d pads\n", pad_count);
+	falcon_pctrl_desc.name	= dev_name(&pdev->dev);
+	falcon_pctrl_desc.npins	= pad_count;
+
+	falcon_info.mfp		= falcon_mfp;
+	falcon_info.num_mfp	= ARRAY_SIZE(falcon_mfp);
+	falcon_info.grps	= falcon_grps;
+	falcon_info.num_grps	= ARRAY_SIZE(falcon_grps);
+	falcon_info.funcs	= falcon_funcs;
+	falcon_info.num_funcs	= ARRAY_SIZE(falcon_funcs);
+
+	ret = ltq_pinctrl_register(pdev, &falcon_info);
+	if (!ret)
+		dev_info(&pdev->dev, "Init done\n");
+	return ret;
+}
+
+static const struct of_device_id falcon_match[] = {
+	{ .compatible = "lantiq,pinctrl-falcon" },
+	{},
+};
+MODULE_DEVICE_TABLE(of, falcon_match);
+
+static struct platform_driver pinctrl_falcon_driver = {
+	.probe = pinctrl_falcon_probe,
+	.driver = {
+		.name = "pinctrl-falcon",
+		.owner = THIS_MODULE,
+		.of_match_table = falcon_match,
+	},
+};
+
+int __init pinctrl_falcon_init(void)
+{
+	return platform_driver_register(&pinctrl_falcon_driver);
+}
+
+core_initcall_sync(pinctrl_falcon_init);
diff --git a/drivers/pinctrl/pinctrl-lantiq.c b/drivers/pinctrl/pinctrl-lantiq.c
new file mode 100644
index 0000000..07ba768
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-lantiq.c
@@ -0,0 +1,342 @@
+/*
+ *  linux/drivers/pinctrl/pinctrl-lantiq.c
+ *  based on linux/drivers/pinctrl/pinctrl-pxa3xx.c
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  publishhed by the Free Software Foundation.
+ *
+ *  Copyright (C) 2012 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+
+#include "pinctrl-lantiq.h"
+
+static int ltq_get_group_count(struct pinctrl_dev *pctrldev)
+{
+	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+	return info->num_grps;
+}
+
+static const char *ltq_get_group_name(struct pinctrl_dev *pctrldev,
+					 unsigned selector)
+{
+	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+	if (selector >= info->num_grps)
+		return NULL;
+	return info->grps[selector].name;
+}
+
+static int ltq_get_group_pins(struct pinctrl_dev *pctrldev,
+				 unsigned selector,
+				 const unsigned **pins,
+				 unsigned *num_pins)
+{
+	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+	if (selector >= info->num_grps)
+		return -EINVAL;
+	*pins = info->grps[selector].pins;
+	*num_pins = info->grps[selector].npins;
+	return 0;
+}
+
+void ltq_pinctrl_dt_free_map(struct pinctrl_dev *pctldev,
+				struct pinctrl_map *map, unsigned num_maps)
+{
+	int i;
+
+	for (i = 0; i < num_maps; i++)
+		if (map[i].type == PIN_MAP_TYPE_CONFIGS_PIN)
+			kfree(map[i].data.configs.configs);
+	kfree(map);
+}
+
+static void ltq_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
+					struct seq_file *s,
+					unsigned offset)
+{
+	seq_printf(s, " %s", dev_name(pctldev->dev));
+}
+
+static int ltq_pinctrl_dt_subnode_to_map(struct pinctrl_dev *pctldev,
+				struct device_node *np,
+				struct pinctrl_map **map)
+{
+	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
+	unsigned long configs[3];
+	unsigned num_configs = 0;
+	struct property *prop;
+	const char *group, *pin;
+	const char *function;
+	int ret, i;
+
+	ret = of_property_read_string(np, "lantiq,function", &function);
+	if (!ret) {
+		of_property_for_each_string(np, "lantiq,groups", prop, group) {
+			(*map)->type = PIN_MAP_TYPE_MUX_GROUP;
+			(*map)->name = function;
+			(*map)->data.mux.group = group;
+			(*map)->data.mux.function = function;
+			(*map)++;
+		}
+		if (of_find_property(np, "lantiq,pins", NULL))
+			dev_err(pctldev->dev,
+				"%s mixes pins and groups settings\n",
+				np->name);
+		return 0;
+	}
+
+	for (i = 0; i < info->num_params; i++) {
+		u32 val;
+		int ret = of_property_read_u32(np,
+				info->params[i].property, &val);
+		if (!ret)
+			configs[num_configs++] =
+				LTQ_PINCONF_PACK(info->params[i].param,
+				val);
+	}
+
+	if (!num_configs)
+		return -EINVAL;
+
+	of_property_for_each_string(np, "lantiq,pins", prop, pin) {
+		(*map)->data.configs.configs = kmemdup(configs,
+					num_configs * sizeof(unsigned long),
+					GFP_KERNEL);
+		(*map)->type = PIN_MAP_TYPE_CONFIGS_PIN;
+		(*map)->name = pin;
+		(*map)->data.configs.group_or_pin = pin;
+		(*map)->data.configs.num_configs = num_configs;
+		(*map)++;
+	}
+	return 0;
+}
+
+static int ltq_pinctrl_dt_subnode_size(struct device_node *np)
+{
+	int ret;
+
+	ret = of_property_count_strings(np, "lantiq,groups");
+	if (ret < 0)
+		ret = of_property_count_strings(np, "lantiq,pins");
+	return ret;
+}
+
+int ltq_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev,
+				struct device_node *np_config,
+				struct pinctrl_map **map,
+				unsigned *num_maps)
+{
+	struct pinctrl_map *tmp;
+	struct device_node *np;
+	int ret;
+
+	*num_maps = 0;
+	for_each_child_of_node(np_config, np)
+		*num_maps += ltq_pinctrl_dt_subnode_size(np);
+	*map = kzalloc(*num_maps * sizeof(struct pinctrl_map), GFP_KERNEL);
+	if (!*map)
+		return -ENOMEM;
+	tmp = *map;
+
+	for_each_child_of_node(np_config, np) {
+		ret = ltq_pinctrl_dt_subnode_to_map(pctldev, np, &tmp);
+		if (ret < 0) {
+			ltq_pinctrl_dt_free_map(pctldev, *map, *num_maps);
+			return ret;
+		}
+	}
+	return 0;
+}
+
+static struct pinctrl_ops ltq_pctrl_ops = {
+	.get_groups_count	= ltq_get_group_count,
+	.get_group_name		= ltq_get_group_name,
+	.get_group_pins		= ltq_get_group_pins,
+	.pin_dbg_show		= ltq_pinctrl_pin_dbg_show,
+	.dt_node_to_map		= ltq_pinctrl_dt_node_to_map,
+	.dt_free_map		= ltq_pinctrl_dt_free_map,
+};
+
+static int ltq_pmx_func_count(struct pinctrl_dev *pctrldev)
+{
+	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+
+	return info->num_funcs;
+}
+
+static const char *ltq_pmx_func_name(struct pinctrl_dev *pctrldev,
+					 unsigned selector)
+{
+	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+
+	if (selector >= info->num_funcs)
+		return NULL;
+
+	return info->funcs[selector].name;
+}
+
+static int ltq_pmx_get_groups(struct pinctrl_dev *pctrldev,
+				unsigned func,
+				const char * const **groups,
+				unsigned * const num_groups)
+{
+	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+
+	*groups = info->funcs[func].groups;
+	*num_groups = info->funcs[func].num_groups;
+
+	return 0;
+}
+
+/* Return function number. If failure, return negative value. */
+static int match_mux(const struct ltq_mfp_pin *mfp, unsigned mux)
+{
+	int i;
+	for (i = 0; i < LTQ_MAX_MUX; i++) {
+		if (mfp->func[i] == mux)
+			break;
+	}
+	if (i >= LTQ_MAX_MUX)
+		return -EINVAL;
+	return i;
+}
+
+/* dont assume .mfp is linearly mapped. find the mfp with the correct .pin */
+static int match_mfp(const struct ltq_pinmux_info *info, int pin)
+{
+	int i;
+	for (i = 0; i < info->num_mfp; i++) {
+		if (info->mfp[i].pin == pin)
+			return i;
+	}
+	return -1;
+}
+
+/* check whether current pin configuration is valid. Negative for failure */
+static int match_group_mux(const struct ltq_pin_group *grp,
+			   const struct ltq_pinmux_info *info,
+			   unsigned mux)
+{
+	int i, pin, ret = 0;
+	for (i = 0; i < grp->npins; i++) {
+		pin = match_mfp(info, grp->pins[i]);
+		if (pin < 0) {
+			dev_err(info->dev, "could not find mfp for pin %d\n",
+				grp->pins[i]);
+			return -EINVAL;
+		}
+		ret = match_mux(&info->mfp[pin], mux);
+		if (ret < 0) {
+			dev_err(info->dev, "Can't find mux %d on pin%d\n",
+				mux, pin);
+			break;
+		}
+	}
+	return ret;
+}
+
+static int ltq_pmx_enable(struct pinctrl_dev *pctrldev,
+				unsigned func,
+				unsigned group)
+{
+	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+	const struct ltq_pin_group *pin_grp = &info->grps[group];
+	int i, pin, pin_func, ret;
+
+	if (!pin_grp->npins ||
+		(match_group_mux(pin_grp, info, pin_grp->mux) < 0)) {
+		dev_err(info->dev, "Failed to set the pin group: %s\n",
+			info->grps[group].name);
+		return -EINVAL;
+	}
+	for (i = 0; i < pin_grp->npins; i++) {
+		pin = match_mfp(info, pin_grp->pins[i]);
+		if (pin < 0) {
+			dev_err(info->dev, "could not find mfp for pin %d\n",
+				pin_grp->pins[i]);
+			return -EINVAL;
+		}
+		pin_func = match_mux(&info->mfp[pin], pin_grp->mux);
+		ret = info->apply_mux(pctrldev, pin, pin_func);
+		if (ret) {
+			dev_err(info->dev,
+				"failed to apply mux %d for pin %d\n",
+				pin_func, pin);
+			return ret;
+		}
+	}
+	return 0;
+}
+
+static void ltq_pmx_disable(struct pinctrl_dev *pctrldev,
+				unsigned func,
+				unsigned group)
+{
+	/*
+	 * Nothing to do here. However, pinconf_check_ops() requires this
+	 * callback to be defined.
+	 */
+}
+
+static int ltq_pmx_gpio_request_enable(struct pinctrl_dev *pctrldev,
+				struct pinctrl_gpio_range *range,
+				unsigned pin)
+{
+	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+	int mfp = match_mfp(info, pin + (range->id * 32));
+	int pin_func;
+
+	if (mfp < 0) {
+		dev_err(info->dev, "could not find mfp for pin %d\n", pin);
+		return -EINVAL;
+	}
+
+	pin_func = match_mux(&info->mfp[mfp], 0);
+	if (pin_func < 0) {
+		dev_err(info->dev, "No GPIO function on pin%d\n", mfp);
+		return -EINVAL;
+	}
+
+	return info->apply_mux(pctrldev, mfp, pin_func);
+}
+
+static struct pinmux_ops ltq_pmx_ops = {
+	.get_functions_count	= ltq_pmx_func_count,
+	.get_function_name	= ltq_pmx_func_name,
+	.get_function_groups	= ltq_pmx_get_groups,
+	.enable			= ltq_pmx_enable,
+	.disable		= ltq_pmx_disable,
+	.gpio_request_enable	= ltq_pmx_gpio_request_enable,
+};
+
+/*
+ * allow different socs to register with the generic part of the lanti
+ * pinctrl code
+ */
+int ltq_pinctrl_register(struct platform_device *pdev,
+				struct ltq_pinmux_info *info)
+{
+	struct pinctrl_desc *desc;
+
+	if (!info)
+		return -EINVAL;
+	desc = info->desc;
+	desc->pctlops = &ltq_pctrl_ops;
+	desc->pmxops = &ltq_pmx_ops;
+	info->dev = &pdev->dev;
+
+	info->pctrl = pinctrl_register(desc, &pdev->dev, info);
+	if (!info->pctrl) {
+		dev_err(&pdev->dev, "failed to register LTQ pinmux driver\n");
+		return -EINVAL;
+	}
+	platform_set_drvdata(pdev, info);
+	return 0;
+}
diff --git a/drivers/pinctrl/pinctrl-lantiq.h b/drivers/pinctrl/pinctrl-lantiq.h
new file mode 100644
index 0000000..4419d32
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-lantiq.h
@@ -0,0 +1,194 @@
+/*
+ *  linux/drivers/pinctrl/pinctrl-lantiq.h
+ *  based on linux/drivers/pinctrl/pinctrl-pxa3xx.h
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  publishhed by the Free Software Foundation.
+ *
+ *  Copyright (C) 2012 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef __PINCTRL_LANTIQ_H
+
+#include <linux/clkdev.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/pinctrl/machine.h>
+
+#include "core.h"
+
+#define ARRAY_AND_SIZE(x)	(x), ARRAY_SIZE(x)
+
+#define LTQ_MAX_MUX		4
+#define MFPR_FUNC_MASK		0x3
+
+#define LTQ_PINCONF_PACK(param, arg)		((param) << 16 | (arg))
+#define LTQ_PINCONF_UNPACK_PARAM(conf)		((conf) >> 16)
+#define LTQ_PINCONF_UNPACK_ARG(conf)		((conf) & 0xffff)
+
+enum ltq_pinconf_param {
+	LTQ_PINCONF_PARAM_PULL,
+	LTQ_PINCONF_PARAM_OPEN_DRAIN,
+	LTQ_PINCONF_PARAM_DRIVE_CURRENT,
+	LTQ_PINCONF_PARAM_SLEW_RATE,
+};
+
+struct ltq_cfg_param {
+	const char *property;
+	enum ltq_pinconf_param param;
+};
+
+struct ltq_mfp_pin {
+	const char *name;
+	const unsigned int pin;
+	const unsigned short func[LTQ_MAX_MUX];
+};
+
+struct ltq_pin_group {
+	const char *name;
+	const unsigned mux;
+	const unsigned *pins;
+	const unsigned npins;
+};
+
+struct ltq_pmx_func {
+	const char *name;
+	const char * const *groups;
+	const unsigned num_groups;
+};
+
+struct ltq_pinmux_info {
+	struct device *dev;
+	struct pinctrl_dev *pctrl;
+
+	/* we need to manage up to 5 pad controllers */
+	void __iomem *membase[5];
+
+	/* the descriptor for the subsystem */
+	struct pinctrl_desc *desc;
+
+	/* we expose our pads to the subsystem */
+	struct pinctrl_pin_desc *pads;
+
+	/* the number of pads. this varies between socs */
+	unsigned int num_pads;
+
+	/* these are our multifunction pins */
+	const struct ltq_mfp_pin *mfp;
+	unsigned int num_mfp;
+
+	/* a number of multifunction pins can be grouped together */
+	const struct ltq_pin_group *grps;
+	unsigned int num_grps;
+
+	/* a mapping between function string and id */
+	const struct ltq_pmx_func *funcs;
+	unsigned int num_funcs;
+
+	/* the pinconf options that we are able to read from the DT */
+	const struct ltq_cfg_param *params;
+	unsigned int num_params;
+
+	/* the pad controller can have a irq mapping  */
+	const unsigned *exin;
+	unsigned int num_exin;
+
+	/* we need 5 clocks max */
+	struct clk *clk[5];
+
+	/* soc specific callback used to apply muxing */
+	int (*apply_mux)(struct pinctrl_dev *pctrldev, int pin, int mux);
+};
+
+enum ltq_pin {
+	GPIO0 = 0,
+	GPIO1,
+	GPIO2,
+	GPIO3,
+	GPIO4,
+	GPIO5,
+	GPIO6,
+	GPIO7,
+	GPIO8,
+	GPIO9,
+	GPIO10, /* 10 */
+	GPIO11,
+	GPIO12,
+	GPIO13,
+	GPIO14,
+	GPIO15,
+	GPIO16,
+	GPIO17,
+	GPIO18,
+	GPIO19,
+	GPIO20, /* 20 */
+	GPIO21,
+	GPIO22,
+	GPIO23,
+	GPIO24,
+	GPIO25,
+	GPIO26,
+	GPIO27,
+	GPIO28,
+	GPIO29,
+	GPIO30, /* 30 */
+	GPIO31,
+	GPIO32,
+	GPIO33,
+	GPIO34,
+	GPIO35,
+	GPIO36,
+	GPIO37,
+	GPIO38,
+	GPIO39,
+	GPIO40, /* 40 */
+	GPIO41,
+	GPIO42,
+	GPIO43,
+	GPIO44,
+	GPIO45,
+	GPIO46,
+	GPIO47,
+	GPIO48,
+	GPIO49,
+	GPIO50, /* 50 */
+	GPIO51,
+	GPIO52,
+	GPIO53,
+	GPIO54,
+	GPIO55,
+
+	GPIO64,
+	GPIO65,
+	GPIO66,
+	GPIO67,
+	GPIO68,
+	GPIO69,
+	GPIO70,
+	GPIO71,
+	GPIO72,
+	GPIO73,
+	GPIO74,
+	GPIO75,
+	GPIO76,
+	GPIO77,
+	GPIO78,
+	GPIO79,
+	GPIO80,
+	GPIO81,
+	GPIO82,
+	GPIO83,
+	GPIO84,
+	GPIO85,
+	GPIO86,
+	GPIO87,
+	GPIO88,
+};
+
+extern int ltq_pinctrl_register(struct platform_device *pdev,
+				   struct ltq_pinmux_info *info);
+extern int ltq_pinctrl_unregister(struct platform_device *pdev);
+#endif	/* __PINCTRL_PXA3XX_H */
diff --git a/drivers/pinctrl/pinctrl-nomadik-db8500.c b/drivers/pinctrl/pinctrl-nomadik-db8500.c
index ec6209d..debaa75b 100644
--- a/drivers/pinctrl/pinctrl-nomadik-db8500.c
+++ b/drivers/pinctrl/pinctrl-nomadik-db8500.c
@@ -725,10 +725,10 @@
 	DB8500_PIN_GROUP(spi0_c_1, NMK_GPIO_ALT_C),
 	DB8500_PIN_GROUP(usbsim_c_2, NMK_GPIO_ALT_C),
 	DB8500_PIN_GROUP(i2c3_c_2, NMK_GPIO_ALT_C),
-	/* Other alt C1 column, these are still configured as alt C */
-	DB8500_PIN_GROUP(kp_oc1_1, NMK_GPIO_ALT_C),
-	DB8500_PIN_GROUP(spi2_oc1_1, NMK_GPIO_ALT_C),
-	DB8500_PIN_GROUP(spi2_oc1_2, NMK_GPIO_ALT_C),
+	/* Other alt C1 column */
+	DB8500_PIN_GROUP(kp_oc1_1, NMK_GPIO_ALT_C1),
+	DB8500_PIN_GROUP(spi2_oc1_1, NMK_GPIO_ALT_C1),
+	DB8500_PIN_GROUP(spi2_oc1_2, NMK_GPIO_ALT_C1),
 };
 
 /* We use this macro to define the groups applicable to a function */
@@ -860,6 +860,284 @@
 	FUNCTION(spi2),
 };
 
+static const struct prcm_gpiocr_altcx_pin_desc db8500_altcx_pins[] = {
+	PRCM_GPIOCR_ALTCX(23,	true, PRCM_IDX_GPIOCR1, 9,	/* STMAPE_CLK_a */
+				true, PRCM_IDX_GPIOCR1, 7,	/* SBAG_CLK_a */
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(24,	true, PRCM_IDX_GPIOCR1, 9,	/* STMAPE or U2_RXD ??? */
+				true, PRCM_IDX_GPIOCR1, 7,	/* SBAG_VAL_a */
+				true, PRCM_IDX_GPIOCR1, 10,	/* STM_MOD_CMD0 */
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(25,	true, PRCM_IDX_GPIOCR1, 9,	/* STMAPE_DAT_a[0] */
+				true, PRCM_IDX_GPIOCR1, 7,	/* SBAG_D_a[0] */
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(26,	true, PRCM_IDX_GPIOCR1, 9,	/* STMAPE_DAT_a[1] */
+				true, PRCM_IDX_GPIOCR1, 7,	/* SBAG_D_a[1] */
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(27,	true, PRCM_IDX_GPIOCR1, 9,	/* STMAPE_DAT_a[2] */
+				true, PRCM_IDX_GPIOCR1, 7,	/* SBAG_D_a[2] */
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(28,	true, PRCM_IDX_GPIOCR1, 9,	/* STMAPE_DAT_a[3] */
+				true, PRCM_IDX_GPIOCR1, 7,	/* SBAG_D_a[3] */
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(29,	false, 0, 0,
+				false, 0, 0,
+				true, PRCM_IDX_GPIOCR1, 10,	/* STM_MOD_CMD0 */
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(30,	false, 0, 0,
+				false, 0, 0,
+				true, PRCM_IDX_GPIOCR1, 10,	/* STM_MOD_CMD0 */
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(31,	false, 0, 0,
+				false, 0, 0,
+				true, PRCM_IDX_GPIOCR1, 10,	/* STM_MOD_CMD0 */
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(32,	false, 0, 0,
+				false, 0, 0,
+				true, PRCM_IDX_GPIOCR1, 10,	/* STM_MOD_CMD0 */
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(68,	true, PRCM_IDX_GPIOCR1, 18,	/* REMAP_SELECT_ON */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(69,	true, PRCM_IDX_GPIOCR1, 18,	/* REMAP_SELECT_ON */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(70,	true, PRCM_IDX_GPIOCR1, 5,	/* PTM_A9_D23 */
+				true, PRCM_IDX_GPIOCR2, 2,	/* DBG_ETM_R4_CMD0 */
+				true, PRCM_IDX_GPIOCR1, 11,	/* STM_MOD_CMD1 */
+				true, PRCM_IDX_GPIOCR1, 8	/* SBAG_CLK */
+	),
+	PRCM_GPIOCR_ALTCX(71,	true, PRCM_IDX_GPIOCR1, 5,	/* PTM_A9_D22 */
+				true, PRCM_IDX_GPIOCR2, 2,	/* DBG_ETM_R4_CMD0 */
+				true, PRCM_IDX_GPIOCR1, 11,	/* STM_MOD_CMD1 */
+				true, PRCM_IDX_GPIOCR1, 8	/* SBAG_D3 */
+	),
+	PRCM_GPIOCR_ALTCX(72,	true, PRCM_IDX_GPIOCR1, 5,	/* PTM_A9_D21 */
+				true, PRCM_IDX_GPIOCR2, 2,	/* DBG_ETM_R4_CMD0 */
+				true, PRCM_IDX_GPIOCR1, 11,	/* STM_MOD_CMD1 */
+				true, PRCM_IDX_GPIOCR1, 8	/* SBAG_D2 */
+	),
+	PRCM_GPIOCR_ALTCX(73,	true, PRCM_IDX_GPIOCR1, 5,	/* PTM_A9_D20 */
+				true, PRCM_IDX_GPIOCR2, 2,	/* DBG_ETM_R4_CMD0 */
+				true, PRCM_IDX_GPIOCR1, 11,	/* STM_MOD_CMD1 */
+				true, PRCM_IDX_GPIOCR1, 8	/* SBAG_D1 */
+	),
+	PRCM_GPIOCR_ALTCX(74,	true, PRCM_IDX_GPIOCR1, 5,	/* PTM_A9_D19 */
+				true, PRCM_IDX_GPIOCR2, 2,	/* DBG_ETM_R4_CMD0 */
+				true, PRCM_IDX_GPIOCR1, 11,	/* STM_MOD_CMD1 */
+				true, PRCM_IDX_GPIOCR1, 8	/* SBAG_D0 */
+	),
+	PRCM_GPIOCR_ALTCX(75,	true, PRCM_IDX_GPIOCR1, 5,	/* PTM_A9_D18 */
+				true, PRCM_IDX_GPIOCR2, 2,	/* DBG_ETM_R4_CMD0 */
+				true, PRCM_IDX_GPIOCR1, 0,	/* DBG_UARTMOD_CMD0 */
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(76,	true, PRCM_IDX_GPIOCR1, 5,	/* PTM_A9_D17 */
+				true, PRCM_IDX_GPIOCR2, 2,	/* DBG_ETM_R4_CMD0 */
+				true, PRCM_IDX_GPIOCR1, 0,	/* DBG_UARTMOD_CMD0 */
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(77,	true, PRCM_IDX_GPIOCR1, 5,	/* PTM_A9_D16 */
+				true, PRCM_IDX_GPIOCR2, 2,	/* DBG_ETM_R4_CMD0 */
+				false, 0, 0,
+				true, PRCM_IDX_GPIOCR1, 8	/* SBAG_VAL */
+	),
+	PRCM_GPIOCR_ALTCX(86,	true, PRCM_IDX_GPIOCR1, 12,	/* KP_O3 */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(87,	true, PRCM_IDX_GPIOCR1, 12,	/* KP_O2 */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(88,	true, PRCM_IDX_GPIOCR1, 12,	/* KP_I3 */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(89,	true, PRCM_IDX_GPIOCR1, 12,	/* KP_I2 */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(90,	true, PRCM_IDX_GPIOCR1, 12,	/* KP_O1 */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(91,	true, PRCM_IDX_GPIOCR1, 12,	/* KP_O0 */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(92,	true, PRCM_IDX_GPIOCR1, 12,	/* KP_I1 */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(93,	true, PRCM_IDX_GPIOCR1, 12,	/* KP_I0 */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(96,	true, PRCM_IDX_GPIOCR2, 3,	/* RF_INT */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(97,	true, PRCM_IDX_GPIOCR2, 1,	/* RF_CTRL */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(151,	false, 0, 0,
+				true, PRCM_IDX_GPIOCR1, 6,	/* PTM_A9_CTL */
+				true, PRCM_IDX_GPIOCR1, 15,	/* DBG_ETM_R4_CMD1*/
+				true, PRCM_IDX_GPIOCR1, 25	/* HW_OBS17 */
+	),
+	PRCM_GPIOCR_ALTCX(152,	true, PRCM_IDX_GPIOCR1, 4,	/* Hx_CLK */
+				true, PRCM_IDX_GPIOCR1, 6,	/* PTM_A9_CLK */
+				true, PRCM_IDX_GPIOCR1, 15,	/* DBG_ETM_R4_CMD1*/
+				true, PRCM_IDX_GPIOCR1, 25	/* HW_OBS16 */
+	),
+	PRCM_GPIOCR_ALTCX(153,	true, PRCM_IDX_GPIOCR1, 1,	/* UARTMOD_CMD1 */
+				true, PRCM_IDX_GPIOCR1, 14,	/* PTM_A9_D15 */
+				true, PRCM_IDX_GPIOCR1, 19,	/* DBG_ETM_R4_CMD2 */
+				true, PRCM_IDX_GPIOCR1, 25	/* HW_OBS15 */
+	),
+	PRCM_GPIOCR_ALTCX(154,	true, PRCM_IDX_GPIOCR1, 1,	/* UARTMOD_CMD1 */
+				true, PRCM_IDX_GPIOCR1, 14,	/* PTM_A9_D14 */
+				true, PRCM_IDX_GPIOCR1, 19,	/* DBG_ETM_R4_CMD2 */
+				true, PRCM_IDX_GPIOCR1, 25	/* HW_OBS14 */
+	),
+	PRCM_GPIOCR_ALTCX(155,	true, PRCM_IDX_GPIOCR1, 13,	/* STM_MOD_CMD2 */
+				true, PRCM_IDX_GPIOCR1, 14,	/* PTM_A9_D13 */
+				true, PRCM_IDX_GPIOCR1, 19,	/* DBG_ETM_R4_CMD2 */
+				true, PRCM_IDX_GPIOCR1, 25	/* HW_OBS13 */
+	),
+	PRCM_GPIOCR_ALTCX(156,	true, PRCM_IDX_GPIOCR1, 13,	/* STM_MOD_CMD2 */
+				true, PRCM_IDX_GPIOCR1, 14,	/* PTM_A9_D12 */
+				true, PRCM_IDX_GPIOCR1, 19,	/* DBG_ETM_R4_CMD2 */
+				true, PRCM_IDX_GPIOCR1, 25	/* HW_OBS12 */
+	),
+	PRCM_GPIOCR_ALTCX(157,	true, PRCM_IDX_GPIOCR1, 13,	/* STM_MOD_CMD2 */
+				true, PRCM_IDX_GPIOCR1, 14,	/* PTM_A9_D11 */
+				true, PRCM_IDX_GPIOCR1, 19,	/* DBG_ETM_R4_CMD2 */
+				true, PRCM_IDX_GPIOCR1, 25	/* HW_OBS11 */
+	),
+	PRCM_GPIOCR_ALTCX(158,	true, PRCM_IDX_GPIOCR1, 13,	/* STM_MOD_CMD2 */
+				true, PRCM_IDX_GPIOCR1, 14,	/* PTM_A9_D10 */
+				true, PRCM_IDX_GPIOCR1, 19,	/* DBG_ETM_R4_CMD2 */
+				true, PRCM_IDX_GPIOCR1, 25	/* HW_OBS10 */
+	),
+	PRCM_GPIOCR_ALTCX(159,	true, PRCM_IDX_GPIOCR1, 13,	/* STM_MOD_CMD2 */
+				true, PRCM_IDX_GPIOCR1, 14,	/* PTM_A9_D9 */
+				true, PRCM_IDX_GPIOCR1, 19,	/* DBG_ETM_R4_CMD2 */
+				true, PRCM_IDX_GPIOCR1, 25	/* HW_OBS9 */
+	),
+	PRCM_GPIOCR_ALTCX(160,	false, 0, 0,
+				true, PRCM_IDX_GPIOCR1, 14,	/* PTM_A9_D8 */
+				true, PRCM_IDX_GPIOCR1, 19,	/* DBG_ETM_R4_CMD2 */
+				true, PRCM_IDX_GPIOCR1, 25	/* HW_OBS8 */
+	),
+	PRCM_GPIOCR_ALTCX(161,	true, PRCM_IDX_GPIOCR1, 4,	/* Hx_GPIO7 */
+				true, PRCM_IDX_GPIOCR1, 6,	/* PTM_A9_D7 */
+				true, PRCM_IDX_GPIOCR1, 15,	/* DBG_ETM_R4_CMD1*/
+				true, PRCM_IDX_GPIOCR1, 24	/* HW_OBS7 */
+	),
+	PRCM_GPIOCR_ALTCX(162,	true, PRCM_IDX_GPIOCR1, 4,	/* Hx_GPIO6 */
+				true, PRCM_IDX_GPIOCR1, 6,	/* PTM_A9_D6 */
+				true, PRCM_IDX_GPIOCR1, 15,	/* DBG_ETM_R4_CMD1*/
+				true, PRCM_IDX_GPIOCR1, 24	/* HW_OBS6 */
+	),
+	PRCM_GPIOCR_ALTCX(163,	true, PRCM_IDX_GPIOCR1, 4,	/* Hx_GPIO5 */
+				true, PRCM_IDX_GPIOCR1, 6,	/* PTM_A9_D5 */
+				true, PRCM_IDX_GPIOCR1, 15,	/* DBG_ETM_R4_CMD1*/
+				true, PRCM_IDX_GPIOCR1, 24	/* HW_OBS5 */
+	),
+	PRCM_GPIOCR_ALTCX(164,	true, PRCM_IDX_GPIOCR1, 4,	/* Hx_GPIO4 */
+				true, PRCM_IDX_GPIOCR1, 6,	/* PTM_A9_D4 */
+				true, PRCM_IDX_GPIOCR1, 15,	/* DBG_ETM_R4_CMD1*/
+				true, PRCM_IDX_GPIOCR1, 24	/* HW_OBS4 */
+	),
+	PRCM_GPIOCR_ALTCX(165,	true, PRCM_IDX_GPIOCR1, 4,	/* Hx_GPIO3 */
+				true, PRCM_IDX_GPIOCR1, 6,	/* PTM_A9_D3 */
+				true, PRCM_IDX_GPIOCR1, 15,	/* DBG_ETM_R4_CMD1*/
+				true, PRCM_IDX_GPIOCR1, 24	/* HW_OBS3 */
+	),
+	PRCM_GPIOCR_ALTCX(166,	true, PRCM_IDX_GPIOCR1, 4,	/* Hx_GPIO2 */
+				true, PRCM_IDX_GPIOCR1, 6,	/* PTM_A9_D2 */
+				true, PRCM_IDX_GPIOCR1, 15,	/* DBG_ETM_R4_CMD1*/
+				true, PRCM_IDX_GPIOCR1, 24	/* HW_OBS2 */
+	),
+	PRCM_GPIOCR_ALTCX(167,	true, PRCM_IDX_GPIOCR1, 4,	/* Hx_GPIO1 */
+				true, PRCM_IDX_GPIOCR1, 6,	/* PTM_A9_D1 */
+				true, PRCM_IDX_GPIOCR1, 15,	/* DBG_ETM_R4_CMD1*/
+				true, PRCM_IDX_GPIOCR1, 24	/* HW_OBS1 */
+	),
+	PRCM_GPIOCR_ALTCX(168,	true, PRCM_IDX_GPIOCR1, 4,	/* Hx_GPIO0 */
+				true, PRCM_IDX_GPIOCR1, 6,	/* PTM_A9_D0 */
+				true, PRCM_IDX_GPIOCR1, 15,	/* DBG_ETM_R4_CMD1*/
+				true, PRCM_IDX_GPIOCR1, 24	/* HW_OBS0 */
+	),
+	PRCM_GPIOCR_ALTCX(170,	true, PRCM_IDX_GPIOCR2, 2,	/* RF_INT */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(171,	true, PRCM_IDX_GPIOCR2, 0,	/* RF_CTRL */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(215,	true, PRCM_IDX_GPIOCR1, 23,	/* SPI2_TXD */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(216,	true, PRCM_IDX_GPIOCR1, 23,	/* SPI2_FRM */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(217,	true, PRCM_IDX_GPIOCR1, 23,	/* SPI2_CLK */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(218,	true, PRCM_IDX_GPIOCR1, 23,	/* SPI2_RXD */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+};
+
+static const u16 db8500_prcm_gpiocr_regs[] = {
+	[PRCM_IDX_GPIOCR1] = 0x138,
+	[PRCM_IDX_GPIOCR2] = 0x574,
+};
+
 static const struct nmk_pinctrl_soc_data nmk_db8500_soc = {
 	.gpio_ranges = nmk_db8500_ranges,
 	.gpio_num_ranges = ARRAY_SIZE(nmk_db8500_ranges),
@@ -869,6 +1147,9 @@
 	.nfunctions = ARRAY_SIZE(nmk_db8500_functions),
 	.groups = nmk_db8500_groups,
 	.ngroups = ARRAY_SIZE(nmk_db8500_groups),
+	.altcx_pins = db8500_altcx_pins,
+	.npins_altcx = ARRAY_SIZE(db8500_altcx_pins),
+	.prcm_gpiocr_registers = db8500_prcm_gpiocr_regs,
 };
 
 void __devinit
diff --git a/drivers/pinctrl/pinctrl-nomadik-db8540.c b/drivers/pinctrl/pinctrl-nomadik-db8540.c
index 3daf665..52fc301 100644
--- a/drivers/pinctrl/pinctrl-nomadik-db8540.c
+++ b/drivers/pinctrl/pinctrl-nomadik-db8540.c
@@ -778,50 +778,50 @@
 	DB8540_PIN_GROUP(spi0_c_1, NMK_GPIO_ALT_C),
 	DB8540_PIN_GROUP(i2c3_c_1, NMK_GPIO_ALT_C),
 
-	/* Other alt C1 column, these are still configured as alt C */
-	DB8540_PIN_GROUP(spi3_oc1_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(stmape_oc1_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(u2_oc1_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(remap0_oc1_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(remap1_oc1_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(modobsrefclk_oc1_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(modobspwrctrl_oc1_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(modobsclkout_oc1_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(moduart1_oc1_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(modprcmudbg_oc1_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(modobsresout_oc1_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(modaccgpo_oc1_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(kp_oc1_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(modxmip_oc1_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(i2c6_oc1_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(u2txrx_oc1_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(u2ctsrts_oc1_1, NMK_GPIO_ALT_C),
+	/* Other alt C1 column */
+	DB8540_PIN_GROUP(spi3_oc1_1, NMK_GPIO_ALT_C1),
+	DB8540_PIN_GROUP(stmape_oc1_1, NMK_GPIO_ALT_C1),
+	DB8540_PIN_GROUP(u2_oc1_1, NMK_GPIO_ALT_C1),
+	DB8540_PIN_GROUP(remap0_oc1_1, NMK_GPIO_ALT_C1),
+	DB8540_PIN_GROUP(remap1_oc1_1, NMK_GPIO_ALT_C1),
+	DB8540_PIN_GROUP(modobsrefclk_oc1_1, NMK_GPIO_ALT_C1),
+	DB8540_PIN_GROUP(modobspwrctrl_oc1_1, NMK_GPIO_ALT_C1),
+	DB8540_PIN_GROUP(modobsclkout_oc1_1, NMK_GPIO_ALT_C1),
+	DB8540_PIN_GROUP(moduart1_oc1_1, NMK_GPIO_ALT_C1),
+	DB8540_PIN_GROUP(modprcmudbg_oc1_1, NMK_GPIO_ALT_C1),
+	DB8540_PIN_GROUP(modobsresout_oc1_1, NMK_GPIO_ALT_C1),
+	DB8540_PIN_GROUP(modaccgpo_oc1_1, NMK_GPIO_ALT_C1),
+	DB8540_PIN_GROUP(kp_oc1_1, NMK_GPIO_ALT_C1),
+	DB8540_PIN_GROUP(modxmip_oc1_1, NMK_GPIO_ALT_C1),
+	DB8540_PIN_GROUP(i2c6_oc1_1, NMK_GPIO_ALT_C1),
+	DB8540_PIN_GROUP(u2txrx_oc1_1, NMK_GPIO_ALT_C1),
+	DB8540_PIN_GROUP(u2ctsrts_oc1_1, NMK_GPIO_ALT_C1),
 
-	/* Other alt C2 column, these are still configured as alt C */
-	DB8540_PIN_GROUP(sbag_oc2_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(hxclk_oc2_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(modaccuart_oc2_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(stmmod_oc2_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(moduartstmmux_oc2_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(hxgpio_oc2_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(sbag_oc2_2, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(modobsservice_oc2_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(moduart0_oc2_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(stmape_oc2_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(u2_oc2_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(modxmip_oc2_1, NMK_GPIO_ALT_C),
+	/* Other alt C2 column */
+	DB8540_PIN_GROUP(sbag_oc2_1, NMK_GPIO_ALT_C2),
+	DB8540_PIN_GROUP(hxclk_oc2_1, NMK_GPIO_ALT_C2),
+	DB8540_PIN_GROUP(modaccuart_oc2_1, NMK_GPIO_ALT_C2),
+	DB8540_PIN_GROUP(stmmod_oc2_1, NMK_GPIO_ALT_C2),
+	DB8540_PIN_GROUP(moduartstmmux_oc2_1, NMK_GPIO_ALT_C2),
+	DB8540_PIN_GROUP(hxgpio_oc2_1, NMK_GPIO_ALT_C2),
+	DB8540_PIN_GROUP(sbag_oc2_2, NMK_GPIO_ALT_C2),
+	DB8540_PIN_GROUP(modobsservice_oc2_1, NMK_GPIO_ALT_C2),
+	DB8540_PIN_GROUP(moduart0_oc2_1, NMK_GPIO_ALT_C2),
+	DB8540_PIN_GROUP(stmape_oc2_1, NMK_GPIO_ALT_C2),
+	DB8540_PIN_GROUP(u2_oc2_1, NMK_GPIO_ALT_C2),
+	DB8540_PIN_GROUP(modxmip_oc2_1, NMK_GPIO_ALT_C2),
 
-	/* Other alt C3 column, these are still configured as alt C */
-	DB8540_PIN_GROUP(modaccgpo_oc3_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(tpui_oc3_1, NMK_GPIO_ALT_C),
+	/* Other alt C3 column */
+	DB8540_PIN_GROUP(modaccgpo_oc3_1, NMK_GPIO_ALT_C3),
+	DB8540_PIN_GROUP(tpui_oc3_1, NMK_GPIO_ALT_C3),
 
-	/* Other alt C4 column, these are still configured as alt C */
-	DB8540_PIN_GROUP(hwobs_oc4_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(moduart1txrx_oc4_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(moduart1rtscts_oc4_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(modaccuarttxrx_oc4_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(modaccuartrtscts_oc4_1, NMK_GPIO_ALT_C),
-	DB8540_PIN_GROUP(stmmod_oc4_1, NMK_GPIO_ALT_C),
+	/* Other alt C4 column */
+	DB8540_PIN_GROUP(hwobs_oc4_1, NMK_GPIO_ALT_C4),
+	DB8540_PIN_GROUP(moduart1txrx_oc4_1, NMK_GPIO_ALT_C4),
+	DB8540_PIN_GROUP(moduart1rtscts_oc4_1, NMK_GPIO_ALT_C4),
+	DB8540_PIN_GROUP(modaccuarttxrx_oc4_1, NMK_GPIO_ALT_C4),
+	DB8540_PIN_GROUP(modaccuartrtscts_oc4_1, NMK_GPIO_ALT_C4),
+	DB8540_PIN_GROUP(stmmod_oc4_1, NMK_GPIO_ALT_C4),
 
 };
 
@@ -981,6 +981,265 @@
 	FUNCTION(usb)
 };
 
+static const struct prcm_gpiocr_altcx_pin_desc db8540_altcx_pins[] = {
+	PRCM_GPIOCR_ALTCX(8,	true, PRCM_IDX_GPIOCR1, 20,	/* SPI3_CLK */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(9,	true, PRCM_IDX_GPIOCR1, 20,	/* SPI3_RXD */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(10,	true, PRCM_IDX_GPIOCR1, 20,	/* SPI3_FRM */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(11,	true, PRCM_IDX_GPIOCR1, 20,	/* SPI3_TXD */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(23,	true, PRCM_IDX_GPIOCR1, 9,	/* STMAPE_CLK_a */
+				true, PRCM_IDX_GPIOCR2, 10,	/* SBAG_CLK_a */
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(24,	true, PRCM_IDX_GPIOCR3, 30,	/* U2_RXD_g */
+				true, PRCM_IDX_GPIOCR2, 10,	/* SBAG_VAL_a */
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(25,	true, PRCM_IDX_GPIOCR1, 9,	/* STMAPE_DAT_a[0] */
+				true, PRCM_IDX_GPIOCR2, 10,	/* SBAG_D_a[0] */
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(26,	true, PRCM_IDX_GPIOCR1, 9,	/* STMAPE_DAT_a[1] */
+				true, PRCM_IDX_GPIOCR2, 10,	/* SBAG_D_a[1] */
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(27,	true, PRCM_IDX_GPIOCR1, 9,	/* STMAPE_DAT_a[2] */
+				true, PRCM_IDX_GPIOCR2, 10,	/* SBAG_D_a[2] */
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(28,	true, PRCM_IDX_GPIOCR1, 9,	/* STMAPE_DAT_a[3] */
+				true, PRCM_IDX_GPIOCR2, 10,	/* SBAG_D_a[3] */
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(64,	true, PRCM_IDX_GPIOCR1, 15,	/* MODOBS_REFCLK_REQ */
+				false, 0, 0,
+				true, PRCM_IDX_GPIOCR1, 2,	/* TPIU_CTL */
+				true, PRCM_IDX_GPIOCR2, 23	/* HW_OBS_APE_PRCMU[17] */
+	),
+	PRCM_GPIOCR_ALTCX(65,	true, PRCM_IDX_GPIOCR1, 19,	/* MODOBS_PWRCTRL0 */
+				true, PRCM_IDX_GPIOCR1, 24,	/* Hx_CLK */
+				true, PRCM_IDX_GPIOCR1, 2,	/* TPIU_CLK */
+				true, PRCM_IDX_GPIOCR2, 24	/* HW_OBS_APE_PRCMU[16] */
+	),
+	PRCM_GPIOCR_ALTCX(66,	true, PRCM_IDX_GPIOCR1, 15,	/* MODOBS_CLKOUT1 */
+				false, 0, 0,
+				true, PRCM_IDX_GPIOCR1, 2,	/* TPIU_D[15] */
+				true, PRCM_IDX_GPIOCR2, 25	/* HW_OBS_APE_PRCMU[15] */
+	),
+	PRCM_GPIOCR_ALTCX(67,	true, PRCM_IDX_GPIOCR1, 1,	/* MODUART1_TXD_a */
+				true, PRCM_IDX_GPIOCR1, 6,	/* MODACCUART_TXD_a */
+				true, PRCM_IDX_GPIOCR1, 2,	/* TPIU_D[14] */
+				true, PRCM_IDX_GPIOCR2, 26	/* HW_OBS_APE_PRCMU[14] */
+	),
+	PRCM_GPIOCR_ALTCX(70,	true, PRCM_IDX_GPIOCR3, 6,	/* MOD_PRCMU_DEBUG[17] */
+				true, PRCM_IDX_GPIOCR1, 10,	/* STMMOD_CLK_b */
+				true, PRCM_IDX_GPIOCR1, 2,	/* TPIU_D[13] */
+				true, PRCM_IDX_GPIOCR2, 27	/* HW_OBS_APE_PRCMU[13] */
+	),
+	PRCM_GPIOCR_ALTCX(71,	true, PRCM_IDX_GPIOCR3, 6,	/* MOD_PRCMU_DEBUG[16] */
+				true, PRCM_IDX_GPIOCR1, 10,	/* STMMOD_DAT_b[3] */
+				true, PRCM_IDX_GPIOCR1, 2,	/* TPIU_D[12] */
+				true, PRCM_IDX_GPIOCR2, 27	/* HW_OBS_APE_PRCMU[12] */
+	),
+	PRCM_GPIOCR_ALTCX(72,	true, PRCM_IDX_GPIOCR3, 6,	/* MOD_PRCMU_DEBUG[15] */
+				true, PRCM_IDX_GPIOCR1, 10,	/* STMMOD_DAT_b[2] */
+				true, PRCM_IDX_GPIOCR1, 2,	/* TPIU_D[11] */
+				true, PRCM_IDX_GPIOCR2, 27	/* HW_OBS_APE_PRCMU[11] */
+	),
+	PRCM_GPIOCR_ALTCX(73,	true, PRCM_IDX_GPIOCR3, 6,	/* MOD_PRCMU_DEBUG[14] */
+				true, PRCM_IDX_GPIOCR1, 10,	/* STMMOD_DAT_b[1] */
+				true, PRCM_IDX_GPIOCR1, 2,	/* TPIU_D[10] */
+				true, PRCM_IDX_GPIOCR2, 27	/* HW_OBS_APE_PRCMU[10] */
+	),
+	PRCM_GPIOCR_ALTCX(74,	true, PRCM_IDX_GPIOCR3, 6,	/* MOD_PRCMU_DEBUG[13] */
+				true, PRCM_IDX_GPIOCR1, 10,	/* STMMOD_DAT_b[0] */
+				true, PRCM_IDX_GPIOCR1, 2,	/* TPIU_D[9] */
+				true, PRCM_IDX_GPIOCR2, 27	/* HW_OBS_APE_PRCMU[9] */
+	),
+	PRCM_GPIOCR_ALTCX(75,	true, PRCM_IDX_GPIOCR1, 12,	/* MODOBS_RESOUT0_N */
+				true, PRCM_IDX_GPIOCR2, 1,	/* MODUART_STMMUX_RXD_b */
+				true, PRCM_IDX_GPIOCR1, 2,	/* TPIU_D[8] */
+				true, PRCM_IDX_GPIOCR2, 28	/* HW_OBS_APE_PRCMU[8] */
+	),
+	PRCM_GPIOCR_ALTCX(76,	true, PRCM_IDX_GPIOCR3, 7,	/* MOD_PRCMU_DEBUG[12] */
+				true, PRCM_IDX_GPIOCR1, 25,	/* Hx_GPIO[7] */
+				true, PRCM_IDX_GPIOCR1, 2,	/* TPIU_D[7] */
+				true, PRCM_IDX_GPIOCR2, 29	/* HW_OBS_APE_PRCMU[7] */
+	),
+	PRCM_GPIOCR_ALTCX(77,	true, PRCM_IDX_GPIOCR3, 7,	/* MOD_PRCMU_DEBUG[11] */
+				true, PRCM_IDX_GPIOCR1, 25,	/* Hx_GPIO[6] */
+				true, PRCM_IDX_GPIOCR1, 2,	/* TPIU_D[6] */
+				true, PRCM_IDX_GPIOCR2, 29	/* HW_OBS_APE_PRCMU[6] */
+	),
+	PRCM_GPIOCR_ALTCX(78,	true, PRCM_IDX_GPIOCR3, 7,	/* MOD_PRCMU_DEBUG[10] */
+				true, PRCM_IDX_GPIOCR1, 25,	/* Hx_GPIO[5] */
+				true, PRCM_IDX_GPIOCR1, 2,	/* TPIU_D[5] */
+				true, PRCM_IDX_GPIOCR2, 29	/* HW_OBS_APE_PRCMU[5] */
+	),
+	PRCM_GPIOCR_ALTCX(79,	true, PRCM_IDX_GPIOCR3, 7,	/* MOD_PRCMU_DEBUG[9] */
+				true, PRCM_IDX_GPIOCR1, 25,	/* Hx_GPIO[4] */
+				true, PRCM_IDX_GPIOCR1, 2,	/* TPIU_D[4] */
+				true, PRCM_IDX_GPIOCR2, 29	/* HW_OBS_APE_PRCMU[4] */
+	),
+	PRCM_GPIOCR_ALTCX(80,	true, PRCM_IDX_GPIOCR1, 26,	/* MODACC_GPO[0] */
+				true, PRCM_IDX_GPIOCR1, 25,	/* Hx_GPIO[3] */
+				true, PRCM_IDX_GPIOCR1, 2,	/* TPIU_D[3] */
+				true, PRCM_IDX_GPIOCR2, 30	/* HW_OBS_APE_PRCMU[3] */
+	),
+	PRCM_GPIOCR_ALTCX(81,	true, PRCM_IDX_GPIOCR2, 17,	/* MODACC_GPO[1] */
+				true, PRCM_IDX_GPIOCR1, 25,	/* Hx_GPIO[2] */
+				true, PRCM_IDX_GPIOCR1, 2,	/* TPIU_D[2] */
+				true, PRCM_IDX_GPIOCR2, 30	/* HW_OBS_APE_PRCMU[2] */
+	),
+	PRCM_GPIOCR_ALTCX(82,	true, PRCM_IDX_GPIOCR3, 8,	/* MOD_PRCMU_DEBUG[8] */
+				true, PRCM_IDX_GPIOCR1, 25,	/* Hx_GPIO[1] */
+				true, PRCM_IDX_GPIOCR1, 2,	/* TPIU_D[1] */
+				true, PRCM_IDX_GPIOCR2, 31	/* HW_OBS_APE_PRCMU[1] */
+	),
+	PRCM_GPIOCR_ALTCX(83,	true, PRCM_IDX_GPIOCR3, 8,	/* MOD_PRCMU_DEBUG[7] */
+				true, PRCM_IDX_GPIOCR1, 25,	/* Hx_GPIO[0] */
+				true, PRCM_IDX_GPIOCR1, 2,	/* TPIU_D[0] */
+				true, PRCM_IDX_GPIOCR2, 31	/* HW_OBS_APE_PRCMU[0] */
+	),
+	PRCM_GPIOCR_ALTCX(84,	true, PRCM_IDX_GPIOCR3, 9,	/* MOD_PRCMU_DEBUG[6] */
+				true, PRCM_IDX_GPIOCR1, 8,	/* SBAG_CLK_b */
+				true, PRCM_IDX_GPIOCR1, 3,	/* TPIU_D[23] */
+				true, PRCM_IDX_GPIOCR1, 16	/* MODUART1_RXD_b */
+	),
+	PRCM_GPIOCR_ALTCX(85,	true, PRCM_IDX_GPIOCR3, 9,	/* MOD_PRCMU_DEBUG[5] */
+				true, PRCM_IDX_GPIOCR1, 8,	/* SBAG_D_b[3] */
+				true, PRCM_IDX_GPIOCR1, 3,	/* TPIU_D[22] */
+				true, PRCM_IDX_GPIOCR1, 16	/* MODUART1_TXD_b */
+	),
+	PRCM_GPIOCR_ALTCX(86,	true, PRCM_IDX_GPIOCR3, 9,	/* MOD_PRCMU_DEBUG[0] */
+				true, PRCM_IDX_GPIOCR2, 18,	/* STMAPE_DAT_b[0] */
+				true, PRCM_IDX_GPIOCR1, 14,	/* TPIU_D[25] */
+				true, PRCM_IDX_GPIOCR1, 11	/* STMMOD_DAT_c[0] */
+	),
+	PRCM_GPIOCR_ALTCX(87,	true, PRCM_IDX_GPIOCR3, 0,	/* MODACC_GPO_a[5] */
+				true, PRCM_IDX_GPIOCR2, 3,	/* U2_RXD_c */
+				true, PRCM_IDX_GPIOCR1, 4,	/* TPIU_D[24] */
+				true, PRCM_IDX_GPIOCR1, 21	/* MODUART_STMMUX_RXD_c */
+	),
+	PRCM_GPIOCR_ALTCX(151,	true, PRCM_IDX_GPIOCR1, 18,	/* REMAP0 */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(152,	true, PRCM_IDX_GPIOCR1, 18,	/* REMAP1 */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(153,	true, PRCM_IDX_GPIOCR3, 2,	/* KP_O_b[6] */
+				true, PRCM_IDX_GPIOCR1, 8,	/* SBAG_D_b[2] */
+				true, PRCM_IDX_GPIOCR1, 3,	/* TPIU_D[21] */
+				true, PRCM_IDX_GPIOCR1, 0	/* MODUART1_RTS */
+	),
+	PRCM_GPIOCR_ALTCX(154,	true, PRCM_IDX_GPIOCR3, 2,	/* KP_I_b[6] */
+				true, PRCM_IDX_GPIOCR1, 8,	/* SBAG_D_b[1] */
+				true, PRCM_IDX_GPIOCR1, 3,	/* TPIU_D[20] */
+				true, PRCM_IDX_GPIOCR1, 0	/* MODUART1_CTS */
+	),
+	PRCM_GPIOCR_ALTCX(155,	true, PRCM_IDX_GPIOCR3, 3,	/* KP_O_b[5] */
+				true, PRCM_IDX_GPIOCR1, 8,	/* SBAG_D_b[0] */
+				true, PRCM_IDX_GPIOCR1, 3,	/* TPIU_D[19] */
+				true, PRCM_IDX_GPIOCR1, 5	/* MODACCUART_RXD_c */
+	),
+	PRCM_GPIOCR_ALTCX(156,	true, PRCM_IDX_GPIOCR3, 3,	/* KP_O_b[4] */
+				true, PRCM_IDX_GPIOCR1, 8,	/* SBAG_VAL_b */
+				true, PRCM_IDX_GPIOCR1, 3,	/* TPIU_D[18] */
+				true, PRCM_IDX_GPIOCR1, 5	/* MODACCUART_TXD_b */
+	),
+	PRCM_GPIOCR_ALTCX(157,	true, PRCM_IDX_GPIOCR3, 4,	/* KP_I_b[5] */
+				true, PRCM_IDX_GPIOCR1, 23,	/* MODOBS_SERVICE_N */
+				true, PRCM_IDX_GPIOCR1, 3,	/* TPIU_D[17] */
+				true, PRCM_IDX_GPIOCR1, 14	/* MODACCUART_RTS */
+	),
+	PRCM_GPIOCR_ALTCX(158,	true, PRCM_IDX_GPIOCR3, 4,	/* KP_I_b[4] */
+				true, PRCM_IDX_GPIOCR2, 0,	/* U2_TXD_c */
+				true, PRCM_IDX_GPIOCR1, 3,	/* TPIU_D[16] */
+				true, PRCM_IDX_GPIOCR1, 14	/* MODACCUART_CTS */
+	),
+	PRCM_GPIOCR_ALTCX(159,	true, PRCM_IDX_GPIOCR3, 5,	/* KP_O_b[3] */
+				true, PRCM_IDX_GPIOCR3, 10,	/* MODUART0_RXD */
+				true, PRCM_IDX_GPIOCR1, 4,	/* TPIU_D[31] */
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(160,	true, PRCM_IDX_GPIOCR3, 5,	/* KP_I_b[3] */
+				true, PRCM_IDX_GPIOCR3, 10,	/* MODUART0_TXD */
+				true, PRCM_IDX_GPIOCR1, 4,	/* TPIU_D[30] */
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(161,	true, PRCM_IDX_GPIOCR3, 9,	/* MOD_PRCMU_DEBUG[4] */
+				true, PRCM_IDX_GPIOCR2, 18,	/* STMAPE_CLK_b */
+				true, PRCM_IDX_GPIOCR1, 4,	/* TPIU_D[29] */
+				true, PRCM_IDX_GPIOCR1, 11	/* STMMOD_CLK_c */
+	),
+	PRCM_GPIOCR_ALTCX(162,	true, PRCM_IDX_GPIOCR3, 9,	/* MOD_PRCMU_DEBUG[3] */
+				true, PRCM_IDX_GPIOCR2, 18,	/* STMAPE_DAT_b[3] */
+				true, PRCM_IDX_GPIOCR1, 4,	/* TPIU_D[28] */
+				true, PRCM_IDX_GPIOCR1, 11	/* STMMOD_DAT_c[3] */
+	),
+	PRCM_GPIOCR_ALTCX(163,	true, PRCM_IDX_GPIOCR3, 9,	/* MOD_PRCMU_DEBUG[2] */
+				true, PRCM_IDX_GPIOCR2, 18,	/* STMAPE_DAT_b[2] */
+				true, PRCM_IDX_GPIOCR1, 4,	/* TPIU_D[27] */
+				true, PRCM_IDX_GPIOCR1, 11	/* STMMOD_DAT_c[2] */
+	),
+	PRCM_GPIOCR_ALTCX(164,	true, PRCM_IDX_GPIOCR3, 9,	/* MOD_PRCMU_DEBUG[1] */
+				true, PRCM_IDX_GPIOCR2, 18,	/* STMAPE_DAT_b[1] */
+				true, PRCM_IDX_GPIOCR1, 4,	/* TPIU_D[26] */
+				true, PRCM_IDX_GPIOCR1, 11	/* STMMOD_DAT_c[1] */
+	),
+	PRCM_GPIOCR_ALTCX(204,	true, PRCM_IDX_GPIOCR2, 2,	/* U2_RXD_f */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(205,	true, PRCM_IDX_GPIOCR2, 2,	/* U2_TXD_f */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(206,	true, PRCM_IDX_GPIOCR2, 2,	/* U2_CTSn_b */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+	PRCM_GPIOCR_ALTCX(207,	true, PRCM_IDX_GPIOCR2, 2,	/* U2_RTSn_b */
+				false, 0, 0,
+				false, 0, 0,
+				false, 0, 0
+	),
+};
+
+static const u16 db8540_prcm_gpiocr_regs[] = {
+	[PRCM_IDX_GPIOCR1] = 0x138,
+	[PRCM_IDX_GPIOCR2] = 0x574,
+	[PRCM_IDX_GPIOCR3] = 0x2bc,
+};
+
 static const struct nmk_pinctrl_soc_data nmk_db8540_soc = {
 	.gpio_ranges = nmk_db8540_ranges,
 	.gpio_num_ranges = ARRAY_SIZE(nmk_db8540_ranges),
@@ -990,6 +1249,9 @@
 	.nfunctions = ARRAY_SIZE(nmk_db8540_functions),
 	.groups = nmk_db8540_groups,
 	.ngroups = ARRAY_SIZE(nmk_db8540_groups),
+	.altcx_pins = db8540_altcx_pins,
+	.npins_altcx = ARRAY_SIZE(db8540_altcx_pins),
+	.prcm_gpiocr_registers = db8540_prcm_gpiocr_regs,
 };
 
 void __devinit
diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c
index 6030a51..fec9c30 100644
--- a/drivers/pinctrl/pinctrl-nomadik.c
+++ b/drivers/pinctrl/pinctrl-nomadik.c
@@ -30,6 +30,7 @@
 #include <linux/pinctrl/pinconf.h>
 /* Since we request GPIOs from ourself */
 #include <linux/pinctrl/consumer.h>
+#include <linux/mfd/dbx500-prcmu.h>
 
 #include <asm/mach/irq.h>
 
@@ -237,6 +238,89 @@
 	dev_dbg(nmk_chip->chip.dev, "%d: clearing interrupt mask\n", gpio);
 }
 
+static void nmk_prcm_altcx_set_mode(struct nmk_pinctrl *npct,
+	unsigned offset, unsigned alt_num)
+{
+	int i;
+	u16 reg;
+	u8 bit;
+	u8 alt_index;
+	const struct prcm_gpiocr_altcx_pin_desc *pin_desc;
+	const u16 *gpiocr_regs;
+
+	if (alt_num > PRCM_IDX_GPIOCR_ALTC_MAX) {
+		dev_err(npct->dev, "PRCM GPIOCR: alternate-C%i is invalid\n",
+			alt_num);
+		return;
+	}
+
+	for (i = 0 ; i < npct->soc->npins_altcx ; i++) {
+		if (npct->soc->altcx_pins[i].pin == offset)
+			break;
+	}
+	if (i == npct->soc->npins_altcx) {
+		dev_dbg(npct->dev, "PRCM GPIOCR: pin %i is not found\n",
+			offset);
+		return;
+	}
+
+	pin_desc = npct->soc->altcx_pins + i;
+	gpiocr_regs = npct->soc->prcm_gpiocr_registers;
+
+	/*
+	 * If alt_num is NULL, just clear current ALTCx selection
+	 * to make sure we come back to a pure ALTC selection
+	 */
+	if (!alt_num) {
+		for (i = 0 ; i < PRCM_IDX_GPIOCR_ALTC_MAX ; i++) {
+			if (pin_desc->altcx[i].used == true) {
+				reg = gpiocr_regs[pin_desc->altcx[i].reg_index];
+				bit = pin_desc->altcx[i].control_bit;
+				if (prcmu_read(reg) & BIT(bit)) {
+					prcmu_write_masked(reg, BIT(bit), 0);
+					dev_dbg(npct->dev,
+						"PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n",
+						offset, i+1);
+				}
+			}
+		}
+		return;
+	}
+
+	alt_index = alt_num - 1;
+	if (pin_desc->altcx[alt_index].used == false) {
+		dev_warn(npct->dev,
+			"PRCM GPIOCR: pin %i: alternate-C%i does not exist\n",
+			offset, alt_num);
+		return;
+	}
+
+	/*
+	 * Check if any other ALTCx functions are activated on this pin
+	 * and disable it first.
+	 */
+	for (i = 0 ; i < PRCM_IDX_GPIOCR_ALTC_MAX ; i++) {
+		if (i == alt_index)
+			continue;
+		if (pin_desc->altcx[i].used == true) {
+			reg = gpiocr_regs[pin_desc->altcx[i].reg_index];
+			bit = pin_desc->altcx[i].control_bit;
+			if (prcmu_read(reg) & BIT(bit)) {
+				prcmu_write_masked(reg, BIT(bit), 0);
+				dev_dbg(npct->dev,
+					"PRCM GPIOCR: pin %i: alternate-C%i has been disabled\n",
+					offset, i+1);
+			}
+		}
+	}
+
+	reg = gpiocr_regs[pin_desc->altcx[alt_index].reg_index];
+	bit = pin_desc->altcx[alt_index].control_bit;
+	dev_dbg(npct->dev, "PRCM GPIOCR: pin %i: alternate-C%i has been selected\n",
+		offset, alt_index+1);
+	prcmu_write_masked(reg, BIT(bit), BIT(bit));
+}
+
 static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset,
 			     pin_cfg_t cfg, bool sleep, unsigned int *slpmregs)
 {
@@ -1287,9 +1371,19 @@
 
 	platform_set_drvdata(dev, nmk_chip);
 
-	nmk_chip->domain = irq_domain_add_legacy(np, NMK_GPIO_PER_CHIP,
-						NOMADIK_GPIO_TO_IRQ(pdata->first_gpio),
-						0, &nmk_gpio_irq_simple_ops, nmk_chip);
+	if (np) {
+		/* The DT case will just grab a set of IRQ numbers */
+		nmk_chip->domain = irq_domain_add_linear(np, NMK_GPIO_PER_CHIP,
+				&nmk_gpio_irq_simple_ops, nmk_chip);
+	} else {
+		/* Non-DT legacy mode, use hardwired IRQ numbers */
+		int irq_start;
+
+		irq_start = NOMADIK_GPIO_TO_IRQ(pdata->first_gpio);
+		nmk_chip->domain = irq_domain_add_simple(NULL,
+				NMK_GPIO_PER_CHIP, irq_start,
+				&nmk_gpio_irq_simple_ops, nmk_chip);
+	}
 	if (!nmk_chip->domain) {
 		dev_err(&dev->dev, "failed to create irqdomain\n");
 		ret = -ENOSYS;
@@ -1441,7 +1535,7 @@
 	 * IOFORCE will switch *all* ports to their sleepmode setting to as
 	 * to avoid glitches. (Not just one port!)
 	 */
-	glitch = (g->altsetting == NMK_GPIO_ALT_C);
+	glitch = ((g->altsetting & NMK_GPIO_ALT_C) == NMK_GPIO_ALT_C);
 
 	if (glitch) {
 		spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
@@ -1491,8 +1585,21 @@
 		 */
 		nmk_gpio_disable_lazy_irq(nmk_chip, bit);
 
-		__nmk_gpio_set_mode_safe(nmk_chip, bit, g->altsetting, glitch);
+		__nmk_gpio_set_mode_safe(nmk_chip, bit,
+			(g->altsetting & NMK_GPIO_ALT_C), glitch);
 		clk_disable(nmk_chip->clk);
+
+		/*
+		 * Call PRCM GPIOCR config function in case ALTC
+		 * has been selected:
+		 * - If selection is a ALTCx, some bits in PRCM GPIOCR registers
+		 *   must be set.
+		 * - If selection is pure ALTC and previous selection was ALTCx,
+		 *   then some bits in PRCM GPIOCR registers must be cleared.
+		 */
+		if ((g->altsetting & NMK_GPIO_ALT_C) == NMK_GPIO_ALT_C)
+			nmk_prcm_altcx_set_mode(npct, g->pins[i],
+				g->altsetting >> NMK_GPIO_ALT_CX_SHIFT);
 	}
 
 	/* When all pins are successfully reconfigured we get here */
diff --git a/drivers/pinctrl/pinctrl-nomadik.h b/drivers/pinctrl/pinctrl-nomadik.h
index 5c99f1c..eef316e 100644
--- a/drivers/pinctrl/pinctrl-nomadik.h
+++ b/drivers/pinctrl/pinctrl-nomadik.h
@@ -8,6 +8,78 @@
 #define PINCTRL_NMK_DB8500	1
 #define PINCTRL_NMK_DB8540	2
 
+#define PRCM_GPIOCR_ALTCX(pin_num,\
+	altc1_used, altc1_ri, altc1_cb,\
+	altc2_used, altc2_ri, altc2_cb,\
+	altc3_used, altc3_ri, altc3_cb,\
+	altc4_used, altc4_ri, altc4_cb)\
+{\
+	.pin = pin_num,\
+	.altcx[PRCM_IDX_GPIOCR_ALTC1] = {\
+		.used = altc1_used,\
+		.reg_index = altc1_ri,\
+		.control_bit = altc1_cb\
+	},\
+	.altcx[PRCM_IDX_GPIOCR_ALTC2] = {\
+		.used = altc2_used,\
+		.reg_index = altc2_ri,\
+		.control_bit = altc2_cb\
+	},\
+	.altcx[PRCM_IDX_GPIOCR_ALTC3] = {\
+		.used = altc3_used,\
+		.reg_index = altc3_ri,\
+		.control_bit = altc3_cb\
+	},\
+	.altcx[PRCM_IDX_GPIOCR_ALTC4] = {\
+		.used = altc4_used,\
+		.reg_index = altc4_ri,\
+		.control_bit = altc4_cb\
+	},\
+}
+
+/**
+ * enum prcm_gpiocr_reg_index
+ * Used to reference an PRCM GPIOCR register address.
+ */
+enum prcm_gpiocr_reg_index {
+	PRCM_IDX_GPIOCR1,
+	PRCM_IDX_GPIOCR2,
+	PRCM_IDX_GPIOCR3
+};
+/**
+ * enum prcm_gpiocr_altcx_index
+ * Used to reference an Other alternate-C function.
+ */
+enum prcm_gpiocr_altcx_index {
+	PRCM_IDX_GPIOCR_ALTC1,
+	PRCM_IDX_GPIOCR_ALTC2,
+	PRCM_IDX_GPIOCR_ALTC3,
+	PRCM_IDX_GPIOCR_ALTC4,
+	PRCM_IDX_GPIOCR_ALTC_MAX,
+};
+
+/**
+ * struct prcm_gpio_altcx - Other alternate-C function
+ * @used: other alternate-C function availability
+ * @reg_index: PRCM GPIOCR register index used to control the function
+ * @control_bit: PRCM GPIOCR bit used to control the function
+ */
+struct prcm_gpiocr_altcx {
+	bool used:1;
+	u8 reg_index:2;
+	u8 control_bit:5;
+} __packed;
+
+/**
+ * struct prcm_gpio_altcx_pin_desc - Other alternate-C pin
+ * @pin: The pin number
+ * @altcx: array of other alternate-C[1-4] functions
+ */
+struct prcm_gpiocr_altcx_pin_desc {
+	unsigned short pin;
+	struct prcm_gpiocr_altcx altcx[PRCM_IDX_GPIOCR_ALTC_MAX];
+};
+
 /**
  * struct nmk_function - Nomadik pinctrl mux function
  * @name: The name of the function, exported to pinctrl core.
@@ -50,6 +122,9 @@
  * @nfunction:	The number of entries in @functions.
  * @groups:	An array describing all pin groups the pin SoC supports.
  * @ngroups:	The number of entries in @groups.
+ * @altcx_pins:	The pins that support Other alternate-C function on this SoC
+ * @npins_altcx: The number of Other alternate-C pins
+ * @prcm_gpiocr_registers: The array of PRCM GPIOCR registers on this SoC
  */
 struct nmk_pinctrl_soc_data {
 	struct pinctrl_gpio_range *gpio_ranges;
@@ -60,6 +135,9 @@
 	unsigned nfunctions;
 	const struct nmk_pingroup *groups;
 	unsigned ngroups;
+	const struct prcm_gpiocr_altcx_pin_desc *altcx_pins;
+	unsigned npins_altcx;
+	const u16 *prcm_gpiocr_registers;
 };
 
 #ifdef CONFIG_PINCTRL_STN8815
diff --git a/drivers/pinctrl/pinctrl-xway.c b/drivers/pinctrl/pinctrl-xway.c
new file mode 100644
index 0000000..f8d917d
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-xway.c
@@ -0,0 +1,781 @@
+/*
+ *  linux/drivers/pinctrl/pinmux-xway.c
+ *  based on linux/drivers/pinctrl/pinmux-pxa910.c
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  publishhed by the Free Software Foundation.
+ *
+ *  Copyright (C) 2012 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/of_gpio.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+#include "pinctrl-lantiq.h"
+
+#include <lantiq_soc.h>
+
+/* we have 3 1/2 banks of 16 bit each */
+#define PINS			16
+#define PORT3			3
+#define PORT(x)			(x / PINS)
+#define PORT_PIN(x)		(x % PINS)
+
+/* we have 2 mux bits that can be set for each pin */
+#define MUX_ALT0	0x1
+#define MUX_ALT1	0x2
+
+/*
+ * each bank has this offset apart from the 1/2 bank that is mixed into the
+ * other 3 ranges
+ */
+#define REG_OFF			0x30
+
+/* these are the offsets to our registers */
+#define GPIO_BASE(p)		(REG_OFF * PORT(p))
+#define GPIO_OUT(p)		GPIO_BASE(p)
+#define GPIO_IN(p)		(GPIO_BASE(p) + 0x04)
+#define GPIO_DIR(p)		(GPIO_BASE(p) + 0x08)
+#define GPIO_ALT0(p)		(GPIO_BASE(p) + 0x0C)
+#define GPIO_ALT1(p)		(GPIO_BASE(p) + 0x10)
+#define GPIO_OD(p)		(GPIO_BASE(p) + 0x14)
+#define GPIO_PUDSEL(p)		(GPIO_BASE(p) + 0x1c)
+#define GPIO_PUDEN(p)		(GPIO_BASE(p) + 0x20)
+
+/* the 1/2 port needs special offsets for some registers */
+#define GPIO3_OD		(GPIO_BASE(0) + 0x24)
+#define GPIO3_PUDSEL		(GPIO_BASE(0) + 0x28)
+#define GPIO3_PUDEN		(GPIO_BASE(0) + 0x2C)
+#define GPIO3_ALT1		(GPIO_BASE(PINS) + 0x24)
+
+/* macros to help us access the registers */
+#define gpio_getbit(m, r, p)	(!!(ltq_r32(m + r) & BIT(p)))
+#define gpio_setbit(m, r, p)	ltq_w32_mask(0, BIT(p), m + r)
+#define gpio_clearbit(m, r, p)	ltq_w32_mask(BIT(p), 0, m + r)
+
+#define MFP_XWAY(a, f0, f1, f2, f3)	\
+	{				\
+		.name = #a,		\
+		.pin = a,		\
+		.func = {		\
+			XWAY_MUX_##f0,	\
+			XWAY_MUX_##f1,	\
+			XWAY_MUX_##f2,	\
+			XWAY_MUX_##f3,	\
+		},			\
+	}
+
+#define GRP_MUX(a, m, p)		\
+	{ .name = a, .mux = XWAY_MUX_##m, .pins = p, .npins = ARRAY_SIZE(p), }
+
+#define FUNC_MUX(f, m)		\
+	{ .func = f, .mux = XWAY_MUX_##m, }
+
+#define XWAY_MAX_PIN		32
+#define XR9_MAX_PIN		56
+
+enum xway_mux {
+	XWAY_MUX_GPIO = 0,
+	XWAY_MUX_SPI,
+	XWAY_MUX_ASC,
+	XWAY_MUX_PCI,
+	XWAY_MUX_CGU,
+	XWAY_MUX_EBU,
+	XWAY_MUX_JTAG,
+	XWAY_MUX_EXIN,
+	XWAY_MUX_TDM,
+	XWAY_MUX_STP,
+	XWAY_MUX_SIN,
+	XWAY_MUX_GPT,
+	XWAY_MUX_NMI,
+	XWAY_MUX_MDIO,
+	XWAY_MUX_MII,
+	XWAY_MUX_EPHY,
+	XWAY_MUX_DFE,
+	XWAY_MUX_SDIO,
+	XWAY_MUX_NONE = 0xffff,
+};
+
+static const struct ltq_mfp_pin xway_mfp[] = {
+	/*       pin    f0	f1	f2	f3   */
+	MFP_XWAY(GPIO0, GPIO,	EXIN,	NONE,	TDM),
+	MFP_XWAY(GPIO1, GPIO,	EXIN,	NONE,	NONE),
+	MFP_XWAY(GPIO2, GPIO,	CGU,	EXIN,	NONE),
+	MFP_XWAY(GPIO3, GPIO,	CGU,	NONE,	PCI),
+	MFP_XWAY(GPIO4, GPIO,	STP,	NONE,	ASC),
+	MFP_XWAY(GPIO5, GPIO,	STP,	NONE,	NONE),
+	MFP_XWAY(GPIO6, GPIO,	STP,	GPT,	ASC),
+	MFP_XWAY(GPIO7, GPIO,	CGU,	PCI,	NONE),
+	MFP_XWAY(GPIO8, GPIO,	CGU,	NMI,	NONE),
+	MFP_XWAY(GPIO9, GPIO,	ASC,	SPI,	EXIN),
+	MFP_XWAY(GPIO10, GPIO,	ASC,	SPI,	NONE),
+	MFP_XWAY(GPIO11, GPIO,	ASC,	PCI,	SPI),
+	MFP_XWAY(GPIO12, GPIO,	ASC,	NONE,	NONE),
+	MFP_XWAY(GPIO13, GPIO,	EBU,	SPI,	NONE),
+	MFP_XWAY(GPIO14, GPIO,	CGU,	PCI,	NONE),
+	MFP_XWAY(GPIO15, GPIO,	SPI,	JTAG,	NONE),
+	MFP_XWAY(GPIO16, GPIO,	SPI,	NONE,	JTAG),
+	MFP_XWAY(GPIO17, GPIO,	SPI,	NONE,	JTAG),
+	MFP_XWAY(GPIO18, GPIO,	SPI,	NONE,	JTAG),
+	MFP_XWAY(GPIO19, GPIO,	PCI,	NONE,	NONE),
+	MFP_XWAY(GPIO20, GPIO,	JTAG,	NONE,	NONE),
+	MFP_XWAY(GPIO21, GPIO,	PCI,	EBU,	GPT),
+	MFP_XWAY(GPIO22, GPIO,	SPI,	NONE,	NONE),
+	MFP_XWAY(GPIO23, GPIO,	EBU,	PCI,	STP),
+	MFP_XWAY(GPIO24, GPIO,	EBU,	TDM,	PCI),
+	MFP_XWAY(GPIO25, GPIO,	TDM,	NONE,	ASC),
+	MFP_XWAY(GPIO26, GPIO,	EBU,	NONE,	TDM),
+	MFP_XWAY(GPIO27, GPIO,	TDM,	NONE,	ASC),
+	MFP_XWAY(GPIO28, GPIO,	GPT,	NONE,	NONE),
+	MFP_XWAY(GPIO29, GPIO,	PCI,	NONE,	NONE),
+	MFP_XWAY(GPIO30, GPIO,	PCI,	NONE,	NONE),
+	MFP_XWAY(GPIO31, GPIO,	EBU,	PCI,	NONE),
+	MFP_XWAY(GPIO32, GPIO,	NONE,	NONE,	EBU),
+	MFP_XWAY(GPIO33, GPIO,	NONE,	NONE,	EBU),
+	MFP_XWAY(GPIO34, GPIO,	NONE,	NONE,	EBU),
+	MFP_XWAY(GPIO35, GPIO,	NONE,	NONE,	EBU),
+	MFP_XWAY(GPIO36, GPIO,	SIN,	NONE,	EBU),
+	MFP_XWAY(GPIO37, GPIO,	PCI,	NONE,	NONE),
+	MFP_XWAY(GPIO38, GPIO,	PCI,	NONE,	NONE),
+	MFP_XWAY(GPIO39, GPIO,	EXIN,	NONE,	NONE),
+	MFP_XWAY(GPIO40, GPIO,	NONE,	NONE,	NONE),
+	MFP_XWAY(GPIO41, GPIO,	NONE,	NONE,	NONE),
+	MFP_XWAY(GPIO42, GPIO,	MDIO,	NONE,	NONE),
+	MFP_XWAY(GPIO43, GPIO,	MDIO,	NONE,	NONE),
+	MFP_XWAY(GPIO44, GPIO,	NONE,	NONE,	SIN),
+	MFP_XWAY(GPIO45, GPIO,	NONE,	NONE,	SIN),
+	MFP_XWAY(GPIO46, GPIO,	NONE,	NONE,	EXIN),
+	MFP_XWAY(GPIO47, GPIO,	NONE,	NONE,	SIN),
+	MFP_XWAY(GPIO48, GPIO,	EBU,	NONE,	NONE),
+	MFP_XWAY(GPIO49, GPIO,	EBU,	NONE,	NONE),
+	MFP_XWAY(GPIO50, GPIO,	NONE,	NONE,	NONE),
+	MFP_XWAY(GPIO51, GPIO,	NONE,	NONE,	NONE),
+	MFP_XWAY(GPIO52, GPIO,	NONE,	NONE,	NONE),
+	MFP_XWAY(GPIO53, GPIO,	NONE,	NONE,	NONE),
+	MFP_XWAY(GPIO54, GPIO,	NONE,	NONE,	NONE),
+	MFP_XWAY(GPIO55, GPIO,	NONE,	NONE,	NONE),
+};
+
+static const struct ltq_mfp_pin ase_mfp[] = {
+	/*       pin    f0	f1	f2	f3   */
+	MFP_XWAY(GPIO0, GPIO,	EXIN,	MII,	TDM),
+	MFP_XWAY(GPIO1, GPIO,	STP,	DFE,	EBU),
+	MFP_XWAY(GPIO2, GPIO,	STP,	DFE,	EPHY),
+	MFP_XWAY(GPIO3, GPIO,	STP,	EPHY,	EBU),
+	MFP_XWAY(GPIO4, GPIO,	GPT,	EPHY,	MII),
+	MFP_XWAY(GPIO5, GPIO,	MII,	ASC,	GPT),
+	MFP_XWAY(GPIO6, GPIO,	MII,	ASC,	EXIN),
+	MFP_XWAY(GPIO7, GPIO,	SPI,	MII,	JTAG),
+	MFP_XWAY(GPIO8, GPIO,	SPI,	MII,	JTAG),
+	MFP_XWAY(GPIO9, GPIO,	SPI,	MII,	JTAG),
+	MFP_XWAY(GPIO10, GPIO,	SPI,	MII,	JTAG),
+	MFP_XWAY(GPIO11, GPIO,	EBU,	CGU,	JTAG),
+	MFP_XWAY(GPIO12, GPIO,	EBU,	MII,	SDIO),
+	MFP_XWAY(GPIO13, GPIO,	EBU,	MII,	CGU),
+	MFP_XWAY(GPIO14, GPIO,	EBU,	SPI,	CGU),
+	MFP_XWAY(GPIO15, GPIO,	EBU,	SPI,	SDIO),
+	MFP_XWAY(GPIO16, GPIO,	NONE,	NONE,	NONE),
+	MFP_XWAY(GPIO17, GPIO,	NONE,	NONE,	NONE),
+	MFP_XWAY(GPIO18, GPIO,	NONE,	NONE,	NONE),
+	MFP_XWAY(GPIO19, GPIO,	EBU,	MII,	SDIO),
+	MFP_XWAY(GPIO20, GPIO,	EBU,	MII,	SDIO),
+	MFP_XWAY(GPIO21, GPIO,	EBU,	MII,	SDIO),
+	MFP_XWAY(GPIO22, GPIO,	EBU,	MII,	CGU),
+	MFP_XWAY(GPIO23, GPIO,	EBU,	MII,	CGU),
+	MFP_XWAY(GPIO24, GPIO,	EBU,	NONE,	MII),
+	MFP_XWAY(GPIO25, GPIO,	EBU,	MII,	GPT),
+	MFP_XWAY(GPIO26, GPIO,	EBU,	MII,	SDIO),
+	MFP_XWAY(GPIO27, GPIO,	EBU,	NONE,	MII),
+	MFP_XWAY(GPIO28, GPIO,	MII,	EBU,	SDIO),
+	MFP_XWAY(GPIO29, GPIO,	EBU,	MII,	EXIN),
+	MFP_XWAY(GPIO30, GPIO,	NONE,	NONE,	NONE),
+	MFP_XWAY(GPIO31, GPIO,	NONE,	NONE,	NONE),
+};
+
+static const unsigned pins_jtag[] = {GPIO15, GPIO16, GPIO17, GPIO19, GPIO35};
+static const unsigned pins_asc0[] = {GPIO11, GPIO12};
+static const unsigned pins_asc0_cts_rts[] = {GPIO9, GPIO10};
+static const unsigned pins_stp[] = {GPIO4, GPIO5, GPIO6};
+static const unsigned pins_nmi[] = {GPIO8};
+static const unsigned pins_mdio[] = {GPIO42, GPIO43};
+
+static const unsigned pins_ebu_a24[] = {GPIO13};
+static const unsigned pins_ebu_clk[] = {GPIO21};
+static const unsigned pins_ebu_cs1[] = {GPIO23};
+static const unsigned pins_ebu_a23[] = {GPIO24};
+static const unsigned pins_ebu_wait[] = {GPIO26};
+static const unsigned pins_ebu_a25[] = {GPIO31};
+static const unsigned pins_ebu_rdy[] = {GPIO48};
+static const unsigned pins_ebu_rd[] = {GPIO49};
+
+static const unsigned pins_nand_ale[] = {GPIO13};
+static const unsigned pins_nand_cs1[] = {GPIO23};
+static const unsigned pins_nand_cle[] = {GPIO24};
+static const unsigned pins_nand_rdy[] = {GPIO48};
+static const unsigned pins_nand_rd[] = {GPIO49};
+
+static const unsigned pins_exin0[] = {GPIO0};
+static const unsigned pins_exin1[] = {GPIO1};
+static const unsigned pins_exin2[] = {GPIO2};
+static const unsigned pins_exin3[] = {GPIO39};
+static const unsigned pins_exin4[] = {GPIO46};
+static const unsigned pins_exin5[] = {GPIO9};
+
+static const unsigned pins_spi[] = {GPIO16, GPIO17, GPIO18};
+static const unsigned pins_spi_cs1[] = {GPIO15};
+static const unsigned pins_spi_cs2[] = {GPIO21};
+static const unsigned pins_spi_cs3[] = {GPIO13};
+static const unsigned pins_spi_cs4[] = {GPIO10};
+static const unsigned pins_spi_cs5[] = {GPIO9};
+static const unsigned pins_spi_cs6[] = {GPIO11};
+
+static const unsigned pins_gpt1[] = {GPIO28};
+static const unsigned pins_gpt2[] = {GPIO21};
+static const unsigned pins_gpt3[] = {GPIO6};
+
+static const unsigned pins_clkout0[] = {GPIO8};
+static const unsigned pins_clkout1[] = {GPIO7};
+static const unsigned pins_clkout2[] = {GPIO3};
+static const unsigned pins_clkout3[] = {GPIO2};
+
+static const unsigned pins_pci_gnt1[] = {GPIO30};
+static const unsigned pins_pci_gnt2[] = {GPIO23};
+static const unsigned pins_pci_gnt3[] = {GPIO19};
+static const unsigned pins_pci_gnt4[] = {GPIO38};
+static const unsigned pins_pci_req1[] = {GPIO29};
+static const unsigned pins_pci_req2[] = {GPIO31};
+static const unsigned pins_pci_req3[] = {GPIO3};
+static const unsigned pins_pci_req4[] = {GPIO37};
+
+static const unsigned ase_pins_jtag[] = {GPIO7, GPIO8, GPIO9, GPIO10, GPIO11};
+static const unsigned ase_pins_asc[] = {GPIO5, GPIO6};
+static const unsigned ase_pins_stp[] = {GPIO1, GPIO2, GPIO3};
+static const unsigned ase_pins_ephy[] = {GPIO2, GPIO3, GPIO4};
+static const unsigned ase_pins_dfe[] = {GPIO1, GPIO2};
+
+static const unsigned ase_pins_spi[] = {GPIO8, GPIO9, GPIO10};
+static const unsigned ase_pins_spi_cs1[] = {GPIO7};
+static const unsigned ase_pins_spi_cs2[] = {GPIO15};
+static const unsigned ase_pins_spi_cs3[] = {GPIO14};
+
+static const unsigned ase_pins_exin0[] = {GPIO6};
+static const unsigned ase_pins_exin1[] = {GPIO29};
+static const unsigned ase_pins_exin2[] = {GPIO0};
+
+static const unsigned ase_pins_gpt1[] = {GPIO5};
+static const unsigned ase_pins_gpt2[] = {GPIO4};
+static const unsigned ase_pins_gpt3[] = {GPIO25};
+
+static const struct ltq_pin_group xway_grps[] = {
+	GRP_MUX("exin0", EXIN, pins_exin0),
+	GRP_MUX("exin1", EXIN, pins_exin1),
+	GRP_MUX("exin2", EXIN, pins_exin2),
+	GRP_MUX("jtag", JTAG, pins_jtag),
+	GRP_MUX("ebu a23", EBU, pins_ebu_a23),
+	GRP_MUX("ebu a24", EBU, pins_ebu_a24),
+	GRP_MUX("ebu a25", EBU, pins_ebu_a25),
+	GRP_MUX("ebu clk", EBU, pins_ebu_clk),
+	GRP_MUX("ebu cs1", EBU, pins_ebu_cs1),
+	GRP_MUX("ebu wait", EBU, pins_ebu_wait),
+	GRP_MUX("nand ale", EBU, pins_nand_ale),
+	GRP_MUX("nand cs1", EBU, pins_nand_cs1),
+	GRP_MUX("nand cle", EBU, pins_nand_cle),
+	GRP_MUX("spi", SPI, pins_spi),
+	GRP_MUX("spi_cs1", SPI, pins_spi_cs1),
+	GRP_MUX("spi_cs2", SPI, pins_spi_cs2),
+	GRP_MUX("spi_cs3", SPI, pins_spi_cs3),
+	GRP_MUX("spi_cs4", SPI, pins_spi_cs4),
+	GRP_MUX("spi_cs5", SPI, pins_spi_cs5),
+	GRP_MUX("spi_cs6", SPI, pins_spi_cs6),
+	GRP_MUX("asc0", ASC, pins_asc0),
+	GRP_MUX("asc0 cts rts", ASC, pins_asc0_cts_rts),
+	GRP_MUX("stp", STP, pins_stp),
+	GRP_MUX("nmi", NMI, pins_nmi),
+	GRP_MUX("gpt1", GPT, pins_gpt1),
+	GRP_MUX("gpt2", GPT, pins_gpt2),
+	GRP_MUX("gpt3", GPT, pins_gpt3),
+	GRP_MUX("clkout0", CGU, pins_clkout0),
+	GRP_MUX("clkout1", CGU, pins_clkout1),
+	GRP_MUX("clkout2", CGU, pins_clkout2),
+	GRP_MUX("clkout3", CGU, pins_clkout3),
+	GRP_MUX("gnt1", PCI, pins_pci_gnt1),
+	GRP_MUX("gnt2", PCI, pins_pci_gnt2),
+	GRP_MUX("gnt3", PCI, pins_pci_gnt3),
+	GRP_MUX("req1", PCI, pins_pci_req1),
+	GRP_MUX("req2", PCI, pins_pci_req2),
+	GRP_MUX("req3", PCI, pins_pci_req3),
+/* xrx only */
+	GRP_MUX("nand rdy", EBU, pins_nand_rdy),
+	GRP_MUX("nand rd", EBU, pins_nand_rd),
+	GRP_MUX("exin3", EXIN, pins_exin3),
+	GRP_MUX("exin4", EXIN, pins_exin4),
+	GRP_MUX("exin5", EXIN, pins_exin5),
+	GRP_MUX("gnt4", PCI, pins_pci_gnt4),
+	GRP_MUX("req4", PCI, pins_pci_gnt4),
+	GRP_MUX("mdio", MDIO, pins_mdio),
+};
+
+static const struct ltq_pin_group ase_grps[] = {
+	GRP_MUX("exin0", EXIN, ase_pins_exin0),
+	GRP_MUX("exin1", EXIN, ase_pins_exin1),
+	GRP_MUX("exin2", EXIN, ase_pins_exin2),
+	GRP_MUX("jtag", JTAG, ase_pins_jtag),
+	GRP_MUX("stp", STP, ase_pins_stp),
+	GRP_MUX("asc", ASC, ase_pins_asc),
+	GRP_MUX("gpt1", GPT, ase_pins_gpt1),
+	GRP_MUX("gpt2", GPT, ase_pins_gpt2),
+	GRP_MUX("gpt3", GPT, ase_pins_gpt3),
+	GRP_MUX("ephy", EPHY, ase_pins_ephy),
+	GRP_MUX("dfe", DFE, ase_pins_dfe),
+	GRP_MUX("spi", SPI, ase_pins_spi),
+	GRP_MUX("spi_cs1", SPI, ase_pins_spi_cs1),
+	GRP_MUX("spi_cs2", SPI, ase_pins_spi_cs2),
+	GRP_MUX("spi_cs3", SPI, ase_pins_spi_cs3),
+};
+
+static const char * const xway_pci_grps[] = {"gnt1", "gnt2",
+						"gnt3", "req1",
+						"req2", "req3"};
+static const char * const xway_spi_grps[] = {"spi", "spi_cs1",
+						"spi_cs2", "spi_cs3",
+						"spi_cs4", "spi_cs5",
+						"spi_cs6"};
+static const char * const xway_cgu_grps[] = {"clkout0", "clkout1",
+						"clkout2", "clkout3"};
+static const char * const xway_ebu_grps[] = {"ebu a23", "ebu a24",
+						"ebu a25", "ebu cs1",
+						"ebu wait", "ebu clk",
+						"nand ale", "nand cs1",
+						"nand cle"};
+static const char * const xway_exin_grps[] = {"exin0", "exin1", "exin2"};
+static const char * const xway_gpt_grps[] = {"gpt1", "gpt2", "gpt3"};
+static const char * const xway_asc_grps[] = {"asc0", "asc0 cts rts"};
+static const char * const xway_jtag_grps[] = {"jtag"};
+static const char * const xway_stp_grps[] = {"stp"};
+static const char * const xway_nmi_grps[] = {"nmi"};
+
+/* ar9/vr9/gr9 */
+static const char * const xrx_mdio_grps[] = {"mdio"};
+static const char * const xrx_ebu_grps[] = {"ebu a23", "ebu a24",
+						"ebu a25", "ebu cs1",
+						"ebu wait", "ebu clk",
+						"nand ale", "nand cs1",
+						"nand cle", "nand rdy",
+						"nand rd"};
+static const char * const xrx_exin_grps[] = {"exin0", "exin1", "exin2",
+						"exin3", "exin4", "exin5"};
+static const char * const xrx_pci_grps[] = {"gnt1", "gnt2",
+						"gnt3", "gnt4",
+						"req1", "req2",
+						"req3", "req4"};
+
+/* ase */
+static const char * const ase_exin_grps[] = {"exin0", "exin1", "exin2"};
+static const char * const ase_gpt_grps[] = {"gpt1", "gpt2", "gpt3"};
+static const char * const ase_dfe_grps[] = {"dfe"};
+static const char * const ase_ephy_grps[] = {"ephy"};
+static const char * const ase_asc_grps[] = {"asc"};
+static const char * const ase_jtag_grps[] = {"jtag"};
+static const char * const ase_stp_grps[] = {"stp"};
+static const char * const ase_spi_grps[] = {"spi", "spi_cs1",
+						"spi_cs2", "spi_cs3"};
+
+static const struct ltq_pmx_func danube_funcs[] = {
+	{"spi",		ARRAY_AND_SIZE(xway_spi_grps)},
+	{"asc",		ARRAY_AND_SIZE(xway_asc_grps)},
+	{"cgu",		ARRAY_AND_SIZE(xway_cgu_grps)},
+	{"jtag",	ARRAY_AND_SIZE(xway_jtag_grps)},
+	{"exin",	ARRAY_AND_SIZE(xway_exin_grps)},
+	{"stp",		ARRAY_AND_SIZE(xway_stp_grps)},
+	{"gpt",		ARRAY_AND_SIZE(xway_gpt_grps)},
+	{"nmi",		ARRAY_AND_SIZE(xway_nmi_grps)},
+	{"pci",		ARRAY_AND_SIZE(xway_pci_grps)},
+	{"ebu",		ARRAY_AND_SIZE(xway_ebu_grps)},
+};
+
+static const struct ltq_pmx_func xrx_funcs[] = {
+	{"spi",		ARRAY_AND_SIZE(xway_spi_grps)},
+	{"asc",		ARRAY_AND_SIZE(xway_asc_grps)},
+	{"cgu",		ARRAY_AND_SIZE(xway_cgu_grps)},
+	{"jtag",	ARRAY_AND_SIZE(xway_jtag_grps)},
+	{"exin",	ARRAY_AND_SIZE(xrx_exin_grps)},
+	{"stp",		ARRAY_AND_SIZE(xway_stp_grps)},
+	{"gpt",		ARRAY_AND_SIZE(xway_gpt_grps)},
+	{"nmi",		ARRAY_AND_SIZE(xway_nmi_grps)},
+	{"pci",		ARRAY_AND_SIZE(xrx_pci_grps)},
+	{"ebu",		ARRAY_AND_SIZE(xrx_ebu_grps)},
+	{"mdio",	ARRAY_AND_SIZE(xrx_mdio_grps)},
+};
+
+static const struct ltq_pmx_func ase_funcs[] = {
+	{"spi",		ARRAY_AND_SIZE(ase_spi_grps)},
+	{"asc",		ARRAY_AND_SIZE(ase_asc_grps)},
+	{"jtag",	ARRAY_AND_SIZE(ase_jtag_grps)},
+	{"exin",	ARRAY_AND_SIZE(ase_exin_grps)},
+	{"stp",		ARRAY_AND_SIZE(ase_stp_grps)},
+	{"gpt",		ARRAY_AND_SIZE(ase_gpt_grps)},
+	{"ephy",	ARRAY_AND_SIZE(ase_ephy_grps)},
+	{"dfe",		ARRAY_AND_SIZE(ase_dfe_grps)},
+};
+
+/* ---------  pinconf related code --------- */
+static int xway_pinconf_get(struct pinctrl_dev *pctldev,
+				unsigned pin,
+				unsigned long *config)
+{
+	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
+	enum ltq_pinconf_param param = LTQ_PINCONF_UNPACK_PARAM(*config);
+	int port = PORT(pin);
+	u32 reg;
+
+	switch (param) {
+	case LTQ_PINCONF_PARAM_OPEN_DRAIN:
+		if (port == PORT3)
+			reg = GPIO3_OD;
+		else
+			reg = GPIO_OD(port);
+		*config = LTQ_PINCONF_PACK(param,
+			!!gpio_getbit(info->membase[0], reg, PORT_PIN(port)));
+		break;
+
+	case LTQ_PINCONF_PARAM_PULL:
+		if (port == PORT3)
+			reg = GPIO3_PUDEN;
+		else
+			reg = GPIO_PUDEN(port);
+		if (!gpio_getbit(info->membase[0], reg, PORT_PIN(port))) {
+			*config = LTQ_PINCONF_PACK(param, 0);
+			break;
+		}
+
+		if (port == PORT3)
+			reg = GPIO3_PUDSEL;
+		else
+			reg = GPIO_PUDSEL(port);
+		if (!gpio_getbit(info->membase[0], reg, PORT_PIN(port)))
+			*config = LTQ_PINCONF_PACK(param, 2);
+		else
+			*config = LTQ_PINCONF_PACK(param, 1);
+		break;
+
+	default:
+		dev_err(pctldev->dev, "Invalid config param %04x\n", param);
+		return -ENOTSUPP;
+	}
+	return 0;
+}
+
+static int xway_pinconf_set(struct pinctrl_dev *pctldev,
+				unsigned pin,
+				unsigned long config)
+{
+	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctldev);
+	enum ltq_pinconf_param param = LTQ_PINCONF_UNPACK_PARAM(config);
+	int arg = LTQ_PINCONF_UNPACK_ARG(config);
+	int port = PORT(pin);
+	u32 reg;
+
+	switch (param) {
+	case LTQ_PINCONF_PARAM_OPEN_DRAIN:
+		if (port == PORT3)
+			reg = GPIO3_OD;
+		else
+			reg = GPIO_OD(port);
+		gpio_setbit(info->membase[0], reg, PORT_PIN(port));
+		break;
+
+	case LTQ_PINCONF_PARAM_PULL:
+		if (port == PORT3)
+			reg = GPIO3_PUDEN;
+		else
+			reg = GPIO_PUDEN(port);
+		if (arg == 0) {
+			gpio_clearbit(info->membase[0], reg, PORT_PIN(port));
+			break;
+		}
+		gpio_setbit(info->membase[0], reg, PORT_PIN(port));
+
+		if (port == PORT3)
+			reg = GPIO3_PUDSEL;
+		else
+			reg = GPIO_PUDSEL(port);
+		if (arg == 1)
+			gpio_clearbit(info->membase[0], reg, PORT_PIN(port));
+		else if (arg == 2)
+			gpio_setbit(info->membase[0], reg, PORT_PIN(port));
+		else
+			dev_err(pctldev->dev, "Invalid pull value %d\n", arg);
+		break;
+
+	default:
+		dev_err(pctldev->dev, "Invalid config param %04x\n", param);
+		return -ENOTSUPP;
+	}
+	return 0;
+}
+
+struct pinconf_ops xway_pinconf_ops = {
+	.pin_config_get	= xway_pinconf_get,
+	.pin_config_set	= xway_pinconf_set,
+};
+
+static struct pinctrl_desc xway_pctrl_desc = {
+	.owner		= THIS_MODULE,
+	.confops	= &xway_pinconf_ops,
+};
+
+static inline int xway_mux_apply(struct pinctrl_dev *pctrldev,
+				int pin, int mux)
+{
+	struct ltq_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+	int port = PORT(pin);
+	u32 alt1_reg = GPIO_ALT1(pin);
+
+	if (port == PORT3)
+		alt1_reg = GPIO3_ALT1;
+
+	if (mux & MUX_ALT0)
+		gpio_setbit(info->membase[0], GPIO_ALT0(pin), PORT_PIN(pin));
+	else
+		gpio_clearbit(info->membase[0], GPIO_ALT0(pin), PORT_PIN(pin));
+
+	if (mux & MUX_ALT1)
+		gpio_setbit(info->membase[0], alt1_reg, PORT_PIN(pin));
+	else
+		gpio_clearbit(info->membase[0], alt1_reg, PORT_PIN(pin));
+
+	return 0;
+}
+
+static const struct ltq_cfg_param xway_cfg_params[] = {
+	{"lantiq,pull",		LTQ_PINCONF_PARAM_PULL},
+	{"lantiq,open-drain",	LTQ_PINCONF_PARAM_OPEN_DRAIN},
+};
+
+static struct ltq_pinmux_info xway_info = {
+	.desc		= &xway_pctrl_desc,
+	.apply_mux	= xway_mux_apply,
+	.params		= xway_cfg_params,
+	.num_params	= ARRAY_SIZE(xway_cfg_params),
+};
+
+/* ---------  gpio_chip related code --------- */
+static void xway_gpio_set(struct gpio_chip *chip, unsigned int pin, int val)
+{
+	struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev);
+
+	if (val)
+		gpio_setbit(info->membase[0], GPIO_OUT(pin), PORT_PIN(pin));
+	else
+		gpio_clearbit(info->membase[0], GPIO_OUT(pin), PORT_PIN(pin));
+}
+
+static int xway_gpio_get(struct gpio_chip *chip, unsigned int pin)
+{
+	struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev);
+
+	return gpio_getbit(info->membase[0], GPIO_IN(pin), PORT_PIN(pin));
+}
+
+static int xway_gpio_dir_in(struct gpio_chip *chip, unsigned int pin)
+{
+	struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev);
+
+	gpio_clearbit(info->membase[0], GPIO_DIR(pin), PORT_PIN(pin));
+
+	return 0;
+}
+
+static int xway_gpio_dir_out(struct gpio_chip *chip, unsigned int pin, int val)
+{
+	struct ltq_pinmux_info *info = dev_get_drvdata(chip->dev);
+
+	gpio_setbit(info->membase[0], GPIO_DIR(pin), PORT_PIN(pin));
+	xway_gpio_set(chip, pin, val);
+
+	return 0;
+}
+
+static int xway_gpio_req(struct gpio_chip *chip, unsigned offset)
+{
+	int gpio = chip->base + offset;
+
+	return pinctrl_request_gpio(gpio);
+}
+
+static void xway_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+	int gpio = chip->base + offset;
+
+	pinctrl_free_gpio(gpio);
+}
+
+static struct gpio_chip xway_chip = {
+	.label = "gpio-xway",
+	.direction_input = xway_gpio_dir_in,
+	.direction_output = xway_gpio_dir_out,
+	.get = xway_gpio_get,
+	.set = xway_gpio_set,
+	.request = xway_gpio_req,
+	.free = xway_gpio_free,
+	.base = -1,
+};
+
+
+/* --------- register the pinctrl layer --------- */
+static const unsigned xway_exin_pin_map[] = {GPIO0, GPIO1, GPIO2, GPIO39, GPIO46, GPIO9};
+static const unsigned ase_exin_pins_map[] = {GPIO6, GPIO29, GPIO0};
+
+static struct pinctrl_xway_soc {
+	int pin_count;
+	const struct ltq_mfp_pin *mfp;
+	const struct ltq_pin_group *grps;
+	unsigned int num_grps;
+	const struct ltq_pmx_func *funcs;
+	unsigned int num_funcs;
+	const unsigned *exin;
+	unsigned int num_exin;
+} soc_cfg[] = {
+	/* legacy xway */
+	{XWAY_MAX_PIN, xway_mfp,
+		xway_grps, ARRAY_SIZE(xway_grps),
+		danube_funcs, ARRAY_SIZE(danube_funcs),
+		xway_exin_pin_map, 3},
+	/* xway xr9 series */
+	{XR9_MAX_PIN, xway_mfp,
+		xway_grps, ARRAY_SIZE(xway_grps),
+		xrx_funcs, ARRAY_SIZE(xrx_funcs),
+		xway_exin_pin_map, 6},
+	/* xway ase series */
+	{XWAY_MAX_PIN, ase_mfp,
+		ase_grps, ARRAY_SIZE(ase_grps),
+		ase_funcs, ARRAY_SIZE(ase_funcs),
+		ase_exin_pins_map, 3},
+};
+
+static struct pinctrl_gpio_range xway_gpio_range = {
+	.name	= "XWAY GPIO",
+	.gc	= &xway_chip,
+};
+
+static const struct of_device_id xway_match[] = {
+	{ .compatible = "lantiq,pinctrl-xway", .data = &soc_cfg[0]},
+	{ .compatible = "lantiq,pinctrl-xr9", .data = &soc_cfg[1]},
+	{ .compatible = "lantiq,pinctrl-ase", .data = &soc_cfg[2]},
+	{},
+};
+MODULE_DEVICE_TABLE(of, xway_match);
+
+static int __devinit pinmux_xway_probe(struct platform_device *pdev)
+{
+	const struct of_device_id *match;
+	const struct pinctrl_xway_soc *xway_soc;
+	struct resource *res;
+	int ret, i;
+
+	/* get and remap our register range */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "Failed to get resource\n");
+		return -ENOENT;
+	}
+	xway_info.membase[0] = devm_request_and_ioremap(&pdev->dev, res);
+	if (!xway_info.membase[0]) {
+		dev_err(&pdev->dev, "Failed to remap resource\n");
+		return -ENOMEM;
+	}
+
+	match = of_match_device(xway_match, &pdev->dev);
+	if (match)
+		xway_soc = (const struct pinctrl_xway_soc *) match->data;
+	else
+		xway_soc = &soc_cfg[0];
+
+	/* find out how many pads we have */
+	xway_chip.ngpio = xway_soc->pin_count;
+
+	/* load our pad descriptors */
+	xway_info.pads = devm_kzalloc(&pdev->dev,
+			sizeof(struct pinctrl_pin_desc) * xway_chip.ngpio,
+			GFP_KERNEL);
+	if (!xway_info.pads) {
+		dev_err(&pdev->dev, "Failed to allocate pads\n");
+		return -ENOMEM;
+	}
+	for (i = 0; i < xway_chip.ngpio; i++) {
+		/* strlen("ioXY") + 1 = 5 */
+		char *name = devm_kzalloc(&pdev->dev, 5, GFP_KERNEL);
+
+		if (!name) {
+			dev_err(&pdev->dev, "Failed to allocate pad name\n");
+			return -ENOMEM;
+		}
+		snprintf(name, 5, "io%d", i);
+		xway_info.pads[i].number = GPIO0 + i;
+		xway_info.pads[i].name = name;
+	}
+	xway_pctrl_desc.pins = xway_info.pads;
+
+	/* load the gpio chip */
+	xway_chip.dev = &pdev->dev;
+	of_gpiochip_add(&xway_chip);
+	ret = gpiochip_add(&xway_chip);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to register gpio chip\n");
+		return ret;
+	}
+
+	/* setup the data needed by pinctrl */
+	xway_pctrl_desc.name	= dev_name(&pdev->dev);
+	xway_pctrl_desc.npins	= xway_chip.ngpio;
+
+	xway_info.num_pads	= xway_chip.ngpio;
+	xway_info.num_mfp	= xway_chip.ngpio;
+	xway_info.mfp		= xway_soc->mfp;
+	xway_info.grps		= xway_soc->grps;
+	xway_info.num_grps	= xway_soc->num_grps;
+	xway_info.funcs		= xway_soc->funcs;
+	xway_info.num_funcs	= xway_soc->num_funcs;
+	xway_info.exin		= xway_soc->exin;
+	xway_info.num_exin	= xway_soc->num_exin;
+
+	/* register with the generic lantiq layer */
+	ret = ltq_pinctrl_register(pdev, &xway_info);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to register pinctrl driver\n");
+		return ret;
+	}
+
+	/* finish with registering the gpio range in pinctrl */
+	xway_gpio_range.npins = xway_chip.ngpio;
+	xway_gpio_range.base = xway_chip.base;
+	pinctrl_add_gpio_range(xway_info.pctrl, &xway_gpio_range);
+	dev_info(&pdev->dev, "Init done\n");
+	return 0;
+}
+
+static struct platform_driver pinmux_xway_driver = {
+	.probe	= pinmux_xway_probe,
+	.driver = {
+		.name	= "pinctrl-xway",
+		.owner	= THIS_MODULE,
+		.of_match_table = xway_match,
+	},
+};
+
+static int __init pinmux_xway_init(void)
+{
+	return platform_driver_register(&pinmux_xway_driver);
+}
+
+core_initcall_sync(pinmux_xway_init);
diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c
index 6b9af98..18d74f2 100644
--- a/drivers/platform/x86/hp_accel.c
+++ b/drivers/platform/x86/hp_accel.c
@@ -382,31 +382,8 @@
 	},
 	.drv.pm = HP_ACCEL_PM,
 };
-
-static int __init lis3lv02d_init_module(void)
-{
-	int ret;
-
-	if (acpi_disabled)
-		return -ENODEV;
-
-	ret = acpi_bus_register_driver(&lis3lv02d_driver);
-	if (ret < 0)
-		return ret;
-
-	pr_info("driver loaded\n");
-
-	return 0;
-}
-
-static void __exit lis3lv02d_exit_module(void)
-{
-	acpi_bus_unregister_driver(&lis3lv02d_driver);
-}
+module_acpi_driver(lis3lv02d_driver);
 
 MODULE_DESCRIPTION("Glue between LIS3LV02Dx and HP ACPI BIOS and support for disk protection LED.");
 MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek");
 MODULE_LICENSE("GPL");
-
-module_init(lis3lv02d_init_module);
-module_exit(lis3lv02d_exit_module);
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
index dae7abe..5ff4f2e 100644
--- a/drivers/platform/x86/ideapad-laptop.c
+++ b/drivers/platform/x86/ideapad-laptop.c
@@ -917,20 +917,8 @@
 	.drv.pm = &ideapad_pm,
 	.owner = THIS_MODULE,
 };
-
-static int __init ideapad_acpi_module_init(void)
-{
-	return acpi_bus_register_driver(&ideapad_acpi_driver);
-}
-
-static void __exit ideapad_acpi_module_exit(void)
-{
-	acpi_bus_unregister_driver(&ideapad_acpi_driver);
-}
+module_acpi_driver(ideapad_acpi_driver);
 
 MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
 MODULE_DESCRIPTION("IdeaPad ACPI Extras");
 MODULE_LICENSE("GPL");
-
-module_init(ideapad_acpi_module_init);
-module_exit(ideapad_acpi_module_exit);
diff --git a/drivers/platform/x86/topstar-laptop.c b/drivers/platform/x86/topstar-laptop.c
index d528daa..d727bfe 100644
--- a/drivers/platform/x86/topstar-laptop.c
+++ b/drivers/platform/x86/topstar-laptop.c
@@ -186,27 +186,7 @@
 		.notify = acpi_topstar_notify,
 	},
 };
-
-static int __init topstar_laptop_init(void)
-{
-	int ret;
-
-	ret = acpi_bus_register_driver(&acpi_topstar_driver);
-	if (ret < 0)
-		return ret;
-
-	pr_info("ACPI extras driver loaded\n");
-
-	return 0;
-}
-
-static void __exit topstar_laptop_exit(void)
-{
-	acpi_bus_unregister_driver(&acpi_topstar_driver);
-}
-
-module_init(topstar_laptop_init);
-module_exit(topstar_laptop_exit);
+module_acpi_driver(acpi_topstar_driver);
 
 MODULE_AUTHOR("Herton Ronaldo Krzesinski");
 MODULE_DESCRIPTION("Topstar Laptop ACPI Extras driver");
diff --git a/drivers/platform/x86/toshiba_bluetooth.c b/drivers/platform/x86/toshiba_bluetooth.c
index 5e5d631..e95be0b 100644
--- a/drivers/platform/x86/toshiba_bluetooth.c
+++ b/drivers/platform/x86/toshiba_bluetooth.c
@@ -122,30 +122,10 @@
 	return result;
 }
 
-static int __init toshiba_bt_rfkill_init(void)
-{
-	int result;
-
-	result = acpi_bus_register_driver(&toshiba_bt_rfkill_driver);
-	if (result < 0) {
-		ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-				  "Error registering driver\n"));
-		return result;
-	}
-
-	return 0;
-}
-
 static int toshiba_bt_rfkill_remove(struct acpi_device *device, int type)
 {
 	/* clean up */
 	return 0;
 }
 
-static void __exit toshiba_bt_rfkill_exit(void)
-{
-	acpi_bus_unregister_driver(&toshiba_bt_rfkill_driver);
-}
-
-module_init(toshiba_bt_rfkill_init);
-module_exit(toshiba_bt_rfkill_exit);
+module_acpi_driver(toshiba_bt_rfkill_driver);
diff --git a/drivers/platform/x86/xo15-ebook.c b/drivers/platform/x86/xo15-ebook.c
index 38ba39d..16d340c 100644
--- a/drivers/platform/x86/xo15-ebook.c
+++ b/drivers/platform/x86/xo15-ebook.c
@@ -170,16 +170,4 @@
 	},
 	.drv.pm = &ebook_switch_pm,
 };
-
-static int __init xo15_ebook_init(void)
-{
-	return acpi_bus_register_driver(&xo15_ebook_driver);
-}
-
-static void __exit xo15_ebook_exit(void)
-{
-	acpi_bus_unregister_driver(&xo15_ebook_driver);
-}
-
-module_init(xo15_ebook_init);
-module_exit(xo15_ebook_exit);
+module_acpi_driver(xo15_ebook_driver);
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index 507a8e2..26b5d4b 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -321,14 +321,9 @@
 {
 	struct acpi_device *acpi = to_acpi_device(dev);
 	struct pnp_dev *pnp = _pnp;
-	struct device *physical_device;
-
-	physical_device = acpi_get_physical_device(acpi->handle);
-	if (physical_device)
-		put_device(physical_device);
 
 	/* true means it matched */
-	return !physical_device
+	return !acpi->physical_node_count
 	    && compare_pnp_id(pnp->id, acpi_device_hid(acpi));
 }
 
diff --git a/drivers/power/avs/smartreflex.c b/drivers/power/avs/smartreflex.c
index d4957b4..24768a2 100644
--- a/drivers/power/avs/smartreflex.c
+++ b/drivers/power/avs/smartreflex.c
@@ -930,7 +930,7 @@
 	if (!sr_info->base) {
 		dev_err(&pdev->dev, "%s: ioremap fail\n", __func__);
 		ret = -ENOMEM;
-		goto err_release_region;
+		goto err_free_name;
 	}
 
 	if (irq)
@@ -969,7 +969,7 @@
 		dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n",
 			__func__);
 		ret = PTR_ERR(sr_info->dbg_dir);
-		goto err_free_name;
+		goto err_debugfs;
 	}
 
 	(void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR,
@@ -1013,11 +1013,11 @@
 
 err_debugfs:
 	debugfs_remove_recursive(sr_info->dbg_dir);
-err_free_name:
-	kfree(sr_info->name);
 err_iounmap:
 	list_del(&sr_info->node);
 	iounmap(sr_info->base);
+err_free_name:
+	kfree(sr_info->name);
 err_release_region:
 	release_mem_region(mem->start, resource_size(mem));
 err_free_devinfo:
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index d7c6b83..ed81720 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -1,6 +1,5 @@
 menuconfig PWM
 	bool "Pulse-Width Modulation (PWM) Support"
-	depends on !MACH_JZ4740 && !PUV3_PWM
 	help
 	  Generic Pulse-Width Modulation (PWM) support.
 
@@ -29,6 +28,15 @@
 
 if PWM
 
+config PWM_AB8500
+	tristate "AB8500 PWM support"
+	depends on AB8500_CORE && ARCH_U8500
+	help
+	  Generic PWM framework driver for Analog Baseband AB8500.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called pwm-ab8500.
+
 config PWM_BFIN
 	tristate "Blackfin PWM support"
 	depends on BFIN_GPTIMERS
@@ -47,6 +55,16 @@
 	  To compile this driver as a module, choose M here: the module
 	  will be called pwm-imx.
 
+config PWM_JZ4740
+	tristate "Ingenic JZ4740 PWM support"
+	depends on MACH_JZ4740
+	help
+	  Generic PWM framework driver for Ingenic JZ4740 based
+	  machines.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called pwm-jz4740.
+
 config PWM_LPC32XX
 	tristate "LPC32XX PWM support"
 	depends on ARCH_LPC32XX
@@ -67,6 +85,15 @@
 	  To compile this driver as a module, choose M here: the module
 	  will be called pwm-mxs.
 
+config PWM_PUV3
+	tristate "PKUnity NetBook-0916 PWM support"
+	depends on ARCH_PUV3
+	help
+	  Generic PWM framework driver for PKUnity NetBook-0916.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called pwm-puv3.
+
 config PWM_PXA
 	tristate "PXA PWM support"
 	depends on ARCH_PXA
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 78f123d..acfe482 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -1,8 +1,11 @@
 obj-$(CONFIG_PWM)		+= core.o
+obj-$(CONFIG_PWM_AB8500)	+= pwm-ab8500.o
 obj-$(CONFIG_PWM_BFIN)		+= pwm-bfin.o
 obj-$(CONFIG_PWM_IMX)		+= pwm-imx.o
+obj-$(CONFIG_PWM_JZ4740)	+= pwm-jz4740.o
 obj-$(CONFIG_PWM_LPC32XX)	+= pwm-lpc32xx.o
 obj-$(CONFIG_PWM_MXS)		+= pwm-mxs.o
+obj-$(CONFIG_PWM_PUV3)		+= pwm-puv3.o
 obj-$(CONFIG_PWM_PXA)		+= pwm-pxa.o
 obj-$(CONFIG_PWM_SAMSUNG)	+= pwm-samsung.o
 obj-$(CONFIG_PWM_TEGRA)		+= pwm-tegra.o
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index c6e0507..f5acdaa 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -371,7 +371,7 @@
  */
 int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
 {
-	if (!pwm || period_ns == 0 || duty_ns > period_ns)
+	if (!pwm || duty_ns < 0 || period_ns <= 0 || duty_ns > period_ns)
 		return -EINVAL;
 
 	return pwm->chip->ops->config(pwm->chip, pwm, duty_ns, period_ns);
@@ -379,6 +379,28 @@
 EXPORT_SYMBOL_GPL(pwm_config);
 
 /**
+ * pwm_set_polarity() - configure the polarity of a PWM signal
+ * @pwm: PWM device
+ * @polarity: new polarity of the PWM signal
+ *
+ * Note that the polarity cannot be configured while the PWM device is enabled
+ */
+int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity)
+{
+	if (!pwm || !pwm->chip->ops)
+		return -EINVAL;
+
+	if (!pwm->chip->ops->set_polarity)
+		return -ENOSYS;
+
+	if (test_bit(PWMF_ENABLED, &pwm->flags))
+		return -EBUSY;
+
+	return pwm->chip->ops->set_polarity(pwm->chip, pwm, polarity);
+}
+EXPORT_SYMBOL_GPL(pwm_set_polarity);
+
+/**
  * pwm_enable() - start a PWM output toggling
  * @pwm: PWM device
  */
@@ -624,6 +646,64 @@
 }
 EXPORT_SYMBOL_GPL(pwm_put);
 
+static void devm_pwm_release(struct device *dev, void *res)
+{
+	pwm_put(*(struct pwm_device **)res);
+}
+
+/**
+ * devm_pwm_get() - resource managed pwm_get()
+ * @dev: device for PWM consumer
+ * @con_id: consumer name
+ *
+ * This function performs like pwm_get() but the acquired PWM device will
+ * automatically be released on driver detach.
+ */
+struct pwm_device *devm_pwm_get(struct device *dev, const char *con_id)
+{
+	struct pwm_device **ptr, *pwm;
+
+	ptr = devres_alloc(devm_pwm_release, sizeof(**ptr), GFP_KERNEL);
+	if (!ptr)
+		return ERR_PTR(-ENOMEM);
+
+	pwm = pwm_get(dev, con_id);
+	if (!IS_ERR(pwm)) {
+		*ptr = pwm;
+		devres_add(dev, ptr);
+	} else {
+		devres_free(ptr);
+	}
+
+	return pwm;
+}
+EXPORT_SYMBOL_GPL(devm_pwm_get);
+
+static int devm_pwm_match(struct device *dev, void *res, void *data)
+{
+	struct pwm_device **p = res;
+
+	if (WARN_ON(!p || !*p))
+		return 0;
+
+	return *p == data;
+}
+
+/**
+ * devm_pwm_put() - resource managed pwm_put()
+ * @dev: device for PWM consumer
+ * @pwm: PWM device
+ *
+ * Release a PWM previously allocated using devm_pwm_get(). Calling this
+ * function is usually not needed because devm-allocated resources are
+ * automatically released on driver detach.
+ */
+void devm_pwm_put(struct device *dev, struct pwm_device *pwm)
+{
+	WARN_ON(devres_release(dev, devm_pwm_release, devm_pwm_match, pwm));
+}
+EXPORT_SYMBOL_GPL(devm_pwm_put);
+
 #ifdef CONFIG_DEBUG_FS
 static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s)
 {
diff --git a/drivers/pwm/pwm-ab8500.c b/drivers/pwm/pwm-ab8500.c
new file mode 100644
index 0000000..cfb72ca
--- /dev/null
+++ b/drivers/pwm/pwm-ab8500.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Arun R Murthy <arun.murthy@stericsson.com>
+ * License terms: GNU General Public License (GPL) version 2
+ */
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/pwm.h>
+#include <linux/mfd/abx500.h>
+#include <linux/mfd/abx500/ab8500.h>
+#include <linux/module.h>
+
+/*
+ * PWM Out generators
+ * Bank: 0x10
+ */
+#define AB8500_PWM_OUT_CTRL1_REG	0x60
+#define AB8500_PWM_OUT_CTRL2_REG	0x61
+#define AB8500_PWM_OUT_CTRL7_REG	0x66
+
+/* backlight driver constants */
+#define ENABLE_PWM			1
+#define DISABLE_PWM			0
+
+struct ab8500_pwm_chip {
+	struct pwm_chip chip;
+};
+
+static int ab8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+			     int duty_ns, int period_ns)
+{
+	int ret = 0;
+	unsigned int higher_val, lower_val;
+	u8 reg;
+
+	/*
+	 * get the first 8 bits that are be written to
+	 * AB8500_PWM_OUT_CTRL1_REG[0:7]
+	 */
+	lower_val = duty_ns & 0x00FF;
+	/*
+	 * get bits [9:10] that are to be written to
+	 * AB8500_PWM_OUT_CTRL2_REG[0:1]
+	 */
+	higher_val = ((duty_ns & 0x0300) >> 8);
+
+	reg = AB8500_PWM_OUT_CTRL1_REG + ((chip->base - 1) * 2);
+
+	ret = abx500_set_register_interruptible(chip->dev, AB8500_MISC,
+			reg, (u8)lower_val);
+	if (ret < 0)
+		return ret;
+	ret = abx500_set_register_interruptible(chip->dev, AB8500_MISC,
+			(reg + 1), (u8)higher_val);
+
+	return ret;
+}
+
+static int ab8500_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	int ret;
+
+	ret = abx500_mask_and_set_register_interruptible(chip->dev,
+				AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG,
+				1 << (chip->base - 1), ENABLE_PWM);
+	if (ret < 0)
+		dev_err(chip->dev, "%s: Failed to disable PWM, Error %d\n",
+							pwm->label, ret);
+	return ret;
+}
+
+static void ab8500_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	int ret;
+
+	ret = abx500_mask_and_set_register_interruptible(chip->dev,
+				AB8500_MISC, AB8500_PWM_OUT_CTRL7_REG,
+				1 << (chip->base - 1), DISABLE_PWM);
+	if (ret < 0)
+		dev_err(chip->dev, "%s: Failed to disable PWM, Error %d\n",
+							pwm->label, ret);
+	return;
+}
+
+static const struct pwm_ops ab8500_pwm_ops = {
+	.config = ab8500_pwm_config,
+	.enable = ab8500_pwm_enable,
+	.disable = ab8500_pwm_disable,
+};
+
+static int __devinit ab8500_pwm_probe(struct platform_device *pdev)
+{
+	struct ab8500_pwm_chip *ab8500;
+	int err;
+
+	/*
+	 * Nothing to be done in probe, this is required to get the
+	 * device which is required for ab8500 read and write
+	 */
+	ab8500 = kzalloc(sizeof(*ab8500), GFP_KERNEL);
+	if (ab8500 == NULL) {
+		dev_err(&pdev->dev, "failed to allocate memory\n");
+		return -ENOMEM;
+	}
+
+	ab8500->chip.dev = &pdev->dev;
+	ab8500->chip.ops = &ab8500_pwm_ops;
+	ab8500->chip.base = pdev->id;
+	ab8500->chip.npwm = 1;
+
+	err = pwmchip_add(&ab8500->chip);
+	if (err < 0) {
+		kfree(ab8500);
+		return err;
+	}
+
+	dev_dbg(&pdev->dev, "pwm probe successful\n");
+	platform_set_drvdata(pdev, ab8500);
+
+	return 0;
+}
+
+static int __devexit ab8500_pwm_remove(struct platform_device *pdev)
+{
+	struct ab8500_pwm_chip *ab8500 = platform_get_drvdata(pdev);
+	int err;
+
+	err = pwmchip_remove(&ab8500->chip);
+	if (err < 0)
+		return err;
+
+	dev_dbg(&pdev->dev, "pwm driver removed\n");
+	kfree(ab8500);
+
+	return 0;
+}
+
+static struct platform_driver ab8500_pwm_driver = {
+	.driver = {
+		.name = "ab8500-pwm",
+		.owner = THIS_MODULE,
+	},
+	.probe = ab8500_pwm_probe,
+	.remove = __devexit_p(ab8500_pwm_remove),
+};
+module_platform_driver(ab8500_pwm_driver);
+
+MODULE_AUTHOR("Arun MURTHY <arun.murthy@stericsson.com>");
+MODULE_DESCRIPTION("AB8500 Pulse Width Modulation Driver");
+MODULE_ALIAS("platform:ab8500-pwm");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pwm/pwm-bfin.c b/drivers/pwm/pwm-bfin.c
index d53c4e7..5da8e18 100644
--- a/drivers/pwm/pwm-bfin.c
+++ b/drivers/pwm/pwm-bfin.c
@@ -69,9 +69,6 @@
 	unsigned long period, duty;
 	unsigned long long val;
 
-	if (duty_ns < 0 || duty_ns > period_ns)
-		return -EINVAL;
-
 	val = (unsigned long long)get_sclk() * period_ns;
 	do_div(val, NSEC_PER_SEC);
 	period = val;
diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c
index 2a0b353..8a5d3ae 100644
--- a/drivers/pwm/pwm-imx.c
+++ b/drivers/pwm/pwm-imx.c
@@ -16,8 +16,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/pwm.h>
-#include <mach/hardware.h>
-
+#include <linux/of_device.h>
 
 /* i.MX1 and i.MX21 share the same PWM function block: */
 
@@ -25,6 +24,7 @@
 #define MX1_PWMS    0x04   /* PWM Sample Register */
 #define MX1_PWMP    0x08   /* PWM Period Register */
 
+#define MX1_PWMC_EN		(1 << 4)
 
 /* i.MX27, i.MX31, i.MX35 share the same PWM function block: */
 
@@ -40,110 +40,165 @@
 #define MX3_PWMCR_EN              (1 << 0)
 
 struct imx_chip {
-	struct clk	*clk;
+	struct clk	*clk_per;
+	struct clk	*clk_ipg;
 
-	int		clk_enabled;
+	int		enabled;
 	void __iomem	*mmio_base;
 
 	struct pwm_chip	chip;
+
+	int (*config)(struct pwm_chip *chip,
+		struct pwm_device *pwm, int duty_ns, int period_ns);
+	void (*set_enable)(struct pwm_chip *chip, bool enable);
 };
 
 #define to_imx_chip(chip)	container_of(chip, struct imx_chip, chip)
 
+static int imx_pwm_config_v1(struct pwm_chip *chip,
+		struct pwm_device *pwm, int duty_ns, int period_ns)
+{
+	struct imx_chip *imx = to_imx_chip(chip);
+
+	/*
+	 * The PWM subsystem allows for exact frequencies. However,
+	 * I cannot connect a scope on my device to the PWM line and
+	 * thus cannot provide the program the PWM controller
+	 * exactly. Instead, I'm relying on the fact that the
+	 * Bootloader (u-boot or WinCE+haret) has programmed the PWM
+	 * function group already. So I'll just modify the PWM sample
+	 * register to follow the ratio of duty_ns vs. period_ns
+	 * accordingly.
+	 *
+	 * This is good enough for programming the brightness of
+	 * the LCD backlight.
+	 *
+	 * The real implementation would divide PERCLK[0] first by
+	 * both the prescaler (/1 .. /128) and then by CLKSEL
+	 * (/2 .. /16).
+	 */
+	u32 max = readl(imx->mmio_base + MX1_PWMP);
+	u32 p = max * duty_ns / period_ns;
+	writel(max - p, imx->mmio_base + MX1_PWMS);
+
+	return 0;
+}
+
+static void imx_pwm_set_enable_v1(struct pwm_chip *chip, bool enable)
+{
+	struct imx_chip *imx = to_imx_chip(chip);
+	u32 val;
+
+	val = readl(imx->mmio_base + MX1_PWMC);
+
+	if (enable)
+		val |= MX1_PWMC_EN;
+	else
+		val &= ~MX1_PWMC_EN;
+
+	writel(val, imx->mmio_base + MX1_PWMC);
+}
+
+static int imx_pwm_config_v2(struct pwm_chip *chip,
+		struct pwm_device *pwm, int duty_ns, int period_ns)
+{
+	struct imx_chip *imx = to_imx_chip(chip);
+	unsigned long long c;
+	unsigned long period_cycles, duty_cycles, prescale;
+	u32 cr;
+
+	c = clk_get_rate(imx->clk_per);
+	c = c * period_ns;
+	do_div(c, 1000000000);
+	period_cycles = c;
+
+	prescale = period_cycles / 0x10000 + 1;
+
+	period_cycles /= prescale;
+	c = (unsigned long long)period_cycles * duty_ns;
+	do_div(c, period_ns);
+	duty_cycles = c;
+
+	/*
+	 * according to imx pwm RM, the real period value should be
+	 * PERIOD value in PWMPR plus 2.
+	 */
+	if (period_cycles > 2)
+		period_cycles -= 2;
+	else
+		period_cycles = 0;
+
+	writel(duty_cycles, imx->mmio_base + MX3_PWMSAR);
+	writel(period_cycles, imx->mmio_base + MX3_PWMPR);
+
+	cr = MX3_PWMCR_PRESCALER(prescale) |
+		MX3_PWMCR_DOZEEN | MX3_PWMCR_WAITEN |
+		MX3_PWMCR_DBGEN | MX3_PWMCR_CLKSRC_IPG_HIGH;
+
+	if (imx->enabled)
+		cr |= MX3_PWMCR_EN;
+
+	writel(cr, imx->mmio_base + MX3_PWMCR);
+
+	return 0;
+}
+
+static void imx_pwm_set_enable_v2(struct pwm_chip *chip, bool enable)
+{
+	struct imx_chip *imx = to_imx_chip(chip);
+	u32 val;
+
+	val = readl(imx->mmio_base + MX3_PWMCR);
+
+	if (enable)
+		val |= MX3_PWMCR_EN;
+	else
+		val &= ~MX3_PWMCR_EN;
+
+	writel(val, imx->mmio_base + MX3_PWMCR);
+}
+
 static int imx_pwm_config(struct pwm_chip *chip,
 		struct pwm_device *pwm, int duty_ns, int period_ns)
 {
 	struct imx_chip *imx = to_imx_chip(chip);
+	int ret;
 
-	if (!(cpu_is_mx1() || cpu_is_mx21())) {
-		unsigned long long c;
-		unsigned long period_cycles, duty_cycles, prescale;
-		u32 cr;
+	ret = clk_prepare_enable(imx->clk_ipg);
+	if (ret)
+		return ret;
 
-		c = clk_get_rate(imx->clk);
-		c = c * period_ns;
-		do_div(c, 1000000000);
-		period_cycles = c;
+	ret = imx->config(chip, pwm, duty_ns, period_ns);
 
-		prescale = period_cycles / 0x10000 + 1;
+	clk_disable_unprepare(imx->clk_ipg);
 
-		period_cycles /= prescale;
-		c = (unsigned long long)period_cycles * duty_ns;
-		do_div(c, period_ns);
-		duty_cycles = c;
-
-		/*
-		 * according to imx pwm RM, the real period value should be
-		 * PERIOD value in PWMPR plus 2.
-		 */
-		if (period_cycles > 2)
-			period_cycles -= 2;
-		else
-			period_cycles = 0;
-
-		writel(duty_cycles, imx->mmio_base + MX3_PWMSAR);
-		writel(period_cycles, imx->mmio_base + MX3_PWMPR);
-
-		cr = MX3_PWMCR_PRESCALER(prescale) |
-			MX3_PWMCR_DOZEEN | MX3_PWMCR_WAITEN |
-			MX3_PWMCR_DBGEN | MX3_PWMCR_EN;
-
-		if (cpu_is_mx25())
-			cr |= MX3_PWMCR_CLKSRC_IPG;
-		else
-			cr |= MX3_PWMCR_CLKSRC_IPG_HIGH;
-
-		writel(cr, imx->mmio_base + MX3_PWMCR);
-	} else if (cpu_is_mx1() || cpu_is_mx21()) {
-		/* The PWM subsystem allows for exact frequencies. However,
-		 * I cannot connect a scope on my device to the PWM line and
-		 * thus cannot provide the program the PWM controller
-		 * exactly. Instead, I'm relying on the fact that the
-		 * Bootloader (u-boot or WinCE+haret) has programmed the PWM
-		 * function group already. So I'll just modify the PWM sample
-		 * register to follow the ratio of duty_ns vs. period_ns
-		 * accordingly.
-		 *
-		 * This is good enough for programming the brightness of
-		 * the LCD backlight.
-		 *
-		 * The real implementation would divide PERCLK[0] first by
-		 * both the prescaler (/1 .. /128) and then by CLKSEL
-		 * (/2 .. /16).
-		 */
-		u32 max = readl(imx->mmio_base + MX1_PWMP);
-		u32 p = max * duty_ns / period_ns;
-		writel(max - p, imx->mmio_base + MX1_PWMS);
-	} else {
-		BUG();
-	}
-
-	return 0;
+	return ret;
 }
 
 static int imx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
 	struct imx_chip *imx = to_imx_chip(chip);
-	int rc = 0;
+	int ret;
 
-	if (!imx->clk_enabled) {
-		rc = clk_prepare_enable(imx->clk);
-		if (!rc)
-			imx->clk_enabled = 1;
-	}
-	return rc;
+	ret = clk_prepare_enable(imx->clk_per);
+	if (ret)
+		return ret;
+
+	imx->set_enable(chip, true);
+
+	imx->enabled = 1;
+
+	return 0;
 }
 
 static void imx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
 	struct imx_chip *imx = to_imx_chip(chip);
 
-	writel(0, imx->mmio_base + MX3_PWMCR);
+	imx->set_enable(chip, false);
 
-	if (imx->clk_enabled) {
-		clk_disable_unprepare(imx->clk);
-		imx->clk_enabled = 0;
-	}
+	clk_disable_unprepare(imx->clk_per);
+	imx->enabled = 0;
 }
 
 static struct pwm_ops imx_pwm_ops = {
@@ -153,30 +208,66 @@
 	.owner = THIS_MODULE,
 };
 
+struct imx_pwm_data {
+	int (*config)(struct pwm_chip *chip,
+		struct pwm_device *pwm, int duty_ns, int period_ns);
+	void (*set_enable)(struct pwm_chip *chip, bool enable);
+};
+
+static struct imx_pwm_data imx_pwm_data_v1 = {
+	.config = imx_pwm_config_v1,
+	.set_enable = imx_pwm_set_enable_v1,
+};
+
+static struct imx_pwm_data imx_pwm_data_v2 = {
+	.config = imx_pwm_config_v2,
+	.set_enable = imx_pwm_set_enable_v2,
+};
+
+static const struct of_device_id imx_pwm_dt_ids[] = {
+	{ .compatible = "fsl,imx1-pwm", .data = &imx_pwm_data_v1, },
+	{ .compatible = "fsl,imx27-pwm", .data = &imx_pwm_data_v2, },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_pwm_dt_ids);
+
 static int __devinit imx_pwm_probe(struct platform_device *pdev)
 {
+	const struct of_device_id *of_id =
+			of_match_device(imx_pwm_dt_ids, &pdev->dev);
+	struct imx_pwm_data *data;
 	struct imx_chip *imx;
 	struct resource *r;
 	int ret = 0;
 
+	if (!of_id)
+		return -ENODEV;
+
 	imx = devm_kzalloc(&pdev->dev, sizeof(*imx), GFP_KERNEL);
 	if (imx == NULL) {
 		dev_err(&pdev->dev, "failed to allocate memory\n");
 		return -ENOMEM;
 	}
 
-	imx->clk = devm_clk_get(&pdev->dev, "pwm");
+	imx->clk_per = devm_clk_get(&pdev->dev, "per");
+	if (IS_ERR(imx->clk_per)) {
+		dev_err(&pdev->dev, "getting per clock failed with %ld\n",
+				PTR_ERR(imx->clk_per));
+		return PTR_ERR(imx->clk_per);
+	}
 
-	if (IS_ERR(imx->clk))
-		return PTR_ERR(imx->clk);
+	imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
+	if (IS_ERR(imx->clk_ipg)) {
+		dev_err(&pdev->dev, "getting ipg clock failed with %ld\n",
+				PTR_ERR(imx->clk_ipg));
+		return PTR_ERR(imx->clk_ipg);
+	}
 
 	imx->chip.ops = &imx_pwm_ops;
 	imx->chip.dev = &pdev->dev;
 	imx->chip.base = -1;
 	imx->chip.npwm = 1;
 
-	imx->clk_enabled = 0;
-
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (r == NULL) {
 		dev_err(&pdev->dev, "no memory resource defined\n");
@@ -187,6 +278,10 @@
 	if (imx->mmio_base == NULL)
 		return -EADDRNOTAVAIL;
 
+	data = of_id->data;
+	imx->config = data->config;
+	imx->set_enable = data->set_enable;
+
 	ret = pwmchip_add(&imx->chip);
 	if (ret < 0)
 		return ret;
@@ -208,23 +303,14 @@
 
 static struct platform_driver imx_pwm_driver = {
 	.driver		= {
-		.name	= "mxc_pwm",
+		.name	= "imx-pwm",
+		.of_match_table = of_match_ptr(imx_pwm_dt_ids),
 	},
 	.probe		= imx_pwm_probe,
 	.remove		= __devexit_p(imx_pwm_remove),
 };
 
-static int __init imx_pwm_init(void)
-{
-	return platform_driver_register(&imx_pwm_driver);
-}
-arch_initcall(imx_pwm_init);
-
-static void __exit imx_pwm_exit(void)
-{
-	platform_driver_unregister(&imx_pwm_driver);
-}
-module_exit(imx_pwm_exit);
+module_platform_driver(imx_pwm_driver);
 
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
diff --git a/drivers/pwm/pwm-jz4740.c b/drivers/pwm/pwm-jz4740.c
new file mode 100644
index 0000000..10250fc
--- /dev/null
+++ b/drivers/pwm/pwm-jz4740.c
@@ -0,0 +1,221 @@
+/*
+ *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 platform PWM support
+ *
+ *  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.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+
+#include <asm/mach-jz4740/gpio.h>
+#include <asm/mach-jz4740/timer.h>
+
+#define NUM_PWM 8
+
+static const unsigned int jz4740_pwm_gpio_list[NUM_PWM] = {
+	JZ_GPIO_PWM0,
+	JZ_GPIO_PWM1,
+	JZ_GPIO_PWM2,
+	JZ_GPIO_PWM3,
+	JZ_GPIO_PWM4,
+	JZ_GPIO_PWM5,
+	JZ_GPIO_PWM6,
+	JZ_GPIO_PWM7,
+};
+
+struct jz4740_pwm_chip {
+	struct pwm_chip chip;
+	struct clk *clk;
+};
+
+static inline struct jz4740_pwm_chip *to_jz4740(struct pwm_chip *chip)
+{
+	return container_of(chip, struct jz4740_pwm_chip, chip);
+}
+
+static int jz4740_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	unsigned int gpio = jz4740_pwm_gpio_list[pwm->hwpwm];
+	int ret;
+
+	/*
+	 * Timers 0 and 1 are used for system tasks, so they are unavailable
+	 * for use as PWMs.
+	 */
+	if (pwm->hwpwm < 2)
+		return -EBUSY;
+
+	ret = gpio_request(gpio, pwm->label);
+	if (ret) {
+		dev_err(chip->dev, "Failed to request GPIO#%u for PWM: %d\n",
+			gpio, ret);
+		return ret;
+	}
+
+	jz_gpio_set_function(gpio, JZ_GPIO_FUNC_PWM);
+
+	jz4740_timer_start(pwm->hwpwm);
+
+	return 0;
+}
+
+static void jz4740_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	unsigned int gpio = jz4740_pwm_gpio_list[pwm->hwpwm];
+
+	jz4740_timer_set_ctrl(pwm->hwpwm, 0);
+
+	jz_gpio_set_function(gpio, JZ_GPIO_FUNC_NONE);
+	gpio_free(gpio);
+
+	jz4740_timer_stop(pwm->hwpwm);
+}
+
+static int jz4740_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	uint32_t ctrl = jz4740_timer_get_ctrl(pwm->pwm);
+
+	ctrl |= JZ_TIMER_CTRL_PWM_ENABLE;
+	jz4740_timer_set_ctrl(pwm->hwpwm, ctrl);
+	jz4740_timer_enable(pwm->hwpwm);
+
+	return 0;
+}
+
+static void jz4740_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	uint32_t ctrl = jz4740_timer_get_ctrl(pwm->hwpwm);
+
+	ctrl &= ~JZ_TIMER_CTRL_PWM_ENABLE;
+	jz4740_timer_disable(pwm->hwpwm);
+	jz4740_timer_set_ctrl(pwm->hwpwm, ctrl);
+}
+
+static int jz4740_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+			     int duty_ns, int period_ns)
+{
+	struct jz4740_pwm_chip *jz4740 = to_jz4740(pwm->chip);
+	unsigned long long tmp;
+	unsigned long period, duty;
+	unsigned int prescaler = 0;
+	uint16_t ctrl;
+	bool is_enabled;
+
+	tmp = (unsigned long long)clk_get_rate(jz4740->clk) * period_ns;
+	do_div(tmp, 1000000000);
+	period = tmp;
+
+	while (period > 0xffff && prescaler < 6) {
+		period >>= 2;
+		++prescaler;
+	}
+
+	if (prescaler == 6)
+		return -EINVAL;
+
+	tmp = (unsigned long long)period * duty_ns;
+	do_div(tmp, period_ns);
+	duty = period - tmp;
+
+	if (duty >= period)
+		duty = period - 1;
+
+	is_enabled = jz4740_timer_is_enabled(pwm->hwpwm);
+	if (is_enabled)
+		jz4740_pwm_disable(chip, pwm);
+
+	jz4740_timer_set_count(pwm->hwpwm, 0);
+	jz4740_timer_set_duty(pwm->hwpwm, duty);
+	jz4740_timer_set_period(pwm->hwpwm, period);
+
+	ctrl = JZ_TIMER_CTRL_PRESCALER(prescaler) | JZ_TIMER_CTRL_SRC_EXT |
+		JZ_TIMER_CTRL_PWM_ABBRUPT_SHUTDOWN;
+
+	jz4740_timer_set_ctrl(pwm->hwpwm, ctrl);
+
+	if (is_enabled)
+		jz4740_pwm_enable(chip, pwm);
+
+	return 0;
+}
+
+static const struct pwm_ops jz4740_pwm_ops = {
+	.request = jz4740_pwm_request,
+	.free = jz4740_pwm_free,
+	.config = jz4740_pwm_config,
+	.enable = jz4740_pwm_enable,
+	.disable = jz4740_pwm_disable,
+	.owner = THIS_MODULE,
+};
+
+static int __devinit jz4740_pwm_probe(struct platform_device *pdev)
+{
+	struct jz4740_pwm_chip *jz4740;
+	int ret;
+
+	jz4740 = devm_kzalloc(&pdev->dev, sizeof(*jz4740), GFP_KERNEL);
+	if (!jz4740)
+		return -ENOMEM;
+
+	jz4740->clk = clk_get(NULL, "ext");
+	if (IS_ERR(jz4740->clk))
+		return PTR_ERR(jz4740->clk);
+
+	jz4740->chip.dev = &pdev->dev;
+	jz4740->chip.ops = &jz4740_pwm_ops;
+	jz4740->chip.npwm = NUM_PWM;
+	jz4740->chip.base = -1;
+
+	ret = pwmchip_add(&jz4740->chip);
+	if (ret < 0) {
+		clk_put(jz4740->clk);
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, jz4740);
+
+	return 0;
+}
+
+static int __devexit jz4740_pwm_remove(struct platform_device *pdev)
+{
+	struct jz4740_pwm_chip *jz4740 = platform_get_drvdata(pdev);
+	int ret;
+
+	ret = pwmchip_remove(&jz4740->chip);
+	if (ret < 0)
+		return ret;
+
+	clk_put(jz4740->clk);
+
+	return 0;
+}
+
+static struct platform_driver jz4740_pwm_driver = {
+	.driver = {
+		.name = "jz4740-pwm",
+		.owner = THIS_MODULE,
+	},
+	.probe = jz4740_pwm_probe,
+	.remove = __devexit_p(jz4740_pwm_remove),
+};
+module_platform_driver(jz4740_pwm_driver);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("Ingenic JZ4740 PWM driver");
+MODULE_ALIAS("platform:jz4740-pwm");
+MODULE_LICENSE("GPL");
diff --git a/drivers/pwm/pwm-puv3.c b/drivers/pwm/pwm-puv3.c
new file mode 100644
index 0000000..2a93f37
--- /dev/null
+++ b/drivers/pwm/pwm-puv3.c
@@ -0,0 +1,161 @@
+/*
+ * linux/arch/unicore32/kernel/pwm.c
+ *
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ *	Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
+ *	Copyright (C) 2001-2010 Guan Xuetao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/pwm.h>
+
+#include <asm/div64.h>
+#include <mach/hardware.h>
+
+struct puv3_pwm_chip {
+	struct pwm_chip chip;
+	void __iomem *base;
+	struct clk *clk;
+	bool enabled;
+};
+
+static inline struct puv3_pwm_chip *to_puv3(struct pwm_chip *chip)
+{
+	return container_of(chip, struct puv3_pwm_chip, chip);
+}
+
+/*
+ * period_ns = 10^9 * (PRESCALE + 1) * (PV + 1) / PWM_CLK_RATE
+ * duty_ns   = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE
+ */
+static int puv3_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+			   int duty_ns, int period_ns)
+{
+	unsigned long period_cycles, prescale, pv, dc;
+	struct puv3_pwm_chip *puv3 = to_puv3(chip);
+	unsigned long long c;
+
+	c = clk_get_rate(puv3->clk);
+	c = c * period_ns;
+	do_div(c, 1000000000);
+	period_cycles = c;
+
+	if (period_cycles < 1)
+		period_cycles = 1;
+
+	prescale = (period_cycles - 1) / 1024;
+	pv = period_cycles / (prescale + 1) - 1;
+
+	if (prescale > 63)
+		return -EINVAL;
+
+	if (duty_ns == period_ns)
+		dc = OST_PWMDCCR_FDCYCLE;
+	else
+		dc = (pv + 1) * duty_ns / period_ns;
+
+	/*
+	 * NOTE: the clock to PWM has to be enabled first
+	 * before writing to the registers
+	 */
+	clk_prepare_enable(puv3->clk);
+
+	writel(prescale, puv3->base + OST_PWM_PWCR);
+	writel(pv - dc, puv3->base + OST_PWM_DCCR);
+	writel(pv, puv3->base + OST_PWM_PCR);
+
+	clk_disable_unprepare(puv3->clk);
+
+	return 0;
+}
+
+static int puv3_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct puv3_pwm_chip *puv3 = to_puv3(chip);
+
+	return clk_prepare_enable(puv3->clk);
+}
+
+static void puv3_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	struct puv3_pwm_chip *puv3 = to_puv3(chip);
+
+	clk_disable_unprepare(puv3->clk);
+}
+
+static const struct pwm_ops puv3_pwm_ops = {
+	.config = puv3_pwm_config,
+	.enable = puv3_pwm_enable,
+	.disable = puv3_pwm_disable,
+	.owner = THIS_MODULE,
+};
+
+static int __devinit pwm_probe(struct platform_device *pdev)
+{
+	struct puv3_pwm_chip *puv3;
+	struct resource *r;
+	int ret;
+
+	puv3 = devm_kzalloc(&pdev->dev, sizeof(*puv3), GFP_KERNEL);
+	if (puv3 == NULL) {
+		dev_err(&pdev->dev, "failed to allocate memory\n");
+		return -ENOMEM;
+	}
+
+	puv3->clk = devm_clk_get(&pdev->dev, "OST_CLK");
+	if (IS_ERR(puv3->clk))
+		return PTR_ERR(puv3->clk);
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (r == NULL) {
+		dev_err(&pdev->dev, "no memory resource defined\n");
+		return -ENODEV;
+	}
+
+	puv3->base = devm_request_and_ioremap(&pdev->dev, r);
+	if (puv3->base == NULL)
+		return -EADDRNOTAVAIL;
+
+	puv3->chip.dev = &pdev->dev;
+	puv3->chip.ops = &puv3_pwm_ops;
+	puv3->chip.base = -1;
+	puv3->chip.npwm = 1;
+
+	ret = pwmchip_add(&puv3->chip);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, puv3);
+	return 0;
+}
+
+static int __devexit pwm_remove(struct platform_device *pdev)
+{
+	struct puv3_pwm_chip *puv3 = platform_get_drvdata(pdev);
+
+	return pwmchip_remove(&puv3->chip);
+}
+
+static struct platform_driver puv3_pwm_driver = {
+	.driver = {
+		.name = "PKUnity-v3-PWM",
+	},
+	.probe = pwm_probe,
+	.remove = __devexit_p(pwm_remove),
+};
+module_platform_driver(puv3_pwm_driver);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pwm/pwm-pxa.c b/drivers/pwm/pwm-pxa.c
index bd5867a..260c3a8 100644
--- a/drivers/pwm/pwm-pxa.c
+++ b/drivers/pwm/pwm-pxa.c
@@ -70,9 +70,6 @@
 	unsigned long offset;
 	int rc;
 
-	if (period_ns == 0 || duty_ns > period_ns)
-		return -EINVAL;
-
 	offset = pwm->hwpwm ? 0x10 : 0;
 
 	c = clk_get_rate(pc->clk);
diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c
index e5187c0..023a3be 100644
--- a/drivers/pwm/pwm-samsung.c
+++ b/drivers/pwm/pwm-samsung.c
@@ -126,9 +126,6 @@
 	if (period_ns > NS_IN_HZ || duty_ns > NS_IN_HZ)
 		return -ERANGE;
 
-	if (duty_ns > period_ns)
-		return -EINVAL;
-
 	if (period_ns == s3c->period_ns &&
 	    duty_ns == s3c->duty_ns)
 		return 0;
diff --git a/drivers/pwm/pwm-tiecap.c b/drivers/pwm/pwm-tiecap.c
index 4b66889..d6d4cf0 100644
--- a/drivers/pwm/pwm-tiecap.c
+++ b/drivers/pwm/pwm-tiecap.c
@@ -32,6 +32,7 @@
 #define CAP3			0x10
 #define CAP4			0x14
 #define ECCTL2			0x2A
+#define ECCTL2_APWM_POL_LOW	BIT(10)
 #define ECCTL2_APWM_MODE	BIT(9)
 #define ECCTL2_SYNC_SEL_DISA	(BIT(7) | BIT(6))
 #define ECCTL2_TSCTR_FREERUN	BIT(4)
@@ -59,7 +60,7 @@
 	unsigned long period_cycles, duty_cycles;
 	unsigned int reg_val;
 
-	if (period_ns < 0 || duty_ns < 0 || period_ns > NSEC_PER_SEC)
+	if (period_ns > NSEC_PER_SEC)
 		return -ERANGE;
 
 	c = pc->clk_rate;
@@ -111,6 +112,26 @@
 	return 0;
 }
 
+static int ecap_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
+		enum pwm_polarity polarity)
+{
+	struct ecap_pwm_chip *pc = to_ecap_pwm_chip(chip);
+	unsigned short reg_val;
+
+	pm_runtime_get_sync(pc->chip.dev);
+	reg_val = readw(pc->mmio_base + ECCTL2);
+	if (polarity == PWM_POLARITY_INVERSED)
+		/* Duty cycle defines LOW period of PWM */
+		reg_val |= ECCTL2_APWM_POL_LOW;
+	else
+		/* Duty cycle defines HIGH period of PWM */
+		reg_val &= ~ECCTL2_APWM_POL_LOW;
+
+	writew(reg_val, pc->mmio_base + ECCTL2);
+	pm_runtime_put_sync(pc->chip.dev);
+	return 0;
+}
+
 static int ecap_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
 	struct ecap_pwm_chip *pc = to_ecap_pwm_chip(chip);
@@ -157,6 +178,7 @@
 static const struct pwm_ops ecap_pwm_ops = {
 	.free		= ecap_pwm_free,
 	.config		= ecap_pwm_config,
+	.set_polarity	= ecap_pwm_set_polarity,
 	.enable		= ecap_pwm_enable,
 	.disable	= ecap_pwm_disable,
 	.owner		= THIS_MODULE,
diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c
index b1996bc..d3c1dff 100644
--- a/drivers/pwm/pwm-tiehrpwm.c
+++ b/drivers/pwm/pwm-tiehrpwm.c
@@ -81,6 +81,15 @@
 #define AQCTL_ZRO_FRCHIGH	BIT(1)
 #define AQCTL_ZRO_FRCTOGGLE	(BIT(1) | BIT(0))
 
+#define AQCTL_CHANA_POLNORMAL	(AQCTL_CAU_FRCLOW | AQCTL_PRD_FRCHIGH | \
+				AQCTL_ZRO_FRCHIGH)
+#define AQCTL_CHANA_POLINVERSED	(AQCTL_CAU_FRCHIGH | AQCTL_PRD_FRCLOW | \
+				AQCTL_ZRO_FRCLOW)
+#define AQCTL_CHANB_POLNORMAL	(AQCTL_CBU_FRCLOW | AQCTL_PRD_FRCHIGH | \
+				AQCTL_ZRO_FRCHIGH)
+#define AQCTL_CHANB_POLINVERSED	(AQCTL_CBU_FRCHIGH | AQCTL_PRD_FRCLOW | \
+				AQCTL_ZRO_FRCLOW)
+
 #define AQSFRC_RLDCSF_MASK	(BIT(7) | BIT(6))
 #define AQSFRC_RLDCSF_ZRO	0
 #define AQSFRC_RLDCSF_PRD	BIT(6)
@@ -105,6 +114,7 @@
 	unsigned int	clk_rate;
 	void __iomem	*mmio_base;
 	unsigned long period_cycles[NUM_PWM_CHANNEL];
+	enum pwm_polarity polarity[NUM_PWM_CHANNEL];
 };
 
 static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip)
@@ -165,39 +175,37 @@
 	return 1;
 }
 
-static void configure_chans(struct ehrpwm_pwm_chip *pc, int chan,
-		unsigned long duty_cycles)
+static void configure_polarity(struct ehrpwm_pwm_chip *pc, int chan)
 {
-	int cmp_reg, aqctl_reg;
+	int aqctl_reg;
 	unsigned short aqctl_val, aqctl_mask;
 
 	/*
-	 * Channels can be configured from action qualifier module.
-	 * Channel 0 configured with compare A register and for
-	 * up-counter mode.
-	 * Channel 1 configured with compare B register and for
-	 * up-counter mode.
+	 * Configure PWM output to HIGH/LOW level on counter
+	 * reaches compare register value and LOW/HIGH level
+	 * on counter value reaches period register value and
+	 * zero value on counter
 	 */
 	if (chan == 1) {
 		aqctl_reg = AQCTLB;
-		cmp_reg = CMPB;
-		/* Configure PWM Low from compare B value */
-		aqctl_val = AQCTL_CBU_FRCLOW;
 		aqctl_mask = AQCTL_CBU_MASK;
+
+		if (pc->polarity[chan] == PWM_POLARITY_INVERSED)
+			aqctl_val = AQCTL_CHANB_POLINVERSED;
+		else
+			aqctl_val = AQCTL_CHANB_POLNORMAL;
 	} else {
-		cmp_reg = CMPA;
 		aqctl_reg = AQCTLA;
-		/* Configure PWM Low from compare A value*/
-		aqctl_val = AQCTL_CAU_FRCLOW;
 		aqctl_mask = AQCTL_CAU_MASK;
+
+		if (pc->polarity[chan] == PWM_POLARITY_INVERSED)
+			aqctl_val = AQCTL_CHANA_POLINVERSED;
+		else
+			aqctl_val = AQCTL_CHANA_POLNORMAL;
 	}
 
-	/* Configure PWM High from period value and zero value */
-	aqctl_val |= AQCTL_PRD_FRCHIGH | AQCTL_ZRO_FRCHIGH;
 	aqctl_mask |= AQCTL_PRD_MASK | AQCTL_ZRO_MASK;
-	ehrpwm_modify(pc->mmio_base,  aqctl_reg, aqctl_mask, aqctl_val);
-
-	ehrpwm_write(pc->mmio_base,  cmp_reg, duty_cycles);
+	ehrpwm_modify(pc->mmio_base, aqctl_reg, aqctl_mask, aqctl_val);
 }
 
 /*
@@ -211,9 +219,9 @@
 	unsigned long long c;
 	unsigned long period_cycles, duty_cycles;
 	unsigned short ps_divval, tb_divval;
-	int i;
+	int i, cmp_reg;
 
-	if (period_ns < 0 || duty_ns < 0 || period_ns > NSEC_PER_SEC)
+	if (period_ns > NSEC_PER_SEC)
 		return -ERANGE;
 
 	c = pc->clk_rate;
@@ -278,12 +286,29 @@
 	ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_CTRMODE_MASK,
 			TBCTL_CTRMODE_UP);
 
-	/* Configure the channel for duty cycle */
-	configure_chans(pc, pwm->hwpwm, duty_cycles);
+	if (pwm->hwpwm == 1)
+		/* Channel 1 configured with compare B register */
+		cmp_reg = CMPB;
+	else
+		/* Channel 0 configured with compare A register */
+		cmp_reg = CMPA;
+
+	ehrpwm_write(pc->mmio_base, cmp_reg, duty_cycles);
+
 	pm_runtime_put_sync(chip->dev);
 	return 0;
 }
 
+static int ehrpwm_pwm_set_polarity(struct pwm_chip *chip,
+		struct pwm_device *pwm,	enum pwm_polarity polarity)
+{
+	struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip);
+
+	/* Configuration of polarity in hardware delayed, do at enable */
+	pc->polarity[pwm->hwpwm] = polarity;
+	return 0;
+}
+
 static int ehrpwm_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
 	struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip);
@@ -307,6 +332,9 @@
 
 	ehrpwm_modify(pc->mmio_base, AQCSFRC, aqcsfrc_mask, aqcsfrc_val);
 
+	/* Channels polarity can be configured from action qualifier module */
+	configure_polarity(pc, pwm->hwpwm);
+
 	/* Enable time counter for free_run */
 	ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_RUN_MASK, TBCTL_FREE_RUN);
 	return 0;
@@ -358,6 +386,7 @@
 static const struct pwm_ops ehrpwm_pwm_ops = {
 	.free		= ehrpwm_pwm_free,
 	.config		= ehrpwm_pwm_config,
+	.set_polarity	= ehrpwm_pwm_set_polarity,
 	.enable		= ehrpwm_pwm_enable,
 	.disable	= ehrpwm_pwm_disable,
 	.owner		= THIS_MODULE,
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index 48e9041..07da58b 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -55,9 +55,9 @@
 };
 
 
-/*
+/**
  * rio_destid_alloc - Allocate next available destID for given network
- * net: RIO network
+ * @net: RIO network
  *
  * Returns next available device destination ID for the specified RIO network.
  * Marks allocated ID as one in use.
@@ -69,14 +69,9 @@
 	struct rio_id_table *idtab = &net->destid_table;
 
 	spin_lock(&idtab->lock);
-	destid = find_next_zero_bit(idtab->table, idtab->max, idtab->next);
-	if (destid >= idtab->max)
-		destid = find_first_zero_bit(idtab->table, idtab->max);
+	destid = find_first_zero_bit(idtab->table, idtab->max);
 
 	if (destid < idtab->max) {
-		idtab->next = destid + 1;
-		if (idtab->next >= idtab->max)
-			idtab->next = 0;
 		set_bit(destid, idtab->table);
 		destid += idtab->start;
 	} else
@@ -86,10 +81,10 @@
 	return (u16)destid;
 }
 
-/*
+/**
  * rio_destid_reserve - Reserve the specivied destID
- * net: RIO network
- * destid: destID to reserve
+ * @net: RIO network
+ * @destid: destID to reserve
  *
  * Tries to reserve the specified destID.
  * Returns 0 if successfull.
@@ -106,10 +101,10 @@
 	return oldbit;
 }
 
-/*
+/**
  * rio_destid_free - free a previously allocated destID
- * net: RIO network
- * destid: destID to free
+ * @net: RIO network
+ * @destid: destID to free
  *
  * Makes the specified destID available for use.
  */
@@ -123,9 +118,9 @@
 	spin_unlock(&idtab->lock);
 }
 
-/*
+/**
  * rio_destid_first - return first destID in use
- * net: RIO network
+ * @net: RIO network
  */
 static u16 rio_destid_first(struct rio_net *net)
 {
@@ -142,10 +137,10 @@
 	return (u16)destid;
 }
 
-/*
+/**
  * rio_destid_next - return next destID in use
- * net: RIO network
- * from: destination ID from which search shall continue
+ * @net: RIO network
+ * @from: destination ID from which search shall continue
  */
 static u16 rio_destid_next(struct rio_net *net, u16 from)
 {
@@ -1163,8 +1158,8 @@
 
 	net = kzalloc(sizeof(struct rio_net), GFP_KERNEL);
 	if (net && do_enum) {
-		net->destid_table.table = kzalloc(
-			BITS_TO_LONGS(RIO_MAX_ROUTE_ENTRIES(port->sys_size)) *
+		net->destid_table.table = kcalloc(
+			BITS_TO_LONGS(RIO_MAX_ROUTE_ENTRIES(port->sys_size)),
 			sizeof(long),
 			GFP_KERNEL);
 
@@ -1174,7 +1169,6 @@
 			net = NULL;
 		} else {
 			net->destid_table.start = start;
-			net->destid_table.next = 0;
 			net->destid_table.max =
 					RIO_MAX_ROUTE_ENTRIES(port->sys_size);
 			spin_lock_init(&net->destid_table.lock);
@@ -1391,7 +1385,7 @@
 		while (time_before(jiffies, to_end)) {
 			if (rio_enum_complete(mport))
 				goto enum_done;
-			schedule_timeout_uninterruptible(msecs_to_jiffies(10));
+			msleep(10);
 		}
 
 		pr_debug("RIO: discovery timeout on mport %d %s\n",
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index d4bd690..c17ae22 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -1275,49 +1275,68 @@
 	pr_debug("RIO: discovery work for mport %d %s\n",
 		 work->mport->id, work->mport->name);
 	rio_disc_mport(work->mport);
-
-	kfree(work);
 }
 
 int __devinit rio_init_mports(void)
 {
 	struct rio_mport *port;
 	struct rio_disc_work *work;
-	int no_disc = 0;
+	int n = 0;
 
+	if (!next_portid)
+		return -ENODEV;
+
+	/*
+	 * First, run enumerations and check if we need to perform discovery
+	 * on any of the registered mports.
+	 */
 	list_for_each_entry(port, &rio_mports, node) {
 		if (port->host_deviceid >= 0)
 			rio_enum_mport(port);
-		else if (!no_disc) {
-			if (!rio_wq) {
-				rio_wq = alloc_workqueue("riodisc", 0, 0);
-				if (!rio_wq) {
-					pr_err("RIO: unable allocate rio_wq\n");
-					no_disc = 1;
-					continue;
-				}
-			}
+		else
+			n++;
+	}
 
-			work = kzalloc(sizeof *work, GFP_KERNEL);
-			if (!work) {
-				pr_err("RIO: no memory for work struct\n");
-				no_disc = 1;
-				continue;
-			}
+	if (!n)
+		goto no_disc;
 
-			work->mport = port;
-			INIT_WORK(&work->work, disc_work_handler);
-			queue_work(rio_wq, &work->work);
+	/*
+	 * If we have mports that require discovery schedule a discovery work
+	 * for each of them. If the code below fails to allocate needed
+	 * resources, exit without error to keep results of enumeration
+	 * process (if any).
+	 * TODO: Implement restart of dicovery process for all or
+	 * individual discovering mports.
+	 */
+	rio_wq = alloc_workqueue("riodisc", 0, 0);
+	if (!rio_wq) {
+		pr_err("RIO: unable allocate rio_wq\n");
+		goto no_disc;
+	}
+
+	work = kcalloc(n, sizeof *work, GFP_KERNEL);
+	if (!work) {
+		pr_err("RIO: no memory for work struct\n");
+		destroy_workqueue(rio_wq);
+		goto no_disc;
+	}
+
+	n = 0;
+	list_for_each_entry(port, &rio_mports, node) {
+		if (port->host_deviceid < 0) {
+			work[n].mport = port;
+			INIT_WORK(&work[n].work, disc_work_handler);
+			queue_work(rio_wq, &work[n].work);
+			n++;
 		}
 	}
 
-	if (rio_wq) {
-		pr_debug("RIO: flush discovery workqueue\n");
-		flush_workqueue(rio_wq);
-		pr_debug("RIO: flush discovery workqueue finished\n");
-		destroy_workqueue(rio_wq);
-	}
+	flush_workqueue(rio_wq);
+	pr_debug("RIO: destroy discovery workqueue\n");
+	destroy_workqueue(rio_wq);
+	kfree(work);
 
+no_disc:
 	rio_init();
 
 	return 0;
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index e069f17..19c03ab 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -59,6 +59,7 @@
 config RTC_INTF_SYSFS
 	boolean "/sys/class/rtc/rtcN (sysfs)"
 	depends on SYSFS
+	default RTC_CLASS
 	help
 	  Say yes here if you want to use your RTCs using sysfs interfaces,
 	  /sys/class/rtc/rtc0 through /sys/.../rtcN.
@@ -68,6 +69,7 @@
 config RTC_INTF_PROC
 	boolean "/proc/driver/rtc (procfs for rtcN)"
 	depends on PROC_FS
+	default RTC_CLASS
 	help
 	  Say yes here if you want to use your system clock RTC through
 	  the proc interface, /proc/driver/rtc.
@@ -79,6 +81,7 @@
 
 config RTC_INTF_DEV
 	boolean "/dev/rtcN (character devices)"
+	default RTC_CLASS
 	help
 	  Say yes here if you want to use your RTCs using the /dev
 	  interfaces, which "udev" sets up as /dev/rtc0 through
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index a5a55da2..b6ad0de 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -69,23 +69,9 @@
 				  size_t count);
 static ssize_t dcssblk_remove_store(struct device * dev, struct device_attribute *attr, const char * buf,
 				  size_t count);
-static ssize_t dcssblk_save_store(struct device * dev, struct device_attribute *attr, const char * buf,
-				  size_t count);
-static ssize_t dcssblk_save_show(struct device *dev, struct device_attribute *attr, char *buf);
-static ssize_t dcssblk_shared_store(struct device * dev, struct device_attribute *attr, const char * buf,
-				  size_t count);
-static ssize_t dcssblk_shared_show(struct device *dev, struct device_attribute *attr, char *buf);
-static ssize_t dcssblk_seglist_show(struct device *dev,
-				struct device_attribute *attr,
-				char *buf);
 
 static DEVICE_ATTR(add, S_IWUSR, NULL, dcssblk_add_store);
 static DEVICE_ATTR(remove, S_IWUSR, NULL, dcssblk_remove_store);
-static DEVICE_ATTR(save, S_IWUSR | S_IRUSR, dcssblk_save_show,
-		   dcssblk_save_store);
-static DEVICE_ATTR(shared, S_IWUSR | S_IRUSR, dcssblk_shared_show,
-		   dcssblk_shared_store);
-static DEVICE_ATTR(seglist, S_IRUSR, dcssblk_seglist_show, NULL);
 
 static struct device *dcssblk_root_dev;
 
@@ -416,6 +402,8 @@
 	up_write(&dcssblk_devices_sem);
 	return rc;
 }
+static DEVICE_ATTR(shared, S_IWUSR | S_IRUSR, dcssblk_shared_show,
+		   dcssblk_shared_store);
 
 /*
  * device attribute for save operation on current copy
@@ -476,6 +464,8 @@
 	up_write(&dcssblk_devices_sem);
 	return count;
 }
+static DEVICE_ATTR(save, S_IWUSR | S_IRUSR, dcssblk_save_show,
+		   dcssblk_save_store);
 
 /*
  * device attribute for showing all segments in a device
@@ -502,6 +492,21 @@
 	up_read(&dcssblk_devices_sem);
 	return i;
 }
+static DEVICE_ATTR(seglist, S_IRUSR, dcssblk_seglist_show, NULL);
+
+static struct attribute *dcssblk_dev_attrs[] = {
+	&dev_attr_shared.attr,
+	&dev_attr_save.attr,
+	&dev_attr_seglist.attr,
+	NULL,
+};
+static struct attribute_group dcssblk_dev_attr_group = {
+	.attrs = dcssblk_dev_attrs,
+};
+static const struct attribute_group *dcssblk_dev_attr_groups[] = {
+	&dcssblk_dev_attr_group,
+	NULL,
+};
 
 /*
  * device attribute for adding devices
@@ -590,6 +595,7 @@
 
 	dev_set_name(&dev_info->dev, dev_info->segment_name);
 	dev_info->dev.release = dcssblk_release_segment;
+	dev_info->dev.groups = dcssblk_dev_attr_groups;
 	INIT_LIST_HEAD(&dev_info->lh);
 	dev_info->gd = alloc_disk(DCSSBLK_MINORS_PER_DISK);
 	if (dev_info->gd == NULL) {
@@ -637,21 +643,10 @@
 	 * register the device
 	 */
 	rc = device_register(&dev_info->dev);
-	if (rc) {
-		module_put(THIS_MODULE);
-		goto dev_list_del;
-	}
-	get_device(&dev_info->dev);
-	rc = device_create_file(&dev_info->dev, &dev_attr_shared);
 	if (rc)
-		goto unregister_dev;
-	rc = device_create_file(&dev_info->dev, &dev_attr_save);
-	if (rc)
-		goto unregister_dev;
-	rc = device_create_file(&dev_info->dev, &dev_attr_seglist);
-	if (rc)
-		goto unregister_dev;
+		goto put_dev;
 
+	get_device(&dev_info->dev);
 	add_disk(dev_info->gd);
 
 	switch (dev_info->segment_type) {
@@ -668,12 +663,11 @@
 	rc = count;
 	goto out;
 
-unregister_dev:
+put_dev:
 	list_del(&dev_info->lh);
 	blk_cleanup_queue(dev_info->dcssblk_queue);
 	dev_info->gd->queue = NULL;
 	put_disk(dev_info->gd);
-	device_unregister(&dev_info->dev);
 	list_for_each_entry(seg_info, &dev_info->seg_list, lh) {
 		segment_unload(seg_info->segment_name);
 	}
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c
index c7275e3..899ffa1 100644
--- a/drivers/s390/crypto/zcrypt_pcixcc.c
+++ b/drivers/s390/crypto/zcrypt_pcixcc.c
@@ -39,7 +39,6 @@
 #include "zcrypt_msgtype6.h"
 #include "zcrypt_pcixcc.h"
 #include "zcrypt_cca_key.h"
-#include "zcrypt_msgtype6.h"
 
 #define PCIXCC_MIN_MOD_SIZE	 16	/*  128 bits	*/
 #define PCIXCC_MIN_MOD_SIZE_OLD	 64	/*  512 bits	*/
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index bddc97c..0e09d8f 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -1403,7 +1403,7 @@
 	ctio->u.status1.scsi_status =
 	    __constant_cpu_to_le16(SS_RESPONSE_INFO_LEN_VALID);
 	ctio->u.status1.response_len = __constant_cpu_to_le16(8);
-	((uint32_t *)ctio->u.status1.sense_data)[0] = cpu_to_be32(resp_code);
+	ctio->u.status1.sense_data[0] = resp_code;
 
 	qla2x00_start_iocbs(ha, ha->req);
 }
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index 4752f65..2358c16 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -735,17 +735,6 @@
 	return 0;
 }
 
-static u16 tcm_qla2xxx_get_fabric_sense_len(void)
-{
-	return 0;
-}
-
-static u16 tcm_qla2xxx_set_fabric_sense_len(struct se_cmd *se_cmd,
-					u32 sense_length)
-{
-	return 0;
-}
-
 /* Local pointer to allocated TCM configfs fabric module */
 struct target_fabric_configfs *tcm_qla2xxx_fabric_configfs;
 struct target_fabric_configfs *tcm_qla2xxx_npiv_fabric_configfs;
@@ -1691,8 +1680,6 @@
 	.queue_data_in			= tcm_qla2xxx_queue_data_in,
 	.queue_status			= tcm_qla2xxx_queue_status,
 	.queue_tm_rsp			= tcm_qla2xxx_queue_tm_rsp,
-	.get_fabric_sense_len		= tcm_qla2xxx_get_fabric_sense_len,
-	.set_fabric_sense_len		= tcm_qla2xxx_set_fabric_sense_len,
 	/*
 	 * Setup function pointers for generic logic in
 	 * target_core_fabric_configfs.c
@@ -1740,8 +1727,6 @@
 	.queue_data_in			= tcm_qla2xxx_queue_data_in,
 	.queue_status			= tcm_qla2xxx_queue_status,
 	.queue_tm_rsp			= tcm_qla2xxx_queue_tm_rsp,
-	.get_fabric_sense_len		= tcm_qla2xxx_get_fabric_sense_len,
-	.set_fabric_sense_len		= tcm_qla2xxx_set_fabric_sense_len,
 	/*
 	 * Setup function pointers for generic logic in
 	 * target_core_fabric_configfs.c
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 9c5c5f2..be2c9a6 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1257,7 +1257,7 @@
 	}
 
 	sfp->mmap_called = 1;
-	vma->vm_flags |= VM_RESERVED;
+	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 	vma->vm_private_data = sfp;
 	vma->vm_ops = &sg_mmap_vm_ops;
 	return 0;
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index ecc31a1..1acae35 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -134,6 +134,7 @@
 	tristate "Texas Instruments DaVinci/DA8x/OMAP-L/AM1x SoC SPI controller"
 	depends on ARCH_DAVINCI
 	select SPI_BITBANG
+	select TI_EDMA
 	help
 	  SPI master controller for DaVinci/DA8x/OMAP-L/AM1x SPI modules.
 
@@ -237,6 +238,13 @@
 	help
 	  This is the driver for OpenCores tiny SPI master controller.
 
+config SPI_OCTEON
+	tristate "Cavium OCTEON SPI controller"
+	depends on CPU_CAVIUM_OCTEON
+	help
+	  SPI host driver for the hardware found on some Cavium OCTEON
+	  SOCs.
+
 config SPI_OMAP_UWIRE
 	tristate "OMAP1 MicroWire"
 	depends on ARCH_OMAP1
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 22fd3a7..c48df47 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -39,6 +39,7 @@
 obj-$(CONFIG_SPI_MXS)			+= spi-mxs.o
 obj-$(CONFIG_SPI_NUC900)		+= spi-nuc900.o
 obj-$(CONFIG_SPI_OC_TINY)		+= spi-oc-tiny.o
+obj-$(CONFIG_SPI_OCTEON)		+= spi-octeon.o
 obj-$(CONFIG_SPI_OMAP_UWIRE)		+= spi-omap-uwire.o
 obj-$(CONFIG_SPI_OMAP_100K)		+= spi-omap-100k.o
 obj-$(CONFIG_SPI_OMAP24XX)		+= spi-omap2-mcspi.o
diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c
index 3afe2f4f..147dfa8 100644
--- a/drivers/spi/spi-davinci.c
+++ b/drivers/spi/spi-davinci.c
@@ -25,13 +25,14 @@
 #include <linux/platform_device.h>
 #include <linux/err.h>
 #include <linux/clk.h>
+#include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
+#include <linux/edma.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_bitbang.h>
 #include <linux/slab.h>
 
 #include <linux/platform_data/spi-davinci.h>
-#include <mach/edma.h>
 
 #define SPI_NO_RESOURCE		((resource_size_t)-1)
 
@@ -113,14 +114,6 @@
 #define SPIDEF		0x4c
 #define SPIFMT0		0x50
 
-/* We have 2 DMA channels per CS, one for RX and one for TX */
-struct davinci_spi_dma {
-	int			tx_channel;
-	int			rx_channel;
-	int			dummy_param_slot;
-	enum dma_event_q	eventq;
-};
-
 /* SPI Controller driver's private data. */
 struct davinci_spi {
 	struct spi_bitbang	bitbang;
@@ -134,11 +127,14 @@
 
 	const void		*tx;
 	void			*rx;
-#define SPI_TMP_BUFSZ	(SMP_CACHE_BYTES + 1)
-	u8			rx_tmp_buf[SPI_TMP_BUFSZ];
 	int			rcount;
 	int			wcount;
-	struct davinci_spi_dma	dma;
+
+	struct dma_chan		*dma_rx;
+	struct dma_chan		*dma_tx;
+	int			dma_rx_chnum;
+	int			dma_tx_chnum;
+
 	struct davinci_spi_platform_data *pdata;
 
 	void			(*get_rx)(u32 rx_data, struct davinci_spi *);
@@ -496,21 +492,23 @@
 	return errors;
 }
 
-static void davinci_spi_dma_callback(unsigned lch, u16 status, void *data)
+static void davinci_spi_dma_rx_callback(void *data)
 {
-	struct davinci_spi *dspi = data;
-	struct davinci_spi_dma *dma = &dspi->dma;
+	struct davinci_spi *dspi = (struct davinci_spi *)data;
 
-	edma_stop(lch);
+	dspi->rcount = 0;
 
-	if (status == DMA_COMPLETE) {
-		if (lch == dma->rx_channel)
-			dspi->rcount = 0;
-		if (lch == dma->tx_channel)
-			dspi->wcount = 0;
-	}
+	if (!dspi->wcount && !dspi->rcount)
+		complete(&dspi->done);
+}
 
-	if ((!dspi->wcount && !dspi->rcount) || (status != DMA_COMPLETE))
+static void davinci_spi_dma_tx_callback(void *data)
+{
+	struct davinci_spi *dspi = (struct davinci_spi *)data;
+
+	dspi->wcount = 0;
+
+	if (!dspi->wcount && !dspi->rcount)
 		complete(&dspi->done);
 }
 
@@ -526,20 +524,20 @@
 static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
 {
 	struct davinci_spi *dspi;
-	int data_type, ret;
+	int data_type, ret = -ENOMEM;
 	u32 tx_data, spidat1;
 	u32 errors = 0;
 	struct davinci_spi_config *spicfg;
 	struct davinci_spi_platform_data *pdata;
 	unsigned uninitialized_var(rx_buf_count);
-	struct device *sdev;
+	void *dummy_buf = NULL;
+	struct scatterlist sg_rx, sg_tx;
 
 	dspi = spi_master_get_devdata(spi->master);
 	pdata = dspi->pdata;
 	spicfg = (struct davinci_spi_config *)spi->controller_data;
 	if (!spicfg)
 		spicfg = &davinci_spi_default_cfg;
-	sdev = dspi->bitbang.master->dev.parent;
 
 	/* convert len to words based on bits_per_word */
 	data_type = dspi->bytes_per_word[spi->chip_select];
@@ -567,112 +565,83 @@
 		spidat1 |= tx_data & 0xFFFF;
 		iowrite32(spidat1, dspi->base + SPIDAT1);
 	} else {
-		struct davinci_spi_dma *dma;
-		unsigned long tx_reg, rx_reg;
-		struct edmacc_param param;
-		void *rx_buf;
-		int b, c;
+		struct dma_slave_config dma_rx_conf = {
+			.direction = DMA_DEV_TO_MEM,
+			.src_addr = (unsigned long)dspi->pbase + SPIBUF,
+			.src_addr_width = data_type,
+			.src_maxburst = 1,
+		};
+		struct dma_slave_config dma_tx_conf = {
+			.direction = DMA_MEM_TO_DEV,
+			.dst_addr = (unsigned long)dspi->pbase + SPIDAT1,
+			.dst_addr_width = data_type,
+			.dst_maxburst = 1,
+		};
+		struct dma_async_tx_descriptor *rxdesc;
+		struct dma_async_tx_descriptor *txdesc;
+		void *buf;
 
-		dma = &dspi->dma;
+		dummy_buf = kzalloc(t->len, GFP_KERNEL);
+		if (!dummy_buf)
+			goto err_alloc_dummy_buf;
 
-		tx_reg = (unsigned long)dspi->pbase + SPIDAT1;
-		rx_reg = (unsigned long)dspi->pbase + SPIBUF;
+		dmaengine_slave_config(dspi->dma_rx, &dma_rx_conf);
+		dmaengine_slave_config(dspi->dma_tx, &dma_tx_conf);
 
-		/*
-		 * Transmit DMA setup
-		 *
-		 * If there is transmit data, map the transmit buffer, set it
-		 * as the source of data and set the source B index to data
-		 * size. If there is no transmit data, set the transmit register
-		 * as the source of data, and set the source B index to zero.
-		 *
-		 * The destination is always the transmit register itself. And
-		 * the destination never increments.
-		 */
-
-		if (t->tx_buf) {
-			t->tx_dma = dma_map_single(&spi->dev, (void *)t->tx_buf,
-						t->len, DMA_TO_DEVICE);
-			if (dma_mapping_error(&spi->dev, t->tx_dma)) {
-				dev_dbg(sdev, "Unable to DMA map %d bytes"
-						"TX buffer\n", t->len);
-				return -ENOMEM;
-			}
-		}
-
-		/*
-		 * If number of words is greater than 65535, then we need
-		 * to configure a 3 dimension transfer.  Use the BCNTRLD
-		 * feature to allow for transfers that aren't even multiples
-		 * of 65535 (or any other possible b size) by first transferring
-		 * the remainder amount then grabbing the next N blocks of
-		 * 65535 words.
-		 */
-
-		c = dspi->wcount / (SZ_64K - 1);	/* N 65535 Blocks */
-		b = dspi->wcount - c * (SZ_64K - 1);	/* Remainder */
-		if (b)
-			c++;
+		sg_init_table(&sg_rx, 1);
+		if (!t->rx_buf)
+			buf = dummy_buf;
 		else
-			b = SZ_64K - 1;
-
-		param.opt = TCINTEN | EDMA_TCC(dma->tx_channel);
-		param.src = t->tx_buf ? t->tx_dma : tx_reg;
-		param.a_b_cnt = b << 16 | data_type;
-		param.dst = tx_reg;
-		param.src_dst_bidx = t->tx_buf ? data_type : 0;
-		param.link_bcntrld = 0xffffffff;
-		param.src_dst_cidx = t->tx_buf ? data_type : 0;
-		param.ccnt = c;
-		edma_write_slot(dma->tx_channel, &param);
-		edma_link(dma->tx_channel, dma->dummy_param_slot);
-
-		/*
-		 * Receive DMA setup
-		 *
-		 * If there is receive buffer, use it to receive data. If there
-		 * is none provided, use a temporary receive buffer. Set the
-		 * destination B index to 0 so effectively only one byte is used
-		 * in the temporary buffer (address does not increment).
-		 *
-		 * The source of receive data is the receive data register. The
-		 * source address never increments.
-		 */
-
-		if (t->rx_buf) {
-			rx_buf = t->rx_buf;
-			rx_buf_count = t->len;
-		} else {
-			rx_buf = dspi->rx_tmp_buf;
-			rx_buf_count = sizeof(dspi->rx_tmp_buf);
+			buf = t->rx_buf;
+		t->rx_dma = dma_map_single(&spi->dev, buf,
+				t->len, DMA_FROM_DEVICE);
+		if (!t->rx_dma) {
+			ret = -EFAULT;
+			goto err_rx_map;
 		}
+		sg_dma_address(&sg_rx) = t->rx_dma;
+		sg_dma_len(&sg_rx) = t->len;
 
-		t->rx_dma = dma_map_single(&spi->dev, rx_buf, rx_buf_count,
-							DMA_FROM_DEVICE);
-		if (dma_mapping_error(&spi->dev, t->rx_dma)) {
-			dev_dbg(sdev, "Couldn't DMA map a %d bytes RX buffer\n",
-								rx_buf_count);
-			if (t->tx_buf)
-				dma_unmap_single(&spi->dev, t->tx_dma, t->len,
-								DMA_TO_DEVICE);
-			return -ENOMEM;
+		sg_init_table(&sg_tx, 1);
+		if (!t->tx_buf)
+			buf = dummy_buf;
+		else
+			buf = (void *)t->tx_buf;
+		t->tx_dma = dma_map_single(&spi->dev, buf,
+				t->len, DMA_FROM_DEVICE);
+		if (!t->tx_dma) {
+			ret = -EFAULT;
+			goto err_tx_map;
 		}
+		sg_dma_address(&sg_tx) = t->tx_dma;
+		sg_dma_len(&sg_tx) = t->len;
 
-		param.opt = TCINTEN | EDMA_TCC(dma->rx_channel);
-		param.src = rx_reg;
-		param.a_b_cnt = b << 16 | data_type;
-		param.dst = t->rx_dma;
-		param.src_dst_bidx = (t->rx_buf ? data_type : 0) << 16;
-		param.link_bcntrld = 0xffffffff;
-		param.src_dst_cidx = (t->rx_buf ? data_type : 0) << 16;
-		param.ccnt = c;
-		edma_write_slot(dma->rx_channel, &param);
+		rxdesc = dmaengine_prep_slave_sg(dspi->dma_rx,
+				&sg_rx, 1, DMA_DEV_TO_MEM,
+				DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+		if (!rxdesc)
+			goto err_desc;
+
+		txdesc = dmaengine_prep_slave_sg(dspi->dma_tx,
+				&sg_tx, 1, DMA_MEM_TO_DEV,
+				DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+		if (!txdesc)
+			goto err_desc;
+
+		rxdesc->callback = davinci_spi_dma_rx_callback;
+		rxdesc->callback_param = (void *)dspi;
+		txdesc->callback = davinci_spi_dma_tx_callback;
+		txdesc->callback_param = (void *)dspi;
 
 		if (pdata->cshold_bug)
 			iowrite16(spidat1 >> 16, dspi->base + SPIDAT1 + 2);
 
-		edma_start(dma->rx_channel);
-		edma_start(dma->tx_channel);
+		dmaengine_submit(rxdesc);
+		dmaengine_submit(txdesc);
+
+		dma_async_issue_pending(dspi->dma_rx);
+		dma_async_issue_pending(dspi->dma_tx);
+
 		set_io_bits(dspi->base + SPIINT, SPIINT_DMA_REQ_EN);
 	}
 
@@ -690,15 +659,13 @@
 
 	clear_io_bits(dspi->base + SPIINT, SPIINT_MASKALL);
 	if (spicfg->io_type == SPI_IO_TYPE_DMA) {
-
-		if (t->tx_buf)
-			dma_unmap_single(&spi->dev, t->tx_dma, t->len,
-								DMA_TO_DEVICE);
-
-		dma_unmap_single(&spi->dev, t->rx_dma, rx_buf_count,
-							DMA_FROM_DEVICE);
-
 		clear_io_bits(dspi->base + SPIINT, SPIINT_DMA_REQ_EN);
+
+		dma_unmap_single(&spi->dev, t->rx_dma,
+				t->len, DMA_FROM_DEVICE);
+		dma_unmap_single(&spi->dev, t->tx_dma,
+				t->len, DMA_TO_DEVICE);
+		kfree(dummy_buf);
 	}
 
 	clear_io_bits(dspi->base + SPIGCR1, SPIGCR1_SPIENA_MASK);
@@ -716,11 +683,20 @@
 	}
 
 	if (dspi->rcount != 0 || dspi->wcount != 0) {
-		dev_err(sdev, "SPI data transfer error\n");
+		dev_err(&spi->dev, "SPI data transfer error\n");
 		return -EIO;
 	}
 
 	return t->len;
+
+err_desc:
+	dma_unmap_single(&spi->dev, t->tx_dma, t->len, DMA_TO_DEVICE);
+err_tx_map:
+	dma_unmap_single(&spi->dev, t->rx_dma, t->len, DMA_FROM_DEVICE);
+err_rx_map:
+	kfree(dummy_buf);
+err_alloc_dummy_buf:
+	return ret;
 }
 
 /**
@@ -751,39 +727,33 @@
 
 static int davinci_spi_request_dma(struct davinci_spi *dspi)
 {
+	dma_cap_mask_t mask;
+	struct device *sdev = dspi->bitbang.master->dev.parent;
 	int r;
-	struct davinci_spi_dma *dma = &dspi->dma;
 
-	r = edma_alloc_channel(dma->rx_channel, davinci_spi_dma_callback, dspi,
-								dma->eventq);
-	if (r < 0) {
-		pr_err("Unable to request DMA channel for SPI RX\n");
-		r = -EAGAIN;
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+
+	dspi->dma_rx = dma_request_channel(mask, edma_filter_fn,
+					   &dspi->dma_rx_chnum);
+	if (!dspi->dma_rx) {
+		dev_err(sdev, "request RX DMA channel failed\n");
+		r = -ENODEV;
 		goto rx_dma_failed;
 	}
 
-	r = edma_alloc_channel(dma->tx_channel, davinci_spi_dma_callback, dspi,
-								dma->eventq);
-	if (r < 0) {
-		pr_err("Unable to request DMA channel for SPI TX\n");
-		r = -EAGAIN;
+	dspi->dma_tx = dma_request_channel(mask, edma_filter_fn,
+					   &dspi->dma_tx_chnum);
+	if (!dspi->dma_tx) {
+		dev_err(sdev, "request TX DMA channel failed\n");
+		r = -ENODEV;
 		goto tx_dma_failed;
 	}
 
-	r = edma_alloc_slot(EDMA_CTLR(dma->tx_channel), EDMA_SLOT_ANY);
-	if (r < 0) {
-		pr_err("Unable to request SPI TX DMA param slot\n");
-		r = -EAGAIN;
-		goto param_failed;
-	}
-	dma->dummy_param_slot = r;
-	edma_link(dma->dummy_param_slot, dma->dummy_param_slot);
-
 	return 0;
-param_failed:
-	edma_free_channel(dma->tx_channel);
+
 tx_dma_failed:
-	edma_free_channel(dma->rx_channel);
+	dma_release_channel(dspi->dma_rx);
 rx_dma_failed:
 	return r;
 }
@@ -898,9 +868,8 @@
 	dspi->bitbang.txrx_bufs = davinci_spi_bufs;
 	if (dma_rx_chan != SPI_NO_RESOURCE &&
 	    dma_tx_chan != SPI_NO_RESOURCE) {
-		dspi->dma.rx_channel = dma_rx_chan;
-		dspi->dma.tx_channel = dma_tx_chan;
-		dspi->dma.eventq = pdata->dma_event_q;
+		dspi->dma_rx_chnum = dma_rx_chan;
+		dspi->dma_tx_chnum = dma_tx_chan;
 
 		ret = davinci_spi_request_dma(dspi);
 		if (ret)
@@ -955,9 +924,8 @@
 	return ret;
 
 free_dma:
-	edma_free_channel(dspi->dma.tx_channel);
-	edma_free_channel(dspi->dma.rx_channel);
-	edma_free_slot(dspi->dma.dummy_param_slot);
+	dma_release_channel(dspi->dma_rx);
+	dma_release_channel(dspi->dma_tx);
 free_clk:
 	clk_disable(dspi->clk);
 	clk_put(dspi->clk);
diff --git a/drivers/spi/spi-octeon.c b/drivers/spi/spi-octeon.c
new file mode 100644
index 0000000..ea8fb2e
--- /dev/null
+++ b/drivers/spi/spi-octeon.c
@@ -0,0 +1,362 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2011, 2012 Cavium, Inc.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/spi/spi.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of.h>
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-mpi-defs.h>
+
+#define OCTEON_SPI_CFG 0
+#define OCTEON_SPI_STS 0x08
+#define OCTEON_SPI_TX 0x10
+#define OCTEON_SPI_DAT0 0x80
+
+#define OCTEON_SPI_MAX_BYTES 9
+
+#define OCTEON_SPI_MAX_CLOCK_HZ 16000000
+
+struct octeon_spi {
+	struct spi_master *my_master;
+	u64 register_base;
+	u64 last_cfg;
+	u64 cs_enax;
+};
+
+struct octeon_spi_setup {
+	u32 max_speed_hz;
+	u8 chip_select;
+	u8 mode;
+	u8 bits_per_word;
+};
+
+static void octeon_spi_wait_ready(struct octeon_spi *p)
+{
+	union cvmx_mpi_sts mpi_sts;
+	unsigned int loops = 0;
+
+	do {
+		if (loops++)
+			__delay(500);
+		mpi_sts.u64 = cvmx_read_csr(p->register_base + OCTEON_SPI_STS);
+	} while (mpi_sts.s.busy);
+}
+
+static int octeon_spi_do_transfer(struct octeon_spi *p,
+				  struct spi_message *msg,
+				  struct spi_transfer *xfer,
+				  bool last_xfer)
+{
+	union cvmx_mpi_cfg mpi_cfg;
+	union cvmx_mpi_tx mpi_tx;
+	unsigned int clkdiv;
+	unsigned int speed_hz;
+	int mode;
+	bool cpha, cpol;
+	int bits_per_word;
+	const u8 *tx_buf;
+	u8 *rx_buf;
+	int len;
+	int i;
+
+	struct octeon_spi_setup *msg_setup = spi_get_ctldata(msg->spi);
+
+	speed_hz = msg_setup->max_speed_hz;
+	mode = msg_setup->mode;
+	cpha = mode & SPI_CPHA;
+	cpol = mode & SPI_CPOL;
+	bits_per_word = msg_setup->bits_per_word;
+
+	if (xfer->speed_hz)
+		speed_hz = xfer->speed_hz;
+	if (xfer->bits_per_word)
+		bits_per_word = xfer->bits_per_word;
+
+	if (speed_hz > OCTEON_SPI_MAX_CLOCK_HZ)
+		speed_hz = OCTEON_SPI_MAX_CLOCK_HZ;
+
+	clkdiv = octeon_get_io_clock_rate() / (2 * speed_hz);
+
+	mpi_cfg.u64 = 0;
+
+	mpi_cfg.s.clkdiv = clkdiv;
+	mpi_cfg.s.cshi = (mode & SPI_CS_HIGH) ? 1 : 0;
+	mpi_cfg.s.lsbfirst = (mode & SPI_LSB_FIRST) ? 1 : 0;
+	mpi_cfg.s.wireor = (mode & SPI_3WIRE) ? 1 : 0;
+	mpi_cfg.s.idlelo = cpha != cpol;
+	mpi_cfg.s.cslate = cpha ? 1 : 0;
+	mpi_cfg.s.enable = 1;
+
+	if (msg_setup->chip_select < 4)
+		p->cs_enax |= 1ull << (12 + msg_setup->chip_select);
+	mpi_cfg.u64 |= p->cs_enax;
+
+	if (mpi_cfg.u64 != p->last_cfg) {
+		p->last_cfg = mpi_cfg.u64;
+		cvmx_write_csr(p->register_base + OCTEON_SPI_CFG, mpi_cfg.u64);
+	}
+	tx_buf = xfer->tx_buf;
+	rx_buf = xfer->rx_buf;
+	len = xfer->len;
+	while (len > OCTEON_SPI_MAX_BYTES) {
+		for (i = 0; i < OCTEON_SPI_MAX_BYTES; i++) {
+			u8 d;
+			if (tx_buf)
+				d = *tx_buf++;
+			else
+				d = 0;
+			cvmx_write_csr(p->register_base + OCTEON_SPI_DAT0 + (8 * i), d);
+		}
+		mpi_tx.u64 = 0;
+		mpi_tx.s.csid = msg_setup->chip_select;
+		mpi_tx.s.leavecs = 1;
+		mpi_tx.s.txnum = tx_buf ? OCTEON_SPI_MAX_BYTES : 0;
+		mpi_tx.s.totnum = OCTEON_SPI_MAX_BYTES;
+		cvmx_write_csr(p->register_base + OCTEON_SPI_TX, mpi_tx.u64);
+
+		octeon_spi_wait_ready(p);
+		if (rx_buf)
+			for (i = 0; i < OCTEON_SPI_MAX_BYTES; i++) {
+				u64 v = cvmx_read_csr(p->register_base + OCTEON_SPI_DAT0 + (8 * i));
+				*rx_buf++ = (u8)v;
+			}
+		len -= OCTEON_SPI_MAX_BYTES;
+	}
+
+	for (i = 0; i < len; i++) {
+		u8 d;
+		if (tx_buf)
+			d = *tx_buf++;
+		else
+			d = 0;
+		cvmx_write_csr(p->register_base + OCTEON_SPI_DAT0 + (8 * i), d);
+	}
+
+	mpi_tx.u64 = 0;
+	mpi_tx.s.csid = msg_setup->chip_select;
+	if (last_xfer)
+		mpi_tx.s.leavecs = xfer->cs_change;
+	else
+		mpi_tx.s.leavecs = !xfer->cs_change;
+	mpi_tx.s.txnum = tx_buf ? len : 0;
+	mpi_tx.s.totnum = len;
+	cvmx_write_csr(p->register_base + OCTEON_SPI_TX, mpi_tx.u64);
+
+	octeon_spi_wait_ready(p);
+	if (rx_buf)
+		for (i = 0; i < len; i++) {
+			u64 v = cvmx_read_csr(p->register_base + OCTEON_SPI_DAT0 + (8 * i));
+			*rx_buf++ = (u8)v;
+		}
+
+	if (xfer->delay_usecs)
+		udelay(xfer->delay_usecs);
+
+	return xfer->len;
+}
+
+static int octeon_spi_validate_bpw(struct spi_device *spi, u32 speed)
+{
+	switch (speed) {
+	case 8:
+		break;
+	default:
+		dev_err(&spi->dev, "Error: %d bits per word not supported\n",
+			speed);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int octeon_spi_transfer_one_message(struct spi_master *master,
+					   struct spi_message *msg)
+{
+	struct octeon_spi *p = spi_master_get_devdata(master);
+	unsigned int total_len = 0;
+	int status = 0;
+	struct spi_transfer *xfer;
+
+	/*
+	 * We better have set the configuration via a call to .setup
+	 * before we get here.
+	 */
+	if (spi_get_ctldata(msg->spi) == NULL) {
+		status = -EINVAL;
+		goto err;
+	}
+
+	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+		if (xfer->bits_per_word) {
+			status = octeon_spi_validate_bpw(msg->spi,
+							 xfer->bits_per_word);
+			if (status)
+				goto err;
+		}
+	}
+
+	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+		bool last_xfer = &xfer->transfer_list == msg->transfers.prev;
+		int r = octeon_spi_do_transfer(p, msg, xfer, last_xfer);
+		if (r < 0) {
+			status = r;
+			goto err;
+		}
+		total_len += r;
+	}
+err:
+	msg->status = status;
+	msg->actual_length = total_len;
+	spi_finalize_current_message(master);
+	return status;
+}
+
+static struct octeon_spi_setup *octeon_spi_new_setup(struct spi_device *spi)
+{
+	struct octeon_spi_setup *setup = kzalloc(sizeof(*setup), GFP_KERNEL);
+	if (!setup)
+		return NULL;
+
+	setup->max_speed_hz = spi->max_speed_hz;
+	setup->chip_select = spi->chip_select;
+	setup->mode = spi->mode;
+	setup->bits_per_word = spi->bits_per_word;
+	return setup;
+}
+
+static int octeon_spi_setup(struct spi_device *spi)
+{
+	int r;
+	struct octeon_spi_setup *new_setup;
+	struct octeon_spi_setup *old_setup = spi_get_ctldata(spi);
+
+	r = octeon_spi_validate_bpw(spi, spi->bits_per_word);
+	if (r)
+		return r;
+
+	new_setup = octeon_spi_new_setup(spi);
+	if (!new_setup)
+		return -ENOMEM;
+
+	spi_set_ctldata(spi, new_setup);
+	kfree(old_setup);
+
+	return 0;
+}
+
+static void octeon_spi_cleanup(struct spi_device *spi)
+{
+	struct octeon_spi_setup *old_setup = spi_get_ctldata(spi);
+	spi_set_ctldata(spi, NULL);
+	kfree(old_setup);
+}
+
+static int octeon_spi_nop_transfer_hardware(struct spi_master *master)
+{
+	return 0;
+}
+
+static int __devinit octeon_spi_probe(struct platform_device *pdev)
+{
+
+	struct resource *res_mem;
+	struct spi_master *master;
+	struct octeon_spi *p;
+	int err = -ENOENT;
+
+	master = spi_alloc_master(&pdev->dev, sizeof(struct octeon_spi));
+	if (!master)
+		return -ENOMEM;
+	p = spi_master_get_devdata(master);
+	platform_set_drvdata(pdev, p);
+	p->my_master = master;
+
+	res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	if (res_mem == NULL) {
+		dev_err(&pdev->dev, "found no memory resource\n");
+		err = -ENXIO;
+		goto fail;
+	}
+	if (!devm_request_mem_region(&pdev->dev, res_mem->start,
+				     resource_size(res_mem), res_mem->name)) {
+		dev_err(&pdev->dev, "request_mem_region failed\n");
+		goto fail;
+	}
+	p->register_base = (u64)devm_ioremap(&pdev->dev, res_mem->start,
+					     resource_size(res_mem));
+
+	/* Dynamic bus numbering */
+	master->bus_num = -1;
+	master->num_chipselect = 4;
+	master->mode_bits = SPI_CPHA |
+			    SPI_CPOL |
+			    SPI_CS_HIGH |
+			    SPI_LSB_FIRST |
+			    SPI_3WIRE;
+
+	master->setup = octeon_spi_setup;
+	master->cleanup = octeon_spi_cleanup;
+	master->prepare_transfer_hardware = octeon_spi_nop_transfer_hardware;
+	master->transfer_one_message = octeon_spi_transfer_one_message;
+	master->unprepare_transfer_hardware = octeon_spi_nop_transfer_hardware;
+
+	master->dev.of_node = pdev->dev.of_node;
+	err = spi_register_master(master);
+	if (err) {
+		dev_err(&pdev->dev, "register master failed: %d\n", err);
+		goto fail;
+	}
+
+	dev_info(&pdev->dev, "OCTEON SPI bus driver\n");
+
+	return 0;
+fail:
+	spi_master_put(master);
+	return err;
+}
+
+static int __devexit octeon_spi_remove(struct platform_device *pdev)
+{
+	struct octeon_spi *p = platform_get_drvdata(pdev);
+	u64 register_base = p->register_base;
+
+	spi_unregister_master(p->my_master);
+
+	/* Clear the CSENA* and put everything in a known state. */
+	cvmx_write_csr(register_base + OCTEON_SPI_CFG, 0);
+
+	return 0;
+}
+
+static struct of_device_id octeon_spi_match[] = {
+	{ .compatible = "cavium,octeon-3010-spi", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, octeon_spi_match);
+
+static struct platform_driver octeon_spi_driver = {
+	.driver = {
+		.name		= "spi-octeon",
+		.owner		= THIS_MODULE,
+		.of_match_table = octeon_spi_match,
+	},
+	.probe		= octeon_spi_probe,
+	.remove		= __devexit_p(octeon_spi_remove),
+};
+
+module_platform_driver(octeon_spi_driver);
+
+MODULE_DESCRIPTION("Cavium, Inc. OCTEON SPI bus driver");
+MODULE_AUTHOR("David Daney");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c
index 94a740d..634b9ae 100644
--- a/drivers/staging/android/ashmem.c
+++ b/drivers/staging/android/ashmem.c
@@ -332,7 +332,6 @@
 	if (vma->vm_file)
 		fput(vma->vm_file);
 	vma->vm_file = asma->file;
-	vma->vm_flags |= VM_CAN_NONLINEAR;
 
 out:
 	mutex_unlock(&ashmem_mutex);
diff --git a/drivers/staging/omapdrm/omap_drv.c b/drivers/staging/omapdrm/omap_drv.c
index 2ec5264..ebdb0b6 100644
--- a/drivers/staging/omapdrm/omap_drv.c
+++ b/drivers/staging/omapdrm/omap_drv.c
@@ -106,7 +106,8 @@
 	for (i = 0; i < omap_dss_get_num_overlays(); i++) {
 		struct omap_overlay *ovl = omap_dss_get_overlay(i);
 		struct omap_overlay_manager *mgr = ovl->manager;
-		struct omap_dss_device *dssdev = mgr ? mgr->device : NULL;
+		struct omap_dss_device *dssdev = mgr ?
+					mgr->get_device(mgr) : NULL;
 		if (dssdev) {
 			DBG("%d: %s -> %s -> %s", i, ovl->name, mgr->name,
 						dssdev->name);
@@ -185,7 +186,7 @@
 	for (j = 0; j < priv->num_encoders; j++) {
 		struct omap_overlay_manager *mgr =
 			omap_encoder_get_manager(priv->encoders[j]);
-		if (mgr->device == dssdev) {
+		if (mgr->get_device(mgr) == dssdev) {
 			drm_mode_connector_attach_encoder(connector,
 					priv->encoders[j]);
 		}
diff --git a/drivers/staging/omapdrm/omap_gem_dmabuf.c b/drivers/staging/omapdrm/omap_gem_dmabuf.c
index 42728e0..c6f3ef6 100644
--- a/drivers/staging/omapdrm/omap_gem_dmabuf.c
+++ b/drivers/staging/omapdrm/omap_gem_dmabuf.c
@@ -160,7 +160,7 @@
 		goto out_unlock;
 	}
 
-	vma->vm_flags |= VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTEXPAND;
+	vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
 	vma->vm_ops = obj->dev->driver->gem_vm_ops;
 	vma->vm_private_data = obj;
 	vma->vm_page_prot =  pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c
index bddea1d..701a11a 100644
--- a/drivers/staging/tidspbridge/rmgr/drv_interface.c
+++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c
@@ -261,7 +261,7 @@
 {
 	u32 status;
 
-	vma->vm_flags |= VM_RESERVED | VM_IO;
+	/* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 
 	dev_dbg(bridge, "%s: vm filp %p start %lx end %lx page_prot %ulx "
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 97c0f78..d6ce218 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -427,7 +427,7 @@
 	return 0;
 }
 
-int iscsit_del_np_comm(struct iscsi_np *np)
+static int iscsit_del_np_comm(struct iscsi_np *np)
 {
 	if (np->np_socket)
 		sock_release(np->np_socket);
@@ -785,10 +785,6 @@
 
 	hdr			= (struct iscsi_scsi_req *) buf;
 	payload_length		= ntoh24(hdr->dlength);
-	hdr->itt		= be32_to_cpu(hdr->itt);
-	hdr->data_length	= be32_to_cpu(hdr->data_length);
-	hdr->cmdsn		= be32_to_cpu(hdr->cmdsn);
-	hdr->exp_statsn		= be32_to_cpu(hdr->exp_statsn);
 
 	/* FIXME; Add checks for AdditionalHeaderSegment */
 
@@ -852,7 +848,7 @@
 				buf, conn);
 	}
 
-	if ((hdr->data_length == payload_length) &&
+	if ((be32_to_cpu(hdr->data_length )== payload_length) &&
 	    (!(hdr->flags & ISCSI_FLAG_CMD_FINAL))) {
 		pr_err("Expected Data Transfer Length and Length of"
 			" Immediate Data are the same, but ISCSI_FLAG_CMD_FINAL"
@@ -861,7 +857,7 @@
 				buf, conn);
 	}
 
-	if (payload_length > hdr->data_length) {
+	if (payload_length > be32_to_cpu(hdr->data_length)) {
 		pr_err("DataSegmentLength: %u is greater than"
 			" EDTL: %u, protocol error.\n", payload_length,
 				hdr->data_length);
@@ -869,10 +865,10 @@
 				buf, conn);
 	}
 
-	if (payload_length > conn->conn_ops->MaxRecvDataSegmentLength) {
+	if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) {
 		pr_err("DataSegmentLength: %u is greater than"
-			" MaxRecvDataSegmentLength: %u, protocol error.\n",
-			payload_length, conn->conn_ops->MaxRecvDataSegmentLength);
+			" MaxXmitDataSegmentLength: %u, protocol error.\n",
+			payload_length, conn->conn_ops->MaxXmitDataSegmentLength);
 		return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
 				buf, conn);
 	}
@@ -932,8 +928,8 @@
 		spin_unlock_bh(&conn->sess->ttt_lock);
 	} else if (hdr->flags & ISCSI_FLAG_CMD_WRITE)
 		cmd->targ_xfer_tag = 0xFFFFFFFF;
-	cmd->cmd_sn		= hdr->cmdsn;
-	cmd->exp_stat_sn	= hdr->exp_statsn;
+	cmd->cmd_sn		= be32_to_cpu(hdr->cmdsn);
+	cmd->exp_stat_sn	= be32_to_cpu(hdr->exp_statsn);
 	cmd->first_burst_len	= payload_length;
 
 	if (cmd->data_direction == DMA_FROM_DEVICE) {
@@ -952,8 +948,9 @@
 	 * Initialize struct se_cmd descriptor from target_core_mod infrastructure
 	 */
 	transport_init_se_cmd(&cmd->se_cmd, &lio_target_fabric_configfs->tf_ops,
-			conn->sess->se_sess, hdr->data_length, cmd->data_direction,
-			sam_task_attr, &cmd->sense_buffer[0]);
+			conn->sess->se_sess, be32_to_cpu(hdr->data_length),
+			cmd->data_direction, sam_task_attr,
+			cmd->sense_buffer + 2);
 
 	pr_debug("Got SCSI Command, ITT: 0x%08x, CmdSN: 0x%08x,"
 		" ExpXferLen: %u, Length: %u, CID: %hu\n", hdr->itt,
@@ -1028,7 +1025,7 @@
 				1, 0, buf, cmd);
 	}
 
-	iscsit_ack_from_expstatsn(conn, hdr->exp_statsn);
+	iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
 
 	/*
 	 * If no Immediate Data is attached, it's OK to return now.
@@ -1194,11 +1191,6 @@
 
 	hdr			= (struct iscsi_data *) buf;
 	payload_length		= ntoh24(hdr->dlength);
-	hdr->itt		= be32_to_cpu(hdr->itt);
-	hdr->ttt		= be32_to_cpu(hdr->ttt);
-	hdr->exp_statsn		= be32_to_cpu(hdr->exp_statsn);
-	hdr->datasn		= be32_to_cpu(hdr->datasn);
-	hdr->offset		= be32_to_cpu(hdr->offset);
 
 	if (!payload_length) {
 		pr_err("DataOUT payload is ZERO, protocol error.\n");
@@ -1216,10 +1208,10 @@
 	}
 	spin_unlock_bh(&conn->sess->session_stats_lock);
 
-	if (payload_length > conn->conn_ops->MaxRecvDataSegmentLength) {
+	if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) {
 		pr_err("DataSegmentLength: %u is greater than"
-			" MaxRecvDataSegmentLength: %u\n", payload_length,
-			conn->conn_ops->MaxRecvDataSegmentLength);
+			" MaxXmitDataSegmentLength: %u\n", payload_length,
+			conn->conn_ops->MaxXmitDataSegmentLength);
 		return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
 					buf, conn);
 	}
@@ -1250,7 +1242,7 @@
 	se_cmd = &cmd->se_cmd;
 	iscsit_mod_dataout_timer(cmd);
 
-	if ((hdr->offset + payload_length) > cmd->se_cmd.data_length) {
+	if ((be32_to_cpu(hdr->offset) + payload_length) > cmd->se_cmd.data_length) {
 		pr_err("DataOut Offset: %u, Length %u greater than"
 			" iSCSI Command EDTL %u, protocol error.\n",
 			hdr->offset, payload_length, cmd->se_cmd.data_length);
@@ -1333,7 +1325,8 @@
 	rx_size += payload_length;
 	iov = &cmd->iov_data[0];
 
-	iov_ret = iscsit_map_iovec(cmd, iov, hdr->offset, payload_length);
+	iov_ret = iscsit_map_iovec(cmd, iov, be32_to_cpu(hdr->offset),
+				   payload_length);
 	if (iov_ret < 0)
 		return -1;
 
@@ -1364,7 +1357,8 @@
 		u32 data_crc;
 
 		data_crc = iscsit_do_crypto_hash_sg(&conn->conn_rx_hash, cmd,
-						    hdr->offset, payload_length, padding,
+						    be32_to_cpu(hdr->offset),
+						    payload_length, padding,
 						    cmd->pad_bytes);
 
 		if (checksum != data_crc) {
@@ -1425,30 +1419,26 @@
 
 	hdr			= (struct iscsi_nopout *) buf;
 	payload_length		= ntoh24(hdr->dlength);
-	hdr->itt		= be32_to_cpu(hdr->itt);
-	hdr->ttt		= be32_to_cpu(hdr->ttt);
-	hdr->cmdsn		= be32_to_cpu(hdr->cmdsn);
-	hdr->exp_statsn		= be32_to_cpu(hdr->exp_statsn);
 
-	if ((hdr->itt == 0xFFFFFFFF) && !(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
+	if (hdr->itt == RESERVED_ITT && !(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
 		pr_err("NOPOUT ITT is reserved, but Immediate Bit is"
 			" not set, protocol error.\n");
 		return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
 					buf, conn);
 	}
 
-	if (payload_length > conn->conn_ops->MaxRecvDataSegmentLength) {
+	if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) {
 		pr_err("NOPOUT Ping Data DataSegmentLength: %u is"
-			" greater than MaxRecvDataSegmentLength: %u, protocol"
+			" greater than MaxXmitDataSegmentLength: %u, protocol"
 			" error.\n", payload_length,
-			conn->conn_ops->MaxRecvDataSegmentLength);
+			conn->conn_ops->MaxXmitDataSegmentLength);
 		return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
 					buf, conn);
 	}
 
 	pr_debug("Got NOPOUT Ping %s ITT: 0x%08x, TTT: 0x%09x,"
 		" CmdSN: 0x%08x, ExpStatSN: 0x%08x, Length: %u\n",
-		(hdr->itt == 0xFFFFFFFF) ? "Response" : "Request",
+		hdr->itt == RESERVED_ITT ? "Response" : "Request",
 		hdr->itt, hdr->ttt, hdr->cmdsn, hdr->exp_statsn,
 		payload_length);
 	/*
@@ -1458,7 +1448,7 @@
 	 * Either way, make sure we allocate an struct iscsi_cmd, as both
 	 * can contain ping data.
 	 */
-	if (hdr->ttt == 0xFFFFFFFF) {
+	if (hdr->ttt == cpu_to_be32(0xFFFFFFFF)) {
 		cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
 		if (!cmd)
 			return iscsit_add_reject(
@@ -1471,12 +1461,12 @@
 						1 : 0);
 		conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt;
 		cmd->targ_xfer_tag	= 0xFFFFFFFF;
-		cmd->cmd_sn		= hdr->cmdsn;
-		cmd->exp_stat_sn	= hdr->exp_statsn;
+		cmd->cmd_sn		= be32_to_cpu(hdr->cmdsn);
+		cmd->exp_stat_sn	= be32_to_cpu(hdr->exp_statsn);
 		cmd->data_direction	= DMA_NONE;
 	}
 
-	if (payload_length && (hdr->ttt == 0xFFFFFFFF)) {
+	if (payload_length && hdr->ttt == cpu_to_be32(0xFFFFFFFF)) {
 		rx_size = payload_length;
 		ping_data = kzalloc(payload_length + 1, GFP_KERNEL);
 		if (!ping_data) {
@@ -1556,7 +1546,7 @@
 		pr_debug("Ping Data: \"%s\"\n", ping_data);
 	}
 
-	if (hdr->itt != 0xFFFFFFFF) {
+	if (hdr->itt != RESERVED_ITT) {
 		if (!cmd) {
 			pr_err("Checking CmdSN for NOPOUT,"
 				" but cmd is NULL!\n");
@@ -1569,7 +1559,7 @@
 		list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
 		spin_unlock_bh(&conn->cmd_lock);
 
-		iscsit_ack_from_expstatsn(conn, hdr->exp_statsn);
+		iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
 
 		if (hdr->opcode & ISCSI_OP_IMMEDIATE) {
 			iscsit_add_cmd_to_response_queue(cmd, conn,
@@ -1590,11 +1580,11 @@
 		return 0;
 	}
 
-	if (hdr->ttt != 0xFFFFFFFF) {
+	if (hdr->ttt != cpu_to_be32(0xFFFFFFFF)) {
 		/*
 		 * This was a response to a unsolicited NOPIN ping.
 		 */
-		cmd = iscsit_find_cmd_from_ttt(conn, hdr->ttt);
+		cmd = iscsit_find_cmd_from_ttt(conn, be32_to_cpu(hdr->ttt));
 		if (!cmd)
 			return -1;
 
@@ -1639,12 +1629,6 @@
 	u8 function;
 
 	hdr			= (struct iscsi_tm *) buf;
-	hdr->itt		= be32_to_cpu(hdr->itt);
-	hdr->rtt		= be32_to_cpu(hdr->rtt);
-	hdr->cmdsn		= be32_to_cpu(hdr->cmdsn);
-	hdr->exp_statsn		= be32_to_cpu(hdr->exp_statsn);
-	hdr->refcmdsn		= be32_to_cpu(hdr->refcmdsn);
-	hdr->exp_datasn		= be32_to_cpu(hdr->exp_datasn);
 	hdr->flags &= ~ISCSI_FLAG_CMD_FINAL;
 	function = hdr->flags;
 
@@ -1655,9 +1639,9 @@
 
 	if ((function != ISCSI_TM_FUNC_ABORT_TASK) &&
 	    ((function != ISCSI_TM_FUNC_TASK_REASSIGN) &&
-	     (hdr->rtt != ISCSI_RESERVED_TAG))) {
+	     hdr->rtt != RESERVED_ITT)) {
 		pr_err("RefTaskTag should be set to 0xFFFFFFFF.\n");
-		hdr->rtt = ISCSI_RESERVED_TAG;
+		hdr->rtt = RESERVED_ITT;
 	}
 
 	if ((function == ISCSI_TM_FUNC_TASK_REASSIGN) &&
@@ -1669,8 +1653,8 @@
 					buf, conn);
 	}
 	if ((function != ISCSI_TM_FUNC_ABORT_TASK) &&
-	    (hdr->refcmdsn != ISCSI_RESERVED_TAG))
-		hdr->refcmdsn = ISCSI_RESERVED_TAG;
+	    be32_to_cpu(hdr->refcmdsn) != ISCSI_RESERVED_TAG)
+		hdr->refcmdsn = cpu_to_be32(ISCSI_RESERVED_TAG);
 
 	cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
 	if (!cmd)
@@ -1700,7 +1684,7 @@
 		transport_init_se_cmd(&cmd->se_cmd,
 				      &lio_target_fabric_configfs->tf_ops,
 				      conn->sess->se_sess, 0, DMA_NONE,
-				      MSG_SIMPLE_TAG, &cmd->sense_buffer[0]);
+				      MSG_SIMPLE_TAG, cmd->sense_buffer + 2);
 
 		switch (function) {
 		case ISCSI_TM_FUNC_ABORT_TASK:
@@ -1747,8 +1731,8 @@
 	cmd->immediate_cmd	= ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0);
 	cmd->init_task_tag	= hdr->itt;
 	cmd->targ_xfer_tag	= 0xFFFFFFFF;
-	cmd->cmd_sn		= hdr->cmdsn;
-	cmd->exp_stat_sn	= hdr->exp_statsn;
+	cmd->cmd_sn		= be32_to_cpu(hdr->cmdsn);
+	cmd->exp_stat_sn	= be32_to_cpu(hdr->exp_statsn);
 	se_tmr			= cmd->se_cmd.se_tmr_req;
 	tmr_req			= cmd->tmr_req;
 	/*
@@ -1832,7 +1816,7 @@
 					ISCSI_REASON_PROTOCOL_ERROR,
 					1, 0, buf, cmd);
 	}
-	iscsit_ack_from_expstatsn(conn, hdr->exp_statsn);
+	iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
 
 	if (out_of_order_cmdsn || !(hdr->opcode & ISCSI_OP_IMMEDIATE))
 		return 0;
@@ -1869,15 +1853,11 @@
 
 	hdr			= (struct iscsi_text *) buf;
 	payload_length		= ntoh24(hdr->dlength);
-	hdr->itt		= be32_to_cpu(hdr->itt);
-	hdr->ttt		= be32_to_cpu(hdr->ttt);
-	hdr->cmdsn		= be32_to_cpu(hdr->cmdsn);
-	hdr->exp_statsn		= be32_to_cpu(hdr->exp_statsn);
 
-	if (payload_length > conn->conn_ops->MaxRecvDataSegmentLength) {
+	if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) {
 		pr_err("Unable to accept text parameter length: %u"
-			"greater than MaxRecvDataSegmentLength %u.\n",
-		       payload_length, conn->conn_ops->MaxRecvDataSegmentLength);
+			"greater than MaxXmitDataSegmentLength %u.\n",
+		       payload_length, conn->conn_ops->MaxXmitDataSegmentLength);
 		return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
 					buf, conn);
 	}
@@ -1989,15 +1969,15 @@
 	cmd->immediate_cmd	= ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0);
 	conn->sess->init_task_tag = cmd->init_task_tag	= hdr->itt;
 	cmd->targ_xfer_tag	= 0xFFFFFFFF;
-	cmd->cmd_sn		= hdr->cmdsn;
-	cmd->exp_stat_sn	= hdr->exp_statsn;
+	cmd->cmd_sn		= be32_to_cpu(hdr->cmdsn);
+	cmd->exp_stat_sn	= be32_to_cpu(hdr->exp_statsn);
 	cmd->data_direction	= DMA_NONE;
 
 	spin_lock_bh(&conn->cmd_lock);
 	list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
 	spin_unlock_bh(&conn->cmd_lock);
 
-	iscsit_ack_from_expstatsn(conn, hdr->exp_statsn);
+	iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
 
 	if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
 		cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn);
@@ -2131,10 +2111,6 @@
 
 	hdr			= (struct iscsi_logout *) buf;
 	reason_code		= (hdr->flags & 0x7f);
-	hdr->itt		= be32_to_cpu(hdr->itt);
-	hdr->cid		= be16_to_cpu(hdr->cid);
-	hdr->cmdsn		= be32_to_cpu(hdr->cmdsn);
-	hdr->exp_statsn	= be32_to_cpu(hdr->exp_statsn);
 
 	if (tiqn) {
 		spin_lock(&tiqn->logout_stats.lock);
@@ -2166,9 +2142,9 @@
 	cmd->immediate_cmd      = ((hdr->opcode & ISCSI_OP_IMMEDIATE) ? 1 : 0);
 	conn->sess->init_task_tag = cmd->init_task_tag  = hdr->itt;
 	cmd->targ_xfer_tag      = 0xFFFFFFFF;
-	cmd->cmd_sn             = hdr->cmdsn;
-	cmd->exp_stat_sn        = hdr->exp_statsn;
-	cmd->logout_cid         = hdr->cid;
+	cmd->cmd_sn             = be32_to_cpu(hdr->cmdsn);
+	cmd->exp_stat_sn        = be32_to_cpu(hdr->exp_statsn);
+	cmd->logout_cid         = be16_to_cpu(hdr->cid);
 	cmd->logout_reason      = reason_code;
 	cmd->data_direction     = DMA_NONE;
 
@@ -2178,7 +2154,7 @@
 	 */
 	if ((reason_code == ISCSI_LOGOUT_REASON_CLOSE_SESSION) ||
 	   ((reason_code == ISCSI_LOGOUT_REASON_CLOSE_CONNECTION) &&
-	    (hdr->cid == conn->cid)))
+	    be16_to_cpu(hdr->cid) == conn->cid))
 		logout_remove = 1;
 
 	spin_lock_bh(&conn->cmd_lock);
@@ -2186,7 +2162,7 @@
 	spin_unlock_bh(&conn->cmd_lock);
 
 	if (reason_code != ISCSI_LOGOUT_REASON_RECOVERY)
-		iscsit_ack_from_expstatsn(conn, hdr->exp_statsn);
+		iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
 
 	/*
 	 * Immediate commands are executed, well, immediately.
@@ -2219,11 +2195,6 @@
 
 	hdr			= (struct iscsi_snack *) buf;
 	hdr->flags		&= ~ISCSI_FLAG_CMD_FINAL;
-	hdr->itt		= be32_to_cpu(hdr->itt);
-	hdr->ttt		= be32_to_cpu(hdr->ttt);
-	hdr->exp_statsn		= be32_to_cpu(hdr->exp_statsn);
-	hdr->begrun		= be32_to_cpu(hdr->begrun);
-	hdr->runlength		= be32_to_cpu(hdr->runlength);
 
 	pr_debug("Got ISCSI_INIT_SNACK, ITT: 0x%08x, ExpStatSN:"
 		" 0x%08x, Type: 0x%02x, BegRun: 0x%08x, RunLength: 0x%08x,"
@@ -2243,13 +2214,18 @@
 	switch (hdr->flags & ISCSI_FLAG_SNACK_TYPE_MASK) {
 	case 0:
 		return iscsit_handle_recovery_datain_or_r2t(conn, buf,
-			hdr->itt, hdr->ttt, hdr->begrun, hdr->runlength);
+			hdr->itt,
+			be32_to_cpu(hdr->ttt),
+			be32_to_cpu(hdr->begrun),
+			be32_to_cpu(hdr->runlength));
 	case ISCSI_FLAG_SNACK_TYPE_STATUS:
-		return iscsit_handle_status_snack(conn, hdr->itt, hdr->ttt,
-			hdr->begrun, hdr->runlength);
+		return iscsit_handle_status_snack(conn, hdr->itt,
+			be32_to_cpu(hdr->ttt),
+			be32_to_cpu(hdr->begrun), be32_to_cpu(hdr->runlength));
 	case ISCSI_FLAG_SNACK_TYPE_DATA_ACK:
-		return iscsit_handle_data_ack(conn, hdr->ttt, hdr->begrun,
-			hdr->runlength);
+		return iscsit_handle_data_ack(conn, be32_to_cpu(hdr->ttt),
+			be32_to_cpu(hdr->begrun),
+			be32_to_cpu(hdr->runlength));
 	case ISCSI_FLAG_SNACK_TYPE_RDATA:
 		/* FIXME: Support R-Data SNACK */
 		pr_err("R-Data SNACK Not Supported.\n");
@@ -2414,7 +2390,7 @@
 	hdr			= (struct iscsi_async *) cmd->pdu;
 	hdr->opcode		= ISCSI_OP_ASYNC_EVENT;
 	hdr->flags		= ISCSI_FLAG_CMD_FINAL;
-	cmd->init_task_tag	= 0xFFFFFFFF;
+	cmd->init_task_tag	= RESERVED_ITT;
 	cmd->targ_xfer_tag	= 0xFFFFFFFF;
 	put_unaligned_be64(0xFFFFFFFFFFFFFFFFULL, &hdr->rsvd4[0]);
 	cmd->stat_sn		= conn->stat_sn++;
@@ -2536,12 +2512,17 @@
 	else
 		put_unaligned_le64(0xFFFFFFFFFFFFFFFFULL, &hdr->lun);
 
-	hdr->itt		= cpu_to_be32(cmd->init_task_tag);
-	hdr->ttt		= (hdr->flags & ISCSI_FLAG_DATA_ACK) ?
-				   cpu_to_be32(cmd->targ_xfer_tag) :
-				   0xFFFFFFFF;
-	hdr->statsn		= (set_statsn) ? cpu_to_be32(cmd->stat_sn) :
-						0xFFFFFFFF;
+	hdr->itt		= cmd->init_task_tag;
+
+	if (hdr->flags & ISCSI_FLAG_DATA_ACK)
+		hdr->ttt		= cpu_to_be32(cmd->targ_xfer_tag);
+	else
+		hdr->ttt		= cpu_to_be32(0xFFFFFFFF);
+	if (set_statsn)
+		hdr->statsn		= cpu_to_be32(cmd->stat_sn);
+	else
+		hdr->statsn		= cpu_to_be32(0xFFFFFFFF);
+
 	hdr->exp_cmdsn		= cpu_to_be32(conn->sess->exp_cmd_sn);
 	hdr->max_cmdsn		= cpu_to_be32(conn->sess->max_cmd_sn);
 	hdr->datasn		= cpu_to_be32(datain.data_sn);
@@ -2708,7 +2689,7 @@
 	hdr->opcode		= ISCSI_OP_LOGOUT_RSP;
 	hdr->flags		|= ISCSI_FLAG_CMD_FINAL;
 	hdr->response		= cmd->logout_response;
-	hdr->itt		= cpu_to_be32(cmd->init_task_tag);
+	hdr->itt		= cmd->init_task_tag;
 	cmd->stat_sn		= conn->stat_sn++;
 	hdr->statsn		= cpu_to_be32(cmd->stat_sn);
 
@@ -2759,7 +2740,7 @@
 	memset(hdr, 0, ISCSI_HDR_LEN);
 	hdr->opcode		= ISCSI_OP_NOOP_IN;
 	hdr->flags		|= ISCSI_FLAG_CMD_FINAL;
-	hdr->itt		= cpu_to_be32(cmd->init_task_tag);
+	hdr->itt		= cmd->init_task_tag;
 	hdr->ttt		= cpu_to_be32(cmd->targ_xfer_tag);
 	cmd->stat_sn		= conn->stat_sn;
 	hdr->statsn		= cpu_to_be32(cmd->stat_sn);
@@ -2816,7 +2797,7 @@
 	hdr->flags		|= ISCSI_FLAG_CMD_FINAL;
 	hton24(hdr->dlength, cmd->buf_ptr_size);
 	put_unaligned_le64(0xFFFFFFFFFFFFFFFFULL, &hdr->lun);
-	hdr->itt		= cpu_to_be32(cmd->init_task_tag);
+	hdr->itt		= cmd->init_task_tag;
 	hdr->ttt		= cpu_to_be32(cmd->targ_xfer_tag);
 	cmd->stat_sn		= conn->stat_sn++;
 	hdr->statsn		= cpu_to_be32(cmd->stat_sn);
@@ -2906,7 +2887,7 @@
 	hdr->flags		|= ISCSI_FLAG_CMD_FINAL;
 	int_to_scsilun(cmd->se_cmd.orig_fe_lun,
 			(struct scsi_lun *)&hdr->lun);
-	hdr->itt		= cpu_to_be32(cmd->init_task_tag);
+	hdr->itt		= cmd->init_task_tag;
 	spin_lock_bh(&conn->sess->ttt_lock);
 	r2t->targ_xfer_tag	= conn->sess->targ_xfer_tag++;
 	if (r2t->targ_xfer_tag == 0xFFFFFFFF)
@@ -3074,7 +3055,7 @@
 	}
 	hdr->response		= cmd->iscsi_response;
 	hdr->cmd_status		= cmd->se_cmd.scsi_status;
-	hdr->itt		= cpu_to_be32(cmd->init_task_tag);
+	hdr->itt		= cmd->init_task_tag;
 	hdr->statsn		= cpu_to_be32(cmd->stat_sn);
 
 	iscsit_increment_maxcmdsn(cmd, conn->sess);
@@ -3092,15 +3073,18 @@
 	if (cmd->se_cmd.sense_buffer &&
 	   ((cmd->se_cmd.se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ||
 	    (cmd->se_cmd.se_cmd_flags & SCF_EMULATED_TASK_SENSE))) {
+		put_unaligned_be16(cmd->se_cmd.scsi_sense_length, cmd->sense_buffer);
+		cmd->se_cmd.scsi_sense_length += sizeof (__be16);
+
 		padding		= -(cmd->se_cmd.scsi_sense_length) & 3;
-		hton24(hdr->dlength, cmd->se_cmd.scsi_sense_length);
-		iov[iov_count].iov_base	= cmd->se_cmd.sense_buffer;
+		hton24(hdr->dlength, (u32)cmd->se_cmd.scsi_sense_length);
+		iov[iov_count].iov_base	= cmd->sense_buffer;
 		iov[iov_count++].iov_len =
 				(cmd->se_cmd.scsi_sense_length + padding);
 		tx_size += cmd->se_cmd.scsi_sense_length;
 
 		if (padding) {
-			memset(cmd->se_cmd.sense_buffer +
+			memset(cmd->sense_buffer +
 				cmd->se_cmd.scsi_sense_length, 0, padding);
 			tx_size += padding;
 			pr_debug("Adding %u bytes of padding to"
@@ -3109,7 +3093,7 @@
 
 		if (conn->conn_ops->DataDigest) {
 			iscsit_do_crypto_hash_buf(&conn->conn_tx_hash,
-				cmd->se_cmd.sense_buffer,
+				cmd->sense_buffer,
 				(cmd->se_cmd.scsi_sense_length + padding),
 				0, NULL, (u8 *)&cmd->data_crc);
 
@@ -3184,7 +3168,7 @@
 	hdr->opcode		= ISCSI_OP_SCSI_TMFUNC_RSP;
 	hdr->flags		= ISCSI_FLAG_CMD_FINAL;
 	hdr->response		= iscsit_convert_tcm_tmr_rsp(se_tmr);
-	hdr->itt		= cpu_to_be32(cmd->init_task_tag);
+	hdr->itt		= cmd->init_task_tag;
 	cmd->stat_sn		= conn->stat_sn++;
 	hdr->statsn		= cpu_to_be32(cmd->stat_sn);
 
@@ -3236,7 +3220,7 @@
 		struct sockaddr_in * sock_in =
 			(struct sockaddr_in *)&np->np_sockaddr;
 
-		if (sock_in->sin_addr.s_addr == INADDR_ANY)
+		if (sock_in->sin_addr.s_addr == htonl(INADDR_ANY))
 			ret = true;
 	}
 
@@ -3271,7 +3255,6 @@
 		len += 1;
 
 		if ((len + payload_len) > buffer_len) {
-			spin_unlock(&tiqn->tiqn_tpg_lock);
 			end_of_buf = 1;
 			goto eob;
 		}
@@ -3358,7 +3341,7 @@
 	hdr->opcode		= ISCSI_OP_TEXT_RSP;
 	hdr->flags		|= ISCSI_FLAG_CMD_FINAL;
 	hton24(hdr->dlength, text_length);
-	hdr->itt		= cpu_to_be32(cmd->init_task_tag);
+	hdr->itt		= cmd->init_task_tag;
 	hdr->ttt		= cpu_to_be32(cmd->targ_xfer_tag);
 	cmd->stat_sn		= conn->stat_sn++;
 	hdr->statsn		= cpu_to_be32(cmd->stat_sn);
@@ -3424,6 +3407,7 @@
 	hdr->opcode		= ISCSI_OP_REJECT;
 	hdr->flags		|= ISCSI_FLAG_CMD_FINAL;
 	hton24(hdr->dlength, ISCSI_HDR_LEN);
+	hdr->ffffffff		= cpu_to_be32(0xffffffff);
 	cmd->stat_sn		= conn->stat_sn++;
 	hdr->statsn		= cpu_to_be32(cmd->stat_sn);
 	hdr->exp_cmdsn	= cpu_to_be32(conn->sess->exp_cmd_sn);
diff --git a/drivers/target/iscsi/iscsi_target.h b/drivers/target/iscsi/iscsi_target.h
index 12abb4c..f1e4f31 100644
--- a/drivers/target/iscsi/iscsi_target.h
+++ b/drivers/target/iscsi/iscsi_target.h
@@ -38,4 +38,9 @@
 extern struct kmem_cache *lio_qr_cache;
 extern struct kmem_cache *lio_r2t_cache;
 
+extern struct idr sess_idr;
+extern struct mutex auth_id_lock;
+extern spinlock_t sess_idr_lock;
+
+
 #endif   /*** ISCSI_TARGET_H ***/
diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c
index a7b25e78..ff6fd4f 100644
--- a/drivers/target/iscsi/iscsi_target_configfs.c
+++ b/drivers/target/iscsi/iscsi_target_configfs.c
@@ -135,7 +135,7 @@
 
 #define MAX_PORTAL_LEN		256
 
-struct se_tpg_np *lio_target_call_addnptotpg(
+static struct se_tpg_np *lio_target_call_addnptotpg(
 	struct se_portal_group *se_tpg,
 	struct config_group *group,
 	const char *name)
@@ -1034,6 +1034,9 @@
 DEF_TPG_PARAM(MaxRecvDataSegmentLength);
 TPG_PARAM_ATTR(MaxRecvDataSegmentLength, S_IRUGO | S_IWUSR);
 
+DEF_TPG_PARAM(MaxXmitDataSegmentLength);
+TPG_PARAM_ATTR(MaxXmitDataSegmentLength, S_IRUGO | S_IWUSR);
+
 DEF_TPG_PARAM(MaxBurstLength);
 TPG_PARAM_ATTR(MaxBurstLength, S_IRUGO | S_IWUSR);
 
@@ -1079,6 +1082,7 @@
 	&iscsi_tpg_param_InitialR2T.attr,
 	&iscsi_tpg_param_ImmediateData.attr,
 	&iscsi_tpg_param_MaxRecvDataSegmentLength.attr,
+	&iscsi_tpg_param_MaxXmitDataSegmentLength.attr,
 	&iscsi_tpg_param_MaxBurstLength.attr,
 	&iscsi_tpg_param_FirstBurstLength.attr,
 	&iscsi_tpg_param_DefaultTime2Wait.attr,
@@ -1166,7 +1170,7 @@
 
 /* Start items for lio_target_tiqn_cit */
 
-struct se_portal_group *lio_target_tiqn_addtpg(
+static struct se_portal_group *lio_target_tiqn_addtpg(
 	struct se_wwn *wwn,
 	struct config_group *group,
 	const char *name)
@@ -1216,7 +1220,7 @@
 	return NULL;
 }
 
-void lio_target_tiqn_deltpg(struct se_portal_group *se_tpg)
+static void lio_target_tiqn_deltpg(struct se_portal_group *se_tpg)
 {
 	struct iscsi_portal_group *tpg;
 	struct iscsi_tiqn *tiqn;
@@ -1248,7 +1252,7 @@
 	NULL,
 };
 
-struct se_wwn *lio_target_call_coreaddtiqn(
+static struct se_wwn *lio_target_call_coreaddtiqn(
 	struct target_fabric_configfs *tf,
 	struct config_group *group,
 	const char *name)
@@ -1296,7 +1300,7 @@
 	return &tiqn->tiqn_wwn;
 }
 
-void lio_target_call_coredeltiqn(
+static void lio_target_call_coredeltiqn(
 	struct se_wwn *wwn)
 {
 	struct iscsi_tiqn *tiqn = container_of(wwn, struct iscsi_tiqn, tiqn_wwn);
@@ -1471,7 +1475,8 @@
 {
 	struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
 
-	return cmd->init_task_tag;
+	/* only used for printks or comparism with ->ref_task_tag */
+	return (__force u32)cmd->init_task_tag;
 }
 
 static int iscsi_get_cmd_state(struct se_cmd *se_cmd)
@@ -1542,29 +1547,6 @@
 	return 0;
 }
 
-static u16 lio_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length)
-{
-	unsigned char *buffer = se_cmd->sense_buffer;
-	/*
-	 * From RFC-3720 10.4.7.  Data Segment - Sense and Response Data Segment
-	 * 16-bit SenseLength.
-	 */
-	buffer[0] = ((sense_length >> 8) & 0xff);
-	buffer[1] = (sense_length & 0xff);
-	/*
-	 * Return two byte offset into allocated sense_buffer.
-	 */
-	return 2;
-}
-
-static u16 lio_get_fabric_sense_len(void)
-{
-	/*
-	 * Return two byte offset into allocated sense_buffer.
-	 */
-	return 2;
-}
-
 static int lio_queue_tm_rsp(struct se_cmd *se_cmd)
 {
 	struct iscsi_cmd *cmd = container_of(se_cmd, struct iscsi_cmd, se_cmd);
@@ -1748,8 +1730,6 @@
 	fabric->tf_ops.queue_data_in = &lio_queue_data_in;
 	fabric->tf_ops.queue_status = &lio_queue_status;
 	fabric->tf_ops.queue_tm_rsp = &lio_queue_tm_rsp;
-	fabric->tf_ops.set_fabric_sense_len = &lio_set_fabric_sense_len;
-	fabric->tf_ops.get_fabric_sense_len = &lio_get_fabric_sense_len;
 	/*
 	 * Setup function pointers for generic logic in target_core_fabric_configfs.c
 	 */
diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h
index 8a908b2..2ba9f9b 100644
--- a/drivers/target/iscsi/iscsi_target_core.h
+++ b/drivers/target/iscsi/iscsi_target_core.h
@@ -25,10 +25,10 @@
 #define NA_DATAOUT_TIMEOUT_RETRIES	5
 #define NA_DATAOUT_TIMEOUT_RETRIES_MAX	15
 #define NA_DATAOUT_TIMEOUT_RETRIES_MIN	1
-#define NA_NOPIN_TIMEOUT		5
+#define NA_NOPIN_TIMEOUT		15
 #define NA_NOPIN_TIMEOUT_MAX		60
 #define NA_NOPIN_TIMEOUT_MIN		3
-#define NA_NOPIN_RESPONSE_TIMEOUT	5
+#define NA_NOPIN_RESPONSE_TIMEOUT	30
 #define NA_NOPIN_RESPONSE_TIMEOUT_MAX	60
 #define NA_NOPIN_RESPONSE_TIMEOUT_MIN	3
 #define NA_RANDOM_DATAIN_PDU_OFFSETS	0
@@ -239,6 +239,7 @@
 	u8	HeaderDigest;			/* [0,1] == [None,CRC32C] */
 	u8	DataDigest;			/* [0,1] == [None,CRC32C] */
 	u32	MaxRecvDataSegmentLength;	/* [512..2**24-1] */
+	u32	MaxXmitDataSegmentLength;	/* [512..2**24-1] */
 	u8	OFMarker;			/* [0,1] == [No,Yes] */
 	u8	IFMarker;			/* [0,1] == [No,Yes] */
 	u32	OFMarkInt;			/* [1..65535] */
@@ -360,7 +361,7 @@
 	/* Command flags */
 	enum cmd_flags_table	cmd_flags;
 	/* Initiator Task Tag assigned from Initiator */
-	u32			init_task_tag;
+	itt_t			init_task_tag;
 	/* Target Transfer Tag assigned from Target */
 	u32			targ_xfer_tag;
 	/* CmdSN assigned from Initiator */
@@ -478,7 +479,6 @@
 
 struct iscsi_tmr_req {
 	bool			task_reassign:1;
-	u32			ref_cmd_sn;
 	u32			exp_data_sn;
 	struct iscsi_cmd	*ref_cmd;
 	struct iscsi_conn_recovery *conn_recovery;
@@ -505,7 +505,7 @@
 	u32			auth_id;
 	u32			conn_flags;
 	/* Used for iscsi_tx_login_rsp() */
-	u32			login_itt;
+	itt_t			login_itt;
 	u32			exp_statsn;
 	/* Per connection status sequence number */
 	u32			stat_sn;
@@ -578,6 +578,7 @@
 	u16			cid;
 	u32			cmd_count;
 	u32			maxrecvdatasegmentlength;
+	u32			maxxmitdatasegmentlength;
 	int			ready_for_reallegiance;
 	struct list_head	conn_recovery_cmd_list;
 	spinlock_t		conn_recovery_cmd_lock;
@@ -597,7 +598,7 @@
 	/* state session is currently in */
 	u32			session_state;
 	/* session wide counter: initiator assigned task tag */
-	u32			init_task_tag;
+	itt_t			init_task_tag;
 	/* session wide counter: target assigned task tag */
 	u32			targ_xfer_tag;
 	u32			cmdsn_window;
@@ -663,7 +664,7 @@
 	u8 version_max;
 	char isid[6];
 	u32 cmd_sn;
-	u32 init_task_tag;
+	itt_t init_task_tag;
 	u32 initial_exp_statsn;
 	u32 rsp_length;
 	u16 cid;
diff --git a/drivers/target/iscsi/iscsi_target_erl0.c b/drivers/target/iscsi/iscsi_target_erl0.c
index 1a02016..8aacf61 100644
--- a/drivers/target/iscsi/iscsi_target_erl0.c
+++ b/drivers/target/iscsi/iscsi_target_erl0.c
@@ -48,9 +48,9 @@
 	if (cmd->unsolicited_data) {
 		cmd->seq_start_offset = cmd->write_data_done;
 		cmd->seq_end_offset = (cmd->write_data_done +
-			(cmd->se_cmd.data_length >
-			 conn->sess->sess_ops->FirstBurstLength) ?
-			conn->sess->sess_ops->FirstBurstLength : cmd->se_cmd.data_length);
+			((cmd->se_cmd.data_length >
+			  conn->sess->sess_ops->FirstBurstLength) ?
+			 conn->sess->sess_ops->FirstBurstLength : cmd->se_cmd.data_length));
 		return;
 	}
 
@@ -95,14 +95,15 @@
 	 */
 	if (conn->sess->sess_ops->DataSequenceInOrder) {
 		if ((cmd->cmd_flags & ICF_WITHIN_COMMAND_RECOVERY) &&
-		    (cmd->write_data_done != hdr->offset))
+		    cmd->write_data_done != be32_to_cpu(hdr->offset))
 			goto dump;
 
 		cmd->cmd_flags &= ~ICF_WITHIN_COMMAND_RECOVERY;
 	} else {
 		struct iscsi_seq *seq;
 
-		seq = iscsit_get_seq_holder(cmd, hdr->offset, payload_length);
+		seq = iscsit_get_seq_holder(cmd, be32_to_cpu(hdr->offset),
+					    payload_length);
 		if (!seq)
 			return DATAOUT_CANNOT_RECOVER;
 		/*
@@ -111,15 +112,15 @@
 		cmd->seq_ptr = seq;
 
 		if (conn->sess->sess_ops->DataPDUInOrder) {
-			if ((seq->status ==
-			     DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY) &&
-			   ((seq->offset != hdr->offset) ||
-			    (seq->data_sn != hdr->datasn)))
+			if (seq->status ==
+			    DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY &&
+			   (seq->offset != be32_to_cpu(hdr->offset) ||
+			    seq->data_sn != be32_to_cpu(hdr->datasn)))
 				goto dump;
 		} else {
-			if ((seq->status ==
-			     DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY) &&
-			    (seq->data_sn != hdr->datasn))
+			if (seq->status ==
+			     DATAOUT_SEQUENCE_WITHIN_COMMAND_RECOVERY &&
+			    seq->data_sn != be32_to_cpu(hdr->datasn))
 				goto dump;
 		}
 
@@ -148,12 +149,12 @@
 	u32 payload_length = ntoh24(hdr->dlength);
 
 
-	if ((hdr->offset < cmd->seq_start_offset) ||
-	   ((hdr->offset + payload_length) > cmd->seq_end_offset)) {
+	if ((be32_to_cpu(hdr->offset) < cmd->seq_start_offset) ||
+	   ((be32_to_cpu(hdr->offset) + payload_length) > cmd->seq_end_offset)) {
 		pr_err("Command ITT: 0x%08x with Offset: %u,"
 		" Length: %u outside of Unsolicited Sequence %u:%u while"
 		" DataSequenceInOrder=Yes.\n", cmd->init_task_tag,
-		hdr->offset, payload_length, cmd->seq_start_offset,
+		be32_to_cpu(hdr->offset), payload_length, cmd->seq_start_offset,
 			cmd->seq_end_offset);
 		return DATAOUT_CANNOT_RECOVER;
 	}
@@ -236,12 +237,12 @@
 		 * fullfilling an Recovery R2T, it's best to just dump the
 		 * payload here, instead of erroring out.
 		 */
-		if ((hdr->offset < cmd->seq_start_offset) ||
-		   ((hdr->offset + payload_length) > cmd->seq_end_offset)) {
+		if ((be32_to_cpu(hdr->offset) < cmd->seq_start_offset) ||
+		   ((be32_to_cpu(hdr->offset) + payload_length) > cmd->seq_end_offset)) {
 			pr_err("Command ITT: 0x%08x with Offset: %u,"
 			" Length: %u outside of Sequence %u:%u while"
 			" DataSequenceInOrder=Yes.\n", cmd->init_task_tag,
-			hdr->offset, payload_length, cmd->seq_start_offset,
+			be32_to_cpu(hdr->offset), payload_length, cmd->seq_start_offset,
 				cmd->seq_end_offset);
 
 			if (iscsit_dump_data_payload(conn, payload_length, 1) < 0)
@@ -251,7 +252,8 @@
 
 		next_burst_len = (cmd->next_burst_len + payload_length);
 	} else {
-		seq = iscsit_get_seq_holder(cmd, hdr->offset, payload_length);
+		seq = iscsit_get_seq_holder(cmd, be32_to_cpu(hdr->offset),
+					    payload_length);
 		if (!seq)
 			return DATAOUT_CANNOT_RECOVER;
 		/*
@@ -366,16 +368,16 @@
 		data_sn = seq->data_sn;
 	}
 
-	if (hdr->datasn > data_sn) {
+	if (be32_to_cpu(hdr->datasn) > data_sn) {
 		pr_err("Command ITT: 0x%08x, received DataSN: 0x%08x"
 			" higher than expected 0x%08x.\n", cmd->init_task_tag,
-				hdr->datasn, data_sn);
+				be32_to_cpu(hdr->datasn), data_sn);
 		recovery = 1;
 		goto recover;
-	} else if (hdr->datasn < data_sn) {
+	} else if (be32_to_cpu(hdr->datasn) < data_sn) {
 		pr_err("Command ITT: 0x%08x, received DataSN: 0x%08x"
 			" lower than expected 0x%08x, discarding payload.\n",
-			cmd->init_task_tag, hdr->datasn, data_sn);
+			cmd->init_task_tag, be32_to_cpu(hdr->datasn), data_sn);
 		dump = 1;
 		goto dump;
 	}
@@ -415,26 +417,27 @@
 	 * error has occured and fail the connection.
 	 */
 	if (conn->sess->sess_ops->DataSequenceInOrder) {
-		if (hdr->offset != cmd->write_data_done) {
+		if (be32_to_cpu(hdr->offset) != cmd->write_data_done) {
 			pr_err("Command ITT: 0x%08x, received offset"
 			" %u different than expected %u.\n", cmd->init_task_tag,
-				hdr->offset, cmd->write_data_done);
+				be32_to_cpu(hdr->offset), cmd->write_data_done);
 			recovery = 1;
 			goto recover;
 		}
 	} else {
 		struct iscsi_seq *seq = cmd->seq_ptr;
 
-		if (hdr->offset > seq->offset) {
+		if (be32_to_cpu(hdr->offset) > seq->offset) {
 			pr_err("Command ITT: 0x%08x, received offset"
 			" %u greater than expected %u.\n", cmd->init_task_tag,
-				hdr->offset, seq->offset);
+				be32_to_cpu(hdr->offset), seq->offset);
 			recovery = 1;
 			goto recover;
-		} else if (hdr->offset < seq->offset) {
+		} else if (be32_to_cpu(hdr->offset) < seq->offset) {
 			pr_err("Command ITT: 0x%08x, received offset"
 			" %u less than expected %u, discarding payload.\n",
-				cmd->init_task_tag, hdr->offset, seq->offset);
+				cmd->init_task_tag, be32_to_cpu(hdr->offset),
+				seq->offset);
 			dump = 1;
 			goto dump;
 		}
@@ -453,7 +456,7 @@
 		return DATAOUT_CANNOT_RECOVER;
 
 	return (recovery) ? iscsit_recover_dataout_sequence(cmd,
-		hdr->offset, payload_length) :
+		be32_to_cpu(hdr->offset), payload_length) :
 	       (dump) ? DATAOUT_WITHIN_COMMAND_RECOVERY : DATAOUT_NORMAL;
 }
 
@@ -465,7 +468,8 @@
 	struct iscsi_data *hdr = (struct iscsi_data *) buf;
 	u32 payload_length = ntoh24(hdr->dlength);
 
-	pdu = iscsit_get_pdu_holder(cmd, hdr->offset, payload_length);
+	pdu = iscsit_get_pdu_holder(cmd, be32_to_cpu(hdr->offset),
+				    payload_length);
 	if (!pdu)
 		return DATAOUT_CANNOT_RECOVER;
 
@@ -479,7 +483,7 @@
 	case ISCSI_PDU_RECEIVED_OK:
 		pr_err("Command ITT: 0x%08x received already gotten"
 			" Offset: %u, Length: %u\n", cmd->init_task_tag,
-				hdr->offset, payload_length);
+				be32_to_cpu(hdr->offset), payload_length);
 		return iscsit_dump_data_payload(cmd->conn, payload_length, 1);
 	default:
 		return DATAOUT_CANNOT_RECOVER;
@@ -553,7 +557,7 @@
 	if (cmd->unsolicited_data) {
 		if ((cmd->first_burst_len + payload_length) ==
 		     conn->sess->sess_ops->FirstBurstLength) {
-			if (iscsit_dataout_update_r2t(cmd, hdr->offset,
+			if (iscsit_dataout_update_r2t(cmd, be32_to_cpu(hdr->offset),
 					payload_length) < 0)
 				return DATAOUT_CANNOT_RECOVER;
 			send_r2t = 1;
@@ -561,7 +565,8 @@
 
 		if (!conn->sess->sess_ops->DataPDUInOrder) {
 			ret = iscsit_dataout_update_datapduinorder_no(cmd,
-				hdr->datasn, (hdr->flags & ISCSI_FLAG_CMD_FINAL));
+				be32_to_cpu(hdr->datasn),
+				(hdr->flags & ISCSI_FLAG_CMD_FINAL));
 			if (ret == DATAOUT_CANNOT_RECOVER)
 				return ret;
 		}
@@ -586,7 +591,8 @@
 		if (conn->sess->sess_ops->DataSequenceInOrder) {
 			if ((cmd->next_burst_len + payload_length) ==
 			     conn->sess->sess_ops->MaxBurstLength) {
-				if (iscsit_dataout_update_r2t(cmd, hdr->offset,
+				if (iscsit_dataout_update_r2t(cmd,
+						be32_to_cpu(hdr->offset),
 						payload_length) < 0)
 					return DATAOUT_CANNOT_RECOVER;
 				send_r2t = 1;
@@ -594,7 +600,7 @@
 
 			if (!conn->sess->sess_ops->DataPDUInOrder) {
 				ret = iscsit_dataout_update_datapduinorder_no(
-						cmd, hdr->datasn,
+						cmd, be32_to_cpu(hdr->datasn),
 						(hdr->flags & ISCSI_FLAG_CMD_FINAL));
 				if (ret == DATAOUT_CANNOT_RECOVER)
 					return ret;
@@ -610,7 +616,8 @@
 
 			if ((seq->next_burst_len + payload_length) ==
 			     seq->xfer_len) {
-				if (iscsit_dataout_update_r2t(cmd, hdr->offset,
+				if (iscsit_dataout_update_r2t(cmd,
+						be32_to_cpu(hdr->offset),
 						payload_length) < 0)
 					return DATAOUT_CANNOT_RECOVER;
 				send_r2t = 1;
@@ -618,7 +625,7 @@
 
 			if (!conn->sess->sess_ops->DataPDUInOrder) {
 				ret = iscsit_dataout_update_datapduinorder_no(
-						cmd, hdr->datasn,
+						cmd, be32_to_cpu(hdr->datasn),
 						(hdr->flags & ISCSI_FLAG_CMD_FINAL));
 				if (ret == DATAOUT_CANNOT_RECOVER)
 					return ret;
@@ -678,14 +685,15 @@
 	}
 
 recover:
-	return iscsit_recover_dataout_sequence(cmd, hdr->offset, payload_length);
+	return iscsit_recover_dataout_sequence(cmd, be32_to_cpu(hdr->offset),
+						payload_length);
 }
 
 /*
  *	Called from iscsit_handle_data_out() before DataOUT Payload is received
  *	and CRC computed.
  */
-extern int iscsit_check_pre_dataout(
+int iscsit_check_pre_dataout(
 	struct iscsi_cmd *cmd,
 	unsigned char *buf)
 {
@@ -789,7 +797,7 @@
 	target_put_session(sess->se_sess);
 }
 
-extern void iscsit_start_time2retain_handler(struct iscsi_session *sess)
+void iscsit_start_time2retain_handler(struct iscsi_session *sess)
 {
 	int tpg_active;
 	/*
@@ -822,7 +830,7 @@
 /*
  *	Called with spin_lock_bh(&struct se_portal_group->session_lock) held
  */
-extern int iscsit_stop_time2retain_timer(struct iscsi_session *sess)
+int iscsit_stop_time2retain_timer(struct iscsi_session *sess)
 {
 	struct iscsi_portal_group *tpg = ISCSI_TPG_S(sess);
 	struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
@@ -926,7 +934,7 @@
 	}
 }
 
-extern void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn)
+void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn)
 {
 	spin_lock_bh(&conn->state_lock);
 	if (atomic_read(&conn->connection_exit)) {
diff --git a/drivers/target/iscsi/iscsi_target_erl1.c b/drivers/target/iscsi/iscsi_target_erl1.c
index 3df8a2c..21f29d9 100644
--- a/drivers/target/iscsi/iscsi_target_erl1.c
+++ b/drivers/target/iscsi/iscsi_target_erl1.c
@@ -466,7 +466,7 @@
 int iscsit_handle_recovery_datain_or_r2t(
 	struct iscsi_conn *conn,
 	unsigned char *buf,
-	u32 init_task_tag,
+	itt_t init_task_tag,
 	u32 targ_xfer_tag,
 	u32 begrun,
 	u32 runlength)
@@ -498,7 +498,7 @@
 /* #warning FIXME: Status SNACK needs to be dependent on OPCODE!!! */
 int iscsit_handle_status_snack(
 	struct iscsi_conn *conn,
-	u32 init_task_tag,
+	itt_t init_task_tag,
 	u32 targ_xfer_tag,
 	u32 begrun,
 	u32 runlength)
diff --git a/drivers/target/iscsi/iscsi_target_erl1.h b/drivers/target/iscsi/iscsi_target_erl1.h
index 85e67e2..2a3ebf1 100644
--- a/drivers/target/iscsi/iscsi_target_erl1.h
+++ b/drivers/target/iscsi/iscsi_target_erl1.h
@@ -7,8 +7,8 @@
 extern int iscsit_create_recovery_datain_values_datasequenceinorder_no(
 			struct iscsi_cmd *, struct iscsi_datain_req *);
 extern int iscsit_handle_recovery_datain_or_r2t(struct iscsi_conn *, unsigned char *,
-			u32, u32, u32, u32);
-extern int iscsit_handle_status_snack(struct iscsi_conn *, u32, u32,
+			itt_t, u32, u32, u32);
+extern int iscsit_handle_status_snack(struct iscsi_conn *, itt_t, u32,
 			u32, u32);
 extern int iscsit_handle_data_ack(struct iscsi_conn *, u32, u32, u32);
 extern int iscsit_dataout_datapduinorder_no_fbit(struct iscsi_cmd *, struct iscsi_pdu *);
diff --git a/drivers/target/iscsi/iscsi_target_erl2.c b/drivers/target/iscsi/iscsi_target_erl2.c
index 65aac14..17d8c20 100644
--- a/drivers/target/iscsi/iscsi_target_erl2.c
+++ b/drivers/target/iscsi/iscsi_target_erl2.c
@@ -36,7 +36,7 @@
  */
 void iscsit_create_conn_recovery_datain_values(
 	struct iscsi_cmd *cmd,
-	u32 exp_data_sn)
+	__be32 exp_data_sn)
 {
 	u32 data_sn = 0;
 	struct iscsi_conn *conn = cmd->conn;
@@ -44,7 +44,7 @@
 	cmd->next_burst_len = 0;
 	cmd->read_data_done = 0;
 
-	while (exp_data_sn > data_sn) {
+	while (be32_to_cpu(exp_data_sn) > data_sn) {
 		if ((cmd->next_burst_len +
 		     conn->conn_ops->MaxRecvDataSegmentLength) <
 		     conn->sess->sess_ops->MaxBurstLength) {
@@ -193,15 +193,13 @@
 	return 0;
 }
 
-int iscsit_remove_inactive_connection_recovery_entry(
+static void iscsit_remove_inactive_connection_recovery_entry(
 	struct iscsi_conn_recovery *cr,
 	struct iscsi_session *sess)
 {
 	spin_lock(&sess->cr_i_lock);
 	list_del(&cr->cr_list);
 	spin_unlock(&sess->cr_i_lock);
-
-	return 0;
 }
 
 /*
@@ -421,6 +419,7 @@
 	cr->cid = conn->cid;
 	cr->cmd_count = cmd_count;
 	cr->maxrecvdatasegmentlength = conn->conn_ops->MaxRecvDataSegmentLength;
+	cr->maxxmitdatasegmentlength = conn->conn_ops->MaxXmitDataSegmentLength;
 	cr->sess = conn->sess;
 
 	iscsit_attach_inactive_connection_recovery_entry(conn->sess, cr);
diff --git a/drivers/target/iscsi/iscsi_target_erl2.h b/drivers/target/iscsi/iscsi_target_erl2.h
index 22f8d24..63f2501 100644
--- a/drivers/target/iscsi/iscsi_target_erl2.h
+++ b/drivers/target/iscsi/iscsi_target_erl2.h
@@ -1,7 +1,7 @@
 #ifndef ISCSI_TARGET_ERL2_H
 #define ISCSI_TARGET_ERL2_H
 
-extern void iscsit_create_conn_recovery_datain_values(struct iscsi_cmd *, u32);
+extern void iscsit_create_conn_recovery_datain_values(struct iscsi_cmd *, __be32);
 extern void iscsit_create_conn_recovery_dataout_values(struct iscsi_cmd *);
 extern struct iscsi_conn_recovery *iscsit_get_inactive_connection_recovery_entry(
 			struct iscsi_session *, u16);
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
index 6aba439..cdc8a10 100644
--- a/drivers/target/iscsi/iscsi_target_login.c
+++ b/drivers/target/iscsi/iscsi_target_login.c
@@ -39,10 +39,6 @@
 #include "iscsi_target.h"
 #include "iscsi_target_parameters.h"
 
-extern struct idr sess_idr;
-extern struct mutex auth_id_lock;
-extern spinlock_t sess_idr_lock;
-
 static int iscsi_login_init_conn(struct iscsi_conn *conn)
 {
 	INIT_LIST_HEAD(&conn->conn_list);
@@ -196,10 +192,10 @@
 static void iscsi_login_set_conn_values(
 	struct iscsi_session *sess,
 	struct iscsi_conn *conn,
-	u16 cid)
+	__be16 cid)
 {
 	conn->sess		= sess;
-	conn->cid		= cid;
+	conn->cid		= be16_to_cpu(cid);
 	/*
 	 * Generate a random Status sequence number (statsn) for the new
 	 * iSCSI connection.
@@ -234,7 +230,7 @@
 	iscsi_login_set_conn_values(sess, conn, pdu->cid);
 	sess->init_task_tag	= pdu->itt;
 	memcpy(&sess->isid, pdu->isid, 6);
-	sess->exp_cmd_sn	= pdu->cmdsn;
+	sess->exp_cmd_sn	= be32_to_cpu(pdu->cmdsn);
 	INIT_LIST_HEAD(&sess->sess_conn_list);
 	INIT_LIST_HEAD(&sess->sess_ooo_cmdsn_list);
 	INIT_LIST_HEAD(&sess->cr_active_list);
@@ -275,7 +271,7 @@
 	 * The FFP CmdSN window values will be allocated from the TPG's
 	 * Initiator Node's ACL once the login has been successfully completed.
 	 */
-	sess->max_cmd_sn	= pdu->cmdsn;
+	sess->max_cmd_sn	= be32_to_cpu(pdu->cmdsn);
 
 	sess->sess_ops = kzalloc(sizeof(struct iscsi_sess_ops), GFP_KERNEL);
 	if (!sess->sess_ops) {
@@ -453,7 +449,7 @@
 		   (sess_p->time2retain_timer_flags & ISCSI_TF_EXPIRED))
 			continue;
 		if (!memcmp(sess_p->isid, pdu->isid, 6) &&
-		     (sess_p->tsih == pdu->tsih)) {
+		     (sess_p->tsih == be16_to_cpu(pdu->tsih))) {
 			iscsit_inc_session_usage_count(sess_p);
 			iscsit_stop_time2retain_timer(sess_p);
 			sess = sess_p;
@@ -955,11 +951,7 @@
 	}
 
 	pdu			= (struct iscsi_login_req *) buffer;
-	pdu->cid		= be16_to_cpu(pdu->cid);
-	pdu->tsih		= be16_to_cpu(pdu->tsih);
-	pdu->itt		= be32_to_cpu(pdu->itt);
-	pdu->cmdsn		= be32_to_cpu(pdu->cmdsn);
-	pdu->exp_statsn		= be32_to_cpu(pdu->exp_statsn);
+
 	/*
 	 * Used by iscsit_tx_login_rsp() for Login Resonses PDUs
 	 * when Status-Class != 0.
diff --git a/drivers/target/iscsi/iscsi_target_nego.c b/drivers/target/iscsi/iscsi_target_nego.c
index 2dba448..e9053a0 100644
--- a/drivers/target/iscsi/iscsi_target_nego.c
+++ b/drivers/target/iscsi/iscsi_target_nego.c
@@ -44,7 +44,7 @@
 			buf[i] = ';';
 }
 
-int strlen_semi(char *buf)
+static int strlen_semi(char *buf)
 {
 	int i = 0;
 
@@ -339,14 +339,14 @@
 	hton24(login_rsp->dlength, login->rsp_length);
 	memcpy(login_rsp->isid, login->isid, 6);
 	login_rsp->tsih			= cpu_to_be16(login->tsih);
-	login_rsp->itt			= cpu_to_be32(login->init_task_tag);
+	login_rsp->itt			= login->init_task_tag;
 	login_rsp->statsn		= cpu_to_be32(conn->stat_sn++);
 	login_rsp->exp_cmdsn		= cpu_to_be32(conn->sess->exp_cmd_sn);
 	login_rsp->max_cmdsn		= cpu_to_be32(conn->sess->max_cmd_sn);
 
 	pr_debug("Sending Login Response, Flags: 0x%02x, ITT: 0x%08x,"
 		" ExpCmdSN; 0x%08x, MaxCmdSN: 0x%08x, StatSN: 0x%08x, Length:"
-		" %u\n", login_rsp->flags, ntohl(login_rsp->itt),
+		" %u\n", login_rsp->flags, (__force u32)login_rsp->itt,
 		ntohl(login_rsp->exp_cmdsn), ntohl(login_rsp->max_cmdsn),
 		ntohl(login_rsp->statsn), login->rsp_length);
 
@@ -360,12 +360,9 @@
 		return -1;
 
 	login->rsp_length		= 0;
-	login_rsp->tsih			= be16_to_cpu(login_rsp->tsih);
-	login_rsp->itt			= be32_to_cpu(login_rsp->itt);
-	login_rsp->statsn		= be32_to_cpu(login_rsp->statsn);
 	mutex_lock(&sess->cmdsn_mutex);
-	login_rsp->exp_cmdsn		= be32_to_cpu(sess->exp_cmd_sn);
-	login_rsp->max_cmdsn		= be32_to_cpu(sess->max_cmd_sn);
+	login_rsp->exp_cmdsn		= cpu_to_be32(sess->exp_cmd_sn);
+	login_rsp->max_cmdsn		= cpu_to_be32(sess->max_cmd_sn);
 	mutex_unlock(&sess->cmdsn_mutex);
 
 	return 0;
@@ -381,11 +378,6 @@
 
 	login_req = (struct iscsi_login_req *) login->req;
 	payload_length			= ntoh24(login_req->dlength);
-	login_req->tsih			= be16_to_cpu(login_req->tsih);
-	login_req->itt			= be32_to_cpu(login_req->itt);
-	login_req->cid			= be16_to_cpu(login_req->cid);
-	login_req->cmdsn		= be32_to_cpu(login_req->cmdsn);
-	login_req->exp_statsn		= be32_to_cpu(login_req->exp_statsn);
 
 	pr_debug("Got Login Command, Flags 0x%02x, ITT: 0x%08x,"
 		" CmdSN: 0x%08x, ExpStatSN: 0x%08x, CID: %hu, Length: %u\n",
@@ -550,7 +542,7 @@
 			SENDER_INITIATOR|SENDER_RECEIVER,
 			login->req_buf,
 			payload_length,
-			conn->param_list);
+			conn);
 	if (ret < 0)
 		return -1;
 
@@ -627,7 +619,7 @@
 			SENDER_INITIATOR|SENDER_RECEIVER,
 			login->req_buf,
 			payload_length,
-			conn->param_list);
+			conn);
 	if (ret < 0)
 		return -1;
 
@@ -762,11 +754,11 @@
 	login->version_min	= login_req->min_version;
 	login->version_max	= login_req->max_version;
 	memcpy(login->isid, login_req->isid, 6);
-	login->cmd_sn		= login_req->cmdsn;
+	login->cmd_sn		= be32_to_cpu(login_req->cmdsn);
 	login->init_task_tag	= login_req->itt;
-	login->initial_exp_statsn = login_req->exp_statsn;
-	login->cid		= login_req->cid;
-	login->tsih		= login_req->tsih;
+	login->initial_exp_statsn = be32_to_cpu(login_req->exp_statsn);
+	login->cid		= be16_to_cpu(login_req->cid);
+	login->tsih		= be16_to_cpu(login_req->tsih);
 
 	if (iscsi_target_get_initial_payload(conn, login) < 0)
 		return -1;
@@ -1000,7 +992,6 @@
 	 *	Locates Target Portal from NP -> Target IQN
 	 */
 	if (iscsi_target_locate_portal(np, conn, login) < 0) {
-		pr_err("iSCSI Login negotiation failed.\n");
 		goto out;
 	}
 
diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c
index 240f7aa..90b7400 100644
--- a/drivers/target/iscsi/iscsi_target_parameters.c
+++ b/drivers/target/iscsi/iscsi_target_parameters.c
@@ -334,6 +334,13 @@
 	if (!param)
 		goto out;
 
+	param = iscsi_set_default_param(pl, MAXXMITDATASEGMENTLENGTH,
+			INITIAL_MAXXMITDATASEGMENTLENGTH,
+			PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
+			TYPERANGE_512_TO_16777215, USE_ALL);
+	if (!param)
+		goto out;
+
 	param = iscsi_set_default_param(pl, MAXRECVDATASEGMENTLENGTH,
 			INITIAL_MAXRECVDATASEGMENTLENGTH,
 			PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
@@ -467,6 +474,8 @@
 			SET_PSTATE_NEGOTIATE(param);
 		} else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
 			SET_PSTATE_NEGOTIATE(param);
+		} else if (!strcmp(param->name, MAXXMITDATASEGMENTLENGTH)) {
+			continue;
 		} else if (!strcmp(param->name, MAXBURSTLENGTH)) {
 			SET_PSTATE_NEGOTIATE(param);
 		} else if (!strcmp(param->name, FIRSTBURSTLENGTH)) {
@@ -1056,7 +1065,8 @@
 	return proposer_values;
 }
 
-static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value)
+static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value,
+				struct iscsi_conn *conn)
 {
 	u8 acceptor_boolean_value = 0, proposer_boolean_value = 0;
 	char *negoitated_value = NULL;
@@ -1131,8 +1141,35 @@
 				return -1;
 		}
 
-		if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH))
-			SET_PSTATE_REPLY_OPTIONAL(param);
+		if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
+			struct iscsi_param *param_mxdsl;
+			unsigned long long tmp;
+			int rc;
+
+			rc = strict_strtoull(param->value, 0, &tmp);
+			if (rc < 0)
+				return -1;
+
+			conn->conn_ops->MaxRecvDataSegmentLength = tmp;
+			pr_debug("Saving op->MaxRecvDataSegmentLength from"
+				" original initiator received value: %u\n",
+				conn->conn_ops->MaxRecvDataSegmentLength);
+
+			param_mxdsl = iscsi_find_param_from_key(
+						MAXXMITDATASEGMENTLENGTH,
+						conn->param_list);
+			if (!param_mxdsl)
+				return -1;
+
+			rc = iscsi_update_param_value(param,
+						param_mxdsl->value);
+			if (rc < 0)
+				return -1;
+
+			pr_debug("Updated %s to target MXDSL value: %s\n",
+					param->name, param->value);
+		}
+
 	} else if (IS_TYPE_NUMBER_RANGE(param)) {
 		negoitated_value = iscsi_get_value_from_number_range(
 					param, value);
@@ -1526,8 +1563,9 @@
 	u8 sender,
 	char *textbuf,
 	u32 length,
-	struct iscsi_param_list *param_list)
+	struct iscsi_conn *conn)
 {
+	struct iscsi_param_list *param_list = conn->param_list;
 	char *tmpbuf, *start = NULL, *end = NULL;
 
 	tmpbuf = kzalloc(length + 1, GFP_KERNEL);
@@ -1585,7 +1623,7 @@
 			}
 			SET_PSTATE_RESPONSE_GOT(param);
 		} else {
-			if (iscsi_check_acceptor_state(param, value) < 0) {
+			if (iscsi_check_acceptor_state(param, value, conn) < 0) {
 				kfree(tmpbuf);
 				return -1;
 			}
@@ -1720,6 +1758,18 @@
 	pr_debug("---------------------------------------------------"
 			"---------------\n");
 	list_for_each_entry(param, &param_list->param_list, p_list) {
+		/*
+		 * Special case to set MAXXMITDATASEGMENTLENGTH from the
+		 * target requested MaxRecvDataSegmentLength, even though
+		 * this key is not sent over the wire.
+		 */
+		if (!strcmp(param->name, MAXXMITDATASEGMENTLENGTH)) {
+			ops->MaxXmitDataSegmentLength =
+				simple_strtoul(param->value, &tmpptr, 0);
+			pr_debug("MaxXmitDataSegmentLength:     %s\n",
+				param->value);
+		}
+
 		if (!IS_PSTATE_ACCEPTOR(param) && !IS_PSTATE_PROPOSER(param))
 			continue;
 		if (!strcmp(param->name, AUTHMETHOD)) {
@@ -1734,10 +1784,13 @@
 			pr_debug("DataDigest:                   %s\n",
 				param->value);
 		} else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
-			ops->MaxRecvDataSegmentLength =
-				simple_strtoul(param->value, &tmpptr, 0);
-			pr_debug("MaxRecvDataSegmentLength:     %s\n",
-				param->value);
+			/*
+			 * At this point iscsi_check_acceptor_state() will have
+			 * set ops->MaxRecvDataSegmentLength from the original
+			 * initiator provided value.
+			 */
+			pr_debug("MaxRecvDataSegmentLength:     %u\n",
+				ops->MaxRecvDataSegmentLength);
 		} else if (!strcmp(param->name, OFMARKER)) {
 			ops->OFMarker = !strcmp(param->value, YES);
 			pr_debug("OFMarker:                     %s\n",
diff --git a/drivers/target/iscsi/iscsi_target_parameters.h b/drivers/target/iscsi/iscsi_target_parameters.h
index 6a37fd6..1e1b750 100644
--- a/drivers/target/iscsi/iscsi_target_parameters.h
+++ b/drivers/target/iscsi/iscsi_target_parameters.h
@@ -36,7 +36,7 @@
 extern struct iscsi_param *iscsi_find_param_from_key(char *, struct iscsi_param_list *);
 extern int iscsi_extract_key_value(char *, char **, char **);
 extern int iscsi_update_param_value(struct iscsi_param *, char *);
-extern int iscsi_decode_text_input(u8, u8, char *, u32, struct iscsi_param_list *);
+extern int iscsi_decode_text_input(u8, u8, char *, u32, struct iscsi_conn *);
 extern int iscsi_encode_text_output(u8, u8, char *, u32 *,
 			struct iscsi_param_list *);
 extern int iscsi_check_negotiated_keys(struct iscsi_param_list *);
@@ -70,6 +70,7 @@
 #define INITIALR2T			"InitialR2T"
 #define IMMEDIATEDATA			"ImmediateData"
 #define MAXRECVDATASEGMENTLENGTH	"MaxRecvDataSegmentLength"
+#define MAXXMITDATASEGMENTLENGTH	"MaxXmitDataSegmentLength"
 #define MAXBURSTLENGTH			"MaxBurstLength"
 #define FIRSTBURSTLENGTH		"FirstBurstLength"
 #define DEFAULTTIME2WAIT		"DefaultTime2Wait"
@@ -113,6 +114,10 @@
 #define INITIAL_INITIALR2T			YES
 #define INITIAL_IMMEDIATEDATA			YES
 #define INITIAL_MAXRECVDATASEGMENTLENGTH	"8192"
+/*
+ * Match outgoing MXDSL default to incoming Open-iSCSI default
+ */
+#define INITIAL_MAXXMITDATASEGMENTLENGTH	"262144"
 #define INITIAL_MAXBURSTLENGTH			"262144"
 #define INITIAL_FIRSTBURSTLENGTH		"65536"
 #define INITIAL_DEFAULTTIME2WAIT		"2"
diff --git a/drivers/target/iscsi/iscsi_target_seq_pdu_list.c b/drivers/target/iscsi/iscsi_target_seq_pdu_list.c
index 85a306e..edb592a 100644
--- a/drivers/target/iscsi/iscsi_target_seq_pdu_list.c
+++ b/drivers/target/iscsi/iscsi_target_seq_pdu_list.c
@@ -219,8 +219,14 @@
 	int check_immediate = 0;
 	u32 burstlength = 0, offset = 0;
 	u32 unsolicited_data_length = 0;
+	u32 mdsl;
 	struct iscsi_conn *conn = cmd->conn;
 
+	if (cmd->se_cmd.data_direction == DMA_TO_DEVICE)
+		mdsl = cmd->conn->conn_ops->MaxXmitDataSegmentLength;
+	else
+		mdsl = cmd->conn->conn_ops->MaxRecvDataSegmentLength;
+
 	if ((bl->type == PDULIST_IMMEDIATE) ||
 	    (bl->type == PDULIST_IMMEDIATE_AND_UNSOLICITED))
 		check_immediate = 1;
@@ -243,14 +249,13 @@
 			continue;
 		}
 		if (unsolicited_data_length > 0) {
-			if ((offset + conn->conn_ops->MaxRecvDataSegmentLength)
-					>= cmd->se_cmd.data_length) {
+			if ((offset + mdsl) >= cmd->se_cmd.data_length) {
 				unsolicited_data_length -=
 					(cmd->se_cmd.data_length - offset);
 				offset += (cmd->se_cmd.data_length - offset);
 				continue;
 			}
-			if ((offset + conn->conn_ops->MaxRecvDataSegmentLength)
+			if ((offset + mdsl)
 					>= conn->sess->sess_ops->FirstBurstLength) {
 				unsolicited_data_length -=
 					(conn->sess->sess_ops->FirstBurstLength -
@@ -262,17 +267,15 @@
 				continue;
 			}
 
-			offset += conn->conn_ops->MaxRecvDataSegmentLength;
-			unsolicited_data_length -=
-				conn->conn_ops->MaxRecvDataSegmentLength;
+			offset += mdsl;
+			unsolicited_data_length -= mdsl;
 			continue;
 		}
-		if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) >=
-		     cmd->se_cmd.data_length) {
+		if ((offset + mdsl) >= cmd->se_cmd.data_length) {
 			offset += (cmd->se_cmd.data_length - offset);
 			continue;
 		}
-		if ((burstlength + conn->conn_ops->MaxRecvDataSegmentLength) >=
+		if ((burstlength + mdsl) >=
 		     conn->sess->sess_ops->MaxBurstLength) {
 			offset += (conn->sess->sess_ops->MaxBurstLength -
 					burstlength);
@@ -281,8 +284,8 @@
 			continue;
 		}
 
-		burstlength += conn->conn_ops->MaxRecvDataSegmentLength;
-		offset += conn->conn_ops->MaxRecvDataSegmentLength;
+		burstlength += mdsl;
+		offset += mdsl;
 	}
 }
 
@@ -296,12 +299,17 @@
 	struct iscsi_build_list *bl)
 {
 	int check_immediate = 0, datapduinorder, datasequenceinorder;
-	u32 burstlength = 0, offset = 0, i = 0;
+	u32 burstlength = 0, offset = 0, i = 0, mdsl;
 	u32 pdu_count = 0, seq_no = 0, unsolicited_data_length = 0;
 	struct iscsi_conn *conn = cmd->conn;
 	struct iscsi_pdu *pdu = cmd->pdu_list;
 	struct iscsi_seq *seq = cmd->seq_list;
 
+	if (cmd->se_cmd.data_direction == DMA_TO_DEVICE)
+		mdsl = cmd->conn->conn_ops->MaxXmitDataSegmentLength;
+	else
+		mdsl = cmd->conn->conn_ops->MaxRecvDataSegmentLength;
+
 	datapduinorder = conn->sess->sess_ops->DataPDUInOrder;
 	datasequenceinorder = conn->sess->sess_ops->DataSequenceInOrder;
 
@@ -348,9 +356,7 @@
 			continue;
 		}
 		if (unsolicited_data_length > 0) {
-			if ((offset +
-			     conn->conn_ops->MaxRecvDataSegmentLength) >=
-			     cmd->se_cmd.data_length) {
+			if ((offset + mdsl) >= cmd->se_cmd.data_length) {
 				if (!datapduinorder) {
 					pdu[i].type = PDUTYPE_UNSOLICITED;
 					pdu[i].length =
@@ -367,8 +373,7 @@
 				offset += (cmd->se_cmd.data_length - offset);
 				continue;
 			}
-			if ((offset +
-			     conn->conn_ops->MaxRecvDataSegmentLength) >=
+			if ((offset + mdsl) >=
 					conn->sess->sess_ops->FirstBurstLength) {
 				if (!datapduinorder) {
 					pdu[i].type = PDUTYPE_UNSOLICITED;
@@ -396,17 +401,14 @@
 
 			if (!datapduinorder) {
 				pdu[i].type = PDUTYPE_UNSOLICITED;
-				pdu[i++].length =
-				     conn->conn_ops->MaxRecvDataSegmentLength;
+				pdu[i++].length = mdsl;
 			}
-			burstlength += conn->conn_ops->MaxRecvDataSegmentLength;
-			offset += conn->conn_ops->MaxRecvDataSegmentLength;
-			unsolicited_data_length -=
-				conn->conn_ops->MaxRecvDataSegmentLength;
+			burstlength += mdsl;
+			offset += mdsl;
+			unsolicited_data_length -= mdsl;
 			continue;
 		}
-		if ((offset + conn->conn_ops->MaxRecvDataSegmentLength) >=
-		     cmd->se_cmd.data_length) {
+		if ((offset + mdsl) >= cmd->se_cmd.data_length) {
 			if (!datapduinorder) {
 				pdu[i].type = PDUTYPE_NORMAL;
 				pdu[i].length = (cmd->se_cmd.data_length - offset);
@@ -420,7 +422,7 @@
 			offset += (cmd->se_cmd.data_length - offset);
 			continue;
 		}
-		if ((burstlength + conn->conn_ops->MaxRecvDataSegmentLength) >=
+		if ((burstlength + mdsl) >=
 		     conn->sess->sess_ops->MaxBurstLength) {
 			if (!datapduinorder) {
 				pdu[i].type = PDUTYPE_NORMAL;
@@ -445,11 +447,10 @@
 
 		if (!datapduinorder) {
 			pdu[i].type = PDUTYPE_NORMAL;
-			pdu[i++].length =
-				conn->conn_ops->MaxRecvDataSegmentLength;
+			pdu[i++].length = mdsl;
 		}
-		burstlength += conn->conn_ops->MaxRecvDataSegmentLength;
-		offset += conn->conn_ops->MaxRecvDataSegmentLength;
+		burstlength += mdsl;
+		offset += mdsl;
 	}
 
 	if (!datasequenceinorder) {
diff --git a/drivers/target/iscsi/iscsi_target_tmr.c b/drivers/target/iscsi/iscsi_target_tmr.c
index f62fe12..4a99820 100644
--- a/drivers/target/iscsi/iscsi_target_tmr.c
+++ b/drivers/target/iscsi/iscsi_target_tmr.c
@@ -50,21 +50,20 @@
 	if (!ref_cmd) {
 		pr_err("Unable to locate RefTaskTag: 0x%08x on CID:"
 			" %hu.\n", hdr->rtt, conn->cid);
-		return ((hdr->refcmdsn >= conn->sess->exp_cmd_sn) &&
-			(hdr->refcmdsn <= conn->sess->max_cmd_sn)) ?
+		return (be32_to_cpu(hdr->refcmdsn) >= conn->sess->exp_cmd_sn &&
+			be32_to_cpu(hdr->refcmdsn) <= conn->sess->max_cmd_sn) ?
 			ISCSI_TMF_RSP_COMPLETE : ISCSI_TMF_RSP_NO_TASK;
 	}
-	if (ref_cmd->cmd_sn != hdr->refcmdsn) {
+	if (ref_cmd->cmd_sn != be32_to_cpu(hdr->refcmdsn)) {
 		pr_err("RefCmdSN 0x%08x does not equal"
 			" task's CmdSN 0x%08x. Rejecting ABORT_TASK.\n",
 			hdr->refcmdsn, ref_cmd->cmd_sn);
 		return ISCSI_TMF_RSP_REJECTED;
 	}
 
-	se_tmr->ref_task_tag		= hdr->rtt;
+	se_tmr->ref_task_tag		= (__force u32)hdr->rtt;
 	tmr_req->ref_cmd		= ref_cmd;
-	tmr_req->ref_cmd_sn		= hdr->refcmdsn;
-	tmr_req->exp_data_sn		= hdr->exp_datasn;
+	tmr_req->exp_data_sn		= be32_to_cpu(hdr->exp_datasn);
 
 	return ISCSI_TMF_RSP_COMPLETE;
 }
@@ -146,7 +145,7 @@
 	}
 	/*
 	 * Temporary check to prevent connection recovery for
-	 * connections with a differing MaxRecvDataSegmentLength.
+	 * connections with a differing Max*DataSegmentLength.
 	 */
 	if (cr->maxrecvdatasegmentlength !=
 	    conn->conn_ops->MaxRecvDataSegmentLength) {
@@ -155,6 +154,13 @@
 			" TMR TASK_REASSIGN.\n");
 		return ISCSI_TMF_RSP_REJECTED;
 	}
+	if (cr->maxxmitdatasegmentlength !=
+	    conn->conn_ops->MaxXmitDataSegmentLength) {
+		pr_err("Unable to perform connection recovery for"
+			" differing MaxXmitDataSegmentLength, rejecting"
+			" TMR TASK_REASSIGN.\n");
+		return ISCSI_TMF_RSP_REJECTED;
+	}
 
 	ref_lun = scsilun_to_int(&hdr->lun);
 	if (ref_lun != ref_cmd->se_cmd.orig_fe_lun) {
@@ -164,10 +170,9 @@
 		return ISCSI_TMF_RSP_REJECTED;
 	}
 
-	se_tmr->ref_task_tag		= hdr->rtt;
+	se_tmr->ref_task_tag		= (__force u32)hdr->rtt;
 	tmr_req->ref_cmd		= ref_cmd;
-	tmr_req->ref_cmd_sn		= hdr->refcmdsn;
-	tmr_req->exp_data_sn		= hdr->exp_datasn;
+	tmr_req->exp_data_sn		= be32_to_cpu(hdr->exp_datasn);
 	tmr_req->conn_recovery		= cr;
 	tmr_req->task_reassign		= 1;
 	/*
@@ -455,7 +460,7 @@
  *	Right now the only one that its really needed for is
  *	connection recovery releated TASK_REASSIGN.
  */
-extern int iscsit_tmr_post_handler(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
+int iscsit_tmr_post_handler(struct iscsi_cmd *cmd, struct iscsi_conn *conn)
 {
 	struct iscsi_tmr_req *tmr_req = cmd->tmr_req;
 	struct se_tmr_req *se_tmr = cmd->se_cmd.se_tmr_req;
@@ -470,7 +475,7 @@
 /*
  *	Nothing to do here, but leave it for good measure. :-)
  */
-int iscsit_task_reassign_prepare_read(
+static int iscsit_task_reassign_prepare_read(
 	struct iscsi_tmr_req *tmr_req,
 	struct iscsi_conn *conn)
 {
@@ -545,7 +550,7 @@
 	}
 }
 
-int iscsit_task_reassign_prepare_write(
+static int iscsit_task_reassign_prepare_write(
 	struct iscsi_tmr_req *tmr_req,
 	struct iscsi_conn *conn)
 {
diff --git a/drivers/target/iscsi/iscsi_target_tpg.c b/drivers/target/iscsi/iscsi_target_tpg.c
index a38a3f8..de9ea32 100644
--- a/drivers/target/iscsi/iscsi_target_tpg.c
+++ b/drivers/target/iscsi/iscsi_target_tpg.c
@@ -677,6 +677,12 @@
 	pr_debug("iSCSI_TPG[%hu] - Generate Initiator Portal Group ACLs: %s\n",
 		tpg->tpgt, (a->generate_node_acls) ? "Enabled" : "Disabled");
 
+	if (flag == 1 && a->cache_dynamic_acls == 0) {
+		pr_debug("Explicitly setting cache_dynamic_acls=1 when "
+			"generate_node_acls=1\n");
+		a->cache_dynamic_acls = 1;
+	}
+
 	return 0;
 }
 
@@ -716,6 +722,12 @@
 		return -EINVAL;
 	}
 
+	if (a->generate_node_acls == 1 && flag == 0) {
+		pr_debug("Skipping cache_dynamic_acls=0 when"
+			" generate_node_acls=1\n");
+		return 0;
+	}
+
 	a->cache_dynamic_acls = flag;
 	pr_debug("iSCSI_TPG[%hu] - Cache Dynamic Initiator Portal Group"
 		" ACLs %s\n", tpg->tpgt, (a->cache_dynamic_acls) ?
diff --git a/drivers/target/iscsi/iscsi_target_tq.c b/drivers/target/iscsi/iscsi_target_tq.c
index 977e1cf..9d881a0 100644
--- a/drivers/target/iscsi/iscsi_target_tq.c
+++ b/drivers/target/iscsi/iscsi_target_tq.c
@@ -40,7 +40,7 @@
 	spin_unlock(&active_ts_lock);
 }
 
-extern void iscsi_add_ts_to_inactive_list(struct iscsi_thread_set *ts)
+static void iscsi_add_ts_to_inactive_list(struct iscsi_thread_set *ts)
 {
 	spin_lock(&inactive_ts_lock);
 	list_add_tail(&ts->ts_list, &inactive_ts_list);
@@ -76,7 +76,7 @@
 	return ts;
 }
 
-extern int iscsi_allocate_thread_sets(u32 thread_pair_count)
+int iscsi_allocate_thread_sets(u32 thread_pair_count)
 {
 	int allocated_thread_pair_count = 0, i, thread_id;
 	struct iscsi_thread_set *ts = NULL;
@@ -140,7 +140,7 @@
 	return allocated_thread_pair_count;
 }
 
-extern void iscsi_deallocate_thread_sets(void)
+void iscsi_deallocate_thread_sets(void)
 {
 	u32 released_count = 0;
 	struct iscsi_thread_set *ts = NULL;
diff --git a/drivers/target/iscsi/iscsi_target_tq.h b/drivers/target/iscsi/iscsi_target_tq.h
index 26e6a95..547d118 100644
--- a/drivers/target/iscsi/iscsi_target_tq.h
+++ b/drivers/target/iscsi/iscsi_target_tq.h
@@ -5,7 +5,6 @@
  * Defines for thread sets.
  */
 extern int iscsi_thread_set_force_reinstatement(struct iscsi_conn *);
-extern void iscsi_add_ts_to_inactive_list(struct iscsi_thread_set *);
 extern int iscsi_allocate_thread_sets(u32);
 extern void iscsi_deallocate_thread_sets(void);
 extern void iscsi_activate_thread_set(struct iscsi_conn *, struct iscsi_thread_set *);
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c
index b42cdeb..afd98cc 100644
--- a/drivers/target/iscsi/iscsi_target_util.c
+++ b/drivers/target/iscsi/iscsi_target_util.c
@@ -274,14 +274,14 @@
 int iscsit_sequence_cmd(
 	struct iscsi_conn *conn,
 	struct iscsi_cmd *cmd,
-	u32 cmdsn)
+	__be32 cmdsn)
 {
 	int ret;
 	int cmdsn_ret;
 
 	mutex_lock(&conn->sess->cmdsn_mutex);
 
-	cmdsn_ret = iscsit_check_received_cmdsn(conn->sess, cmdsn);
+	cmdsn_ret = iscsit_check_received_cmdsn(conn->sess, be32_to_cpu(cmdsn));
 	switch (cmdsn_ret) {
 	case CMDSN_NORMAL_OPERATION:
 		ret = iscsit_execute_cmd(cmd, 0);
@@ -289,7 +289,7 @@
 			iscsit_execute_ooo_cmdsns(conn->sess);
 		break;
 	case CMDSN_HIGHER_THAN_EXP:
-		ret = iscsit_handle_ooo_cmdsn(conn->sess, cmd, cmdsn);
+		ret = iscsit_handle_ooo_cmdsn(conn->sess, cmd, be32_to_cpu(cmdsn));
 		break;
 	case CMDSN_LOWER_THAN_EXP:
 		cmd->i_state = ISTATE_REMOVE;
@@ -351,7 +351,7 @@
 
 struct iscsi_cmd *iscsit_find_cmd_from_itt(
 	struct iscsi_conn *conn,
-	u32 init_task_tag)
+	itt_t init_task_tag)
 {
 	struct iscsi_cmd *cmd;
 
@@ -371,7 +371,7 @@
 
 struct iscsi_cmd *iscsit_find_cmd_from_itt_or_dump(
 	struct iscsi_conn *conn,
-	u32 init_task_tag,
+	itt_t init_task_tag,
 	u32 length)
 {
 	struct iscsi_cmd *cmd;
@@ -417,7 +417,7 @@
 	struct iscsi_session *sess,
 	struct iscsi_cmd **cmd_ptr,
 	struct iscsi_conn_recovery **cr_ptr,
-	u32 init_task_tag)
+	itt_t init_task_tag)
 {
 	struct iscsi_cmd *cmd = NULL;
 	struct iscsi_conn_recovery *cr;
@@ -855,7 +855,7 @@
 	cmd->iscsi_opcode = ISCSI_OP_NOOP_IN;
 	state = (want_response) ? ISTATE_SEND_NOPIN_WANT_RESPONSE :
 				ISTATE_SEND_NOPIN_NO_RESPONSE;
-	cmd->init_task_tag = 0xFFFFFFFF;
+	cmd->init_task_tag = RESERVED_ITT;
 	spin_lock_bh(&conn->sess->ttt_lock);
 	cmd->targ_xfer_tag = (want_response) ? conn->sess->targ_xfer_tag++ :
 			0xFFFFFFFF;
@@ -1222,7 +1222,7 @@
 	hdr->opcode		= ISCSI_OP_LOGIN_RSP;
 	hdr->status_class	= status_class;
 	hdr->status_detail	= status_detail;
-	hdr->itt		= cpu_to_be32(conn->login_itt);
+	hdr->itt		= conn->login_itt;
 
 	iov.iov_base		= &iscsi_hdr;
 	iov.iov_len		= ISCSI_HDR_LEN;
diff --git a/drivers/target/iscsi/iscsi_target_util.h b/drivers/target/iscsi/iscsi_target_util.h
index e1c729b..44054bd3 100644
--- a/drivers/target/iscsi/iscsi_target_util.h
+++ b/drivers/target/iscsi/iscsi_target_util.h
@@ -12,14 +12,14 @@
 extern struct iscsi_seq *iscsit_get_seq_holder_for_datain(struct iscsi_cmd *, u32);
 extern struct iscsi_seq *iscsit_get_seq_holder_for_r2t(struct iscsi_cmd *);
 extern struct iscsi_r2t *iscsit_get_holder_for_r2tsn(struct iscsi_cmd *, u32);
-int iscsit_sequence_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, u32 cmdsn);
+int iscsit_sequence_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, __be32 cmdsn);
 extern int iscsit_check_unsolicited_dataout(struct iscsi_cmd *, unsigned char *);
-extern struct iscsi_cmd *iscsit_find_cmd_from_itt(struct iscsi_conn *, u32);
+extern struct iscsi_cmd *iscsit_find_cmd_from_itt(struct iscsi_conn *, itt_t);
 extern struct iscsi_cmd *iscsit_find_cmd_from_itt_or_dump(struct iscsi_conn *,
-			u32, u32);
+			itt_t, u32);
 extern struct iscsi_cmd *iscsit_find_cmd_from_ttt(struct iscsi_conn *, u32);
 extern int iscsit_find_cmd_for_recovery(struct iscsi_session *, struct iscsi_cmd **,
-			struct iscsi_conn_recovery **, u32);
+			struct iscsi_conn_recovery **, itt_t);
 extern void iscsit_add_cmd_to_immediate_queue(struct iscsi_cmd *, struct iscsi_conn *, u8);
 extern struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_conn *);
 extern void iscsit_add_cmd_to_response_queue(struct iscsi_cmd *, struct iscsi_conn *, u8);
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index 5491c63..2d444b1 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -166,7 +166,7 @@
 	struct tcm_loop_tpg *tl_tpg;
 	struct scatterlist *sgl_bidi = NULL;
 	u32 sgl_bidi_count = 0;
-	int ret;
+	int rc;
 
 	tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host);
 	tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id];
@@ -187,12 +187,6 @@
 		set_host_byte(sc, DID_ERROR);
 		goto out_done;
 	}
-
-	transport_init_se_cmd(se_cmd, tl_tpg->tl_se_tpg.se_tpg_tfo,
-			tl_nexus->se_sess,
-			scsi_bufflen(sc), sc->sc_data_direction,
-			tcm_loop_sam_attr(sc), &tl_cmd->tl_sense_buf[0]);
-
 	if (scsi_bidi_cmnd(sc)) {
 		struct scsi_data_buffer *sdb = scsi_in(sc);
 
@@ -201,56 +195,16 @@
 		se_cmd->se_cmd_flags |= SCF_BIDI;
 
 	}
-
-	if (transport_lookup_cmd_lun(se_cmd, tl_cmd->sc->device->lun) < 0) {
-		kmem_cache_free(tcm_loop_cmd_cache, tl_cmd);
+	rc = target_submit_cmd_map_sgls(se_cmd, tl_nexus->se_sess, sc->cmnd,
+			&tl_cmd->tl_sense_buf[0], tl_cmd->sc->device->lun,
+			scsi_bufflen(sc), tcm_loop_sam_attr(sc),
+			sc->sc_data_direction, 0,
+			scsi_sglist(sc), scsi_sg_count(sc),
+			sgl_bidi, sgl_bidi_count);
+	if (rc < 0) {
 		set_host_byte(sc, DID_NO_CONNECT);
 		goto out_done;
 	}
-
-	/*
-	 * Because some userspace code via scsi-generic do not memset their
-	 * associated read buffers, go ahead and do that here for type
-	 * non-data CDBs.  Also note that this is currently guaranteed to be a
-	 * single SGL for this case by target core in
-	 * target_setup_cmd_from_cdb() -> transport_generic_cmd_sequencer().
-	 */
-	if (!(se_cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) &&
-	    se_cmd->data_direction == DMA_FROM_DEVICE) {
-		struct scatterlist *sg = scsi_sglist(sc);
-		unsigned char *buf = kmap(sg_page(sg)) + sg->offset;
-
-		if (buf != NULL) {
-			memset(buf, 0, sg->length);
-			kunmap(sg_page(sg));
-		}
-	}
-
-	ret = target_setup_cmd_from_cdb(se_cmd, sc->cmnd);
-	if (ret == -ENOMEM) {
-		transport_send_check_condition_and_sense(se_cmd,
-				TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0);
-		transport_generic_free_cmd(se_cmd, 0);
-		return;
-	} else if (ret < 0) {
-		if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT)
-			tcm_loop_queue_status(se_cmd);
-		else
-			transport_send_check_condition_and_sense(se_cmd,
-					se_cmd->scsi_sense_reason, 0);
-		transport_generic_free_cmd(se_cmd, 0);
-		return;
-	}
-
-	ret = transport_generic_map_mem_to_cmd(se_cmd, scsi_sglist(sc),
-			scsi_sg_count(sc), sgl_bidi, sgl_bidi_count);
-	if (ret) {
-		transport_send_check_condition_and_sense(se_cmd,
-					se_cmd->scsi_sense_reason, 0);
-		transport_generic_free_cmd(se_cmd, 0);
-		return;
-	}
-	transport_handle_cdb_direct(se_cmd);
 	return;
 
 out_done:
@@ -846,16 +800,6 @@
 	return 0;
 }
 
-static u16 tcm_loop_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length)
-{
-	return 0;
-}
-
-static u16 tcm_loop_get_fabric_sense_len(void)
-{
-	return 0;
-}
-
 static char *tcm_loop_dump_proto_id(struct tcm_loop_hba *tl_hba)
 {
 	switch (tl_hba->tl_proto_id) {
@@ -1373,8 +1317,6 @@
 	fabric->tf_ops.queue_data_in = &tcm_loop_queue_data_in;
 	fabric->tf_ops.queue_status = &tcm_loop_queue_status;
 	fabric->tf_ops.queue_tm_rsp = &tcm_loop_queue_tm_rsp;
-	fabric->tf_ops.set_fabric_sense_len = &tcm_loop_set_fabric_sense_len;
-	fabric->tf_ops.get_fabric_sense_len = &tcm_loop_get_fabric_sense_len;
 
 	/*
 	 * Setup function pointers for generic logic in target_core_fabric_configfs.c
diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c
index 39ddba5..0d6d7c1 100644
--- a/drivers/target/sbp/sbp_target.c
+++ b/drivers/target/sbp/sbp_target.c
@@ -660,8 +660,7 @@
 	spin_lock_bh(&sess->lock);
 	list_for_each_entry_safe(login, temp, &sess->login_list, link) {
 		login->sess = NULL;
-		list_del(&login->link);
-		list_add_tail(&login->link, &login_list);
+		list_move_tail(&login->link, &login_list);
 	}
 	spin_unlock_bh(&sess->lock);
 
@@ -1847,16 +1846,6 @@
 	return 0;
 }
 
-static u16 sbp_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length)
-{
-	return 0;
-}
-
-static u16 sbp_get_fabric_sense_len(void)
-{
-	return 0;
-}
-
 static int sbp_check_stop_free(struct se_cmd *se_cmd)
 {
 	struct sbp_target_request *req = container_of(se_cmd,
@@ -2068,7 +2057,7 @@
 	return ret;
 }
 
-static ssize_t sbp_parse_wwn(const char *name, u64 *wwn, int strict)
+static ssize_t sbp_parse_wwn(const char *name, u64 *wwn)
 {
 	const char *cp;
 	char c, nibble;
@@ -2088,7 +2077,7 @@
 		err = 3;
 		if (isdigit(c))
 			nibble = c - '0';
-		else if (isxdigit(c) && (islower(c) || !strict))
+		else if (isxdigit(c))
 			nibble = tolower(c) - 'a' + 10;
 		else
 			goto fail;
@@ -2117,7 +2106,7 @@
 	u64 guid = 0;
 	u32 nexus_depth = 1;
 
-	if (sbp_parse_wwn(name, &guid, 1) < 0)
+	if (sbp_parse_wwn(name, &guid) < 0)
 		return ERR_PTR(-EINVAL);
 
 	se_nacl_new = sbp_alloc_fabric_acl(se_tpg);
@@ -2253,7 +2242,7 @@
 	struct sbp_tport *tport;
 	u64 guid = 0;
 
-	if (sbp_parse_wwn(name, &guid, 1) < 0)
+	if (sbp_parse_wwn(name, &guid) < 0)
 		return ERR_PTR(-EINVAL);
 
 	tport = kzalloc(sizeof(*tport), GFP_KERNEL);
@@ -2534,8 +2523,6 @@
 	.queue_data_in			= sbp_queue_data_in,
 	.queue_status			= sbp_queue_status,
 	.queue_tm_rsp			= sbp_queue_tm_rsp,
-	.get_fabric_sense_len		= sbp_get_fabric_sense_len,
-	.set_fabric_sense_len		= sbp_set_fabric_sense_len,
 	.check_stop_free		= sbp_check_stop_free,
 
 	.fabric_make_wwn		= sbp_make_tport,
@@ -2556,9 +2543,9 @@
 	int ret;
 
 	fabric = target_fabric_configfs_init(THIS_MODULE, "sbp");
-	if (!fabric) {
+	if (IS_ERR(fabric)) {
 		pr_err("target_fabric_configfs_init() failed\n");
-		return -ENOMEM;
+		return PTR_ERR(fabric);
 	}
 
 	fabric->tf_ops = sbp_ops;
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
index 41641ba..9a5f9a7 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -344,7 +344,7 @@
 			 */
 			rtpi = get_unaligned_be16(ptr + 2);
 			/*
-			 * Locate the matching relative target port identifer
+			 * Locate the matching relative target port identifier
 			 * for the struct se_device storage object.
 			 */
 			spin_lock(&dev->se_port_lock);
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c
index 801efa8..015f5be 100644
--- a/drivers/target/target_core_configfs.c
+++ b/drivers/target/target_core_configfs.c
@@ -457,14 +457,6 @@
 		pr_err("Missing tfo->queue_tm_rsp()\n");
 		return -EINVAL;
 	}
-	if (!tfo->set_fabric_sense_len) {
-		pr_err("Missing tfo->set_fabric_sense_len()\n");
-		return -EINVAL;
-	}
-	if (!tfo->get_fabric_sense_len) {
-		pr_err("Missing tfo->get_fabric_sense_len()\n");
-		return -EINVAL;
-	}
 	/*
 	 * We at least require tfo->fabric_make_wwn(), tfo->fabric_drop_wwn()
 	 * tfo->fabric_make_tpg() and tfo->fabric_drop_tpg() in
@@ -1208,7 +1200,7 @@
 		" Target Node Endpoint: %s\n", tfo->get_fabric_name(),
 		tfo->tpg_get_wwn(se_tpg));
 	len += sprintf(page+len, "SPC-3 Reservation: Relative Port"
-		" Identifer Tag: %hu %s Portal Group Tag: %hu"
+		" Identifier Tag: %hu %s Portal Group Tag: %hu"
 		" %s Logical Unit: %u\n", lun->lun_sep->sep_rtpi,
 		tfo->get_fabric_name(), tfo->tpg_get_tag(se_tpg),
 		tfo->get_fabric_name(), lun->unpacked_lun);
@@ -3132,6 +3124,7 @@
 				GFP_KERNEL);
 	if (!target_cg->default_groups) {
 		pr_err("Unable to allocate target_cg->default_groups\n");
+		ret = -ENOMEM;
 		goto out_global;
 	}
 
@@ -3147,6 +3140,7 @@
 				GFP_KERNEL);
 	if (!hba_cg->default_groups) {
 		pr_err("Unable to allocate hba_cg->default_groups\n");
+		ret = -ENOMEM;
 		goto out_global;
 	}
 	config_group_init_type_name(&alua_group,
@@ -3162,6 +3156,7 @@
 			GFP_KERNEL);
 	if (!alua_cg->default_groups) {
 		pr_err("Unable to allocate alua_cg->default_groups\n");
+		ret = -ENOMEM;
 		goto out_global;
 	}
 
@@ -3173,14 +3168,17 @@
 	 * Add core/alua/lu_gps/default_lu_gp
 	 */
 	lu_gp = core_alua_allocate_lu_gp("default_lu_gp", 1);
-	if (IS_ERR(lu_gp))
+	if (IS_ERR(lu_gp)) {
+		ret = -ENOMEM;
 		goto out_global;
+	}
 
 	lu_gp_cg = &alua_lu_gps_group;
 	lu_gp_cg->default_groups = kzalloc(sizeof(struct config_group) * 2,
 			GFP_KERNEL);
 	if (!lu_gp_cg->default_groups) {
 		pr_err("Unable to allocate lu_gp_cg->default_groups\n");
+		ret = -ENOMEM;
 		goto out_global;
 	}
 
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index 9fc9a60..8d774da 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -531,7 +531,7 @@
 	}
 again:
 	/*
-	 * Allocate the next RELATIVE TARGET PORT IDENTIFER for this struct se_device
+	 * Allocate the next RELATIVE TARGET PORT IDENTIFIER for this struct se_device
 	 * Here is the table from spc4r17 section 7.7.3.8.
 	 *
 	 *    Table 473 -- RELATIVE TARGET PORT IDENTIFIER field
@@ -548,7 +548,7 @@
 
 	list_for_each_entry(port_tmp, &dev->dev_sep_list, sep_list) {
 		/*
-		 * Make sure RELATIVE TARGET PORT IDENTIFER is unique
+		 * Make sure RELATIVE TARGET PORT IDENTIFIER is unique
 		 * for 16-bit wrap..
 		 */
 		if (port->sep_rtpi == port_tmp->sep_rtpi)
@@ -595,7 +595,7 @@
 	}
 
 	dev->dev_port_count++;
-	port->sep_index = port->sep_rtpi; /* RELATIVE TARGET PORT IDENTIFER */
+	port->sep_index = port->sep_rtpi; /* RELATIVE TARGET PORT IDENTIFIER */
 }
 
 /*
@@ -988,8 +988,9 @@
 		return -EINVAL;
 	}
 
-	if (flag && dev->transport->fua_write_emulated == 0) {
-		pr_err("fua_write_emulated not supported\n");
+	if (flag &&
+	    dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) {
+		pr_err("emulate_fua_write not supported for pSCSI\n");
 		return -EINVAL;
 	}
 	dev->se_sub_dev->se_dev_attrib.emulate_fua_write = flag;
@@ -1019,8 +1020,9 @@
 		pr_err("Illegal value %d\n", flag);
 		return -EINVAL;
 	}
-	if (flag && dev->transport->write_cache_emulated == 0) {
-		pr_err("write_cache_emulated not supported\n");
+	if (flag &&
+	    dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV) {
+		pr_err("emulate_write_cache not supported for pSCSI\n");
 		return -EINVAL;
 	}
 	dev->se_sub_dev->se_dev_attrib.emulate_write_cache = flag;
diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c
index ea479e5..bca737b 100644
--- a/drivers/target/target_core_fabric_configfs.c
+++ b/drivers/target/target_core_fabric_configfs.c
@@ -22,7 +22,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <generated/utsrelease.h>
 #include <linux/utsname.h>
 #include <linux/init.h>
 #include <linux/fs.h>
diff --git a/drivers/target/target_core_fabric_lib.c b/drivers/target/target_core_fabric_lib.c
index 283a36e..e460d62 100644
--- a/drivers/target/target_core_fabric_lib.c
+++ b/drivers/target/target_core_fabric_lib.c
@@ -338,7 +338,7 @@
 	 * 00b: iSCSI Initiator device TransportID format
 	 */
 	if (pr_reg->isid_present_at_reg) {
-		len += 5; /* For ",i,0x" ASCII seperator */
+		len += 5; /* For ",i,0x" ASCII separator */
 		len += 7; /* For iSCSI Initiator Session ID + Null terminator */
 		*format_code = 1;
 	} else
@@ -415,20 +415,20 @@
 			*out_tid_len = (add_len + 4);
 	}
 	/*
-	 * Check for ',i,0x' seperator between iSCSI Name and iSCSI Initiator
+	 * Check for ',i,0x' separator between iSCSI Name and iSCSI Initiator
 	 * Session ID as defined in Table 390 - iSCSI initiator port TransportID
 	 * format.
 	 */
 	if (format_code == 0x40) {
 		p = strstr(&buf[4], ",i,0x");
 		if (!p) {
-			pr_err("Unable to locate \",i,0x\" seperator"
+			pr_err("Unable to locate \",i,0x\" separator"
 				" for Initiator port identifier: %s\n",
 				&buf[4]);
 			return NULL;
 		}
 		*p = '\0'; /* Terminate iSCSI Name */
-		p += 5; /* Skip over ",i,0x" seperator */
+		p += 5; /* Skip over ",i,0x" separator */
 
 		*port_nexus_ptr = p;
 		/*
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c
index cbb5aaf..0360383 100644
--- a/drivers/target/target_core_file.c
+++ b/drivers/target/target_core_file.c
@@ -125,6 +125,19 @@
 	 * of pure timestamp updates.
 	 */
 	flags = O_RDWR | O_CREAT | O_LARGEFILE | O_DSYNC;
+	/*
+	 * Optionally allow fd_buffered_io=1 to be enabled for people
+	 * who want use the fs buffer cache as an WriteCache mechanism.
+	 *
+	 * This means that in event of a hard failure, there is a risk
+	 * of silent data-loss if the SCSI client has *not* performed a
+	 * forced unit access (FUA) write, or issued SYNCHRONIZE_CACHE
+	 * to write-out the entire device cache.
+	 */
+	if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) {
+		pr_debug("FILEIO: Disabling O_DSYNC, using buffered FILEIO\n");
+		flags &= ~O_DSYNC;
+	}
 
 	file = filp_open(fd_dev->fd_dev_name, flags, 0600);
 	if (IS_ERR(file)) {
@@ -188,6 +201,12 @@
 	if (!dev)
 		goto fail;
 
+	if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) {
+		pr_debug("FILEIO: Forcing setting of emulate_write_cache=1"
+			" with FDBD_HAS_BUFFERED_IO_WCE\n");
+		dev->se_sub_dev->se_dev_attrib.emulate_write_cache = 1;
+	}
+
 	fd_dev->fd_dev_id = fd_host->fd_host_dev_id_count++;
 	fd_dev->fd_queue_depth = dev->queue_depth;
 
@@ -407,6 +426,7 @@
 static match_table_t tokens = {
 	{Opt_fd_dev_name, "fd_dev_name=%s"},
 	{Opt_fd_dev_size, "fd_dev_size=%s"},
+	{Opt_fd_buffered_io, "fd_buffered_io=%d"},
 	{Opt_err, NULL}
 };
 
@@ -418,7 +438,7 @@
 	struct fd_dev *fd_dev = se_dev->se_dev_su_ptr;
 	char *orig, *ptr, *arg_p, *opts;
 	substring_t args[MAX_OPT_ARGS];
-	int ret = 0, token;
+	int ret = 0, arg, token;
 
 	opts = kstrdup(page, GFP_KERNEL);
 	if (!opts)
@@ -459,6 +479,19 @@
 					" bytes\n", fd_dev->fd_dev_size);
 			fd_dev->fbd_flags |= FBDF_HAS_SIZE;
 			break;
+		case Opt_fd_buffered_io:
+			match_int(args, &arg);
+			if (arg != 1) {
+				pr_err("bogus fd_buffered_io=%d value\n", arg);
+				ret = -EINVAL;
+				goto out;
+			}
+
+			pr_debug("FILEIO: Using buffered I/O"
+				" operations for struct fd_dev\n");
+
+			fd_dev->fbd_flags |= FDBD_HAS_BUFFERED_IO_WCE;
+			break;
 		default:
 			break;
 		}
@@ -490,8 +523,10 @@
 	ssize_t bl = 0;
 
 	bl = sprintf(b + bl, "TCM FILEIO ID: %u", fd_dev->fd_dev_id);
-	bl += sprintf(b + bl, "        File: %s  Size: %llu  Mode: O_DSYNC\n",
-		fd_dev->fd_dev_name, fd_dev->fd_dev_size);
+	bl += sprintf(b + bl, "        File: %s  Size: %llu  Mode: %s\n",
+		fd_dev->fd_dev_name, fd_dev->fd_dev_size,
+		(fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) ?
+		"Buffered-WCE" : "O_DSYNC");
 	return bl;
 }
 
@@ -546,8 +581,6 @@
 	.name			= "fileio",
 	.owner			= THIS_MODULE,
 	.transport_type		= TRANSPORT_PLUGIN_VHBA_PDEV,
-	.write_cache_emulated	= 1,
-	.fua_write_emulated	= 1,
 	.attach_hba		= fd_attach_hba,
 	.detach_hba		= fd_detach_hba,
 	.allocate_virtdevice	= fd_allocate_virtdevice,
diff --git a/drivers/target/target_core_file.h b/drivers/target/target_core_file.h
index 70ce7fd..876ae53 100644
--- a/drivers/target/target_core_file.h
+++ b/drivers/target/target_core_file.h
@@ -14,6 +14,7 @@
 
 #define FBDF_HAS_PATH		0x01
 #define FBDF_HAS_SIZE		0x02
+#define FDBD_HAS_BUFFERED_IO_WCE 0x04
 
 struct fd_dev {
 	u32		fbd_flags;
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index 9ba4954..57d7674 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -454,14 +454,11 @@
 				ret = -EEXIST;
 				goto out;
 			}
-			arg_p = match_strdup(&args[0]);
-			if (!arg_p) {
-				ret = -ENOMEM;
+			if (match_strlcpy(ib_dev->ibd_udev_path, &args[0],
+				SE_UDEV_PATH_LEN) == 0) {
+				ret = -EINVAL;
 				break;
 			}
-			snprintf(ib_dev->ibd_udev_path, SE_UDEV_PATH_LEN,
-					"%s", arg_p);
-			kfree(arg_p);
 			pr_debug("IBLOCK: Referencing UDEV path: %s\n",
 					ib_dev->ibd_udev_path);
 			ib_dev->ibd_flags |= IBDF_HAS_UDEV_PATH;
@@ -556,14 +553,6 @@
 	kfree(ibr);
 }
 
-static void iblock_bio_destructor(struct bio *bio)
-{
-	struct se_cmd *cmd = bio->bi_private;
-	struct iblock_dev *ib_dev = cmd->se_dev->dev_ptr;
-
-	bio_free(bio, ib_dev->ibd_bio_set);
-}
-
 static struct bio *
 iblock_get_bio(struct se_cmd *cmd, sector_t lba, u32 sg_num)
 {
@@ -585,7 +574,6 @@
 
 	bio->bi_bdev = ib_dev->ibd_bd;
 	bio->bi_private = cmd;
-	bio->bi_destructor = iblock_bio_destructor;
 	bio->bi_end_io = &iblock_bio_done;
 	bio->bi_sector = lba;
 	return bio;
@@ -657,6 +645,12 @@
 		goto fail;
 	cmd->priv = ibr;
 
+	if (!sgl_nents) {
+		atomic_set(&ibr->pending, 1);
+		iblock_complete_cmd(cmd);
+		return 0;
+	}
+
 	bio = iblock_get_bio(cmd, block_lba, sgl_nents);
 	if (!bio)
 		goto fail_free_ibr;
@@ -769,8 +763,6 @@
 	.name			= "iblock",
 	.owner			= THIS_MODULE,
 	.transport_type		= TRANSPORT_PLUGIN_VHBA_PDEV,
-	.write_cache_emulated	= 1,
-	.fua_write_emulated	= 1,
 	.attach_hba		= iblock_attach_hba,
 	.detach_hba		= iblock_detach_hba,
 	.allocate_virtdevice	= iblock_allocate_virtdevice,
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
index 956c84c..8c323a9 100644
--- a/drivers/target/target_core_pr.c
+++ b/drivers/target/target_core_pr.c
@@ -197,10 +197,10 @@
 {
 	struct se_device *dev = cmd->se_dev;
 	struct se_session *sess = cmd->se_sess;
-	struct se_portal_group *tpg = sess->se_tpg;
+	struct se_portal_group *tpg;
 	int ret = 0, rc;
 
-	if (!sess || !tpg)
+	if (!sess || !sess->se_tpg)
 		goto out;
 	rc = target_check_scsi2_reservation_conflict(cmd);
 	if (rc == 1)
@@ -228,6 +228,7 @@
 		dev->dev_res_bin_isid = 0;
 		dev->dev_flags &= ~DF_SPC2_RESERVATIONS_WITH_ISID;
 	}
+	tpg = sess->se_tpg;
 	pr_debug("SCSI-2 Released reservation for %s LUN: %u ->"
 		" MAPPED LUN: %u for %s\n", tpg->se_tpg_tfo->get_fabric_name(),
 		cmd->se_lun->unpacked_lun, cmd->se_deve->mapped_lun,
@@ -245,7 +246,7 @@
 {
 	struct se_device *dev = cmd->se_dev;
 	struct se_session *sess = cmd->se_sess;
-	struct se_portal_group *tpg = sess->se_tpg;
+	struct se_portal_group *tpg;
 	int ret = 0, rc;
 
 	if ((cmd->t_task_cdb[1] & 0x01) &&
@@ -260,7 +261,7 @@
 	 * This is currently the case for target_core_mod passthrough struct se_cmd
 	 * ops
 	 */
-	if (!sess || !tpg)
+	if (!sess || !sess->se_tpg)
 		goto out;
 	rc = target_check_scsi2_reservation_conflict(cmd);
 	if (rc == 1)
@@ -272,6 +273,7 @@
 	}
 
 	ret = 0;
+	tpg = sess->se_tpg;
 	spin_lock(&dev->dev_reservation_lock);
 	if (dev->dev_reserved_node_acl &&
 	   (dev->dev_reserved_node_acl != sess->se_node_acl)) {
@@ -1620,7 +1622,7 @@
 				goto out;
 			}
 			/*
-			 * Locate the desination initiator ACL to be registered
+			 * Locate the destination initiator ACL to be registered
 			 * from the decoded fabric module specific TransportID
 			 * at *i_str.
 			 */
@@ -4257,7 +4259,7 @@
 			buf[off++] = ((port->sep_rtpi >> 8) & 0xff);
 			buf[off++] = (port->sep_rtpi & 0xff);
 		} else
-			off += 2; /* Skip over RELATIVE TARGET PORT IDENTIFER */
+			off += 2; /* Skip over RELATIVE TARGET PORT IDENTIFIER */
 
 		/*
 		 * Now, have the $FABRIC_MOD fill in the protocol identifier
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c
index 9d7ce3d..617c086 100644
--- a/drivers/target/target_core_pscsi.c
+++ b/drivers/target/target_core_pscsi.c
@@ -264,7 +264,7 @@
 					" length zero!\n");
 			break;
 		}
-		pr_debug("T10 VPD Identifer Length: %d\n", ident_len);
+		pr_debug("T10 VPD Identifier Length: %d\n", ident_len);
 
 		vpd = kzalloc(sizeof(struct t10_vpd), GFP_KERNEL);
 		if (!vpd) {
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
index a9dd946..868f8aa 100644
--- a/drivers/target/target_core_sbc.c
+++ b/drivers/target/target_core_sbc.c
@@ -40,8 +40,9 @@
 static int sbc_emulate_readcapacity(struct se_cmd *cmd)
 {
 	struct se_device *dev = cmd->se_dev;
-	unsigned char *buf;
 	unsigned long long blocks_long = dev->transport->get_blocks(dev);
+	unsigned char *rbuf;
+	unsigned char buf[8];
 	u32 blocks;
 
 	if (blocks_long >= 0x00000000ffffffff)
@@ -49,8 +50,6 @@
 	else
 		blocks = (u32)blocks_long;
 
-	buf = transport_kmap_data_sg(cmd);
-
 	buf[0] = (blocks >> 24) & 0xff;
 	buf[1] = (blocks >> 16) & 0xff;
 	buf[2] = (blocks >> 8) & 0xff;
@@ -60,7 +59,11 @@
 	buf[6] = (dev->se_sub_dev->se_dev_attrib.block_size >> 8) & 0xff;
 	buf[7] = dev->se_sub_dev->se_dev_attrib.block_size & 0xff;
 
-	transport_kunmap_data_sg(cmd);
+	rbuf = transport_kmap_data_sg(cmd);
+	if (rbuf) {
+		memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
+		transport_kunmap_data_sg(cmd);
+	}
 
 	target_complete_cmd(cmd, GOOD);
 	return 0;
@@ -69,11 +72,11 @@
 static int sbc_emulate_readcapacity_16(struct se_cmd *cmd)
 {
 	struct se_device *dev = cmd->se_dev;
-	unsigned char *buf;
+	unsigned char *rbuf;
+	unsigned char buf[32];
 	unsigned long long blocks = dev->transport->get_blocks(dev);
 
-	buf = transport_kmap_data_sg(cmd);
-
+	memset(buf, 0, sizeof(buf));
 	buf[0] = (blocks >> 56) & 0xff;
 	buf[1] = (blocks >> 48) & 0xff;
 	buf[2] = (blocks >> 40) & 0xff;
@@ -93,7 +96,11 @@
 	if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws)
 		buf[14] = 0x80;
 
-	transport_kunmap_data_sg(cmd);
+	rbuf = transport_kmap_data_sg(cmd);
+	if (rbuf) {
+		memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
+		transport_kunmap_data_sg(cmd);
+	}
 
 	target_complete_cmd(cmd, GOOD);
 	return 0;
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c
index 388a922..9229bd9 100644
--- a/drivers/target/target_core_spc.c
+++ b/drivers/target/target_core_spc.c
@@ -600,30 +600,11 @@
 {
 	struct se_device *dev = cmd->se_dev;
 	struct se_portal_group *tpg = cmd->se_lun->lun_sep->sep_tpg;
-	unsigned char *buf, *map_buf;
+	unsigned char *rbuf;
 	unsigned char *cdb = cmd->t_task_cdb;
+	unsigned char buf[SE_INQUIRY_BUF];
 	int p, ret;
 
-	map_buf = transport_kmap_data_sg(cmd);
-	/*
-	 * If SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC is not set, then we
-	 * know we actually allocated a full page.  Otherwise, if the
-	 * data buffer is too small, allocate a temporary buffer so we
-	 * don't have to worry about overruns in all our INQUIRY
-	 * emulation handling.
-	 */
-	if (cmd->data_length < SE_INQUIRY_BUF &&
-	    (cmd->se_cmd_flags & SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC)) {
-		buf = kzalloc(SE_INQUIRY_BUF, GFP_KERNEL);
-		if (!buf) {
-			transport_kunmap_data_sg(cmd);
-			cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
-			return -ENOMEM;
-		}
-	} else {
-		buf = map_buf;
-	}
-
 	if (dev == tpg->tpg_virt_lun0.lun_se_dev)
 		buf[0] = 0x3f; /* Not connected */
 	else
@@ -655,11 +636,11 @@
 	ret = -EINVAL;
 
 out:
-	if (buf != map_buf) {
-		memcpy(map_buf, buf, cmd->data_length);
-		kfree(buf);
+	rbuf = transport_kmap_data_sg(cmd);
+	if (rbuf) {
+		memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
+		transport_kunmap_data_sg(cmd);
 	}
-	transport_kunmap_data_sg(cmd);
 
 	if (!ret)
 		target_complete_cmd(cmd, GOOD);
@@ -803,7 +784,7 @@
 	unsigned char *rbuf;
 	int type = dev->transport->get_device_type(dev);
 	int ten = (cmd->t_task_cdb[0] == MODE_SENSE_10);
-	int offset = ten ? 8 : 4;
+	u32 offset = ten ? 8 : 4;
 	int length = 0;
 	unsigned char buf[SE_MODE_PAGE_BUF];
 
@@ -836,6 +817,7 @@
 		offset -= 2;
 		buf[0] = (offset >> 8) & 0xff;
 		buf[1] = offset & 0xff;
+		offset += 2;
 
 		if ((cmd->se_lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) ||
 		    (cmd->se_deve &&
@@ -845,13 +827,10 @@
 		if ((dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0) &&
 		    (dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0))
 			spc_modesense_dpofua(&buf[3], type);
-
-		if ((offset + 2) > cmd->data_length)
-			offset = cmd->data_length;
-
 	} else {
 		offset -= 1;
 		buf[0] = offset & 0xff;
+		offset += 1;
 
 		if ((cmd->se_lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) ||
 		    (cmd->se_deve &&
@@ -861,14 +840,13 @@
 		if ((dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0) &&
 		    (dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0))
 			spc_modesense_dpofua(&buf[2], type);
-
-		if ((offset + 1) > cmd->data_length)
-			offset = cmd->data_length;
 	}
 
 	rbuf = transport_kmap_data_sg(cmd);
-	memcpy(rbuf, buf, offset);
-	transport_kunmap_data_sg(cmd);
+	if (rbuf) {
+		memcpy(rbuf, buf, min(offset, cmd->data_length));
+		transport_kunmap_data_sg(cmd);
+	}
 
 	target_complete_cmd(cmd, GOOD);
 	return 0;
diff --git a/drivers/target/target_core_stat.c b/drivers/target/target_core_stat.c
index 3d44beb..cb6b003 100644
--- a/drivers/target/target_core_stat.c
+++ b/drivers/target/target_core_stat.c
@@ -32,7 +32,6 @@
 #include <linux/delay.h>
 #include <linux/timer.h>
 #include <linux/string.h>
-#include <generated/utsrelease.h>
 #include <linux/utsname.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c
index b8628a5..a531fe2 100644
--- a/drivers/target/target_core_tpg.c
+++ b/drivers/target/target_core_tpg.c
@@ -303,7 +303,7 @@
 	}
 	/*
 	 * Here we only create demo-mode MappedLUNs from the active
-	 * TPG LUNs if the fabric is not explictly asking for
+	 * TPG LUNs if the fabric is not explicitly asking for
 	 * tpg_check_demo_mode_login_only() == 1.
 	 */
 	if ((tpg->se_tpg_tfo->tpg_check_demo_mode_login_only == NULL) ||
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 269f544..c33baff 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -55,8 +55,6 @@
 #include "target_core_pr.h"
 #include "target_core_ua.h"
 
-static int sub_api_initialized;
-
 static struct workqueue_struct *target_completion_wq;
 static struct kmem_cache *se_sess_cache;
 struct kmem_cache *se_ua_cache;
@@ -195,6 +193,7 @@
 void transport_subsystem_check_init(void)
 {
 	int ret;
+	static int sub_api_initialized;
 
 	if (sub_api_initialized)
 		return;
@@ -211,12 +210,7 @@
 	if (ret != 0)
 		pr_err("Unable to load target_core_pscsi\n");
 
-	ret = request_module("target_core_stgt");
-	if (ret != 0)
-		pr_err("Unable to load target_core_stgt\n");
-
 	sub_api_initialized = 1;
-	return;
 }
 
 struct se_session *transport_init_session(void)
@@ -573,9 +567,7 @@
  */
 static unsigned char *transport_get_sense_buffer(struct se_cmd *cmd)
 {
-	unsigned char *buffer = cmd->sense_buffer;
 	struct se_device *dev = cmd->se_dev;
-	u32 offset = 0;
 
 	WARN_ON(!cmd->se_lun);
 
@@ -585,14 +577,11 @@
 	if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION)
 		return NULL;
 
-	offset = cmd->se_tfo->set_fabric_sense_len(cmd, TRANSPORT_SENSE_BUFFER);
-
-	/* Automatically padded */
-	cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER + offset;
+	cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER;
 
 	pr_debug("HBA_[%u]_PLUG[%s]: Requesting sense for SAM STATUS: 0x%02x\n",
 		dev->se_hba->hba_id, dev->transport->name, cmd->scsi_status);
-	return &buffer[offset];
+	return cmd->sense_buffer;
 }
 
 void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status)
@@ -969,7 +958,7 @@
 transport_set_vpd_ident(struct t10_vpd *vpd, unsigned char *page_83)
 {
 	static const char hex_str[] = "0123456789abcdef";
-	int j = 0, i = 4; /* offset to start of the identifer */
+	int j = 0, i = 4; /* offset to start of the identifier */
 
 	/*
 	 * The VPD Code Set (encoding)
@@ -1466,8 +1455,9 @@
 }
 EXPORT_SYMBOL(transport_handle_cdb_direct);
 
-/**
- * target_submit_cmd - lookup unpacked lun and submit uninitialized se_cmd
+/*
+ * target_submit_cmd_map_sgls - lookup unpacked lun and submit uninitialized
+ * 			 se_cmd + use pre-allocated SGL memory.
  *
  * @se_cmd: command descriptor to submit
  * @se_sess: associated se_sess for endpoint
@@ -1478,6 +1468,10 @@
  * @task_addr: SAM task attribute
  * @data_dir: DMA data direction
  * @flags: flags for command submission from target_sc_flags_tables
+ * @sgl: struct scatterlist memory for unidirectional mapping
+ * @sgl_count: scatterlist count for unidirectional mapping
+ * @sgl_bidi: struct scatterlist memory for bidirectional READ mapping
+ * @sgl_bidi_count: scatterlist count for bidirectional READ mapping
  *
  * Returns non zero to signal active I/O shutdown failure.  All other
  * setup exceptions will be returned as a SCSI CHECK_CONDITION response,
@@ -1485,10 +1479,12 @@
  *
  * This may only be called from process context, and also currently
  * assumes internal allocation of fabric payload buffer by target-core.
- **/
-int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
+ */
+int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess,
 		unsigned char *cdb, unsigned char *sense, u32 unpacked_lun,
-		u32 data_length, int task_attr, int data_dir, int flags)
+		u32 data_length, int task_attr, int data_dir, int flags,
+		struct scatterlist *sgl, u32 sgl_count,
+		struct scatterlist *sgl_bidi, u32 sgl_bidi_count)
 {
 	struct se_portal_group *se_tpg;
 	int rc;
@@ -1535,7 +1531,42 @@
 		transport_generic_request_failure(se_cmd);
 		return 0;
 	}
+	/*
+	 * When a non zero sgl_count has been passed perform SGL passthrough
+	 * mapping for pre-allocated fabric memory instead of having target
+	 * core perform an internal SGL allocation..
+	 */
+	if (sgl_count != 0) {
+		BUG_ON(!sgl);
 
+		/*
+		 * A work-around for tcm_loop as some userspace code via
+		 * scsi-generic do not memset their associated read buffers,
+		 * so go ahead and do that here for type non-data CDBs.  Also
+		 * note that this is currently guaranteed to be a single SGL
+		 * for this case by target core in target_setup_cmd_from_cdb()
+		 * -> transport_generic_cmd_sequencer().
+		 */
+		if (!(se_cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) &&
+		     se_cmd->data_direction == DMA_FROM_DEVICE) {
+			unsigned char *buf = NULL;
+
+			if (sgl)
+				buf = kmap(sg_page(sgl)) + sgl->offset;
+
+			if (buf) {
+				memset(buf, 0, sgl->length);
+				kunmap(sg_page(sgl));
+			}
+		}
+
+		rc = transport_generic_map_mem_to_cmd(se_cmd, sgl, sgl_count,
+				sgl_bidi, sgl_bidi_count);
+		if (rc != 0) {
+			transport_generic_request_failure(se_cmd);
+			return 0;
+		}
+	}
 	/*
 	 * Check if we need to delay processing because of ALUA
 	 * Active/NonOptimized primary access state..
@@ -1545,6 +1576,38 @@
 	transport_handle_cdb_direct(se_cmd);
 	return 0;
 }
+EXPORT_SYMBOL(target_submit_cmd_map_sgls);
+
+/*
+ * target_submit_cmd - lookup unpacked lun and submit uninitialized se_cmd
+ *
+ * @se_cmd: command descriptor to submit
+ * @se_sess: associated se_sess for endpoint
+ * @cdb: pointer to SCSI CDB
+ * @sense: pointer to SCSI sense buffer
+ * @unpacked_lun: unpacked LUN to reference for struct se_lun
+ * @data_length: fabric expected data transfer length
+ * @task_addr: SAM task attribute
+ * @data_dir: DMA data direction
+ * @flags: flags for command submission from target_sc_flags_tables
+ *
+ * Returns non zero to signal active I/O shutdown failure.  All other
+ * setup exceptions will be returned as a SCSI CHECK_CONDITION response,
+ * but still return zero here.
+ *
+ * This may only be called from process context, and also currently
+ * assumes internal allocation of fabric payload buffer by target-core.
+ *
+ * It also assumes interal target core SGL memory allocation.
+ */
+int target_submit_cmd(struct se_cmd *se_cmd, struct se_session *se_sess,
+		unsigned char *cdb, unsigned char *sense, u32 unpacked_lun,
+		u32 data_length, int task_attr, int data_dir, int flags)
+{
+	return target_submit_cmd_map_sgls(se_cmd, se_sess, cdb, sense,
+			unpacked_lun, data_length, task_attr, data_dir,
+			flags, NULL, 0, NULL, 0);
+}
 EXPORT_SYMBOL(target_submit_cmd);
 
 static void target_complete_tmr_failure(struct work_struct *work)
@@ -2300,23 +2363,6 @@
 		if (ret < 0)
 			goto out_fail;
 	}
-	/*
-	 * If this command doesn't have any payload and we don't have to call
-	 * into the fabric for data transfers, go ahead and complete it right
-	 * away.
-	 */
-	if (!cmd->data_length &&
-	    cmd->t_task_cdb[0] != REQUEST_SENSE &&
-	    cmd->se_dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV) {
-		spin_lock_irq(&cmd->t_state_lock);
-		cmd->t_state = TRANSPORT_COMPLETE;
-		cmd->transport_state |= CMD_T_ACTIVE;
-		spin_unlock_irq(&cmd->t_state_lock);
-
-		INIT_WORK(&cmd->work, target_complete_ok_work);
-		queue_work(target_completion_wq, &cmd->work);
-		return 0;
-	}
 
 	atomic_inc(&cmd->t_fe_count);
 
@@ -2771,7 +2817,7 @@
 	spin_lock_irqsave(&cmd->t_state_lock, flags);
 	cmd->transport_state &= ~(CMD_T_ACTIVE | CMD_T_STOP);
 
-	pr_debug("wait_for_tasks: Stopped wait_for_compltion("
+	pr_debug("wait_for_tasks: Stopped wait_for_completion("
 		"&cmd->t_transport_stop_comp) for ITT: 0x%08x\n",
 		cmd->se_tfo->get_task_tag(cmd));
 
@@ -2810,7 +2856,6 @@
 {
 	unsigned char *buffer = cmd->sense_buffer;
 	unsigned long flags;
-	int offset;
 	u8 asc = 0, ascq = 0;
 
 	spin_lock_irqsave(&cmd->t_state_lock, flags);
@@ -2826,14 +2871,7 @@
 
 	if (!from_transport)
 		cmd->se_cmd_flags |= SCF_EMULATED_TASK_SENSE;
-	/*
-	 * Data Segment and SenseLength of the fabric response PDU.
-	 *
-	 * TRANSPORT_SENSE_BUFFER is now set to SCSI_SENSE_BUFFERSIZE
-	 * from include/scsi/scsi_cmnd.h
-	 */
-	offset = cmd->se_tfo->set_fabric_sense_len(cmd,
-				TRANSPORT_SENSE_BUFFER);
+
 	/*
 	 * Actual SENSE DATA, see SPC-3 7.23.2  SPC_SENSE_KEY_OFFSET uses
 	 * SENSE KEY values from include/scsi/scsi.h
@@ -2841,151 +2879,151 @@
 	switch (reason) {
 	case TCM_NON_EXISTENT_LUN:
 		/* CURRENT ERROR */
-		buffer[offset] = 0x70;
-		buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+		buffer[0] = 0x70;
+		buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
 		/* ILLEGAL REQUEST */
-		buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
+		buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
 		/* LOGICAL UNIT NOT SUPPORTED */
-		buffer[offset+SPC_ASC_KEY_OFFSET] = 0x25;
+		buffer[SPC_ASC_KEY_OFFSET] = 0x25;
 		break;
 	case TCM_UNSUPPORTED_SCSI_OPCODE:
 	case TCM_SECTOR_COUNT_TOO_MANY:
 		/* CURRENT ERROR */
-		buffer[offset] = 0x70;
-		buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+		buffer[0] = 0x70;
+		buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
 		/* ILLEGAL REQUEST */
-		buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
+		buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
 		/* INVALID COMMAND OPERATION CODE */
-		buffer[offset+SPC_ASC_KEY_OFFSET] = 0x20;
+		buffer[SPC_ASC_KEY_OFFSET] = 0x20;
 		break;
 	case TCM_UNKNOWN_MODE_PAGE:
 		/* CURRENT ERROR */
-		buffer[offset] = 0x70;
-		buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+		buffer[0] = 0x70;
+		buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
 		/* ILLEGAL REQUEST */
-		buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
+		buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
 		/* INVALID FIELD IN CDB */
-		buffer[offset+SPC_ASC_KEY_OFFSET] = 0x24;
+		buffer[SPC_ASC_KEY_OFFSET] = 0x24;
 		break;
 	case TCM_CHECK_CONDITION_ABORT_CMD:
 		/* CURRENT ERROR */
-		buffer[offset] = 0x70;
-		buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+		buffer[0] = 0x70;
+		buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
 		/* ABORTED COMMAND */
-		buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
+		buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
 		/* BUS DEVICE RESET FUNCTION OCCURRED */
-		buffer[offset+SPC_ASC_KEY_OFFSET] = 0x29;
-		buffer[offset+SPC_ASCQ_KEY_OFFSET] = 0x03;
+		buffer[SPC_ASC_KEY_OFFSET] = 0x29;
+		buffer[SPC_ASCQ_KEY_OFFSET] = 0x03;
 		break;
 	case TCM_INCORRECT_AMOUNT_OF_DATA:
 		/* CURRENT ERROR */
-		buffer[offset] = 0x70;
-		buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+		buffer[0] = 0x70;
+		buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
 		/* ABORTED COMMAND */
-		buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
+		buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
 		/* WRITE ERROR */
-		buffer[offset+SPC_ASC_KEY_OFFSET] = 0x0c;
+		buffer[SPC_ASC_KEY_OFFSET] = 0x0c;
 		/* NOT ENOUGH UNSOLICITED DATA */
-		buffer[offset+SPC_ASCQ_KEY_OFFSET] = 0x0d;
+		buffer[SPC_ASCQ_KEY_OFFSET] = 0x0d;
 		break;
 	case TCM_INVALID_CDB_FIELD:
 		/* CURRENT ERROR */
-		buffer[offset] = 0x70;
-		buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+		buffer[0] = 0x70;
+		buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
 		/* ILLEGAL REQUEST */
-		buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
+		buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
 		/* INVALID FIELD IN CDB */
-		buffer[offset+SPC_ASC_KEY_OFFSET] = 0x24;
+		buffer[SPC_ASC_KEY_OFFSET] = 0x24;
 		break;
 	case TCM_INVALID_PARAMETER_LIST:
 		/* CURRENT ERROR */
-		buffer[offset] = 0x70;
-		buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+		buffer[0] = 0x70;
+		buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
 		/* ILLEGAL REQUEST */
-		buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
+		buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
 		/* INVALID FIELD IN PARAMETER LIST */
-		buffer[offset+SPC_ASC_KEY_OFFSET] = 0x26;
+		buffer[SPC_ASC_KEY_OFFSET] = 0x26;
 		break;
 	case TCM_UNEXPECTED_UNSOLICITED_DATA:
 		/* CURRENT ERROR */
-		buffer[offset] = 0x70;
-		buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+		buffer[0] = 0x70;
+		buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
 		/* ABORTED COMMAND */
-		buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
+		buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
 		/* WRITE ERROR */
-		buffer[offset+SPC_ASC_KEY_OFFSET] = 0x0c;
+		buffer[SPC_ASC_KEY_OFFSET] = 0x0c;
 		/* UNEXPECTED_UNSOLICITED_DATA */
-		buffer[offset+SPC_ASCQ_KEY_OFFSET] = 0x0c;
+		buffer[SPC_ASCQ_KEY_OFFSET] = 0x0c;
 		break;
 	case TCM_SERVICE_CRC_ERROR:
 		/* CURRENT ERROR */
-		buffer[offset] = 0x70;
-		buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+		buffer[0] = 0x70;
+		buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
 		/* ABORTED COMMAND */
-		buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
+		buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
 		/* PROTOCOL SERVICE CRC ERROR */
-		buffer[offset+SPC_ASC_KEY_OFFSET] = 0x47;
+		buffer[SPC_ASC_KEY_OFFSET] = 0x47;
 		/* N/A */
-		buffer[offset+SPC_ASCQ_KEY_OFFSET] = 0x05;
+		buffer[SPC_ASCQ_KEY_OFFSET] = 0x05;
 		break;
 	case TCM_SNACK_REJECTED:
 		/* CURRENT ERROR */
-		buffer[offset] = 0x70;
-		buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+		buffer[0] = 0x70;
+		buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
 		/* ABORTED COMMAND */
-		buffer[offset+SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
+		buffer[SPC_SENSE_KEY_OFFSET] = ABORTED_COMMAND;
 		/* READ ERROR */
-		buffer[offset+SPC_ASC_KEY_OFFSET] = 0x11;
+		buffer[SPC_ASC_KEY_OFFSET] = 0x11;
 		/* FAILED RETRANSMISSION REQUEST */
-		buffer[offset+SPC_ASCQ_KEY_OFFSET] = 0x13;
+		buffer[SPC_ASCQ_KEY_OFFSET] = 0x13;
 		break;
 	case TCM_WRITE_PROTECTED:
 		/* CURRENT ERROR */
-		buffer[offset] = 0x70;
-		buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+		buffer[0] = 0x70;
+		buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
 		/* DATA PROTECT */
-		buffer[offset+SPC_SENSE_KEY_OFFSET] = DATA_PROTECT;
+		buffer[SPC_SENSE_KEY_OFFSET] = DATA_PROTECT;
 		/* WRITE PROTECTED */
-		buffer[offset+SPC_ASC_KEY_OFFSET] = 0x27;
+		buffer[SPC_ASC_KEY_OFFSET] = 0x27;
 		break;
 	case TCM_ADDRESS_OUT_OF_RANGE:
 		/* CURRENT ERROR */
-		buffer[offset] = 0x70;
-		buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+		buffer[0] = 0x70;
+		buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
 		/* ILLEGAL REQUEST */
-		buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
+		buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
 		/* LOGICAL BLOCK ADDRESS OUT OF RANGE */
-		buffer[offset+SPC_ASC_KEY_OFFSET] = 0x21;
+		buffer[SPC_ASC_KEY_OFFSET] = 0x21;
 		break;
 	case TCM_CHECK_CONDITION_UNIT_ATTENTION:
 		/* CURRENT ERROR */
-		buffer[offset] = 0x70;
-		buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+		buffer[0] = 0x70;
+		buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
 		/* UNIT ATTENTION */
-		buffer[offset+SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION;
+		buffer[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION;
 		core_scsi3_ua_for_check_condition(cmd, &asc, &ascq);
-		buffer[offset+SPC_ASC_KEY_OFFSET] = asc;
-		buffer[offset+SPC_ASCQ_KEY_OFFSET] = ascq;
+		buffer[SPC_ASC_KEY_OFFSET] = asc;
+		buffer[SPC_ASCQ_KEY_OFFSET] = ascq;
 		break;
 	case TCM_CHECK_CONDITION_NOT_READY:
 		/* CURRENT ERROR */
-		buffer[offset] = 0x70;
-		buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+		buffer[0] = 0x70;
+		buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
 		/* Not Ready */
-		buffer[offset+SPC_SENSE_KEY_OFFSET] = NOT_READY;
+		buffer[SPC_SENSE_KEY_OFFSET] = NOT_READY;
 		transport_get_sense_codes(cmd, &asc, &ascq);
-		buffer[offset+SPC_ASC_KEY_OFFSET] = asc;
-		buffer[offset+SPC_ASCQ_KEY_OFFSET] = ascq;
+		buffer[SPC_ASC_KEY_OFFSET] = asc;
+		buffer[SPC_ASCQ_KEY_OFFSET] = ascq;
 		break;
 	case TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE:
 	default:
 		/* CURRENT ERROR */
-		buffer[offset] = 0x70;
-		buffer[offset+SPC_ADD_SENSE_LEN_OFFSET] = 10;
+		buffer[0] = 0x70;
+		buffer[SPC_ADD_SENSE_LEN_OFFSET] = 10;
 		/* ILLEGAL REQUEST */
-		buffer[offset+SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
+		buffer[SPC_SENSE_KEY_OFFSET] = ILLEGAL_REQUEST;
 		/* LOGICAL UNIT COMMUNICATION FAILURE */
-		buffer[offset+SPC_ASC_KEY_OFFSET] = 0x80;
+		buffer[SPC_ASC_KEY_OFFSET] = 0x80;
 		break;
 	}
 	/*
@@ -2996,7 +3034,7 @@
 	 * Automatically padded, this value is encoded in the fabric's
 	 * data_length response PDU containing the SCSI defined sense data.
 	 */
-	cmd->scsi_sense_length  = TRANSPORT_SENSE_BUFFER + offset;
+	cmd->scsi_sense_length  = TRANSPORT_SENSE_BUFFER;
 
 after_reason:
 	return cmd->se_tfo->queue_status(cmd);
diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c
index 823e692..b406f17 100644
--- a/drivers/target/tcm_fc/tfc_cmd.c
+++ b/drivers/target/tcm_fc/tfc_cmd.c
@@ -19,7 +19,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <generated/utsrelease.h>
 #include <linux/utsname.h>
 #include <linux/init.h>
 #include <linux/slab.h>
diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c
index 9501844..b74feb0 100644
--- a/drivers/target/tcm_fc/tfc_conf.c
+++ b/drivers/target/tcm_fc/tfc_conf.c
@@ -495,16 +495,6 @@
 {
 }
 
-static u16 ft_get_fabric_sense_len(void)
-{
-	return 0;
-}
-
-static u16 ft_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_len)
-{
-	return 0;
-}
-
 static u32 ft_tpg_get_inst_index(struct se_portal_group *se_tpg)
 {
 	struct ft_tpg *tpg = se_tpg->se_tpg_fabric_ptr;
@@ -542,8 +532,6 @@
 	.queue_data_in =		ft_queue_data_in,
 	.queue_status =			ft_queue_status,
 	.queue_tm_rsp =			ft_queue_tm_resp,
-	.get_fabric_sense_len =		ft_get_fabric_sense_len,
-	.set_fabric_sense_len =		ft_set_fabric_sense_len,
 	/*
 	 * Setup function pointers for generic logic in
 	 * target_core_fabric_configfs.c
diff --git a/drivers/target/tcm_fc/tfc_io.c b/drivers/target/tcm_fc/tfc_io.c
index ad36ede1..b6fd4cf 100644
--- a/drivers/target/tcm_fc/tfc_io.c
+++ b/drivers/target/tcm_fc/tfc_io.c
@@ -28,7 +28,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <generated/utsrelease.h>
 #include <linux/utsname.h>
 #include <linux/init.h>
 #include <linux/slab.h>
@@ -328,11 +327,12 @@
  */
 void ft_invl_hw_context(struct ft_cmd *cmd)
 {
-	struct fc_seq *seq = cmd->seq;
+	struct fc_seq *seq;
 	struct fc_exch *ep = NULL;
 	struct fc_lport *lport = NULL;
 
 	BUG_ON(!cmd);
+	seq = cmd->seq;
 
 	/* Cleanup the DDP context in HW if DDP was setup */
 	if (cmd->was_ddp_setup && seq) {
diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c
index 3c9e5b5..9585010 100644
--- a/drivers/target/tcm_fc/tfc_sess.c
+++ b/drivers/target/tcm_fc/tfc_sess.c
@@ -19,7 +19,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <generated/utsrelease.h>
 #include <linux/utsname.h>
 #include <linux/init.h>
 #include <linux/slab.h>
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index a783d53..5110f36 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -653,8 +653,6 @@
 	if (mi < 0)
 		return -EINVAL;
 
-	vma->vm_flags |= VM_IO | VM_RESERVED;
-
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 
 	return remap_pfn_range(vma,
@@ -666,7 +664,7 @@
 
 static int uio_mmap_logical(struct vm_area_struct *vma)
 {
-	vma->vm_flags |= VM_RESERVED;
+	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 	vma->vm_ops = &uio_vm_ops;
 	uio_vma_open(vma);
 	return 0;
diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c
index 0ef7d42..cef4252 100644
--- a/drivers/usb/core/usb-acpi.c
+++ b/drivers/usb/core/usb-acpi.c
@@ -87,7 +87,7 @@
 	acpi_status status;
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 	union acpi_object *upc;
-	struct acpi_pld pld;
+	struct acpi_pld_info *pld;
 	int ret = 0;
 
 	/*
@@ -111,16 +111,17 @@
 	}
 
 	if (upc->package.elements[0].integer.value)
-		if (pld.user_visible)
+		if (pld->user_visible)
 			usb_set_hub_port_connect_type(hdev, port1,
 				USB_PORT_CONNECT_TYPE_HOT_PLUG);
 		else
 			usb_set_hub_port_connect_type(hdev, port1,
 				USB_PORT_CONNECT_TYPE_HARD_WIRED);
-	else if (!pld.user_visible)
+	else if (!pld->user_visible)
 		usb_set_hub_port_connect_type(hdev, port1, USB_PORT_NOT_USED);
 
 out:
+	ACPI_FREE(pld);
 	kfree(upc);
 	return ret;
 }
diff --git a/drivers/usb/gadget/tcm_usb_gadget.c b/drivers/usb/gadget/tcm_usb_gadget.c
index eaa1005..97e68b3 100644
--- a/drivers/usb/gadget/tcm_usb_gadget.c
+++ b/drivers/usb/gadget/tcm_usb_gadget.c
@@ -1472,16 +1472,6 @@
 	return 0;
 }
 
-static u16 usbg_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length)
-{
-	return 0;
-}
-
-static u16 usbg_get_fabric_sense_len(void)
-{
-	return 0;
-}
-
 static const char *usbg_check_wwn(const char *name)
 {
 	const char *n;
@@ -1822,7 +1812,7 @@
 		ret = tcm_usbg_drop_nexus(tpg);
 		return (!ret) ? count : ret;
 	}
-	if (strlen(page) > USBG_NAMELEN) {
+	if (strlen(page) >= USBG_NAMELEN) {
 		pr_err("Emulated NAA Sas Address: %s, exceeds"
 				" max: %d\n", page, USBG_NAMELEN);
 		return -EINVAL;
@@ -1907,8 +1897,6 @@
 	.queue_data_in			= usbg_send_read_response,
 	.queue_status			= usbg_send_status_response,
 	.queue_tm_rsp			= usbg_queue_tm_rsp,
-	.get_fabric_sense_len		= usbg_get_fabric_sense_len,
-	.set_fabric_sense_len		= usbg_set_fabric_sense_len,
 	.check_stop_free		= usbg_check_stop_free,
 
 	.fabric_make_wwn		= usbg_make_tport,
@@ -1968,7 +1956,6 @@
 static struct usb_interface_descriptor bot_intf_desc = {
 	.bLength =              sizeof(bot_intf_desc),
 	.bDescriptorType =      USB_DT_INTERFACE,
-	.bAlternateSetting =	0,
 	.bNumEndpoints =        2,
 	.bAlternateSetting =	USB_G_ALT_INT_BBB,
 	.bInterfaceClass =      USB_CLASS_MASS_STORAGE,
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c
index 91cd850..9a62e89 100644
--- a/drivers/usb/mon/mon_bin.c
+++ b/drivers/usb/mon/mon_bin.c
@@ -1247,7 +1247,7 @@
 {
 	/* don't do anything here: "fault" will set up page table entries */
 	vma->vm_ops = &mon_bin_vm_ops;
-	vma->vm_flags |= VM_RESERVED;
+	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 	vma->vm_private_data = filp->private_data;
 	mon_bin_vma_open(vma);
 	return 0;
diff --git a/drivers/usb/musb/musb_io.h b/drivers/usb/musb/musb_io.h
index f7c1c8e2..565ad16 100644
--- a/drivers/usb/musb/musb_io.h
+++ b/drivers/usb/musb/musb_io.h
@@ -40,7 +40,8 @@
 #if !defined(CONFIG_ARM) && !defined(CONFIG_SUPERH) \
 	&& !defined(CONFIG_AVR32) && !defined(CONFIG_PPC32) \
 	&& !defined(CONFIG_PPC64) && !defined(CONFIG_BLACKFIN) \
-	&& !defined(CONFIG_MIPS) && !defined(CONFIG_M68K)
+	&& !defined(CONFIG_MIPS) && !defined(CONFIG_M68K) \
+	&& !defined(CONFIG_XTENSA)
 static inline void readsl(const void __iomem *addr, void *buf, int len)
 	{ insl((unsigned long)addr, buf, len); }
 static inline void readsw(const void __iomem *addr, void *buf, int len)
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index 6968b72..6c11994 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -408,7 +408,7 @@
 	struct vfio_pci_device *vdev = device_data;
 	struct pci_dev *pdev = vdev->pdev;
 	unsigned int index;
-	u64 phys_len, req_len, pgoff, req_start, phys;
+	u64 phys_len, req_len, pgoff, req_start;
 	int ret;
 
 	index = vma->vm_pgoff >> (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT);
@@ -461,12 +461,11 @@
 	}
 
 	vma->vm_private_data = vdev;
-	vma->vm_flags |= (VM_IO | VM_RESERVED);
+	vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+	vma->vm_pgoff = (pci_resource_start(pdev, index) >> PAGE_SHIFT) + pgoff;
 
-	phys = (pci_resource_start(pdev, index) >> PAGE_SHIFT) + pgoff;
-
-	return remap_pfn_range(vma, vma->vm_start, phys,
+	return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
 			       req_len, vma->vm_page_prot);
 }
 
diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c
index d8dedc7..3639371 100644
--- a/drivers/vfio/pci/vfio_pci_intrs.c
+++ b/drivers/vfio/pci/vfio_pci_intrs.c
@@ -366,6 +366,17 @@
 		return -ENOMEM;
 
 	vdev->num_ctx = 1;
+
+	/*
+	 * If the virtual interrupt is masked, restore it.  Devices
+	 * supporting DisINTx can be masked at the hardware level
+	 * here, non-PCI-2.3 devices will have to wait until the
+	 * interrupt is enabled.
+	 */
+	vdev->ctx[0].masked = vdev->virq_disabled;
+	if (vdev->pci_2_3)
+		pci_intx(vdev->pdev, !vdev->ctx[0].masked);
+
 	vdev->irq_type = VFIO_PCI_INTX_IRQ_INDEX;
 
 	return 0;
@@ -400,25 +411,26 @@
 		return PTR_ERR(trigger);
 	}
 
+	vdev->ctx[0].trigger = trigger;
+
 	if (!vdev->pci_2_3)
 		irqflags = 0;
 
 	ret = request_irq(pdev->irq, vfio_intx_handler,
 			  irqflags, vdev->ctx[0].name, vdev);
 	if (ret) {
+		vdev->ctx[0].trigger = NULL;
 		kfree(vdev->ctx[0].name);
 		eventfd_ctx_put(trigger);
 		return ret;
 	}
 
-	vdev->ctx[0].trigger = trigger;
-
 	/*
 	 * INTx disable will stick across the new irq setup,
 	 * disable_irq won't.
 	 */
 	spin_lock_irqsave(&vdev->irqlock, flags);
-	if (!vdev->pci_2_3 && (vdev->ctx[0].masked || vdev->virq_disabled))
+	if (!vdev->pci_2_3 && vdev->ctx[0].masked)
 		disable_irq_nosync(pdev->irq);
 	spin_unlock_irqrestore(&vdev->irqlock, flags);
 
diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c
index ed8e2e6..aa31692 100644
--- a/drivers/vhost/tcm_vhost.c
+++ b/drivers/vhost/tcm_vhost.c
@@ -330,17 +330,6 @@
 	return 0;
 }
 
-static u16 tcm_vhost_set_fabric_sense_len(struct se_cmd *se_cmd,
-	u32 sense_length)
-{
-	return 0;
-}
-
-static u16 tcm_vhost_get_fabric_sense_len(void)
-{
-	return 0;
-}
-
 static void vhost_scsi_free_cmd(struct tcm_vhost_cmd *tv_cmd)
 {
 	struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd;
@@ -426,10 +415,7 @@
 {
 	struct tcm_vhost_cmd *tv_cmd;
 	struct tcm_vhost_nexus *tv_nexus;
-	struct se_portal_group *se_tpg = &tv_tpg->se_tpg;
 	struct se_session *se_sess;
-	struct se_cmd *se_cmd;
-	int sam_task_attr;
 
 	tv_nexus = tv_tpg->tpg_nexus;
 	if (!tv_nexus) {
@@ -445,23 +431,11 @@
 	}
 	INIT_LIST_HEAD(&tv_cmd->tvc_completion_list);
 	tv_cmd->tvc_tag = v_req->tag;
+	tv_cmd->tvc_task_attr = v_req->task_attr;
+	tv_cmd->tvc_exp_data_len = exp_data_len;
+	tv_cmd->tvc_data_direction = data_direction;
+	tv_cmd->tvc_nexus = tv_nexus;
 
-	se_cmd = &tv_cmd->tvc_se_cmd;
-	/*
-	 * Locate the SAM Task Attr from virtio_scsi_cmd_req
-	 */
-	sam_task_attr = v_req->task_attr;
-	/*
-	 * Initialize struct se_cmd descriptor from TCM infrastructure
-	 */
-	transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, exp_data_len,
-				data_direction, sam_task_attr,
-				&tv_cmd->tvc_sense_buf[0]);
-
-#if 0	/* FIXME: vhost_scsi_allocate_cmd() BIDI operation */
-	if (bidi)
-		se_cmd->se_cmd_flags |= SCF_BIDI;
-#endif
 	return tv_cmd;
 }
 
@@ -560,37 +534,10 @@
 {
 	struct tcm_vhost_cmd *tv_cmd =
 		container_of(work, struct tcm_vhost_cmd, work);
+	struct tcm_vhost_nexus *tv_nexus;
 	struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd;
 	struct scatterlist *sg_ptr, *sg_bidi_ptr = NULL;
 	int rc, sg_no_bidi = 0;
-	/*
-	 * Locate the struct se_lun pointer based on v_req->lun, and
-	 * attach it to struct se_cmd
-	 */
-	rc = transport_lookup_cmd_lun(&tv_cmd->tvc_se_cmd, tv_cmd->tvc_lun);
-	if (rc < 0) {
-		pr_err("Failed to look up lun: %d\n", tv_cmd->tvc_lun);
-		transport_send_check_condition_and_sense(&tv_cmd->tvc_se_cmd,
-			tv_cmd->tvc_se_cmd.scsi_sense_reason, 0);
-		transport_generic_free_cmd(se_cmd, 0);
-		return;
-	}
-
-	rc = target_setup_cmd_from_cdb(se_cmd, tv_cmd->tvc_cdb);
-	if (rc == -ENOMEM) {
-		transport_send_check_condition_and_sense(se_cmd,
-				TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0);
-		transport_generic_free_cmd(se_cmd, 0);
-		return;
-	} else if (rc < 0) {
-		if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT)
-			tcm_vhost_queue_status(se_cmd);
-		else
-			transport_send_check_condition_and_sense(se_cmd,
-					se_cmd->scsi_sense_reason, 0);
-		transport_generic_free_cmd(se_cmd, 0);
-		return;
-	}
 
 	if (tv_cmd->tvc_sgl_count) {
 		sg_ptr = tv_cmd->tvc_sgl;
@@ -608,17 +555,19 @@
 	} else {
 		sg_ptr = NULL;
 	}
+	tv_nexus = tv_cmd->tvc_nexus;
 
-	rc = transport_generic_map_mem_to_cmd(se_cmd, sg_ptr,
-				tv_cmd->tvc_sgl_count, sg_bidi_ptr,
-				sg_no_bidi);
+	rc = target_submit_cmd_map_sgls(se_cmd, tv_nexus->tvn_se_sess,
+			tv_cmd->tvc_cdb, &tv_cmd->tvc_sense_buf[0],
+			tv_cmd->tvc_lun, tv_cmd->tvc_exp_data_len,
+			tv_cmd->tvc_task_attr, tv_cmd->tvc_data_direction,
+			0, sg_ptr, tv_cmd->tvc_sgl_count,
+			sg_bidi_ptr, sg_no_bidi);
 	if (rc < 0) {
 		transport_send_check_condition_and_sense(se_cmd,
-				se_cmd->scsi_sense_reason, 0);
+				TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0);
 		transport_generic_free_cmd(se_cmd, 0);
-		return;
 	}
-	transport_handle_cdb_direct(se_cmd);
 }
 
 static void vhost_scsi_handle_vq(struct vhost_scsi *vs)
@@ -1531,8 +1480,6 @@
 	.queue_data_in			= tcm_vhost_queue_data_in,
 	.queue_status			= tcm_vhost_queue_status,
 	.queue_tm_rsp			= tcm_vhost_queue_tm_rsp,
-	.get_fabric_sense_len		= tcm_vhost_get_fabric_sense_len,
-	.set_fabric_sense_len		= tcm_vhost_set_fabric_sense_len,
 	/*
 	 * Setup callers for generic logic in target_core_fabric_configfs.c
 	 */
diff --git a/drivers/vhost/tcm_vhost.h b/drivers/vhost/tcm_vhost.h
index d9e9355..7e87c63 100644
--- a/drivers/vhost/tcm_vhost.h
+++ b/drivers/vhost/tcm_vhost.h
@@ -5,6 +5,12 @@
 struct tcm_vhost_cmd {
 	/* Descriptor from vhost_get_vq_desc() for virt_queue segment */
 	int tvc_vq_desc;
+	/* virtio-scsi initiator task attribute */
+	int tvc_task_attr;
+	/* virtio-scsi initiator data direction */
+	enum dma_data_direction tvc_data_direction;
+	/* Expected data transfer length from virtio-scsi header */
+	u32 tvc_exp_data_len;
 	/* The Tag from include/linux/virtio_scsi.h:struct virtio_scsi_cmd_req */
 	u64 tvc_tag;
 	/* The number of scatterlists associated with this cmd */
@@ -17,6 +23,8 @@
 	struct virtio_scsi_cmd_resp __user *tvc_resp;
 	/* Pointer to vhost_scsi for our device */
 	struct vhost_scsi *tvc_vhost;
+	/* Pointer to vhost nexus memory */
+	struct tcm_vhost_nexus *tvc_nexus;
 	/* The TCM I/O descriptor that is accessed via container_of() */
 	struct se_cmd tvc_se_cmd;
 	/* work item used for cmwq dispatch to tcm_vhost_submission_work() */
diff --git a/drivers/video/68328fb.c b/drivers/video/68328fb.c
index a425d65..fa44fbe 100644
--- a/drivers/video/68328fb.c
+++ b/drivers/video/68328fb.c
@@ -400,7 +400,7 @@
 #ifndef MMU
 	/* this is uClinux (no MMU) specific code */
 
-	vma->vm_flags |= VM_RESERVED;
+	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 	vma->vm_start = videomemory;
 
 	return 0;
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 20c33c4..d08d799 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2139,21 +2139,6 @@
 	  mplayer -vo fbdev. Supports all USB 2.0 era DisplayLink devices.
 	  To compile as a module, choose M here: the module name is udlfb.
 
-config FB_PNX4008_DUM
-	tristate "Display Update Module support on Philips PNX4008 board"
-	depends on FB && ARCH_PNX4008
-	---help---
-	  Say Y here to enable support for PNX4008 Display Update Module (DUM)
-
-config FB_PNX4008_DUM_RGB
-	tristate "RGB Framebuffer support on Philips PNX4008 board"
-	depends on FB_PNX4008_DUM
-	select FB_CFB_FILLRECT
-	select FB_CFB_COPYAREA
-	select FB_CFB_IMAGEBLIT
-	---help---
-	  Say Y here to enable support for PNX4008 RGB Framebuffer
-
 config FB_IBM_GXT4500
 	tristate "Framebuffer support for IBM GXT4500P adaptor"
 	depends on FB && PPC
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 1940359..23e948e 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -127,8 +127,6 @@
 obj-$(CONFIG_FB_S3C2410)	  += s3c2410fb.o
 obj-$(CONFIG_FB_FSL_DIU)	  += fsl-diu-fb.o
 obj-$(CONFIG_FB_COBALT)           += cobalt_lcdfb.o
-obj-$(CONFIG_FB_PNX4008_DUM)	  += pnx4008/
-obj-$(CONFIG_FB_PNX4008_DUM_RGB)  += pnx4008/
 obj-$(CONFIG_FB_IBM_GXT4500)	  += gxt4500.o
 obj-$(CONFIG_FB_PS3)		  += ps3fb.o
 obj-$(CONFIG_FB_SM501)            += sm501fb.o
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index 887df9d..7fa1bf8 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -949,7 +949,6 @@
 
 
 static int amifb_ilbm = 0;	/* interleaved or normal bitplanes */
-static int amifb_inverse = 0;
 
 static u32 amifb_hfmin __initdata;	/* monitor hfreq lower limit (Hz) */
 static u32 amifb_hfmax __initdata;	/* monitor hfreq upper limit (Hz) */
@@ -2355,7 +2354,6 @@
 		if (!*this_opt)
 			continue;
 		if (!strcmp(this_opt, "inverse")) {
-			amifb_inverse = 1;
 			fb_invert_cmaps();
 		} else if (!strcmp(this_opt, "ilbm"))
 			amifb_ilbm = 1;
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c
index a1d58e9..4659d5d 100644
--- a/drivers/video/arcfb.c
+++ b/drivers/video/arcfb.c
@@ -552,6 +552,7 @@
 				"arcfb", info)) {
 			printk(KERN_INFO
 				"arcfb: Failed req IRQ %d\n", par->irq);
+			retval = -EBUSY;
 			goto err1;
 		}
 	}
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 1505539..94cac9f 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -931,8 +931,10 @@
 		}
 
 		info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
-		if (!info->screen_base)
+		if (!info->screen_base) {
+			ret = -ENOMEM;
 			goto release_intmem;
+		}
 
 		/*
 		 * Don't clear the framebuffer -- someone may have set
@@ -960,6 +962,7 @@
 	sinfo->mmio = ioremap(info->fix.mmio_start, info->fix.mmio_len);
 	if (!sinfo->mmio) {
 		dev_err(dev, "cannot map LCDC registers\n");
+		ret = -ENOMEM;
 		goto release_mem;
 	}
 
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 3f2e8c1..868932f 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -1942,8 +1942,7 @@
 	off = vma->vm_pgoff << PAGE_SHIFT;
 	size = vma->vm_end - vma->vm_start;
 
-	/* To stop the swapper from even considering these pages. */
-	vma->vm_flags |= (VM_IO | VM_RESERVED);
+	/* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
 
 	if (((vma->vm_pgoff == 0) && (size == info->fix.smem_len)) ||
 	    ((off == info->fix.smem_len) && (size == PAGE_SIZE)))
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index 995f016..069983c 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -213,7 +213,7 @@
 	pb->exit = data->exit;
 	pb->dev = &pdev->dev;
 
-	pb->pwm = pwm_get(&pdev->dev, NULL);
+	pb->pwm = devm_pwm_get(&pdev->dev, NULL);
 	if (IS_ERR(pb->pwm)) {
 		dev_err(&pdev->dev, "unable to request PWM, trying legacy API\n");
 
@@ -246,7 +246,7 @@
 	if (IS_ERR(bl)) {
 		dev_err(&pdev->dev, "failed to register backlight\n");
 		ret = PTR_ERR(bl);
-		goto err_bl;
+		goto err_alloc;
 	}
 
 	bl->props.brightness = data->dft_brightness;
@@ -255,8 +255,6 @@
 	platform_set_drvdata(pdev, bl);
 	return 0;
 
-err_bl:
-	pwm_put(pb->pwm);
 err_alloc:
 	if (data->exit)
 		data->exit(&pdev->dev);
@@ -271,7 +269,6 @@
 	backlight_device_unregister(bl);
 	pwm_config(pb->pwm, 0, pb->period);
 	pwm_disable(pb->pwm);
-	pwm_put(pb->pwm);
 	if (pb->exit)
 		pb->exit(&pdev->dev);
 	return 0;
diff --git a/drivers/video/bf537-lq035.c b/drivers/video/bf537-lq035.c
index befbc80..7347aa1 100644
--- a/drivers/video/bf537-lq035.c
+++ b/drivers/video/bf537-lq035.c
@@ -760,18 +760,20 @@
 	bfin_lq035_fb.flags = FBINFO_DEFAULT;
 
 
-	bfin_lq035_fb.pseudo_palette = kzalloc(sizeof(u32) * 16, GFP_KERNEL);
+	bfin_lq035_fb.pseudo_palette = devm_kzalloc(&pdev->dev,
+						    sizeof(u32) * 16,
+						    GFP_KERNEL);
 	if (bfin_lq035_fb.pseudo_palette == NULL) {
 		pr_err("failed to allocate pseudo_palette\n");
 		ret = -ENOMEM;
-		goto out_palette;
+		goto out_table;
 	}
 
 	if (fb_alloc_cmap(&bfin_lq035_fb.cmap, NBR_PALETTE, 0) < 0) {
 		pr_err("failed to allocate colormap (%d entries)\n",
 			NBR_PALETTE);
 		ret = -EFAULT;
-		goto out_cmap;
+		goto out_table;
 	}
 
 	if (register_framebuffer(&bfin_lq035_fb) < 0) {
@@ -804,9 +806,6 @@
 	unregister_framebuffer(&bfin_lq035_fb);
 out_reg:
 	fb_dealloc_cmap(&bfin_lq035_fb.cmap);
-out_cmap:
-	kfree(bfin_lq035_fb.pseudo_palette);
-out_palette:
 out_table:
 	dma_free_coherent(NULL, TOTAL_VIDEO_MEM_SIZE, fb_buffer, 0);
 	fb_buffer = NULL;
@@ -834,7 +833,6 @@
 	free_dma(CH_PPI);
 
 
-	kfree(bfin_lq035_fb.pseudo_palette);
 	fb_dealloc_cmap(&bfin_lq035_fb.cmap);
 
 
diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c
index dc2f004..ff5663f 100644
--- a/drivers/video/bf54x-lq043fb.c
+++ b/drivers/video/bf54x-lq043fb.c
@@ -525,6 +525,7 @@
 	info = fbinfo->par;
 	info->fb = fbinfo;
 	info->dev = &pdev->dev;
+	spin_lock_init(&info->lock);
 
 	platform_set_drvdata(pdev, fbinfo);
 
@@ -601,7 +602,8 @@
 
 	fbinfo->fbops = &bfin_bf54x_fb_ops;
 
-	fbinfo->pseudo_palette = kzalloc(sizeof(u32) * 16, GFP_KERNEL);
+	fbinfo->pseudo_palette = devm_kzalloc(&pdev->dev, sizeof(u32) * 16,
+					      GFP_KERNEL);
 	if (!fbinfo->pseudo_palette) {
 		printk(KERN_ERR DRIVER_NAME
 		       "Fail to allocate pseudo_palette\n");
@@ -616,7 +618,7 @@
 		       "Fail to allocate colormap (%d entries)\n",
 		       BFIN_LCD_NBR_PALETTE_ENTRIES);
 		ret = -EFAULT;
-		goto out5;
+		goto out4;
 	}
 
 	if (request_ports(info)) {
@@ -671,8 +673,6 @@
 	free_ports(info);
 out6:
 	fb_dealloc_cmap(&fbinfo->cmap);
-out5:
-	kfree(fbinfo->pseudo_palette);
 out4:
 	dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer,
 			  info->dma_handle);
@@ -699,7 +699,6 @@
 		dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer,
 				  info->dma_handle);
 
-	kfree(fbinfo->pseudo_palette);
 	fb_dealloc_cmap(&fbinfo->cmap);
 
 #ifndef NO_BL_SUPPORT
diff --git a/drivers/video/bfin-lq035q1-fb.c b/drivers/video/bfin-lq035q1-fb.c
index 353c02f..6fbc75c 100644
--- a/drivers/video/bfin-lq035q1-fb.c
+++ b/drivers/video/bfin-lq035q1-fb.c
@@ -577,6 +577,7 @@
 	info = fbinfo->par;
 	info->fb = fbinfo;
 	info->dev = &pdev->dev;
+	spin_lock_init(&info->lock);
 
 	info->disp_info = pdev->dev.platform_data;
 
@@ -853,17 +854,7 @@
 	},
 };
 
-static int __init bfin_lq035q1_driver_init(void)
-{
-	return platform_driver_register(&bfin_lq035q1_driver);
-}
-module_init(bfin_lq035q1_driver_init);
-
-static void __exit bfin_lq035q1_driver_cleanup(void)
-{
-	platform_driver_unregister(&bfin_lq035q1_driver);
-}
-module_exit(bfin_lq035q1_driver_cleanup);
+module_platform_driver(bfin_lq035q1_driver);
 
 MODULE_DESCRIPTION("Blackfin TFT LCD Driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/bfin-t350mcqb-fb.c
index 7a0c05f..ae0fb24 100644
--- a/drivers/video/bfin-t350mcqb-fb.c
+++ b/drivers/video/bfin-t350mcqb-fb.c
@@ -447,6 +447,7 @@
 	info = fbinfo->par;
 	info->fb = fbinfo;
 	info->dev = &pdev->dev;
+	spin_lock_init(&info->lock);
 
 	platform_set_drvdata(pdev, fbinfo);
 
diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c
index 7ba74cd..6bea9a9 100644
--- a/drivers/video/bw2.c
+++ b/drivers/video/bw2.c
@@ -319,8 +319,10 @@
 
 	info->screen_base = of_ioremap(&op->resource[0], 0,
 				       info->fix.smem_len, "bw2 ram");
-	if (!info->screen_base)
+	if (!info->screen_base) {
+		err = -ENOMEM;
 		goto out_unmap_regs;
+	}
 
 	bw2_blank(FB_BLANK_UNBLANK, info);
 
diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c
index f927a7b..c5e7612 100644
--- a/drivers/video/cg3.c
+++ b/drivers/video/cg3.c
@@ -398,7 +398,8 @@
 			goto out_unmap_screen;
 	}
 
-	if (fb_alloc_cmap(&info->cmap, 256, 0))
+	err = fb_alloc_cmap(&info->cmap, 256, 0);
+	if (err)
 		goto out_unmap_screen;
 
 	fb_set_cmap(&info->cmap, info);
diff --git a/drivers/video/cobalt_lcdfb.c b/drivers/video/cobalt_lcdfb.c
index eae46f6..01a4ee7 100644
--- a/drivers/video/cobalt_lcdfb.c
+++ b/drivers/video/cobalt_lcdfb.c
@@ -348,7 +348,8 @@
 	}
 
 	info->screen_size = resource_size(res);
-	info->screen_base = ioremap(res->start, info->screen_size);
+	info->screen_base = devm_ioremap(&dev->dev, res->start,
+					 info->screen_size);
 	info->fbops = &cobalt_lcd_fbops;
 	info->fix = cobalt_lcdfb_fix;
 	info->fix.smem_start = res->start;
@@ -359,7 +360,6 @@
 
 	retval = register_framebuffer(info);
 	if (retval < 0) {
-		iounmap(info->screen_base);
 		framebuffer_release(info);
 		return retval;
 	}
@@ -380,7 +380,6 @@
 
 	info = platform_get_drvdata(dev);
 	if (info) {
-		iounmap(info->screen_base);
 		unregister_framebuffer(info);
 		framebuffer_release(info);
 	}
diff --git a/drivers/video/console/font_mini_4x6.c b/drivers/video/console/font_mini_4x6.c
index fa6e698..838caa1 100644
--- a/drivers/video/console/font_mini_4x6.c
+++ b/drivers/video/console/font_mini_4x6.c
@@ -1092,7 +1092,7 @@
 	/*{*/ 	/*   Char 124: '|' */
 	0x44,	/*=   [ *  ]        */
 	0x44,	/*=   [ *  ]        */
-	0x00,	/*=   [    ]        */
+	0x44,	/*=   [ *  ]        */
 	0x44,	/*=   [ *  ]        */
 	0x44,	/*=   [ *  ]        */
 	0x00,	/*=   [    ]        */
diff --git a/drivers/video/console/font_sun8x16.c b/drivers/video/console/font_sun8x16.c
index 5abf290..2681513 100644
--- a/drivers/video/console/font_sun8x16.c
+++ b/drivers/video/console/font_sun8x16.c
@@ -127,7 +127,7 @@
 /*y*/ 0x00,0x00,0x00,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0xf8,0x00,
 /*z*/ 0x00,0x00,0x00,0x00,0x00,0xfe,0xcc,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00,
 /*{*/ 0x00,0x00,0x0e,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0e,0x00,0x00,0x00,0x00,
-/*|*/ 0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
+/*|*/ 0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
 /*}*/ 0x00,0x00,0x70,0x18,0x18,0x18,0x0e,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00,
 /*~*/ 0x00,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 /* */ 0x00,0x00,0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xc6,0xfe,0x00,0x00,0x00,0x00,0x00,
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index c1527f5..e40125c 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -1804,8 +1804,10 @@
 
 	cfb->irq = dev->irq;
 	cfb->region = pci_ioremap_bar(dev, 0);
-	if (!cfb->region)
+	if (!cfb->region) {
+		err = -ENOMEM;
 		goto failed_ioremap;
+	}
 
 	cfb->regs = cfb->region + MMIO_OFFSET;
 	cfb->fb.device = &dev->dev;
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index 113d43a..80665f6 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -26,7 +26,9 @@
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/uaccess.h>
+#include <linux/pm_runtime.h>
 #include <linux/interrupt.h>
+#include <linux/wait.h>
 #include <linux/clk.h>
 #include <linux/cpufreq.h>
 #include <linux/console.h>
@@ -48,6 +50,7 @@
 #define LCD_PL_LOAD_DONE		BIT(6)
 #define LCD_FIFO_UNDERFLOW		BIT(5)
 #define LCD_SYNC_LOST			BIT(2)
+#define LCD_FRAME_DONE			BIT(0)
 
 /* LCD DMA Control Register */
 #define LCD_DMA_BURST_SIZE(x)		((x) << 4)
@@ -86,6 +89,8 @@
 #define LCD_V2_LIDD_CLK_EN		BIT(1)
 #define LCD_V2_CORE_CLK_EN		BIT(0)
 #define LCD_V2_LPP_B10			26
+#define LCD_V2_TFT_24BPP_MODE		BIT(25)
+#define LCD_V2_TFT_24BPP_UNPACK		BIT(26)
 
 /* LCD Raster Timing 2 Register */
 #define LCD_AC_BIAS_TRANSITIONS_PER_INT(x)	((x) << 16)
@@ -135,6 +140,8 @@
 static struct resource *lcdc_regs;
 static unsigned int lcd_revision;
 static irq_handler_t lcdc_irq_handler;
+static wait_queue_head_t frame_done_wq;
+static int frame_done_flag;
 
 static inline unsigned int lcdc_read(unsigned int addr)
 {
@@ -156,7 +163,6 @@
 	unsigned int		dma_end;
 	struct clk *lcdc_clk;
 	int irq;
-	unsigned short pseudo_palette[16];
 	unsigned int palette_sz;
 	unsigned int pxl_clk;
 	int blank;
@@ -175,6 +181,7 @@
 	unsigned int		lcd_fck_rate;
 #endif
 	void (*panel_power_ctrl)(int);
+	u32 pseudo_palette[16];
 };
 
 /* Variable Screen Information */
@@ -288,13 +295,26 @@
 }
 
 /* Disable the Raster Engine of the LCD Controller */
-static inline void lcd_disable_raster(void)
+static inline void lcd_disable_raster(bool wait_for_frame_done)
 {
 	u32 reg;
+	int ret;
 
 	reg = lcdc_read(LCD_RASTER_CTRL_REG);
 	if (reg & LCD_RASTER_ENABLE)
 		lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG);
+	else
+		/* return if already disabled */
+		return;
+
+	if ((wait_for_frame_done == true) && (lcd_revision == LCD_VERSION_2)) {
+		frame_done_flag = 0;
+		ret = wait_event_interruptible_timeout(frame_done_wq,
+				frame_done_flag != 0,
+				msecs_to_jiffies(50));
+		if (ret == 0)
+			pr_err("LCD Controller timed out\n");
+	}
 }
 
 static void lcd_blit(int load_mode, struct da8xx_fb_par *par)
@@ -321,7 +341,8 @@
 		} else {
 			reg_int = lcdc_read(LCD_INT_ENABLE_SET_REG) |
 				LCD_V2_END_OF_FRAME0_INT_ENA |
-				LCD_V2_END_OF_FRAME1_INT_ENA;
+				LCD_V2_END_OF_FRAME1_INT_ENA |
+				LCD_FRAME_DONE;
 			lcdc_write(reg_int, LCD_INT_ENABLE_SET_REG);
 		}
 		reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE;
@@ -499,6 +520,9 @@
 {
 	u32 reg;
 
+	if (bpp > 16 && lcd_revision == LCD_VERSION_1)
+		return -EINVAL;
+
 	/* Set the Panel Width */
 	/* Pixels per line = (PPL + 1)*16 */
 	if (lcd_revision == LCD_VERSION_1) {
@@ -542,14 +566,19 @@
 	reg = lcdc_read(LCD_RASTER_CTRL_REG) & ~(1 << 8);
 	if (raster_order)
 		reg |= LCD_RASTER_ORDER;
-	lcdc_write(reg, LCD_RASTER_CTRL_REG);
+
+	par->palette_sz = 16 * 2;
 
 	switch (bpp) {
 	case 1:
 	case 2:
 	case 4:
 	case 16:
-		par->palette_sz = 16 * 2;
+		break;
+	case 24:
+		reg |= LCD_V2_TFT_24BPP_MODE;
+	case 32:
+		reg |= LCD_V2_TFT_24BPP_UNPACK;
 		break;
 
 	case 8:
@@ -560,9 +589,12 @@
 		return -EINVAL;
 	}
 
+	lcdc_write(reg, LCD_RASTER_CTRL_REG);
+
 	return 0;
 }
 
+#define CNVT_TOHW(val, width) ((((val) << (width)) + 0x7FFF - (val)) >> 16)
 static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
 			      unsigned blue, unsigned transp,
 			      struct fb_info *info)
@@ -578,13 +610,38 @@
 	if (info->fix.visual == FB_VISUAL_DIRECTCOLOR)
 		return 1;
 
-	if (info->var.bits_per_pixel == 4) {
-		if (regno > 15)
-			return 1;
+	if (info->var.bits_per_pixel > 16 && lcd_revision == LCD_VERSION_1)
+		return -EINVAL;
 
-		if (info->var.grayscale) {
-			pal = regno;
-		} else {
+	switch (info->fix.visual) {
+	case FB_VISUAL_TRUECOLOR:
+		red = CNVT_TOHW(red, info->var.red.length);
+		green = CNVT_TOHW(green, info->var.green.length);
+		blue = CNVT_TOHW(blue, info->var.blue.length);
+		break;
+	case FB_VISUAL_PSEUDOCOLOR:
+		switch (info->var.bits_per_pixel) {
+		case 4:
+			if (regno > 15)
+				return -EINVAL;
+
+			if (info->var.grayscale) {
+				pal = regno;
+			} else {
+				red >>= 4;
+				green >>= 8;
+				blue >>= 12;
+
+				pal = red & 0x0f00;
+				pal |= green & 0x00f0;
+				pal |= blue & 0x000f;
+			}
+			if (regno == 0)
+				pal |= 0x2000;
+			palette[regno] = pal;
+			break;
+
+		case 8:
 			red >>= 4;
 			green >>= 8;
 			blue >>= 12;
@@ -592,36 +649,36 @@
 			pal = (red & 0x0f00);
 			pal |= (green & 0x00f0);
 			pal |= (blue & 0x000f);
+
+			if (palette[regno] != pal) {
+				update_hw = 1;
+				palette[regno] = pal;
+			}
+			break;
 		}
-		if (regno == 0)
-			pal |= 0x2000;
-		palette[regno] = pal;
+		break;
+	}
 
-	} else if (info->var.bits_per_pixel == 8) {
-		red >>= 4;
-		green >>= 8;
-		blue >>= 12;
+	/* Truecolor has hardware independent palette */
+	if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
+		u32 v;
 
-		pal = (red & 0x0f00);
-		pal |= (green & 0x00f0);
-		pal |= (blue & 0x000f);
+		if (regno > 15)
+			return -EINVAL;
 
-		if (palette[regno] != pal) {
-			update_hw = 1;
-			palette[regno] = pal;
+		v = (red << info->var.red.offset) |
+			(green << info->var.green.offset) |
+			(blue << info->var.blue.offset);
+
+		switch (info->var.bits_per_pixel) {
+		case 16:
+			((u16 *) (info->pseudo_palette))[regno] = v;
+			break;
+		case 24:
+		case 32:
+			((u32 *) (info->pseudo_palette))[regno] = v;
+			break;
 		}
-	} else if ((info->var.bits_per_pixel == 16) && regno < 16) {
-		red >>= (16 - info->var.red.length);
-		red <<= info->var.red.offset;
-
-		green >>= (16 - info->var.green.length);
-		green <<= info->var.green.offset;
-
-		blue >>= (16 - info->var.blue.length);
-		blue <<= info->var.blue.offset;
-
-		par->pseudo_palette[regno] = red | green | blue;
-
 		if (palette[0] != 0x4000) {
 			update_hw = 1;
 			palette[0] = 0x4000;
@@ -634,11 +691,12 @@
 
 	return 0;
 }
+#undef CNVT_TOHW
 
 static void lcd_reset(struct da8xx_fb_par *par)
 {
 	/* Disable the Raster if previously Enabled */
-	lcd_disable_raster();
+	lcd_disable_raster(false);
 
 	/* DMA has to be disabled */
 	lcdc_write(0, LCD_DMA_CTRL_REG);
@@ -734,7 +792,7 @@
 	u32 stat = lcdc_read(LCD_MASKED_STAT_REG);
 
 	if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
-		lcd_disable_raster();
+		lcd_disable_raster(false);
 		lcdc_write(stat, LCD_MASKED_STAT_REG);
 		lcd_enable_raster();
 	} else if (stat & LCD_PL_LOAD_DONE) {
@@ -744,7 +802,7 @@
 		 * interrupt via the following write to the status register. If
 		 * this is done after then one gets multiple PL done interrupts.
 		 */
-		lcd_disable_raster();
+		lcd_disable_raster(false);
 
 		lcdc_write(stat, LCD_MASKED_STAT_REG);
 
@@ -775,6 +833,14 @@
 			par->vsync_flag = 1;
 			wake_up_interruptible(&par->vsync_wait);
 		}
+
+		/* Set only when controller is disabled and at the end of
+		 * active frame
+		 */
+		if (stat & BIT(0)) {
+			frame_done_flag = 1;
+			wake_up_interruptible(&frame_done_wq);
+		}
 	}
 
 	lcdc_write(0, LCD_END_OF_INT_IND_REG);
@@ -789,7 +855,7 @@
 	u32 reg_ras;
 
 	if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) {
-		lcd_disable_raster();
+		lcd_disable_raster(false);
 		lcdc_write(stat, LCD_STAT_REG);
 		lcd_enable_raster();
 	} else if (stat & LCD_PL_LOAD_DONE) {
@@ -799,7 +865,7 @@
 		 * interrupt via the following write to the status register. If
 		 * this is done after then one gets multiple PL done interrupts.
 		 */
-		lcd_disable_raster();
+		lcd_disable_raster(false);
 
 		lcdc_write(stat, LCD_STAT_REG);
 
@@ -842,6 +908,9 @@
 {
 	int err = 0;
 
+	if (var->bits_per_pixel > 16 && lcd_revision == LCD_VERSION_1)
+		return -EINVAL;
+
 	switch (var->bits_per_pixel) {
 	case 1:
 	case 8:
@@ -877,6 +946,26 @@
 		var->transp.length = 0;
 		var->nonstd = 0;
 		break;
+	case 24:
+		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->nonstd = 0;
+		break;
+	case 32:
+		var->transp.offset = 24;
+		var->transp.length = 8;
+		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->nonstd = 0;
+		break;
 	default:
 		err = -EINVAL;
 	}
@@ -898,9 +987,10 @@
 	if (val == CPUFREQ_POSTCHANGE) {
 		if (par->lcd_fck_rate != clk_get_rate(par->lcdc_clk)) {
 			par->lcd_fck_rate = clk_get_rate(par->lcdc_clk);
-			lcd_disable_raster();
+			lcd_disable_raster(true);
 			lcd_calc_clk_divider(par);
-			lcd_enable_raster();
+			if (par->blank == FB_BLANK_UNBLANK)
+				lcd_enable_raster();
 		}
 	}
 
@@ -935,7 +1025,7 @@
 		if (par->panel_power_ctrl)
 			par->panel_power_ctrl(0);
 
-		lcd_disable_raster();
+		lcd_disable_raster(true);
 		lcdc_write(0, LCD_RASTER_CTRL_REG);
 
 		/* disable DMA  */
@@ -948,8 +1038,8 @@
 		dma_free_coherent(NULL, par->vram_size, par->vram_virt,
 				  par->vram_phys);
 		free_irq(par->irq, par);
-		clk_disable(par->lcdc_clk);
-		clk_put(par->lcdc_clk);
+		pm_runtime_put_sync(&dev->dev);
+		pm_runtime_disable(&dev->dev);
 		framebuffer_release(info);
 		iounmap(da8xx_fb_reg_base);
 		release_mem_region(lcdc_regs->start, resource_size(lcdc_regs));
@@ -1051,7 +1141,7 @@
 		if (par->panel_power_ctrl)
 			par->panel_power_ctrl(0);
 
-		lcd_disable_raster();
+		lcd_disable_raster(true);
 		break;
 	default:
 		ret = -EINVAL;
@@ -1183,9 +1273,9 @@
 		ret = -ENODEV;
 		goto err_ioremap;
 	}
-	ret = clk_enable(fb_clk);
-	if (ret)
-		goto err_clk_put;
+
+	pm_runtime_enable(&device->dev);
+	pm_runtime_get_sync(&device->dev);
 
 	/* Determine LCD IP Version */
 	switch (lcdc_read(LCD_PID_REG)) {
@@ -1213,7 +1303,7 @@
 	if (i == ARRAY_SIZE(known_lcd_panels)) {
 		dev_err(&device->dev, "GLCD: No valid panel found\n");
 		ret = -ENODEV;
-		goto err_clk_disable;
+		goto err_pm_runtime_disable;
 	} else
 		dev_info(&device->dev, "GLCD: Found %s panel\n",
 					fb_pdata->type);
@@ -1225,7 +1315,7 @@
 	if (!da8xx_fb_info) {
 		dev_dbg(&device->dev, "Memory allocation failed for fb_info\n");
 		ret = -ENOMEM;
-		goto err_clk_disable;
+		goto err_pm_runtime_disable;
 	}
 
 	par = da8xx_fb_info->par;
@@ -1356,8 +1446,10 @@
 
 	if (lcd_revision == LCD_VERSION_1)
 		lcdc_irq_handler = lcdc_irq_handler_rev01;
-	else
+	else {
+		init_waitqueue_head(&frame_done_wq);
 		lcdc_irq_handler = lcdc_irq_handler_rev02;
+	}
 
 	ret = request_irq(par->irq, lcdc_irq_handler, 0,
 			DRIVER_NAME, par);
@@ -1385,11 +1477,9 @@
 err_release_fb:
 	framebuffer_release(da8xx_fb_info);
 
-err_clk_disable:
-	clk_disable(fb_clk);
-
-err_clk_put:
-	clk_put(fb_clk);
+err_pm_runtime_disable:
+	pm_runtime_put_sync(&device->dev);
+	pm_runtime_disable(&device->dev);
 
 err_ioremap:
 	iounmap(da8xx_fb_reg_base);
@@ -1401,6 +1491,69 @@
 }
 
 #ifdef CONFIG_PM
+struct lcdc_context {
+	u32 clk_enable;
+	u32 ctrl;
+	u32 dma_ctrl;
+	u32 raster_timing_0;
+	u32 raster_timing_1;
+	u32 raster_timing_2;
+	u32 int_enable_set;
+	u32 dma_frm_buf_base_addr_0;
+	u32 dma_frm_buf_ceiling_addr_0;
+	u32 dma_frm_buf_base_addr_1;
+	u32 dma_frm_buf_ceiling_addr_1;
+	u32 raster_ctrl;
+} reg_context;
+
+static void lcd_context_save(void)
+{
+	if (lcd_revision == LCD_VERSION_2) {
+		reg_context.clk_enable = lcdc_read(LCD_CLK_ENABLE_REG);
+		reg_context.int_enable_set = lcdc_read(LCD_INT_ENABLE_SET_REG);
+	}
+
+	reg_context.ctrl = lcdc_read(LCD_CTRL_REG);
+	reg_context.dma_ctrl = lcdc_read(LCD_DMA_CTRL_REG);
+	reg_context.raster_timing_0 = lcdc_read(LCD_RASTER_TIMING_0_REG);
+	reg_context.raster_timing_1 = lcdc_read(LCD_RASTER_TIMING_1_REG);
+	reg_context.raster_timing_2 = lcdc_read(LCD_RASTER_TIMING_2_REG);
+	reg_context.dma_frm_buf_base_addr_0 =
+		lcdc_read(LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
+	reg_context.dma_frm_buf_ceiling_addr_0 =
+		lcdc_read(LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
+	reg_context.dma_frm_buf_base_addr_1 =
+		lcdc_read(LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
+	reg_context.dma_frm_buf_ceiling_addr_1 =
+		lcdc_read(LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
+	reg_context.raster_ctrl = lcdc_read(LCD_RASTER_CTRL_REG);
+	return;
+}
+
+static void lcd_context_restore(void)
+{
+	if (lcd_revision == LCD_VERSION_2) {
+		lcdc_write(reg_context.clk_enable, LCD_CLK_ENABLE_REG);
+		lcdc_write(reg_context.int_enable_set, LCD_INT_ENABLE_SET_REG);
+	}
+
+	lcdc_write(reg_context.ctrl, LCD_CTRL_REG);
+	lcdc_write(reg_context.dma_ctrl, LCD_DMA_CTRL_REG);
+	lcdc_write(reg_context.raster_timing_0, LCD_RASTER_TIMING_0_REG);
+	lcdc_write(reg_context.raster_timing_1, LCD_RASTER_TIMING_1_REG);
+	lcdc_write(reg_context.raster_timing_2, LCD_RASTER_TIMING_2_REG);
+	lcdc_write(reg_context.dma_frm_buf_base_addr_0,
+			LCD_DMA_FRM_BUF_BASE_ADDR_0_REG);
+	lcdc_write(reg_context.dma_frm_buf_ceiling_addr_0,
+			LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG);
+	lcdc_write(reg_context.dma_frm_buf_base_addr_1,
+			LCD_DMA_FRM_BUF_BASE_ADDR_1_REG);
+	lcdc_write(reg_context.dma_frm_buf_ceiling_addr_1,
+			LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG);
+	lcdc_write(reg_context.raster_ctrl, LCD_RASTER_CTRL_REG);
+	return;
+}
+
 static int fb_suspend(struct platform_device *dev, pm_message_t state)
 {
 	struct fb_info *info = platform_get_drvdata(dev);
@@ -1411,8 +1564,9 @@
 		par->panel_power_ctrl(0);
 
 	fb_set_suspend(info, 1);
-	lcd_disable_raster();
-	clk_disable(par->lcdc_clk);
+	lcd_disable_raster(true);
+	lcd_context_save();
+	pm_runtime_put_sync(&dev->dev);
 	console_unlock();
 
 	return 0;
@@ -1423,11 +1577,14 @@
 	struct da8xx_fb_par *par = info->par;
 
 	console_lock();
-	clk_enable(par->lcdc_clk);
-	lcd_enable_raster();
+	pm_runtime_get_sync(&dev->dev);
+	lcd_context_restore();
+	if (par->blank == FB_BLANK_UNBLANK) {
+		lcd_enable_raster();
 
-	if (par->panel_power_ctrl)
-		par->panel_power_ctrl(1);
+		if (par->panel_power_ctrl)
+			par->panel_power_ctrl(1);
+	}
 
 	fb_set_suspend(info, 0);
 	console_unlock();
diff --git a/drivers/video/ep93xx-fb.c b/drivers/video/ep93xx-fb.c
index f2c092d..755ef3e 100644
--- a/drivers/video/ep93xx-fb.c
+++ b/drivers/video/ep93xx-fb.c
@@ -529,7 +529,8 @@
 	 * any of the framebuffer registers.
 	 */
 	fbi->res = res;
-	fbi->mmio_base = ioremap(res->start, resource_size(res));
+	fbi->mmio_base = devm_ioremap(&pdev->dev, res->start,
+				      resource_size(res));
 	if (!fbi->mmio_base) {
 		err = -ENXIO;
 		goto failed_resource;
@@ -553,20 +554,20 @@
 	if (err == 0) {
 		dev_err(info->dev, "No suitable video mode found\n");
 		err = -EINVAL;
-		goto failed_mode;
+		goto failed_resource;
 	}
 
 	if (mach_info->setup) {
 		err = mach_info->setup(pdev);
 		if (err)
-			goto failed_mode;
+			goto failed_resource;
 	}
 
 	err = ep93xxfb_check_var(&info->var, info);
 	if (err)
 		goto failed_check;
 
-	fbi->clk = clk_get(info->dev, NULL);
+	fbi->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(fbi->clk)) {
 		err = PTR_ERR(fbi->clk);
 		fbi->clk = NULL;
@@ -578,19 +579,15 @@
 
 	err = register_framebuffer(info);
 	if (err)
-		goto failed;
+		goto failed_check;
 
 	dev_info(info->dev, "registered. Mode = %dx%d-%d\n",
 		 info->var.xres, info->var.yres, info->var.bits_per_pixel);
 	return 0;
 
-failed:
-	clk_put(fbi->clk);
 failed_check:
 	if (fbi->mach_info->teardown)
 		fbi->mach_info->teardown(pdev);
-failed_mode:
-	iounmap(fbi->mmio_base);
 failed_resource:
 	ep93xxfb_dealloc_videomem(info);
 failed_videomem:
@@ -609,8 +606,6 @@
 
 	unregister_framebuffer(info);
 	clk_disable(fbi->clk);
-	clk_put(fbi->clk);
-	iounmap(fbi->mmio_base);
 	ep93xxfb_dealloc_videomem(info);
 	fb_dealloc_cmap(&info->cmap);
 
diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index c6c016a..d55470e 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -29,6 +29,9 @@
 
 	exynos_dp_swreset(dp);
 
+	exynos_dp_init_analog_param(dp);
+	exynos_dp_init_interrupt(dp);
+
 	/* SW defined function Normal operation */
 	exynos_dp_enable_sw_function(dp);
 
@@ -260,7 +263,7 @@
 
 static void exynos_dp_link_start(struct exynos_dp_device *dp)
 {
-	u8 buf[5];
+	u8 buf[4];
 	int lane;
 	int lane_count;
 
@@ -295,10 +298,10 @@
 	exynos_dp_set_training_pattern(dp, TRAINING_PTN1);
 
 	/* Set RX training pattern */
-	buf[0] = DPCD_SCRAMBLING_DISABLED |
-		 DPCD_TRAINING_PATTERN_1;
 	exynos_dp_write_byte_to_dpcd(dp,
-		DPCD_ADDR_TRAINING_PATTERN_SET, buf[0]);
+		DPCD_ADDR_TRAINING_PATTERN_SET,
+		DPCD_SCRAMBLING_DISABLED |
+		DPCD_TRAINING_PATTERN_1);
 
 	for (lane = 0; lane < lane_count; lane++)
 		buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 |
@@ -308,7 +311,7 @@
 		lane_count, buf);
 }
 
-static unsigned char exynos_dp_get_lane_status(u8 link_status[6], int lane)
+static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int lane)
 {
 	int shift = (lane & 1) * 4;
 	u8 link_value = link_status[lane>>1];
@@ -316,7 +319,7 @@
 	return (link_value >> shift) & 0xf;
 }
 
-static int exynos_dp_clock_recovery_ok(u8 link_status[6], int lane_count)
+static int exynos_dp_clock_recovery_ok(u8 link_status[2], int lane_count)
 {
 	int lane;
 	u8 lane_status;
@@ -329,22 +332,23 @@
 	return 0;
 }
 
-static int exynos_dp_channel_eq_ok(u8 link_status[6], int lane_count)
+static int exynos_dp_channel_eq_ok(u8 link_align[3], int lane_count)
 {
 	int lane;
 	u8 lane_align;
 	u8 lane_status;
 
-	lane_align = link_status[2];
+	lane_align = link_align[2];
 	if ((lane_align & DPCD_INTERLANE_ALIGN_DONE) == 0)
 		return -EINVAL;
 
 	for (lane = 0; lane < lane_count; lane++) {
-		lane_status = exynos_dp_get_lane_status(link_status, lane);
+		lane_status = exynos_dp_get_lane_status(link_align, lane);
 		lane_status &= DPCD_CHANNEL_EQ_BITS;
 		if (lane_status != DPCD_CHANNEL_EQ_BITS)
 			return -EINVAL;
 	}
+
 	return 0;
 }
 
@@ -417,69 +421,17 @@
 
 static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp)
 {
-	if (dp->link_train.link_rate == LINK_RATE_2_70GBPS) {
-		/* set to reduced bit rate */
-		dp->link_train.link_rate = LINK_RATE_1_62GBPS;
-		dev_err(dp->dev, "set to bandwidth %.2x\n",
-			dp->link_train.link_rate);
-		dp->link_train.lt_state = START;
-	} else {
-		exynos_dp_training_pattern_dis(dp);
-		/* set enhanced mode if available */
-		exynos_dp_set_enhanced_mode(dp);
-		dp->link_train.lt_state = FAILED;
-	}
-}
+	exynos_dp_training_pattern_dis(dp);
+	exynos_dp_set_enhanced_mode(dp);
 
-static void exynos_dp_get_adjust_train(struct exynos_dp_device *dp,
-				u8 adjust_request[2])
-{
-	int lane;
-	int lane_count;
-	u8 voltage_swing;
-	u8 pre_emphasis;
-	u8 training_lane;
-
-	lane_count = dp->link_train.lane_count;
-	for (lane = 0; lane < lane_count; lane++) {
-		voltage_swing = exynos_dp_get_adjust_request_voltage(
-						adjust_request, lane);
-		pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
-						adjust_request, lane);
-		training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
-				DPCD_PRE_EMPHASIS_SET(pre_emphasis);
-
-		if (voltage_swing == VOLTAGE_LEVEL_3 ||
-		   pre_emphasis == PRE_EMPHASIS_LEVEL_3) {
-			training_lane |= DPCD_MAX_SWING_REACHED;
-			training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
-		}
-		dp->link_train.training_lane[lane] = training_lane;
-	}
-}
-
-static int exynos_dp_check_max_cr_loop(struct exynos_dp_device *dp,
-					u8 voltage_swing)
-{
-	int lane;
-	int lane_count;
-
-	lane_count = dp->link_train.lane_count;
-	for (lane = 0; lane < lane_count; lane++) {
-		if (voltage_swing == VOLTAGE_LEVEL_3 ||
-			dp->link_train.cr_loop[lane] == MAX_CR_LOOP)
-			return -EINVAL;
-	}
-	return 0;
+	dp->link_train.lt_state = FAILED;
 }
 
 static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp)
 {
-	u8 data;
-	u8 link_status[6];
+	u8 link_status[2];
 	int lane;
 	int lane_count;
-	u8 buf[5];
 
 	u8 adjust_request[2];
 	u8 voltage_swing;
@@ -488,100 +440,154 @@
 
 	usleep_range(100, 101);
 
-	exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
-				6, link_status);
 	lane_count = dp->link_train.lane_count;
 
+	exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
+				2, link_status);
+
 	if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
 		/* set training pattern 2 for EQ */
 		exynos_dp_set_training_pattern(dp, TRAINING_PTN2);
 
-		adjust_request[0] = link_status[4];
-		adjust_request[1] = link_status[5];
-
-		exynos_dp_get_adjust_train(dp, adjust_request);
-
-		buf[0] = DPCD_SCRAMBLING_DISABLED |
-			 DPCD_TRAINING_PATTERN_2;
-		exynos_dp_write_byte_to_dpcd(dp,
-			DPCD_ADDR_TRAINING_PATTERN_SET,
-			buf[0]);
-
 		for (lane = 0; lane < lane_count; lane++) {
-			exynos_dp_set_lane_link_training(dp,
-				dp->link_train.training_lane[lane],
-				lane);
-			buf[lane] = dp->link_train.training_lane[lane];
-			exynos_dp_write_byte_to_dpcd(dp,
-				DPCD_ADDR_TRAINING_LANE0_SET + lane,
-				buf[lane]);
-		}
-		dp->link_train.lt_state = EQUALIZER_TRAINING;
-	} else {
-		exynos_dp_read_byte_from_dpcd(dp,
-			DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
-			&data);
-		adjust_request[0] = data;
-
-		exynos_dp_read_byte_from_dpcd(dp,
-			DPCD_ADDR_ADJUST_REQUEST_LANE2_3,
-			&data);
-		adjust_request[1] = data;
-
-		for (lane = 0; lane < lane_count; lane++) {
-			training_lane = exynos_dp_get_lane_link_training(
-							dp, lane);
+			exynos_dp_read_bytes_from_dpcd(dp,
+					DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
+					2, adjust_request);
 			voltage_swing = exynos_dp_get_adjust_request_voltage(
 							adjust_request, lane);
 			pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
 							adjust_request, lane);
-			if ((DPCD_VOLTAGE_SWING_GET(training_lane) == voltage_swing) &&
-			    (DPCD_PRE_EMPHASIS_GET(training_lane) == pre_emphasis))
-				dp->link_train.cr_loop[lane]++;
+			training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
+					DPCD_PRE_EMPHASIS_SET(pre_emphasis);
+
+			if (voltage_swing == VOLTAGE_LEVEL_3)
+				training_lane |= DPCD_MAX_SWING_REACHED;
+			if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
+				training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
+
 			dp->link_train.training_lane[lane] = training_lane;
+
+			exynos_dp_set_lane_link_training(dp,
+				dp->link_train.training_lane[lane],
+				lane);
 		}
 
-		if (exynos_dp_check_max_cr_loop(dp, voltage_swing) != 0) {
-			exynos_dp_reduce_link_rate(dp);
-		} else {
-			exynos_dp_get_adjust_train(dp, adjust_request);
+		exynos_dp_write_byte_to_dpcd(dp,
+			DPCD_ADDR_TRAINING_PATTERN_SET,
+			DPCD_SCRAMBLING_DISABLED |
+			DPCD_TRAINING_PATTERN_2);
 
-			for (lane = 0; lane < lane_count; lane++) {
-				exynos_dp_set_lane_link_training(dp,
-					dp->link_train.training_lane[lane],
-					lane);
-				buf[lane] = dp->link_train.training_lane[lane];
-				exynos_dp_write_byte_to_dpcd(dp,
-					DPCD_ADDR_TRAINING_LANE0_SET + lane,
-					buf[lane]);
+		exynos_dp_write_bytes_to_dpcd(dp,
+			DPCD_ADDR_TRAINING_LANE0_SET,
+			lane_count,
+			dp->link_train.training_lane);
+
+		dev_info(dp->dev, "Link Training Clock Recovery success\n");
+		dp->link_train.lt_state = EQUALIZER_TRAINING;
+	} else {
+		for (lane = 0; lane < lane_count; lane++) {
+			training_lane = exynos_dp_get_lane_link_training(
+							dp, lane);
+			exynos_dp_read_bytes_from_dpcd(dp,
+					DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
+					2, adjust_request);
+			voltage_swing = exynos_dp_get_adjust_request_voltage(
+							adjust_request, lane);
+			pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
+							adjust_request, lane);
+
+			if (voltage_swing == VOLTAGE_LEVEL_3 ||
+			    pre_emphasis == PRE_EMPHASIS_LEVEL_3) {
+				dev_err(dp->dev, "voltage or pre emphasis reached max level\n");
+				goto reduce_link_rate;
 			}
+
+			if ((DPCD_VOLTAGE_SWING_GET(training_lane) ==
+					voltage_swing) &&
+			   (DPCD_PRE_EMPHASIS_GET(training_lane) ==
+					pre_emphasis)) {
+				dp->link_train.cr_loop[lane]++;
+				if (dp->link_train.cr_loop[lane] == MAX_CR_LOOP) {
+					dev_err(dp->dev, "CR Max loop\n");
+					goto reduce_link_rate;
+				}
+			}
+
+			training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
+					DPCD_PRE_EMPHASIS_SET(pre_emphasis);
+
+			if (voltage_swing == VOLTAGE_LEVEL_3)
+				training_lane |= DPCD_MAX_SWING_REACHED;
+			if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
+				training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
+
+			dp->link_train.training_lane[lane] = training_lane;
+
+			exynos_dp_set_lane_link_training(dp,
+				dp->link_train.training_lane[lane], lane);
 		}
+
+		exynos_dp_write_bytes_to_dpcd(dp,
+			DPCD_ADDR_TRAINING_LANE0_SET,
+			lane_count,
+			dp->link_train.training_lane);
 	}
 
 	return 0;
+
+reduce_link_rate:
+	exynos_dp_reduce_link_rate(dp);
+	return -EIO;
 }
 
 static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp)
 {
-	u8 link_status[6];
+	u8 link_status[2];
+	u8 link_align[3];
 	int lane;
 	int lane_count;
-	u8 buf[5];
 	u32 reg;
 
 	u8 adjust_request[2];
+	u8 voltage_swing;
+	u8 pre_emphasis;
+	u8 training_lane;
 
 	usleep_range(400, 401);
 
-	exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
-				6, link_status);
 	lane_count = dp->link_train.lane_count;
 
-	if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
-		adjust_request[0] = link_status[4];
-		adjust_request[1] = link_status[5];
+	exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_LANE0_1_STATUS,
+				2, link_status);
 
-		if (exynos_dp_channel_eq_ok(link_status, lane_count) == 0) {
+	if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) {
+		link_align[0] = link_status[0];
+		link_align[1] = link_status[1];
+
+		exynos_dp_read_byte_from_dpcd(dp,
+			DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED,
+			&link_align[2]);
+
+		for (lane = 0; lane < lane_count; lane++) {
+			exynos_dp_read_bytes_from_dpcd(dp,
+					DPCD_ADDR_ADJUST_REQUEST_LANE0_1,
+					2, adjust_request);
+			voltage_swing = exynos_dp_get_adjust_request_voltage(
+							adjust_request, lane);
+			pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis(
+							adjust_request, lane);
+			training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) |
+					DPCD_PRE_EMPHASIS_SET(pre_emphasis);
+
+			if (voltage_swing == VOLTAGE_LEVEL_3)
+				training_lane |= DPCD_MAX_SWING_REACHED;
+			if (pre_emphasis == PRE_EMPHASIS_LEVEL_3)
+				training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED;
+
+			dp->link_train.training_lane[lane] = training_lane;
+		}
+
+		if (exynos_dp_channel_eq_ok(link_align, lane_count) == 0) {
 			/* traing pattern Set to Normal */
 			exynos_dp_training_pattern_dis(dp);
 
@@ -596,39 +602,42 @@
 			dp->link_train.lane_count = reg;
 			dev_dbg(dp->dev, "final lane count = %.2x\n",
 				dp->link_train.lane_count);
+
 			/* set enhanced mode if available */
 			exynos_dp_set_enhanced_mode(dp);
-
 			dp->link_train.lt_state = FINISHED;
 		} else {
 			/* not all locked */
 			dp->link_train.eq_loop++;
 
 			if (dp->link_train.eq_loop > MAX_EQ_LOOP) {
-				exynos_dp_reduce_link_rate(dp);
-			} else {
-				exynos_dp_get_adjust_train(dp, adjust_request);
-
-				for (lane = 0; lane < lane_count; lane++) {
-					exynos_dp_set_lane_link_training(dp,
-						dp->link_train.training_lane[lane],
-						lane);
-					buf[lane] = dp->link_train.training_lane[lane];
-					exynos_dp_write_byte_to_dpcd(dp,
-						DPCD_ADDR_TRAINING_LANE0_SET + lane,
-						buf[lane]);
-				}
+				dev_err(dp->dev, "EQ Max loop\n");
+				goto reduce_link_rate;
 			}
+
+			for (lane = 0; lane < lane_count; lane++)
+				exynos_dp_set_lane_link_training(dp,
+					dp->link_train.training_lane[lane],
+					lane);
+
+			exynos_dp_write_bytes_to_dpcd(dp,
+				DPCD_ADDR_TRAINING_LANE0_SET,
+				lane_count,
+				dp->link_train.training_lane);
 		}
 	} else {
-		exynos_dp_reduce_link_rate(dp);
+		goto reduce_link_rate;
 	}
 
 	return 0;
+
+reduce_link_rate:
+	exynos_dp_reduce_link_rate(dp);
+	return -EIO;
 }
 
 static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp,
-			u8 *bandwidth)
+					u8 *bandwidth)
 {
 	u8 data;
 
@@ -641,7 +650,7 @@
 }
 
 static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp,
-			u8 *lane_count)
+					u8 *lane_count)
 {
 	u8 data;
 
@@ -693,13 +702,7 @@
 static int exynos_dp_sw_link_training(struct exynos_dp_device *dp)
 {
 	int retval = 0;
-	int training_finished;
-
-	/* Turn off unnecessary lane */
-	if (dp->link_train.lane_count == 1)
-		exynos_dp_set_analog_power_down(dp, CH1_BLOCK, 1);
-
-	training_finished = 0;
+	int training_finished = 0;
 
 	dp->link_train.lt_state = START;
 
@@ -710,10 +713,14 @@
 			exynos_dp_link_start(dp);
 			break;
 		case CLOCK_RECOVERY:
-			exynos_dp_process_clock_recovery(dp);
+			retval = exynos_dp_process_clock_recovery(dp);
+			if (retval)
+				dev_err(dp->dev, "LT CR failed!\n");
 			break;
 		case EQUALIZER_TRAINING:
-			exynos_dp_process_equalizer_training(dp);
+			retval = exynos_dp_process_equalizer_training(dp);
+			if (retval)
+				dev_err(dp->dev, "LT EQ failed!\n");
 			break;
 		case FINISHED:
 			training_finished = 1;
@@ -872,40 +879,33 @@
 
 	dp->dev = &pdev->dev;
 
-	dp->clock = clk_get(&pdev->dev, "dp");
+	dp->clock = devm_clk_get(&pdev->dev, "dp");
 	if (IS_ERR(dp->clock)) {
 		dev_err(&pdev->dev, "failed to get clock\n");
 		return PTR_ERR(dp->clock);
 	}
 
-	clk_enable(dp->clock);
+	clk_prepare_enable(dp->clock);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		dev_err(&pdev->dev, "failed to get registers\n");
-		ret = -EINVAL;
-		goto err_clock;
-	}
 
 	dp->reg_base = devm_request_and_ioremap(&pdev->dev, res);
 	if (!dp->reg_base) {
 		dev_err(&pdev->dev, "failed to ioremap\n");
-		ret = -ENOMEM;
-		goto err_clock;
+		return -ENOMEM;
 	}
 
 	dp->irq = platform_get_irq(pdev, 0);
 	if (!dp->irq) {
 		dev_err(&pdev->dev, "failed to get irq\n");
-		ret = -ENODEV;
-		goto err_clock;
+		return -ENODEV;
 	}
 
 	ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, 0,
 				"exynos-dp", dp);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to request irq\n");
-		goto err_clock;
+		return ret;
 	}
 
 	dp->video_info = pdata->video_info;
@@ -917,7 +917,7 @@
 	ret = exynos_dp_detect_hpd(dp);
 	if (ret) {
 		dev_err(&pdev->dev, "unable to detect hpd\n");
-		goto err_clock;
+		return ret;
 	}
 
 	exynos_dp_handle_edid(dp);
@@ -926,7 +926,7 @@
 				dp->video_info->link_rate);
 	if (ret) {
 		dev_err(&pdev->dev, "unable to do link train\n");
-		goto err_clock;
+		return ret;
 	}
 
 	exynos_dp_enable_scramble(dp, 1);
@@ -940,17 +940,12 @@
 	ret = exynos_dp_config_video(dp, dp->video_info);
 	if (ret) {
 		dev_err(&pdev->dev, "unable to config video\n");
-		goto err_clock;
+		return ret;
 	}
 
 	platform_set_drvdata(pdev, dp);
 
 	return 0;
-
-err_clock:
-	clk_put(dp->clock);
-
-	return ret;
 }
 
 static int __devexit exynos_dp_remove(struct platform_device *pdev)
@@ -961,8 +956,7 @@
 	if (pdata && pdata->phy_exit)
 		pdata->phy_exit();
 
-	clk_disable(dp->clock);
-	clk_put(dp->clock);
+	clk_disable_unprepare(dp->clock);
 
 	return 0;
 }
@@ -977,7 +971,7 @@
 	if (pdata && pdata->phy_exit)
 		pdata->phy_exit();
 
-	clk_disable(dp->clock);
+	clk_disable_unprepare(dp->clock);
 
 	return 0;
 }
@@ -991,7 +985,7 @@
 	if (pdata && pdata->phy_init)
 		pdata->phy_init();
 
-	clk_enable(dp->clock);
+	clk_prepare_enable(dp->clock);
 
 	exynos_dp_init_dp(dp);
 
diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
index 8526e54..57b8a65 100644
--- a/drivers/video/exynos/exynos_dp_core.h
+++ b/drivers/video/exynos/exynos_dp_core.h
@@ -43,7 +43,7 @@
 void exynos_dp_reset(struct exynos_dp_device *dp);
 void exynos_dp_swreset(struct exynos_dp_device *dp);
 void exynos_dp_config_interrupt(struct exynos_dp_device *dp);
-u32 exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp);
+enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp);
 void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable);
 void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp,
 				enum analog_power_block block,
@@ -105,7 +105,7 @@
 u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp);
 u32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp);
 void exynos_dp_reset_macro(struct exynos_dp_device *dp);
-int exynos_dp_init_video(struct exynos_dp_device *dp);
+void exynos_dp_init_video(struct exynos_dp_device *dp);
 
 void exynos_dp_set_video_color_format(struct exynos_dp_device *dp,
 				u32 color_depth,
@@ -144,7 +144,7 @@
 #define DPCD_ADDR_TRAINING_PATTERN_SET		0x0102
 #define DPCD_ADDR_TRAINING_LANE0_SET		0x0103
 #define DPCD_ADDR_LANE0_1_STATUS		0x0202
-#define DPCD_ADDR_LANE_ALIGN__STATUS_UPDATED	0x0204
+#define DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED	0x0204
 #define DPCD_ADDR_ADJUST_REQUEST_LANE0_1	0x0206
 #define DPCD_ADDR_ADJUST_REQUEST_LANE2_3	0x0207
 #define DPCD_ADDR_TEST_REQUEST			0x0218
diff --git a/drivers/video/exynos/exynos_dp_reg.c b/drivers/video/exynos/exynos_dp_reg.c
index 2db5b9a..3f5ca8a 100644
--- a/drivers/video/exynos/exynos_dp_reg.c
+++ b/drivers/video/exynos/exynos_dp_reg.c
@@ -77,7 +77,7 @@
 	writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_3);
 
 	reg = PD_RING_OSC | AUX_TERMINAL_CTRL_50_OHM |
-		TX_CUR1_2X | TX_CUR_8_MA;
+		TX_CUR1_2X | TX_CUR_16_MA;
 	writel(reg, dp->reg_base + EXYNOS_DP_PLL_FILTER_CTL_1);
 
 	reg = CH3_AMP_400_MV | CH2_AMP_400_MV |
@@ -148,9 +148,6 @@
 	writel(0x2, dp->reg_base + EXYNOS_DP_M_AUD_GEN_FILTER_TH);
 
 	writel(0x00000101, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL);
-
-	exynos_dp_init_analog_param(dp);
-	exynos_dp_init_interrupt(dp);
 }
 
 void exynos_dp_swreset(struct exynos_dp_device *dp)
@@ -179,7 +176,7 @@
 	writel(reg, dp->reg_base + EXYNOS_DP_INT_STA_MASK);
 }
 
-u32 exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp)
+enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp)
 {
 	u32 reg;
 
@@ -401,6 +398,7 @@
 {
 	int reg;
 	int retval = 0;
+	int timeout_loop = 0;
 
 	/* Enable AUX CH operation */
 	reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2);
@@ -409,8 +407,15 @@
 
 	/* Is AUX CH command reply received? */
 	reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
-	while (!(reg & RPLY_RECEIV))
+	while (!(reg & RPLY_RECEIV)) {
+		timeout_loop++;
+		if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
+			dev_err(dp->dev, "AUX CH command reply failed!\n");
+			return -ETIMEDOUT;
+		}
 		reg = readl(dp->reg_base + EXYNOS_DP_INT_STA);
+		usleep_range(10, 11);
+	}
 
 	/* Clear interrupt source for AUX CH command reply */
 	writel(RPLY_RECEIV, dp->reg_base + EXYNOS_DP_INT_STA);
@@ -471,7 +476,8 @@
 		if (retval == 0)
 			break;
 		else
-			dev_err(dp->dev, "Aux Transaction fail!\n");
+			dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+				__func__);
 	}
 
 	return retval;
@@ -511,7 +517,8 @@
 		if (retval == 0)
 			break;
 		else
-			dev_err(dp->dev, "Aux Transaction fail!\n");
+			dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+				__func__);
 	}
 
 	/* Read data buffer */
@@ -575,7 +582,8 @@
 			if (retval == 0)
 				break;
 			else
-				dev_err(dp->dev, "Aux Transaction fail!\n");
+				dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+					__func__);
 		}
 
 		start_offset += cur_data_count;
@@ -632,7 +640,8 @@
 			if (retval == 0)
 				break;
 			else
-				dev_err(dp->dev, "Aux Transaction fail!\n");
+				dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+					__func__);
 		}
 
 		for (cur_data_idx = 0; cur_data_idx < cur_data_count;
@@ -677,7 +686,7 @@
 	/* Start AUX transaction */
 	retval = exynos_dp_start_aux_transaction(dp);
 	if (retval != 0)
-		dev_err(dp->dev, "Aux Transaction fail!\n");
+		dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
 
 	return retval;
 }
@@ -717,7 +726,8 @@
 		if (retval == 0)
 			break;
 		else
-			dev_err(dp->dev, "Aux Transaction fail!\n");
+			dev_dbg(dp->dev, "%s: Aux Transaction fail!\n",
+				__func__);
 	}
 
 	/* Read data */
@@ -777,7 +787,9 @@
 				if (retval == 0)
 					break;
 				else
-					dev_err(dp->dev, "Aux Transaction fail!\n");
+					dev_dbg(dp->dev,
+						"%s: Aux Transaction fail!\n",
+						__func__);
 			}
 			/* Check if Rx sends defer */
 			reg = readl(dp->reg_base + EXYNOS_DP_AUX_RX_COMM);
@@ -883,7 +895,9 @@
 {
 	u32 reg;
 
-	reg = level << PRE_EMPHASIS_SET_SHIFT;
+	reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
+	reg &= ~PRE_EMPHASIS_SET_MASK;
+	reg |= level << PRE_EMPHASIS_SET_SHIFT;
 	writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL);
 }
 
@@ -891,7 +905,9 @@
 {
 	u32 reg;
 
-	reg = level << PRE_EMPHASIS_SET_SHIFT;
+	reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
+	reg &= ~PRE_EMPHASIS_SET_MASK;
+	reg |= level << PRE_EMPHASIS_SET_SHIFT;
 	writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL);
 }
 
@@ -899,7 +915,9 @@
 {
 	u32 reg;
 
-	reg = level << PRE_EMPHASIS_SET_SHIFT;
+	reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
+	reg &= ~PRE_EMPHASIS_SET_MASK;
+	reg |= level << PRE_EMPHASIS_SET_SHIFT;
 	writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL);
 }
 
@@ -907,7 +925,9 @@
 {
 	u32 reg;
 
-	reg = level << PRE_EMPHASIS_SET_SHIFT;
+	reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
+	reg &= ~PRE_EMPHASIS_SET_MASK;
+	reg |= level << PRE_EMPHASIS_SET_SHIFT;
 	writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL);
 }
 
@@ -994,7 +1014,7 @@
 	writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST);
 }
 
-int exynos_dp_init_video(struct exynos_dp_device *dp)
+void exynos_dp_init_video(struct exynos_dp_device *dp)
 {
 	u32 reg;
 
@@ -1012,8 +1032,6 @@
 
 	reg = VID_HRES_TH(2) | VID_VRES_TH(0);
 	writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_8);
-
-	return 0;
 }
 
 void exynos_dp_set_video_color_format(struct exynos_dp_device *dp,
diff --git a/drivers/video/exynos/exynos_dp_reg.h b/drivers/video/exynos/exynos_dp_reg.h
index 125b27c..1f2f014c 100644
--- a/drivers/video/exynos/exynos_dp_reg.h
+++ b/drivers/video/exynos/exynos_dp_reg.h
@@ -187,7 +187,7 @@
 #define PD_RING_OSC				(0x1 << 6)
 #define AUX_TERMINAL_CTRL_50_OHM		(0x2 << 4)
 #define TX_CUR1_2X				(0x1 << 2)
-#define TX_CUR_8_MA				(0x2 << 0)
+#define TX_CUR_16_MA				(0x3 << 0)
 
 /* EXYNOS_DP_TX_AMP_TUNING_CTL */
 #define CH3_AMP_400_MV				(0x0 << 24)
@@ -285,6 +285,7 @@
 #define SW_TRAINING_PATTERN_SET_NORMAL		(0x0 << 0)
 
 /* EXYNOS_DP_LN0_LINK_TRAINING_CTL */
+#define PRE_EMPHASIS_SET_MASK			(0x3 << 3)
 #define PRE_EMPHASIS_SET_SHIFT			(3)
 
 /* EXYNOS_DP_DEBUG_CTL */
diff --git a/drivers/video/exynos/exynos_mipi_dsi.c b/drivers/video/exynos/exynos_mipi_dsi.c
index 663c308..07d70a3 100644
--- a/drivers/video/exynos/exynos_mipi_dsi.c
+++ b/drivers/video/exynos/exynos_mipi_dsi.c
@@ -205,7 +205,8 @@
 	return 0;
 }
 
-struct mipi_dsim_ddi *exynos_mipi_dsi_find_lcd_device(struct mipi_dsim_lcd_driver *lcd_drv)
+static struct mipi_dsim_ddi *exynos_mipi_dsi_find_lcd_device(
+					struct mipi_dsim_lcd_driver *lcd_drv)
 {
 	struct mipi_dsim_ddi *dsim_ddi, *next;
 	struct mipi_dsim_lcd_device *lcd_dev;
@@ -265,7 +266,8 @@
 
 }
 
-struct mipi_dsim_ddi *exynos_mipi_dsi_bind_lcd_ddi(struct mipi_dsim_device *dsim,
+static struct mipi_dsim_ddi *exynos_mipi_dsi_bind_lcd_ddi(
+						struct mipi_dsim_device *dsim,
 						const char *name)
 {
 	struct mipi_dsim_ddi *dsim_ddi, *next;
@@ -373,6 +375,7 @@
 	dsim->clock = clk_get(&pdev->dev, "dsim0");
 	if (IS_ERR(dsim->clock)) {
 		dev_err(&pdev->dev, "failed to get dsim clock source\n");
+		ret = -ENODEV;
 		goto err_clock_get;
 	}
 
@@ -381,6 +384,7 @@
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
 		dev_err(&pdev->dev, "failed to get io memory region\n");
+		ret = -ENODEV;
 		goto err_platform_get;
 	}
 
@@ -405,6 +409,7 @@
 	dsim_ddi = exynos_mipi_dsi_bind_lcd_ddi(dsim, dsim_pd->lcd_panel_name);
 	if (!dsim_ddi) {
 		dev_err(&pdev->dev, "mipi_dsim_ddi object not found.\n");
+		ret = -EINVAL;
 		goto err_bind;
 	}
 
diff --git a/drivers/video/exynos/exynos_mipi_dsi_common.c b/drivers/video/exynos/exynos_mipi_dsi_common.c
index 47b533a..3cd29a4 100644
--- a/drivers/video/exynos/exynos_mipi_dsi_common.c
+++ b/drivers/video/exynos/exynos_mipi_dsi_common.c
@@ -79,11 +79,6 @@
 	struct mipi_dsim_device *dsim = dev_id;
 	unsigned int intsrc, intmsk;
 
-	if (dsim == NULL) {
-		dev_err(dsim->dev, "%s: wrong parameter\n", __func__);
-		return IRQ_NONE;
-	}
-
 	intsrc = exynos_mipi_dsi_read_interrupt(dsim);
 	intmsk = exynos_mipi_dsi_read_interrupt_mask(dsim);
 	intmsk = ~intmsk & intsrc;
@@ -288,9 +283,6 @@
 		mutex_unlock(&dsim->lock);
 		return -EINVAL;
 	}
-
-	mutex_unlock(&dsim->lock);
-	return 0;
 }
 
 static unsigned int exynos_mipi_dsi_long_data_rd(struct mipi_dsim_device *dsim,
diff --git a/drivers/video/fb-puv3.c b/drivers/video/fb-puv3.c
index 60a787f..7d106f1f 100644
--- a/drivers/video/fb-puv3.c
+++ b/drivers/video/fb-puv3.c
@@ -653,9 +653,8 @@
 				vma->vm_page_prot))
 		return -EAGAIN;
 
-	vma->vm_flags |= VM_RESERVED;	/* avoid to swap out this VMA */
+	/* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
 	return 0;
-
 }
 
 static struct fb_ops unifb_ops = {
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c
index 64cda56..88cad6b 100644
--- a/drivers/video/fb_defio.c
+++ b/drivers/video/fb_defio.c
@@ -166,7 +166,7 @@
 static int fb_deferred_io_mmap(struct fb_info *info, struct vm_area_struct *vma)
 {
 	vma->vm_ops = &fb_deferred_io_vm_ops;
-	vma->vm_flags |= ( VM_RESERVED | VM_DONTEXPAND );
+	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 	if (!(info->flags & FBINFO_VIRTFB))
 		vma->vm_flags |= VM_IO;
 	vma->vm_private_data = info;
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 0dff12a..3ff0105 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1410,8 +1410,7 @@
 		return -EINVAL;
 	off += start;
 	vma->vm_pgoff = off >> PAGE_SHIFT;
-	/* This is an IO map - tell maydump to skip this VMA */
-	vma->vm_flags |= VM_IO | VM_RESERVED;
+	/* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by io_remap_pfn_range()*/
 	vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
 	fb_pgprotect(file, vma, off);
 	if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index 458c006..ede9e55 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -1501,8 +1501,8 @@
 	unsigned int i;
 	int ret;
 
-	data = dma_alloc_coherent(&pdev->dev, sizeof(struct fsl_diu_data),
-				  &dma_addr, GFP_DMA | __GFP_ZERO);
+	data = dmam_alloc_coherent(&pdev->dev, sizeof(struct fsl_diu_data),
+				   &dma_addr, GFP_DMA | __GFP_ZERO);
 	if (!data)
 		return -ENOMEM;
 	data->dma_addr = dma_addr;
@@ -1628,9 +1628,6 @@
 
 	iounmap(data->diu_reg);
 
-	dma_free_coherent(&pdev->dev, sizeof(struct fsl_diu_data), data,
-			  data->dma_addr);
-
 	return ret;
 }
 
@@ -1648,9 +1645,6 @@
 
 	iounmap(data->diu_reg);
 
-	dma_free_coherent(&pdev->dev, sizeof(struct fsl_diu_data), data,
-			  data->dma_addr);
-
 	return 0;
 }
 
diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c
index 7e7b7a9..3dad319 100644
--- a/drivers/video/gbefb.c
+++ b/drivers/video/gbefb.c
@@ -20,6 +20,7 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/module.h>
+#include <linux/io.h>
 
 #ifdef CONFIG_X86
 #include <asm/mtrr.h>
@@ -28,7 +29,6 @@
 #include <asm/addrspace.h>
 #endif
 #include <asm/byteorder.h>
-#include <asm/io.h>
 #include <asm/tlbflush.h>
 
 #include <video/gbe.h>
@@ -1024,7 +1024,7 @@
 	pgprot_val(vma->vm_page_prot) =
 		pgprot_fb(pgprot_val(vma->vm_page_prot));
 
-	vma->vm_flags |= VM_IO | VM_RESERVED;
+	/* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
 
 	/* look for the starting tile */
 	tile = &gbe_tiles.cpu[offset >> TILE_SHIFT];
@@ -1156,7 +1156,8 @@
 		goto out_release_framebuffer;
 	}
 
-	gbe = (struct sgi_gbe *) ioremap(GBE_BASE, sizeof(struct sgi_gbe));
+	gbe = (struct sgi_gbe *) devm_ioremap(&p_dev->dev, GBE_BASE,
+					      sizeof(struct sgi_gbe));
 	if (!gbe) {
 		printk(KERN_ERR "gbefb: couldn't map mmio region\n");
 		ret = -ENXIO;
@@ -1170,12 +1171,13 @@
 	if (!gbe_tiles.cpu) {
 		printk(KERN_ERR "gbefb: couldn't allocate tiles table\n");
 		ret = -ENOMEM;
-		goto out_unmap;
+		goto out_release_mem_region;
 	}
 
 	if (gbe_mem_phys) {
 		/* memory was allocated at boot time */
-		gbe_mem = ioremap_nocache(gbe_mem_phys, gbe_mem_size);
+		gbe_mem = devm_ioremap_nocache(&p_dev->dev, gbe_mem_phys,
+					       gbe_mem_size);
 		if (!gbe_mem) {
 			printk(KERN_ERR "gbefb: couldn't map framebuffer\n");
 			ret = -ENOMEM;
@@ -1241,13 +1243,9 @@
 out_gbe_unmap:
 	if (gbe_dma_addr)
 		dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
-	else
-		iounmap(gbe_mem);
 out_tiles_free:
 	dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
 			  (void *)gbe_tiles.cpu, gbe_tiles.dma);
-out_unmap:
-	iounmap(gbe);
 out_release_mem_region:
 	release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
 out_release_framebuffer:
@@ -1264,12 +1262,9 @@
 	gbe_turn_off();
 	if (gbe_dma_addr)
 		dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
-	else
-		iounmap(gbe_mem);
 	dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
 			  (void *)gbe_tiles.cpu, gbe_tiles.dma);
 	release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
-	iounmap(gbe);
 	gbefb_remove_sysfs(&p_dev->dev);
 	framebuffer_release(info);
 
diff --git a/drivers/video/hpfb.c b/drivers/video/hpfb.c
index ebf8495..7324865 100644
--- a/drivers/video/hpfb.c
+++ b/drivers/video/hpfb.c
@@ -210,6 +210,7 @@
 				   unsigned long virt_base)
 {
 	unsigned long fboff, fb_width, fb_height, fb_start;
+	int ret;
 
 	fb_regs = virt_base;
 	fboff = (in_8(fb_regs + HPFB_FBOMSB) << 8) | in_8(fb_regs + HPFB_FBOLSB);
@@ -290,19 +291,29 @@
 	fb_info.var   = hpfb_defined;
 	fb_info.screen_base = (char *)fb_start;
 
-	fb_alloc_cmap(&fb_info.cmap, 1 << hpfb_defined.bits_per_pixel, 0);
+	ret = fb_alloc_cmap(&fb_info.cmap, 1 << hpfb_defined.bits_per_pixel, 0);
+	if (ret < 0)
+		goto unmap_screen_base;
 
-	if (register_framebuffer(&fb_info) < 0) {
-		fb_dealloc_cmap(&fb_info.cmap);
-		iounmap(fb_info.screen_base);
-		fb_info.screen_base = NULL;
-		return 1;
-	}
+	ret = register_framebuffer(&fb_info);
+	if (ret < 0)
+		goto dealloc_cmap;
 
 	printk(KERN_INFO "fb%d: %s frame buffer device\n",
 	       fb_info.node, fb_info.fix.id);
 
 	return 0;
+
+dealloc_cmap:
+	fb_dealloc_cmap(&fb_info.cmap);
+
+unmap_screen_base:
+	if (fb_info.screen_base) {
+		iounmap(fb_info.screen_base);
+		fb_info.screen_base = NULL;
+	}
+
+	return ret;
 }
 
 /* 
@@ -345,6 +356,9 @@
 	if (d->scode >= DIOII_SCBASE)
 		iounmap((void *)fb_regs);
 	release_mem_region(d->resource.start, resource_size(&d->resource));
+	fb_dealloc_cmap(&fb_info.cmap);
+	if (fb_info.screen_base)
+		iounmap(fb_info.screen_base);
 }
 
 static struct dio_device_id hpfb_dio_tbl[] = {
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 53ffdfc..cf2688d 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -803,6 +803,7 @@
 	fbi->regs = ioremap(res->start, resource_size(res));
 	if (fbi->regs == NULL) {
 		dev_err(&pdev->dev, "Cannot map frame buffer registers\n");
+		ret = -ENOMEM;
 		goto failed_ioremap;
 	}
 
diff --git a/drivers/video/jz4740_fb.c b/drivers/video/jz4740_fb.c
index 3c63fc2..4d25711 100644
--- a/drivers/video/jz4740_fb.c
+++ b/drivers/video/jz4740_fb.c
@@ -632,23 +632,10 @@
 		return -ENXIO;
 	}
 
-	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!mem) {
-		dev_err(&pdev->dev, "Failed to get register memory resource\n");
-		return -ENXIO;
-	}
-
-	mem = request_mem_region(mem->start, resource_size(mem), pdev->name);
-	if (!mem) {
-		dev_err(&pdev->dev, "Failed to request register memory region\n");
-		return -EBUSY;
-	}
-
 	fb = framebuffer_alloc(sizeof(struct jzfb), &pdev->dev);
 	if (!fb) {
 		dev_err(&pdev->dev, "Failed to allocate framebuffer device\n");
-		ret = -ENOMEM;
-		goto err_release_mem_region;
+		return -ENOMEM;
 	}
 
 	fb->fbops = &jzfb_ops;
@@ -657,27 +644,26 @@
 	jzfb = fb->par;
 	jzfb->pdev = pdev;
 	jzfb->pdata = pdata;
-	jzfb->mem = mem;
 
-	jzfb->ldclk = clk_get(&pdev->dev, "lcd");
+	jzfb->ldclk = devm_clk_get(&pdev->dev, "lcd");
 	if (IS_ERR(jzfb->ldclk)) {
 		ret = PTR_ERR(jzfb->ldclk);
 		dev_err(&pdev->dev, "Failed to get lcd clock: %d\n", ret);
 		goto err_framebuffer_release;
 	}
 
-	jzfb->lpclk = clk_get(&pdev->dev, "lcd_pclk");
+	jzfb->lpclk = devm_clk_get(&pdev->dev, "lcd_pclk");
 	if (IS_ERR(jzfb->lpclk)) {
 		ret = PTR_ERR(jzfb->lpclk);
 		dev_err(&pdev->dev, "Failed to get lcd pixel clock: %d\n", ret);
-		goto err_put_ldclk;
+		goto err_framebuffer_release;
 	}
 
-	jzfb->base = ioremap(mem->start, resource_size(mem));
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	jzfb->base = devm_request_and_ioremap(&pdev->dev, mem);
 	if (!jzfb->base) {
-		dev_err(&pdev->dev, "Failed to ioremap register memory region\n");
 		ret = -EBUSY;
-		goto err_put_lpclk;
+		goto err_framebuffer_release;
 	}
 
 	platform_set_drvdata(pdev, jzfb);
@@ -693,7 +679,7 @@
 	ret = jzfb_alloc_devmem(jzfb);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to allocate video memory\n");
-		goto err_iounmap;
+		goto err_framebuffer_release;
 	}
 
 	fb->fix = jzfb_fix;
@@ -734,16 +720,8 @@
 
 	fb_dealloc_cmap(&fb->cmap);
 	jzfb_free_devmem(jzfb);
-err_iounmap:
-	iounmap(jzfb->base);
-err_put_lpclk:
-	clk_put(jzfb->lpclk);
-err_put_ldclk:
-	clk_put(jzfb->ldclk);
 err_framebuffer_release:
 	framebuffer_release(fb);
-err_release_mem_region:
-	release_mem_region(mem->start, resource_size(mem));
 	return ret;
 }
 
@@ -756,17 +734,11 @@
 	jz_gpio_bulk_free(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));
 	jz_gpio_bulk_free(jz_lcd_data_pins, jzfb_num_data_pins(jzfb));
 
-	iounmap(jzfb->base);
-	release_mem_region(jzfb->mem->start, resource_size(jzfb->mem));
-
 	fb_dealloc_cmap(&jzfb->fb->cmap);
 	jzfb_free_devmem(jzfb);
 
 	platform_set_drvdata(pdev, NULL);
 
-	clk_put(jzfb->lpclk);
-	clk_put(jzfb->ldclk);
-
 	framebuffer_release(jzfb->fb);
 
 	return 0;
diff --git a/drivers/video/mb862xx/mb862xxfbdrv.c b/drivers/video/mb862xx/mb862xxfbdrv.c
index 57d940b..d68e332 100644
--- a/drivers/video/mb862xx/mb862xxfbdrv.c
+++ b/drivers/video/mb862xx/mb862xxfbdrv.c
@@ -1052,12 +1052,14 @@
 		break;
 	default:
 		/* should never occur */
+		ret = -EIO;
 		goto rel_reg;
 	}
 
 	par->fb_base = ioremap(par->fb_base_phys, par->mapped_vram);
 	if (par->fb_base == NULL) {
 		dev_err(dev, "Cannot map framebuffer\n");
+		ret = -EIO;
 		goto rel_reg;
 	}
 
@@ -1073,11 +1075,13 @@
 	dev_dbg(dev, "mmio phys 0x%llx 0x%lx\n",
 		(unsigned long long)par->mmio_base_phys, (ulong)par->mmio_len);
 
-	if (mb862xx_pci_gdc_init(par))
+	ret = mb862xx_pci_gdc_init(par);
+	if (ret)
 		goto io_unmap;
 
-	if (request_irq(par->irq, mb862xx_intr, IRQF_SHARED,
-			DRV_NAME, (void *)par)) {
+	ret = request_irq(par->irq, mb862xx_intr, IRQF_SHARED,
+			  DRV_NAME, (void *)par);
+	if (ret) {
 		dev_err(dev, "Cannot request irq\n");
 		goto io_unmap;
 	}
diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/mbx/mbxfb.c
index 85e4f44..6563e50 100644
--- a/drivers/video/mbx/mbxfb.c
+++ b/drivers/video/mbx/mbxfb.c
@@ -26,8 +26,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/uaccess.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
 
 #include <video/mbxfb.h>
 
@@ -939,8 +938,9 @@
 	}
 	mfbi->reg_phys_addr = mfbi->reg_res->start;
 
-	mfbi->reg_virt_addr = ioremap_nocache(mfbi->reg_phys_addr,
-					      res_size(mfbi->reg_req));
+	mfbi->reg_virt_addr = devm_ioremap_nocache(&dev->dev,
+						   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;
@@ -948,12 +948,12 @@
 	}
 	virt_base_2700 = mfbi->reg_virt_addr;
 
-	mfbi->fb_virt_addr = ioremap_nocache(mfbi->fb_phys_addr,
-					     res_size(mfbi->fb_req));
+	mfbi->fb_virt_addr = devm_ioremap_nocache(&dev->dev, mfbi->fb_phys_addr,
+						  res_size(mfbi->fb_req));
 	if (!mfbi->fb_virt_addr) {
 		dev_err(&dev->dev, "failed to ioremap frame buffer\n");
 		ret = -EINVAL;
-		goto err4;
+		goto err3;
 	}
 
 	fbi->screen_base = (char __iomem *)(mfbi->fb_virt_addr + 0x60000);
@@ -971,7 +971,7 @@
 	if (ret < 0) {
 		dev_err(&dev->dev, "fb_alloc_cmap failed\n");
 		ret = -EINVAL;
-		goto err5;
+		goto err3;
 	}
 
 	platform_set_drvdata(dev, fbi);
@@ -996,10 +996,6 @@
 
 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:
@@ -1026,10 +1022,7 @@
 			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));
diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c
index bf73f04..35ac9e8 100644
--- a/drivers/video/msm/mddi.c
+++ b/drivers/video/msm/mddi.c
@@ -26,9 +26,6 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/sched.h>
-#include <mach/msm_iomap.h>
-#include <mach/irqs.h>
-#include <mach/board.h>
 #include <linux/platform_data/video-msm_fb.h>
 #include "mddi_hw.h"
 
diff --git a/drivers/video/msm/mddi_client_nt35399.c b/drivers/video/msm/mddi_client_nt35399.c
index d7a5bf8..f96df32e 100644
--- a/drivers/video/msm/mddi_client_nt35399.c
+++ b/drivers/video/msm/mddi_client_nt35399.c
@@ -189,8 +189,9 @@
 
 	int ret;
 
-	struct panel_info *panel = kzalloc(sizeof(struct panel_info),
-					   GFP_KERNEL);
+	struct panel_info *panel = devm_kzalloc(&pdev->dev,
+						sizeof(struct panel_info),
+						GFP_KERNEL);
 
 	printk(KERN_DEBUG "%s: enter.\n", __func__);
 
@@ -233,7 +234,6 @@
 	struct panel_info *panel = platform_get_drvdata(pdev);
 
 	setup_vsync(panel, 0);
-	kfree(panel);
 	return 0;
 }
 
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 2e0f3ba..f2566c1 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -25,7 +25,6 @@
 #include <linux/major.h>
 #include <linux/slab.h>
 
-#include <mach/msm_iomap.h>
 #include <linux/platform_data/video-msm_fb.h>
 #include <linux/platform_device.h>
 #include <linux/export.h>
diff --git a/drivers/video/msm/mdp_hw.h b/drivers/video/msm/mdp_hw.h
index a0bacf5..35848d7 100644
--- a/drivers/video/msm/mdp_hw.h
+++ b/drivers/video/msm/mdp_hw.h
@@ -15,7 +15,6 @@
 #ifndef _MDP_HW_H_
 #define _MDP_HW_H_
 
-#include <mach/msm_iomap.h>
 #include <linux/platform_data/video-msm_fb.h>
 
 struct mdp_info {
diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c
index d738108..ce1d452 100644
--- a/drivers/video/mx3fb.c
+++ b/drivers/video/mx3fb.c
@@ -1568,7 +1568,8 @@
 
 static struct platform_driver mx3fb_driver = {
 	.driver = {
-		   .name = MX3FB_NAME,
+		.name = MX3FB_NAME,
+		.owner = THIS_MODULE,
 	},
 	.probe = mx3fb_probe,
 	.remove = mx3fb_remove,
diff --git a/drivers/video/nuc900fb.c b/drivers/video/nuc900fb.c
index 9338755..475dfee 100644
--- a/drivers/video/nuc900fb.c
+++ b/drivers/video/nuc900fb.c
@@ -387,7 +387,7 @@
  *    The buffer should be a non-cached, non-buffered, memory region
  *    to allow palette and pixel writes without flushing the cache.
  */
-static int __init nuc900fb_map_video_memory(struct fb_info *info)
+static int __devinit nuc900fb_map_video_memory(struct fb_info *info)
 {
 	struct nuc900fb_info *fbi = info->par;
 	dma_addr_t map_dma;
diff --git a/drivers/video/omap/hwa742.c b/drivers/video/omap/hwa742.c
index 9f1d23c..f349ee6 100644
--- a/drivers/video/omap/hwa742.c
+++ b/drivers/video/omap/hwa742.c
@@ -27,7 +27,6 @@
 #include <linux/clk.h>
 #include <linux/interrupt.h>
 
-#include <plat/dma.h>
 #include "omapfb.h"
 
 #define HWA742_REV_CODE_REG       0x0
diff --git a/drivers/video/omap/lcd_palmte.c b/drivers/video/omap/lcd_palmte.c
index 88c31eb..ff4fb62 100644
--- a/drivers/video/omap/lcd_palmte.c
+++ b/drivers/video/omap/lcd_palmte.c
@@ -23,7 +23,6 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 
-#include <plat/fpga.h>
 #include "omapfb.h"
 
 static int palmte_panel_init(struct lcd_panel *panel,
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index f54b463..4351c43 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -131,15 +131,6 @@
  * LCD controller and LCD DMA
  * ---------------------------------------------------------------------------
  */
-/* Lookup table to map elem size to elem type. */
-static const int dma_elem_type[] = {
-	0,
-	OMAP_DMA_DATA_TYPE_S8,
-	OMAP_DMA_DATA_TYPE_S16,
-	0,
-	OMAP_DMA_DATA_TYPE_S32,
-};
-
 /*
  * Allocate resources needed for LCD controller and LCD DMA operations. Video
  * memory is allocated from system memory according to the virtual display
diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c
index eaeed43..c835aa7 100644
--- a/drivers/video/omap2/displays/panel-acx565akm.c
+++ b/drivers/video/omap2/displays/panel-acx565akm.c
@@ -600,6 +600,9 @@
 
 	mutex_lock(&md->mutex);
 
+	omapdss_sdi_set_timings(dssdev, &dssdev->panel.timings);
+	omapdss_sdi_set_datapairs(dssdev, dssdev->phy.sdi.datapairs);
+
 	r = omapdss_sdi_display_enable(dssdev);
 	if (r) {
 		pr_err("%s sdi enable failed\n", __func__);
@@ -731,18 +734,9 @@
 static void acx_panel_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
-	int r;
-
-	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
-		omapdss_sdi_display_disable(dssdev);
+	omapdss_sdi_set_timings(dssdev, timings);
 
 	dssdev->panel.timings = *timings;
-
-	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
-		r = omapdss_sdi_display_enable(dssdev);
-		if (r)
-			dev_err(&dssdev->dev, "%s enable failed\n", __func__);
-	}
 }
 
 static int acx_panel_check_timings(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index bc5af25..88295c5 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -545,6 +545,8 @@
 	struct omap_dss_device *dssdev;
 
 	struct panel_config *panel_config;
+
+	struct mutex lock;
 };
 
 static inline struct panel_generic_dpi_data
@@ -563,6 +565,9 @@
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+	omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
@@ -634,6 +639,8 @@
 	drv_data->dssdev = dssdev;
 	drv_data->panel_config = panel_config;
 
+	mutex_init(&drv_data->lock);
+
 	dev_set_drvdata(&dssdev->dev, drv_data);
 
 	return 0;
@@ -652,56 +659,108 @@
 
 static int generic_dpi_panel_enable(struct omap_dss_device *dssdev)
 {
-	int r = 0;
+	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+	int r;
+
+	mutex_lock(&drv_data->lock);
 
 	r = generic_dpi_panel_power_on(dssdev);
 	if (r)
-		return r;
+		goto err;
 
 	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+err:
+	mutex_unlock(&drv_data->lock);
 
-	return 0;
+	return r;
 }
 
 static void generic_dpi_panel_disable(struct omap_dss_device *dssdev)
 {
+	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+
+	mutex_lock(&drv_data->lock);
+
 	generic_dpi_panel_power_off(dssdev);
 
 	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+
+	mutex_unlock(&drv_data->lock);
 }
 
 static int generic_dpi_panel_suspend(struct omap_dss_device *dssdev)
 {
+	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+
+	mutex_lock(&drv_data->lock);
+
 	generic_dpi_panel_power_off(dssdev);
 
 	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
 
+	mutex_unlock(&drv_data->lock);
+
 	return 0;
 }
 
 static int generic_dpi_panel_resume(struct omap_dss_device *dssdev)
 {
-	int r = 0;
+	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+	int r;
+
+	mutex_lock(&drv_data->lock);
 
 	r = generic_dpi_panel_power_on(dssdev);
 	if (r)
-		return r;
+		goto err;
 
 	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
 
-	return 0;
+err:
+	mutex_unlock(&drv_data->lock);
+
+	return r;
 }
 
 static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
-	dpi_set_timings(dssdev, timings);
+	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+
+	mutex_lock(&drv_data->lock);
+
+	omapdss_dpi_set_timings(dssdev, timings);
+
+	dssdev->panel.timings = *timings;
+
+	mutex_unlock(&drv_data->lock);
+}
+
+static void generic_dpi_panel_get_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+
+	mutex_lock(&drv_data->lock);
+
+	*timings = dssdev->panel.timings;
+
+	mutex_unlock(&drv_data->lock);
 }
 
 static int generic_dpi_panel_check_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
-	return dpi_check_timings(dssdev, timings);
+	struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
+	int r;
+
+	mutex_lock(&drv_data->lock);
+
+	r = dpi_check_timings(dssdev, timings);
+
+	mutex_unlock(&drv_data->lock);
+
+	return r;
 }
 
 static struct omap_dss_driver dpi_driver = {
@@ -714,6 +773,7 @@
 	.resume		= generic_dpi_panel_resume,
 
 	.set_timings	= generic_dpi_panel_set_timings,
+	.get_timings	= generic_dpi_panel_get_timings,
 	.check_timings	= generic_dpi_panel_check_timings,
 
 	.driver         = {
diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
index 8028077..90c1cab 100644
--- a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
@@ -55,6 +55,9 @@
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+	omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
diff --git a/drivers/video/omap2/displays/panel-n8x0.c b/drivers/video/omap2/displays/panel-n8x0.c
index e6c1153..3fc5ad0 100644
--- a/drivers/video/omap2/displays/panel-n8x0.c
+++ b/drivers/video/omap2/displays/panel-n8x0.c
@@ -150,11 +150,17 @@
 			BLIZZARD_SRC_WRITE_LCD :
 			BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE;
 
-	omap_rfbi_configure(dssdev, 16, 8);
+	omapdss_rfbi_set_pixel_size(dssdev, 16);
+	omapdss_rfbi_set_data_lines(dssdev, 8);
+
+	omap_rfbi_configure(dssdev);
 
 	blizzard_write(BLIZZARD_INPUT_WIN_X_START_0, tmp, 18);
 
-	omap_rfbi_configure(dssdev, 16, 16);
+	omapdss_rfbi_set_pixel_size(dssdev, 16);
+	omapdss_rfbi_set_data_lines(dssdev, 16);
+
+	omap_rfbi_configure(dssdev);
 }
 
 static void mipid_transfer(struct spi_device *spi, int cmd, const u8 *wbuf,
@@ -297,6 +303,12 @@
 			goto err_plat_en;
 	}
 
+	omapdss_rfbi_set_size(dssdev, dssdev->panel.timings.x_res,
+		dssdev->panel.timings.y_res);
+	omapdss_rfbi_set_pixel_size(dssdev, dssdev->ctrl.pixel_size);
+	omapdss_rfbi_set_data_lines(dssdev, dssdev->phy.rfbi.data_lines);
+	omapdss_rfbi_set_interface_timings(dssdev, &dssdev->ctrl.rfbi_timings);
+
 	r = omapdss_rfbi_display_enable(dssdev);
 	if (r)
 		goto err_rfbi_en;
@@ -477,6 +489,7 @@
 	dssdev->panel.timings.y_res = 480;
 	dssdev->ctrl.pixel_size = 16;
 	dssdev->ctrl.rfbi_timings = n8x0_panel_timings;
+	dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
 
 	memset(&props, 0, sizeof(props));
 	props.max_brightness = 127;
@@ -625,17 +638,25 @@
 		u16 x, u16 y, u16 w, u16 h)
 {
 	struct panel_drv_data *ddata = get_drv_data(dssdev);
+	u16 dw, dh;
 
 	dev_dbg(&dssdev->dev, "update\n");
 
+	dw = dssdev->panel.timings.x_res;
+	dh = dssdev->panel.timings.y_res;
+
+	if (x != 0 || y != 0 || w != dw || h != dh) {
+		dev_err(&dssdev->dev, "invaid update region %d, %d, %d, %d\n",
+			x, y, w, h);
+		return -EINVAL;
+	}
+
 	mutex_lock(&ddata->lock);
 	rfbi_bus_lock();
 
-	omap_rfbi_prepare_update(dssdev, &x, &y, &w, &h);
-
 	blizzard_ctrl_setup_update(dssdev, x, y, w, h);
 
-	omap_rfbi_update(dssdev, x, y, w, h, update_done, NULL);
+	omap_rfbi_update(dssdev, update_done, NULL);
 
 	mutex_unlock(&ddata->lock);
 
diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
index b122b0f..908fd26 100644
--- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
+++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
@@ -175,6 +175,9 @@
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+	omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
diff --git a/drivers/video/omap2/displays/panel-picodlp.c b/drivers/video/omap2/displays/panel-picodlp.c
index 2d35bd3..9df8764 100644
--- a/drivers/video/omap2/displays/panel-picodlp.c
+++ b/drivers/video/omap2/displays/panel-picodlp.c
@@ -377,6 +377,10 @@
 	 * then only i2c commands can be successfully sent to dpp2600
 	 */
 	msleep(1000);
+
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+	omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r) {
 		dev_err(&dssdev->dev, "failed to enable DPI\n");
diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
index bd86ba9..1ec3b27 100644
--- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
@@ -142,6 +142,9 @@
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+	omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 6b5e6e0..f2f6446 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -121,6 +121,18 @@
 
 	struct omap_dss_device *dssdev;
 
+	/* panel specific HW info */
+	struct panel_config *panel_config;
+
+	/* panel HW configuration from DT or platform data */
+	int reset_gpio;
+	int ext_te_gpio;
+
+	bool use_dsi_backlight;
+
+	struct omap_dsi_pin_config pin_config;
+
+	/* runtime variables */
 	bool enabled;
 	u8 rotate;
 	bool mirror;
@@ -145,16 +157,8 @@
 	bool ulps_enabled;
 	unsigned ulps_timeout;
 	struct delayed_work ulps_work;
-
-	struct panel_config *panel_config;
 };
 
-static inline struct nokia_dsi_panel_data
-*get_panel_data(const struct omap_dss_device *dssdev)
-{
-	return (struct nokia_dsi_panel_data *) dssdev->data;
-}
-
 static void taal_esd_work(struct work_struct *work);
 static void taal_ulps_work(struct work_struct *work);
 
@@ -371,7 +375,6 @@
 static int taal_enter_ulps(struct omap_dss_device *dssdev)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
-	struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
 	int r;
 
 	if (td->ulps_enabled)
@@ -383,7 +386,8 @@
 	if (r)
 		goto err;
 
-	disable_irq(gpio_to_irq(panel_data->ext_te_gpio));
+	if (gpio_is_valid(td->ext_te_gpio))
+		disable_irq(gpio_to_irq(td->ext_te_gpio));
 
 	omapdss_dsi_display_disable(dssdev, false, true);
 
@@ -405,7 +409,6 @@
 static int taal_exit_ulps(struct omap_dss_device *dssdev)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
-	struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
 	int r;
 
 	if (!td->ulps_enabled)
@@ -425,7 +428,8 @@
 		goto err2;
 	}
 
-	enable_irq(gpio_to_irq(panel_data->ext_te_gpio));
+	if (gpio_is_valid(td->ext_te_gpio))
+		enable_irq(gpio_to_irq(td->ext_te_gpio));
 
 	taal_queue_ulps_work(dssdev);
 
@@ -438,7 +442,8 @@
 
 	r = taal_panel_reset(dssdev);
 	if (!r) {
-		enable_irq(gpio_to_irq(panel_data->ext_te_gpio));
+		if (gpio_is_valid(td->ext_te_gpio))
+			enable_irq(gpio_to_irq(td->ext_te_gpio));
 		td->ulps_enabled = false;
 	}
 err1:
@@ -835,94 +840,135 @@
 static void taal_hw_reset(struct omap_dss_device *dssdev)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
-	struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
 
-	if (panel_data->reset_gpio == -1)
+	if (!gpio_is_valid(td->reset_gpio))
 		return;
 
-	gpio_set_value(panel_data->reset_gpio, 1);
+	gpio_set_value(td->reset_gpio, 1);
 	if (td->panel_config->reset_sequence.high)
 		udelay(td->panel_config->reset_sequence.high);
 	/* reset the panel */
-	gpio_set_value(panel_data->reset_gpio, 0);
+	gpio_set_value(td->reset_gpio, 0);
 	/* assert reset */
 	if (td->panel_config->reset_sequence.low)
 		udelay(td->panel_config->reset_sequence.low);
-	gpio_set_value(panel_data->reset_gpio, 1);
+	gpio_set_value(td->reset_gpio, 1);
 	/* wait after releasing reset */
 	if (td->panel_config->sleep.hw_reset)
 		msleep(td->panel_config->sleep.hw_reset);
 }
 
+static void taal_probe_pdata(struct taal_data *td,
+		const struct nokia_dsi_panel_data *pdata)
+{
+	td->reset_gpio = pdata->reset_gpio;
+
+	if (pdata->use_ext_te)
+		td->ext_te_gpio = pdata->ext_te_gpio;
+	else
+		td->ext_te_gpio = -1;
+
+	td->esd_interval = pdata->esd_interval;
+	td->ulps_timeout = pdata->ulps_timeout;
+
+	td->use_dsi_backlight = pdata->use_dsi_backlight;
+
+	td->pin_config = pdata->pin_config;
+}
+
 static int taal_probe(struct omap_dss_device *dssdev)
 {
 	struct backlight_properties props;
 	struct taal_data *td;
 	struct backlight_device *bldev = NULL;
-	struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
-	struct panel_config *panel_config = NULL;
 	int r, i;
+	const char *panel_name;
 
 	dev_dbg(&dssdev->dev, "probe\n");
 
-	if (!panel_data || !panel_data->name) {
-		r = -EINVAL;
-		goto err;
+	td = devm_kzalloc(&dssdev->dev, sizeof(*td), GFP_KERNEL);
+	if (!td)
+		return -ENOMEM;
+
+	dev_set_drvdata(&dssdev->dev, td);
+	td->dssdev = dssdev;
+
+	if (dssdev->data) {
+		const struct nokia_dsi_panel_data *pdata = dssdev->data;
+
+		taal_probe_pdata(td, pdata);
+
+		panel_name = pdata->name;
+	} else {
+		return -ENODEV;
 	}
 
+	if (panel_name == NULL)
+		return -EINVAL;
+
 	for (i = 0; i < ARRAY_SIZE(panel_configs); i++) {
-		if (strcmp(panel_data->name, panel_configs[i].name) == 0) {
-			panel_config = &panel_configs[i];
+		if (strcmp(panel_name, panel_configs[i].name) == 0) {
+			td->panel_config = &panel_configs[i];
 			break;
 		}
 	}
 
-	if (!panel_config) {
-		r = -EINVAL;
-		goto err;
-	}
+	if (!td->panel_config)
+		return -EINVAL;
 
-	dssdev->panel.timings = panel_config->timings;
+	dssdev->panel.timings = td->panel_config->timings;
 	dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888;
-
-	td = kzalloc(sizeof(*td), GFP_KERNEL);
-	if (!td) {
-		r = -ENOMEM;
-		goto err;
-	}
-	td->dssdev = dssdev;
-	td->panel_config = panel_config;
-	td->esd_interval = panel_data->esd_interval;
-	td->ulps_enabled = false;
-	td->ulps_timeout = panel_data->ulps_timeout;
+	dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
+		OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
 
 	mutex_init(&td->lock);
 
 	atomic_set(&td->do_update, 0);
 
+	if (gpio_is_valid(td->reset_gpio)) {
+		r = devm_gpio_request_one(&dssdev->dev, td->reset_gpio,
+				GPIOF_OUT_INIT_LOW, "taal rst");
+		if (r) {
+			dev_err(&dssdev->dev, "failed to request reset gpio\n");
+			return r;
+		}
+	}
+
+	if (gpio_is_valid(td->ext_te_gpio)) {
+		r = devm_gpio_request_one(&dssdev->dev, td->ext_te_gpio,
+				GPIOF_IN, "taal irq");
+		if (r) {
+			dev_err(&dssdev->dev, "GPIO request failed\n");
+			return r;
+		}
+
+		r = devm_request_irq(&dssdev->dev, gpio_to_irq(td->ext_te_gpio),
+				taal_te_isr,
+				IRQF_TRIGGER_RISING,
+				"taal vsync", dssdev);
+
+		if (r) {
+			dev_err(&dssdev->dev, "IRQ request failed\n");
+			return r;
+		}
+
+		INIT_DEFERRABLE_WORK(&td->te_timeout_work,
+					taal_te_timeout_work_callback);
+
+		dev_dbg(&dssdev->dev, "Using GPIO TE\n");
+	}
+
 	td->workqueue = create_singlethread_workqueue("taal_esd");
 	if (td->workqueue == NULL) {
 		dev_err(&dssdev->dev, "can't create ESD workqueue\n");
-		r = -ENOMEM;
-		goto err_wq;
+		return -ENOMEM;
 	}
 	INIT_DEFERRABLE_WORK(&td->esd_work, taal_esd_work);
 	INIT_DELAYED_WORK(&td->ulps_work, taal_ulps_work);
 
-	dev_set_drvdata(&dssdev->dev, td);
-
-	if (gpio_is_valid(panel_data->reset_gpio)) {
-		r = gpio_request_one(panel_data->reset_gpio, GPIOF_OUT_INIT_LOW,
-				"taal rst");
-		if (r) {
-			dev_err(&dssdev->dev, "failed to request reset gpio\n");
-			goto err_rst_gpio;
-		}
-	}
-
 	taal_hw_reset(dssdev);
 
-	if (panel_data->use_dsi_backlight) {
+	if (td->use_dsi_backlight) {
 		memset(&props, 0, sizeof(struct backlight_properties));
 		props.max_brightness = 255;
 
@@ -943,31 +989,6 @@
 		taal_bl_update_status(bldev);
 	}
 
-	if (panel_data->use_ext_te) {
-		int gpio = panel_data->ext_te_gpio;
-
-		r = gpio_request_one(gpio, GPIOF_IN, "taal irq");
-		if (r) {
-			dev_err(&dssdev->dev, "GPIO request failed\n");
-			goto err_gpio;
-		}
-
-		r = request_irq(gpio_to_irq(gpio), taal_te_isr,
-				IRQF_TRIGGER_RISING,
-				"taal vsync", dssdev);
-
-		if (r) {
-			dev_err(&dssdev->dev, "IRQ request failed\n");
-			gpio_free(gpio);
-			goto err_irq;
-		}
-
-		INIT_DEFERRABLE_WORK(&td->te_timeout_work,
-				     taal_te_timeout_work_callback);
-
-		dev_dbg(&dssdev->dev, "Using GPIO TE\n");
-	}
-
 	r = omap_dsi_request_vc(dssdev, &td->channel);
 	if (r) {
 		dev_err(&dssdev->dev, "failed to get virtual channel\n");
@@ -991,29 +1012,16 @@
 err_vc_id:
 	omap_dsi_release_vc(dssdev, td->channel);
 err_req_vc:
-	if (panel_data->use_ext_te)
-		free_irq(gpio_to_irq(panel_data->ext_te_gpio), dssdev);
-err_irq:
-	if (panel_data->use_ext_te)
-		gpio_free(panel_data->ext_te_gpio);
-err_gpio:
 	if (bldev != NULL)
 		backlight_device_unregister(bldev);
 err_bl:
-	if (gpio_is_valid(panel_data->reset_gpio))
-		gpio_free(panel_data->reset_gpio);
-err_rst_gpio:
 	destroy_workqueue(td->workqueue);
-err_wq:
-	kfree(td);
-err:
 	return r;
 }
 
 static void __exit taal_remove(struct omap_dss_device *dssdev)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
-	struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
 	struct backlight_device *bldev;
 
 	dev_dbg(&dssdev->dev, "remove\n");
@@ -1021,12 +1029,6 @@
 	sysfs_remove_group(&dssdev->dev.kobj, &taal_attr_group);
 	omap_dsi_release_vc(dssdev, td->channel);
 
-	if (panel_data->use_ext_te) {
-		int gpio = panel_data->ext_te_gpio;
-		free_irq(gpio_to_irq(gpio), dssdev);
-		gpio_free(gpio);
-	}
-
 	bldev = td->bldev;
 	if (bldev != NULL) {
 		bldev->props.power = FB_BLANK_POWERDOWN;
@@ -1040,26 +1042,31 @@
 
 	/* reset, to be sure that the panel is in a valid state */
 	taal_hw_reset(dssdev);
-
-	if (gpio_is_valid(panel_data->reset_gpio))
-		gpio_free(panel_data->reset_gpio);
-
-	kfree(td);
 }
 
 static int taal_power_on(struct omap_dss_device *dssdev)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
-	struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
 	u8 id1, id2, id3;
 	int r;
 
-	r = omapdss_dsi_configure_pins(dssdev, &panel_data->pin_config);
+	r = omapdss_dsi_configure_pins(dssdev, &td->pin_config);
 	if (r) {
 		dev_err(&dssdev->dev, "failed to configure DSI pins\n");
 		goto err0;
 	};
 
+	omapdss_dsi_set_size(dssdev, dssdev->panel.timings.x_res,
+		dssdev->panel.timings.y_res);
+	omapdss_dsi_set_pixel_format(dssdev, OMAP_DSS_DSI_FMT_RGB888);
+	omapdss_dsi_set_operation_mode(dssdev, OMAP_DSS_DSI_CMD_MODE);
+
+	r = omapdss_dsi_set_clocks(dssdev, 216000000, 10000000);
+	if (r) {
+		dev_err(&dssdev->dev, "failed to set HS and LP clocks\n");
+		goto err0;
+	}
+
 	r = omapdss_dsi_display_enable(dssdev);
 	if (r) {
 		dev_err(&dssdev->dev, "failed to enable DSI\n");
@@ -1356,7 +1363,6 @@
 				    u16 x, u16 y, u16 w, u16 h)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
-	struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
 	int r;
 
 	dev_dbg(&dssdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
@@ -1380,7 +1386,7 @@
 	if (r)
 		goto err;
 
-	if (td->te_enabled && panel_data->use_ext_te) {
+	if (td->te_enabled && gpio_is_valid(td->ext_te_gpio)) {
 		schedule_delayed_work(&td->te_timeout_work,
 				msecs_to_jiffies(250));
 		atomic_set(&td->do_update, 1);
@@ -1419,7 +1425,6 @@
 static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
-	struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
 	int r;
 
 	if (enable)
@@ -1427,7 +1432,7 @@
 	else
 		r = taal_dcs_write_0(td, MIPI_DCS_SET_TEAR_OFF);
 
-	if (!panel_data->use_ext_te)
+	if (!gpio_is_valid(td->ext_te_gpio))
 		omapdss_dsi_enable_te(dssdev, enable);
 
 	if (td->panel_config->sleep.enable_te)
@@ -1487,6 +1492,7 @@
 static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
 {
 	struct taal_data *td = dev_get_drvdata(&dssdev->dev);
+	u16 dw, dh;
 	int r;
 
 	dev_dbg(&dssdev->dev, "rotate %d\n", rotate);
@@ -1508,6 +1514,16 @@
 			goto err;
 	}
 
+	if (rotate == 0 || rotate == 2) {
+		dw = dssdev->panel.timings.x_res;
+		dh = dssdev->panel.timings.y_res;
+	} else {
+		dw = dssdev->panel.timings.y_res;
+		dh = dssdev->panel.timings.x_res;
+	}
+
+	omapdss_dsi_set_size(dssdev, dw, dh);
+
 	td->rotate = rotate;
 
 	dsi_bus_unlock(dssdev);
@@ -1726,7 +1742,6 @@
 	struct taal_data *td = container_of(work, struct taal_data,
 			esd_work.work);
 	struct omap_dss_device *dssdev = td->dssdev;
-	struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
 	u8 state1, state2;
 	int r;
 
@@ -1773,7 +1788,7 @@
 	}
 	/* Self-diagnostics result is also shown on TE GPIO line. We need
 	 * to re-enable TE after self diagnostics */
-	if (td->te_enabled && panel_data->use_ext_te) {
+	if (td->te_enabled && gpio_is_valid(td->ext_te_gpio)) {
 		r = taal_dcs_write_1(td, MIPI_DCS_SET_TEAR_ON, 0);
 		if (r)
 			goto err;
diff --git a/drivers/video/omap2/displays/panel-tfp410.c b/drivers/video/omap2/displays/panel-tfp410.c
index 40cc0cfa..383811c 100644
--- a/drivers/video/omap2/displays/panel-tfp410.c
+++ b/drivers/video/omap2/displays/panel-tfp410.c
@@ -65,6 +65,9 @@
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+	omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
@@ -116,8 +119,8 @@
 	}
 
 	if (gpio_is_valid(ddata->pd_gpio)) {
-		r = gpio_request_one(ddata->pd_gpio, GPIOF_OUT_INIT_LOW,
-				"tfp410 pd");
+		r = devm_gpio_request_one(&dssdev->dev, ddata->pd_gpio,
+				GPIOF_OUT_INIT_LOW, "tfp410 pd");
 		if (r) {
 			dev_err(&dssdev->dev, "Failed to request PD GPIO %d\n",
 					ddata->pd_gpio);
@@ -132,8 +135,7 @@
 		if (!adapter) {
 			dev_err(&dssdev->dev, "Failed to get I2C adapter, bus %d\n",
 					i2c_bus_num);
-			r = -EINVAL;
-			goto err_i2c;
+			return -EINVAL;
 		}
 
 		ddata->i2c_adapter = adapter;
@@ -142,10 +144,6 @@
 	dev_set_drvdata(&dssdev->dev, ddata);
 
 	return 0;
-err_i2c:
-	if (gpio_is_valid(ddata->pd_gpio))
-		gpio_free(ddata->pd_gpio);
-	return r;
 }
 
 static void __exit tfp410_remove(struct omap_dss_device *dssdev)
@@ -157,9 +155,6 @@
 	if (ddata->i2c_adapter)
 		i2c_put_adapter(ddata->i2c_adapter);
 
-	if (gpio_is_valid(ddata->pd_gpio))
-		gpio_free(ddata->pd_gpio);
-
 	dev_set_drvdata(&dssdev->dev, NULL);
 
 	mutex_unlock(&ddata->lock);
@@ -231,7 +226,8 @@
 	struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
 
 	mutex_lock(&ddata->lock);
-	dpi_set_timings(dssdev, timings);
+	omapdss_dpi_set_timings(dssdev, timings);
+	dssdev->panel.timings = *timings;
 	mutex_unlock(&ddata->lock);
 }
 
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index fa7baa6..b5e6dbc 100644
--- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -337,6 +337,9 @@
 	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
 
+	omapdss_dpi_set_timings(dssdev, &dssdev->panel.timings);
+	omapdss_dpi_set_data_lines(dssdev, dssdev->phy.dpi.data_lines);
+
 	r = omapdss_dpi_display_enable(dssdev);
 	if (r)
 		goto err0;
@@ -480,7 +483,9 @@
 static void tpo_td043_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
-	dpi_set_timings(dssdev, timings);
+	omapdss_dpi_set_timings(dssdev, timings);
+
+	dssdev->panel.timings = *timings;
 }
 
 static int tpo_td043_check_timings(struct omap_dss_device *dssdev,
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
index b337a84..80f5390 100644
--- a/drivers/video/omap2/dss/Kconfig
+++ b/drivers/video/omap2/dss/Kconfig
@@ -84,7 +84,7 @@
 
 config OMAP2_DSS_DSI
 	bool "DSI support"
-	depends on ARCH_OMAP3 || ARCH_OMAP4
+	depends on ARCH_OMAP3 || ARCH_OMAP4 || ARCH_OMAP5
         default n
 	help
 	  MIPI DSI (Display Serial Interface) support.
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index 5c450b0..4549869 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -1,9 +1,9 @@
 obj-$(CONFIG_OMAP2_DSS) += omapdss.o
 omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
-	manager.o overlay.o apply.o
+	manager.o manager-sysfs.o overlay.o overlay-sysfs.o output.o apply.o
 omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
 omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
-omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
+omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o
 omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
 omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
 omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o \
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 0fefc68..19d66f4 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -111,9 +111,6 @@
 	struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS];
 	struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS];
 
-	bool fifo_merge_dirty;
-	bool fifo_merge;
-
 	bool irq_enabled;
 } dss_data;
 
@@ -424,17 +421,25 @@
 int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
 {
 	unsigned long timeout = msecs_to_jiffies(500);
-	struct mgr_priv_data *mp;
+	struct mgr_priv_data *mp = get_mgr_priv(mgr);
 	u32 irq;
+	unsigned long flags;
 	int r;
 	int i;
-	struct omap_dss_device *dssdev = mgr->device;
 
-	if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
-		return 0;
+	spin_lock_irqsave(&data_lock, flags);
 
-	if (mgr_manual_update(mgr))
+	if (mgr_manual_update(mgr)) {
+		spin_unlock_irqrestore(&data_lock, flags);
 		return 0;
+	}
+
+	if (!mp->enabled) {
+		spin_unlock_irqrestore(&data_lock, flags);
+		return 0;
+	}
+
+	spin_unlock_irqrestore(&data_lock, flags);
 
 	r = dispc_runtime_get();
 	if (r)
@@ -442,10 +447,8 @@
 
 	irq = dispc_mgr_get_vsync_irq(mgr->id);
 
-	mp = get_mgr_priv(mgr);
 	i = 0;
 	while (1) {
-		unsigned long flags;
 		bool shadow_dirty, dirty;
 
 		spin_lock_irqsave(&data_lock, flags);
@@ -489,21 +492,30 @@
 {
 	unsigned long timeout = msecs_to_jiffies(500);
 	struct ovl_priv_data *op;
-	struct omap_dss_device *dssdev;
+	struct mgr_priv_data *mp;
 	u32 irq;
+	unsigned long flags;
 	int r;
 	int i;
 
 	if (!ovl->manager)
 		return 0;
 
-	dssdev = ovl->manager->device;
+	mp = get_mgr_priv(ovl->manager);
 
-	if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
-		return 0;
+	spin_lock_irqsave(&data_lock, flags);
 
-	if (ovl_manual_update(ovl))
+	if (ovl_manual_update(ovl)) {
+		spin_unlock_irqrestore(&data_lock, flags);
 		return 0;
+	}
+
+	if (!mp->enabled) {
+		spin_unlock_irqrestore(&data_lock, flags);
+		return 0;
+	}
+
+	spin_unlock_irqrestore(&data_lock, flags);
 
 	r = dispc_runtime_get();
 	if (r)
@@ -514,7 +526,6 @@
 	op = get_ovl_priv(ovl);
 	i = 0;
 	while (1) {
-		unsigned long flags;
 		bool shadow_dirty, dirty;
 
 		spin_lock_irqsave(&data_lock, flags);
@@ -573,7 +584,7 @@
 
 	replication = dss_ovl_use_replication(mp->lcd_config, oi->color_mode);
 
-	r = dispc_ovl_setup(ovl->id, oi, replication, &mp->timings);
+	r = dispc_ovl_setup(ovl->id, oi, replication, &mp->timings, false);
 	if (r) {
 		/*
 		 * We can't do much here, as this function can be called from
@@ -677,40 +688,11 @@
 		mp->shadow_extra_info_dirty = true;
 }
 
-static void dss_write_regs_common(void)
-{
-	const int num_mgrs = omap_dss_get_num_overlay_managers();
-	int i;
-
-	if (!dss_data.fifo_merge_dirty)
-		return;
-
-	for (i = 0; i < num_mgrs; ++i) {
-		struct omap_overlay_manager *mgr;
-		struct mgr_priv_data *mp;
-
-		mgr = omap_dss_get_overlay_manager(i);
-		mp = get_mgr_priv(mgr);
-
-		if (mp->enabled) {
-			if (dss_data.fifo_merge_dirty) {
-				dispc_enable_fifomerge(dss_data.fifo_merge);
-				dss_data.fifo_merge_dirty = false;
-			}
-
-			if (mp->updating)
-				mp->shadow_info_dirty = true;
-		}
-	}
-}
-
 static void dss_write_regs(void)
 {
 	const int num_mgrs = omap_dss_get_num_overlay_managers();
 	int i;
 
-	dss_write_regs_common();
-
 	for (i = 0; i < num_mgrs; ++i) {
 		struct omap_overlay_manager *mgr;
 		struct mgr_priv_data *mp;
@@ -799,8 +781,6 @@
 	dss_mgr_write_regs(mgr);
 	dss_mgr_write_regs_extra(mgr);
 
-	dss_write_regs_common();
-
 	mp->updating = true;
 
 	if (!dss_data.irq_enabled && need_isr())
@@ -984,20 +964,11 @@
 	op->extra_info_dirty = true;
 }
 
-static void dss_apply_fifo_merge(bool use_fifo_merge)
-{
-	if (dss_data.fifo_merge == use_fifo_merge)
-		return;
-
-	dss_data.fifo_merge = use_fifo_merge;
-	dss_data.fifo_merge_dirty = true;
-}
-
-static void dss_ovl_setup_fifo(struct omap_overlay *ovl,
-		bool use_fifo_merge)
+static void dss_ovl_setup_fifo(struct omap_overlay *ovl)
 {
 	struct ovl_priv_data *op = get_ovl_priv(ovl);
 	u32 fifo_low, fifo_high;
+	bool use_fifo_merge = false;
 
 	if (!op->enabled && !op->enabling)
 		return;
@@ -1008,8 +979,7 @@
 	dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high);
 }
 
-static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr,
-		bool use_fifo_merge)
+static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr)
 {
 	struct omap_overlay *ovl;
 	struct mgr_priv_data *mp;
@@ -1020,10 +990,10 @@
 		return;
 
 	list_for_each_entry(ovl, &mgr->overlays, list)
-		dss_ovl_setup_fifo(ovl, use_fifo_merge);
+		dss_ovl_setup_fifo(ovl);
 }
 
-static void dss_setup_fifos(bool use_fifo_merge)
+static void dss_setup_fifos(void)
 {
 	const int num_mgrs = omap_dss_get_num_overlay_managers();
 	struct omap_overlay_manager *mgr;
@@ -1031,91 +1001,15 @@
 
 	for (i = 0; i < num_mgrs; ++i) {
 		mgr = omap_dss_get_overlay_manager(i);
-		dss_mgr_setup_fifos(mgr, use_fifo_merge);
+		dss_mgr_setup_fifos(mgr);
 	}
 }
 
-static int get_num_used_managers(void)
-{
-	const int num_mgrs = omap_dss_get_num_overlay_managers();
-	struct omap_overlay_manager *mgr;
-	struct mgr_priv_data *mp;
-	int i;
-	int enabled_mgrs;
-
-	enabled_mgrs = 0;
-
-	for (i = 0; i < num_mgrs; ++i) {
-		mgr = omap_dss_get_overlay_manager(i);
-		mp = get_mgr_priv(mgr);
-
-		if (!mp->enabled)
-			continue;
-
-		enabled_mgrs++;
-	}
-
-	return enabled_mgrs;
-}
-
-static int get_num_used_overlays(void)
-{
-	const int num_ovls = omap_dss_get_num_overlays();
-	struct omap_overlay *ovl;
-	struct ovl_priv_data *op;
-	struct mgr_priv_data *mp;
-	int i;
-	int enabled_ovls;
-
-	enabled_ovls = 0;
-
-	for (i = 0; i < num_ovls; ++i) {
-		ovl = omap_dss_get_overlay(i);
-		op = get_ovl_priv(ovl);
-
-		if (!op->enabled && !op->enabling)
-			continue;
-
-		mp = get_mgr_priv(ovl->manager);
-
-		if (!mp->enabled)
-			continue;
-
-		enabled_ovls++;
-	}
-
-	return enabled_ovls;
-}
-
-static bool get_use_fifo_merge(void)
-{
-	int enabled_mgrs = get_num_used_managers();
-	int enabled_ovls = get_num_used_overlays();
-
-	if (!dss_has_feature(FEAT_FIFO_MERGE))
-		return false;
-
-	/*
-	 * In theory the only requirement for fifomerge is enabled_ovls <= 1.
-	 * However, if we have two managers enabled and set/unset the fifomerge,
-	 * we need to set the GO bits in particular sequence for the managers,
-	 * and wait in between.
-	 *
-	 * This is rather difficult as new apply calls can happen at any time,
-	 * so we simplify the problem by requiring also that enabled_mgrs <= 1.
-	 * In practice this shouldn't matter, because when only one overlay is
-	 * enabled, most likely only one output is enabled.
-	 */
-
-	return enabled_mgrs <= 1 && enabled_ovls <= 1;
-}
-
 int dss_mgr_enable(struct omap_overlay_manager *mgr)
 {
 	struct mgr_priv_data *mp = get_mgr_priv(mgr);
 	unsigned long flags;
 	int r;
-	bool fifo_merge;
 
 	mutex_lock(&apply_lock);
 
@@ -1133,23 +1027,11 @@
 		goto err;
 	}
 
-	/* step 1: setup fifos/fifomerge before enabling the manager */
-
-	fifo_merge = get_use_fifo_merge();
-	dss_setup_fifos(fifo_merge);
-	dss_apply_fifo_merge(fifo_merge);
+	dss_setup_fifos();
 
 	dss_write_regs();
 	dss_set_go_bits();
 
-	spin_unlock_irqrestore(&data_lock, flags);
-
-	/* wait until fifo config is in */
-	wait_pending_extra_info_updates();
-
-	/* step 2: enable the manager */
-	spin_lock_irqsave(&data_lock, flags);
-
 	if (!mgr_manual_update(mgr))
 		mp->updating = true;
 
@@ -1174,7 +1056,6 @@
 {
 	struct mgr_priv_data *mp = get_mgr_priv(mgr);
 	unsigned long flags;
-	bool fifo_merge;
 
 	mutex_lock(&apply_lock);
 
@@ -1189,16 +1070,8 @@
 	mp->updating = false;
 	mp->enabled = false;
 
-	fifo_merge = get_use_fifo_merge();
-	dss_setup_fifos(fifo_merge);
-	dss_apply_fifo_merge(fifo_merge);
-
-	dss_write_regs();
-	dss_set_go_bits();
-
 	spin_unlock_irqrestore(&data_lock, flags);
 
-	wait_pending_extra_info_updates();
 out:
 	mutex_unlock(&apply_lock);
 }
@@ -1237,29 +1110,29 @@
 	spin_unlock_irqrestore(&data_lock, flags);
 }
 
-int dss_mgr_set_device(struct omap_overlay_manager *mgr,
-		struct omap_dss_device *dssdev)
+int dss_mgr_set_output(struct omap_overlay_manager *mgr,
+		struct omap_dss_output *output)
 {
 	int r;
 
 	mutex_lock(&apply_lock);
 
-	if (dssdev->manager) {
-		DSSERR("display '%s' already has a manager '%s'\n",
-			       dssdev->name, dssdev->manager->name);
+	if (mgr->output) {
+		DSSERR("manager %s is already connected to an output\n",
+			mgr->name);
 		r = -EINVAL;
 		goto err;
 	}
 
-	if ((mgr->supported_displays & dssdev->type) == 0) {
-		DSSERR("display '%s' does not support manager '%s'\n",
-			       dssdev->name, mgr->name);
+	if ((mgr->supported_outputs & output->id) == 0) {
+		DSSERR("output does not support manager %s\n",
+			mgr->name);
 		r = -EINVAL;
 		goto err;
 	}
 
-	dssdev->manager = mgr;
-	mgr->device = dssdev;
+	output->manager = mgr;
+	mgr->output = output;
 
 	mutex_unlock(&apply_lock);
 
@@ -1269,40 +1142,46 @@
 	return r;
 }
 
-int dss_mgr_unset_device(struct omap_overlay_manager *mgr)
+int dss_mgr_unset_output(struct omap_overlay_manager *mgr)
 {
 	int r;
+	struct mgr_priv_data *mp = get_mgr_priv(mgr);
+	unsigned long flags;
 
 	mutex_lock(&apply_lock);
 
-	if (!mgr->device) {
-		DSSERR("failed to unset display, display not set.\n");
+	if (!mgr->output) {
+		DSSERR("failed to unset output, output not set\n");
 		r = -EINVAL;
 		goto err;
 	}
 
-	/*
-	 * Don't allow currently enabled displays to have the overlay manager
-	 * pulled out from underneath them
-	 */
-	if (mgr->device->state != OMAP_DSS_DISPLAY_DISABLED) {
+	spin_lock_irqsave(&data_lock, flags);
+
+	if (mp->enabled) {
+		DSSERR("output can't be unset when manager is enabled\n");
 		r = -EINVAL;
-		goto err;
+		goto err1;
 	}
 
-	mgr->device->manager = NULL;
-	mgr->device = NULL;
+	spin_unlock_irqrestore(&data_lock, flags);
+
+	mgr->output->manager = NULL;
+	mgr->output = NULL;
 
 	mutex_unlock(&apply_lock);
 
 	return 0;
+err1:
+	spin_unlock_irqrestore(&data_lock, flags);
 err:
 	mutex_unlock(&apply_lock);
+
 	return r;
 }
 
 static void dss_apply_mgr_timings(struct omap_overlay_manager *mgr,
-		struct omap_video_timings *timings)
+		const struct omap_video_timings *timings)
 {
 	struct mgr_priv_data *mp = get_mgr_priv(mgr);
 
@@ -1311,24 +1190,22 @@
 }
 
 void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
-		struct omap_video_timings *timings)
+		const struct omap_video_timings *timings)
 {
 	unsigned long flags;
-
-	mutex_lock(&apply_lock);
+	struct mgr_priv_data *mp = get_mgr_priv(mgr);
 
 	spin_lock_irqsave(&data_lock, flags);
 
+	if (mp->updating) {
+		DSSERR("cannot set timings for %s: manager needs to be disabled\n",
+			mgr->name);
+		goto out;
+	}
+
 	dss_apply_mgr_timings(mgr, timings);
-
-	dss_write_regs();
-	dss_set_go_bits();
-
+out:
 	spin_unlock_irqrestore(&data_lock, flags);
-
-	wait_pending_extra_info_updates();
-
-	mutex_unlock(&apply_lock);
 }
 
 static void dss_apply_mgr_lcd_config(struct omap_overlay_manager *mgr,
@@ -1346,7 +1223,7 @@
 	unsigned long flags;
 	struct mgr_priv_data *mp = get_mgr_priv(mgr);
 
-	mutex_lock(&apply_lock);
+	spin_lock_irqsave(&data_lock, flags);
 
 	if (mp->enabled) {
 		DSSERR("cannot apply lcd config for %s: manager needs to be disabled\n",
@@ -1354,19 +1231,9 @@
 		goto out;
 	}
 
-	spin_lock_irqsave(&data_lock, flags);
-
 	dss_apply_mgr_lcd_config(mgr, config);
-
-	dss_write_regs();
-	dss_set_go_bits();
-
-	spin_unlock_irqrestore(&data_lock, flags);
-
-	wait_pending_extra_info_updates();
-
 out:
-	mutex_unlock(&apply_lock);
+	spin_unlock_irqrestore(&data_lock, flags);
 }
 
 int dss_ovl_set_info(struct omap_overlay *ovl,
@@ -1483,6 +1350,13 @@
 		goto err;
 	}
 
+	spin_unlock_irqrestore(&data_lock, flags);
+
+	/* wait for pending extra_info updates to ensure the ovl is disabled */
+	wait_pending_extra_info_updates();
+
+	spin_lock_irqsave(&data_lock, flags);
+
 	op->channel = -1;
 
 	ovl->manager = NULL;
@@ -1517,7 +1391,6 @@
 {
 	struct ovl_priv_data *op = get_ovl_priv(ovl);
 	unsigned long flags;
-	bool fifo_merge;
 	int r;
 
 	mutex_lock(&apply_lock);
@@ -1527,7 +1400,7 @@
 		goto err1;
 	}
 
-	if (ovl->manager == NULL || ovl->manager->device == NULL) {
+	if (ovl->manager == NULL || ovl->manager->output == NULL) {
 		r = -EINVAL;
 		goto err1;
 	}
@@ -1543,22 +1416,7 @@
 		goto err2;
 	}
 
-	/* step 1: configure fifos/fifomerge for currently enabled ovls */
-
-	fifo_merge = get_use_fifo_merge();
-	dss_setup_fifos(fifo_merge);
-	dss_apply_fifo_merge(fifo_merge);
-
-	dss_write_regs();
-	dss_set_go_bits();
-
-	spin_unlock_irqrestore(&data_lock, flags);
-
-	/* wait for fifo configs to go in */
-	wait_pending_extra_info_updates();
-
-	/* step 2: enable the overlay */
-	spin_lock_irqsave(&data_lock, flags);
+	dss_setup_fifos();
 
 	op->enabling = false;
 	dss_apply_ovl_enable(ovl, true);
@@ -1568,9 +1426,6 @@
 
 	spin_unlock_irqrestore(&data_lock, flags);
 
-	/* wait for overlay to be enabled */
-	wait_pending_extra_info_updates();
-
 	mutex_unlock(&apply_lock);
 
 	return 0;
@@ -1586,7 +1441,6 @@
 {
 	struct ovl_priv_data *op = get_ovl_priv(ovl);
 	unsigned long flags;
-	bool fifo_merge;
 	int r;
 
 	mutex_lock(&apply_lock);
@@ -1596,39 +1450,19 @@
 		goto err;
 	}
 
-	if (ovl->manager == NULL || ovl->manager->device == NULL) {
+	if (ovl->manager == NULL || ovl->manager->output == NULL) {
 		r = -EINVAL;
 		goto err;
 	}
 
-	/* step 1: disable the overlay */
 	spin_lock_irqsave(&data_lock, flags);
 
 	dss_apply_ovl_enable(ovl, false);
-
 	dss_write_regs();
 	dss_set_go_bits();
 
 	spin_unlock_irqrestore(&data_lock, flags);
 
-	/* wait for the overlay to be disabled */
-	wait_pending_extra_info_updates();
-
-	/* step 2: configure fifos/fifomerge */
-	spin_lock_irqsave(&data_lock, flags);
-
-	fifo_merge = get_use_fifo_merge();
-	dss_setup_fifos(fifo_merge);
-	dss_apply_fifo_merge(fifo_merge);
-
-	dss_write_regs();
-	dss_set_go_bits();
-
-	spin_unlock_irqrestore(&data_lock, flags);
-
-	/* wait for fifo config to go in */
-	wait_pending_extra_info_updates();
-
 	mutex_unlock(&apply_lock);
 
 	return 0;
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 58bd9c2..b2af72d 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -33,6 +33,7 @@
 #include <linux/device.h>
 #include <linux/regulator/consumer.h>
 #include <linux/suspend.h>
+#include <linux/slab.h>
 
 #include <video/omapdss.h>
 
@@ -57,6 +58,11 @@
 module_param_named(debug, dss_debug, bool, 0644);
 #endif
 
+const char *dss_get_default_display_name(void)
+{
+	return core.default_display_name;
+}
+
 /* REGULATORS */
 
 struct regulator *dss_get_vdds_dsi(void)
@@ -347,17 +353,14 @@
 	int r;
 	struct omap_dss_driver *dssdrv = to_dss_driver(dev->driver);
 	struct omap_dss_device *dssdev = to_dss_device(dev);
-	bool force;
 
 	DSSDBG("driver_probe: dev %s/%s, drv %s\n",
 				dev_name(dev), dssdev->driver_name,
 				dssdrv->driver.name);
 
-	dss_init_device(core.pdev, dssdev);
-
-	force = core.default_display_name &&
-		strcmp(core.default_display_name, dssdev->name) == 0;
-	dss_recheck_connections(dssdev, force);
+	r = dss_init_device(core.pdev, dssdev);
+	if (r)
+		return r;
 
 	r = dssdrv->probe(dssdev);
 
@@ -416,54 +419,44 @@
 EXPORT_SYMBOL(omap_dss_unregister_driver);
 
 /* DEVICE */
-static void reset_device(struct device *dev, int check)
-{
-	u8 *dev_p = (u8 *)dev;
-	u8 *dev_end = dev_p + sizeof(*dev);
-	void *saved_pdata;
-
-	saved_pdata = dev->platform_data;
-	if (check) {
-		/*
-		 * Check if there is any other setting than platform_data
-		 * in struct device; warn that these will be reset by our
-		 * init.
-		 */
-		dev->platform_data = NULL;
-		while (dev_p < dev_end) {
-			if (*dev_p) {
-				WARN("%s: struct device fields will be "
-						"discarded\n",
-				     __func__);
-				break;
-			}
-			dev_p++;
-		}
-	}
-	memset(dev, 0, sizeof(*dev));
-	dev->platform_data = saved_pdata;
-}
-
 
 static void omap_dss_dev_release(struct device *dev)
 {
-	reset_device(dev, 0);
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	kfree(dssdev);
 }
 
-int omap_dss_register_device(struct omap_dss_device *dssdev,
-		struct device *parent, int disp_num)
-{
-	WARN_ON(!dssdev->driver_name);
+static int disp_num_counter;
 
-	reset_device(&dssdev->dev, 1);
+struct omap_dss_device *dss_alloc_and_init_device(struct device *parent)
+{
+	struct omap_dss_device *dssdev;
+
+	dssdev = kzalloc(sizeof(*dssdev), GFP_KERNEL);
+	if (!dssdev)
+		return NULL;
+
 	dssdev->dev.bus = &dss_bus_type;
 	dssdev->dev.parent = parent;
 	dssdev->dev.release = omap_dss_dev_release;
-	dev_set_name(&dssdev->dev, "display%d", disp_num);
-	return device_register(&dssdev->dev);
+	dev_set_name(&dssdev->dev, "display%d", disp_num_counter++);
+
+	device_initialize(&dssdev->dev);
+
+	return dssdev;
 }
 
-void omap_dss_unregister_device(struct omap_dss_device *dssdev)
+int dss_add_device(struct omap_dss_device *dssdev)
+{
+	return device_add(&dssdev->dev);
+}
+
+void dss_put_device(struct omap_dss_device *dssdev)
+{
+	put_device(&dssdev->dev);
+}
+
+void dss_unregister_device(struct omap_dss_device *dssdev)
 {
 	device_unregister(&dssdev->dev);
 }
@@ -471,15 +464,25 @@
 static int dss_unregister_dss_dev(struct device *dev, void *data)
 {
 	struct omap_dss_device *dssdev = to_dss_device(dev);
-	omap_dss_unregister_device(dssdev);
+	dss_unregister_device(dssdev);
 	return 0;
 }
 
-void omap_dss_unregister_child_devices(struct device *parent)
+void dss_unregister_child_devices(struct device *parent)
 {
 	device_for_each_child(parent, NULL, dss_unregister_dss_dev);
 }
 
+void dss_copy_device_pdata(struct omap_dss_device *dst,
+		const struct omap_dss_device *src)
+{
+	u8 *d = (u8 *)dst;
+	u8 *s = (u8 *)src;
+	size_t dsize = sizeof(struct device);
+
+	memcpy(d + dsize, s + dsize, sizeof(struct omap_dss_device) - dsize);
+}
+
 /* BUS */
 static int __init omap_dss_bus_register(void)
 {
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index ee9e296..b43477a 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -38,7 +38,6 @@
 #include <linux/pm_runtime.h>
 
 #include <plat/cpu.h>
-#include <plat/clock.h>
 
 #include <video/omapdss.h>
 
@@ -82,6 +81,30 @@
 	unsigned irqs[32];
 };
 
+struct dispc_features {
+	u8 sw_start;
+	u8 fp_start;
+	u8 bp_start;
+	u16 sw_max;
+	u16 vp_max;
+	u16 hp_max;
+	int (*calc_scaling) (enum omap_plane plane,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk, bool mem_to_mem);
+	unsigned long (*calc_core_clk) (enum omap_plane plane,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		bool mem_to_mem);
+	u8 num_fifos;
+
+	/* swap GFX & WB fifos */
+	bool gfx_fifo_workaround:1;
+};
+
+#define DISPC_MAX_NR_FIFOS 5
+
 static struct {
 	struct platform_device *pdev;
 	void __iomem    *base;
@@ -91,7 +114,9 @@
 	int irq;
 	struct clk *dss_clk;
 
-	u32	fifo_size[MAX_DSS_OVERLAYS];
+	u32 fifo_size[DISPC_MAX_NR_FIFOS];
+	/* maps which plane is using a fifo. fifo-id -> plane-id */
+	int fifo_assignment[DISPC_MAX_NR_FIFOS];
 
 	spinlock_t irq_lock;
 	u32 irq_error_mask;
@@ -102,6 +127,8 @@
 	bool		ctx_valid;
 	u32		ctx[DISPC_SZ_REGS / sizeof(u32)];
 
+	const struct dispc_features *feat;
+
 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
 	spinlock_t irq_stats_lock;
 	struct dispc_irq_stats irq_stats;
@@ -211,7 +238,14 @@
 	},
 };
 
+struct color_conv_coef {
+	int ry, rcr, rcb, gy, gcr, gcb, by, bcr, bcb;
+	int full_range;
+};
+
 static void _omap_dispc_set_irqs(void);
+static unsigned long dispc_plane_pclk_rate(enum omap_plane plane);
+static unsigned long dispc_plane_lclk_rate(enum omap_plane plane);
 
 static inline void dispc_write_reg(const u16 idx, u32 val)
 {
@@ -509,6 +543,11 @@
 	return mgr_desc[channel].framedone_irq;
 }
 
+u32 dispc_wb_get_framedone_irq(void)
+{
+	return DISPC_IRQ_FRAMEDONEWB;
+}
+
 bool dispc_mgr_go_busy(enum omap_channel channel)
 {
 	return mgr_fld_read(channel, DISPC_MGR_FLD_GO) == 1;
@@ -536,6 +575,30 @@
 	mgr_fld_write(channel, DISPC_MGR_FLD_GO, 1);
 }
 
+bool dispc_wb_go_busy(void)
+{
+	return REG_GET(DISPC_CONTROL2, 6, 6) == 1;
+}
+
+void dispc_wb_go(void)
+{
+	enum omap_plane plane = OMAP_DSS_WB;
+	bool enable, go;
+
+	enable = REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0) == 1;
+
+	if (!enable)
+		return;
+
+	go = REG_GET(DISPC_CONTROL2, 6, 6) == 1;
+	if (go) {
+		DSSERR("GO bit not down for WB\n");
+		return;
+	}
+
+	REG_FLD_MOD(DISPC_CONTROL2, 1, 6, 6);
+}
+
 static void dispc_ovl_write_firh_reg(enum omap_plane plane, int reg, u32 value)
 {
 	dispc_write_reg(DISPC_OVL_FIR_COEF_H(plane, reg), value);
@@ -618,41 +681,41 @@
 	}
 }
 
-static void _dispc_setup_color_conv_coef(void)
+
+static void dispc_ovl_write_color_conv_coef(enum omap_plane plane,
+		const struct color_conv_coef *ct)
 {
-	int i;
-	const struct color_conv_coef {
-		int  ry,  rcr,  rcb,   gy,  gcr,  gcb,   by,  bcr,  bcb;
-		int  full_range;
-	}  ctbl_bt601_5 = {
-		298,  409,    0,  298, -208, -100,  298,    0,  517, 0,
-	};
-
-	const struct color_conv_coef *ct;
-
 #define CVAL(x, y) (FLD_VAL(x, 26, 16) | FLD_VAL(y, 10, 0))
 
-	ct = &ctbl_bt601_5;
+	dispc_write_reg(DISPC_OVL_CONV_COEF(plane, 0), CVAL(ct->rcr, ct->ry));
+	dispc_write_reg(DISPC_OVL_CONV_COEF(plane, 1), CVAL(ct->gy,  ct->rcb));
+	dispc_write_reg(DISPC_OVL_CONV_COEF(plane, 2), CVAL(ct->gcb, ct->gcr));
+	dispc_write_reg(DISPC_OVL_CONV_COEF(plane, 3), CVAL(ct->bcr, ct->by));
+	dispc_write_reg(DISPC_OVL_CONV_COEF(plane, 4), CVAL(0, ct->bcb));
 
-	for (i = 1; i < dss_feat_get_num_ovls(); i++) {
-		dispc_write_reg(DISPC_OVL_CONV_COEF(i, 0),
-			CVAL(ct->rcr, ct->ry));
-		dispc_write_reg(DISPC_OVL_CONV_COEF(i, 1),
-			CVAL(ct->gy,  ct->rcb));
-		dispc_write_reg(DISPC_OVL_CONV_COEF(i, 2),
-			CVAL(ct->gcb, ct->gcr));
-		dispc_write_reg(DISPC_OVL_CONV_COEF(i, 3),
-			CVAL(ct->bcr, ct->by));
-		dispc_write_reg(DISPC_OVL_CONV_COEF(i, 4),
-			CVAL(0, ct->bcb));
-
-		REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), ct->full_range,
-			11, 11);
-	}
+	REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), ct->full_range, 11, 11);
 
 #undef CVAL
 }
 
+static void dispc_setup_color_conv_coef(void)
+{
+	int i;
+	int num_ovl = dss_feat_get_num_ovls();
+	int num_wb = dss_feat_get_num_wbs();
+	const struct color_conv_coef ctbl_bt601_5_ovl = {
+		298, 409, 0, 298, -208, -100, 298, 0, 517, 0,
+	};
+	const struct color_conv_coef ctbl_bt601_5_wb = {
+		66, 112, -38, 129, -94, -74, 25, -18, 112, 0,
+	};
+
+	for (i = 1; i < num_ovl; i++)
+		dispc_ovl_write_color_conv_coef(i, &ctbl_bt601_5_ovl);
+
+	for (; i < num_wb; i++)
+		dispc_ovl_write_color_conv_coef(i, &ctbl_bt601_5_wb);
+}
 
 static void dispc_ovl_set_ba0(enum omap_plane plane, u32 paddr)
 {
@@ -674,24 +737,32 @@
 	dispc_write_reg(DISPC_OVL_BA1_UV(plane), paddr);
 }
 
-static void dispc_ovl_set_pos(enum omap_plane plane, int x, int y)
+static void dispc_ovl_set_pos(enum omap_plane plane,
+		enum omap_overlay_caps caps, int x, int y)
 {
-	u32 val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0);
+	u32 val;
+
+	if ((caps & OMAP_DSS_OVL_CAP_POS) == 0)
+		return;
+
+	val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0);
 
 	dispc_write_reg(DISPC_OVL_POSITION(plane), val);
 }
 
-static void dispc_ovl_set_pic_size(enum omap_plane plane, int width, int height)
+static void dispc_ovl_set_input_size(enum omap_plane plane, int width,
+		int height)
 {
 	u32 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
 
-	if (plane == OMAP_DSS_GFX)
+	if (plane == OMAP_DSS_GFX || plane == OMAP_DSS_WB)
 		dispc_write_reg(DISPC_OVL_SIZE(plane), val);
 	else
 		dispc_write_reg(DISPC_OVL_PICTURE_SIZE(plane), val);
 }
 
-static void dispc_ovl_set_vid_size(enum omap_plane plane, int width, int height)
+static void dispc_ovl_set_output_size(enum omap_plane plane, int width,
+		int height)
 {
 	u32 val;
 
@@ -699,14 +770,16 @@
 
 	val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
 
-	dispc_write_reg(DISPC_OVL_SIZE(plane), val);
+	if (plane == OMAP_DSS_WB)
+		dispc_write_reg(DISPC_OVL_PICTURE_SIZE(plane), val);
+	else
+		dispc_write_reg(DISPC_OVL_SIZE(plane), val);
 }
 
-static void dispc_ovl_set_zorder(enum omap_plane plane, u8 zorder)
+static void dispc_ovl_set_zorder(enum omap_plane plane,
+		enum omap_overlay_caps caps, u8 zorder)
 {
-	struct omap_overlay *ovl = omap_dss_get_overlay(plane);
-
-	if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
+	if ((caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
 		return;
 
 	REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), zorder, 27, 26);
@@ -723,23 +796,22 @@
 		REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), 1, 25, 25);
 }
 
-static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane, bool enable)
+static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane,
+		enum omap_overlay_caps caps, bool enable)
 {
-	struct omap_overlay *ovl = omap_dss_get_overlay(plane);
-
-	if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0)
+	if ((caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0)
 		return;
 
 	REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 28, 28);
 }
 
-static void dispc_ovl_setup_global_alpha(enum omap_plane plane, u8 global_alpha)
+static void dispc_ovl_setup_global_alpha(enum omap_plane plane,
+		enum omap_overlay_caps caps, u8 global_alpha)
 {
 	static const unsigned shifts[] = { 0, 8, 16, 24, };
 	int shift;
-	struct omap_overlay *ovl = omap_dss_get_overlay(plane);
 
-	if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
+	if ((caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
 		return;
 
 	shift = shifts[plane];
@@ -947,10 +1019,17 @@
 	return channel;
 }
 
+void dispc_wb_set_channel_in(enum dss_writeback_channel channel)
+{
+	enum omap_plane plane = OMAP_DSS_WB;
+
+	REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), channel, 18, 16);
+}
+
 static void dispc_ovl_set_burst_size(enum omap_plane plane,
 		enum omap_burst_size burst_size)
 {
-	static const unsigned shifts[] = { 6, 14, 14, 14, };
+	static const unsigned shifts[] = { 6, 14, 14, 14, 14, };
 	int shift;
 
 	shift = shifts[plane];
@@ -1027,11 +1106,15 @@
 	dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val);
 }
 
-static void dispc_ovl_enable_replication(enum omap_plane plane, bool enable)
+static void dispc_ovl_enable_replication(enum omap_plane plane,
+		enum omap_overlay_caps caps, bool enable)
 {
 	static const unsigned shifts[] = { 5, 10, 10, 10 };
 	int shift;
 
+	if ((caps & OMAP_DSS_OVL_CAP_REPLICATION) == 0)
+		return;
+
 	shift = shifts[plane];
 	REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, shift, shift);
 }
@@ -1045,10 +1128,10 @@
 	dispc_write_reg(DISPC_SIZE_MGR(channel), val);
 }
 
-static void dispc_read_plane_fifo_sizes(void)
+static void dispc_init_fifos(void)
 {
 	u32 size;
-	int plane;
+	int fifo;
 	u8 start, end;
 	u32 unit;
 
@@ -1056,16 +1139,53 @@
 
 	dss_feat_get_reg_field(FEAT_REG_FIFOSIZE, &start, &end);
 
-	for (plane = 0; plane < dss_feat_get_num_ovls(); ++plane) {
-		size = REG_GET(DISPC_OVL_FIFO_SIZE_STATUS(plane), start, end);
+	for (fifo = 0; fifo < dispc.feat->num_fifos; ++fifo) {
+		size = REG_GET(DISPC_OVL_FIFO_SIZE_STATUS(fifo), start, end);
 		size *= unit;
-		dispc.fifo_size[plane] = size;
+		dispc.fifo_size[fifo] = size;
+
+		/*
+		 * By default fifos are mapped directly to overlays, fifo 0 to
+		 * ovl 0, fifo 1 to ovl 1, etc.
+		 */
+		dispc.fifo_assignment[fifo] = fifo;
+	}
+
+	/*
+	 * The GFX fifo on OMAP4 is smaller than the other fifos. The small fifo
+	 * causes problems with certain use cases, like using the tiler in 2D
+	 * mode. The below hack swaps the fifos of GFX and WB planes, thus
+	 * giving GFX plane a larger fifo. WB but should work fine with a
+	 * smaller fifo.
+	 */
+	if (dispc.feat->gfx_fifo_workaround) {
+		u32 v;
+
+		v = dispc_read_reg(DISPC_GLOBAL_BUFFER);
+
+		v = FLD_MOD(v, 4, 2, 0); /* GFX BUF top to WB */
+		v = FLD_MOD(v, 4, 5, 3); /* GFX BUF bottom to WB */
+		v = FLD_MOD(v, 0, 26, 24); /* WB BUF top to GFX */
+		v = FLD_MOD(v, 0, 29, 27); /* WB BUF bottom to GFX */
+
+		dispc_write_reg(DISPC_GLOBAL_BUFFER, v);
+
+		dispc.fifo_assignment[OMAP_DSS_GFX] = OMAP_DSS_WB;
+		dispc.fifo_assignment[OMAP_DSS_WB] = OMAP_DSS_GFX;
 	}
 }
 
 static u32 dispc_ovl_get_fifo_size(enum omap_plane plane)
 {
-	return dispc.fifo_size[plane];
+	int fifo;
+	u32 size = 0;
+
+	for (fifo = 0; fifo < dispc.feat->num_fifos; ++fifo) {
+		if (dispc.fifo_assignment[fifo] == plane)
+			size += dispc.fifo_size[fifo];
+	}
+
+	return size;
 }
 
 void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
@@ -1141,6 +1261,14 @@
 	if (manual_update && dss_has_feature(FEAT_OMAP3_DSI_FIFO_BUG)) {
 		*fifo_low = ovl_fifo_size - burst_size * 2;
 		*fifo_high = total_fifo_size - burst_size;
+	} else if (plane == OMAP_DSS_WB) {
+		/*
+		 * Most optimal configuration for writeback is to push out data
+		 * to the interconnect the moment writeback pushes enough pixels
+		 * in the FIFO to form a burst
+		 */
+		*fifo_low = 0;
+		*fifo_high = burst_size;
 	} else {
 		*fifo_low = ovl_fifo_size - burst_size;
 		*fifo_high = total_fifo_size - buf_unit;
@@ -1383,6 +1511,7 @@
 {
 	int scale_x = out_width != orig_width;
 	int scale_y = out_height != orig_height;
+	bool chroma_upscale = plane != OMAP_DSS_WB ? true : false;
 
 	if (!dss_has_feature(FEAT_HANDLE_UV_SEPARATE))
 		return;
@@ -1390,7 +1519,8 @@
 			color_mode != OMAP_DSS_COLOR_UYVY &&
 			color_mode != OMAP_DSS_COLOR_NV12)) {
 		/* reset chroma resampling for RGB formats  */
-		REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), 0, 8, 8);
+		if (plane != OMAP_DSS_WB)
+			REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), 0, 8, 8);
 		return;
 	}
 
@@ -1399,23 +1529,34 @@
 
 	switch (color_mode) {
 	case OMAP_DSS_COLOR_NV12:
-		/* UV is subsampled by 2 vertically*/
-		orig_height >>= 1;
-		/* UV is subsampled by 2 horz.*/
-		orig_width >>= 1;
+		if (chroma_upscale) {
+			/* UV is subsampled by 2 horizontally and vertically */
+			orig_height >>= 1;
+			orig_width >>= 1;
+		} else {
+			/* UV is downsampled by 2 horizontally and vertically */
+			orig_height <<= 1;
+			orig_width <<= 1;
+		}
+
 		break;
 	case OMAP_DSS_COLOR_YUV2:
 	case OMAP_DSS_COLOR_UYVY:
-		/*For YUV422 with 90/270 rotation,
-		 *we don't upsample chroma
-		 */
+		/* For YUV422 with 90/270 rotation, we don't upsample chroma */
 		if (rotation == OMAP_DSS_ROT_0 ||
-			rotation == OMAP_DSS_ROT_180)
-			/* UV is subsampled by 2 hrz*/
-			orig_width >>= 1;
+				rotation == OMAP_DSS_ROT_180) {
+			if (chroma_upscale)
+				/* UV is subsampled by 2 horizontally */
+				orig_width >>= 1;
+			else
+				/* UV is downsampled by 2 horizontally */
+				orig_width <<= 1;
+		}
+
 		/* must use FIR for YUV422 if rotated */
 		if (rotation != OMAP_DSS_ROT_0)
 			scale_x = scale_y = true;
+
 		break;
 	default:
 		BUG();
@@ -1431,8 +1572,10 @@
 			out_width, out_height, five_taps,
 				rotation, DISPC_COLOR_COMPONENT_UV);
 
-	REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane),
-		(scale_x || scale_y) ? 1 : 0, 8, 8);
+	if (plane != OMAP_DSS_WB)
+		REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane),
+			(scale_x || scale_y) ? 1 : 0, 8, 8);
+
 	/* set H scaling */
 	REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_x ? 1 : 0, 5, 5);
 	/* set V scaling */
@@ -1848,22 +1991,19 @@
  * This function is used to avoid synclosts in OMAP3, because of some
  * undocumented horizontal position and timing related limitations.
  */
-static int check_horiz_timing_omap3(enum omap_channel channel,
+static int check_horiz_timing_omap3(enum omap_plane plane,
 		const struct omap_video_timings *t, u16 pos_x,
 		u16 width, u16 height, u16 out_width, u16 out_height)
 {
 	int DS = DIV_ROUND_UP(height, out_height);
-	unsigned long nonactive, lclk, pclk;
+	unsigned long nonactive;
 	static const u8 limits[3] = { 8, 10, 20 };
 	u64 val, blank;
+	unsigned long pclk = dispc_plane_pclk_rate(plane);
+	unsigned long lclk = dispc_plane_lclk_rate(plane);
 	int i;
 
 	nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width;
-	pclk = dispc_mgr_pclk_rate(channel);
-	if (dss_mgr_is_lcd(channel))
-		lclk = dispc_mgr_lclk_rate(channel);
-	else
-		lclk = dispc_fclk_rate();
 
 	i = 0;
 	if (out_height < height)
@@ -1900,13 +2040,14 @@
 	return 0;
 }
 
-static unsigned long calc_core_clk_five_taps(enum omap_channel channel,
+static unsigned long calc_core_clk_five_taps(enum omap_plane plane,
 		const struct omap_video_timings *mgr_timings, u16 width,
 		u16 height, u16 out_width, u16 out_height,
 		enum omap_color_mode color_mode)
 {
 	u32 core_clk = 0;
-	u64 tmp, pclk = dispc_mgr_pclk_rate(channel);
+	u64 tmp;
+	unsigned long pclk = dispc_plane_pclk_rate(plane);
 
 	if (height <= out_height && width <= out_width)
 		return (unsigned long) pclk;
@@ -1940,11 +2081,22 @@
 	return core_clk;
 }
 
-static unsigned long calc_core_clk(enum omap_channel channel, u16 width,
-		u16 height, u16 out_width, u16 out_height)
+static unsigned long calc_core_clk_24xx(enum omap_plane plane, u16 width,
+		u16 height, u16 out_width, u16 out_height, bool mem_to_mem)
+{
+	unsigned long pclk = dispc_plane_pclk_rate(plane);
+
+	if (height > out_height && width > out_width)
+		return pclk * 4;
+	else
+		return pclk * 2;
+}
+
+static unsigned long calc_core_clk_34xx(enum omap_plane plane, u16 width,
+		u16 height, u16 out_width, u16 out_height, bool mem_to_mem)
 {
 	unsigned int hf, vf;
-	unsigned long pclk = dispc_mgr_pclk_rate(channel);
+	unsigned long pclk = dispc_plane_pclk_rate(plane);
 
 	/*
 	 * FIXME how to determine the 'A' factor
@@ -1959,51 +2111,207 @@
 		hf = 2;
 	else
 		hf = 1;
-
 	if (height > out_height)
 		vf = 2;
 	else
 		vf = 1;
 
-	if (cpu_is_omap24xx()) {
-		if (vf > 1 && hf > 1)
-			return pclk * 4;
-		else
-			return pclk * 2;
-	} else if (cpu_is_omap34xx()) {
-		return pclk * vf * hf;
-	} else {
-		if (hf > 1)
-			return DIV_ROUND_UP(pclk, out_width) * width;
-		else
-			return pclk;
-	}
+	return pclk * vf * hf;
 }
 
-static int dispc_ovl_calc_scaling(enum omap_plane plane,
-		enum omap_channel channel,
+static unsigned long calc_core_clk_44xx(enum omap_plane plane, u16 width,
+		u16 height, u16 out_width, u16 out_height, bool mem_to_mem)
+{
+	unsigned long pclk;
+
+	/*
+	 * If the overlay/writeback is in mem to mem mode, there are no
+	 * downscaling limitations with respect to pixel clock, return 1 as
+	 * required core clock to represent that we have sufficient enough
+	 * core clock to do maximum downscaling
+	 */
+	if (mem_to_mem)
+		return 1;
+
+	pclk = dispc_plane_pclk_rate(plane);
+
+	if (width > out_width)
+		return DIV_ROUND_UP(pclk, out_width) * width;
+	else
+		return pclk;
+}
+
+static int dispc_ovl_calc_scaling_24xx(enum omap_plane plane,
 		const struct omap_video_timings *mgr_timings,
 		u16 width, u16 height, u16 out_width, u16 out_height,
 		enum omap_color_mode color_mode, bool *five_taps,
-		int *x_predecim, int *y_predecim, u16 pos_x)
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk, bool mem_to_mem)
 {
-	struct omap_overlay *ovl = omap_dss_get_overlay(plane);
-	const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
+	int error;
+	u16 in_width, in_height;
+	int min_factor = min(*decim_x, *decim_y);
+	const int maxsinglelinewidth =
+			dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+	*five_taps = false;
+
+	do {
+		in_height = DIV_ROUND_UP(height, *decim_y);
+		in_width = DIV_ROUND_UP(width, *decim_x);
+		*core_clk = dispc.feat->calc_core_clk(plane, in_width,
+				in_height, out_width, out_height, mem_to_mem);
+		error = (in_width > maxsinglelinewidth || !*core_clk ||
+			*core_clk > dispc_core_clk_rate());
+		if (error) {
+			if (*decim_x == *decim_y) {
+				*decim_x = min_factor;
+				++*decim_y;
+			} else {
+				swap(*decim_x, *decim_y);
+				if (*decim_x < *decim_y)
+					++*decim_x;
+			}
+		}
+	} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+	if (in_width > maxsinglelinewidth) {
+		DSSERR("Cannot scale max input width exceeded");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk, bool mem_to_mem)
+{
+	int error;
+	u16 in_width, in_height;
+	int min_factor = min(*decim_x, *decim_y);
+	const int maxsinglelinewidth =
+			dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+
+	do {
+		in_height = DIV_ROUND_UP(height, *decim_y);
+		in_width = DIV_ROUND_UP(width, *decim_x);
+		*core_clk = calc_core_clk_five_taps(plane, mgr_timings,
+			in_width, in_height, out_width, out_height, color_mode);
+
+		error = check_horiz_timing_omap3(plane, mgr_timings,
+				pos_x, in_width, in_height, out_width,
+				out_height);
+
+		if (in_width > maxsinglelinewidth)
+			if (in_height > out_height &&
+						in_height < out_height * 2)
+				*five_taps = false;
+		if (!*five_taps)
+			*core_clk = dispc.feat->calc_core_clk(plane, in_width,
+					in_height, out_width, out_height,
+					mem_to_mem);
+
+		error = (error || in_width > maxsinglelinewidth * 2 ||
+			(in_width > maxsinglelinewidth && *five_taps) ||
+			!*core_clk || *core_clk > dispc_core_clk_rate());
+		if (error) {
+			if (*decim_x == *decim_y) {
+				*decim_x = min_factor;
+				++*decim_y;
+			} else {
+				swap(*decim_x, *decim_y);
+				if (*decim_x < *decim_y)
+					++*decim_x;
+			}
+		}
+	} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
+
+	if (check_horiz_timing_omap3(plane, mgr_timings, pos_x, width, height,
+		out_width, out_height)){
+			DSSERR("horizontal timing too tight\n");
+			return -EINVAL;
+	}
+
+	if (in_width > (maxsinglelinewidth * 2)) {
+		DSSERR("Cannot setup scaling");
+		DSSERR("width exceeds maximum width possible");
+		return -EINVAL;
+	}
+
+	if (in_width > maxsinglelinewidth && *five_taps) {
+		DSSERR("cannot setup scaling with five taps");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int dispc_ovl_calc_scaling_44xx(enum omap_plane plane,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
+		u16 pos_x, unsigned long *core_clk, bool mem_to_mem)
+{
+	u16 in_width, in_width_max;
+	int decim_x_min = *decim_x;
+	u16 in_height = DIV_ROUND_UP(height, *decim_y);
 	const int maxsinglelinewidth =
 				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
+	unsigned long pclk = dispc_plane_pclk_rate(plane);
+	const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
+
+	if (mem_to_mem)
+		in_width_max = DIV_ROUND_UP(out_width, maxdownscale);
+	else
+		in_width_max = dispc_core_clk_rate() /
+					DIV_ROUND_UP(pclk, out_width);
+
+	*decim_x = DIV_ROUND_UP(width, in_width_max);
+
+	*decim_x = *decim_x > decim_x_min ? *decim_x : decim_x_min;
+	if (*decim_x > *x_predecim)
+		return -EINVAL;
+
+	do {
+		in_width = DIV_ROUND_UP(width, *decim_x);
+	} while (*decim_x <= *x_predecim &&
+			in_width > maxsinglelinewidth && ++*decim_x);
+
+	if (in_width > maxsinglelinewidth) {
+		DSSERR("Cannot scale width exceeds max line width");
+		return -EINVAL;
+	}
+
+	*core_clk = dispc.feat->calc_core_clk(plane, in_width, in_height,
+				out_width, out_height, mem_to_mem);
+	return 0;
+}
+
+static int dispc_ovl_calc_scaling(enum omap_plane plane,
+		enum omap_overlay_caps caps,
+		const struct omap_video_timings *mgr_timings,
+		u16 width, u16 height, u16 out_width, u16 out_height,
+		enum omap_color_mode color_mode, bool *five_taps,
+		int *x_predecim, int *y_predecim, u16 pos_x,
+		enum omap_dss_rotation_type rotation_type, bool mem_to_mem)
+{
+	const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
 	const int max_decim_limit = 16;
 	unsigned long core_clk = 0;
-	int decim_x, decim_y, error, min_factor;
-	u16 in_width, in_height, in_width_max = 0;
+	int decim_x, decim_y, ret;
 
 	if (width == out_width && height == out_height)
 		return 0;
 
-	if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0)
+	if ((caps & OMAP_DSS_OVL_CAP_SCALE) == 0)
 		return -EINVAL;
 
 	*x_predecim = max_decim_limit;
-	*y_predecim = max_decim_limit;
+	*y_predecim = (rotation_type == OMAP_DSS_ROT_TILER &&
+			dss_has_feature(FEAT_BURST_2D)) ? 2 : max_decim_limit;
 
 	if (color_mode == OMAP_DSS_COLOR_CLUT1 ||
 	    color_mode == OMAP_DSS_COLOR_CLUT2 ||
@@ -2018,118 +2326,18 @@
 	decim_x = DIV_ROUND_UP(DIV_ROUND_UP(width, out_width), maxdownscale);
 	decim_y = DIV_ROUND_UP(DIV_ROUND_UP(height, out_height), maxdownscale);
 
-	min_factor = min(decim_x, decim_y);
-
 	if (decim_x > *x_predecim || out_width > width * 8)
 		return -EINVAL;
 
 	if (decim_y > *y_predecim || out_height > height * 8)
 		return -EINVAL;
 
-	if (cpu_is_omap24xx()) {
-		*five_taps = false;
-
-		do {
-			in_height = DIV_ROUND_UP(height, decim_y);
-			in_width = DIV_ROUND_UP(width, decim_x);
-			core_clk = calc_core_clk(channel, in_width, in_height,
-					out_width, out_height);
-			error = (in_width > maxsinglelinewidth || !core_clk ||
-				core_clk > dispc_core_clk_rate());
-			if (error) {
-				if (decim_x == decim_y) {
-					decim_x = min_factor;
-					decim_y++;
-				} else {
-					swap(decim_x, decim_y);
-					if (decim_x < decim_y)
-						decim_x++;
-				}
-			}
-		} while (decim_x <= *x_predecim && decim_y <= *y_predecim &&
-				error);
-
-		if (in_width > maxsinglelinewidth) {
-			DSSERR("Cannot scale max input width exceeded");
-			return -EINVAL;
-		}
-	} else if (cpu_is_omap34xx()) {
-
-		do {
-			in_height = DIV_ROUND_UP(height, decim_y);
-			in_width = DIV_ROUND_UP(width, decim_x);
-			core_clk = calc_core_clk_five_taps(channel, mgr_timings,
-				in_width, in_height, out_width, out_height,
-				color_mode);
-
-			error = check_horiz_timing_omap3(channel, mgr_timings,
-				pos_x, in_width, in_height, out_width,
-				out_height);
-
-			if (in_width > maxsinglelinewidth)
-				if (in_height > out_height &&
-					in_height < out_height * 2)
-					*five_taps = false;
-			if (!*five_taps)
-				core_clk = calc_core_clk(channel, in_width,
-					in_height, out_width, out_height);
-			error = (error || in_width > maxsinglelinewidth * 2 ||
-				(in_width > maxsinglelinewidth && *five_taps) ||
-				!core_clk || core_clk > dispc_core_clk_rate());
-			if (error) {
-				if (decim_x == decim_y) {
-					decim_x = min_factor;
-					decim_y++;
-				} else {
-					swap(decim_x, decim_y);
-					if (decim_x < decim_y)
-						decim_x++;
-				}
-			}
-		} while (decim_x <= *x_predecim && decim_y <= *y_predecim
-			&& error);
-
-		if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width,
-			height, out_width, out_height)){
-				DSSERR("horizontal timing too tight\n");
-				return -EINVAL;
-		}
-
-		if (in_width > (maxsinglelinewidth * 2)) {
-			DSSERR("Cannot setup scaling");
-			DSSERR("width exceeds maximum width possible");
-			return -EINVAL;
-		}
-
-		if (in_width > maxsinglelinewidth && *five_taps) {
-			DSSERR("cannot setup scaling with five taps");
-			return -EINVAL;
-		}
-	} else {
-		int decim_x_min = decim_x;
-		in_height = DIV_ROUND_UP(height, decim_y);
-		in_width_max = dispc_core_clk_rate() /
-				DIV_ROUND_UP(dispc_mgr_pclk_rate(channel),
-						out_width);
-		decim_x = DIV_ROUND_UP(width, in_width_max);
-
-		decim_x = decim_x > decim_x_min ? decim_x : decim_x_min;
-		if (decim_x > *x_predecim)
-			return -EINVAL;
-
-		do {
-			in_width = DIV_ROUND_UP(width, decim_x);
-		} while (decim_x <= *x_predecim &&
-				in_width > maxsinglelinewidth && decim_x++);
-
-		if (in_width > maxsinglelinewidth) {
-			DSSERR("Cannot scale width exceeds max line width");
-			return -EINVAL;
-		}
-
-		core_clk = calc_core_clk(channel, in_width, in_height,
-				out_width, out_height);
-	}
+	ret = dispc.feat->calc_scaling(plane, mgr_timings, width, height,
+		out_width, out_height, color_mode, five_taps,
+		x_predecim, y_predecim, &decim_x, &decim_y, pos_x, &core_clk,
+		mem_to_mem);
+	if (ret)
+		return ret;
 
 	DSSDBG("required core clk rate = %lu Hz\n", core_clk);
 	DSSDBG("current core clk rate = %lu Hz\n", dispc_core_clk_rate());
@@ -2147,69 +2355,64 @@
 	return 0;
 }
 
-int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
-		bool replication, const struct omap_video_timings *mgr_timings)
+static int dispc_ovl_setup_common(enum omap_plane plane,
+		enum omap_overlay_caps caps, u32 paddr, u32 p_uv_addr,
+		u16 screen_width, int pos_x, int pos_y, u16 width, u16 height,
+		u16 out_width, u16 out_height, enum omap_color_mode color_mode,
+		u8 rotation, bool mirror, u8 zorder, u8 pre_mult_alpha,
+		u8 global_alpha, enum omap_dss_rotation_type rotation_type,
+		bool replication, const struct omap_video_timings *mgr_timings,
+		bool mem_to_mem)
 {
-	struct omap_overlay *ovl = omap_dss_get_overlay(plane);
 	bool five_taps = true;
 	bool fieldmode = 0;
 	int r, cconv = 0;
 	unsigned offset0, offset1;
 	s32 row_inc;
 	s32 pix_inc;
-	u16 frame_height = oi->height;
+	u16 frame_height = height;
 	unsigned int field_offset = 0;
-	u16 in_height = oi->height;
-	u16 in_width = oi->width;
-	u16 out_width, out_height;
-	enum omap_channel channel;
+	u16 in_height = height;
+	u16 in_width = width;
 	int x_predecim = 1, y_predecim = 1;
 	bool ilace = mgr_timings->interlace;
 
-	channel = dispc_ovl_get_channel_out(plane);
-
-	DSSDBG("dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d -> "
-		"%dx%d, cmode %x, rot %d, mir %d, ilace %d chan %d repl %d\n",
-		plane, oi->paddr, oi->p_uv_addr,
-		oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height,
-		oi->out_width, oi->out_height, oi->color_mode, oi->rotation,
-		oi->mirror, ilace, channel, replication);
-
-	if (oi->paddr == 0)
+	if (paddr == 0)
 		return -EINVAL;
 
-	out_width = oi->out_width == 0 ? oi->width : oi->out_width;
-	out_height = oi->out_height == 0 ? oi->height : oi->out_height;
+	out_width = out_width == 0 ? width : out_width;
+	out_height = out_height == 0 ? height : out_height;
 
-	if (ilace && oi->height == out_height)
+	if (ilace && height == out_height)
 		fieldmode = 1;
 
 	if (ilace) {
 		if (fieldmode)
 			in_height /= 2;
-		oi->pos_y /= 2;
+		pos_y /= 2;
 		out_height /= 2;
 
 		DSSDBG("adjusting for ilace: height %d, pos_y %d, "
-				"out_height %d\n",
-				in_height, oi->pos_y, out_height);
+			"out_height %d\n", in_height, pos_y,
+			out_height);
 	}
 
-	if (!dss_feat_color_mode_supported(plane, oi->color_mode))
+	if (!dss_feat_color_mode_supported(plane, color_mode))
 		return -EINVAL;
 
-	r = dispc_ovl_calc_scaling(plane, channel, mgr_timings, in_width,
-			in_height, out_width, out_height, oi->color_mode,
-			&five_taps, &x_predecim, &y_predecim, oi->pos_x);
+	r = dispc_ovl_calc_scaling(plane, caps, mgr_timings, in_width,
+			in_height, out_width, out_height, color_mode,
+			&five_taps, &x_predecim, &y_predecim, pos_x,
+			rotation_type, mem_to_mem);
 	if (r)
 		return r;
 
 	in_width = DIV_ROUND_UP(in_width, x_predecim);
 	in_height = DIV_ROUND_UP(in_height, y_predecim);
 
-	if (oi->color_mode == OMAP_DSS_COLOR_YUV2 ||
-			oi->color_mode == OMAP_DSS_COLOR_UYVY ||
-			oi->color_mode == OMAP_DSS_COLOR_NV12)
+	if (color_mode == OMAP_DSS_COLOR_YUV2 ||
+			color_mode == OMAP_DSS_COLOR_UYVY ||
+			color_mode == OMAP_DSS_COLOR_NV12)
 		cconv = 1;
 
 	if (ilace && !fieldmode) {
@@ -2235,70 +2438,144 @@
 	row_inc = 0;
 	pix_inc = 0;
 
-	if (oi->rotation_type == OMAP_DSS_ROT_TILER)
-		calc_tiler_rotation_offset(oi->screen_width, in_width,
-				oi->color_mode, fieldmode, field_offset,
+	if (rotation_type == OMAP_DSS_ROT_TILER)
+		calc_tiler_rotation_offset(screen_width, in_width,
+				color_mode, fieldmode, field_offset,
 				&offset0, &offset1, &row_inc, &pix_inc,
 				x_predecim, y_predecim);
-	else if (oi->rotation_type == OMAP_DSS_ROT_DMA)
-		calc_dma_rotation_offset(oi->rotation, oi->mirror,
-				oi->screen_width, in_width, frame_height,
-				oi->color_mode, fieldmode, field_offset,
+	else if (rotation_type == OMAP_DSS_ROT_DMA)
+		calc_dma_rotation_offset(rotation, mirror,
+				screen_width, in_width, frame_height,
+				color_mode, fieldmode, field_offset,
 				&offset0, &offset1, &row_inc, &pix_inc,
 				x_predecim, y_predecim);
 	else
-		calc_vrfb_rotation_offset(oi->rotation, oi->mirror,
-				oi->screen_width, in_width, frame_height,
-				oi->color_mode, fieldmode, field_offset,
+		calc_vrfb_rotation_offset(rotation, mirror,
+				screen_width, in_width, frame_height,
+				color_mode, fieldmode, field_offset,
 				&offset0, &offset1, &row_inc, &pix_inc,
 				x_predecim, y_predecim);
 
 	DSSDBG("offset0 %u, offset1 %u, row_inc %d, pix_inc %d\n",
 			offset0, offset1, row_inc, pix_inc);
 
-	dispc_ovl_set_color_mode(plane, oi->color_mode);
+	dispc_ovl_set_color_mode(plane, color_mode);
 
-	dispc_ovl_configure_burst_type(plane, oi->rotation_type);
+	dispc_ovl_configure_burst_type(plane, rotation_type);
 
-	dispc_ovl_set_ba0(plane, oi->paddr + offset0);
-	dispc_ovl_set_ba1(plane, oi->paddr + offset1);
+	dispc_ovl_set_ba0(plane, paddr + offset0);
+	dispc_ovl_set_ba1(plane, paddr + offset1);
 
-	if (OMAP_DSS_COLOR_NV12 == oi->color_mode) {
-		dispc_ovl_set_ba0_uv(plane, oi->p_uv_addr + offset0);
-		dispc_ovl_set_ba1_uv(plane, oi->p_uv_addr + offset1);
+	if (OMAP_DSS_COLOR_NV12 == color_mode) {
+		dispc_ovl_set_ba0_uv(plane, p_uv_addr + offset0);
+		dispc_ovl_set_ba1_uv(plane, p_uv_addr + offset1);
 	}
 
-
 	dispc_ovl_set_row_inc(plane, row_inc);
 	dispc_ovl_set_pix_inc(plane, pix_inc);
 
-	DSSDBG("%d,%d %dx%d -> %dx%d\n", oi->pos_x, oi->pos_y, in_width,
+	DSSDBG("%d,%d %dx%d -> %dx%d\n", pos_x, pos_y, in_width,
 			in_height, out_width, out_height);
 
-	dispc_ovl_set_pos(plane, oi->pos_x, oi->pos_y);
+	dispc_ovl_set_pos(plane, caps, pos_x, pos_y);
 
-	dispc_ovl_set_pic_size(plane, in_width, in_height);
+	dispc_ovl_set_input_size(plane, in_width, in_height);
 
-	if (ovl->caps & OMAP_DSS_OVL_CAP_SCALE) {
+	if (caps & OMAP_DSS_OVL_CAP_SCALE) {
 		dispc_ovl_set_scaling(plane, in_width, in_height, out_width,
 				   out_height, ilace, five_taps, fieldmode,
-				   oi->color_mode, oi->rotation);
-		dispc_ovl_set_vid_size(plane, out_width, out_height);
+				   color_mode, rotation);
+		dispc_ovl_set_output_size(plane, out_width, out_height);
 		dispc_ovl_set_vid_color_conv(plane, cconv);
 	}
 
-	dispc_ovl_set_rotation_attrs(plane, oi->rotation, oi->mirror,
-			oi->color_mode);
+	dispc_ovl_set_rotation_attrs(plane, rotation, mirror, color_mode);
 
-	dispc_ovl_set_zorder(plane, oi->zorder);
-	dispc_ovl_set_pre_mult_alpha(plane, oi->pre_mult_alpha);
-	dispc_ovl_setup_global_alpha(plane, oi->global_alpha);
+	dispc_ovl_set_zorder(plane, caps, zorder);
+	dispc_ovl_set_pre_mult_alpha(plane, caps, pre_mult_alpha);
+	dispc_ovl_setup_global_alpha(plane, caps, global_alpha);
 
-	dispc_ovl_enable_replication(plane, replication);
+	dispc_ovl_enable_replication(plane, caps, replication);
 
 	return 0;
 }
 
+int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
+		bool replication, const struct omap_video_timings *mgr_timings,
+		bool mem_to_mem)
+{
+	int r;
+	struct omap_overlay *ovl = omap_dss_get_overlay(plane);
+	enum omap_channel channel;
+
+	channel = dispc_ovl_get_channel_out(plane);
+
+	DSSDBG("dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d -> "
+		"%dx%d, cmode %x, rot %d, mir %d, chan %d repl %d\n",
+		plane, oi->paddr, oi->p_uv_addr, oi->screen_width, oi->pos_x,
+		oi->pos_y, oi->width, oi->height, oi->out_width, oi->out_height,
+		oi->color_mode, oi->rotation, oi->mirror, channel, replication);
+
+	r = dispc_ovl_setup_common(plane, ovl->caps, oi->paddr, oi->p_uv_addr,
+		oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height,
+		oi->out_width, oi->out_height, oi->color_mode, oi->rotation,
+		oi->mirror, oi->zorder, oi->pre_mult_alpha, oi->global_alpha,
+		oi->rotation_type, replication, mgr_timings, mem_to_mem);
+
+	return r;
+}
+
+int dispc_wb_setup(const struct omap_dss_writeback_info *wi,
+		bool mem_to_mem, const struct omap_video_timings *mgr_timings)
+{
+	int r;
+	u32 l;
+	enum omap_plane plane = OMAP_DSS_WB;
+	const int pos_x = 0, pos_y = 0;
+	const u8 zorder = 0, global_alpha = 0;
+	const bool replication = false;
+	bool truncation;
+	int in_width = mgr_timings->x_res;
+	int in_height = mgr_timings->y_res;
+	enum omap_overlay_caps caps =
+		OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA;
+
+	DSSDBG("dispc_wb_setup, pa %x, pa_uv %x, %d,%d -> %dx%d, cmode %x, "
+		"rot %d, mir %d\n", wi->paddr, wi->p_uv_addr, in_width,
+		in_height, wi->width, wi->height, wi->color_mode, wi->rotation,
+		wi->mirror);
+
+	r = dispc_ovl_setup_common(plane, caps, wi->paddr, wi->p_uv_addr,
+		wi->buf_width, pos_x, pos_y, in_width, in_height, wi->width,
+		wi->height, wi->color_mode, wi->rotation, wi->mirror, zorder,
+		wi->pre_mult_alpha, global_alpha, wi->rotation_type,
+		replication, mgr_timings, mem_to_mem);
+
+	switch (wi->color_mode) {
+	case OMAP_DSS_COLOR_RGB16:
+	case OMAP_DSS_COLOR_RGB24P:
+	case OMAP_DSS_COLOR_ARGB16:
+	case OMAP_DSS_COLOR_RGBA16:
+	case OMAP_DSS_COLOR_RGB12U:
+	case OMAP_DSS_COLOR_ARGB16_1555:
+	case OMAP_DSS_COLOR_XRGB16_1555:
+	case OMAP_DSS_COLOR_RGBX16:
+		truncation = true;
+		break;
+	default:
+		truncation = false;
+		break;
+	}
+
+	/* setup extra DISPC_WB_ATTRIBUTES */
+	l = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));
+	l = FLD_MOD(l, truncation, 10, 10);	/* TRUNCATIONENABLE */
+	l = FLD_MOD(l, mem_to_mem, 19, 19);	/* WRITEBACKMODE */
+	dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), l);
+
+	return r;
+}
+
 int dispc_ovl_enable(enum omap_plane plane, bool enable)
 {
 	DSSDBG("dispc_enable_plane %d, %d\n", plane, enable);
@@ -2451,6 +2728,47 @@
 		BUG();
 }
 
+void dispc_wb_enable(bool enable)
+{
+	enum omap_plane plane = OMAP_DSS_WB;
+	struct completion frame_done_completion;
+	bool is_on;
+	int r;
+	u32 irq;
+
+	is_on = REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0);
+	irq = DISPC_IRQ_FRAMEDONEWB;
+
+	if (!enable && is_on) {
+		init_completion(&frame_done_completion);
+
+		r = omap_dispc_register_isr(dispc_disable_isr,
+				&frame_done_completion, irq);
+		if (r)
+			DSSERR("failed to register FRAMEDONEWB isr\n");
+	}
+
+	REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 0, 0);
+
+	if (!enable && is_on) {
+		if (!wait_for_completion_timeout(&frame_done_completion,
+					msecs_to_jiffies(100)))
+			DSSERR("timeout waiting for FRAMEDONEWB\n");
+
+		r = omap_dispc_unregister_isr(dispc_disable_isr,
+				&frame_done_completion, irq);
+		if (r)
+			DSSERR("failed to unregister FRAMEDONEWB isr\n");
+	}
+}
+
+bool dispc_wb_is_enabled(void)
+{
+	enum omap_plane plane = OMAP_DSS_WB;
+
+	return REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0);
+}
+
 void dispc_lcd_enable_signal_polarity(bool act_high)
 {
 	if (!dss_has_feature(FEAT_LCDENABLEPOL))
@@ -2605,24 +2923,13 @@
 static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
 		int vsw, int vfp, int vbp)
 {
-	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
-		if (hsw < 1 || hsw > 64 ||
-				hfp < 1 || hfp > 256 ||
-				hbp < 1 || hbp > 256 ||
-				vsw < 1 || vsw > 64 ||
-				vfp < 0 || vfp > 255 ||
-				vbp < 0 || vbp > 255)
-			return false;
-	} else {
-		if (hsw < 1 || hsw > 256 ||
-				hfp < 1 || hfp > 4096 ||
-				hbp < 1 || hbp > 4096 ||
-				vsw < 1 || vsw > 256 ||
-				vfp < 0 || vfp > 4095 ||
-				vbp < 0 || vbp > 4095)
-			return false;
-	}
-
+	if (hsw < 1 || hsw > dispc.feat->sw_max ||
+			hfp < 1 || hfp > dispc.feat->hp_max ||
+			hbp < 1 || hbp > dispc.feat->hp_max ||
+			vsw < 1 || vsw > dispc.feat->sw_max ||
+			vfp < 0 || vfp > dispc.feat->vp_max ||
+			vbp < 0 || vbp > dispc.feat->vp_max)
+		return false;
 	return true;
 }
 
@@ -2654,19 +2961,12 @@
 	u32 timing_h, timing_v, l;
 	bool onoff, rf, ipc;
 
-	if (cpu_is_omap24xx() || omap_rev() < OMAP3430_REV_ES3_0) {
-		timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) |
-			FLD_VAL(hbp-1, 27, 20);
-
-		timing_v = FLD_VAL(vsw-1, 5, 0) | FLD_VAL(vfp, 15, 8) |
-			FLD_VAL(vbp, 27, 20);
-	} else {
-		timing_h = FLD_VAL(hsw-1, 7, 0) | FLD_VAL(hfp-1, 19, 8) |
-			FLD_VAL(hbp-1, 31, 20);
-
-		timing_v = FLD_VAL(vsw-1, 7, 0) | FLD_VAL(vfp, 19, 8) |
-			FLD_VAL(vbp, 31, 20);
-	}
+	timing_h = FLD_VAL(hsw-1, dispc.feat->sw_start, 0) |
+			FLD_VAL(hfp-1, dispc.feat->fp_start, 8) |
+			FLD_VAL(hbp-1, dispc.feat->bp_start, 20);
+	timing_v = FLD_VAL(vsw-1, dispc.feat->sw_start, 0) |
+			FLD_VAL(vfp, dispc.feat->fp_start, 8) |
+			FLD_VAL(vbp, dispc.feat->bp_start, 20);
 
 	dispc_write_reg(DISPC_TIMING_H(channel), timing_h);
 	dispc_write_reg(DISPC_TIMING_V(channel), timing_v);
@@ -2872,6 +3172,23 @@
 	return fclk / lcd;
 }
 
+static unsigned long dispc_plane_pclk_rate(enum omap_plane plane)
+{
+	enum omap_channel channel = dispc_ovl_get_channel_out(plane);
+
+	return dispc_mgr_pclk_rate(channel);
+}
+
+static unsigned long dispc_plane_lclk_rate(enum omap_plane plane)
+{
+	enum omap_channel channel = dispc_ovl_get_channel_out(plane);
+
+	if (dss_mgr_is_lcd(channel))
+		return dispc_mgr_lclk_rate(channel);
+	else
+		return dispc_fclk_rate();
+
+}
 static void dispc_dump_clocks_channel(struct seq_file *s, enum omap_channel channel)
 {
 	int lcd, pcd;
@@ -3492,7 +3809,7 @@
 					ovl->name);
 			dispc_ovl_enable(ovl->id, false);
 			dispc_mgr_go(ovl->manager->id);
-			mdelay(50);
+			msleep(50);
 		}
 	}
 
@@ -3504,7 +3821,7 @@
 		bit = mgr_desc[i].sync_lost_irq;
 
 		if (bit & errors) {
-			struct omap_dss_device *dssdev = mgr->device;
+			struct omap_dss_device *dssdev = mgr->get_device(mgr);
 			bool enable;
 
 			DSSERR("SYNC_LOST on channel %s, restarting the output "
@@ -3524,7 +3841,7 @@
 			}
 
 			dispc_mgr_go(mgr->id);
-			mdelay(50);
+			msleep(50);
 
 			if (enable)
 				dssdev->driver->enable(dssdev);
@@ -3535,9 +3852,13 @@
 		DSSERR("OCP_ERR\n");
 		for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
 			struct omap_overlay_manager *mgr;
+			struct omap_dss_device *dssdev;
+
 			mgr = omap_dss_get_overlay_manager(i);
-			if (mgr->device && mgr->device->driver)
-				mgr->device->driver->disable(mgr->device);
+			dssdev = mgr->get_device(mgr);
+
+			if (dssdev && dssdev->driver)
+				dssdev->driver->disable(dssdev);
 		}
 	}
 
@@ -3661,17 +3982,98 @@
 	if (dss_has_feature(FEAT_FUNCGATED))
 		REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9);
 
-	_dispc_setup_color_conv_coef();
+	dispc_setup_color_conv_coef();
 
 	dispc_set_loadmode(OMAP_DSS_LOAD_FRAME_ONLY);
 
-	dispc_read_plane_fifo_sizes();
+	dispc_init_fifos();
 
 	dispc_configure_burst_sizes();
 
 	dispc_ovl_enable_zorder_planes();
 }
 
+static const struct dispc_features omap24xx_dispc_feats __initconst = {
+	.sw_start		=	5,
+	.fp_start		=	15,
+	.bp_start		=	27,
+	.sw_max			=	64,
+	.vp_max			=	255,
+	.hp_max			=	256,
+	.calc_scaling		=	dispc_ovl_calc_scaling_24xx,
+	.calc_core_clk		=	calc_core_clk_24xx,
+	.num_fifos		=	3,
+};
+
+static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
+	.sw_start		=	5,
+	.fp_start		=	15,
+	.bp_start		=	27,
+	.sw_max			=	64,
+	.vp_max			=	255,
+	.hp_max			=	256,
+	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
+	.calc_core_clk		=	calc_core_clk_34xx,
+	.num_fifos		=	3,
+};
+
+static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
+	.sw_start		=	7,
+	.fp_start		=	19,
+	.bp_start		=	31,
+	.sw_max			=	256,
+	.vp_max			=	4095,
+	.hp_max			=	4096,
+	.calc_scaling		=	dispc_ovl_calc_scaling_34xx,
+	.calc_core_clk		=	calc_core_clk_34xx,
+	.num_fifos		=	3,
+};
+
+static const struct dispc_features omap44xx_dispc_feats __initconst = {
+	.sw_start		=	7,
+	.fp_start		=	19,
+	.bp_start		=	31,
+	.sw_max			=	256,
+	.vp_max			=	4095,
+	.hp_max			=	4096,
+	.calc_scaling		=	dispc_ovl_calc_scaling_44xx,
+	.calc_core_clk		=	calc_core_clk_44xx,
+	.num_fifos		=	5,
+	.gfx_fifo_workaround	=	true,
+};
+
+static int __init dispc_init_features(struct device *dev)
+{
+	const struct dispc_features *src;
+	struct dispc_features *dst;
+
+	dst = devm_kzalloc(dev, sizeof(*dst), GFP_KERNEL);
+	if (!dst) {
+		dev_err(dev, "Failed to allocate DISPC Features\n");
+		return -ENOMEM;
+	}
+
+	if (cpu_is_omap24xx()) {
+		src = &omap24xx_dispc_feats;
+	} else if (cpu_is_omap34xx()) {
+		if (omap_rev() < OMAP3430_REV_ES3_0)
+			src = &omap34xx_rev1_0_dispc_feats;
+		else
+			src = &omap34xx_rev3_0_dispc_feats;
+	} else if (cpu_is_omap44xx()) {
+		src = &omap44xx_dispc_feats;
+	} else if (soc_is_omap54xx()) {
+		src = &omap44xx_dispc_feats;
+	} else {
+		return -ENODEV;
+	}
+
+	memcpy(dst, src, sizeof(*dst));
+	dispc.feat = dst;
+
+	return 0;
+}
+
 /* DISPC HW IP initialisation */
 static int __init omap_dispchw_probe(struct platform_device *pdev)
 {
@@ -3682,6 +4084,10 @@
 
 	dispc.pdev = pdev;
 
+	r = dispc_init_features(&dispc.pdev->dev);
+	if (r)
+		return r;
+
 	spin_lock_init(&dispc.irq_lock);
 
 #ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
diff --git a/drivers/video/omap2/dss/dispc.h b/drivers/video/omap2/dss/dispc.h
index 92d8a9b..222363c6 100644
--- a/drivers/video/omap2/dss/dispc.h
+++ b/drivers/video/omap2/dss/dispc.h
@@ -36,6 +36,7 @@
 #define DISPC_CONTROL2			0x0238
 #define DISPC_CONFIG2			0x0620
 #define DISPC_DIVISOR			0x0804
+#define DISPC_GLOBAL_BUFFER		0x0800
 #define DISPC_CONTROL3                  0x0848
 #define DISPC_CONFIG3                   0x084C
 
@@ -355,6 +356,8 @@
 		return 0x014C;
 	case OMAP_DSS_VIDEO3:
 		return 0x0300;
+	case OMAP_DSS_WB:
+		return 0x0500;
 	default:
 		BUG();
 		return 0;
@@ -370,6 +373,7 @@
 	case OMAP_DSS_VIDEO2:
 		return 0x0000;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x0008;
 	default:
 		BUG();
@@ -385,6 +389,7 @@
 	case OMAP_DSS_VIDEO2:
 		return 0x0004;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x000C;
 	default:
 		BUG();
@@ -404,6 +409,8 @@
 		return 0x04BC;
 	case OMAP_DSS_VIDEO3:
 		return 0x0310;
+	case OMAP_DSS_WB:
+		return 0x0118;
 	default:
 		BUG();
 		return 0;
@@ -422,6 +429,8 @@
 		return 0x04C0;
 	case OMAP_DSS_VIDEO3:
 		return 0x0314;
+	case OMAP_DSS_WB:
+		return 0x011C;
 	default:
 		BUG();
 		return 0;
@@ -451,6 +460,7 @@
 	case OMAP_DSS_VIDEO2:
 		return 0x000C;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x00A8;
 	default:
 		BUG();
@@ -467,6 +477,7 @@
 	case OMAP_DSS_VIDEO2:
 		return 0x0010;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x0070;
 	default:
 		BUG();
@@ -486,6 +497,8 @@
 		return 0x04DC;
 	case OMAP_DSS_VIDEO3:
 		return 0x032C;
+	case OMAP_DSS_WB:
+		return 0x0310;
 	default:
 		BUG();
 		return 0;
@@ -501,6 +514,7 @@
 	case OMAP_DSS_VIDEO2:
 		return 0x0014;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x008C;
 	default:
 		BUG();
@@ -517,6 +531,7 @@
 	case OMAP_DSS_VIDEO2:
 		return 0x0018;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x0088;
 	default:
 		BUG();
@@ -533,6 +548,7 @@
 	case OMAP_DSS_VIDEO2:
 		return 0x001C;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x00A4;
 	default:
 		BUG();
@@ -549,6 +565,7 @@
 	case OMAP_DSS_VIDEO2:
 		return 0x0020;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x0098;
 	default:
 		BUG();
@@ -598,6 +615,7 @@
 	case OMAP_DSS_VIDEO2:
 		return 0x0024;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x0090;
 	default:
 		BUG();
@@ -617,6 +635,8 @@
 		return 0x055C;
 	case OMAP_DSS_VIDEO3:
 		return 0x0424;
+	case OMAP_DSS_WB:
+		return 0x290;
 	default:
 		BUG();
 		return 0;
@@ -633,6 +653,7 @@
 	case OMAP_DSS_VIDEO2:
 		return 0x0028;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x0094;
 	default:
 		BUG();
@@ -651,6 +672,7 @@
 	case OMAP_DSS_VIDEO2:
 		return 0x002C;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x0000;
 	default:
 		BUG();
@@ -670,6 +692,8 @@
 		return 0x0560;
 	case OMAP_DSS_VIDEO3:
 		return 0x0428;
+	case OMAP_DSS_WB:
+		return 0x0294;
 	default:
 		BUG();
 		return 0;
@@ -686,6 +710,7 @@
 	case OMAP_DSS_VIDEO2:
 		return 0x0030;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x0004;
 	default:
 		BUG();
@@ -705,6 +730,8 @@
 		return 0x0564;
 	case OMAP_DSS_VIDEO3:
 		return 0x042C;
+	case OMAP_DSS_WB:
+		return 0x0298;
 	default:
 		BUG();
 		return 0;
@@ -722,6 +749,7 @@
 	case OMAP_DSS_VIDEO2:
 		return 0x0034 + i * 0x8;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x0010 + i * 0x8;
 	default:
 		BUG();
@@ -742,6 +770,8 @@
 		return 0x0568 + i * 0x8;
 	case OMAP_DSS_VIDEO3:
 		return 0x0430 + i * 0x8;
+	case OMAP_DSS_WB:
+		return 0x02A0 + i * 0x8;
 	default:
 		BUG();
 		return 0;
@@ -759,6 +789,7 @@
 	case OMAP_DSS_VIDEO2:
 		return 0x0038 + i * 0x8;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x0014 + i * 0x8;
 	default:
 		BUG();
@@ -779,6 +810,8 @@
 		return 0x056C + i * 0x8;
 	case OMAP_DSS_VIDEO3:
 		return 0x0434 + i * 0x8;
+	case OMAP_DSS_WB:
+		return 0x02A4 + i * 0x8;
 	default:
 		BUG();
 		return 0;
@@ -795,6 +828,7 @@
 	case OMAP_DSS_VIDEO1:
 	case OMAP_DSS_VIDEO2:
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x0074 + i * 0x4;
 	default:
 		BUG();
@@ -814,6 +848,7 @@
 	case OMAP_DSS_VIDEO2:
 		return 0x00B4 + i * 0x4;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x0050 + i * 0x4;
 	default:
 		BUG();
@@ -834,6 +869,8 @@
 		return 0x05A8 + i * 0x4;
 	case OMAP_DSS_VIDEO3:
 		return 0x0470 + i * 0x4;
+	case OMAP_DSS_WB:
+		return 0x02E0 + i * 0x4;
 	default:
 		BUG();
 		return 0;
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index 5bd957e..ccf8550 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -142,7 +142,11 @@
 	if (r)
 		return r;
 
+	dssdev->driver->disable(dssdev);
 	dssdev->driver->set_timings(dssdev, &t);
+	r = dssdev->driver->enable(dssdev);
+	if (r)
+		return r;
 
 	return size;
 }
@@ -316,26 +320,117 @@
 }
 EXPORT_SYMBOL(omapdss_default_get_timings);
 
-void dss_init_device(struct platform_device *pdev,
+/*
+ * Connect dssdev to a manager if the manager is free or if force is specified.
+ * Connect all overlays to that manager if they are free or if force is
+ * specified.
+ */
+static int dss_init_connections(struct omap_dss_device *dssdev, bool force)
+{
+	struct omap_dss_output *out;
+	struct omap_overlay_manager *mgr;
+	int i, r;
+
+	out = omapdss_get_output_from_dssdev(dssdev);
+
+	WARN_ON(dssdev->output);
+	WARN_ON(out->device);
+
+	r = omapdss_output_set_device(out, dssdev);
+	if (r) {
+		DSSERR("failed to connect output to new device\n");
+		return r;
+	}
+
+	mgr = omap_dss_get_overlay_manager(dssdev->channel);
+
+	if (mgr->output && !force)
+		return 0;
+
+	if (mgr->output)
+		mgr->unset_output(mgr);
+
+	r = mgr->set_output(mgr, out);
+	if (r) {
+		DSSERR("failed to connect manager to output of new device\n");
+
+		/* remove the output-device connection we just made */
+		omapdss_output_unset_device(out);
+		return r;
+	}
+
+	for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
+		struct omap_overlay *ovl = omap_dss_get_overlay(i);
+
+		if (!ovl->manager || force) {
+			if (ovl->manager)
+				ovl->unset_manager(ovl);
+
+			r = ovl->set_manager(ovl, mgr);
+			if (r) {
+				DSSERR("failed to set initial overlay\n");
+				return r;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static void dss_uninit_connections(struct omap_dss_device *dssdev)
+{
+	if (dssdev->output) {
+		struct omap_overlay_manager *mgr = dssdev->output->manager;
+
+		if (mgr)
+			mgr->unset_output(mgr);
+
+		omapdss_output_unset_device(dssdev->output);
+	}
+}
+
+int dss_init_device(struct platform_device *pdev,
 		struct omap_dss_device *dssdev)
 {
 	struct device_attribute *attr;
-	int i;
-	int r;
+	int i, r;
+	const char *def_disp_name = dss_get_default_display_name();
+	bool force;
+
+	force = def_disp_name && strcmp(def_disp_name, dssdev->name) == 0;
+	dss_init_connections(dssdev, force);
 
 	/* create device sysfs files */
 	i = 0;
 	while ((attr = display_sysfs_attrs[i++]) != NULL) {
 		r = device_create_file(&dssdev->dev, attr);
-		if (r)
+		if (r) {
+			for (i = i - 2; i >= 0; i--) {
+				attr = display_sysfs_attrs[i];
+				device_remove_file(&dssdev->dev, attr);
+			}
+
+			dss_uninit_connections(dssdev);
+
 			DSSERR("failed to create sysfs file\n");
+			return r;
+		}
 	}
 
 	/* create display? sysfs links */
 	r = sysfs_create_link(&pdev->dev.kobj, &dssdev->dev.kobj,
 			dev_name(&dssdev->dev));
-	if (r)
+	if (r) {
+		while ((attr = display_sysfs_attrs[i++]) != NULL)
+			device_remove_file(&dssdev->dev, attr);
+
+		dss_uninit_connections(dssdev);
+
 		DSSERR("failed to create sysfs display link\n");
+		return r;
+	}
+
+	return 0;
 }
 
 void dss_uninit_device(struct platform_device *pdev,
@@ -349,8 +444,7 @@
 	while ((attr = display_sysfs_attrs[i++]) != NULL)
 		device_remove_file(&dssdev->dev, attr);
 
-	if (dssdev->manager)
-		dssdev->manager->unset_device(dssdev->manager);
+	dss_uninit_connections(dssdev);
 }
 
 static int dss_suspend_device(struct device *dev, void *data)
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 3266be2..56748cf 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -29,17 +29,24 @@
 #include <linux/errno.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
+#include <linux/string.h>
 
 #include <video/omapdss.h>
-#include <plat/cpu.h>
 
 #include "dss.h"
+#include "dss_features.h"
 
 static struct {
 	struct regulator *vdds_dsi_reg;
 	struct platform_device *dsidev;
 
+	struct mutex lock;
+
+	struct omap_video_timings timings;
 	struct dss_lcd_mgr_config mgr_config;
+	int data_lines;
+
+	struct omap_dss_output output;
 } dpi;
 
 static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk)
@@ -121,7 +128,8 @@
 
 static int dpi_set_mode(struct omap_dss_device *dssdev)
 {
-	struct omap_video_timings *t = &dssdev->panel.timings;
+	struct omap_video_timings *t = &dpi.timings;
+	struct omap_overlay_manager *mgr = dssdev->output->manager;
 	int lck_div = 0, pck_div = 0;
 	unsigned long fck = 0;
 	unsigned long pck;
@@ -146,37 +154,44 @@
 		t->pixel_clock = pck;
 	}
 
-	dss_mgr_set_timings(dssdev->manager, t);
+	dss_mgr_set_timings(mgr, t);
 
 	return 0;
 }
 
 static void dpi_config_lcd_manager(struct omap_dss_device *dssdev)
 {
+	struct omap_overlay_manager *mgr = dssdev->output->manager;
+
 	dpi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
 
 	dpi.mgr_config.stallmode = false;
 	dpi.mgr_config.fifohandcheck = false;
 
-	dpi.mgr_config.video_port_width = dssdev->phy.dpi.data_lines;
+	dpi.mgr_config.video_port_width = dpi.data_lines;
 
 	dpi.mgr_config.lcden_sig_polarity = 0;
 
-	dss_mgr_set_lcd_config(dssdev->manager, &dpi.mgr_config);
+	dss_mgr_set_lcd_config(mgr, &dpi.mgr_config);
 }
 
 int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
-	if (cpu_is_omap34xx() && !dpi.vdds_dsi_reg) {
+	mutex_lock(&dpi.lock);
+
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) && !dpi.vdds_dsi_reg) {
 		DSSERR("no VDSS_DSI regulator\n");
-		return -ENODEV;
+		r = -ENODEV;
+		goto err_no_reg;
 	}
 
-	if (dssdev->manager == NULL) {
-		DSSERR("failed to enable display: no manager\n");
-		return -ENODEV;
+	if (out == NULL || out->manager == NULL) {
+		DSSERR("failed to enable display: no output/manager\n");
+		r = -ENODEV;
+		goto err_no_out_mgr;
 	}
 
 	r = omap_dss_start_device(dssdev);
@@ -185,7 +200,7 @@
 		goto err_start_dev;
 	}
 
-	if (cpu_is_omap34xx()) {
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) {
 		r = regulator_enable(dpi.vdds_dsi_reg);
 		if (r)
 			goto err_reg_enable;
@@ -195,6 +210,10 @@
 	if (r)
 		goto err_get_dispc;
 
+	r = dss_dpi_select_source(dssdev->channel);
+	if (r)
+		goto err_src_sel;
+
 	if (dpi_use_dsi_pll(dssdev)) {
 		r = dsi_runtime_get(dpi.dsidev);
 		if (r)
@@ -213,10 +232,12 @@
 
 	mdelay(2);
 
-	r = dss_mgr_enable(dssdev->manager);
+	r = dss_mgr_enable(out->manager);
 	if (r)
 		goto err_mgr_enable;
 
+	mutex_unlock(&dpi.lock);
+
 	return 0;
 
 err_mgr_enable:
@@ -227,20 +248,28 @@
 	if (dpi_use_dsi_pll(dssdev))
 		dsi_runtime_put(dpi.dsidev);
 err_get_dsi:
+err_src_sel:
 	dispc_runtime_put();
 err_get_dispc:
-	if (cpu_is_omap34xx())
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
 		regulator_disable(dpi.vdds_dsi_reg);
 err_reg_enable:
 	omap_dss_stop_device(dssdev);
 err_start_dev:
+err_no_out_mgr:
+err_no_reg:
+	mutex_unlock(&dpi.lock);
 	return r;
 }
 EXPORT_SYMBOL(omapdss_dpi_display_enable);
 
 void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
 {
-	dss_mgr_disable(dssdev->manager);
+	struct omap_overlay_manager *mgr = dssdev->output->manager;
+
+	mutex_lock(&dpi.lock);
+
+	dss_mgr_disable(mgr);
 
 	if (dpi_use_dsi_pll(dssdev)) {
 		dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
@@ -250,44 +279,39 @@
 
 	dispc_runtime_put();
 
-	if (cpu_is_omap34xx())
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
 		regulator_disable(dpi.vdds_dsi_reg);
 
 	omap_dss_stop_device(dssdev);
+
+	mutex_unlock(&dpi.lock);
 }
 EXPORT_SYMBOL(omapdss_dpi_display_disable);
 
-void dpi_set_timings(struct omap_dss_device *dssdev,
-			struct omap_video_timings *timings)
+void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
 {
-	int r;
-
 	DSSDBG("dpi_set_timings\n");
-	dssdev->panel.timings = *timings;
-	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
-		r = dispc_runtime_get();
-		if (r)
-			return;
 
-		dpi_set_mode(dssdev);
+	mutex_lock(&dpi.lock);
 
-		dispc_runtime_put();
-	} else {
-		dss_mgr_set_timings(dssdev->manager, timings);
-	}
+	dpi.timings = *timings;
+
+	mutex_unlock(&dpi.lock);
 }
-EXPORT_SYMBOL(dpi_set_timings);
+EXPORT_SYMBOL(omapdss_dpi_set_timings);
 
 int dpi_check_timings(struct omap_dss_device *dssdev,
 			struct omap_video_timings *timings)
 {
 	int r;
+	struct omap_overlay_manager *mgr = dssdev->output->manager;
 	int lck_div, pck_div;
 	unsigned long fck;
 	unsigned long pck;
 	struct dispc_clock_info dispc_cinfo;
 
-	if (dss_mgr_check_timings(dssdev->manager, timings))
+	if (dss_mgr_check_timings(mgr, timings))
 		return -EINVAL;
 
 	if (timings->pixel_clock == 0)
@@ -325,11 +349,22 @@
 }
 EXPORT_SYMBOL(dpi_check_timings);
 
+void omapdss_dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
+{
+	mutex_lock(&dpi.lock);
+
+	dpi.data_lines = data_lines;
+
+	mutex_unlock(&dpi.lock);
+}
+EXPORT_SYMBOL(omapdss_dpi_set_data_lines);
+
 static int __init dpi_init_display(struct omap_dss_device *dssdev)
 {
 	DSSDBG("init_display\n");
 
-	if (cpu_is_omap34xx() && dpi.vdds_dsi_reg == NULL) {
+	if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) &&
+					dpi.vdds_dsi_reg == NULL) {
 		struct regulator *vdds_dsi;
 
 		vdds_dsi = dss_get_vdds_dsi();
@@ -351,10 +386,14 @@
 	return 0;
 }
 
-static void __init dpi_probe_pdata(struct platform_device *pdev)
+static struct omap_dss_device * __init dpi_find_dssdev(struct platform_device *pdev)
 {
 	struct omap_dss_board_info *pdata = pdev->dev.platform_data;
-	int i, r;
+	const char *def_disp_name = dss_get_default_display_name();
+	struct omap_dss_device *def_dssdev;
+	int i;
+
+	def_dssdev = NULL;
 
 	for (i = 0; i < pdata->num_devices; ++i) {
 		struct omap_dss_device *dssdev = pdata->devices[i];
@@ -362,21 +401,75 @@
 		if (dssdev->type != OMAP_DISPLAY_TYPE_DPI)
 			continue;
 
-		r = dpi_init_display(dssdev);
-		if (r) {
-			DSSERR("device %s init failed: %d\n", dssdev->name, r);
-			continue;
-		}
+		if (def_dssdev == NULL)
+			def_dssdev = dssdev;
 
-		r = omap_dss_register_device(dssdev, &pdev->dev, i);
-		if (r)
-			DSSERR("device %s register failed: %d\n",
-					dssdev->name, r);
+		if (def_disp_name != NULL &&
+				strcmp(dssdev->name, def_disp_name) == 0) {
+			def_dssdev = dssdev;
+			break;
+		}
 	}
+
+	return def_dssdev;
+}
+
+static void __init dpi_probe_pdata(struct platform_device *dpidev)
+{
+	struct omap_dss_device *plat_dssdev;
+	struct omap_dss_device *dssdev;
+	int r;
+
+	plat_dssdev = dpi_find_dssdev(dpidev);
+
+	if (!plat_dssdev)
+		return;
+
+	dssdev = dss_alloc_and_init_device(&dpidev->dev);
+	if (!dssdev)
+		return;
+
+	dss_copy_device_pdata(dssdev, plat_dssdev);
+
+	r = dpi_init_display(dssdev);
+	if (r) {
+		DSSERR("device %s init failed: %d\n", dssdev->name, r);
+		dss_put_device(dssdev);
+		return;
+	}
+
+	r = dss_add_device(dssdev);
+	if (r) {
+		DSSERR("device %s register failed: %d\n", dssdev->name, r);
+		dss_put_device(dssdev);
+		return;
+	}
+}
+
+static void __init dpi_init_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out = &dpi.output;
+
+	out->pdev = pdev;
+	out->id = OMAP_DSS_OUTPUT_DPI;
+	out->type = OMAP_DISPLAY_TYPE_DPI;
+
+	dss_register_output(out);
+}
+
+static void __exit dpi_uninit_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out = &dpi.output;
+
+	dss_unregister_output(out);
 }
 
 static int __init omap_dpi_probe(struct platform_device *pdev)
 {
+	mutex_init(&dpi.lock);
+
+	dpi_init_output(pdev);
+
 	dpi_probe_pdata(pdev);
 
 	return 0;
@@ -384,7 +477,9 @@
 
 static int __exit omap_dpi_remove(struct platform_device *pdev)
 {
-	omap_dss_unregister_child_devices(&pdev->dev);
+	dss_unregister_child_devices(&pdev->dev);
+
+	dpi_uninit_output(pdev);
 
 	return 0;
 }
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 05ee046..d64ac38 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -41,7 +41,6 @@
 
 #include <video/omapdss.h>
 #include <video/mipi_display.h>
-#include <plat/clock.h>
 
 #include "dss.h"
 #include "dss_features.h"
@@ -333,6 +332,12 @@
 	unsigned scp_clk_refcount;
 
 	struct dss_lcd_mgr_config mgr_config;
+	struct omap_video_timings timings;
+	enum omap_dss_dsi_pixel_format pix_fmt;
+	enum omap_dss_dsi_mode mode;
+	struct omap_dss_dsi_videomode_timings vm_timings;
+
+	struct omap_dss_output output;
 };
 
 struct dsi_packet_sent_handler_data {
@@ -340,8 +345,6 @@
 	struct completion *completion;
 };
 
-static struct platform_device *dsi_pdev_map[MAX_NUM_DSI];
-
 #ifdef DEBUG
 static bool dsi_perf;
 module_param(dsi_perf, bool, 0644);
@@ -354,12 +357,19 @@
 
 static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss_device *dssdev)
 {
-	return dsi_pdev_map[dssdev->phy.dsi.module];
+	return dssdev->output->pdev;
 }
 
 struct platform_device *dsi_get_dsidev_from_id(int module)
 {
-	return dsi_pdev_map[module];
+	struct omap_dss_output *out;
+	enum omap_dss_output_id	id;
+
+	id = module == 0 ? OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
+
+	out = omap_dss_get_output(id);
+
+	return out->pdev;
 }
 
 static inline void dsi_write_reg(struct platform_device *dsidev,
@@ -1450,6 +1460,148 @@
 	return 0;
 }
 
+static int dsi_pll_calc_ddrfreq(struct platform_device *dsidev,
+		unsigned long req_clkin4ddr, struct dsi_clock_info *cinfo)
+{
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	struct dsi_clock_info cur, best;
+
+	DSSDBG("dsi_pll_calc_ddrfreq\n");
+
+	memset(&best, 0, sizeof(best));
+	memset(&cur, 0, sizeof(cur));
+
+	cur.clkin = clk_get_rate(dsi->sys_clk);
+
+	for (cur.regn = 1; cur.regn < dsi->regn_max; ++cur.regn) {
+		cur.fint = cur.clkin / cur.regn;
+
+		if (cur.fint > dsi->fint_max || cur.fint < dsi->fint_min)
+			continue;
+
+		/* DSIPHY(MHz) = (2 * regm / regn) * clkin */
+		for (cur.regm = 1; cur.regm < dsi->regm_max; ++cur.regm) {
+			unsigned long a, b;
+
+			a = 2 * cur.regm * (cur.clkin/1000);
+			b = cur.regn;
+			cur.clkin4ddr = a / b * 1000;
+
+			if (cur.clkin4ddr > 1800 * 1000 * 1000)
+				break;
+
+			if (abs(cur.clkin4ddr - req_clkin4ddr) <
+					abs(best.clkin4ddr - req_clkin4ddr)) {
+				best = cur;
+				DSSDBG("best %ld\n", best.clkin4ddr);
+			}
+
+			if (cur.clkin4ddr == req_clkin4ddr)
+				goto found;
+		}
+	}
+found:
+	if (cinfo)
+		*cinfo = best;
+
+	return 0;
+}
+
+static void dsi_pll_calc_dsi_fck(struct platform_device *dsidev,
+		struct dsi_clock_info *cinfo)
+{
+	unsigned long max_dsi_fck;
+
+	max_dsi_fck = dss_feat_get_param_max(FEAT_PARAM_DSI_FCK);
+
+	cinfo->regm_dsi = DIV_ROUND_UP(cinfo->clkin4ddr, max_dsi_fck);
+	cinfo->dsi_pll_hsdiv_dsi_clk = cinfo->clkin4ddr / cinfo->regm_dsi;
+}
+
+static int dsi_pll_calc_dispc_fck(struct platform_device *dsidev,
+		unsigned long req_pck, struct dsi_clock_info *cinfo,
+		struct dispc_clock_info *dispc_cinfo)
+{
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	unsigned regm_dispc, best_regm_dispc;
+	unsigned long dispc_clk, best_dispc_clk;
+	int min_fck_per_pck;
+	unsigned long max_dss_fck;
+	struct dispc_clock_info best_dispc;
+	bool match;
+
+	max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
+
+	min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK;
+
+	if (min_fck_per_pck &&
+			req_pck * min_fck_per_pck > max_dss_fck) {
+		DSSERR("Requested pixel clock not possible with the current "
+				"OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning "
+				"the constraint off.\n");
+		min_fck_per_pck = 0;
+	}
+
+retry:
+	best_regm_dispc = 0;
+	best_dispc_clk = 0;
+	memset(&best_dispc, 0, sizeof(best_dispc));
+	match = false;
+
+	for (regm_dispc = 1; regm_dispc < dsi->regm_dispc_max; ++regm_dispc) {
+		struct dispc_clock_info cur_dispc;
+
+		dispc_clk = cinfo->clkin4ddr / regm_dispc;
+
+		/* this will narrow down the search a bit,
+		 * but still give pixclocks below what was
+		 * requested */
+		if (dispc_clk  < req_pck)
+			break;
+
+		if (dispc_clk > max_dss_fck)
+			continue;
+
+		if (min_fck_per_pck && dispc_clk < req_pck * min_fck_per_pck)
+			continue;
+
+		match = true;
+
+		dispc_find_clk_divs(req_pck, dispc_clk, &cur_dispc);
+
+		if (abs(cur_dispc.pck - req_pck) <
+				abs(best_dispc.pck - req_pck)) {
+			best_regm_dispc = regm_dispc;
+			best_dispc_clk = dispc_clk;
+			best_dispc = cur_dispc;
+
+			if (cur_dispc.pck == req_pck)
+				goto found;
+		}
+	}
+
+	if (!match) {
+		if (min_fck_per_pck) {
+			DSSERR("Could not find suitable clock settings.\n"
+					"Turning FCK/PCK constraint off and"
+					"trying again.\n");
+			min_fck_per_pck = 0;
+			goto retry;
+		}
+
+		DSSERR("Could not find suitable clock settings.\n");
+
+		return -EINVAL;
+	}
+found:
+	cinfo->regm_dispc = best_regm_dispc;
+	cinfo->dsi_pll_hsdiv_dispc_clk = best_dispc_clk;
+
+	*dispc_cinfo = best_dispc;
+
+	return 0;
+}
+
 int dsi_pll_set_clock_div(struct platform_device *dsidev,
 		struct dsi_clock_info *cinfo)
 {
@@ -1526,21 +1678,27 @@
 
 	BUG_ON(cinfo->fint < dsi->fint_min || cinfo->fint > dsi->fint_max);
 
+	l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2);
+
 	if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) {
 		f = cinfo->fint < 1000000 ? 0x3 :
 			cinfo->fint < 1250000 ? 0x4 :
 			cinfo->fint < 1500000 ? 0x5 :
 			cinfo->fint < 1750000 ? 0x6 :
 			0x7;
+
+		l = FLD_MOD(l, f, 4, 1);	/* DSI_PLL_FREQSEL */
+	} else if (dss_has_feature(FEAT_DSI_PLL_SELFREQDCO)) {
+		f = cinfo->clkin4ddr < 1000000000 ? 0x2 : 0x4;
+
+		l = FLD_MOD(l, f, 4, 1);	/* PLL_SELFREQDCO */
 	}
 
-	l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2);
-
-	if (dss_has_feature(FEAT_DSI_PLL_FREQSEL))
-		l = FLD_MOD(l, f, 4, 1);	/* DSI_PLL_FREQSEL */
 	l = FLD_MOD(l, 1, 13, 13);		/* DSI_PLL_REFEN */
 	l = FLD_MOD(l, 0, 14, 14);		/* DSIPHY_CLKINEN */
 	l = FLD_MOD(l, 1, 20, 20);		/* DSI_HSDIVBYPASS */
+	if (dss_has_feature(FEAT_DSI_PLL_REFSEL))
+		l = FLD_MOD(l, 3, 22, 21);	/* REF_SYSCLK = sysclk */
 	dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION2, l);
 
 	REG_FLD_MOD(dsidev, DSI_PLL_GO, 1, 0, 0);	/* DSI_PLL_GO */
@@ -2004,15 +2162,16 @@
 		return 1194 * 3;	/* 1194x24 bits */
 	case 6:
 		return 1365 * 3;	/* 1365x24 bits */
+	case 7:
+		return 1920 * 3;	/* 1920x24 bits */
 	default:
 		BUG();
 		return 0;
 	}
 }
 
-static int dsi_set_lane_config(struct omap_dss_device *dssdev)
+static int dsi_set_lane_config(struct platform_device *dsidev)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 	static const u8 offsets[] = { 0, 4, 8, 12, 16 };
 	static const enum dsi_lane_function functions[] = {
@@ -2136,9 +2295,16 @@
 	dsi_write_reg(dsidev, DSI_DSIPHY_CFG0, r);
 
 	r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG1);
-	r = FLD_MOD(r, tlpx_half, 22, 16);
+	r = FLD_MOD(r, tlpx_half, 20, 16);
 	r = FLD_MOD(r, tclk_trail, 15, 8);
 	r = FLD_MOD(r, tclk_zero, 7, 0);
+
+	if (dss_has_feature(FEAT_DSI_PHY_DCC)) {
+		r = FLD_MOD(r, 0, 21, 21);	/* DCCEN = disable */
+		r = FLD_MOD(r, 1, 22, 22);	/* CLKINP_DIVBY2EN = enable */
+		r = FLD_MOD(r, 1, 23, 23);	/* CLKINP_SEL = enable */
+	}
+
 	dsi_write_reg(dsidev, DSI_DSIPHY_CFG1, r);
 
 	r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG2);
@@ -2147,10 +2313,9 @@
 }
 
 /* lane masks have lane 0 at lsb. mask_p for positive lines, n for negative */
-static void dsi_cio_enable_lane_override(struct omap_dss_device *dssdev,
+static void dsi_cio_enable_lane_override(struct platform_device *dsidev,
 		unsigned mask_p, unsigned mask_n)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 	int i;
 	u32 l;
@@ -2197,9 +2362,8 @@
 	REG_FLD_MOD(dsidev, DSI_DSIPHY_CFG10, 0, 22, 17);
 }
 
-static int dsi_cio_wait_tx_clk_esc_reset(struct omap_dss_device *dssdev)
+static int dsi_cio_wait_tx_clk_esc_reset(struct platform_device *dsidev)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 	int t, i;
 	bool in_use[DSI_MAX_NR_LANES];
@@ -2247,9 +2411,8 @@
 }
 
 /* return bitmask of enabled lanes, lane0 being the lsb */
-static unsigned dsi_get_lane_mask(struct omap_dss_device *dssdev)
+static unsigned dsi_get_lane_mask(struct platform_device *dsidev)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 	unsigned mask = 0;
 	int i;
@@ -2262,16 +2425,15 @@
 	return mask;
 }
 
-static int dsi_cio_init(struct omap_dss_device *dssdev)
+static int dsi_cio_init(struct platform_device *dsidev)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 	int r;
 	u32 l;
 
 	DSSDBGF();
 
-	r = dss_dsi_enable_pads(dsi->module_id, dsi_get_lane_mask(dssdev));
+	r = dss_dsi_enable_pads(dsi->module_id, dsi_get_lane_mask(dsidev));
 	if (r)
 		return r;
 
@@ -2288,7 +2450,7 @@
 		goto err_scp_clk_dom;
 	}
 
-	r = dsi_set_lane_config(dssdev);
+	r = dsi_set_lane_config(dsidev);
 	if (r)
 		goto err_scp_clk_dom;
 
@@ -2323,7 +2485,7 @@
 			mask_p |= 1 << i;
 		}
 
-		dsi_cio_enable_lane_override(dssdev, mask_p, 0);
+		dsi_cio_enable_lane_override(dsidev, mask_p, 0);
 	}
 
 	r = dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ON);
@@ -2340,7 +2502,7 @@
 	dsi_if_enable(dsidev, false);
 	REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 20, 20); /* LP_CLK_ENABLE */
 
-	r = dsi_cio_wait_tx_clk_esc_reset(dssdev);
+	r = dsi_cio_wait_tx_clk_esc_reset(dsidev);
 	if (r)
 		goto err_tx_clk_esc_rst;
 
@@ -2360,10 +2522,10 @@
 
 	dsi_cio_timings(dsidev);
 
-	if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
+	if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
 		/* DDR_CLK_ALWAYS_ON */
 		REG_FLD_MOD(dsidev, DSI_CLK_CTRL,
-			dssdev->panel.dsi_vm_data.ddr_clk_always_on, 13, 13);
+			dsi->vm_timings.ddr_clk_always_on, 13, 13);
 	}
 
 	dsi->ulps_enabled = false;
@@ -2381,13 +2543,12 @@
 		dsi_cio_disable_lane_override(dsidev);
 err_scp_clk_dom:
 	dsi_disable_scp_clk(dsidev);
-	dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dssdev));
+	dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dsidev));
 	return r;
 }
 
-static void dsi_cio_uninit(struct omap_dss_device *dssdev)
+static void dsi_cio_uninit(struct platform_device *dsidev)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	/* DDR_CLK_ALWAYS_ON */
@@ -2395,7 +2556,7 @@
 
 	dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_OFF);
 	dsi_disable_scp_clk(dsidev);
-	dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dssdev));
+	dss_dsi_disable_pads(dsi->module_id, dsi_get_lane_mask(dsidev));
 }
 
 static void dsi_config_tx_fifo(struct platform_device *dsidev,
@@ -2685,6 +2846,7 @@
 		bool enable)
 {
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable);
 
@@ -2701,7 +2863,7 @@
 	dsi_force_tx_stop_mode_io(dsidev);
 
 	/* start the DDR clock by sending a NULL packet */
-	if (dssdev->panel.dsi_vm_data.ddr_clk_always_on && enable)
+	if (dsi->vm_timings.ddr_clk_always_on && enable)
 		dsi_vc_send_null(dssdev, channel);
 }
 EXPORT_SYMBOL(omapdss_dsi_vc_enable_hs);
@@ -2987,10 +3149,9 @@
 }
 EXPORT_SYMBOL(dsi_vc_send_null);
 
-static int dsi_vc_write_nosync_common(struct omap_dss_device *dssdev,
+static int dsi_vc_write_nosync_common(struct platform_device *dsidev,
 		int channel, u8 *data, int len, enum dss_dsi_content_type type)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
 	int r;
 
 	if (len == 0) {
@@ -3021,7 +3182,9 @@
 int dsi_vc_dcs_write_nosync(struct omap_dss_device *dssdev, int channel,
 		u8 *data, int len)
 {
-	return dsi_vc_write_nosync_common(dssdev, channel, data, len,
+	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+
+	return dsi_vc_write_nosync_common(dsidev, channel, data, len,
 			DSS_DSI_CONTENT_DCS);
 }
 EXPORT_SYMBOL(dsi_vc_dcs_write_nosync);
@@ -3029,7 +3192,9 @@
 int dsi_vc_generic_write_nosync(struct omap_dss_device *dssdev, int channel,
 		u8 *data, int len)
 {
-	return dsi_vc_write_nosync_common(dssdev, channel, data, len,
+	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+
+	return dsi_vc_write_nosync_common(dsidev, channel, data, len,
 			DSS_DSI_CONTENT_GENERIC);
 }
 EXPORT_SYMBOL(dsi_vc_generic_write_nosync);
@@ -3040,7 +3205,7 @@
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
 	int r;
 
-	r = dsi_vc_write_nosync_common(dssdev, channel, data, len, type);
+	r = dsi_vc_write_nosync_common(dsidev, channel, data, len, type);
 	if (r)
 		goto err;
 
@@ -3118,10 +3283,9 @@
 }
 EXPORT_SYMBOL(dsi_vc_generic_write_2);
 
-static int dsi_vc_dcs_send_read_request(struct omap_dss_device *dssdev,
+static int dsi_vc_dcs_send_read_request(struct platform_device *dsidev,
 		int channel, u8 dcs_cmd)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 	int r;
 
@@ -3139,10 +3303,9 @@
 	return 0;
 }
 
-static int dsi_vc_generic_send_read_request(struct omap_dss_device *dssdev,
+static int dsi_vc_generic_send_read_request(struct platform_device *dsidev,
 		int channel, u8 *reqdata, int reqlen)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 	u16 data;
 	u8 data_type;
@@ -3291,7 +3454,7 @@
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
 	int r;
 
-	r = dsi_vc_dcs_send_read_request(dssdev, channel, dcs_cmd);
+	r = dsi_vc_dcs_send_read_request(dsidev, channel, dcs_cmd);
 	if (r)
 		goto err;
 
@@ -3322,7 +3485,7 @@
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
 	int r;
 
-	r = dsi_vc_generic_send_read_request(dssdev, channel, reqdata, reqlen);
+	r = dsi_vc_generic_send_read_request(dsidev, channel, reqdata, reqlen);
 	if (r)
 		return r;
 
@@ -3604,15 +3767,15 @@
 			(total_ticks * 1000) / (fck / 1000 / 1000));
 }
 
-static void dsi_config_vp_num_line_buffers(struct omap_dss_device *dssdev)
+static void dsi_config_vp_num_line_buffers(struct platform_device *dsidev)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 	int num_line_buffers;
 
-	if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
-		int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
+	if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
+		int bpp = dsi_get_pixel_size(dsi->pix_fmt);
 		unsigned line_buf_size = dsi_get_line_buf_size(dsidev);
-		struct omap_video_timings *timings = &dssdev->panel.timings;
+		struct omap_video_timings *timings = &dsi->timings;
 		/*
 		 * Don't use line buffers if width is greater than the video
 		 * port's line buffer size
@@ -3630,11 +3793,11 @@
 	REG_FLD_MOD(dsidev, DSI_CTRL, num_line_buffers, 13, 12);
 }
 
-static void dsi_config_vp_sync_events(struct omap_dss_device *dssdev)
+static void dsi_config_vp_sync_events(struct platform_device *dsidev)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
-	bool vsync_end = dssdev->panel.dsi_vm_data.vp_vsync_end;
-	bool hsync_end = dssdev->panel.dsi_vm_data.vp_hsync_end;
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	bool vsync_end = dsi->vm_timings.vp_vsync_end;
+	bool hsync_end = dsi->vm_timings.vp_hsync_end;
 	u32 r;
 
 	r = dsi_read_reg(dsidev, DSI_CTRL);
@@ -3648,13 +3811,13 @@
 	dsi_write_reg(dsidev, DSI_CTRL, r);
 }
 
-static void dsi_config_blanking_modes(struct omap_dss_device *dssdev)
+static void dsi_config_blanking_modes(struct platform_device *dsidev)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
-	int blanking_mode = dssdev->panel.dsi_vm_data.blanking_mode;
-	int hfp_blanking_mode = dssdev->panel.dsi_vm_data.hfp_blanking_mode;
-	int hbp_blanking_mode = dssdev->panel.dsi_vm_data.hbp_blanking_mode;
-	int hsa_blanking_mode = dssdev->panel.dsi_vm_data.hsa_blanking_mode;
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	int blanking_mode = dsi->vm_timings.blanking_mode;
+	int hfp_blanking_mode = dsi->vm_timings.hfp_blanking_mode;
+	int hbp_blanking_mode = dsi->vm_timings.hbp_blanking_mode;
+	int hsa_blanking_mode = dsi->vm_timings.hsa_blanking_mode;
 	u32 r;
 
 	/*
@@ -3741,8 +3904,8 @@
 	int ddr_clk_pre, ddr_clk_post, enter_hs_mode_lat, exit_hs_mode_lat;
 	int tclk_trail, ths_exit, exiths_clk;
 	bool ddr_alwon;
-	struct omap_video_timings *timings = &dssdev->panel.timings;
-	int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
+	struct omap_video_timings *timings = &dsi->timings;
+	int bpp = dsi_get_pixel_size(dsi->pix_fmt);
 	int ndl = dsi->num_lanes_used - 1;
 	int dsi_fclk_hsdiv = dssdev->clocks.dsi.regm_dsi + 1;
 	int hsa_interleave_hs = 0, hsa_interleave_lp = 0;
@@ -3852,6 +4015,7 @@
 static int dsi_proto_config(struct omap_dss_device *dssdev)
 {
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 	u32 r;
 	int buswidth = 0;
 
@@ -3871,7 +4035,7 @@
 	dsi_set_lp_rx_timeout(dsidev, 0x1fff, true, true);
 	dsi_set_hs_tx_timeout(dsidev, 0x1fff, true, true);
 
-	switch (dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt)) {
+	switch (dsi_get_pixel_size(dsi->pix_fmt)) {
 	case 16:
 		buswidth = 0;
 		break;
@@ -3903,11 +4067,11 @@
 
 	dsi_write_reg(dsidev, DSI_CTRL, r);
 
-	dsi_config_vp_num_line_buffers(dssdev);
+	dsi_config_vp_num_line_buffers(dsidev);
 
-	if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
-		dsi_config_vp_sync_events(dssdev);
-		dsi_config_blanking_modes(dssdev);
+	if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
+		dsi_config_vp_sync_events(dsidev);
+		dsi_config_blanking_modes(dsidev);
 		dsi_config_cmd_mode_interleaving(dssdev);
 	}
 
@@ -3919,9 +4083,8 @@
 	return 0;
 }
 
-static void dsi_proto_timings(struct omap_dss_device *dssdev)
+static void dsi_proto_timings(struct platform_device *dsidev)
 {
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 	unsigned tlpx, tclk_zero, tclk_prepare, tclk_trail;
 	unsigned tclk_pre, tclk_post;
@@ -3941,7 +4104,7 @@
 	ths_exit = FLD_GET(r, 7, 0);
 
 	r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG1);
-	tlpx = FLD_GET(r, 22, 16) * 2;
+	tlpx = FLD_GET(r, 20, 16) * 2;
 	tclk_trail = FLD_GET(r, 15, 8);
 	tclk_zero = FLD_GET(r, 7, 0);
 
@@ -3984,18 +4147,18 @@
 	DSSDBG("enter_hs_mode_lat %u, exit_hs_mode_lat %u\n",
 			enter_hs_mode_lat, exit_hs_mode_lat);
 
-	 if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
+	 if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
 		/* TODO: Implement a video mode check_timings function */
-		int hsa = dssdev->panel.dsi_vm_data.hsa;
-		int hfp = dssdev->panel.dsi_vm_data.hfp;
-		int hbp = dssdev->panel.dsi_vm_data.hbp;
-		int vsa = dssdev->panel.dsi_vm_data.vsa;
-		int vfp = dssdev->panel.dsi_vm_data.vfp;
-		int vbp = dssdev->panel.dsi_vm_data.vbp;
-		int window_sync = dssdev->panel.dsi_vm_data.window_sync;
-		bool hsync_end = dssdev->panel.dsi_vm_data.vp_hsync_end;
-		struct omap_video_timings *timings = &dssdev->panel.timings;
-		int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
+		int hsa = dsi->vm_timings.hsa;
+		int hfp = dsi->vm_timings.hfp;
+		int hbp = dsi->vm_timings.hbp;
+		int vsa = dsi->vm_timings.vsa;
+		int vfp = dsi->vm_timings.vfp;
+		int vbp = dsi->vm_timings.vbp;
+		int window_sync = dsi->vm_timings.window_sync;
+		bool hsync_end = dsi->vm_timings.vp_hsync_end;
+		struct omap_video_timings *timings = &dsi->timings;
+		int bpp = dsi_get_pixel_size(dsi->pix_fmt);
 		int tl, t_he, width_bytes;
 
 		t_he = hsync_end ?
@@ -4100,16 +4263,84 @@
 }
 EXPORT_SYMBOL(omapdss_dsi_configure_pins);
 
+int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev,
+		unsigned long ddr_clk, unsigned long lp_clk)
+{
+	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	struct dsi_clock_info cinfo;
+	struct dispc_clock_info dispc_cinfo;
+	unsigned lp_clk_div;
+	unsigned long dsi_fclk;
+	int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
+	unsigned long pck;
+	int r;
+
+	DSSDBGF("ddr_clk %lu, lp_clk %lu", ddr_clk, lp_clk);
+
+	mutex_lock(&dsi->lock);
+
+	/* Calculate PLL output clock */
+	r = dsi_pll_calc_ddrfreq(dsidev, ddr_clk * 4, &cinfo);
+	if (r)
+		goto err;
+
+	/* Calculate PLL's DSI clock */
+	dsi_pll_calc_dsi_fck(dsidev, &cinfo);
+
+	/* Calculate PLL's DISPC clock and pck & lck divs */
+	pck = cinfo.clkin4ddr / 16 * (dsi->num_lanes_used - 1) * 8 / bpp;
+	DSSDBG("finding dispc dividers for pck %lu\n", pck);
+	r = dsi_pll_calc_dispc_fck(dsidev, pck, &cinfo, &dispc_cinfo);
+	if (r)
+		goto err;
+
+	/* Calculate LP clock */
+	dsi_fclk = cinfo.dsi_pll_hsdiv_dsi_clk;
+	lp_clk_div = DIV_ROUND_UP(dsi_fclk, lp_clk * 2);
+
+	dssdev->clocks.dsi.regn = cinfo.regn;
+	dssdev->clocks.dsi.regm = cinfo.regm;
+	dssdev->clocks.dsi.regm_dispc = cinfo.regm_dispc;
+	dssdev->clocks.dsi.regm_dsi = cinfo.regm_dsi;
+
+	dssdev->clocks.dsi.lp_clk_div = lp_clk_div;
+
+	dssdev->clocks.dispc.channel.lck_div = dispc_cinfo.lck_div;
+	dssdev->clocks.dispc.channel.pck_div = dispc_cinfo.pck_div;
+
+	dssdev->clocks.dispc.dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK;
+
+	dssdev->clocks.dispc.channel.lcd_clk_src =
+		dsi->module_id == 0 ?
+		OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC :
+		OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC;
+
+	dssdev->clocks.dsi.dsi_fclk_src =
+		dsi->module_id == 0 ?
+		OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI :
+		OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI;
+
+	mutex_unlock(&dsi->lock);
+	return 0;
+err:
+	mutex_unlock(&dsi->lock);
+	return r;
+}
+EXPORT_SYMBOL(omapdss_dsi_set_clocks);
+
 int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
 {
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
-	int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	struct omap_overlay_manager *mgr = dssdev->output->manager;
+	int bpp = dsi_get_pixel_size(dsi->pix_fmt);
 	u8 data_type;
 	u16 word_count;
 	int r;
 
-	if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
-		switch (dssdev->panel.dsi_pix_fmt) {
+	if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
+		switch (dsi->pix_fmt) {
 		case OMAP_DSS_DSI_FMT_RGB888:
 			data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24;
 			break;
@@ -4133,7 +4364,7 @@
 		/* MODE, 1 = video mode */
 		REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 4, 4);
 
-		word_count = DIV_ROUND_UP(dssdev->panel.timings.x_res * bpp, 8);
+		word_count = DIV_ROUND_UP(dsi->timings.x_res * bpp, 8);
 
 		dsi_vc_write_long_header(dsidev, channel, data_type,
 				word_count, 0);
@@ -4142,9 +4373,9 @@
 		dsi_if_enable(dsidev, true);
 	}
 
-	r = dss_mgr_enable(dssdev->manager);
+	r = dss_mgr_enable(mgr);
 	if (r) {
-		if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
+		if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
 			dsi_if_enable(dsidev, false);
 			dsi_vc_enable(dsidev, channel, false);
 		}
@@ -4159,8 +4390,10 @@
 void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel)
 {
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	struct omap_overlay_manager *mgr = dssdev->output->manager;
 
-	if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
+	if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
 		dsi_if_enable(dsidev, false);
 		dsi_vc_enable(dsidev, channel, false);
 
@@ -4171,15 +4404,15 @@
 		dsi_if_enable(dsidev, true);
 	}
 
-	dss_mgr_disable(dssdev->manager);
+	dss_mgr_disable(mgr);
 }
 EXPORT_SYMBOL(dsi_disable_video_output);
 
-static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
-		u16 w, u16 h)
+static void dsi_update_screen_dispc(struct omap_dss_device *dssdev)
 {
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	struct omap_overlay_manager *mgr = dssdev->output->manager;
 	unsigned bytespp;
 	unsigned bytespl;
 	unsigned bytespf;
@@ -4190,12 +4423,14 @@
 	int r;
 	const unsigned channel = dsi->update_channel;
 	const unsigned line_buf_size = dsi_get_line_buf_size(dsidev);
+	u16 w = dsi->timings.x_res;
+	u16 h = dsi->timings.y_res;
 
 	DSSDBG("dsi_update_screen_dispc(%dx%d)\n", w, h);
 
 	dsi_vc_config_source(dsidev, channel, DSI_VC_SOURCE_VP);
 
-	bytespp	= dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) / 8;
+	bytespp	= dsi_get_pixel_size(dsi->pix_fmt) / 8;
 	bytespl = w * bytespp;
 	bytespf = bytespl * h;
 
@@ -4239,7 +4474,9 @@
 		msecs_to_jiffies(250));
 	BUG_ON(r == 0);
 
-	dss_mgr_start_update(dssdev->manager);
+	dss_mgr_set_timings(mgr, &dsi->timings);
+
+	dss_mgr_start_update(mgr);
 
 	if (dsi->te_enabled) {
 		/* disable LP_RX_TO, so that we can receive TE.  Time to wait
@@ -4297,8 +4534,7 @@
 
 static void dsi_framedone_irq_callback(void *data, u32 mask)
 {
-	struct omap_dss_device *dssdev = (struct omap_dss_device *) data;
-	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct platform_device *dsidev = (struct platform_device *) data;
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
 	/* Note: We get FRAMEDONE when DISPC has finished sending pixels and
@@ -4325,13 +4561,14 @@
 	dsi->framedone_callback = callback;
 	dsi->framedone_data = data;
 
-	dssdev->driver->get_resolution(dssdev, &dw, &dh);
+	dw = dsi->timings.x_res;
+	dh = dsi->timings.y_res;
 
 #ifdef DEBUG
 	dsi->update_bytes = dw * dh *
-		dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) / 8;
+		dsi_get_pixel_size(dsi->pix_fmt) / 8;
 #endif
-	dsi_update_screen_dispc(dssdev, dw, dh);
+	dsi_update_screen_dispc(dssdev);
 
 	return 0;
 }
@@ -4367,28 +4604,22 @@
 {
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
-	struct omap_video_timings timings;
+	struct omap_overlay_manager *mgr = dssdev->output->manager;
 	int r;
 	u32 irq = 0;
 
-	if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) {
-		u16 dw, dh;
+	if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) {
+		dsi->timings.hsw = 1;
+		dsi->timings.hfp = 1;
+		dsi->timings.hbp = 1;
+		dsi->timings.vsw = 1;
+		dsi->timings.vfp = 0;
+		dsi->timings.vbp = 0;
 
-		dssdev->driver->get_resolution(dssdev, &dw, &dh);
-
-		timings.x_res = dw;
-		timings.y_res = dh;
-		timings.hsw = 1;
-		timings.hfp = 1;
-		timings.hbp = 1;
-		timings.vsw = 1;
-		timings.vfp = 0;
-		timings.vbp = 0;
-
-		irq = dispc_mgr_get_framedone_irq(dssdev->manager->id);
+		irq = dispc_mgr_get_framedone_irq(mgr->id);
 
 		r = omap_dispc_register_isr(dsi_framedone_irq_callback,
-			(void *) dssdev, irq);
+			(void *) dsidev, irq);
 		if (r) {
 			DSSERR("can't get FRAMEDONE irq\n");
 			goto err;
@@ -4397,8 +4628,6 @@
 		dsi->mgr_config.stallmode = true;
 		dsi->mgr_config.fifohandcheck = true;
 	} else {
-		timings = dssdev->panel.timings;
-
 		dsi->mgr_config.stallmode = false;
 		dsi->mgr_config.fifohandcheck = false;
 	}
@@ -4407,14 +4636,14 @@
 	 * override interlace, logic level and edge related parameters in
 	 * omap_video_timings with default values
 	 */
-	timings.interlace = false;
-	timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
-	timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
-	timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
-	timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
-	timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
+	dsi->timings.interlace = false;
+	dsi->timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
+	dsi->timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
+	dsi->timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
+	dsi->timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
+	dsi->timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
 
-	dss_mgr_set_timings(dssdev->manager, &timings);
+	dss_mgr_set_timings(mgr, &dsi->timings);
 
 	r = dsi_configure_dispc_clocks(dssdev);
 	if (r)
@@ -4422,29 +4651,33 @@
 
 	dsi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
 	dsi->mgr_config.video_port_width =
-			dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
+			dsi_get_pixel_size(dsi->pix_fmt);
 	dsi->mgr_config.lcden_sig_polarity = 0;
 
-	dss_mgr_set_lcd_config(dssdev->manager, &dsi->mgr_config);
+	dss_mgr_set_lcd_config(mgr, &dsi->mgr_config);
 
 	return 0;
 err1:
-	if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE)
+	if (dsi->mode == OMAP_DSS_DSI_CMD_MODE)
 		omap_dispc_unregister_isr(dsi_framedone_irq_callback,
-			(void *) dssdev, irq);
+			(void *) dsidev, irq);
 err:
 	return r;
 }
 
 static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev)
 {
-	if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) {
+	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	struct omap_overlay_manager *mgr = dssdev->output->manager;
+
+	if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) {
 		u32 irq;
 
-		irq = dispc_mgr_get_framedone_irq(dssdev->manager->id);
+		irq = dispc_mgr_get_framedone_irq(mgr->id);
 
 		omap_dispc_unregister_isr(dsi_framedone_irq_callback,
-			(void *) dssdev, irq);
+			(void *) dsidev, irq);
 	}
 }
 
@@ -4477,6 +4710,7 @@
 {
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	struct omap_overlay_manager *mgr = dssdev->output->manager;
 	int r;
 
 	r = dsi_pll_init(dsidev, true, true);
@@ -4489,18 +4723,18 @@
 
 	dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src);
 	dss_select_dsi_clk_source(dsi->module_id, dssdev->clocks.dsi.dsi_fclk_src);
-	dss_select_lcd_clk_source(dssdev->manager->id,
+	dss_select_lcd_clk_source(mgr->id,
 			dssdev->clocks.dispc.channel.lcd_clk_src);
 
 	DSSDBG("PLL OK\n");
 
-	r = dsi_cio_init(dssdev);
+	r = dsi_cio_init(dsidev);
 	if (r)
 		goto err2;
 
 	_dsi_print_reset_status(dsidev);
 
-	dsi_proto_timings(dssdev);
+	dsi_proto_timings(dsidev);
 	dsi_set_lp_clk_divisor(dssdev);
 
 	if (1)
@@ -4520,11 +4754,11 @@
 
 	return 0;
 err3:
-	dsi_cio_uninit(dssdev);
+	dsi_cio_uninit(dsidev);
 err2:
 	dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
 	dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
-	dss_select_lcd_clk_source(dssdev->manager->id, OMAP_DSS_CLK_SRC_FCK);
+	dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);
 
 err1:
 	dsi_pll_uninit(dsidev, true);
@@ -4537,6 +4771,7 @@
 {
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	struct omap_overlay_manager *mgr = dssdev->output->manager;
 
 	if (enter_ulps && !dsi->ulps_enabled)
 		dsi_enter_ulps(dsidev);
@@ -4550,8 +4785,8 @@
 
 	dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
 	dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
-	dss_select_lcd_clk_source(dssdev->manager->id, OMAP_DSS_CLK_SRC_FCK);
-	dsi_cio_uninit(dssdev);
+	dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);
+	dsi_cio_uninit(dsidev);
 	dsi_pll_uninit(dsidev, disconnect_lanes);
 }
 
@@ -4559,6 +4794,7 @@
 {
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	struct omap_dss_output *out = dssdev->output;
 	int r = 0;
 
 	DSSDBG("dsi_display_enable\n");
@@ -4567,8 +4803,8 @@
 
 	mutex_lock(&dsi->lock);
 
-	if (dssdev->manager == NULL) {
-		DSSERR("failed to enable display: no manager\n");
+	if (out == NULL || out->manager == NULL) {
+		DSSERR("failed to enable display: no output/manager\n");
 		r = -ENODEV;
 		goto err_start_dev;
 	}
@@ -4653,17 +4889,83 @@
 }
 EXPORT_SYMBOL(omapdss_dsi_enable_te);
 
-static int __init dsi_init_display(struct omap_dss_device *dssdev)
+void omapdss_dsi_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
 {
 	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
 
-	DSSDBG("DSI init\n");
+	mutex_lock(&dsi->lock);
 
-	if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) {
-		dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
-			OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
-	}
+	dsi->timings = *timings;
+
+	mutex_unlock(&dsi->lock);
+}
+EXPORT_SYMBOL(omapdss_dsi_set_timings);
+
+void omapdss_dsi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h)
+{
+	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+
+	mutex_lock(&dsi->lock);
+
+	dsi->timings.x_res = w;
+	dsi->timings.y_res = h;
+
+	mutex_unlock(&dsi->lock);
+}
+EXPORT_SYMBOL(omapdss_dsi_set_size);
+
+void omapdss_dsi_set_pixel_format(struct omap_dss_device *dssdev,
+		enum omap_dss_dsi_pixel_format fmt)
+{
+	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+
+	mutex_lock(&dsi->lock);
+
+	dsi->pix_fmt = fmt;
+
+	mutex_unlock(&dsi->lock);
+}
+EXPORT_SYMBOL(omapdss_dsi_set_pixel_format);
+
+void omapdss_dsi_set_operation_mode(struct omap_dss_device *dssdev,
+		enum omap_dss_dsi_mode mode)
+{
+	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+
+	mutex_lock(&dsi->lock);
+
+	dsi->mode = mode;
+
+	mutex_unlock(&dsi->lock);
+}
+EXPORT_SYMBOL(omapdss_dsi_set_operation_mode);
+
+void omapdss_dsi_set_videomode_timings(struct omap_dss_device *dssdev,
+		struct omap_dss_dsi_videomode_timings *timings)
+{
+	struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+
+	mutex_lock(&dsi->lock);
+
+	dsi->vm_timings = *timings;
+
+	mutex_unlock(&dsi->lock);
+}
+EXPORT_SYMBOL(omapdss_dsi_set_videomode_timings);
+
+static int __init dsi_init_display(struct omap_dss_device *dssdev)
+{
+	struct platform_device *dsidev =
+			dsi_get_dsidev_from_id(dssdev->phy.dsi.module);
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+
+	DSSDBG("DSI init\n");
 
 	if (dsi->vdds_dsi_reg == NULL) {
 		struct regulator *vdds_dsi;
@@ -4806,11 +5108,15 @@
 		clk_put(dsi->sys_clk);
 }
 
-static void __init dsi_probe_pdata(struct platform_device *dsidev)
+static struct omap_dss_device * __init dsi_find_dssdev(struct platform_device *pdev)
 {
-	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
-	struct omap_dss_board_info *pdata = dsidev->dev.platform_data;
-	int i, r;
+	struct omap_dss_board_info *pdata = pdev->dev.platform_data;
+	struct dsi_data *dsi = dsi_get_dsidrv_data(pdev);
+	const char *def_disp_name = dss_get_default_display_name();
+	struct omap_dss_device *def_dssdev;
+	int i;
+
+	def_dssdev = NULL;
 
 	for (i = 0; i < pdata->num_devices; ++i) {
 		struct omap_dss_device *dssdev = pdata->devices[i];
@@ -4821,17 +5127,71 @@
 		if (dssdev->phy.dsi.module != dsi->module_id)
 			continue;
 
-		r = dsi_init_display(dssdev);
-		if (r) {
-			DSSERR("device %s init failed: %d\n", dssdev->name, r);
-			continue;
-		}
+		if (def_dssdev == NULL)
+			def_dssdev = dssdev;
 
-		r = omap_dss_register_device(dssdev, &dsidev->dev, i);
-		if (r)
-			DSSERR("device %s register failed: %d\n",
-					dssdev->name, r);
+		if (def_disp_name != NULL &&
+				strcmp(dssdev->name, def_disp_name) == 0) {
+			def_dssdev = dssdev;
+			break;
+		}
 	}
+
+	return def_dssdev;
+}
+
+static void __init dsi_probe_pdata(struct platform_device *dsidev)
+{
+	struct omap_dss_device *plat_dssdev;
+	struct omap_dss_device *dssdev;
+	int r;
+
+	plat_dssdev = dsi_find_dssdev(dsidev);
+
+	if (!plat_dssdev)
+		return;
+
+	dssdev = dss_alloc_and_init_device(&dsidev->dev);
+	if (!dssdev)
+		return;
+
+	dss_copy_device_pdata(dssdev, plat_dssdev);
+
+	r = dsi_init_display(dssdev);
+	if (r) {
+		DSSERR("device %s init failed: %d\n", dssdev->name, r);
+		dss_put_device(dssdev);
+		return;
+	}
+
+	r = dss_add_device(dssdev);
+	if (r) {
+		DSSERR("device %s register failed: %d\n", dssdev->name, r);
+		dss_put_device(dssdev);
+		return;
+	}
+}
+
+static void __init dsi_init_output(struct platform_device *dsidev)
+{
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	struct omap_dss_output *out = &dsi->output;
+
+	out->pdev = dsidev;
+	out->id = dsi->module_id == 0 ?
+			OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
+
+	out->type = OMAP_DISPLAY_TYPE_DSI;
+
+	dss_register_output(out);
+}
+
+static void __exit dsi_uninit_output(struct platform_device *dsidev)
+{
+	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	struct omap_dss_output *out = &dsi->output;
+
+	dss_unregister_output(out);
 }
 
 /* DSI1 HW IP initialisation */
@@ -4848,7 +5208,6 @@
 
 	dsi->module_id = dsidev->id;
 	dsi->pdev = dsidev;
-	dsi_pdev_map[dsi->module_id] = dsidev;
 	dev_set_drvdata(&dsidev->dev, dsi);
 
 	spin_lock_init(&dsi->irq_lock);
@@ -4928,6 +5287,8 @@
 	else
 		dsi->num_lanes_supported = 3;
 
+	dsi_init_output(dsidev);
+
 	dsi_probe_pdata(dsidev);
 
 	dsi_runtime_put(dsidev);
@@ -4957,7 +5318,9 @@
 
 	WARN_ON(dsi->scp_clk_refcount > 0);
 
-	omap_dss_unregister_child_devices(&dsidev->dev);
+	dss_unregister_child_devices(&dsidev->dev);
+
+	dsi_uninit_output(dsidev);
 
 	pm_runtime_disable(&dsidev->dev);
 
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 04b4586..2ab1c3e 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -31,11 +31,11 @@
 #include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/gfp.h>
 
 #include <video/omapdss.h>
 
 #include <plat/cpu.h>
-#include <plat/clock.h>
 
 #include "dss.h"
 #include "dss_features.h"
@@ -65,6 +65,13 @@
 static int dss_runtime_get(void);
 static void dss_runtime_put(void);
 
+struct dss_features {
+	u8 fck_div_max;
+	u8 dss_fck_multiplier;
+	const char *clk_name;
+	int (*dpi_select_source)(enum omap_channel channel);
+};
+
 static struct {
 	struct platform_device *pdev;
 	void __iomem    *base;
@@ -83,6 +90,8 @@
 
 	bool		ctx_valid;
 	u32		ctx[DSS_SZ_REGS / sizeof(u32)];
+
+	const struct dss_features *feat;
 } dss;
 
 static const char * const dss_generic_clk_source_names[] = {
@@ -144,7 +153,7 @@
 #undef SR
 #undef RR
 
-void dss_sdi_init(u8 datapairs)
+void dss_sdi_init(int datapairs)
 {
 	u32 l;
 
@@ -236,7 +245,6 @@
 	return dss_generic_clk_source_names[clk_src];
 }
 
-
 void dss_dump_clocks(struct seq_file *s)
 {
 	unsigned long dpll4_ck_rate;
@@ -259,18 +267,10 @@
 
 		seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
 
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			seq_printf(s, "%s (%s) = %lu / %lu  = %lu\n",
-					fclk_name, fclk_real_name,
-					dpll4_ck_rate,
-					dpll4_ck_rate / dpll4_m4_ck_rate,
-					fclk_rate);
-		else
-			seq_printf(s, "%s (%s) = %lu / %lu * 2 = %lu\n",
-					fclk_name, fclk_real_name,
-					dpll4_ck_rate,
-					dpll4_ck_rate / dpll4_m4_ck_rate,
-					fclk_rate);
+		seq_printf(s, "%s (%s) = %lu / %lu * %d  = %lu\n",
+				fclk_name, fclk_real_name, dpll4_ck_rate,
+				dpll4_ck_rate / dpll4_m4_ck_rate,
+				dss.feat->dss_fck_multiplier, fclk_rate);
 	} else {
 		seq_printf(s, "%s (%s) = %lu\n",
 				fclk_name, fclk_real_name,
@@ -431,31 +431,6 @@
 	}
 }
 
-/* calculate clock rates using dividers in cinfo */
-int dss_calc_clock_rates(struct dss_clock_info *cinfo)
-{
-	if (dss.dpll4_m4_ck) {
-		unsigned long prate;
-		u16 fck_div_max = 16;
-
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			fck_div_max = 32;
-
-		if (cinfo->fck_div > fck_div_max || cinfo->fck_div == 0)
-			return -EINVAL;
-
-		prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
-
-		cinfo->fck = prate / cinfo->fck_div;
-	} else {
-		if (cinfo->fck_div != 0)
-			return -EINVAL;
-		cinfo->fck = clk_get_rate(dss.dss_clk);
-	}
-
-	return 0;
-}
-
 int dss_set_clock_div(struct dss_clock_info *cinfo)
 {
 	if (dss.dpll4_m4_ck) {
@@ -478,26 +453,6 @@
 	return 0;
 }
 
-int dss_get_clock_div(struct dss_clock_info *cinfo)
-{
-	cinfo->fck = clk_get_rate(dss.dss_clk);
-
-	if (dss.dpll4_m4_ck) {
-		unsigned long prate;
-
-		prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
-
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			cinfo->fck_div = prate / (cinfo->fck);
-		else
-			cinfo->fck_div = prate / (cinfo->fck / 2);
-	} else {
-		cinfo->fck_div = 0;
-	}
-
-	return 0;
-}
-
 unsigned long dss_get_dpll4_rate(void)
 {
 	if (dss.dpll4_m4_ck)
@@ -515,7 +470,7 @@
 
 	unsigned long fck, max_dss_fck;
 
-	u16 fck_div, fck_div_max = 16;
+	u16 fck_div;
 
 	int match = 0;
 	int min_fck_per_pck;
@@ -525,9 +480,8 @@
 	max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
 
 	fck = clk_get_rate(dss.dss_clk);
-	if (req_pck == dss.cache_req_pck &&
-			((cpu_is_omap34xx() && prate == dss.cache_prate) ||
-			 dss.cache_dss_cinfo.fck == fck)) {
+	if (req_pck == dss.cache_req_pck && prate == dss.cache_prate &&
+		dss.cache_dss_cinfo.fck == fck) {
 		DSSDBG("dispc clock info found from cache.\n");
 		*dss_cinfo = dss.cache_dss_cinfo;
 		*dispc_cinfo = dss.cache_dispc_cinfo;
@@ -564,16 +518,10 @@
 
 		goto found;
 	} else {
-		if (cpu_is_omap3630() || cpu_is_omap44xx())
-			fck_div_max = 32;
-
-		for (fck_div = fck_div_max; fck_div > 0; --fck_div) {
+		for (fck_div = dss.feat->fck_div_max; fck_div > 0; --fck_div) {
 			struct dispc_clock_info cur_dispc;
 
-			if (fck_div_max == 32)
-				fck = prate / fck_div;
-			else
-				fck = prate / fck_div * 2;
+			fck = prate / fck_div * dss.feat->dss_fck_multiplier;
 
 			if (fck > max_dss_fck)
 				continue;
@@ -648,9 +596,18 @@
 	REG_FLD_MOD(DSS_CONTROL, enable, 5, 5);	/* DAC Power-Down Control */
 }
 
-void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select hdmi)
+void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select src)
 {
-	REG_FLD_MOD(DSS_CONTROL, hdmi, 15, 15);	/* VENC_HDMI_SWITCH */
+	enum omap_display_type dp;
+	dp = dss_feat_get_supported_displays(OMAP_DSS_CHANNEL_DIGIT);
+
+	/* Complain about invalid selections */
+	WARN_ON((src == DSS_VENC_TV_CLK) && !(dp & OMAP_DISPLAY_TYPE_VENC));
+	WARN_ON((src == DSS_HDMI_M_PCLK) && !(dp & OMAP_DISPLAY_TYPE_HDMI));
+
+	/* Select only if we have options */
+	if ((dp & OMAP_DISPLAY_TYPE_VENC) && (dp & OMAP_DISPLAY_TYPE_HDMI))
+		REG_FLD_MOD(DSS_CONTROL, src, 15, 15);	/* VENC_HDMI_SWITCH */
 }
 
 enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
@@ -661,9 +618,71 @@
 	if ((displays & OMAP_DISPLAY_TYPE_HDMI) == 0)
 		return DSS_VENC_TV_CLK;
 
+	if ((displays & OMAP_DISPLAY_TYPE_VENC) == 0)
+		return DSS_HDMI_M_PCLK;
+
 	return REG_GET(DSS_CONTROL, 15, 15);
 }
 
+static int dss_dpi_select_source_omap2_omap3(enum omap_channel channel)
+{
+	if (channel != OMAP_DSS_CHANNEL_LCD)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int dss_dpi_select_source_omap4(enum omap_channel channel)
+{
+	int val;
+
+	switch (channel) {
+	case OMAP_DSS_CHANNEL_LCD2:
+		val = 0;
+		break;
+	case OMAP_DSS_CHANNEL_DIGIT:
+		val = 1;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	REG_FLD_MOD(DSS_CONTROL, val, 17, 17);
+
+	return 0;
+}
+
+static int dss_dpi_select_source_omap5(enum omap_channel channel)
+{
+	int val;
+
+	switch (channel) {
+	case OMAP_DSS_CHANNEL_LCD:
+		val = 1;
+		break;
+	case OMAP_DSS_CHANNEL_LCD2:
+		val = 2;
+		break;
+	case OMAP_DSS_CHANNEL_LCD3:
+		val = 3;
+		break;
+	case OMAP_DSS_CHANNEL_DIGIT:
+		val = 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	REG_FLD_MOD(DSS_CONTROL, val, 17, 16);
+
+	return 0;
+}
+
+int dss_dpi_select_source(enum omap_channel channel)
+{
+	return dss.feat->dpi_select_source(channel);
+}
+
 static int dss_get_clocks(void)
 {
 	struct clk *clk;
@@ -678,22 +697,11 @@
 
 	dss.dss_clk = clk;
 
-	if (cpu_is_omap34xx()) {
-		clk = clk_get(NULL, "dpll4_m4_ck");
-		if (IS_ERR(clk)) {
-			DSSERR("Failed to get dpll4_m4_ck\n");
-			r = PTR_ERR(clk);
-			goto err;
-		}
-	} else if (cpu_is_omap44xx()) {
-		clk = clk_get(NULL, "dpll_per_m5x2_ck");
-		if (IS_ERR(clk)) {
-			DSSERR("Failed to get dpll_per_m5x2_ck\n");
-			r = PTR_ERR(clk);
-			goto err;
-		}
-	} else { /* omap24xx */
-		clk = NULL;
+	clk = clk_get(NULL, dss.feat->clk_name);
+	if (IS_ERR(clk)) {
+		DSSERR("Failed to get %s\n", dss.feat->clk_name);
+		r = PTR_ERR(clk);
+		goto err;
 	}
 
 	dss.dpll4_m4_ck = clk;
@@ -749,6 +757,71 @@
 }
 #endif
 
+static const struct dss_features omap24xx_dss_feats __initconst = {
+	.fck_div_max		=	16,
+	.dss_fck_multiplier	=	2,
+	.clk_name		=	NULL,
+	.dpi_select_source	=	&dss_dpi_select_source_omap2_omap3,
+};
+
+static const struct dss_features omap34xx_dss_feats __initconst = {
+	.fck_div_max		=	16,
+	.dss_fck_multiplier	=	2,
+	.clk_name		=	"dpll4_m4_ck",
+	.dpi_select_source	=	&dss_dpi_select_source_omap2_omap3,
+};
+
+static const struct dss_features omap3630_dss_feats __initconst = {
+	.fck_div_max		=	32,
+	.dss_fck_multiplier	=	1,
+	.clk_name		=	"dpll4_m4_ck",
+	.dpi_select_source	=	&dss_dpi_select_source_omap2_omap3,
+};
+
+static const struct dss_features omap44xx_dss_feats __initconst = {
+	.fck_div_max		=	32,
+	.dss_fck_multiplier	=	1,
+	.clk_name		=	"dpll_per_m5x2_ck",
+	.dpi_select_source	=	&dss_dpi_select_source_omap4,
+};
+
+static const struct dss_features omap54xx_dss_feats __initconst = {
+	.fck_div_max		=	64,
+	.dss_fck_multiplier	=	1,
+	.clk_name		=	"dpll_per_h12x2_ck",
+	.dpi_select_source	=	&dss_dpi_select_source_omap5,
+};
+
+static int __init dss_init_features(struct device *dev)
+{
+	const struct dss_features *src;
+	struct dss_features *dst;
+
+	dst = devm_kzalloc(dev, sizeof(*dst), GFP_KERNEL);
+	if (!dst) {
+		dev_err(dev, "Failed to allocate local DSS Features\n");
+		return -ENOMEM;
+	}
+
+	if (cpu_is_omap24xx())
+		src = &omap24xx_dss_feats;
+	else if (cpu_is_omap34xx())
+		src = &omap34xx_dss_feats;
+	else if (cpu_is_omap3630())
+		src = &omap3630_dss_feats;
+	else if (cpu_is_omap44xx())
+		src = &omap44xx_dss_feats;
+	else if (soc_is_omap54xx())
+		src = &omap54xx_dss_feats;
+	else
+		return -ENODEV;
+
+	memcpy(dst, src, sizeof(*dst));
+	dss.feat = dst;
+
+	return 0;
+}
+
 /* DSS HW IP initialisation */
 static int __init omap_dsshw_probe(struct platform_device *pdev)
 {
@@ -758,6 +831,10 @@
 
 	dss.pdev = pdev;
 
+	r = dss_init_features(&dss.pdev->dev);
+	if (r)
+		return r;
+
 	dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
 	if (!dss_mem) {
 		DSSERR("can't get IORESOURCE_MEM DSS\n");
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index f67afe7..6728892 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -113,6 +113,17 @@
 	DSS_DSI_CONTENT_GENERIC,
 };
 
+enum dss_writeback_channel {
+	DSS_WB_LCD1_MGR =	0,
+	DSS_WB_LCD2_MGR =	1,
+	DSS_WB_TV_MGR =		2,
+	DSS_WB_OVL0 =		3,
+	DSS_WB_OVL1 =		4,
+	DSS_WB_OVL2 =		5,
+	DSS_WB_OVL3 =		6,
+	DSS_WB_LCD3_MGR =	7,
+};
+
 struct dss_clock_info {
 	/* rates that we get with dividers below */
 	unsigned long fck;
@@ -175,6 +186,7 @@
 struct platform_device;
 
 /* core */
+const char *dss_get_default_display_name(void);
 struct bus_type *dss_get_bus(void);
 struct regulator *dss_get_vdds_dsi(void);
 struct regulator *dss_get_vdds_sdi(void);
@@ -184,10 +196,13 @@
 int dss_set_min_bus_tput(struct device *dev, unsigned long tput);
 int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *));
 
-int omap_dss_register_device(struct omap_dss_device *dssdev,
-		struct device *parent, int disp_num);
-void omap_dss_unregister_device(struct omap_dss_device *dssdev);
-void omap_dss_unregister_child_devices(struct device *parent);
+struct omap_dss_device *dss_alloc_and_init_device(struct device *parent);
+int dss_add_device(struct omap_dss_device *dssdev);
+void dss_unregister_device(struct omap_dss_device *dssdev);
+void dss_unregister_child_devices(struct device *parent);
+void dss_put_device(struct omap_dss_device *dssdev);
+void dss_copy_device_pdata(struct omap_dss_device *dst,
+		const struct omap_dss_device *src);
 
 /* apply */
 void dss_apply_init(void);
@@ -205,8 +220,11 @@
 int dss_mgr_set_device(struct omap_overlay_manager *mgr,
 		struct omap_dss_device *dssdev);
 int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
+int dss_mgr_set_output(struct omap_overlay_manager *mgr,
+		struct omap_dss_output *output);
+int dss_mgr_unset_output(struct omap_overlay_manager *mgr);
 void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
-		struct omap_video_timings *timings);
+		const struct omap_video_timings *timings);
 void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
 		const struct dss_lcd_mgr_config *config);
 const struct omap_video_timings *dss_mgr_get_timings(struct omap_overlay_manager *mgr);
@@ -222,12 +240,17 @@
 		struct omap_overlay_manager *mgr);
 int dss_ovl_unset_manager(struct omap_overlay *ovl);
 
+/* output */
+void dss_register_output(struct omap_dss_output *out);
+void dss_unregister_output(struct omap_dss_output *out);
+struct omap_dss_output *omapdss_get_output_from_dssdev(struct omap_dss_device *dssdev);
+
 /* display */
 int dss_suspend_all_devices(void);
 int dss_resume_all_devices(void);
 void dss_disable_all_devices(void);
 
-void dss_init_device(struct platform_device *pdev,
+int dss_init_device(struct platform_device *pdev,
 		struct omap_dss_device *dssdev);
 void dss_uninit_device(struct platform_device *pdev,
 		struct omap_dss_device *dssdev);
@@ -254,22 +277,29 @@
 		return false;
 }
 
+int dss_manager_kobj_init(struct omap_overlay_manager *mgr,
+		struct platform_device *pdev);
+void dss_manager_kobj_uninit(struct omap_overlay_manager *mgr);
+
 /* overlay */
 void dss_init_overlays(struct platform_device *pdev);
 void dss_uninit_overlays(struct platform_device *pdev);
 void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr);
-void dss_recheck_connections(struct omap_dss_device *dssdev, bool force);
 int dss_ovl_simple_check(struct omap_overlay *ovl,
 		const struct omap_overlay_info *info);
 int dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info,
 		const struct omap_video_timings *mgr_timings);
 bool dss_ovl_use_replication(struct dss_lcd_mgr_config config,
 		enum omap_color_mode mode);
+int dss_overlay_kobj_init(struct omap_overlay *ovl,
+		struct platform_device *pdev);
+void dss_overlay_kobj_uninit(struct omap_overlay *ovl);
 
 /* DSS */
 int dss_init_platform_driver(void) __init;
 void dss_uninit_platform_driver(void);
 
+int dss_dpi_select_source(enum omap_channel channel);
 void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
 enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void);
 const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src);
@@ -279,7 +309,7 @@
 void dss_debug_dump_clocks(struct seq_file *s);
 #endif
 
-void dss_sdi_init(u8 datapairs);
+void dss_sdi_init(int datapairs);
 int dss_sdi_enable(void);
 void dss_sdi_disable(void);
 
@@ -296,9 +326,7 @@
 void dss_set_dac_pwrdn_bgz(bool enable);
 
 unsigned long dss_get_dpll4_rate(void);
-int dss_calc_clock_rates(struct dss_clock_info *cinfo);
 int dss_set_clock_div(struct dss_clock_info *cinfo);
-int dss_get_clock_div(struct dss_clock_info *cinfo);
 int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
 		struct dispc_clock_info *dispc_cinfo);
 
@@ -427,8 +455,9 @@
 void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,
 		u32 *fifo_low, u32 *fifo_high, bool use_fifomerge,
 		bool manual_update);
-int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
-		bool replication, const struct omap_video_timings *mgr_timings);
+int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
+		bool replication, const struct omap_video_timings *mgr_timings,
+		bool mem_to_mem);
 int dispc_ovl_enable(enum omap_plane plane, bool enable);
 void dispc_ovl_set_channel_out(enum omap_plane plane,
 		enum omap_channel channel);
@@ -457,6 +486,15 @@
 void dispc_mgr_setup(enum omap_channel channel,
 		struct omap_overlay_manager_info *info);
 
+u32 dispc_wb_get_framedone_irq(void);
+bool dispc_wb_go_busy(void);
+void dispc_wb_go(void);
+void dispc_wb_enable(bool enable);
+bool dispc_wb_is_enabled(void);
+void dispc_wb_set_channel_in(enum dss_writeback_channel channel);
+int dispc_wb_setup(const struct omap_dss_writeback_info *wi,
+		bool mem_to_mem, const struct omap_video_timings *timings);
+
 /* VENC */
 #ifdef CONFIG_OMAP2_DSS_VENC
 int venc_init_platform_driver(void) __init;
@@ -469,6 +507,20 @@
 	return 0;
 }
 #endif
+int omapdss_venc_display_enable(struct omap_dss_device *dssdev);
+void omapdss_venc_display_disable(struct omap_dss_device *dssdev);
+void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings);
+int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings);
+u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev);
+int omapdss_venc_set_wss(struct omap_dss_device *dssdev, u32 wss);
+void omapdss_venc_set_type(struct omap_dss_device *dssdev,
+		enum omap_dss_venc_type type);
+void omapdss_venc_invert_vid_out_polarity(struct omap_dss_device *dssdev,
+		bool invert_polarity);
+int venc_panel_init(void);
+void venc_panel_exit(void);
 
 /* HDMI */
 #ifdef CONFIG_OMAP4_DSS_HDMI
@@ -484,7 +536,8 @@
 #endif
 int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev);
 void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev);
-void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev);
+void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings);
 int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
 					struct omap_video_timings *timings);
 int omapdss_hdmi_read_edid(u8 *buf, int len);
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 9387097..acbc1e1 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -46,7 +46,9 @@
 
 	const int num_mgrs;
 	const int num_ovls;
+	const int num_wbs;
 	const enum omap_display_type *supported_displays;
+	const enum omap_dss_output_id *supported_outputs;
 	const enum omap_color_mode *supported_color_modes;
 	const enum omap_overlay_caps *overlay_caps;
 	const char * const *clksrc_names;
@@ -106,6 +108,21 @@
 	[FEAT_REG_DSIPLL_REGM_DSI]		= { 30, 26 },
 };
 
+static const struct dss_reg_field omap5_dss_reg_fields[] = {
+	[FEAT_REG_FIRHINC]			= { 12, 0 },
+	[FEAT_REG_FIRVINC]			= { 28, 16 },
+	[FEAT_REG_FIFOLOWTHRESHOLD]		= { 15, 0 },
+	[FEAT_REG_FIFOHIGHTHRESHOLD]		= { 31, 16 },
+	[FEAT_REG_FIFOSIZE]			= { 15, 0 },
+	[FEAT_REG_HORIZONTALACCU]		= { 10, 0 },
+	[FEAT_REG_VERTICALACCU]			= { 26, 16 },
+	[FEAT_REG_DISPC_CLK_SWITCH]		= { 9, 7 },
+	[FEAT_REG_DSIPLL_REGN]			= { 8, 1 },
+	[FEAT_REG_DSIPLL_REGM]			= { 20, 9 },
+	[FEAT_REG_DSIPLL_REGM_DISPC]		= { 25, 21 },
+	[FEAT_REG_DSIPLL_REGM_DSI]		= { 30, 26 },
+};
+
 static const enum omap_display_type omap2_dss_supported_displays[] = {
 	/* OMAP_DSS_CHANNEL_LCD */
 	OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI,
@@ -144,6 +161,76 @@
 	OMAP_DISPLAY_TYPE_DSI,
 };
 
+static const enum omap_display_type omap5_dss_supported_displays[] = {
+	/* OMAP_DSS_CHANNEL_LCD */
+	OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
+	OMAP_DISPLAY_TYPE_DSI,
+
+	/* OMAP_DSS_CHANNEL_DIGIT */
+	OMAP_DISPLAY_TYPE_HDMI | OMAP_DISPLAY_TYPE_DPI,
+
+	/* OMAP_DSS_CHANNEL_LCD2 */
+	OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
+	OMAP_DISPLAY_TYPE_DSI,
+};
+
+static const enum omap_dss_output_id omap2_dss_supported_outputs[] = {
+	/* OMAP_DSS_CHANNEL_LCD */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI,
+
+	/* OMAP_DSS_CHANNEL_DIGIT */
+	OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap3430_dss_supported_outputs[] = {
+	/* OMAP_DSS_CHANNEL_LCD */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+	OMAP_DSS_OUTPUT_SDI | OMAP_DSS_OUTPUT_DSI1,
+
+	/* OMAP_DSS_CHANNEL_DIGIT */
+	OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap3630_dss_supported_outputs[] = {
+	/* OMAP_DSS_CHANNEL_LCD */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+	OMAP_DSS_OUTPUT_DSI1,
+
+	/* OMAP_DSS_CHANNEL_DIGIT */
+	OMAP_DSS_OUTPUT_VENC,
+};
+
+static const enum omap_dss_output_id omap4_dss_supported_outputs[] = {
+	/* OMAP_DSS_CHANNEL_LCD */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+	OMAP_DSS_OUTPUT_DSI1,
+
+	/* OMAP_DSS_CHANNEL_DIGIT */
+	OMAP_DSS_OUTPUT_VENC | OMAP_DSS_OUTPUT_HDMI |
+	OMAP_DSS_OUTPUT_DPI,
+
+	/* OMAP_DSS_CHANNEL_LCD2 */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+	OMAP_DSS_OUTPUT_DSI2,
+};
+
+static const enum omap_dss_output_id omap5_dss_supported_outputs[] = {
+	/* OMAP_DSS_CHANNEL_LCD */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+	OMAP_DSS_OUTPUT_DSI1 | OMAP_DSS_OUTPUT_DSI2,
+
+	/* OMAP_DSS_CHANNEL_DIGIT */
+	OMAP_DSS_OUTPUT_HDMI | OMAP_DSS_OUTPUT_DPI,
+
+	/* OMAP_DSS_CHANNEL_LCD2 */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+	OMAP_DSS_OUTPUT_DSI1,
+
+	/* OMAP_DSS_CHANNEL_LCD3 */
+	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
+	OMAP_DSS_OUTPUT_DSI2,
+};
+
 static const enum omap_color_mode omap2_dss_supported_color_modes[] = {
 	/* OMAP_DSS_GFX */
 	OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 |
@@ -224,58 +311,80 @@
 	OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 |
 	OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 |
 	OMAP_DSS_COLOR_RGBX32,
+
+	/* OMAP_DSS_WB */
+	OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB12U |
+	OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_ARGB16_1555 |
+	OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_NV12 |
+	OMAP_DSS_COLOR_RGBA16 | OMAP_DSS_COLOR_RGB24U |
+	OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_UYVY |
+	OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 |
+	OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 |
+	OMAP_DSS_COLOR_RGBX32,
 };
 
 static const enum omap_overlay_caps omap2_dss_overlay_caps[] = {
 	/* OMAP_DSS_GFX */
-	0,
+	OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
 
 	/* OMAP_DSS_VIDEO1 */
-	OMAP_DSS_OVL_CAP_SCALE,
+	OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
+		OMAP_DSS_OVL_CAP_REPLICATION,
 
 	/* OMAP_DSS_VIDEO2 */
-	OMAP_DSS_OVL_CAP_SCALE,
+	OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
+		OMAP_DSS_OVL_CAP_REPLICATION,
 };
 
 static const enum omap_overlay_caps omap3430_dss_overlay_caps[] = {
 	/* OMAP_DSS_GFX */
-	OMAP_DSS_OVL_CAP_GLOBAL_ALPHA,
+	OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_POS |
+		OMAP_DSS_OVL_CAP_REPLICATION,
 
 	/* OMAP_DSS_VIDEO1 */
-	OMAP_DSS_OVL_CAP_SCALE,
+	OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
+		OMAP_DSS_OVL_CAP_REPLICATION,
 
 	/* OMAP_DSS_VIDEO2 */
-	OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA,
+	OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
+		OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
 };
 
 static const enum omap_overlay_caps omap3630_dss_overlay_caps[] = {
 	/* OMAP_DSS_GFX */
-	OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA,
+	OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA |
+		OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
 
 	/* OMAP_DSS_VIDEO1 */
-	OMAP_DSS_OVL_CAP_SCALE,
+	OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
+		OMAP_DSS_OVL_CAP_REPLICATION,
 
 	/* OMAP_DSS_VIDEO2 */
 	OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
-		OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA,
+		OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_POS |
+		OMAP_DSS_OVL_CAP_REPLICATION,
 };
 
 static const enum omap_overlay_caps omap4_dss_overlay_caps[] = {
 	/* OMAP_DSS_GFX */
 	OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA |
-		OMAP_DSS_OVL_CAP_ZORDER,
+		OMAP_DSS_OVL_CAP_ZORDER | OMAP_DSS_OVL_CAP_POS |
+		OMAP_DSS_OVL_CAP_REPLICATION,
 
 	/* OMAP_DSS_VIDEO1 */
 	OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
-		OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER,
+		OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER |
+		OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
 
 	/* OMAP_DSS_VIDEO2 */
 	OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
-		OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER,
+		OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER |
+		OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
 
 	/* OMAP_DSS_VIDEO3 */
 	OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
-		OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER,
+		OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER |
+		OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
 };
 
 static const char * const omap2_dss_clk_source_names[] = {
@@ -298,6 +407,14 @@
 	[OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI]	= "PLL2_CLK2",
 };
 
+static const char * const omap5_dss_clk_source_names[] = {
+	[OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC]	= "DPLL_DSI1_A_CLK1",
+	[OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI]	= "DPLL_DSI1_A_CLK2",
+	[OMAP_DSS_CLK_SRC_FCK]			= "DSS_CLK",
+	[OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC]	= "DPLL_DSI1_C_CLK1",
+	[OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI]	= "DPLL_DSI1_C_CLK2",
+};
+
 static const struct dss_param_range omap2_dss_param_range[] = {
 	[FEAT_PARAM_DSS_FCK]			= { 0, 173000000 },
 	[FEAT_PARAM_DSS_PCD]			= { 2, 255 },
@@ -326,6 +443,7 @@
 	[FEAT_PARAM_DSIPLL_REGM_DSI]		= { 0, (1 << 4) - 1 },
 	[FEAT_PARAM_DSIPLL_FINT]		= { 750000, 2100000 },
 	[FEAT_PARAM_DSIPLL_LPDIV]		= { 1, (1 << 13) - 1},
+	[FEAT_PARAM_DSI_FCK]			= { 0, 173000000 },
 	[FEAT_PARAM_DOWNSCALE]			= { 1, 4 },
 	[FEAT_PARAM_LINEWIDTH]			= { 1, 1024 },
 	[FEAT_PARAM_MGR_WIDTH]			= { 1, 2048 },
@@ -341,6 +459,23 @@
 	[FEAT_PARAM_DSIPLL_REGM_DSI]		= { 0, (1 << 5) - 1 },
 	[FEAT_PARAM_DSIPLL_FINT]		= { 500000, 2500000 },
 	[FEAT_PARAM_DSIPLL_LPDIV]		= { 0, (1 << 13) - 1 },
+	[FEAT_PARAM_DSI_FCK]			= { 0, 170000000 },
+	[FEAT_PARAM_DOWNSCALE]			= { 1, 4 },
+	[FEAT_PARAM_LINEWIDTH]			= { 1, 2048 },
+	[FEAT_PARAM_MGR_WIDTH]			= { 1, 2048 },
+	[FEAT_PARAM_MGR_HEIGHT]			= { 1, 2048 },
+};
+
+static const struct dss_param_range omap5_dss_param_range[] = {
+	[FEAT_PARAM_DSS_FCK]			= { 0, 200000000 },
+	[FEAT_PARAM_DSS_PCD]			= { 1, 255 },
+	[FEAT_PARAM_DSIPLL_REGN]		= { 0, (1 << 8) - 1 },
+	[FEAT_PARAM_DSIPLL_REGM]		= { 0, (1 << 12) - 1 },
+	[FEAT_PARAM_DSIPLL_REGM_DISPC]		= { 0, (1 << 5) - 1 },
+	[FEAT_PARAM_DSIPLL_REGM_DSI]		= { 0, (1 << 5) - 1 },
+	[FEAT_PARAM_DSIPLL_FINT]		= { 500000, 2500000 },
+	[FEAT_PARAM_DSIPLL_LPDIV]		= { 0, (1 << 13) - 1 },
+	[FEAT_PARAM_DSI_FCK]			= { 0, 170000000 },
 	[FEAT_PARAM_DOWNSCALE]			= { 1, 4 },
 	[FEAT_PARAM_LINEWIDTH]			= { 1, 2048 },
 	[FEAT_PARAM_MGR_WIDTH]			= { 1, 2048 },
@@ -373,6 +508,26 @@
 	FEAT_ALPHA_FIXED_ZORDER,
 	FEAT_FIFO_MERGE,
 	FEAT_OMAP3_DSI_FIFO_BUG,
+	FEAT_DPI_USES_VDDS_DSI,
+};
+
+static const enum dss_feat_id am35xx_dss_feat_list[] = {
+	FEAT_LCDENABLEPOL,
+	FEAT_LCDENABLESIGNAL,
+	FEAT_PCKFREEENABLE,
+	FEAT_FUNCGATED,
+	FEAT_LINEBUFFERSPLIT,
+	FEAT_ROWREPEATENABLE,
+	FEAT_RESIZECONF,
+	FEAT_DSI_PLL_FREQSEL,
+	FEAT_DSI_REVERSE_TXCLKESC,
+	FEAT_VENC_REQUIRES_TV_DAC_CLK,
+	FEAT_CPR,
+	FEAT_PRELOAD,
+	FEAT_FIR_COEF_V,
+	FEAT_ALPHA_FIXED_ZORDER,
+	FEAT_FIFO_MERGE,
+	FEAT_OMAP3_DSI_FIFO_BUG,
 };
 
 static const enum dss_feat_id omap3630_dss_feat_list[] = {
@@ -447,6 +602,28 @@
 	FEAT_BURST_2D,
 };
 
+static const enum dss_feat_id omap5_dss_feat_list[] = {
+	FEAT_MGR_LCD2,
+	FEAT_CORE_CLK_DIV,
+	FEAT_LCD_CLK_SRC,
+	FEAT_DSI_DCS_CMD_CONFIG_VC,
+	FEAT_DSI_VC_OCP_WIDTH,
+	FEAT_DSI_GNQ,
+	FEAT_HDMI_CTS_SWMODE,
+	FEAT_HDMI_AUDIO_USE_MCLK,
+	FEAT_HANDLE_UV_SEPARATE,
+	FEAT_ATTR2,
+	FEAT_CPR,
+	FEAT_PRELOAD,
+	FEAT_FIR_COEF_V,
+	FEAT_ALPHA_FREE_ZORDER,
+	FEAT_FIFO_MERGE,
+	FEAT_BURST_2D,
+	FEAT_DSI_PLL_SELFREQDCO,
+	FEAT_DSI_PLL_REFSEL,
+	FEAT_DSI_PHY_DCC,
+};
+
 /* OMAP2 DSS Features */
 static const struct omap_dss_features omap2_dss_features = {
 	.reg_fields = omap2_dss_reg_fields,
@@ -458,6 +635,7 @@
 	.num_mgrs = 2,
 	.num_ovls = 3,
 	.supported_displays = omap2_dss_supported_displays,
+	.supported_outputs = omap2_dss_supported_outputs,
 	.supported_color_modes = omap2_dss_supported_color_modes,
 	.overlay_caps = omap2_dss_overlay_caps,
 	.clksrc_names = omap2_dss_clk_source_names,
@@ -478,6 +656,31 @@
 	.num_mgrs = 2,
 	.num_ovls = 3,
 	.supported_displays = omap3430_dss_supported_displays,
+	.supported_outputs = omap3430_dss_supported_outputs,
+	.supported_color_modes = omap3_dss_supported_color_modes,
+	.overlay_caps = omap3430_dss_overlay_caps,
+	.clksrc_names = omap3_dss_clk_source_names,
+	.dss_params = omap3_dss_param_range,
+	.supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_VRFB,
+	.buffer_size_unit = 1,
+	.burst_size_unit = 8,
+};
+
+/*
+ * AM35xx DSS Features. This is basically OMAP3 DSS Features without the
+ * vdds_dsi regulator.
+ */
+static const struct omap_dss_features am35xx_dss_features = {
+	.reg_fields = omap3_dss_reg_fields,
+	.num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields),
+
+	.features = am35xx_dss_feat_list,
+	.num_features = ARRAY_SIZE(am35xx_dss_feat_list),
+
+	.num_mgrs = 2,
+	.num_ovls = 3,
+	.supported_displays = omap3430_dss_supported_displays,
+	.supported_outputs = omap3430_dss_supported_outputs,
 	.supported_color_modes = omap3_dss_supported_color_modes,
 	.overlay_caps = omap3430_dss_overlay_caps,
 	.clksrc_names = omap3_dss_clk_source_names,
@@ -497,6 +700,7 @@
 	.num_mgrs = 2,
 	.num_ovls = 3,
 	.supported_displays = omap3630_dss_supported_displays,
+	.supported_outputs = omap3630_dss_supported_outputs,
 	.supported_color_modes = omap3_dss_supported_color_modes,
 	.overlay_caps = omap3630_dss_overlay_caps,
 	.clksrc_names = omap3_dss_clk_source_names,
@@ -517,7 +721,9 @@
 
 	.num_mgrs = 3,
 	.num_ovls = 4,
+	.num_wbs = 1,
 	.supported_displays = omap4_dss_supported_displays,
+	.supported_outputs = omap4_dss_supported_outputs,
 	.supported_color_modes = omap4_dss_supported_color_modes,
 	.overlay_caps = omap4_dss_overlay_caps,
 	.clksrc_names = omap4_dss_clk_source_names,
@@ -537,7 +743,9 @@
 
 	.num_mgrs = 3,
 	.num_ovls = 4,
+	.num_wbs = 1,
 	.supported_displays = omap4_dss_supported_displays,
+	.supported_outputs = omap4_dss_supported_outputs,
 	.supported_color_modes = omap4_dss_supported_color_modes,
 	.overlay_caps = omap4_dss_overlay_caps,
 	.clksrc_names = omap4_dss_clk_source_names,
@@ -557,7 +765,9 @@
 
 	.num_mgrs = 3,
 	.num_ovls = 4,
+	.num_wbs = 1,
 	.supported_displays = omap4_dss_supported_displays,
+	.supported_outputs = omap4_dss_supported_outputs,
 	.supported_color_modes = omap4_dss_supported_color_modes,
 	.overlay_caps = omap4_dss_overlay_caps,
 	.clksrc_names = omap4_dss_clk_source_names,
@@ -567,6 +777,27 @@
 	.burst_size_unit = 16,
 };
 
+/* OMAP5 DSS Features */
+static const struct omap_dss_features omap5_dss_features = {
+	.reg_fields = omap5_dss_reg_fields,
+	.num_reg_fields = ARRAY_SIZE(omap5_dss_reg_fields),
+
+	.features = omap5_dss_feat_list,
+	.num_features = ARRAY_SIZE(omap5_dss_feat_list),
+
+	.num_mgrs = 3,
+	.num_ovls = 4,
+	.supported_displays = omap5_dss_supported_displays,
+	.supported_outputs = omap5_dss_supported_outputs,
+	.supported_color_modes = omap4_dss_supported_color_modes,
+	.overlay_caps = omap4_dss_overlay_caps,
+	.clksrc_names = omap5_dss_clk_source_names,
+	.dss_params = omap5_dss_param_range,
+	.supported_rotation_types = OMAP_DSS_ROT_DMA | OMAP_DSS_ROT_TILER,
+	.buffer_size_unit = 16,
+	.burst_size_unit = 16,
+};
+
 #if defined(CONFIG_OMAP4_DSS_HDMI)
 /* HDMI OMAP4 Functions*/
 static const struct ti_hdmi_ip_ops omap4_hdmi_functions = {
@@ -612,6 +843,11 @@
 	return omap_current_dss_features->num_ovls;
 }
 
+int dss_feat_get_num_wbs(void)
+{
+	return omap_current_dss_features->num_wbs;
+}
+
 unsigned long dss_feat_get_param_min(enum dss_range_param param)
 {
 	return omap_current_dss_features->dss_params[param].min;
@@ -627,6 +863,11 @@
 	return omap_current_dss_features->supported_displays[channel];
 }
 
+enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel)
+{
+	return omap_current_dss_features->supported_outputs[channel];
+}
+
 enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane)
 {
 	return omap_current_dss_features->supported_color_modes[plane];
@@ -694,8 +935,13 @@
 		omap_current_dss_features = &omap2_dss_features;
 	else if (cpu_is_omap3630())
 		omap_current_dss_features = &omap3630_dss_features;
-	else if (cpu_is_omap34xx())
-		omap_current_dss_features = &omap3430_dss_features;
+	else if (cpu_is_omap34xx()) {
+		if (soc_is_am35xx()) {
+			omap_current_dss_features = &am35xx_dss_features;
+		} else {
+			omap_current_dss_features = &omap3430_dss_features;
+		}
+	}
 	else if (omap_rev() == OMAP4430_REV_ES1_0)
 		omap_current_dss_features = &omap4430_es1_0_dss_features;
 	else if (omap_rev() == OMAP4430_REV_ES2_0 ||
@@ -704,6 +950,8 @@
 		omap_current_dss_features = &omap4430_es2_0_1_2_dss_features;
 	else if (cpu_is_omap44xx())
 		omap_current_dss_features = &omap4_dss_features;
+	else if (soc_is_omap54xx())
+		omap_current_dss_features = &omap5_dss_features;
 	else
 		DSSWARN("Unsupported OMAP version");
 }
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 996ffcb..9218113 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -50,6 +50,7 @@
 	FEAT_DSI_VC_OCP_WIDTH,
 	FEAT_DSI_REVERSE_TXCLKESC,
 	FEAT_DSI_GNQ,
+	FEAT_DPI_USES_VDDS_DSI,
 	FEAT_HDMI_CTS_SWMODE,
 	FEAT_HDMI_AUDIO_USE_MCLK,
 	FEAT_HANDLE_UV_SEPARATE,
@@ -64,6 +65,9 @@
 	/* An unknown HW bug causing the normal FIFO thresholds not to work */
 	FEAT_OMAP3_DSI_FIFO_BUG,
 	FEAT_BURST_2D,
+	FEAT_DSI_PLL_SELFREQDCO,
+	FEAT_DSI_PLL_REFSEL,
+	FEAT_DSI_PHY_DCC,
 };
 
 /* DSS register field id */
@@ -91,6 +95,7 @@
 	FEAT_PARAM_DSIPLL_REGM_DSI,
 	FEAT_PARAM_DSIPLL_FINT,
 	FEAT_PARAM_DSIPLL_LPDIV,
+	FEAT_PARAM_DSI_FCK,
 	FEAT_PARAM_DOWNSCALE,
 	FEAT_PARAM_LINEWIDTH,
 	FEAT_PARAM_MGR_WIDTH,
@@ -100,9 +105,11 @@
 /* DSS Feature Functions */
 int dss_feat_get_num_mgrs(void);
 int dss_feat_get_num_ovls(void);
+int dss_feat_get_num_wbs(void);
 unsigned long dss_feat_get_param_min(enum dss_range_param param);
 unsigned long dss_feat_get_param_max(enum dss_range_param param);
 enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
+enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel);
 enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
 enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane);
 bool dss_feat_color_mode_supported(enum omap_plane plane,
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 060216f..a48a7dd 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -32,6 +32,8 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
 #include <video/omapdss.h>
 
 #include "ti_hdmi.h"
@@ -61,6 +63,13 @@
 	struct hdmi_ip_data ip_data;
 
 	struct clk *sys_clk;
+	struct regulator *vdda_hdmi_dac_reg;
+
+	int ct_cp_hpd_gpio;
+	int ls_oe_gpio;
+	int hpd_gpio;
+
+	struct omap_dss_output output;
 } hdmi;
 
 /*
@@ -314,12 +323,47 @@
 
 static int __init hdmi_init_display(struct omap_dss_device *dssdev)
 {
+	int r;
+
+	struct gpio gpios[] = {
+		{ hdmi.ct_cp_hpd_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ct_cp_hpd" },
+		{ hdmi.ls_oe_gpio, GPIOF_OUT_INIT_LOW, "hdmi_ls_oe" },
+		{ hdmi.hpd_gpio, GPIOF_DIR_IN, "hdmi_hpd" },
+	};
+
 	DSSDBG("init_display\n");
 
 	dss_init_hdmi_ip_ops(&hdmi.ip_data);
+
+	if (hdmi.vdda_hdmi_dac_reg == NULL) {
+		struct regulator *reg;
+
+		reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac");
+
+		if (IS_ERR(reg)) {
+			DSSERR("can't get VDDA_HDMI_DAC regulator\n");
+			return PTR_ERR(reg);
+		}
+
+		hdmi.vdda_hdmi_dac_reg = reg;
+	}
+
+	r = gpio_request_array(gpios, ARRAY_SIZE(gpios));
+	if (r)
+		return r;
+
 	return 0;
 }
 
+static void __exit hdmi_uninit_display(struct omap_dss_device *dssdev)
+{
+	DSSDBG("uninit_display\n");
+
+	gpio_free(hdmi.ct_cp_hpd_gpio);
+	gpio_free(hdmi.ls_oe_gpio);
+	gpio_free(hdmi.hpd_gpio);
+}
+
 static const struct hdmi_config *hdmi_find_timing(
 					const struct hdmi_config *timings_arr,
 					int len)
@@ -459,32 +503,30 @@
 static int hdmi_power_on(struct omap_dss_device *dssdev)
 {
 	int r;
-	const struct hdmi_config *timing;
 	struct omap_video_timings *p;
+	struct omap_overlay_manager *mgr = dssdev->output->manager;
 	unsigned long phy;
 
+	gpio_set_value(hdmi.ct_cp_hpd_gpio, 1);
+	gpio_set_value(hdmi.ls_oe_gpio, 1);
+
+	/* wait 300us after CT_CP_HPD for the 5V power output to reach 90% */
+	udelay(300);
+
+	r = regulator_enable(hdmi.vdda_hdmi_dac_reg);
+	if (r)
+		goto err_vdac_enable;
+
 	r = hdmi_runtime_get();
 	if (r)
-		return r;
+		goto err_runtime_get;
 
-	dss_mgr_disable(dssdev->manager);
+	dss_mgr_disable(mgr);
 
-	p = &dssdev->panel.timings;
+	p = &hdmi.ip_data.cfg.timings;
 
-	DSSDBG("hdmi_power_on x_res= %d y_res = %d\n",
-		dssdev->panel.timings.x_res,
-		dssdev->panel.timings.y_res);
+	DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
 
-	timing = hdmi_get_timings();
-	if (timing == NULL) {
-		/* HDMI code 4 corresponds to 640 * 480 VGA */
-		hdmi.ip_data.cfg.cm.code = 4;
-		/* DVI mode 1 corresponds to HDMI 0 to DVI */
-		hdmi.ip_data.cfg.cm.mode = HDMI_DVI;
-		hdmi.ip_data.cfg = vesa_timings[0];
-	} else {
-		hdmi.ip_data.cfg = *timing;
-	}
 	phy = p->pixel_clock;
 
 	hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data);
@@ -495,13 +537,13 @@
 	r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data);
 	if (r) {
 		DSSDBG("Failed to lock PLL\n");
-		goto err;
+		goto err_pll_enable;
 	}
 
 	r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data);
 	if (r) {
 		DSSDBG("Failed to start PHY\n");
-		goto err;
+		goto err_phy_enable;
 	}
 
 	hdmi.ip_data.ops->video_configure(&hdmi.ip_data);
@@ -521,13 +563,13 @@
 	dispc_enable_gamma_table(0);
 
 	/* tv size */
-	dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
+	dss_mgr_set_timings(mgr, p);
 
 	r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data);
 	if (r)
 		goto err_vid_enable;
 
-	r = dss_mgr_enable(dssdev->manager);
+	r = dss_mgr_enable(mgr);
 	if (r)
 		goto err_mgr_enable;
 
@@ -537,20 +579,33 @@
 	hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
 err_vid_enable:
 	hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
+err_phy_enable:
 	hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
-err:
+err_pll_enable:
 	hdmi_runtime_put();
+err_runtime_get:
+	regulator_disable(hdmi.vdda_hdmi_dac_reg);
+err_vdac_enable:
+	gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
+	gpio_set_value(hdmi.ls_oe_gpio, 0);
 	return -EIO;
 }
 
 static void hdmi_power_off(struct omap_dss_device *dssdev)
 {
-	dss_mgr_disable(dssdev->manager);
+	struct omap_overlay_manager *mgr = dssdev->output->manager;
+
+	dss_mgr_disable(mgr);
 
 	hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
 	hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
 	hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
 	hdmi_runtime_put();
+
+	regulator_disable(hdmi.vdda_hdmi_dac_reg);
+
+	gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
+	gpio_set_value(hdmi.ls_oe_gpio, 0);
 }
 
 int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev,
@@ -567,25 +622,22 @@
 
 }
 
-void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev)
+void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
 {
 	struct hdmi_cm cm;
+	const struct hdmi_config *t;
 
-	cm = hdmi_get_code(&dssdev->panel.timings);
-	hdmi.ip_data.cfg.cm.code = cm.code;
-	hdmi.ip_data.cfg.cm.mode = cm.mode;
+	mutex_lock(&hdmi.lock);
 
-	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
-		int r;
+	cm = hdmi_get_code(timings);
+	hdmi.ip_data.cfg.cm = cm;
 
-		hdmi_power_off(dssdev);
+	t = hdmi_get_timings();
+	if (t != NULL)
+		hdmi.ip_data.cfg = *t;
 
-		r = hdmi_power_on(dssdev);
-		if (r)
-			DSSERR("failed to power on device\n");
-	} else {
-		dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
-	}
+	mutex_unlock(&hdmi.lock);
 }
 
 static void hdmi_dump_regs(struct seq_file *s)
@@ -640,20 +692,20 @@
 
 int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
 {
-	struct omap_dss_hdmi_data *priv = dssdev->data;
+	struct omap_dss_output *out = dssdev->output;
 	int r = 0;
 
 	DSSDBG("ENTER hdmi_display_enable\n");
 
 	mutex_lock(&hdmi.lock);
 
-	if (dssdev->manager == NULL) {
-		DSSERR("failed to enable display: no manager\n");
+	if (out == NULL || out->manager == NULL) {
+		DSSERR("failed to enable display: no output/manager\n");
 		r = -ENODEV;
 		goto err0;
 	}
 
-	hdmi.ip_data.hpd_gpio = priv->hpd_gpio;
+	hdmi.ip_data.hpd_gpio = hdmi.hpd_gpio;
 
 	r = omap_dss_start_device(dssdev);
 	if (r) {
@@ -661,26 +713,15 @@
 		goto err0;
 	}
 
-	if (dssdev->platform_enable) {
-		r = dssdev->platform_enable(dssdev);
-		if (r) {
-			DSSERR("failed to enable GPIO's\n");
-			goto err1;
-		}
-	}
-
 	r = hdmi_power_on(dssdev);
 	if (r) {
 		DSSERR("failed to power on device\n");
-		goto err2;
+		goto err1;
 	}
 
 	mutex_unlock(&hdmi.lock);
 	return 0;
 
-err2:
-	if (dssdev->platform_disable)
-		dssdev->platform_disable(dssdev);
 err1:
 	omap_dss_stop_device(dssdev);
 err0:
@@ -696,9 +737,6 @@
 
 	hdmi_power_off(dssdev);
 
-	if (dssdev->platform_disable)
-		dssdev->platform_disable(dssdev);
-
 	omap_dss_stop_device(dssdev);
 
 	mutex_unlock(&hdmi.lock);
@@ -869,10 +907,14 @@
 
 #endif
 
-static void __init hdmi_probe_pdata(struct platform_device *pdev)
+static struct omap_dss_device * __init hdmi_find_dssdev(struct platform_device *pdev)
 {
 	struct omap_dss_board_info *pdata = pdev->dev.platform_data;
-	int r, i;
+	const char *def_disp_name = dss_get_default_display_name();
+	struct omap_dss_device *def_dssdev;
+	int i;
+
+	def_dssdev = NULL;
 
 	for (i = 0; i < pdata->num_devices; ++i) {
 		struct omap_dss_device *dssdev = pdata->devices[i];
@@ -880,17 +922,76 @@
 		if (dssdev->type != OMAP_DISPLAY_TYPE_HDMI)
 			continue;
 
-		r = hdmi_init_display(dssdev);
-		if (r) {
-			DSSERR("device %s init failed: %d\n", dssdev->name, r);
-			continue;
-		}
+		if (def_dssdev == NULL)
+			def_dssdev = dssdev;
 
-		r = omap_dss_register_device(dssdev, &pdev->dev, i);
-		if (r)
-			DSSERR("device %s register failed: %d\n",
-					dssdev->name, r);
+		if (def_disp_name != NULL &&
+				strcmp(dssdev->name, def_disp_name) == 0) {
+			def_dssdev = dssdev;
+			break;
+		}
 	}
+
+	return def_dssdev;
+}
+
+static void __init hdmi_probe_pdata(struct platform_device *pdev)
+{
+	struct omap_dss_device *plat_dssdev;
+	struct omap_dss_device *dssdev;
+	struct omap_dss_hdmi_data *priv;
+	int r;
+
+	plat_dssdev = hdmi_find_dssdev(pdev);
+
+	if (!plat_dssdev)
+		return;
+
+	dssdev = dss_alloc_and_init_device(&pdev->dev);
+	if (!dssdev)
+		return;
+
+	dss_copy_device_pdata(dssdev, plat_dssdev);
+
+	priv = dssdev->data;
+
+	hdmi.ct_cp_hpd_gpio = priv->ct_cp_hpd_gpio;
+	hdmi.ls_oe_gpio = priv->ls_oe_gpio;
+	hdmi.hpd_gpio = priv->hpd_gpio;
+
+	dssdev->channel = OMAP_DSS_CHANNEL_DIGIT;
+
+	r = hdmi_init_display(dssdev);
+	if (r) {
+		DSSERR("device %s init failed: %d\n", dssdev->name, r);
+		dss_put_device(dssdev);
+		return;
+	}
+
+	r = dss_add_device(dssdev);
+	if (r) {
+		DSSERR("device %s register failed: %d\n", dssdev->name, r);
+		dss_put_device(dssdev);
+		return;
+	}
+}
+
+static void __init hdmi_init_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out = &hdmi.output;
+
+	out->pdev = pdev;
+	out->id = OMAP_DSS_OUTPUT_HDMI;
+	out->type = OMAP_DISPLAY_TYPE_HDMI;
+
+	dss_register_output(out);
+}
+
+static void __exit hdmi_uninit_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out = &hdmi.output;
+
+	dss_unregister_output(out);
 }
 
 /* HDMI HW IP initialisation */
@@ -929,23 +1030,37 @@
 	hdmi.ip_data.core_av_offset = HDMI_CORE_AV;
 	hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
 	hdmi.ip_data.phy_offset = HDMI_PHY;
+
 	mutex_init(&hdmi.ip_data.lock);
 
 	hdmi_panel_init();
 
 	dss_debugfs_create_file("hdmi", hdmi_dump_regs);
 
+	hdmi_init_output(pdev);
+
 	hdmi_probe_pdata(pdev);
 
 	return 0;
 }
 
+static int __exit hdmi_remove_child(struct device *dev, void *data)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	hdmi_uninit_display(dssdev);
+	return 0;
+}
+
 static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
 {
-	omap_dss_unregister_child_devices(&pdev->dev);
+	device_for_each_child(&pdev->dev, NULL, hdmi_remove_child);
+
+	dss_unregister_child_devices(&pdev->dev);
 
 	hdmi_panel_exit();
 
+	hdmi_uninit_output(pdev);
+
 	pm_runtime_disable(&pdev->dev);
 
 	hdmi_put_clocks();
diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c
index e10844f..69fb115 100644
--- a/drivers/video/omap2/dss/hdmi_panel.c
+++ b/drivers/video/omap2/dss/hdmi_panel.c
@@ -41,17 +41,34 @@
 
 static int hdmi_panel_probe(struct omap_dss_device *dssdev)
 {
+	/* Initialize default timings to VGA in DVI mode */
+	const struct omap_video_timings default_timings = {
+		.x_res		= 640,
+		.y_res		= 480,
+		.pixel_clock	= 25175,
+		.hsw		= 96,
+		.hfp		= 16,
+		.hbp		= 48,
+		.vsw		= 2,
+		.vfp		= 11,
+		.vbp		= 31,
+
+		.vsync_level	= OMAPDSS_SIG_ACTIVE_LOW,
+		.hsync_level	= OMAPDSS_SIG_ACTIVE_LOW,
+
+		.interlace	= false,
+	};
+
 	DSSDBG("ENTER hdmi_panel_probe\n");
 
-	dssdev->panel.timings = (struct omap_video_timings)
-			{ 640, 480, 25175, 96, 16, 48, 2, 11, 31,
-				OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
-				false,
-			};
+	dssdev->panel.timings = default_timings;
 
 	DSSDBG("hdmi_panel_probe x_res= %d y_res = %d\n",
 		dssdev->panel.timings.x_res,
 		dssdev->panel.timings.y_res);
+
+	omapdss_hdmi_display_set_timing(dssdev, &dssdev->panel.timings);
+
 	return 0;
 }
 
@@ -228,6 +245,8 @@
 		goto err;
 	}
 
+	omapdss_hdmi_display_set_timing(dssdev, &dssdev->panel.timings);
+
 	r = omapdss_hdmi_display_enable(dssdev);
 	if (r) {
 		DSSERR("failed to power on\n");
@@ -336,8 +355,8 @@
 	 */
 	hdmi_panel_audio_disable(dssdev);
 
+	omapdss_hdmi_display_set_timing(dssdev, timings);
 	dssdev->panel.timings = *timings;
-	omapdss_hdmi_display_set_timing(dssdev);
 
 	mutex_unlock(&hdmi.lock);
 }
diff --git a/drivers/video/omap2/dss/manager-sysfs.c b/drivers/video/omap2/dss/manager-sysfs.c
new file mode 100644
index 0000000..9a2fb59
--- /dev/null
+++ b/drivers/video/omap2/dss/manager-sysfs.c
@@ -0,0 +1,512 @@
+/*
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * Some code and ideas taken from drivers/video/omap/ driver
+ * by Imre Deak.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define DSS_SUBSYS_NAME "MANAGER"
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/jiffies.h>
+
+#include <video/omapdss.h>
+
+#include "dss.h"
+#include "dss_features.h"
+
+static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%s\n", mgr->name);
+}
+
+static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf)
+{
+	struct omap_dss_device *dssdev = mgr->get_device(mgr);
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", dssdev ?
+			dssdev->name : "<none>");
+}
+
+static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
+		const char *buf, size_t size)
+{
+	int r = 0;
+	size_t len = size;
+	struct omap_dss_device *dssdev = NULL;
+
+	int match(struct omap_dss_device *dssdev, void *data)
+	{
+		const char *str = data;
+		return sysfs_streq(dssdev->name, str);
+	}
+
+	if (buf[size-1] == '\n')
+		--len;
+
+	if (len > 0)
+		dssdev = omap_dss_find_device((void *)buf, match);
+
+	if (len > 0 && dssdev == NULL)
+		return -EINVAL;
+
+	if (dssdev)
+		DSSDBG("display %s found\n", dssdev->name);
+
+	if (mgr->output) {
+		r = mgr->unset_output(mgr);
+		if (r) {
+			DSSERR("failed to unset current output\n");
+			goto put_device;
+		}
+	}
+
+	if (dssdev) {
+		struct omap_dss_output *out = dssdev->output;
+
+		/*
+		 * a registered device should have an output connected to it
+		 * already
+		 */
+		if (!out) {
+			DSSERR("device has no output connected to it\n");
+			goto put_device;
+		}
+
+		r = mgr->set_output(mgr, out);
+		if (r) {
+			DSSERR("failed to set manager output\n");
+			goto put_device;
+		}
+
+		r = mgr->apply(mgr);
+		if (r) {
+			DSSERR("failed to apply dispc config\n");
+			goto put_device;
+		}
+	}
+
+put_device:
+	if (dssdev)
+		omap_dss_put_device(dssdev);
+
+	return r ? r : size;
+}
+
+static ssize_t manager_default_color_show(struct omap_overlay_manager *mgr,
+					  char *buf)
+{
+	struct omap_overlay_manager_info info;
+
+	mgr->get_manager_info(mgr, &info);
+
+	return snprintf(buf, PAGE_SIZE, "%#x\n", info.default_color);
+}
+
+static ssize_t manager_default_color_store(struct omap_overlay_manager *mgr,
+					   const char *buf, size_t size)
+{
+	struct omap_overlay_manager_info info;
+	u32 color;
+	int r;
+
+	r = kstrtouint(buf, 0, &color);
+	if (r)
+		return r;
+
+	mgr->get_manager_info(mgr, &info);
+
+	info.default_color = color;
+
+	r = mgr->set_manager_info(mgr, &info);
+	if (r)
+		return r;
+
+	r = mgr->apply(mgr);
+	if (r)
+		return r;
+
+	return size;
+}
+
+static const char *trans_key_type_str[] = {
+	"gfx-destination",
+	"video-source",
+};
+
+static ssize_t manager_trans_key_type_show(struct omap_overlay_manager *mgr,
+					   char *buf)
+{
+	enum omap_dss_trans_key_type key_type;
+	struct omap_overlay_manager_info info;
+
+	mgr->get_manager_info(mgr, &info);
+
+	key_type = info.trans_key_type;
+	BUG_ON(key_type >= ARRAY_SIZE(trans_key_type_str));
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", trans_key_type_str[key_type]);
+}
+
+static ssize_t manager_trans_key_type_store(struct omap_overlay_manager *mgr,
+					    const char *buf, size_t size)
+{
+	enum omap_dss_trans_key_type key_type;
+	struct omap_overlay_manager_info info;
+	int r;
+
+	for (key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
+			key_type < ARRAY_SIZE(trans_key_type_str); key_type++) {
+		if (sysfs_streq(buf, trans_key_type_str[key_type]))
+			break;
+	}
+
+	if (key_type == ARRAY_SIZE(trans_key_type_str))
+		return -EINVAL;
+
+	mgr->get_manager_info(mgr, &info);
+
+	info.trans_key_type = key_type;
+
+	r = mgr->set_manager_info(mgr, &info);
+	if (r)
+		return r;
+
+	r = mgr->apply(mgr);
+	if (r)
+		return r;
+
+	return size;
+}
+
+static ssize_t manager_trans_key_value_show(struct omap_overlay_manager *mgr,
+					    char *buf)
+{
+	struct omap_overlay_manager_info info;
+
+	mgr->get_manager_info(mgr, &info);
+
+	return snprintf(buf, PAGE_SIZE, "%#x\n", info.trans_key);
+}
+
+static ssize_t manager_trans_key_value_store(struct omap_overlay_manager *mgr,
+					     const char *buf, size_t size)
+{
+	struct omap_overlay_manager_info info;
+	u32 key_value;
+	int r;
+
+	r = kstrtouint(buf, 0, &key_value);
+	if (r)
+		return r;
+
+	mgr->get_manager_info(mgr, &info);
+
+	info.trans_key = key_value;
+
+	r = mgr->set_manager_info(mgr, &info);
+	if (r)
+		return r;
+
+	r = mgr->apply(mgr);
+	if (r)
+		return r;
+
+	return size;
+}
+
+static ssize_t manager_trans_key_enabled_show(struct omap_overlay_manager *mgr,
+					      char *buf)
+{
+	struct omap_overlay_manager_info info;
+
+	mgr->get_manager_info(mgr, &info);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", info.trans_enabled);
+}
+
+static ssize_t manager_trans_key_enabled_store(struct omap_overlay_manager *mgr,
+					       const char *buf, size_t size)
+{
+	struct omap_overlay_manager_info info;
+	bool enable;
+	int r;
+
+	r = strtobool(buf, &enable);
+	if (r)
+		return r;
+
+	mgr->get_manager_info(mgr, &info);
+
+	info.trans_enabled = enable;
+
+	r = mgr->set_manager_info(mgr, &info);
+	if (r)
+		return r;
+
+	r = mgr->apply(mgr);
+	if (r)
+		return r;
+
+	return size;
+}
+
+static ssize_t manager_alpha_blending_enabled_show(
+		struct omap_overlay_manager *mgr, char *buf)
+{
+	struct omap_overlay_manager_info info;
+
+	mgr->get_manager_info(mgr, &info);
+
+	WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER));
+
+	return snprintf(buf, PAGE_SIZE, "%d\n",
+		info.partial_alpha_enabled);
+}
+
+static ssize_t manager_alpha_blending_enabled_store(
+		struct omap_overlay_manager *mgr,
+		const char *buf, size_t size)
+{
+	struct omap_overlay_manager_info info;
+	bool enable;
+	int r;
+
+	WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER));
+
+	r = strtobool(buf, &enable);
+	if (r)
+		return r;
+
+	mgr->get_manager_info(mgr, &info);
+
+	info.partial_alpha_enabled = enable;
+
+	r = mgr->set_manager_info(mgr, &info);
+	if (r)
+		return r;
+
+	r = mgr->apply(mgr);
+	if (r)
+		return r;
+
+	return size;
+}
+
+static ssize_t manager_cpr_enable_show(struct omap_overlay_manager *mgr,
+		char *buf)
+{
+	struct omap_overlay_manager_info info;
+
+	mgr->get_manager_info(mgr, &info);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", info.cpr_enable);
+}
+
+static ssize_t manager_cpr_enable_store(struct omap_overlay_manager *mgr,
+		const char *buf, size_t size)
+{
+	struct omap_overlay_manager_info info;
+	int r;
+	bool enable;
+
+	if (!dss_has_feature(FEAT_CPR))
+		return -ENODEV;
+
+	r = strtobool(buf, &enable);
+	if (r)
+		return r;
+
+	mgr->get_manager_info(mgr, &info);
+
+	if (info.cpr_enable == enable)
+		return size;
+
+	info.cpr_enable = enable;
+
+	r = mgr->set_manager_info(mgr, &info);
+	if (r)
+		return r;
+
+	r = mgr->apply(mgr);
+	if (r)
+		return r;
+
+	return size;
+}
+
+static ssize_t manager_cpr_coef_show(struct omap_overlay_manager *mgr,
+		char *buf)
+{
+	struct omap_overlay_manager_info info;
+
+	mgr->get_manager_info(mgr, &info);
+
+	return snprintf(buf, PAGE_SIZE,
+			"%d %d %d %d %d %d %d %d %d\n",
+			info.cpr_coefs.rr,
+			info.cpr_coefs.rg,
+			info.cpr_coefs.rb,
+			info.cpr_coefs.gr,
+			info.cpr_coefs.gg,
+			info.cpr_coefs.gb,
+			info.cpr_coefs.br,
+			info.cpr_coefs.bg,
+			info.cpr_coefs.bb);
+}
+
+static ssize_t manager_cpr_coef_store(struct omap_overlay_manager *mgr,
+		const char *buf, size_t size)
+{
+	struct omap_overlay_manager_info info;
+	struct omap_dss_cpr_coefs coefs;
+	int r, i;
+	s16 *arr;
+
+	if (!dss_has_feature(FEAT_CPR))
+		return -ENODEV;
+
+	if (sscanf(buf, "%hd %hd %hd %hd %hd %hd %hd %hd %hd",
+				&coefs.rr, &coefs.rg, &coefs.rb,
+				&coefs.gr, &coefs.gg, &coefs.gb,
+				&coefs.br, &coefs.bg, &coefs.bb) != 9)
+		return -EINVAL;
+
+	arr = (s16[]){ coefs.rr, coefs.rg, coefs.rb,
+		coefs.gr, coefs.gg, coefs.gb,
+		coefs.br, coefs.bg, coefs.bb };
+
+	for (i = 0; i < 9; ++i) {
+		if (arr[i] < -512 || arr[i] > 511)
+			return -EINVAL;
+	}
+
+	mgr->get_manager_info(mgr, &info);
+
+	info.cpr_coefs = coefs;
+
+	r = mgr->set_manager_info(mgr, &info);
+	if (r)
+		return r;
+
+	r = mgr->apply(mgr);
+	if (r)
+		return r;
+
+	return size;
+}
+
+struct manager_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct omap_overlay_manager *, char *);
+	ssize_t	(*store)(struct omap_overlay_manager *, const char *, size_t);
+};
+
+#define MANAGER_ATTR(_name, _mode, _show, _store) \
+	struct manager_attribute manager_attr_##_name = \
+	__ATTR(_name, _mode, _show, _store)
+
+static MANAGER_ATTR(name, S_IRUGO, manager_name_show, NULL);
+static MANAGER_ATTR(display, S_IRUGO|S_IWUSR,
+		manager_display_show, manager_display_store);
+static MANAGER_ATTR(default_color, S_IRUGO|S_IWUSR,
+		manager_default_color_show, manager_default_color_store);
+static MANAGER_ATTR(trans_key_type, S_IRUGO|S_IWUSR,
+		manager_trans_key_type_show, manager_trans_key_type_store);
+static MANAGER_ATTR(trans_key_value, S_IRUGO|S_IWUSR,
+		manager_trans_key_value_show, manager_trans_key_value_store);
+static MANAGER_ATTR(trans_key_enabled, S_IRUGO|S_IWUSR,
+		manager_trans_key_enabled_show,
+		manager_trans_key_enabled_store);
+static MANAGER_ATTR(alpha_blending_enabled, S_IRUGO|S_IWUSR,
+		manager_alpha_blending_enabled_show,
+		manager_alpha_blending_enabled_store);
+static MANAGER_ATTR(cpr_enable, S_IRUGO|S_IWUSR,
+		manager_cpr_enable_show,
+		manager_cpr_enable_store);
+static MANAGER_ATTR(cpr_coef, S_IRUGO|S_IWUSR,
+		manager_cpr_coef_show,
+		manager_cpr_coef_store);
+
+
+static struct attribute *manager_sysfs_attrs[] = {
+	&manager_attr_name.attr,
+	&manager_attr_display.attr,
+	&manager_attr_default_color.attr,
+	&manager_attr_trans_key_type.attr,
+	&manager_attr_trans_key_value.attr,
+	&manager_attr_trans_key_enabled.attr,
+	&manager_attr_alpha_blending_enabled.attr,
+	&manager_attr_cpr_enable.attr,
+	&manager_attr_cpr_coef.attr,
+	NULL
+};
+
+static ssize_t manager_attr_show(struct kobject *kobj, struct attribute *attr,
+		char *buf)
+{
+	struct omap_overlay_manager *manager;
+	struct manager_attribute *manager_attr;
+
+	manager = container_of(kobj, struct omap_overlay_manager, kobj);
+	manager_attr = container_of(attr, struct manager_attribute, attr);
+
+	if (!manager_attr->show)
+		return -ENOENT;
+
+	return manager_attr->show(manager, buf);
+}
+
+static ssize_t manager_attr_store(struct kobject *kobj, struct attribute *attr,
+		const char *buf, size_t size)
+{
+	struct omap_overlay_manager *manager;
+	struct manager_attribute *manager_attr;
+
+	manager = container_of(kobj, struct omap_overlay_manager, kobj);
+	manager_attr = container_of(attr, struct manager_attribute, attr);
+
+	if (!manager_attr->store)
+		return -ENOENT;
+
+	return manager_attr->store(manager, buf, size);
+}
+
+static const struct sysfs_ops manager_sysfs_ops = {
+	.show = manager_attr_show,
+	.store = manager_attr_store,
+};
+
+static struct kobj_type manager_ktype = {
+	.sysfs_ops = &manager_sysfs_ops,
+	.default_attrs = manager_sysfs_attrs,
+};
+
+int dss_manager_kobj_init(struct omap_overlay_manager *mgr,
+		struct platform_device *pdev)
+{
+	return kobject_init_and_add(&mgr->kobj, &manager_ktype,
+			&pdev->dev.kobj, "manager%d", mgr->id);
+}
+
+void dss_manager_kobj_uninit(struct omap_overlay_manager *mgr)
+{
+	kobject_del(&mgr->kobj);
+	kobject_put(&mgr->kobj);
+}
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 53710fa..c54d2f6 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -36,463 +36,15 @@
 static int num_managers;
 static struct omap_overlay_manager *managers;
 
-static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf)
+static inline struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr)
 {
-	return snprintf(buf, PAGE_SIZE, "%s\n", mgr->name);
+	return mgr->output ? mgr->output->device : NULL;
 }
 
-static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf)
-{
-	return snprintf(buf, PAGE_SIZE, "%s\n",
-			mgr->device ? mgr->device->name : "<none>");
-}
-
-static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
-		const char *buf, size_t size)
-{
-	int r = 0;
-	size_t len = size;
-	struct omap_dss_device *dssdev = NULL;
-
-	int match(struct omap_dss_device *dssdev, void *data)
-	{
-		const char *str = data;
-		return sysfs_streq(dssdev->name, str);
-	}
-
-	if (buf[size-1] == '\n')
-		--len;
-
-	if (len > 0)
-		dssdev = omap_dss_find_device((void *)buf, match);
-
-	if (len > 0 && dssdev == NULL)
-		return -EINVAL;
-
-	if (dssdev)
-		DSSDBG("display %s found\n", dssdev->name);
-
-	if (mgr->device) {
-		r = mgr->unset_device(mgr);
-		if (r) {
-			DSSERR("failed to unset display\n");
-			goto put_device;
-		}
-	}
-
-	if (dssdev) {
-		r = mgr->set_device(mgr, dssdev);
-		if (r) {
-			DSSERR("failed to set manager\n");
-			goto put_device;
-		}
-
-		r = mgr->apply(mgr);
-		if (r) {
-			DSSERR("failed to apply dispc config\n");
-			goto put_device;
-		}
-	}
-
-put_device:
-	if (dssdev)
-		omap_dss_put_device(dssdev);
-
-	return r ? r : size;
-}
-
-static ssize_t manager_default_color_show(struct omap_overlay_manager *mgr,
-					  char *buf)
-{
-	struct omap_overlay_manager_info info;
-
-	mgr->get_manager_info(mgr, &info);
-
-	return snprintf(buf, PAGE_SIZE, "%#x\n", info.default_color);
-}
-
-static ssize_t manager_default_color_store(struct omap_overlay_manager *mgr,
-					   const char *buf, size_t size)
-{
-	struct omap_overlay_manager_info info;
-	u32 color;
-	int r;
-
-	r = kstrtouint(buf, 0, &color);
-	if (r)
-		return r;
-
-	mgr->get_manager_info(mgr, &info);
-
-	info.default_color = color;
-
-	r = mgr->set_manager_info(mgr, &info);
-	if (r)
-		return r;
-
-	r = mgr->apply(mgr);
-	if (r)
-		return r;
-
-	return size;
-}
-
-static const char *trans_key_type_str[] = {
-	"gfx-destination",
-	"video-source",
-};
-
-static ssize_t manager_trans_key_type_show(struct omap_overlay_manager *mgr,
-					   char *buf)
-{
-	enum omap_dss_trans_key_type key_type;
-	struct omap_overlay_manager_info info;
-
-	mgr->get_manager_info(mgr, &info);
-
-	key_type = info.trans_key_type;
-	BUG_ON(key_type >= ARRAY_SIZE(trans_key_type_str));
-
-	return snprintf(buf, PAGE_SIZE, "%s\n", trans_key_type_str[key_type]);
-}
-
-static ssize_t manager_trans_key_type_store(struct omap_overlay_manager *mgr,
-					    const char *buf, size_t size)
-{
-	enum omap_dss_trans_key_type key_type;
-	struct omap_overlay_manager_info info;
-	int r;
-
-	for (key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
-			key_type < ARRAY_SIZE(trans_key_type_str); key_type++) {
-		if (sysfs_streq(buf, trans_key_type_str[key_type]))
-			break;
-	}
-
-	if (key_type == ARRAY_SIZE(trans_key_type_str))
-		return -EINVAL;
-
-	mgr->get_manager_info(mgr, &info);
-
-	info.trans_key_type = key_type;
-
-	r = mgr->set_manager_info(mgr, &info);
-	if (r)
-		return r;
-
-	r = mgr->apply(mgr);
-	if (r)
-		return r;
-
-	return size;
-}
-
-static ssize_t manager_trans_key_value_show(struct omap_overlay_manager *mgr,
-					    char *buf)
-{
-	struct omap_overlay_manager_info info;
-
-	mgr->get_manager_info(mgr, &info);
-
-	return snprintf(buf, PAGE_SIZE, "%#x\n", info.trans_key);
-}
-
-static ssize_t manager_trans_key_value_store(struct omap_overlay_manager *mgr,
-					     const char *buf, size_t size)
-{
-	struct omap_overlay_manager_info info;
-	u32 key_value;
-	int r;
-
-	r = kstrtouint(buf, 0, &key_value);
-	if (r)
-		return r;
-
-	mgr->get_manager_info(mgr, &info);
-
-	info.trans_key = key_value;
-
-	r = mgr->set_manager_info(mgr, &info);
-	if (r)
-		return r;
-
-	r = mgr->apply(mgr);
-	if (r)
-		return r;
-
-	return size;
-}
-
-static ssize_t manager_trans_key_enabled_show(struct omap_overlay_manager *mgr,
-					      char *buf)
-{
-	struct omap_overlay_manager_info info;
-
-	mgr->get_manager_info(mgr, &info);
-
-	return snprintf(buf, PAGE_SIZE, "%d\n", info.trans_enabled);
-}
-
-static ssize_t manager_trans_key_enabled_store(struct omap_overlay_manager *mgr,
-					       const char *buf, size_t size)
-{
-	struct omap_overlay_manager_info info;
-	bool enable;
-	int r;
-
-	r = strtobool(buf, &enable);
-	if (r)
-		return r;
-
-	mgr->get_manager_info(mgr, &info);
-
-	info.trans_enabled = enable;
-
-	r = mgr->set_manager_info(mgr, &info);
-	if (r)
-		return r;
-
-	r = mgr->apply(mgr);
-	if (r)
-		return r;
-
-	return size;
-}
-
-static ssize_t manager_alpha_blending_enabled_show(
-		struct omap_overlay_manager *mgr, char *buf)
-{
-	struct omap_overlay_manager_info info;
-
-	mgr->get_manager_info(mgr, &info);
-
-	WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER));
-
-	return snprintf(buf, PAGE_SIZE, "%d\n",
-		info.partial_alpha_enabled);
-}
-
-static ssize_t manager_alpha_blending_enabled_store(
-		struct omap_overlay_manager *mgr,
-		const char *buf, size_t size)
-{
-	struct omap_overlay_manager_info info;
-	bool enable;
-	int r;
-
-	WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER));
-
-	r = strtobool(buf, &enable);
-	if (r)
-		return r;
-
-	mgr->get_manager_info(mgr, &info);
-
-	info.partial_alpha_enabled = enable;
-
-	r = mgr->set_manager_info(mgr, &info);
-	if (r)
-		return r;
-
-	r = mgr->apply(mgr);
-	if (r)
-		return r;
-
-	return size;
-}
-
-static ssize_t manager_cpr_enable_show(struct omap_overlay_manager *mgr,
-		char *buf)
-{
-	struct omap_overlay_manager_info info;
-
-	mgr->get_manager_info(mgr, &info);
-
-	return snprintf(buf, PAGE_SIZE, "%d\n", info.cpr_enable);
-}
-
-static ssize_t manager_cpr_enable_store(struct omap_overlay_manager *mgr,
-		const char *buf, size_t size)
-{
-	struct omap_overlay_manager_info info;
-	int r;
-	bool enable;
-
-	if (!dss_has_feature(FEAT_CPR))
-		return -ENODEV;
-
-	r = strtobool(buf, &enable);
-	if (r)
-		return r;
-
-	mgr->get_manager_info(mgr, &info);
-
-	if (info.cpr_enable == enable)
-		return size;
-
-	info.cpr_enable = enable;
-
-	r = mgr->set_manager_info(mgr, &info);
-	if (r)
-		return r;
-
-	r = mgr->apply(mgr);
-	if (r)
-		return r;
-
-	return size;
-}
-
-static ssize_t manager_cpr_coef_show(struct omap_overlay_manager *mgr,
-		char *buf)
-{
-	struct omap_overlay_manager_info info;
-
-	mgr->get_manager_info(mgr, &info);
-
-	return snprintf(buf, PAGE_SIZE,
-			"%d %d %d %d %d %d %d %d %d\n",
-			info.cpr_coefs.rr,
-			info.cpr_coefs.rg,
-			info.cpr_coefs.rb,
-			info.cpr_coefs.gr,
-			info.cpr_coefs.gg,
-			info.cpr_coefs.gb,
-			info.cpr_coefs.br,
-			info.cpr_coefs.bg,
-			info.cpr_coefs.bb);
-}
-
-static ssize_t manager_cpr_coef_store(struct omap_overlay_manager *mgr,
-		const char *buf, size_t size)
-{
-	struct omap_overlay_manager_info info;
-	struct omap_dss_cpr_coefs coefs;
-	int r, i;
-	s16 *arr;
-
-	if (!dss_has_feature(FEAT_CPR))
-		return -ENODEV;
-
-	if (sscanf(buf, "%hd %hd %hd %hd %hd %hd %hd %hd %hd",
-				&coefs.rr, &coefs.rg, &coefs.rb,
-				&coefs.gr, &coefs.gg, &coefs.gb,
-				&coefs.br, &coefs.bg, &coefs.bb) != 9)
-		return -EINVAL;
-
-	arr = (s16[]){ coefs.rr, coefs.rg, coefs.rb,
-		coefs.gr, coefs.gg, coefs.gb,
-		coefs.br, coefs.bg, coefs.bb };
-
-	for (i = 0; i < 9; ++i) {
-		if (arr[i] < -512 || arr[i] > 511)
-			return -EINVAL;
-	}
-
-	mgr->get_manager_info(mgr, &info);
-
-	info.cpr_coefs = coefs;
-
-	r = mgr->set_manager_info(mgr, &info);
-	if (r)
-		return r;
-
-	r = mgr->apply(mgr);
-	if (r)
-		return r;
-
-	return size;
-}
-
-struct manager_attribute {
-	struct attribute attr;
-	ssize_t (*show)(struct omap_overlay_manager *, char *);
-	ssize_t	(*store)(struct omap_overlay_manager *, const char *, size_t);
-};
-
-#define MANAGER_ATTR(_name, _mode, _show, _store) \
-	struct manager_attribute manager_attr_##_name = \
-	__ATTR(_name, _mode, _show, _store)
-
-static MANAGER_ATTR(name, S_IRUGO, manager_name_show, NULL);
-static MANAGER_ATTR(display, S_IRUGO|S_IWUSR,
-		manager_display_show, manager_display_store);
-static MANAGER_ATTR(default_color, S_IRUGO|S_IWUSR,
-		manager_default_color_show, manager_default_color_store);
-static MANAGER_ATTR(trans_key_type, S_IRUGO|S_IWUSR,
-		manager_trans_key_type_show, manager_trans_key_type_store);
-static MANAGER_ATTR(trans_key_value, S_IRUGO|S_IWUSR,
-		manager_trans_key_value_show, manager_trans_key_value_store);
-static MANAGER_ATTR(trans_key_enabled, S_IRUGO|S_IWUSR,
-		manager_trans_key_enabled_show,
-		manager_trans_key_enabled_store);
-static MANAGER_ATTR(alpha_blending_enabled, S_IRUGO|S_IWUSR,
-		manager_alpha_blending_enabled_show,
-		manager_alpha_blending_enabled_store);
-static MANAGER_ATTR(cpr_enable, S_IRUGO|S_IWUSR,
-		manager_cpr_enable_show,
-		manager_cpr_enable_store);
-static MANAGER_ATTR(cpr_coef, S_IRUGO|S_IWUSR,
-		manager_cpr_coef_show,
-		manager_cpr_coef_store);
-
-
-static struct attribute *manager_sysfs_attrs[] = {
-	&manager_attr_name.attr,
-	&manager_attr_display.attr,
-	&manager_attr_default_color.attr,
-	&manager_attr_trans_key_type.attr,
-	&manager_attr_trans_key_value.attr,
-	&manager_attr_trans_key_enabled.attr,
-	&manager_attr_alpha_blending_enabled.attr,
-	&manager_attr_cpr_enable.attr,
-	&manager_attr_cpr_coef.attr,
-	NULL
-};
-
-static ssize_t manager_attr_show(struct kobject *kobj, struct attribute *attr,
-		char *buf)
-{
-	struct omap_overlay_manager *manager;
-	struct manager_attribute *manager_attr;
-
-	manager = container_of(kobj, struct omap_overlay_manager, kobj);
-	manager_attr = container_of(attr, struct manager_attribute, attr);
-
-	if (!manager_attr->show)
-		return -ENOENT;
-
-	return manager_attr->show(manager, buf);
-}
-
-static ssize_t manager_attr_store(struct kobject *kobj, struct attribute *attr,
-		const char *buf, size_t size)
-{
-	struct omap_overlay_manager *manager;
-	struct manager_attribute *manager_attr;
-
-	manager = container_of(kobj, struct omap_overlay_manager, kobj);
-	manager_attr = container_of(attr, struct manager_attribute, attr);
-
-	if (!manager_attr->store)
-		return -ENOENT;
-
-	return manager_attr->store(manager, buf, size);
-}
-
-static const struct sysfs_ops manager_sysfs_ops = {
-	.show = manager_attr_show,
-	.store = manager_attr_store,
-};
-
-static struct kobj_type manager_ktype = {
-	.sysfs_ops = &manager_sysfs_ops,
-	.default_attrs = manager_sysfs_attrs,
-};
-
 static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
 {
 	unsigned long timeout = msecs_to_jiffies(500);
+	struct omap_dss_device *dssdev = mgr->get_device(mgr);
 	u32 irq;
 	int r;
 
@@ -500,9 +52,9 @@
 	if (r)
 		return r;
 
-	if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC)
+	if (dssdev->type == OMAP_DISPLAY_TYPE_VENC)
 		irq = DISPC_IRQ_EVSYNC_ODD;
-	else if (mgr->device->type == OMAP_DISPLAY_TYPE_HDMI)
+	else if (dssdev->type == OMAP_DISPLAY_TYPE_HDMI)
 		irq = DISPC_IRQ_EVSYNC_EVEN;
 	else
 		irq = dispc_mgr_get_vsync_irq(mgr->id);
@@ -547,23 +99,24 @@
 			break;
 		}
 
-		mgr->set_device = &dss_mgr_set_device;
-		mgr->unset_device = &dss_mgr_unset_device;
+		mgr->set_output = &dss_mgr_set_output;
+		mgr->unset_output = &dss_mgr_unset_output;
 		mgr->apply = &omap_dss_mgr_apply;
 		mgr->set_manager_info = &dss_mgr_set_info;
 		mgr->get_manager_info = &dss_mgr_get_info;
 		mgr->wait_for_go = &dss_mgr_wait_for_go;
 		mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
+		mgr->get_device = &dss_mgr_get_device;
 
 		mgr->caps = 0;
 		mgr->supported_displays =
 			dss_feat_get_supported_displays(mgr->id);
+		mgr->supported_outputs =
+			dss_feat_get_supported_outputs(mgr->id);
 
 		INIT_LIST_HEAD(&mgr->overlays);
 
-		r = kobject_init_and_add(&mgr->kobj, &manager_ktype,
-				&pdev->dev.kobj, "manager%d", i);
-
+		r = dss_manager_kobj_init(mgr, pdev);
 		if (r)
 			DSSERR("failed to create sysfs file\n");
 	}
@@ -577,9 +130,7 @@
 
 	for (i = 0; i < num_managers; ++i) {
 		struct omap_overlay_manager *mgr = &managers[i];
-
-		kobject_del(&mgr->kobj);
-		kobject_put(&mgr->kobj);
+		dss_manager_kobj_uninit(mgr);
 	}
 
 	kfree(managers);
diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
new file mode 100644
index 0000000..813f266
--- /dev/null
+++ b/drivers/video/omap2/dss/output.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2012 Texas Instruments Ltd
+ * Author: Archit Taneja <archit@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <video/omapdss.h>
+
+#include "dss.h"
+
+static LIST_HEAD(output_list);
+static DEFINE_MUTEX(output_lock);
+
+int omapdss_output_set_device(struct omap_dss_output *out,
+		struct omap_dss_device *dssdev)
+{
+	int r;
+
+	mutex_lock(&output_lock);
+
+	if (out->device) {
+		DSSERR("output already has device %s connected to it\n",
+			out->device->name);
+		r = -EINVAL;
+		goto err;
+	}
+
+	if (out->type != dssdev->type) {
+		DSSERR("output type and display type don't match\n");
+		r = -EINVAL;
+		goto err;
+	}
+
+	out->device = dssdev;
+	dssdev->output = out;
+
+	mutex_unlock(&output_lock);
+
+	return 0;
+err:
+	mutex_unlock(&output_lock);
+
+	return r;
+}
+EXPORT_SYMBOL(omapdss_output_set_device);
+
+int omapdss_output_unset_device(struct omap_dss_output *out)
+{
+	int r;
+
+	mutex_lock(&output_lock);
+
+	if (!out->device) {
+		DSSERR("output doesn't have a device connected to it\n");
+		r = -EINVAL;
+		goto err;
+	}
+
+	if (out->device->state != OMAP_DSS_DISPLAY_DISABLED) {
+		DSSERR("device %s is not disabled, cannot unset device\n",
+				out->device->name);
+		r = -EINVAL;
+		goto err;
+	}
+
+	out->device->output = NULL;
+	out->device = NULL;
+
+	mutex_unlock(&output_lock);
+
+	return 0;
+err:
+	mutex_unlock(&output_lock);
+
+	return r;
+}
+EXPORT_SYMBOL(omapdss_output_unset_device);
+
+void dss_register_output(struct omap_dss_output *out)
+{
+	list_add_tail(&out->list, &output_list);
+}
+
+void dss_unregister_output(struct omap_dss_output *out)
+{
+	list_del(&out->list);
+}
+
+struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id)
+{
+	struct omap_dss_output *out;
+
+	list_for_each_entry(out, &output_list, list) {
+		if (out->id == id)
+			return out;
+	}
+
+	return NULL;
+}
+
+struct omap_dss_output *omapdss_get_output_from_dssdev(struct omap_dss_device *dssdev)
+{
+	struct omap_dss_output *out = NULL;
+	enum omap_dss_output_id id;
+
+	switch (dssdev->type) {
+	case OMAP_DISPLAY_TYPE_DPI:
+		out = omap_dss_get_output(OMAP_DSS_OUTPUT_DPI);
+		break;
+	case OMAP_DISPLAY_TYPE_DBI:
+		out = omap_dss_get_output(OMAP_DSS_OUTPUT_DBI);
+		break;
+	case OMAP_DISPLAY_TYPE_SDI:
+		out = omap_dss_get_output(OMAP_DSS_OUTPUT_SDI);
+		break;
+	case OMAP_DISPLAY_TYPE_VENC:
+		out = omap_dss_get_output(OMAP_DSS_OUTPUT_VENC);
+		break;
+	case OMAP_DISPLAY_TYPE_HDMI:
+		out = omap_dss_get_output(OMAP_DSS_OUTPUT_HDMI);
+		break;
+	case OMAP_DISPLAY_TYPE_DSI:
+		id = dssdev->phy.dsi.module == 0 ? OMAP_DSS_OUTPUT_DSI1 :
+					OMAP_DSS_OUTPUT_DSI2;
+		out = omap_dss_get_output(id);
+		break;
+	default:
+		break;
+	}
+
+	return out;
+}
diff --git a/drivers/video/omap2/dss/overlay-sysfs.c b/drivers/video/omap2/dss/overlay-sysfs.c
new file mode 100644
index 0000000..4cc5ddebf
--- /dev/null
+++ b/drivers/video/omap2/dss/overlay-sysfs.c
@@ -0,0 +1,456 @@
+/*
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * Some code and ideas taken from drivers/video/omap/ driver
+ * by Imre Deak.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define DSS_SUBSYS_NAME "OVERLAY"
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/sysfs.h>
+#include <linux/kobject.h>
+#include <linux/platform_device.h>
+
+#include <video/omapdss.h>
+
+#include "dss.h"
+#include "dss_features.h"
+
+static ssize_t overlay_name_show(struct omap_overlay *ovl, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%s\n", ovl->name);
+}
+
+static ssize_t overlay_manager_show(struct omap_overlay *ovl, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%s\n",
+			ovl->manager ? ovl->manager->name : "<none>");
+}
+
+static ssize_t overlay_manager_store(struct omap_overlay *ovl, const char *buf,
+		size_t size)
+{
+	int i, r;
+	struct omap_overlay_manager *mgr = NULL;
+	struct omap_overlay_manager *old_mgr;
+	int len = size;
+
+	if (buf[size-1] == '\n')
+		--len;
+
+	if (len > 0) {
+		for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
+			mgr = omap_dss_get_overlay_manager(i);
+
+			if (sysfs_streq(buf, mgr->name))
+				break;
+
+			mgr = NULL;
+		}
+	}
+
+	if (len > 0 && mgr == NULL)
+		return -EINVAL;
+
+	if (mgr)
+		DSSDBG("manager %s found\n", mgr->name);
+
+	if (mgr == ovl->manager)
+		return size;
+
+	old_mgr = ovl->manager;
+
+	r = dispc_runtime_get();
+	if (r)
+		return r;
+
+	/* detach old manager */
+	if (old_mgr) {
+		r = ovl->unset_manager(ovl);
+		if (r) {
+			DSSERR("detach failed\n");
+			goto err;
+		}
+
+		r = old_mgr->apply(old_mgr);
+		if (r)
+			goto err;
+	}
+
+	if (mgr) {
+		r = ovl->set_manager(ovl, mgr);
+		if (r) {
+			DSSERR("Failed to attach overlay\n");
+			goto err;
+		}
+
+		r = mgr->apply(mgr);
+		if (r)
+			goto err;
+	}
+
+	dispc_runtime_put();
+
+	return size;
+
+err:
+	dispc_runtime_put();
+	return r;
+}
+
+static ssize_t overlay_input_size_show(struct omap_overlay *ovl, char *buf)
+{
+	struct omap_overlay_info info;
+
+	ovl->get_overlay_info(ovl, &info);
+
+	return snprintf(buf, PAGE_SIZE, "%d,%d\n",
+			info.width, info.height);
+}
+
+static ssize_t overlay_screen_width_show(struct omap_overlay *ovl, char *buf)
+{
+	struct omap_overlay_info info;
+
+	ovl->get_overlay_info(ovl, &info);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", info.screen_width);
+}
+
+static ssize_t overlay_position_show(struct omap_overlay *ovl, char *buf)
+{
+	struct omap_overlay_info info;
+
+	ovl->get_overlay_info(ovl, &info);
+
+	return snprintf(buf, PAGE_SIZE, "%d,%d\n",
+			info.pos_x, info.pos_y);
+}
+
+static ssize_t overlay_position_store(struct omap_overlay *ovl,
+		const char *buf, size_t size)
+{
+	int r;
+	char *last;
+	struct omap_overlay_info info;
+
+	ovl->get_overlay_info(ovl, &info);
+
+	info.pos_x = simple_strtoul(buf, &last, 10);
+	++last;
+	if (last - buf >= size)
+		return -EINVAL;
+
+	info.pos_y = simple_strtoul(last, &last, 10);
+
+	r = ovl->set_overlay_info(ovl, &info);
+	if (r)
+		return r;
+
+	if (ovl->manager) {
+		r = ovl->manager->apply(ovl->manager);
+		if (r)
+			return r;
+	}
+
+	return size;
+}
+
+static ssize_t overlay_output_size_show(struct omap_overlay *ovl, char *buf)
+{
+	struct omap_overlay_info info;
+
+	ovl->get_overlay_info(ovl, &info);
+
+	return snprintf(buf, PAGE_SIZE, "%d,%d\n",
+			info.out_width, info.out_height);
+}
+
+static ssize_t overlay_output_size_store(struct omap_overlay *ovl,
+		const char *buf, size_t size)
+{
+	int r;
+	char *last;
+	struct omap_overlay_info info;
+
+	ovl->get_overlay_info(ovl, &info);
+
+	info.out_width = simple_strtoul(buf, &last, 10);
+	++last;
+	if (last - buf >= size)
+		return -EINVAL;
+
+	info.out_height = simple_strtoul(last, &last, 10);
+
+	r = ovl->set_overlay_info(ovl, &info);
+	if (r)
+		return r;
+
+	if (ovl->manager) {
+		r = ovl->manager->apply(ovl->manager);
+		if (r)
+			return r;
+	}
+
+	return size;
+}
+
+static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%d\n", ovl->is_enabled(ovl));
+}
+
+static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
+		size_t size)
+{
+	int r;
+	bool enable;
+
+	r = strtobool(buf, &enable);
+	if (r)
+		return r;
+
+	if (enable)
+		r = ovl->enable(ovl);
+	else
+		r = ovl->disable(ovl);
+
+	if (r)
+		return r;
+
+	return size;
+}
+
+static ssize_t overlay_global_alpha_show(struct omap_overlay *ovl, char *buf)
+{
+	struct omap_overlay_info info;
+
+	ovl->get_overlay_info(ovl, &info);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n",
+			info.global_alpha);
+}
+
+static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
+		const char *buf, size_t size)
+{
+	int r;
+	u8 alpha;
+	struct omap_overlay_info info;
+
+	if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
+		return -ENODEV;
+
+	r = kstrtou8(buf, 0, &alpha);
+	if (r)
+		return r;
+
+	ovl->get_overlay_info(ovl, &info);
+
+	info.global_alpha = alpha;
+
+	r = ovl->set_overlay_info(ovl, &info);
+	if (r)
+		return r;
+
+	if (ovl->manager) {
+		r = ovl->manager->apply(ovl->manager);
+		if (r)
+			return r;
+	}
+
+	return size;
+}
+
+static ssize_t overlay_pre_mult_alpha_show(struct omap_overlay *ovl,
+		char *buf)
+{
+	struct omap_overlay_info info;
+
+	ovl->get_overlay_info(ovl, &info);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n",
+			info.pre_mult_alpha);
+}
+
+static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
+		const char *buf, size_t size)
+{
+	int r;
+	u8 alpha;
+	struct omap_overlay_info info;
+
+	if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0)
+		return -ENODEV;
+
+	r = kstrtou8(buf, 0, &alpha);
+	if (r)
+		return r;
+
+	ovl->get_overlay_info(ovl, &info);
+
+	info.pre_mult_alpha = alpha;
+
+	r = ovl->set_overlay_info(ovl, &info);
+	if (r)
+		return r;
+
+	if (ovl->manager) {
+		r = ovl->manager->apply(ovl->manager);
+		if (r)
+			return r;
+	}
+
+	return size;
+}
+
+static ssize_t overlay_zorder_show(struct omap_overlay *ovl, char *buf)
+{
+	struct omap_overlay_info info;
+
+	ovl->get_overlay_info(ovl, &info);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", info.zorder);
+}
+
+static ssize_t overlay_zorder_store(struct omap_overlay *ovl,
+		const char *buf, size_t size)
+{
+	int r;
+	u8 zorder;
+	struct omap_overlay_info info;
+
+	if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
+		return -ENODEV;
+
+	r = kstrtou8(buf, 0, &zorder);
+	if (r)
+		return r;
+
+	ovl->get_overlay_info(ovl, &info);
+
+	info.zorder = zorder;
+
+	r = ovl->set_overlay_info(ovl, &info);
+	if (r)
+		return r;
+
+	if (ovl->manager) {
+		r = ovl->manager->apply(ovl->manager);
+		if (r)
+			return r;
+	}
+
+	return size;
+}
+
+struct overlay_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct omap_overlay *, char *);
+	ssize_t	(*store)(struct omap_overlay *, const char *, size_t);
+};
+
+#define OVERLAY_ATTR(_name, _mode, _show, _store) \
+	struct overlay_attribute overlay_attr_##_name = \
+	__ATTR(_name, _mode, _show, _store)
+
+static OVERLAY_ATTR(name, S_IRUGO, overlay_name_show, NULL);
+static OVERLAY_ATTR(manager, S_IRUGO|S_IWUSR,
+		overlay_manager_show, overlay_manager_store);
+static OVERLAY_ATTR(input_size, S_IRUGO, overlay_input_size_show, NULL);
+static OVERLAY_ATTR(screen_width, S_IRUGO, overlay_screen_width_show, NULL);
+static OVERLAY_ATTR(position, S_IRUGO|S_IWUSR,
+		overlay_position_show, overlay_position_store);
+static OVERLAY_ATTR(output_size, S_IRUGO|S_IWUSR,
+		overlay_output_size_show, overlay_output_size_store);
+static OVERLAY_ATTR(enabled, S_IRUGO|S_IWUSR,
+		overlay_enabled_show, overlay_enabled_store);
+static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR,
+		overlay_global_alpha_show, overlay_global_alpha_store);
+static OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR,
+		overlay_pre_mult_alpha_show,
+		overlay_pre_mult_alpha_store);
+static OVERLAY_ATTR(zorder, S_IRUGO|S_IWUSR,
+		overlay_zorder_show, overlay_zorder_store);
+
+static struct attribute *overlay_sysfs_attrs[] = {
+	&overlay_attr_name.attr,
+	&overlay_attr_manager.attr,
+	&overlay_attr_input_size.attr,
+	&overlay_attr_screen_width.attr,
+	&overlay_attr_position.attr,
+	&overlay_attr_output_size.attr,
+	&overlay_attr_enabled.attr,
+	&overlay_attr_global_alpha.attr,
+	&overlay_attr_pre_mult_alpha.attr,
+	&overlay_attr_zorder.attr,
+	NULL
+};
+
+static ssize_t overlay_attr_show(struct kobject *kobj, struct attribute *attr,
+		char *buf)
+{
+	struct omap_overlay *overlay;
+	struct overlay_attribute *overlay_attr;
+
+	overlay = container_of(kobj, struct omap_overlay, kobj);
+	overlay_attr = container_of(attr, struct overlay_attribute, attr);
+
+	if (!overlay_attr->show)
+		return -ENOENT;
+
+	return overlay_attr->show(overlay, buf);
+}
+
+static ssize_t overlay_attr_store(struct kobject *kobj, struct attribute *attr,
+		const char *buf, size_t size)
+{
+	struct omap_overlay *overlay;
+	struct overlay_attribute *overlay_attr;
+
+	overlay = container_of(kobj, struct omap_overlay, kobj);
+	overlay_attr = container_of(attr, struct overlay_attribute, attr);
+
+	if (!overlay_attr->store)
+		return -ENOENT;
+
+	return overlay_attr->store(overlay, buf, size);
+}
+
+static const struct sysfs_ops overlay_sysfs_ops = {
+	.show = overlay_attr_show,
+	.store = overlay_attr_store,
+};
+
+static struct kobj_type overlay_ktype = {
+	.sysfs_ops = &overlay_sysfs_ops,
+	.default_attrs = overlay_sysfs_attrs,
+};
+
+int dss_overlay_kobj_init(struct omap_overlay *ovl,
+		struct platform_device *pdev)
+{
+	return kobject_init_and_add(&ovl->kobj, &overlay_ktype,
+			&pdev->dev.kobj, "overlay%d", ovl->id);
+}
+
+void dss_overlay_kobj_uninit(struct omap_overlay *ovl)
+{
+	kobject_del(&ovl->kobj);
+	kobject_put(&ovl->kobj);
+}
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 952c6fa..45f4994 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -26,13 +26,11 @@
 #include <linux/module.h>
 #include <linux/err.h>
 #include <linux/sysfs.h>
-#include <linux/kobject.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
 
 #include <video/omapdss.h>
-#include <plat/cpu.h>
 
 #include "dss.h"
 #include "dss_features.h"
@@ -40,417 +38,13 @@
 static int num_overlays;
 static struct omap_overlay *overlays;
 
-static ssize_t overlay_name_show(struct omap_overlay *ovl, char *buf)
+static inline struct omap_dss_device *dss_ovl_get_device(struct omap_overlay *ovl)
 {
-	return snprintf(buf, PAGE_SIZE, "%s\n", ovl->name);
+	return ovl->manager ?
+		(ovl->manager->output ? ovl->manager->output->device : NULL) :
+		NULL;
 }
 
-static ssize_t overlay_manager_show(struct omap_overlay *ovl, char *buf)
-{
-	return snprintf(buf, PAGE_SIZE, "%s\n",
-			ovl->manager ? ovl->manager->name : "<none>");
-}
-
-static ssize_t overlay_manager_store(struct omap_overlay *ovl, const char *buf,
-		size_t size)
-{
-	int i, r;
-	struct omap_overlay_manager *mgr = NULL;
-	struct omap_overlay_manager *old_mgr;
-	int len = size;
-
-	if (buf[size-1] == '\n')
-		--len;
-
-	if (len > 0) {
-		for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
-			mgr = omap_dss_get_overlay_manager(i);
-
-			if (sysfs_streq(buf, mgr->name))
-				break;
-
-			mgr = NULL;
-		}
-	}
-
-	if (len > 0 && mgr == NULL)
-		return -EINVAL;
-
-	if (mgr)
-		DSSDBG("manager %s found\n", mgr->name);
-
-	if (mgr == ovl->manager)
-		return size;
-
-	old_mgr = ovl->manager;
-
-	r = dispc_runtime_get();
-	if (r)
-		return r;
-
-	/* detach old manager */
-	if (old_mgr) {
-		r = ovl->unset_manager(ovl);
-		if (r) {
-			DSSERR("detach failed\n");
-			goto err;
-		}
-
-		r = old_mgr->apply(old_mgr);
-		if (r)
-			goto err;
-	}
-
-	if (mgr) {
-		r = ovl->set_manager(ovl, mgr);
-		if (r) {
-			DSSERR("Failed to attach overlay\n");
-			goto err;
-		}
-
-		r = mgr->apply(mgr);
-		if (r)
-			goto err;
-	}
-
-	dispc_runtime_put();
-
-	return size;
-
-err:
-	dispc_runtime_put();
-	return r;
-}
-
-static ssize_t overlay_input_size_show(struct omap_overlay *ovl, char *buf)
-{
-	struct omap_overlay_info info;
-
-	ovl->get_overlay_info(ovl, &info);
-
-	return snprintf(buf, PAGE_SIZE, "%d,%d\n",
-			info.width, info.height);
-}
-
-static ssize_t overlay_screen_width_show(struct omap_overlay *ovl, char *buf)
-{
-	struct omap_overlay_info info;
-
-	ovl->get_overlay_info(ovl, &info);
-
-	return snprintf(buf, PAGE_SIZE, "%d\n", info.screen_width);
-}
-
-static ssize_t overlay_position_show(struct omap_overlay *ovl, char *buf)
-{
-	struct omap_overlay_info info;
-
-	ovl->get_overlay_info(ovl, &info);
-
-	return snprintf(buf, PAGE_SIZE, "%d,%d\n",
-			info.pos_x, info.pos_y);
-}
-
-static ssize_t overlay_position_store(struct omap_overlay *ovl,
-		const char *buf, size_t size)
-{
-	int r;
-	char *last;
-	struct omap_overlay_info info;
-
-	ovl->get_overlay_info(ovl, &info);
-
-	info.pos_x = simple_strtoul(buf, &last, 10);
-	++last;
-	if (last - buf >= size)
-		return -EINVAL;
-
-	info.pos_y = simple_strtoul(last, &last, 10);
-
-	r = ovl->set_overlay_info(ovl, &info);
-	if (r)
-		return r;
-
-	if (ovl->manager) {
-		r = ovl->manager->apply(ovl->manager);
-		if (r)
-			return r;
-	}
-
-	return size;
-}
-
-static ssize_t overlay_output_size_show(struct omap_overlay *ovl, char *buf)
-{
-	struct omap_overlay_info info;
-
-	ovl->get_overlay_info(ovl, &info);
-
-	return snprintf(buf, PAGE_SIZE, "%d,%d\n",
-			info.out_width, info.out_height);
-}
-
-static ssize_t overlay_output_size_store(struct omap_overlay *ovl,
-		const char *buf, size_t size)
-{
-	int r;
-	char *last;
-	struct omap_overlay_info info;
-
-	ovl->get_overlay_info(ovl, &info);
-
-	info.out_width = simple_strtoul(buf, &last, 10);
-	++last;
-	if (last - buf >= size)
-		return -EINVAL;
-
-	info.out_height = simple_strtoul(last, &last, 10);
-
-	r = ovl->set_overlay_info(ovl, &info);
-	if (r)
-		return r;
-
-	if (ovl->manager) {
-		r = ovl->manager->apply(ovl->manager);
-		if (r)
-			return r;
-	}
-
-	return size;
-}
-
-static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf)
-{
-	return snprintf(buf, PAGE_SIZE, "%d\n", ovl->is_enabled(ovl));
-}
-
-static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
-		size_t size)
-{
-	int r;
-	bool enable;
-
-	r = strtobool(buf, &enable);
-	if (r)
-		return r;
-
-	if (enable)
-		r = ovl->enable(ovl);
-	else
-		r = ovl->disable(ovl);
-
-	if (r)
-		return r;
-
-	return size;
-}
-
-static ssize_t overlay_global_alpha_show(struct omap_overlay *ovl, char *buf)
-{
-	struct omap_overlay_info info;
-
-	ovl->get_overlay_info(ovl, &info);
-
-	return snprintf(buf, PAGE_SIZE, "%d\n",
-			info.global_alpha);
-}
-
-static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
-		const char *buf, size_t size)
-{
-	int r;
-	u8 alpha;
-	struct omap_overlay_info info;
-
-	if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0)
-		return -ENODEV;
-
-	r = kstrtou8(buf, 0, &alpha);
-	if (r)
-		return r;
-
-	ovl->get_overlay_info(ovl, &info);
-
-	info.global_alpha = alpha;
-
-	r = ovl->set_overlay_info(ovl, &info);
-	if (r)
-		return r;
-
-	if (ovl->manager) {
-		r = ovl->manager->apply(ovl->manager);
-		if (r)
-			return r;
-	}
-
-	return size;
-}
-
-static ssize_t overlay_pre_mult_alpha_show(struct omap_overlay *ovl,
-		char *buf)
-{
-	struct omap_overlay_info info;
-
-	ovl->get_overlay_info(ovl, &info);
-
-	return snprintf(buf, PAGE_SIZE, "%d\n",
-			info.pre_mult_alpha);
-}
-
-static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
-		const char *buf, size_t size)
-{
-	int r;
-	u8 alpha;
-	struct omap_overlay_info info;
-
-	if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) == 0)
-		return -ENODEV;
-
-	r = kstrtou8(buf, 0, &alpha);
-	if (r)
-		return r;
-
-	ovl->get_overlay_info(ovl, &info);
-
-	info.pre_mult_alpha = alpha;
-
-	r = ovl->set_overlay_info(ovl, &info);
-	if (r)
-		return r;
-
-	if (ovl->manager) {
-		r = ovl->manager->apply(ovl->manager);
-		if (r)
-			return r;
-	}
-
-	return size;
-}
-
-static ssize_t overlay_zorder_show(struct omap_overlay *ovl, char *buf)
-{
-	struct omap_overlay_info info;
-
-	ovl->get_overlay_info(ovl, &info);
-
-	return snprintf(buf, PAGE_SIZE, "%d\n", info.zorder);
-}
-
-static ssize_t overlay_zorder_store(struct omap_overlay *ovl,
-		const char *buf, size_t size)
-{
-	int r;
-	u8 zorder;
-	struct omap_overlay_info info;
-
-	if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) == 0)
-		return -ENODEV;
-
-	r = kstrtou8(buf, 0, &zorder);
-	if (r)
-		return r;
-
-	ovl->get_overlay_info(ovl, &info);
-
-	info.zorder = zorder;
-
-	r = ovl->set_overlay_info(ovl, &info);
-	if (r)
-		return r;
-
-	if (ovl->manager) {
-		r = ovl->manager->apply(ovl->manager);
-		if (r)
-			return r;
-	}
-
-	return size;
-}
-
-struct overlay_attribute {
-	struct attribute attr;
-	ssize_t (*show)(struct omap_overlay *, char *);
-	ssize_t	(*store)(struct omap_overlay *, const char *, size_t);
-};
-
-#define OVERLAY_ATTR(_name, _mode, _show, _store) \
-	struct overlay_attribute overlay_attr_##_name = \
-	__ATTR(_name, _mode, _show, _store)
-
-static OVERLAY_ATTR(name, S_IRUGO, overlay_name_show, NULL);
-static OVERLAY_ATTR(manager, S_IRUGO|S_IWUSR,
-		overlay_manager_show, overlay_manager_store);
-static OVERLAY_ATTR(input_size, S_IRUGO, overlay_input_size_show, NULL);
-static OVERLAY_ATTR(screen_width, S_IRUGO, overlay_screen_width_show, NULL);
-static OVERLAY_ATTR(position, S_IRUGO|S_IWUSR,
-		overlay_position_show, overlay_position_store);
-static OVERLAY_ATTR(output_size, S_IRUGO|S_IWUSR,
-		overlay_output_size_show, overlay_output_size_store);
-static OVERLAY_ATTR(enabled, S_IRUGO|S_IWUSR,
-		overlay_enabled_show, overlay_enabled_store);
-static OVERLAY_ATTR(global_alpha, S_IRUGO|S_IWUSR,
-		overlay_global_alpha_show, overlay_global_alpha_store);
-static OVERLAY_ATTR(pre_mult_alpha, S_IRUGO|S_IWUSR,
-		overlay_pre_mult_alpha_show,
-		overlay_pre_mult_alpha_store);
-static OVERLAY_ATTR(zorder, S_IRUGO|S_IWUSR,
-		overlay_zorder_show, overlay_zorder_store);
-
-static struct attribute *overlay_sysfs_attrs[] = {
-	&overlay_attr_name.attr,
-	&overlay_attr_manager.attr,
-	&overlay_attr_input_size.attr,
-	&overlay_attr_screen_width.attr,
-	&overlay_attr_position.attr,
-	&overlay_attr_output_size.attr,
-	&overlay_attr_enabled.attr,
-	&overlay_attr_global_alpha.attr,
-	&overlay_attr_pre_mult_alpha.attr,
-	&overlay_attr_zorder.attr,
-	NULL
-};
-
-static ssize_t overlay_attr_show(struct kobject *kobj, struct attribute *attr,
-		char *buf)
-{
-	struct omap_overlay *overlay;
-	struct overlay_attribute *overlay_attr;
-
-	overlay = container_of(kobj, struct omap_overlay, kobj);
-	overlay_attr = container_of(attr, struct overlay_attribute, attr);
-
-	if (!overlay_attr->show)
-		return -ENOENT;
-
-	return overlay_attr->show(overlay, buf);
-}
-
-static ssize_t overlay_attr_store(struct kobject *kobj, struct attribute *attr,
-		const char *buf, size_t size)
-{
-	struct omap_overlay *overlay;
-	struct overlay_attribute *overlay_attr;
-
-	overlay = container_of(kobj, struct omap_overlay, kobj);
-	overlay_attr = container_of(attr, struct overlay_attribute, attr);
-
-	if (!overlay_attr->store)
-		return -ENOENT;
-
-	return overlay_attr->store(overlay, buf, size);
-}
-
-static const struct sysfs_ops overlay_sysfs_ops = {
-	.show = overlay_attr_show,
-	.store = overlay_attr_store,
-};
-
-static struct kobj_type overlay_ktype = {
-	.sysfs_ops = &overlay_sysfs_ops,
-	.default_attrs = overlay_sysfs_attrs,
-};
-
 int omap_dss_get_num_overlays(void)
 {
 	return num_overlays;
@@ -507,97 +101,25 @@
 		ovl->set_overlay_info = &dss_ovl_set_info;
 		ovl->get_overlay_info = &dss_ovl_get_info;
 		ovl->wait_for_go = &dss_mgr_wait_for_go_ovl;
+		ovl->get_device = &dss_ovl_get_device;
 
 		ovl->caps = dss_feat_get_overlay_caps(ovl->id);
 		ovl->supported_modes =
 			dss_feat_get_supported_color_modes(ovl->id);
 
-		r = kobject_init_and_add(&ovl->kobj, &overlay_ktype,
-				&pdev->dev.kobj, "overlay%d", i);
-
+		r = dss_overlay_kobj_init(ovl, pdev);
 		if (r)
 			DSSERR("failed to create sysfs file\n");
 	}
 }
 
-/* connect overlays to the new device, if not already connected. if force
- * selected, connect always. */
-void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
-{
-	int i;
-	struct omap_overlay_manager *lcd_mgr;
-	struct omap_overlay_manager *tv_mgr;
-	struct omap_overlay_manager *lcd2_mgr = NULL;
-	struct omap_overlay_manager *lcd3_mgr = NULL;
-	struct omap_overlay_manager *mgr = NULL;
-
-	lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD);
-	tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_DIGIT);
-	if (dss_has_feature(FEAT_MGR_LCD3))
-		lcd3_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD3);
-	if (dss_has_feature(FEAT_MGR_LCD2))
-		lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_CHANNEL_LCD2);
-
-	if (dssdev->channel == OMAP_DSS_CHANNEL_LCD3) {
-		if (!lcd3_mgr->device || force) {
-			if (lcd3_mgr->device)
-				lcd3_mgr->unset_device(lcd3_mgr);
-			lcd3_mgr->set_device(lcd3_mgr, dssdev);
-			mgr = lcd3_mgr;
-		}
-	} else if (dssdev->channel == OMAP_DSS_CHANNEL_LCD2) {
-		if (!lcd2_mgr->device || force) {
-			if (lcd2_mgr->device)
-				lcd2_mgr->unset_device(lcd2_mgr);
-			lcd2_mgr->set_device(lcd2_mgr, dssdev);
-			mgr = lcd2_mgr;
-		}
-	} else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC
-			&& dssdev->type != OMAP_DISPLAY_TYPE_HDMI) {
-		if (!lcd_mgr->device || force) {
-			if (lcd_mgr->device)
-				lcd_mgr->unset_device(lcd_mgr);
-			lcd_mgr->set_device(lcd_mgr, dssdev);
-			mgr = lcd_mgr;
-		}
-	}
-
-	if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
-			|| dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
-		if (!tv_mgr->device || force) {
-			if (tv_mgr->device)
-				tv_mgr->unset_device(tv_mgr);
-			tv_mgr->set_device(tv_mgr, dssdev);
-			mgr = tv_mgr;
-		}
-	}
-
-	if (mgr) {
-		dispc_runtime_get();
-
-		for (i = 0; i < dss_feat_get_num_ovls(); i++) {
-			struct omap_overlay *ovl;
-			ovl = omap_dss_get_overlay(i);
-			if (!ovl->manager || force) {
-				if (ovl->manager)
-					ovl->unset_manager(ovl);
-				ovl->set_manager(ovl, mgr);
-			}
-		}
-
-		dispc_runtime_put();
-	}
-}
-
 void dss_uninit_overlays(struct platform_device *pdev)
 {
 	int i;
 
 	for (i = 0; i < num_overlays; ++i) {
 		struct omap_overlay *ovl = &overlays[i];
-
-		kobject_del(&ovl->kobj);
-		kobject_put(&ovl->kobj);
+		dss_overlay_kobj_uninit(ovl);
 	}
 
 	kfree(overlays);
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 7c08742..7282e5a 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -111,6 +111,13 @@
 	struct omap_dss_device *dssdev[2];
 
 	struct semaphore bus_lock;
+
+	struct omap_video_timings timings;
+	int pixel_size;
+	int data_lines;
+	struct rfbi_timings intf_timings;
+
+	struct omap_dss_output output;
 } rfbi;
 
 static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val)
@@ -300,30 +307,23 @@
 }
 EXPORT_SYMBOL(omap_rfbi_write_pixels);
 
-static int rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
-		u16 height, void (*callback)(void *data), void *data)
+static int rfbi_transfer_area(struct omap_dss_device *dssdev,
+		void (*callback)(void *data), void *data)
 {
 	u32 l;
 	int r;
-	struct omap_video_timings timings = {
-		.hsw		= 1,
-		.hfp		= 1,
-		.hbp		= 1,
-		.vsw		= 1,
-		.vfp		= 0,
-		.vbp		= 0,
-		.x_res		= width,
-		.y_res		= height,
-	};
+	struct omap_overlay_manager *mgr = dssdev->output->manager;
+	u16 width = rfbi.timings.x_res;
+	u16 height = rfbi.timings.y_res;
 
 	/*BUG_ON(callback == 0);*/
 	BUG_ON(rfbi.framedone_callback != NULL);
 
 	DSSDBG("rfbi_transfer_area %dx%d\n", width, height);
 
-	dss_mgr_set_timings(dssdev->manager, &timings);
+	dss_mgr_set_timings(mgr, &rfbi.timings);
 
-	r = dss_mgr_enable(dssdev->manager);
+	r = dss_mgr_enable(mgr);
 	if (r)
 		return r;
 
@@ -770,63 +770,46 @@
 	return 0;
 }
 
-int omap_rfbi_configure(struct omap_dss_device *dssdev, int pixel_size,
-		int data_lines)
+int omap_rfbi_configure(struct omap_dss_device *dssdev)
 {
-	return rfbi_configure(dssdev->phy.rfbi.channel, pixel_size, data_lines);
+	return rfbi_configure(dssdev->phy.rfbi.channel, rfbi.pixel_size,
+			rfbi.data_lines);
 }
 EXPORT_SYMBOL(omap_rfbi_configure);
 
-int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
-		u16 *x, u16 *y, u16 *w, u16 *h)
+int omap_rfbi_update(struct omap_dss_device *dssdev, void (*callback)(void *),
+		void *data)
 {
-	u16 dw, dh;
-	struct omap_video_timings timings = {
-		.hsw		= 1,
-		.hfp		= 1,
-		.hbp		= 1,
-		.vsw		= 1,
-		.vfp		= 0,
-		.vbp		= 0,
-		.x_res		= *w,
-		.y_res		= *h,
-	};
-
-	dssdev->driver->get_resolution(dssdev, &dw, &dh);
-
-	if  (*x > dw || *y > dh)
-		return -EINVAL;
-
-	if (*x + *w > dw)
-		return -EINVAL;
-
-	if (*y + *h > dh)
-		return -EINVAL;
-
-	if (*w == 1)
-		return -EINVAL;
-
-	if (*w == 0 || *h == 0)
-		return -EINVAL;
-
-	dss_mgr_set_timings(dssdev->manager, &timings);
-
-	return 0;
-}
-EXPORT_SYMBOL(omap_rfbi_prepare_update);
-
-int omap_rfbi_update(struct omap_dss_device *dssdev,
-		u16 x, u16 y, u16 w, u16 h,
-		void (*callback)(void *), void *data)
-{
-	int r;
-
-	r = rfbi_transfer_area(dssdev, w, h, callback, data);
-
-	return r;
+	return rfbi_transfer_area(dssdev, callback, data);
 }
 EXPORT_SYMBOL(omap_rfbi_update);
 
+void omapdss_rfbi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h)
+{
+	rfbi.timings.x_res = w;
+	rfbi.timings.y_res = h;
+}
+EXPORT_SYMBOL(omapdss_rfbi_set_size);
+
+void omapdss_rfbi_set_pixel_size(struct omap_dss_device *dssdev, int pixel_size)
+{
+	rfbi.pixel_size = pixel_size;
+}
+EXPORT_SYMBOL(omapdss_rfbi_set_pixel_size);
+
+void omapdss_rfbi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
+{
+	rfbi.data_lines = data_lines;
+}
+EXPORT_SYMBOL(omapdss_rfbi_set_data_lines);
+
+void omapdss_rfbi_set_interface_timings(struct omap_dss_device *dssdev,
+		struct rfbi_timings *timings)
+{
+	rfbi.intf_timings = *timings;
+}
+EXPORT_SYMBOL(omapdss_rfbi_set_interface_timings);
+
 static void rfbi_dump_regs(struct seq_file *s)
 {
 #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r))
@@ -869,6 +852,7 @@
 
 static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
 {
+	struct omap_overlay_manager *mgr = dssdev->output->manager;
 	struct dss_lcd_mgr_config mgr_config;
 
 	mgr_config.io_pad_mode = DSS_IO_PAD_MODE_RFBI;
@@ -877,18 +861,40 @@
 	/* Do we need fifohandcheck for RFBI? */
 	mgr_config.fifohandcheck = false;
 
-	mgr_config.video_port_width = dssdev->ctrl.pixel_size;
+	mgr_config.video_port_width = rfbi.pixel_size;
 	mgr_config.lcden_sig_polarity = 0;
 
-	dss_mgr_set_lcd_config(dssdev->manager, &mgr_config);
+	dss_mgr_set_lcd_config(mgr, &mgr_config);
+
+	/*
+	 * Set rfbi.timings with default values, the x_res and y_res fields
+	 * are expected to be already configured by the panel driver via
+	 * omapdss_rfbi_set_size()
+	 */
+	rfbi.timings.hsw = 1;
+	rfbi.timings.hfp = 1;
+	rfbi.timings.hbp = 1;
+	rfbi.timings.vsw = 1;
+	rfbi.timings.vfp = 0;
+	rfbi.timings.vbp = 0;
+
+	rfbi.timings.interlace = false;
+	rfbi.timings.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
+	rfbi.timings.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH;
+	rfbi.timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
+	rfbi.timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
+	rfbi.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
+
+	dss_mgr_set_timings(mgr, &rfbi.timings);
 }
 
 int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
 {
+	struct omap_dss_output *out = dssdev->output;
 	int r;
 
-	if (dssdev->manager == NULL) {
-		DSSERR("failed to enable display: no manager\n");
+	if (out == NULL || out->manager == NULL) {
+		DSSERR("failed to enable display: no output/manager\n");
 		return -ENODEV;
 	}
 
@@ -911,13 +917,10 @@
 
 	rfbi_config_lcd_manager(dssdev);
 
-	rfbi_configure(dssdev->phy.rfbi.channel,
-			       dssdev->ctrl.pixel_size,
-			       dssdev->phy.rfbi.data_lines);
+	rfbi_configure(dssdev->phy.rfbi.channel, rfbi.pixel_size,
+			rfbi.data_lines);
 
-	rfbi_set_timings(dssdev->phy.rfbi.channel,
-			 &dssdev->ctrl.rfbi_timings);
-
+	rfbi_set_timings(dssdev->phy.rfbi.channel, &rfbi.intf_timings);
 
 	return 0;
 err1:
@@ -941,14 +944,17 @@
 static int __init rfbi_init_display(struct omap_dss_device *dssdev)
 {
 	rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev;
-	dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
 	return 0;
 }
 
-static void __init rfbi_probe_pdata(struct platform_device *pdev)
+static struct omap_dss_device * __init rfbi_find_dssdev(struct platform_device *pdev)
 {
 	struct omap_dss_board_info *pdata = pdev->dev.platform_data;
-	int i, r;
+	const char *def_disp_name = dss_get_default_display_name();
+	struct omap_dss_device *def_dssdev;
+	int i;
+
+	def_dssdev = NULL;
 
 	for (i = 0; i < pdata->num_devices; ++i) {
 		struct omap_dss_device *dssdev = pdata->devices[i];
@@ -956,17 +962,67 @@
 		if (dssdev->type != OMAP_DISPLAY_TYPE_DBI)
 			continue;
 
-		r = rfbi_init_display(dssdev);
-		if (r) {
-			DSSERR("device %s init failed: %d\n", dssdev->name, r);
-			continue;
-		}
+		if (def_dssdev == NULL)
+			def_dssdev = dssdev;
 
-		r = omap_dss_register_device(dssdev, &pdev->dev, i);
-		if (r)
-			DSSERR("device %s register failed: %d\n",
-				dssdev->name, r);
+		if (def_disp_name != NULL &&
+				strcmp(dssdev->name, def_disp_name) == 0) {
+			def_dssdev = dssdev;
+			break;
+		}
 	}
+
+	return def_dssdev;
+}
+
+static void __init rfbi_probe_pdata(struct platform_device *rfbidev)
+{
+	struct omap_dss_device *plat_dssdev;
+	struct omap_dss_device *dssdev;
+	int r;
+
+	plat_dssdev = rfbi_find_dssdev(rfbidev);
+
+	if (!plat_dssdev)
+		return;
+
+	dssdev = dss_alloc_and_init_device(&rfbidev->dev);
+	if (!dssdev)
+		return;
+
+	dss_copy_device_pdata(dssdev, plat_dssdev);
+
+	r = rfbi_init_display(dssdev);
+	if (r) {
+		DSSERR("device %s init failed: %d\n", dssdev->name, r);
+		dss_put_device(dssdev);
+		return;
+	}
+
+	r = dss_add_device(dssdev);
+	if (r) {
+		DSSERR("device %s register failed: %d\n", dssdev->name, r);
+		dss_put_device(dssdev);
+		return;
+	}
+}
+
+static void __init rfbi_init_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out = &rfbi.output;
+
+	out->pdev = pdev;
+	out->id = OMAP_DSS_OUTPUT_DBI;
+	out->type = OMAP_DISPLAY_TYPE_DBI;
+
+	dss_register_output(out);
+}
+
+static void __exit rfbi_uninit_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out = &rfbi.output;
+
+	dss_unregister_output(out);
 }
 
 /* RFBI HW IP initialisation */
@@ -1020,6 +1076,8 @@
 
 	dss_debugfs_create_file("rfbi", rfbi_dump_regs);
 
+	rfbi_init_output(pdev);
+
 	rfbi_probe_pdata(pdev);
 
 	return 0;
@@ -1031,8 +1089,12 @@
 
 static int __exit omap_rfbihw_remove(struct platform_device *pdev)
 {
-	omap_dss_unregister_child_devices(&pdev->dev);
+	dss_unregister_child_devices(&pdev->dev);
+
+	rfbi_uninit_output(pdev);
+
 	pm_runtime_disable(&pdev->dev);
+
 	return 0;
 }
 
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index f43bfe1..7760851 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -25,6 +25,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/export.h>
 #include <linux/platform_device.h>
+#include <linux/string.h>
 
 #include <video/omapdss.h>
 #include "dss.h"
@@ -34,10 +35,16 @@
 	struct regulator *vdds_sdi_reg;
 
 	struct dss_lcd_mgr_config mgr_config;
+	struct omap_video_timings timings;
+	int datapairs;
+
+	struct omap_dss_output output;
 } sdi;
 
 static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
 {
+	struct omap_overlay_manager *mgr = dssdev->output->manager;
+
 	sdi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
 
 	sdi.mgr_config.stallmode = false;
@@ -46,19 +53,20 @@
 	sdi.mgr_config.video_port_width = 24;
 	sdi.mgr_config.lcden_sig_polarity = 1;
 
-	dss_mgr_set_lcd_config(dssdev->manager, &sdi.mgr_config);
+	dss_mgr_set_lcd_config(mgr, &sdi.mgr_config);
 }
 
 int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
 {
-	struct omap_video_timings *t = &dssdev->panel.timings;
+	struct omap_dss_output *out = dssdev->output;
+	struct omap_video_timings *t = &sdi.timings;
 	struct dss_clock_info dss_cinfo;
 	struct dispc_clock_info dispc_cinfo;
 	unsigned long pck;
 	int r;
 
-	if (dssdev->manager == NULL) {
-		DSSERR("failed to enable display: no manager\n");
+	if (out == NULL || out->manager == NULL) {
+		DSSERR("failed to enable display: no output/manager\n");
 		return -ENODEV;
 	}
 
@@ -77,8 +85,8 @@
 		goto err_get_dispc;
 
 	/* 15.5.9.1.2 */
-	dssdev->panel.timings.data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
-	dssdev->panel.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
+	t->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
+	t->sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
 
 	r = dss_calc_clock_div(t->pixel_clock * 1000, &dss_cinfo, &dispc_cinfo);
 	if (r)
@@ -97,7 +105,7 @@
 	}
 
 
-	dss_mgr_set_timings(dssdev->manager, t);
+	dss_mgr_set_timings(out->manager, t);
 
 	r = dss_set_clock_div(&dss_cinfo);
 	if (r)
@@ -116,16 +124,15 @@
 	 * need to care about the shadow register mechanism for pck-free. The
 	 * exact reason for this is unknown.
 	 */
-	dispc_mgr_set_clock_div(dssdev->manager->id,
-			&sdi.mgr_config.clock_info);
+	dispc_mgr_set_clock_div(out->manager->id, &sdi.mgr_config.clock_info);
 
-	dss_sdi_init(dssdev->phy.sdi.datapairs);
+	dss_sdi_init(sdi.datapairs);
 	r = dss_sdi_enable();
 	if (r)
 		goto err_sdi_enable;
 	mdelay(2);
 
-	r = dss_mgr_enable(dssdev->manager);
+	r = dss_mgr_enable(out->manager);
 	if (r)
 		goto err_mgr_enable;
 
@@ -148,7 +155,9 @@
 
 void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
 {
-	dss_mgr_disable(dssdev->manager);
+	struct omap_overlay_manager *mgr = dssdev->output->manager;
+
+	dss_mgr_disable(mgr);
 
 	dss_sdi_disable();
 
@@ -160,6 +169,19 @@
 }
 EXPORT_SYMBOL(omapdss_sdi_display_disable);
 
+void omapdss_sdi_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	sdi.timings = *timings;
+}
+EXPORT_SYMBOL(omapdss_sdi_set_timings);
+
+void omapdss_sdi_set_datapairs(struct omap_dss_device *dssdev, int datapairs)
+{
+	sdi.datapairs = datapairs;
+}
+EXPORT_SYMBOL(omapdss_sdi_set_datapairs);
+
 static int __init sdi_init_display(struct omap_dss_device *dssdev)
 {
 	DSSDBG("SDI init\n");
@@ -180,10 +202,14 @@
 	return 0;
 }
 
-static void __init sdi_probe_pdata(struct platform_device *pdev)
+static struct omap_dss_device * __init sdi_find_dssdev(struct platform_device *pdev)
 {
 	struct omap_dss_board_info *pdata = pdev->dev.platform_data;
-	int i, r;
+	const char *def_disp_name = dss_get_default_display_name();
+	struct omap_dss_device *def_dssdev;
+	int i;
+
+	def_dssdev = NULL;
 
 	for (i = 0; i < pdata->num_devices; ++i) {
 		struct omap_dss_device *dssdev = pdata->devices[i];
@@ -191,21 +217,73 @@
 		if (dssdev->type != OMAP_DISPLAY_TYPE_SDI)
 			continue;
 
-		r = sdi_init_display(dssdev);
-		if (r) {
-			DSSERR("device %s init failed: %d\n", dssdev->name, r);
-			continue;
-		}
+		if (def_dssdev == NULL)
+			def_dssdev = dssdev;
 
-		r = omap_dss_register_device(dssdev, &pdev->dev, i);
-		if (r)
-			DSSERR("device %s register failed: %d\n",
-					dssdev->name, r);
+		if (def_disp_name != NULL &&
+				strcmp(dssdev->name, def_disp_name) == 0) {
+			def_dssdev = dssdev;
+			break;
+		}
 	}
+
+	return def_dssdev;
+}
+
+static void __init sdi_probe_pdata(struct platform_device *sdidev)
+{
+	struct omap_dss_device *plat_dssdev;
+	struct omap_dss_device *dssdev;
+	int r;
+
+	plat_dssdev = sdi_find_dssdev(sdidev);
+
+	if (!plat_dssdev)
+		return;
+
+	dssdev = dss_alloc_and_init_device(&sdidev->dev);
+	if (!dssdev)
+		return;
+
+	dss_copy_device_pdata(dssdev, plat_dssdev);
+
+	r = sdi_init_display(dssdev);
+	if (r) {
+		DSSERR("device %s init failed: %d\n", dssdev->name, r);
+		dss_put_device(dssdev);
+		return;
+	}
+
+	r = dss_add_device(dssdev);
+	if (r) {
+		DSSERR("device %s register failed: %d\n", dssdev->name, r);
+		dss_put_device(dssdev);
+		return;
+	}
+}
+
+static void __init sdi_init_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out = &sdi.output;
+
+	out->pdev = pdev;
+	out->id = OMAP_DSS_OUTPUT_SDI;
+	out->type = OMAP_DISPLAY_TYPE_SDI;
+
+	dss_register_output(out);
+}
+
+static void __exit sdi_uninit_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out = &sdi.output;
+
+	dss_unregister_output(out);
 }
 
 static int __init omap_sdi_probe(struct platform_device *pdev)
 {
+	sdi_init_output(pdev);
+
 	sdi_probe_pdata(pdev);
 
 	return 0;
@@ -213,7 +291,9 @@
 
 static int __exit omap_sdi_remove(struct platform_device *pdev)
 {
-	omap_dss_unregister_child_devices(&pdev->dev);
+	dss_unregister_child_devices(&pdev->dev);
+
+	sdi_uninit_output(pdev);
 
 	return 0;
 }
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 3a22087..56efa3b 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -36,7 +36,6 @@
 #include <linux/pm_runtime.h>
 
 #include <video/omapdss.h>
-#include <plat/cpu.h>
 
 #include "dss.h"
 #include "dss_features.h"
@@ -300,6 +299,12 @@
 	struct regulator *vdda_dac_reg;
 
 	struct clk	*tv_dac_clk;
+
+	struct omap_video_timings timings;
+	enum omap_dss_venc_type type;
+	bool invert_polarity;
+
+	struct omap_dss_output output;
 } venc;
 
 static inline void venc_write_reg(int idx, u32 val)
@@ -424,65 +429,67 @@
 
 static int venc_power_on(struct omap_dss_device *dssdev)
 {
+	struct omap_overlay_manager *mgr = dssdev->output->manager;
 	u32 l;
 	int r;
 
-	venc_reset();
-	venc_write_config(venc_timings_to_config(&dssdev->panel.timings));
+	r = venc_runtime_get();
+	if (r)
+		goto err0;
 
-	dss_set_venc_output(dssdev->phy.venc.type);
+	venc_reset();
+	venc_write_config(venc_timings_to_config(&venc.timings));
+
+	dss_set_venc_output(venc.type);
 	dss_set_dac_pwrdn_bgz(1);
 
 	l = 0;
 
-	if (dssdev->phy.venc.type == OMAP_DSS_VENC_TYPE_COMPOSITE)
+	if (venc.type == OMAP_DSS_VENC_TYPE_COMPOSITE)
 		l |= 1 << 1;
 	else /* S-Video */
 		l |= (1 << 0) | (1 << 2);
 
-	if (dssdev->phy.venc.invert_polarity == false)
+	if (venc.invert_polarity == false)
 		l |= 1 << 3;
 
 	venc_write_reg(VENC_OUTPUT_CONTROL, l);
 
-	dss_mgr_set_timings(dssdev->manager, &dssdev->panel.timings);
+	dss_mgr_set_timings(mgr, &venc.timings);
 
 	r = regulator_enable(venc.vdda_dac_reg);
 	if (r)
-		goto err;
+		goto err1;
 
-	if (dssdev->platform_enable)
-		dssdev->platform_enable(dssdev);
-
-	r = dss_mgr_enable(dssdev->manager);
+	r = dss_mgr_enable(mgr);
 	if (r)
-		goto err;
+		goto err2;
 
 	return 0;
 
-err:
+err2:
+	regulator_disable(venc.vdda_dac_reg);
+err1:
 	venc_write_reg(VENC_OUTPUT_CONTROL, 0);
 	dss_set_dac_pwrdn_bgz(0);
 
-	if (dssdev->platform_disable)
-		dssdev->platform_disable(dssdev);
-
-	regulator_disable(venc.vdda_dac_reg);
-
+	venc_runtime_put();
+err0:
 	return r;
 }
 
 static void venc_power_off(struct omap_dss_device *dssdev)
 {
+	struct omap_overlay_manager *mgr = dssdev->output->manager;
+
 	venc_write_reg(VENC_OUTPUT_CONTROL, 0);
 	dss_set_dac_pwrdn_bgz(0);
 
-	dss_mgr_disable(dssdev->manager);
-
-	if (dssdev->platform_disable)
-		dssdev->platform_disable(dssdev);
+	dss_mgr_disable(mgr);
 
 	regulator_disable(venc.vdda_dac_reg);
+
+	venc_runtime_put();
 }
 
 unsigned long venc_get_pixel_clock(void)
@@ -491,171 +498,83 @@
 	return 13500000;
 }
 
-static ssize_t display_output_type_show(struct device *dev,
-		struct device_attribute *attr, char *buf)
+int omapdss_venc_display_enable(struct omap_dss_device *dssdev)
 {
-	struct omap_dss_device *dssdev = to_dss_device(dev);
-	const char *ret;
+	struct omap_dss_output *out = dssdev->output;
+	int r;
 
-	switch (dssdev->phy.venc.type) {
-	case OMAP_DSS_VENC_TYPE_COMPOSITE:
-		ret = "composite";
-		break;
-	case OMAP_DSS_VENC_TYPE_SVIDEO:
-		ret = "svideo";
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return snprintf(buf, PAGE_SIZE, "%s\n", ret);
-}
-
-static ssize_t display_output_type_store(struct device *dev,
-		struct device_attribute *attr, const char *buf, size_t size)
-{
-	struct omap_dss_device *dssdev = to_dss_device(dev);
-	enum omap_dss_venc_type new_type;
-
-	if (sysfs_streq("composite", buf))
-		new_type = OMAP_DSS_VENC_TYPE_COMPOSITE;
-	else if (sysfs_streq("svideo", buf))
-		new_type = OMAP_DSS_VENC_TYPE_SVIDEO;
-	else
-		return -EINVAL;
+	DSSDBG("venc_display_enable\n");
 
 	mutex_lock(&venc.venc_lock);
 
-	if (dssdev->phy.venc.type != new_type) {
-		dssdev->phy.venc.type = new_type;
-		if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
-			venc_power_off(dssdev);
-			venc_power_on(dssdev);
-		}
+	if (out == NULL || out->manager == NULL) {
+		DSSERR("Failed to enable display: no output/manager\n");
+		r = -ENODEV;
+		goto err0;
 	}
 
-	mutex_unlock(&venc.venc_lock);
-
-	return size;
-}
-
-static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR,
-		display_output_type_show, display_output_type_store);
-
-/* driver */
-static int venc_panel_probe(struct omap_dss_device *dssdev)
-{
-	dssdev->panel.timings = omap_dss_pal_timings;
-
-	return device_create_file(&dssdev->dev, &dev_attr_output_type);
-}
-
-static void venc_panel_remove(struct omap_dss_device *dssdev)
-{
-	device_remove_file(&dssdev->dev, &dev_attr_output_type);
-}
-
-static int venc_panel_enable(struct omap_dss_device *dssdev)
-{
-	int r = 0;
-
-	DSSDBG("venc_enable_display\n");
-
-	mutex_lock(&venc.venc_lock);
-
 	r = omap_dss_start_device(dssdev);
 	if (r) {
 		DSSERR("failed to start device\n");
 		goto err0;
 	}
 
-	if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
-		r = -EINVAL;
-		goto err1;
-	}
+	if (dssdev->platform_enable)
+		dssdev->platform_enable(dssdev);
 
-	r = venc_runtime_get();
-	if (r)
-		goto err1;
 
 	r = venc_power_on(dssdev);
 	if (r)
-		goto err2;
+		goto err1;
 
 	venc.wss_data = 0;
 
-	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
-
 	mutex_unlock(&venc.venc_lock);
+
 	return 0;
-err2:
-	venc_runtime_put();
 err1:
+	if (dssdev->platform_disable)
+		dssdev->platform_disable(dssdev);
 	omap_dss_stop_device(dssdev);
 err0:
 	mutex_unlock(&venc.venc_lock);
-
 	return r;
 }
 
-static void venc_panel_disable(struct omap_dss_device *dssdev)
+void omapdss_venc_display_disable(struct omap_dss_device *dssdev)
 {
-	DSSDBG("venc_disable_display\n");
+	DSSDBG("venc_display_disable\n");
 
 	mutex_lock(&venc.venc_lock);
 
-	if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
-		goto end;
-
-	if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) {
-		/* suspended is the same as disabled with venc */
-		dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
-		goto end;
-	}
-
 	venc_power_off(dssdev);
 
-	venc_runtime_put();
-
-	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
-
 	omap_dss_stop_device(dssdev);
-end:
+
+	if (dssdev->platform_disable)
+		dssdev->platform_disable(dssdev);
+
 	mutex_unlock(&venc.venc_lock);
 }
 
-static int venc_panel_suspend(struct omap_dss_device *dssdev)
-{
-	venc_panel_disable(dssdev);
-	return 0;
-}
-
-static int venc_panel_resume(struct omap_dss_device *dssdev)
-{
-	return venc_panel_enable(dssdev);
-}
-
-static void venc_set_timings(struct omap_dss_device *dssdev,
-			struct omap_video_timings *timings)
+void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
 {
 	DSSDBG("venc_set_timings\n");
 
+	mutex_lock(&venc.venc_lock);
+
 	/* Reset WSS data when the TV standard changes. */
-	if (memcmp(&dssdev->panel.timings, timings, sizeof(*timings)))
+	if (memcmp(&venc.timings, timings, sizeof(*timings)))
 		venc.wss_data = 0;
 
-	dssdev->panel.timings = *timings;
-	if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
-		/* turn the venc off and on to get new timings to use */
-		venc_panel_disable(dssdev);
-		venc_panel_enable(dssdev);
-	} else {
-		dss_mgr_set_timings(dssdev->manager, timings);
-	}
+	venc.timings = *timings;
+
+	mutex_unlock(&venc.venc_lock);
 }
 
-static int venc_check_timings(struct omap_dss_device *dssdev,
-			struct omap_video_timings *timings)
+int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
 {
 	DSSDBG("venc_check_timings\n");
 
@@ -668,13 +587,13 @@
 	return -EINVAL;
 }
 
-static u32 venc_get_wss(struct omap_dss_device *dssdev)
+u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev)
 {
 	/* Invert due to VENC_L21_WC_CTL:INV=1 */
 	return (venc.wss_data >> 8) ^ 0xfffff;
 }
 
-static int venc_set_wss(struct omap_dss_device *dssdev,	u32 wss)
+int omapdss_venc_set_wss(struct omap_dss_device *dssdev, u32 wss)
 {
 	const struct venc_config *config;
 	int r;
@@ -683,7 +602,7 @@
 
 	mutex_lock(&venc.venc_lock);
 
-	config = venc_timings_to_config(&dssdev->panel.timings);
+	config = venc_timings_to_config(&venc.timings);
 
 	/* Invert due to VENC_L21_WC_CTL:INV=1 */
 	venc.wss_data = (wss ^ 0xfffff) << 8;
@@ -703,30 +622,25 @@
 	return r;
 }
 
-static struct omap_dss_driver venc_driver = {
-	.probe		= venc_panel_probe,
-	.remove		= venc_panel_remove,
+void omapdss_venc_set_type(struct omap_dss_device *dssdev,
+		enum omap_dss_venc_type type)
+{
+	mutex_lock(&venc.venc_lock);
 
-	.enable		= venc_panel_enable,
-	.disable	= venc_panel_disable,
-	.suspend	= venc_panel_suspend,
-	.resume		= venc_panel_resume,
+	venc.type = type;
 
-	.get_resolution	= omapdss_default_get_resolution,
-	.get_recommended_bpp = omapdss_default_get_recommended_bpp,
+	mutex_unlock(&venc.venc_lock);
+}
 
-	.set_timings	= venc_set_timings,
-	.check_timings	= venc_check_timings,
+void omapdss_venc_invert_vid_out_polarity(struct omap_dss_device *dssdev,
+		bool invert_polarity)
+{
+	mutex_lock(&venc.venc_lock);
 
-	.get_wss	= venc_get_wss,
-	.set_wss	= venc_set_wss,
+	venc.invert_polarity = invert_polarity;
 
-	.driver         = {
-		.name   = "venc",
-		.owner  = THIS_MODULE,
-	},
-};
-/* driver end */
+	mutex_unlock(&venc.venc_lock);
+}
 
 static int __init venc_init_display(struct omap_dss_device *dssdev)
 {
@@ -752,11 +666,6 @@
 {
 #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r))
 
-	if (cpu_is_omap44xx()) {
-		seq_printf(s, "VENC currently disabled on OMAP44xx\n");
-		return;
-	}
-
 	if (venc_runtime_get())
 		return;
 
@@ -832,10 +741,14 @@
 		clk_put(venc.tv_dac_clk);
 }
 
-static void __init venc_probe_pdata(struct platform_device *pdev)
+static struct omap_dss_device * __init venc_find_dssdev(struct platform_device *pdev)
 {
 	struct omap_dss_board_info *pdata = pdev->dev.platform_data;
-	int r, i;
+	const char *def_disp_name = dss_get_default_display_name();
+	struct omap_dss_device *def_dssdev;
+	int i;
+
+	def_dssdev = NULL;
 
 	for (i = 0; i < pdata->num_devices; ++i) {
 		struct omap_dss_device *dssdev = pdata->devices[i];
@@ -843,17 +756,69 @@
 		if (dssdev->type != OMAP_DISPLAY_TYPE_VENC)
 			continue;
 
-		r = venc_init_display(dssdev);
-		if (r) {
-			DSSERR("device %s init failed: %d\n", dssdev->name, r);
-			continue;
-		}
+		if (def_dssdev == NULL)
+			def_dssdev = dssdev;
 
-		r = omap_dss_register_device(dssdev, &pdev->dev, i);
-		if (r)
-			DSSERR("device %s register failed: %d\n",
-					dssdev->name, r);
+		if (def_disp_name != NULL &&
+				strcmp(dssdev->name, def_disp_name) == 0) {
+			def_dssdev = dssdev;
+			break;
+		}
 	}
+
+	return def_dssdev;
+}
+
+static void __init venc_probe_pdata(struct platform_device *vencdev)
+{
+	struct omap_dss_device *plat_dssdev;
+	struct omap_dss_device *dssdev;
+	int r;
+
+	plat_dssdev = venc_find_dssdev(vencdev);
+
+	if (!plat_dssdev)
+		return;
+
+	dssdev = dss_alloc_and_init_device(&vencdev->dev);
+	if (!dssdev)
+		return;
+
+	dss_copy_device_pdata(dssdev, plat_dssdev);
+
+	dssdev->channel = OMAP_DSS_CHANNEL_DIGIT;
+
+	r = venc_init_display(dssdev);
+	if (r) {
+		DSSERR("device %s init failed: %d\n", dssdev->name, r);
+		dss_put_device(dssdev);
+		return;
+	}
+
+	r = dss_add_device(dssdev);
+	if (r) {
+		DSSERR("device %s register failed: %d\n", dssdev->name, r);
+		dss_put_device(dssdev);
+		return;
+	}
+}
+
+static void __init venc_init_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out = &venc.output;
+
+	out->pdev = pdev;
+	out->id = OMAP_DSS_OUTPUT_VENC;
+	out->type = OMAP_DISPLAY_TYPE_VENC;
+
+	dss_register_output(out);
+}
+
+static void __exit venc_uninit_output(struct platform_device *pdev)
+{
+	struct omap_dss_output *out = &venc.output;
+
+	dss_unregister_output(out);
 }
 
 /* VENC HW IP initialisation */
@@ -897,17 +862,19 @@
 
 	venc_runtime_put();
 
-	r = omap_dss_register_driver(&venc_driver);
+	r = venc_panel_init();
 	if (r)
-		goto err_reg_panel_driver;
+		goto err_panel_init;
 
 	dss_debugfs_create_file("venc", venc_dump_regs);
 
+	venc_init_output(pdev);
+
 	venc_probe_pdata(pdev);
 
 	return 0;
 
-err_reg_panel_driver:
+err_panel_init:
 err_runtime_get:
 	pm_runtime_disable(&pdev->dev);
 	venc_put_clocks();
@@ -916,14 +883,16 @@
 
 static int __exit omap_venchw_remove(struct platform_device *pdev)
 {
-	omap_dss_unregister_child_devices(&pdev->dev);
+	dss_unregister_child_devices(&pdev->dev);
 
 	if (venc.vdda_dac_reg != NULL) {
 		regulator_put(venc.vdda_dac_reg);
 		venc.vdda_dac_reg = NULL;
 	}
 
-	omap_dss_unregister_driver(&venc_driver);
+	venc_panel_exit();
+
+	venc_uninit_output(pdev);
 
 	pm_runtime_disable(&pdev->dev);
 	venc_put_clocks();
@@ -971,16 +940,10 @@
 
 int __init venc_init_platform_driver(void)
 {
-	if (cpu_is_omap44xx())
-		return 0;
-
 	return platform_driver_probe(&omap_venchw_driver, omap_venchw_probe);
 }
 
 void __exit venc_uninit_platform_driver(void)
 {
-	if (cpu_is_omap44xx())
-		return;
-
 	platform_driver_unregister(&omap_venchw_driver);
 }
diff --git a/drivers/video/omap2/dss/venc_panel.c b/drivers/video/omap2/dss/venc_panel.c
new file mode 100644
index 0000000..d55b878
--- /dev/null
+++ b/drivers/video/omap2/dss/venc_panel.c
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * VENC panel driver
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/mutex.h>
+#include <linux/module.h>
+
+#include <video/omapdss.h>
+
+#include "dss.h"
+
+static struct {
+	struct mutex lock;
+} venc_panel;
+
+static ssize_t display_output_type_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	const char *ret;
+
+	switch (dssdev->phy.venc.type) {
+	case OMAP_DSS_VENC_TYPE_COMPOSITE:
+		ret = "composite";
+		break;
+	case OMAP_DSS_VENC_TYPE_SVIDEO:
+		ret = "svideo";
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", ret);
+}
+
+static ssize_t display_output_type_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t size)
+{
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	enum omap_dss_venc_type new_type;
+
+	if (sysfs_streq("composite", buf))
+		new_type = OMAP_DSS_VENC_TYPE_COMPOSITE;
+	else if (sysfs_streq("svideo", buf))
+		new_type = OMAP_DSS_VENC_TYPE_SVIDEO;
+	else
+		return -EINVAL;
+
+	mutex_lock(&venc_panel.lock);
+
+	if (dssdev->phy.venc.type != new_type) {
+		dssdev->phy.venc.type = new_type;
+		omapdss_venc_set_type(dssdev, new_type);
+		if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
+			omapdss_venc_display_disable(dssdev);
+			omapdss_venc_display_enable(dssdev);
+		}
+	}
+
+	mutex_unlock(&venc_panel.lock);
+
+	return size;
+}
+
+static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR,
+		display_output_type_show, display_output_type_store);
+
+static int venc_panel_probe(struct omap_dss_device *dssdev)
+{
+	/* set default timings to PAL */
+	const struct omap_video_timings default_timings = {
+		.x_res		= 720,
+		.y_res		= 574,
+		.pixel_clock	= 13500,
+		.hsw		= 64,
+		.hfp		= 12,
+		.hbp		= 68,
+		.vsw		= 5,
+		.vfp		= 5,
+		.vbp		= 41,
+
+		.vsync_level	= OMAPDSS_SIG_ACTIVE_HIGH,
+		.hsync_level	= OMAPDSS_SIG_ACTIVE_HIGH,
+
+		.interlace	= true,
+	};
+
+	mutex_init(&venc_panel.lock);
+
+	dssdev->panel.timings = default_timings;
+
+	return device_create_file(&dssdev->dev, &dev_attr_output_type);
+}
+
+static void venc_panel_remove(struct omap_dss_device *dssdev)
+{
+	device_remove_file(&dssdev->dev, &dev_attr_output_type);
+}
+
+static int venc_panel_enable(struct omap_dss_device *dssdev)
+{
+	int r;
+
+	dev_dbg(&dssdev->dev, "venc_panel_enable\n");
+
+	mutex_lock(&venc_panel.lock);
+
+	if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
+		r = -EINVAL;
+		goto err;
+	}
+
+	omapdss_venc_set_timings(dssdev, &dssdev->panel.timings);
+	omapdss_venc_set_type(dssdev, dssdev->phy.venc.type);
+	omapdss_venc_invert_vid_out_polarity(dssdev,
+		dssdev->phy.venc.invert_polarity);
+
+	r = omapdss_venc_display_enable(dssdev);
+	if (r)
+		goto err;
+
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+	mutex_unlock(&venc_panel.lock);
+
+	return 0;
+err:
+	mutex_unlock(&venc_panel.lock);
+
+	return r;
+}
+
+static void venc_panel_disable(struct omap_dss_device *dssdev)
+{
+	dev_dbg(&dssdev->dev, "venc_panel_disable\n");
+
+	mutex_lock(&venc_panel.lock);
+
+	if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
+		goto end;
+
+	if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) {
+		/* suspended is the same as disabled with venc */
+		dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+		goto end;
+	}
+
+	omapdss_venc_display_disable(dssdev);
+
+	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+end:
+	mutex_unlock(&venc_panel.lock);
+}
+
+static int venc_panel_suspend(struct omap_dss_device *dssdev)
+{
+	venc_panel_disable(dssdev);
+	return 0;
+}
+
+static int venc_panel_resume(struct omap_dss_device *dssdev)
+{
+	return venc_panel_enable(dssdev);
+}
+
+static void venc_panel_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	dev_dbg(&dssdev->dev, "venc_panel_set_timings\n");
+
+	mutex_lock(&venc_panel.lock);
+
+	omapdss_venc_set_timings(dssdev, timings);
+	dssdev->panel.timings = *timings;
+
+	mutex_unlock(&venc_panel.lock);
+}
+
+static int venc_panel_check_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	dev_dbg(&dssdev->dev, "venc_panel_check_timings\n");
+
+	return omapdss_venc_check_timings(dssdev, timings);
+}
+
+static u32 venc_panel_get_wss(struct omap_dss_device *dssdev)
+{
+	dev_dbg(&dssdev->dev, "venc_panel_get_wss\n");
+
+	return omapdss_venc_get_wss(dssdev);
+}
+
+static int venc_panel_set_wss(struct omap_dss_device *dssdev, u32 wss)
+{
+	dev_dbg(&dssdev->dev, "venc_panel_set_wss\n");
+
+	return omapdss_venc_set_wss(dssdev, wss);
+}
+
+static struct omap_dss_driver venc_driver = {
+	.probe		= venc_panel_probe,
+	.remove		= venc_panel_remove,
+
+	.enable		= venc_panel_enable,
+	.disable	= venc_panel_disable,
+	.suspend	= venc_panel_suspend,
+	.resume		= venc_panel_resume,
+
+	.get_resolution	= omapdss_default_get_resolution,
+	.get_recommended_bpp = omapdss_default_get_recommended_bpp,
+
+	.set_timings	= venc_panel_set_timings,
+	.check_timings	= venc_panel_check_timings,
+
+	.get_wss	= venc_panel_get_wss,
+	.set_wss	= venc_panel_set_wss,
+
+	.driver         = {
+		.name   = "venc",
+		.owner  = THIS_MODULE,
+	},
+};
+
+int venc_panel_init(void)
+{
+	return omap_dss_register_driver(&venc_driver);
+}
+
+void venc_panel_exit(void)
+{
+	omap_dss_unregister_driver(&venc_driver);
+}
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index c6cf372..606b89f 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -599,6 +599,7 @@
 	struct omapfb_info *ofbi = FB2OFB(fbi);
 	struct omapfb2_device *fbdev = ofbi->fbdev;
 	struct omap_dss_device *display = fb2display(fbi);
+	struct omap_overlay_manager *mgr;
 
 	union {
 		struct omapfb_update_window_old	uwnd_o;
@@ -786,12 +787,14 @@
 
 	case OMAPFB_WAITFORVSYNC:
 		DBG("ioctl WAITFORVSYNC\n");
-		if (!display) {
+		if (!display && !display->output && !display->output->manager) {
 			r = -EINVAL;
 			break;
 		}
 
-		r = display->manager->wait_for_vsync(display->manager);
+		mgr = display->output->manager;
+
+		r = mgr->wait_for_vsync(mgr);
 		break;
 
 	case OMAPFB_WAITFORGO:
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 3c39aa8..16db158 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -1128,7 +1128,7 @@
 	DBG("user mmap region start %lx, len %d, off %lx\n", start, len, off);
 
 	vma->vm_pgoff = off >> PAGE_SHIFT;
-	vma->vm_flags |= VM_IO | VM_RESERVED;
+	/* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
 	vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
 	vma->vm_ops = &mmap_user_ops;
 	vma->vm_private_data = rg;
@@ -1593,6 +1593,20 @@
 	return 0;
 }
 
+static void omapfb_clear_fb(struct fb_info *fbi)
+{
+	const struct fb_fillrect rect = {
+		.dx = 0,
+		.dy = 0,
+		.width = fbi->var.xres_virtual,
+		.height = fbi->var.yres_virtual,
+		.color = 0,
+		.rop = ROP_COPY,
+	};
+
+	cfb_fillrect(fbi, &rect);
+}
+
 int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
 {
 	struct omapfb_info *ofbi = FB2OFB(fbi);
@@ -1662,6 +1676,8 @@
 			goto err;
 	}
 
+	omapfb_clear_fb(fbi);
+
 	return 0;
 err:
 	omapfb_free_fbmem(fbi);
@@ -1946,6 +1962,16 @@
 		}
 	}
 
+	for (i = 0; i < fbdev->num_fbs; i++) {
+		struct fb_info *fbi = fbdev->fbs[i];
+		struct omapfb_info *ofbi = FB2OFB(fbi);
+
+		if (ofbi->region->size == 0)
+			continue;
+
+		omapfb_clear_fb(fbi);
+	}
+
 	DBG("fb_infos initialized\n");
 
 	for (i = 0; i < fbdev->num_fbs; i++) {
@@ -2354,6 +2380,7 @@
 	struct omap_overlay *ovl;
 	struct omap_dss_device *def_display;
 	struct omap_dss_device *dssdev;
+	struct omap_dss_device *ovl_device;
 
 	DBG("omapfb_probe\n");
 
@@ -2427,8 +2454,9 @@
 	/* gfx overlay should be the default one. find a display
 	 * connected to that, and use it as default display */
 	ovl = omap_dss_get_overlay(0);
-	if (ovl->manager && ovl->manager->device) {
-		def_display = ovl->manager->device;
+	ovl_device = ovl->get_device(ovl);
+	if (ovl_device) {
+		def_display = ovl_device;
 	} else {
 		dev_warn(&pdev->dev, "cannot find default display\n");
 		def_display = NULL;
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index 30361a0..5ced9b3 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -148,8 +148,9 @@
 
 	/* XXX: returns the display connected to first attached overlay */
 	for (i = 0; i < ofbi->num_overlays; i++) {
-		if (ofbi->overlays[i]->manager)
-			return ofbi->overlays[i]->manager->device;
+		struct omap_overlay *ovl = ofbi->overlays[i];
+
+		return ovl->get_device(ovl);
 	}
 
 	return NULL;
diff --git a/drivers/video/omap2/vram.c b/drivers/video/omap2/vram.c
index 87e421e..f2b15c4 100644
--- a/drivers/video/omap2/vram.c
+++ b/drivers/video/omap2/vram.c
@@ -34,7 +34,6 @@
 #include <asm/setup.h>
 
 #include <plat/vram.h>
-#include <plat/dma.h>
 
 #ifdef DEBUG
 #define DBG(format, ...) pr_debug("VRAM: " format, ## __VA_ARGS__)
@@ -250,59 +249,6 @@
 }
 EXPORT_SYMBOL(omap_vram_reserve);
 
-static void _omap_vram_dma_cb(int lch, u16 ch_status, void *data)
-{
-	struct completion *compl = data;
-	complete(compl);
-}
-
-static int _omap_vram_clear(u32 paddr, unsigned pages)
-{
-	struct completion compl;
-	unsigned elem_count;
-	unsigned frame_count;
-	int r;
-	int lch;
-
-	init_completion(&compl);
-
-	r = omap_request_dma(OMAP_DMA_NO_DEVICE, "VRAM DMA",
-			_omap_vram_dma_cb,
-			&compl, &lch);
-	if (r) {
-		pr_err("VRAM: request_dma failed for memory clear\n");
-		return -EBUSY;
-	}
-
-	elem_count = pages * PAGE_SIZE / 4;
-	frame_count = 1;
-
-	omap_set_dma_transfer_params(lch, OMAP_DMA_DATA_TYPE_S32,
-			elem_count, frame_count,
-			OMAP_DMA_SYNC_ELEMENT,
-			0, 0);
-
-	omap_set_dma_dest_params(lch, 0, OMAP_DMA_AMODE_POST_INC,
-			paddr, 0, 0);
-
-	omap_set_dma_color_mode(lch, OMAP_DMA_CONSTANT_FILL, 0x000000);
-
-	omap_start_dma(lch);
-
-	if (wait_for_completion_timeout(&compl, msecs_to_jiffies(1000)) == 0) {
-		omap_stop_dma(lch);
-		pr_err("VRAM: dma timeout while clearing memory\n");
-		r = -EIO;
-		goto err;
-	}
-
-	r = 0;
-err:
-	omap_free_dma(lch);
-
-	return r;
-}
-
 static int _omap_vram_alloc(unsigned pages, unsigned long *paddr)
 {
 	struct vram_region *rm;
@@ -337,8 +283,6 @@
 
 		*paddr = start;
 
-		_omap_vram_clear(start, pages);
-
 		return 0;
 	}
 
diff --git a/drivers/video/pnx4008/Makefile b/drivers/video/pnx4008/Makefile
deleted file mode 100644
index 636aacc..0000000
--- a/drivers/video/pnx4008/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# Makefile for the new PNX4008 framebuffer device driver
-#
-
-obj-$(CONFIG_FB_PNX4008_DUM) += sdum.o
-obj-$(CONFIG_FB_PNX4008_DUM_RGB) += pnxrgbfb.o
-
diff --git a/drivers/video/pnx4008/dum.h b/drivers/video/pnx4008/dum.h
deleted file mode 100644
index 1234d43..0000000
--- a/drivers/video/pnx4008/dum.h
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * linux/drivers/video/pnx4008/dum.h
- *
- * Internal header for SDUM
- *
- * 2005 (c) Koninklijke Philips N.V. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-
-#ifndef __PNX008_DUM_H__
-#define __PNX008_DUM_H__
-
-#include <mach/platform.h>
-
-#define PNX4008_DUMCONF_VA_BASE		IO_ADDRESS(PNX4008_DUMCONF_BASE)
-#define PNX4008_DUM_MAIN_VA_BASE	IO_ADDRESS(PNX4008_DUM_MAINCFG_BASE)
-
-/* DUM CFG ADDRESSES */
-#define DUM_CH_BASE_ADR		(PNX4008_DUMCONF_VA_BASE + 0x00)
-#define DUM_CH_MIN_ADR		(PNX4008_DUMCONF_VA_BASE + 0x00)
-#define DUM_CH_MAX_ADR		(PNX4008_DUMCONF_VA_BASE + 0x04)
-#define DUM_CH_CONF_ADR		(PNX4008_DUMCONF_VA_BASE + 0x08)
-#define DUM_CH_STAT_ADR		(PNX4008_DUMCONF_VA_BASE + 0x0C)
-#define DUM_CH_CTRL_ADR		(PNX4008_DUMCONF_VA_BASE + 0x10)
-
-#define CH_MARG		(0x100 / sizeof(u32))
-#define DUM_CH_MIN(i)	(*((volatile u32 *)DUM_CH_MIN_ADR + (i) * CH_MARG))
-#define DUM_CH_MAX(i)	(*((volatile u32 *)DUM_CH_MAX_ADR + (i) * CH_MARG))
-#define DUM_CH_CONF(i)	(*((volatile u32 *)DUM_CH_CONF_ADR + (i) * CH_MARG))
-#define DUM_CH_STAT(i)	(*((volatile u32 *)DUM_CH_STAT_ADR + (i) * CH_MARG))
-#define DUM_CH_CTRL(i)	(*((volatile u32 *)DUM_CH_CTRL_ADR + (i) * CH_MARG))
-
-#define DUM_CONF_ADR          (PNX4008_DUM_MAIN_VA_BASE + 0x00)
-#define DUM_CTRL_ADR          (PNX4008_DUM_MAIN_VA_BASE + 0x04)
-#define DUM_STAT_ADR          (PNX4008_DUM_MAIN_VA_BASE + 0x08)
-#define DUM_DECODE_ADR        (PNX4008_DUM_MAIN_VA_BASE + 0x0C)
-#define DUM_COM_BASE_ADR      (PNX4008_DUM_MAIN_VA_BASE + 0x10)
-#define DUM_SYNC_C_ADR        (PNX4008_DUM_MAIN_VA_BASE + 0x14)
-#define DUM_CLK_DIV_ADR       (PNX4008_DUM_MAIN_VA_BASE + 0x18)
-#define DUM_DIRTY_LOW_ADR     (PNX4008_DUM_MAIN_VA_BASE + 0x20)
-#define DUM_DIRTY_HIGH_ADR    (PNX4008_DUM_MAIN_VA_BASE + 0x24)
-#define DUM_FORMAT_ADR        (PNX4008_DUM_MAIN_VA_BASE + 0x28)
-#define DUM_WTCFG1_ADR        (PNX4008_DUM_MAIN_VA_BASE + 0x30)
-#define DUM_RTCFG1_ADR        (PNX4008_DUM_MAIN_VA_BASE + 0x34)
-#define DUM_WTCFG2_ADR        (PNX4008_DUM_MAIN_VA_BASE + 0x38)
-#define DUM_RTCFG2_ADR        (PNX4008_DUM_MAIN_VA_BASE + 0x3C)
-#define DUM_TCFG_ADR          (PNX4008_DUM_MAIN_VA_BASE + 0x40)
-#define DUM_OUTP_FORMAT1_ADR  (PNX4008_DUM_MAIN_VA_BASE + 0x44)
-#define DUM_OUTP_FORMAT2_ADR  (PNX4008_DUM_MAIN_VA_BASE + 0x48)
-#define DUM_SYNC_MODE_ADR     (PNX4008_DUM_MAIN_VA_BASE + 0x4C)
-#define DUM_SYNC_OUT_C_ADR    (PNX4008_DUM_MAIN_VA_BASE + 0x50)
-
-#define DUM_CONF              (*(volatile u32 *)(DUM_CONF_ADR))
-#define DUM_CTRL              (*(volatile u32 *)(DUM_CTRL_ADR))
-#define DUM_STAT              (*(volatile u32 *)(DUM_STAT_ADR))
-#define DUM_DECODE            (*(volatile u32 *)(DUM_DECODE_ADR))
-#define DUM_COM_BASE          (*(volatile u32 *)(DUM_COM_BASE_ADR))
-#define DUM_SYNC_C            (*(volatile u32 *)(DUM_SYNC_C_ADR))
-#define DUM_CLK_DIV           (*(volatile u32 *)(DUM_CLK_DIV_ADR))
-#define DUM_DIRTY_LOW         (*(volatile u32 *)(DUM_DIRTY_LOW_ADR))
-#define DUM_DIRTY_HIGH        (*(volatile u32 *)(DUM_DIRTY_HIGH_ADR))
-#define DUM_FORMAT            (*(volatile u32 *)(DUM_FORMAT_ADR))
-#define DUM_WTCFG1            (*(volatile u32 *)(DUM_WTCFG1_ADR))
-#define DUM_RTCFG1            (*(volatile u32 *)(DUM_RTCFG1_ADR))
-#define DUM_WTCFG2            (*(volatile u32 *)(DUM_WTCFG2_ADR))
-#define DUM_RTCFG2            (*(volatile u32 *)(DUM_RTCFG2_ADR))
-#define DUM_TCFG              (*(volatile u32 *)(DUM_TCFG_ADR))
-#define DUM_OUTP_FORMAT1      (*(volatile u32 *)(DUM_OUTP_FORMAT1_ADR))
-#define DUM_OUTP_FORMAT2      (*(volatile u32 *)(DUM_OUTP_FORMAT2_ADR))
-#define DUM_SYNC_MODE         (*(volatile u32 *)(DUM_SYNC_MODE_ADR))
-#define DUM_SYNC_OUT_C        (*(volatile u32 *)(DUM_SYNC_OUT_C_ADR))
-
-/* DUM SLAVE ADDRESSES */
-#define DUM_SLAVE_WRITE_ADR      (PNX4008_DUM_MAINCFG_BASE + 0x0000000)
-#define DUM_SLAVE_READ1_I_ADR    (PNX4008_DUM_MAINCFG_BASE + 0x1000000)
-#define DUM_SLAVE_READ1_R_ADR    (PNX4008_DUM_MAINCFG_BASE + 0x1000004)
-#define DUM_SLAVE_READ2_I_ADR    (PNX4008_DUM_MAINCFG_BASE + 0x1000008)
-#define DUM_SLAVE_READ2_R_ADR    (PNX4008_DUM_MAINCFG_BASE + 0x100000C)
-
-#define DUM_SLAVE_WRITE_W  ((volatile u32 *)(DUM_SLAVE_WRITE_ADR))
-#define DUM_SLAVE_WRITE_HW ((volatile u16 *)(DUM_SLAVE_WRITE_ADR))
-#define DUM_SLAVE_READ1_I  ((volatile u8 *)(DUM_SLAVE_READ1_I_ADR))
-#define DUM_SLAVE_READ1_R  ((volatile u16 *)(DUM_SLAVE_READ1_R_ADR))
-#define DUM_SLAVE_READ2_I  ((volatile u8 *)(DUM_SLAVE_READ2_I_ADR))
-#define DUM_SLAVE_READ2_R  ((volatile u16 *)(DUM_SLAVE_READ2_R_ADR))
-
-/* Sony display register addresses */
-#define DISP_0_REG            (0x00)
-#define DISP_1_REG            (0x01)
-#define DISP_CAL_REG          (0x20)
-#define DISP_ID_REG           (0x2A)
-#define DISP_XMIN_L_REG       (0x30)
-#define DISP_XMIN_H_REG       (0x31)
-#define DISP_YMIN_REG         (0x32)
-#define DISP_XMAX_L_REG       (0x34)
-#define DISP_XMAX_H_REG       (0x35)
-#define DISP_YMAX_REG         (0x36)
-#define DISP_SYNC_EN_REG      (0x38)
-#define DISP_SYNC_RISE_L_REG  (0x3C)
-#define DISP_SYNC_RISE_H_REG  (0x3D)
-#define DISP_SYNC_FALL_L_REG  (0x3E)
-#define DISP_SYNC_FALL_H_REG  (0x3F)
-#define DISP_PIXEL_REG        (0x0B)
-#define DISP_DUMMY1_REG       (0x28)
-#define DISP_DUMMY2_REG       (0x29)
-#define DISP_TIMING_REG       (0x98)
-#define DISP_DUMP_REG         (0x99)
-
-/* Sony display constants */
-#define SONY_ID1              (0x22)
-#define SONY_ID2              (0x23)
-
-/* Philips display register addresses */
-#define PH_DISP_ORIENT_REG    (0x003)
-#define PH_DISP_YPOINT_REG    (0x200)
-#define PH_DISP_XPOINT_REG    (0x201)
-#define PH_DISP_PIXEL_REG     (0x202)
-#define PH_DISP_YMIN_REG      (0x406)
-#define PH_DISP_YMAX_REG      (0x407)
-#define PH_DISP_XMIN_REG      (0x408)
-#define PH_DISP_XMAX_REG      (0x409)
-
-/* Misc constants */
-#define NO_VALID_DISPLAY_FOUND      (0)
-#define DISPLAY2_IS_NOT_CONNECTED   (0)
-
-/* register values */
-#define V_BAC_ENABLE		(BIT(0))
-#define V_BAC_DISABLE_IDLE	(BIT(1))
-#define V_BAC_DISABLE_TRIG	(BIT(2))
-#define V_DUM_RESET		(BIT(3))
-#define V_MUX_RESET		(BIT(4))
-#define BAC_ENABLED		(BIT(0))
-#define BAC_DISABLED		0
-
-/* Sony LCD commands */
-#define V_LCD_STANDBY_OFF	((BIT(25)) | (0 << 16) | DISP_0_REG)
-#define V_LCD_USE_9BIT_BUS	((BIT(25)) | (2 << 16) | DISP_1_REG)
-#define V_LCD_SYNC_RISE_L	((BIT(25)) | (0 << 16) | DISP_SYNC_RISE_L_REG)
-#define V_LCD_SYNC_RISE_H	((BIT(25)) | (0 << 16) | DISP_SYNC_RISE_H_REG)
-#define V_LCD_SYNC_FALL_L	((BIT(25)) | (160 << 16) | DISP_SYNC_FALL_L_REG)
-#define V_LCD_SYNC_FALL_H	((BIT(25)) | (0 << 16) | DISP_SYNC_FALL_H_REG)
-#define V_LCD_SYNC_ENABLE	((BIT(25)) | (128 << 16) | DISP_SYNC_EN_REG)
-#define V_LCD_DISPLAY_ON	((BIT(25)) | (64 << 16) | DISP_0_REG)
-
-enum {
-	PAD_NONE,
-	PAD_512,
-	PAD_1024
-};
-
-enum {
-	RGB888,
-	RGB666,
-	RGB565,
-	BGR565,
-	ARGB1555,
-	ABGR1555,
-	ARGB4444,
-	ABGR4444
-};
-
-struct dum_setup {
-	int sync_neg_edge;
-	int round_robin;
-	int mux_int;
-	int synced_dirty_flag_int;
-	int dirty_flag_int;
-	int error_int;
-	int pf_empty_int;
-	int sf_empty_int;
-	int bac_dis_int;
-	u32 dirty_base_adr;
-	u32 command_base_adr;
-	u32 sync_clk_div;
-	int sync_output;
-	u32 sync_restart_val;
-	u32 set_sync_high;
-	u32 set_sync_low;
-};
-
-struct dum_ch_setup {
-	int disp_no;
-	u32 xmin;
-	u32 ymin;
-	u32 xmax;
-	u32 ymax;
-	int xmirror;
-	int ymirror;
-	int rotate;
-	u32 minadr;
-	u32 maxadr;
-	u32 dirtybuffer;
-	int pad;
-	int format;
-	int hwdirty;
-	int slave_trans;
-};
-
-struct disp_window {
-	u32 xmin_l;
-	u32 xmin_h;
-	u32 ymin;
-	u32 xmax_l;
-	u32 xmax_h;
-	u32 ymax;
-};
-
-#endif				/* #ifndef __PNX008_DUM_H__ */
diff --git a/drivers/video/pnx4008/fbcommon.h b/drivers/video/pnx4008/fbcommon.h
deleted file mode 100644
index 4ebc87d..0000000
--- a/drivers/video/pnx4008/fbcommon.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2005 Philips Semiconductors
- *
- * 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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.  If not, write to
- * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA, or http://www.gnu.org/licenses/gpl.html
-*/
-
-#define QCIF_W  (176)
-#define QCIF_H  (144)
-
-#define CIF_W   (352)
-#define CIF_H   (288)
-
-#define LCD_X_RES	208
-#define LCD_Y_RES	320
-#define LCD_X_PAD	256
-#define LCD_BBP		4	/* Bytes Per Pixel */
-
-#define DISP_MAX_X_SIZE     (320)
-#define DISP_MAX_Y_SIZE     (208)
-
-#define RETURNVAL_BASE (0x400)
-
-enum fb_ioctl_returntype {
-	ENORESOURCESLEFT = RETURNVAL_BASE,
-	ERESOURCESNOTFREED,
-	EPROCNOTOWNER,
-	EFBNOTOWNER,
-	ECOPYFAILED,
-	EIOREMAPFAILED,
-};
diff --git a/drivers/video/pnx4008/pnxrgbfb.c b/drivers/video/pnx4008/pnxrgbfb.c
deleted file mode 100644
index 6d30428..0000000
--- a/drivers/video/pnx4008/pnxrgbfb.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * drivers/video/pnx4008/pnxrgbfb.c
- *
- * PNX4008's framebuffer support
- *
- * Author: Grigory Tolstolytkin <gtolstolytkin@ru.mvista.com>
- * Based on Philips Semiconductors's code
- *
- * Copyrght (c) 2005 MontaVista Software, Inc.
- * Copyright (c) 2005 Philips Semiconductors
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/vmalloc.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-
-#include "sdum.h"
-#include "fbcommon.h"
-
-static u32 colreg[16];
-
-static struct fb_var_screeninfo rgbfb_var __initdata = {
-	.xres = LCD_X_RES,
-	.yres = LCD_Y_RES,
-	.xres_virtual = LCD_X_RES,
-	.yres_virtual = LCD_Y_RES,
-	.bits_per_pixel = 32,
-	.red.offset = 16,
-	.red.length = 8,
-	.green.offset = 8,
-	.green.length = 8,
-	.blue.offset = 0,
-	.blue.length = 8,
-	.left_margin = 0,
-	.right_margin = 0,
-	.upper_margin = 0,
-	.lower_margin = 0,
-	.vmode = FB_VMODE_NONINTERLACED,
-};
-static struct fb_fix_screeninfo rgbfb_fix __initdata = {
-	.id = "RGBFB",
-	.line_length = LCD_X_RES * LCD_BBP,
-	.type = FB_TYPE_PACKED_PIXELS,
-	.visual = FB_VISUAL_TRUECOLOR,
-	.xpanstep = 0,
-	.ypanstep = 0,
-	.ywrapstep = 0,
-	.accel = FB_ACCEL_NONE,
-};
-
-static int channel_owned;
-
-static int no_cursor(struct fb_info *info, struct fb_cursor *cursor)
-{
-	return 0;
-}
-
-static int rgbfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-			   u_int transp, struct fb_info *info)
-{
-	if (regno > 15)
-		return 1;
-
-	colreg[regno] = ((red & 0xff00) << 8) | (green & 0xff00) |
-	    ((blue & 0xff00) >> 8);
-	return 0;
-}
-
-static int rgbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
-{
-	return pnx4008_sdum_mmap(info, vma, NULL);
-}
-
-static struct fb_ops rgbfb_ops = {
-	.fb_mmap = rgbfb_mmap,
-	.fb_setcolreg = rgbfb_setcolreg,
-	.fb_fillrect = cfb_fillrect,
-	.fb_copyarea = cfb_copyarea,
-	.fb_imageblit = cfb_imageblit,
-};
-
-static int rgbfb_remove(struct platform_device *pdev)
-{
-	struct fb_info *info = platform_get_drvdata(pdev);
-
-	if (info) {
-		unregister_framebuffer(info);
-		fb_dealloc_cmap(&info->cmap);
-		framebuffer_release(info);
-		platform_set_drvdata(pdev, NULL);
-	}
-
-	pnx4008_free_dum_channel(channel_owned, pdev->id);
-	pnx4008_set_dum_exit_notification(pdev->id);
-
-	return 0;
-}
-
-static int __devinit rgbfb_probe(struct platform_device *pdev)
-{
-	struct fb_info *info;
-	struct dumchannel_uf chan_uf;
-	int ret;
-	char *option;
-
-	info = framebuffer_alloc(sizeof(u32) * 16, &pdev->dev);
-	if (!info) {
-		ret = -ENOMEM;
-		goto err;
-	}
-
-	pnx4008_get_fb_addresses(FB_TYPE_RGB, (void **)&info->screen_base,
-				 (dma_addr_t *) &rgbfb_fix.smem_start,
-				 &rgbfb_fix.smem_len);
-
-	if ((ret = pnx4008_alloc_dum_channel(pdev->id)) < 0)
-		goto err0;
-	else {
-		channel_owned = ret;
-		chan_uf.channelnr = channel_owned;
-		chan_uf.dirty = (u32 *) NULL;
-		chan_uf.source = (u32 *) rgbfb_fix.smem_start;
-		chan_uf.x_offset = 0;
-		chan_uf.y_offset = 0;
-		chan_uf.width = LCD_X_RES;
-		chan_uf.height = LCD_Y_RES;
-
-		if ((ret = pnx4008_put_dum_channel_uf(chan_uf, pdev->id))< 0)
-			goto err1;
-
-		if ((ret =
-		     pnx4008_set_dum_channel_sync(channel_owned, CONF_SYNC_ON,
-						  pdev->id)) < 0)
-			goto err1;
-
-		if ((ret =
-		     pnx4008_set_dum_channel_dirty_detect(channel_owned,
-							 CONF_DIRTYDETECTION_ON,
-							 pdev->id)) < 0)
-			goto err1;
-	}
-
-	if (!fb_get_options("pnxrgbfb", &option) && option &&
-			!strcmp(option, "nocursor"))
-		rgbfb_ops.fb_cursor = no_cursor;
-
-	info->node = -1;
-	info->flags = FBINFO_FLAG_DEFAULT;
-	info->fbops = &rgbfb_ops;
-	info->fix = rgbfb_fix;
-	info->var = rgbfb_var;
-	info->screen_size = rgbfb_fix.smem_len;
-	info->pseudo_palette = info->par;
-	info->par = NULL;
-
-	ret = fb_alloc_cmap(&info->cmap, 256, 0);
-	if (ret < 0)
-		goto err1;
-
-	ret = register_framebuffer(info);
-	if (ret < 0)
-		goto err2;
-	platform_set_drvdata(pdev, info);
-
-	return 0;
-
-err2:
-	fb_dealloc_cmap(&info->cmap);
-err1:
-	pnx4008_free_dum_channel(channel_owned, pdev->id);
-err0:
-	framebuffer_release(info);
-err:
-	return ret;
-}
-
-static struct platform_driver rgbfb_driver = {
-	.driver = {
-		.name = "pnx4008-rgbfb",
-	},
-	.probe = rgbfb_probe,
-	.remove = rgbfb_remove,
-};
-
-module_platform_driver(rgbfb_driver);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/video/pnx4008/sdum.c b/drivers/video/pnx4008/sdum.c
deleted file mode 100644
index c5c7414..0000000
--- a/drivers/video/pnx4008/sdum.c
+++ /dev/null
@@ -1,861 +0,0 @@
-/*
- * drivers/video/pnx4008/sdum.c
- *
- * Display Update Master support
- *
- * Authors: Grigory Tolstolytkin <gtolstolytkin@ru.mvista.com>
- *          Vitaly Wool <vitalywool@gmail.com>
- * Based on Philips Semiconductors's code
- *
- * Copyrght (c) 2005-2006 MontaVista Software, Inc.
- * Copyright (c) 2005 Philips Semiconductors
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/vmalloc.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/dma-mapping.h>
-#include <linux/clk.h>
-#include <linux/gfp.h>
-#include <asm/uaccess.h>
-#include <asm/gpio.h>
-
-#include "sdum.h"
-#include "fbcommon.h"
-#include "dum.h"
-
-/* Framebuffers we have */
-
-static struct pnx4008_fb_addr {
-	int fb_type;
-	long addr_offset;
-	long fb_length;
-} fb_addr[] = {
-	[0] = {
-		FB_TYPE_YUV, 0, 0xB0000
-	},
-	[1] = {
-		FB_TYPE_RGB, 0xB0000, 0x50000
-	},
-};
-
-static struct dum_data {
-	u32 lcd_phys_start;
-	u32 lcd_virt_start;
-	u32 slave_phys_base;
-	u32 *slave_virt_base;
-	int fb_owning_channel[MAX_DUM_CHANNELS];
-	struct dumchannel_uf chan_uf_store[MAX_DUM_CHANNELS];
-} dum_data;
-
-/* Different local helper functions */
-
-static u32 nof_pixels_dx(struct dum_ch_setup *ch_setup)
-{
-	return (ch_setup->xmax - ch_setup->xmin + 1);
-}
-
-static u32 nof_pixels_dy(struct dum_ch_setup *ch_setup)
-{
-	return (ch_setup->ymax - ch_setup->ymin + 1);
-}
-
-static u32 nof_pixels_dxy(struct dum_ch_setup *ch_setup)
-{
-	return (nof_pixels_dx(ch_setup) * nof_pixels_dy(ch_setup));
-}
-
-static u32 nof_bytes(struct dum_ch_setup *ch_setup)
-{
-	u32 r = nof_pixels_dxy(ch_setup);
-	switch (ch_setup->format) {
-	case RGB888:
-	case RGB666:
-		r *= 4;
-		break;
-
-	default:
-		r *= 2;
-		break;
-	}
-	return r;
-}
-
-static u32 build_command(int disp_no, u32 reg, u32 val)
-{
-	return ((disp_no << 26) | BIT(25) | (val << 16) | (disp_no << 10) |
-		(reg << 0));
-}
-
-static u32 build_double_index(int disp_no, u32 val)
-{
-	return ((disp_no << 26) | (val << 16) | (disp_no << 10) | (val << 0));
-}
-
-static void build_disp_window(struct dum_ch_setup * ch_setup, struct disp_window * dw)
-{
-	dw->ymin = ch_setup->ymin;
-	dw->ymax = ch_setup->ymax;
-	dw->xmin_l = ch_setup->xmin & 0xFF;
-	dw->xmin_h = (ch_setup->xmin & BIT(8)) >> 8;
-	dw->xmax_l = ch_setup->xmax & 0xFF;
-	dw->xmax_h = (ch_setup->xmax & BIT(8)) >> 8;
-}
-
-static int put_channel(struct dumchannel chan)
-{
-	int i = chan.channelnr;
-
-	if (i < 0 || i > MAX_DUM_CHANNELS)
-		return -EINVAL;
-	else {
-		DUM_CH_MIN(i) = chan.dum_ch_min;
-		DUM_CH_MAX(i) = chan.dum_ch_max;
-		DUM_CH_CONF(i) = chan.dum_ch_conf;
-		DUM_CH_CTRL(i) = chan.dum_ch_ctrl;
-	}
-
-	return 0;
-}
-
-static void clear_channel(int channr)
-{
-	struct dumchannel chan;
-
-	chan.channelnr = channr;
-	chan.dum_ch_min = 0;
-	chan.dum_ch_max = 0;
-	chan.dum_ch_conf = 0;
-	chan.dum_ch_ctrl = 0;
-
-	put_channel(chan);
-}
-
-static int put_cmd_string(struct cmdstring cmds)
-{
-	u16 *cmd_str_virtaddr;
-	u32 *cmd_ptr0_virtaddr;
-	u32 cmd_str_physaddr;
-
-	int i = cmds.channelnr;
-
-	if (i < 0 || i > MAX_DUM_CHANNELS)
-		return -EINVAL;
-	else if ((cmd_ptr0_virtaddr =
-		  (int *)ioremap_nocache(DUM_COM_BASE,
-					 sizeof(int) * MAX_DUM_CHANNELS)) ==
-		 NULL)
-		return -EIOREMAPFAILED;
-	else {
-		cmd_str_physaddr = ioread32(&cmd_ptr0_virtaddr[cmds.channelnr]);
-		if ((cmd_str_virtaddr =
-		     (u16 *) ioremap_nocache(cmd_str_physaddr,
-					     sizeof(cmds))) == NULL) {
-			iounmap(cmd_ptr0_virtaddr);
-			return -EIOREMAPFAILED;
-		} else {
-			int t;
-			for (t = 0; t < 8; t++)
-				iowrite16(*((u16 *)&cmds.prestringlen + t),
-					  cmd_str_virtaddr + t);
-
-			for (t = 0; t < cmds.prestringlen / 2; t++)
-				 iowrite16(*((u16 *)&cmds.precmd + t),
-					   cmd_str_virtaddr + t + 8);
-
-			for (t = 0; t < cmds.poststringlen / 2; t++)
-				iowrite16(*((u16 *)&cmds.postcmd + t),
-					  cmd_str_virtaddr + t + 8 +
-					  	cmds.prestringlen / 2);
-
-			iounmap(cmd_ptr0_virtaddr);
-			iounmap(cmd_str_virtaddr);
-		}
-	}
-
-	return 0;
-}
-
-static u32 dum_ch_setup(int ch_no, struct dum_ch_setup * ch_setup)
-{
-	struct cmdstring cmds_c;
-	struct cmdstring *cmds = &cmds_c;
-	struct disp_window dw;
-	int standard;
-	u32 orientation = 0;
-	struct dumchannel chan = { 0 };
-	int ret;
-
-	if ((ch_setup->xmirror) || (ch_setup->ymirror) || (ch_setup->rotate)) {
-		standard = 0;
-
-		orientation = BIT(1);	/* always set 9-bit-bus */
-		if (ch_setup->xmirror)
-			orientation |= BIT(4);
-		if (ch_setup->ymirror)
-			orientation |= BIT(3);
-		if (ch_setup->rotate)
-			orientation |= BIT(0);
-	} else
-		standard = 1;
-
-	cmds->channelnr = ch_no;
-
-	/* build command string header */
-	if (standard) {
-		cmds->prestringlen = 32;
-		cmds->poststringlen = 0;
-	} else {
-		cmds->prestringlen = 48;
-		cmds->poststringlen = 16;
-	}
-
-	cmds->format =
-	    (u16) ((ch_setup->disp_no << 4) | (BIT(3)) | (ch_setup->format));
-	cmds->reserved = 0x0;
-	cmds->startaddr_low = (ch_setup->minadr & 0xFFFF);
-	cmds->startaddr_high = (ch_setup->minadr >> 16);
-
-	if ((ch_setup->minadr == 0) && (ch_setup->maxadr == 0)
-	    && (ch_setup->xmin == 0)
-	    && (ch_setup->ymin == 0) && (ch_setup->xmax == 0)
-	    && (ch_setup->ymax == 0)) {
-		cmds->pixdatlen_low = 0;
-		cmds->pixdatlen_high = 0;
-	} else {
-		u32 nbytes = nof_bytes(ch_setup);
-		cmds->pixdatlen_low = (nbytes & 0xFFFF);
-		cmds->pixdatlen_high = (nbytes >> 16);
-	}
-
-	if (ch_setup->slave_trans)
-		cmds->pixdatlen_high |= BIT(15);
-
-	/* build pre-string */
-	build_disp_window(ch_setup, &dw);
-
-	if (standard) {
-		cmds->precmd[0] =
-		    build_command(ch_setup->disp_no, DISP_XMIN_L_REG, 0x99);
-		cmds->precmd[1] =
-		    build_command(ch_setup->disp_no, DISP_XMIN_L_REG,
-				  dw.xmin_l);
-		cmds->precmd[2] =
-		    build_command(ch_setup->disp_no, DISP_XMIN_H_REG,
-				  dw.xmin_h);
-		cmds->precmd[3] =
-		    build_command(ch_setup->disp_no, DISP_YMIN_REG, dw.ymin);
-		cmds->precmd[4] =
-		    build_command(ch_setup->disp_no, DISP_XMAX_L_REG,
-				  dw.xmax_l);
-		cmds->precmd[5] =
-		    build_command(ch_setup->disp_no, DISP_XMAX_H_REG,
-				  dw.xmax_h);
-		cmds->precmd[6] =
-		    build_command(ch_setup->disp_no, DISP_YMAX_REG, dw.ymax);
-		cmds->precmd[7] =
-		    build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
-	} else {
-		if (dw.xmin_l == ch_no)
-			cmds->precmd[0] =
-			    build_command(ch_setup->disp_no, DISP_XMIN_L_REG,
-					  0x99);
-		else
-			cmds->precmd[0] =
-			    build_command(ch_setup->disp_no, DISP_XMIN_L_REG,
-					  ch_no);
-
-		cmds->precmd[1] =
-		    build_command(ch_setup->disp_no, DISP_XMIN_L_REG,
-				  dw.xmin_l);
-		cmds->precmd[2] =
-		    build_command(ch_setup->disp_no, DISP_XMIN_H_REG,
-				  dw.xmin_h);
-		cmds->precmd[3] =
-		    build_command(ch_setup->disp_no, DISP_YMIN_REG, dw.ymin);
-		cmds->precmd[4] =
-		    build_command(ch_setup->disp_no, DISP_XMAX_L_REG,
-				  dw.xmax_l);
-		cmds->precmd[5] =
-		    build_command(ch_setup->disp_no, DISP_XMAX_H_REG,
-				  dw.xmax_h);
-		cmds->precmd[6] =
-		    build_command(ch_setup->disp_no, DISP_YMAX_REG, dw.ymax);
-		cmds->precmd[7] =
-		    build_command(ch_setup->disp_no, DISP_1_REG, orientation);
-		cmds->precmd[8] =
-		    build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
-		cmds->precmd[9] =
-		    build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
-		cmds->precmd[0xA] =
-		    build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
-		cmds->precmd[0xB] =
-		    build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
-		cmds->postcmd[0] =
-		    build_command(ch_setup->disp_no, DISP_1_REG, BIT(1));
-		cmds->postcmd[1] =
-		    build_command(ch_setup->disp_no, DISP_DUMMY1_REG, 1);
-		cmds->postcmd[2] =
-		    build_command(ch_setup->disp_no, DISP_DUMMY1_REG, 2);
-		cmds->postcmd[3] =
-		    build_command(ch_setup->disp_no, DISP_DUMMY1_REG, 3);
-	}
-
-	if ((ret = put_cmd_string(cmds_c)) != 0) {
-		return ret;
-	}
-
-	chan.channelnr = cmds->channelnr;
-	chan.dum_ch_min = ch_setup->dirtybuffer + ch_setup->minadr;
-	chan.dum_ch_max = ch_setup->dirtybuffer + ch_setup->maxadr;
-	chan.dum_ch_conf = 0x002;
-	chan.dum_ch_ctrl = 0x04;
-
-	put_channel(chan);
-
-	return 0;
-}
-
-static u32 display_open(int ch_no, int auto_update, u32 * dirty_buffer,
-			u32 * frame_buffer, u32 xpos, u32 ypos, u32 w, u32 h)
-{
-
-	struct dum_ch_setup k;
-	int ret;
-
-	/* keep width & height within display area */
-	if ((xpos + w) > DISP_MAX_X_SIZE)
-		w = DISP_MAX_X_SIZE - xpos;
-
-	if ((ypos + h) > DISP_MAX_Y_SIZE)
-		h = DISP_MAX_Y_SIZE - ypos;
-
-	/* assume 1 display only */
-	k.disp_no = 0;
-	k.xmin = xpos;
-	k.ymin = ypos;
-	k.xmax = xpos + (w - 1);
-	k.ymax = ypos + (h - 1);
-
-	/* adjust min and max values if necessary */
-	if (k.xmin > DISP_MAX_X_SIZE - 1)
-		k.xmin = DISP_MAX_X_SIZE - 1;
-	if (k.ymin > DISP_MAX_Y_SIZE - 1)
-		k.ymin = DISP_MAX_Y_SIZE - 1;
-
-	if (k.xmax > DISP_MAX_X_SIZE - 1)
-		k.xmax = DISP_MAX_X_SIZE - 1;
-	if (k.ymax > DISP_MAX_Y_SIZE - 1)
-		k.ymax = DISP_MAX_Y_SIZE - 1;
-
-	k.xmirror = 0;
-	k.ymirror = 0;
-	k.rotate = 0;
-	k.minadr = (u32) frame_buffer;
-	k.maxadr = (u32) frame_buffer + (((w - 1) << 10) | ((h << 2) - 2));
-	k.pad = PAD_1024;
-	k.dirtybuffer = (u32) dirty_buffer;
-	k.format = RGB888;
-	k.hwdirty = 0;
-	k.slave_trans = 0;
-
-	ret = dum_ch_setup(ch_no, &k);
-
-	return ret;
-}
-
-static void lcd_reset(void)
-{
-	u32 *dum_pio_base = (u32 *)IO_ADDRESS(PNX4008_PIO_BASE);
-
-	udelay(1);
-	iowrite32(BIT(19), &dum_pio_base[2]);
-	udelay(1);
-	iowrite32(BIT(19), &dum_pio_base[1]);
-	udelay(1);
-}
-
-static int dum_init(struct platform_device *pdev)
-{
-	struct clk *clk;
-
-	/* enable DUM clock */
-	clk = clk_get(&pdev->dev, "dum_ck");
-	if (IS_ERR(clk)) {
-		printk(KERN_ERR "pnx4008_dum: Unable to access DUM clock\n");
-		return PTR_ERR(clk);
-	}
-
-	clk_set_rate(clk, 1);
-	clk_put(clk);
-
-	DUM_CTRL = V_DUM_RESET;
-
-	/* set priority to "round-robin". All other params to "false" */
-	DUM_CONF = BIT(9);
-
-	/* Display 1 */
-	DUM_WTCFG1 = PNX4008_DUM_WT_CFG;
-	DUM_RTCFG1 = PNX4008_DUM_RT_CFG;
-	DUM_TCFG = PNX4008_DUM_T_CFG;
-
-	return 0;
-}
-
-static void dum_chan_init(void)
-{
-	int i = 0, ch = 0;
-	u32 *cmdptrs;
-	u32 *cmdstrings;
-
-	DUM_COM_BASE =
-		CMDSTRING_BASEADDR + BYTES_PER_CMDSTRING * NR_OF_CMDSTRINGS;
-
-	if ((cmdptrs =
-	     (u32 *) ioremap_nocache(DUM_COM_BASE,
-				     sizeof(u32) * NR_OF_CMDSTRINGS)) == NULL)
-		return;
-
-	for (ch = 0; ch < NR_OF_CMDSTRINGS; ch++)
-		iowrite32(CMDSTRING_BASEADDR + BYTES_PER_CMDSTRING * ch,
-			  cmdptrs + ch);
-
-	for (ch = 0; ch < MAX_DUM_CHANNELS; ch++)
-		clear_channel(ch);
-
-	/* Clear the cmdstrings */
-	cmdstrings =
-	    (u32 *)ioremap_nocache(*cmdptrs,
-				   BYTES_PER_CMDSTRING * NR_OF_CMDSTRINGS);
-
-	if (!cmdstrings)
-		goto out;
-
-	for (i = 0; i < NR_OF_CMDSTRINGS * BYTES_PER_CMDSTRING / sizeof(u32);
-	     i++)
-		iowrite32(0, cmdstrings + i);
-
-	iounmap((u32 *)cmdstrings);
-
-out:
-	iounmap((u32 *)cmdptrs);
-}
-
-static void lcd_init(void)
-{
-	lcd_reset();
-
-	DUM_OUTP_FORMAT1 = 0; /* RGB666 */
-
-	udelay(1);
-	iowrite32(V_LCD_STANDBY_OFF, dum_data.slave_virt_base);
-	udelay(1);
-	iowrite32(V_LCD_USE_9BIT_BUS, dum_data.slave_virt_base);
-	udelay(1);
-	iowrite32(V_LCD_SYNC_RISE_L, dum_data.slave_virt_base);
-	udelay(1);
-	iowrite32(V_LCD_SYNC_RISE_H, dum_data.slave_virt_base);
-	udelay(1);
-	iowrite32(V_LCD_SYNC_FALL_L, dum_data.slave_virt_base);
-	udelay(1);
-	iowrite32(V_LCD_SYNC_FALL_H, dum_data.slave_virt_base);
-	udelay(1);
-	iowrite32(V_LCD_SYNC_ENABLE, dum_data.slave_virt_base);
-	udelay(1);
-	iowrite32(V_LCD_DISPLAY_ON, dum_data.slave_virt_base);
-	udelay(1);
-}
-
-/* Interface exported to framebuffer drivers */
-
-int pnx4008_get_fb_addresses(int fb_type, void **virt_addr,
-			     dma_addr_t *phys_addr, int *fb_length)
-{
-	int i;
-	int ret = -1;
-	for (i = 0; i < ARRAY_SIZE(fb_addr); i++)
-		if (fb_addr[i].fb_type == fb_type) {
-			*virt_addr = (void *)(dum_data.lcd_virt_start +
-					fb_addr[i].addr_offset);
-			*phys_addr =
-			    dum_data.lcd_phys_start + fb_addr[i].addr_offset;
-			*fb_length = fb_addr[i].fb_length;
-			ret = 0;
-			break;
-		}
-
-	return ret;
-}
-
-EXPORT_SYMBOL(pnx4008_get_fb_addresses);
-
-int pnx4008_alloc_dum_channel(int dev_id)
-{
-	int i = 0;
-
-	while ((i < MAX_DUM_CHANNELS) && (dum_data.fb_owning_channel[i] != -1))
-		i++;
-
-	if (i == MAX_DUM_CHANNELS)
-		return -ENORESOURCESLEFT;
-	else {
-		dum_data.fb_owning_channel[i] = dev_id;
-		return i;
-	}
-}
-
-EXPORT_SYMBOL(pnx4008_alloc_dum_channel);
-
-int pnx4008_free_dum_channel(int channr, int dev_id)
-{
-	if (channr < 0 || channr > MAX_DUM_CHANNELS)
-		return -EINVAL;
-	else if (dum_data.fb_owning_channel[channr] != dev_id)
-		return -EFBNOTOWNER;
-	else {
-		clear_channel(channr);
-		dum_data.fb_owning_channel[channr] = -1;
-	}
-
-	return 0;
-}
-
-EXPORT_SYMBOL(pnx4008_free_dum_channel);
-
-int pnx4008_put_dum_channel_uf(struct dumchannel_uf chan_uf, int dev_id)
-{
-	int i = chan_uf.channelnr;
-	int ret;
-
-	if (i < 0 || i > MAX_DUM_CHANNELS)
-		return -EINVAL;
-	else if (dum_data.fb_owning_channel[i] != dev_id)
-		return -EFBNOTOWNER;
-	else if ((ret =
-		  display_open(chan_uf.channelnr, 0, chan_uf.dirty,
-			       chan_uf.source, chan_uf.y_offset,
-			       chan_uf.x_offset, chan_uf.height,
-			       chan_uf.width)) != 0)
-		return ret;
-	else {
-		dum_data.chan_uf_store[i].dirty = chan_uf.dirty;
-		dum_data.chan_uf_store[i].source = chan_uf.source;
-		dum_data.chan_uf_store[i].x_offset = chan_uf.x_offset;
-		dum_data.chan_uf_store[i].y_offset = chan_uf.y_offset;
-		dum_data.chan_uf_store[i].width = chan_uf.width;
-		dum_data.chan_uf_store[i].height = chan_uf.height;
-	}
-
-	return 0;
-}
-
-EXPORT_SYMBOL(pnx4008_put_dum_channel_uf);
-
-int pnx4008_set_dum_channel_sync(int channr, int val, int dev_id)
-{
-	if (channr < 0 || channr > MAX_DUM_CHANNELS)
-		return -EINVAL;
-	else if (dum_data.fb_owning_channel[channr] != dev_id)
-		return -EFBNOTOWNER;
-	else {
-		if (val == CONF_SYNC_ON) {
-			DUM_CH_CONF(channr) |= CONF_SYNCENABLE;
-			DUM_CH_CONF(channr) |= DUM_CHANNEL_CFG_SYNC_MASK |
-				DUM_CHANNEL_CFG_SYNC_MASK_SET;
-		} else if (val == CONF_SYNC_OFF)
-			DUM_CH_CONF(channr) &= ~CONF_SYNCENABLE;
-		else
-			return -EINVAL;
-	}
-
-	return 0;
-}
-
-EXPORT_SYMBOL(pnx4008_set_dum_channel_sync);
-
-int pnx4008_set_dum_channel_dirty_detect(int channr, int val, int dev_id)
-{
-	if (channr < 0 || channr > MAX_DUM_CHANNELS)
-		return -EINVAL;
-	else if (dum_data.fb_owning_channel[channr] != dev_id)
-		return -EFBNOTOWNER;
-	else {
-		if (val == CONF_DIRTYDETECTION_ON)
-			DUM_CH_CONF(channr) |= CONF_DIRTYENABLE;
-		else if (val == CONF_DIRTYDETECTION_OFF)
-			DUM_CH_CONF(channr) &= ~CONF_DIRTYENABLE;
-		else
-			return -EINVAL;
-	}
-
-	return 0;
-}
-
-EXPORT_SYMBOL(pnx4008_set_dum_channel_dirty_detect);
-
-#if 0 /* Functions not used currently, but likely to be used in future */
-
-static int get_channel(struct dumchannel *p_chan)
-{
-	int i = p_chan->channelnr;
-
-	if (i < 0 || i > MAX_DUM_CHANNELS)
-		return -EINVAL;
-	else {
-		p_chan->dum_ch_min = DUM_CH_MIN(i);
-		p_chan->dum_ch_max = DUM_CH_MAX(i);
-		p_chan->dum_ch_conf = DUM_CH_CONF(i);
-		p_chan->dum_ch_stat = DUM_CH_STAT(i);
-		p_chan->dum_ch_ctrl = 0;	/* WriteOnly control register */
-	}
-
-	return 0;
-}
-
-int pnx4008_get_dum_channel_uf(struct dumchannel_uf *p_chan_uf, int dev_id)
-{
-	int i = p_chan_uf->channelnr;
-
-	if (i < 0 || i > MAX_DUM_CHANNELS)
-		return -EINVAL;
-	else if (dum_data.fb_owning_channel[i] != dev_id)
-		return -EFBNOTOWNER;
-	else {
-		p_chan_uf->dirty = dum_data.chan_uf_store[i].dirty;
-		p_chan_uf->source = dum_data.chan_uf_store[i].source;
-		p_chan_uf->x_offset = dum_data.chan_uf_store[i].x_offset;
-		p_chan_uf->y_offset = dum_data.chan_uf_store[i].y_offset;
-		p_chan_uf->width = dum_data.chan_uf_store[i].width;
-		p_chan_uf->height = dum_data.chan_uf_store[i].height;
-	}
-
-	return 0;
-}
-
-EXPORT_SYMBOL(pnx4008_get_dum_channel_uf);
-
-int pnx4008_get_dum_channel_config(int channr, int dev_id)
-{
-	int ret;
-	struct dumchannel chan;
-
-	if (channr < 0 || channr > MAX_DUM_CHANNELS)
-		return -EINVAL;
-	else if (dum_data.fb_owning_channel[channr] != dev_id)
-		return -EFBNOTOWNER;
-	else {
-		chan.channelnr = channr;
-		if ((ret = get_channel(&chan)) != 0)
-			return ret;
-	}
-
-	return (chan.dum_ch_conf & DUM_CHANNEL_CFG_MASK);
-}
-
-EXPORT_SYMBOL(pnx4008_get_dum_channel_config);
-
-int pnx4008_force_update_dum_channel(int channr, int dev_id)
-{
-	if (channr < 0 || channr > MAX_DUM_CHANNELS)
-		return -EINVAL;
-
-	else if (dum_data.fb_owning_channel[channr] != dev_id)
-		return -EFBNOTOWNER;
-	else
-		DUM_CH_CTRL(channr) = CTRL_SETDIRTY;
-
-	return 0;
-}
-
-EXPORT_SYMBOL(pnx4008_force_update_dum_channel);
-
-#endif
-
-int pnx4008_sdum_mmap(struct fb_info *info, struct vm_area_struct *vma,
-		      struct device *dev)
-{
-	unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
-
-	if (off < info->fix.smem_len) {
-		vma->vm_pgoff += 1;
-		return dma_mmap_writecombine(dev, vma,
-				(void *)dum_data.lcd_virt_start,
-				dum_data.lcd_phys_start,
-				FB_DMA_SIZE);
-	}
-	return -EINVAL;
-}
-
-EXPORT_SYMBOL(pnx4008_sdum_mmap);
-
-int pnx4008_set_dum_exit_notification(int dev_id)
-{
-	int i;
-
-	for (i = 0; i < MAX_DUM_CHANNELS; i++)
-		if (dum_data.fb_owning_channel[i] == dev_id)
-			return -ERESOURCESNOTFREED;
-
-	return 0;
-}
-
-EXPORT_SYMBOL(pnx4008_set_dum_exit_notification);
-
-/* Platform device driver for DUM */
-
-static int sdum_suspend(struct platform_device *pdev, pm_message_t state)
-{
-	int retval = 0;
-	struct clk *clk;
-
-	clk = clk_get(0, "dum_ck");
-	if (!IS_ERR(clk)) {
-		clk_set_rate(clk, 0);
-		clk_put(clk);
-	} else
-		retval = PTR_ERR(clk);
-
-	/* disable BAC */
-	DUM_CTRL = V_BAC_DISABLE_IDLE;
-
-	/* LCD standby & turn off display */
-	lcd_reset();
-
-	return retval;
-}
-
-static int sdum_resume(struct platform_device *pdev)
-{
-	int retval = 0;
-	struct clk *clk;
-
-	clk = clk_get(0, "dum_ck");
-	if (!IS_ERR(clk)) {
-		clk_set_rate(clk, 1);
-		clk_put(clk);
-	} else
-		retval = PTR_ERR(clk);
-
-	/* wait for BAC disable */
-	DUM_CTRL = V_BAC_DISABLE_TRIG;
-
-	while (DUM_CTRL & BAC_ENABLED)
-		udelay(10);
-
-	/* re-init LCD */
-	lcd_init();
-
-	/* enable BAC and reset MUX */
-	DUM_CTRL = V_BAC_ENABLE;
-	udelay(1);
-	DUM_CTRL = V_MUX_RESET;
-	return 0;
-}
-
-static int __devinit sdum_probe(struct platform_device *pdev)
-{
-	int ret = 0, i = 0;
-
-	/* map frame buffer */
-	dum_data.lcd_virt_start = (u32) dma_alloc_writecombine(&pdev->dev,
-						       FB_DMA_SIZE,
-						       &dum_data.lcd_phys_start,
-						       GFP_KERNEL);
-
-	if (!dum_data.lcd_virt_start) {
-		ret = -ENOMEM;
-		goto out_3;
-	}
-
-	/* map slave registers */
-	dum_data.slave_phys_base = PNX4008_DUM_SLAVE_BASE;
-	dum_data.slave_virt_base =
-	    (u32 *) ioremap_nocache(dum_data.slave_phys_base, sizeof(u32));
-
-	if (dum_data.slave_virt_base == NULL) {
-		ret = -ENOMEM;
-		goto out_2;
-	}
-
-	/* initialize DUM and LCD display */
-	ret = dum_init(pdev);
-	if (ret)
-		goto out_1;
-
-	dum_chan_init();
-	lcd_init();
-
-	DUM_CTRL = V_BAC_ENABLE;
-	udelay(1);
-	DUM_CTRL = V_MUX_RESET;
-
-	/* set decode address and sync clock divider */
-	DUM_DECODE = dum_data.lcd_phys_start & DUM_DECODE_MASK;
-	DUM_CLK_DIV = PNX4008_DUM_CLK_DIV;
-
-	for (i = 0; i < MAX_DUM_CHANNELS; i++)
-		dum_data.fb_owning_channel[i] = -1;
-
-	/*setup wakeup interrupt */
-	start_int_set_rising_edge(SE_DISP_SYNC_INT);
-	start_int_ack(SE_DISP_SYNC_INT);
-	start_int_umask(SE_DISP_SYNC_INT);
-
-	return 0;
-
-out_1:
-	iounmap((void *)dum_data.slave_virt_base);
-out_2:
-	dma_free_writecombine(&pdev->dev, FB_DMA_SIZE,
-			(void *)dum_data.lcd_virt_start,
-			dum_data.lcd_phys_start);
-out_3:
-	return ret;
-}
-
-static int sdum_remove(struct platform_device *pdev)
-{
-	struct clk *clk;
-
-	start_int_mask(SE_DISP_SYNC_INT);
-
-	clk = clk_get(0, "dum_ck");
-	if (!IS_ERR(clk)) {
-		clk_set_rate(clk, 0);
-		clk_put(clk);
-	}
-
-	iounmap((void *)dum_data.slave_virt_base);
-
-	dma_free_writecombine(&pdev->dev, FB_DMA_SIZE,
-			(void *)dum_data.lcd_virt_start,
-			dum_data.lcd_phys_start);
-
-	return 0;
-}
-
-static struct platform_driver sdum_driver = {
-	.driver = {
-		.name = "pnx4008-sdum",
-	},
-	.probe = sdum_probe,
-	.remove = sdum_remove,
-	.suspend = sdum_suspend,
-	.resume = sdum_resume,
-};
-
-module_platform_driver(sdum_driver);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/video/pnx4008/sdum.h b/drivers/video/pnx4008/sdum.h
deleted file mode 100644
index 189c3d6..0000000
--- a/drivers/video/pnx4008/sdum.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2005 Philips Semiconductors
- *
- * 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, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.  If not, write to
- * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA, or http://www.gnu.org/licenses/gpl.html
-*/
-
-#define MAX_DUM_CHANNELS	64
-
-#define RGB_MEM_WINDOW(x) (0x10000000 + (x)*0x00100000)
-
-#define QCIF_OFFSET(x) (((x) == 0) ? 0x00000: ((x) == 1) ? 0x30000: -1)
-#define CIF_OFFSET(x)  (((x) == 0) ? 0x00000: ((x) == 1) ? 0x60000: -1)
-
-#define CTRL_SETDIRTY	 	(0x00000001)
-#define CONF_DIRTYENABLE	(0x00000020)
-#define CONF_SYNCENABLE		(0x00000004)
-
-#define DIRTY_ENABLED(conf)	((conf) & 0x0020)
-#define SYNC_ENABLED(conf) 	((conf) & 0x0004)
-
-/* Display 1 & 2 Write Timing Configuration */
-#define PNX4008_DUM_WT_CFG		0x00372000
-
-/* Display 1 & 2 Read Timing Configuration */
-#define PNX4008_DUM_RT_CFG		0x00003A47
-
-/* DUM Transit State Timing Configuration */
-#define PNX4008_DUM_T_CFG		0x1D	/* 29 HCLK cycles */
-
-/* DUM Sync count clock divider */
-#define PNX4008_DUM_CLK_DIV		0x02DD
-
-/* Memory size for framebuffer, allocated through dma_alloc_writecombine().
- * Must be PAGE aligned
- */
-#define FB_DMA_SIZE (PAGE_ALIGN(SZ_1M + PAGE_SIZE))
-
-#define OFFSET_RGBBUFFER (0xB0000)
-#define OFFSET_YUVBUFFER (0x00000)
-
-#define YUVBUFFER (lcd_video_start + OFFSET_YUVBUFFER)
-#define RGBBUFFER (lcd_video_start + OFFSET_RGBBUFFER)
-
-#define CMDSTRING_BASEADDR	(0x00C000)	/* iram */
-#define BYTES_PER_CMDSTRING	(0x80)
-#define NR_OF_CMDSTRINGS	(64)
-
-#define MAX_NR_PRESTRINGS (0x40)
-#define MAX_NR_POSTSTRINGS (0x40)
-
-/* various mask definitions */
-#define DUM_CLK_ENABLE 0x01
-#define DUM_CLK_DISABLE 0
-#define DUM_DECODE_MASK 0x1FFFFFFF
-#define DUM_CHANNEL_CFG_MASK 0x01FF
-#define DUM_CHANNEL_CFG_SYNC_MASK 0xFFFE00FF
-#define DUM_CHANNEL_CFG_SYNC_MASK_SET 0x0CA00
-
-#define SDUM_RETURNVAL_BASE (0x500)
-
-#define CONF_SYNC_OFF		(0x602)
-#define CONF_SYNC_ON		(0x603)
-
-#define CONF_DIRTYDETECTION_OFF	(0x600)
-#define CONF_DIRTYDETECTION_ON	(0x601)
-
-struct dumchannel_uf {
-	int channelnr;
-	u32 *dirty;
-	u32 *source;
-	u32 x_offset;
-	u32 y_offset;
-	u32 width;
-	u32 height;
-};
-
-enum {
-	FB_TYPE_YUV,
-	FB_TYPE_RGB
-};
-
-struct cmdstring {
-	int channelnr;
-	uint16_t prestringlen;
-	uint16_t poststringlen;
-	uint16_t format;
-	uint16_t reserved;
-	uint16_t startaddr_low;
-	uint16_t startaddr_high;
-	uint16_t pixdatlen_low;
-	uint16_t pixdatlen_high;
-	u32 precmd[MAX_NR_PRESTRINGS];
-	u32 postcmd[MAX_NR_POSTSTRINGS];
-
-};
-
-struct dumchannel {
-	int channelnr;
-	int dum_ch_min;
-	int dum_ch_max;
-	int dum_ch_conf;
-	int dum_ch_stat;
-	int dum_ch_ctrl;
-};
-
-int pnx4008_alloc_dum_channel(int dev_id);
-int pnx4008_free_dum_channel(int channr, int dev_id);
-
-int pnx4008_get_dum_channel_uf(struct dumchannel_uf *pChan_uf, int dev_id);
-int pnx4008_put_dum_channel_uf(struct dumchannel_uf chan_uf, int dev_id);
-
-int pnx4008_set_dum_channel_sync(int channr, int val, int dev_id);
-int pnx4008_set_dum_channel_dirty_detect(int channr, int val, int dev_id);
-
-int pnx4008_force_dum_update_channel(int channr, int dev_id);
-
-int pnx4008_get_dum_channel_config(int channr, int dev_id);
-
-int pnx4008_sdum_mmap(struct fb_info *info, struct vm_area_struct *vma, struct device *dev);
-int pnx4008_set_dum_exit_notification(int dev_id);
-
-int pnx4008_get_fb_addresses(int fb_type, void **virt_addr,
-			     dma_addr_t * phys_addr, int *fb_length);
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index 4e292f2..0b340d6 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -1034,6 +1034,7 @@
 	if (status) {
 		dev_err(&dev->core, "%s: lv1_gpu_memory_allocate failed: %d\n",
 			__func__, status);
+		retval = -ENOMEM;
 		goto err_close_device;
 	}
 	dev_dbg(&dev->core, "ddr:lpar:0x%llx\n", ddr_lpar);
@@ -1046,6 +1047,7 @@
 		dev_err(&dev->core,
 			"%s: lv1_gpu_context_allocate failed: %d\n", __func__,
 			status);
+		retval = -ENOMEM;
 		goto err_gpu_memory_free;
 	}
 
@@ -1053,6 +1055,7 @@
 	dinfo = (void __force *)ioremap(lpar_driver_info, 128 * 1024);
 	if (!dinfo) {
 		dev_err(&dev->core, "%s: ioremap failed\n", __func__);
+		retval = -ENOMEM;
 		goto err_gpu_context_free;
 	}
 
@@ -1121,8 +1124,10 @@
 	}
 
 	info = framebuffer_alloc(sizeof(struct ps3fb_par), &dev->core);
-	if (!info)
+	if (!info) {
+		retval = -ENOMEM;
 		goto err_context_fb_close;
+	}
 
 	par = info->par;
 	par->mode_id = ~ps3fb_mode;	/* != ps3fb_mode, to trigger change */
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 69bf9d0..2ed7b63 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -25,8 +25,8 @@
 #include <linux/interrupt.h>
 #include <linux/pm_runtime.h>
 
+#include <video/samsung_fimd.h>
 #include <mach/map.h>
-#include <plat/regs-fb-v4.h>
 #include <plat/fb.h>
 
 /* This driver will export a number of framebuffer interfaces depending
@@ -1398,35 +1398,28 @@
 
 	spin_lock_init(&sfb->slock);
 
-	sfb->bus_clk = clk_get(dev, "lcd");
+	sfb->bus_clk = devm_clk_get(dev, "lcd");
 	if (IS_ERR(sfb->bus_clk)) {
 		dev_err(dev, "failed to get bus clock\n");
-		ret = PTR_ERR(sfb->bus_clk);
-		goto err_sfb;
+		return PTR_ERR(sfb->bus_clk);
 	}
 
-	clk_enable(sfb->bus_clk);
+	clk_prepare_enable(sfb->bus_clk);
 
 	if (!sfb->variant.has_clksel) {
-		sfb->lcd_clk = clk_get(dev, "sclk_fimd");
+		sfb->lcd_clk = devm_clk_get(dev, "sclk_fimd");
 		if (IS_ERR(sfb->lcd_clk)) {
 			dev_err(dev, "failed to get lcd clock\n");
 			ret = PTR_ERR(sfb->lcd_clk);
 			goto err_bus_clk;
 		}
 
-		clk_enable(sfb->lcd_clk);
+		clk_prepare_enable(sfb->lcd_clk);
 	}
 
 	pm_runtime_enable(sfb->dev);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res) {
-		dev_err(dev, "failed to find registers\n");
-		ret = -ENOENT;
-		goto err_lcd_clk;
-	}
-
 	sfb->regs = devm_request_and_ioremap(dev, res);
 	if (!sfb->regs) {
 		dev_err(dev, "failed to map registers\n");
@@ -1510,16 +1503,12 @@
 err_lcd_clk:
 	pm_runtime_disable(sfb->dev);
 
-	if (!sfb->variant.has_clksel) {
-		clk_disable(sfb->lcd_clk);
-		clk_put(sfb->lcd_clk);
-	}
+	if (!sfb->variant.has_clksel)
+		clk_disable_unprepare(sfb->lcd_clk);
 
 err_bus_clk:
-	clk_disable(sfb->bus_clk);
-	clk_put(sfb->bus_clk);
+	clk_disable_unprepare(sfb->bus_clk);
 
-err_sfb:
 	return ret;
 }
 
@@ -1541,13 +1530,10 @@
 		if (sfb->windows[win])
 			s3c_fb_release_win(sfb, sfb->windows[win]);
 
-	if (!sfb->variant.has_clksel) {
-		clk_disable(sfb->lcd_clk);
-		clk_put(sfb->lcd_clk);
-	}
+	if (!sfb->variant.has_clksel)
+		clk_disable_unprepare(sfb->lcd_clk);
 
-	clk_disable(sfb->bus_clk);
-	clk_put(sfb->bus_clk);
+	clk_disable_unprepare(sfb->bus_clk);
 
 	pm_runtime_put_sync(sfb->dev);
 	pm_runtime_disable(sfb->dev);
@@ -1575,9 +1561,9 @@
 	}
 
 	if (!sfb->variant.has_clksel)
-		clk_disable(sfb->lcd_clk);
+		clk_disable_unprepare(sfb->lcd_clk);
 
-	clk_disable(sfb->bus_clk);
+	clk_disable_unprepare(sfb->bus_clk);
 
 	pm_runtime_put_sync(sfb->dev);
 
@@ -1595,10 +1581,10 @@
 
 	pm_runtime_get_sync(sfb->dev);
 
-	clk_enable(sfb->bus_clk);
+	clk_prepare_enable(sfb->bus_clk);
 
 	if (!sfb->variant.has_clksel)
-		clk_enable(sfb->lcd_clk);
+		clk_prepare_enable(sfb->lcd_clk);
 
 	/* setup gpio and output polarity controls */
 	pd->setup_gpio();
@@ -1654,9 +1640,9 @@
 	struct s3c_fb *sfb = platform_get_drvdata(pdev);
 
 	if (!sfb->variant.has_clksel)
-		clk_disable(sfb->lcd_clk);
+		clk_disable_unprepare(sfb->lcd_clk);
 
-	clk_disable(sfb->bus_clk);
+	clk_disable_unprepare(sfb->bus_clk);
 
 	return 0;
 }
@@ -1667,10 +1653,10 @@
 	struct s3c_fb *sfb = platform_get_drvdata(pdev);
 	struct s3c_fb_platdata *pd = sfb->pdata;
 
-	clk_enable(sfb->bus_clk);
+	clk_prepare_enable(sfb->bus_clk);
 
 	if (!sfb->variant.has_clksel)
-		clk_enable(sfb->lcd_clk);
+		clk_prepare_enable(sfb->lcd_clk);
 
 	/* setup gpio and output polarity controls */
 	pd->setup_gpio();
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index 77f34c6..1083bb9 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -11,6 +11,8 @@
  * Driver based on skeletonfb.c, sa1100fb.c and others.
 */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/err.h>
@@ -48,7 +50,11 @@
 static int debug;
 #endif
 
-#define dprintk(msg...)	if (debug) printk(KERN_DEBUG "s3c2410fb: " msg);
+#define dprintk(msg...) \
+do { \
+	if (debug) \
+		pr_debug(msg); \
+} while (0)
 
 /* useful functions */
 
@@ -598,11 +604,11 @@
 	if (strnicmp(buf, "on", 2) == 0 ||
 	    strnicmp(buf, "1", 1) == 0) {
 		debug = 1;
-		printk(KERN_DEBUG "s3c2410fb: Debug On");
+		dev_dbg(dev, "s3c2410fb: Debug On");
 	} else if (strnicmp(buf, "off", 3) == 0 ||
 		   strnicmp(buf, "0", 1) == 0) {
 		debug = 0;
-		printk(KERN_DEBUG "s3c2410fb: Debug Off");
+		dev_dbg(dev, "s3c2410fb: Debug Off");
 	} else {
 		return -EINVAL;
 	}
@@ -921,7 +927,7 @@
 
 	info->clk = clk_get(NULL, "lcd");
 	if (IS_ERR(info->clk)) {
-		printk(KERN_ERR "failed to get lcd clock source\n");
+		dev_err(&pdev->dev, "failed to get lcd clock source\n");
 		ret = PTR_ERR(info->clk);
 		goto release_irq;
 	}
@@ -929,7 +935,7 @@
 	clk_enable(info->clk);
 	dprintk("got and enabled clock\n");
 
-	usleep_range(1000, 1000);
+	usleep_range(1000, 1100);
 
 	info->clk_rate = clk_get_rate(info->clk);
 
@@ -947,7 +953,7 @@
 	/* Initialize video memory */
 	ret = s3c2410fb_map_video_memory(fbinfo);
 	if (ret) {
-		printk(KERN_ERR "Failed to allocate video RAM: %d\n", ret);
+		dev_err(&pdev->dev, "Failed to allocate video RAM: %d\n", ret);
 		ret = -ENOMEM;
 		goto release_clock;
 	}
@@ -970,7 +976,7 @@
 
 	ret = register_framebuffer(fbinfo);
 	if (ret < 0) {
-		printk(KERN_ERR "Failed to register framebuffer device: %d\n",
+		dev_err(&pdev->dev, "Failed to register framebuffer device: %d\n",
 			ret);
 		goto free_cpufreq;
 	}
@@ -978,9 +984,9 @@
 	/* create device files */
 	ret = device_create_file(&pdev->dev, &dev_attr_debug);
 	if (ret)
-		printk(KERN_ERR "failed to add debug attribute\n");
+		dev_err(&pdev->dev, "failed to add debug attribute\n");
 
-	printk(KERN_INFO "fb%d: %s frame buffer device\n",
+	dev_info(&pdev->dev, "fb%d: %s frame buffer device\n",
 		fbinfo->node, fbinfo->fix.id);
 
 	return 0;
@@ -1028,7 +1034,7 @@
 	s3c2410fb_cpufreq_deregister(info);
 
 	s3c2410fb_lcd_enable(info, 0);
-	usleep_range(1000, 1000);
+	usleep_range(1000, 1100);
 
 	s3c2410fb_unmap_video_memory(fbinfo);
 
@@ -1065,7 +1071,7 @@
 	 * the LCD DMA engine is not going to get back on the bus
 	 * before the clock goes off again (bjd) */
 
-	usleep_range(1000, 1000);
+	usleep_range(1000, 1100);
 	clk_disable(info->clk);
 
 	return 0;
@@ -1077,7 +1083,7 @@
 	struct s3c2410fb_info *info = fbinfo->par;
 
 	clk_enable(info->clk);
-	usleep_range(1000, 1000);
+	usleep_range(1000, 1100);
 
 	s3c2410fb_init_registers(fbinfo);
 
@@ -1134,8 +1140,8 @@
 module_init(s3c2410fb_init);
 module_exit(s3c2410fb_cleanup);
 
-MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>, "
-	      "Ben Dooks <ben-linux@fluff.org>");
+MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
+MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>");
 MODULE_DESCRIPTION("Framebuffer driver for the s3c2410");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:s3c2410-lcd");
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index 0d0f52c..f4f53b0 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -2266,8 +2266,10 @@
 	lpitch = info->var.xres_virtual*((info->var.bits_per_pixel + 7) >> 3);
 	info->var.yres_virtual = info->fix.smem_len/lpitch;
 
-	if (info->var.yres_virtual < info->var.yres)
+	if (info->var.yres_virtual < info->var.yres) {
+		err = -ENOMEM;
 		goto failed;
+	}
 
 #if defined(CONFIG_FB_SAVAGE_ACCEL)
 	/*
diff --git a/drivers/video/sbuslib.c b/drivers/video/sbuslib.c
index 3c1de98..296afae 100644
--- a/drivers/video/sbuslib.c
+++ b/drivers/video/sbuslib.c
@@ -57,9 +57,8 @@
 
 	off = vma->vm_pgoff << PAGE_SHIFT;
 
-	/* To stop the swapper from even considering these pages */
-	vma->vm_flags |= (VM_IO | VM_RESERVED);
-	
+	/* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
+
 	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 
 	/* Each page, see which map applies */
diff --git a/drivers/video/sis/initextlfb.c b/drivers/video/sis/initextlfb.c
index 9dec64d..3ab18f5 100644
--- a/drivers/video/sis/initextlfb.c
+++ b/drivers/video/sis/initextlfb.c
@@ -65,7 +65,7 @@
     }
 #endif
 
-    if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) {;
+    if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) {
        printk(KERN_ERR "Could not find mode %x\n", ModeNo);
        return 65000;
     }
diff --git a/drivers/video/smscufx.c b/drivers/video/smscufx.c
index 5533a32..97bd662 100644
--- a/drivers/video/smscufx.c
+++ b/drivers/video/smscufx.c
@@ -803,7 +803,6 @@
 			size = 0;
 	}
 
-	vma->vm_flags |= VM_RESERVED;	/* avoid to swap out this VMA */
 	return 0;
 }
 
diff --git a/drivers/video/sunxvr1000.c b/drivers/video/sunxvr1000.c
index b7f27ac..729a507 100644
--- a/drivers/video/sunxvr1000.c
+++ b/drivers/video/sunxvr1000.c
@@ -141,8 +141,10 @@
 
 	gp->fb_base = of_ioremap(&op->resource[6], 0,
 				 gp->fb_size, "gfb fb");
-	if (!gp->fb_base)
+	if (!gp->fb_base) {
+		err = -ENOMEM;
 		goto err_release_fb;
+	}
 
 	err = gfb_set_fbinfo(gp);
 	if (err)
diff --git a/drivers/video/sunxvr2500.c b/drivers/video/sunxvr2500.c
index 5848436..7fbcba8 100644
--- a/drivers/video/sunxvr2500.c
+++ b/drivers/video/sunxvr2500.c
@@ -181,8 +181,10 @@
 	sp->fb_size = info->fix.line_length * sp->height;
 
 	sp->fb_base = ioremap(sp->fb_base_phys, sp->fb_size);
-	if (!sp->fb_base)
+	if (!sp->fb_base) {
+		err = -ENOMEM;
 		goto err_release_pci;
+	}
 
 	err = s3d_set_fbinfo(sp);
 	if (err)
diff --git a/drivers/video/sunxvr500.c b/drivers/video/sunxvr500.c
index eb931b8..6c71b1b 100644
--- a/drivers/video/sunxvr500.c
+++ b/drivers/video/sunxvr500.c
@@ -298,8 +298,10 @@
 		goto err_release_fb;
 	}
 	ep->ramdac = ioremap(ep->regs_base_phys + 0x8000, 0x1000);
-	if (!ep->ramdac)
+	if (!ep->ramdac) {
+		err = -ENOMEM;
 		goto err_release_pci1;
+	}
 
 	ep->fb8_0_off = readl(ep->ramdac + RAMDAC_VID_8FB_0);
 	ep->fb8_0_off -= ep->fb_base_reg;
@@ -343,8 +345,10 @@
 	ep->fb_size = info->fix.line_length * ep->height;
 
 	ep->fb_base = ioremap(ep->fb_base_phys, ep->fb_size);
-	if (!ep->fb_base)
+	if (!ep->fb_base) {
+		err = -ENOMEM;
 		goto err_release_pci0;
+	}
 
 	err = e3d_set_fbinfo(ep);
 	if (err)
diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c
index 8af6414..86d449e 100644
--- a/drivers/video/udlfb.c
+++ b/drivers/video/udlfb.c
@@ -345,7 +345,6 @@
 			size = 0;
 	}
 
-	vma->vm_flags |= VM_RESERVED;	/* avoid to swap out this VMA */
 	return 0;
 }
 
@@ -647,7 +646,7 @@
 	result = fb_sys_write(info, buf, count, ppos);
 
 	if (result > 0) {
-		int start = max((int)(offset / info->fix.line_length) - 1, 0);
+		int start = max((int)(offset / info->fix.line_length), 0);
 		int lines = min((u32)((result / info->fix.line_length) + 1),
 				(u32)info->var.yres);
 
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index b0e2a42..2f8f82d 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -659,6 +659,8 @@
 	task->t.flags = TF_BUF_RET | TF_BUF_ESDI;
 	task->t.buf_len = EDID_LENGTH;
 	task->buf = kzalloc(EDID_LENGTH, GFP_KERNEL);
+	if (!task->buf)
+		return -ENOMEM;
 
 	err = uvesafb_exec(task);
 
diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/vermilion/vermilion.c
index 970e43d..4709edc 100644
--- a/drivers/video/vermilion/vermilion.c
+++ b/drivers/video/vermilion/vermilion.c
@@ -1018,7 +1018,6 @@
 	offset += vinfo->vram_start;
 	pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
 	pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
-	vma->vm_flags |= VM_RESERVED | VM_IO;
 	if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT,
 						size, vma->vm_page_prot))
 		return -EAGAIN;
@@ -1168,8 +1167,7 @@
 	list_for_each_entry_safe(entry, next, &global_has_mode, head) {
 		printk(KERN_DEBUG MODULE_NAME ": subsys disable pipe\n");
 		vmlfb_disable_pipe(entry);
-		list_del(&entry->head);
-		list_add_tail(&entry->head, &global_no_mode);
+		list_move_tail(&entry->head, &global_no_mode);
 	}
 	mutex_unlock(&vml_mutex);
 }
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index 501a922..c7f69252 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -439,7 +439,6 @@
 			size = 0;
 	}
 
-	vma->vm_flags |= VM_RESERVED;	/* avoid to swap out this VMA */
 	return 0;
 
 }
diff --git a/drivers/video/via/via_clock.c b/drivers/video/via/via_clock.c
index af8f26b..db1e392 100644
--- a/drivers/video/via/via_clock.c
+++ b/drivers/video/via/via_clock.c
@@ -25,6 +25,7 @@
 
 #include <linux/kernel.h>
 #include <linux/via-core.h>
+#include <asm/olpc.h>
 #include "via_clock.h"
 #include "global.h"
 #include "debug.h"
@@ -289,6 +290,10 @@
 	printk(KERN_INFO "Using undocumented set PLL.\n%s", via_slap);
 }
 
+static void noop_set_clock_state(u8 state)
+{
+}
+
 void via_clock_init(struct via_clock *clock, int gfx_chip)
 {
 	switch (gfx_chip) {
@@ -346,4 +351,18 @@
 		break;
 
 	}
+
+	if (machine_is_olpc()) {
+		/* The OLPC XO-1.5 cannot suspend/resume reliably if the
+		 * IGA1/IGA2 clocks are set as on or off (memory rot
+		 * occasionally happens during suspend under such
+		 * configurations).
+		 *
+		 * The only known stable scenario is to leave this bits as-is,
+		 * which in their default states are documented to enable the
+		 * clock only when it is needed.
+		 */
+		clock->set_primary_clock_state = noop_set_clock_state;
+		clock->set_secondary_clock_state = noop_set_clock_state;
+	}
 }
diff --git a/drivers/xen/gntalloc.c b/drivers/xen/gntalloc.c
index 934985d..4097987 100644
--- a/drivers/xen/gntalloc.c
+++ b/drivers/xen/gntalloc.c
@@ -535,7 +535,7 @@
 
 	vma->vm_private_data = vm_priv;
 
-	vma->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
+	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 
 	vma->vm_ops = &gntalloc_vmops;
 
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
index 5df9fd8..610bfc6be 100644
--- a/drivers/xen/gntdev.c
+++ b/drivers/xen/gntdev.c
@@ -720,7 +720,7 @@
 
 	vma->vm_ops = &gntdev_vmops;
 
-	vma->vm_flags |= VM_RESERVED|VM_DONTEXPAND;
+	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 
 	if (use_ptemod)
 		vma->vm_flags |= VM_DONTCOPY;
diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c
index ef63895..8adb9cc 100644
--- a/drivers/xen/privcmd.c
+++ b/drivers/xen/privcmd.c
@@ -455,7 +455,8 @@
 {
 	/* DONTCOPY is essential for Xen because copy_page_range doesn't know
 	 * how to recreate these mappings */
-	vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY | VM_PFNMAP;
+	vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTCOPY |
+			 VM_DONTEXPAND | VM_DONTDUMP;
 	vma->vm_ops = &privcmd_vm_ops;
 	vma->vm_private_data = NULL;
 
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index 392c5da..d934f04e7 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -184,10 +184,20 @@
 			v9ses->afid = option;
 			break;
 		case Opt_uname:
-			match_strlcpy(v9ses->uname, &args[0], PATH_MAX);
+			kfree(v9ses->uname);
+			v9ses->uname = match_strdup(&args[0]);
+			if (!v9ses->uname) {
+				ret = -ENOMEM;
+				goto free_and_return;
+			}
 			break;
 		case Opt_remotename:
-			match_strlcpy(v9ses->aname, &args[0], PATH_MAX);
+			kfree(v9ses->aname);
+			v9ses->aname = match_strdup(&args[0]);
+			if (!v9ses->aname) {
+				ret = -ENOMEM;
+				goto free_and_return;
+			}
 			break;
 		case Opt_nodevmap:
 			v9ses->nodev = 1;
@@ -287,21 +297,21 @@
 	struct p9_fid *fid;
 	int rc;
 
-	v9ses->uname = __getname();
+	v9ses->uname = kstrdup(V9FS_DEFUSER, GFP_KERNEL);
 	if (!v9ses->uname)
 		return ERR_PTR(-ENOMEM);
 
-	v9ses->aname = __getname();
+	v9ses->aname = kstrdup(V9FS_DEFANAME, GFP_KERNEL);
 	if (!v9ses->aname) {
-		__putname(v9ses->uname);
+		kfree(v9ses->uname);
 		return ERR_PTR(-ENOMEM);
 	}
 	init_rwsem(&v9ses->rename_sem);
 
 	rc = bdi_setup_and_register(&v9ses->bdi, "9p", BDI_CAP_MAP_COPY);
 	if (rc) {
-		__putname(v9ses->aname);
-		__putname(v9ses->uname);
+		kfree(v9ses->aname);
+		kfree(v9ses->uname);
 		return ERR_PTR(rc);
 	}
 
@@ -309,8 +319,6 @@
 	list_add(&v9ses->slist, &v9fs_sessionlist);
 	spin_unlock(&v9fs_sessionlist_lock);
 
-	strcpy(v9ses->uname, V9FS_DEFUSER);
-	strcpy(v9ses->aname, V9FS_DEFANAME);
 	v9ses->uid = ~0;
 	v9ses->dfltuid = V9FS_DEFUID;
 	v9ses->dfltgid = V9FS_DEFGID;
@@ -412,8 +420,8 @@
 		kfree(v9ses->cachetag);
 	}
 #endif
-	__putname(v9ses->uname);
-	__putname(v9ses->aname);
+	kfree(v9ses->uname);
+	kfree(v9ses->aname);
 
 	bdi_destroy(&v9ses->bdi);
 
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index dd6f7ee..c2483e9 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -738,6 +738,7 @@
 static const struct vm_operations_struct v9fs_file_vm_ops = {
 	.fault = filemap_fault,
 	.page_mkwrite = v9fs_vm_page_mkwrite,
+	.remap_pages = generic_file_remap_pages,
 };
 
 
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index cbf9dbb..890bed5 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -1276,12 +1276,12 @@
 	}
 
 	/* copy extension buffer into buffer */
-	strncpy(buffer, st->extension, buflen);
+	retval = min(strlen(st->extension)+1, (size_t)buflen);
+	memcpy(buffer, st->extension, retval);
 
-	p9_debug(P9_DEBUG_VFS, "%s -> %s (%s)\n",
-		 dentry->d_name.name, st->extension, buffer);
+	p9_debug(P9_DEBUG_VFS, "%s -> %s (%.*s)\n",
+		 dentry->d_name.name, st->extension, buflen, buffer);
 
-	retval = strnlen(buffer, buflen);
 done:
 	p9stat_free(st);
 	kfree(st);
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index e7396cf..91b1165 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -392,10 +392,12 @@
 		ino->flags |= AUTOFS_INF_PENDING;
 		spin_unlock(&sbi->fs_lock);
 		status = autofs4_mount_wait(dentry);
-		if (status)
-			return ERR_PTR(status);
 		spin_lock(&sbi->fs_lock);
 		ino->flags &= ~AUTOFS_INF_PENDING;
+		if (status) {
+			spin_unlock(&sbi->fs_lock);
+			return ERR_PTR(status);
+		}
 	}
 done:
 	if (!(ino->flags & AUTOFS_INF_EXPIRING)) {
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 28a64e7..fbd9f60 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -36,7 +36,6 @@
 #include <asm/uaccess.h>
 #include <asm/param.h>
 #include <asm/page.h>
-#include <asm/exec.h>
 
 #ifndef user_long_t
 #define user_long_t long
@@ -1123,7 +1122,7 @@
 	if (always_dump_vma(vma))
 		goto whole;
 
-	if (vma->vm_flags & VM_NODUMP)
+	if (vma->vm_flags & VM_DONTDUMP)
 		return 0;
 
 	/* Hugetlb memory check */
@@ -1135,7 +1134,7 @@
 	}
 
 	/* Do not dump I/O mapped devices or special mappings */
-	if (vma->vm_flags & (VM_IO | VM_RESERVED))
+	if (vma->vm_flags & VM_IO)
 		return 0;
 
 	/* By default, dump shared memory if mapped from an anonymous file. */
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 08d812b..a460491 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -39,7 +39,6 @@
 #include <asm/uaccess.h>
 #include <asm/param.h>
 #include <asm/pgalloc.h>
-#include <asm/exec.h>
 
 typedef char *elf_caddr_t;
 
@@ -1205,7 +1204,7 @@
 	int dump_ok;
 
 	/* Do not dump I/O mapped devices or special mappings */
-	if (vma->vm_flags & (VM_IO | VM_RESERVED)) {
+	if (vma->vm_flags & VM_IO) {
 		kdcore("%08lx: %08lx: no (IO)", vma->vm_start, vma->vm_flags);
 		return 0;
 	}
diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c
index e85c04b..a3f28f3 100644
--- a/fs/bio-integrity.c
+++ b/fs/bio-integrity.c
@@ -70,23 +70,25 @@
 }
 
 /**
- * bio_integrity_alloc_bioset - Allocate integrity payload and attach it to bio
+ * bio_integrity_alloc - Allocate integrity payload and attach it to bio
  * @bio:	bio to attach integrity metadata to
  * @gfp_mask:	Memory allocation mask
  * @nr_vecs:	Number of integrity metadata scatter-gather elements
- * @bs:		bio_set to allocate from
  *
  * Description: This function prepares a bio for attaching integrity
  * metadata.  nr_vecs specifies the maximum number of pages containing
  * integrity metadata that can be attached.
  */
-struct bio_integrity_payload *bio_integrity_alloc_bioset(struct bio *bio,
-							 gfp_t gfp_mask,
-							 unsigned int nr_vecs,
-							 struct bio_set *bs)
+struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio,
+						  gfp_t gfp_mask,
+						  unsigned int nr_vecs)
 {
 	struct bio_integrity_payload *bip;
 	unsigned int idx = vecs_to_idx(nr_vecs);
+	struct bio_set *bs = bio->bi_pool;
+
+	if (!bs)
+		bs = fs_bio_set;
 
 	BUG_ON(bio == NULL);
 	bip = NULL;
@@ -114,37 +116,22 @@
 
 	return bip;
 }
-EXPORT_SYMBOL(bio_integrity_alloc_bioset);
-
-/**
- * bio_integrity_alloc - Allocate integrity payload and attach it to bio
- * @bio:	bio to attach integrity metadata to
- * @gfp_mask:	Memory allocation mask
- * @nr_vecs:	Number of integrity metadata scatter-gather elements
- *
- * Description: This function prepares a bio for attaching integrity
- * metadata.  nr_vecs specifies the maximum number of pages containing
- * integrity metadata that can be attached.
- */
-struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio,
-						  gfp_t gfp_mask,
-						  unsigned int nr_vecs)
-{
-	return bio_integrity_alloc_bioset(bio, gfp_mask, nr_vecs, fs_bio_set);
-}
 EXPORT_SYMBOL(bio_integrity_alloc);
 
 /**
  * bio_integrity_free - Free bio integrity payload
  * @bio:	bio containing bip to be freed
- * @bs:		bio_set this bio was allocated from
  *
  * Description: Used to free the integrity portion of a bio. Usually
  * called from bio_free().
  */
-void bio_integrity_free(struct bio *bio, struct bio_set *bs)
+void bio_integrity_free(struct bio *bio)
 {
 	struct bio_integrity_payload *bip = bio->bi_integrity;
+	struct bio_set *bs = bio->bi_pool;
+
+	if (!bs)
+		bs = fs_bio_set;
 
 	BUG_ON(bip == NULL);
 
@@ -730,19 +717,18 @@
  * @bio:	New bio
  * @bio_src:	Original bio
  * @gfp_mask:	Memory allocation mask
- * @bs:		bio_set to allocate bip from
  *
  * Description:	Called to allocate a bip when cloning a bio
  */
 int bio_integrity_clone(struct bio *bio, struct bio *bio_src,
-			gfp_t gfp_mask, struct bio_set *bs)
+			gfp_t gfp_mask)
 {
 	struct bio_integrity_payload *bip_src = bio_src->bi_integrity;
 	struct bio_integrity_payload *bip;
 
 	BUG_ON(bip_src == NULL);
 
-	bip = bio_integrity_alloc_bioset(bio, gfp_mask, bip_src->bip_vcnt, bs);
+	bip = bio_integrity_alloc(bio, gfp_mask, bip_src->bip_vcnt);
 
 	if (bip == NULL)
 		return -EIO;
diff --git a/fs/bio.c b/fs/bio.c
index 71072ab..9298c65 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -55,6 +55,7 @@
  * IO code that does not need private memory pools.
  */
 struct bio_set *fs_bio_set;
+EXPORT_SYMBOL(fs_bio_set);
 
 /*
  * Our slab pool management
@@ -233,26 +234,37 @@
 	return bvl;
 }
 
-void bio_free(struct bio *bio, struct bio_set *bs)
+static void __bio_free(struct bio *bio)
 {
-	void *p;
-
-	if (bio_has_allocated_vec(bio))
-		bvec_free_bs(bs, bio->bi_io_vec, BIO_POOL_IDX(bio));
+	bio_disassociate_task(bio);
 
 	if (bio_integrity(bio))
-		bio_integrity_free(bio, bs);
+		bio_integrity_free(bio);
+}
 
-	/*
-	 * If we have front padding, adjust the bio pointer before freeing
-	 */
-	p = bio;
-	if (bs->front_pad)
+static void bio_free(struct bio *bio)
+{
+	struct bio_set *bs = bio->bi_pool;
+	void *p;
+
+	__bio_free(bio);
+
+	if (bs) {
+		if (bio_has_allocated_vec(bio))
+			bvec_free_bs(bs, bio->bi_io_vec, BIO_POOL_IDX(bio));
+
+		/*
+		 * If we have front padding, adjust the bio pointer before freeing
+		 */
+		p = bio;
 		p -= bs->front_pad;
 
-	mempool_free(p, bs->bio_pool);
+		mempool_free(p, bs->bio_pool);
+	} else {
+		/* Bio was allocated by bio_kmalloc() */
+		kfree(bio);
+	}
 }
-EXPORT_SYMBOL(bio_free);
 
 void bio_init(struct bio *bio)
 {
@@ -263,48 +275,85 @@
 EXPORT_SYMBOL(bio_init);
 
 /**
+ * bio_reset - reinitialize a bio
+ * @bio:	bio to reset
+ *
+ * Description:
+ *   After calling bio_reset(), @bio will be in the same state as a freshly
+ *   allocated bio returned bio bio_alloc_bioset() - the only fields that are
+ *   preserved are the ones that are initialized by bio_alloc_bioset(). See
+ *   comment in struct bio.
+ */
+void bio_reset(struct bio *bio)
+{
+	unsigned long flags = bio->bi_flags & (~0UL << BIO_RESET_BITS);
+
+	__bio_free(bio);
+
+	memset(bio, 0, BIO_RESET_BYTES);
+	bio->bi_flags = flags|(1 << BIO_UPTODATE);
+}
+EXPORT_SYMBOL(bio_reset);
+
+/**
  * bio_alloc_bioset - allocate a bio for I/O
  * @gfp_mask:   the GFP_ mask given to the slab allocator
  * @nr_iovecs:	number of iovecs to pre-allocate
  * @bs:		the bio_set to allocate from.
  *
  * Description:
- *   bio_alloc_bioset will try its own mempool to satisfy the allocation.
- *   If %__GFP_WAIT is set then we will block on the internal pool waiting
- *   for a &struct bio to become free.
+ *   If @bs is NULL, uses kmalloc() to allocate the bio; else the allocation is
+ *   backed by the @bs's mempool.
  *
- *   Note that the caller must set ->bi_destructor on successful return
- *   of a bio, to do the appropriate freeing of the bio once the reference
- *   count drops to zero.
- **/
+ *   When @bs is not NULL, if %__GFP_WAIT is set then bio_alloc will always be
+ *   able to allocate a bio. This is due to the mempool guarantees. To make this
+ *   work, callers must never allocate more than 1 bio at a time from this pool.
+ *   Callers that need to allocate more than 1 bio must always submit the
+ *   previously allocated bio for IO before attempting to allocate a new one.
+ *   Failure to do so can cause deadlocks under memory pressure.
+ *
+ *   RETURNS:
+ *   Pointer to new bio on success, NULL on failure.
+ */
 struct bio *bio_alloc_bioset(gfp_t gfp_mask, int nr_iovecs, struct bio_set *bs)
 {
+	unsigned front_pad;
+	unsigned inline_vecs;
 	unsigned long idx = BIO_POOL_NONE;
 	struct bio_vec *bvl = NULL;
 	struct bio *bio;
 	void *p;
 
-	p = mempool_alloc(bs->bio_pool, gfp_mask);
+	if (!bs) {
+		if (nr_iovecs > UIO_MAXIOV)
+			return NULL;
+
+		p = kmalloc(sizeof(struct bio) +
+			    nr_iovecs * sizeof(struct bio_vec),
+			    gfp_mask);
+		front_pad = 0;
+		inline_vecs = nr_iovecs;
+	} else {
+		p = mempool_alloc(bs->bio_pool, gfp_mask);
+		front_pad = bs->front_pad;
+		inline_vecs = BIO_INLINE_VECS;
+	}
+
 	if (unlikely(!p))
 		return NULL;
-	bio = p + bs->front_pad;
 
+	bio = p + front_pad;
 	bio_init(bio);
 
-	if (unlikely(!nr_iovecs))
-		goto out_set;
-
-	if (nr_iovecs <= BIO_INLINE_VECS) {
-		bvl = bio->bi_inline_vecs;
-		nr_iovecs = BIO_INLINE_VECS;
-	} else {
+	if (nr_iovecs > inline_vecs) {
 		bvl = bvec_alloc_bs(gfp_mask, nr_iovecs, &idx, bs);
 		if (unlikely(!bvl))
 			goto err_free;
-
-		nr_iovecs = bvec_nr_vecs(idx);
+	} else if (nr_iovecs) {
+		bvl = bio->bi_inline_vecs;
 	}
-out_set:
+
+	bio->bi_pool = bs;
 	bio->bi_flags |= idx << BIO_POOL_OFFSET;
 	bio->bi_max_vecs = nr_iovecs;
 	bio->bi_io_vec = bvl;
@@ -316,80 +365,6 @@
 }
 EXPORT_SYMBOL(bio_alloc_bioset);
 
-static void bio_fs_destructor(struct bio *bio)
-{
-	bio_free(bio, fs_bio_set);
-}
-
-/**
- *	bio_alloc - allocate a new bio, memory pool backed
- *	@gfp_mask: allocation mask to use
- *	@nr_iovecs: number of iovecs
- *
- *	bio_alloc will allocate a bio and associated bio_vec array that can hold
- *	at least @nr_iovecs entries. Allocations will be done from the
- *	fs_bio_set. Also see @bio_alloc_bioset and @bio_kmalloc.
- *
- *	If %__GFP_WAIT is set, then bio_alloc will always be able to allocate
- *	a bio. This is due to the mempool guarantees. To make this work, callers
- *	must never allocate more than 1 bio at a time from this pool. Callers
- *	that need to allocate more than 1 bio must always submit the previously
- *	allocated bio for IO before attempting to allocate a new one. Failure to
- *	do so can cause livelocks under memory pressure.
- *
- *	RETURNS:
- *	Pointer to new bio on success, NULL on failure.
- */
-struct bio *bio_alloc(gfp_t gfp_mask, unsigned int nr_iovecs)
-{
-	struct bio *bio = bio_alloc_bioset(gfp_mask, nr_iovecs, fs_bio_set);
-
-	if (bio)
-		bio->bi_destructor = bio_fs_destructor;
-
-	return bio;
-}
-EXPORT_SYMBOL(bio_alloc);
-
-static void bio_kmalloc_destructor(struct bio *bio)
-{
-	if (bio_integrity(bio))
-		bio_integrity_free(bio, fs_bio_set);
-	kfree(bio);
-}
-
-/**
- * bio_kmalloc - allocate a bio for I/O using kmalloc()
- * @gfp_mask:   the GFP_ mask given to the slab allocator
- * @nr_iovecs:	number of iovecs to pre-allocate
- *
- * Description:
- *   Allocate a new bio with @nr_iovecs bvecs.  If @gfp_mask contains
- *   %__GFP_WAIT, the allocation is guaranteed to succeed.
- *
- **/
-struct bio *bio_kmalloc(gfp_t gfp_mask, unsigned int nr_iovecs)
-{
-	struct bio *bio;
-
-	if (nr_iovecs > UIO_MAXIOV)
-		return NULL;
-
-	bio = kmalloc(sizeof(struct bio) + nr_iovecs * sizeof(struct bio_vec),
-		      gfp_mask);
-	if (unlikely(!bio))
-		return NULL;
-
-	bio_init(bio);
-	bio->bi_flags |= BIO_POOL_NONE << BIO_POOL_OFFSET;
-	bio->bi_max_vecs = nr_iovecs;
-	bio->bi_io_vec = bio->bi_inline_vecs;
-	bio->bi_destructor = bio_kmalloc_destructor;
-
-	return bio;
-}
-EXPORT_SYMBOL(bio_kmalloc);
-
 void zero_fill_bio(struct bio *bio)
 {
 	unsigned long flags;
@@ -420,11 +395,8 @@
 	/*
 	 * last put frees it
 	 */
-	if (atomic_dec_and_test(&bio->bi_cnt)) {
-		bio_disassociate_task(bio);
-		bio->bi_next = NULL;
-		bio->bi_destructor(bio);
-	}
+	if (atomic_dec_and_test(&bio->bi_cnt))
+		bio_free(bio);
 }
 EXPORT_SYMBOL(bio_put);
 
@@ -466,26 +438,28 @@
 EXPORT_SYMBOL(__bio_clone);
 
 /**
- *	bio_clone	-	clone a bio
+ *	bio_clone_bioset -	clone a bio
  *	@bio: bio to clone
  *	@gfp_mask: allocation priority
+ *	@bs: bio_set to allocate from
  *
  * 	Like __bio_clone, only also allocates the returned bio
  */
-struct bio *bio_clone(struct bio *bio, gfp_t gfp_mask)
+struct bio *bio_clone_bioset(struct bio *bio, gfp_t gfp_mask,
+			     struct bio_set *bs)
 {
-	struct bio *b = bio_alloc_bioset(gfp_mask, bio->bi_max_vecs, fs_bio_set);
+	struct bio *b;
 
+	b = bio_alloc_bioset(gfp_mask, bio->bi_max_vecs, bs);
 	if (!b)
 		return NULL;
 
-	b->bi_destructor = bio_fs_destructor;
 	__bio_clone(b, bio);
 
 	if (bio_integrity(bio)) {
 		int ret;
 
-		ret = bio_integrity_clone(b, bio, gfp_mask, fs_bio_set);
+		ret = bio_integrity_clone(b, bio, gfp_mask);
 
 		if (ret < 0) {
 			bio_put(b);
@@ -495,7 +469,7 @@
 
 	return b;
 }
-EXPORT_SYMBOL(bio_clone);
+EXPORT_SYMBOL(bio_clone_bioset);
 
 /**
  *	bio_get_nr_vecs		- return approx number of vecs
@@ -1501,7 +1475,7 @@
 	trace_block_split(bdev_get_queue(bi->bi_bdev), bi,
 				bi->bi_sector + first_sectors);
 
-	BUG_ON(bi->bi_vcnt != 1);
+	BUG_ON(bi->bi_vcnt != 1 && bi->bi_vcnt != 0);
 	BUG_ON(bi->bi_idx != 0);
 	atomic_set(&bp->cnt, 3);
 	bp->error = 0;
@@ -1511,17 +1485,22 @@
 	bp->bio2.bi_size -= first_sectors << 9;
 	bp->bio1.bi_size = first_sectors << 9;
 
-	bp->bv1 = bi->bi_io_vec[0];
-	bp->bv2 = bi->bi_io_vec[0];
-	bp->bv2.bv_offset += first_sectors << 9;
-	bp->bv2.bv_len -= first_sectors << 9;
-	bp->bv1.bv_len = first_sectors << 9;
+	if (bi->bi_vcnt != 0) {
+		bp->bv1 = bi->bi_io_vec[0];
+		bp->bv2 = bi->bi_io_vec[0];
 
-	bp->bio1.bi_io_vec = &bp->bv1;
-	bp->bio2.bi_io_vec = &bp->bv2;
+		if (bio_is_rw(bi)) {
+			bp->bv2.bv_offset += first_sectors << 9;
+			bp->bv2.bv_len -= first_sectors << 9;
+			bp->bv1.bv_len = first_sectors << 9;
+		}
 
-	bp->bio1.bi_max_vecs = 1;
-	bp->bio2.bi_max_vecs = 1;
+		bp->bio1.bi_io_vec = &bp->bv1;
+		bp->bio2.bi_io_vec = &bp->bv2;
+
+		bp->bio1.bi_max_vecs = 1;
+		bp->bio2.bi_max_vecs = 1;
+	}
 
 	bp->bio1.bi_end_io = bio_pair_end_1;
 	bp->bio2.bi_end_io = bio_pair_end_2;
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 38e721b..b3c1d3d 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -116,6 +116,8 @@
 
 int set_blocksize(struct block_device *bdev, int size)
 {
+	struct address_space *mapping;
+
 	/* Size must be a power of two, and between 512 and PAGE_SIZE */
 	if (size > PAGE_SIZE || size < 512 || !is_power_of_2(size))
 		return -EINVAL;
@@ -124,6 +126,19 @@
 	if (size < bdev_logical_block_size(bdev))
 		return -EINVAL;
 
+	/* Prevent starting I/O or mapping the device */
+	percpu_down_write(&bdev->bd_block_size_semaphore);
+
+	/* Check that the block device is not memory mapped */
+	mapping = bdev->bd_inode->i_mapping;
+	mutex_lock(&mapping->i_mmap_mutex);
+	if (mapping_mapped(mapping)) {
+		mutex_unlock(&mapping->i_mmap_mutex);
+		percpu_up_write(&bdev->bd_block_size_semaphore);
+		return -EBUSY;
+	}
+	mutex_unlock(&mapping->i_mmap_mutex);
+
 	/* Don't change the size if it is same as current */
 	if (bdev->bd_block_size != size) {
 		sync_blockdev(bdev);
@@ -131,6 +146,9 @@
 		bdev->bd_inode->i_blkbits = blksize_bits(size);
 		kill_bdev(bdev);
 	}
+
+	percpu_up_write(&bdev->bd_block_size_semaphore);
+
 	return 0;
 }
 
@@ -441,6 +459,12 @@
 	struct bdev_inode *ei = kmem_cache_alloc(bdev_cachep, GFP_KERNEL);
 	if (!ei)
 		return NULL;
+
+	if (unlikely(percpu_init_rwsem(&ei->bdev.bd_block_size_semaphore))) {
+		kmem_cache_free(bdev_cachep, ei);
+		return NULL;
+	}
+
 	return &ei->vfs_inode;
 }
 
@@ -449,6 +473,8 @@
 	struct inode *inode = container_of(head, struct inode, i_rcu);
 	struct bdev_inode *bdi = BDEV_I(inode);
 
+	percpu_free_rwsem(&bdi->bdev.bd_block_size_semaphore);
+
 	kmem_cache_free(bdev_cachep, bdi);
 }
 
@@ -1567,6 +1593,22 @@
 	return blkdev_ioctl(bdev, mode, cmd, arg);
 }
 
+ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov,
+			unsigned long nr_segs, loff_t pos)
+{
+	ssize_t ret;
+	struct block_device *bdev = I_BDEV(iocb->ki_filp->f_mapping->host);
+
+	percpu_down_read(&bdev->bd_block_size_semaphore);
+
+	ret = generic_file_aio_read(iocb, iov, nr_segs, pos);
+
+	percpu_up_read(&bdev->bd_block_size_semaphore);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(blkdev_aio_read);
+
 /*
  * Write data to the block device.  Only intended for the block device itself
  * and the raw driver which basically is a fake block device.
@@ -1578,12 +1620,16 @@
 			 unsigned long nr_segs, loff_t pos)
 {
 	struct file *file = iocb->ki_filp;
+	struct block_device *bdev = I_BDEV(file->f_mapping->host);
 	struct blk_plug plug;
 	ssize_t ret;
 
 	BUG_ON(iocb->ki_pos != pos);
 
 	blk_start_plug(&plug);
+
+	percpu_down_read(&bdev->bd_block_size_semaphore);
+
 	ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);
 	if (ret > 0 || ret == -EIOCBQUEUED) {
 		ssize_t err;
@@ -1592,11 +1638,29 @@
 		if (err < 0 && ret > 0)
 			ret = err;
 	}
+
+	percpu_up_read(&bdev->bd_block_size_semaphore);
+
 	blk_finish_plug(&plug);
+
 	return ret;
 }
 EXPORT_SYMBOL_GPL(blkdev_aio_write);
 
+static int blkdev_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	int ret;
+	struct block_device *bdev = I_BDEV(file->f_mapping->host);
+
+	percpu_down_read(&bdev->bd_block_size_semaphore);
+
+	ret = generic_file_mmap(file, vma);
+
+	percpu_up_read(&bdev->bd_block_size_semaphore);
+
+	return ret;
+}
+
 /*
  * Try to release a page associated with block device when the system
  * is under memory pressure.
@@ -1627,9 +1691,9 @@
 	.llseek		= block_llseek,
 	.read		= do_sync_read,
 	.write		= do_sync_write,
-  	.aio_read	= generic_file_aio_read,
+  	.aio_read	= blkdev_aio_read,
 	.aio_write	= blkdev_aio_write,
-	.mmap		= generic_file_mmap,
+	.mmap		= blkdev_mmap,
 	.fsync		= blkdev_fsync,
 	.unlocked_ioctl	= block_ioctl,
 #ifdef CONFIG_COMPAT
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index ff6475f..f318793 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -16,6 +16,7 @@
  * Boston, MA 021110-1307, USA.
  */
 
+#include <linux/vmalloc.h>
 #include "ctree.h"
 #include "disk-io.h"
 #include "backref.h"
@@ -231,7 +232,7 @@
 			}
 			if (!ret) {
 				ret = ulist_add(parents, eb->start,
-						(unsigned long)eie, GFP_NOFS);
+						(uintptr_t)eie, GFP_NOFS);
 				if (ret < 0)
 					break;
 				if (!extent_item_pos) {
@@ -363,8 +364,8 @@
 		ULIST_ITER_INIT(&uiter);
 		node = ulist_next(parents, &uiter);
 		ref->parent = node ? node->val : 0;
-		ref->inode_list =
-			node ? (struct extent_inode_elem *)node->aux : 0;
+		ref->inode_list = node ?
+			(struct extent_inode_elem *)(uintptr_t)node->aux : 0;
 
 		/* additional parents require new refs being added here */
 		while ((node = ulist_next(parents, &uiter))) {
@@ -375,8 +376,8 @@
 			}
 			memcpy(new_ref, ref, sizeof(*ref));
 			new_ref->parent = node->val;
-			new_ref->inode_list =
-					(struct extent_inode_elem *)node->aux;
+			new_ref->inode_list = (struct extent_inode_elem *)
+							(uintptr_t)node->aux;
 			list_add(&new_ref->list, &ref->list);
 		}
 		ulist_reinit(parents);
@@ -914,8 +915,8 @@
 				free_extent_buffer(eb);
 			}
 			ret = ulist_add_merge(refs, ref->parent,
-					      (unsigned long)ref->inode_list,
-					      (unsigned long *)&eie, GFP_NOFS);
+					      (uintptr_t)ref->inode_list,
+					      (u64 *)&eie, GFP_NOFS);
 			if (!ret && extent_item_pos) {
 				/*
 				 * we've recorded that parent, so we must extend
@@ -959,7 +960,7 @@
 	while ((node = ulist_next(blocks, &uiter))) {
 		if (!node->aux)
 			continue;
-		eie = (struct extent_inode_elem *)node->aux;
+		eie = (struct extent_inode_elem *)(uintptr_t)node->aux;
 		for (; eie; eie = eie_next) {
 			eie_next = eie->next;
 			kfree(eie);
@@ -1108,26 +1109,80 @@
 				found_key);
 }
 
-/*
- * this iterates to turn a btrfs_inode_ref into a full filesystem path. elements
- * of the path are separated by '/' and the path is guaranteed to be
- * 0-terminated. the path is only given within the current file system.
- * Therefore, it never starts with a '/'. the caller is responsible to provide
- * "size" bytes in "dest". the dest buffer will be filled backwards. finally,
- * the start point of the resulting string is returned. this pointer is within
- * dest, normally.
- * in case the path buffer would overflow, the pointer is decremented further
- * as if output was written to the buffer, though no more output is actually
- * generated. that way, the caller can determine how much space would be
- * required for the path to fit into the buffer. in that case, the returned
- * value will be smaller than dest. callers must check this!
- */
-char *btrfs_iref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,
-			 struct btrfs_inode_ref *iref,
+int btrfs_find_one_extref(struct btrfs_root *root, u64 inode_objectid,
+			  u64 start_off, struct btrfs_path *path,
+			  struct btrfs_inode_extref **ret_extref,
+			  u64 *found_off)
+{
+	int ret, slot;
+	struct btrfs_key key;
+	struct btrfs_key found_key;
+	struct btrfs_inode_extref *extref;
+	struct extent_buffer *leaf;
+	unsigned long ptr;
+
+	key.objectid = inode_objectid;
+	btrfs_set_key_type(&key, BTRFS_INODE_EXTREF_KEY);
+	key.offset = start_off;
+
+	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+	if (ret < 0)
+		return ret;
+
+	while (1) {
+		leaf = path->nodes[0];
+		slot = path->slots[0];
+		if (slot >= btrfs_header_nritems(leaf)) {
+			/*
+			 * If the item at offset is not found,
+			 * btrfs_search_slot will point us to the slot
+			 * where it should be inserted. In our case
+			 * that will be the slot directly before the
+			 * next INODE_REF_KEY_V2 item. In the case
+			 * that we're pointing to the last slot in a
+			 * leaf, we must move one leaf over.
+			 */
+			ret = btrfs_next_leaf(root, path);
+			if (ret) {
+				if (ret >= 1)
+					ret = -ENOENT;
+				break;
+			}
+			continue;
+		}
+
+		btrfs_item_key_to_cpu(leaf, &found_key, slot);
+
+		/*
+		 * Check that we're still looking at an extended ref key for
+		 * this particular objectid. If we have different
+		 * objectid or type then there are no more to be found
+		 * in the tree and we can exit.
+		 */
+		ret = -ENOENT;
+		if (found_key.objectid != inode_objectid)
+			break;
+		if (btrfs_key_type(&found_key) != BTRFS_INODE_EXTREF_KEY)
+			break;
+
+		ret = 0;
+		ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
+		extref = (struct btrfs_inode_extref *)ptr;
+		*ret_extref = extref;
+		if (found_off)
+			*found_off = found_key.offset;
+		break;
+	}
+
+	return ret;
+}
+
+static char *ref_to_path(struct btrfs_root *fs_root,
+			 struct btrfs_path *path,
+			 u32 name_len, unsigned long name_off,
 			 struct extent_buffer *eb_in, u64 parent,
 			 char *dest, u32 size)
 {
-	u32 len;
 	int slot;
 	u64 next_inum;
 	int ret;
@@ -1135,17 +1190,17 @@
 	struct extent_buffer *eb = eb_in;
 	struct btrfs_key found_key;
 	int leave_spinning = path->leave_spinning;
+	struct btrfs_inode_ref *iref;
 
 	if (bytes_left >= 0)
 		dest[bytes_left] = '\0';
 
 	path->leave_spinning = 1;
 	while (1) {
-		len = btrfs_inode_ref_name_len(eb, iref);
-		bytes_left -= len;
+		bytes_left -= name_len;
 		if (bytes_left >= 0)
 			read_extent_buffer(eb, dest + bytes_left,
-						(unsigned long)(iref + 1), len);
+					   name_off, name_len);
 		if (eb != eb_in) {
 			btrfs_tree_read_unlock_blocking(eb);
 			free_extent_buffer(eb);
@@ -1155,6 +1210,7 @@
 			ret = -ENOENT;
 		if (ret)
 			break;
+
 		next_inum = found_key.offset;
 
 		/* regular exit ahead */
@@ -1170,8 +1226,11 @@
 			btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK);
 		}
 		btrfs_release_path(path);
-
 		iref = btrfs_item_ptr(eb, slot, struct btrfs_inode_ref);
+
+		name_len = btrfs_inode_ref_name_len(eb, iref);
+		name_off = (unsigned long)(iref + 1);
+
 		parent = next_inum;
 		--bytes_left;
 		if (bytes_left >= 0)
@@ -1188,12 +1247,39 @@
 }
 
 /*
+ * this iterates to turn a btrfs_inode_ref into a full filesystem path. elements
+ * of the path are separated by '/' and the path is guaranteed to be
+ * 0-terminated. the path is only given within the current file system.
+ * Therefore, it never starts with a '/'. the caller is responsible to provide
+ * "size" bytes in "dest". the dest buffer will be filled backwards. finally,
+ * the start point of the resulting string is returned. this pointer is within
+ * dest, normally.
+ * in case the path buffer would overflow, the pointer is decremented further
+ * as if output was written to the buffer, though no more output is actually
+ * generated. that way, the caller can determine how much space would be
+ * required for the path to fit into the buffer. in that case, the returned
+ * value will be smaller than dest. callers must check this!
+ */
+char *btrfs_iref_to_path(struct btrfs_root *fs_root,
+			 struct btrfs_path *path,
+			 struct btrfs_inode_ref *iref,
+			 struct extent_buffer *eb_in, u64 parent,
+			 char *dest, u32 size)
+{
+	return ref_to_path(fs_root, path,
+			   btrfs_inode_ref_name_len(eb_in, iref),
+			   (unsigned long)(iref + 1),
+			   eb_in, parent, dest, size);
+}
+
+/*
  * this makes the path point to (logical EXTENT_ITEM *)
  * returns BTRFS_EXTENT_FLAG_DATA for data, BTRFS_EXTENT_FLAG_TREE_BLOCK for
  * tree blocks and <0 on error.
  */
 int extent_from_logical(struct btrfs_fs_info *fs_info, u64 logical,
-			struct btrfs_path *path, struct btrfs_key *found_key)
+			struct btrfs_path *path, struct btrfs_key *found_key,
+			u64 *flags_ret)
 {
 	int ret;
 	u64 flags;
@@ -1237,10 +1323,17 @@
 		 (unsigned long long)found_key->objectid,
 		 (unsigned long long)found_key->offset,
 		 (unsigned long long)flags, item_size);
-	if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK)
-		return BTRFS_EXTENT_FLAG_TREE_BLOCK;
-	if (flags & BTRFS_EXTENT_FLAG_DATA)
-		return BTRFS_EXTENT_FLAG_DATA;
+
+	WARN_ON(!flags_ret);
+	if (flags_ret) {
+		if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK)
+			*flags_ret = BTRFS_EXTENT_FLAG_TREE_BLOCK;
+		else if (flags & BTRFS_EXTENT_FLAG_DATA)
+			*flags_ret = BTRFS_EXTENT_FLAG_DATA;
+		else
+			BUG_ON(1);
+		return 0;
+	}
 
 	return -EIO;
 }
@@ -1404,12 +1497,13 @@
 		ULIST_ITER_INIT(&root_uiter);
 		while (!ret && (root_node = ulist_next(roots, &root_uiter))) {
 			pr_debug("root %llu references leaf %llu, data list "
-				 "%#lx\n", root_node->val, ref_node->val,
-				 ref_node->aux);
-			ret = iterate_leaf_refs(
-				(struct extent_inode_elem *)ref_node->aux,
-				root_node->val, extent_item_objectid,
-				iterate, ctx);
+				 "%#llx\n", root_node->val, ref_node->val,
+				 (long long)ref_node->aux);
+			ret = iterate_leaf_refs((struct extent_inode_elem *)
+						(uintptr_t)ref_node->aux,
+						root_node->val,
+						extent_item_objectid,
+						iterate, ctx);
 		}
 		ulist_free(roots);
 		roots = NULL;
@@ -1432,15 +1526,15 @@
 {
 	int ret;
 	u64 extent_item_pos;
+	u64 flags = 0;
 	struct btrfs_key found_key;
 	int search_commit_root = path->search_commit_root;
 
-	ret = extent_from_logical(fs_info, logical, path,
-					&found_key);
+	ret = extent_from_logical(fs_info, logical, path, &found_key, &flags);
 	btrfs_release_path(path);
 	if (ret < 0)
 		return ret;
-	if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK)
+	if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK)
 		return -EINVAL;
 
 	extent_item_pos = logical - found_key.objectid;
@@ -1451,9 +1545,12 @@
 	return ret;
 }
 
-static int iterate_irefs(u64 inum, struct btrfs_root *fs_root,
-				struct btrfs_path *path,
-				iterate_irefs_t *iterate, void *ctx)
+typedef int (iterate_irefs_t)(u64 parent, u32 name_len, unsigned long name_off,
+			      struct extent_buffer *eb, void *ctx);
+
+static int iterate_inode_refs(u64 inum, struct btrfs_root *fs_root,
+			      struct btrfs_path *path,
+			      iterate_irefs_t *iterate, void *ctx)
 {
 	int ret = 0;
 	int slot;
@@ -1470,7 +1567,7 @@
 	while (!ret) {
 		path->leave_spinning = 1;
 		ret = inode_ref_info(inum, parent ? parent+1 : 0, fs_root, path,
-					&found_key);
+				     &found_key);
 		if (ret < 0)
 			break;
 		if (ret) {
@@ -1498,7 +1595,8 @@
 				 "tree %llu\n", cur,
 				 (unsigned long long)found_key.objectid,
 				 (unsigned long long)fs_root->objectid);
-			ret = iterate(parent, iref, eb, ctx);
+			ret = iterate(parent, name_len,
+				      (unsigned long)(iref + 1), eb, ctx);
 			if (ret)
 				break;
 			len = sizeof(*iref) + name_len;
@@ -1513,12 +1611,98 @@
 	return ret;
 }
 
+static int iterate_inode_extrefs(u64 inum, struct btrfs_root *fs_root,
+				 struct btrfs_path *path,
+				 iterate_irefs_t *iterate, void *ctx)
+{
+	int ret;
+	int slot;
+	u64 offset = 0;
+	u64 parent;
+	int found = 0;
+	struct extent_buffer *eb;
+	struct btrfs_inode_extref *extref;
+	struct extent_buffer *leaf;
+	u32 item_size;
+	u32 cur_offset;
+	unsigned long ptr;
+
+	while (1) {
+		ret = btrfs_find_one_extref(fs_root, inum, offset, path, &extref,
+					    &offset);
+		if (ret < 0)
+			break;
+		if (ret) {
+			ret = found ? 0 : -ENOENT;
+			break;
+		}
+		++found;
+
+		slot = path->slots[0];
+		eb = path->nodes[0];
+		/* make sure we can use eb after releasing the path */
+		atomic_inc(&eb->refs);
+
+		btrfs_tree_read_lock(eb);
+		btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK);
+		btrfs_release_path(path);
+
+		leaf = path->nodes[0];
+		item_size = btrfs_item_size_nr(leaf, path->slots[0]);
+		ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
+		cur_offset = 0;
+
+		while (cur_offset < item_size) {
+			u32 name_len;
+
+			extref = (struct btrfs_inode_extref *)(ptr + cur_offset);
+			parent = btrfs_inode_extref_parent(eb, extref);
+			name_len = btrfs_inode_extref_name_len(eb, extref);
+			ret = iterate(parent, name_len,
+				      (unsigned long)&extref->name, eb, ctx);
+			if (ret)
+				break;
+
+			cur_offset += btrfs_inode_extref_name_len(leaf, extref);
+			cur_offset += sizeof(*extref);
+		}
+		btrfs_tree_read_unlock_blocking(eb);
+		free_extent_buffer(eb);
+
+		offset++;
+	}
+
+	btrfs_release_path(path);
+
+	return ret;
+}
+
+static int iterate_irefs(u64 inum, struct btrfs_root *fs_root,
+			 struct btrfs_path *path, iterate_irefs_t *iterate,
+			 void *ctx)
+{
+	int ret;
+	int found_refs = 0;
+
+	ret = iterate_inode_refs(inum, fs_root, path, iterate, ctx);
+	if (!ret)
+		++found_refs;
+	else if (ret != -ENOENT)
+		return ret;
+
+	ret = iterate_inode_extrefs(inum, fs_root, path, iterate, ctx);
+	if (ret == -ENOENT && found_refs)
+		return 0;
+
+	return ret;
+}
+
 /*
  * returns 0 if the path could be dumped (probably truncated)
  * returns <0 in case of an error
  */
-static int inode_to_path(u64 inum, struct btrfs_inode_ref *iref,
-				struct extent_buffer *eb, void *ctx)
+static int inode_to_path(u64 inum, u32 name_len, unsigned long name_off,
+			 struct extent_buffer *eb, void *ctx)
 {
 	struct inode_fs_paths *ipath = ctx;
 	char *fspath;
@@ -1531,20 +1715,17 @@
 					ipath->fspath->bytes_left - s_ptr : 0;
 
 	fspath_min = (char *)ipath->fspath->val + (i + 1) * s_ptr;
-	fspath = btrfs_iref_to_path(ipath->fs_root, ipath->btrfs_path, iref, eb,
-				inum, fspath_min, bytes_left);
+	fspath = ref_to_path(ipath->fs_root, ipath->btrfs_path, name_len,
+			     name_off, eb, inum, fspath_min,
+			     bytes_left);
 	if (IS_ERR(fspath))
 		return PTR_ERR(fspath);
 
 	if (fspath > fspath_min) {
-		pr_debug("path resolved: %s\n", fspath);
 		ipath->fspath->val[i] = (u64)(unsigned long)fspath;
 		++ipath->fspath->elem_cnt;
 		ipath->fspath->bytes_left = fspath - fspath_min;
 	} else {
-		pr_debug("missed path, not enough space. missing bytes: %lu, "
-			 "constructed so far: %s\n",
-			 (unsigned long)(fspath_min - fspath), fspath_min);
 		++ipath->fspath->elem_missed;
 		ipath->fspath->bytes_missing += fspath_min - fspath;
 		ipath->fspath->bytes_left = 0;
@@ -1566,7 +1747,7 @@
 int paths_from_inode(u64 inum, struct inode_fs_paths *ipath)
 {
 	return iterate_irefs(inum, ipath->fs_root, ipath->btrfs_path,
-				inode_to_path, ipath);
+			     inode_to_path, ipath);
 }
 
 struct btrfs_data_container *init_data_container(u32 total_bytes)
@@ -1575,7 +1756,7 @@
 	size_t alloc_bytes;
 
 	alloc_bytes = max_t(size_t, total_bytes, sizeof(*data));
-	data = kmalloc(alloc_bytes, GFP_NOFS);
+	data = vmalloc(alloc_bytes);
 	if (!data)
 		return ERR_PTR(-ENOMEM);
 
@@ -1626,6 +1807,6 @@
 {
 	if (!ipath)
 		return;
-	kfree(ipath->fspath);
+	vfree(ipath->fspath);
 	kfree(ipath);
 }
diff --git a/fs/btrfs/backref.h b/fs/btrfs/backref.h
index 032f4dc..e755330 100644
--- a/fs/btrfs/backref.h
+++ b/fs/btrfs/backref.h
@@ -33,14 +33,13 @@
 
 typedef int (iterate_extent_inodes_t)(u64 inum, u64 offset, u64 root,
 		void *ctx);
-typedef int (iterate_irefs_t)(u64 parent, struct btrfs_inode_ref *iref,
-				struct extent_buffer *eb, void *ctx);
 
 int inode_item_info(u64 inum, u64 ioff, struct btrfs_root *fs_root,
 			struct btrfs_path *path);
 
 int extent_from_logical(struct btrfs_fs_info *fs_info, u64 logical,
-			struct btrfs_path *path, struct btrfs_key *found_key);
+			struct btrfs_path *path, struct btrfs_key *found_key,
+			u64 *flags);
 
 int tree_backref_for_extent(unsigned long *ptr, struct extent_buffer *eb,
 				struct btrfs_extent_item *ei, u32 item_size,
@@ -69,4 +68,9 @@
 					struct btrfs_path *path);
 void free_ipath(struct inode_fs_paths *ipath);
 
+int btrfs_find_one_extref(struct btrfs_root *root, u64 inode_objectid,
+			  u64 start_off, struct btrfs_path *path,
+			  struct btrfs_inode_extref **ret_extref,
+			  u64 *found_off);
+
 #endif
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
index 5b2ad6b..ed8ca7c 100644
--- a/fs/btrfs/btrfs_inode.h
+++ b/fs/btrfs/btrfs_inode.h
@@ -38,6 +38,7 @@
 #define BTRFS_INODE_DELALLOC_META_RESERVED	4
 #define BTRFS_INODE_HAS_ORPHAN_ITEM		5
 #define BTRFS_INODE_HAS_ASYNC_EXTENT		6
+#define BTRFS_INODE_NEEDS_FULL_SYNC		7
 
 /* in memory btrfs inode */
 struct btrfs_inode {
@@ -143,6 +144,9 @@
 	/* flags field from the on disk inode */
 	u32 flags;
 
+	/* a local copy of root's last_log_commit */
+	unsigned long last_log_commit;
+
 	/*
 	 * Counters to keep track of the number of extent item's we may use due
 	 * to delalloc and such.  outstanding_extents is the number of extent
@@ -202,15 +206,10 @@
 
 static inline int btrfs_inode_in_log(struct inode *inode, u64 generation)
 {
-	struct btrfs_root *root = BTRFS_I(inode)->root;
-	int ret = 0;
-
-	mutex_lock(&root->log_mutex);
 	if (BTRFS_I(inode)->logged_trans == generation &&
-	    BTRFS_I(inode)->last_sub_trans <= root->last_log_commit)
-		ret = 1;
-	mutex_unlock(&root->log_mutex);
-	return ret;
+	    BTRFS_I(inode)->last_sub_trans <= BTRFS_I(inode)->last_log_commit)
+		return 1;
+	return 0;
 }
 
 #endif
diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c
index 9197e2e..5a3e45d 100644
--- a/fs/btrfs/check-integrity.c
+++ b/fs/btrfs/check-integrity.c
@@ -37,8 +37,9 @@
  *        the file system was mounted, (i.e., they have been
  *        referenced by the super block) or they have been
  *        written since then and the write completion callback
- *        was called and a FLUSH request to the device where
- *        these blocks are located was received and completed.
+ *        was called and no write error was indicated and a
+ *        FLUSH request to the device where these blocks are
+ *        located was received and completed.
  *    2b. All referenced blocks need to have a generation
  *        number which is equal to the parent's number.
  *
@@ -2601,6 +2602,17 @@
 			       (unsigned long long)l->block_ref_to->dev_bytenr,
 			       l->block_ref_to->mirror_num);
 			ret = -1;
+		} else if (l->block_ref_to->iodone_w_error) {
+			printk(KERN_INFO "btrfs: attempt to write superblock"
+			       " which references block %c @%llu (%s/%llu/%d)"
+			       " which has write error!\n",
+			       btrfsic_get_block_type(state, l->block_ref_to),
+			       (unsigned long long)
+			       l->block_ref_to->logical_bytenr,
+			       l->block_ref_to->dev_state->name,
+			       (unsigned long long)l->block_ref_to->dev_bytenr,
+			       l->block_ref_to->mirror_num);
+			ret = -1;
 		} else if (l->parent_generation !=
 			   l->block_ref_to->generation &&
 			   BTRFSIC_GENERATION_UNKNOWN !=
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index 43d1c5a..c6467aa 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -577,6 +577,7 @@
 	u64 em_start;
 	struct extent_map *em;
 	int ret = -ENOMEM;
+	int faili = 0;
 	u32 *sums;
 
 	tree = &BTRFS_I(inode)->io_tree;
@@ -626,9 +627,13 @@
 	for (pg_index = 0; pg_index < nr_pages; pg_index++) {
 		cb->compressed_pages[pg_index] = alloc_page(GFP_NOFS |
 							      __GFP_HIGHMEM);
-		if (!cb->compressed_pages[pg_index])
+		if (!cb->compressed_pages[pg_index]) {
+			faili = pg_index - 1;
+			ret = -ENOMEM;
 			goto fail2;
+		}
 	}
+	faili = nr_pages - 1;
 	cb->nr_pages = nr_pages;
 
 	add_ra_bio_pages(inode, em_start + em_len, cb);
@@ -713,8 +718,10 @@
 	return 0;
 
 fail2:
-	for (pg_index = 0; pg_index < nr_pages; pg_index++)
-		free_page((unsigned long)cb->compressed_pages[pg_index]);
+	while (faili >= 0) {
+		__free_page(cb->compressed_pages[faili]);
+		faili--;
+	}
 
 	kfree(cb->compressed_pages);
 fail1:
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 6d183f6..b334362 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -4402,149 +4402,6 @@
 }
 
 /*
- * Given a key and some data, insert items into the tree.
- * This does all the path init required, making room in the tree if needed.
- * Returns the number of keys that were inserted.
- */
-int btrfs_insert_some_items(struct btrfs_trans_handle *trans,
-			    struct btrfs_root *root,
-			    struct btrfs_path *path,
-			    struct btrfs_key *cpu_key, u32 *data_size,
-			    int nr)
-{
-	struct extent_buffer *leaf;
-	struct btrfs_item *item;
-	int ret = 0;
-	int slot;
-	int i;
-	u32 nritems;
-	u32 total_data = 0;
-	u32 total_size = 0;
-	unsigned int data_end;
-	struct btrfs_disk_key disk_key;
-	struct btrfs_key found_key;
-	struct btrfs_map_token token;
-
-	btrfs_init_map_token(&token);
-
-	for (i = 0; i < nr; i++) {
-		if (total_size + data_size[i] + sizeof(struct btrfs_item) >
-		    BTRFS_LEAF_DATA_SIZE(root)) {
-			break;
-			nr = i;
-		}
-		total_data += data_size[i];
-		total_size += data_size[i] + sizeof(struct btrfs_item);
-	}
-	BUG_ON(nr == 0);
-
-	ret = btrfs_search_slot(trans, root, cpu_key, path, total_size, 1);
-	if (ret == 0)
-		return -EEXIST;
-	if (ret < 0)
-		goto out;
-
-	leaf = path->nodes[0];
-
-	nritems = btrfs_header_nritems(leaf);
-	data_end = leaf_data_end(root, leaf);
-
-	if (btrfs_leaf_free_space(root, leaf) < total_size) {
-		for (i = nr; i >= 0; i--) {
-			total_data -= data_size[i];
-			total_size -= data_size[i] + sizeof(struct btrfs_item);
-			if (total_size < btrfs_leaf_free_space(root, leaf))
-				break;
-		}
-		nr = i;
-	}
-
-	slot = path->slots[0];
-	BUG_ON(slot < 0);
-
-	if (slot != nritems) {
-		unsigned int old_data = btrfs_item_end_nr(leaf, slot);
-
-		item = btrfs_item_nr(leaf, slot);
-		btrfs_item_key_to_cpu(leaf, &found_key, slot);
-
-		/* figure out how many keys we can insert in here */
-		total_data = data_size[0];
-		for (i = 1; i < nr; i++) {
-			if (btrfs_comp_cpu_keys(&found_key, cpu_key + i) <= 0)
-				break;
-			total_data += data_size[i];
-		}
-		nr = i;
-
-		if (old_data < data_end) {
-			btrfs_print_leaf(root, leaf);
-			printk(KERN_CRIT "slot %d old_data %d data_end %d\n",
-			       slot, old_data, data_end);
-			BUG_ON(1);
-		}
-		/*
-		 * item0..itemN ... dataN.offset..dataN.size .. data0.size
-		 */
-		/* first correct the data pointers */
-		for (i = slot; i < nritems; i++) {
-			u32 ioff;
-
-			item = btrfs_item_nr(leaf, i);
-			ioff = btrfs_token_item_offset(leaf, item, &token);
-			btrfs_set_token_item_offset(leaf, item,
-						    ioff - total_data, &token);
-		}
-		/* shift the items */
-		memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot + nr),
-			      btrfs_item_nr_offset(slot),
-			      (nritems - slot) * sizeof(struct btrfs_item));
-
-		/* shift the data */
-		memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) +
-			      data_end - total_data, btrfs_leaf_data(leaf) +
-			      data_end, old_data - data_end);
-		data_end = old_data;
-	} else {
-		/*
-		 * this sucks but it has to be done, if we are inserting at
-		 * the end of the leaf only insert 1 of the items, since we
-		 * have no way of knowing whats on the next leaf and we'd have
-		 * to drop our current locks to figure it out
-		 */
-		nr = 1;
-	}
-
-	/* setup the item for the new data */
-	for (i = 0; i < nr; i++) {
-		btrfs_cpu_key_to_disk(&disk_key, cpu_key + i);
-		btrfs_set_item_key(leaf, &disk_key, slot + i);
-		item = btrfs_item_nr(leaf, slot + i);
-		btrfs_set_token_item_offset(leaf, item,
-					    data_end - data_size[i], &token);
-		data_end -= data_size[i];
-		btrfs_set_token_item_size(leaf, item, data_size[i], &token);
-	}
-	btrfs_set_header_nritems(leaf, nritems + nr);
-	btrfs_mark_buffer_dirty(leaf);
-
-	ret = 0;
-	if (slot == 0) {
-		btrfs_cpu_key_to_disk(&disk_key, cpu_key);
-		fixup_low_keys(trans, root, path, &disk_key, 1);
-	}
-
-	if (btrfs_leaf_free_space(root, leaf) < 0) {
-		btrfs_print_leaf(root, leaf);
-		BUG();
-	}
-out:
-	if (!ret)
-		ret = nr;
-	return ret;
-}
-
-/*
  * this is a helper for btrfs_insert_empty_items, the main goal here is
  * to save stack depth by doing the bulk of the work in a function
  * that doesn't call btrfs_search_slot
@@ -5073,6 +4930,7 @@
 			   struct btrfs_path *path,
 			   int *level, int root_level)
 {
+	BUG_ON(*level == 0);
 	path->nodes[*level - 1] = read_node_slot(root, path->nodes[*level],
 					path->slots[*level]);
 	path->slots[*level - 1] = 0;
@@ -5089,7 +4947,7 @@
 
 	path->slots[*level]++;
 
-	while (path->slots[*level] == nritems) {
+	while (path->slots[*level] >= nritems) {
 		if (*level == root_level)
 			return -1;
 
@@ -5433,9 +5291,11 @@
 					goto out;
 				advance_right = ADVANCE;
 			} else {
+				WARN_ON(!extent_buffer_uptodate(left_path->nodes[0]));
 				ret = tree_compare_item(left_root, left_path,
 						right_path, tmp_buf);
 				if (ret) {
+					WARN_ON(!extent_buffer_uptodate(left_path->nodes[0]));
 					ret = changed_cb(left_root, right_root,
 						left_path, right_path,
 						&left_key,
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 9821b67..926c9ff 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -154,6 +154,13 @@
  */
 #define BTRFS_NAME_LEN 255
 
+/*
+ * Theoretical limit is larger, but we keep this down to a sane
+ * value. That should limit greatly the possibility of collisions on
+ * inode ref items.
+ */
+#define BTRFS_LINK_MAX 65535U
+
 /* 32 bytes in various csum fields */
 #define BTRFS_CSUM_SIZE 32
 
@@ -489,6 +496,8 @@
  */
 #define BTRFS_FEATURE_INCOMPAT_BIG_METADATA	(1ULL << 5)
 
+#define BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF	(1ULL << 6)
+
 #define BTRFS_FEATURE_COMPAT_SUPP		0ULL
 #define BTRFS_FEATURE_COMPAT_RO_SUPP		0ULL
 #define BTRFS_FEATURE_INCOMPAT_SUPP			\
@@ -496,7 +505,8 @@
 	 BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL |	\
 	 BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS |		\
 	 BTRFS_FEATURE_INCOMPAT_BIG_METADATA |		\
-	 BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO)
+	 BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO |		\
+	 BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF)
 
 /*
  * A leaf is full of items. offset and size tell us where to find
@@ -643,6 +653,14 @@
 	/* name goes here */
 } __attribute__ ((__packed__));
 
+struct btrfs_inode_extref {
+	__le64 parent_objectid;
+	__le64 index;
+	__le16 name_len;
+	__u8   name[0];
+	/* name goes here */
+} __attribute__ ((__packed__));
+
 struct btrfs_timespec {
 	__le64 sec;
 	__le32 nsec;
@@ -1028,12 +1046,22 @@
 	wait_queue_head_t wait;
 };
 
+#define	BTRFS_BLOCK_RSV_GLOBAL		1
+#define	BTRFS_BLOCK_RSV_DELALLOC	2
+#define	BTRFS_BLOCK_RSV_TRANS		3
+#define	BTRFS_BLOCK_RSV_CHUNK		4
+#define	BTRFS_BLOCK_RSV_DELOPS		5
+#define	BTRFS_BLOCK_RSV_EMPTY		6
+#define	BTRFS_BLOCK_RSV_TEMP		7
+
 struct btrfs_block_rsv {
 	u64 size;
 	u64 reserved;
 	struct btrfs_space_info *space_info;
 	spinlock_t lock;
-	unsigned int full;
+	unsigned short full;
+	unsigned short type;
+	unsigned short failfast;
 };
 
 /*
@@ -1127,6 +1155,9 @@
 	 * Today it will only have one thing on it, but that may change
 	 */
 	struct list_head cluster_list;
+
+	/* For delayed block group creation */
+	struct list_head new_bg_list;
 };
 
 /* delayed seq elem */
@@ -1240,7 +1271,6 @@
 	struct mutex reloc_mutex;
 
 	struct list_head trans_list;
-	struct list_head hashers;
 	struct list_head dead_roots;
 	struct list_head caching_block_groups;
 
@@ -1366,9 +1396,6 @@
 	struct rb_root defrag_inodes;
 	atomic_t defrag_running;
 
-	spinlock_t ref_cache_lock;
-	u64 total_ref_cache_size;
-
 	/*
 	 * these three are in extended format (availability of single
 	 * chunks is denoted by BTRFS_AVAIL_ALLOC_BIT_SINGLE bit, other
@@ -1441,6 +1468,8 @@
 
 	/* next backup root to be overwritten */
 	int backup_root_index;
+
+	int num_tolerated_disk_barrier_failures;
 };
 
 /*
@@ -1481,9 +1510,9 @@
 	wait_queue_head_t log_commit_wait[2];
 	atomic_t log_writers;
 	atomic_t log_commit[2];
+	atomic_t log_batch;
 	unsigned long log_transid;
 	unsigned long last_log_commit;
-	unsigned long log_batch;
 	pid_t log_start_pid;
 	bool log_multiple_pids;
 
@@ -1592,6 +1621,7 @@
  */
 #define BTRFS_INODE_ITEM_KEY		1
 #define BTRFS_INODE_REF_KEY		12
+#define BTRFS_INODE_EXTREF_KEY		13
 #define BTRFS_XATTR_ITEM_KEY		24
 #define BTRFS_ORPHAN_ITEM_KEY		48
 /* reserve 2-15 close to the inode for later flexibility */
@@ -1978,6 +2008,13 @@
 BTRFS_SETGET_FUNCS(inode_ref_name_len, struct btrfs_inode_ref, name_len, 16);
 BTRFS_SETGET_FUNCS(inode_ref_index, struct btrfs_inode_ref, index, 64);
 
+/* struct btrfs_inode_extref */
+BTRFS_SETGET_FUNCS(inode_extref_parent, struct btrfs_inode_extref,
+		   parent_objectid, 64);
+BTRFS_SETGET_FUNCS(inode_extref_name_len, struct btrfs_inode_extref,
+		   name_len, 16);
+BTRFS_SETGET_FUNCS(inode_extref_index, struct btrfs_inode_extref, index, 64);
+
 /* struct btrfs_inode_item */
 BTRFS_SETGET_FUNCS(inode_generation, struct btrfs_inode_item, generation, 64);
 BTRFS_SETGET_FUNCS(inode_sequence, struct btrfs_inode_item, sequence, 64);
@@ -2858,6 +2895,8 @@
 			   u64 size);
 int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
 			     struct btrfs_root *root, u64 group_start);
+void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans,
+				       struct btrfs_root *root);
 u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags);
 u64 btrfs_get_alloc_profile(struct btrfs_root *root, int data);
 void btrfs_clear_space_info_full(struct btrfs_fs_info *info);
@@ -2874,8 +2913,9 @@
 void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes);
 int btrfs_delalloc_reserve_space(struct inode *inode, u64 num_bytes);
 void btrfs_delalloc_release_space(struct inode *inode, u64 num_bytes);
-void btrfs_init_block_rsv(struct btrfs_block_rsv *rsv);
-struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_root *root);
+void btrfs_init_block_rsv(struct btrfs_block_rsv *rsv, unsigned short type);
+struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_root *root,
+					      unsigned short type);
 void btrfs_free_block_rsv(struct btrfs_root *root,
 			  struct btrfs_block_rsv *rsv);
 int btrfs_block_rsv_add(struct btrfs_root *root,
@@ -3172,12 +3212,12 @@
 			   struct btrfs_root *root,
 			   const char *name, int name_len,
 			   u64 inode_objectid, u64 ref_objectid, u64 *index);
-struct btrfs_inode_ref *
-btrfs_lookup_inode_ref(struct btrfs_trans_handle *trans,
-			struct btrfs_root *root,
-			struct btrfs_path *path,
-			const char *name, int name_len,
-			u64 inode_objectid, u64 ref_objectid, int mod);
+int btrfs_get_inode_ref_index(struct btrfs_trans_handle *trans,
+			      struct btrfs_root *root,
+			      struct btrfs_path *path,
+			      const char *name, int name_len,
+			      u64 inode_objectid, u64 ref_objectid, int mod,
+			      u64 *ret_index);
 int btrfs_insert_empty_inode(struct btrfs_trans_handle *trans,
 			     struct btrfs_root *root,
 			     struct btrfs_path *path, u64 objectid);
@@ -3185,6 +3225,19 @@
 		       *root, struct btrfs_path *path,
 		       struct btrfs_key *location, int mod);
 
+struct btrfs_inode_extref *
+btrfs_lookup_inode_extref(struct btrfs_trans_handle *trans,
+			  struct btrfs_root *root,
+			  struct btrfs_path *path,
+			  const char *name, int name_len,
+			  u64 inode_objectid, u64 ref_objectid, int ins_len,
+			  int cow);
+
+int btrfs_find_name_in_ext_backref(struct btrfs_path *path,
+				   u64 ref_objectid, const char *name,
+				   int name_len,
+				   struct btrfs_inode_extref **extref_ret);
+
 /* file-item.c */
 int btrfs_del_csums(struct btrfs_trans_handle *trans,
 		    struct btrfs_root *root, u64 bytenr, u64 len);
@@ -3249,6 +3302,8 @@
 			struct btrfs_root *root,
 			struct inode *dir, u64 objectid,
 			const char *name, int name_len);
+int btrfs_truncate_page(struct inode *inode, loff_t from, loff_t len,
+			int front);
 int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
 			       struct btrfs_root *root,
 			       struct inode *inode, u64 new_size,
@@ -3308,16 +3363,27 @@
 int btrfs_defrag_file(struct inode *inode, struct file *file,
 		      struct btrfs_ioctl_defrag_range_args *range,
 		      u64 newer_than, unsigned long max_pages);
+void btrfs_get_block_group_info(struct list_head *groups_list,
+				struct btrfs_ioctl_space_info *space);
+
 /* file.c */
 int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans,
 			   struct inode *inode);
 int btrfs_run_defrag_inodes(struct btrfs_fs_info *fs_info);
 int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync);
-int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
-			    int skip_pinned);
+void btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
+			     int skip_pinned);
+int btrfs_replace_extent_cache(struct inode *inode, struct extent_map *replace,
+			       u64 start, u64 end, int skip_pinned,
+			       int modified);
 extern const struct file_operations btrfs_file_operations;
-int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode,
-		       u64 start, u64 end, u64 *hint_byte, int drop_cache);
+int __btrfs_drop_extents(struct btrfs_trans_handle *trans,
+			 struct btrfs_root *root, struct inode *inode,
+			 struct btrfs_path *path, u64 start, u64 end,
+			 u64 *drop_end, int drop_cache);
+int btrfs_drop_extents(struct btrfs_trans_handle *trans,
+		       struct btrfs_root *root, struct inode *inode, u64 start,
+		       u64 end, int drop_cache);
 int btrfs_mark_extent_written(struct btrfs_trans_handle *trans,
 			      struct inode *inode, u64 start, u64 end);
 int btrfs_release_file(struct inode *inode, struct file *file);
@@ -3378,6 +3444,11 @@
 	}
 }
 
+/*
+ * Call btrfs_abort_transaction as early as possible when an error condition is
+ * detected, that way the exact line number is reported.
+ */
+
 #define btrfs_abort_transaction(trans, root, errno)		\
 do {								\
 	__btrfs_abort_transaction(trans, root, __func__,	\
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
index 52c85e2..478f66b 100644
--- a/fs/btrfs/delayed-inode.c
+++ b/fs/btrfs/delayed-inode.c
@@ -29,7 +29,7 @@
 
 int __init btrfs_delayed_inode_init(void)
 {
-	delayed_node_cache = kmem_cache_create("delayed_node",
+	delayed_node_cache = kmem_cache_create("btrfs_delayed_node",
 					sizeof(struct btrfs_delayed_node),
 					0,
 					SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD,
@@ -650,7 +650,7 @@
 	 * we're accounted for.
 	 */
 	if (!src_rsv || (!trans->bytes_reserved &&
-	    src_rsv != &root->fs_info->delalloc_block_rsv)) {
+			 src_rsv->type != BTRFS_BLOCK_RSV_DELALLOC)) {
 		ret = btrfs_block_rsv_add_noflush(root, dst_rsv, num_bytes);
 		/*
 		 * Since we're under a transaction reserve_metadata_bytes could
@@ -668,7 +668,7 @@
 						      num_bytes, 1);
 		}
 		return ret;
-	} else if (src_rsv == &root->fs_info->delalloc_block_rsv) {
+	} else if (src_rsv->type == BTRFS_BLOCK_RSV_DELALLOC) {
 		spin_lock(&BTRFS_I(inode)->lock);
 		if (test_and_clear_bit(BTRFS_INODE_DELALLOC_META_RESERVED,
 				       &BTRFS_I(inode)->runtime_flags)) {
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 22e98e0..7cda519 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -46,6 +46,10 @@
 #include "check-integrity.h"
 #include "rcu-string.h"
 
+#ifdef CONFIG_X86
+#include <asm/cpufeature.h>
+#endif
+
 static struct extent_io_ops btree_extent_io_ops;
 static void end_workqueue_fn(struct btrfs_work *work);
 static void free_fs_root(struct btrfs_root *root);
@@ -217,26 +221,16 @@
 	write_lock(&em_tree->lock);
 	ret = add_extent_mapping(em_tree, em);
 	if (ret == -EEXIST) {
-		u64 failed_start = em->start;
-		u64 failed_len = em->len;
-
 		free_extent_map(em);
 		em = lookup_extent_mapping(em_tree, start, len);
-		if (em) {
-			ret = 0;
-		} else {
-			em = lookup_extent_mapping(em_tree, failed_start,
-						   failed_len);
-			ret = -EIO;
-		}
+		if (!em)
+			em = ERR_PTR(-EIO);
 	} else if (ret) {
 		free_extent_map(em);
-		em = NULL;
+		em = ERR_PTR(ret);
 	}
 	write_unlock(&em_tree->lock);
 
-	if (ret)
-		em = ERR_PTR(ret);
 out:
 	return em;
 }
@@ -439,10 +433,6 @@
 		WARN_ON(1);
 		return 0;
 	}
-	if (eb->pages[0] != page) {
-		WARN_ON(1);
-		return 0;
-	}
 	if (!PageUptodate(page)) {
 		WARN_ON(1);
 		return 0;
@@ -869,10 +859,22 @@
 	return btrfs_map_bio(BTRFS_I(inode)->root, rw, bio, mirror_num, 1);
 }
 
+static int check_async_write(struct inode *inode, unsigned long bio_flags)
+{
+	if (bio_flags & EXTENT_BIO_TREE_LOG)
+		return 0;
+#ifdef CONFIG_X86
+	if (cpu_has_xmm4_2)
+		return 0;
+#endif
+	return 1;
+}
+
 static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
 				 int mirror_num, unsigned long bio_flags,
 				 u64 bio_offset)
 {
+	int async = check_async_write(inode, bio_flags);
 	int ret;
 
 	if (!(rw & REQ_WRITE)) {
@@ -887,6 +889,12 @@
 			return ret;
 		return btrfs_map_bio(BTRFS_I(inode)->root, rw, bio,
 				     mirror_num, 0);
+	} else if (!async) {
+		ret = btree_csum_one_bio(bio);
+		if (ret)
+			return ret;
+		return btrfs_map_bio(BTRFS_I(inode)->root, rw, bio,
+				     mirror_num, 0);
 	}
 
 	/*
@@ -1168,8 +1176,8 @@
 	atomic_set(&root->log_commit[0], 0);
 	atomic_set(&root->log_commit[1], 0);
 	atomic_set(&root->log_writers, 0);
+	atomic_set(&root->log_batch, 0);
 	atomic_set(&root->orphan_inodes, 0);
-	root->log_batch = 0;
 	root->log_transid = 0;
 	root->last_log_commit = 0;
 	extent_io_tree_init(&root->dirty_log_pages,
@@ -1667,9 +1675,10 @@
 		spin_unlock(&root->fs_info->trans_lock);
 
 		/* If the file system is aborted, this will always fail. */
-		trans = btrfs_join_transaction(root);
+		trans = btrfs_attach_transaction(root);
 		if (IS_ERR(trans)) {
-			cannot_commit = true;
+			if (PTR_ERR(trans) != -ENOENT)
+				cannot_commit = true;
 			goto sleep;
 		}
 		if (transid == trans->transid) {
@@ -1994,13 +2003,11 @@
 	INIT_LIST_HEAD(&fs_info->trans_list);
 	INIT_LIST_HEAD(&fs_info->dead_roots);
 	INIT_LIST_HEAD(&fs_info->delayed_iputs);
-	INIT_LIST_HEAD(&fs_info->hashers);
 	INIT_LIST_HEAD(&fs_info->delalloc_inodes);
 	INIT_LIST_HEAD(&fs_info->ordered_operations);
 	INIT_LIST_HEAD(&fs_info->caching_block_groups);
 	spin_lock_init(&fs_info->delalloc_lock);
 	spin_lock_init(&fs_info->trans_lock);
-	spin_lock_init(&fs_info->ref_cache_lock);
 	spin_lock_init(&fs_info->fs_roots_radix_lock);
 	spin_lock_init(&fs_info->delayed_iput_lock);
 	spin_lock_init(&fs_info->defrag_inodes_lock);
@@ -2014,12 +2021,15 @@
 	INIT_LIST_HEAD(&fs_info->space_info);
 	INIT_LIST_HEAD(&fs_info->tree_mod_seq_list);
 	btrfs_mapping_init(&fs_info->mapping_tree);
-	btrfs_init_block_rsv(&fs_info->global_block_rsv);
-	btrfs_init_block_rsv(&fs_info->delalloc_block_rsv);
-	btrfs_init_block_rsv(&fs_info->trans_block_rsv);
-	btrfs_init_block_rsv(&fs_info->chunk_block_rsv);
-	btrfs_init_block_rsv(&fs_info->empty_block_rsv);
-	btrfs_init_block_rsv(&fs_info->delayed_block_rsv);
+	btrfs_init_block_rsv(&fs_info->global_block_rsv,
+			     BTRFS_BLOCK_RSV_GLOBAL);
+	btrfs_init_block_rsv(&fs_info->delalloc_block_rsv,
+			     BTRFS_BLOCK_RSV_DELALLOC);
+	btrfs_init_block_rsv(&fs_info->trans_block_rsv, BTRFS_BLOCK_RSV_TRANS);
+	btrfs_init_block_rsv(&fs_info->chunk_block_rsv, BTRFS_BLOCK_RSV_CHUNK);
+	btrfs_init_block_rsv(&fs_info->empty_block_rsv, BTRFS_BLOCK_RSV_EMPTY);
+	btrfs_init_block_rsv(&fs_info->delayed_block_rsv,
+			     BTRFS_BLOCK_RSV_DELOPS);
 	atomic_set(&fs_info->nr_async_submits, 0);
 	atomic_set(&fs_info->async_delalloc_pages, 0);
 	atomic_set(&fs_info->async_submit_draining, 0);
@@ -2491,6 +2501,8 @@
 		printk(KERN_ERR "Failed to read block groups: %d\n", ret);
 		goto fail_block_groups;
 	}
+	fs_info->num_tolerated_disk_barrier_failures =
+		btrfs_calc_num_tolerated_disk_barrier_failures(fs_info);
 
 	fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root,
 					       "btrfs-cleaner");
@@ -2874,12 +2886,10 @@
 			printk_in_rcu("btrfs: disabling barriers on dev %s\n",
 				      rcu_str_deref(device->name));
 			device->nobarriers = 1;
-		}
-		if (!bio_flagged(bio, BIO_UPTODATE)) {
+		} else if (!bio_flagged(bio, BIO_UPTODATE)) {
 			ret = -EIO;
-			if (!bio_flagged(bio, BIO_EOPNOTSUPP))
-				btrfs_dev_stat_inc_and_print(device,
-					BTRFS_DEV_STAT_FLUSH_ERRS);
+			btrfs_dev_stat_inc_and_print(device,
+				BTRFS_DEV_STAT_FLUSH_ERRS);
 		}
 
 		/* drop the reference from the wait == 0 run */
@@ -2918,14 +2928,15 @@
 {
 	struct list_head *head;
 	struct btrfs_device *dev;
-	int errors = 0;
+	int errors_send = 0;
+	int errors_wait = 0;
 	int ret;
 
 	/* send down all the barriers */
 	head = &info->fs_devices->devices;
 	list_for_each_entry_rcu(dev, head, dev_list) {
 		if (!dev->bdev) {
-			errors++;
+			errors_send++;
 			continue;
 		}
 		if (!dev->in_fs_metadata || !dev->writeable)
@@ -2933,13 +2944,13 @@
 
 		ret = write_dev_flush(dev, 0);
 		if (ret)
-			errors++;
+			errors_send++;
 	}
 
 	/* wait for all the barriers */
 	list_for_each_entry_rcu(dev, head, dev_list) {
 		if (!dev->bdev) {
-			errors++;
+			errors_wait++;
 			continue;
 		}
 		if (!dev->in_fs_metadata || !dev->writeable)
@@ -2947,13 +2958,87 @@
 
 		ret = write_dev_flush(dev, 1);
 		if (ret)
-			errors++;
+			errors_wait++;
 	}
-	if (errors)
+	if (errors_send > info->num_tolerated_disk_barrier_failures ||
+	    errors_wait > info->num_tolerated_disk_barrier_failures)
 		return -EIO;
 	return 0;
 }
 
+int btrfs_calc_num_tolerated_disk_barrier_failures(
+	struct btrfs_fs_info *fs_info)
+{
+	struct btrfs_ioctl_space_info space;
+	struct btrfs_space_info *sinfo;
+	u64 types[] = {BTRFS_BLOCK_GROUP_DATA,
+		       BTRFS_BLOCK_GROUP_SYSTEM,
+		       BTRFS_BLOCK_GROUP_METADATA,
+		       BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_METADATA};
+	int num_types = 4;
+	int i;
+	int c;
+	int num_tolerated_disk_barrier_failures =
+		(int)fs_info->fs_devices->num_devices;
+
+	for (i = 0; i < num_types; i++) {
+		struct btrfs_space_info *tmp;
+
+		sinfo = NULL;
+		rcu_read_lock();
+		list_for_each_entry_rcu(tmp, &fs_info->space_info, list) {
+			if (tmp->flags == types[i]) {
+				sinfo = tmp;
+				break;
+			}
+		}
+		rcu_read_unlock();
+
+		if (!sinfo)
+			continue;
+
+		down_read(&sinfo->groups_sem);
+		for (c = 0; c < BTRFS_NR_RAID_TYPES; c++) {
+			if (!list_empty(&sinfo->block_groups[c])) {
+				u64 flags;
+
+				btrfs_get_block_group_info(
+					&sinfo->block_groups[c], &space);
+				if (space.total_bytes == 0 ||
+				    space.used_bytes == 0)
+					continue;
+				flags = space.flags;
+				/*
+				 * return
+				 * 0: if dup, single or RAID0 is configured for
+				 *    any of metadata, system or data, else
+				 * 1: if RAID5 is configured, or if RAID1 or
+				 *    RAID10 is configured and only two mirrors
+				 *    are used, else
+				 * 2: if RAID6 is configured, else
+				 * num_mirrors - 1: if RAID1 or RAID10 is
+				 *                  configured and more than
+				 *                  2 mirrors are used.
+				 */
+				if (num_tolerated_disk_barrier_failures > 0 &&
+				    ((flags & (BTRFS_BLOCK_GROUP_DUP |
+					       BTRFS_BLOCK_GROUP_RAID0)) ||
+				     ((flags & BTRFS_BLOCK_GROUP_PROFILE_MASK)
+				      == 0)))
+					num_tolerated_disk_barrier_failures = 0;
+				else if (num_tolerated_disk_barrier_failures > 1
+					 &&
+					 (flags & (BTRFS_BLOCK_GROUP_RAID1 |
+						   BTRFS_BLOCK_GROUP_RAID10)))
+					num_tolerated_disk_barrier_failures = 1;
+			}
+		}
+		up_read(&sinfo->groups_sem);
+	}
+
+	return num_tolerated_disk_barrier_failures;
+}
+
 int write_all_supers(struct btrfs_root *root, int max_mirrors)
 {
 	struct list_head *head;
@@ -2976,8 +3061,16 @@
 	mutex_lock(&root->fs_info->fs_devices->device_list_mutex);
 	head = &root->fs_info->fs_devices->devices;
 
-	if (do_barriers)
-		barrier_all_devices(root->fs_info);
+	if (do_barriers) {
+		ret = barrier_all_devices(root->fs_info);
+		if (ret) {
+			mutex_unlock(
+				&root->fs_info->fs_devices->device_list_mutex);
+			btrfs_error(root->fs_info, ret,
+				    "errors while submitting device barriers.");
+			return ret;
+		}
+	}
 
 	list_for_each_entry_rcu(dev, head, dev_list) {
 		if (!dev->bdev) {
@@ -3211,10 +3304,6 @@
 		printk(KERN_INFO "btrfs: at unmount delalloc count %llu\n",
 		       (unsigned long long)fs_info->delalloc_bytes);
 	}
-	if (fs_info->total_ref_cache_size) {
-		printk(KERN_INFO "btrfs: at umount reference cache size %llu\n",
-		       (unsigned long long)fs_info->total_ref_cache_size);
-	}
 
 	free_extent_buffer(fs_info->extent_root->node);
 	free_extent_buffer(fs_info->extent_root->commit_root);
@@ -3360,52 +3449,6 @@
 	return btree_read_extent_buffer_pages(root, buf, 0, parent_transid);
 }
 
-int btree_lock_page_hook(struct page *page, void *data,
-				void (*flush_fn)(void *))
-{
-	struct inode *inode = page->mapping->host;
-	struct btrfs_root *root = BTRFS_I(inode)->root;
-	struct extent_buffer *eb;
-
-	/*
-	 * We culled this eb but the page is still hanging out on the mapping,
-	 * carry on.
-	 */
-	if (!PagePrivate(page))
-		goto out;
-
-	eb = (struct extent_buffer *)page->private;
-	if (!eb) {
-		WARN_ON(1);
-		goto out;
-	}
-	if (page != eb->pages[0])
-		goto out;
-
-	if (!btrfs_try_tree_write_lock(eb)) {
-		flush_fn(data);
-		btrfs_tree_lock(eb);
-	}
-	btrfs_set_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN);
-
-	if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &eb->bflags)) {
-		spin_lock(&root->fs_info->delalloc_lock);
-		if (root->fs_info->dirty_metadata_bytes >= eb->len)
-			root->fs_info->dirty_metadata_bytes -= eb->len;
-		else
-			WARN_ON(1);
-		spin_unlock(&root->fs_info->delalloc_lock);
-	}
-
-	btrfs_tree_unlock(eb);
-out:
-	if (!trylock_page(page)) {
-		flush_fn(data);
-		lock_page(page);
-	}
-	return 0;
-}
-
 static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info,
 			      int read_only)
 {
@@ -3608,7 +3651,7 @@
 
 	while (1) {
 		ret = find_first_extent_bit(dirty_pages, start, &start, &end,
-					    mark);
+					    mark, NULL);
 		if (ret)
 			break;
 
@@ -3663,7 +3706,7 @@
 again:
 	while (1) {
 		ret = find_first_extent_bit(unpin, 0, &start, &end,
-					    EXTENT_DIRTY);
+					    EXTENT_DIRTY, NULL);
 		if (ret)
 			break;
 
@@ -3800,7 +3843,6 @@
 }
 
 static struct extent_io_ops btree_extent_io_ops = {
-	.write_cache_pages_lock_hook = btree_lock_page_hook,
 	.readpage_end_io_hook = btree_readpage_end_io_hook,
 	.readpage_io_failed_hook = btree_io_failed_hook,
 	.submit_bio_hook = btree_submit_bio_hook,
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index c5b00a7..2025a91 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -95,6 +95,8 @@
 				     u64 objectid);
 int btree_lock_page_hook(struct page *page, void *data,
 				void (*flush_fn)(void *));
+int btrfs_calc_num_tolerated_disk_barrier_failures(
+	struct btrfs_fs_info *fs_info);
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 void btrfs_init_lockdep(void);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index ba58024..3d3e2c1 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -94,8 +94,8 @@
 				     u64 flags, struct btrfs_disk_key *key,
 				     int level, struct btrfs_key *ins);
 static int do_chunk_alloc(struct btrfs_trans_handle *trans,
-			  struct btrfs_root *extent_root, u64 alloc_bytes,
-			  u64 flags, int force);
+			  struct btrfs_root *extent_root, u64 flags,
+			  int force);
 static int find_next_key(struct btrfs_path *path, int level,
 			 struct btrfs_key *key);
 static void dump_space_info(struct btrfs_space_info *info, u64 bytes,
@@ -312,7 +312,8 @@
 	while (start < end) {
 		ret = find_first_extent_bit(info->pinned_extents, start,
 					    &extent_start, &extent_end,
-					    EXTENT_DIRTY | EXTENT_UPTODATE);
+					    EXTENT_DIRTY | EXTENT_UPTODATE,
+					    NULL);
 		if (ret)
 			break;
 
@@ -2361,10 +2362,6 @@
 		}
 
 next:
-		do_chunk_alloc(trans, fs_info->extent_root,
-			       2 * 1024 * 1024,
-			       btrfs_get_alloc_profile(root, 0),
-			       CHUNK_ALLOC_NO_FORCE);
 		cond_resched();
 		spin_lock(&delayed_refs->lock);
 	}
@@ -2478,10 +2475,6 @@
 	if (root == root->fs_info->extent_root)
 		root = root->fs_info->tree_root;
 
-	do_chunk_alloc(trans, root->fs_info->extent_root,
-		       2 * 1024 * 1024, btrfs_get_alloc_profile(root, 0),
-		       CHUNK_ALLOC_NO_FORCE);
-
 	btrfs_delayed_refs_qgroup_accounting(trans, root->fs_info);
 
 	delayed_refs = &trans->transaction->delayed_refs;
@@ -2551,6 +2544,12 @@
 	}
 
 	if (run_all) {
+		if (!list_empty(&trans->new_bgs)) {
+			spin_unlock(&delayed_refs->lock);
+			btrfs_create_pending_block_groups(trans, root);
+			spin_lock(&delayed_refs->lock);
+		}
+
 		node = rb_first(&delayed_refs->root);
 		if (!node)
 			goto out;
@@ -3406,7 +3405,6 @@
 				return PTR_ERR(trans);
 
 			ret = do_chunk_alloc(trans, root->fs_info->extent_root,
-					     bytes + 2 * 1024 * 1024,
 					     alloc_target,
 					     CHUNK_ALLOC_NO_FORCE);
 			btrfs_end_transaction(trans, root);
@@ -3488,8 +3486,7 @@
 }
 
 static int should_alloc_chunk(struct btrfs_root *root,
-			      struct btrfs_space_info *sinfo, u64 alloc_bytes,
-			      int force)
+			      struct btrfs_space_info *sinfo, int force)
 {
 	struct btrfs_block_rsv *global_rsv = &root->fs_info->global_block_rsv;
 	u64 num_bytes = sinfo->total_bytes - sinfo->bytes_readonly;
@@ -3504,7 +3501,8 @@
 	 * and purposes it's used space.  Don't worry about locking the
 	 * global_rsv, it doesn't change except when the transaction commits.
 	 */
-	num_allocated += global_rsv->size;
+	if (sinfo->flags & BTRFS_BLOCK_GROUP_METADATA)
+		num_allocated += global_rsv->size;
 
 	/*
 	 * in limited mode, we want to have some free space up to
@@ -3518,15 +3516,8 @@
 		if (num_bytes - num_allocated < thresh)
 			return 1;
 	}
-	thresh = btrfs_super_total_bytes(root->fs_info->super_copy);
 
-	/* 256MB or 2% of the FS */
-	thresh = max_t(u64, 256 * 1024 * 1024, div_factor_fine(thresh, 2));
-	/* system chunks need a much small threshold */
-	if (sinfo->flags & BTRFS_BLOCK_GROUP_SYSTEM)
-		thresh = 32 * 1024 * 1024;
-
-	if (num_bytes > thresh && sinfo->bytes_used < div_factor(num_bytes, 8))
+	if (num_allocated + 2 * 1024 * 1024 < div_factor(num_bytes, 8))
 		return 0;
 	return 1;
 }
@@ -3576,8 +3567,7 @@
 }
 
 static int do_chunk_alloc(struct btrfs_trans_handle *trans,
-			  struct btrfs_root *extent_root, u64 alloc_bytes,
-			  u64 flags, int force)
+			  struct btrfs_root *extent_root, u64 flags, int force)
 {
 	struct btrfs_space_info *space_info;
 	struct btrfs_fs_info *fs_info = extent_root->fs_info;
@@ -3601,7 +3591,7 @@
 		return 0;
 	}
 
-	if (!should_alloc_chunk(extent_root, space_info, alloc_bytes, force)) {
+	if (!should_alloc_chunk(extent_root, space_info, force)) {
 		spin_unlock(&space_info->lock);
 		return 0;
 	} else if (space_info->chunk_alloc) {
@@ -3669,6 +3659,46 @@
 	return ret;
 }
 
+static int can_overcommit(struct btrfs_root *root,
+			  struct btrfs_space_info *space_info, u64 bytes,
+			  int flush)
+{
+	u64 profile = btrfs_get_alloc_profile(root, 0);
+	u64 avail;
+	u64 used;
+
+	used = space_info->bytes_used + space_info->bytes_reserved +
+		space_info->bytes_pinned + space_info->bytes_readonly +
+		space_info->bytes_may_use;
+
+	spin_lock(&root->fs_info->free_chunk_lock);
+	avail = root->fs_info->free_chunk_space;
+	spin_unlock(&root->fs_info->free_chunk_lock);
+
+	/*
+	 * If we have dup, raid1 or raid10 then only half of the free
+	 * space is actually useable.
+	 */
+	if (profile & (BTRFS_BLOCK_GROUP_DUP |
+		       BTRFS_BLOCK_GROUP_RAID1 |
+		       BTRFS_BLOCK_GROUP_RAID10))
+		avail >>= 1;
+
+	/*
+	 * If we aren't flushing don't let us overcommit too much, say
+	 * 1/8th of the space.  If we can flush, let it overcommit up to
+	 * 1/2 of the space.
+	 */
+	if (flush)
+		avail >>= 3;
+	else
+		avail >>= 1;
+
+	if (used + bytes < space_info->total_bytes + avail)
+		return 1;
+	return 0;
+}
+
 /*
  * shrink metadata reservation for delalloc
  */
@@ -3693,7 +3723,7 @@
 	if (delalloc_bytes == 0) {
 		if (trans)
 			return;
-		btrfs_wait_ordered_extents(root, 0, 0);
+		btrfs_wait_ordered_extents(root, 0);
 		return;
 	}
 
@@ -3703,11 +3733,15 @@
 		writeback_inodes_sb_nr_if_idle(root->fs_info->sb, nr_pages,
 					       WB_REASON_FS_FREE_SPACE);
 
+		/*
+		 * We need to wait for the async pages to actually start before
+		 * we do anything.
+		 */
+		wait_event(root->fs_info->async_submit_wait,
+			   !atomic_read(&root->fs_info->async_delalloc_pages));
+
 		spin_lock(&space_info->lock);
-		if (space_info->bytes_used + space_info->bytes_reserved +
-		    space_info->bytes_pinned + space_info->bytes_readonly +
-		    space_info->bytes_may_use + orig <=
-		    space_info->total_bytes) {
+		if (can_overcommit(root, space_info, orig, !trans)) {
 			spin_unlock(&space_info->lock);
 			break;
 		}
@@ -3715,7 +3749,7 @@
 
 		loops++;
 		if (wait_ordered && !trans) {
-			btrfs_wait_ordered_extents(root, 0, 0);
+			btrfs_wait_ordered_extents(root, 0);
 		} else {
 			time_left = schedule_timeout_killable(1);
 			if (time_left)
@@ -3784,11 +3818,12 @@
 }
 
 enum flush_state {
-	FLUSH_DELALLOC		=	1,
-	FLUSH_DELALLOC_WAIT	=	2,
-	FLUSH_DELAYED_ITEMS_NR	=	3,
-	FLUSH_DELAYED_ITEMS	=	4,
-	COMMIT_TRANS		=	5,
+	FLUSH_DELAYED_ITEMS_NR	=	1,
+	FLUSH_DELAYED_ITEMS	=	2,
+	FLUSH_DELALLOC		=	3,
+	FLUSH_DELALLOC_WAIT	=	4,
+	ALLOC_CHUNK		=	5,
+	COMMIT_TRANS		=	6,
 };
 
 static int flush_space(struct btrfs_root *root,
@@ -3800,11 +3835,6 @@
 	int ret = 0;
 
 	switch (state) {
-	case FLUSH_DELALLOC:
-	case FLUSH_DELALLOC_WAIT:
-		shrink_delalloc(root, num_bytes, orig_bytes,
-				state == FLUSH_DELALLOC_WAIT);
-		break;
 	case FLUSH_DELAYED_ITEMS_NR:
 	case FLUSH_DELAYED_ITEMS:
 		if (state == FLUSH_DELAYED_ITEMS_NR) {
@@ -3825,6 +3855,24 @@
 		ret = btrfs_run_delayed_items_nr(trans, root, nr);
 		btrfs_end_transaction(trans, root);
 		break;
+	case FLUSH_DELALLOC:
+	case FLUSH_DELALLOC_WAIT:
+		shrink_delalloc(root, num_bytes, orig_bytes,
+				state == FLUSH_DELALLOC_WAIT);
+		break;
+	case ALLOC_CHUNK:
+		trans = btrfs_join_transaction(root);
+		if (IS_ERR(trans)) {
+			ret = PTR_ERR(trans);
+			break;
+		}
+		ret = do_chunk_alloc(trans, root->fs_info->extent_root,
+				     btrfs_get_alloc_profile(root, 0),
+				     CHUNK_ALLOC_NO_FORCE);
+		btrfs_end_transaction(trans, root);
+		if (ret == -ENOSPC)
+			ret = 0;
+		break;
 	case COMMIT_TRANS:
 		ret = may_commit_transaction(root, space_info, orig_bytes, 0);
 		break;
@@ -3856,10 +3904,9 @@
 	struct btrfs_space_info *space_info = block_rsv->space_info;
 	u64 used;
 	u64 num_bytes = orig_bytes;
-	int flush_state = FLUSH_DELALLOC;
+	int flush_state = FLUSH_DELAYED_ITEMS_NR;
 	int ret = 0;
 	bool flushing = false;
-	bool committed = false;
 
 again:
 	ret = 0;
@@ -3922,57 +3969,12 @@
 			(orig_bytes * 2);
 	}
 
-	if (ret) {
-		u64 profile = btrfs_get_alloc_profile(root, 0);
-		u64 avail;
-
-		/*
-		 * If we have a lot of space that's pinned, don't bother doing
-		 * the overcommit dance yet and just commit the transaction.
-		 */
-		avail = (space_info->total_bytes - space_info->bytes_used) * 8;
-		do_div(avail, 10);
-		if (space_info->bytes_pinned >= avail && flush && !committed) {
-			space_info->flush = 1;
-			flushing = true;
-			spin_unlock(&space_info->lock);
-			ret = may_commit_transaction(root, space_info,
-						     orig_bytes, 1);
-			if (ret)
-				goto out;
-			committed = true;
-			goto again;
-		}
-
-		spin_lock(&root->fs_info->free_chunk_lock);
-		avail = root->fs_info->free_chunk_space;
-
-		/*
-		 * If we have dup, raid1 or raid10 then only half of the free
-		 * space is actually useable.
-		 */
-		if (profile & (BTRFS_BLOCK_GROUP_DUP |
-			       BTRFS_BLOCK_GROUP_RAID1 |
-			       BTRFS_BLOCK_GROUP_RAID10))
-			avail >>= 1;
-
-		/*
-		 * If we aren't flushing don't let us overcommit too much, say
-		 * 1/8th of the space.  If we can flush, let it overcommit up to
-		 * 1/2 of the space.
-		 */
-		if (flush)
-			avail >>= 3;
-		else
-			avail >>= 1;
-		 spin_unlock(&root->fs_info->free_chunk_lock);
-
-		if (used + num_bytes < space_info->total_bytes + avail) {
-			space_info->bytes_may_use += orig_bytes;
-			trace_btrfs_space_reservation(root->fs_info,
-				"space_info", space_info->flags, orig_bytes, 1);
-			ret = 0;
-		}
+	if (ret && can_overcommit(root, space_info, orig_bytes, flush)) {
+		space_info->bytes_may_use += orig_bytes;
+		trace_btrfs_space_reservation(root->fs_info, "space_info",
+					      space_info->flags, orig_bytes,
+					      1);
+		ret = 0;
 	}
 
 	/*
@@ -4114,13 +4116,15 @@
 	return 0;
 }
 
-void btrfs_init_block_rsv(struct btrfs_block_rsv *rsv)
+void btrfs_init_block_rsv(struct btrfs_block_rsv *rsv, unsigned short type)
 {
 	memset(rsv, 0, sizeof(*rsv));
 	spin_lock_init(&rsv->lock);
+	rsv->type = type;
 }
 
-struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_root *root)
+struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_root *root,
+					      unsigned short type)
 {
 	struct btrfs_block_rsv *block_rsv;
 	struct btrfs_fs_info *fs_info = root->fs_info;
@@ -4129,7 +4133,7 @@
 	if (!block_rsv)
 		return NULL;
 
-	btrfs_init_block_rsv(block_rsv);
+	btrfs_init_block_rsv(block_rsv, type);
 	block_rsv->space_info = __find_space_info(fs_info,
 						  BTRFS_BLOCK_GROUP_METADATA);
 	return block_rsv;
@@ -4138,6 +4142,8 @@
 void btrfs_free_block_rsv(struct btrfs_root *root,
 			  struct btrfs_block_rsv *rsv)
 {
+	if (!rsv)
+		return;
 	btrfs_block_rsv_release(root, rsv, (u64)-1);
 	kfree(rsv);
 }
@@ -4416,10 +4422,10 @@
 	struct btrfs_block_rsv *src_rsv = get_block_rsv(trans, root);
 	struct btrfs_block_rsv *dst_rsv = &pending->block_rsv;
 	/*
-	 * two for root back/forward refs, two for directory entries
-	 * and one for root of the snapshot.
+	 * two for root back/forward refs, two for directory entries,
+	 * one for root of the snapshot and one for parent inode.
 	 */
-	u64 num_bytes = btrfs_calc_trans_metadata_size(root, 5);
+	u64 num_bytes = btrfs_calc_trans_metadata_size(root, 6);
 	dst_rsv->space_info = src_rsv->space_info;
 	return block_rsv_migrate_bytes(src_rsv, dst_rsv, num_bytes);
 }
@@ -5018,7 +5024,7 @@
 
 	while (1) {
 		ret = find_first_extent_bit(unpin, 0, &start, &end,
-					    EXTENT_DIRTY);
+					    EXTENT_DIRTY, NULL);
 		if (ret)
 			break;
 
@@ -5096,8 +5102,10 @@
 			ret = remove_extent_backref(trans, extent_root, path,
 						    NULL, refs_to_drop,
 						    is_data);
-			if (ret)
-				goto abort;
+			if (ret) {
+				btrfs_abort_transaction(trans, extent_root, ret);
+				goto out;
+			}
 			btrfs_release_path(path);
 			path->leave_spinning = 1;
 
@@ -5115,8 +5123,10 @@
 					btrfs_print_leaf(extent_root,
 							 path->nodes[0]);
 			}
-			if (ret < 0)
-				goto abort;
+			if (ret < 0) {
+				btrfs_abort_transaction(trans, extent_root, ret);
+				goto out;
+			}
 			extent_slot = path->slots[0];
 		}
 	} else if (ret == -ENOENT) {
@@ -5130,7 +5140,8 @@
 		       (unsigned long long)owner_objectid,
 		       (unsigned long long)owner_offset);
 	} else {
-		goto abort;
+		btrfs_abort_transaction(trans, extent_root, ret);
+		goto out;
 	}
 
 	leaf = path->nodes[0];
@@ -5140,8 +5151,10 @@
 		BUG_ON(found_extent || extent_slot != path->slots[0]);
 		ret = convert_extent_item_v0(trans, extent_root, path,
 					     owner_objectid, 0);
-		if (ret < 0)
-			goto abort;
+		if (ret < 0) {
+			btrfs_abort_transaction(trans, extent_root, ret);
+			goto out;
+		}
 
 		btrfs_release_path(path);
 		path->leave_spinning = 1;
@@ -5158,8 +5171,11 @@
 			       (unsigned long long)bytenr);
 			btrfs_print_leaf(extent_root, path->nodes[0]);
 		}
-		if (ret < 0)
-			goto abort;
+		if (ret < 0) {
+			btrfs_abort_transaction(trans, extent_root, ret);
+			goto out;
+		}
+
 		extent_slot = path->slots[0];
 		leaf = path->nodes[0];
 		item_size = btrfs_item_size_nr(leaf, extent_slot);
@@ -5196,8 +5212,10 @@
 			ret = remove_extent_backref(trans, extent_root, path,
 						    iref, refs_to_drop,
 						    is_data);
-			if (ret)
-				goto abort;
+			if (ret) {
+				btrfs_abort_transaction(trans, extent_root, ret);
+				goto out;
+			}
 		}
 	} else {
 		if (found_extent) {
@@ -5214,27 +5232,29 @@
 
 		ret = btrfs_del_items(trans, extent_root, path, path->slots[0],
 				      num_to_del);
-		if (ret)
-			goto abort;
+		if (ret) {
+			btrfs_abort_transaction(trans, extent_root, ret);
+			goto out;
+		}
 		btrfs_release_path(path);
 
 		if (is_data) {
 			ret = btrfs_del_csums(trans, root, bytenr, num_bytes);
-			if (ret)
-				goto abort;
+			if (ret) {
+				btrfs_abort_transaction(trans, extent_root, ret);
+				goto out;
+			}
 		}
 
 		ret = update_block_group(trans, root, bytenr, num_bytes, 0);
-		if (ret)
-			goto abort;
+		if (ret) {
+			btrfs_abort_transaction(trans, extent_root, ret);
+			goto out;
+		}
 	}
 out:
 	btrfs_free_path(path);
 	return ret;
-
-abort:
-	btrfs_abort_transaction(trans, extent_root, ret);
-	goto out;
 }
 
 /*
@@ -5497,8 +5517,6 @@
 	struct btrfs_block_group_cache *used_block_group;
 	u64 search_start = 0;
 	int empty_cluster = 2 * 1024 * 1024;
-	int allowed_chunk_alloc = 0;
-	int done_chunk_alloc = 0;
 	struct btrfs_space_info *space_info;
 	int loop = 0;
 	int index = 0;
@@ -5530,9 +5548,6 @@
 	if (btrfs_mixed_space_info(space_info))
 		use_cluster = false;
 
-	if (orig_root->ref_cows || empty_size)
-		allowed_chunk_alloc = 1;
-
 	if (data & BTRFS_BLOCK_GROUP_METADATA && use_cluster) {
 		last_ptr = &root->fs_info->meta_alloc_cluster;
 		if (!btrfs_test_opt(root, SSD))
@@ -5806,10 +5821,6 @@
 
 		trace_btrfs_reserve_extent(orig_root, block_group,
 					   search_start, num_bytes);
-		if (offset < search_start)
-			btrfs_add_free_space(used_block_group, offset,
-					     search_start - offset);
-		BUG_ON(offset > search_start);
 		if (used_block_group != block_group)
 			btrfs_put_block_group(used_block_group);
 		btrfs_put_block_group(block_group);
@@ -5842,34 +5853,17 @@
 		index = 0;
 		loop++;
 		if (loop == LOOP_ALLOC_CHUNK) {
-		       if (allowed_chunk_alloc) {
-				ret = do_chunk_alloc(trans, root, num_bytes +
-						     2 * 1024 * 1024, data,
-						     CHUNK_ALLOC_LIMITED);
-				/*
-				 * Do not bail out on ENOSPC since we
-				 * can do more things.
-				 */
-				if (ret < 0 && ret != -ENOSPC) {
-					btrfs_abort_transaction(trans,
-								root, ret);
-					goto out;
-				}
-				allowed_chunk_alloc = 0;
-				if (ret == 1)
-					done_chunk_alloc = 1;
-			} else if (!done_chunk_alloc &&
-				   space_info->force_alloc ==
-				   CHUNK_ALLOC_NO_FORCE) {
-				space_info->force_alloc = CHUNK_ALLOC_LIMITED;
+			ret = do_chunk_alloc(trans, root, data,
+					     CHUNK_ALLOC_FORCE);
+			/*
+			 * Do not bail out on ENOSPC since we
+			 * can do more things.
+			 */
+			if (ret < 0 && ret != -ENOSPC) {
+				btrfs_abort_transaction(trans,
+							root, ret);
+				goto out;
 			}
-
-		       /*
-			* We didn't allocate a chunk, go ahead and drop the
-			* empty size and loop again.
-			*/
-		       if (!done_chunk_alloc)
-			       loop = LOOP_NO_EMPTY_SIZE;
 		}
 
 		if (loop == LOOP_NO_EMPTY_SIZE) {
@@ -5944,20 +5938,6 @@
 
 	data = btrfs_get_alloc_profile(root, data);
 again:
-	/*
-	 * the only place that sets empty_size is btrfs_realloc_node, which
-	 * is not called recursively on allocations
-	 */
-	if (empty_size || root->ref_cows) {
-		ret = do_chunk_alloc(trans, root->fs_info->extent_root,
-				     num_bytes + 2 * 1024 * 1024, data,
-				     CHUNK_ALLOC_NO_FORCE);
-		if (ret < 0 && ret != -ENOSPC) {
-			btrfs_abort_transaction(trans, root, ret);
-			return ret;
-		}
-	}
-
 	WARN_ON(num_bytes < root->sectorsize);
 	ret = find_free_extent(trans, root, num_bytes, empty_size,
 			       hint_byte, ins, data);
@@ -5967,12 +5947,6 @@
 			num_bytes = num_bytes >> 1;
 			num_bytes = num_bytes & ~(root->sectorsize - 1);
 			num_bytes = max(num_bytes, min_alloc_size);
-			ret = do_chunk_alloc(trans, root->fs_info->extent_root,
-				       num_bytes, data, CHUNK_ALLOC_FORCE);
-			if (ret < 0 && ret != -ENOSPC) {
-				btrfs_abort_transaction(trans, root, ret);
-				return ret;
-			}
 			if (num_bytes == min_alloc_size)
 				final_tried = true;
 			goto again;
@@ -6314,7 +6288,7 @@
 	ret = block_rsv_use_bytes(block_rsv, blocksize);
 	if (!ret)
 		return block_rsv;
-	if (ret) {
+	if (ret && !block_rsv->failfast) {
 		static DEFINE_RATELIMIT_STATE(_rs,
 				DEFAULT_RATELIMIT_INTERVAL,
 				/*DEFAULT_RATELIMIT_BURST*/ 2);
@@ -7279,7 +7253,7 @@
 
 	alloc_flags = update_block_group_flags(root, cache->flags);
 	if (alloc_flags != cache->flags) {
-		ret = do_chunk_alloc(trans, root, 2 * 1024 * 1024, alloc_flags,
+		ret = do_chunk_alloc(trans, root, alloc_flags,
 				     CHUNK_ALLOC_FORCE);
 		if (ret < 0)
 			goto out;
@@ -7289,7 +7263,7 @@
 	if (!ret)
 		goto out;
 	alloc_flags = get_alloc_profile(root, cache->space_info->flags);
-	ret = do_chunk_alloc(trans, root, 2 * 1024 * 1024, alloc_flags,
+	ret = do_chunk_alloc(trans, root, alloc_flags,
 			     CHUNK_ALLOC_FORCE);
 	if (ret < 0)
 		goto out;
@@ -7303,7 +7277,7 @@
 			    struct btrfs_root *root, u64 type)
 {
 	u64 alloc_flags = get_alloc_profile(root, type);
-	return do_chunk_alloc(trans, root, 2 * 1024 * 1024, alloc_flags,
+	return do_chunk_alloc(trans, root, alloc_flags,
 			      CHUNK_ALLOC_FORCE);
 }
 
@@ -7810,6 +7784,34 @@
 	return ret;
 }
 
+void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans,
+				       struct btrfs_root *root)
+{
+	struct btrfs_block_group_cache *block_group, *tmp;
+	struct btrfs_root *extent_root = root->fs_info->extent_root;
+	struct btrfs_block_group_item item;
+	struct btrfs_key key;
+	int ret = 0;
+
+	list_for_each_entry_safe(block_group, tmp, &trans->new_bgs,
+				 new_bg_list) {
+		list_del_init(&block_group->new_bg_list);
+
+		if (ret)
+			continue;
+
+		spin_lock(&block_group->lock);
+		memcpy(&item, &block_group->item, sizeof(item));
+		memcpy(&key, &block_group->key, sizeof(key));
+		spin_unlock(&block_group->lock);
+
+		ret = btrfs_insert_item(trans, extent_root, &key, &item,
+					sizeof(item));
+		if (ret)
+			btrfs_abort_transaction(trans, extent_root, ret);
+	}
+}
+
 int btrfs_make_block_group(struct btrfs_trans_handle *trans,
 			   struct btrfs_root *root, u64 bytes_used,
 			   u64 type, u64 chunk_objectid, u64 chunk_offset,
@@ -7843,6 +7845,7 @@
 	spin_lock_init(&cache->lock);
 	INIT_LIST_HEAD(&cache->list);
 	INIT_LIST_HEAD(&cache->cluster_list);
+	INIT_LIST_HEAD(&cache->new_bg_list);
 
 	btrfs_init_free_space_ctl(cache);
 
@@ -7874,12 +7877,7 @@
 	ret = btrfs_add_block_group_cache(root->fs_info, cache);
 	BUG_ON(ret); /* Logic error */
 
-	ret = btrfs_insert_item(trans, extent_root, &cache->key, &cache->item,
-				sizeof(cache->item));
-	if (ret) {
-		btrfs_abort_transaction(trans, extent_root, ret);
-		return ret;
-	}
+	list_add_tail(&cache->new_bg_list, &trans->new_bgs);
 
 	set_avail_alloc_bits(extent_root->fs_info, type);
 
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index b08ea47..8036d3a 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -45,6 +45,7 @@
 	struct bio *bio;
 	struct extent_io_tree *tree;
 	get_extent_t *get_extent;
+	unsigned long bio_flags;
 
 	/* tells writepage not to lock the state bits for this range
 	 * it still does the unlocking
@@ -64,13 +65,13 @@
 
 int __init extent_io_init(void)
 {
-	extent_state_cache = kmem_cache_create("extent_state",
+	extent_state_cache = kmem_cache_create("btrfs_extent_state",
 			sizeof(struct extent_state), 0,
 			SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
 	if (!extent_state_cache)
 		return -ENOMEM;
 
-	extent_buffer_cache = kmem_cache_create("extent_buffers",
+	extent_buffer_cache = kmem_cache_create("btrfs_extent_buffer",
 			sizeof(struct extent_buffer), 0,
 			SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
 	if (!extent_buffer_cache)
@@ -942,6 +943,7 @@
  * @end:	the end offset in bytes (inclusive)
  * @bits:	the bits to set in this range
  * @clear_bits:	the bits to clear in this range
+ * @cached_state:	state that we're going to cache
  * @mask:	the allocation mask
  *
  * This will go through and set bits for the given range.  If any states exist
@@ -951,7 +953,8 @@
  * boundary bits like LOCK.
  */
 int convert_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
-		       int bits, int clear_bits, gfp_t mask)
+		       int bits, int clear_bits,
+		       struct extent_state **cached_state, gfp_t mask)
 {
 	struct extent_state *state;
 	struct extent_state *prealloc = NULL;
@@ -968,6 +971,15 @@
 	}
 
 	spin_lock(&tree->lock);
+	if (cached_state && *cached_state) {
+		state = *cached_state;
+		if (state->start <= start && state->end > start &&
+		    state->tree) {
+			node = &state->rb_node;
+			goto hit_next;
+		}
+	}
+
 	/*
 	 * this search will find all the extents that end after
 	 * our range starts.
@@ -998,6 +1010,7 @@
 	 */
 	if (state->start == start && state->end <= end) {
 		set_state_bits(tree, state, &bits);
+		cache_state(state, cached_state);
 		state = clear_state_bit(tree, state, &clear_bits, 0);
 		if (last_end == (u64)-1)
 			goto out;
@@ -1038,6 +1051,7 @@
 			goto out;
 		if (state->end <= end) {
 			set_state_bits(tree, state, &bits);
+			cache_state(state, cached_state);
 			state = clear_state_bit(tree, state, &clear_bits, 0);
 			if (last_end == (u64)-1)
 				goto out;
@@ -1076,6 +1090,7 @@
 				   &bits);
 		if (err)
 			extent_io_tree_panic(tree, err);
+		cache_state(prealloc, cached_state);
 		prealloc = NULL;
 		start = this_end + 1;
 		goto search_again;
@@ -1098,6 +1113,7 @@
 			extent_io_tree_panic(tree, err);
 
 		set_state_bits(tree, prealloc, &bits);
+		cache_state(prealloc, cached_state);
 		clear_state_bit(tree, prealloc, &clear_bits, 0);
 		prealloc = NULL;
 		goto out;
@@ -1150,6 +1166,14 @@
 			      NULL, cached_state, mask);
 }
 
+int set_extent_defrag(struct extent_io_tree *tree, u64 start, u64 end,
+		      struct extent_state **cached_state, gfp_t mask)
+{
+	return set_extent_bit(tree, start, end,
+			      EXTENT_DELALLOC | EXTENT_UPTODATE | EXTENT_DEFRAG,
+			      NULL, cached_state, mask);
+}
+
 int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end,
 		       gfp_t mask)
 {
@@ -1294,18 +1318,42 @@
  * If nothing was found, 1 is returned. If found something, return 0.
  */
 int find_first_extent_bit(struct extent_io_tree *tree, u64 start,
-			  u64 *start_ret, u64 *end_ret, int bits)
+			  u64 *start_ret, u64 *end_ret, int bits,
+			  struct extent_state **cached_state)
 {
 	struct extent_state *state;
+	struct rb_node *n;
 	int ret = 1;
 
 	spin_lock(&tree->lock);
+	if (cached_state && *cached_state) {
+		state = *cached_state;
+		if (state->end == start - 1 && state->tree) {
+			n = rb_next(&state->rb_node);
+			while (n) {
+				state = rb_entry(n, struct extent_state,
+						 rb_node);
+				if (state->state & bits)
+					goto got_it;
+				n = rb_next(n);
+			}
+			free_extent_state(*cached_state);
+			*cached_state = NULL;
+			goto out;
+		}
+		free_extent_state(*cached_state);
+		*cached_state = NULL;
+	}
+
 	state = find_first_extent_bit_state(tree, start, bits);
+got_it:
 	if (state) {
+		cache_state(state, cached_state);
 		*start_ret = state->start;
 		*end_ret = state->end;
 		ret = 0;
 	}
+out:
 	spin_unlock(&tree->lock);
 	return ret;
 }
@@ -2068,7 +2116,7 @@
 		}
 		read_unlock(&em_tree->lock);
 
-		if (!em || IS_ERR(em)) {
+		if (!em) {
 			kfree(failrec);
 			return -EIO;
 		}
@@ -2304,8 +2352,8 @@
 		struct extent_state *cached = NULL;
 		struct extent_state *state;
 
-		pr_debug("end_bio_extent_readpage: bi_vcnt=%d, idx=%d, err=%d, "
-			 "mirror=%ld\n", bio->bi_vcnt, bio->bi_idx, err,
+		pr_debug("end_bio_extent_readpage: bi_sector=%llu, err=%d, "
+			 "mirror=%ld\n", (u64)bio->bi_sector, err,
 			 (long int)bio->bi_bdev);
 		tree = &BTRFS_I(page->mapping->host)->io_tree;
 
@@ -2709,12 +2757,15 @@
 					 end_bio_extent_readpage, mirror_num,
 					 *bio_flags,
 					 this_bio_flag);
-			BUG_ON(ret == -ENOMEM);
-			nr++;
-			*bio_flags = this_bio_flag;
+			if (!ret) {
+				nr++;
+				*bio_flags = this_bio_flag;
+			}
 		}
-		if (ret)
+		if (ret) {
 			SetPageError(page);
+			unlock_extent(tree, cur, cur + iosize - 1);
+		}
 		cur = cur + iosize;
 		pg_offset += iosize;
 	}
@@ -3161,12 +3212,16 @@
 	struct block_device *bdev = fs_info->fs_devices->latest_bdev;
 	u64 offset = eb->start;
 	unsigned long i, num_pages;
+	unsigned long bio_flags = 0;
 	int rw = (epd->sync_io ? WRITE_SYNC : WRITE);
 	int ret = 0;
 
 	clear_bit(EXTENT_BUFFER_IOERR, &eb->bflags);
 	num_pages = num_extent_pages(eb->start, eb->len);
 	atomic_set(&eb->io_pages, num_pages);
+	if (btrfs_header_owner(eb) == BTRFS_TREE_LOG_OBJECTID)
+		bio_flags = EXTENT_BIO_TREE_LOG;
+
 	for (i = 0; i < num_pages; i++) {
 		struct page *p = extent_buffer_page(eb, i);
 
@@ -3175,7 +3230,8 @@
 		ret = submit_extent_page(rw, eb->tree, p, offset >> 9,
 					 PAGE_CACHE_SIZE, 0, bdev, &epd->bio,
 					 -1, end_bio_extent_buffer_writepage,
-					 0, 0, 0);
+					 0, epd->bio_flags, bio_flags);
+		epd->bio_flags = bio_flags;
 		if (ret) {
 			set_bit(EXTENT_BUFFER_IOERR, &eb->bflags);
 			SetPageError(p);
@@ -3210,6 +3266,7 @@
 		.tree = tree,
 		.extent_locked = 0,
 		.sync_io = wbc->sync_mode == WB_SYNC_ALL,
+		.bio_flags = 0,
 	};
 	int ret = 0;
 	int done = 0;
@@ -3254,20 +3311,35 @@
 				break;
 			}
 
+			spin_lock(&mapping->private_lock);
+			if (!PagePrivate(page)) {
+				spin_unlock(&mapping->private_lock);
+				continue;
+			}
+
 			eb = (struct extent_buffer *)page->private;
+
+			/*
+			 * Shouldn't happen and normally this would be a BUG_ON
+			 * but no sense in crashing the users box for something
+			 * we can survive anyway.
+			 */
 			if (!eb) {
+				spin_unlock(&mapping->private_lock);
 				WARN_ON(1);
 				continue;
 			}
 
-			if (eb == prev_eb)
-				continue;
-
-			if (!atomic_inc_not_zero(&eb->refs)) {
-				WARN_ON(1);
+			if (eb == prev_eb) {
+				spin_unlock(&mapping->private_lock);
 				continue;
 			}
 
+			ret = atomic_inc_not_zero(&eb->refs);
+			spin_unlock(&mapping->private_lock);
+			if (!ret)
+				continue;
+
 			prev_eb = eb;
 			ret = lock_extent_buffer_for_io(eb, fs_info, &epd);
 			if (!ret) {
@@ -3457,7 +3529,7 @@
 		if (epd->sync_io)
 			rw = WRITE_SYNC;
 
-		ret = submit_one_bio(rw, epd->bio, 0, 0);
+		ret = submit_one_bio(rw, epd->bio, 0, epd->bio_flags);
 		BUG_ON(ret < 0); /* -ENOMEM */
 		epd->bio = NULL;
 	}
@@ -3480,6 +3552,7 @@
 		.get_extent = get_extent,
 		.extent_locked = 0,
 		.sync_io = wbc->sync_mode == WB_SYNC_ALL,
+		.bio_flags = 0,
 	};
 
 	ret = __extent_writepage(page, wbc, &epd);
@@ -3504,6 +3577,7 @@
 		.get_extent = get_extent,
 		.extent_locked = 1,
 		.sync_io = mode == WB_SYNC_ALL,
+		.bio_flags = 0,
 	};
 	struct writeback_control wbc_writepages = {
 		.sync_mode	= mode,
@@ -3543,6 +3617,7 @@
 		.get_extent = get_extent,
 		.extent_locked = 0,
 		.sync_io = wbc->sync_mode == WB_SYNC_ALL,
+		.bio_flags = 0,
 	};
 
 	ret = extent_write_cache_pages(tree, mapping, wbc,
@@ -3920,18 +3995,6 @@
 	return ret;
 }
 
-inline struct page *extent_buffer_page(struct extent_buffer *eb,
-					      unsigned long i)
-{
-	return eb->pages[i];
-}
-
-inline unsigned long num_extent_pages(u64 start, u64 len)
-{
-	return ((start + len + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT) -
-		(start >> PAGE_CACHE_SHIFT);
-}
-
 static void __free_extent_buffer(struct extent_buffer *eb)
 {
 #if LEAK_DEBUG
@@ -4047,7 +4110,7 @@
 
 	return eb;
 err:
-	for (i--; i > 0; i--)
+	for (i--; i >= 0; i--)
 		__free_page(eb->pages[i]);
 	__free_extent_buffer(eb);
 	return NULL;
@@ -4192,10 +4255,8 @@
 
 	for (i = 0; i < num_pages; i++, index++) {
 		p = find_or_create_page(mapping, index, GFP_NOFS);
-		if (!p) {
-			WARN_ON(1);
+		if (!p)
 			goto free_eb;
-		}
 
 		spin_lock(&mapping->private_lock);
 		if (PagePrivate(p)) {
@@ -4338,7 +4399,6 @@
 
 		/* Should be safe to release our pages at this point */
 		btrfs_release_extent_buffer_page(eb, 0);
-
 		call_rcu(&eb->rcu_head, btrfs_release_extent_buffer_rcu);
 		return 1;
 	}
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index 25900af..711d12b 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -27,6 +27,7 @@
  * type for this bio
  */
 #define EXTENT_BIO_COMPRESSED 1
+#define EXTENT_BIO_TREE_LOG 2
 #define EXTENT_BIO_FLAG_SHIFT 16
 
 /* these are bit numbers for test/set bit */
@@ -232,11 +233,15 @@
 int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end,
 		       gfp_t mask);
 int convert_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
-		       int bits, int clear_bits, gfp_t mask);
+		       int bits, int clear_bits,
+		       struct extent_state **cached_state, gfp_t mask);
 int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end,
 			struct extent_state **cached_state, gfp_t mask);
+int set_extent_defrag(struct extent_io_tree *tree, u64 start, u64 end,
+		      struct extent_state **cached_state, gfp_t mask);
 int find_first_extent_bit(struct extent_io_tree *tree, u64 start,
-			  u64 *start_ret, u64 *end_ret, int bits);
+			  u64 *start_ret, u64 *end_ret, int bits,
+			  struct extent_state **cached_state);
 struct extent_state *find_first_extent_bit_state(struct extent_io_tree *tree,
 						 u64 start, int bits);
 int extent_invalidatepage(struct extent_io_tree *tree,
@@ -277,8 +282,18 @@
 int read_extent_buffer_pages(struct extent_io_tree *tree,
 			     struct extent_buffer *eb, u64 start, int wait,
 			     get_extent_t *get_extent, int mirror_num);
-unsigned long num_extent_pages(u64 start, u64 len);
-struct page *extent_buffer_page(struct extent_buffer *eb, unsigned long i);
+
+static inline unsigned long num_extent_pages(u64 start, u64 len)
+{
+	return ((start + len + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT) -
+		(start >> PAGE_CACHE_SHIFT);
+}
+
+static inline struct page *extent_buffer_page(struct extent_buffer *eb,
+					      unsigned long i)
+{
+	return eb->pages[i];
+}
 
 static inline void extent_buffer_get(struct extent_buffer *eb)
 {
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
index 7c97b33..b8cbc8d 100644
--- a/fs/btrfs/extent_map.c
+++ b/fs/btrfs/extent_map.c
@@ -11,7 +11,7 @@
 
 int __init extent_map_init(void)
 {
-	extent_map_cache = kmem_cache_create("extent_map",
+	extent_map_cache = kmem_cache_create("btrfs_extent_map",
 			sizeof(struct extent_map), 0,
 			SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
 	if (!extent_map_cache)
@@ -35,6 +35,7 @@
 void extent_map_tree_init(struct extent_map_tree *tree)
 {
 	tree->map = RB_ROOT;
+	INIT_LIST_HEAD(&tree->modified_extents);
 	rwlock_init(&tree->lock);
 }
 
@@ -54,7 +55,9 @@
 	em->in_tree = 0;
 	em->flags = 0;
 	em->compress_type = BTRFS_COMPRESS_NONE;
+	em->generation = 0;
 	atomic_set(&em->refs, 1);
+	INIT_LIST_HEAD(&em->list);
 	return em;
 }
 
@@ -72,6 +75,7 @@
 	WARN_ON(atomic_read(&em->refs) == 0);
 	if (atomic_dec_and_test(&em->refs)) {
 		WARN_ON(em->in_tree);
+		WARN_ON(!list_empty(&em->list));
 		kmem_cache_free(extent_map_cache, em);
 	}
 }
@@ -198,6 +202,14 @@
 			em->block_len += merge->block_len;
 			em->block_start = merge->block_start;
 			merge->in_tree = 0;
+			if (merge->generation > em->generation) {
+				em->mod_start = em->start;
+				em->mod_len = em->len;
+				em->generation = merge->generation;
+				list_move(&em->list, &tree->modified_extents);
+			}
+
+			list_del_init(&merge->list);
 			rb_erase(&merge->rb_node, &tree->map);
 			free_extent_map(merge);
 		}
@@ -211,14 +223,34 @@
 		em->block_len += merge->len;
 		rb_erase(&merge->rb_node, &tree->map);
 		merge->in_tree = 0;
+		if (merge->generation > em->generation) {
+			em->mod_len = em->len;
+			em->generation = merge->generation;
+			list_move(&em->list, &tree->modified_extents);
+		}
+		list_del_init(&merge->list);
 		free_extent_map(merge);
 	}
 }
 
-int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len)
+/**
+ * unpint_extent_cache - unpin an extent from the cache
+ * @tree:	tree to unpin the extent in
+ * @start:	logical offset in the file
+ * @len:	length of the extent
+ * @gen:	generation that this extent has been modified in
+ * @prealloc:	if this is set we need to clear the prealloc flag
+ *
+ * Called after an extent has been written to disk properly.  Set the generation
+ * to the generation that actually added the file item to the inode so we know
+ * we need to sync this extent when we call fsync().
+ */
+int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len,
+		       u64 gen)
 {
 	int ret = 0;
 	struct extent_map *em;
+	bool prealloc = false;
 
 	write_lock(&tree->lock);
 	em = lookup_extent_mapping(tree, start, len);
@@ -228,10 +260,24 @@
 	if (!em)
 		goto out;
 
+	list_move(&em->list, &tree->modified_extents);
+	em->generation = gen;
 	clear_bit(EXTENT_FLAG_PINNED, &em->flags);
+	em->mod_start = em->start;
+	em->mod_len = em->len;
+
+	if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) {
+		prealloc = true;
+		clear_bit(EXTENT_FLAG_PREALLOC, &em->flags);
+	}
 
 	try_merge_map(tree, em);
 
+	if (prealloc) {
+		em->mod_start = em->start;
+		em->mod_len = em->len;
+	}
+
 	free_extent_map(em);
 out:
 	write_unlock(&tree->lock);
@@ -269,6 +315,9 @@
 	}
 	atomic_inc(&em->refs);
 
+	em->mod_start = em->start;
+	em->mod_len = em->len;
+
 	try_merge_map(tree, em);
 out:
 	return ret;
@@ -358,6 +407,8 @@
 
 	WARN_ON(test_bit(EXTENT_FLAG_PINNED, &em->flags));
 	rb_erase(&em->rb_node, &tree->map);
+	if (!test_bit(EXTENT_FLAG_LOGGING, &em->flags))
+		list_del_init(&em->list);
 	em->in_tree = 0;
 	return ret;
 }
diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h
index 1195f09..6792255 100644
--- a/fs/btrfs/extent_map.h
+++ b/fs/btrfs/extent_map.h
@@ -13,6 +13,7 @@
 #define EXTENT_FLAG_COMPRESSED 1
 #define EXTENT_FLAG_VACANCY 2 /* no file extent item found */
 #define EXTENT_FLAG_PREALLOC 3 /* pre-allocated extent */
+#define EXTENT_FLAG_LOGGING 4 /* Logging this extent */
 
 struct extent_map {
 	struct rb_node rb_node;
@@ -20,18 +21,23 @@
 	/* all of these are in bytes */
 	u64 start;
 	u64 len;
+	u64 mod_start;
+	u64 mod_len;
 	u64 orig_start;
 	u64 block_start;
 	u64 block_len;
+	u64 generation;
 	unsigned long flags;
 	struct block_device *bdev;
 	atomic_t refs;
 	unsigned int in_tree;
 	unsigned int compress_type;
+	struct list_head list;
 };
 
 struct extent_map_tree {
 	struct rb_root map;
+	struct list_head modified_extents;
 	rwlock_t lock;
 };
 
@@ -60,7 +66,7 @@
 void free_extent_map(struct extent_map *em);
 int __init extent_map_init(void);
 void extent_map_exit(void);
-int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len);
+int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len, u64 gen);
 struct extent_map *search_extent_mapping(struct extent_map_tree *tree,
 					 u64 start, u64 len);
 #endif
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index 857d93c..1ad08e4e4 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -25,11 +25,12 @@
 #include "transaction.h"
 #include "print-tree.h"
 
-#define __MAX_CSUM_ITEMS(r, size) ((((BTRFS_LEAF_DATA_SIZE(r) - \
+#define __MAX_CSUM_ITEMS(r, size) ((unsigned long)(((BTRFS_LEAF_DATA_SIZE(r) - \
 				   sizeof(struct btrfs_item) * 2) / \
 				  size) - 1))
 
-#define MAX_CSUM_ITEMS(r, size) (min(__MAX_CSUM_ITEMS(r, size), PAGE_CACHE_SIZE))
+#define MAX_CSUM_ITEMS(r, size) (min_t(u32, __MAX_CSUM_ITEMS(r, size), \
+				       PAGE_CACHE_SIZE))
 
 #define MAX_ORDERED_SUM_BYTES(r) ((PAGE_SIZE - \
 				   sizeof(struct btrfs_ordered_sum)) / \
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 5caf285..9ab1bed 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -39,6 +39,7 @@
 #include "tree-log.h"
 #include "locking.h"
 #include "compat.h"
+#include "volumes.h"
 
 /*
  * when auto defrag is enabled we
@@ -458,14 +459,15 @@
  * this drops all the extents in the cache that intersect the range
  * [start, end].  Existing extents are split as required.
  */
-int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
-			    int skip_pinned)
+void btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
+			     int skip_pinned)
 {
 	struct extent_map *em;
 	struct extent_map *split = NULL;
 	struct extent_map *split2 = NULL;
 	struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
 	u64 len = end - start + 1;
+	u64 gen;
 	int ret;
 	int testend = 1;
 	unsigned long flags;
@@ -477,11 +479,14 @@
 		testend = 0;
 	}
 	while (1) {
+		int no_splits = 0;
+
 		if (!split)
 			split = alloc_extent_map();
 		if (!split2)
 			split2 = alloc_extent_map();
-		BUG_ON(!split || !split2); /* -ENOMEM */
+		if (!split || !split2)
+			no_splits = 1;
 
 		write_lock(&em_tree->lock);
 		em = lookup_extent_mapping(em_tree, start, len);
@@ -490,6 +495,7 @@
 			break;
 		}
 		flags = em->flags;
+		gen = em->generation;
 		if (skip_pinned && test_bit(EXTENT_FLAG_PINNED, &em->flags)) {
 			if (testend && em->start + em->len >= start + len) {
 				free_extent_map(em);
@@ -506,6 +512,8 @@
 		compressed = test_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
 		clear_bit(EXTENT_FLAG_PINNED, &em->flags);
 		remove_extent_mapping(em_tree, em);
+		if (no_splits)
+			goto next;
 
 		if (em->block_start < EXTENT_MAP_LAST_BYTE &&
 		    em->start < start) {
@@ -518,12 +526,13 @@
 				split->block_len = em->block_len;
 			else
 				split->block_len = split->len;
-
+			split->generation = gen;
 			split->bdev = em->bdev;
 			split->flags = flags;
 			split->compress_type = em->compress_type;
 			ret = add_extent_mapping(em_tree, split);
 			BUG_ON(ret); /* Logic error */
+			list_move(&split->list, &em_tree->modified_extents);
 			free_extent_map(split);
 			split = split2;
 			split2 = NULL;
@@ -537,6 +546,7 @@
 			split->bdev = em->bdev;
 			split->flags = flags;
 			split->compress_type = em->compress_type;
+			split->generation = gen;
 
 			if (compressed) {
 				split->block_len = em->block_len;
@@ -550,9 +560,11 @@
 
 			ret = add_extent_mapping(em_tree, split);
 			BUG_ON(ret); /* Logic error */
+			list_move(&split->list, &em_tree->modified_extents);
 			free_extent_map(split);
 			split = NULL;
 		}
+next:
 		write_unlock(&em_tree->lock);
 
 		/* once for us */
@@ -564,7 +576,6 @@
 		free_extent_map(split);
 	if (split2)
 		free_extent_map(split2);
-	return 0;
 }
 
 /*
@@ -576,13 +587,13 @@
  * it is either truncated or split.  Anything entirely inside the range
  * is deleted from the tree.
  */
-int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode,
-		       u64 start, u64 end, u64 *hint_byte, int drop_cache)
+int __btrfs_drop_extents(struct btrfs_trans_handle *trans,
+			 struct btrfs_root *root, struct inode *inode,
+			 struct btrfs_path *path, u64 start, u64 end,
+			 u64 *drop_end, int drop_cache)
 {
-	struct btrfs_root *root = BTRFS_I(inode)->root;
 	struct extent_buffer *leaf;
 	struct btrfs_file_extent_item *fi;
-	struct btrfs_path *path;
 	struct btrfs_key key;
 	struct btrfs_key new_key;
 	u64 ino = btrfs_ino(inode);
@@ -597,14 +608,12 @@
 	int recow;
 	int ret;
 	int modify_tree = -1;
+	int update_refs = (root->ref_cows || root == root->fs_info->tree_root);
+	int found = 0;
 
 	if (drop_cache)
 		btrfs_drop_extent_cache(inode, start, end - 1, 0);
 
-	path = btrfs_alloc_path();
-	if (!path)
-		return -ENOMEM;
-
 	if (start >= BTRFS_I(inode)->disk_i_size)
 		modify_tree = 0;
 
@@ -666,6 +675,7 @@
 			goto next_slot;
 		}
 
+		found = 1;
 		search_start = max(key.offset, start);
 		if (recow || !modify_tree) {
 			modify_tree = -1;
@@ -707,14 +717,13 @@
 							extent_end - start);
 			btrfs_mark_buffer_dirty(leaf);
 
-			if (disk_bytenr > 0) {
+			if (update_refs && disk_bytenr > 0) {
 				ret = btrfs_inc_extent_ref(trans, root,
 						disk_bytenr, num_bytes, 0,
 						root->root_key.objectid,
 						new_key.objectid,
 						start - extent_offset, 0);
 				BUG_ON(ret); /* -ENOMEM */
-				*hint_byte = disk_bytenr;
 			}
 			key.offset = start;
 		}
@@ -734,10 +743,8 @@
 			btrfs_set_file_extent_num_bytes(leaf, fi,
 							extent_end - end);
 			btrfs_mark_buffer_dirty(leaf);
-			if (disk_bytenr > 0) {
+			if (update_refs && disk_bytenr > 0)
 				inode_sub_bytes(inode, end - key.offset);
-				*hint_byte = disk_bytenr;
-			}
 			break;
 		}
 
@@ -753,10 +760,8 @@
 			btrfs_set_file_extent_num_bytes(leaf, fi,
 							start - key.offset);
 			btrfs_mark_buffer_dirty(leaf);
-			if (disk_bytenr > 0) {
+			if (update_refs && disk_bytenr > 0)
 				inode_sub_bytes(inode, extent_end - start);
-				*hint_byte = disk_bytenr;
-			}
 			if (end == extent_end)
 				break;
 
@@ -777,12 +782,13 @@
 				del_nr++;
 			}
 
-			if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
+			if (update_refs &&
+			    extent_type == BTRFS_FILE_EXTENT_INLINE) {
 				inode_sub_bytes(inode,
 						extent_end - key.offset);
 				extent_end = ALIGN(extent_end,
 						   root->sectorsize);
-			} else if (disk_bytenr > 0) {
+			} else if (update_refs && disk_bytenr > 0) {
 				ret = btrfs_free_extent(trans, root,
 						disk_bytenr, num_bytes, 0,
 						root->root_key.objectid,
@@ -791,7 +797,6 @@
 				BUG_ON(ret); /* -ENOMEM */
 				inode_sub_bytes(inode,
 						extent_end - key.offset);
-				*hint_byte = disk_bytenr;
 			}
 
 			if (end == extent_end)
@@ -806,7 +811,7 @@
 					      del_nr);
 			if (ret) {
 				btrfs_abort_transaction(trans, root, ret);
-				goto out;
+				break;
 			}
 
 			del_nr = 0;
@@ -825,7 +830,24 @@
 			btrfs_abort_transaction(trans, root, ret);
 	}
 
-out:
+	if (drop_end)
+		*drop_end = found ? min(end, extent_end) : end;
+	btrfs_release_path(path);
+	return ret;
+}
+
+int btrfs_drop_extents(struct btrfs_trans_handle *trans,
+		       struct btrfs_root *root, struct inode *inode, u64 start,
+		       u64 end, int drop_cache)
+{
+	struct btrfs_path *path;
+	int ret;
+
+	path = btrfs_alloc_path();
+	if (!path)
+		return -ENOMEM;
+	ret = __btrfs_drop_extents(trans, root, inode, path, start, end, NULL,
+				   drop_cache);
 	btrfs_free_path(path);
 	return ret;
 }
@@ -892,8 +914,6 @@
 	int ret;
 	u64 ino = btrfs_ino(inode);
 
-	btrfs_drop_extent_cache(inode, start, end - 1, 0);
-
 	path = btrfs_alloc_path();
 	if (!path)
 		return -ENOMEM;
@@ -935,12 +955,16 @@
 			btrfs_set_item_key_safe(trans, root, path, &new_key);
 			fi = btrfs_item_ptr(leaf, path->slots[0],
 					    struct btrfs_file_extent_item);
+			btrfs_set_file_extent_generation(leaf, fi,
+							 trans->transid);
 			btrfs_set_file_extent_num_bytes(leaf, fi,
 							extent_end - end);
 			btrfs_set_file_extent_offset(leaf, fi,
 						     end - orig_offset);
 			fi = btrfs_item_ptr(leaf, path->slots[0] - 1,
 					    struct btrfs_file_extent_item);
+			btrfs_set_file_extent_generation(leaf, fi,
+							 trans->transid);
 			btrfs_set_file_extent_num_bytes(leaf, fi,
 							end - other_start);
 			btrfs_mark_buffer_dirty(leaf);
@@ -958,12 +982,16 @@
 					    struct btrfs_file_extent_item);
 			btrfs_set_file_extent_num_bytes(leaf, fi,
 							start - key.offset);
+			btrfs_set_file_extent_generation(leaf, fi,
+							 trans->transid);
 			path->slots[0]++;
 			new_key.offset = start;
 			btrfs_set_item_key_safe(trans, root, path, &new_key);
 
 			fi = btrfs_item_ptr(leaf, path->slots[0],
 					    struct btrfs_file_extent_item);
+			btrfs_set_file_extent_generation(leaf, fi,
+							 trans->transid);
 			btrfs_set_file_extent_num_bytes(leaf, fi,
 							other_end - start);
 			btrfs_set_file_extent_offset(leaf, fi,
@@ -991,12 +1019,14 @@
 		leaf = path->nodes[0];
 		fi = btrfs_item_ptr(leaf, path->slots[0] - 1,
 				    struct btrfs_file_extent_item);
+		btrfs_set_file_extent_generation(leaf, fi, trans->transid);
 		btrfs_set_file_extent_num_bytes(leaf, fi,
 						split - key.offset);
 
 		fi = btrfs_item_ptr(leaf, path->slots[0],
 				    struct btrfs_file_extent_item);
 
+		btrfs_set_file_extent_generation(leaf, fi, trans->transid);
 		btrfs_set_file_extent_offset(leaf, fi, split - orig_offset);
 		btrfs_set_file_extent_num_bytes(leaf, fi,
 						extent_end - split);
@@ -1056,12 +1086,14 @@
 			   struct btrfs_file_extent_item);
 		btrfs_set_file_extent_type(leaf, fi,
 					   BTRFS_FILE_EXTENT_REG);
+		btrfs_set_file_extent_generation(leaf, fi, trans->transid);
 		btrfs_mark_buffer_dirty(leaf);
 	} else {
 		fi = btrfs_item_ptr(leaf, del_slot - 1,
 			   struct btrfs_file_extent_item);
 		btrfs_set_file_extent_type(leaf, fi,
 					   BTRFS_FILE_EXTENT_REG);
+		btrfs_set_file_extent_generation(leaf, fi, trans->transid);
 		btrfs_set_file_extent_num_bytes(leaf, fi,
 						extent_end - key.offset);
 		btrfs_mark_buffer_dirty(leaf);
@@ -1173,8 +1205,8 @@
 
 		clear_extent_bit(&BTRFS_I(inode)->io_tree, start_pos,
 				  last_pos - 1, EXTENT_DIRTY | EXTENT_DELALLOC |
-				  EXTENT_DO_ACCOUNTING, 0, 0, &cached_state,
-				  GFP_NOFS);
+				  EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
+				  0, 0, &cached_state, GFP_NOFS);
 		unlock_extent_cached(&BTRFS_I(inode)->io_tree,
 				     start_pos, last_pos - 1, &cached_state,
 				     GFP_NOFS);
@@ -1514,16 +1546,24 @@
 
 	trace_btrfs_sync_file(file, datasync);
 
+	/*
+	 * We write the dirty pages in the range and wait until they complete
+	 * out of the ->i_mutex. If so, we can flush the dirty pages by
+	 * multi-task, and make the performance up.
+	 */
+	ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
+	if (ret)
+		return ret;
+
 	mutex_lock(&inode->i_mutex);
 
 	/*
-	 * we wait first, since the writeback may change the inode, also wait
-	 * ordered range does a filemape_write_and_wait_range which is why we
-	 * don't do it above like other file systems.
+	 * We flush the dirty pages again to avoid some dirty pages in the
+	 * range being left.
 	 */
-	root->log_batch++;
+	atomic_inc(&root->log_batch);
 	btrfs_wait_ordered_range(inode, start, end);
-	root->log_batch++;
+	atomic_inc(&root->log_batch);
 
 	/*
 	 * check the transaction that last modified this inode
@@ -1544,6 +1584,14 @@
 	    BTRFS_I(inode)->last_trans <=
 	    root->fs_info->last_trans_committed) {
 		BTRFS_I(inode)->last_trans = 0;
+
+		/*
+		 * We'v had everything committed since the last time we were
+		 * modified so clear this flag in case it was set for whatever
+		 * reason, it's no longer relevant.
+		 */
+		clear_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
+			  &BTRFS_I(inode)->runtime_flags);
 		mutex_unlock(&inode->i_mutex);
 		goto out;
 	}
@@ -1599,6 +1647,7 @@
 static const struct vm_operations_struct btrfs_file_vm_ops = {
 	.fault		= filemap_fault,
 	.page_mkwrite	= btrfs_page_mkwrite,
+	.remap_pages	= generic_file_remap_pages,
 };
 
 static int btrfs_file_mmap(struct file	*filp, struct vm_area_struct *vma)
@@ -1610,11 +1659,328 @@
 
 	file_accessed(filp);
 	vma->vm_ops = &btrfs_file_vm_ops;
-	vma->vm_flags |= VM_CAN_NONLINEAR;
 
 	return 0;
 }
 
+static int hole_mergeable(struct inode *inode, struct extent_buffer *leaf,
+			  int slot, u64 start, u64 end)
+{
+	struct btrfs_file_extent_item *fi;
+	struct btrfs_key key;
+
+	if (slot < 0 || slot >= btrfs_header_nritems(leaf))
+		return 0;
+
+	btrfs_item_key_to_cpu(leaf, &key, slot);
+	if (key.objectid != btrfs_ino(inode) ||
+	    key.type != BTRFS_EXTENT_DATA_KEY)
+		return 0;
+
+	fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
+
+	if (btrfs_file_extent_type(leaf, fi) != BTRFS_FILE_EXTENT_REG)
+		return 0;
+
+	if (btrfs_file_extent_disk_bytenr(leaf, fi))
+		return 0;
+
+	if (key.offset == end)
+		return 1;
+	if (key.offset + btrfs_file_extent_num_bytes(leaf, fi) == start)
+		return 1;
+	return 0;
+}
+
+static int fill_holes(struct btrfs_trans_handle *trans, struct inode *inode,
+		      struct btrfs_path *path, u64 offset, u64 end)
+{
+	struct btrfs_root *root = BTRFS_I(inode)->root;
+	struct extent_buffer *leaf;
+	struct btrfs_file_extent_item *fi;
+	struct extent_map *hole_em;
+	struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
+	struct btrfs_key key;
+	int ret;
+
+	key.objectid = btrfs_ino(inode);
+	key.type = BTRFS_EXTENT_DATA_KEY;
+	key.offset = offset;
+
+
+	ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
+	if (ret < 0)
+		return ret;
+	BUG_ON(!ret);
+
+	leaf = path->nodes[0];
+	if (hole_mergeable(inode, leaf, path->slots[0]-1, offset, end)) {
+		u64 num_bytes;
+
+		path->slots[0]--;
+		fi = btrfs_item_ptr(leaf, path->slots[0],
+				    struct btrfs_file_extent_item);
+		num_bytes = btrfs_file_extent_num_bytes(leaf, fi) +
+			end - offset;
+		btrfs_set_file_extent_num_bytes(leaf, fi, num_bytes);
+		btrfs_set_file_extent_ram_bytes(leaf, fi, num_bytes);
+		btrfs_set_file_extent_offset(leaf, fi, 0);
+		btrfs_mark_buffer_dirty(leaf);
+		goto out;
+	}
+
+	if (hole_mergeable(inode, leaf, path->slots[0]+1, offset, end)) {
+		u64 num_bytes;
+
+		path->slots[0]++;
+		key.offset = offset;
+		btrfs_set_item_key_safe(trans, root, path, &key);
+		fi = btrfs_item_ptr(leaf, path->slots[0],
+				    struct btrfs_file_extent_item);
+		num_bytes = btrfs_file_extent_num_bytes(leaf, fi) + end -
+			offset;
+		btrfs_set_file_extent_num_bytes(leaf, fi, num_bytes);
+		btrfs_set_file_extent_ram_bytes(leaf, fi, num_bytes);
+		btrfs_set_file_extent_offset(leaf, fi, 0);
+		btrfs_mark_buffer_dirty(leaf);
+		goto out;
+	}
+	btrfs_release_path(path);
+
+	ret = btrfs_insert_file_extent(trans, root, btrfs_ino(inode), offset,
+				       0, 0, end - offset, 0, end - offset,
+				       0, 0, 0);
+	if (ret)
+		return ret;
+
+out:
+	btrfs_release_path(path);
+
+	hole_em = alloc_extent_map();
+	if (!hole_em) {
+		btrfs_drop_extent_cache(inode, offset, end - 1, 0);
+		set_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
+			&BTRFS_I(inode)->runtime_flags);
+	} else {
+		hole_em->start = offset;
+		hole_em->len = end - offset;
+		hole_em->orig_start = offset;
+
+		hole_em->block_start = EXTENT_MAP_HOLE;
+		hole_em->block_len = 0;
+		hole_em->bdev = root->fs_info->fs_devices->latest_bdev;
+		hole_em->compress_type = BTRFS_COMPRESS_NONE;
+		hole_em->generation = trans->transid;
+
+		do {
+			btrfs_drop_extent_cache(inode, offset, end - 1, 0);
+			write_lock(&em_tree->lock);
+			ret = add_extent_mapping(em_tree, hole_em);
+			if (!ret)
+				list_move(&hole_em->list,
+					  &em_tree->modified_extents);
+			write_unlock(&em_tree->lock);
+		} while (ret == -EEXIST);
+		free_extent_map(hole_em);
+		if (ret)
+			set_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
+				&BTRFS_I(inode)->runtime_flags);
+	}
+
+	return 0;
+}
+
+static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
+{
+	struct btrfs_root *root = BTRFS_I(inode)->root;
+	struct extent_state *cached_state = NULL;
+	struct btrfs_path *path;
+	struct btrfs_block_rsv *rsv;
+	struct btrfs_trans_handle *trans;
+	u64 mask = BTRFS_I(inode)->root->sectorsize - 1;
+	u64 lockstart = (offset + mask) & ~mask;
+	u64 lockend = ((offset + len) & ~mask) - 1;
+	u64 cur_offset = lockstart;
+	u64 min_size = btrfs_calc_trunc_metadata_size(root, 1);
+	u64 drop_end;
+	unsigned long nr;
+	int ret = 0;
+	int err = 0;
+	bool same_page = (offset >> PAGE_CACHE_SHIFT) ==
+		((offset + len) >> PAGE_CACHE_SHIFT);
+
+	btrfs_wait_ordered_range(inode, offset, len);
+
+	mutex_lock(&inode->i_mutex);
+	if (offset >= inode->i_size) {
+		mutex_unlock(&inode->i_mutex);
+		return 0;
+	}
+
+	/*
+	 * Only do this if we are in the same page and we aren't doing the
+	 * entire page.
+	 */
+	if (same_page && len < PAGE_CACHE_SIZE) {
+		ret = btrfs_truncate_page(inode, offset, len, 0);
+		mutex_unlock(&inode->i_mutex);
+		return ret;
+	}
+
+	/* zero back part of the first page */
+	ret = btrfs_truncate_page(inode, offset, 0, 0);
+	if (ret) {
+		mutex_unlock(&inode->i_mutex);
+		return ret;
+	}
+
+	/* zero the front end of the last page */
+	ret = btrfs_truncate_page(inode, offset + len, 0, 1);
+	if (ret) {
+		mutex_unlock(&inode->i_mutex);
+		return ret;
+	}
+
+	if (lockend < lockstart) {
+		mutex_unlock(&inode->i_mutex);
+		return 0;
+	}
+
+	while (1) {
+		struct btrfs_ordered_extent *ordered;
+
+		truncate_pagecache_range(inode, lockstart, lockend);
+
+		lock_extent_bits(&BTRFS_I(inode)->io_tree, lockstart, lockend,
+				 0, &cached_state);
+		ordered = btrfs_lookup_first_ordered_extent(inode, lockend);
+
+		/*
+		 * We need to make sure we have no ordered extents in this range
+		 * and nobody raced in and read a page in this range, if we did
+		 * we need to try again.
+		 */
+		if ((!ordered ||
+		    (ordered->file_offset + ordered->len < lockstart ||
+		     ordered->file_offset > lockend)) &&
+		     !test_range_bit(&BTRFS_I(inode)->io_tree, lockstart,
+				     lockend, EXTENT_UPTODATE, 0,
+				     cached_state)) {
+			if (ordered)
+				btrfs_put_ordered_extent(ordered);
+			break;
+		}
+		if (ordered)
+			btrfs_put_ordered_extent(ordered);
+		unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart,
+				     lockend, &cached_state, GFP_NOFS);
+		btrfs_wait_ordered_range(inode, lockstart,
+					 lockend - lockstart + 1);
+	}
+
+	path = btrfs_alloc_path();
+	if (!path) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	rsv = btrfs_alloc_block_rsv(root, BTRFS_BLOCK_RSV_TEMP);
+	if (!rsv) {
+		ret = -ENOMEM;
+		goto out_free;
+	}
+	rsv->size = btrfs_calc_trunc_metadata_size(root, 1);
+	rsv->failfast = 1;
+
+	/*
+	 * 1 - update the inode
+	 * 1 - removing the extents in the range
+	 * 1 - adding the hole extent
+	 */
+	trans = btrfs_start_transaction(root, 3);
+	if (IS_ERR(trans)) {
+		err = PTR_ERR(trans);
+		goto out_free;
+	}
+
+	ret = btrfs_block_rsv_migrate(&root->fs_info->trans_block_rsv, rsv,
+				      min_size);
+	BUG_ON(ret);
+	trans->block_rsv = rsv;
+
+	while (cur_offset < lockend) {
+		ret = __btrfs_drop_extents(trans, root, inode, path,
+					   cur_offset, lockend + 1,
+					   &drop_end, 1);
+		if (ret != -ENOSPC)
+			break;
+
+		trans->block_rsv = &root->fs_info->trans_block_rsv;
+
+		ret = fill_holes(trans, inode, path, cur_offset, drop_end);
+		if (ret) {
+			err = ret;
+			break;
+		}
+
+		cur_offset = drop_end;
+
+		ret = btrfs_update_inode(trans, root, inode);
+		if (ret) {
+			err = ret;
+			break;
+		}
+
+		nr = trans->blocks_used;
+		btrfs_end_transaction(trans, root);
+		btrfs_btree_balance_dirty(root, nr);
+
+		trans = btrfs_start_transaction(root, 3);
+		if (IS_ERR(trans)) {
+			ret = PTR_ERR(trans);
+			trans = NULL;
+			break;
+		}
+
+		ret = btrfs_block_rsv_migrate(&root->fs_info->trans_block_rsv,
+					      rsv, min_size);
+		BUG_ON(ret);	/* shouldn't happen */
+		trans->block_rsv = rsv;
+	}
+
+	if (ret) {
+		err = ret;
+		goto out_trans;
+	}
+
+	trans->block_rsv = &root->fs_info->trans_block_rsv;
+	ret = fill_holes(trans, inode, path, cur_offset, drop_end);
+	if (ret) {
+		err = ret;
+		goto out_trans;
+	}
+
+out_trans:
+	if (!trans)
+		goto out_free;
+
+	trans->block_rsv = &root->fs_info->trans_block_rsv;
+	ret = btrfs_update_inode(trans, root, inode);
+	nr = trans->blocks_used;
+	btrfs_end_transaction(trans, root);
+	btrfs_btree_balance_dirty(root, nr);
+out_free:
+	btrfs_free_path(path);
+	btrfs_free_block_rsv(root, rsv);
+out:
+	unlock_extent_cached(&BTRFS_I(inode)->io_tree, lockstart, lockend,
+			     &cached_state, GFP_NOFS);
+	mutex_unlock(&inode->i_mutex);
+	if (ret && !err)
+		err = ret;
+	return err;
+}
+
 static long btrfs_fallocate(struct file *file, int mode,
 			    loff_t offset, loff_t len)
 {
@@ -1633,15 +1999,18 @@
 	alloc_start = offset & ~mask;
 	alloc_end =  (offset + len + mask) & ~mask;
 
-	/* We only support the FALLOC_FL_KEEP_SIZE mode */
-	if (mode & ~FALLOC_FL_KEEP_SIZE)
+	/* Make sure we aren't being give some crap mode */
+	if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
 		return -EOPNOTSUPP;
 
+	if (mode & FALLOC_FL_PUNCH_HOLE)
+		return btrfs_punch_hole(inode, offset, len);
+
 	/*
 	 * Make sure we have enough space before we do the
 	 * allocation.
 	 */
-	ret = btrfs_check_data_free_space(inode, len);
+	ret = btrfs_check_data_free_space(inode, alloc_end - alloc_start + 1);
 	if (ret)
 		return ret;
 
@@ -1748,7 +2117,7 @@
 out:
 	mutex_unlock(&inode->i_mutex);
 	/* Let go of our reservation. */
-	btrfs_free_reserved_data_space(inode, len);
+	btrfs_free_reserved_data_space(inode, alloc_end - alloc_start + 1);
 	return ret;
 }
 
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index 6b10acf..1027b85 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -966,7 +966,7 @@
 			       block_group->key.offset)) {
 		ret = find_first_extent_bit(unpin, start,
 					    &extent_start, &extent_end,
-					    EXTENT_DIRTY);
+					    EXTENT_DIRTY, NULL);
 		if (ret) {
 			ret = 0;
 			break;
@@ -1454,9 +1454,7 @@
 			  max_t(u64, *offset, bitmap_info->offset));
 	bits = bytes_to_bits(*bytes, ctl->unit);
 
-	for (i = find_next_bit(bitmap_info->bitmap, BITS_PER_BITMAP, i);
-	     i < BITS_PER_BITMAP;
-	     i = find_next_bit(bitmap_info->bitmap, BITS_PER_BITMAP, i + 1)) {
+	for_each_set_bit_from(i, bitmap_info->bitmap, BITS_PER_BITMAP) {
 		next_zero = find_next_zero_bit(bitmap_info->bitmap,
 					       BITS_PER_BITMAP, i);
 		if ((next_zero - i) >= bits) {
@@ -2307,9 +2305,7 @@
 
 again:
 	found_bits = 0;
-	for (i = find_next_bit(entry->bitmap, BITS_PER_BITMAP, i);
-	     i < BITS_PER_BITMAP;
-	     i = find_next_bit(entry->bitmap, BITS_PER_BITMAP, i + 1)) {
+	for_each_set_bit_from(i, entry->bitmap, BITS_PER_BITMAP) {
 		next_zero = find_next_zero_bit(entry->bitmap,
 					       BITS_PER_BITMAP, i);
 		if (next_zero - i >= min_bits) {
diff --git a/fs/btrfs/hash.h b/fs/btrfs/hash.h
index db2ff97..1d982812 100644
--- a/fs/btrfs/hash.h
+++ b/fs/btrfs/hash.h
@@ -24,4 +24,14 @@
 {
 	return crc32c((u32)~1, name, len);
 }
+
+/*
+ * Figure the key offset of an extended inode ref
+ */
+static inline u64 btrfs_extref_hash(u64 parent_objectid, const char *name,
+				    int len)
+{
+	return (u64) crc32c(parent_objectid, name, len);
+}
+
 #endif
diff --git a/fs/btrfs/inode-item.c b/fs/btrfs/inode-item.c
index a13cf1a..48b8fda 100644
--- a/fs/btrfs/inode-item.c
+++ b/fs/btrfs/inode-item.c
@@ -18,6 +18,7 @@
 
 #include "ctree.h"
 #include "disk-io.h"
+#include "hash.h"
 #include "transaction.h"
 #include "print-tree.h"
 
@@ -50,18 +51,57 @@
 	return 0;
 }
 
-struct btrfs_inode_ref *
-btrfs_lookup_inode_ref(struct btrfs_trans_handle *trans,
-			struct btrfs_root *root,
-			struct btrfs_path *path,
-			const char *name, int name_len,
-			u64 inode_objectid, u64 ref_objectid, int mod)
+int btrfs_find_name_in_ext_backref(struct btrfs_path *path, u64 ref_objectid,
+				   const char *name, int name_len,
+				   struct btrfs_inode_extref **extref_ret)
 {
+	struct extent_buffer *leaf;
+	struct btrfs_inode_extref *extref;
+	unsigned long ptr;
+	unsigned long name_ptr;
+	u32 item_size;
+	u32 cur_offset = 0;
+	int ref_name_len;
+
+	leaf = path->nodes[0];
+	item_size = btrfs_item_size_nr(leaf, path->slots[0]);
+	ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
+
+	/*
+	 * Search all extended backrefs in this item. We're only
+	 * looking through any collisions so most of the time this is
+	 * just going to compare against one buffer. If all is well,
+	 * we'll return success and the inode ref object.
+	 */
+	while (cur_offset < item_size) {
+		extref = (struct btrfs_inode_extref *) (ptr + cur_offset);
+		name_ptr = (unsigned long)(&extref->name);
+		ref_name_len = btrfs_inode_extref_name_len(leaf, extref);
+
+		if (ref_name_len == name_len &&
+		    btrfs_inode_extref_parent(leaf, extref) == ref_objectid &&
+		    (memcmp_extent_buffer(leaf, name, name_ptr, name_len) == 0)) {
+			if (extref_ret)
+				*extref_ret = extref;
+			return 1;
+		}
+
+		cur_offset += ref_name_len + sizeof(*extref);
+	}
+	return 0;
+}
+
+static struct btrfs_inode_ref *
+btrfs_lookup_inode_ref(struct btrfs_trans_handle *trans,
+		       struct btrfs_root *root,
+		       struct btrfs_path *path,
+		       const char *name, int name_len,
+		       u64 inode_objectid, u64 ref_objectid, int ins_len,
+		       int cow)
+{
+	int ret;
 	struct btrfs_key key;
 	struct btrfs_inode_ref *ref;
-	int ins_len = mod < 0 ? -1 : 0;
-	int cow = mod != 0;
-	int ret;
 
 	key.objectid = inode_objectid;
 	key.type = BTRFS_INODE_REF_KEY;
@@ -77,13 +117,150 @@
 	return ref;
 }
 
-int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
+/* Returns NULL if no extref found */
+struct btrfs_inode_extref *
+btrfs_lookup_inode_extref(struct btrfs_trans_handle *trans,
+			  struct btrfs_root *root,
+			  struct btrfs_path *path,
+			  const char *name, int name_len,
+			  u64 inode_objectid, u64 ref_objectid, int ins_len,
+			  int cow)
+{
+	int ret;
+	struct btrfs_key key;
+	struct btrfs_inode_extref *extref;
+
+	key.objectid = inode_objectid;
+	key.type = BTRFS_INODE_EXTREF_KEY;
+	key.offset = btrfs_extref_hash(ref_objectid, name, name_len);
+
+	ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
+	if (ret < 0)
+		return ERR_PTR(ret);
+	if (ret > 0)
+		return NULL;
+	if (!btrfs_find_name_in_ext_backref(path, ref_objectid, name, name_len, &extref))
+		return NULL;
+	return extref;
+}
+
+int btrfs_get_inode_ref_index(struct btrfs_trans_handle *trans,
+			      struct btrfs_root *root,
+			      struct btrfs_path *path,
+			      const char *name, int name_len,
+			      u64 inode_objectid, u64 ref_objectid, int mod,
+			      u64 *ret_index)
+{
+	struct btrfs_inode_ref *ref;
+	struct btrfs_inode_extref *extref;
+	int ins_len = mod < 0 ? -1 : 0;
+	int cow = mod != 0;
+
+	ref = btrfs_lookup_inode_ref(trans, root, path, name, name_len,
+				     inode_objectid, ref_objectid, ins_len,
+				     cow);
+	if (IS_ERR(ref))
+		return PTR_ERR(ref);
+
+	if (ref != NULL) {
+		*ret_index = btrfs_inode_ref_index(path->nodes[0], ref);
+		return 0;
+	}
+
+	btrfs_release_path(path);
+
+	extref = btrfs_lookup_inode_extref(trans, root, path, name,
+					   name_len, inode_objectid,
+					   ref_objectid, ins_len, cow);
+	if (IS_ERR(extref))
+		return PTR_ERR(extref);
+
+	if (extref) {
+		*ret_index = btrfs_inode_extref_index(path->nodes[0], extref);
+		return 0;
+	}
+
+	return -ENOENT;
+}
+
+int btrfs_del_inode_extref(struct btrfs_trans_handle *trans,
 			   struct btrfs_root *root,
 			   const char *name, int name_len,
 			   u64 inode_objectid, u64 ref_objectid, u64 *index)
 {
 	struct btrfs_path *path;
 	struct btrfs_key key;
+	struct btrfs_inode_extref *extref;
+	struct extent_buffer *leaf;
+	int ret;
+	int del_len = name_len + sizeof(*extref);
+	unsigned long ptr;
+	unsigned long item_start;
+	u32 item_size;
+
+	key.objectid = inode_objectid;
+	btrfs_set_key_type(&key, BTRFS_INODE_EXTREF_KEY);
+	key.offset = btrfs_extref_hash(ref_objectid, name, name_len);
+
+	path = btrfs_alloc_path();
+	if (!path)
+		return -ENOMEM;
+
+	path->leave_spinning = 1;
+
+	ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
+	if (ret > 0)
+		ret = -ENOENT;
+	if (ret < 0)
+		goto out;
+
+	/*
+	 * Sanity check - did we find the right item for this name?
+	 * This should always succeed so error here will make the FS
+	 * readonly.
+	 */
+	if (!btrfs_find_name_in_ext_backref(path, ref_objectid,
+					    name, name_len, &extref)) {
+		btrfs_std_error(root->fs_info, -ENOENT);
+		ret = -EROFS;
+		goto out;
+	}
+
+	leaf = path->nodes[0];
+	item_size = btrfs_item_size_nr(leaf, path->slots[0]);
+	if (index)
+		*index = btrfs_inode_extref_index(leaf, extref);
+
+	if (del_len == item_size) {
+		/*
+		 * Common case only one ref in the item, remove the
+		 * whole item.
+		 */
+		ret = btrfs_del_item(trans, root, path);
+		goto out;
+	}
+
+	ptr = (unsigned long)extref;
+	item_start = btrfs_item_ptr_offset(leaf, path->slots[0]);
+
+	memmove_extent_buffer(leaf, ptr, ptr + del_len,
+			      item_size - (ptr + del_len - item_start));
+
+	btrfs_truncate_item(trans, root, path, item_size - del_len, 1);
+
+out:
+	btrfs_free_path(path);
+
+	return ret;
+}
+
+int btrfs_del_inode_ref(struct btrfs_trans_handle *trans,
+			struct btrfs_root *root,
+			const char *name, int name_len,
+			u64 inode_objectid, u64 ref_objectid, u64 *index)
+{
+	struct btrfs_path *path;
+	struct btrfs_key key;
 	struct btrfs_inode_ref *ref;
 	struct extent_buffer *leaf;
 	unsigned long ptr;
@@ -91,6 +268,7 @@
 	u32 item_size;
 	u32 sub_item_len;
 	int ret;
+	int search_ext_refs = 0;
 	int del_len = name_len + sizeof(*ref);
 
 	key.objectid = inode_objectid;
@@ -106,12 +284,14 @@
 	ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
 	if (ret > 0) {
 		ret = -ENOENT;
+		search_ext_refs = 1;
 		goto out;
 	} else if (ret < 0) {
 		goto out;
 	}
 	if (!find_name_in_backref(path, name, name_len, &ref)) {
 		ret = -ENOENT;
+		search_ext_refs = 1;
 		goto out;
 	}
 	leaf = path->nodes[0];
@@ -129,8 +309,78 @@
 	item_start = btrfs_item_ptr_offset(leaf, path->slots[0]);
 	memmove_extent_buffer(leaf, ptr, ptr + sub_item_len,
 			      item_size - (ptr + sub_item_len - item_start));
-	btrfs_truncate_item(trans, root, path,
-				  item_size - sub_item_len, 1);
+	btrfs_truncate_item(trans, root, path, item_size - sub_item_len, 1);
+out:
+	btrfs_free_path(path);
+
+	if (search_ext_refs) {
+		/*
+		 * No refs were found, or we could not find the
+		 * name in our ref array. Find and remove the extended
+		 * inode ref then.
+		 */
+		return btrfs_del_inode_extref(trans, root, name, name_len,
+					      inode_objectid, ref_objectid, index);
+	}
+
+	return ret;
+}
+
+/*
+ * btrfs_insert_inode_extref() - Inserts an extended inode ref into a tree.
+ *
+ * The caller must have checked against BTRFS_LINK_MAX already.
+ */
+static int btrfs_insert_inode_extref(struct btrfs_trans_handle *trans,
+				     struct btrfs_root *root,
+				     const char *name, int name_len,
+				     u64 inode_objectid, u64 ref_objectid, u64 index)
+{
+	struct btrfs_inode_extref *extref;
+	int ret;
+	int ins_len = name_len + sizeof(*extref);
+	unsigned long ptr;
+	struct btrfs_path *path;
+	struct btrfs_key key;
+	struct extent_buffer *leaf;
+	struct btrfs_item *item;
+
+	key.objectid = inode_objectid;
+	key.type = BTRFS_INODE_EXTREF_KEY;
+	key.offset = btrfs_extref_hash(ref_objectid, name, name_len);
+
+	path = btrfs_alloc_path();
+	if (!path)
+		return -ENOMEM;
+
+	path->leave_spinning = 1;
+	ret = btrfs_insert_empty_item(trans, root, path, &key,
+				      ins_len);
+	if (ret == -EEXIST) {
+		if (btrfs_find_name_in_ext_backref(path, ref_objectid,
+						   name, name_len, NULL))
+			goto out;
+
+		btrfs_extend_item(trans, root, path, ins_len);
+		ret = 0;
+	}
+	if (ret < 0)
+		goto out;
+
+	leaf = path->nodes[0];
+	item = btrfs_item_nr(leaf, path->slots[0]);
+	ptr = (unsigned long)btrfs_item_ptr(leaf, path->slots[0], char);
+	ptr += btrfs_item_size(leaf, item) - ins_len;
+	extref = (struct btrfs_inode_extref *)ptr;
+
+	btrfs_set_inode_extref_name_len(path->nodes[0], extref, name_len);
+	btrfs_set_inode_extref_index(path->nodes[0], extref, index);
+	btrfs_set_inode_extref_parent(path->nodes[0], extref, ref_objectid);
+
+	ptr = (unsigned long)&extref->name;
+	write_extent_buffer(path->nodes[0], name, ptr, name_len);
+	btrfs_mark_buffer_dirty(path->nodes[0]);
+
 out:
 	btrfs_free_path(path);
 	return ret;
@@ -191,6 +441,19 @@
 
 out:
 	btrfs_free_path(path);
+
+	if (ret == -EMLINK) {
+		struct btrfs_super_block *disk_super = root->fs_info->super_copy;
+		/* We ran out of space in the ref array. Need to
+		 * add an extended ref. */
+		if (btrfs_super_incompat_flags(disk_super)
+		    & BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF)
+			ret = btrfs_insert_inode_extref(trans, root, name,
+							name_len,
+							inode_objectid,
+							ref_objectid, index);
+	}
+
 	return ret;
 }
 
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index a6ed694..85a1e50 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -230,7 +230,6 @@
 	u64 inline_len = actual_end - start;
 	u64 aligned_end = (end + root->sectorsize - 1) &
 			~((u64)root->sectorsize - 1);
-	u64 hint_byte;
 	u64 data_len = inline_len;
 	int ret;
 
@@ -247,8 +246,7 @@
 		return 1;
 	}
 
-	ret = btrfs_drop_extents(trans, inode, start, aligned_end,
-				 &hint_byte, 1);
+	ret = btrfs_drop_extents(trans, root, inode, start, aligned_end, 1);
 	if (ret)
 		return ret;
 
@@ -664,7 +662,7 @@
 					   async_extent->compressed_size,
 					   async_extent->compressed_size,
 					   0, alloc_hint, &ins, 1);
-			if (ret)
+			if (ret && ret != -ENOSPC)
 				btrfs_abort_transaction(trans, root, ret);
 			btrfs_end_transaction(trans, root);
 		}
@@ -1308,6 +1306,7 @@
 			em->block_start = disk_bytenr;
 			em->bdev = root->fs_info->fs_devices->latest_bdev;
 			set_bit(EXTENT_FLAG_PINNED, &em->flags);
+			set_bit(EXTENT_FLAG_PREALLOC, &em->flags);
 			while (1) {
 				write_lock(&em_tree->lock);
 				ret = add_extent_mapping(em_tree, em);
@@ -1364,11 +1363,7 @@
 	}
 
 error:
-	if (nolock) {
-		err = btrfs_end_transaction_nolock(trans, root);
-	} else {
-		err = btrfs_end_transaction(trans, root);
-	}
+	err = btrfs_end_transaction(trans, root);
 	if (!ret)
 		ret = err;
 
@@ -1785,7 +1780,6 @@
 	struct btrfs_path *path;
 	struct extent_buffer *leaf;
 	struct btrfs_key ins;
-	u64 hint;
 	int ret;
 
 	path = btrfs_alloc_path();
@@ -1803,8 +1797,8 @@
 	 * the caller is expected to unpin it and allow it to be merged
 	 * with the others.
 	 */
-	ret = btrfs_drop_extents(trans, inode, file_pos, file_pos + num_bytes,
-				 &hint, 0);
+	ret = btrfs_drop_extents(trans, root, inode, file_pos,
+				 file_pos + num_bytes, 0);
 	if (ret)
 		goto out;
 
@@ -1828,10 +1822,8 @@
 	btrfs_set_file_extent_encryption(leaf, fi, encryption);
 	btrfs_set_file_extent_other_encoding(leaf, fi, other_encoding);
 
-	btrfs_unlock_up_safe(path, 1);
-	btrfs_set_lock_blocking(leaf);
-
 	btrfs_mark_buffer_dirty(leaf);
+	btrfs_release_path(path);
 
 	inode_add_bytes(inode, num_bytes);
 
@@ -1929,11 +1921,10 @@
 						ordered_extent->len,
 						compress_type, 0, 0,
 						BTRFS_FILE_EXTENT_REG);
-		unpin_extent_cache(&BTRFS_I(inode)->extent_tree,
-				   ordered_extent->file_offset,
-				   ordered_extent->len);
 	}
-
+	unpin_extent_cache(&BTRFS_I(inode)->extent_tree,
+			   ordered_extent->file_offset, ordered_extent->len,
+			   trans->transid);
 	if (ret < 0) {
 		btrfs_abort_transaction(trans, root, ret);
 		goto out_unlock;
@@ -1949,6 +1940,8 @@
 			btrfs_abort_transaction(trans, root, ret);
 			goto out_unlock;
 		}
+	} else {
+		btrfs_set_inode_last_trans(trans, inode);
 	}
 	ret = 0;
 out_unlock:
@@ -1958,12 +1951,8 @@
 out:
 	if (root != root->fs_info->tree_root)
 		btrfs_delalloc_release_metadata(inode, ordered_extent->len);
-	if (trans) {
-		if (nolock)
-			btrfs_end_transaction_nolock(trans, root);
-		else
-			btrfs_end_transaction(trans, root);
-	}
+	if (trans)
+		btrfs_end_transaction(trans, root);
 
 	if (ret)
 		clear_extent_uptodate(io_tree, ordered_extent->file_offset,
@@ -2119,7 +2108,6 @@
 	if (empty)
 		return;
 
-	down_read(&root->fs_info->cleanup_work_sem);
 	spin_lock(&fs_info->delayed_iput_lock);
 	list_splice_init(&fs_info->delayed_iputs, &list);
 	spin_unlock(&fs_info->delayed_iput_lock);
@@ -2130,7 +2118,6 @@
 		iput(delayed->inode);
 		kfree(delayed);
 	}
-	up_read(&root->fs_info->cleanup_work_sem);
 }
 
 enum btrfs_orphan_cleanup_state {
@@ -2198,7 +2185,7 @@
 	int ret;
 
 	if (!root->orphan_block_rsv) {
-		block_rsv = btrfs_alloc_block_rsv(root);
+		block_rsv = btrfs_alloc_block_rsv(root, BTRFS_BLOCK_RSV_TEMP);
 		if (!block_rsv)
 			return -ENOMEM;
 	}
@@ -2225,7 +2212,7 @@
 			insert = 1;
 #endif
 		insert = 1;
-		atomic_dec(&root->orphan_inodes);
+		atomic_inc(&root->orphan_inodes);
 	}
 
 	if (!test_and_set_bit(BTRFS_INODE_ORPHAN_META_RESERVED,
@@ -2590,6 +2577,18 @@
 
 	inode_set_bytes(inode, btrfs_inode_nbytes(leaf, inode_item));
 	BTRFS_I(inode)->generation = btrfs_inode_generation(leaf, inode_item);
+	BTRFS_I(inode)->last_trans = btrfs_inode_transid(leaf, inode_item);
+
+	/*
+	 * If we were modified in the current generation and evicted from memory
+	 * and then re-read we need to do a full sync since we don't have any
+	 * idea about which extents were modified before we were evicted from
+	 * cache.
+	 */
+	if (BTRFS_I(inode)->last_trans == root->fs_info->generation)
+		set_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
+			&BTRFS_I(inode)->runtime_flags);
+
 	inode->i_version = btrfs_inode_sequence(leaf, inode_item);
 	inode->i_generation = BTRFS_I(inode)->generation;
 	inode->i_rdev = 0;
@@ -2894,7 +2893,6 @@
 	struct btrfs_trans_handle *trans;
 	struct btrfs_root *root = BTRFS_I(dir)->root;
 	struct btrfs_path *path;
-	struct btrfs_inode_ref *ref;
 	struct btrfs_dir_item *di;
 	struct inode *inode = dentry->d_inode;
 	u64 index;
@@ -3008,17 +3006,17 @@
 	}
 	btrfs_release_path(path);
 
-	ref = btrfs_lookup_inode_ref(trans, root, path,
-				dentry->d_name.name, dentry->d_name.len,
-				ino, dir_ino, 0);
-	if (IS_ERR(ref)) {
-		err = PTR_ERR(ref);
+	ret = btrfs_get_inode_ref_index(trans, root, path, dentry->d_name.name,
+					dentry->d_name.len, ino, dir_ino, 0,
+					&index);
+	if (ret) {
+		err = ret;
 		goto out;
 	}
-	BUG_ON(!ref); /* Logic error */
+
 	if (check_path_shared(root, path))
 		goto out;
-	index = btrfs_inode_ref_index(path->nodes[0], ref);
+
 	btrfs_release_path(path);
 
 	/*
@@ -3061,7 +3059,7 @@
 static void __unlink_end_trans(struct btrfs_trans_handle *trans,
 			       struct btrfs_root *root)
 {
-	if (trans->block_rsv == &root->fs_info->global_block_rsv) {
+	if (trans->block_rsv->type == BTRFS_BLOCK_RSV_GLOBAL) {
 		btrfs_block_rsv_release(root, trans->block_rsv,
 					trans->bytes_reserved);
 		trans->block_rsv = &root->fs_info->trans_block_rsv;
@@ -3191,9 +3189,10 @@
 	struct btrfs_trans_handle *trans;
 	unsigned long nr = 0;
 
-	if (inode->i_size > BTRFS_EMPTY_DIR_SIZE ||
-	    btrfs_ino(inode) == BTRFS_FIRST_FREE_OBJECTID)
+	if (inode->i_size > BTRFS_EMPTY_DIR_SIZE)
 		return -ENOTEMPTY;
+	if (btrfs_ino(inode) == BTRFS_FIRST_FREE_OBJECTID)
+		return -EPERM;
 
 	trans = __unlink_start_trans(dir, dentry);
 	if (IS_ERR(trans))
@@ -3267,8 +3266,13 @@
 		return -ENOMEM;
 	path->reada = -1;
 
+	/*
+	 * We want to drop from the next block forward in case this new size is
+	 * not block aligned since we will be keeping the last block of the
+	 * extent just the way it is.
+	 */
 	if (root->ref_cows || root == root->fs_info->tree_root)
-		btrfs_drop_extent_cache(inode, new_size & (~mask), (u64)-1, 0);
+		btrfs_drop_extent_cache(inode, (new_size + mask) & (~mask), (u64)-1, 0);
 
 	/*
 	 * This function is also used to drop the items in the log tree before
@@ -3429,12 +3433,6 @@
 
 		if (path->slots[0] == 0 ||
 		    path->slots[0] != pending_del_slot) {
-			if (root->ref_cows &&
-			    BTRFS_I(inode)->location.objectid !=
-						BTRFS_FREE_INO_OBJECTID) {
-				err = -EAGAIN;
-				goto out;
-			}
 			if (pending_del_nr) {
 				ret = btrfs_del_items(trans, root, path,
 						pending_del_slot,
@@ -3465,12 +3463,20 @@
 }
 
 /*
- * taken from block_truncate_page, but does cow as it zeros out
- * any bytes left in the last page in the file.
+ * btrfs_truncate_page - read, zero a chunk and write a page
+ * @inode - inode that we're zeroing
+ * @from - the offset to start zeroing
+ * @len - the length to zero, 0 to zero the entire range respective to the
+ *	offset
+ * @front - zero up to the offset instead of from the offset on
+ *
+ * This will find the page for the "from" offset and cow the page and zero the
+ * part we want to zero.  This is used with truncate and hole punching.
  */
-static int btrfs_truncate_page(struct address_space *mapping, loff_t from)
+int btrfs_truncate_page(struct inode *inode, loff_t from, loff_t len,
+			int front)
 {
-	struct inode *inode = mapping->host;
+	struct address_space *mapping = inode->i_mapping;
 	struct btrfs_root *root = BTRFS_I(inode)->root;
 	struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
 	struct btrfs_ordered_extent *ordered;
@@ -3485,7 +3491,8 @@
 	u64 page_start;
 	u64 page_end;
 
-	if ((offset & (blocksize - 1)) == 0)
+	if ((offset & (blocksize - 1)) == 0 &&
+	    (!len || ((len & (blocksize - 1)) == 0)))
 		goto out;
 	ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE);
 	if (ret)
@@ -3532,7 +3539,8 @@
 	}
 
 	clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start, page_end,
-			  EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING,
+			  EXTENT_DIRTY | EXTENT_DELALLOC |
+			  EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
 			  0, 0, &cached_state, GFP_NOFS);
 
 	ret = btrfs_set_extent_delalloc(inode, page_start, page_end,
@@ -3545,8 +3553,13 @@
 
 	ret = 0;
 	if (offset != PAGE_CACHE_SIZE) {
+		if (!len)
+			len = PAGE_CACHE_SIZE - offset;
 		kaddr = kmap(page);
-		memset(kaddr + offset, 0, PAGE_CACHE_SIZE - offset);
+		if (front)
+			memset(kaddr, 0, offset);
+		else
+			memset(kaddr + offset, 0, len);
 		flush_dcache_page(page);
 		kunmap(page);
 	}
@@ -3577,6 +3590,7 @@
 	struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
 	struct extent_map *em = NULL;
 	struct extent_state *cached_state = NULL;
+	struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
 	u64 mask = root->sectorsize - 1;
 	u64 hole_start = (oldsize + mask) & ~mask;
 	u64 block_end = (size + mask) & ~mask;
@@ -3613,7 +3627,7 @@
 		last_byte = min(extent_map_end(em), block_end);
 		last_byte = (last_byte + mask) & ~mask;
 		if (!test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) {
-			u64 hint_byte = 0;
+			struct extent_map *hole_em;
 			hole_size = last_byte - cur_offset;
 
 			trans = btrfs_start_transaction(root, 3);
@@ -3622,9 +3636,9 @@
 				break;
 			}
 
-			err = btrfs_drop_extents(trans, inode, cur_offset,
-						 cur_offset + hole_size,
-						 &hint_byte, 1);
+			err = btrfs_drop_extents(trans, root, inode,
+						 cur_offset,
+						 cur_offset + hole_size, 1);
 			if (err) {
 				btrfs_abort_transaction(trans, root, err);
 				btrfs_end_transaction(trans, root);
@@ -3641,9 +3655,39 @@
 				break;
 			}
 
-			btrfs_drop_extent_cache(inode, hole_start,
-					last_byte - 1, 0);
+			btrfs_drop_extent_cache(inode, cur_offset,
+						cur_offset + hole_size - 1, 0);
+			hole_em = alloc_extent_map();
+			if (!hole_em) {
+				set_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
+					&BTRFS_I(inode)->runtime_flags);
+				goto next;
+			}
+			hole_em->start = cur_offset;
+			hole_em->len = hole_size;
+			hole_em->orig_start = cur_offset;
 
+			hole_em->block_start = EXTENT_MAP_HOLE;
+			hole_em->block_len = 0;
+			hole_em->bdev = root->fs_info->fs_devices->latest_bdev;
+			hole_em->compress_type = BTRFS_COMPRESS_NONE;
+			hole_em->generation = trans->transid;
+
+			while (1) {
+				write_lock(&em_tree->lock);
+				err = add_extent_mapping(em_tree, hole_em);
+				if (!err)
+					list_move(&hole_em->list,
+						  &em_tree->modified_extents);
+				write_unlock(&em_tree->lock);
+				if (err != -EEXIST)
+					break;
+				btrfs_drop_extent_cache(inode, cur_offset,
+							cur_offset +
+							hole_size - 1, 0);
+			}
+			free_extent_map(hole_em);
+next:
 			btrfs_update_inode(trans, root, inode);
 			btrfs_end_transaction(trans, root);
 		}
@@ -3768,26 +3812,22 @@
 		goto no_delete;
 	}
 
-	rsv = btrfs_alloc_block_rsv(root);
+	rsv = btrfs_alloc_block_rsv(root, BTRFS_BLOCK_RSV_TEMP);
 	if (!rsv) {
 		btrfs_orphan_del(NULL, inode);
 		goto no_delete;
 	}
 	rsv->size = min_size;
+	rsv->failfast = 1;
 	global_rsv = &root->fs_info->global_block_rsv;
 
 	btrfs_i_size_write(inode, 0);
 
 	/*
-	 * This is a bit simpler than btrfs_truncate since
-	 *
-	 * 1) We've already reserved our space for our orphan item in the
-	 *    unlink.
-	 * 2) We're going to delete the inode item, so we don't need to update
-	 *    it at all.
-	 *
-	 * So we just need to reserve some slack space in case we add bytes when
-	 * doing the truncate.
+	 * This is a bit simpler than btrfs_truncate since we've already
+	 * reserved our space for our orphan item in the unlink, so we just
+	 * need to reserve some slack space in case we add bytes and update
+	 * inode item when doing the truncate.
 	 */
 	while (1) {
 		ret = btrfs_block_rsv_refill_noflush(root, rsv, min_size);
@@ -3808,7 +3848,7 @@
 			goto no_delete;
 		}
 
-		trans = btrfs_start_transaction(root, 0);
+		trans = btrfs_start_transaction_noflush(root, 1);
 		if (IS_ERR(trans)) {
 			btrfs_orphan_del(NULL, inode);
 			btrfs_free_block_rsv(root, rsv);
@@ -3818,9 +3858,13 @@
 		trans->block_rsv = rsv;
 
 		ret = btrfs_truncate_inode_items(trans, root, inode, 0, 0);
-		if (ret != -EAGAIN)
+		if (ret != -ENOSPC)
 			break;
 
+		trans->block_rsv = &root->fs_info->trans_block_rsv;
+		ret = btrfs_update_inode(trans, root, inode);
+		BUG_ON(ret);
+
 		nr = trans->blocks_used;
 		btrfs_end_transaction(trans, root);
 		trans = NULL;
@@ -4470,10 +4514,7 @@
 			trans = btrfs_join_transaction(root);
 		if (IS_ERR(trans))
 			return PTR_ERR(trans);
-		if (nolock)
-			ret = btrfs_end_transaction_nolock(trans, root);
-		else
-			ret = btrfs_commit_transaction(trans, root);
+		ret = btrfs_commit_transaction(trans, root);
 	}
 	return ret;
 }
@@ -4671,6 +4712,14 @@
 	BTRFS_I(inode)->generation = trans->transid;
 	inode->i_generation = BTRFS_I(inode)->generation;
 
+	/*
+	 * We could have gotten an inode number from somebody who was fsynced
+	 * and then removed in this same transaction, so let's just set full
+	 * sync since it will be a full sync anyway and this will blow away the
+	 * old info in the log.
+	 */
+	set_bit(BTRFS_INODE_NEEDS_FULL_SYNC, &BTRFS_I(inode)->runtime_flags);
+
 	if (S_ISDIR(mode))
 		owner = 0;
 	else
@@ -4680,6 +4729,12 @@
 	btrfs_set_key_type(&key[0], BTRFS_INODE_ITEM_KEY);
 	key[0].offset = 0;
 
+	/*
+	 * Start new inodes with an inode_ref. This is slightly more
+	 * efficient for small numbers of hard links since they will
+	 * be packed into one item. Extended refs will kick in if we
+	 * add more hard links than can fit in the ref item.
+	 */
 	key[1].objectid = objectid;
 	btrfs_set_key_type(&key[1], BTRFS_INODE_REF_KEY);
 	key[1].offset = ref_objectid;
@@ -4986,7 +5041,7 @@
 	if (root->objectid != BTRFS_I(inode)->root->objectid)
 		return -EXDEV;
 
-	if (inode->i_nlink == ~0U)
+	if (inode->i_nlink >= BTRFS_LINK_MAX)
 		return -EMLINK;
 
 	err = btrfs_set_inode_index(dir, &index);
@@ -5450,7 +5505,8 @@
 	write_unlock(&em_tree->lock);
 out:
 
-	trace_btrfs_get_extent(root, em);
+	if (em)
+		trace_btrfs_get_extent(root, em);
 
 	if (path)
 		btrfs_free_path(path);
@@ -5836,6 +5892,48 @@
 	return ret;
 }
 
+static struct extent_map *create_pinned_em(struct inode *inode, u64 start,
+					   u64 len, u64 orig_start,
+					   u64 block_start, u64 block_len,
+					   int type)
+{
+	struct extent_map_tree *em_tree;
+	struct extent_map *em;
+	struct btrfs_root *root = BTRFS_I(inode)->root;
+	int ret;
+
+	em_tree = &BTRFS_I(inode)->extent_tree;
+	em = alloc_extent_map();
+	if (!em)
+		return ERR_PTR(-ENOMEM);
+
+	em->start = start;
+	em->orig_start = orig_start;
+	em->len = len;
+	em->block_len = block_len;
+	em->block_start = block_start;
+	em->bdev = root->fs_info->fs_devices->latest_bdev;
+	set_bit(EXTENT_FLAG_PINNED, &em->flags);
+	if (type == BTRFS_ORDERED_PREALLOC)
+		set_bit(EXTENT_FLAG_PREALLOC, &em->flags);
+
+	do {
+		btrfs_drop_extent_cache(inode, em->start,
+				em->start + em->len - 1, 0);
+		write_lock(&em_tree->lock);
+		ret = add_extent_mapping(em_tree, em);
+		write_unlock(&em_tree->lock);
+	} while (ret == -EEXIST);
+
+	if (ret) {
+		free_extent_map(em);
+		return ERR_PTR(ret);
+	}
+
+	return em;
+}
+
+
 static int btrfs_get_blocks_direct(struct inode *inode, sector_t iblock,
 				   struct buffer_head *bh_result, int create)
 {
@@ -5950,6 +6048,19 @@
 			goto must_cow;
 
 		if (can_nocow_odirect(trans, inode, start, len) == 1) {
+			u64 orig_start = em->start;
+
+			if (type == BTRFS_ORDERED_PREALLOC) {
+				free_extent_map(em);
+				em = create_pinned_em(inode, start, len,
+						       orig_start,
+						       block_start, len, type);
+				if (IS_ERR(em)) {
+					btrfs_end_transaction(trans, root);
+					goto unlock_err;
+				}
+			}
+
 			ret = btrfs_add_ordered_extent_dio(inode, start,
 					   block_start, len, len, type);
 			btrfs_end_transaction(trans, root);
@@ -5999,7 +6110,8 @@
 	if (lockstart < lockend) {
 		if (create && len < lockend - lockstart) {
 			clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart,
-					 lockstart + len - 1, unlock_bits, 1, 0,
+					 lockstart + len - 1,
+					 unlock_bits | EXTENT_DEFRAG, 1, 0,
 					 &cached_state, GFP_NOFS);
 			/*
 			 * Beside unlock, we also need to cleanup reserved space
@@ -6007,8 +6119,8 @@
 			 */
 			clear_extent_bit(&BTRFS_I(inode)->io_tree,
 					 lockstart + len, lockend,
-					 unlock_bits | EXTENT_DO_ACCOUNTING,
-					 1, 0, NULL, GFP_NOFS);
+					 unlock_bits | EXTENT_DO_ACCOUNTING |
+					 EXTENT_DEFRAG, 1, 0, NULL, GFP_NOFS);
 		} else {
 			clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart,
 					 lockend, unlock_bits, 1, 0,
@@ -6573,8 +6685,8 @@
 		 */
 		clear_extent_bit(tree, page_start, page_end,
 				 EXTENT_DIRTY | EXTENT_DELALLOC |
-				 EXTENT_LOCKED | EXTENT_DO_ACCOUNTING, 1, 0,
-				 &cached_state, GFP_NOFS);
+				 EXTENT_LOCKED | EXTENT_DO_ACCOUNTING |
+				 EXTENT_DEFRAG, 1, 0, &cached_state, GFP_NOFS);
 		/*
 		 * whoever cleared the private bit is responsible
 		 * for the finish_ordered_io
@@ -6590,7 +6702,8 @@
 	}
 	clear_extent_bit(tree, page_start, page_end,
 		 EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC |
-		 EXTENT_DO_ACCOUNTING, 1, 1, &cached_state, GFP_NOFS);
+		 EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, 1, 1,
+		 &cached_state, GFP_NOFS);
 	__btrfs_releasepage(page, GFP_NOFS);
 
 	ClearPageChecked(page);
@@ -6687,7 +6800,8 @@
 	 * prepare_pages in the normal write path.
 	 */
 	clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start, page_end,
-			  EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING,
+			  EXTENT_DIRTY | EXTENT_DELALLOC |
+			  EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
 			  0, 0, &cached_state, GFP_NOFS);
 
 	ret = btrfs_set_extent_delalloc(inode, page_start, page_end,
@@ -6718,6 +6832,7 @@
 
 	BTRFS_I(inode)->last_trans = root->fs_info->generation;
 	BTRFS_I(inode)->last_sub_trans = BTRFS_I(inode)->root->log_transid;
+	BTRFS_I(inode)->last_log_commit = BTRFS_I(inode)->root->last_log_commit;
 
 	unlock_extent_cached(io_tree, page_start, page_end, &cached_state, GFP_NOFS);
 
@@ -6745,7 +6860,7 @@
 	u64 mask = root->sectorsize - 1;
 	u64 min_size = btrfs_calc_trunc_metadata_size(root, 1);
 
-	ret = btrfs_truncate_page(inode->i_mapping, inode->i_size);
+	ret = btrfs_truncate_page(inode, inode->i_size, 0, 0);
 	if (ret)
 		return ret;
 
@@ -6788,10 +6903,11 @@
 	 * 3) fs_info->trans_block_rsv - this will have 1 items worth left for
 	 * updating the inode.
 	 */
-	rsv = btrfs_alloc_block_rsv(root);
+	rsv = btrfs_alloc_block_rsv(root, BTRFS_BLOCK_RSV_TEMP);
 	if (!rsv)
 		return -ENOMEM;
 	rsv->size = min_size;
+	rsv->failfast = 1;
 
 	/*
 	 * 1 for the truncate slack space
@@ -6837,36 +6953,21 @@
 					   &BTRFS_I(inode)->runtime_flags))
 		btrfs_add_ordered_operation(trans, root, inode);
 
+	/*
+	 * So if we truncate and then write and fsync we normally would just
+	 * write the extents that changed, which is a problem if we need to
+	 * first truncate that entire inode.  So set this flag so we write out
+	 * all of the extents in the inode to the sync log so we're completely
+	 * safe.
+	 */
+	set_bit(BTRFS_INODE_NEEDS_FULL_SYNC, &BTRFS_I(inode)->runtime_flags);
+	trans->block_rsv = rsv;
+
 	while (1) {
-		ret = btrfs_block_rsv_refill(root, rsv, min_size);
-		if (ret) {
-			/*
-			 * This can only happen with the original transaction we
-			 * started above, every other time we shouldn't have a
-			 * transaction started yet.
-			 */
-			if (ret == -EAGAIN)
-				goto end_trans;
-			err = ret;
-			break;
-		}
-
-		if (!trans) {
-			/* Just need the 1 for updating the inode */
-			trans = btrfs_start_transaction(root, 1);
-			if (IS_ERR(trans)) {
-				ret = err = PTR_ERR(trans);
-				trans = NULL;
-				break;
-			}
-		}
-
-		trans->block_rsv = rsv;
-
 		ret = btrfs_truncate_inode_items(trans, root, inode,
 						 inode->i_size,
 						 BTRFS_EXTENT_DATA_KEY);
-		if (ret != -EAGAIN) {
+		if (ret != -ENOSPC) {
 			err = ret;
 			break;
 		}
@@ -6877,11 +6978,22 @@
 			err = ret;
 			break;
 		}
-end_trans:
+
 		nr = trans->blocks_used;
 		btrfs_end_transaction(trans, root);
-		trans = NULL;
 		btrfs_btree_balance_dirty(root, nr);
+
+		trans = btrfs_start_transaction(root, 2);
+		if (IS_ERR(trans)) {
+			ret = err = PTR_ERR(trans);
+			trans = NULL;
+			break;
+		}
+
+		ret = btrfs_block_rsv_migrate(&root->fs_info->trans_block_rsv,
+					      rsv, min_size);
+		BUG_ON(ret);	/* shouldn't happen */
+		trans->block_rsv = rsv;
 	}
 
 	if (ret == 0 && inode->i_nlink > 0) {
@@ -6965,6 +7077,7 @@
 	ei->csum_bytes = 0;
 	ei->index_cnt = (u64)-1;
 	ei->last_unlink_trans = 0;
+	ei->last_log_commit = 0;
 
 	spin_lock_init(&ei->lock);
 	ei->outstanding_extents = 0;
@@ -7095,31 +7208,31 @@
 
 int btrfs_init_cachep(void)
 {
-	btrfs_inode_cachep = kmem_cache_create("btrfs_inode_cache",
+	btrfs_inode_cachep = kmem_cache_create("btrfs_inode",
 			sizeof(struct btrfs_inode), 0,
 			SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, init_once);
 	if (!btrfs_inode_cachep)
 		goto fail;
 
-	btrfs_trans_handle_cachep = kmem_cache_create("btrfs_trans_handle_cache",
+	btrfs_trans_handle_cachep = kmem_cache_create("btrfs_trans_handle",
 			sizeof(struct btrfs_trans_handle), 0,
 			SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
 	if (!btrfs_trans_handle_cachep)
 		goto fail;
 
-	btrfs_transaction_cachep = kmem_cache_create("btrfs_transaction_cache",
+	btrfs_transaction_cachep = kmem_cache_create("btrfs_transaction",
 			sizeof(struct btrfs_transaction), 0,
 			SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
 	if (!btrfs_transaction_cachep)
 		goto fail;
 
-	btrfs_path_cachep = kmem_cache_create("btrfs_path_cache",
+	btrfs_path_cachep = kmem_cache_create("btrfs_path",
 			sizeof(struct btrfs_path), 0,
 			SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
 	if (!btrfs_path_cachep)
 		goto fail;
 
-	btrfs_free_space_cachep = kmem_cache_create("btrfs_free_space_cache",
+	btrfs_free_space_cachep = kmem_cache_create("btrfs_free_space",
 			sizeof(struct btrfs_free_space), 0,
 			SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
 	if (!btrfs_free_space_cachep)
@@ -7513,6 +7626,8 @@
 				       loff_t actual_len, u64 *alloc_hint,
 				       struct btrfs_trans_handle *trans)
 {
+	struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
+	struct extent_map *em;
 	struct btrfs_root *root = BTRFS_I(inode)->root;
 	struct btrfs_key ins;
 	u64 cur_offset = start;
@@ -7553,6 +7668,37 @@
 		btrfs_drop_extent_cache(inode, cur_offset,
 					cur_offset + ins.offset -1, 0);
 
+		em = alloc_extent_map();
+		if (!em) {
+			set_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
+				&BTRFS_I(inode)->runtime_flags);
+			goto next;
+		}
+
+		em->start = cur_offset;
+		em->orig_start = cur_offset;
+		em->len = ins.offset;
+		em->block_start = ins.objectid;
+		em->block_len = ins.offset;
+		em->bdev = root->fs_info->fs_devices->latest_bdev;
+		set_bit(EXTENT_FLAG_PREALLOC, &em->flags);
+		em->generation = trans->transid;
+
+		while (1) {
+			write_lock(&em_tree->lock);
+			ret = add_extent_mapping(em_tree, em);
+			if (!ret)
+				list_move(&em->list,
+					  &em_tree->modified_extents);
+			write_unlock(&em_tree->lock);
+			if (ret != -EEXIST)
+				break;
+			btrfs_drop_extent_cache(inode, cur_offset,
+						cur_offset + ins.offset - 1,
+						0);
+		}
+		free_extent_map(em);
+next:
 		num_bytes -= ins.offset;
 		cur_offset += ins.offset;
 		*alloc_hint = ins.objectid + ins.offset;
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 47127c1..e568c47 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -181,6 +181,7 @@
 	int ret;
 	u64 ip_oldflags;
 	unsigned int i_oldflags;
+	umode_t mode;
 
 	if (btrfs_root_readonly(root))
 		return -EROFS;
@@ -203,6 +204,7 @@
 
 	ip_oldflags = ip->flags;
 	i_oldflags = inode->i_flags;
+	mode = inode->i_mode;
 
 	flags = btrfs_mask_flags(inode->i_mode, flags);
 	oldflags = btrfs_flags_to_ioctl(ip->flags);
@@ -237,10 +239,31 @@
 		ip->flags |= BTRFS_INODE_DIRSYNC;
 	else
 		ip->flags &= ~BTRFS_INODE_DIRSYNC;
-	if (flags & FS_NOCOW_FL)
-		ip->flags |= BTRFS_INODE_NODATACOW;
-	else
-		ip->flags &= ~BTRFS_INODE_NODATACOW;
+	if (flags & FS_NOCOW_FL) {
+		if (S_ISREG(mode)) {
+			/*
+			 * It's safe to turn csums off here, no extents exist.
+			 * Otherwise we want the flag to reflect the real COW
+			 * status of the file and will not set it.
+			 */
+			if (inode->i_size == 0)
+				ip->flags |= BTRFS_INODE_NODATACOW
+					   | BTRFS_INODE_NODATASUM;
+		} else {
+			ip->flags |= BTRFS_INODE_NODATACOW;
+		}
+	} else {
+		/*
+		 * Revert back under same assuptions as above
+		 */
+		if (S_ISREG(mode)) {
+			if (inode->i_size == 0)
+				ip->flags &= ~(BTRFS_INODE_NODATACOW
+				             | BTRFS_INODE_NODATASUM);
+		} else {
+			ip->flags &= ~BTRFS_INODE_NODATACOW;
+		}
+	}
 
 	/*
 	 * The COMPRESS flag can only be changed by users, while the NOCOMPRESS
@@ -516,7 +539,8 @@
 	if (!pending_snapshot)
 		return -ENOMEM;
 
-	btrfs_init_block_rsv(&pending_snapshot->block_rsv);
+	btrfs_init_block_rsv(&pending_snapshot->block_rsv,
+			     BTRFS_BLOCK_RSV_TEMP);
 	pending_snapshot->dentry = dentry;
 	pending_snapshot->root = root;
 	pending_snapshot->readonly = readonly;
@@ -525,7 +549,7 @@
 		*inherit = NULL;	/* take responsibility to free it */
 	}
 
-	trans = btrfs_start_transaction(root->fs_info->extent_root, 5);
+	trans = btrfs_start_transaction(root->fs_info->extent_root, 6);
 	if (IS_ERR(trans)) {
 		ret = PTR_ERR(trans);
 		goto fail;
@@ -1022,8 +1046,8 @@
 			 page_start, page_end - 1, 0, &cached_state);
 	clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start,
 			  page_end - 1, EXTENT_DIRTY | EXTENT_DELALLOC |
-			  EXTENT_DO_ACCOUNTING, 0, 0, &cached_state,
-			  GFP_NOFS);
+			  EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, 0, 0,
+			  &cached_state, GFP_NOFS);
 
 	if (i_done != page_cnt) {
 		spin_lock(&BTRFS_I(inode)->lock);
@@ -1034,8 +1058,8 @@
 	}
 
 
-	btrfs_set_extent_delalloc(inode, page_start, page_end - 1,
-				  &cached_state);
+	set_extent_defrag(&BTRFS_I(inode)->io_tree, page_start, page_end - 1,
+			  &cached_state, GFP_NOFS);
 
 	unlock_extent_cached(&BTRFS_I(inode)->io_tree,
 			     page_start, page_end - 1, &cached_state,
@@ -2351,7 +2375,6 @@
 	int ret;
 	u64 len = olen;
 	u64 bs = root->fs_info->sb->s_blocksize;
-	u64 hint_byte;
 
 	/*
 	 * TODO:
@@ -2456,13 +2479,13 @@
 	   another, and lock file content */
 	while (1) {
 		struct btrfs_ordered_extent *ordered;
-		lock_extent(&BTRFS_I(src)->io_tree, off, off+len);
-		ordered = btrfs_lookup_first_ordered_extent(src, off+len);
+		lock_extent(&BTRFS_I(src)->io_tree, off, off + len - 1);
+		ordered = btrfs_lookup_first_ordered_extent(src, off + len - 1);
 		if (!ordered &&
-		    !test_range_bit(&BTRFS_I(src)->io_tree, off, off+len,
-				   EXTENT_DELALLOC, 0, NULL))
+		    !test_range_bit(&BTRFS_I(src)->io_tree, off, off + len - 1,
+				    EXTENT_DELALLOC, 0, NULL))
 			break;
-		unlock_extent(&BTRFS_I(src)->io_tree, off, off+len);
+		unlock_extent(&BTRFS_I(src)->io_tree, off, off + len - 1);
 		if (ordered)
 			btrfs_put_ordered_extent(ordered);
 		btrfs_wait_ordered_range(src, off, len);
@@ -2536,7 +2559,7 @@
 			btrfs_release_path(path);
 
 			if (key.offset + datal <= off ||
-			    key.offset >= off+len)
+			    key.offset >= off + len - 1)
 				goto next;
 
 			memcpy(&new_key, &key, sizeof(new_key));
@@ -2574,10 +2597,10 @@
 					datal -= off - key.offset;
 				}
 
-				ret = btrfs_drop_extents(trans, inode,
+				ret = btrfs_drop_extents(trans, root, inode,
 							 new_key.offset,
 							 new_key.offset + datal,
-							 &hint_byte, 1);
+							 1);
 				if (ret) {
 					btrfs_abort_transaction(trans, root,
 								ret);
@@ -2637,8 +2660,8 @@
 					new_key.offset += skip;
 				}
 
-				if (key.offset + datal > off+len)
-					trim = key.offset + datal - (off+len);
+				if (key.offset + datal > off + len)
+					trim = key.offset + datal - (off + len);
 
 				if (comp && (skip || trim)) {
 					ret = -EINVAL;
@@ -2648,10 +2671,10 @@
 				size -= skip + trim;
 				datal -= skip + trim;
 
-				ret = btrfs_drop_extents(trans, inode,
+				ret = btrfs_drop_extents(trans, root, inode,
 							 new_key.offset,
 							 new_key.offset + datal,
-							 &hint_byte, 1);
+							 1);
 				if (ret) {
 					btrfs_abort_transaction(trans, root,
 								ret);
@@ -2715,7 +2738,7 @@
 	ret = 0;
 out:
 	btrfs_release_path(path);
-	unlock_extent(&BTRFS_I(src)->io_tree, off, off+len);
+	unlock_extent(&BTRFS_I(src)->io_tree, off, off + len - 1);
 out_unlock:
 	mutex_unlock(&src->i_mutex);
 	mutex_unlock(&inode->i_mutex);
@@ -2850,8 +2873,8 @@
 	return 0;
 }
 
-static void get_block_group_info(struct list_head *groups_list,
-				 struct btrfs_ioctl_space_info *space)
+void btrfs_get_block_group_info(struct list_head *groups_list,
+				struct btrfs_ioctl_space_info *space)
 {
 	struct btrfs_block_group_cache *block_group;
 
@@ -2959,8 +2982,8 @@
 		down_read(&info->groups_sem);
 		for (c = 0; c < BTRFS_NR_RAID_TYPES; c++) {
 			if (!list_empty(&info->block_groups[c])) {
-				get_block_group_info(&info->block_groups[c],
-						     &space);
+				btrfs_get_block_group_info(
+					&info->block_groups[c], &space);
 				memcpy(dest, &space, sizeof(space));
 				dest++;
 				space_args.total_spaces++;
@@ -3208,11 +3231,9 @@
 {
 	int ret = 0;
 	int size;
-	u64 extent_item_pos;
 	struct btrfs_ioctl_logical_ino_args *loi;
 	struct btrfs_data_container *inodes = NULL;
 	struct btrfs_path *path = NULL;
-	struct btrfs_key key;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
@@ -3230,7 +3251,7 @@
 		goto out;
 	}
 
-	size = min_t(u32, loi->size, 4096);
+	size = min_t(u32, loi->size, 64 * 1024);
 	inodes = init_data_container(size);
 	if (IS_ERR(inodes)) {
 		ret = PTR_ERR(inodes);
@@ -3238,22 +3259,13 @@
 		goto out;
 	}
 
-	ret = extent_from_logical(root->fs_info, loi->logical, path, &key);
-	btrfs_release_path(path);
-
-	if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK)
+	ret = iterate_inodes_from_logical(loi->logical, root->fs_info, path,
+					  build_ino_list, inodes);
+	if (ret == -EINVAL)
 		ret = -ENOENT;
 	if (ret < 0)
 		goto out;
 
-	extent_item_pos = loi->logical - key.objectid;
-	ret = iterate_extent_inodes(root->fs_info, key.objectid,
-					extent_item_pos, 0, build_ino_list,
-					inodes);
-
-	if (ret < 0)
-		goto out;
-
 	ret = copy_to_user((void *)(unsigned long)loi->inodes,
 			   (void *)(unsigned long)inodes, size);
 	if (ret)
@@ -3261,7 +3273,7 @@
 
 out:
 	btrfs_free_path(path);
-	kfree(inodes);
+	vfree(inodes);
 	kfree(loi);
 
 	return ret;
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index 051c7fe..7772f02 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -25,6 +25,8 @@
 #include "btrfs_inode.h"
 #include "extent_io.h"
 
+static struct kmem_cache *btrfs_ordered_extent_cache;
+
 static u64 entry_end(struct btrfs_ordered_extent *entry)
 {
 	if (entry->file_offset + entry->len < entry->file_offset)
@@ -187,7 +189,7 @@
 	struct btrfs_ordered_extent *entry;
 
 	tree = &BTRFS_I(inode)->ordered_tree;
-	entry = kzalloc(sizeof(*entry), GFP_NOFS);
+	entry = kmem_cache_zalloc(btrfs_ordered_extent_cache, GFP_NOFS);
 	if (!entry)
 		return -ENOMEM;
 
@@ -421,7 +423,7 @@
 			list_del(&sum->list);
 			kfree(sum);
 		}
-		kfree(entry);
+		kmem_cache_free(btrfs_ordered_extent_cache, entry);
 	}
 }
 
@@ -466,8 +468,7 @@
  * wait for all the ordered extents in a root.  This is done when balancing
  * space between drives.
  */
-void btrfs_wait_ordered_extents(struct btrfs_root *root,
-				int nocow_only, int delay_iput)
+void btrfs_wait_ordered_extents(struct btrfs_root *root, int delay_iput)
 {
 	struct list_head splice;
 	struct list_head *cur;
@@ -482,15 +483,6 @@
 		cur = splice.next;
 		ordered = list_entry(cur, struct btrfs_ordered_extent,
 				     root_extent_list);
-		if (nocow_only &&
-		    !test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags) &&
-		    !test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags)) {
-			list_move(&ordered->root_extent_list,
-				  &root->fs_info->ordered_extents);
-			cond_resched_lock(&root->fs_info->ordered_extent_lock);
-			continue;
-		}
-
 		list_del_init(&ordered->root_extent_list);
 		atomic_inc(&ordered->refs);
 
@@ -775,7 +767,6 @@
 	struct btrfs_ordered_inode_tree *tree = &BTRFS_I(inode)->ordered_tree;
 	u64 disk_i_size;
 	u64 new_i_size;
-	u64 i_size_test;
 	u64 i_size = i_size_read(inode);
 	struct rb_node *node;
 	struct rb_node *prev = NULL;
@@ -835,55 +826,30 @@
 			break;
 		if (test->file_offset >= i_size)
 			break;
-		if (test->file_offset >= disk_i_size)
+		if (test->file_offset >= disk_i_size) {
+			/*
+			 * we don't update disk_i_size now, so record this
+			 * undealt i_size. Or we will not know the real
+			 * i_size.
+			 */
+			if (test->outstanding_isize < offset)
+				test->outstanding_isize = offset;
+			if (ordered &&
+			    ordered->outstanding_isize >
+			    test->outstanding_isize)
+				test->outstanding_isize =
+						ordered->outstanding_isize;
 			goto out;
+		}
 	}
 	new_i_size = min_t(u64, offset, i_size);
 
 	/*
-	 * at this point, we know we can safely update i_size to at least
-	 * the offset from this ordered extent.  But, we need to
-	 * walk forward and see if ios from higher up in the file have
-	 * finished.
+	 * Some ordered extents may completed before the current one, and
+	 * we hold the real i_size in ->outstanding_isize.
 	 */
-	if (ordered) {
-		node = rb_next(&ordered->rb_node);
-	} else {
-		if (prev)
-			node = rb_next(prev);
-		else
-			node = rb_first(&tree->tree);
-	}
-
-	/*
-	 * We are looking for an area between our current extent and the next
-	 * ordered extent to update the i_size to.  There are 3 cases here
-	 *
-	 * 1) We don't actually have anything and we can update to i_size.
-	 * 2) We have stuff but they already did their i_size update so again we
-	 * can just update to i_size.
-	 * 3) We have an outstanding ordered extent so the most we can update
-	 * our disk_i_size to is the start of the next offset.
-	 */
-	i_size_test = i_size;
-	for (; node; node = rb_next(node)) {
-		test = rb_entry(node, struct btrfs_ordered_extent, rb_node);
-
-		if (test_bit(BTRFS_ORDERED_UPDATED_ISIZE, &test->flags))
-			continue;
-		if (test->file_offset > offset) {
-			i_size_test = test->file_offset;
-			break;
-		}
-	}
-
-	/*
-	 * i_size_test is the end of a region after this ordered
-	 * extent where there are no ordered extents, we can safely set
-	 * disk_i_size to this.
-	 */
-	if (i_size_test > offset)
-		new_i_size = min_t(u64, i_size_test, i_size);
+	if (ordered && ordered->outstanding_isize > new_i_size)
+		new_i_size = min_t(u64, ordered->outstanding_isize, i_size);
 	BTRFS_I(inode)->disk_i_size = new_i_size;
 	ret = 0;
 out:
@@ -984,3 +950,20 @@
 	}
 	spin_unlock(&root->fs_info->ordered_extent_lock);
 }
+
+int __init ordered_data_init(void)
+{
+	btrfs_ordered_extent_cache = kmem_cache_create("btrfs_ordered_extent",
+				     sizeof(struct btrfs_ordered_extent), 0,
+				     SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD,
+				     NULL);
+	if (!btrfs_ordered_extent_cache)
+		return -ENOMEM;
+	return 0;
+}
+
+void ordered_data_exit(void)
+{
+	if (btrfs_ordered_extent_cache)
+		kmem_cache_destroy(btrfs_ordered_extent_cache);
+}
diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h
index e03c560..dd27a0b 100644
--- a/fs/btrfs/ordered-data.h
+++ b/fs/btrfs/ordered-data.h
@@ -96,6 +96,13 @@
 	/* number of bytes that still need writing */
 	u64 bytes_left;
 
+	/*
+	 * the end of the ordered extent which is behind it but
+	 * didn't update disk_i_size. Please see the comment of
+	 * btrfs_ordered_update_i_size();
+	 */
+	u64 outstanding_isize;
+
 	/* flags (described above) */
 	unsigned long flags;
 
@@ -183,6 +190,7 @@
 void btrfs_add_ordered_operation(struct btrfs_trans_handle *trans,
 				 struct btrfs_root *root,
 				 struct inode *inode);
-void btrfs_wait_ordered_extents(struct btrfs_root *root,
-				int nocow_only, int delay_iput);
+void btrfs_wait_ordered_extents(struct btrfs_root *root, int delay_iput);
+int __init ordered_data_init(void);
+void ordered_data_exit(void);
 #endif
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index b650155..5039686 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -1145,12 +1145,12 @@
 
 		ulist_reinit(tmp);
 						/* XXX id not needed */
-		ulist_add(tmp, qg->qgroupid, (unsigned long)qg, GFP_ATOMIC);
+		ulist_add(tmp, qg->qgroupid, (u64)(uintptr_t)qg, GFP_ATOMIC);
 		ULIST_ITER_INIT(&tmp_uiter);
 		while ((tmp_unode = ulist_next(tmp, &tmp_uiter))) {
 			struct btrfs_qgroup_list *glist;
 
-			qg = (struct btrfs_qgroup *)tmp_unode->aux;
+			qg = (struct btrfs_qgroup *)(uintptr_t)tmp_unode->aux;
 			if (qg->refcnt < seq)
 				qg->refcnt = seq + 1;
 			else
@@ -1158,7 +1158,7 @@
 
 			list_for_each_entry(glist, &qg->groups, next_group) {
 				ulist_add(tmp, glist->group->qgroupid,
-					  (unsigned long)glist->group,
+					  (u64)(uintptr_t)glist->group,
 					  GFP_ATOMIC);
 			}
 		}
@@ -1168,13 +1168,13 @@
 	 * step 2: walk from the new root
 	 */
 	ulist_reinit(tmp);
-	ulist_add(tmp, qgroup->qgroupid, (unsigned long)qgroup, GFP_ATOMIC);
+	ulist_add(tmp, qgroup->qgroupid, (uintptr_t)qgroup, GFP_ATOMIC);
 	ULIST_ITER_INIT(&uiter);
 	while ((unode = ulist_next(tmp, &uiter))) {
 		struct btrfs_qgroup *qg;
 		struct btrfs_qgroup_list *glist;
 
-		qg = (struct btrfs_qgroup *)unode->aux;
+		qg = (struct btrfs_qgroup *)(uintptr_t)unode->aux;
 		if (qg->refcnt < seq) {
 			/* not visited by step 1 */
 			qg->rfer += sgn * node->num_bytes;
@@ -1190,7 +1190,7 @@
 
 		list_for_each_entry(glist, &qg->groups, next_group) {
 			ulist_add(tmp, glist->group->qgroupid,
-				  (unsigned long)glist->group, GFP_ATOMIC);
+				  (uintptr_t)glist->group, GFP_ATOMIC);
 		}
 	}
 
@@ -1208,12 +1208,12 @@
 			continue;
 
 		ulist_reinit(tmp);
-		ulist_add(tmp, qg->qgroupid, (unsigned long)qg, GFP_ATOMIC);
+		ulist_add(tmp, qg->qgroupid, (uintptr_t)qg, GFP_ATOMIC);
 		ULIST_ITER_INIT(&tmp_uiter);
 		while ((tmp_unode = ulist_next(tmp, &tmp_uiter))) {
 			struct btrfs_qgroup_list *glist;
 
-			qg = (struct btrfs_qgroup *)tmp_unode->aux;
+			qg = (struct btrfs_qgroup *)(uintptr_t)tmp_unode->aux;
 			if (qg->tag == seq)
 				continue;
 
@@ -1225,7 +1225,7 @@
 
 			list_for_each_entry(glist, &qg->groups, next_group) {
 				ulist_add(tmp, glist->group->qgroupid,
-					  (unsigned long)glist->group,
+					  (uintptr_t)glist->group,
 					  GFP_ATOMIC);
 			}
 		}
@@ -1469,13 +1469,17 @@
 	 * be exceeded
 	 */
 	ulist = ulist_alloc(GFP_ATOMIC);
-	ulist_add(ulist, qgroup->qgroupid, (unsigned long)qgroup, GFP_ATOMIC);
+	if (!ulist) {
+		ret = -ENOMEM;
+		goto out;
+	}
+	ulist_add(ulist, qgroup->qgroupid, (uintptr_t)qgroup, GFP_ATOMIC);
 	ULIST_ITER_INIT(&uiter);
 	while ((unode = ulist_next(ulist, &uiter))) {
 		struct btrfs_qgroup *qg;
 		struct btrfs_qgroup_list *glist;
 
-		qg = (struct btrfs_qgroup *)unode->aux;
+		qg = (struct btrfs_qgroup *)(uintptr_t)unode->aux;
 
 		if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_RFER) &&
 		    qg->reserved + qg->rfer + num_bytes >
@@ -1489,7 +1493,7 @@
 
 		list_for_each_entry(glist, &qg->groups, next_group) {
 			ulist_add(ulist, glist->group->qgroupid,
-				  (unsigned long)glist->group, GFP_ATOMIC);
+				  (uintptr_t)glist->group, GFP_ATOMIC);
 		}
 	}
 	if (ret)
@@ -1502,7 +1506,7 @@
 	while ((unode = ulist_next(ulist, &uiter))) {
 		struct btrfs_qgroup *qg;
 
-		qg = (struct btrfs_qgroup *)unode->aux;
+		qg = (struct btrfs_qgroup *)(uintptr_t)unode->aux;
 
 		qg->reserved += num_bytes;
 	}
@@ -1541,19 +1545,23 @@
 		goto out;
 
 	ulist = ulist_alloc(GFP_ATOMIC);
-	ulist_add(ulist, qgroup->qgroupid, (unsigned long)qgroup, GFP_ATOMIC);
+	if (!ulist) {
+		btrfs_std_error(fs_info, -ENOMEM);
+		goto out;
+	}
+	ulist_add(ulist, qgroup->qgroupid, (uintptr_t)qgroup, GFP_ATOMIC);
 	ULIST_ITER_INIT(&uiter);
 	while ((unode = ulist_next(ulist, &uiter))) {
 		struct btrfs_qgroup *qg;
 		struct btrfs_qgroup_list *glist;
 
-		qg = (struct btrfs_qgroup *)unode->aux;
+		qg = (struct btrfs_qgroup *)(uintptr_t)unode->aux;
 
 		qg->reserved -= num_bytes;
 
 		list_for_each_entry(glist, &qg->groups, next_group) {
 			ulist_add(ulist, glist->group->qgroupid,
-				  (unsigned long)glist->group, GFP_ATOMIC);
+				  (uintptr_t)glist->group, GFP_ATOMIC);
 		}
 	}
 
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 4da0865..776f0aa 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -3270,8 +3270,8 @@
 	key.offset = 0;
 
 	inode = btrfs_iget(fs_info->sb, &key, root, NULL);
-	if (IS_ERR_OR_NULL(inode) || is_bad_inode(inode)) {
-		if (inode && !IS_ERR(inode))
+	if (IS_ERR(inode) || is_bad_inode(inode)) {
+		if (!IS_ERR(inode))
 			iput(inode);
 		return -ENOENT;
 	}
@@ -3621,7 +3621,7 @@
 
 		ret = find_first_extent_bit(&rc->processed_blocks,
 					    key.objectid, &start, &end,
-					    EXTENT_DIRTY);
+					    EXTENT_DIRTY, NULL);
 
 		if (ret == 0 && start <= key.objectid) {
 			btrfs_release_path(path);
@@ -3674,7 +3674,8 @@
 	struct btrfs_trans_handle *trans;
 	int ret;
 
-	rc->block_rsv = btrfs_alloc_block_rsv(rc->extent_root);
+	rc->block_rsv = btrfs_alloc_block_rsv(rc->extent_root,
+					      BTRFS_BLOCK_RSV_TEMP);
 	if (!rc->block_rsv)
 		return -ENOMEM;
 
@@ -4057,7 +4058,7 @@
 	       (unsigned long long)rc->block_group->flags);
 
 	btrfs_start_delalloc_inodes(fs_info->tree_root, 0);
-	btrfs_wait_ordered_extents(fs_info->tree_root, 0, 0);
+	btrfs_wait_ordered_extents(fs_info->tree_root, 0);
 
 	while (1) {
 		mutex_lock(&fs_info->cleaner_mutex);
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c
index 10d8e4d..eb923d0 100644
--- a/fs/btrfs/root-tree.c
+++ b/fs/btrfs/root-tree.c
@@ -141,8 +141,10 @@
 		return -ENOMEM;
 
 	ret = btrfs_search_slot(trans, root, key, path, 0, 1);
-	if (ret < 0)
-		goto out_abort;
+	if (ret < 0) {
+		btrfs_abort_transaction(trans, root, ret);
+		goto out;
+	}
 
 	if (ret != 0) {
 		btrfs_print_leaf(root, path->nodes[0]);
@@ -166,16 +168,23 @@
 		btrfs_release_path(path);
 		ret = btrfs_search_slot(trans, root, key, path,
 				-1, 1);
-		if (ret < 0)
-			goto out_abort;
+		if (ret < 0) {
+			btrfs_abort_transaction(trans, root, ret);
+			goto out;
+		}
+
 		ret = btrfs_del_item(trans, root, path);
-		if (ret < 0)
-			goto out_abort;
+		if (ret < 0) {
+			btrfs_abort_transaction(trans, root, ret);
+			goto out;
+		}
 		btrfs_release_path(path);
 		ret = btrfs_insert_empty_item(trans, root, path,
 				key, sizeof(*item));
-		if (ret < 0)
-			goto out_abort;
+		if (ret < 0) {
+			btrfs_abort_transaction(trans, root, ret);
+			goto out;
+		}
 		l = path->nodes[0];
 		slot = path->slots[0];
 		ptr = btrfs_item_ptr_offset(l, slot);
@@ -192,10 +201,6 @@
 out:
 	btrfs_free_path(path);
 	return ret;
-
-out_abort:
-	btrfs_abort_transaction(trans, root, ret);
-	goto out;
 }
 
 int btrfs_insert_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index b223620..27892f6 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -352,13 +352,14 @@
 	struct extent_buffer *eb;
 	struct btrfs_extent_item *ei;
 	struct scrub_warning swarn;
-	u32 item_size;
-	int ret;
-	u64 ref_root;
-	u8 ref_level;
 	unsigned long ptr = 0;
-	const int bufsize = 4096;
 	u64 extent_item_pos;
+	u64 flags = 0;
+	u64 ref_root;
+	u32 item_size;
+	u8 ref_level;
+	const int bufsize = 4096;
+	int ret;
 
 	path = btrfs_alloc_path();
 
@@ -375,7 +376,8 @@
 	if (!path || !swarn.scratch_buf || !swarn.msg_buf)
 		goto out;
 
-	ret = extent_from_logical(fs_info, swarn.logical, path, &found_key);
+	ret = extent_from_logical(fs_info, swarn.logical, path, &found_key,
+				  &flags);
 	if (ret < 0)
 		goto out;
 
@@ -387,7 +389,7 @@
 	item_size = btrfs_item_size_nr(eb, path->slots[0]);
 	btrfs_release_path(path);
 
-	if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
+	if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
 		do {
 			ret = tree_backref_for_extent(&ptr, eb, ei, item_size,
 							&ref_root, &ref_level);
@@ -1029,6 +1031,7 @@
 				spin_lock(&sdev->stat_lock);
 				sdev->stat.malloc_errors++;
 				spin_unlock(&sdev->stat_lock);
+				kfree(bbio);
 				return -ENOMEM;
 			}
 			sblock->page_count++;
@@ -1666,21 +1669,6 @@
 		scrub_block_put(sblock);
 	}
 
-	if (sbio->err) {
-		/* what is this good for??? */
-		sbio->bio->bi_flags &= ~(BIO_POOL_MASK - 1);
-		sbio->bio->bi_flags |= 1 << BIO_UPTODATE;
-		sbio->bio->bi_phys_segments = 0;
-		sbio->bio->bi_idx = 0;
-
-		for (i = 0; i < sbio->page_count; i++) {
-			struct bio_vec *bi;
-			bi = &sbio->bio->bi_io_vec[i];
-			bi->bv_offset = 0;
-			bi->bv_len = PAGE_SIZE;
-		}
-	}
-
 	bio_put(sbio->bio);
 	sbio->bio = NULL;
 	spin_lock(&sdev->list_lock);
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index fb5ffe9..c7beb54 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -107,7 +107,6 @@
 	int cur_inode_new;
 	int cur_inode_new_gen;
 	int cur_inode_deleted;
-	int cur_inode_first_ref_orphan;
 	u64 cur_inode_size;
 	u64 cur_inode_mode;
 
@@ -126,7 +125,15 @@
 
 struct name_cache_entry {
 	struct list_head list;
-	struct list_head use_list;
+	/*
+	 * radix_tree has only 32bit entries but we need to handle 64bit inums.
+	 * We use the lower 32bit of the 64bit inum to store it in the tree. If
+	 * more then one inum would fall into the same entry, we use radix_list
+	 * to store the additional entries. radix_list is also used to store
+	 * entries where two entries have the same inum but different
+	 * generations.
+	 */
+	struct list_head radix_list;
 	u64 ino;
 	u64 gen;
 	u64 parent_ino;
@@ -328,6 +335,7 @@
 	return ret;
 }
 
+#if 0
 static void fs_path_remove(struct fs_path *p)
 {
 	BUG_ON(p->reversed);
@@ -335,6 +343,7 @@
 		p->end--;
 	*p->end = 0;
 }
+#endif
 
 static int fs_path_copy(struct fs_path *p, struct fs_path *from)
 {
@@ -377,7 +386,7 @@
 	return path;
 }
 
-static int write_buf(struct send_ctx *sctx, const void *buf, u32 len)
+int write_buf(struct file *filp, const void *buf, u32 len, loff_t *off)
 {
 	int ret;
 	mm_segment_t old_fs;
@@ -387,8 +396,7 @@
 	set_fs(KERNEL_DS);
 
 	while (pos < len) {
-		ret = vfs_write(sctx->send_filp, (char *)buf + pos, len - pos,
-				&sctx->send_off);
+		ret = vfs_write(filp, (char *)buf + pos, len - pos, off);
 		/* TODO handle that correctly */
 		/*if (ret == -ERESTARTSYS) {
 			continue;
@@ -544,7 +552,8 @@
 	strcpy(hdr.magic, BTRFS_SEND_STREAM_MAGIC);
 	hdr.version = cpu_to_le32(BTRFS_SEND_STREAM_VERSION);
 
-	return write_buf(sctx, &hdr, sizeof(hdr));
+	return write_buf(sctx->send_filp, &hdr, sizeof(hdr),
+					&sctx->send_off);
 }
 
 /*
@@ -581,7 +590,8 @@
 	crc = crc32c(0, (unsigned char *)sctx->send_buf, sctx->send_size);
 	hdr->crc = cpu_to_le32(crc);
 
-	ret = write_buf(sctx, sctx->send_buf, sctx->send_size);
+	ret = write_buf(sctx->send_filp, sctx->send_buf, sctx->send_size,
+					&sctx->send_off);
 
 	sctx->total_send_size += sctx->send_size;
 	sctx->cmd_send_size[le16_to_cpu(hdr->cmd)] += sctx->send_size;
@@ -687,7 +697,8 @@
  */
 static int get_inode_info(struct btrfs_root *root,
 			  u64 ino, u64 *size, u64 *gen,
-			  u64 *mode, u64 *uid, u64 *gid)
+			  u64 *mode, u64 *uid, u64 *gid,
+			  u64 *rdev)
 {
 	int ret;
 	struct btrfs_inode_item *ii;
@@ -721,6 +732,8 @@
 		*uid = btrfs_inode_uid(path->nodes[0], ii);
 	if (gid)
 		*gid = btrfs_inode_gid(path->nodes[0], ii);
+	if (rdev)
+		*rdev = btrfs_inode_rdev(path->nodes[0], ii);
 
 out:
 	btrfs_free_path(path);
@@ -852,7 +865,6 @@
 	struct extent_buffer *eb;
 	struct btrfs_item *item;
 	struct btrfs_dir_item *di;
-	struct btrfs_path *tmp_path = NULL;
 	struct btrfs_key di_key;
 	char *buf = NULL;
 	char *buf2 = NULL;
@@ -874,12 +886,6 @@
 		goto out;
 	}
 
-	tmp_path = alloc_path_for_send();
-	if (!tmp_path) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
 	eb = path->nodes[0];
 	slot = path->slots[0];
 	item = btrfs_item_nr(eb, slot);
@@ -941,7 +947,6 @@
 	}
 
 out:
-	btrfs_free_path(tmp_path);
 	if (buf_virtual)
 		vfree(buf);
 	else
@@ -1026,12 +1031,12 @@
 	u64 extent_len;
 
 	/* Just to check for bugs in backref resolving */
-	int found_in_send_root;
+	int found_itself;
 };
 
 static int __clone_root_cmp_bsearch(const void *key, const void *elt)
 {
-	u64 root = (u64)key;
+	u64 root = (u64)(uintptr_t)key;
 	struct clone_root *cr = (struct clone_root *)elt;
 
 	if (root < cr->root->objectid)
@@ -1055,6 +1060,7 @@
 
 /*
  * Called for every backref that is found for the current extent.
+ * Results are collected in sctx->clone_roots->ino/offset/found_refs
  */
 static int __iterate_backrefs(u64 ino, u64 offset, u64 root, void *ctx_)
 {
@@ -1064,7 +1070,7 @@
 	u64 i_size;
 
 	/* First check if the root is in the list of accepted clone sources */
-	found = bsearch((void *)root, bctx->sctx->clone_roots,
+	found = bsearch((void *)(uintptr_t)root, bctx->sctx->clone_roots,
 			bctx->sctx->clone_roots_cnt,
 			sizeof(struct clone_root),
 			__clone_root_cmp_bsearch);
@@ -1074,14 +1080,15 @@
 	if (found->root == bctx->sctx->send_root &&
 	    ino == bctx->cur_objectid &&
 	    offset == bctx->cur_offset) {
-		bctx->found_in_send_root = 1;
+		bctx->found_itself = 1;
 	}
 
 	/*
-	 * There are inodes that have extents that lie behind it's i_size. Don't
+	 * There are inodes that have extents that lie behind its i_size. Don't
 	 * accept clones from these extents.
 	 */
-	ret = get_inode_info(found->root, ino, &i_size, NULL, NULL, NULL, NULL);
+	ret = get_inode_info(found->root, ino, &i_size, NULL, NULL, NULL, NULL,
+			NULL);
 	if (ret < 0)
 		return ret;
 
@@ -1101,16 +1108,12 @@
 		 */
 		if (ino >= bctx->cur_objectid)
 			return 0;
-		/*if (ino > ctx->cur_objectid)
+#if 0
+		if (ino > bctx->cur_objectid)
 			return 0;
-		if (offset + ctx->extent_len > ctx->cur_offset)
-			return 0;*/
-
-		bctx->found++;
-		found->found_refs++;
-		found->ino = ino;
-		found->offset = offset;
-		return 0;
+		if (offset + bctx->extent_len > bctx->cur_offset)
+			return 0;
+#endif
 	}
 
 	bctx->found++;
@@ -1130,6 +1133,12 @@
 }
 
 /*
+ * Given an inode, offset and extent item, it finds a good clone for a clone
+ * instruction. Returns -ENOENT when none could be found. The function makes
+ * sure that the returned clone is usable at the point where sending is at the
+ * moment. This means, that no clones are accepted which lie behind the current
+ * inode+offset.
+ *
  * path must point to the extent item when called.
  */
 static int find_extent_clone(struct send_ctx *sctx,
@@ -1141,20 +1150,29 @@
 	int ret;
 	int extent_type;
 	u64 logical;
+	u64 disk_byte;
 	u64 num_bytes;
 	u64 extent_item_pos;
+	u64 flags = 0;
 	struct btrfs_file_extent_item *fi;
 	struct extent_buffer *eb = path->nodes[0];
-	struct backref_ctx backref_ctx;
+	struct backref_ctx *backref_ctx = NULL;
 	struct clone_root *cur_clone_root;
 	struct btrfs_key found_key;
 	struct btrfs_path *tmp_path;
+	int compressed;
 	u32 i;
 
 	tmp_path = alloc_path_for_send();
 	if (!tmp_path)
 		return -ENOMEM;
 
+	backref_ctx = kmalloc(sizeof(*backref_ctx), GFP_NOFS);
+	if (!backref_ctx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
 	if (data_offset >= ino_size) {
 		/*
 		 * There may be extents that lie behind the file's size.
@@ -1172,22 +1190,23 @@
 		ret = -ENOENT;
 		goto out;
 	}
+	compressed = btrfs_file_extent_compression(eb, fi);
 
 	num_bytes = btrfs_file_extent_num_bytes(eb, fi);
-	logical = btrfs_file_extent_disk_bytenr(eb, fi);
-	if (logical == 0) {
+	disk_byte = btrfs_file_extent_disk_bytenr(eb, fi);
+	if (disk_byte == 0) {
 		ret = -ENOENT;
 		goto out;
 	}
-	logical += btrfs_file_extent_offset(eb, fi);
+	logical = disk_byte + btrfs_file_extent_offset(eb, fi);
 
-	ret = extent_from_logical(sctx->send_root->fs_info,
-			logical, tmp_path, &found_key);
+	ret = extent_from_logical(sctx->send_root->fs_info, disk_byte, tmp_path,
+				  &found_key, &flags);
 	btrfs_release_path(tmp_path);
 
 	if (ret < 0)
 		goto out;
-	if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
+	if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
 		ret = -EIO;
 		goto out;
 	}
@@ -1202,12 +1221,12 @@
 		cur_clone_root->found_refs = 0;
 	}
 
-	backref_ctx.sctx = sctx;
-	backref_ctx.found = 0;
-	backref_ctx.cur_objectid = ino;
-	backref_ctx.cur_offset = data_offset;
-	backref_ctx.found_in_send_root = 0;
-	backref_ctx.extent_len = num_bytes;
+	backref_ctx->sctx = sctx;
+	backref_ctx->found = 0;
+	backref_ctx->cur_objectid = ino;
+	backref_ctx->cur_offset = data_offset;
+	backref_ctx->found_itself = 0;
+	backref_ctx->extent_len = num_bytes;
 
 	/*
 	 * The last extent of a file may be too large due to page alignment.
@@ -1215,25 +1234,31 @@
 	 * __iterate_backrefs work.
 	 */
 	if (data_offset + num_bytes >= ino_size)
-		backref_ctx.extent_len = ino_size - data_offset;
+		backref_ctx->extent_len = ino_size - data_offset;
 
 	/*
 	 * Now collect all backrefs.
 	 */
+	if (compressed == BTRFS_COMPRESS_NONE)
+		extent_item_pos = logical - found_key.objectid;
+	else
+		extent_item_pos = 0;
+
 	extent_item_pos = logical - found_key.objectid;
 	ret = iterate_extent_inodes(sctx->send_root->fs_info,
 					found_key.objectid, extent_item_pos, 1,
-					__iterate_backrefs, &backref_ctx);
+					__iterate_backrefs, backref_ctx);
+
 	if (ret < 0)
 		goto out;
 
-	if (!backref_ctx.found_in_send_root) {
+	if (!backref_ctx->found_itself) {
 		/* found a bug in backref code? */
 		ret = -EIO;
 		printk(KERN_ERR "btrfs: ERROR did not find backref in "
 				"send_root. inode=%llu, offset=%llu, "
-				"logical=%llu\n",
-				ino, data_offset, logical);
+				"disk_byte=%llu found extent=%llu\n",
+				ino, data_offset, disk_byte, found_key.objectid);
 		goto out;
 	}
 
@@ -1242,7 +1267,7 @@
 		"num_bytes=%llu, logical=%llu\n",
 		data_offset, ino, num_bytes, logical);
 
-	if (!backref_ctx.found)
+	if (!backref_ctx->found)
 		verbose_printk("btrfs:    no clones found\n");
 
 	cur_clone_root = NULL;
@@ -1253,7 +1278,6 @@
 			else if (sctx->clone_roots[i].root == sctx->send_root)
 				/* prefer clones from send_root over others */
 				cur_clone_root = sctx->clone_roots + i;
-			break;
 		}
 
 	}
@@ -1267,6 +1291,7 @@
 
 out:
 	btrfs_free_path(tmp_path);
+	kfree(backref_ctx);
 	return ret;
 }
 
@@ -1307,8 +1332,6 @@
 	len = btrfs_file_extent_inline_len(path->nodes[0], ei);
 
 	ret = fs_path_add_from_extent_buffer(dest, path->nodes[0], off, len);
-	if (ret < 0)
-		goto out;
 
 out:
 	btrfs_free_path(path);
@@ -1404,7 +1427,7 @@
 	u64 right_gen;
 
 	ret = get_inode_info(sctx->send_root, ino, NULL, &left_gen, NULL, NULL,
-			NULL);
+			NULL, NULL);
 	if (ret < 0 && ret != -ENOENT)
 		goto out;
 	left_ret = ret;
@@ -1413,16 +1436,16 @@
 		right_ret = -ENOENT;
 	} else {
 		ret = get_inode_info(sctx->parent_root, ino, NULL, &right_gen,
-				NULL, NULL, NULL);
+				NULL, NULL, NULL, NULL);
 		if (ret < 0 && ret != -ENOENT)
 			goto out;
 		right_ret = ret;
 	}
 
 	if (!left_ret && !right_ret) {
-		if (left_gen == gen && right_gen == gen)
+		if (left_gen == gen && right_gen == gen) {
 			ret = inode_state_no_change;
-		else if (left_gen == gen) {
+		} else if (left_gen == gen) {
 			if (ino < sctx->send_progress)
 				ret = inode_state_did_create;
 			else
@@ -1516,6 +1539,10 @@
 	return ret;
 }
 
+/*
+ * Looks up the first btrfs_inode_ref of a given ino. It returns the parent dir,
+ * generation of the parent dir and the name of the dir entry.
+ */
 static int get_first_ref(struct send_ctx *sctx,
 			 struct btrfs_root *root, u64 ino,
 			 u64 *dir, u64 *dir_gen, struct fs_path *name)
@@ -1557,7 +1584,7 @@
 	btrfs_release_path(path);
 
 	ret = get_inode_info(root, found_key.offset, NULL, dir_gen, NULL, NULL,
-			NULL);
+			NULL, NULL);
 	if (ret < 0)
 		goto out;
 
@@ -1586,22 +1613,28 @@
 	if (ret < 0)
 		goto out;
 
-	if (name_len != fs_path_len(tmp_name)) {
+	if (dir != tmp_dir || name_len != fs_path_len(tmp_name)) {
 		ret = 0;
 		goto out;
 	}
 
-	ret = memcmp(tmp_name->start, name, name_len);
-	if (ret)
-		ret = 0;
-	else
-		ret = 1;
+	ret = !memcmp(tmp_name->start, name, name_len);
 
 out:
 	fs_path_free(sctx, tmp_name);
 	return ret;
 }
 
+/*
+ * Used by process_recorded_refs to determine if a new ref would overwrite an
+ * already existing ref. In case it detects an overwrite, it returns the
+ * inode/gen in who_ino/who_gen.
+ * When an overwrite is detected, process_recorded_refs does proper orphanizing
+ * to make sure later references to the overwritten inode are possible.
+ * Orphanizing is however only required for the first ref of an inode.
+ * process_recorded_refs does an additional is_first_ref check to see if
+ * orphanizing is really required.
+ */
 static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen,
 			      const char *name, int name_len,
 			      u64 *who_ino, u64 *who_gen)
@@ -1626,9 +1659,14 @@
 		goto out;
 	}
 
+	/*
+	 * Check if the overwritten ref was already processed. If yes, the ref
+	 * was already unlinked/moved, so we can safely assume that we will not
+	 * overwrite anything at this point in time.
+	 */
 	if (other_inode > sctx->send_progress) {
 		ret = get_inode_info(sctx->parent_root, other_inode, NULL,
-				who_gen, NULL, NULL, NULL);
+				who_gen, NULL, NULL, NULL, NULL);
 		if (ret < 0)
 			goto out;
 
@@ -1642,6 +1680,13 @@
 	return ret;
 }
 
+/*
+ * Checks if the ref was overwritten by an already processed inode. This is
+ * used by __get_cur_name_and_parent to find out if the ref was orphanized and
+ * thus the orphan name needs be used.
+ * process_recorded_refs also uses it to avoid unlinking of refs that were
+ * overwritten.
+ */
 static int did_overwrite_ref(struct send_ctx *sctx,
 			    u64 dir, u64 dir_gen,
 			    u64 ino, u64 ino_gen,
@@ -1671,7 +1716,7 @@
 	}
 
 	ret = get_inode_info(sctx->send_root, ow_inode, NULL, &gen, NULL, NULL,
-			NULL);
+			NULL, NULL);
 	if (ret < 0)
 		goto out;
 
@@ -1690,6 +1735,11 @@
 	return ret;
 }
 
+/*
+ * Same as did_overwrite_ref, but also checks if it is the first ref of an inode
+ * that got overwritten. This is used by process_recorded_refs to determine
+ * if it has to use the path as returned by get_cur_path or the orphan name.
+ */
 static int did_overwrite_first_ref(struct send_ctx *sctx, u64 ino, u64 gen)
 {
 	int ret = 0;
@@ -1710,39 +1760,40 @@
 
 	ret = did_overwrite_ref(sctx, dir, dir_gen, ino, gen,
 			name->start, fs_path_len(name));
-	if (ret < 0)
-		goto out;
 
 out:
 	fs_path_free(sctx, name);
 	return ret;
 }
 
+/*
+ * Insert a name cache entry. On 32bit kernels the radix tree index is 32bit,
+ * so we need to do some special handling in case we have clashes. This function
+ * takes care of this with the help of name_cache_entry::radix_list.
+ * In case of error, nce is kfreed.
+ */
 static int name_cache_insert(struct send_ctx *sctx,
 			     struct name_cache_entry *nce)
 {
 	int ret = 0;
-	struct name_cache_entry **ncea;
+	struct list_head *nce_head;
 
-	ncea = radix_tree_lookup(&sctx->name_cache, nce->ino);
-	if (ncea) {
-		if (!ncea[0])
-			ncea[0] = nce;
-		else if (!ncea[1])
-			ncea[1] = nce;
-		else
-			BUG();
-	} else {
-		ncea = kmalloc(sizeof(void *) * 2, GFP_NOFS);
-		if (!ncea)
+	nce_head = radix_tree_lookup(&sctx->name_cache,
+			(unsigned long)nce->ino);
+	if (!nce_head) {
+		nce_head = kmalloc(sizeof(*nce_head), GFP_NOFS);
+		if (!nce_head)
 			return -ENOMEM;
+		INIT_LIST_HEAD(nce_head);
 
-		ncea[0] = nce;
-		ncea[1] = NULL;
-		ret = radix_tree_insert(&sctx->name_cache, nce->ino, ncea);
-		if (ret < 0)
+		ret = radix_tree_insert(&sctx->name_cache, nce->ino, nce_head);
+		if (ret < 0) {
+			kfree(nce_head);
+			kfree(nce);
 			return ret;
+		}
 	}
+	list_add_tail(&nce->radix_list, nce_head);
 	list_add_tail(&nce->list, &sctx->name_cache_list);
 	sctx->name_cache_size++;
 
@@ -1752,50 +1803,52 @@
 static void name_cache_delete(struct send_ctx *sctx,
 			      struct name_cache_entry *nce)
 {
-	struct name_cache_entry **ncea;
+	struct list_head *nce_head;
 
-	ncea = radix_tree_lookup(&sctx->name_cache, nce->ino);
-	BUG_ON(!ncea);
+	nce_head = radix_tree_lookup(&sctx->name_cache,
+			(unsigned long)nce->ino);
+	BUG_ON(!nce_head);
 
-	if (ncea[0] == nce)
-		ncea[0] = NULL;
-	else if (ncea[1] == nce)
-		ncea[1] = NULL;
-	else
-		BUG();
-
-	if (!ncea[0] && !ncea[1]) {
-		radix_tree_delete(&sctx->name_cache, nce->ino);
-		kfree(ncea);
-	}
-
+	list_del(&nce->radix_list);
 	list_del(&nce->list);
-
 	sctx->name_cache_size--;
+
+	if (list_empty(nce_head)) {
+		radix_tree_delete(&sctx->name_cache, (unsigned long)nce->ino);
+		kfree(nce_head);
+	}
 }
 
 static struct name_cache_entry *name_cache_search(struct send_ctx *sctx,
 						    u64 ino, u64 gen)
 {
-	struct name_cache_entry **ncea;
+	struct list_head *nce_head;
+	struct name_cache_entry *cur;
 
-	ncea = radix_tree_lookup(&sctx->name_cache, ino);
-	if (!ncea)
+	nce_head = radix_tree_lookup(&sctx->name_cache, (unsigned long)ino);
+	if (!nce_head)
 		return NULL;
 
-	if (ncea[0] && ncea[0]->gen == gen)
-		return ncea[0];
-	else if (ncea[1] && ncea[1]->gen == gen)
-		return ncea[1];
+	list_for_each_entry(cur, nce_head, radix_list) {
+		if (cur->ino == ino && cur->gen == gen)
+			return cur;
+	}
 	return NULL;
 }
 
+/*
+ * Removes the entry from the list and adds it back to the end. This marks the
+ * entry as recently used so that name_cache_clean_unused does not remove it.
+ */
 static void name_cache_used(struct send_ctx *sctx, struct name_cache_entry *nce)
 {
 	list_del(&nce->list);
 	list_add_tail(&nce->list, &sctx->name_cache_list);
 }
 
+/*
+ * Remove some entries from the beginning of name_cache_list.
+ */
 static void name_cache_clean_unused(struct send_ctx *sctx)
 {
 	struct name_cache_entry *nce;
@@ -1814,13 +1867,23 @@
 static void name_cache_free(struct send_ctx *sctx)
 {
 	struct name_cache_entry *nce;
-	struct name_cache_entry *tmp;
 
-	list_for_each_entry_safe(nce, tmp, &sctx->name_cache_list, list) {
+	while (!list_empty(&sctx->name_cache_list)) {
+		nce = list_entry(sctx->name_cache_list.next,
+				struct name_cache_entry, list);
 		name_cache_delete(sctx, nce);
+		kfree(nce);
 	}
 }
 
+/*
+ * Used by get_cur_path for each ref up to the root.
+ * Returns 0 if it succeeded.
+ * Returns 1 if the inode is not existent or got overwritten. In that case, the
+ * name is an orphan name. This instructs get_cur_path to stop iterating. If 1
+ * is returned, parent_ino/parent_gen are not guaranteed to be valid.
+ * Returns <0 in case of error.
+ */
 static int __get_cur_name_and_parent(struct send_ctx *sctx,
 				     u64 ino, u64 gen,
 				     u64 *parent_ino,
@@ -1832,6 +1895,11 @@
 	struct btrfs_path *path = NULL;
 	struct name_cache_entry *nce = NULL;
 
+	/*
+	 * First check if we already did a call to this function with the same
+	 * ino/gen. If yes, check if the cache entry is still up-to-date. If yes
+	 * return the cached result.
+	 */
 	nce = name_cache_search(sctx, ino, gen);
 	if (nce) {
 		if (ino < sctx->send_progress && nce->need_later_update) {
@@ -1854,6 +1922,11 @@
 	if (!path)
 		return -ENOMEM;
 
+	/*
+	 * If the inode is not existent yet, add the orphan name and return 1.
+	 * This should only happen for the parent dir that we determine in
+	 * __record_new_ref
+	 */
 	ret = is_inode_existent(sctx, ino, gen);
 	if (ret < 0)
 		goto out;
@@ -1866,6 +1939,10 @@
 		goto out_cache;
 	}
 
+	/*
+	 * Depending on whether the inode was already processed or not, use
+	 * send_root or parent_root for ref lookup.
+	 */
 	if (ino < sctx->send_progress)
 		ret = get_first_ref(sctx, sctx->send_root, ino,
 				parent_ino, parent_gen, dest);
@@ -1875,6 +1952,10 @@
 	if (ret < 0)
 		goto out;
 
+	/*
+	 * Check if the ref was overwritten by an inode's ref that was processed
+	 * earlier. If yes, treat as orphan and return 1.
+	 */
 	ret = did_overwrite_ref(sctx, *parent_ino, *parent_gen, ino, gen,
 			dest->start, dest->end - dest->start);
 	if (ret < 0)
@@ -1888,6 +1969,9 @@
 	}
 
 out_cache:
+	/*
+	 * Store the result of the lookup in the name cache.
+	 */
 	nce = kmalloc(sizeof(*nce) + fs_path_len(dest) + 1, GFP_NOFS);
 	if (!nce) {
 		ret = -ENOMEM;
@@ -1901,7 +1985,6 @@
 	nce->name_len = fs_path_len(dest);
 	nce->ret = ret;
 	strcpy(nce->name, dest->start);
-	memset(&nce->use_list, 0, sizeof(nce->use_list));
 
 	if (ino < sctx->send_progress)
 		nce->need_later_update = 0;
@@ -2107,9 +2190,6 @@
 	read_extent_buffer(leaf, name, (unsigned long)(ref + 1), namelen);
 	btrfs_release_path(path);
 
-	if (ret < 0)
-		goto out;
-
 	if (parent_root) {
 		ret = begin_cmd(sctx, BTRFS_SEND_C_SNAPSHOT);
 		if (ret < 0)
@@ -2276,7 +2356,7 @@
 			btrfs_inode_mtime(ii));
 	TLV_PUT_BTRFS_TIMESPEC(sctx, BTRFS_SEND_A_CTIME, eb,
 			btrfs_inode_ctime(ii));
-	/* TODO otime? */
+	/* TODO Add otime support when the otime patches get into upstream */
 
 	ret = send_cmd(sctx);
 
@@ -2292,39 +2372,39 @@
  * a valid path yet because we did not process the refs yet. So, the inode
  * is created as orphan.
  */
-static int send_create_inode(struct send_ctx *sctx, struct btrfs_path *path,
-			     struct btrfs_key *key)
+static int send_create_inode(struct send_ctx *sctx, u64 ino)
 {
 	int ret = 0;
-	struct extent_buffer *eb = path->nodes[0];
-	struct btrfs_inode_item *ii;
 	struct fs_path *p;
-	int slot = path->slots[0];
 	int cmd;
+	u64 gen;
 	u64 mode;
+	u64 rdev;
 
-verbose_printk("btrfs: send_create_inode %llu\n", sctx->cur_ino);
+verbose_printk("btrfs: send_create_inode %llu\n", ino);
 
 	p = fs_path_alloc(sctx);
 	if (!p)
 		return -ENOMEM;
 
-	ii = btrfs_item_ptr(eb, slot, struct btrfs_inode_item);
-	mode = btrfs_inode_mode(eb, ii);
+	ret = get_inode_info(sctx->send_root, ino, NULL, &gen, &mode, NULL,
+			NULL, &rdev);
+	if (ret < 0)
+		goto out;
 
-	if (S_ISREG(mode))
+	if (S_ISREG(mode)) {
 		cmd = BTRFS_SEND_C_MKFILE;
-	else if (S_ISDIR(mode))
+	} else if (S_ISDIR(mode)) {
 		cmd = BTRFS_SEND_C_MKDIR;
-	else if (S_ISLNK(mode))
+	} else if (S_ISLNK(mode)) {
 		cmd = BTRFS_SEND_C_SYMLINK;
-	else if (S_ISCHR(mode) || S_ISBLK(mode))
+	} else if (S_ISCHR(mode) || S_ISBLK(mode)) {
 		cmd = BTRFS_SEND_C_MKNOD;
-	else if (S_ISFIFO(mode))
+	} else if (S_ISFIFO(mode)) {
 		cmd = BTRFS_SEND_C_MKFIFO;
-	else if (S_ISSOCK(mode))
+	} else if (S_ISSOCK(mode)) {
 		cmd = BTRFS_SEND_C_MKSOCK;
-	else {
+	} else {
 		printk(KERN_WARNING "btrfs: unexpected inode type %o",
 				(int)(mode & S_IFMT));
 		ret = -ENOTSUPP;
@@ -2335,22 +2415,22 @@
 	if (ret < 0)
 		goto out;
 
-	ret = gen_unique_name(sctx, sctx->cur_ino, sctx->cur_inode_gen, p);
+	ret = gen_unique_name(sctx, ino, gen, p);
 	if (ret < 0)
 		goto out;
 
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
-	TLV_PUT_U64(sctx, BTRFS_SEND_A_INO, sctx->cur_ino);
+	TLV_PUT_U64(sctx, BTRFS_SEND_A_INO, ino);
 
 	if (S_ISLNK(mode)) {
 		fs_path_reset(p);
-		ret = read_symlink(sctx, sctx->send_root, sctx->cur_ino, p);
+		ret = read_symlink(sctx, sctx->send_root, ino, p);
 		if (ret < 0)
 			goto out;
 		TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH_LINK, p);
 	} else if (S_ISCHR(mode) || S_ISBLK(mode) ||
 		   S_ISFIFO(mode) || S_ISSOCK(mode)) {
-		TLV_PUT_U64(sctx, BTRFS_SEND_A_RDEV, btrfs_inode_rdev(eb, ii));
+		TLV_PUT_U64(sctx, BTRFS_SEND_A_RDEV, rdev);
 	}
 
 	ret = send_cmd(sctx);
@@ -2364,6 +2444,92 @@
 	return ret;
 }
 
+/*
+ * We need some special handling for inodes that get processed before the parent
+ * directory got created. See process_recorded_refs for details.
+ * This function does the check if we already created the dir out of order.
+ */
+static int did_create_dir(struct send_ctx *sctx, u64 dir)
+{
+	int ret = 0;
+	struct btrfs_path *path = NULL;
+	struct btrfs_key key;
+	struct btrfs_key found_key;
+	struct btrfs_key di_key;
+	struct extent_buffer *eb;
+	struct btrfs_dir_item *di;
+	int slot;
+
+	path = alloc_path_for_send();
+	if (!path) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	key.objectid = dir;
+	key.type = BTRFS_DIR_INDEX_KEY;
+	key.offset = 0;
+	while (1) {
+		ret = btrfs_search_slot_for_read(sctx->send_root, &key, path,
+				1, 0);
+		if (ret < 0)
+			goto out;
+		if (!ret) {
+			eb = path->nodes[0];
+			slot = path->slots[0];
+			btrfs_item_key_to_cpu(eb, &found_key, slot);
+		}
+		if (ret || found_key.objectid != key.objectid ||
+		    found_key.type != key.type) {
+			ret = 0;
+			goto out;
+		}
+
+		di = btrfs_item_ptr(eb, slot, struct btrfs_dir_item);
+		btrfs_dir_item_key_to_cpu(eb, di, &di_key);
+
+		if (di_key.objectid < sctx->send_progress) {
+			ret = 1;
+			goto out;
+		}
+
+		key.offset = found_key.offset + 1;
+		btrfs_release_path(path);
+	}
+
+out:
+	btrfs_free_path(path);
+	return ret;
+}
+
+/*
+ * Only creates the inode if it is:
+ * 1. Not a directory
+ * 2. Or a directory which was not created already due to out of order
+ *    directories. See did_create_dir and process_recorded_refs for details.
+ */
+static int send_create_inode_if_needed(struct send_ctx *sctx)
+{
+	int ret;
+
+	if (S_ISDIR(sctx->cur_inode_mode)) {
+		ret = did_create_dir(sctx, sctx->cur_ino);
+		if (ret < 0)
+			goto out;
+		if (ret) {
+			ret = 0;
+			goto out;
+		}
+	}
+
+	ret = send_create_inode(sctx, sctx->cur_ino);
+	if (ret < 0)
+		goto out;
+
+out:
+	return ret;
+}
+
 struct recorded_ref {
 	struct list_head list;
 	char *dir_path;
@@ -2416,13 +2582,13 @@
 static void __free_recorded_refs(struct send_ctx *sctx, struct list_head *head)
 {
 	struct recorded_ref *cur;
-	struct recorded_ref *tmp;
 
-	list_for_each_entry_safe(cur, tmp, head, list) {
+	while (!list_empty(head)) {
+		cur = list_entry(head->next, struct recorded_ref, list);
 		fs_path_free(sctx, cur->full_path);
+		list_del(&cur->list);
 		kfree(cur);
 	}
-	INIT_LIST_HEAD(head);
 }
 
 static void free_recorded_refs(struct send_ctx *sctx)
@@ -2432,7 +2598,7 @@
 }
 
 /*
- * Renames/moves a file/dir to it's orphan name. Used when the first
+ * Renames/moves a file/dir to its orphan name. Used when the first
  * ref of an unprocessed inode gets overwritten and for all non empty
  * directories.
  */
@@ -2472,6 +2638,12 @@
 	struct btrfs_key loc;
 	struct btrfs_dir_item *di;
 
+	/*
+	 * Don't try to rmdir the top/root subvolume dir.
+	 */
+	if (dir == BTRFS_FIRST_FREE_OBJECTID)
+		return 0;
+
 	path = alloc_path_for_send();
 	if (!path)
 		return -ENOMEM;
@@ -2513,160 +2685,6 @@
 	return ret;
 }
 
-struct finish_unordered_dir_ctx {
-	struct send_ctx *sctx;
-	struct fs_path *cur_path;
-	struct fs_path *dir_path;
-	u64 dir_ino;
-	int need_delete;
-	int delete_pass;
-};
-
-int __finish_unordered_dir(int num, struct btrfs_key *di_key,
-			   const char *name, int name_len,
-			   const char *data, int data_len,
-			   u8 type, void *ctx)
-{
-	int ret = 0;
-	struct finish_unordered_dir_ctx *fctx = ctx;
-	struct send_ctx *sctx = fctx->sctx;
-	u64 di_gen;
-	u64 di_mode;
-	int is_orphan = 0;
-
-	if (di_key->objectid >= fctx->dir_ino)
-		goto out;
-
-	fs_path_reset(fctx->cur_path);
-
-	ret = get_inode_info(sctx->send_root, di_key->objectid,
-			NULL, &di_gen, &di_mode, NULL, NULL);
-	if (ret < 0)
-		goto out;
-
-	ret = is_first_ref(sctx, sctx->send_root, di_key->objectid,
-			fctx->dir_ino, name, name_len);
-	if (ret < 0)
-		goto out;
-	if (ret) {
-		is_orphan = 1;
-		ret = gen_unique_name(sctx, di_key->objectid, di_gen,
-				fctx->cur_path);
-	} else {
-		ret = get_cur_path(sctx, di_key->objectid, di_gen,
-				fctx->cur_path);
-	}
-	if (ret < 0)
-		goto out;
-
-	ret = fs_path_add(fctx->dir_path, name, name_len);
-	if (ret < 0)
-		goto out;
-
-	if (!fctx->delete_pass) {
-		if (S_ISDIR(di_mode)) {
-			ret = send_rename(sctx, fctx->cur_path,
-					fctx->dir_path);
-		} else {
-			ret = send_link(sctx, fctx->dir_path,
-					fctx->cur_path);
-			if (is_orphan)
-				fctx->need_delete = 1;
-		}
-	} else if (!S_ISDIR(di_mode)) {
-		ret = send_unlink(sctx, fctx->cur_path);
-	} else {
-		ret = 0;
-	}
-
-	fs_path_remove(fctx->dir_path);
-
-out:
-	return ret;
-}
-
-/*
- * Go through all dir items and see if we find refs which could not be created
- * in the past because the dir did not exist at that time.
- */
-static int finish_outoforder_dir(struct send_ctx *sctx, u64 dir, u64 dir_gen)
-{
-	int ret = 0;
-	struct btrfs_path *path = NULL;
-	struct btrfs_key key;
-	struct btrfs_key found_key;
-	struct extent_buffer *eb;
-	struct finish_unordered_dir_ctx fctx;
-	int slot;
-
-	path = alloc_path_for_send();
-	if (!path) {
-		ret = -ENOMEM;
-		goto out;
-	}
-
-	memset(&fctx, 0, sizeof(fctx));
-	fctx.sctx = sctx;
-	fctx.cur_path = fs_path_alloc(sctx);
-	fctx.dir_path = fs_path_alloc(sctx);
-	if (!fctx.cur_path || !fctx.dir_path) {
-		ret = -ENOMEM;
-		goto out;
-	}
-	fctx.dir_ino = dir;
-
-	ret = get_cur_path(sctx, dir, dir_gen, fctx.dir_path);
-	if (ret < 0)
-		goto out;
-
-	/*
-	 * We do two passes. The first links in the new refs and the second
-	 * deletes orphans if required. Deletion of orphans is not required for
-	 * directory inodes, as we always have only one ref and use rename
-	 * instead of link for those.
-	 */
-
-again:
-	key.objectid = dir;
-	key.type = BTRFS_DIR_ITEM_KEY;
-	key.offset = 0;
-	while (1) {
-		ret = btrfs_search_slot_for_read(sctx->send_root, &key, path,
-				1, 0);
-		if (ret < 0)
-			goto out;
-		eb = path->nodes[0];
-		slot = path->slots[0];
-		btrfs_item_key_to_cpu(eb, &found_key, slot);
-
-		if (found_key.objectid != key.objectid ||
-		    found_key.type != key.type) {
-			btrfs_release_path(path);
-			break;
-		}
-
-		ret = iterate_dir_item(sctx, sctx->send_root, path,
-				&found_key, __finish_unordered_dir,
-				&fctx);
-		if (ret < 0)
-			goto out;
-
-		key.offset = found_key.offset + 1;
-		btrfs_release_path(path);
-	}
-
-	if (!fctx.delete_pass && fctx.need_delete) {
-		fctx.delete_pass = 1;
-		goto again;
-	}
-
-out:
-	btrfs_free_path(path);
-	fs_path_free(sctx, fctx.cur_path);
-	fs_path_free(sctx, fctx.dir_path);
-	return ret;
-}
-
 /*
  * This does all the move/link/unlink/rmdir magic.
  */
@@ -2674,6 +2692,7 @@
 {
 	int ret = 0;
 	struct recorded_ref *cur;
+	struct recorded_ref *cur2;
 	struct ulist *check_dirs = NULL;
 	struct ulist_iterator uit;
 	struct ulist_node *un;
@@ -2685,6 +2704,12 @@
 
 verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino);
 
+	/*
+	 * This should never happen as the root dir always has the same ref
+	 * which is always '..'
+	 */
+	BUG_ON(sctx->cur_ino <= BTRFS_FIRST_FREE_OBJECTID);
+
 	valid_path = fs_path_alloc(sctx);
 	if (!valid_path) {
 		ret = -ENOMEM;
@@ -2731,6 +2756,46 @@
 
 	list_for_each_entry(cur, &sctx->new_refs, list) {
 		/*
+		 * We may have refs where the parent directory does not exist
+		 * yet. This happens if the parent directories inum is higher
+		 * the the current inum. To handle this case, we create the
+		 * parent directory out of order. But we need to check if this
+		 * did already happen before due to other refs in the same dir.
+		 */
+		ret = get_cur_inode_state(sctx, cur->dir, cur->dir_gen);
+		if (ret < 0)
+			goto out;
+		if (ret == inode_state_will_create) {
+			ret = 0;
+			/*
+			 * First check if any of the current inodes refs did
+			 * already create the dir.
+			 */
+			list_for_each_entry(cur2, &sctx->new_refs, list) {
+				if (cur == cur2)
+					break;
+				if (cur2->dir == cur->dir) {
+					ret = 1;
+					break;
+				}
+			}
+
+			/*
+			 * If that did not happen, check if a previous inode
+			 * did already create the dir.
+			 */
+			if (!ret)
+				ret = did_create_dir(sctx, cur->dir);
+			if (ret < 0)
+				goto out;
+			if (!ret) {
+				ret = send_create_inode(sctx, cur->dir);
+				if (ret < 0)
+					goto out;
+			}
+		}
+
+		/*
 		 * Check if this new ref would overwrite the first ref of
 		 * another unprocessed inode. If yes, orphanize the
 		 * overwritten inode. If we find an overwritten ref that is
@@ -2764,7 +2829,7 @@
 		 * inode, move it and update valid_path. If not, link or move
 		 * it depending on the inode mode.
 		 */
-		if (is_orphan && !sctx->cur_inode_first_ref_orphan) {
+		if (is_orphan) {
 			ret = send_rename(sctx, valid_path, cur->full_path);
 			if (ret < 0)
 				goto out;
@@ -2827,6 +2892,17 @@
 			if (ret < 0)
 				goto out;
 		}
+	} else if (S_ISDIR(sctx->cur_inode_mode) &&
+		   !list_empty(&sctx->deleted_refs)) {
+		/*
+		 * We have a moved dir. Add the old parent to check_dirs
+		 */
+		cur = list_entry(sctx->deleted_refs.next, struct recorded_ref,
+				list);
+		ret = ulist_add(check_dirs, cur->dir, cur->dir_gen,
+				GFP_NOFS);
+		if (ret < 0)
+			goto out;
 	} else if (!S_ISDIR(sctx->cur_inode_mode)) {
 		/*
 		 * We have a non dir inode. Go through all deleted refs and
@@ -2840,35 +2916,9 @@
 			if (ret < 0)
 				goto out;
 			if (!ret) {
-				/*
-				 * In case the inode was moved to a directory
-				 * that was not created yet (see
-				 * __record_new_ref), we can not unlink the ref
-				 * as it will be needed later when the parent
-				 * directory is created, so that we can move in
-				 * the inode to the new dir.
-				 */
-				if (!is_orphan &&
-				    sctx->cur_inode_first_ref_orphan) {
-					ret = orphanize_inode(sctx,
-							sctx->cur_ino,
-							sctx->cur_inode_gen,
-							cur->full_path);
-					if (ret < 0)
-						goto out;
-					ret = gen_unique_name(sctx,
-							sctx->cur_ino,
-							sctx->cur_inode_gen,
-							valid_path);
-					if (ret < 0)
-						goto out;
-					is_orphan = 1;
-
-				} else {
-					ret = send_unlink(sctx, cur->full_path);
-					if (ret < 0)
-						goto out;
-				}
+				ret = send_unlink(sctx, cur->full_path);
+				if (ret < 0)
+					goto out;
 			}
 			ret = ulist_add(check_dirs, cur->dir, cur->dir_gen,
 					GFP_NOFS);
@@ -2880,12 +2930,11 @@
 		 * If the inode is still orphan, unlink the orphan. This may
 		 * happen when a previous inode did overwrite the first ref
 		 * of this inode and no new refs were added for the current
-		 * inode.
-		 * We can however not delete the orphan in case the inode relies
-		 * in a directory that was not created yet (see
-		 * __record_new_ref)
+		 * inode. Unlinking does not mean that the inode is deleted in
+		 * all cases. There may still be links to this inode in other
+		 * places.
 		 */
-		if (is_orphan && !sctx->cur_inode_first_ref_orphan) {
+		if (is_orphan) {
 			ret = send_unlink(sctx, valid_path);
 			if (ret < 0)
 				goto out;
@@ -2900,6 +2949,11 @@
 	 */
 	ULIST_ITER_INIT(&uit);
 	while ((un = ulist_next(check_dirs, &uit))) {
+		/*
+		 * In case we had refs into dirs that were not processed yet,
+		 * we don't need to do the utime and rmdir logic for these dirs.
+		 * The dir will be processed later.
+		 */
 		if (un->val > sctx->cur_ino)
 			continue;
 
@@ -2929,25 +2983,6 @@
 		}
 	}
 
-	/*
-	 * Current inode is now at it's new position, so we must increase
-	 * send_progress
-	 */
-	sctx->send_progress = sctx->cur_ino + 1;
-
-	/*
-	 * We may have a directory here that has pending refs which could not
-	 * be created before (because the dir did not exist before, see
-	 * __record_new_ref). finish_outoforder_dir will link/move the pending
-	 * refs.
-	 */
-	if (S_ISDIR(sctx->cur_inode_mode) && sctx->cur_inode_new) {
-		ret = finish_outoforder_dir(sctx, sctx->cur_ino,
-				sctx->cur_inode_gen);
-		if (ret < 0)
-			goto out;
-	}
-
 	ret = 0;
 
 out:
@@ -2971,35 +3006,10 @@
 		return -ENOMEM;
 
 	ret = get_inode_info(sctx->send_root, dir, NULL, &gen, NULL, NULL,
-			NULL);
+			NULL, NULL);
 	if (ret < 0)
 		goto out;
 
-	/*
-	 * The parent may be non-existent at this point in time. This happens
-	 * if the ino of the parent dir is higher then the current ino. In this
-	 * case, we can not process this ref until the parent dir is finally
-	 * created. If we reach the parent dir later, process_recorded_refs
-	 * will go through all dir items and process the refs that could not be
-	 * processed before. In case this is the first ref, we set
-	 * cur_inode_first_ref_orphan to 1 to inform process_recorded_refs to
-	 * keep an orphan of the inode so that it later can be used for
-	 * link/move
-	 */
-	ret = is_inode_existent(sctx, dir, gen);
-	if (ret < 0)
-		goto out;
-	if (!ret) {
-		ret = is_first_ref(sctx, sctx->send_root, sctx->cur_ino, dir,
-				name->start, fs_path_len(name));
-		if (ret < 0)
-			goto out;
-		if (ret)
-			sctx->cur_inode_first_ref_orphan = 1;
-		ret = 0;
-		goto out;
-	}
-
 	ret = get_cur_path(sctx, dir, gen, p);
 	if (ret < 0)
 		goto out;
@@ -3029,7 +3039,7 @@
 		return -ENOMEM;
 
 	ret = get_inode_info(sctx->parent_root, dir, NULL, &gen, NULL, NULL,
-			NULL);
+			NULL, NULL);
 	if (ret < 0)
 		goto out;
 
@@ -3206,33 +3216,28 @@
 	key.offset = 0;
 	while (1) {
 		ret = btrfs_search_slot_for_read(root, &key, path, 1, 0);
-		if (ret < 0) {
-			btrfs_release_path(path);
+		if (ret < 0)
 			goto out;
-		}
-		if (ret) {
-			btrfs_release_path(path);
+		if (ret)
 			break;
-		}
 
 		eb = path->nodes[0];
 		slot = path->slots[0];
 		btrfs_item_key_to_cpu(eb, &found_key, slot);
 
 		if (found_key.objectid != key.objectid ||
-		    found_key.type != key.type) {
-			btrfs_release_path(path);
+		    found_key.type != key.type)
 			break;
-		}
 
-		ret = iterate_inode_ref(sctx, sctx->parent_root, path,
-				&found_key, 0, cb, sctx);
+		ret = iterate_inode_ref(sctx, root, path, &found_key, 0, cb,
+				sctx);
 		btrfs_release_path(path);
 		if (ret < 0)
 			goto out;
 
 		key.offset = found_key.offset + 1;
 	}
+	btrfs_release_path(path);
 
 	ret = process_recorded_refs(sctx);
 
@@ -3555,7 +3560,7 @@
 	int ret = 0;
 	struct fs_path *p;
 	loff_t pos = offset;
-	int readed = 0;
+	int num_read = 0;
 	mm_segment_t old_fs;
 
 	p = fs_path_alloc(sctx);
@@ -3580,8 +3585,8 @@
 	ret = vfs_read(sctx->cur_inode_filp, sctx->read_buf, len, &pos);
 	if (ret < 0)
 		goto out;
-	readed = ret;
-	if (!readed)
+	num_read = ret;
+	if (!num_read)
 		goto out;
 
 	ret = begin_cmd(sctx, BTRFS_SEND_C_WRITE);
@@ -3594,7 +3599,7 @@
 
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
 	TLV_PUT_U64(sctx, BTRFS_SEND_A_FILE_OFFSET, offset);
-	TLV_PUT(sctx, BTRFS_SEND_A_DATA, sctx->read_buf, readed);
+	TLV_PUT(sctx, BTRFS_SEND_A_DATA, sctx->read_buf, num_read);
 
 	ret = send_cmd(sctx);
 
@@ -3604,7 +3609,7 @@
 	set_fs(old_fs);
 	if (ret < 0)
 		return ret;
-	return readed;
+	return num_read;
 }
 
 /*
@@ -3615,7 +3620,6 @@
 		      struct clone_root *clone_root)
 {
 	int ret = 0;
-	struct btrfs_root *clone_root2 = clone_root->root;
 	struct fs_path *p;
 	u64 gen;
 
@@ -3640,22 +3644,23 @@
 	TLV_PUT_U64(sctx, BTRFS_SEND_A_CLONE_LEN, len);
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_PATH, p);
 
-	if (clone_root2 == sctx->send_root) {
+	if (clone_root->root == sctx->send_root) {
 		ret = get_inode_info(sctx->send_root, clone_root->ino, NULL,
-				&gen, NULL, NULL, NULL);
+				&gen, NULL, NULL, NULL, NULL);
 		if (ret < 0)
 			goto out;
 		ret = get_cur_path(sctx, clone_root->ino, gen, p);
 	} else {
-		ret = get_inode_path(sctx, clone_root2, clone_root->ino, p);
+		ret = get_inode_path(sctx, clone_root->root,
+				clone_root->ino, p);
 	}
 	if (ret < 0)
 		goto out;
 
 	TLV_PUT_UUID(sctx, BTRFS_SEND_A_CLONE_UUID,
-			clone_root2->root_item.uuid);
+			clone_root->root->root_item.uuid);
 	TLV_PUT_U64(sctx, BTRFS_SEND_A_CLONE_CTRANSID,
-			clone_root2->root_item.ctransid);
+			clone_root->root->root_item.ctransid);
 	TLV_PUT_PATH(sctx, BTRFS_SEND_A_CLONE_PATH, p);
 	TLV_PUT_U64(sctx, BTRFS_SEND_A_CLONE_OFFSET,
 			clone_root->offset);
@@ -3684,10 +3689,17 @@
 	ei = btrfs_item_ptr(path->nodes[0], path->slots[0],
 			struct btrfs_file_extent_item);
 	type = btrfs_file_extent_type(path->nodes[0], ei);
-	if (type == BTRFS_FILE_EXTENT_INLINE)
+	if (type == BTRFS_FILE_EXTENT_INLINE) {
 		len = btrfs_file_extent_inline_len(path->nodes[0], ei);
-	else
+		/*
+		 * it is possible the inline item won't cover the whole page,
+		 * but there may be items after this page.  Make
+		 * sure to send the whole thing
+		 */
+		len = PAGE_CACHE_ALIGN(len);
+	} else {
 		len = btrfs_file_extent_num_bytes(path->nodes[0], ei);
+	}
 
 	if (offset + len > sctx->cur_inode_size)
 		len = sctx->cur_inode_size - offset;
@@ -3735,6 +3747,8 @@
 	u64 left_offset_fixed;
 	u64 left_len;
 	u64 right_len;
+	u64 left_gen;
+	u64 right_gen;
 	u8 left_type;
 	u8 right_type;
 
@@ -3744,17 +3758,17 @@
 
 	eb = left_path->nodes[0];
 	slot = left_path->slots[0];
-
 	ei = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
 	left_type = btrfs_file_extent_type(eb, ei);
-	left_disknr = btrfs_file_extent_disk_bytenr(eb, ei);
-	left_len = btrfs_file_extent_num_bytes(eb, ei);
-	left_offset = btrfs_file_extent_offset(eb, ei);
 
 	if (left_type != BTRFS_FILE_EXTENT_REG) {
 		ret = 0;
 		goto out;
 	}
+	left_disknr = btrfs_file_extent_disk_bytenr(eb, ei);
+	left_len = btrfs_file_extent_num_bytes(eb, ei);
+	left_offset = btrfs_file_extent_offset(eb, ei);
+	left_gen = btrfs_file_extent_generation(eb, ei);
 
 	/*
 	 * Following comments will refer to these graphics. L is the left
@@ -3810,6 +3824,7 @@
 		right_disknr = btrfs_file_extent_disk_bytenr(eb, ei);
 		right_len = btrfs_file_extent_num_bytes(eb, ei);
 		right_offset = btrfs_file_extent_offset(eb, ei);
+		right_gen = btrfs_file_extent_generation(eb, ei);
 
 		if (right_type != BTRFS_FILE_EXTENT_REG) {
 			ret = 0;
@@ -3820,7 +3835,7 @@
 		 * Are we at extent 8? If yes, we know the extent is changed.
 		 * This may only happen on the first iteration.
 		 */
-		if (found_key.offset + right_len < ekey->offset) {
+		if (found_key.offset + right_len <= ekey->offset) {
 			ret = 0;
 			goto out;
 		}
@@ -3837,8 +3852,9 @@
 		/*
 		 * Check if we have the same extent.
 		 */
-		if (left_disknr + left_offset_fixed !=
-				right_disknr + right_offset) {
+		if (left_disknr != right_disknr ||
+		    left_offset_fixed != right_offset ||
+		    left_gen != right_gen) {
 			ret = 0;
 			goto out;
 		}
@@ -3977,6 +3993,15 @@
 		goto out;
 
 	ret = process_recorded_refs(sctx);
+	if (ret < 0)
+		goto out;
+
+	/*
+	 * We have processed the refs and thus need to advance send_progress.
+	 * Now, calls to get_cur_xxx will take the updated refs of the current
+	 * inode into account.
+	 */
+	sctx->send_progress = sctx->cur_ino + 1;
 
 out:
 	return ret;
@@ -4004,7 +4029,7 @@
 		goto out;
 
 	ret = get_inode_info(sctx->send_root, sctx->cur_ino, NULL, NULL,
-			&left_mode, &left_uid, &left_gid);
+			&left_mode, &left_uid, &left_gid, NULL);
 	if (ret < 0)
 		goto out;
 
@@ -4015,7 +4040,7 @@
 		} else {
 			ret = get_inode_info(sctx->parent_root, sctx->cur_ino,
 					NULL, NULL, &right_mode, &right_uid,
-					&right_gid);
+					&right_gid, NULL);
 			if (ret < 0)
 				goto out;
 
@@ -4074,7 +4099,12 @@
 
 	sctx->cur_ino = key->objectid;
 	sctx->cur_inode_new_gen = 0;
-	sctx->cur_inode_first_ref_orphan = 0;
+
+	/*
+	 * Set send_progress to current inode. This will tell all get_cur_xxx
+	 * functions that the current inode's refs are not updated yet. Later,
+	 * when process_recorded_refs is finished, it is set to cur_ino + 1.
+	 */
 	sctx->send_progress = sctx->cur_ino;
 
 	if (result == BTRFS_COMPARE_TREE_NEW ||
@@ -4098,7 +4128,14 @@
 
 		right_gen = btrfs_inode_generation(sctx->right_path->nodes[0],
 				right_ii);
-		if (left_gen != right_gen)
+
+		/*
+		 * The cur_ino = root dir case is special here. We can't treat
+		 * the inode as deleted+reused because it would generate a
+		 * stream that tries to delete/mkdir the root dir.
+		 */
+		if (left_gen != right_gen &&
+		    sctx->cur_ino != BTRFS_FIRST_FREE_OBJECTID)
 			sctx->cur_inode_new_gen = 1;
 	}
 
@@ -4111,8 +4148,7 @@
 		sctx->cur_inode_mode = btrfs_inode_mode(
 				sctx->left_path->nodes[0], left_ii);
 		if (sctx->cur_ino != BTRFS_FIRST_FREE_OBJECTID)
-			ret = send_create_inode(sctx, sctx->left_path,
-					sctx->cmp_key);
+			ret = send_create_inode_if_needed(sctx);
 	} else if (result == BTRFS_COMPARE_TREE_DELETED) {
 		sctx->cur_inode_gen = right_gen;
 		sctx->cur_inode_new = 0;
@@ -4122,7 +4158,17 @@
 		sctx->cur_inode_mode = btrfs_inode_mode(
 				sctx->right_path->nodes[0], right_ii);
 	} else if (result == BTRFS_COMPARE_TREE_CHANGED) {
+		/*
+		 * We need to do some special handling in case the inode was
+		 * reported as changed with a changed generation number. This
+		 * means that the original inode was deleted and new inode
+		 * reused the same inum. So we have to treat the old inode as
+		 * deleted and the new one as new.
+		 */
 		if (sctx->cur_inode_new_gen) {
+			/*
+			 * First, process the inode as if it was deleted.
+			 */
 			sctx->cur_inode_gen = right_gen;
 			sctx->cur_inode_new = 0;
 			sctx->cur_inode_deleted = 1;
@@ -4135,6 +4181,9 @@
 			if (ret < 0)
 				goto out;
 
+			/*
+			 * Now process the inode as if it was new.
+			 */
 			sctx->cur_inode_gen = left_gen;
 			sctx->cur_inode_new = 1;
 			sctx->cur_inode_deleted = 0;
@@ -4142,14 +4191,23 @@
 					sctx->left_path->nodes[0], left_ii);
 			sctx->cur_inode_mode = btrfs_inode_mode(
 					sctx->left_path->nodes[0], left_ii);
-			ret = send_create_inode(sctx, sctx->left_path,
-					sctx->cmp_key);
+			ret = send_create_inode_if_needed(sctx);
 			if (ret < 0)
 				goto out;
 
 			ret = process_all_refs(sctx, BTRFS_COMPARE_TREE_NEW);
 			if (ret < 0)
 				goto out;
+			/*
+			 * Advance send_progress now as we did not get into
+			 * process_recorded_refs_if_needed in the new_gen case.
+			 */
+			sctx->send_progress = sctx->cur_ino + 1;
+
+			/*
+			 * Now process all extents and xattrs of the inode as if
+			 * they were all new.
+			 */
 			ret = process_all_extents(sctx);
 			if (ret < 0)
 				goto out;
@@ -4172,6 +4230,16 @@
 	return ret;
 }
 
+/*
+ * We have to process new refs before deleted refs, but compare_trees gives us
+ * the new and deleted refs mixed. To fix this, we record the new/deleted refs
+ * first and later process them in process_recorded_refs.
+ * For the cur_inode_new_gen case, we skip recording completely because
+ * changed_inode did already initiate processing of refs. The reason for this is
+ * that in this case, compare_tree actually compares the refs of 2 different
+ * inodes. To fix this, process_all_refs is used in changed_inode to handle all
+ * refs of the right tree as deleted and all refs of the left tree as new.
+ */
 static int changed_ref(struct send_ctx *sctx,
 		       enum btrfs_compare_tree_result result)
 {
@@ -4192,6 +4260,11 @@
 	return ret;
 }
 
+/*
+ * Process new/deleted/changed xattrs. We skip processing in the
+ * cur_inode_new_gen case because changed_inode did already initiate processing
+ * of xattrs. The reason is the same as in changed_ref
+ */
 static int changed_xattr(struct send_ctx *sctx,
 			 enum btrfs_compare_tree_result result)
 {
@@ -4211,6 +4284,11 @@
 	return ret;
 }
 
+/*
+ * Process new/deleted/changed extents. We skip processing in the
+ * cur_inode_new_gen case because changed_inode did already initiate processing
+ * of extents. The reason is the same as in changed_ref
+ */
 static int changed_extent(struct send_ctx *sctx,
 			  enum btrfs_compare_tree_result result)
 {
@@ -4227,7 +4305,10 @@
 	return ret;
 }
 
-
+/*
+ * Updates compare related fields in sctx and simply forwards to the actual
+ * changed_xxx functions.
+ */
 static int changed_cb(struct btrfs_root *left_root,
 		      struct btrfs_root *right_root,
 		      struct btrfs_path *left_path,
@@ -4247,6 +4328,11 @@
 	if (ret < 0)
 		goto out;
 
+	/* Ignore non-FS objects */
+	if (key->objectid == BTRFS_FREE_INO_OBJECTID ||
+	    key->objectid == BTRFS_FREE_SPACE_OBJECTID)
+		goto out;
+
 	if (key->type == BTRFS_INODE_ITEM_KEY)
 		ret = changed_inode(sctx, result);
 	else if (key->type == BTRFS_INODE_REF_KEY)
@@ -4299,7 +4385,8 @@
 	}
 
 	/*
-	 * Make sure the tree has not changed
+	 * Make sure the tree has not changed after re-joining. We detect this
+	 * by comparing start_ctransid and ctransid. They should always match.
 	 */
 	spin_lock(&send_root->root_times_lock);
 	ctransid = btrfs_root_ctransid(&send_root->root_item);
diff --git a/fs/btrfs/send.h b/fs/btrfs/send.h
index 9934e94..1bf4f32 100644
--- a/fs/btrfs/send.h
+++ b/fs/btrfs/send.h
@@ -130,4 +130,5 @@
 
 #ifdef __KERNEL__
 long btrfs_ioctl_send(struct file *mnt_file, void __user *arg);
+int write_buf(struct file *filp, const void *buf, u32 len, loff_t *off);
 #endif
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 83d6f9f..915ac14 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -243,12 +243,18 @@
 			       struct btrfs_root *root, const char *function,
 			       unsigned int line, int errno)
 {
-	WARN_ONCE(1, KERN_DEBUG "btrfs: Transaction aborted");
+	WARN_ONCE(1, KERN_DEBUG "btrfs: Transaction aborted\n");
 	trans->aborted = errno;
 	/* Nothing used. The other threads that have joined this
 	 * transaction may be able to continue. */
 	if (!trans->blocks_used) {
-		btrfs_printk(root->fs_info, "Aborting unused transaction.\n");
+		char nbuf[16];
+		const char *errstr;
+
+		errstr = btrfs_decode_error(root->fs_info, errno, nbuf);
+		btrfs_printk(root->fs_info,
+			     "%s:%d: Aborting unused transaction(%s).\n",
+			     function, line, errstr);
 		return;
 	}
 	trans->transaction->aborted = errno;
@@ -407,7 +413,15 @@
 			btrfs_set_opt(info->mount_opt, NODATASUM);
 			break;
 		case Opt_nodatacow:
-			printk(KERN_INFO "btrfs: setting nodatacow\n");
+			if (!btrfs_test_opt(root, COMPRESS) ||
+				!btrfs_test_opt(root, FORCE_COMPRESS)) {
+					printk(KERN_INFO "btrfs: setting nodatacow, compression disabled\n");
+			} else {
+				printk(KERN_INFO "btrfs: setting nodatacow\n");
+			}
+			info->compress_type = BTRFS_COMPRESS_NONE;
+			btrfs_clear_opt(info->mount_opt, COMPRESS);
+			btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS);
 			btrfs_set_opt(info->mount_opt, NODATACOW);
 			btrfs_set_opt(info->mount_opt, NODATASUM);
 			break;
@@ -422,10 +436,14 @@
 				compress_type = "zlib";
 				info->compress_type = BTRFS_COMPRESS_ZLIB;
 				btrfs_set_opt(info->mount_opt, COMPRESS);
+				btrfs_clear_opt(info->mount_opt, NODATACOW);
+				btrfs_clear_opt(info->mount_opt, NODATASUM);
 			} else if (strcmp(args[0].from, "lzo") == 0) {
 				compress_type = "lzo";
 				info->compress_type = BTRFS_COMPRESS_LZO;
 				btrfs_set_opt(info->mount_opt, COMPRESS);
+				btrfs_clear_opt(info->mount_opt, NODATACOW);
+				btrfs_clear_opt(info->mount_opt, NODATASUM);
 				btrfs_set_fs_incompat(info, COMPRESS_LZO);
 			} else if (strncmp(args[0].from, "no", 2) == 0) {
 				compress_type = "no";
@@ -543,11 +561,11 @@
 			btrfs_set_opt(info->mount_opt, ENOSPC_DEBUG);
 			break;
 		case Opt_defrag:
-			printk(KERN_INFO "btrfs: enabling auto defrag");
+			printk(KERN_INFO "btrfs: enabling auto defrag\n");
 			btrfs_set_opt(info->mount_opt, AUTO_DEFRAG);
 			break;
 		case Opt_recovery:
-			printk(KERN_INFO "btrfs: enabling auto recovery");
+			printk(KERN_INFO "btrfs: enabling auto recovery\n");
 			btrfs_set_opt(info->mount_opt, RECOVERY);
 			break;
 		case Opt_skip_balance:
@@ -846,18 +864,15 @@
 		return 0;
 	}
 
-	btrfs_wait_ordered_extents(root, 0, 0);
+	btrfs_wait_ordered_extents(root, 0);
 
-	spin_lock(&fs_info->trans_lock);
-	if (!fs_info->running_transaction) {
-		spin_unlock(&fs_info->trans_lock);
-		return 0;
-	}
-	spin_unlock(&fs_info->trans_lock);
-
-	trans = btrfs_join_transaction(root);
-	if (IS_ERR(trans))
+	trans = btrfs_attach_transaction(root);
+	if (IS_ERR(trans)) {
+		/* no transaction, don't bother */
+		if (PTR_ERR(trans) == -ENOENT)
+			return 0;
 		return PTR_ERR(trans);
+	}
 	return btrfs_commit_transaction(trans, root);
 }
 
@@ -1508,17 +1523,21 @@
 
 static int btrfs_freeze(struct super_block *sb)
 {
-	struct btrfs_fs_info *fs_info = btrfs_sb(sb);
-	mutex_lock(&fs_info->transaction_kthread_mutex);
-	mutex_lock(&fs_info->cleaner_mutex);
-	return 0;
+	struct btrfs_trans_handle *trans;
+	struct btrfs_root *root = btrfs_sb(sb)->tree_root;
+
+	trans = btrfs_attach_transaction(root);
+	if (IS_ERR(trans)) {
+		/* no transaction, don't bother */
+		if (PTR_ERR(trans) == -ENOENT)
+			return 0;
+		return PTR_ERR(trans);
+	}
+	return btrfs_commit_transaction(trans, root);
 }
 
 static int btrfs_unfreeze(struct super_block *sb)
 {
-	struct btrfs_fs_info *fs_info = btrfs_sb(sb);
-	mutex_unlock(&fs_info->cleaner_mutex);
-	mutex_unlock(&fs_info->transaction_kthread_mutex);
 	return 0;
 }
 
@@ -1595,7 +1614,7 @@
 static void btrfs_interface_exit(void)
 {
 	if (misc_deregister(&btrfs_misc) < 0)
-		printk(KERN_INFO "misc_deregister failed for control device");
+		printk(KERN_INFO "btrfs: misc_deregister failed for control device\n");
 }
 
 static int __init init_btrfs_fs(void)
@@ -1620,10 +1639,14 @@
 	if (err)
 		goto free_extent_io;
 
-	err = btrfs_delayed_inode_init();
+	err = ordered_data_init();
 	if (err)
 		goto free_extent_map;
 
+	err = btrfs_delayed_inode_init();
+	if (err)
+		goto free_ordered_data;
+
 	err = btrfs_interface_init();
 	if (err)
 		goto free_delayed_inode;
@@ -1641,6 +1664,8 @@
 	btrfs_interface_exit();
 free_delayed_inode:
 	btrfs_delayed_inode_exit();
+free_ordered_data:
+	ordered_data_exit();
 free_extent_map:
 	extent_map_exit();
 free_extent_io:
@@ -1657,6 +1682,7 @@
 {
 	btrfs_destroy_cachep();
 	btrfs_delayed_inode_exit();
+	ordered_data_exit();
 	extent_map_exit();
 	extent_io_exit();
 	btrfs_interface_exit();
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 27c2600..77db875 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -53,7 +53,7 @@
 /*
  * either allocate a new transaction or hop into the existing one
  */
-static noinline int join_transaction(struct btrfs_root *root, int nofail)
+static noinline int join_transaction(struct btrfs_root *root, int type)
 {
 	struct btrfs_transaction *cur_trans;
 	struct btrfs_fs_info *fs_info = root->fs_info;
@@ -67,7 +67,13 @@
 	}
 
 	if (fs_info->trans_no_join) {
-		if (!nofail) {
+		/* 
+		 * If we are JOIN_NOLOCK we're already committing a current
+		 * transaction, we just need a handle to deal with something
+		 * when committing the transaction, such as inode cache and
+		 * space cache. It is a special case.
+		 */
+		if (type != TRANS_JOIN_NOLOCK) {
 			spin_unlock(&fs_info->trans_lock);
 			return -EBUSY;
 		}
@@ -87,6 +93,13 @@
 	}
 	spin_unlock(&fs_info->trans_lock);
 
+	/*
+	 * If we are ATTACH, we just want to catch the current transaction,
+	 * and commit it. If there is no transaction, just return ENOENT.
+	 */
+	if (type == TRANS_ATTACH)
+		return -ENOENT;
+
 	cur_trans = kmem_cache_alloc(btrfs_transaction_cachep, GFP_NOFS);
 	if (!cur_trans)
 		return -ENOMEM;
@@ -267,13 +280,6 @@
 	}
 }
 
-enum btrfs_trans_type {
-	TRANS_START,
-	TRANS_JOIN,
-	TRANS_USERSPACE,
-	TRANS_JOIN_NOLOCK,
-};
-
 static int may_wait_transaction(struct btrfs_root *root, int type)
 {
 	if (root->fs_info->log_root_recovering)
@@ -290,7 +296,8 @@
 }
 
 static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
-						    u64 num_items, int type)
+						    u64 num_items, int type,
+						    int noflush)
 {
 	struct btrfs_trans_handle *h;
 	struct btrfs_transaction *cur_trans;
@@ -324,9 +331,14 @@
 		}
 
 		num_bytes = btrfs_calc_trans_metadata_size(root, num_items);
-		ret = btrfs_block_rsv_add(root,
-					  &root->fs_info->trans_block_rsv,
-					  num_bytes);
+		if (noflush)
+			ret = btrfs_block_rsv_add_noflush(root,
+						&root->fs_info->trans_block_rsv,
+						num_bytes);
+		else
+			ret = btrfs_block_rsv_add(root,
+						&root->fs_info->trans_block_rsv,
+						num_bytes);
 		if (ret)
 			return ERR_PTR(ret);
 	}
@@ -335,19 +347,34 @@
 	if (!h)
 		return ERR_PTR(-ENOMEM);
 
-	sb_start_intwrite(root->fs_info->sb);
+	/*
+	 * If we are JOIN_NOLOCK we're already committing a transaction and
+	 * waiting on this guy, so we don't need to do the sb_start_intwrite
+	 * because we're already holding a ref.  We need this because we could
+	 * have raced in and did an fsync() on a file which can kick a commit
+	 * and then we deadlock with somebody doing a freeze.
+	 *
+	 * If we are ATTACH, it means we just want to catch the current
+	 * transaction and commit it, so we needn't do sb_start_intwrite(). 
+	 */
+	if (type < TRANS_JOIN_NOLOCK)
+		sb_start_intwrite(root->fs_info->sb);
 
 	if (may_wait_transaction(root, type))
 		wait_current_trans(root);
 
 	do {
-		ret = join_transaction(root, type == TRANS_JOIN_NOLOCK);
+		ret = join_transaction(root, type);
 		if (ret == -EBUSY)
 			wait_current_trans(root);
 	} while (ret == -EBUSY);
 
 	if (ret < 0) {
-		sb_end_intwrite(root->fs_info->sb);
+		/* We must get the transaction if we are JOIN_NOLOCK. */
+		BUG_ON(type == TRANS_JOIN_NOLOCK);
+
+		if (type < TRANS_JOIN_NOLOCK)
+			sb_end_intwrite(root->fs_info->sb);
 		kmem_cache_free(btrfs_trans_handle_cachep, h);
 		return ERR_PTR(ret);
 	}
@@ -367,7 +394,9 @@
 	h->aborted = 0;
 	h->qgroup_reserved = qgroup_reserved;
 	h->delayed_ref_elem.seq = 0;
+	h->type = type;
 	INIT_LIST_HEAD(&h->qgroup_ref_list);
+	INIT_LIST_HEAD(&h->new_bgs);
 
 	smp_mb();
 	if (cur_trans->blocked && may_wait_transaction(root, type)) {
@@ -393,21 +422,33 @@
 struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
 						   int num_items)
 {
-	return start_transaction(root, num_items, TRANS_START);
+	return start_transaction(root, num_items, TRANS_START, 0);
 }
+
+struct btrfs_trans_handle *btrfs_start_transaction_noflush(
+					struct btrfs_root *root, int num_items)
+{
+	return start_transaction(root, num_items, TRANS_START, 1);
+}
+
 struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root)
 {
-	return start_transaction(root, 0, TRANS_JOIN);
+	return start_transaction(root, 0, TRANS_JOIN, 0);
 }
 
 struct btrfs_trans_handle *btrfs_join_transaction_nolock(struct btrfs_root *root)
 {
-	return start_transaction(root, 0, TRANS_JOIN_NOLOCK);
+	return start_transaction(root, 0, TRANS_JOIN_NOLOCK, 0);
 }
 
 struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *root)
 {
-	return start_transaction(root, 0, TRANS_USERSPACE);
+	return start_transaction(root, 0, TRANS_USERSPACE, 0);
+}
+
+struct btrfs_trans_handle *btrfs_attach_transaction(struct btrfs_root *root)
+{
+	return start_transaction(root, 0, TRANS_ATTACH, 0);
 }
 
 /* wait for a transaction commit to be fully complete */
@@ -506,11 +547,12 @@
 }
 
 static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
-			  struct btrfs_root *root, int throttle, int lock)
+			  struct btrfs_root *root, int throttle)
 {
 	struct btrfs_transaction *cur_trans = trans->transaction;
 	struct btrfs_fs_info *info = root->fs_info;
 	int count = 0;
+	int lock = (trans->type != TRANS_JOIN_NOLOCK);
 	int err = 0;
 
 	if (--trans->use_count) {
@@ -536,6 +578,9 @@
 		trans->qgroup_reserved = 0;
 	}
 
+	if (!list_empty(&trans->new_bgs))
+		btrfs_create_pending_block_groups(trans, root);
+
 	while (count < 2) {
 		unsigned long cur = trans->delayed_ref_updates;
 		trans->delayed_ref_updates = 0;
@@ -551,7 +596,8 @@
 	btrfs_trans_release_metadata(trans, root);
 	trans->block_rsv = NULL;
 
-	sb_end_intwrite(root->fs_info->sb);
+	if (!list_empty(&trans->new_bgs))
+		btrfs_create_pending_block_groups(trans, root);
 
 	if (lock && !atomic_read(&root->fs_info->open_ioctl_trans) &&
 	    should_end_transaction(trans, root)) {
@@ -573,6 +619,9 @@
 		}
 	}
 
+	if (trans->type < TRANS_JOIN_NOLOCK)
+		sb_end_intwrite(root->fs_info->sb);
+
 	WARN_ON(cur_trans != info->running_transaction);
 	WARN_ON(atomic_read(&cur_trans->num_writers) < 1);
 	atomic_dec(&cur_trans->num_writers);
@@ -604,7 +653,7 @@
 {
 	int ret;
 
-	ret = __btrfs_end_transaction(trans, root, 0, 1);
+	ret = __btrfs_end_transaction(trans, root, 0);
 	if (ret)
 		return ret;
 	return 0;
@@ -615,18 +664,7 @@
 {
 	int ret;
 
-	ret = __btrfs_end_transaction(trans, root, 1, 1);
-	if (ret)
-		return ret;
-	return 0;
-}
-
-int btrfs_end_transaction_nolock(struct btrfs_trans_handle *trans,
-				 struct btrfs_root *root)
-{
-	int ret;
-
-	ret = __btrfs_end_transaction(trans, root, 0, 0);
+	ret = __btrfs_end_transaction(trans, root, 1);
 	if (ret)
 		return ret;
 	return 0;
@@ -635,7 +673,7 @@
 int btrfs_end_transaction_dmeta(struct btrfs_trans_handle *trans,
 				struct btrfs_root *root)
 {
-	return __btrfs_end_transaction(trans, root, 1, 1);
+	return __btrfs_end_transaction(trans, root, 1);
 }
 
 /*
@@ -649,13 +687,15 @@
 	int err = 0;
 	int werr = 0;
 	struct address_space *mapping = root->fs_info->btree_inode->i_mapping;
+	struct extent_state *cached_state = NULL;
 	u64 start = 0;
 	u64 end;
 
 	while (!find_first_extent_bit(dirty_pages, start, &start, &end,
-				      mark)) {
-		convert_extent_bit(dirty_pages, start, end, EXTENT_NEED_WAIT, mark,
-				   GFP_NOFS);
+				      mark, &cached_state)) {
+		convert_extent_bit(dirty_pages, start, end, EXTENT_NEED_WAIT,
+				   mark, &cached_state, GFP_NOFS);
+		cached_state = NULL;
 		err = filemap_fdatawrite_range(mapping, start, end);
 		if (err)
 			werr = err;
@@ -679,12 +719,14 @@
 	int err = 0;
 	int werr = 0;
 	struct address_space *mapping = root->fs_info->btree_inode->i_mapping;
+	struct extent_state *cached_state = NULL;
 	u64 start = 0;
 	u64 end;
 
 	while (!find_first_extent_bit(dirty_pages, start, &start, &end,
-				      EXTENT_NEED_WAIT)) {
-		clear_extent_bits(dirty_pages, start, end, EXTENT_NEED_WAIT, GFP_NOFS);
+				      EXTENT_NEED_WAIT, &cached_state)) {
+		clear_extent_bit(dirty_pages, start, end, EXTENT_NEED_WAIT,
+				 0, 0, &cached_state, GFP_NOFS);
 		err = filemap_fdatawait_range(mapping, start, end);
 		if (err)
 			werr = err;
@@ -955,6 +997,8 @@
 	struct btrfs_root *parent_root;
 	struct btrfs_block_rsv *rsv;
 	struct inode *parent_inode;
+	struct btrfs_path *path;
+	struct btrfs_dir_item *dir_item;
 	struct dentry *parent;
 	struct dentry *dentry;
 	struct extent_buffer *tmp;
@@ -967,18 +1011,22 @@
 	u64 root_flags;
 	uuid_le new_uuid;
 
-	rsv = trans->block_rsv;
+	path = btrfs_alloc_path();
+	if (!path) {
+		ret = pending->error = -ENOMEM;
+		goto path_alloc_fail;
+	}
 
 	new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS);
 	if (!new_root_item) {
 		ret = pending->error = -ENOMEM;
-		goto fail;
+		goto root_item_alloc_fail;
 	}
 
 	ret = btrfs_find_free_objectid(tree_root, &objectid);
 	if (ret) {
 		pending->error = ret;
-		goto fail;
+		goto no_free_objectid;
 	}
 
 	btrfs_reloc_pre_snapshot(trans, pending, &to_reserve);
@@ -988,22 +1036,22 @@
 						  to_reserve);
 		if (ret) {
 			pending->error = ret;
-			goto fail;
+			goto no_free_objectid;
 		}
 	}
 
 	ret = btrfs_qgroup_inherit(trans, fs_info, root->root_key.objectid,
 				   objectid, pending->inherit);
-	kfree(pending->inherit);
 	if (ret) {
 		pending->error = ret;
-		goto fail;
+		goto no_free_objectid;
 	}
 
 	key.objectid = objectid;
 	key.offset = (u64)-1;
 	key.type = BTRFS_ROOT_ITEM_KEY;
 
+	rsv = trans->block_rsv;
 	trans->block_rsv = &pending->block_rsv;
 
 	dentry = pending->dentry;
@@ -1017,24 +1065,21 @@
 	 */
 	ret = btrfs_set_inode_index(parent_inode, &index);
 	BUG_ON(ret); /* -ENOMEM */
-	ret = btrfs_insert_dir_item(trans, parent_root,
-				dentry->d_name.name, dentry->d_name.len,
-				parent_inode, &key,
-				BTRFS_FT_DIR, index);
-	if (ret == -EEXIST) {
-		pending->error = -EEXIST;
-		dput(parent);
-		goto fail;
-	} else if (ret) {
-		goto abort_trans_dput;
-	}
 
-	btrfs_i_size_write(parent_inode, parent_inode->i_size +
-					 dentry->d_name.len * 2);
-	parent_inode->i_mtime = parent_inode->i_ctime = CURRENT_TIME;
-	ret = btrfs_update_inode(trans, parent_root, parent_inode);
-	if (ret)
-		goto abort_trans_dput;
+	/* check if there is a file/dir which has the same name. */
+	dir_item = btrfs_lookup_dir_item(NULL, parent_root, path,
+					 btrfs_ino(parent_inode),
+					 dentry->d_name.name,
+					 dentry->d_name.len, 0);
+	if (dir_item != NULL && !IS_ERR(dir_item)) {
+		pending->error = -EEXIST;
+		goto fail;
+	} else if (IS_ERR(dir_item)) {
+		ret = PTR_ERR(dir_item);
+		btrfs_abort_transaction(trans, root, ret);
+		goto fail;
+	}
+	btrfs_release_path(path);
 
 	/*
 	 * pull in the delayed directory update
@@ -1043,8 +1088,8 @@
 	 * snapshot
 	 */
 	ret = btrfs_run_delayed_items(trans, root);
-	if (ret) { /* Transaction aborted */
-		dput(parent);
+	if (ret) {	/* Transaction aborted */
+		btrfs_abort_transaction(trans, root, ret);
 		goto fail;
 	}
 
@@ -1079,7 +1124,8 @@
 	if (ret) {
 		btrfs_tree_unlock(old);
 		free_extent_buffer(old);
-		goto abort_trans_dput;
+		btrfs_abort_transaction(trans, root, ret);
+		goto fail;
 	}
 
 	btrfs_set_lock_blocking(old);
@@ -1088,8 +1134,10 @@
 	/* clean up in any case */
 	btrfs_tree_unlock(old);
 	free_extent_buffer(old);
-	if (ret)
-		goto abort_trans_dput;
+	if (ret) {
+		btrfs_abort_transaction(trans, root, ret);
+		goto fail;
+	}
 
 	/* see comments in should_cow_block() */
 	root->force_cow = 1;
@@ -1101,8 +1149,10 @@
 	ret = btrfs_insert_root(trans, tree_root, &key, new_root_item);
 	btrfs_tree_unlock(tmp);
 	free_extent_buffer(tmp);
-	if (ret)
-		goto abort_trans_dput;
+	if (ret) {
+		btrfs_abort_transaction(trans, root, ret);
+		goto fail;
+	}
 
 	/*
 	 * insert root back/forward references
@@ -1111,32 +1161,58 @@
 				 parent_root->root_key.objectid,
 				 btrfs_ino(parent_inode), index,
 				 dentry->d_name.name, dentry->d_name.len);
-	dput(parent);
-	if (ret)
+	if (ret) {
+		btrfs_abort_transaction(trans, root, ret);
 		goto fail;
+	}
 
 	key.offset = (u64)-1;
 	pending->snap = btrfs_read_fs_root_no_name(root->fs_info, &key);
 	if (IS_ERR(pending->snap)) {
 		ret = PTR_ERR(pending->snap);
-		goto abort_trans;
+		btrfs_abort_transaction(trans, root, ret);
+		goto fail;
 	}
 
 	ret = btrfs_reloc_post_snapshot(trans, pending);
+	if (ret) {
+		btrfs_abort_transaction(trans, root, ret);
+		goto fail;
+	}
+
+	ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1);
+	if (ret) {
+		btrfs_abort_transaction(trans, root, ret);
+		goto fail;
+	}
+
+	ret = btrfs_insert_dir_item(trans, parent_root,
+				    dentry->d_name.name, dentry->d_name.len,
+				    parent_inode, &key,
+				    BTRFS_FT_DIR, index);
+	/* We have check then name at the beginning, so it is impossible. */
+	BUG_ON(ret == -EEXIST);
+	if (ret) {
+		btrfs_abort_transaction(trans, root, ret);
+		goto fail;
+	}
+
+	btrfs_i_size_write(parent_inode, parent_inode->i_size +
+					 dentry->d_name.len * 2);
+	parent_inode->i_mtime = parent_inode->i_ctime = CURRENT_TIME;
+	ret = btrfs_update_inode(trans, parent_root, parent_inode);
 	if (ret)
-		goto abort_trans;
-	ret = 0;
+		btrfs_abort_transaction(trans, root, ret);
 fail:
-	kfree(new_root_item);
+	dput(parent);
 	trans->block_rsv = rsv;
+no_free_objectid:
+	kfree(new_root_item);
+root_item_alloc_fail:
+	btrfs_free_path(path);
+path_alloc_fail:
 	btrfs_block_rsv_release(root, &pending->block_rsv, (u64)-1);
 	return ret;
-
-abort_trans_dput:
-	dput(parent);
-abort_trans:
-	btrfs_abort_transaction(trans, root, ret);
-	goto fail;
 }
 
 /*
@@ -1229,6 +1305,16 @@
 	struct btrfs_async_commit *ac =
 		container_of(work, struct btrfs_async_commit, work.work);
 
+	/*
+	 * We've got freeze protection passed with the transaction.
+	 * Tell lockdep about it.
+	 */
+	rwsem_acquire_read(
+		&ac->root->fs_info->sb->s_writers.lock_map[SB_FREEZE_FS-1],
+		0, 1, _THIS_IP_);
+
+	current->journal_info = ac->newtrans;
+
 	btrfs_commit_transaction(ac->newtrans, ac->root);
 	kfree(ac);
 }
@@ -1258,6 +1344,14 @@
 	atomic_inc(&cur_trans->use_count);
 
 	btrfs_end_transaction(trans, root);
+
+	/*
+	 * Tell lockdep we've released the freeze rwsem, since the
+	 * async commit thread will be the one to unlock it.
+	 */
+	rwsem_release(&root->fs_info->sb->s_writers.lock_map[SB_FREEZE_FS-1],
+		      1, _THIS_IP_);
+
 	schedule_delayed_work(&ac->work, 0);
 
 	/* wait for transaction to start and unblock */
@@ -1348,6 +1442,9 @@
 	 */
 	cur_trans->delayed_refs.flushing = 1;
 
+	if (!list_empty(&trans->new_bgs))
+		btrfs_create_pending_block_groups(trans, root);
+
 	ret = btrfs_run_delayed_refs(trans, root, 0);
 	if (ret)
 		goto cleanup_transaction;
@@ -1403,7 +1500,7 @@
 
 		if (flush_on_commit || snap_pending) {
 			btrfs_start_delalloc_inodes(root, 1);
-			btrfs_wait_ordered_extents(root, 0, 1);
+			btrfs_wait_ordered_extents(root, 1);
 		}
 
 		ret = btrfs_run_delayed_items(trans, root);
@@ -1456,13 +1553,28 @@
 	 */
 	mutex_lock(&root->fs_info->reloc_mutex);
 
-	ret = btrfs_run_delayed_items(trans, root);
+	/*
+	 * We needn't worry about the delayed items because we will
+	 * deal with them in create_pending_snapshot(), which is the
+	 * core function of the snapshot creation.
+	 */
+	ret = create_pending_snapshots(trans, root->fs_info);
 	if (ret) {
 		mutex_unlock(&root->fs_info->reloc_mutex);
 		goto cleanup_transaction;
 	}
 
-	ret = create_pending_snapshots(trans, root->fs_info);
+	/*
+	 * We insert the dir indexes of the snapshots and update the inode
+	 * of the snapshots' parents after the snapshot creation, so there
+	 * are some delayed items which are not dealt with. Now deal with
+	 * them.
+	 *
+	 * We needn't worry that this operation will corrupt the snapshots,
+	 * because all the tree which are snapshoted will be forced to COW
+	 * the nodes and leaves.
+	 */
+	ret = btrfs_run_delayed_items(trans, root);
 	if (ret) {
 		mutex_unlock(&root->fs_info->reloc_mutex);
 		goto cleanup_transaction;
@@ -1584,7 +1696,8 @@
 	put_transaction(cur_trans);
 	put_transaction(cur_trans);
 
-	sb_end_intwrite(root->fs_info->sb);
+	if (trans->type < TRANS_JOIN_NOLOCK)
+		sb_end_intwrite(root->fs_info->sb);
 
 	trace_btrfs_transaction_commit(root);
 
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h
index e8b8416..8096194 100644
--- a/fs/btrfs/transaction.h
+++ b/fs/btrfs/transaction.h
@@ -47,6 +47,14 @@
 	int aborted;
 };
 
+enum btrfs_trans_type {
+	TRANS_START,
+	TRANS_JOIN,
+	TRANS_USERSPACE,
+	TRANS_JOIN_NOLOCK,
+	TRANS_ATTACH,
+};
+
 struct btrfs_trans_handle {
 	u64 transid;
 	u64 bytes_reserved;
@@ -58,8 +66,9 @@
 	struct btrfs_transaction *transaction;
 	struct btrfs_block_rsv *block_rsv;
 	struct btrfs_block_rsv *orig_rsv;
-	int aborted;
-	int adding_csums;
+	short aborted;
+	short adding_csums;
+	enum btrfs_trans_type type;
 	/*
 	 * this root is only needed to validate that the root passed to
 	 * start_transaction is the same as the one passed to end_transaction.
@@ -68,6 +77,7 @@
 	struct btrfs_root *root;
 	struct seq_list delayed_ref_elem;
 	struct list_head qgroup_ref_list;
+	struct list_head new_bgs;
 };
 
 struct btrfs_pending_snapshot {
@@ -88,16 +98,18 @@
 {
 	BTRFS_I(inode)->last_trans = trans->transaction->transid;
 	BTRFS_I(inode)->last_sub_trans = BTRFS_I(inode)->root->log_transid;
+	BTRFS_I(inode)->last_log_commit = BTRFS_I(inode)->root->last_log_commit;
 }
 
 int btrfs_end_transaction(struct btrfs_trans_handle *trans,
 			  struct btrfs_root *root);
-int btrfs_end_transaction_nolock(struct btrfs_trans_handle *trans,
-				 struct btrfs_root *root);
 struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
 						   int num_items);
+struct btrfs_trans_handle *btrfs_start_transaction_noflush(
+					struct btrfs_root *root, int num_items);
 struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root);
 struct btrfs_trans_handle *btrfs_join_transaction_nolock(struct btrfs_root *root);
+struct btrfs_trans_handle *btrfs_attach_transaction(struct btrfs_root *root);
 struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *root);
 int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid);
 int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index c86670f..e9ebb47 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -18,13 +18,16 @@
 
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/list_sort.h>
 #include "ctree.h"
 #include "transaction.h"
 #include "disk-io.h"
 #include "locking.h"
 #include "print-tree.h"
+#include "backref.h"
 #include "compat.h"
 #include "tree-log.h"
+#include "hash.h"
 
 /* magic values for the inode_only field in btrfs_log_inode:
  *
@@ -146,7 +149,7 @@
 			root->log_multiple_pids = true;
 		}
 
-		root->log_batch++;
+		atomic_inc(&root->log_batch);
 		atomic_inc(&root->log_writers);
 		mutex_unlock(&root->log_mutex);
 		return 0;
@@ -165,7 +168,7 @@
 			err = ret;
 	}
 	mutex_unlock(&root->fs_info->tree_log_mutex);
-	root->log_batch++;
+	atomic_inc(&root->log_batch);
 	atomic_inc(&root->log_writers);
 	mutex_unlock(&root->log_mutex);
 	return err;
@@ -484,7 +487,6 @@
 	int found_type;
 	u64 mask = root->sectorsize - 1;
 	u64 extent_end;
-	u64 alloc_hint;
 	u64 start = key->offset;
 	u64 saved_nbytes;
 	struct btrfs_file_extent_item *item;
@@ -550,8 +552,7 @@
 
 	saved_nbytes = inode_get_bytes(inode);
 	/* drop any overlapping extents */
-	ret = btrfs_drop_extents(trans, inode, start, extent_end,
-				 &alloc_hint, 1);
+	ret = btrfs_drop_extents(trans, root, inode, start, extent_end, 1);
 	BUG_ON(ret);
 
 	if (found_type == BTRFS_FILE_EXTENT_REG ||
@@ -744,6 +745,7 @@
  */
 static noinline int backref_in_log(struct btrfs_root *log,
 				   struct btrfs_key *key,
+				   u64 ref_objectid,
 				   char *name, int namelen)
 {
 	struct btrfs_path *path;
@@ -764,8 +766,17 @@
 	if (ret != 0)
 		goto out;
 
-	item_size = btrfs_item_size_nr(path->nodes[0], path->slots[0]);
 	ptr = btrfs_item_ptr_offset(path->nodes[0], path->slots[0]);
+
+	if (key->type == BTRFS_INODE_EXTREF_KEY) {
+		if (btrfs_find_name_in_ext_backref(path, ref_objectid,
+						   name, namelen, NULL))
+			match = 1;
+
+		goto out;
+	}
+
+	item_size = btrfs_item_size_nr(path->nodes[0], path->slots[0]);
 	ptr_end = ptr + item_size;
 	while (ptr < ptr_end) {
 		ref = (struct btrfs_inode_ref *)ptr;
@@ -786,91 +797,42 @@
 	return match;
 }
 
-
-/*
- * replay one inode back reference item found in the log tree.
- * eb, slot and key refer to the buffer and key found in the log tree.
- * root is the destination we are replaying into, and path is for temp
- * use by this function.  (it should be released on return).
- */
-static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
+static inline int __add_inode_ref(struct btrfs_trans_handle *trans,
 				  struct btrfs_root *root,
-				  struct btrfs_root *log,
 				  struct btrfs_path *path,
-				  struct extent_buffer *eb, int slot,
-				  struct btrfs_key *key)
+				  struct btrfs_root *log_root,
+				  struct inode *dir, struct inode *inode,
+				  struct extent_buffer *eb,
+				  u64 inode_objectid, u64 parent_objectid,
+				  u64 ref_index, char *name, int namelen,
+				  int *search_done)
 {
-	struct btrfs_inode_ref *ref;
-	struct btrfs_dir_item *di;
-	struct inode *dir;
-	struct inode *inode;
-	unsigned long ref_ptr;
-	unsigned long ref_end;
-	char *name;
-	int namelen;
 	int ret;
-	int search_done = 0;
-
-	/*
-	 * it is possible that we didn't log all the parent directories
-	 * for a given inode.  If we don't find the dir, just don't
-	 * copy the back ref in.  The link count fixup code will take
-	 * care of the rest
-	 */
-	dir = read_one_inode(root, key->offset);
-	if (!dir)
-		return -ENOENT;
-
-	inode = read_one_inode(root, key->objectid);
-	if (!inode) {
-		iput(dir);
-		return -EIO;
-	}
-
-	ref_ptr = btrfs_item_ptr_offset(eb, slot);
-	ref_end = ref_ptr + btrfs_item_size_nr(eb, slot);
+	char *victim_name;
+	int victim_name_len;
+	struct extent_buffer *leaf;
+	struct btrfs_dir_item *di;
+	struct btrfs_key search_key;
+	struct btrfs_inode_extref *extref;
 
 again:
-	ref = (struct btrfs_inode_ref *)ref_ptr;
-
-	namelen = btrfs_inode_ref_name_len(eb, ref);
-	name = kmalloc(namelen, GFP_NOFS);
-	BUG_ON(!name);
-
-	read_extent_buffer(eb, name, (unsigned long)(ref + 1), namelen);
-
-	/* if we already have a perfect match, we're done */
-	if (inode_in_dir(root, path, btrfs_ino(dir), btrfs_ino(inode),
-			 btrfs_inode_ref_index(eb, ref),
-			 name, namelen)) {
-		goto out;
-	}
-
-	/*
-	 * look for a conflicting back reference in the metadata.
-	 * if we find one we have to unlink that name of the file
-	 * before we add our new link.  Later on, we overwrite any
-	 * existing back reference, and we don't want to create
-	 * dangling pointers in the directory.
-	 */
-
-	if (search_done)
-		goto insert;
-
-	ret = btrfs_search_slot(NULL, root, key, path, 0, 0);
+	/* Search old style refs */
+	search_key.objectid = inode_objectid;
+	search_key.type = BTRFS_INODE_REF_KEY;
+	search_key.offset = parent_objectid;
+	ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0);
 	if (ret == 0) {
-		char *victim_name;
-		int victim_name_len;
 		struct btrfs_inode_ref *victim_ref;
 		unsigned long ptr;
 		unsigned long ptr_end;
-		struct extent_buffer *leaf = path->nodes[0];
+
+		leaf = path->nodes[0];
 
 		/* are we trying to overwrite a back ref for the root directory
 		 * if so, just jump out, we're done
 		 */
-		if (key->objectid == key->offset)
-			goto out_nowrite;
+		if (search_key.objectid == search_key.offset)
+			return 1;
 
 		/* check all the names in this back reference to see
 		 * if they are in the log.  if so, we allow them to stay
@@ -889,7 +851,9 @@
 					   (unsigned long)(victim_ref + 1),
 					   victim_name_len);
 
-			if (!backref_in_log(log, key, victim_name,
+			if (!backref_in_log(log_root, &search_key,
+					    parent_objectid,
+					    victim_name,
 					    victim_name_len)) {
 				btrfs_inc_nlink(inode);
 				btrfs_release_path(path);
@@ -897,9 +861,14 @@
 				ret = btrfs_unlink_inode(trans, root, dir,
 							 inode, victim_name,
 							 victim_name_len);
+				BUG_ON(ret);
 				btrfs_run_delayed_items(trans, root);
+				kfree(victim_name);
+				*search_done = 1;
+				goto again;
 			}
 			kfree(victim_name);
+
 			ptr = (unsigned long)(victim_ref + 1) + victim_name_len;
 		}
 		BUG_ON(ret);
@@ -908,14 +877,78 @@
 		 * NOTE: we have searched root tree and checked the
 		 * coresponding ref, it does not need to check again.
 		 */
-		search_done = 1;
+		*search_done = 1;
+	}
+	btrfs_release_path(path);
+
+	/* Same search but for extended refs */
+	extref = btrfs_lookup_inode_extref(NULL, root, path, name, namelen,
+					   inode_objectid, parent_objectid, 0,
+					   0);
+	if (!IS_ERR_OR_NULL(extref)) {
+		u32 item_size;
+		u32 cur_offset = 0;
+		unsigned long base;
+		struct inode *victim_parent;
+
+		leaf = path->nodes[0];
+
+		item_size = btrfs_item_size_nr(leaf, path->slots[0]);
+		base = btrfs_item_ptr_offset(leaf, path->slots[0]);
+
+		while (cur_offset < item_size) {
+			extref = (struct btrfs_inode_extref *)base + cur_offset;
+
+			victim_name_len = btrfs_inode_extref_name_len(leaf, extref);
+
+			if (btrfs_inode_extref_parent(leaf, extref) != parent_objectid)
+				goto next;
+
+			victim_name = kmalloc(victim_name_len, GFP_NOFS);
+			read_extent_buffer(leaf, victim_name, (unsigned long)&extref->name,
+					   victim_name_len);
+
+			search_key.objectid = inode_objectid;
+			search_key.type = BTRFS_INODE_EXTREF_KEY;
+			search_key.offset = btrfs_extref_hash(parent_objectid,
+							      victim_name,
+							      victim_name_len);
+			ret = 0;
+			if (!backref_in_log(log_root, &search_key,
+					    parent_objectid, victim_name,
+					    victim_name_len)) {
+				ret = -ENOENT;
+				victim_parent = read_one_inode(root,
+							       parent_objectid);
+				if (victim_parent) {
+					btrfs_inc_nlink(inode);
+					btrfs_release_path(path);
+
+					ret = btrfs_unlink_inode(trans, root,
+								 victim_parent,
+								 inode,
+								 victim_name,
+								 victim_name_len);
+					btrfs_run_delayed_items(trans, root);
+				}
+				BUG_ON(ret);
+				iput(victim_parent);
+				kfree(victim_name);
+				*search_done = 1;
+				goto again;
+			}
+			kfree(victim_name);
+			BUG_ON(ret);
+next:
+			cur_offset += victim_name_len + sizeof(*extref);
+		}
+		*search_done = 1;
 	}
 	btrfs_release_path(path);
 
 	/* look for a conflicting sequence number */
 	di = btrfs_lookup_dir_index_item(trans, root, path, btrfs_ino(dir),
-					 btrfs_inode_ref_index(eb, ref),
-					 name, namelen, 0);
+					 ref_index, name, namelen, 0);
 	if (di && !IS_ERR(di)) {
 		ret = drop_one_dir_item(trans, root, path, dir, di);
 		BUG_ON(ret);
@@ -931,25 +964,173 @@
 	}
 	btrfs_release_path(path);
 
-insert:
-	/* insert our name */
-	ret = btrfs_add_link(trans, dir, inode, name, namelen, 0,
-			     btrfs_inode_ref_index(eb, ref));
-	BUG_ON(ret);
+	return 0;
+}
 
-	btrfs_update_inode(trans, root, inode);
+static int extref_get_fields(struct extent_buffer *eb, unsigned long ref_ptr,
+			     u32 *namelen, char **name, u64 *index,
+			     u64 *parent_objectid)
+{
+	struct btrfs_inode_extref *extref;
 
-out:
-	ref_ptr = (unsigned long)(ref + 1) + namelen;
-	kfree(name);
-	if (ref_ptr < ref_end)
-		goto again;
+	extref = (struct btrfs_inode_extref *)ref_ptr;
+
+	*namelen = btrfs_inode_extref_name_len(eb, extref);
+	*name = kmalloc(*namelen, GFP_NOFS);
+	if (*name == NULL)
+		return -ENOMEM;
+
+	read_extent_buffer(eb, *name, (unsigned long)&extref->name,
+			   *namelen);
+
+	*index = btrfs_inode_extref_index(eb, extref);
+	if (parent_objectid)
+		*parent_objectid = btrfs_inode_extref_parent(eb, extref);
+
+	return 0;
+}
+
+static int ref_get_fields(struct extent_buffer *eb, unsigned long ref_ptr,
+			  u32 *namelen, char **name, u64 *index)
+{
+	struct btrfs_inode_ref *ref;
+
+	ref = (struct btrfs_inode_ref *)ref_ptr;
+
+	*namelen = btrfs_inode_ref_name_len(eb, ref);
+	*name = kmalloc(*namelen, GFP_NOFS);
+	if (*name == NULL)
+		return -ENOMEM;
+
+	read_extent_buffer(eb, *name, (unsigned long)(ref + 1), *namelen);
+
+	*index = btrfs_inode_ref_index(eb, ref);
+
+	return 0;
+}
+
+/*
+ * replay one inode back reference item found in the log tree.
+ * eb, slot and key refer to the buffer and key found in the log tree.
+ * root is the destination we are replaying into, and path is for temp
+ * use by this function.  (it should be released on return).
+ */
+static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
+				  struct btrfs_root *root,
+				  struct btrfs_root *log,
+				  struct btrfs_path *path,
+				  struct extent_buffer *eb, int slot,
+				  struct btrfs_key *key)
+{
+	struct inode *dir;
+	struct inode *inode;
+	unsigned long ref_ptr;
+	unsigned long ref_end;
+	char *name;
+	int namelen;
+	int ret;
+	int search_done = 0;
+	int log_ref_ver = 0;
+	u64 parent_objectid;
+	u64 inode_objectid;
+	u64 ref_index = 0;
+	int ref_struct_size;
+
+	ref_ptr = btrfs_item_ptr_offset(eb, slot);
+	ref_end = ref_ptr + btrfs_item_size_nr(eb, slot);
+
+	if (key->type == BTRFS_INODE_EXTREF_KEY) {
+		struct btrfs_inode_extref *r;
+
+		ref_struct_size = sizeof(struct btrfs_inode_extref);
+		log_ref_ver = 1;
+		r = (struct btrfs_inode_extref *)ref_ptr;
+		parent_objectid = btrfs_inode_extref_parent(eb, r);
+	} else {
+		ref_struct_size = sizeof(struct btrfs_inode_ref);
+		parent_objectid = key->offset;
+	}
+	inode_objectid = key->objectid;
+
+	/*
+	 * it is possible that we didn't log all the parent directories
+	 * for a given inode.  If we don't find the dir, just don't
+	 * copy the back ref in.  The link count fixup code will take
+	 * care of the rest
+	 */
+	dir = read_one_inode(root, parent_objectid);
+	if (!dir)
+		return -ENOENT;
+
+	inode = read_one_inode(root, inode_objectid);
+	if (!inode) {
+		iput(dir);
+		return -EIO;
+	}
+
+	while (ref_ptr < ref_end) {
+		if (log_ref_ver) {
+			ret = extref_get_fields(eb, ref_ptr, &namelen, &name,
+						&ref_index, &parent_objectid);
+			/*
+			 * parent object can change from one array
+			 * item to another.
+			 */
+			if (!dir)
+				dir = read_one_inode(root, parent_objectid);
+			if (!dir)
+				return -ENOENT;
+		} else {
+			ret = ref_get_fields(eb, ref_ptr, &namelen, &name,
+					     &ref_index);
+		}
+		if (ret)
+			return ret;
+
+		/* if we already have a perfect match, we're done */
+		if (!inode_in_dir(root, path, btrfs_ino(dir), btrfs_ino(inode),
+				  ref_index, name, namelen)) {
+			/*
+			 * look for a conflicting back reference in the
+			 * metadata. if we find one we have to unlink that name
+			 * of the file before we add our new link.  Later on, we
+			 * overwrite any existing back reference, and we don't
+			 * want to create dangling pointers in the directory.
+			 */
+
+			if (!search_done) {
+				ret = __add_inode_ref(trans, root, path, log,
+						      dir, inode, eb,
+						      inode_objectid,
+						      parent_objectid,
+						      ref_index, name, namelen,
+						      &search_done);
+				if (ret == 1)
+					goto out;
+				BUG_ON(ret);
+			}
+
+			/* insert our name */
+			ret = btrfs_add_link(trans, dir, inode, name, namelen,
+					     0, ref_index);
+			BUG_ON(ret);
+
+			btrfs_update_inode(trans, root, inode);
+		}
+
+		ref_ptr = (unsigned long)(ref_ptr + ref_struct_size) + namelen;
+		kfree(name);
+		if (log_ref_ver) {
+			iput(dir);
+			dir = NULL;
+		}
+	}
 
 	/* finally write the back reference in the inode */
 	ret = overwrite_item(trans, root, path, eb, slot, key);
 	BUG_ON(ret);
 
-out_nowrite:
+out:
 	btrfs_release_path(path);
 	iput(dir);
 	iput(inode);
@@ -966,25 +1147,55 @@
 	return ret;
 }
 
-
-/*
- * There are a few corners where the link count of the file can't
- * be properly maintained during replay.  So, instead of adding
- * lots of complexity to the log code, we just scan the backrefs
- * for any file that has been through replay.
- *
- * The scan will update the link count on the inode to reflect the
- * number of back refs found.  If it goes down to zero, the iput
- * will free the inode.
- */
-static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans,
-					   struct btrfs_root *root,
-					   struct inode *inode)
+static int count_inode_extrefs(struct btrfs_root *root,
+			       struct inode *inode, struct btrfs_path *path)
 {
-	struct btrfs_path *path;
+	int ret = 0;
+	int name_len;
+	unsigned int nlink = 0;
+	u32 item_size;
+	u32 cur_offset = 0;
+	u64 inode_objectid = btrfs_ino(inode);
+	u64 offset = 0;
+	unsigned long ptr;
+	struct btrfs_inode_extref *extref;
+	struct extent_buffer *leaf;
+
+	while (1) {
+		ret = btrfs_find_one_extref(root, inode_objectid, offset, path,
+					    &extref, &offset);
+		if (ret)
+			break;
+
+		leaf = path->nodes[0];
+		item_size = btrfs_item_size_nr(leaf, path->slots[0]);
+		ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
+
+		while (cur_offset < item_size) {
+			extref = (struct btrfs_inode_extref *) (ptr + cur_offset);
+			name_len = btrfs_inode_extref_name_len(leaf, extref);
+
+			nlink++;
+
+			cur_offset += name_len + sizeof(*extref);
+		}
+
+		offset++;
+		btrfs_release_path(path);
+	}
+	btrfs_release_path(path);
+
+	if (ret < 0)
+		return ret;
+	return nlink;
+}
+
+static int count_inode_refs(struct btrfs_root *root,
+			       struct inode *inode, struct btrfs_path *path)
+{
 	int ret;
 	struct btrfs_key key;
-	u64 nlink = 0;
+	unsigned int nlink = 0;
 	unsigned long ptr;
 	unsigned long ptr_end;
 	int name_len;
@@ -994,10 +1205,6 @@
 	key.type = BTRFS_INODE_REF_KEY;
 	key.offset = (u64)-1;
 
-	path = btrfs_alloc_path();
-	if (!path)
-		return -ENOMEM;
-
 	while (1) {
 		ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
 		if (ret < 0)
@@ -1031,6 +1238,50 @@
 		btrfs_release_path(path);
 	}
 	btrfs_release_path(path);
+
+	return nlink;
+}
+
+/*
+ * There are a few corners where the link count of the file can't
+ * be properly maintained during replay.  So, instead of adding
+ * lots of complexity to the log code, we just scan the backrefs
+ * for any file that has been through replay.
+ *
+ * The scan will update the link count on the inode to reflect the
+ * number of back refs found.  If it goes down to zero, the iput
+ * will free the inode.
+ */
+static noinline int fixup_inode_link_count(struct btrfs_trans_handle *trans,
+					   struct btrfs_root *root,
+					   struct inode *inode)
+{
+	struct btrfs_path *path;
+	int ret;
+	u64 nlink = 0;
+	u64 ino = btrfs_ino(inode);
+
+	path = btrfs_alloc_path();
+	if (!path)
+		return -ENOMEM;
+
+	ret = count_inode_refs(root, inode, path);
+	if (ret < 0)
+		goto out;
+
+	nlink = ret;
+
+	ret = count_inode_extrefs(root, inode, path);
+	if (ret == -ENOENT)
+		ret = 0;
+
+	if (ret < 0)
+		goto out;
+
+	nlink += ret;
+
+	ret = 0;
+
 	if (nlink != inode->i_nlink) {
 		set_nlink(inode, nlink);
 		btrfs_update_inode(trans, root, inode);
@@ -1046,9 +1297,10 @@
 		ret = insert_orphan_item(trans, root, ino);
 		BUG_ON(ret);
 	}
-	btrfs_free_path(path);
 
-	return 0;
+out:
+	btrfs_free_path(path);
+	return ret;
 }
 
 static noinline int fixup_inode_link_counts(struct btrfs_trans_handle *trans,
@@ -1695,6 +1947,10 @@
 			ret = add_inode_ref(wc->trans, root, log, path,
 					    eb, i, &key);
 			BUG_ON(ret && ret != -ENOENT);
+		} else if (key.type == BTRFS_INODE_EXTREF_KEY) {
+			ret = add_inode_ref(wc->trans, root, log, path,
+					    eb, i, &key);
+			BUG_ON(ret && ret != -ENOENT);
 		} else if (key.type == BTRFS_EXTENT_DATA_KEY) {
 			ret = replay_one_extent(wc->trans, root, path,
 						eb, i, &key);
@@ -2037,7 +2293,7 @@
 	if (atomic_read(&root->log_commit[(index1 + 1) % 2]))
 		wait_log_commit(trans, root, root->log_transid - 1);
 	while (1) {
-		unsigned long batch = root->log_batch;
+		int batch = atomic_read(&root->log_batch);
 		/* when we're on an ssd, just kick the log commit out */
 		if (!btrfs_test_opt(root, SSD) && root->log_multiple_pids) {
 			mutex_unlock(&root->log_mutex);
@@ -2045,7 +2301,7 @@
 			mutex_lock(&root->log_mutex);
 		}
 		wait_for_writer(trans, root);
-		if (batch == root->log_batch)
+		if (batch == atomic_read(&root->log_batch))
 			break;
 	}
 
@@ -2074,7 +2330,6 @@
 
 	btrfs_set_root_node(&log->root_item, log->node);
 
-	root->log_batch = 0;
 	root->log_transid++;
 	log->log_transid = root->log_transid;
 	root->log_start_pid = 0;
@@ -2087,7 +2342,7 @@
 	mutex_unlock(&root->log_mutex);
 
 	mutex_lock(&log_root_tree->log_mutex);
-	log_root_tree->log_batch++;
+	atomic_inc(&log_root_tree->log_batch);
 	atomic_inc(&log_root_tree->log_writers);
 	mutex_unlock(&log_root_tree->log_mutex);
 
@@ -2157,7 +2412,6 @@
 	btrfs_set_super_log_root_level(root->fs_info->super_for_commit,
 				btrfs_header_level(log_root_tree->node));
 
-	log_root_tree->log_batch = 0;
 	log_root_tree->log_transid++;
 	smp_mb();
 
@@ -2171,9 +2425,12 @@
 	 * in and cause problems either.
 	 */
 	btrfs_scrub_pause_super(root);
-	write_ctree_super(trans, root->fs_info->tree_root, 1);
+	ret = write_ctree_super(trans, root->fs_info->tree_root, 1);
 	btrfs_scrub_continue_super(root);
-	ret = 0;
+	if (ret) {
+		btrfs_abort_transaction(trans, root, ret);
+		goto out_wake_log_root;
+	}
 
 	mutex_lock(&root->log_mutex);
 	if (root->last_log_commit < log_transid)
@@ -2209,7 +2466,8 @@
 
 	while (1) {
 		ret = find_first_extent_bit(&log->dirty_log_pages,
-				0, &start, &end, EXTENT_DIRTY | EXTENT_NEW);
+				0, &start, &end, EXTENT_DIRTY | EXTENT_NEW,
+				NULL);
 		if (ret)
 			break;
 
@@ -2646,6 +2904,7 @@
 	int ret;
 	struct btrfs_key key;
 	struct btrfs_key found_key;
+	int start_slot;
 
 	key.objectid = objectid;
 	key.type = max_key_type;
@@ -2667,8 +2926,18 @@
 		if (found_key.objectid != objectid)
 			break;
 
-		ret = btrfs_del_item(trans, log, path);
-		if (ret)
+		found_key.offset = 0;
+		found_key.type = 0;
+		ret = btrfs_bin_search(path->nodes[0], &found_key, 0,
+				       &start_slot);
+
+		ret = btrfs_del_items(trans, log, path, start_slot,
+				      path->slots[0] - start_slot + 1);
+		/*
+		 * If start slot isn't 0 then we don't need to re-search, we've
+		 * found the last guy with the objectid in this tree.
+		 */
+		if (ret || start_slot != 0)
 			break;
 		btrfs_release_path(path);
 	}
@@ -2678,14 +2947,64 @@
 	return ret;
 }
 
+static void fill_inode_item(struct btrfs_trans_handle *trans,
+			    struct extent_buffer *leaf,
+			    struct btrfs_inode_item *item,
+			    struct inode *inode, int log_inode_only)
+{
+	btrfs_set_inode_uid(leaf, item, inode->i_uid);
+	btrfs_set_inode_gid(leaf, item, inode->i_gid);
+	btrfs_set_inode_mode(leaf, item, inode->i_mode);
+	btrfs_set_inode_nlink(leaf, item, inode->i_nlink);
+
+	btrfs_set_timespec_sec(leaf, btrfs_inode_atime(item),
+			       inode->i_atime.tv_sec);
+	btrfs_set_timespec_nsec(leaf, btrfs_inode_atime(item),
+				inode->i_atime.tv_nsec);
+
+	btrfs_set_timespec_sec(leaf, btrfs_inode_mtime(item),
+			       inode->i_mtime.tv_sec);
+	btrfs_set_timespec_nsec(leaf, btrfs_inode_mtime(item),
+				inode->i_mtime.tv_nsec);
+
+	btrfs_set_timespec_sec(leaf, btrfs_inode_ctime(item),
+			       inode->i_ctime.tv_sec);
+	btrfs_set_timespec_nsec(leaf, btrfs_inode_ctime(item),
+				inode->i_ctime.tv_nsec);
+
+	btrfs_set_inode_nbytes(leaf, item, inode_get_bytes(inode));
+
+	btrfs_set_inode_sequence(leaf, item, inode->i_version);
+	btrfs_set_inode_transid(leaf, item, trans->transid);
+	btrfs_set_inode_rdev(leaf, item, inode->i_rdev);
+	btrfs_set_inode_flags(leaf, item, BTRFS_I(inode)->flags);
+	btrfs_set_inode_block_group(leaf, item, 0);
+
+	if (log_inode_only) {
+		/* set the generation to zero so the recover code
+		 * can tell the difference between an logging
+		 * just to say 'this inode exists' and a logging
+		 * to say 'update this inode with these values'
+		 */
+		btrfs_set_inode_generation(leaf, item, 0);
+		btrfs_set_inode_size(leaf, item, 0);
+	} else {
+		btrfs_set_inode_generation(leaf, item,
+					   BTRFS_I(inode)->generation);
+		btrfs_set_inode_size(leaf, item, inode->i_size);
+	}
+
+}
+
 static noinline int copy_items(struct btrfs_trans_handle *trans,
-			       struct btrfs_root *log,
+			       struct inode *inode,
 			       struct btrfs_path *dst_path,
 			       struct extent_buffer *src,
 			       int start_slot, int nr, int inode_only)
 {
 	unsigned long src_offset;
 	unsigned long dst_offset;
+	struct btrfs_root *log = BTRFS_I(inode)->root->log_root;
 	struct btrfs_file_extent_item *extent;
 	struct btrfs_inode_item *inode_item;
 	int ret;
@@ -2694,6 +3013,7 @@
 	char *ins_data;
 	int i;
 	struct list_head ordered_sums;
+	int skip_csum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
 
 	INIT_LIST_HEAD(&ordered_sums);
 
@@ -2722,29 +3042,23 @@
 
 		src_offset = btrfs_item_ptr_offset(src, start_slot + i);
 
-		copy_extent_buffer(dst_path->nodes[0], src, dst_offset,
-				   src_offset, ins_sizes[i]);
-
-		if (inode_only == LOG_INODE_EXISTS &&
-		    ins_keys[i].type == BTRFS_INODE_ITEM_KEY) {
+		if (ins_keys[i].type == BTRFS_INODE_ITEM_KEY) {
 			inode_item = btrfs_item_ptr(dst_path->nodes[0],
 						    dst_path->slots[0],
 						    struct btrfs_inode_item);
-			btrfs_set_inode_size(dst_path->nodes[0], inode_item, 0);
-
-			/* set the generation to zero so the recover code
-			 * can tell the difference between an logging
-			 * just to say 'this inode exists' and a logging
-			 * to say 'update this inode with these values'
-			 */
-			btrfs_set_inode_generation(dst_path->nodes[0],
-						   inode_item, 0);
+			fill_inode_item(trans, dst_path->nodes[0], inode_item,
+					inode, inode_only == LOG_INODE_EXISTS);
+		} else {
+			copy_extent_buffer(dst_path->nodes[0], src, dst_offset,
+					   src_offset, ins_sizes[i]);
 		}
+
 		/* take a reference on file data extents so that truncates
 		 * or deletes of this inode don't have to relog the inode
 		 * again
 		 */
-		if (btrfs_key_type(ins_keys + i) == BTRFS_EXTENT_DATA_KEY) {
+		if (btrfs_key_type(ins_keys + i) == BTRFS_EXTENT_DATA_KEY &&
+		    !skip_csum) {
 			int found_type;
 			extent = btrfs_item_ptr(src, start_slot + i,
 						struct btrfs_file_extent_item);
@@ -2753,8 +3067,7 @@
 				continue;
 
 			found_type = btrfs_file_extent_type(src, extent);
-			if (found_type == BTRFS_FILE_EXTENT_REG ||
-			    found_type == BTRFS_FILE_EXTENT_PREALLOC) {
+			if (found_type == BTRFS_FILE_EXTENT_REG) {
 				u64 ds, dl, cs, cl;
 				ds = btrfs_file_extent_disk_bytenr(src,
 								extent);
@@ -2803,6 +3116,239 @@
 	return ret;
 }
 
+static int extent_cmp(void *priv, struct list_head *a, struct list_head *b)
+{
+	struct extent_map *em1, *em2;
+
+	em1 = list_entry(a, struct extent_map, list);
+	em2 = list_entry(b, struct extent_map, list);
+
+	if (em1->start < em2->start)
+		return -1;
+	else if (em1->start > em2->start)
+		return 1;
+	return 0;
+}
+
+struct log_args {
+	struct extent_buffer *src;
+	u64 next_offset;
+	int start_slot;
+	int nr;
+};
+
+static int log_one_extent(struct btrfs_trans_handle *trans,
+			  struct inode *inode, struct btrfs_root *root,
+			  struct extent_map *em, struct btrfs_path *path,
+			  struct btrfs_path *dst_path, struct log_args *args)
+{
+	struct btrfs_root *log = root->log_root;
+	struct btrfs_file_extent_item *fi;
+	struct btrfs_key key;
+	u64 start = em->mod_start;
+	u64 search_start = start;
+	u64 len = em->mod_len;
+	u64 num_bytes;
+	int nritems;
+	int ret;
+
+	if (BTRFS_I(inode)->logged_trans == trans->transid) {
+		ret = __btrfs_drop_extents(trans, log, inode, dst_path, start,
+					   start + len, NULL, 0);
+		if (ret)
+			return ret;
+	}
+
+	while (len) {
+		if (args->nr)
+			goto next_slot;
+again:
+		key.objectid = btrfs_ino(inode);
+		key.type = BTRFS_EXTENT_DATA_KEY;
+		key.offset = search_start;
+
+		ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+		if (ret < 0)
+			return ret;
+
+		if (ret) {
+			/*
+			 * A rare case were we can have an em for a section of a
+			 * larger extent so we need to make sure that this em
+			 * falls within the extent we've found.  If not we just
+			 * bail and go back to ye-olde way of doing things but
+			 * it happens often enough in testing that we need to do
+			 * this dance to make sure.
+			 */
+			do {
+				if (path->slots[0] == 0) {
+					btrfs_release_path(path);
+					if (search_start == 0)
+						return -ENOENT;
+					search_start--;
+					goto again;
+				}
+
+				path->slots[0]--;
+				btrfs_item_key_to_cpu(path->nodes[0], &key,
+						      path->slots[0]);
+				if (key.objectid != btrfs_ino(inode) ||
+				    key.type != BTRFS_EXTENT_DATA_KEY) {
+					btrfs_release_path(path);
+					return -ENOENT;
+				}
+			} while (key.offset > start);
+
+			fi = btrfs_item_ptr(path->nodes[0], path->slots[0],
+					    struct btrfs_file_extent_item);
+			num_bytes = btrfs_file_extent_num_bytes(path->nodes[0],
+								fi);
+			if (key.offset + num_bytes <= start) {
+				btrfs_release_path(path);
+				return -ENOENT;
+			}
+		}
+		args->src = path->nodes[0];
+next_slot:
+		btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
+		fi = btrfs_item_ptr(args->src, path->slots[0],
+				    struct btrfs_file_extent_item);
+		if (args->nr &&
+		    args->start_slot + args->nr == path->slots[0]) {
+			args->nr++;
+		} else if (args->nr) {
+			ret = copy_items(trans, inode, dst_path, args->src,
+					 args->start_slot, args->nr,
+					 LOG_INODE_ALL);
+			if (ret)
+				return ret;
+			args->nr = 1;
+			args->start_slot = path->slots[0];
+		} else if (!args->nr) {
+			args->nr = 1;
+			args->start_slot = path->slots[0];
+		}
+		nritems = btrfs_header_nritems(path->nodes[0]);
+		path->slots[0]++;
+		num_bytes = btrfs_file_extent_num_bytes(args->src, fi);
+		if (len < num_bytes) {
+			/* I _think_ this is ok, envision we write to a
+			 * preallocated space that is adjacent to a previously
+			 * written preallocated space that gets merged when we
+			 * mark this preallocated space written.  If we do not
+			 * have the adjacent extent in cache then when we copy
+			 * this extent it could end up being larger than our EM
+			 * thinks it is, which is a-ok, so just set len to 0.
+			 */
+			len = 0;
+		} else {
+			len -= num_bytes;
+		}
+		start = key.offset + num_bytes;
+		args->next_offset = start;
+		search_start = start;
+
+		if (path->slots[0] < nritems) {
+			if (len)
+				goto next_slot;
+			break;
+		}
+
+		if (args->nr) {
+			ret = copy_items(trans, inode, dst_path, args->src,
+					 args->start_slot, args->nr,
+					 LOG_INODE_ALL);
+			if (ret)
+				return ret;
+			args->nr = 0;
+			btrfs_release_path(path);
+		}
+	}
+
+	return 0;
+}
+
+static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
+				     struct btrfs_root *root,
+				     struct inode *inode,
+				     struct btrfs_path *path,
+				     struct btrfs_path *dst_path)
+{
+	struct log_args args;
+	struct extent_map *em, *n;
+	struct list_head extents;
+	struct extent_map_tree *tree = &BTRFS_I(inode)->extent_tree;
+	u64 test_gen;
+	int ret = 0;
+
+	INIT_LIST_HEAD(&extents);
+
+	memset(&args, 0, sizeof(args));
+
+	write_lock(&tree->lock);
+	test_gen = root->fs_info->last_trans_committed;
+
+	list_for_each_entry_safe(em, n, &tree->modified_extents, list) {
+		list_del_init(&em->list);
+		if (em->generation <= test_gen)
+			continue;
+		/* Need a ref to keep it from getting evicted from cache */
+		atomic_inc(&em->refs);
+		set_bit(EXTENT_FLAG_LOGGING, &em->flags);
+		list_add_tail(&em->list, &extents);
+	}
+
+	list_sort(NULL, &extents, extent_cmp);
+
+	while (!list_empty(&extents)) {
+		em = list_entry(extents.next, struct extent_map, list);
+
+		list_del_init(&em->list);
+		clear_bit(EXTENT_FLAG_LOGGING, &em->flags);
+
+		/*
+		 * If we had an error we just need to delete everybody from our
+		 * private list.
+		 */
+		if (ret) {
+			free_extent_map(em);
+			continue;
+		}
+
+		write_unlock(&tree->lock);
+
+		/*
+		 * If the previous EM and the last extent we left off on aren't
+		 * sequential then we need to copy the items we have and redo
+		 * our search
+		 */
+		if (args.nr && em->mod_start != args.next_offset) {
+			ret = copy_items(trans, inode, dst_path, args.src,
+					 args.start_slot, args.nr,
+					 LOG_INODE_ALL);
+			if (ret) {
+				free_extent_map(em);
+				write_lock(&tree->lock);
+				continue;
+			}
+			btrfs_release_path(path);
+			args.nr = 0;
+		}
+
+		ret = log_one_extent(trans, inode, root, em, path, dst_path, &args);
+		free_extent_map(em);
+		write_lock(&tree->lock);
+	}
+	WARN_ON(!list_empty(&extents));
+	write_unlock(&tree->lock);
+
+	if (!ret && args.nr)
+		ret = copy_items(trans, inode, dst_path, args.src,
+				 args.start_slot, args.nr, LOG_INODE_ALL);
+	btrfs_release_path(path);
+	return ret;
+}
+
 /* log a single inode in the tree log.
  * At least one parent directory for this inode must exist in the tree
  * or be logged already.
@@ -2832,6 +3378,7 @@
 	int nritems;
 	int ins_start_slot = 0;
 	int ins_nr;
+	bool fast_search = false;
 	u64 ino = btrfs_ino(inode);
 
 	log = root->log_root;
@@ -2851,21 +3398,23 @@
 
 	max_key.objectid = ino;
 
-	/* today the code can only do partial logging of directories */
-	if (!S_ISDIR(inode->i_mode))
-	    inode_only = LOG_INODE_ALL;
 
+	/* today the code can only do partial logging of directories */
 	if (inode_only == LOG_INODE_EXISTS || S_ISDIR(inode->i_mode))
 		max_key.type = BTRFS_XATTR_ITEM_KEY;
 	else
 		max_key.type = (u8)-1;
 	max_key.offset = (u64)-1;
 
-	ret = btrfs_commit_inode_delayed_items(trans, inode);
-	if (ret) {
-		btrfs_free_path(path);
-		btrfs_free_path(dst_path);
-		return ret;
+	/* Only run delayed items if we are a dir or a new file */
+	if (S_ISDIR(inode->i_mode) ||
+	    BTRFS_I(inode)->generation > root->fs_info->last_trans_committed) {
+		ret = btrfs_commit_inode_delayed_items(trans, inode);
+		if (ret) {
+			btrfs_free_path(path);
+			btrfs_free_path(dst_path);
+			return ret;
+		}
 	}
 
 	mutex_lock(&BTRFS_I(inode)->log_mutex);
@@ -2881,7 +3430,16 @@
 			max_key_type = BTRFS_XATTR_ITEM_KEY;
 		ret = drop_objectid_items(trans, log, path, ino, max_key_type);
 	} else {
-		ret = btrfs_truncate_inode_items(trans, log, inode, 0, 0);
+		if (test_and_clear_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
+				       &BTRFS_I(inode)->runtime_flags)) {
+			ret = btrfs_truncate_inode_items(trans, log,
+							 inode, 0, 0);
+		} else {
+			fast_search = true;
+			max_key.type = BTRFS_XATTR_ITEM_KEY;
+			ret = drop_objectid_items(trans, log, path, ino,
+						  BTRFS_XATTR_ITEM_KEY);
+		}
 	}
 	if (ret) {
 		err = ret;
@@ -2912,7 +3470,7 @@
 			goto next_slot;
 		}
 
-		ret = copy_items(trans, log, dst_path, src, ins_start_slot,
+		ret = copy_items(trans, inode, dst_path, src, ins_start_slot,
 				 ins_nr, inode_only);
 		if (ret) {
 			err = ret;
@@ -2930,7 +3488,7 @@
 			goto again;
 		}
 		if (ins_nr) {
-			ret = copy_items(trans, log, dst_path, src,
+			ret = copy_items(trans, inode, dst_path, src,
 					 ins_start_slot,
 					 ins_nr, inode_only);
 			if (ret) {
@@ -2951,8 +3509,7 @@
 			break;
 	}
 	if (ins_nr) {
-		ret = copy_items(trans, log, dst_path, src,
-				 ins_start_slot,
+		ret = copy_items(trans, inode, dst_path, src, ins_start_slot,
 				 ins_nr, inode_only);
 		if (ret) {
 			err = ret;
@@ -2960,7 +3517,24 @@
 		}
 		ins_nr = 0;
 	}
-	WARN_ON(ins_nr);
+
+	if (fast_search) {
+		btrfs_release_path(path);
+		btrfs_release_path(dst_path);
+		ret = btrfs_log_changed_extents(trans, root, inode, path,
+						dst_path);
+		if (ret) {
+			err = ret;
+			goto out_unlock;
+		}
+	} else {
+		struct extent_map_tree *tree = &BTRFS_I(inode)->extent_tree;
+		struct extent_map *em, *n;
+
+		list_for_each_entry_safe(em, n, &tree->modified_extents, list)
+			list_del_init(&em->list);
+	}
+
 	if (inode_only == LOG_INODE_ALL && S_ISDIR(inode->i_mode)) {
 		btrfs_release_path(path);
 		btrfs_release_path(dst_path);
@@ -2971,6 +3545,7 @@
 		}
 	}
 	BTRFS_I(inode)->logged_trans = trans->transid;
+	BTRFS_I(inode)->last_log_commit = BTRFS_I(inode)->last_sub_trans;
 out_unlock:
 	mutex_unlock(&BTRFS_I(inode)->log_mutex);
 
@@ -3138,7 +3713,7 @@
 end_trans:
 	dput(old_parent);
 	if (ret < 0) {
-		BUG_ON(ret != -ENOSPC);
+		WARN_ON(ret != -ENOSPC);
 		root->fs_info->last_trans_log_full_commit = trans->transid;
 		ret = 1;
 	}
diff --git a/fs/btrfs/ulist.c b/fs/btrfs/ulist.c
index ab942f4..99be4c1 100644
--- a/fs/btrfs/ulist.c
+++ b/fs/btrfs/ulist.c
@@ -143,14 +143,13 @@
  * In case of allocation failure -ENOMEM is returned and the ulist stays
  * unaltered.
  */
-int ulist_add(struct ulist *ulist, u64 val, unsigned long aux,
-	      gfp_t gfp_mask)
+int ulist_add(struct ulist *ulist, u64 val, u64 aux, gfp_t gfp_mask)
 {
 	return ulist_add_merge(ulist, val, aux, NULL, gfp_mask);
 }
 
-int ulist_add_merge(struct ulist *ulist, u64 val, unsigned long aux,
-		    unsigned long *old_aux, gfp_t gfp_mask)
+int ulist_add_merge(struct ulist *ulist, u64 val, u64 aux,
+		    u64 *old_aux, gfp_t gfp_mask)
 {
 	int i;
 
diff --git a/fs/btrfs/ulist.h b/fs/btrfs/ulist.h
index 21bdc8e..21a1963 100644
--- a/fs/btrfs/ulist.h
+++ b/fs/btrfs/ulist.h
@@ -33,7 +33,7 @@
  */
 struct ulist_node {
 	u64 val;		/* value to store */
-	unsigned long aux;	/* auxiliary value saved along with the val */
+	u64 aux;		/* auxiliary value saved along with the val */
 };
 
 struct ulist {
@@ -65,10 +65,9 @@
 void ulist_reinit(struct ulist *ulist);
 struct ulist *ulist_alloc(gfp_t gfp_mask);
 void ulist_free(struct ulist *ulist);
-int ulist_add(struct ulist *ulist, u64 val, unsigned long aux,
-	      gfp_t gfp_mask);
-int ulist_add_merge(struct ulist *ulist, u64 val, unsigned long aux,
-		    unsigned long *old_aux, gfp_t gfp_mask);
+int ulist_add(struct ulist *ulist, u64 val, u64 aux, gfp_t gfp_mask);
+int ulist_add_merge(struct ulist *ulist, u64 val, u64 aux,
+		    u64 *old_aux, gfp_t gfp_mask);
 struct ulist_node *ulist_next(struct ulist *ulist,
 			      struct ulist_iterator *uiter);
 
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 88b969a..029b903 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -639,7 +639,7 @@
 
 		bdev = blkdev_get_by_path(device->name->str, flags, holder);
 		if (IS_ERR(bdev)) {
-			printk(KERN_INFO "open %s failed\n", device->name->str);
+			printk(KERN_INFO "btrfs: open %s failed\n", device->name->str);
 			goto error;
 		}
 		filemap_write_and_wait(bdev->bd_inode->i_mapping);
@@ -1475,6 +1475,9 @@
 		free_fs_devices(cur_devices);
 	}
 
+	root->fs_info->num_tolerated_disk_barrier_failures =
+		btrfs_calc_num_tolerated_disk_barrier_failures(root->fs_info);
+
 	/*
 	 * at this point, the device is zero sized.  We want to
 	 * remove it from the devices list and zero out the old super
@@ -1775,15 +1778,21 @@
 
 	if (seeding_dev) {
 		ret = init_first_rw_device(trans, root, device);
-		if (ret)
+		if (ret) {
+			btrfs_abort_transaction(trans, root, ret);
 			goto error_trans;
+		}
 		ret = btrfs_finish_sprout(trans, root);
-		if (ret)
+		if (ret) {
+			btrfs_abort_transaction(trans, root, ret);
 			goto error_trans;
+		}
 	} else {
 		ret = btrfs_add_device(trans, root, device);
-		if (ret)
+		if (ret) {
+			btrfs_abort_transaction(trans, root, ret);
 			goto error_trans;
+		}
 	}
 
 	/*
@@ -1793,6 +1802,8 @@
 	btrfs_clear_space_info_full(root->fs_info);
 
 	unlock_chunks(root);
+	root->fs_info->num_tolerated_disk_barrier_failures =
+		btrfs_calc_num_tolerated_disk_barrier_failures(root->fs_info);
 	ret = btrfs_commit_transaction(trans, root);
 
 	if (seeding_dev) {
@@ -1814,7 +1825,6 @@
 
 error_trans:
 	unlock_chunks(root);
-	btrfs_abort_transaction(trans, root, ret);
 	btrfs_end_transaction(trans, root);
 	rcu_string_free(device->name);
 	kfree(device);
@@ -2804,6 +2814,26 @@
 		}
 	}
 
+	if (bctl->sys.flags & BTRFS_BALANCE_ARGS_CONVERT) {
+		int num_tolerated_disk_barrier_failures;
+		u64 target = bctl->sys.target;
+
+		num_tolerated_disk_barrier_failures =
+			btrfs_calc_num_tolerated_disk_barrier_failures(fs_info);
+		if (num_tolerated_disk_barrier_failures > 0 &&
+		    (target &
+		     (BTRFS_BLOCK_GROUP_DUP | BTRFS_BLOCK_GROUP_RAID0 |
+		      BTRFS_AVAIL_ALLOC_BIT_SINGLE)))
+			num_tolerated_disk_barrier_failures = 0;
+		else if (num_tolerated_disk_barrier_failures > 1 &&
+			 (target &
+			  (BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID10)))
+			num_tolerated_disk_barrier_failures = 1;
+
+		fs_info->num_tolerated_disk_barrier_failures =
+			num_tolerated_disk_barrier_failures;
+	}
+
 	ret = insert_balance_item(fs_info->tree_root, bctl);
 	if (ret && ret != -EEXIST)
 		goto out;
@@ -2836,6 +2866,11 @@
 		__cancel_balance(fs_info);
 	}
 
+	if (bctl->sys.flags & BTRFS_BALANCE_ARGS_CONVERT) {
+		fs_info->num_tolerated_disk_barrier_failures =
+			btrfs_calc_num_tolerated_disk_barrier_failures(fs_info);
+	}
+
 	wake_up(&fs_info->balance_wait_q);
 
 	return ret;
@@ -3608,12 +3643,16 @@
 	ret = __btrfs_alloc_chunk(trans, extent_root, &sys_map,
 				  &sys_chunk_size, &sys_stripe_size,
 				  sys_chunk_offset, alloc_profile);
-	if (ret)
-		goto abort;
+	if (ret) {
+		btrfs_abort_transaction(trans, root, ret);
+		goto out;
+	}
 
 	ret = btrfs_add_device(trans, fs_info->chunk_root, device);
-	if (ret)
-		goto abort;
+	if (ret) {
+		btrfs_abort_transaction(trans, root, ret);
+		goto out;
+	}
 
 	/*
 	 * Modifying chunk tree needs allocating new blocks from both
@@ -3623,19 +3662,19 @@
 	 */
 	ret = __finish_chunk_alloc(trans, extent_root, map, chunk_offset,
 				   chunk_size, stripe_size);
-	if (ret)
-		goto abort;
+	if (ret) {
+		btrfs_abort_transaction(trans, root, ret);
+		goto out;
+	}
 
 	ret = __finish_chunk_alloc(trans, extent_root, sys_map,
 				   sys_chunk_offset, sys_chunk_size,
 				   sys_stripe_size);
 	if (ret)
-		goto abort;
+		btrfs_abort_transaction(trans, root, ret);
 
-	return 0;
+out:
 
-abort:
-	btrfs_abort_transaction(trans, root, ret);
 	return ret;
 }
 
@@ -3760,7 +3799,7 @@
 	read_unlock(&em_tree->lock);
 
 	if (!em) {
-		printk(KERN_CRIT "unable to find logical %llu len %llu\n",
+		printk(KERN_CRIT "btrfs: unable to find logical %llu len %llu\n",
 		       (unsigned long long)logical,
 		       (unsigned long long)*length);
 		BUG();
@@ -4217,7 +4256,7 @@
 
 	total_devs = bbio->num_stripes;
 	if (map_length < length) {
-		printk(KERN_CRIT "mapping failed logical %llu bio len %llu "
+		printk(KERN_CRIT "btrfs: mapping failed logical %llu bio len %llu "
 		       "len %llu\n", (unsigned long long)logical,
 		       (unsigned long long)length,
 		       (unsigned long long)map_length);
diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c
index 92c2065..9acb846 100644
--- a/fs/btrfs/zlib.c
+++ b/fs/btrfs/zlib.c
@@ -97,7 +97,7 @@
 	*total_in = 0;
 
 	if (Z_OK != zlib_deflateInit(&workspace->def_strm, 3)) {
-		printk(KERN_WARNING "deflateInit failed\n");
+		printk(KERN_WARNING "btrfs: deflateInit failed\n");
 		ret = -1;
 		goto out;
 	}
@@ -125,7 +125,7 @@
 	while (workspace->def_strm.total_in < len) {
 		ret = zlib_deflate(&workspace->def_strm, Z_SYNC_FLUSH);
 		if (ret != Z_OK) {
-			printk(KERN_DEBUG "btrfs deflate in loop returned %d\n",
+			printk(KERN_DEBUG "btrfs: deflate in loop returned %d\n",
 			       ret);
 			zlib_deflateEnd(&workspace->def_strm);
 			ret = -1;
@@ -252,7 +252,7 @@
 	}
 
 	if (Z_OK != zlib_inflateInit2(&workspace->inf_strm, wbits)) {
-		printk(KERN_WARNING "inflateInit failed\n");
+		printk(KERN_WARNING "btrfs: inflateInit failed\n");
 		return -1;
 	}
 	while (workspace->inf_strm.total_in < srclen) {
@@ -336,7 +336,7 @@
 	}
 
 	if (Z_OK != zlib_inflateInit2(&workspace->inf_strm, wbits)) {
-		printk(KERN_WARNING "inflateInit failed\n");
+		printk(KERN_WARNING "btrfs: inflateInit failed\n");
 		return -1;
 	}
 
diff --git a/fs/buffer.c b/fs/buffer.c
index 58e2e7b..b5f0442 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2312,12 +2312,6 @@
 	loff_t size;
 	int ret;
 
-	/*
-	 * Update file times before taking page lock. We may end up failing the
-	 * fault so this update may be superfluous but who really cares...
-	 */
-	file_update_time(vma->vm_file);
-
 	lock_page(page);
 	size = i_size_read(inode);
 	if ((page->mapping != inode->i_mapping) ||
@@ -2355,6 +2349,13 @@
 	struct super_block *sb = vma->vm_file->f_path.dentry->d_inode->i_sb;
 
 	sb_start_pagefault(sb);
+
+	/*
+	 * Update file times before taking page lock. We may end up failing the
+	 * fault so this update may be superfluous but who really cares...
+	 */
+	file_update_time(vma->vm_file);
+
 	ret = __block_page_mkwrite(vma, vmf, get_block);
 	sb_end_pagefault(sb);
 	return block_page_mkwrite_return(ret);
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index 452e71a..6690269 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -205,7 +205,7 @@
 	dout("readpage inode %p file %p page %p index %lu\n",
 	     inode, filp, page, page->index);
 	err = ceph_osdc_readpages(osdc, ceph_vino(inode), &ci->i_layout,
-				  page->index << PAGE_CACHE_SHIFT, &len,
+				  (u64) page_offset(page), &len,
 				  ci->i_truncate_seq, ci->i_truncate_size,
 				  &page, 1, 0);
 	if (err == -ENOENT)
@@ -286,7 +286,7 @@
 	int nr_pages = 0;
 	int ret;
 
-	off = page->index << PAGE_CACHE_SHIFT;
+	off = (u64) page_offset(page);
 
 	/* count pages */
 	next_index = page->index;
@@ -308,8 +308,8 @@
 				    NULL, 0,
 				    ci->i_truncate_seq, ci->i_truncate_size,
 				    NULL, false, 1, 0);
-	if (!req)
-		return -ENOMEM;
+	if (IS_ERR(req))
+		return PTR_ERR(req);
 
 	/* build page vector */
 	nr_pages = len >> PAGE_CACHE_SHIFT;
@@ -426,7 +426,7 @@
 	struct ceph_inode_info *ci;
 	struct ceph_fs_client *fsc;
 	struct ceph_osd_client *osdc;
-	loff_t page_off = page->index << PAGE_CACHE_SHIFT;
+	loff_t page_off = page_offset(page);
 	int len = PAGE_CACHE_SIZE;
 	loff_t i_size;
 	int err = 0;
@@ -817,8 +817,7 @@
 			/* ok */
 			if (locked_pages == 0) {
 				/* prepare async write request */
-				offset = (unsigned long long)page->index
-					<< PAGE_CACHE_SHIFT;
+				offset = (u64) page_offset(page);
 				len = wsize;
 				req = ceph_osdc_new_request(&fsc->client->osdc,
 					    &ci->i_layout,
@@ -832,8 +831,8 @@
 					    ci->i_truncate_size,
 					    &inode->i_mtime, true, 1, 0);
 
-				if (!req) {
-					rc = -ENOMEM;
+				if (IS_ERR(req)) {
+					rc = PTR_ERR(req);
 					unlock_page(page);
 					break;
 				}
@@ -1180,7 +1179,7 @@
 	struct inode *inode = vma->vm_file->f_dentry->d_inode;
 	struct page *page = vmf->page;
 	struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
-	loff_t off = page->index << PAGE_CACHE_SHIFT;
+	loff_t off = page_offset(page);
 	loff_t size, len;
 	int ret;
 
@@ -1225,6 +1224,7 @@
 static struct vm_operations_struct ceph_vmops = {
 	.fault		= filemap_fault,
 	.page_mkwrite	= ceph_page_mkwrite,
+	.remap_pages	= generic_file_remap_pages,
 };
 
 int ceph_mmap(struct file *file, struct vm_area_struct *vma)
@@ -1235,6 +1235,5 @@
 		return -ENOEXEC;
 	file_accessed(file);
 	vma->vm_ops = &ceph_vmops;
-	vma->vm_flags |= VM_CAN_NONLINEAR;
 	return 0;
 }
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 620daad..3251e9c 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -1005,7 +1005,7 @@
 
 	BUG_ON(msg->front.iov_len + sizeof(*item) > PAGE_CACHE_SIZE);
 	head = msg->front.iov_base;
-	head->num = cpu_to_le32(le32_to_cpu(head->num) + 1);
+	le32_add_cpu(&head->num, 1);
 	item = msg->front.iov_base + msg->front.iov_len;
 	item->ino = cpu_to_le64(ino);
 	item->cap_id = cpu_to_le64(cap_id);
diff --git a/fs/ceph/export.c b/fs/ceph/export.c
index 8e1b60e..02ce909 100644
--- a/fs/ceph/export.c
+++ b/fs/ceph/export.c
@@ -99,7 +99,7 @@
  * FIXME: we should try harder by querying the mds for the ino.
  */
 static struct dentry *__fh_to_dentry(struct super_block *sb,
-				     struct ceph_nfs_fh *fh)
+				     struct ceph_nfs_fh *fh, int fh_len)
 {
 	struct ceph_mds_client *mdsc = ceph_sb_to_client(sb)->mdsc;
 	struct inode *inode;
@@ -107,6 +107,9 @@
 	struct ceph_vino vino;
 	int err;
 
+	if (fh_len < sizeof(*fh) / 4)
+		return ERR_PTR(-ESTALE);
+
 	dout("__fh_to_dentry %llx\n", fh->ino);
 	vino.ino = fh->ino;
 	vino.snap = CEPH_NOSNAP;
@@ -150,7 +153,7 @@
  * convert connectable fh to dentry
  */
 static struct dentry *__cfh_to_dentry(struct super_block *sb,
-				      struct ceph_nfs_confh *cfh)
+				      struct ceph_nfs_confh *cfh, int fh_len)
 {
 	struct ceph_mds_client *mdsc = ceph_sb_to_client(sb)->mdsc;
 	struct inode *inode;
@@ -158,6 +161,9 @@
 	struct ceph_vino vino;
 	int err;
 
+	if (fh_len < sizeof(*cfh) / 4)
+		return ERR_PTR(-ESTALE);
+
 	dout("__cfh_to_dentry %llx (%llx/%x)\n",
 	     cfh->ino, cfh->parent_ino, cfh->parent_name_hash);
 
@@ -207,9 +213,11 @@
 					int fh_len, int fh_type)
 {
 	if (fh_type == 1)
-		return __fh_to_dentry(sb, (struct ceph_nfs_fh *)fid->raw);
+		return __fh_to_dentry(sb, (struct ceph_nfs_fh *)fid->raw,
+								fh_len);
 	else
-		return __cfh_to_dentry(sb, (struct ceph_nfs_confh *)fid->raw);
+		return __cfh_to_dentry(sb, (struct ceph_nfs_confh *)fid->raw,
+								fh_len);
 }
 
 /*
@@ -230,6 +238,8 @@
 
 	if (fh_type == 1)
 		return ERR_PTR(-ESTALE);
+	if (fh_len < sizeof(*cfh) / 4)
+		return ERR_PTR(-ESTALE);
 
 	pr_debug("fh_to_parent %llx/%d\n", cfh->parent_ino,
 		 cfh->parent_name_hash);
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index ecebbc0..5840d2a 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -536,8 +536,8 @@
 				    do_sync,
 				    ci->i_truncate_seq, ci->i_truncate_size,
 				    &mtime, false, 2, page_align);
-	if (!req)
-		return -ENOMEM;
+	if (IS_ERR(req))
+		return PTR_ERR(req);
 
 	if (file->f_flags & O_DIRECT) {
 		pages = ceph_get_direct_page_vector(data, num_pages, false);
diff --git a/fs/ceph/ioctl.c b/fs/ceph/ioctl.c
index 1396ceb..36549a4 100644
--- a/fs/ceph/ioctl.c
+++ b/fs/ceph/ioctl.c
@@ -187,14 +187,18 @@
 	u64 tmp;
 	struct ceph_object_layout ol;
 	struct ceph_pg pgid;
+	int r;
 
 	/* copy and validate */
 	if (copy_from_user(&dl, arg, sizeof(dl)))
 		return -EFAULT;
 
 	down_read(&osdc->map_sem);
-	ceph_calc_file_object_mapping(&ci->i_layout, dl.file_offset, &len,
-				      &dl.object_no, &dl.object_offset, &olen);
+	r = ceph_calc_file_object_mapping(&ci->i_layout, dl.file_offset, &len,
+					  &dl.object_no, &dl.object_offset,
+					  &olen);
+	if (r < 0)
+		return -EIO;
 	dl.file_offset -= dl.object_offset;
 	dl.object_size = ceph_file_layout_object_size(ci->i_layout);
 	dl.block_size = ceph_file_layout_su(ci->i_layout);
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index a5a7354..1bcf712 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -2625,7 +2625,8 @@
 		     ceph_mdsmap_is_laggy(newmap, i) ? " (laggy)" : "",
 		     session_state_name(s->s_state));
 
-		if (memcmp(ceph_mdsmap_get_addr(oldmap, i),
+		if (i >= newmap->m_max_mds ||
+		    memcmp(ceph_mdsmap_get_addr(oldmap, i),
 			   ceph_mdsmap_get_addr(newmap, i),
 			   sizeof(struct ceph_entity_addr))) {
 			if (s->s_state == CEPH_MDS_SESSION_OPENING) {
diff --git a/fs/ceph/super.c b/fs/ceph/super.c
index 3a42d93..2eb43f2 100644
--- a/fs/ceph/super.c
+++ b/fs/ceph/super.c
@@ -307,7 +307,10 @@
 {
 	struct ceph_mount_options *fsopt;
 	const char *dev_name_end;
-	int err = -ENOMEM;
+	int err;
+
+	if (!dev_name || !*dev_name)
+		return -EINVAL;
 
 	fsopt = kzalloc(sizeof(*fsopt), GFP_KERNEL);
 	if (!fsopt)
@@ -328,21 +331,33 @@
 	fsopt->max_readdir_bytes = CEPH_MAX_READDIR_BYTES_DEFAULT;
 	fsopt->congestion_kb = default_congestion_kb();
 
-	/* ip1[:port1][,ip2[:port2]...]:/subdir/in/fs */
+	/*
+	 * Distinguish the server list from the path in "dev_name".
+	 * Internally we do not include the leading '/' in the path.
+	 *
+	 * "dev_name" will look like:
+	 *     <server_spec>[,<server_spec>...]:[<path>]
+	 * where
+	 *     <server_spec> is <ip>[:<port>]
+	 *     <path> is optional, but if present must begin with '/'
+	 */
+	dev_name_end = strchr(dev_name, '/');
+	if (dev_name_end) {
+		/* skip over leading '/' for path */
+		*path = dev_name_end + 1;
+	} else {
+		/* path is empty */
+		dev_name_end = dev_name + strlen(dev_name);
+		*path = dev_name_end;
+	}
 	err = -EINVAL;
-	if (!dev_name)
-		goto out;
-	*path = strstr(dev_name, ":/");
-	if (*path == NULL) {
-		pr_err("device name is missing path (no :/ in %s)\n",
+	dev_name_end--;		/* back up to ':' separator */
+	if (*dev_name_end != ':') {
+		pr_err("device name is missing path (no : separator in %s)\n",
 				dev_name);
 		goto out;
 	}
-	dev_name_end = *path;
 	dout("device name '%.*s'\n", (int)(dev_name_end - dev_name), dev_name);
-
-	/* path on server */
-	*path += 2;
 	dout("server path '%s'\n", *path);
 
 	*popt = ceph_parse_options(options, dev_name, dev_name_end,
diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c
index 53cf2aa..71d5d0a 100644
--- a/fs/cifs/cifs_unicode.c
+++ b/fs/cifs/cifs_unicode.c
@@ -203,6 +203,27 @@
 	int i;
 	wchar_t wchar_to; /* needed to quiet sparse */
 
+	/* special case for utf8 to handle no plane0 chars */
+	if (!strcmp(codepage->charset, "utf8")) {
+		/*
+		 * convert utf8 -> utf16, we assume we have enough space
+		 * as caller should have assumed conversion does not overflow
+		 * in destination len is length in wchar_t units (16bits)
+		 */
+		i  = utf8s_to_utf16s(from, len, UTF16_LITTLE_ENDIAN,
+				       (wchar_t *) to, len);
+
+		/* if success terminate and exit */
+		if (i >= 0)
+			goto success;
+		/*
+		 * if fails fall back to UCS encoding as this
+		 * function should not return negative values
+		 * currently can fail only if source contains
+		 * invalid encoded characters
+		 */
+	}
+
 	for (i = 0; len && *from; i++, from += charlen, len -= charlen) {
 		charlen = codepage->char2uni(from, len, &wchar_to);
 		if (charlen < 1) {
@@ -215,6 +236,7 @@
 		put_unaligned_le16(wchar_to, &to[i]);
 	}
 
+success:
 	put_unaligned_le16(0, &to[i]);
 	return i;
 }
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 2fdbe08..5c670b9 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -67,6 +67,7 @@
 	/* Mount options that take no arguments */
 	Opt_user_xattr, Opt_nouser_xattr,
 	Opt_forceuid, Opt_noforceuid,
+	Opt_forcegid, Opt_noforcegid,
 	Opt_noblocksend, Opt_noautotune,
 	Opt_hard, Opt_soft, Opt_perm, Opt_noperm,
 	Opt_mapchars, Opt_nomapchars, Opt_sfu,
@@ -117,6 +118,8 @@
 	{ Opt_nouser_xattr, "nouser_xattr" },
 	{ Opt_forceuid, "forceuid" },
 	{ Opt_noforceuid, "noforceuid" },
+	{ Opt_forcegid, "forcegid" },
+	{ Opt_noforcegid, "noforcegid" },
 	{ Opt_noblocksend, "noblocksend" },
 	{ Opt_noautotune, "noautotune" },
 	{ Opt_hard, "hard" },
@@ -1195,6 +1198,12 @@
 		case Opt_noforceuid:
 			override_uid = 0;
 			break;
+		case Opt_forcegid:
+			override_gid = 1;
+			break;
+		case Opt_noforcegid:
+			override_gid = 0;
+			break;
 		case Opt_noblocksend:
 			vol->noblocksnd = 1;
 			break;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 7d7bbdc..edb25b4 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -3003,6 +3003,7 @@
 static struct vm_operations_struct cifs_file_vm_ops = {
 	.fault = filemap_fault,
 	.page_mkwrite = cifs_page_mkwrite,
+	.remap_pages = generic_file_remap_pages,
 };
 
 int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma)
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 2126ab1..76d974c 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -183,6 +183,12 @@
 		rc = kernel_sendmsg(ssocket, &smb_msg, &iov[first_vec],
 				    n_vec - first_vec, remaining);
 		if (rc == -ENOSPC || rc == -EAGAIN) {
+			/*
+			 * Catch if a low level driver returns -ENOSPC. This
+			 * WARN_ON will be removed by 3.10 if no one reports
+			 * seeing this.
+			 */
+			WARN_ON_ONCE(rc == -ENOSPC);
 			i++;
 			if (i >= 14 || (!server->noblocksnd && (i > 2))) {
 				cERROR(1, "sends on sock %p stuck for 15 "
diff --git a/fs/exec.c b/fs/exec.c
index 9824473..ca43453 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -59,7 +59,6 @@
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
 #include <asm/tlb.h>
-#include <asm/exec.h>
 
 #include <trace/events/task.h>
 #include "internal.h"
@@ -392,7 +391,7 @@
 	union {
 		const char __user *const __user *native;
 #ifdef CONFIG_COMPAT
-		compat_uptr_t __user *compat;
+		const compat_uptr_t __user *compat;
 #endif
 	} ptr;
 };
@@ -603,7 +602,7 @@
 	 * process cleanup to remove whatever mess we made.
 	 */
 	if (length != move_page_tables(vma, old_start,
-				       vma, new_start, length))
+				       vma, new_start, length, false))
 		return -ENOMEM;
 
 	lru_add_drain();
@@ -878,9 +877,11 @@
 		sig->notify_count--;
 
 	while (sig->notify_count) {
-		__set_current_state(TASK_UNINTERRUPTIBLE);
+		__set_current_state(TASK_KILLABLE);
 		spin_unlock_irq(lock);
 		schedule();
+		if (unlikely(__fatal_signal_pending(tsk)))
+			goto killed;
 		spin_lock_irq(lock);
 	}
 	spin_unlock_irq(lock);
@@ -898,9 +899,11 @@
 			write_lock_irq(&tasklist_lock);
 			if (likely(leader->exit_state))
 				break;
-			__set_current_state(TASK_UNINTERRUPTIBLE);
+			__set_current_state(TASK_KILLABLE);
 			write_unlock_irq(&tasklist_lock);
 			schedule();
+			if (unlikely(__fatal_signal_pending(tsk)))
+				goto killed;
 		}
 
 		/*
@@ -994,6 +997,14 @@
 
 	BUG_ON(!thread_group_leader(tsk));
 	return 0;
+
+killed:
+	/* protects against exit_notify() and __exit_signal() */
+	read_lock(&tasklist_lock);
+	sig->group_exit_task = NULL;
+	sig->notify_count = 0;
+	read_unlock(&tasklist_lock);
+	return -EAGAIN;
 }
 
 char *get_task_comm(char *buf, struct task_struct *tsk)
@@ -1562,9 +1573,9 @@
 }
 
 #ifdef CONFIG_COMPAT
-int compat_do_execve(char *filename,
-	compat_uptr_t __user *__argv,
-	compat_uptr_t __user *__envp,
+int compat_do_execve(const char *filename,
+	const compat_uptr_t __user *__argv,
+	const compat_uptr_t __user *__envp,
 	struct pt_regs *regs)
 {
 	struct user_arg_ptr argv = {
@@ -1646,3 +1657,55 @@
 {
 	return __get_dumpable(mm->flags);
 }
+
+#ifdef __ARCH_WANT_SYS_EXECVE
+SYSCALL_DEFINE3(execve,
+		const char __user *, filename,
+		const char __user *const __user *, argv,
+		const char __user *const __user *, envp)
+{
+	const char *path = getname(filename);
+	int error = PTR_ERR(path);
+	if (!IS_ERR(path)) {
+		error = do_execve(path, argv, envp, current_pt_regs());
+		putname(path);
+	}
+	return error;
+}
+#ifdef CONFIG_COMPAT
+asmlinkage long compat_sys_execve(const char __user * filename,
+	const compat_uptr_t __user * argv,
+	const compat_uptr_t __user * envp)
+{
+	const char *path = getname(filename);
+	int error = PTR_ERR(path);
+	if (!IS_ERR(path)) {
+		error = compat_do_execve(path, argv, envp, current_pt_regs());
+		putname(path);
+	}
+	return error;
+}
+#endif
+#endif
+
+#ifdef __ARCH_WANT_KERNEL_EXECVE
+int kernel_execve(const char *filename,
+		  const char *const argv[],
+		  const char *const envp[])
+{
+	struct pt_regs *p = current_pt_regs();
+	int ret;
+
+	ret = do_execve(filename,
+			(const char __user *const __user *)argv,
+			(const char __user *const __user *)envp, p);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * We were successful.  We won't be returning to our caller, but
+	 * instead to user space by manipulating the kernel stack.
+	 */
+	ret_from_kernel_execve(p);
+}
+#endif
diff --git a/fs/exofs/ore.c b/fs/exofs/ore.c
index 1585db1..f936cb5 100644
--- a/fs/exofs/ore.c
+++ b/fs/exofs/ore.c
@@ -814,8 +814,8 @@
 			struct bio *bio;
 
 			if (per_dev != master_dev) {
-				bio = bio_kmalloc(GFP_KERNEL,
-						  master_dev->bio->bi_max_vecs);
+				bio = bio_clone_kmalloc(master_dev->bio,
+							GFP_KERNEL);
 				if (unlikely(!bio)) {
 					ORE_DBGMSG(
 					      "Failed to allocate BIO size=%u\n",
@@ -824,7 +824,6 @@
 					goto out;
 				}
 
-				__bio_clone(bio, master_dev->bio);
 				bio->bi_bdev = NULL;
 				bio->bi_next = NULL;
 				per_dev->offset = master_dev->offset;
diff --git a/fs/exofs/ore_raid.c b/fs/exofs/ore_raid.c
index 5f376d1..b963f38 100644
--- a/fs/exofs/ore_raid.c
+++ b/fs/exofs/ore_raid.c
@@ -203,7 +203,7 @@
 
 static unsigned _sp2d_max_pg(struct __stripe_pages_2d *sp2d)
 {
-	unsigned p;
+	int p;
 
 	for (p = sp2d->pages_in_unit - 1; p >= 0; --p) {
 		struct __1_page_stripe *_1ps = &sp2d->_1p_stripes[p];
diff --git a/fs/exofs/super.c b/fs/exofs/super.c
index 59e3bbf..5e59280 100644
--- a/fs/exofs/super.c
+++ b/fs/exofs/super.c
@@ -389,8 +389,6 @@
 	if (unlikely(ret))
 		goto out;
 
-	lock_super(sb);
-
 	ios->length = offsetof(struct exofs_fscb, s_dev_table_oid);
 	memset(fscb, 0, ios->length);
 	fscb->s_nextid = cpu_to_le64(sbi->s_nextid);
@@ -406,8 +404,6 @@
 	if (unlikely(ret))
 		EXOFS_ERR("%s: ore_write failed.\n", __func__);
 
-
-	unlock_super(sb);
 out:
 	EXOFS_DBGMSG("s_nextid=0x%llx ret=%d\n", _LLU(sbi->s_nextid), ret);
 	ore_put_io_state(ios);
diff --git a/fs/exofs/sys.c b/fs/exofs/sys.c
index 5a7b691..1b4f2f9 100644
--- a/fs/exofs/sys.c
+++ b/fs/exofs/sys.c
@@ -80,8 +80,13 @@
 
 static ssize_t uri_store(struct exofs_dev *edp, const char *buf, size_t len)
 {
+	uint8_t *new_uri;
+
 	edp->urilen = strlen(buf) + 1;
-	edp->uri = krealloc(edp->uri, edp->urilen, GFP_KERNEL);
+	new_uri = krealloc(edp->uri, edp->urilen, GFP_KERNEL);
+	if (new_uri == NULL)
+		return -ENOMEM;
+	edp->uri = new_uri;
 	strncpy(edp->uri, buf, edp->urilen);
 	return edp->urilen;
 }
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 17ae5c8..29e7971 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -2578,11 +2578,9 @@
 static int ext3_unfreeze(struct super_block *sb)
 {
 	if (!(sb->s_flags & MS_RDONLY)) {
-		lock_super(sb);
 		/* Reser the needs_recovery flag before the fs is unlocked. */
 		EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
 		ext3_commit_super(sb, EXT3_SB(sb)->s_es, 1);
-		unlock_super(sb);
 		journal_unlock_updates(EXT3_SB(sb)->s_journal);
 	}
 	return 0;
@@ -2602,7 +2600,6 @@
 #endif
 
 	/* Store the original options */
-	lock_super(sb);
 	old_sb_flags = sb->s_flags;
 	old_opts.s_mount_opt = sbi->s_mount_opt;
 	old_opts.s_resuid = sbi->s_resuid;
@@ -2708,8 +2705,6 @@
 		    old_opts.s_qf_names[i] != sbi->s_qf_names[i])
 			kfree(old_opts.s_qf_names[i]);
 #endif
-	unlock_super(sb);
-
 	if (enable_quota)
 		dquot_resume(sb, -1);
 	return 0;
@@ -2728,7 +2723,6 @@
 		sbi->s_qf_names[i] = old_opts.s_qf_names[i];
 	}
 #endif
-	unlock_super(sb);
 	return err;
 }
 
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index c3411d4..3ab2539 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -186,7 +186,6 @@
 #define EXT4_IO_END_ERROR	0x0002
 #define EXT4_IO_END_QUEUED	0x0004
 #define EXT4_IO_END_DIRECT	0x0008
-#define EXT4_IO_END_IN_FSYNC	0x0010
 
 struct ext4_io_page {
 	struct page	*p_page;
@@ -912,9 +911,7 @@
 	struct list_head i_completed_io_list;
 	spinlock_t i_completed_io_lock;
 	atomic_t i_ioend_count;	/* Number of outstanding io_end structs */
-	/* current io_end structure for async DIO write*/
-	ext4_io_end_t *cur_aio_dio;
-	atomic_t i_aiodio_unwritten; /* Nr. of inflight conversions pending */
+	atomic_t i_unwritten; /* Nr. of inflight conversions pending */
 
 	spinlock_t i_block_reservation_lock;
 
@@ -1233,6 +1230,7 @@
 	spinlock_t s_md_lock;
 	unsigned short *s_mb_offsets;
 	unsigned int *s_mb_maxs;
+	unsigned int s_group_info_size;
 
 	/* tunables */
 	unsigned long s_stripe;
@@ -1243,6 +1241,7 @@
 	unsigned int s_mb_order2_reqs;
 	unsigned int s_mb_group_prealloc;
 	unsigned int s_max_writeback_mb_bump;
+	unsigned int s_max_dir_size_kb;
 	/* where last allocation was done - for stream allocation */
 	unsigned long s_mb_last_group;
 	unsigned long s_mb_last_start;
@@ -1270,8 +1269,12 @@
 	unsigned long s_sectors_written_start;
 	u64 s_kbytes_written;
 
+	/* the size of zero-out chunk */
+	unsigned int s_extent_max_zeroout_kb;
+
 	unsigned int s_log_groups_per_flex;
 	struct flex_groups *s_flex_groups;
+	ext4_group_t s_flex_groups_allocated;
 
 	/* workqueue for dio unwritten */
 	struct workqueue_struct *dio_unwritten_wq;
@@ -1328,10 +1331,20 @@
 {
 	if (!(io_end->flag & EXT4_IO_END_UNWRITTEN)) {
 		io_end->flag |= EXT4_IO_END_UNWRITTEN;
-		atomic_inc(&EXT4_I(inode)->i_aiodio_unwritten);
+		atomic_inc(&EXT4_I(inode)->i_unwritten);
 	}
 }
 
+static inline ext4_io_end_t *ext4_inode_aio(struct inode *inode)
+{
+	return inode->i_private;
+}
+
+static inline void ext4_inode_aio_set(struct inode *inode, ext4_io_end_t *io)
+{
+	inode->i_private = io;
+}
+
 /*
  * Inode dynamic state flags
  */
@@ -1345,6 +1358,8 @@
 	EXT4_STATE_DIO_UNWRITTEN,	/* need convert on dio done*/
 	EXT4_STATE_NEWENTRY,		/* File just added to dir */
 	EXT4_STATE_DELALLOC_RESERVED,	/* blks already reserved for delalloc */
+	EXT4_STATE_DIOREAD_LOCK,	/* Disable support for dio read
+					   nolocking */
 };
 
 #define EXT4_INODE_BIT_FNS(name, field, offset)				\
@@ -1932,7 +1947,7 @@
 
 /* fsync.c */
 extern int ext4_sync_file(struct file *, loff_t, loff_t, int);
-extern int ext4_flush_completed_IO(struct inode *);
+extern int ext4_flush_unwritten_io(struct inode *);
 
 /* hash.c */
 extern int ext4fs_dirhash(const char *name, int len, struct
@@ -1966,6 +1981,8 @@
 extern void ext4_free_blocks(handle_t *handle, struct inode *inode,
 			     struct buffer_head *bh, ext4_fsblk_t block,
 			     unsigned long count, int flags);
+extern int ext4_mb_alloc_groupinfo(struct super_block *sb,
+				   ext4_group_t ngroups);
 extern int ext4_mb_add_groupinfo(struct super_block *sb,
 		ext4_group_t i, struct ext4_group_desc *desc);
 extern int ext4_group_add_blocks(handle_t *handle, struct super_block *sb,
@@ -2051,6 +2068,8 @@
 extern void *ext4_kvmalloc(size_t size, gfp_t flags);
 extern void *ext4_kvzalloc(size_t size, gfp_t flags);
 extern void ext4_kvfree(void *ptr);
+extern int ext4_alloc_flex_bg_array(struct super_block *sb,
+				    ext4_group_t ngroup);
 extern __printf(4, 5)
 void __ext4_error(struct super_block *, const char *, unsigned int,
 		  const char *, ...);
@@ -2352,6 +2371,7 @@
 extern const struct inode_operations ext4_file_inode_operations;
 extern const struct file_operations ext4_file_operations;
 extern loff_t ext4_llseek(struct file *file, loff_t offset, int origin);
+extern void ext4_unwritten_wait(struct inode *inode);
 
 /* namei.c */
 extern const struct inode_operations ext4_dir_inode_operations;
@@ -2400,11 +2420,11 @@
 
 /* page-io.c */
 extern int __init ext4_init_pageio(void);
+extern void ext4_add_complete_io(ext4_io_end_t *io_end);
 extern void ext4_exit_pageio(void);
 extern void ext4_ioend_wait(struct inode *);
 extern void ext4_free_io_end(ext4_io_end_t *io);
 extern ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags);
-extern int ext4_end_io_nolock(ext4_io_end_t *io);
 extern void ext4_io_submit(struct ext4_io_submit *io);
 extern int ext4_bio_write_page(struct ext4_io_submit *io,
 			       struct page *page,
@@ -2452,6 +2472,21 @@
 	set_bit(BH_BITMAP_UPTODATE, &(bh)->b_state);
 }
 
+/*
+ * Disable DIO read nolock optimization, so new dioreaders will be forced
+ * to grab i_mutex
+ */
+static inline void ext4_inode_block_unlocked_dio(struct inode *inode)
+{
+	ext4_set_inode_state(inode, EXT4_STATE_DIOREAD_LOCK);
+	smp_mb();
+}
+static inline void ext4_inode_resume_unlocked_dio(struct inode *inode)
+{
+	smp_mb();
+	ext4_clear_inode_state(inode, EXT4_STATE_DIOREAD_LOCK);
+}
+
 #define in_range(b, first, len)	((b) >= (first) && (b) <= (first) + (len) - 1)
 
 /* For ioend & aio unwritten conversion wait queues */
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index aabbb3f..1c94cca 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -1177,7 +1177,7 @@
 		  le32_to_cpu(EXT_FIRST_INDEX(neh)->ei_block),
 		  ext4_idx_pblock(EXT_FIRST_INDEX(neh)));
 
-	neh->eh_depth = cpu_to_le16(le16_to_cpu(neh->eh_depth) + 1);
+	le16_add_cpu(&neh->eh_depth, 1);
 	ext4_mark_inode_dirty(handle, inode);
 out:
 	brelse(bh);
@@ -1656,16 +1656,60 @@
 }
 
 /*
+ * This function does a very simple check to see if we can collapse
+ * an extent tree with a single extent tree leaf block into the inode.
+ */
+static void ext4_ext_try_to_merge_up(handle_t *handle,
+				     struct inode *inode,
+				     struct ext4_ext_path *path)
+{
+	size_t s;
+	unsigned max_root = ext4_ext_space_root(inode, 0);
+	ext4_fsblk_t blk;
+
+	if ((path[0].p_depth != 1) ||
+	    (le16_to_cpu(path[0].p_hdr->eh_entries) != 1) ||
+	    (le16_to_cpu(path[1].p_hdr->eh_entries) > max_root))
+		return;
+
+	/*
+	 * We need to modify the block allocation bitmap and the block
+	 * group descriptor to release the extent tree block.  If we
+	 * can't get the journal credits, give up.
+	 */
+	if (ext4_journal_extend(handle, 2))
+		return;
+
+	/*
+	 * Copy the extent data up to the inode
+	 */
+	blk = ext4_idx_pblock(path[0].p_idx);
+	s = le16_to_cpu(path[1].p_hdr->eh_entries) *
+		sizeof(struct ext4_extent_idx);
+	s += sizeof(struct ext4_extent_header);
+
+	memcpy(path[0].p_hdr, path[1].p_hdr, s);
+	path[0].p_depth = 0;
+	path[0].p_ext = EXT_FIRST_EXTENT(path[0].p_hdr) +
+		(path[1].p_ext - EXT_FIRST_EXTENT(path[1].p_hdr));
+	path[0].p_hdr->eh_max = cpu_to_le16(max_root);
+
+	brelse(path[1].p_bh);
+	ext4_free_blocks(handle, inode, NULL, blk, 1,
+			 EXT4_FREE_BLOCKS_METADATA | EXT4_FREE_BLOCKS_FORGET);
+}
+
+/*
  * This function tries to merge the @ex extent to neighbours in the tree.
  * return 1 if merge left else 0.
  */
-static int ext4_ext_try_to_merge(struct inode *inode,
+static void ext4_ext_try_to_merge(handle_t *handle,
+				  struct inode *inode,
 				  struct ext4_ext_path *path,
 				  struct ext4_extent *ex) {
 	struct ext4_extent_header *eh;
 	unsigned int depth;
 	int merge_done = 0;
-	int ret = 0;
 
 	depth = ext_depth(inode);
 	BUG_ON(path[depth].p_hdr == NULL);
@@ -1675,9 +1719,9 @@
 		merge_done = ext4_ext_try_to_merge_right(inode, path, ex - 1);
 
 	if (!merge_done)
-		ret = ext4_ext_try_to_merge_right(inode, path, ex);
+		(void) ext4_ext_try_to_merge_right(inode, path, ex);
 
-	return ret;
+	ext4_ext_try_to_merge_up(handle, inode, path);
 }
 
 /*
@@ -1893,7 +1937,7 @@
 merge:
 	/* try to merge extents */
 	if (!(flag & EXT4_GET_BLOCKS_PRE_IO))
-		ext4_ext_try_to_merge(inode, path, nearex);
+		ext4_ext_try_to_merge(handle, inode, path, nearex);
 
 
 	/* time to correct all indexes above */
@@ -1901,7 +1945,7 @@
 	if (err)
 		goto cleanup;
 
-	err = ext4_ext_dirty(handle, inode, path + depth);
+	err = ext4_ext_dirty(handle, inode, path + path->p_depth);
 
 cleanup:
 	if (npath) {
@@ -2092,13 +2136,10 @@
 }
 
 /*
- * ext4_ext_check_cache()
+ * ext4_ext_in_cache()
  * Checks to see if the given block is in the cache.
  * If it is, the cached extent is stored in the given
- * cache extent pointer.  If the cached extent is a hole,
- * this routine should be used instead of
- * ext4_ext_in_cache if the calling function needs to
- * know the size of the hole.
+ * cache extent pointer.
  *
  * @inode: The files inode
  * @block: The block to look for in the cache
@@ -2107,8 +2148,10 @@
  *
  * Return 0 if cache is invalid; 1 if the cache is valid
  */
-static int ext4_ext_check_cache(struct inode *inode, ext4_lblk_t block,
-	struct ext4_ext_cache *ex){
+static int
+ext4_ext_in_cache(struct inode *inode, ext4_lblk_t block,
+		  struct ext4_extent *ex)
+{
 	struct ext4_ext_cache *cex;
 	struct ext4_sb_info *sbi;
 	int ret = 0;
@@ -2125,7 +2168,9 @@
 		goto errout;
 
 	if (in_range(block, cex->ec_block, cex->ec_len)) {
-		memcpy(ex, cex, sizeof(struct ext4_ext_cache));
+		ex->ee_block = cpu_to_le32(cex->ec_block);
+		ext4_ext_store_pblock(ex, cex->ec_start);
+		ex->ee_len = cpu_to_le16(cex->ec_len);
 		ext_debug("%u cached by %u:%u:%llu\n",
 				block,
 				cex->ec_block, cex->ec_len, cex->ec_start);
@@ -2138,37 +2183,6 @@
 }
 
 /*
- * ext4_ext_in_cache()
- * Checks to see if the given block is in the cache.
- * If it is, the cached extent is stored in the given
- * extent pointer.
- *
- * @inode: The files inode
- * @block: The block to look for in the cache
- * @ex:    Pointer where the cached extent will be stored
- *         if it contains block
- *
- * Return 0 if cache is invalid; 1 if the cache is valid
- */
-static int
-ext4_ext_in_cache(struct inode *inode, ext4_lblk_t block,
-			struct ext4_extent *ex)
-{
-	struct ext4_ext_cache cex;
-	int ret = 0;
-
-	if (ext4_ext_check_cache(inode, block, &cex)) {
-		ex->ee_block = cpu_to_le32(cex.ec_block);
-		ext4_ext_store_pblock(ex, cex.ec_start);
-		ex->ee_len = cpu_to_le16(cex.ec_len);
-		ret = 1;
-	}
-
-	return ret;
-}
-
-
-/*
  * ext4_ext_rm_idx:
  * removes index from the index block.
  */
@@ -2274,10 +2288,13 @@
 	struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
 	unsigned short ee_len =  ext4_ext_get_actual_len(ex);
 	ext4_fsblk_t pblk;
-	int flags = EXT4_FREE_BLOCKS_FORGET;
+	int flags = 0;
 
 	if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
-		flags |= EXT4_FREE_BLOCKS_METADATA;
+		flags |= EXT4_FREE_BLOCKS_METADATA | EXT4_FREE_BLOCKS_FORGET;
+	else if (ext4_should_journal_data(inode))
+		flags |= EXT4_FREE_BLOCKS_FORGET;
+
 	/*
 	 * For bigalloc file systems, we never free a partial cluster
 	 * at the beginning of the extent.  Instead, we make a note
@@ -2572,7 +2589,7 @@
 	struct ext4_ext_path *path = NULL;
 	ext4_fsblk_t partial_cluster = 0;
 	handle_t *handle;
-	int i = 0, err;
+	int i = 0, err = 0;
 
 	ext_debug("truncate since %u to %u\n", start, end);
 
@@ -2604,12 +2621,16 @@
 			return PTR_ERR(path);
 		}
 		depth = ext_depth(inode);
+		/* Leaf not may not exist only if inode has no blocks at all */
 		ex = path[depth].p_ext;
 		if (!ex) {
-			ext4_ext_drop_refs(path);
-			kfree(path);
-			path = NULL;
-			goto cont;
+			if (depth) {
+				EXT4_ERROR_INODE(inode,
+						 "path[%d].p_hdr == NULL",
+						 depth);
+				err = -EIO;
+			}
+			goto out;
 		}
 
 		ee_block = le32_to_cpu(ex->ee_block);
@@ -2641,8 +2662,6 @@
 				goto out;
 		}
 	}
-cont:
-
 	/*
 	 * We start scanning from right side, freeing all the blocks
 	 * after i_size and walking into the tree depth-wise.
@@ -2924,9 +2943,9 @@
 			ext4_ext_mark_initialized(ex);
 
 		if (!(flags & EXT4_GET_BLOCKS_PRE_IO))
-			ext4_ext_try_to_merge(inode, path, ex);
+			ext4_ext_try_to_merge(handle, inode, path, ex);
 
-		err = ext4_ext_dirty(handle, inode, path + depth);
+		err = ext4_ext_dirty(handle, inode, path + path->p_depth);
 		goto out;
 	}
 
@@ -2958,8 +2977,8 @@
 			goto fix_extent_len;
 		/* update the extent length and mark as initialized */
 		ex->ee_len = cpu_to_le16(ee_len);
-		ext4_ext_try_to_merge(inode, path, ex);
-		err = ext4_ext_dirty(handle, inode, path + depth);
+		ext4_ext_try_to_merge(handle, inode, path, ex);
+		err = ext4_ext_dirty(handle, inode, path + path->p_depth);
 		goto out;
 	} else if (err)
 		goto fix_extent_len;
@@ -3041,7 +3060,6 @@
 	return err ? err : map->m_len;
 }
 
-#define EXT4_EXT_ZERO_LEN 7
 /*
  * This function is called by ext4_ext_map_blocks() if someone tries to write
  * to an uninitialized extent. It may result in splitting the uninitialized
@@ -3067,13 +3085,14 @@
 					   struct ext4_map_blocks *map,
 					   struct ext4_ext_path *path)
 {
+	struct ext4_sb_info *sbi;
 	struct ext4_extent_header *eh;
 	struct ext4_map_blocks split_map;
 	struct ext4_extent zero_ex;
 	struct ext4_extent *ex;
 	ext4_lblk_t ee_block, eof_block;
 	unsigned int ee_len, depth;
-	int allocated;
+	int allocated, max_zeroout = 0;
 	int err = 0;
 	int split_flag = 0;
 
@@ -3081,6 +3100,7 @@
 		"block %llu, max_blocks %u\n", inode->i_ino,
 		(unsigned long long)map->m_lblk, map->m_len);
 
+	sbi = EXT4_SB(inode->i_sb);
 	eof_block = (inode->i_size + inode->i_sb->s_blocksize - 1) >>
 		inode->i_sb->s_blocksize_bits;
 	if (eof_block < map->m_lblk + map->m_len)
@@ -3180,9 +3200,12 @@
 	 */
 	split_flag |= ee_block + ee_len <= eof_block ? EXT4_EXT_MAY_ZEROOUT : 0;
 
-	/* If extent has less than 2*EXT4_EXT_ZERO_LEN zerout directly */
-	if (ee_len <= 2*EXT4_EXT_ZERO_LEN &&
-	    (EXT4_EXT_MAY_ZEROOUT & split_flag)) {
+	if (EXT4_EXT_MAY_ZEROOUT & split_flag)
+		max_zeroout = sbi->s_extent_max_zeroout_kb >>
+			inode->i_sb->s_blocksize_bits;
+
+	/* If extent is less than s_max_zeroout_kb, zeroout directly */
+	if (max_zeroout && (ee_len <= max_zeroout)) {
 		err = ext4_ext_zeroout(inode, ex);
 		if (err)
 			goto out;
@@ -3191,8 +3214,8 @@
 		if (err)
 			goto out;
 		ext4_ext_mark_initialized(ex);
-		ext4_ext_try_to_merge(inode, path, ex);
-		err = ext4_ext_dirty(handle, inode, path + depth);
+		ext4_ext_try_to_merge(handle, inode, path, ex);
+		err = ext4_ext_dirty(handle, inode, path + path->p_depth);
 		goto out;
 	}
 
@@ -3206,9 +3229,8 @@
 	split_map.m_lblk = map->m_lblk;
 	split_map.m_len = map->m_len;
 
-	if (allocated > map->m_len) {
-		if (allocated <= EXT4_EXT_ZERO_LEN &&
-		    (EXT4_EXT_MAY_ZEROOUT & split_flag)) {
+	if (max_zeroout && (allocated > map->m_len)) {
+		if (allocated <= max_zeroout) {
 			/* case 3 */
 			zero_ex.ee_block =
 					 cpu_to_le32(map->m_lblk);
@@ -3220,9 +3242,7 @@
 				goto out;
 			split_map.m_lblk = map->m_lblk;
 			split_map.m_len = allocated;
-		} else if ((map->m_lblk - ee_block + map->m_len <
-			   EXT4_EXT_ZERO_LEN) &&
-			   (EXT4_EXT_MAY_ZEROOUT & split_flag)) {
+		} else if (map->m_lblk - ee_block + map->m_len < max_zeroout) {
 			/* case 2 */
 			if (map->m_lblk != ee_block) {
 				zero_ex.ee_block = ex->ee_block;
@@ -3242,7 +3262,7 @@
 	}
 
 	allocated = ext4_split_extent(handle, inode, path,
-				       &split_map, split_flag, 0);
+				      &split_map, split_flag, 0);
 	if (allocated < 0)
 		err = allocated;
 
@@ -3256,7 +3276,7 @@
  * to an uninitialized extent.
  *
  * Writing to an uninitialized extent may result in splitting the uninitialized
- * extent into multiple /initialized uninitialized extents (up to three)
+ * extent into multiple initialized/uninitialized extents (up to three)
  * There are three possibilities:
  *   a> There is no split required: Entire extent should be uninitialized
  *   b> Splits in two extents: Write is happening at either end of the extent
@@ -3333,10 +3353,10 @@
 	/* note: ext4_ext_correct_indexes() isn't needed here because
 	 * borders are not changed
 	 */
-	ext4_ext_try_to_merge(inode, path, ex);
+	ext4_ext_try_to_merge(handle, inode, path, ex);
 
 	/* Mark modified extent as dirty */
-	err = ext4_ext_dirty(handle, inode, path + depth);
+	err = ext4_ext_dirty(handle, inode, path + path->p_depth);
 out:
 	ext4_ext_show_leaf(inode, path);
 	return err;
@@ -3600,7 +3620,7 @@
 {
 	int ret = 0;
 	int err = 0;
-	ext4_io_end_t *io = EXT4_I(inode)->cur_aio_dio;
+	ext4_io_end_t *io = ext4_inode_aio(inode);
 
 	ext_debug("ext4_ext_handle_uninitialized_extents: inode %lu, logical "
 		  "block %llu, max_blocks %u, flags %x, allocated %u\n",
@@ -3615,6 +3635,8 @@
 	if ((flags & EXT4_GET_BLOCKS_PRE_IO)) {
 		ret = ext4_split_unwritten_extents(handle, inode, map,
 						   path, flags);
+		if (ret <= 0)
+			goto out;
 		/*
 		 * Flag the inode(non aio case) or end_io struct (aio case)
 		 * that this IO needs to conversion to written when IO is
@@ -3858,8 +3880,9 @@
 	unsigned int allocated = 0, offset = 0;
 	unsigned int allocated_clusters = 0;
 	struct ext4_allocation_request ar;
-	ext4_io_end_t *io = EXT4_I(inode)->cur_aio_dio;
+	ext4_io_end_t *io = ext4_inode_aio(inode);
 	ext4_lblk_t cluster_offset;
+	int set_unwritten = 0;
 
 	ext_debug("blocks %u/%u requested for inode %lu\n",
 		  map->m_lblk, map->m_len, inode->i_ino);
@@ -4082,13 +4105,8 @@
 		 * For non asycn direct IO case, flag the inode state
 		 * that we need to perform conversion when IO is done.
 		 */
-		if ((flags & EXT4_GET_BLOCKS_PRE_IO)) {
-			if (io)
-				ext4_set_io_unwritten_flag(inode, io);
-			else
-				ext4_set_inode_state(inode,
-						     EXT4_STATE_DIO_UNWRITTEN);
-		}
+		if ((flags & EXT4_GET_BLOCKS_PRE_IO))
+			set_unwritten = 1;
 		if (ext4_should_dioread_nolock(inode))
 			map->m_flags |= EXT4_MAP_UNINIT;
 	}
@@ -4100,6 +4118,15 @@
 	if (!err)
 		err = ext4_ext_insert_extent(handle, inode, path,
 					     &newex, flags);
+
+	if (!err && set_unwritten) {
+		if (io)
+			ext4_set_io_unwritten_flag(inode, io);
+		else
+			ext4_set_inode_state(inode,
+					     EXT4_STATE_DIO_UNWRITTEN);
+	}
+
 	if (err && free_on_err) {
 		int fb_flags = flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE ?
 			EXT4_FREE_BLOCKS_NO_QUOT_UPDATE : 0;
@@ -4241,7 +4268,7 @@
 	 * finish any pending end_io work so we won't run the risk of
 	 * converting any truncated blocks to initialized later
 	 */
-	ext4_flush_completed_IO(inode);
+	ext4_flush_unwritten_io(inode);
 
 	/*
 	 * probably first extent we're gonna free will be last in block
@@ -4769,9 +4796,32 @@
 	loff_t first_page_offset, last_page_offset;
 	int credits, err = 0;
 
+	/*
+	 * Write out all dirty pages to avoid race conditions
+	 * Then release them.
+	 */
+	if (mapping->nrpages && mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) {
+		err = filemap_write_and_wait_range(mapping,
+			offset, offset + length - 1);
+
+		if (err)
+			return err;
+	}
+
+	mutex_lock(&inode->i_mutex);
+	/* It's not possible punch hole on append only file */
+	if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) {
+		err = -EPERM;
+		goto out_mutex;
+	}
+	if (IS_SWAPFILE(inode)) {
+		err = -ETXTBSY;
+		goto out_mutex;
+	}
+
 	/* No need to punch hole beyond i_size */
 	if (offset >= inode->i_size)
-		return 0;
+		goto out_mutex;
 
 	/*
 	 * If the hole extends beyond i_size, set the hole
@@ -4789,35 +4839,26 @@
 	first_page_offset = first_page << PAGE_CACHE_SHIFT;
 	last_page_offset = last_page << PAGE_CACHE_SHIFT;
 
-	/*
-	 * Write out all dirty pages to avoid race conditions
-	 * Then release them.
-	 */
-	if (mapping->nrpages && mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) {
-		err = filemap_write_and_wait_range(mapping,
-			offset, offset + length - 1);
-
-		if (err)
-			return err;
-	}
-
 	/* Now release the pages */
 	if (last_page_offset > first_page_offset) {
 		truncate_pagecache_range(inode, first_page_offset,
 					 last_page_offset - 1);
 	}
 
-	/* finish any pending end_io work */
-	ext4_flush_completed_IO(inode);
+	/* Wait all existing dio workers, newcomers will block on i_mutex */
+	ext4_inode_block_unlocked_dio(inode);
+	err = ext4_flush_unwritten_io(inode);
+	if (err)
+		goto out_dio;
+	inode_dio_wait(inode);
 
 	credits = ext4_writepage_trans_blocks(inode);
 	handle = ext4_journal_start(inode, credits);
-	if (IS_ERR(handle))
-		return PTR_ERR(handle);
+	if (IS_ERR(handle)) {
+		err = PTR_ERR(handle);
+		goto out_dio;
+	}
 
-	err = ext4_orphan_add(handle, inode);
-	if (err)
-		goto out;
 
 	/*
 	 * Now we need to zero out the non-page-aligned data in the
@@ -4903,10 +4944,13 @@
 	up_write(&EXT4_I(inode)->i_data_sem);
 
 out:
-	ext4_orphan_del(handle, inode);
 	inode->i_mtime = inode->i_ctime = ext4_current_time(inode);
 	ext4_mark_inode_dirty(handle, inode);
 	ext4_journal_stop(handle);
+out_dio:
+	ext4_inode_resume_unlocked_dio(inode);
+out_mutex:
+	mutex_unlock(&inode->i_mutex);
 	return err;
 }
 int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 3b0e3bd..bf3966b 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -55,11 +55,11 @@
 	return 0;
 }
 
-static void ext4_aiodio_wait(struct inode *inode)
+void ext4_unwritten_wait(struct inode *inode)
 {
 	wait_queue_head_t *wq = ext4_ioend_wq(inode);
 
-	wait_event(*wq, (atomic_read(&EXT4_I(inode)->i_aiodio_unwritten) == 0));
+	wait_event(*wq, (atomic_read(&EXT4_I(inode)->i_unwritten) == 0));
 }
 
 /*
@@ -116,7 +116,7 @@
 				 "performance will be poor.",
 				 inode->i_ino, current->comm);
 		mutex_lock(ext4_aio_mutex(inode));
-		ext4_aiodio_wait(inode);
+		ext4_unwritten_wait(inode);
 	}
 
 	BUG_ON(iocb->ki_pos != pos);
@@ -207,6 +207,7 @@
 static const struct vm_operations_struct ext4_file_vm_ops = {
 	.fault		= filemap_fault,
 	.page_mkwrite   = ext4_page_mkwrite,
+	.remap_pages	= generic_file_remap_pages,
 };
 
 static int ext4_file_mmap(struct file *file, struct vm_area_struct *vma)
@@ -217,7 +218,6 @@
 		return -ENOEXEC;
 	file_accessed(file);
 	vma->vm_ops = &ext4_file_vm_ops;
-	vma->vm_flags |= VM_CAN_NONLINEAR;
 	return 0;
 }
 
diff --git a/fs/ext4/fsync.c b/fs/ext4/fsync.c
index 2a1dcea..be1d89f 100644
--- a/fs/ext4/fsync.c
+++ b/fs/ext4/fsync.c
@@ -34,87 +34,6 @@
 
 #include <trace/events/ext4.h>
 
-static void dump_completed_IO(struct inode * inode)
-{
-#ifdef	EXT4FS_DEBUG
-	struct list_head *cur, *before, *after;
-	ext4_io_end_t *io, *io0, *io1;
-	unsigned long flags;
-
-	if (list_empty(&EXT4_I(inode)->i_completed_io_list)){
-		ext4_debug("inode %lu completed_io list is empty\n", inode->i_ino);
-		return;
-	}
-
-	ext4_debug("Dump inode %lu completed_io list \n", inode->i_ino);
-	spin_lock_irqsave(&EXT4_I(inode)->i_completed_io_lock, flags);
-	list_for_each_entry(io, &EXT4_I(inode)->i_completed_io_list, list){
-		cur = &io->list;
-		before = cur->prev;
-		io0 = container_of(before, ext4_io_end_t, list);
-		after = cur->next;
-		io1 = container_of(after, ext4_io_end_t, list);
-
-		ext4_debug("io 0x%p from inode %lu,prev 0x%p,next 0x%p\n",
-			    io, inode->i_ino, io0, io1);
-	}
-	spin_unlock_irqrestore(&EXT4_I(inode)->i_completed_io_lock, flags);
-#endif
-}
-
-/*
- * This function is called from ext4_sync_file().
- *
- * When IO is completed, the work to convert unwritten extents to
- * written is queued on workqueue but may not get immediately
- * scheduled. When fsync is called, we need to ensure the
- * conversion is complete before fsync returns.
- * The inode keeps track of a list of pending/completed IO that
- * might needs to do the conversion. This function walks through
- * the list and convert the related unwritten extents for completed IO
- * to written.
- * The function return the number of pending IOs on success.
- */
-int ext4_flush_completed_IO(struct inode *inode)
-{
-	ext4_io_end_t *io;
-	struct ext4_inode_info *ei = EXT4_I(inode);
-	unsigned long flags;
-	int ret = 0;
-	int ret2 = 0;
-
-	dump_completed_IO(inode);
-	spin_lock_irqsave(&ei->i_completed_io_lock, flags);
-	while (!list_empty(&ei->i_completed_io_list)){
-		io = list_entry(ei->i_completed_io_list.next,
-				ext4_io_end_t, list);
-		list_del_init(&io->list);
-		io->flag |= EXT4_IO_END_IN_FSYNC;
-		/*
-		 * Calling ext4_end_io_nolock() to convert completed
-		 * IO to written.
-		 *
-		 * When ext4_sync_file() is called, run_queue() may already
-		 * about to flush the work corresponding to this io structure.
-		 * It will be upset if it founds the io structure related
-		 * to the work-to-be schedule is freed.
-		 *
-		 * Thus we need to keep the io structure still valid here after
-		 * conversion finished. The io structure has a flag to
-		 * avoid double converting from both fsync and background work
-		 * queue work.
-		 */
-		spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
-		ret = ext4_end_io_nolock(io);
-		if (ret < 0)
-			ret2 = ret;
-		spin_lock_irqsave(&ei->i_completed_io_lock, flags);
-		io->flag &= ~EXT4_IO_END_IN_FSYNC;
-	}
-	spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
-	return (ret2 < 0) ? ret2 : 0;
-}
-
 /*
  * If we're not journaling and this is a just-created file, we have to
  * sync our parent directory (if it was freshly created) since
@@ -203,7 +122,7 @@
 	struct inode *inode = file->f_mapping->host;
 	struct ext4_inode_info *ei = EXT4_I(inode);
 	journal_t *journal = EXT4_SB(inode->i_sb)->s_journal;
-	int ret;
+	int ret, err;
 	tid_t commit_tid;
 	bool needs_barrier = false;
 
@@ -219,7 +138,7 @@
 	if (inode->i_sb->s_flags & MS_RDONLY)
 		goto out;
 
-	ret = ext4_flush_completed_IO(inode);
+	ret = ext4_flush_unwritten_io(inode);
 	if (ret < 0)
 		goto out;
 
@@ -255,8 +174,11 @@
 		needs_barrier = true;
 	jbd2_log_start_commit(journal, commit_tid);
 	ret = jbd2_log_wait_commit(journal, commit_tid);
-	if (needs_barrier)
-		blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
+	if (needs_barrier) {
+		err = blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL, NULL);
+		if (!ret)
+			ret = err;
+	}
  out:
 	mutex_unlock(&inode->i_mutex);
 	trace_ext4_sync_file_exit(inode, ret);
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 26154b8..fa36372f 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -697,6 +697,15 @@
 		if (!gdp)
 			goto fail;
 
+		/*
+		 * Check free inodes count before loading bitmap.
+		 */
+		if (ext4_free_inodes_count(sb, gdp) == 0) {
+			if (++group == ngroups)
+				group = 0;
+			continue;
+		}
+
 		brelse(inode_bitmap_bh);
 		inode_bitmap_bh = ext4_read_inode_bitmap(sb, group);
 		if (!inode_bitmap_bh)
diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c
index 830e1b2..792e388 100644
--- a/fs/ext4/indirect.c
+++ b/fs/ext4/indirect.c
@@ -807,16 +807,30 @@
 
 retry:
 	if (rw == READ && ext4_should_dioread_nolock(inode)) {
-		if (unlikely(!list_empty(&ei->i_completed_io_list))) {
+		if (unlikely(atomic_read(&EXT4_I(inode)->i_unwritten))) {
 			mutex_lock(&inode->i_mutex);
-			ext4_flush_completed_IO(inode);
+			ext4_flush_unwritten_io(inode);
 			mutex_unlock(&inode->i_mutex);
 		}
+		/*
+		 * Nolock dioread optimization may be dynamically disabled
+		 * via ext4_inode_block_unlocked_dio(). Check inode's state
+		 * while holding extra i_dio_count ref.
+		 */
+		atomic_inc(&inode->i_dio_count);
+		smp_mb();
+		if (unlikely(ext4_test_inode_state(inode,
+						    EXT4_STATE_DIOREAD_LOCK))) {
+			inode_dio_done(inode);
+			goto locked;
+		}
 		ret = __blockdev_direct_IO(rw, iocb, inode,
 				 inode->i_sb->s_bdev, iov,
 				 offset, nr_segs,
 				 ext4_get_block, NULL, NULL, 0);
+		inode_dio_done(inode);
 	} else {
+locked:
 		ret = blockdev_direct_IO(rw, iocb, inode, iov,
 				 offset, nr_segs, ext4_get_block);
 
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index c862ee5..b3c243b 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -732,11 +732,13 @@
 	err = ext4_map_blocks(handle, inode, &map,
 			      create ? EXT4_GET_BLOCKS_CREATE : 0);
 
+	/* ensure we send some value back into *errp */
+	*errp = 0;
+
 	if (err < 0)
 		*errp = err;
 	if (err <= 0)
 		return NULL;
-	*errp = 0;
 
 	bh = sb_getblk(inode->i_sb, map.m_pblk);
 	if (!bh) {
@@ -1954,9 +1956,6 @@
 	return ret;
 }
 
-static int ext4_set_bh_endio(struct buffer_head *bh, struct inode *inode);
-static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate);
-
 /*
  * Note that we don't need to start a transaction unless we're journaling data
  * because we should have holes filled from ext4_page_mkwrite(). We even don't
@@ -2463,6 +2462,16 @@
 	free_blocks  = EXT4_C2B(sbi,
 		percpu_counter_read_positive(&sbi->s_freeclusters_counter));
 	dirty_blocks = percpu_counter_read_positive(&sbi->s_dirtyclusters_counter);
+	/*
+	 * Start pushing delalloc when 1/2 of free blocks are dirty.
+	 */
+	if (dirty_blocks && (free_blocks < 2 * dirty_blocks) &&
+	    !writeback_in_progress(sb->s_bdi) &&
+	    down_read_trylock(&sb->s_umount)) {
+		writeback_inodes_sb(sb, WB_REASON_FS_FREE_SPACE);
+		up_read(&sb->s_umount);
+	}
+
 	if (2 * free_blocks < 3 * dirty_blocks ||
 		free_blocks < (dirty_blocks + EXT4_FREECLUSTERS_WATERMARK)) {
 		/*
@@ -2471,13 +2480,6 @@
 		 */
 		return 1;
 	}
-	/*
-	 * Even if we don't switch but are nearing capacity,
-	 * start pushing delalloc when 1/2 of free blocks are dirty.
-	 */
-	if (free_blocks < 2 * dirty_blocks)
-		writeback_inodes_sb_if_idle(sb, WB_REASON_FS_FREE_SPACE);
-
 	return 0;
 }
 
@@ -2879,9 +2881,6 @@
 {
 	struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode;
         ext4_io_end_t *io_end = iocb->private;
-	struct workqueue_struct *wq;
-	unsigned long flags;
-	struct ext4_inode_info *ei;
 
 	/* if not async direct IO or dio with 0 bytes write, just return */
 	if (!io_end || !size)
@@ -2910,24 +2909,14 @@
 		io_end->iocb = iocb;
 		io_end->result = ret;
 	}
-	wq = EXT4_SB(io_end->inode->i_sb)->dio_unwritten_wq;
 
-	/* Add the io_end to per-inode completed aio dio list*/
-	ei = EXT4_I(io_end->inode);
-	spin_lock_irqsave(&ei->i_completed_io_lock, flags);
-	list_add_tail(&io_end->list, &ei->i_completed_io_list);
-	spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
-
-	/* queue the work to convert unwritten extents to written */
-	queue_work(wq, &io_end->work);
+	ext4_add_complete_io(io_end);
 }
 
 static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate)
 {
 	ext4_io_end_t *io_end = bh->b_private;
-	struct workqueue_struct *wq;
 	struct inode *inode;
-	unsigned long flags;
 
 	if (!test_clear_buffer_uninit(bh) || !io_end)
 		goto out;
@@ -2946,15 +2935,7 @@
 	 */
 	inode = io_end->inode;
 	ext4_set_io_unwritten_flag(inode, io_end);
-
-	/* Add the io_end to per-inode completed io list*/
-	spin_lock_irqsave(&EXT4_I(inode)->i_completed_io_lock, flags);
-	list_add_tail(&io_end->list, &EXT4_I(inode)->i_completed_io_list);
-	spin_unlock_irqrestore(&EXT4_I(inode)->i_completed_io_lock, flags);
-
-	wq = EXT4_SB(inode->i_sb)->dio_unwritten_wq;
-	/* queue the work to convert unwritten extents to written */
-	queue_work(wq, &io_end->work);
+	ext4_add_complete_io(io_end);
 out:
 	bh->b_private = NULL;
 	bh->b_end_io = NULL;
@@ -3029,6 +3010,7 @@
 		overwrite = *((int *)iocb->private);
 
 		if (overwrite) {
+			atomic_inc(&inode->i_dio_count);
 			down_read(&EXT4_I(inode)->i_data_sem);
 			mutex_unlock(&inode->i_mutex);
 		}
@@ -3054,7 +3036,7 @@
 		 * hook to the iocb.
  		 */
 		iocb->private = NULL;
-		EXT4_I(inode)->cur_aio_dio = NULL;
+		ext4_inode_aio_set(inode, NULL);
 		if (!is_sync_kiocb(iocb)) {
 			ext4_io_end_t *io_end =
 				ext4_init_io_end(inode, GFP_NOFS);
@@ -3071,7 +3053,7 @@
 			 * is a unwritten extents needs to be converted
 			 * when IO is completed.
 			 */
-			EXT4_I(inode)->cur_aio_dio = iocb->private;
+			ext4_inode_aio_set(inode, io_end);
 		}
 
 		if (overwrite)
@@ -3091,7 +3073,7 @@
 						 NULL,
 						 DIO_LOCKING);
 		if (iocb->private)
-			EXT4_I(inode)->cur_aio_dio = NULL;
+			ext4_inode_aio_set(inode, NULL);
 		/*
 		 * The io_end structure takes a reference to the inode,
 		 * that structure needs to be destroyed and the
@@ -3126,6 +3108,7 @@
 	retake_lock:
 		/* take i_mutex locking again if we do a ovewrite dio */
 		if (overwrite) {
+			inode_dio_done(inode);
 			up_read(&EXT4_I(inode)->i_data_sem);
 			mutex_lock(&inode->i_mutex);
 		}
@@ -4052,6 +4035,7 @@
 	struct ext4_inode_info *ei = EXT4_I(inode);
 	struct buffer_head *bh = iloc->bh;
 	int err = 0, rc, block;
+	int need_datasync = 0;
 	uid_t i_uid;
 	gid_t i_gid;
 
@@ -4102,7 +4086,10 @@
 		raw_inode->i_file_acl_high =
 			cpu_to_le16(ei->i_file_acl >> 32);
 	raw_inode->i_file_acl_lo = cpu_to_le32(ei->i_file_acl);
-	ext4_isize_set(raw_inode, ei->i_disksize);
+	if (ei->i_disksize != ext4_isize(raw_inode)) {
+		ext4_isize_set(raw_inode, ei->i_disksize);
+		need_datasync = 1;
+	}
 	if (ei->i_disksize > 0x7fffffffULL) {
 		struct super_block *sb = inode->i_sb;
 		if (!EXT4_HAS_RO_COMPAT_FEATURE(sb,
@@ -4155,7 +4142,7 @@
 		err = rc;
 	ext4_clear_inode_state(inode, EXT4_STATE_NEW);
 
-	ext4_update_inode_fsync_trans(handle, inode, 0);
+	ext4_update_inode_fsync_trans(handle, inode, need_datasync);
 out_brelse:
 	brelse(bh);
 	ext4_std_error(inode->i_sb, err);
@@ -4298,7 +4285,6 @@
 	}
 
 	if (attr->ia_valid & ATTR_SIZE) {
-		inode_dio_wait(inode);
 
 		if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
 			struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
@@ -4347,8 +4333,17 @@
 	}
 
 	if (attr->ia_valid & ATTR_SIZE) {
-		if (attr->ia_size != i_size_read(inode))
+		if (attr->ia_size != i_size_read(inode)) {
 			truncate_setsize(inode, attr->ia_size);
+			/* Inode size will be reduced, wait for dio in flight.
+			 * Temporarily disable dioread_nolock to prevent
+			 * livelock. */
+			if (orphan) {
+				ext4_inode_block_unlocked_dio(inode);
+				inode_dio_wait(inode);
+				ext4_inode_resume_unlocked_dio(inode);
+			}
+		}
 		ext4_truncate(inode);
 	}
 
@@ -4727,6 +4722,10 @@
 			return err;
 	}
 
+	/* Wait for all existing dio workers */
+	ext4_inode_block_unlocked_dio(inode);
+	inode_dio_wait(inode);
+
 	jbd2_journal_lock_updates(journal);
 
 	/*
@@ -4746,6 +4745,7 @@
 	ext4_set_aops(inode);
 
 	jbd2_journal_unlock_updates(journal);
+	ext4_inode_resume_unlocked_dio(inode);
 
 	/* Finally we can mark the inode as dirty. */
 
@@ -4780,6 +4780,7 @@
 	int retries = 0;
 
 	sb_start_pagefault(inode->i_sb);
+	file_update_time(vma->vm_file);
 	/* Delalloc case is easy... */
 	if (test_opt(inode->i_sb, DELALLOC) &&
 	    !ext4_should_journal_data(inode) &&
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index 5439d6a..5747f52 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -366,26 +366,11 @@
 			return -EOPNOTSUPP;
 		}
 
-		if (EXT4_HAS_INCOMPAT_FEATURE(sb,
-			       EXT4_FEATURE_INCOMPAT_META_BG)) {
-			ext4_msg(sb, KERN_ERR,
-				 "Online resizing not (yet) supported with meta_bg");
-			return -EOPNOTSUPP;
-		}
-
 		if (copy_from_user(&n_blocks_count, (__u64 __user *)arg,
 				   sizeof(__u64))) {
 			return -EFAULT;
 		}
 
-		if (n_blocks_count > MAX_32_NUM &&
-		    !EXT4_HAS_INCOMPAT_FEATURE(sb,
-					       EXT4_FEATURE_INCOMPAT_64BIT)) {
-			ext4_msg(sb, KERN_ERR,
-				 "File system only supports 32-bit block numbers");
-			return -EOPNOTSUPP;
-		}
-
 		err = ext4_resize_begin(sb);
 		if (err)
 			return err;
@@ -420,13 +405,6 @@
 		if (!blk_queue_discard(q))
 			return -EOPNOTSUPP;
 
-		if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
-			       EXT4_FEATURE_RO_COMPAT_BIGALLOC)) {
-			ext4_msg(sb, KERN_ERR,
-				 "FITRIM not supported with bigalloc");
-			return -EOPNOTSUPP;
-		}
-
 		if (copy_from_user(&range, (struct fstrim_range __user *)arg,
 		    sizeof(range)))
 			return -EFAULT;
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 08778f6..f8b27bf 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -24,6 +24,7 @@
 #include "ext4_jbd2.h"
 #include "mballoc.h"
 #include <linux/debugfs.h>
+#include <linux/log2.h>
 #include <linux/slab.h>
 #include <trace/events/ext4.h>
 
@@ -1338,17 +1339,17 @@
 	mb_check_buddy(e4b);
 }
 
-static int mb_find_extent(struct ext4_buddy *e4b, int order, int block,
+static int mb_find_extent(struct ext4_buddy *e4b, int block,
 				int needed, struct ext4_free_extent *ex)
 {
 	int next = block;
-	int max;
+	int max, order;
 	void *buddy;
 
 	assert_spin_locked(ext4_group_lock_ptr(e4b->bd_sb, e4b->bd_group));
 	BUG_ON(ex == NULL);
 
-	buddy = mb_find_buddy(e4b, order, &max);
+	buddy = mb_find_buddy(e4b, 0, &max);
 	BUG_ON(buddy == NULL);
 	BUG_ON(block >= max);
 	if (mb_test_bit(block, buddy)) {
@@ -1358,12 +1359,9 @@
 		return 0;
 	}
 
-	/* FIXME dorp order completely ? */
-	if (likely(order == 0)) {
-		/* find actual order */
-		order = mb_find_order_for_block(e4b, block);
-		block = block >> order;
-	}
+	/* find actual order */
+	order = mb_find_order_for_block(e4b, block);
+	block = block >> order;
 
 	ex->fe_len = 1 << order;
 	ex->fe_start = block << order;
@@ -1549,7 +1547,7 @@
 		/* recheck chunk's availability - we don't know
 		 * when it was found (within this lock-unlock
 		 * period or not) */
-		max = mb_find_extent(e4b, 0, bex->fe_start, gex->fe_len, &ex);
+		max = mb_find_extent(e4b, bex->fe_start, gex->fe_len, &ex);
 		if (max >= gex->fe_len) {
 			ext4_mb_use_best_found(ac, e4b);
 			return;
@@ -1641,7 +1639,7 @@
 		return err;
 
 	ext4_lock_group(ac->ac_sb, group);
-	max = mb_find_extent(e4b, 0, ex.fe_start, ex.fe_len, &ex);
+	max = mb_find_extent(e4b, ex.fe_start, ex.fe_len, &ex);
 
 	if (max > 0) {
 		ac->ac_b_ex = ex;
@@ -1662,17 +1660,20 @@
 	int max;
 	int err;
 	struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
+	struct ext4_group_info *grp = ext4_get_group_info(ac->ac_sb, group);
 	struct ext4_free_extent ex;
 
 	if (!(ac->ac_flags & EXT4_MB_HINT_TRY_GOAL))
 		return 0;
+	if (grp->bb_free == 0)
+		return 0;
 
 	err = ext4_mb_load_buddy(ac->ac_sb, group, e4b);
 	if (err)
 		return err;
 
 	ext4_lock_group(ac->ac_sb, group);
-	max = mb_find_extent(e4b, 0, ac->ac_g_ex.fe_start,
+	max = mb_find_extent(e4b, ac->ac_g_ex.fe_start,
 			     ac->ac_g_ex.fe_len, &ex);
 
 	if (max >= ac->ac_g_ex.fe_len && ac->ac_g_ex.fe_len == sbi->s_stripe) {
@@ -1788,7 +1789,7 @@
 			break;
 		}
 
-		mb_find_extent(e4b, 0, i, ac->ac_g_ex.fe_len, &ex);
+		mb_find_extent(e4b, i, ac->ac_g_ex.fe_len, &ex);
 		BUG_ON(ex.fe_len <= 0);
 		if (free < ex.fe_len) {
 			ext4_grp_locked_error(sb, e4b->bd_group, 0, 0,
@@ -1840,7 +1841,7 @@
 
 	while (i < EXT4_CLUSTERS_PER_GROUP(sb)) {
 		if (!mb_test_bit(i, bitmap)) {
-			max = mb_find_extent(e4b, 0, i, sbi->s_stripe, &ex);
+			max = mb_find_extent(e4b, i, sbi->s_stripe, &ex);
 			if (max >= sbi->s_stripe) {
 				ac->ac_found++;
 				ac->ac_b_ex = ex;
@@ -1862,6 +1863,12 @@
 
 	BUG_ON(cr < 0 || cr >= 4);
 
+	free = grp->bb_free;
+	if (free == 0)
+		return 0;
+	if (cr <= 2 && free < ac->ac_g_ex.fe_len)
+		return 0;
+
 	/* We only do this if the grp has never been initialized */
 	if (unlikely(EXT4_MB_GRP_NEED_INIT(grp))) {
 		int ret = ext4_mb_init_group(ac->ac_sb, group);
@@ -1869,10 +1876,7 @@
 			return 0;
 	}
 
-	free = grp->bb_free;
 	fragments = grp->bb_fragments;
-	if (free == 0)
-		return 0;
 	if (fragments == 0)
 		return 0;
 
@@ -2163,6 +2167,39 @@
 	return cachep;
 }
 
+/*
+ * Allocate the top-level s_group_info array for the specified number
+ * of groups
+ */
+int ext4_mb_alloc_groupinfo(struct super_block *sb, ext4_group_t ngroups)
+{
+	struct ext4_sb_info *sbi = EXT4_SB(sb);
+	unsigned size;
+	struct ext4_group_info ***new_groupinfo;
+
+	size = (ngroups + EXT4_DESC_PER_BLOCK(sb) - 1) >>
+		EXT4_DESC_PER_BLOCK_BITS(sb);
+	if (size <= sbi->s_group_info_size)
+		return 0;
+
+	size = roundup_pow_of_two(sizeof(*sbi->s_group_info) * size);
+	new_groupinfo = ext4_kvzalloc(size, GFP_KERNEL);
+	if (!new_groupinfo) {
+		ext4_msg(sb, KERN_ERR, "can't allocate buddy meta group");
+		return -ENOMEM;
+	}
+	if (sbi->s_group_info) {
+		memcpy(new_groupinfo, sbi->s_group_info,
+		       sbi->s_group_info_size * sizeof(*sbi->s_group_info));
+		ext4_kvfree(sbi->s_group_info);
+	}
+	sbi->s_group_info = new_groupinfo;
+	sbi->s_group_info_size = size / sizeof(*sbi->s_group_info);
+	ext4_debug("allocated s_groupinfo array for %d meta_bg's\n", 
+		   sbi->s_group_info_size);
+	return 0;
+}
+
 /* Create and initialize ext4_group_info data for the given group. */
 int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group,
 			  struct ext4_group_desc *desc)
@@ -2195,12 +2232,11 @@
 		sbi->s_group_info[group >> EXT4_DESC_PER_BLOCK_BITS(sb)];
 	i = group & (EXT4_DESC_PER_BLOCK(sb) - 1);
 
-	meta_group_info[i] = kmem_cache_alloc(cachep, GFP_KERNEL);
+	meta_group_info[i] = kmem_cache_zalloc(cachep, GFP_KERNEL);
 	if (meta_group_info[i] == NULL) {
 		ext4_msg(sb, KERN_ERR, "can't allocate buddy mem");
 		goto exit_group_info;
 	}
-	memset(meta_group_info[i], 0, kmem_cache_size(cachep));
 	set_bit(EXT4_GROUP_INFO_NEED_INIT_BIT,
 		&(meta_group_info[i]->bb_state));
 
@@ -2252,49 +2288,14 @@
 	ext4_group_t ngroups = ext4_get_groups_count(sb);
 	ext4_group_t i;
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
-	struct ext4_super_block *es = sbi->s_es;
-	int num_meta_group_infos;
-	int num_meta_group_infos_max;
-	int array_size;
+	int err;
 	struct ext4_group_desc *desc;
 	struct kmem_cache *cachep;
 
-	/* This is the number of blocks used by GDT */
-	num_meta_group_infos = (ngroups + EXT4_DESC_PER_BLOCK(sb) -
-				1) >> EXT4_DESC_PER_BLOCK_BITS(sb);
+	err = ext4_mb_alloc_groupinfo(sb, ngroups);
+	if (err)
+		return err;
 
-	/*
-	 * This is the total number of blocks used by GDT including
-	 * the number of reserved blocks for GDT.
-	 * The s_group_info array is allocated with this value
-	 * to allow a clean online resize without a complex
-	 * manipulation of pointer.
-	 * The drawback is the unused memory when no resize
-	 * occurs but it's very low in terms of pages
-	 * (see comments below)
-	 * Need to handle this properly when META_BG resizing is allowed
-	 */
-	num_meta_group_infos_max = num_meta_group_infos +
-				le16_to_cpu(es->s_reserved_gdt_blocks);
-
-	/*
-	 * array_size is the size of s_group_info array. We round it
-	 * to the next power of two because this approximation is done
-	 * internally by kmalloc so we can have some more memory
-	 * for free here (e.g. may be used for META_BG resize).
-	 */
-	array_size = 1;
-	while (array_size < sizeof(*sbi->s_group_info) *
-	       num_meta_group_infos_max)
-		array_size = array_size << 1;
-	/* An 8TB filesystem with 64-bit pointers requires a 4096 byte
-	 * kmalloc. A 128kb malloc should suffice for a 256TB filesystem.
-	 * So a two level scheme suffices for now. */
-	sbi->s_group_info = ext4_kvzalloc(array_size, GFP_KERNEL);
-	if (sbi->s_group_info == NULL) {
-		ext4_msg(sb, KERN_ERR, "can't allocate buddy meta group");
-		return -ENOMEM;
-	}
 	sbi->s_buddy_cache = new_inode(sb);
 	if (sbi->s_buddy_cache == NULL) {
 		ext4_msg(sb, KERN_ERR, "can't get new inode");
@@ -2322,7 +2323,7 @@
 	cachep = get_groupinfo_cache(sb->s_blocksize_bits);
 	while (i-- > 0)
 		kmem_cache_free(cachep, ext4_get_group_info(sb, i));
-	i = num_meta_group_infos;
+	i = sbi->s_group_info_size;
 	while (i-- > 0)
 		kfree(sbi->s_group_info[i]);
 	iput(sbi->s_buddy_cache);
@@ -4008,7 +4009,6 @@
 	ext4_get_group_no_and_offset(sb, goal, &group, &block);
 
 	/* set up allocation goals */
-	memset(ac, 0, sizeof(struct ext4_allocation_context));
 	ac->ac_b_ex.fe_logical = ar->logical & ~(sbi->s_cluster_ratio - 1);
 	ac->ac_status = AC_STATUS_CONTINUE;
 	ac->ac_sb = sb;
@@ -4291,7 +4291,7 @@
 		}
 	}
 
-	ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS);
+	ac = kmem_cache_zalloc(ext4_ac_cachep, GFP_NOFS);
 	if (!ac) {
 		ar->len = 0;
 		*errp = -ENOMEM;
@@ -4657,6 +4657,8 @@
 		 * with group lock held. generate_buddy look at
 		 * them with group lock_held
 		 */
+		if (test_opt(sb, DISCARD))
+			ext4_issue_discard(sb, block_group, bit, count);
 		ext4_lock_group(sb, block_group);
 		mb_clear_bits(bitmap_bh->b_data, bit, count_clusters);
 		mb_free_blocks(inode, &e4b, bit, count_clusters);
@@ -4988,7 +4990,8 @@
 
 	start = range->start >> sb->s_blocksize_bits;
 	end = start + (range->len >> sb->s_blocksize_bits) - 1;
-	minlen = range->minlen >> sb->s_blocksize_bits;
+	minlen = EXT4_NUM_B2C(EXT4_SB(sb),
+			      range->minlen >> sb->s_blocksize_bits);
 
 	if (unlikely(minlen > EXT4_CLUSTERS_PER_GROUP(sb)) ||
 	    unlikely(start >= max_blks))
@@ -5048,6 +5051,6 @@
 		atomic_set(&EXT4_SB(sb)->s_last_trim_minblks, minlen);
 
 out:
-	range->len = trimmed * sb->s_blocksize;
+	range->len = EXT4_C2B(EXT4_SB(sb), trimmed) << sb->s_blocksize_bits;
 	return ret;
 }
diff --git a/fs/ext4/mballoc.h b/fs/ext4/mballoc.h
index c070618..3ccd889 100644
--- a/fs/ext4/mballoc.h
+++ b/fs/ext4/mballoc.h
@@ -65,11 +65,6 @@
 #define MB_DEFAULT_MIN_TO_SCAN		10
 
 /*
- * How many groups mballoc will scan looking for the best chunk
- */
-#define MB_DEFAULT_MAX_GROUPS_TO_SCAN	5
-
-/*
  * with 'ext4_mb_stats' allocator will collect stats that will be
  * shown at umount. The collecting costs though!
  */
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index c5826c6..292daee 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -141,55 +141,21 @@
 }
 
 /**
- * mext_check_null_inode - NULL check for two inodes
- *
- * If inode1 or inode2 is NULL, return -EIO. Otherwise, return 0.
- */
-static int
-mext_check_null_inode(struct inode *inode1, struct inode *inode2,
-		      const char *function, unsigned int line)
-{
-	int ret = 0;
-
-	if (inode1 == NULL) {
-		__ext4_error(inode2->i_sb, function, line,
-			"Both inodes should not be NULL: "
-			"inode1 NULL inode2 %lu", inode2->i_ino);
-		ret = -EIO;
-	} else if (inode2 == NULL) {
-		__ext4_error(inode1->i_sb, function, line,
-			"Both inodes should not be NULL: "
-			"inode1 %lu inode2 NULL", inode1->i_ino);
-		ret = -EIO;
-	}
-	return ret;
-}
-
-/**
  * double_down_write_data_sem - Acquire two inodes' write lock of i_data_sem
  *
- * @orig_inode:		original inode structure
- * @donor_inode:	donor inode structure
- * Acquire write lock of i_data_sem of the two inodes (orig and donor) by
- * i_ino order.
+ * Acquire write lock of i_data_sem of the two inodes
  */
 static void
-double_down_write_data_sem(struct inode *orig_inode, struct inode *donor_inode)
+double_down_write_data_sem(struct inode *first, struct inode *second)
 {
-	struct inode *first = orig_inode, *second = donor_inode;
+	if (first < second) {
+		down_write(&EXT4_I(first)->i_data_sem);
+		down_write_nested(&EXT4_I(second)->i_data_sem, SINGLE_DEPTH_NESTING);
+	} else {
+		down_write(&EXT4_I(second)->i_data_sem);
+		down_write_nested(&EXT4_I(first)->i_data_sem, SINGLE_DEPTH_NESTING);
 
-	/*
-	 * Use the inode number to provide the stable locking order instead
-	 * of its address, because the C language doesn't guarantee you can
-	 * compare pointers that don't come from the same array.
-	 */
-	if (donor_inode->i_ino < orig_inode->i_ino) {
-		first = donor_inode;
-		second = orig_inode;
 	}
-
-	down_write(&EXT4_I(first)->i_data_sem);
-	down_write_nested(&EXT4_I(second)->i_data_sem, SINGLE_DEPTH_NESTING);
 }
 
 /**
@@ -604,9 +570,8 @@
 	diff = donor_off - le32_to_cpu(tmp_dext->ee_block);
 
 	ext4_ext_store_pblock(tmp_dext, ext4_ext_pblock(tmp_dext) + diff);
-	tmp_dext->ee_block =
-			cpu_to_le32(le32_to_cpu(tmp_dext->ee_block) + diff);
-	tmp_dext->ee_len = cpu_to_le16(le16_to_cpu(tmp_dext->ee_len) - diff);
+	le32_add_cpu(&tmp_dext->ee_block, diff);
+	le16_add_cpu(&tmp_dext->ee_len, -diff);
 
 	if (max_count < ext4_ext_get_actual_len(tmp_dext))
 		tmp_dext->ee_len = cpu_to_le16(max_count);
@@ -629,6 +594,43 @@
 }
 
 /**
+ * mext_check_coverage - Check that all extents in range has the same type
+ *
+ * @inode:		inode in question
+ * @from:		block offset of inode
+ * @count:		block count to be checked
+ * @uninit:		extents expected to be uninitialized
+ * @err:		pointer to save error value
+ *
+ * Return 1 if all extents in range has expected type, and zero otherwise.
+ */
+static int
+mext_check_coverage(struct inode *inode, ext4_lblk_t from, ext4_lblk_t count,
+			  int uninit, int *err)
+{
+	struct ext4_ext_path *path = NULL;
+	struct ext4_extent *ext;
+	ext4_lblk_t last = from + count;
+	while (from < last) {
+		*err = get_ext_path(inode, from, &path);
+		if (*err)
+			return 0;
+		ext = path[ext_depth(inode)].p_ext;
+		if (!ext) {
+			ext4_ext_drop_refs(path);
+			return 0;
+		}
+		if (uninit != ext4_ext_is_uninitialized(ext)) {
+			ext4_ext_drop_refs(path);
+			return 0;
+		}
+		from += ext4_ext_get_actual_len(ext);
+		ext4_ext_drop_refs(path);
+	}
+	return 1;
+}
+
+/**
  * mext_replace_branches - Replace original extents with new extents
  *
  * @handle:		journal handle
@@ -663,9 +665,6 @@
 	int replaced_count = 0;
 	int dext_alen;
 
-	/* Protect extent trees against block allocations via delalloc */
-	double_down_write_data_sem(orig_inode, donor_inode);
-
 	/* Get the original extent for the block "orig_off" */
 	*err = get_ext_path(orig_inode, orig_off, &orig_path);
 	if (*err)
@@ -764,12 +763,122 @@
 	ext4_ext_invalidate_cache(orig_inode);
 	ext4_ext_invalidate_cache(donor_inode);
 
-	double_up_write_data_sem(orig_inode, donor_inode);
-
 	return replaced_count;
 }
 
 /**
+ * mext_page_double_lock - Grab and lock pages on both @inode1 and @inode2
+ *
+ * @inode1:	the inode structure
+ * @inode2:	the inode structure
+ * @index:	page index
+ * @page:	result page vector
+ *
+ * Grab two locked pages for inode's by inode order
+ */
+static int
+mext_page_double_lock(struct inode *inode1, struct inode *inode2,
+		      pgoff_t index, struct page *page[2])
+{
+	struct address_space *mapping[2];
+	unsigned fl = AOP_FLAG_NOFS;
+
+	BUG_ON(!inode1 || !inode2);
+	if (inode1 < inode2) {
+		mapping[0] = inode1->i_mapping;
+		mapping[1] = inode2->i_mapping;
+	} else {
+		mapping[0] = inode2->i_mapping;
+		mapping[1] = inode1->i_mapping;
+	}
+
+	page[0] = grab_cache_page_write_begin(mapping[0], index, fl);
+	if (!page[0])
+		return -ENOMEM;
+
+	page[1] = grab_cache_page_write_begin(mapping[1], index, fl);
+	if (!page[1]) {
+		unlock_page(page[0]);
+		page_cache_release(page[0]);
+		return -ENOMEM;
+	}
+
+	if (inode1 > inode2) {
+		struct page *tmp;
+		tmp = page[0];
+		page[0] = page[1];
+		page[1] = tmp;
+	}
+	return 0;
+}
+
+/* Force page buffers uptodate w/o dropping page's lock */
+static int
+mext_page_mkuptodate(struct page *page, unsigned from, unsigned to)
+{
+	struct inode *inode = page->mapping->host;
+	sector_t block;
+	struct buffer_head *bh, *head, *arr[MAX_BUF_PER_PAGE];
+	unsigned int blocksize, block_start, block_end;
+	int i, err,  nr = 0, partial = 0;
+	BUG_ON(!PageLocked(page));
+	BUG_ON(PageWriteback(page));
+
+	if (PageUptodate(page))
+		return 0;
+
+	blocksize = 1 << inode->i_blkbits;
+	if (!page_has_buffers(page))
+		create_empty_buffers(page, blocksize, 0);
+
+	head = page_buffers(page);
+	block = (sector_t)page->index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
+	for (bh = head, block_start = 0; bh != head || !block_start;
+	     block++, block_start = block_end, bh = bh->b_this_page) {
+		block_end = block_start + blocksize;
+		if (block_end <= from || block_start >= to) {
+			if (!buffer_uptodate(bh))
+				partial = 1;
+			continue;
+		}
+		if (buffer_uptodate(bh))
+			continue;
+		if (!buffer_mapped(bh)) {
+			int err = 0;
+			err = ext4_get_block(inode, block, bh, 0);
+			if (err) {
+				SetPageError(page);
+				return err;
+			}
+			if (!buffer_mapped(bh)) {
+				zero_user(page, block_start, blocksize);
+				if (!err)
+					set_buffer_uptodate(bh);
+				continue;
+			}
+		}
+		BUG_ON(nr >= MAX_BUF_PER_PAGE);
+		arr[nr++] = bh;
+	}
+	/* No io required */
+	if (!nr)
+		goto out;
+
+	for (i = 0; i < nr; i++) {
+		bh = arr[i];
+		if (!bh_uptodate_or_lock(bh)) {
+			err = bh_submit_read(bh);
+			if (err)
+				return err;
+		}
+	}
+out:
+	if (!partial)
+		SetPageUptodate(page);
+	return 0;
+}
+
+/**
  * move_extent_per_page - Move extent data per page
  *
  * @o_filp:			file structure of original file
@@ -791,26 +900,24 @@
 		  int block_len_in_page, int uninit, int *err)
 {
 	struct inode *orig_inode = o_filp->f_dentry->d_inode;
-	struct address_space *mapping = orig_inode->i_mapping;
-	struct buffer_head *bh;
-	struct page *page = NULL;
-	const struct address_space_operations *a_ops = mapping->a_ops;
+	struct page *pagep[2] = {NULL, NULL};
 	handle_t *handle;
 	ext4_lblk_t orig_blk_offset;
 	long long offs = orig_page_offset << PAGE_CACHE_SHIFT;
 	unsigned long blocksize = orig_inode->i_sb->s_blocksize;
 	unsigned int w_flags = 0;
 	unsigned int tmp_data_size, data_size, replaced_size;
-	void *fsdata;
-	int i, jblocks;
-	int err2 = 0;
+	int err2, jblocks, retries = 0;
 	int replaced_count = 0;
+	int from = data_offset_in_page << orig_inode->i_blkbits;
 	int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits;
 
 	/*
 	 * It needs twice the amount of ordinary journal buffers because
 	 * inode and donor_inode may change each different metadata blocks.
 	 */
+again:
+	*err = 0;
 	jblocks = ext4_writepage_trans_blocks(orig_inode) * 2;
 	handle = ext4_journal_start(orig_inode, jblocks);
 	if (IS_ERR(handle)) {
@@ -824,19 +931,6 @@
 	orig_blk_offset = orig_page_offset * blocks_per_page +
 		data_offset_in_page;
 
-	/*
-	 * If orig extent is uninitialized one,
-	 * it's not necessary force the page into memory
-	 * and then force it to be written out again.
-	 * Just swap data blocks between orig and donor.
-	 */
-	if (uninit) {
-		replaced_count = mext_replace_branches(handle, orig_inode,
-						donor_inode, orig_blk_offset,
-						block_len_in_page, err);
-		goto out2;
-	}
-
 	offs = (long long)orig_blk_offset << orig_inode->i_blkbits;
 
 	/* Calculate data_size */
@@ -858,75 +952,120 @@
 
 	replaced_size = data_size;
 
-	*err = a_ops->write_begin(o_filp, mapping, offs, data_size, w_flags,
-				 &page, &fsdata);
+	*err = mext_page_double_lock(orig_inode, donor_inode, orig_page_offset,
+				     pagep);
 	if (unlikely(*err < 0))
-		goto out;
+		goto stop_journal;
+	/*
+	 * If orig extent was uninitialized it can become initialized
+	 * at any time after i_data_sem was dropped, in order to
+	 * serialize with delalloc we have recheck extent while we
+	 * hold page's lock, if it is still the case data copy is not
+	 * necessary, just swap data blocks between orig and donor.
+	 */
+	if (uninit) {
+		double_down_write_data_sem(orig_inode, donor_inode);
+		/* If any of extents in range became initialized we have to
+		 * fallback to data copying */
+		uninit = mext_check_coverage(orig_inode, orig_blk_offset,
+					     block_len_in_page, 1, err);
+		if (*err)
+			goto drop_data_sem;
 
-	if (!PageUptodate(page)) {
-		mapping->a_ops->readpage(o_filp, page);
-		lock_page(page);
+		uninit &= mext_check_coverage(donor_inode, orig_blk_offset,
+					      block_len_in_page, 1, err);
+		if (*err)
+			goto drop_data_sem;
+
+		if (!uninit) {
+			double_up_write_data_sem(orig_inode, donor_inode);
+			goto data_copy;
+		}
+		if ((page_has_private(pagep[0]) &&
+		     !try_to_release_page(pagep[0], 0)) ||
+		    (page_has_private(pagep[1]) &&
+		     !try_to_release_page(pagep[1], 0))) {
+			*err = -EBUSY;
+			goto drop_data_sem;
+		}
+		replaced_count = mext_replace_branches(handle, orig_inode,
+						donor_inode, orig_blk_offset,
+						block_len_in_page, err);
+	drop_data_sem:
+		double_up_write_data_sem(orig_inode, donor_inode);
+		goto unlock_pages;
+	}
+data_copy:
+	*err = mext_page_mkuptodate(pagep[0], from, from + replaced_size);
+	if (*err)
+		goto unlock_pages;
+
+	/* At this point all buffers in range are uptodate, old mapping layout
+	 * is no longer required, try to drop it now. */
+	if ((page_has_private(pagep[0]) && !try_to_release_page(pagep[0], 0)) ||
+	    (page_has_private(pagep[1]) && !try_to_release_page(pagep[1], 0))) {
+		*err = -EBUSY;
+		goto unlock_pages;
 	}
 
-	/*
-	 * try_to_release_page() doesn't call releasepage in writeback mode.
-	 * We should care about the order of writing to the same file
-	 * by multiple move extent processes.
-	 * It needs to call wait_on_page_writeback() to wait for the
-	 * writeback of the page.
-	 */
-	wait_on_page_writeback(page);
-
-	/* Release old bh and drop refs */
-	try_to_release_page(page, 0);
-
 	replaced_count = mext_replace_branches(handle, orig_inode, donor_inode,
-					orig_blk_offset, block_len_in_page,
-					&err2);
-	if (err2) {
+					       orig_blk_offset,
+					       block_len_in_page, err);
+	if (*err) {
 		if (replaced_count) {
 			block_len_in_page = replaced_count;
 			replaced_size =
 				block_len_in_page << orig_inode->i_blkbits;
 		} else
-			goto out;
+			goto unlock_pages;
 	}
+	/* Perform all necessary steps similar write_begin()/write_end()
+	 * but keeping in mind that i_size will not change */
+	*err = __block_write_begin(pagep[0], from, from + replaced_size,
+				   ext4_get_block);
+	if (!*err)
+		*err = block_commit_write(pagep[0], from, from + replaced_size);
 
-	if (!page_has_buffers(page))
-		create_empty_buffers(page, 1 << orig_inode->i_blkbits, 0);
+	if (unlikely(*err < 0))
+		goto repair_branches;
 
-	bh = page_buffers(page);
-	for (i = 0; i < data_offset_in_page; i++)
-		bh = bh->b_this_page;
+	/* Even in case of data=writeback it is reasonable to pin
+	 * inode to transaction, to prevent unexpected data loss */
+	*err = ext4_jbd2_file_inode(handle, orig_inode);
 
-	for (i = 0; i < block_len_in_page; i++) {
-		*err = ext4_get_block(orig_inode,
-				(sector_t)(orig_blk_offset + i), bh, 0);
-		if (*err < 0)
-			goto out;
-
-		if (bh->b_this_page != NULL)
-			bh = bh->b_this_page;
-	}
-
-	*err = a_ops->write_end(o_filp, mapping, offs, data_size, replaced_size,
-			       page, fsdata);
-	page = NULL;
-
-out:
-	if (unlikely(page)) {
-		if (PageLocked(page))
-			unlock_page(page);
-		page_cache_release(page);
-		ext4_journal_stop(handle);
-	}
-out2:
+unlock_pages:
+	unlock_page(pagep[0]);
+	page_cache_release(pagep[0]);
+	unlock_page(pagep[1]);
+	page_cache_release(pagep[1]);
+stop_journal:
 	ext4_journal_stop(handle);
-
-	if (err2)
-		*err = err2;
-
+	/* Buffer was busy because probably is pinned to journal transaction,
+	 * force transaction commit may help to free it. */
+	if (*err == -EBUSY && ext4_should_retry_alloc(orig_inode->i_sb,
+						      &retries))
+		goto again;
 	return replaced_count;
+
+repair_branches:
+	/*
+	 * This should never ever happen!
+	 * Extents are swapped already, but we are not able to copy data.
+	 * Try to swap extents to it's original places
+	 */
+	double_down_write_data_sem(orig_inode, donor_inode);
+	replaced_count = mext_replace_branches(handle, donor_inode, orig_inode,
+					       orig_blk_offset,
+					       block_len_in_page, &err2);
+	double_up_write_data_sem(orig_inode, donor_inode);
+	if (replaced_count != block_len_in_page) {
+		EXT4_ERROR_INODE_BLOCK(orig_inode, (sector_t)(orig_blk_offset),
+				       "Unable to copy data block,"
+				       " data will be lost.");
+		*err = -EIO;
+	}
+	replaced_count = 0;
+	goto unlock_pages;
 }
 
 /**
@@ -969,14 +1108,6 @@
 		return -EINVAL;
 	}
 
-	/* Files should be in the same ext4 FS */
-	if (orig_inode->i_sb != donor_inode->i_sb) {
-		ext4_debug("ext4 move extent: The argument files "
-			"should be in same FS [ino:orig %lu, donor %lu]\n",
-			orig_inode->i_ino, donor_inode->i_ino);
-		return -EINVAL;
-	}
-
 	/* Ext4 move extent supports only extent based file */
 	if (!(ext4_test_inode_flag(orig_inode, EXT4_INODE_EXTENTS))) {
 		ext4_debug("ext4 move extent: orig file is not extents "
@@ -1002,7 +1133,6 @@
 	}
 
 	if ((orig_start >= EXT_MAX_BLOCKS) ||
-	    (donor_start >= EXT_MAX_BLOCKS) ||
 	    (*len > EXT_MAX_BLOCKS) ||
 	    (orig_start + *len >= EXT_MAX_BLOCKS))  {
 		ext4_debug("ext4 move extent: Can't handle over [%u] blocks "
@@ -1072,35 +1202,19 @@
  * @inode1:	the inode structure
  * @inode2:	the inode structure
  *
- * Lock two inodes' i_mutex by i_ino order.
- * If inode1 or inode2 is NULL, return -EIO. Otherwise, return 0.
+ * Lock two inodes' i_mutex
  */
-static int
+static void
 mext_inode_double_lock(struct inode *inode1, struct inode *inode2)
 {
-	int ret = 0;
-
-	BUG_ON(inode1 == NULL && inode2 == NULL);
-
-	ret = mext_check_null_inode(inode1, inode2, __func__, __LINE__);
-	if (ret < 0)
-		goto out;
-
-	if (inode1 == inode2) {
-		mutex_lock(&inode1->i_mutex);
-		goto out;
-	}
-
-	if (inode1->i_ino < inode2->i_ino) {
+	BUG_ON(inode1 == inode2);
+	if (inode1 < inode2) {
 		mutex_lock_nested(&inode1->i_mutex, I_MUTEX_PARENT);
 		mutex_lock_nested(&inode2->i_mutex, I_MUTEX_CHILD);
 	} else {
 		mutex_lock_nested(&inode2->i_mutex, I_MUTEX_PARENT);
 		mutex_lock_nested(&inode1->i_mutex, I_MUTEX_CHILD);
 	}
-
-out:
-	return ret;
 }
 
 /**
@@ -1109,28 +1223,13 @@
  * @inode1:     the inode that is released first
  * @inode2:     the inode that is released second
  *
- * If inode1 or inode2 is NULL, return -EIO. Otherwise, return 0.
  */
 
-static int
+static void
 mext_inode_double_unlock(struct inode *inode1, struct inode *inode2)
 {
-	int ret = 0;
-
-	BUG_ON(inode1 == NULL && inode2 == NULL);
-
-	ret = mext_check_null_inode(inode1, inode2, __func__, __LINE__);
-	if (ret < 0)
-		goto out;
-
-	if (inode1)
-		mutex_unlock(&inode1->i_mutex);
-
-	if (inode2 && inode2 != inode1)
-		mutex_unlock(&inode2->i_mutex);
-
-out:
-	return ret;
+	mutex_unlock(&inode1->i_mutex);
+	mutex_unlock(&inode2->i_mutex);
 }
 
 /**
@@ -1187,16 +1286,23 @@
 	ext4_lblk_t block_end, seq_start, add_blocks, file_end, seq_blocks = 0;
 	ext4_lblk_t rest_blocks;
 	pgoff_t orig_page_offset = 0, seq_end_page;
-	int ret1, ret2, depth, last_extent = 0;
+	int ret, depth, last_extent = 0;
 	int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits;
 	int data_offset_in_page;
 	int block_len_in_page;
 	int uninit;
 
-	/* orig and donor should be different file */
-	if (orig_inode->i_ino == donor_inode->i_ino) {
+	if (orig_inode->i_sb != donor_inode->i_sb) {
+		ext4_debug("ext4 move extent: The argument files "
+			"should be in same FS [ino:orig %lu, donor %lu]\n",
+			orig_inode->i_ino, donor_inode->i_ino);
+		return -EINVAL;
+	}
+
+	/* orig and donor should be different inodes */
+	if (orig_inode == donor_inode) {
 		ext4_debug("ext4 move extent: The argument files should not "
-			"be same file [ino:orig %lu, donor %lu]\n",
+			"be same inode [ino:orig %lu, donor %lu]\n",
 			orig_inode->i_ino, donor_inode->i_ino);
 		return -EINVAL;
 	}
@@ -1208,18 +1314,27 @@
 			orig_inode->i_ino, donor_inode->i_ino);
 		return -EINVAL;
 	}
-
+	/* TODO: This is non obvious task to swap blocks for inodes with full
+	   jornaling enabled */
+	if (ext4_should_journal_data(orig_inode) ||
+	    ext4_should_journal_data(donor_inode)) {
+		return -EINVAL;
+	}
 	/* Protect orig and donor inodes against a truncate */
-	ret1 = mext_inode_double_lock(orig_inode, donor_inode);
-	if (ret1 < 0)
-		return ret1;
+	mext_inode_double_lock(orig_inode, donor_inode);
+
+	/* Wait for all existing dio workers */
+	ext4_inode_block_unlocked_dio(orig_inode);
+	ext4_inode_block_unlocked_dio(donor_inode);
+	inode_dio_wait(orig_inode);
+	inode_dio_wait(donor_inode);
 
 	/* Protect extent tree against block allocations via delalloc */
 	double_down_write_data_sem(orig_inode, donor_inode);
 	/* Check the filesystem environment whether move_extent can be done */
-	ret1 = mext_check_arguments(orig_inode, donor_inode, orig_start,
+	ret = mext_check_arguments(orig_inode, donor_inode, orig_start,
 				    donor_start, &len);
-	if (ret1)
+	if (ret)
 		goto out;
 
 	file_end = (i_size_read(orig_inode) - 1) >> orig_inode->i_blkbits;
@@ -1227,13 +1342,13 @@
 	if (file_end < block_end)
 		len -= block_end - file_end;
 
-	ret1 = get_ext_path(orig_inode, block_start, &orig_path);
-	if (ret1)
+	ret = get_ext_path(orig_inode, block_start, &orig_path);
+	if (ret)
 		goto out;
 
 	/* Get path structure to check the hole */
-	ret1 = get_ext_path(orig_inode, block_start, &holecheck_path);
-	if (ret1)
+	ret = get_ext_path(orig_inode, block_start, &holecheck_path);
+	if (ret)
 		goto out;
 
 	depth = ext_depth(orig_inode);
@@ -1252,13 +1367,13 @@
 		last_extent = mext_next_extent(orig_inode,
 					holecheck_path, &ext_cur);
 		if (last_extent < 0) {
-			ret1 = last_extent;
+			ret = last_extent;
 			goto out;
 		}
 		last_extent = mext_next_extent(orig_inode, orig_path,
 							&ext_dummy);
 		if (last_extent < 0) {
-			ret1 = last_extent;
+			ret = last_extent;
 			goto out;
 		}
 		seq_start = le32_to_cpu(ext_cur->ee_block);
@@ -1272,7 +1387,7 @@
 	if (le32_to_cpu(ext_cur->ee_block) > block_end) {
 		ext4_debug("ext4 move extent: The specified range of file "
 							"may be the hole\n");
-		ret1 = -EINVAL;
+		ret = -EINVAL;
 		goto out;
 	}
 
@@ -1292,7 +1407,7 @@
 		last_extent = mext_next_extent(orig_inode, holecheck_path,
 						&ext_cur);
 		if (last_extent < 0) {
-			ret1 = last_extent;
+			ret = last_extent;
 			break;
 		}
 		add_blocks = ext4_ext_get_actual_len(ext_cur);
@@ -1349,18 +1464,18 @@
 						orig_page_offset,
 						data_offset_in_page,
 						block_len_in_page, uninit,
-						&ret1);
+						&ret);
 
 			/* Count how many blocks we have exchanged */
 			*moved_len += block_len_in_page;
-			if (ret1 < 0)
+			if (ret < 0)
 				break;
 			if (*moved_len > len) {
 				EXT4_ERROR_INODE(orig_inode,
 					"We replaced blocks too much! "
 					"sum of replaced: %llu requested: %llu",
 					*moved_len, len);
-				ret1 = -EIO;
+				ret = -EIO;
 				break;
 			}
 
@@ -1374,22 +1489,22 @@
 		}
 
 		double_down_write_data_sem(orig_inode, donor_inode);
-		if (ret1 < 0)
+		if (ret < 0)
 			break;
 
 		/* Decrease buffer counter */
 		if (holecheck_path)
 			ext4_ext_drop_refs(holecheck_path);
-		ret1 = get_ext_path(orig_inode, seq_start, &holecheck_path);
-		if (ret1)
+		ret = get_ext_path(orig_inode, seq_start, &holecheck_path);
+		if (ret)
 			break;
 		depth = holecheck_path->p_depth;
 
 		/* Decrease buffer counter */
 		if (orig_path)
 			ext4_ext_drop_refs(orig_path);
-		ret1 = get_ext_path(orig_inode, seq_start, &orig_path);
-		if (ret1)
+		ret = get_ext_path(orig_inode, seq_start, &orig_path);
+		if (ret)
 			break;
 
 		ext_cur = holecheck_path[depth].p_ext;
@@ -1412,12 +1527,9 @@
 		kfree(holecheck_path);
 	}
 	double_up_write_data_sem(orig_inode, donor_inode);
-	ret2 = mext_inode_double_unlock(orig_inode, donor_inode);
+	ext4_inode_resume_unlocked_dio(orig_inode);
+	ext4_inode_resume_unlocked_dio(donor_inode);
+	mext_inode_double_unlock(orig_inode, donor_inode);
 
-	if (ret1)
-		return ret1;
-	else if (ret2)
-		return ret2;
-
-	return 0;
+	return ret;
 }
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 2a42cc0..6d600a6 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -55,6 +55,13 @@
 {
 	struct buffer_head *bh;
 
+	if (unlikely(EXT4_SB(inode->i_sb)->s_max_dir_size_kb &&
+		     ((inode->i_size >> 10) >=
+		      EXT4_SB(inode->i_sb)->s_max_dir_size_kb))) {
+		*err = -ENOSPC;
+		return NULL;
+	}
+
 	*block = inode->i_size >> inode->i_sb->s_blocksize_bits;
 
 	bh = ext4_bread(handle, inode, *block, 1, err);
@@ -67,6 +74,12 @@
 			bh = NULL;
 		}
 	}
+	if (!bh && !(*err)) {
+		*err = -EIO;
+		ext4_error(inode->i_sb,
+			   "Directory hole detected on inode %lu\n",
+			   inode->i_ino);
+	}
 	return bh;
 }
 
@@ -594,8 +607,11 @@
 	u32 hash;
 
 	frame->bh = NULL;
-	if (!(bh = ext4_bread (NULL,dir, 0, 0, err)))
+	if (!(bh = ext4_bread(NULL, dir, 0, 0, err))) {
+		if (*err == 0)
+			*err = ERR_BAD_DX_DIR;
 		goto fail;
+	}
 	root = (struct dx_root *) bh->b_data;
 	if (root->info.hash_version != DX_HASH_TEA &&
 	    root->info.hash_version != DX_HASH_HALF_MD4 &&
@@ -696,8 +712,11 @@
 		frame->entries = entries;
 		frame->at = at;
 		if (!indirect--) return frame;
-		if (!(bh = ext4_bread (NULL,dir, dx_get_block(at), 0, err)))
+		if (!(bh = ext4_bread(NULL, dir, dx_get_block(at), 0, err))) {
+			if (!(*err))
+				*err = ERR_BAD_DX_DIR;
 			goto fail2;
+		}
 		at = entries = ((struct dx_node *) bh->b_data)->entries;
 
 		if (!buffer_verified(bh) &&
@@ -807,8 +826,15 @@
 	 */
 	while (num_frames--) {
 		if (!(bh = ext4_bread(NULL, dir, dx_get_block(p->at),
-				      0, &err)))
+				      0, &err))) {
+			if (!err) {
+				ext4_error(dir->i_sb,
+					   "Directory hole detected on inode %lu\n",
+					   dir->i_ino);
+				return -EIO;
+			}
 			return err; /* Failure */
+		}
 
 		if (!buffer_verified(bh) &&
 		    !ext4_dx_csum_verify(dir,
@@ -839,12 +865,19 @@
 {
 	struct buffer_head *bh;
 	struct ext4_dir_entry_2 *de, *top;
-	int err, count = 0;
+	int err = 0, count = 0;
 
 	dxtrace(printk(KERN_INFO "In htree dirblock_to_tree: block %lu\n",
 							(unsigned long)block));
-	if (!(bh = ext4_bread (NULL, dir, block, 0, &err)))
+	if (!(bh = ext4_bread(NULL, dir, block, 0, &err))) {
+		if (!err) {
+			err = -EIO;
+			ext4_error(dir->i_sb,
+				   "Directory hole detected on inode %lu\n",
+				   dir->i_ino);
+		}
 		return err;
+	}
 
 	if (!buffer_verified(bh) &&
 	    !ext4_dirent_csum_verify(dir, (struct ext4_dir_entry *)bh->b_data))
@@ -1267,8 +1300,15 @@
 		return NULL;
 	do {
 		block = dx_get_block(frame->at);
-		if (!(bh = ext4_bread(NULL, dir, block, 0, err)))
+		if (!(bh = ext4_bread(NULL, dir, block, 0, err))) {
+			if (!(*err)) {
+				*err = -EIO;
+				ext4_error(dir->i_sb,
+					   "Directory hole detected on inode %lu\n",
+					   dir->i_ino);
+			}
 			goto errout;
+		}
 
 		if (!buffer_verified(bh) &&
 		    !ext4_dirent_csum_verify(dir,
@@ -1801,9 +1841,15 @@
 	}
 	blocks = dir->i_size >> sb->s_blocksize_bits;
 	for (block = 0; block < blocks; block++) {
-		bh = ext4_bread(handle, dir, block, 0, &retval);
-		if(!bh)
+		if (!(bh = ext4_bread(handle, dir, block, 0, &retval))) {
+			if (!retval) {
+				retval = -EIO;
+				ext4_error(inode->i_sb,
+					   "Directory hole detected on inode %lu\n",
+					   inode->i_ino);
+			}
 			return retval;
+		}
 		if (!buffer_verified(bh) &&
 		    !ext4_dirent_csum_verify(dir,
 				(struct ext4_dir_entry *)bh->b_data))
@@ -1860,8 +1906,15 @@
 	entries = frame->entries;
 	at = frame->at;
 
-	if (!(bh = ext4_bread(handle,dir, dx_get_block(frame->at), 0, &err)))
+	if (!(bh = ext4_bread(handle, dir, dx_get_block(frame->at), 0, &err))) {
+		if (!err) {
+			err = -EIO;
+			ext4_error(dir->i_sb,
+				   "Directory hole detected on inode %lu\n",
+				   dir->i_ino);
+		}
 		goto cleanup;
+	}
 
 	if (!buffer_verified(bh) &&
 	    !ext4_dirent_csum_verify(dir, (struct ext4_dir_entry *)bh->b_data))
@@ -2149,9 +2202,7 @@
 	err = PTR_ERR(inode);
 	if (!IS_ERR(inode)) {
 		init_special_inode(inode, inode->i_mode, rdev);
-#ifdef CONFIG_EXT4_FS_XATTR
 		inode->i_op = &ext4_special_inode_operations;
-#endif
 		err = ext4_add_nondir(handle, dentry, inode);
 	}
 	ext4_journal_stop(handle);
@@ -2199,9 +2250,15 @@
 	inode->i_op = &ext4_dir_inode_operations;
 	inode->i_fop = &ext4_dir_operations;
 	inode->i_size = EXT4_I(inode)->i_disksize = inode->i_sb->s_blocksize;
-	dir_block = ext4_bread(handle, inode, 0, 1, &err);
-	if (!dir_block)
+	if (!(dir_block = ext4_bread(handle, inode, 0, 1, &err))) {
+		if (!err) {
+			err = -EIO;
+			ext4_error(inode->i_sb,
+				   "Directory hole detected on inode %lu\n",
+				   inode->i_ino);
+		}
 		goto out_clear_inode;
+	}
 	BUFFER_TRACE(dir_block, "get_write_access");
 	err = ext4_journal_get_write_access(handle, dir_block);
 	if (err)
@@ -2318,6 +2375,11 @@
 					EXT4_ERROR_INODE(inode,
 						"error %d reading directory "
 						"lblock %u", err, lblock);
+				else
+					ext4_warning(inode->i_sb,
+						"bad directory (dir #%lu) - no data block",
+						inode->i_ino);
+
 				offset += sb->s_blocksize;
 				continue;
 			}
@@ -2362,7 +2424,7 @@
 	struct ext4_iloc iloc;
 	int err = 0, rc;
 
-	if (!ext4_handle_valid(handle))
+	if (!EXT4_SB(sb)->s_journal)
 		return 0;
 
 	mutex_lock(&EXT4_SB(sb)->s_orphan_lock);
@@ -2436,8 +2498,7 @@
 	struct ext4_iloc iloc;
 	int err = 0;
 
-	/* ext4_handle_valid() assumes a valid handle_t pointer */
-	if (handle && !ext4_handle_valid(handle))
+	if (!EXT4_SB(inode->i_sb)->s_journal)
 		return 0;
 
 	mutex_lock(&EXT4_SB(inode->i_sb)->s_orphan_lock);
@@ -2456,7 +2517,7 @@
 	 * transaction handle with which to update the orphan list on
 	 * disk, but we still need to remove the inode from the linked
 	 * list in memory. */
-	if (sbi->s_journal && !handle)
+	if (!handle)
 		goto out;
 
 	err = ext4_reserve_inode_write(handle, inode, &iloc);
@@ -2826,9 +2887,15 @@
 				goto end_rename;
 		}
 		retval = -EIO;
-		dir_bh = ext4_bread(handle, old_inode, 0, 0, &retval);
-		if (!dir_bh)
+		if (!(dir_bh = ext4_bread(handle, old_inode, 0, 0, &retval))) {
+			if (!retval) {
+				retval = -EIO;
+				ext4_error(old_inode->i_sb,
+					   "Directory hole detected on inode %lu\n",
+					   old_inode->i_ino);
+			}
 			goto end_rename;
+		}
 		if (!buffer_verified(dir_bh) &&
 		    !ext4_dirent_csum_verify(old_inode,
 				(struct ext4_dir_entry *)dir_bh->b_data))
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
index dcdeef1..68e896e 100644
--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -71,6 +71,9 @@
 	int i;
 
 	BUG_ON(!io);
+	BUG_ON(!list_empty(&io->list));
+	BUG_ON(io->flag & EXT4_IO_END_UNWRITTEN);
+
 	if (io->page)
 		put_page(io->page);
 	for (i = 0; i < io->num_io_pages; i++)
@@ -81,13 +84,8 @@
 	kmem_cache_free(io_end_cachep, io);
 }
 
-/*
- * check a range of space and convert unwritten extents to written.
- *
- * Called with inode->i_mutex; we depend on this when we manipulate
- * io->flag, since we could otherwise race with ext4_flush_completed_IO()
- */
-int ext4_end_io_nolock(ext4_io_end_t *io)
+/* check a range of space and convert unwritten extents to written. */
+static int ext4_end_io(ext4_io_end_t *io)
 {
 	struct inode *inode = io->inode;
 	loff_t offset = io->offset;
@@ -106,63 +104,136 @@
 			 "(inode %lu, offset %llu, size %zd, error %d)",
 			 inode->i_ino, offset, size, ret);
 	}
-
 	if (io->iocb)
 		aio_complete(io->iocb, io->result, 0);
 
 	if (io->flag & EXT4_IO_END_DIRECT)
 		inode_dio_done(inode);
 	/* Wake up anyone waiting on unwritten extent conversion */
-	if (atomic_dec_and_test(&EXT4_I(inode)->i_aiodio_unwritten))
+	if (atomic_dec_and_test(&EXT4_I(inode)->i_unwritten))
 		wake_up_all(ext4_ioend_wq(io->inode));
 	return ret;
 }
 
+static void dump_completed_IO(struct inode *inode)
+{
+#ifdef	EXT4FS_DEBUG
+	struct list_head *cur, *before, *after;
+	ext4_io_end_t *io, *io0, *io1;
+	unsigned long flags;
+
+	if (list_empty(&EXT4_I(inode)->i_completed_io_list)) {
+		ext4_debug("inode %lu completed_io list is empty\n",
+			   inode->i_ino);
+		return;
+	}
+
+	ext4_debug("Dump inode %lu completed_io list\n", inode->i_ino);
+	list_for_each_entry(io, &EXT4_I(inode)->i_completed_io_list, list) {
+		cur = &io->list;
+		before = cur->prev;
+		io0 = container_of(before, ext4_io_end_t, list);
+		after = cur->next;
+		io1 = container_of(after, ext4_io_end_t, list);
+
+		ext4_debug("io 0x%p from inode %lu,prev 0x%p,next 0x%p\n",
+			    io, inode->i_ino, io0, io1);
+	}
+#endif
+}
+
+/* Add the io_end to per-inode completed end_io list. */
+void ext4_add_complete_io(ext4_io_end_t *io_end)
+{
+	struct ext4_inode_info *ei = EXT4_I(io_end->inode);
+	struct workqueue_struct *wq;
+	unsigned long flags;
+
+	BUG_ON(!(io_end->flag & EXT4_IO_END_UNWRITTEN));
+	wq = EXT4_SB(io_end->inode->i_sb)->dio_unwritten_wq;
+
+	spin_lock_irqsave(&ei->i_completed_io_lock, flags);
+	if (list_empty(&ei->i_completed_io_list)) {
+		io_end->flag |= EXT4_IO_END_QUEUED;
+		queue_work(wq, &io_end->work);
+	}
+	list_add_tail(&io_end->list, &ei->i_completed_io_list);
+	spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
+}
+
+static int ext4_do_flush_completed_IO(struct inode *inode,
+				      ext4_io_end_t *work_io)
+{
+	ext4_io_end_t *io;
+	struct list_head unwritten, complete, to_free;
+	unsigned long flags;
+	struct ext4_inode_info *ei = EXT4_I(inode);
+	int err, ret = 0;
+
+	INIT_LIST_HEAD(&complete);
+	INIT_LIST_HEAD(&to_free);
+
+	spin_lock_irqsave(&ei->i_completed_io_lock, flags);
+	dump_completed_IO(inode);
+	list_replace_init(&ei->i_completed_io_list, &unwritten);
+	spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
+
+	while (!list_empty(&unwritten)) {
+		io = list_entry(unwritten.next, ext4_io_end_t, list);
+		BUG_ON(!(io->flag & EXT4_IO_END_UNWRITTEN));
+		list_del_init(&io->list);
+
+		err = ext4_end_io(io);
+		if (unlikely(!ret && err))
+			ret = err;
+
+		list_add_tail(&io->list, &complete);
+	}
+	spin_lock_irqsave(&ei->i_completed_io_lock, flags);
+	while (!list_empty(&complete)) {
+		io = list_entry(complete.next, ext4_io_end_t, list);
+		io->flag &= ~EXT4_IO_END_UNWRITTEN;
+		/* end_io context can not be destroyed now because it still
+		 * used by queued worker. Worker thread will destroy it later */
+		if (io->flag & EXT4_IO_END_QUEUED)
+			list_del_init(&io->list);
+		else
+			list_move(&io->list, &to_free);
+	}
+	/* If we are called from worker context, it is time to clear queued
+	 * flag, and destroy it's end_io if it was converted already */
+	if (work_io) {
+		work_io->flag &= ~EXT4_IO_END_QUEUED;
+		if (!(work_io->flag & EXT4_IO_END_UNWRITTEN))
+			list_add_tail(&work_io->list, &to_free);
+	}
+	spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
+
+	while (!list_empty(&to_free)) {
+		io = list_entry(to_free.next, ext4_io_end_t, list);
+		list_del_init(&io->list);
+		ext4_free_io_end(io);
+	}
+	return ret;
+}
+
 /*
  * work on completed aio dio IO, to convert unwritten extents to extents
  */
 static void ext4_end_io_work(struct work_struct *work)
 {
-	ext4_io_end_t		*io = container_of(work, ext4_io_end_t, work);
-	struct inode		*inode = io->inode;
-	struct ext4_inode_info	*ei = EXT4_I(inode);
-	unsigned long		flags;
+	ext4_io_end_t *io = container_of(work, ext4_io_end_t, work);
+	ext4_do_flush_completed_IO(io->inode, io);
+}
 
-	spin_lock_irqsave(&ei->i_completed_io_lock, flags);
-	if (io->flag & EXT4_IO_END_IN_FSYNC)
-		goto requeue;
-	if (list_empty(&io->list)) {
-		spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
-		goto free;
-	}
-
-	if (!mutex_trylock(&inode->i_mutex)) {
-		bool was_queued;
-requeue:
-		was_queued = !!(io->flag & EXT4_IO_END_QUEUED);
-		io->flag |= EXT4_IO_END_QUEUED;
-		spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
-		/*
-		 * Requeue the work instead of waiting so that the work
-		 * items queued after this can be processed.
-		 */
-		queue_work(EXT4_SB(inode->i_sb)->dio_unwritten_wq, &io->work);
-		/*
-		 * To prevent the ext4-dio-unwritten thread from keeping
-		 * requeueing end_io requests and occupying cpu for too long,
-		 * yield the cpu if it sees an end_io request that has already
-		 * been requeued.
-		 */
-		if (was_queued)
-			yield();
-		return;
-	}
-	list_del_init(&io->list);
-	spin_unlock_irqrestore(&ei->i_completed_io_lock, flags);
-	(void) ext4_end_io_nolock(io);
-	mutex_unlock(&inode->i_mutex);
-free:
-	ext4_free_io_end(io);
+int ext4_flush_unwritten_io(struct inode *inode)
+{
+	int ret;
+	WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex) &&
+		     !(inode->i_state & I_FREEING));
+	ret = ext4_do_flush_completed_IO(inode, NULL);
+	ext4_unwritten_wait(inode);
+	return ret;
 }
 
 ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags)
@@ -195,9 +266,7 @@
 static void ext4_end_bio(struct bio *bio, int error)
 {
 	ext4_io_end_t *io_end = bio->bi_private;
-	struct workqueue_struct *wq;
 	struct inode *inode;
-	unsigned long flags;
 	int i;
 	sector_t bi_sector = bio->bi_sector;
 
@@ -255,14 +324,7 @@
 		return;
 	}
 
-	/* Add the io_end to per-inode completed io list*/
-	spin_lock_irqsave(&EXT4_I(inode)->i_completed_io_lock, flags);
-	list_add_tail(&io_end->list, &EXT4_I(inode)->i_completed_io_list);
-	spin_unlock_irqrestore(&EXT4_I(inode)->i_completed_io_lock, flags);
-
-	wq = EXT4_SB(inode->i_sb)->dio_unwritten_wq;
-	/* queue the work to convert unwritten extents to written */
-	queue_work(wq, &io_end->work);
+	ext4_add_complete_io(io_end);
 }
 
 void ext4_io_submit(struct ext4_io_submit *io)
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 41f6ef6..7a75e10 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -45,6 +45,28 @@
 	smp_mb__after_clear_bit();
 }
 
+static ext4_group_t ext4_meta_bg_first_group(struct super_block *sb,
+					     ext4_group_t group) {
+	return (group >> EXT4_DESC_PER_BLOCK_BITS(sb)) <<
+	       EXT4_DESC_PER_BLOCK_BITS(sb);
+}
+
+static ext4_fsblk_t ext4_meta_bg_first_block_no(struct super_block *sb,
+					     ext4_group_t group) {
+	group = ext4_meta_bg_first_group(sb, group);
+	return ext4_group_first_block_no(sb, group);
+}
+
+static ext4_grpblk_t ext4_group_overhead_blocks(struct super_block *sb,
+						ext4_group_t group) {
+	ext4_grpblk_t overhead;
+	overhead = ext4_bg_num_gdb(sb, group);
+	if (ext4_bg_has_super(sb, group))
+		overhead += 1 +
+			  le16_to_cpu(EXT4_SB(sb)->s_es->s_reserved_gdt_blocks);
+	return overhead;
+}
+
 #define outside(b, first, last)	((b) < (first) || (b) >= (last))
 #define inside(b, first, last)	((b) >= (first) && (b) < (last))
 
@@ -57,9 +79,7 @@
 	ext4_fsblk_t end = start + input->blocks_count;
 	ext4_group_t group = input->group;
 	ext4_fsblk_t itend = input->inode_table + sbi->s_itb_per_group;
-	unsigned overhead = ext4_bg_has_super(sb, group) ?
-		(1 + ext4_bg_num_gdb(sb, group) +
-		 le16_to_cpu(es->s_reserved_gdt_blocks)) : 0;
+	unsigned overhead = ext4_group_overhead_blocks(sb, group);
 	ext4_fsblk_t metaend = start + overhead;
 	struct buffer_head *bh = NULL;
 	ext4_grpblk_t free_blocks_count, offset;
@@ -200,13 +220,15 @@
  * be a partial of a flex group.
  *
  * @sb: super block of fs to which the groups belongs
+ *
+ * Returns 0 on a successful allocation of the metadata blocks in the
+ * block group.
  */
-static void ext4_alloc_group_tables(struct super_block *sb,
+static int ext4_alloc_group_tables(struct super_block *sb,
 				struct ext4_new_flex_group_data *flex_gd,
 				int flexbg_size)
 {
 	struct ext4_new_group_data *group_data = flex_gd->groups;
-	struct ext4_super_block *es = EXT4_SB(sb)->s_es;
 	ext4_fsblk_t start_blk;
 	ext4_fsblk_t last_blk;
 	ext4_group_t src_group;
@@ -226,23 +248,24 @@
 	       (last_group & ~(flexbg_size - 1))));
 next_group:
 	group = group_data[0].group;
+	if (src_group >= group_data[0].group + flex_gd->count)
+		return -ENOSPC;
 	start_blk = ext4_group_first_block_no(sb, src_group);
 	last_blk = start_blk + group_data[src_group - group].blocks_count;
 
-	overhead = ext4_bg_has_super(sb, src_group) ?
-		   (1 + ext4_bg_num_gdb(sb, src_group) +
-		    le16_to_cpu(es->s_reserved_gdt_blocks)) : 0;
+	overhead = ext4_group_overhead_blocks(sb, src_group);
 
 	start_blk += overhead;
 
-	BUG_ON(src_group >= group_data[0].group + flex_gd->count);
 	/* We collect contiguous blocks as much as possible. */
 	src_group++;
-	for (; src_group <= last_group; src_group++)
-		if (!ext4_bg_has_super(sb, src_group))
+	for (; src_group <= last_group; src_group++) {
+		overhead = ext4_group_overhead_blocks(sb, src_group);
+		if (overhead != 0)
 			last_blk += group_data[src_group - group].blocks_count;
 		else
 			break;
+	}
 
 	/* Allocate block bitmaps */
 	for (; bb_index < flex_gd->count; bb_index++) {
@@ -300,6 +323,7 @@
 			       group_data[i].free_blocks_count);
 		}
 	}
+	return 0;
 }
 
 static struct buffer_head *bclean(handle_t *handle, struct super_block *sb,
@@ -433,11 +457,13 @@
 	ext4_group_t group, count;
 	struct buffer_head *bh = NULL;
 	int reserved_gdb, i, j, err = 0, err2;
+	int meta_bg;
 
 	BUG_ON(!flex_gd->count || !group_data ||
 	       group_data[0].group != sbi->s_groups_count);
 
 	reserved_gdb = le16_to_cpu(es->s_reserved_gdt_blocks);
+	meta_bg = EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG);
 
 	/* This transaction may be extended/restarted along the way */
 	handle = ext4_journal_start_sb(sb, EXT4_MAX_TRANS_DATA);
@@ -447,12 +473,25 @@
 	group = group_data[0].group;
 	for (i = 0; i < flex_gd->count; i++, group++) {
 		unsigned long gdblocks;
+		ext4_grpblk_t overhead;
 
 		gdblocks = ext4_bg_num_gdb(sb, group);
 		start = ext4_group_first_block_no(sb, group);
 
+		if (meta_bg == 0 && !ext4_bg_has_super(sb, group))
+			goto handle_itb;
+
+		if (meta_bg == 1) {
+			ext4_group_t first_group;
+			first_group = ext4_meta_bg_first_group(sb, group);
+			if (first_group != group + 1 &&
+			    first_group != group + EXT4_DESC_PER_BLOCK(sb) - 1)
+				goto handle_itb;
+		}
+
+		block = start + ext4_bg_has_super(sb, group);
 		/* Copy all of the GDT blocks into the backup in this group */
-		for (j = 0, block = start + 1; j < gdblocks; j++, block++) {
+		for (j = 0; j < gdblocks; j++, block++) {
 			struct buffer_head *gdb;
 
 			ext4_debug("update backup group %#04llx\n", block);
@@ -493,6 +532,7 @@
 				goto out;
 		}
 
+handle_itb:
 		/* Initialize group tables of the grop @group */
 		if (!(bg_flags[i] & EXT4_BG_INODE_ZEROED))
 			goto handle_bb;
@@ -521,11 +561,11 @@
 			err = PTR_ERR(bh);
 			goto out;
 		}
-		if (ext4_bg_has_super(sb, group)) {
+		overhead = ext4_group_overhead_blocks(sb, group);
+		if (overhead != 0) {
 			ext4_debug("mark backup superblock %#04llx (+0)\n",
 				   start);
-			ext4_set_bits(bh->b_data, 0, gdblocks + reserved_gdb +
-						     1);
+			ext4_set_bits(bh->b_data, 0, overhead);
 		}
 		ext4_mark_bitmap_end(group_data[i].blocks_count,
 				     sb->s_blocksize * 8, bh->b_data);
@@ -822,6 +862,45 @@
 }
 
 /*
+ * add_new_gdb_meta_bg is the sister of add_new_gdb.
+ */
+static int add_new_gdb_meta_bg(struct super_block *sb,
+			       handle_t *handle, ext4_group_t group) {
+	ext4_fsblk_t gdblock;
+	struct buffer_head *gdb_bh;
+	struct buffer_head **o_group_desc, **n_group_desc;
+	unsigned long gdb_num = group / EXT4_DESC_PER_BLOCK(sb);
+	int err;
+
+	gdblock = ext4_meta_bg_first_block_no(sb, group) +
+		   ext4_bg_has_super(sb, group);
+	gdb_bh = sb_bread(sb, gdblock);
+	if (!gdb_bh)
+		return -EIO;
+	n_group_desc = ext4_kvmalloc((gdb_num + 1) *
+				     sizeof(struct buffer_head *),
+				     GFP_NOFS);
+	if (!n_group_desc) {
+		err = -ENOMEM;
+		ext4_warning(sb, "not enough memory for %lu groups",
+			     gdb_num + 1);
+		return err;
+	}
+
+	o_group_desc = EXT4_SB(sb)->s_group_desc;
+	memcpy(n_group_desc, o_group_desc,
+	       EXT4_SB(sb)->s_gdb_count * sizeof(struct buffer_head *));
+	n_group_desc[gdb_num] = gdb_bh;
+	EXT4_SB(sb)->s_group_desc = n_group_desc;
+	EXT4_SB(sb)->s_gdb_count++;
+	ext4_kvfree(o_group_desc);
+	err = ext4_journal_get_write_access(handle, gdb_bh);
+	if (unlikely(err))
+		brelse(gdb_bh);
+	return err;
+}
+
+/*
  * Called when we are adding a new group which has a backup copy of each of
  * the GDT blocks (i.e. sparse group) and there are reserved GDT blocks.
  * We need to add these reserved backup GDT blocks to the resize inode, so
@@ -949,16 +1028,16 @@
  * do not copy the full number of backups at this time.  The resize
  * which changed s_groups_count will backup again.
  */
-static void update_backups(struct super_block *sb,
-			   int blk_off, char *data, int size)
+static void update_backups(struct super_block *sb, int blk_off, char *data,
+			   int size, int meta_bg)
 {
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
-	const ext4_group_t last = sbi->s_groups_count;
+	ext4_group_t last;
 	const int bpg = EXT4_BLOCKS_PER_GROUP(sb);
 	unsigned three = 1;
 	unsigned five = 5;
 	unsigned seven = 7;
-	ext4_group_t group;
+	ext4_group_t group = 0;
 	int rest = sb->s_blocksize - size;
 	handle_t *handle;
 	int err = 0, err2;
@@ -970,10 +1049,17 @@
 		goto exit_err;
 	}
 
-	ext4_superblock_csum_set(sb, (struct ext4_super_block *)data);
+	if (meta_bg == 0) {
+		group = ext4_list_backups(sb, &three, &five, &seven);
+		last = sbi->s_groups_count;
+	} else {
+		group = ext4_meta_bg_first_group(sb, group) + 1;
+		last = (ext4_group_t)(group + EXT4_DESC_PER_BLOCK(sb) - 2);
+	}
 
-	while ((group = ext4_list_backups(sb, &three, &five, &seven)) < last) {
+	while (group < sbi->s_groups_count) {
 		struct buffer_head *bh;
+		ext4_fsblk_t backup_block;
 
 		/* Out of journal space, and can't get more - abort - so sad */
 		if (ext4_handle_valid(handle) &&
@@ -982,13 +1068,20 @@
 		    (err = ext4_journal_restart(handle, EXT4_MAX_TRANS_DATA)))
 			break;
 
-		bh = sb_getblk(sb, group * bpg + blk_off);
+		if (meta_bg == 0)
+			backup_block = group * bpg + blk_off;
+		else
+			backup_block = (ext4_group_first_block_no(sb, group) +
+					ext4_bg_has_super(sb, group));
+
+		bh = sb_getblk(sb, backup_block);
 		if (!bh) {
 			err = -EIO;
 			break;
 		}
-		ext4_debug("update metadata backup %#04lx\n",
-			  (unsigned long)bh->b_blocknr);
+		ext4_debug("update metadata backup %llu(+%llu)\n",
+			   backup_block, backup_block -
+			   ext4_group_first_block_no(sb, group));
 		if ((err = ext4_journal_get_write_access(handle, bh)))
 			break;
 		lock_buffer(bh);
@@ -1001,6 +1094,13 @@
 		if (unlikely(err))
 			ext4_std_error(sb, err);
 		brelse(bh);
+
+		if (meta_bg == 0)
+			group = ext4_list_backups(sb, &three, &five, &seven);
+		else if (group == last)
+			break;
+		else
+			group = last;
 	}
 	if ((err2 = ext4_journal_stop(handle)) && !err)
 		err = err2;
@@ -1043,7 +1143,9 @@
 	struct ext4_super_block *es = sbi->s_es;
 	struct buffer_head *gdb_bh;
 	int i, gdb_off, gdb_num, err = 0;
+	int meta_bg;
 
+	meta_bg = EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG);
 	for (i = 0; i < count; i++, group++) {
 		int reserved_gdb = ext4_bg_has_super(sb, group) ?
 			le16_to_cpu(es->s_reserved_gdt_blocks) : 0;
@@ -1063,8 +1165,11 @@
 
 			if (!err && reserved_gdb && ext4_bg_num_gdb(sb, group))
 				err = reserve_backup_gdb(handle, resize_inode, group);
-		} else
+		} else if (meta_bg != 0) {
+			err = add_new_gdb_meta_bg(sb, handle, group);
+		} else {
 			err = add_new_gdb(handle, resize_inode, group);
+		}
 		if (err)
 			break;
 	}
@@ -1076,17 +1181,12 @@
 	struct buffer_head *bh = sb_getblk(sb, block);
 	if (!bh)
 		return NULL;
-
-	if (bitmap_uptodate(bh))
-		return bh;
-
-	lock_buffer(bh);
-	if (bh_submit_read(bh) < 0) {
-		unlock_buffer(bh);
-		brelse(bh);
-		return NULL;
+	if (!bh_uptodate_or_lock(bh)) {
+		if (bh_submit_read(bh) < 0) {
+			brelse(bh);
+			return NULL;
+		}
 	}
-	unlock_buffer(bh);
 
 	return bh;
 }
@@ -1161,6 +1261,9 @@
 		ext4_free_group_clusters_set(sb, gdp,
 					     EXT4_B2C(sbi, group_data->free_blocks_count));
 		ext4_free_inodes_set(sb, gdp, EXT4_INODES_PER_GROUP(sb));
+		if (ext4_has_group_desc_csum(sb))
+			ext4_itable_unused_set(sb, gdp,
+					       EXT4_INODES_PER_GROUP(sb));
 		gdp->bg_flags = cpu_to_le16(*bg_flags);
 		ext4_group_desc_csum_set(sb, group, gdp);
 
@@ -1216,7 +1319,7 @@
 	}
 
 	reserved_blocks = ext4_r_blocks_count(es) * 100;
-	do_div(reserved_blocks, ext4_blocks_count(es));
+	reserved_blocks = div64_u64(reserved_blocks, ext4_blocks_count(es));
 	reserved_blocks *= blocks_count;
 	do_div(reserved_blocks, 100);
 
@@ -1227,6 +1330,7 @@
 	le32_add_cpu(&es->s_free_inodes_count, EXT4_INODES_PER_GROUP(sb) *
 		     flex_gd->count);
 
+	ext4_debug("free blocks count %llu", ext4_free_blocks_count(es));
 	/*
 	 * We need to protect s_groups_count against other CPUs seeing
 	 * inconsistent state in the superblock.
@@ -1261,6 +1365,8 @@
 	percpu_counter_add(&sbi->s_freeinodes_counter,
 			   EXT4_INODES_PER_GROUP(sb) * flex_gd->count);
 
+	ext4_debug("free blocks count %llu",
+		   percpu_counter_read(&sbi->s_freeclusters_counter));
 	if (EXT4_HAS_INCOMPAT_FEATURE(sb,
 				      EXT4_FEATURE_INCOMPAT_FLEX_BG) &&
 	    sbi->s_log_groups_per_flex) {
@@ -1349,16 +1455,24 @@
 		err = err2;
 
 	if (!err) {
-		int i;
+		int gdb_num = group / EXT4_DESC_PER_BLOCK(sb);
+		int gdb_num_end = ((group + flex_gd->count - 1) /
+				   EXT4_DESC_PER_BLOCK(sb));
+		int meta_bg = EXT4_HAS_INCOMPAT_FEATURE(sb,
+				EXT4_FEATURE_INCOMPAT_META_BG);
+		sector_t old_gdb = 0;
+
 		update_backups(sb, sbi->s_sbh->b_blocknr, (char *)es,
-			       sizeof(struct ext4_super_block));
-		for (i = 0; i < flex_gd->count; i++, group++) {
+			       sizeof(struct ext4_super_block), 0);
+		for (; gdb_num <= gdb_num_end; gdb_num++) {
 			struct buffer_head *gdb_bh;
-			int gdb_num;
-			gdb_num = group / EXT4_BLOCKS_PER_GROUP(sb);
+
 			gdb_bh = sbi->s_group_desc[gdb_num];
+			if (old_gdb == gdb_bh->b_blocknr)
+				continue;
 			update_backups(sb, gdb_bh->b_blocknr, gdb_bh->b_data,
-				       gdb_bh->b_size);
+				       gdb_bh->b_size, meta_bg);
+			old_gdb = gdb_bh->b_blocknr;
 		}
 	}
 exit:
@@ -1402,9 +1516,7 @@
 
 		group_data[i].group = group + i;
 		group_data[i].blocks_count = blocks_per_group;
-		overhead = ext4_bg_has_super(sb, group + i) ?
-			   (1 + ext4_bg_num_gdb(sb, group + i) +
-			    le16_to_cpu(es->s_reserved_gdt_blocks)) : 0;
+		overhead = ext4_group_overhead_blocks(sb, group + i);
 		group_data[i].free_blocks_count = blocks_per_group - overhead;
 		if (ext4_has_group_desc_csum(sb))
 			flex_gd->bg_flags[i] = EXT4_BG_BLOCK_UNINIT |
@@ -1492,6 +1604,14 @@
 	if (err)
 		goto out;
 
+	err = ext4_alloc_flex_bg_array(sb, input->group + 1);
+	if (err)
+		return err;
+
+	err = ext4_mb_alloc_groupinfo(sb, input->group + 1);
+	if (err)
+		goto out;
+
 	flex_gd.count = 1;
 	flex_gd.groups = input;
 	flex_gd.bg_flags = &bg_flags;
@@ -1544,11 +1664,13 @@
 		err = err2;
 
 	if (!err) {
+		ext4_fsblk_t first_block;
+		first_block = ext4_group_first_block_no(sb, 0);
 		if (test_opt(sb, DEBUG))
 			printk(KERN_DEBUG "EXT4-fs: extended group to %llu "
 			       "blocks\n", ext4_blocks_count(es));
-		update_backups(sb, EXT4_SB(sb)->s_sbh->b_blocknr, (char *)es,
-			       sizeof(struct ext4_super_block));
+		update_backups(sb, EXT4_SB(sb)->s_sbh->b_blocknr - first_block,
+			       (char *)es, sizeof(struct ext4_super_block), 0);
 	}
 	return err;
 }
@@ -1631,6 +1753,94 @@
 	return err;
 } /* ext4_group_extend */
 
+
+static int num_desc_blocks(struct super_block *sb, ext4_group_t groups)
+{
+	return (groups + EXT4_DESC_PER_BLOCK(sb) - 1) / EXT4_DESC_PER_BLOCK(sb);
+}
+
+/*
+ * Release the resize inode and drop the resize_inode feature if there
+ * are no more reserved gdt blocks, and then convert the file system
+ * to enable meta_bg
+ */
+static int ext4_convert_meta_bg(struct super_block *sb, struct inode *inode)
+{
+	handle_t *handle;
+	struct ext4_sb_info *sbi = EXT4_SB(sb);
+	struct ext4_super_block *es = sbi->s_es;
+	struct ext4_inode_info *ei = EXT4_I(inode);
+	ext4_fsblk_t nr;
+	int i, ret, err = 0;
+	int credits = 1;
+
+	ext4_msg(sb, KERN_INFO, "Converting file system to meta_bg");
+	if (inode) {
+		if (es->s_reserved_gdt_blocks) {
+			ext4_error(sb, "Unexpected non-zero "
+				   "s_reserved_gdt_blocks");
+			return -EPERM;
+		}
+
+		/* Do a quick sanity check of the resize inode */
+		if (inode->i_blocks != 1 << (inode->i_blkbits - 9))
+			goto invalid_resize_inode;
+		for (i = 0; i < EXT4_N_BLOCKS; i++) {
+			if (i == EXT4_DIND_BLOCK) {
+				if (ei->i_data[i])
+					continue;
+				else
+					goto invalid_resize_inode;
+			}
+			if (ei->i_data[i])
+				goto invalid_resize_inode;
+		}
+		credits += 3;	/* block bitmap, bg descriptor, resize inode */
+	}
+
+	handle = ext4_journal_start_sb(sb, credits);
+	if (IS_ERR(handle))
+		return PTR_ERR(handle);
+
+	err = ext4_journal_get_write_access(handle, sbi->s_sbh);
+	if (err)
+		goto errout;
+
+	EXT4_CLEAR_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_RESIZE_INODE);
+	EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG);
+	sbi->s_es->s_first_meta_bg =
+		cpu_to_le32(num_desc_blocks(sb, sbi->s_groups_count));
+
+	err = ext4_handle_dirty_super(handle, sb);
+	if (err) {
+		ext4_std_error(sb, err);
+		goto errout;
+	}
+
+	if (inode) {
+		nr = le32_to_cpu(ei->i_data[EXT4_DIND_BLOCK]);
+		ext4_free_blocks(handle, inode, NULL, nr, 1,
+				 EXT4_FREE_BLOCKS_METADATA |
+				 EXT4_FREE_BLOCKS_FORGET);
+		ei->i_data[EXT4_DIND_BLOCK] = 0;
+		inode->i_blocks = 0;
+
+		err = ext4_mark_inode_dirty(handle, inode);
+		if (err)
+			ext4_std_error(sb, err);
+	}
+
+errout:
+	ret = ext4_journal_stop(handle);
+	if (!err)
+		err = ret;
+	return ret;
+
+invalid_resize_inode:
+	ext4_error(sb, "corrupted/inconsistent resize inode");
+	return -EINVAL;
+}
+
 /*
  * ext4_resize_fs() resizes a fs to new size specified by @n_blocks_count
  *
@@ -1643,21 +1853,31 @@
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
 	struct ext4_super_block *es = sbi->s_es;
 	struct buffer_head *bh;
-	struct inode *resize_inode;
-	ext4_fsblk_t o_blocks_count;
-	ext4_group_t o_group;
-	ext4_group_t n_group;
-	ext4_grpblk_t offset, add;
+	struct inode *resize_inode = NULL;
+	ext4_grpblk_t add, offset;
 	unsigned long n_desc_blocks;
 	unsigned long o_desc_blocks;
-	unsigned long desc_blocks;
-	int err = 0, flexbg_size = 1;
+	ext4_group_t o_group;
+	ext4_group_t n_group;
+	ext4_fsblk_t o_blocks_count;
+	ext4_fsblk_t n_blocks_count_retry = 0;
+	unsigned long last_update_time = 0;
+	int err = 0, flexbg_size = 1 << sbi->s_log_groups_per_flex;
+	int meta_bg;
 
+	/* See if the device is actually as big as what was requested */
+	bh = sb_bread(sb, n_blocks_count - 1);
+	if (!bh) {
+		ext4_warning(sb, "can't read last block, resize aborted");
+		return -ENOSPC;
+	}
+	brelse(bh);
+
+retry:
 	o_blocks_count = ext4_blocks_count(es);
 
-	if (test_opt(sb, DEBUG))
-		ext4_msg(sb, KERN_DEBUG, "resizing filesystem from %llu "
-		       "to %llu blocks", o_blocks_count, n_blocks_count);
+	ext4_msg(sb, KERN_INFO, "resizing filesystem from %llu "
+		 "to %llu blocks", o_blocks_count, n_blocks_count);
 
 	if (n_blocks_count < o_blocks_count) {
 		/* On-line shrinking not supported */
@@ -1672,33 +1892,50 @@
 	ext4_get_group_no_and_offset(sb, n_blocks_count - 1, &n_group, &offset);
 	ext4_get_group_no_and_offset(sb, o_blocks_count - 1, &o_group, &offset);
 
-	n_desc_blocks = (n_group + EXT4_DESC_PER_BLOCK(sb)) /
-			EXT4_DESC_PER_BLOCK(sb);
-	o_desc_blocks = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) /
-			EXT4_DESC_PER_BLOCK(sb);
-	desc_blocks = n_desc_blocks - o_desc_blocks;
+	n_desc_blocks = num_desc_blocks(sb, n_group + 1);
+	o_desc_blocks = num_desc_blocks(sb, sbi->s_groups_count);
 
-	if (desc_blocks &&
-	    (!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_RESIZE_INODE) ||
-	     le16_to_cpu(es->s_reserved_gdt_blocks) < desc_blocks)) {
-		ext4_warning(sb, "No reserved GDT blocks, can't resize");
-		return -EPERM;
+	meta_bg = EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG);
+
+	if (EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_RESIZE_INODE)) {
+		if (meta_bg) {
+			ext4_error(sb, "resize_inode and meta_bg enabled "
+				   "simultaneously");
+			return -EINVAL;
+		}
+		if (n_desc_blocks > o_desc_blocks +
+		    le16_to_cpu(es->s_reserved_gdt_blocks)) {
+			n_blocks_count_retry = n_blocks_count;
+			n_desc_blocks = o_desc_blocks +
+				le16_to_cpu(es->s_reserved_gdt_blocks);
+			n_group = n_desc_blocks * EXT4_DESC_PER_BLOCK(sb);
+			n_blocks_count = n_group * EXT4_BLOCKS_PER_GROUP(sb);
+			n_group--; /* set to last group number */
+		}
+
+		if (!resize_inode)
+			resize_inode = ext4_iget(sb, EXT4_RESIZE_INO);
+		if (IS_ERR(resize_inode)) {
+			ext4_warning(sb, "Error opening resize inode");
+			return PTR_ERR(resize_inode);
+		}
 	}
 
-	resize_inode = ext4_iget(sb, EXT4_RESIZE_INO);
-	if (IS_ERR(resize_inode)) {
-		ext4_warning(sb, "Error opening resize inode");
-		return PTR_ERR(resize_inode);
+	if ((!resize_inode && !meta_bg) || n_blocks_count == o_blocks_count) {
+		err = ext4_convert_meta_bg(sb, resize_inode);
+		if (err)
+			goto out;
+		if (resize_inode) {
+			iput(resize_inode);
+			resize_inode = NULL;
+		}
+		if (n_blocks_count_retry) {
+			n_blocks_count = n_blocks_count_retry;
+			n_blocks_count_retry = 0;
+			goto retry;
+		}
 	}
 
-	/* See if the device is actually as big as what was requested */
-	bh = sb_bread(sb, n_blocks_count - 1);
-	if (!bh) {
-		ext4_warning(sb, "can't read last block, resize aborted");
-		return -ENOSPC;
-	}
-	brelse(bh);
-
 	/* extend the last group */
 	if (n_group == o_group)
 		add = n_blocks_count - o_blocks_count;
@@ -1710,12 +1947,15 @@
 			goto out;
 	}
 
-	if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG) &&
-	    es->s_log_groups_per_flex)
-		flexbg_size = 1 << es->s_log_groups_per_flex;
+	if (ext4_blocks_count(es) == n_blocks_count)
+		goto out;
 
-	o_blocks_count = ext4_blocks_count(es);
-	if (o_blocks_count == n_blocks_count)
+	err = ext4_alloc_flex_bg_array(sb, n_group + 1);
+	if (err)
+		return err;
+
+	err = ext4_mb_alloc_groupinfo(sb, n_group + 1);
+	if (err)
 		goto out;
 
 	flex_gd = alloc_flex_gd(flexbg_size);
@@ -1729,19 +1969,33 @@
 	 */
 	while (ext4_setup_next_flex_gd(sb, flex_gd, n_blocks_count,
 					      flexbg_size)) {
-		ext4_alloc_group_tables(sb, flex_gd, flexbg_size);
+		if (jiffies - last_update_time > HZ * 10) {
+			if (last_update_time)
+				ext4_msg(sb, KERN_INFO,
+					 "resized to %llu blocks",
+					 ext4_blocks_count(es));
+			last_update_time = jiffies;
+		}
+		if (ext4_alloc_group_tables(sb, flex_gd, flexbg_size) != 0)
+			break;
 		err = ext4_flex_group_add(sb, resize_inode, flex_gd);
 		if (unlikely(err))
 			break;
 	}
 
+	if (!err && n_blocks_count_retry) {
+		n_blocks_count = n_blocks_count_retry;
+		n_blocks_count_retry = 0;
+		free_flex_gd(flex_gd);
+		flex_gd = NULL;
+		goto retry;
+	}
+
 out:
 	if (flex_gd)
 		free_flex_gd(flex_gd);
-
-	iput(resize_inode);
-	if (test_opt(sb, DEBUG))
-		ext4_msg(sb, KERN_DEBUG, "resized filesystem from %llu "
-		       "upto %llu blocks", o_blocks_count, n_blocks_count);
+	if (resize_inode != NULL)
+		iput(resize_inode);
+	ext4_msg(sb, KERN_INFO, "resized filesystem to %llu", n_blocks_count);
 	return err;
 }
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 69c55d4..7265a03 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -420,7 +420,7 @@
 	 */
 	if (!es->s_error_count)
 		mod_timer(&EXT4_SB(sb)->s_err_report, jiffies + 24*60*60*HZ);
-	es->s_error_count = cpu_to_le32(le32_to_cpu(es->s_error_count) + 1);
+	le32_add_cpu(&es->s_error_count, 1);
 }
 
 static void save_error_info(struct super_block *sb, const char *func,
@@ -850,7 +850,6 @@
 	flush_workqueue(sbi->dio_unwritten_wq);
 	destroy_workqueue(sbi->dio_unwritten_wq);
 
-	lock_super(sb);
 	if (sbi->s_journal) {
 		err = jbd2_journal_destroy(sbi->s_journal);
 		sbi->s_journal = NULL;
@@ -917,7 +916,6 @@
 	 * Now that we are completely done shutting down the
 	 * superblock, we need to actually destroy the kobject.
 	 */
-	unlock_super(sb);
 	kobject_put(&sbi->s_kobj);
 	wait_for_completion(&sbi->s_kobj_unregister);
 	if (sbi->s_chksum_driver)
@@ -956,11 +954,10 @@
 	ei->jinode = NULL;
 	INIT_LIST_HEAD(&ei->i_completed_io_list);
 	spin_lock_init(&ei->i_completed_io_lock);
-	ei->cur_aio_dio = NULL;
 	ei->i_sync_tid = 0;
 	ei->i_datasync_tid = 0;
 	atomic_set(&ei->i_ioend_count, 0);
-	atomic_set(&ei->i_aiodio_unwritten, 0);
+	atomic_set(&ei->i_unwritten, 0);
 
 	return &ei->vfs_inode;
 }
@@ -1224,6 +1221,7 @@
 	Opt_inode_readahead_blks, Opt_journal_ioprio,
 	Opt_dioread_nolock, Opt_dioread_lock,
 	Opt_discard, Opt_nodiscard, Opt_init_itable, Opt_noinit_itable,
+	Opt_max_dir_size_kb,
 };
 
 static const match_table_t tokens = {
@@ -1297,6 +1295,7 @@
 	{Opt_init_itable, "init_itable=%u"},
 	{Opt_init_itable, "init_itable"},
 	{Opt_noinit_itable, "noinit_itable"},
+	{Opt_max_dir_size_kb, "max_dir_size_kb=%u"},
 	{Opt_removed, "check=none"},	/* mount option from ext2/3 */
 	{Opt_removed, "nocheck"},	/* mount option from ext2/3 */
 	{Opt_removed, "reservation"},	/* mount option from ext2/3 */
@@ -1477,6 +1476,7 @@
 	{Opt_jqfmt_vfsold, QFMT_VFS_OLD, MOPT_QFMT},
 	{Opt_jqfmt_vfsv0, QFMT_VFS_V0, MOPT_QFMT},
 	{Opt_jqfmt_vfsv1, QFMT_VFS_V1, MOPT_QFMT},
+	{Opt_max_dir_size_kb, 0, MOPT_GTE0},
 	{Opt_err, 0, 0}
 };
 
@@ -1592,6 +1592,8 @@
 			if (!args->from)
 				arg = EXT4_DEF_LI_WAIT_MULT;
 			sbi->s_li_wait_mult = arg;
+		} else if (token == Opt_max_dir_size_kb) {
+			sbi->s_max_dir_size_kb = arg;
 		} else if (token == Opt_stripe) {
 			sbi->s_stripe = arg;
 		} else if (m->flags & MOPT_DATAJ) {
@@ -1664,7 +1666,7 @@
 		 * Initialize args struct so we know whether arg was
 		 * found; some options take optional arguments.
 		 */
-		args[0].to = args[0].from = 0;
+		args[0].to = args[0].from = NULL;
 		token = match_token(p, tokens, args);
 		if (handle_mount_opt(sb, p, token, args, journal_devnum,
 				     journal_ioprio, is_remount) < 0)
@@ -1740,7 +1742,7 @@
 
 static const char *token2str(int token)
 {
-	static const struct match_token *t;
+	const struct match_token *t;
 
 	for (t = tokens; t->token != Opt_err; t++)
 		if (t->token == token && !strchr(t->pattern, '='))
@@ -1823,6 +1825,8 @@
 	if (nodefs || (test_opt(sb, INIT_INODE_TABLE) &&
 		       (sbi->s_li_wait_mult != EXT4_DEF_LI_WAIT_MULT)))
 		SEQ_OPTS_PRINT("init_itable=%u", sbi->s_li_wait_mult);
+	if (nodefs || sbi->s_max_dir_size_kb)
+		SEQ_OPTS_PRINT("max_dir_size_kb=%u", sbi->s_max_dir_size_kb);
 
 	ext4_show_quota_options(seq, sb);
 	return 0;
@@ -1914,15 +1918,45 @@
 	return res;
 }
 
+int ext4_alloc_flex_bg_array(struct super_block *sb, ext4_group_t ngroup)
+{
+	struct ext4_sb_info *sbi = EXT4_SB(sb);
+	struct flex_groups *new_groups;
+	int size;
+
+	if (!sbi->s_log_groups_per_flex)
+		return 0;
+
+	size = ext4_flex_group(sbi, ngroup - 1) + 1;
+	if (size <= sbi->s_flex_groups_allocated)
+		return 0;
+
+	size = roundup_pow_of_two(size * sizeof(struct flex_groups));
+	new_groups = ext4_kvzalloc(size, GFP_KERNEL);
+	if (!new_groups) {
+		ext4_msg(sb, KERN_ERR, "not enough memory for %d flex groups",
+			 size / (int) sizeof(struct flex_groups));
+		return -ENOMEM;
+	}
+
+	if (sbi->s_flex_groups) {
+		memcpy(new_groups, sbi->s_flex_groups,
+		       (sbi->s_flex_groups_allocated *
+			sizeof(struct flex_groups)));
+		ext4_kvfree(sbi->s_flex_groups);
+	}
+	sbi->s_flex_groups = new_groups;
+	sbi->s_flex_groups_allocated = size / sizeof(struct flex_groups);
+	return 0;
+}
+
 static int ext4_fill_flex_info(struct super_block *sb)
 {
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
 	struct ext4_group_desc *gdp = NULL;
-	ext4_group_t flex_group_count;
 	ext4_group_t flex_group;
 	unsigned int groups_per_flex = 0;
-	size_t size;
-	int i;
+	int i, err;
 
 	sbi->s_log_groups_per_flex = sbi->s_es->s_log_groups_per_flex;
 	if (sbi->s_log_groups_per_flex < 1 || sbi->s_log_groups_per_flex > 31) {
@@ -1931,17 +1965,9 @@
 	}
 	groups_per_flex = 1 << sbi->s_log_groups_per_flex;
 
-	/* We allocate both existing and potentially added groups */
-	flex_group_count = ((sbi->s_groups_count + groups_per_flex - 1) +
-			((le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) + 1) <<
-			      EXT4_DESC_PER_BLOCK_BITS(sb))) / groups_per_flex;
-	size = flex_group_count * sizeof(struct flex_groups);
-	sbi->s_flex_groups = ext4_kvzalloc(size, GFP_KERNEL);
-	if (sbi->s_flex_groups == NULL) {
-		ext4_msg(sb, KERN_ERR, "not enough memory for %u flex groups",
-			 flex_group_count);
+	err = ext4_alloc_flex_bg_array(sb, sbi->s_groups_count);
+	if (err)
 		goto failed;
-	}
 
 	for (i = 0; i < sbi->s_groups_count; i++) {
 		gdp = ext4_get_group_desc(sb, i, NULL);
@@ -2144,10 +2170,12 @@
 	}
 
 	if (EXT4_SB(sb)->s_mount_state & EXT4_ERROR_FS) {
-		if (es->s_last_orphan)
+		/* don't clear list on RO mount w/ errors */
+		if (es->s_last_orphan && !(s_flags & MS_RDONLY)) {
 			jbd_debug(1, "Errors on filesystem, "
 				  "clearing orphan list.\n");
-		es->s_last_orphan = 0;
+			es->s_last_orphan = 0;
+		}
 		jbd_debug(1, "Skipping orphan recovery on fs with errors.\n");
 		return;
 	}
@@ -2528,6 +2556,7 @@
 EXT4_RW_ATTR_SBI_UI(mb_stream_req, s_mb_stream_request);
 EXT4_RW_ATTR_SBI_UI(mb_group_prealloc, s_mb_group_prealloc);
 EXT4_RW_ATTR_SBI_UI(max_writeback_mb_bump, s_max_writeback_mb_bump);
+EXT4_RW_ATTR_SBI_UI(extent_max_zeroout_kb, s_extent_max_zeroout_kb);
 EXT4_ATTR(trigger_fs_error, 0200, NULL, trigger_test_error);
 
 static struct attribute *ext4_attrs[] = {
@@ -2543,6 +2572,7 @@
 	ATTR_LIST(mb_stream_req),
 	ATTR_LIST(mb_group_prealloc),
 	ATTR_LIST(max_writeback_mb_bump),
+	ATTR_LIST(extent_max_zeroout_kb),
 	ATTR_LIST(trigger_fs_error),
 	NULL,
 };
@@ -2550,10 +2580,12 @@
 /* Features this copy of ext4 supports */
 EXT4_INFO_ATTR(lazy_itable_init);
 EXT4_INFO_ATTR(batched_discard);
+EXT4_INFO_ATTR(meta_bg_resize);
 
 static struct attribute *ext4_feat_attrs[] = {
 	ATTR_LIST(lazy_itable_init),
 	ATTR_LIST(batched_discard),
+	ATTR_LIST(meta_bg_resize),
 	NULL,
 };
 
@@ -3374,7 +3406,7 @@
 	 * enable delayed allocation by default
 	 * Use -o nodelalloc to turn it off
 	 */
-	if (!IS_EXT3_SB(sb) &&
+	if (!IS_EXT3_SB(sb) && !IS_EXT2_SB(sb) &&
 	    ((def_mount_opts & EXT4_DEFM_NODELALLOC) == 0))
 		set_opt(sb, DELALLOC);
 
@@ -3743,6 +3775,7 @@
 
 	sbi->s_stripe = ext4_get_stripe_size(sbi);
 	sbi->s_max_writeback_mb_bump = 128;
+	sbi->s_extent_max_zeroout_kb = 32;
 
 	/*
 	 * set up enough so that it can read an inode
@@ -4519,11 +4552,9 @@
 	if (sb->s_flags & MS_RDONLY)
 		return 0;
 
-	lock_super(sb);
 	/* Reset the needs_recovery flag before the fs is unlocked. */
 	EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
 	ext4_commit_super(sb, 1);
-	unlock_super(sb);
 	return 0;
 }
 
@@ -4559,7 +4590,6 @@
 	char *orig_data = kstrdup(data, GFP_KERNEL);
 
 	/* Store the original options */
-	lock_super(sb);
 	old_sb_flags = sb->s_flags;
 	old_opts.s_mount_opt = sbi->s_mount_opt;
 	old_opts.s_mount_opt2 = sbi->s_mount_opt2;
@@ -4701,7 +4731,6 @@
 	if (sbi->s_journal == NULL)
 		ext4_commit_super(sb, 1);
 
-	unlock_super(sb);
 #ifdef CONFIG_QUOTA
 	/* Release old quota file names */
 	for (i = 0; i < MAXQUOTAS; i++)
@@ -4714,10 +4743,8 @@
 		else if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
 					EXT4_FEATURE_RO_COMPAT_QUOTA)) {
 			err = ext4_enable_quotas(sb);
-			if (err) {
-				lock_super(sb);
+			if (err)
 				goto restore_opts;
-			}
 		}
 	}
 #endif
@@ -4744,7 +4771,6 @@
 		sbi->s_qf_names[i] = old_opts.s_qf_names[i];
 	}
 #endif
-	unlock_super(sb);
 	kfree(orig_data);
 	return err;
 }
@@ -5269,8 +5295,10 @@
 	if (err)
 		goto out6;
 	ext4_kset = kset_create_and_add("ext4", NULL, fs_kobj);
-	if (!ext4_kset)
+	if (!ext4_kset) {
+		err = -ENOMEM;
 		goto out5;
+	}
 	ext4_proc_root = proc_mkdir("fs/ext4", NULL);
 
 	err = ext4_init_feat_adverts();
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
index bca6d0a..2a18234 100644
--- a/fs/fat/dir.c
+++ b/fs/fat/dir.c
@@ -571,7 +571,7 @@
 	int short_len = 0, fill_len = 0;
 	int ret = 0;
 
-	lock_super(sb);
+	mutex_lock(&sbi->s_lock);
 
 	cpos = filp->f_pos;
 	/* Fake . and .. for the root directory. */
@@ -693,7 +693,7 @@
 	if (unicode)
 		__putname(unicode);
 out:
-	unlock_super(sb);
+	mutex_unlock(&sbi->s_lock);
 	return ret;
 }
 
diff --git a/fs/fat/fat.h b/fs/fat/fat.h
index ca7e8f8..623f36f 100644
--- a/fs/fat/fat.h
+++ b/fs/fat/fat.h
@@ -71,8 +71,9 @@
 	unsigned long root_cluster;   /* first cluster of the root directory */
 	unsigned long fsinfo_sector;  /* sector number of FAT32 fsinfo */
 	struct mutex fat_lock;
-	unsigned int prev_free;       /* previously allocated cluster number */
-	unsigned int free_clusters;   /* -1 if undefined */
+	struct mutex s_lock;
+	unsigned int prev_free;      /* previously allocated cluster number */
+	unsigned int free_clusters;  /* -1 if undefined */
 	unsigned int free_clus_valid; /* is free_clusters valid? */
 	struct fat_mount_options options;
 	struct nls_table *nls_disk;   /* Codepage used on disk */
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 76f60c6..5bafaad 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -673,9 +673,9 @@
 	if (inode->i_ino == MSDOS_FSINFO_INO) {
 		struct super_block *sb = inode->i_sb;
 
-		lock_super(sb);
+		mutex_lock(&MSDOS_SB(sb)->s_lock);
 		err = fat_clusters_flush(sb);
-		unlock_super(sb);
+		mutex_unlock(&MSDOS_SB(sb)->s_lock);
 	} else
 		err = __fat_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
 
@@ -1268,6 +1268,7 @@
 		b = (struct fat_boot_sector *) bh->b_data;
 	}
 
+	mutex_init(&sbi->s_lock);
 	sbi->cluster_size = sb->s_blocksize * sbi->sec_per_clus;
 	sbi->cluster_bits = ffs(sbi->cluster_size) - 1;
 	sbi->fats = b->fats;
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c
index c1055e7..e2cfda9 100644
--- a/fs/fat/namei_msdos.c
+++ b/fs/fat/namei_msdos.c
@@ -208,7 +208,7 @@
 	struct inode *inode;
 	int err;
 
-	lock_super(sb);
+	mutex_lock(&MSDOS_SB(sb)->s_lock);
 	err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo);
 	switch (err) {
 	case -ENOENT:
@@ -221,7 +221,7 @@
 	default:
 		inode = ERR_PTR(err);
 	}
-	unlock_super(sb);
+	mutex_unlock(&MSDOS_SB(sb)->s_lock);
 	return d_splice_alias(inode, dentry);
 }
 
@@ -273,7 +273,7 @@
 	unsigned char msdos_name[MSDOS_NAME];
 	int err, is_hid;
 
-	lock_super(sb);
+	mutex_lock(&MSDOS_SB(sb)->s_lock);
 
 	err = msdos_format_name(dentry->d_name.name, dentry->d_name.len,
 				msdos_name, &MSDOS_SB(sb)->options);
@@ -302,7 +302,7 @@
 
 	d_instantiate(dentry, inode);
 out:
-	unlock_super(sb);
+	mutex_unlock(&MSDOS_SB(sb)->s_lock);
 	if (!err)
 		err = fat_flush_inodes(sb, dir, inode);
 	return err;
@@ -316,7 +316,7 @@
 	struct fat_slot_info sinfo;
 	int err;
 
-	lock_super(sb);
+	mutex_lock(&MSDOS_SB(sb)->s_lock);
 	/*
 	 * Check whether the directory is not in use, then check
 	 * whether it is empty.
@@ -337,7 +337,7 @@
 	inode->i_ctime = CURRENT_TIME_SEC;
 	fat_detach(inode);
 out:
-	unlock_super(sb);
+	mutex_unlock(&MSDOS_SB(sb)->s_lock);
 	if (!err)
 		err = fat_flush_inodes(sb, dir, inode);
 
@@ -354,7 +354,7 @@
 	struct timespec ts;
 	int err, is_hid, cluster;
 
-	lock_super(sb);
+	mutex_lock(&MSDOS_SB(sb)->s_lock);
 
 	err = msdos_format_name(dentry->d_name.name, dentry->d_name.len,
 				msdos_name, &MSDOS_SB(sb)->options);
@@ -392,14 +392,14 @@
 
 	d_instantiate(dentry, inode);
 
-	unlock_super(sb);
+	mutex_unlock(&MSDOS_SB(sb)->s_lock);
 	fat_flush_inodes(sb, dir, inode);
 	return 0;
 
 out_free:
 	fat_free_clusters(dir, cluster);
 out:
-	unlock_super(sb);
+	mutex_unlock(&MSDOS_SB(sb)->s_lock);
 	return err;
 }
 
@@ -411,7 +411,7 @@
 	struct fat_slot_info sinfo;
 	int err;
 
-	lock_super(sb);
+	mutex_lock(&MSDOS_SB(sb)->s_lock);
 	err = msdos_find(dir, dentry->d_name.name, dentry->d_name.len, &sinfo);
 	if (err)
 		goto out;
@@ -423,7 +423,7 @@
 	inode->i_ctime = CURRENT_TIME_SEC;
 	fat_detach(inode);
 out:
-	unlock_super(sb);
+	mutex_unlock(&MSDOS_SB(sb)->s_lock);
 	if (!err)
 		err = fat_flush_inodes(sb, dir, inode);
 
@@ -606,7 +606,7 @@
 	unsigned char old_msdos_name[MSDOS_NAME], new_msdos_name[MSDOS_NAME];
 	int err, is_hid;
 
-	lock_super(sb);
+	mutex_lock(&MSDOS_SB(sb)->s_lock);
 
 	err = msdos_format_name(old_dentry->d_name.name,
 				old_dentry->d_name.len, old_msdos_name,
@@ -625,7 +625,7 @@
 	err = do_msdos_rename(old_dir, old_msdos_name, old_dentry,
 			      new_dir, new_msdos_name, new_dentry, is_hid);
 out:
-	unlock_super(sb);
+	mutex_unlock(&MSDOS_SB(sb)->s_lock);
 	if (!err)
 		err = fat_flush_inodes(sb, old_dir, new_dir);
 	return err;
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
index e535dd7..ac959d6 100644
--- a/fs/fat/namei_vfat.c
+++ b/fs/fat/namei_vfat.c
@@ -721,7 +721,7 @@
 	struct dentry *alias;
 	int err;
 
-	lock_super(sb);
+	mutex_lock(&MSDOS_SB(sb)->s_lock);
 
 	err = vfat_find(dir, &dentry->d_name, &sinfo);
 	if (err) {
@@ -752,13 +752,13 @@
 		if (!S_ISDIR(inode->i_mode))
 			d_move(alias, dentry);
 		iput(inode);
-		unlock_super(sb);
+		mutex_unlock(&MSDOS_SB(sb)->s_lock);
 		return alias;
 	} else
 		dput(alias);
 
 out:
-	unlock_super(sb);
+	mutex_unlock(&MSDOS_SB(sb)->s_lock);
 	dentry->d_time = dentry->d_parent->d_inode->i_version;
 	dentry = d_splice_alias(inode, dentry);
 	if (dentry)
@@ -766,7 +766,7 @@
 	return dentry;
 
 error:
-	unlock_super(sb);
+	mutex_unlock(&MSDOS_SB(sb)->s_lock);
 	return ERR_PTR(err);
 }
 
@@ -779,7 +779,7 @@
 	struct timespec ts;
 	int err;
 
-	lock_super(sb);
+	mutex_lock(&MSDOS_SB(sb)->s_lock);
 
 	ts = CURRENT_TIME_SEC;
 	err = vfat_add_entry(dir, &dentry->d_name, 0, 0, &ts, &sinfo);
@@ -800,7 +800,7 @@
 	dentry->d_time = dentry->d_parent->d_inode->i_version;
 	d_instantiate(dentry, inode);
 out:
-	unlock_super(sb);
+	mutex_unlock(&MSDOS_SB(sb)->s_lock);
 	return err;
 }
 
@@ -811,7 +811,7 @@
 	struct fat_slot_info sinfo;
 	int err;
 
-	lock_super(sb);
+	mutex_lock(&MSDOS_SB(sb)->s_lock);
 
 	err = fat_dir_empty(inode);
 	if (err)
@@ -829,7 +829,7 @@
 	inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
 	fat_detach(inode);
 out:
-	unlock_super(sb);
+	mutex_unlock(&MSDOS_SB(sb)->s_lock);
 
 	return err;
 }
@@ -841,7 +841,7 @@
 	struct fat_slot_info sinfo;
 	int err;
 
-	lock_super(sb);
+	mutex_lock(&MSDOS_SB(sb)->s_lock);
 
 	err = vfat_find(dir, &dentry->d_name, &sinfo);
 	if (err)
@@ -854,7 +854,7 @@
 	inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
 	fat_detach(inode);
 out:
-	unlock_super(sb);
+	mutex_unlock(&MSDOS_SB(sb)->s_lock);
 
 	return err;
 }
@@ -867,7 +867,7 @@
 	struct timespec ts;
 	int err, cluster;
 
-	lock_super(sb);
+	mutex_lock(&MSDOS_SB(sb)->s_lock);
 
 	ts = CURRENT_TIME_SEC;
 	cluster = fat_alloc_new_dir(dir, &ts);
@@ -896,13 +896,13 @@
 	dentry->d_time = dentry->d_parent->d_inode->i_version;
 	d_instantiate(dentry, inode);
 
-	unlock_super(sb);
+	mutex_unlock(&MSDOS_SB(sb)->s_lock);
 	return 0;
 
 out_free:
 	fat_free_clusters(dir, cluster);
 out:
-	unlock_super(sb);
+	mutex_unlock(&MSDOS_SB(sb)->s_lock);
 	return err;
 }
 
@@ -921,7 +921,7 @@
 	old_sinfo.bh = sinfo.bh = dotdot_bh = NULL;
 	old_inode = old_dentry->d_inode;
 	new_inode = new_dentry->d_inode;
-	lock_super(sb);
+	mutex_lock(&MSDOS_SB(sb)->s_lock);
 	err = vfat_find(old_dir, &old_dentry->d_name, &old_sinfo);
 	if (err)
 		goto out;
@@ -996,7 +996,7 @@
 	brelse(sinfo.bh);
 	brelse(dotdot_bh);
 	brelse(old_sinfo.bh);
-	unlock_super(sb);
+	mutex_unlock(&MSDOS_SB(sb)->s_lock);
 
 	return err;
 
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 8f704291..71a600a 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -258,7 +258,7 @@
 		err = f_dupfd(arg, filp, 0);
 		break;
 	case F_DUPFD_CLOEXEC:
-		err = f_dupfd(arg, filp, FD_CLOEXEC);
+		err = f_dupfd(arg, filp, O_CLOEXEC);
 		break;
 	case F_GETFD:
 		err = get_close_on_exec(fd) ? FD_CLOEXEC : 0;
diff --git a/fs/file.c b/fs/file.c
index 0f1bda4..d3b5fa8 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -922,6 +922,9 @@
 	if ((flags & ~O_CLOEXEC) != 0)
 		return -EINVAL;
 
+	if (unlikely(oldfd == newfd))
+		return -EINVAL;
+
 	if (newfd >= rlimit(RLIMIT_NOFILE))
 		return -EMFILE;
 
diff --git a/fs/file_table.c b/fs/file_table.c
index dac6792..a72bf9d 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -36,7 +36,7 @@
 	.max_files = NR_FILE
 };
 
-DEFINE_LGLOCK(files_lglock);
+DEFINE_STATIC_LGLOCK(files_lglock);
 
 /* SLAB cache for file structures */
 static struct kmem_cache *filp_cachep __read_mostly;
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 6d46c0d..51ea267 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -63,6 +63,7 @@
 {
 	return test_bit(BDI_writeback_running, &bdi->state);
 }
+EXPORT_SYMBOL(writeback_in_progress);
 
 static inline struct backing_dev_info *inode_to_bdi(struct inode *inode)
 {
@@ -248,7 +249,7 @@
 }
 
 /*
- * Move expired (dirtied after work->older_than_this) dirty inodes from
+ * Move expired (dirtied before work->older_than_this) dirty inodes from
  * @delaying_queue to @dispatch_queue.
  */
 static int move_expired_inodes(struct list_head *delaying_queue,
@@ -438,8 +439,7 @@
  * setting I_SYNC flag and calling inode_sync_complete() to clear it.
  */
 static int
-__writeback_single_inode(struct inode *inode, struct bdi_writeback *wb,
-			 struct writeback_control *wbc)
+__writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
 {
 	struct address_space *mapping = inode->i_mapping;
 	long nr_to_write = wbc->nr_to_write;
@@ -526,7 +526,7 @@
 	inode->i_state |= I_SYNC;
 	spin_unlock(&inode->i_lock);
 
-	ret = __writeback_single_inode(inode, wb, wbc);
+	ret = __writeback_single_inode(inode, wbc);
 
 	spin_lock(&wb->list_lock);
 	spin_lock(&inode->i_lock);
@@ -669,7 +669,7 @@
 		 * We use I_SYNC to pin the inode in memory. While it is set
 		 * evict_inode() will wait so the inode cannot be freed.
 		 */
-		__writeback_single_inode(inode, wb, &wbc);
+		__writeback_single_inode(inode, &wbc);
 
 		work->nr_pages -= write_chunk - wbc.nr_to_write;
 		wrote += write_chunk - wbc.nr_to_write;
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index aba15f1..78d2837 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1379,6 +1379,7 @@
 	.close		= fuse_vma_close,
 	.fault		= filemap_fault,
 	.page_mkwrite	= fuse_page_mkwrite,
+	.remap_pages	= generic_file_remap_pages,
 };
 
 static int fuse_file_mmap(struct file *file, struct vm_area_struct *vma)
diff --git a/fs/gfs2/export.c b/fs/gfs2/export.c
index e8ed6d4..4767774 100644
--- a/fs/gfs2/export.c
+++ b/fs/gfs2/export.c
@@ -161,6 +161,8 @@
 	case GFS2_SMALL_FH_SIZE:
 	case GFS2_LARGE_FH_SIZE:
 	case GFS2_OLD_FH_SIZE:
+		if (fh_len < GFS2_SMALL_FH_SIZE)
+			return NULL;
 		this.no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32;
 		this.no_formal_ino |= be32_to_cpu(fh[1]);
 		this.no_addr = ((u64)be32_to_cpu(fh[2])) << 32;
@@ -180,6 +182,8 @@
 	switch (fh_type) {
 	case GFS2_LARGE_FH_SIZE:
 	case GFS2_OLD_FH_SIZE:
+		if (fh_len < GFS2_LARGE_FH_SIZE)
+			return NULL;
 		parent.no_formal_ino = ((u64)be32_to_cpu(fh[4])) << 32;
 		parent.no_formal_ino |= be32_to_cpu(fh[5]);
 		parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32;
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index 30e2199..0def050 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -492,6 +492,7 @@
 static const struct vm_operations_struct gfs2_vm_ops = {
 	.fault = filemap_fault,
 	.page_mkwrite = gfs2_page_mkwrite,
+	.remap_pages = generic_file_remap_pages,
 };
 
 /**
@@ -526,7 +527,6 @@
 			return error;
 	}
 	vma->vm_ops = &gfs2_vm_ops;
-	vma->vm_flags |= VM_CAN_NONLINEAR;
 
 	return 0;
 }
diff --git a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h
index 1fe7313..9c88da0 100644
--- a/fs/hostfs/hostfs.h
+++ b/fs/hostfs/hostfs.h
@@ -1,7 +1,7 @@
 #ifndef __UM_FS_HOSTFS
 #define __UM_FS_HOSTFS
 
-#include "os.h"
+#include <os.h>
 
 /*
  * These are exactly the same definitions as in fs.h, but the names are
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index 6c9f3a9..457addc 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -16,8 +16,8 @@
 #include <linux/mount.h>
 #include <linux/namei.h>
 #include "hostfs.h"
-#include "init.h"
-#include "kern.h"
+#include <init.h>
+#include <kern.h>
 
 struct hostfs_inode_info {
 	int fd;
@@ -848,9 +848,11 @@
 	    attr->ia_size != i_size_read(inode)) {
 		int error;
 
-		error = vmtruncate(inode, attr->ia_size);
-		if (err)
-			return err;
+		error = inode_newsize_ok(inode, attr->ia_size);
+		if (error)
+			return error;
+
+		truncate_setsize(inode, attr->ia_size);
 	}
 
 	setattr_copy(inode, attr);
diff --git a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c
index a74ad0d..67838f3 100644
--- a/fs/hostfs/hostfs_user.c
+++ b/fs/hostfs/hostfs_user.c
@@ -15,7 +15,6 @@
 #include <sys/types.h>
 #include <sys/vfs.h>
 #include "hostfs.h"
-#include "os.h"
 #include <utime.h>
 
 static void stat64_to_hostfs(const struct stat64 *buf, struct hostfs_stat *p)
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index bc28bf07..a307622 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -398,7 +398,6 @@
 	*flags |= MS_NOATIME;
 	
 	hpfs_lock(s);
-	lock_super(s);
 	uid = sbi->sb_uid; gid = sbi->sb_gid;
 	umask = 0777 & ~sbi->sb_mode;
 	lowercase = sbi->sb_lowercase;
@@ -431,12 +430,10 @@
 
 	replace_mount_options(s, new_opts);
 
-	unlock_super(s);
 	hpfs_unlock(s);
 	return 0;
 
 out_err:
-	unlock_super(s);
 	hpfs_unlock(s);
 	kfree(new_opts);
 	return -EINVAL;
diff --git a/fs/hppfs/hppfs.c b/fs/hppfs/hppfs.c
index c1dffe4..78f21f8 100644
--- a/fs/hppfs/hppfs.c
+++ b/fs/hppfs/hppfs.c
@@ -18,7 +18,7 @@
 #include <linux/pid_namespace.h>
 #include <linux/namei.h>
 #include <asm/uaccess.h>
-#include "os.h"
+#include <os.h>
 
 static struct inode *get_inode(struct super_block *, struct dentry *);
 
@@ -674,7 +674,7 @@
 
 	if (!inode) {
 		dput(dentry);
-		return ERR_PTR(-ENOMEM);
+		return NULL;
 	}
 
 	if (S_ISDIR(dentry->d_inode->i_mode)) {
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 9460120..c5bc355 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -110,7 +110,7 @@
 	 * way when do_mmap_pgoff unwinds (may be important on powerpc
 	 * and ia64).
 	 */
-	vma->vm_flags |= VM_HUGETLB | VM_RESERVED;
+	vma->vm_flags |= VM_HUGETLB | VM_DONTEXPAND | VM_DONTDUMP;
 	vma->vm_ops = &hugetlb_vm_ops;
 
 	if (vma->vm_pgoff & (~huge_page_mask(h) >> PAGE_SHIFT))
@@ -397,17 +397,16 @@
 }
 
 static inline void
-hugetlb_vmtruncate_list(struct prio_tree_root *root, pgoff_t pgoff)
+hugetlb_vmtruncate_list(struct rb_root *root, pgoff_t pgoff)
 {
 	struct vm_area_struct *vma;
-	struct prio_tree_iter iter;
 
-	vma_prio_tree_foreach(vma, &iter, root, pgoff, ULONG_MAX) {
+	vma_interval_tree_foreach(vma, root, pgoff, ULONG_MAX) {
 		unsigned long v_offset;
 
 		/*
 		 * Can the expression below overflow on 32-bit arches?
-		 * No, because the prio_tree returns us only those vmas
+		 * No, because the interval tree returns us only those vmas
 		 * which overlap the truncated area starting at pgoff,
 		 * and no vma on a 32-bit arch can span beyond the 4GB.
 		 */
@@ -432,7 +431,7 @@
 
 	i_size_write(inode, offset);
 	mutex_lock(&mapping->i_mmap_mutex);
-	if (!prio_tree_empty(&mapping->i_mmap))
+	if (!RB_EMPTY_ROOT(&mapping->i_mmap))
 		hugetlb_vmtruncate_list(&mapping->i_mmap, pgoff);
 	mutex_unlock(&mapping->i_mmap_mutex);
 	truncate_hugepages(inode, offset);
diff --git a/fs/inode.c b/fs/inode.c
index ac8d904..b03c719 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -348,7 +348,7 @@
 	mutex_init(&mapping->i_mmap_mutex);
 	INIT_LIST_HEAD(&mapping->private_list);
 	spin_lock_init(&mapping->private_lock);
-	INIT_RAW_PRIO_TREE_ROOT(&mapping->i_mmap);
+	mapping->i_mmap = RB_ROOT;
 	INIT_LIST_HEAD(&mapping->i_mmap_nonlinear);
 }
 EXPORT_SYMBOL(address_space_init_once);
diff --git a/fs/isofs/export.c b/fs/isofs/export.c
index 1d38044..2b4f235 100644
--- a/fs/isofs/export.c
+++ b/fs/isofs/export.c
@@ -175,7 +175,7 @@
 {
 	struct isofs_fid *ifid = (struct isofs_fid *)fid;
 
-	if (fh_type != 2)
+	if (fh_len < 2 || fh_type != 2)
 		return NULL;
 
 	return isofs_export_iget(sb,
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index af5280f..3091d42 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -1014,17 +1014,35 @@
 		 * there's no point in keeping a checkpoint record for
 		 * it. */
 
-		/* A buffer which has been freed while still being
-		 * journaled by a previous transaction may end up still
-		 * being dirty here, but we want to avoid writing back
-		 * that buffer in the future after the "add to orphan"
-		 * operation been committed,  That's not only a performance
-		 * gain, it also stops aliasing problems if the buffer is
-		 * left behind for writeback and gets reallocated for another
-		 * use in a different page. */
-		if (buffer_freed(bh) && !jh->b_next_transaction) {
-			clear_buffer_freed(bh);
-			clear_buffer_jbddirty(bh);
+		/*
+		* A buffer which has been freed while still being journaled by
+		* a previous transaction.
+		*/
+		if (buffer_freed(bh)) {
+			/*
+			 * If the running transaction is the one containing
+			 * "add to orphan" operation (b_next_transaction !=
+			 * NULL), we have to wait for that transaction to
+			 * commit before we can really get rid of the buffer.
+			 * So just clear b_modified to not confuse transaction
+			 * credit accounting and refile the buffer to
+			 * BJ_Forget of the running transaction. If the just
+			 * committed transaction contains "add to orphan"
+			 * operation, we can completely invalidate the buffer
+			 * now. We are rather through in that since the
+			 * buffer may be still accessible when blocksize <
+			 * pagesize and it is attached to the last partial
+			 * page.
+			 */
+			jh->b_modified = 0;
+			if (!jh->b_next_transaction) {
+				clear_buffer_freed(bh);
+				clear_buffer_jbddirty(bh);
+				clear_buffer_mapped(bh);
+				clear_buffer_new(bh);
+				clear_buffer_req(bh);
+				bh->b_bdev = NULL;
+			}
 		}
 
 		if (buffer_jbddirty(bh)) {
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index e149b99..484b8d1 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -1354,6 +1354,11 @@
 
 	BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex));
 	read_lock(&journal->j_state_lock);
+	/* Is it already empty? */
+	if (sb->s_start == 0) {
+		read_unlock(&journal->j_state_lock);
+		return;
+	}
 	jbd_debug(1, "JBD2: Marking journal as empty (seq %d)\n",
 		  journal->j_tail_sequence);
 
diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c
index 0131e43..626846b 100644
--- a/fs/jbd2/recovery.c
+++ b/fs/jbd2/recovery.c
@@ -289,8 +289,11 @@
 	if (!err)
 		err = err2;
 	/* Make sure all replayed data is on permanent storage */
-	if (journal->j_flags & JBD2_BARRIER)
-		blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL);
+	if (journal->j_flags & JBD2_BARRIER) {
+		err2 = blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL);
+		if (!err)
+			err = err2;
+	}
 	return err;
 }
 
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index fb1ab953..a74ba46 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -1841,15 +1841,16 @@
  * We're outside-transaction here.  Either or both of j_running_transaction
  * and j_committing_transaction may be NULL.
  */
-static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
+static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh,
+				int partial_page)
 {
 	transaction_t *transaction;
 	struct journal_head *jh;
 	int may_free = 1;
-	int ret;
 
 	BUFFER_TRACE(bh, "entry");
 
+retry:
 	/*
 	 * It is safe to proceed here without the j_list_lock because the
 	 * buffers cannot be stolen by try_to_free_buffers as long as we are
@@ -1878,10 +1879,18 @@
 	 * clear the buffer dirty bit at latest at the moment when the
 	 * transaction marking the buffer as freed in the filesystem
 	 * structures is committed because from that moment on the
-	 * buffer can be reallocated and used by a different page.
+	 * block can be reallocated and used by a different page.
 	 * Since the block hasn't been freed yet but the inode has
 	 * already been added to orphan list, it is safe for us to add
 	 * the buffer to BJ_Forget list of the newest transaction.
+	 *
+	 * Also we have to clear buffer_mapped flag of a truncated buffer
+	 * because the buffer_head may be attached to the page straddling
+	 * i_size (can happen only when blocksize < pagesize) and thus the
+	 * buffer_head can be reused when the file is extended again. So we end
+	 * up keeping around invalidated buffers attached to transactions'
+	 * BJ_Forget list just to stop checkpointing code from cleaning up
+	 * the transaction this buffer was modified in.
 	 */
 	transaction = jh->b_transaction;
 	if (transaction == NULL) {
@@ -1908,13 +1917,9 @@
 			 * committed, the buffer won't be needed any
 			 * longer. */
 			JBUFFER_TRACE(jh, "checkpointed: add to BJ_Forget");
-			ret = __dispose_buffer(jh,
+			may_free = __dispose_buffer(jh,
 					journal->j_running_transaction);
-			jbd2_journal_put_journal_head(jh);
-			spin_unlock(&journal->j_list_lock);
-			jbd_unlock_bh_state(bh);
-			write_unlock(&journal->j_state_lock);
-			return ret;
+			goto zap_buffer;
 		} else {
 			/* There is no currently-running transaction. So the
 			 * orphan record which we wrote for this file must have
@@ -1922,13 +1927,9 @@
 			 * the committing transaction, if it exists. */
 			if (journal->j_committing_transaction) {
 				JBUFFER_TRACE(jh, "give to committing trans");
-				ret = __dispose_buffer(jh,
+				may_free = __dispose_buffer(jh,
 					journal->j_committing_transaction);
-				jbd2_journal_put_journal_head(jh);
-				spin_unlock(&journal->j_list_lock);
-				jbd_unlock_bh_state(bh);
-				write_unlock(&journal->j_state_lock);
-				return ret;
+				goto zap_buffer;
 			} else {
 				/* The orphan record's transaction has
 				 * committed.  We can cleanse this buffer */
@@ -1940,10 +1941,24 @@
 		JBUFFER_TRACE(jh, "on committing transaction");
 		/*
 		 * The buffer is committing, we simply cannot touch
-		 * it. So we just set j_next_transaction to the
-		 * running transaction (if there is one) and mark
-		 * buffer as freed so that commit code knows it should
-		 * clear dirty bits when it is done with the buffer.
+		 * it. If the page is straddling i_size we have to wait
+		 * for commit and try again.
+		 */
+		if (partial_page) {
+			tid_t tid = journal->j_committing_transaction->t_tid;
+
+			jbd2_journal_put_journal_head(jh);
+			spin_unlock(&journal->j_list_lock);
+			jbd_unlock_bh_state(bh);
+			write_unlock(&journal->j_state_lock);
+			jbd2_log_wait_commit(journal, tid);
+			goto retry;
+		}
+		/*
+		 * OK, buffer won't be reachable after truncate. We just set
+		 * j_next_transaction to the running transaction (if there is
+		 * one) and mark buffer as freed so that commit code knows it
+		 * should clear dirty bits when it is done with the buffer.
 		 */
 		set_buffer_freed(bh);
 		if (journal->j_running_transaction && buffer_jbddirty(bh))
@@ -1966,6 +1981,15 @@
 	}
 
 zap_buffer:
+	/*
+	 * This is tricky. Although the buffer is truncated, it may be reused
+	 * if blocksize < pagesize and it is attached to the page straddling
+	 * EOF. Since the buffer might have been added to BJ_Forget list of the
+	 * running transaction, journal_get_write_access() won't clear
+	 * b_modified and credit accounting gets confused. So clear b_modified
+	 * here.
+	 */
+	jh->b_modified = 0;
 	jbd2_journal_put_journal_head(jh);
 zap_buffer_no_jh:
 	spin_unlock(&journal->j_list_lock);
@@ -2017,7 +2041,8 @@
 		if (offset <= curr_off) {
 			/* This block is wholly outside the truncation point */
 			lock_buffer(bh);
-			may_free &= journal_unmap_buffer(journal, bh);
+			may_free &= journal_unmap_buffer(journal, bh,
+							 offset > 0);
 			unlock_buffer(bh);
 		}
 		curr_off = next_off;
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index 1ea349f..ae81b01 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -394,8 +394,11 @@
 }
 
 /* Trivial function to remove the last node in the tree. Which by definition
-   has no right-hand -- so can be removed just by making its only child (if
-   any) take its place under its parent. */
+   has no right-hand child — so can be removed just by making its left-hand
+   child (if any) take its place under its parent. Since this is only done
+   when we're consuming the whole tree, there's no need to use rb_erase()
+   and let it worry about adjusting colours and balancing the tree. That
+   would just be a waste of time. */
 static void eat_last(struct rb_root *root, struct rb_node *node)
 {
 	struct rb_node *parent = rb_parent(node);
@@ -412,12 +415,12 @@
 		link = &parent->rb_right;
 
 	*link = node->rb_left;
-	/* Colour doesn't matter now. Only the parent pointer. */
 	if (node->rb_left)
-		node->rb_left->rb_parent_color = node->rb_parent_color;
+		node->rb_left->__rb_parent_color = node->__rb_parent_color;
 }
 
-/* We put this in reverse order, so we can just use eat_last */
+/* We put the version tree in reverse order, so we can use the same eat_last()
+   function that we use to consume the tmpnode tree (tn_root). */
 static void ver_insert(struct rb_root *ver_root, struct jffs2_tmp_dnode_info *tn)
 {
 	struct rb_node **link = &ver_root->rb_node;
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index ff48795..d3d8799 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -100,6 +100,10 @@
 {
 	struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
 
+#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
+	cancel_delayed_work_sync(&c->wbuf_dwork);
+#endif
+
 	mutex_lock(&c->alloc_sem);
 	jffs2_flush_wbuf_pad(c);
 	mutex_unlock(&c->alloc_sem);
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index 6f4529d..a6597d6 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -1044,10 +1044,10 @@
 	ops.datbuf = NULL;
 
 	ret = mtd_read_oob(c->mtd, jeb->offset, &ops);
-	if (ret || ops.oobretlen != ops.ooblen) {
+	if ((ret && !mtd_is_bitflip(ret)) || ops.oobretlen != ops.ooblen) {
 		pr_err("cannot read OOB for EB at %08x, requested %zd bytes, read %zd bytes, error %d\n",
 		       jeb->offset, ops.ooblen, ops.oobretlen, ret);
-		if (!ret)
+		if (!ret || mtd_is_bitflip(ret))
 			ret = -EIO;
 		return ret;
 	}
@@ -1086,10 +1086,10 @@
 	ops.datbuf = NULL;
 
 	ret = mtd_read_oob(c->mtd, jeb->offset, &ops);
-	if (ret || ops.oobretlen != ops.ooblen) {
+	if ((ret && !mtd_is_bitflip(ret)) || ops.oobretlen != ops.ooblen) {
 		pr_err("cannot read OOB for EB at %08x, requested %zd bytes, read %zd bytes, error %d\n",
 		       jeb->offset, ops.ooblen, ops.oobretlen, ret);
-		if (!ret)
+		if (!ret || mtd_is_bitflip(ret))
 			ret = -EIO;
 		return ret;
 	}
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 7ef14b3..e4fb3ba 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -7,7 +7,6 @@
  */
 
 #include <linux/types.h>
-#include <linux/utsname.h>
 #include <linux/kernel.h>
 #include <linux/ktime.h>
 #include <linux/slab.h>
@@ -19,6 +18,8 @@
 
 #include <asm/unaligned.h>
 
+#include "netns.h"
+
 #define NLMDBG_FACILITY		NLMDBG_MONITOR
 #define NSM_PROGRAM		100024
 #define NSM_VERSION		1
@@ -40,6 +41,7 @@
 	u32			proc;
 
 	char			*mon_name;
+	char			*nodename;
 };
 
 struct nsm_res {
@@ -70,7 +72,7 @@
 	};
 	struct rpc_create_args args = {
 		.net			= net,
-		.protocol		= XPRT_TRANSPORT_UDP,
+		.protocol		= XPRT_TRANSPORT_TCP,
 		.address		= (struct sockaddr *)&sin,
 		.addrsize		= sizeof(sin),
 		.servername		= "rpc.statd",
@@ -83,10 +85,54 @@
 	return rpc_create(&args);
 }
 
-static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
-			 struct net *net)
+static struct rpc_clnt *nsm_client_get(struct net *net)
 {
+	static DEFINE_MUTEX(nsm_create_mutex);
 	struct rpc_clnt	*clnt;
+	struct lockd_net *ln = net_generic(net, lockd_net_id);
+
+	spin_lock(&ln->nsm_clnt_lock);
+	if (ln->nsm_users) {
+		ln->nsm_users++;
+		clnt = ln->nsm_clnt;
+		spin_unlock(&ln->nsm_clnt_lock);
+		goto out;
+	}
+	spin_unlock(&ln->nsm_clnt_lock);
+
+	mutex_lock(&nsm_create_mutex);
+	clnt = nsm_create(net);
+	if (!IS_ERR(clnt)) {
+		ln->nsm_clnt = clnt;
+		smp_wmb();
+		ln->nsm_users = 1;
+	}
+	mutex_unlock(&nsm_create_mutex);
+out:
+	return clnt;
+}
+
+static void nsm_client_put(struct net *net)
+{
+	struct lockd_net *ln = net_generic(net, lockd_net_id);
+	struct rpc_clnt	*clnt = ln->nsm_clnt;
+	int shutdown = 0;
+
+	spin_lock(&ln->nsm_clnt_lock);
+	if (ln->nsm_users) {
+		if (--ln->nsm_users)
+			ln->nsm_clnt = NULL;
+		shutdown = !ln->nsm_users;
+	}
+	spin_unlock(&ln->nsm_clnt_lock);
+
+	if (shutdown)
+		rpc_shutdown_client(clnt);
+}
+
+static int nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res,
+			 struct rpc_clnt *clnt)
+{
 	int		status;
 	struct nsm_args args = {
 		.priv		= &nsm->sm_priv,
@@ -94,31 +140,24 @@
 		.vers		= 3,
 		.proc		= NLMPROC_NSM_NOTIFY,
 		.mon_name	= nsm->sm_mon_name,
+		.nodename	= clnt->cl_nodename,
 	};
 	struct rpc_message msg = {
 		.rpc_argp	= &args,
 		.rpc_resp	= res,
 	};
 
-	clnt = nsm_create(net);
-	if (IS_ERR(clnt)) {
-		status = PTR_ERR(clnt);
-		dprintk("lockd: failed to create NSM upcall transport, "
-				"status=%d\n", status);
-		goto out;
-	}
+	BUG_ON(clnt == NULL);
 
 	memset(res, 0, sizeof(*res));
 
 	msg.rpc_proc = &clnt->cl_procinfo[proc];
-	status = rpc_call_sync(clnt, &msg, 0);
+	status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFTCONN);
 	if (status < 0)
 		dprintk("lockd: NSM upcall RPC failed, status=%d\n",
 				status);
 	else
 		status = 0;
-	rpc_shutdown_client(clnt);
- out:
 	return status;
 }
 
@@ -138,6 +177,7 @@
 	struct nsm_handle *nsm = host->h_nsmhandle;
 	struct nsm_res	res;
 	int		status;
+	struct rpc_clnt *clnt;
 
 	dprintk("lockd: nsm_monitor(%s)\n", nsm->sm_name);
 
@@ -150,7 +190,15 @@
 	 */
 	nsm->sm_mon_name = nsm_use_hostnames ? nsm->sm_name : nsm->sm_addrbuf;
 
-	status = nsm_mon_unmon(nsm, NSMPROC_MON, &res, host->net);
+	clnt = nsm_client_get(host->net);
+	if (IS_ERR(clnt)) {
+		status = PTR_ERR(clnt);
+		dprintk("lockd: failed to create NSM upcall transport, "
+				"status=%d, net=%p\n", status, host->net);
+		return status;
+	}
+
+	status = nsm_mon_unmon(nsm, NSMPROC_MON, &res, clnt);
 	if (unlikely(res.status != 0))
 		status = -EIO;
 	if (unlikely(status < 0)) {
@@ -182,9 +230,11 @@
 
 	if (atomic_read(&nsm->sm_count) == 1
 	 && nsm->sm_monitored && !nsm->sm_sticky) {
+		struct lockd_net *ln = net_generic(host->net, lockd_net_id);
+
 		dprintk("lockd: nsm_unmonitor(%s)\n", nsm->sm_name);
 
-		status = nsm_mon_unmon(nsm, NSMPROC_UNMON, &res, host->net);
+		status = nsm_mon_unmon(nsm, NSMPROC_UNMON, &res, ln->nsm_clnt);
 		if (res.status != 0)
 			status = -EIO;
 		if (status < 0)
@@ -192,6 +242,8 @@
 					nsm->sm_name);
 		else
 			nsm->sm_monitored = 0;
+
+		nsm_client_put(host->net);
 	}
 }
 
@@ -430,7 +482,7 @@
 {
 	__be32 *p;
 
-	encode_nsm_string(xdr, utsname()->nodename);
+	encode_nsm_string(xdr, argp->nodename);
 	p = xdr_reserve_space(xdr, 4 + 4 + 4);
 	*p++ = cpu_to_be32(argp->prog);
 	*p++ = cpu_to_be32(argp->vers);
diff --git a/fs/lockd/netns.h b/fs/lockd/netns.h
index 4eee248..5010b556 100644
--- a/fs/lockd/netns.h
+++ b/fs/lockd/netns.h
@@ -12,6 +12,10 @@
 	struct delayed_work grace_period_end;
 	struct lock_manager lockd_manager;
 	struct list_head grace_list;
+
+	spinlock_t nsm_clnt_lock;
+	unsigned int nsm_users;
+	struct rpc_clnt *nsm_clnt;
 };
 
 extern int lockd_net_id;
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 31a63f8..7e35587 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -596,6 +596,7 @@
 
 	INIT_DELAYED_WORK(&ln->grace_period_end, grace_ender);
 	INIT_LIST_HEAD(&ln->grace_list);
+	spin_lock_init(&ln->nsm_clnt_lock);
 	return 0;
 }
 
diff --git a/fs/namei.c b/fs/namei.c
index aa30d19..c1f18e4 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -692,9 +692,9 @@
 	if (uid_eq(parent->i_uid, inode->i_uid))
 		return 0;
 
+	audit_log_link_denied("follow_link", link);
 	path_put_conditional(link, nd);
 	path_put(&nd->path);
-	audit_log_link_denied("follow_link", link);
 	return -EACCES;
 }
 
@@ -810,6 +810,7 @@
 	return error;
 
 out_put_nd_path:
+	*p = NULL;
 	path_put(&nd->path);
 	path_put(link);
 	return error;
diff --git a/fs/namespace.c b/fs/namespace.c
index 7bdf790..fc33207 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1640,7 +1640,7 @@
 /*
  * do loopback mount.
  */
-static int do_loopback(struct path *path, char *old_name,
+static int do_loopback(struct path *path, const char *old_name,
 				int recurse)
 {
 	LIST_HEAD(umount_list);
@@ -1764,7 +1764,7 @@
 	return 0;
 }
 
-static int do_move_mount(struct path *path, char *old_name)
+static int do_move_mount(struct path *path, const char *old_name)
 {
 	struct path old_path, parent_path;
 	struct mount *p;
@@ -1917,8 +1917,8 @@
  * create a new mount for userspace and request it to be added into the
  * namespace's tree
  */
-static int do_new_mount(struct path *path, char *type, int flags,
-			int mnt_flags, char *name, void *data)
+static int do_new_mount(struct path *path, const char *type, int flags,
+			int mnt_flags, const char *name, void *data)
 {
 	struct vfsmount *mnt;
 	int err;
@@ -2191,8 +2191,8 @@
  * Therefore, if this magic number is present, it carries no information
  * and must be discarded.
  */
-long do_mount(char *dev_name, char *dir_name, char *type_page,
-		  unsigned long flags, void *data_page)
+long do_mount(const char *dev_name, const char *dir_name,
+		const char *type_page, unsigned long flags, void *data_page)
 {
 	struct path path;
 	int retval = 0;
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
index db7ad719..13ca196 100644
--- a/fs/nfs/Kconfig
+++ b/fs/nfs/Kconfig
@@ -95,8 +95,8 @@
 	  This option enables swapon to work on files located on NFS mounts.
 
 config NFS_V4_1
-	bool "NFS client support for NFSv4.1 (EXPERIMENTAL)"
-	depends on NFS_V4 && EXPERIMENTAL
+	bool "NFS client support for NFSv4.1"
+	depends on NFS_V4
 	select SUNRPC_BACKCHANNEL
 	help
 	  This option enables support for minor version 1 of the NFSv4 protocol
diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c
index dd392ed..f1027b0 100644
--- a/fs/nfs/blocklayout/blocklayout.c
+++ b/fs/nfs/blocklayout/blocklayout.c
@@ -37,6 +37,7 @@
 #include <linux/bio.h>		/* struct bio */
 #include <linux/buffer_head.h>	/* various write calls */
 #include <linux/prefetch.h>
+#include <linux/pagevec.h>
 
 #include "../pnfs.h"
 #include "../internal.h"
@@ -162,25 +163,39 @@
 	return bio;
 }
 
-static struct bio *bl_add_page_to_bio(struct bio *bio, int npg, int rw,
+static struct bio *do_add_page_to_bio(struct bio *bio, int npg, int rw,
 				      sector_t isect, struct page *page,
 				      struct pnfs_block_extent *be,
 				      void (*end_io)(struct bio *, int err),
-				      struct parallel_io *par)
+				      struct parallel_io *par,
+				      unsigned int offset, int len)
 {
+	isect = isect + (offset >> SECTOR_SHIFT);
+	dprintk("%s: npg %d rw %d isect %llu offset %u len %d\n", __func__,
+		npg, rw, (unsigned long long)isect, offset, len);
 retry:
 	if (!bio) {
 		bio = bl_alloc_init_bio(npg, isect, be, end_io, par);
 		if (!bio)
 			return ERR_PTR(-ENOMEM);
 	}
-	if (bio_add_page(bio, page, PAGE_CACHE_SIZE, 0) < PAGE_CACHE_SIZE) {
+	if (bio_add_page(bio, page, len, offset) < len) {
 		bio = bl_submit_bio(rw, bio);
 		goto retry;
 	}
 	return bio;
 }
 
+static struct bio *bl_add_page_to_bio(struct bio *bio, int npg, int rw,
+				      sector_t isect, struct page *page,
+				      struct pnfs_block_extent *be,
+				      void (*end_io)(struct bio *, int err),
+				      struct parallel_io *par)
+{
+	return do_add_page_to_bio(bio, npg, rw, isect, page, be,
+				  end_io, par, 0, PAGE_CACHE_SIZE);
+}
+
 /* This is basically copied from mpage_end_io_read */
 static void bl_end_io_read(struct bio *bio, int err)
 {
@@ -228,14 +243,6 @@
 	schedule_work(&rdata->task.u.tk_work);
 }
 
-static bool
-bl_check_alignment(u64 offset, u32 len, unsigned long blkmask)
-{
-	if ((offset & blkmask) || (len & blkmask))
-		return false;
-	return true;
-}
-
 static enum pnfs_try_status
 bl_read_pagelist(struct nfs_read_data *rdata)
 {
@@ -246,15 +253,15 @@
 	sector_t isect, extent_length = 0;
 	struct parallel_io *par;
 	loff_t f_offset = rdata->args.offset;
+	size_t bytes_left = rdata->args.count;
+	unsigned int pg_offset, pg_len;
 	struct page **pages = rdata->args.pages;
 	int pg_index = rdata->args.pgbase >> PAGE_CACHE_SHIFT;
+	const bool is_dio = (header->dreq != NULL);
 
 	dprintk("%s enter nr_pages %u offset %lld count %u\n", __func__,
 	       rdata->pages.npages, f_offset, (unsigned int)rdata->args.count);
 
-	if (!bl_check_alignment(f_offset, rdata->args.count, PAGE_CACHE_MASK))
-		goto use_mds;
-
 	par = alloc_parallel(rdata);
 	if (!par)
 		goto use_mds;
@@ -284,36 +291,53 @@
 				extent_length = min(extent_length, cow_length);
 			}
 		}
+
+		if (is_dio) {
+			pg_offset = f_offset & ~PAGE_CACHE_MASK;
+			if (pg_offset + bytes_left > PAGE_CACHE_SIZE)
+				pg_len = PAGE_CACHE_SIZE - pg_offset;
+			else
+				pg_len = bytes_left;
+
+			f_offset += pg_len;
+			bytes_left -= pg_len;
+			isect += (pg_offset >> SECTOR_SHIFT);
+		} else {
+			pg_offset = 0;
+			pg_len = PAGE_CACHE_SIZE;
+		}
+
 		hole = is_hole(be, isect);
 		if (hole && !cow_read) {
 			bio = bl_submit_bio(READ, bio);
 			/* Fill hole w/ zeroes w/o accessing device */
 			dprintk("%s Zeroing page for hole\n", __func__);
-			zero_user_segment(pages[i], 0, PAGE_CACHE_SIZE);
+			zero_user_segment(pages[i], pg_offset, pg_len);
 			print_page(pages[i]);
 			SetPageUptodate(pages[i]);
 		} else {
 			struct pnfs_block_extent *be_read;
 
 			be_read = (hole && cow_read) ? cow_read : be;
-			bio = bl_add_page_to_bio(bio, rdata->pages.npages - i,
+			bio = do_add_page_to_bio(bio, rdata->pages.npages - i,
 						 READ,
 						 isect, pages[i], be_read,
-						 bl_end_io_read, par);
+						 bl_end_io_read, par,
+						 pg_offset, pg_len);
 			if (IS_ERR(bio)) {
 				header->pnfs_error = PTR_ERR(bio);
 				bio = NULL;
 				goto out;
 			}
 		}
-		isect += PAGE_CACHE_SECTORS;
+		isect += (pg_len >> SECTOR_SHIFT);
 		extent_length -= PAGE_CACHE_SECTORS;
 	}
 	if ((isect << SECTOR_SHIFT) >= header->inode->i_size) {
 		rdata->res.eof = 1;
-		rdata->res.count = header->inode->i_size - f_offset;
+		rdata->res.count = header->inode->i_size - rdata->args.offset;
 	} else {
-		rdata->res.count = (isect << SECTOR_SHIFT) - f_offset;
+		rdata->res.count = (isect << SECTOR_SHIFT) - rdata->args.offset;
 	}
 out:
 	bl_put_extent(be);
@@ -461,6 +485,106 @@
 	return;
 }
 
+static void
+bl_read_single_end_io(struct bio *bio, int error)
+{
+	struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
+	struct page *page = bvec->bv_page;
+
+	/* Only one page in bvec */
+	unlock_page(page);
+}
+
+static int
+bl_do_readpage_sync(struct page *page, struct pnfs_block_extent *be,
+		    unsigned int offset, unsigned int len)
+{
+	struct bio *bio;
+	struct page *shadow_page;
+	sector_t isect;
+	char *kaddr, *kshadow_addr;
+	int ret = 0;
+
+	dprintk("%s: offset %u len %u\n", __func__, offset, len);
+
+	shadow_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM);
+	if (shadow_page == NULL)
+		return -ENOMEM;
+
+	bio = bio_alloc(GFP_NOIO, 1);
+	if (bio == NULL)
+		return -ENOMEM;
+
+	isect = (page->index << PAGE_CACHE_SECTOR_SHIFT) +
+		(offset / SECTOR_SIZE);
+
+	bio->bi_sector = isect - be->be_f_offset + be->be_v_offset;
+	bio->bi_bdev = be->be_mdev;
+	bio->bi_end_io = bl_read_single_end_io;
+
+	lock_page(shadow_page);
+	if (bio_add_page(bio, shadow_page,
+			 SECTOR_SIZE, round_down(offset, SECTOR_SIZE)) == 0) {
+		unlock_page(shadow_page);
+		bio_put(bio);
+		return -EIO;
+	}
+
+	submit_bio(READ, bio);
+	wait_on_page_locked(shadow_page);
+	if (unlikely(!test_bit(BIO_UPTODATE, &bio->bi_flags))) {
+		ret = -EIO;
+	} else {
+		kaddr = kmap_atomic(page);
+		kshadow_addr = kmap_atomic(shadow_page);
+		memcpy(kaddr + offset, kshadow_addr + offset, len);
+		kunmap_atomic(kshadow_addr);
+		kunmap_atomic(kaddr);
+	}
+	__free_page(shadow_page);
+	bio_put(bio);
+
+	return ret;
+}
+
+static int
+bl_read_partial_page_sync(struct page *page, struct pnfs_block_extent *be,
+			  unsigned int dirty_offset, unsigned int dirty_len,
+			  bool full_page)
+{
+	int ret = 0;
+	unsigned int start, end;
+
+	if (full_page) {
+		start = 0;
+		end = PAGE_CACHE_SIZE;
+	} else {
+		start = round_down(dirty_offset, SECTOR_SIZE);
+		end = round_up(dirty_offset + dirty_len, SECTOR_SIZE);
+	}
+
+	dprintk("%s: offset %u len %d\n", __func__, dirty_offset, dirty_len);
+	if (!be) {
+		zero_user_segments(page, start, dirty_offset,
+				   dirty_offset + dirty_len, end);
+		if (start == 0 && end == PAGE_CACHE_SIZE &&
+		    trylock_page(page)) {
+			SetPageUptodate(page);
+			unlock_page(page);
+		}
+		return ret;
+	}
+
+	if (start != dirty_offset)
+		ret = bl_do_readpage_sync(page, be, start, dirty_offset - start);
+
+	if (!ret && (dirty_offset + dirty_len < end))
+		ret = bl_do_readpage_sync(page, be, dirty_offset + dirty_len,
+					  end - dirty_offset - dirty_len);
+
+	return ret;
+}
+
 /* Given an unmapped page, zero it or read in page for COW, page is locked
  * by caller.
  */
@@ -494,7 +618,6 @@
 	SetPageUptodate(page);
 
 cleanup:
-	bl_put_extent(cow_read);
 	if (bh)
 		free_buffer_head(bh);
 	if (ret) {
@@ -566,6 +689,7 @@
 	struct parallel_io *par = NULL;
 	loff_t offset = wdata->args.offset;
 	size_t count = wdata->args.count;
+	unsigned int pg_offset, pg_len, saved_len;
 	struct page **pages = wdata->args.pages;
 	struct page *page;
 	pgoff_t index;
@@ -574,10 +698,13 @@
 	    NFS_SERVER(header->inode)->pnfs_blksize >> PAGE_CACHE_SHIFT;
 
 	dprintk("%s enter, %Zu@%lld\n", __func__, count, offset);
-	/* Check for alignment first */
-	if (!bl_check_alignment(offset, count, PAGE_CACHE_MASK))
-		goto out_mds;
 
+	if (header->dreq != NULL &&
+	    (!IS_ALIGNED(offset, NFS_SERVER(header->inode)->pnfs_blksize) ||
+	     !IS_ALIGNED(count, NFS_SERVER(header->inode)->pnfs_blksize))) {
+		dprintk("pnfsblock nonblock aligned DIO writes. Resend MDS\n");
+		goto out_mds;
+	}
 	/* At this point, wdata->pages is a (sequential) list of nfs_pages.
 	 * We want to write each, and if there is an error set pnfs_error
 	 * to have it redone using nfs.
@@ -674,10 +801,11 @@
 		if (!extent_length) {
 			/* We've used up the previous extent */
 			bl_put_extent(be);
+			bl_put_extent(cow_read);
 			bio = bl_submit_bio(WRITE, bio);
 			/* Get the next one */
 			be = bl_find_get_extent(BLK_LSEG2EXT(header->lseg),
-					     isect, NULL);
+					     isect, &cow_read);
 			if (!be || !is_writable(be, isect)) {
 				header->pnfs_error = -EINVAL;
 				goto out;
@@ -694,7 +822,26 @@
 			extent_length = be->be_length -
 			    (isect - be->be_f_offset);
 		}
-		if (be->be_state == PNFS_BLOCK_INVALID_DATA) {
+
+		dprintk("%s offset %lld count %Zu\n", __func__, offset, count);
+		pg_offset = offset & ~PAGE_CACHE_MASK;
+		if (pg_offset + count > PAGE_CACHE_SIZE)
+			pg_len = PAGE_CACHE_SIZE - pg_offset;
+		else
+			pg_len = count;
+
+		saved_len = pg_len;
+		if (be->be_state == PNFS_BLOCK_INVALID_DATA &&
+		    !bl_is_sector_init(be->be_inval, isect)) {
+			ret = bl_read_partial_page_sync(pages[i], cow_read,
+							pg_offset, pg_len, true);
+			if (ret) {
+				dprintk("%s bl_read_partial_page_sync fail %d\n",
+					__func__, ret);
+				header->pnfs_error = ret;
+				goto out;
+			}
+
 			ret = bl_mark_sectors_init(be->be_inval, isect,
 						       PAGE_CACHE_SECTORS);
 			if (unlikely(ret)) {
@@ -703,15 +850,35 @@
 				header->pnfs_error = ret;
 				goto out;
 			}
+
+			/* Expand to full page write */
+			pg_offset = 0;
+			pg_len = PAGE_CACHE_SIZE;
+		} else if  ((pg_offset & (SECTOR_SIZE - 1)) ||
+			    (pg_len & (SECTOR_SIZE - 1))){
+			/* ahh, nasty case. We have to do sync full sector
+			 * read-modify-write cycles.
+			 */
+			unsigned int saved_offset = pg_offset;
+			ret = bl_read_partial_page_sync(pages[i], be, pg_offset,
+							pg_len, false);
+			pg_offset = round_down(pg_offset, SECTOR_SIZE);
+			pg_len = round_up(saved_offset + pg_len, SECTOR_SIZE)
+				 - pg_offset;
 		}
-		bio = bl_add_page_to_bio(bio, wdata->pages.npages - i, WRITE,
+
+
+		bio = do_add_page_to_bio(bio, wdata->pages.npages - i, WRITE,
 					 isect, pages[i], be,
-					 bl_end_io_write, par);
+					 bl_end_io_write, par,
+					 pg_offset, pg_len);
 		if (IS_ERR(bio)) {
 			header->pnfs_error = PTR_ERR(bio);
 			bio = NULL;
 			goto out;
 		}
+		offset += saved_len;
+		count -= saved_len;
 		isect += PAGE_CACHE_SECTORS;
 		last_isect = isect;
 		extent_length -= PAGE_CACHE_SECTORS;
@@ -729,17 +896,16 @@
 	}
 
 write_done:
-	wdata->res.count = (last_isect << SECTOR_SHIFT) - (offset);
-	if (count < wdata->res.count) {
-		wdata->res.count = count;
-	}
+	wdata->res.count = wdata->args.count;
 out:
 	bl_put_extent(be);
+	bl_put_extent(cow_read);
 	bl_submit_bio(WRITE, bio);
 	put_parallel(par);
 	return PNFS_ATTEMPTED;
 out_mds:
 	bl_put_extent(be);
+	bl_put_extent(cow_read);
 	kfree(par);
 	return PNFS_NOT_ATTEMPTED;
 }
@@ -874,7 +1040,7 @@
 	}
 }
 
-/* This is mostly copied from the filelayout's get_device_info function.
+/* This is mostly copied from the filelayout_get_device_info function.
  * It seems much of this should be at the generic pnfs level.
  */
 static struct pnfs_block_dev *
@@ -1011,33 +1177,95 @@
 	return 0;
 }
 
+static bool
+is_aligned_req(struct nfs_page *req, unsigned int alignment)
+{
+	return IS_ALIGNED(req->wb_offset, alignment) &&
+	       IS_ALIGNED(req->wb_bytes, alignment);
+}
+
 static void
 bl_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
 {
-	if (!bl_check_alignment(req->wb_offset, req->wb_bytes, PAGE_CACHE_MASK))
+	if (pgio->pg_dreq != NULL &&
+	    !is_aligned_req(req, SECTOR_SIZE))
 		nfs_pageio_reset_read_mds(pgio);
 	else
 		pnfs_generic_pg_init_read(pgio, req);
 }
 
+static bool
+bl_pg_test_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
+		struct nfs_page *req)
+{
+	if (pgio->pg_dreq != NULL &&
+	    !is_aligned_req(req, SECTOR_SIZE))
+		return false;
+
+	return pnfs_generic_pg_test(pgio, prev, req);
+}
+
+/*
+ * Return the number of contiguous bytes for a given inode
+ * starting at page frame idx.
+ */
+static u64 pnfs_num_cont_bytes(struct inode *inode, pgoff_t idx)
+{
+	struct address_space *mapping = inode->i_mapping;
+	pgoff_t end;
+
+	/* Optimize common case that writes from 0 to end of file */
+	end = DIV_ROUND_UP(i_size_read(inode), PAGE_CACHE_SIZE);
+	if (end != NFS_I(inode)->npages) {
+		rcu_read_lock();
+		end = radix_tree_next_hole(&mapping->page_tree, idx + 1, ULONG_MAX);
+		rcu_read_unlock();
+	}
+
+	if (!end)
+		return i_size_read(inode) - (idx << PAGE_CACHE_SHIFT);
+	else
+		return (end - idx) << PAGE_CACHE_SHIFT;
+}
+
 static void
 bl_pg_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
 {
-	if (!bl_check_alignment(req->wb_offset, req->wb_bytes, PAGE_CACHE_MASK))
+	if (pgio->pg_dreq != NULL &&
+	    !is_aligned_req(req, PAGE_CACHE_SIZE)) {
 		nfs_pageio_reset_write_mds(pgio);
-	else
-		pnfs_generic_pg_init_write(pgio, req);
+	} else {
+		u64 wb_size;
+		if (pgio->pg_dreq == NULL)
+			wb_size = pnfs_num_cont_bytes(pgio->pg_inode,
+						      req->wb_index);
+		else
+			wb_size = nfs_dreq_bytes_left(pgio->pg_dreq);
+
+		pnfs_generic_pg_init_write(pgio, req, wb_size);
+	}
+}
+
+static bool
+bl_pg_test_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
+		 struct nfs_page *req)
+{
+	if (pgio->pg_dreq != NULL &&
+	    !is_aligned_req(req, PAGE_CACHE_SIZE))
+		return false;
+
+	return pnfs_generic_pg_test(pgio, prev, req);
 }
 
 static const struct nfs_pageio_ops bl_pg_read_ops = {
 	.pg_init = bl_pg_init_read,
-	.pg_test = pnfs_generic_pg_test,
+	.pg_test = bl_pg_test_read,
 	.pg_doio = pnfs_generic_pg_readpages,
 };
 
 static const struct nfs_pageio_ops bl_pg_write_ops = {
 	.pg_init = bl_pg_init_write,
-	.pg_test = pnfs_generic_pg_test,
+	.pg_test = bl_pg_test_write,
 	.pg_doio = pnfs_generic_pg_writepages,
 };
 
diff --git a/fs/nfs/blocklayout/blocklayout.h b/fs/nfs/blocklayout/blocklayout.h
index 0335069..f4891bd 100644
--- a/fs/nfs/blocklayout/blocklayout.h
+++ b/fs/nfs/blocklayout/blocklayout.h
@@ -41,6 +41,7 @@
 
 #define PAGE_CACHE_SECTORS (PAGE_CACHE_SIZE >> SECTOR_SHIFT)
 #define PAGE_CACHE_SECTOR_SHIFT (PAGE_CACHE_SHIFT - SECTOR_SHIFT)
+#define SECTOR_SIZE (1 << SECTOR_SHIFT)
 
 struct block_mount_id {
 	spinlock_t			bm_lock;    /* protects list */
@@ -172,7 +173,6 @@
 /* blocklayoutdev.c */
 ssize_t bl_pipe_downcall(struct file *, const char __user *, size_t);
 void bl_pipe_destroy_msg(struct rpc_pipe_msg *);
-struct block_device *nfs4_blkdev_get(dev_t dev);
 int nfs4_blkdev_put(struct block_device *bdev);
 struct pnfs_block_dev *nfs4_blk_decode_device(struct nfs_server *server,
 						struct pnfs_device *dev);
diff --git a/fs/nfs/blocklayout/blocklayoutdev.c b/fs/nfs/blocklayout/blocklayoutdev.c
index c965542..a86c5bd 100644
--- a/fs/nfs/blocklayout/blocklayoutdev.c
+++ b/fs/nfs/blocklayout/blocklayoutdev.c
@@ -53,22 +53,6 @@
 	return 0;
 }
 
-/* Open a block_device by device number. */
-struct block_device *nfs4_blkdev_get(dev_t dev)
-{
-	struct block_device *bd;
-
-	dprintk("%s enter\n", __func__);
-	bd = blkdev_get_by_dev(dev, FMODE_READ, NULL);
-	if (IS_ERR(bd))
-		goto fail;
-	return bd;
-fail:
-	dprintk("%s failed to open device : %ld\n",
-			__func__, PTR_ERR(bd));
-	return NULL;
-}
-
 /*
  * Release the block device
  */
@@ -172,11 +156,12 @@
 		goto out;
 	}
 
-	bd = nfs4_blkdev_get(MKDEV(reply->major, reply->minor));
+	bd = blkdev_get_by_dev(MKDEV(reply->major, reply->minor),
+			       FMODE_READ, NULL);
 	if (IS_ERR(bd)) {
-		rc = PTR_ERR(bd);
-		dprintk("%s failed to open device : %d\n", __func__, rc);
-		rv = ERR_PTR(rc);
+		dprintk("%s failed to open device : %ld\n", __func__,
+			PTR_ERR(bd));
+		rv = ERR_CAST(bd);
 		goto out;
 	}
 
diff --git a/fs/nfs/blocklayout/extents.c b/fs/nfs/blocklayout/extents.c
index 1f9a603..9c3e117 100644
--- a/fs/nfs/blocklayout/extents.c
+++ b/fs/nfs/blocklayout/extents.c
@@ -683,8 +683,7 @@
 		p = xdr_encode_hyper(p, lce->bse_length << SECTOR_SHIFT);
 		p = xdr_encode_hyper(p, 0LL);
 		*p++ = cpu_to_be32(PNFS_BLOCK_READWRITE_DATA);
-		list_del(&lce->bse_node);
-		list_add_tail(&lce->bse_node, &bl->bl_committing);
+		list_move_tail(&lce->bse_node, &bl->bl_committing);
 		bl->bl_count--;
 		count++;
 	}
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index 4c8459e..2245bef 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -12,6 +12,7 @@
 #include <linux/sunrpc/svc.h>
 #include <linux/sunrpc/svcsock.h>
 #include <linux/nfs_fs.h>
+#include <linux/errno.h>
 #include <linux/mutex.h>
 #include <linux/freezer.h>
 #include <linux/kthread.h>
@@ -23,6 +24,7 @@
 #include "nfs4_fs.h"
 #include "callback.h"
 #include "internal.h"
+#include "netns.h"
 
 #define NFSDBG_FACILITY NFSDBG_CALLBACK
 
@@ -37,7 +39,32 @@
 static DEFINE_MUTEX(nfs_callback_mutex);
 static struct svc_program nfs4_callback_program;
 
-unsigned short nfs_callback_tcpport6;
+static int nfs4_callback_up_net(struct svc_serv *serv, struct net *net)
+{
+	int ret;
+	struct nfs_net *nn = net_generic(net, nfs_net_id);
+
+	ret = svc_create_xprt(serv, "tcp", net, PF_INET,
+				nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS);
+	if (ret <= 0)
+		goto out_err;
+	nn->nfs_callback_tcpport = ret;
+	dprintk("NFS: Callback listener port = %u (af %u, net %p)\n",
+			nn->nfs_callback_tcpport, PF_INET, net);
+
+	ret = svc_create_xprt(serv, "tcp", net, PF_INET6,
+				nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS);
+	if (ret > 0) {
+		nn->nfs_callback_tcpport6 = ret;
+		dprintk("NFS: Callback listener port = %u (af %u, net %p)\n",
+				nn->nfs_callback_tcpport6, PF_INET6, net);
+	} else if (ret != -EAFNOSUPPORT)
+		goto out_err;
+	return 0;
+
+out_err:
+	return (ret) ? ret : -ENOMEM;
+}
 
 /*
  * This is the NFSv4 callback kernel thread.
@@ -78,38 +105,23 @@
  * Prepare to bring up the NFSv4 callback service
  */
 static struct svc_rqst *
-nfs4_callback_up(struct svc_serv *serv, struct rpc_xprt *xprt)
+nfs4_callback_up(struct svc_serv *serv)
 {
-	int ret;
-
-	ret = svc_create_xprt(serv, "tcp", &init_net, PF_INET,
-				nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS);
-	if (ret <= 0)
-		goto out_err;
-	nfs_callback_tcpport = ret;
-	dprintk("NFS: Callback listener port = %u (af %u)\n",
-			nfs_callback_tcpport, PF_INET);
-
-	ret = svc_create_xprt(serv, "tcp", &init_net, PF_INET6,
-				nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS);
-	if (ret > 0) {
-		nfs_callback_tcpport6 = ret;
-		dprintk("NFS: Callback listener port = %u (af %u)\n",
-				nfs_callback_tcpport6, PF_INET6);
-	} else if (ret == -EAFNOSUPPORT)
-		ret = 0;
-	else
-		goto out_err;
-
 	return svc_prepare_thread(serv, &serv->sv_pools[0], NUMA_NO_NODE);
-
-out_err:
-	if (ret == 0)
-		ret = -ENOMEM;
-	return ERR_PTR(ret);
 }
 
 #if defined(CONFIG_NFS_V4_1)
+static int nfs41_callback_up_net(struct svc_serv *serv, struct net *net)
+{
+	/*
+	 * Create an svc_sock for the back channel service that shares the
+	 * fore channel connection.
+	 * Returns the input port (0) and sets the svc_serv bc_xprt on success
+	 */
+	return svc_create_xprt(serv, "tcp-bc", net, PF_INET, 0,
+			      SVC_SOCK_ANONYMOUS);
+}
+
 /*
  * The callback service for NFSv4.1 callbacks
  */
@@ -149,28 +161,9 @@
  * Bring up the NFSv4.1 callback service
  */
 static struct svc_rqst *
-nfs41_callback_up(struct svc_serv *serv, struct rpc_xprt *xprt)
+nfs41_callback_up(struct svc_serv *serv)
 {
 	struct svc_rqst *rqstp;
-	int ret;
-
-	/*
-	 * Create an svc_sock for the back channel service that shares the
-	 * fore channel connection.
-	 * Returns the input port (0) and sets the svc_serv bc_xprt on success
-	 */
-	ret = svc_create_xprt(serv, "tcp-bc", &init_net, PF_INET, 0,
-			      SVC_SOCK_ANONYMOUS);
-	if (ret < 0) {
-		rqstp = ERR_PTR(ret);
-		goto out;
-	}
-
-	/*
-	 * Save the svc_serv in the transport so that it can
-	 * be referenced when the session backchannel is initialized
-	 */
-	xprt->bc_serv = serv;
 
 	INIT_LIST_HEAD(&serv->sv_cb_list);
 	spin_lock_init(&serv->sv_cb_lock);
@@ -180,90 +173,74 @@
 		svc_xprt_put(serv->sv_bc_xprt);
 		serv->sv_bc_xprt = NULL;
 	}
-out:
 	dprintk("--> %s return %ld\n", __func__,
 		IS_ERR(rqstp) ? PTR_ERR(rqstp) : 0);
 	return rqstp;
 }
 
-static inline int nfs_minorversion_callback_svc_setup(u32 minorversion,
-		struct svc_serv *serv, struct rpc_xprt *xprt,
+static void nfs_minorversion_callback_svc_setup(struct svc_serv *serv,
 		struct svc_rqst **rqstpp, int (**callback_svc)(void *vrqstp))
 {
-	if (minorversion) {
-		*rqstpp = nfs41_callback_up(serv, xprt);
-		*callback_svc = nfs41_callback_svc;
-	}
-	return minorversion;
+	*rqstpp = nfs41_callback_up(serv);
+	*callback_svc = nfs41_callback_svc;
 }
 
 static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt,
-		struct nfs_callback_data *cb_info)
+		struct svc_serv *serv)
 {
 	if (minorversion)
-		xprt->bc_serv = cb_info->serv;
+		/*
+		 * Save the svc_serv in the transport so that it can
+		 * be referenced when the session backchannel is initialized
+		 */
+		xprt->bc_serv = serv;
 }
 #else
-static inline int nfs_minorversion_callback_svc_setup(u32 minorversion,
-		struct svc_serv *serv, struct rpc_xprt *xprt,
-		struct svc_rqst **rqstpp, int (**callback_svc)(void *vrqstp))
+static int nfs41_callback_up_net(struct svc_serv *serv, struct net *net)
 {
 	return 0;
 }
 
+static void nfs_minorversion_callback_svc_setup(struct svc_serv *serv,
+		struct svc_rqst **rqstpp, int (**callback_svc)(void *vrqstp))
+{
+	*rqstpp = ERR_PTR(-ENOTSUPP);
+	*callback_svc = ERR_PTR(-ENOTSUPP);
+}
+
 static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt,
-		struct nfs_callback_data *cb_info)
+		struct svc_serv *serv)
 {
 }
 #endif /* CONFIG_NFS_V4_1 */
 
-/*
- * Bring up the callback thread if it is not already up.
- */
-int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt)
+static int nfs_callback_start_svc(int minorversion, struct rpc_xprt *xprt,
+				  struct svc_serv *serv)
 {
-	struct svc_serv *serv = NULL;
 	struct svc_rqst *rqstp;
 	int (*callback_svc)(void *vrqstp);
 	struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion];
 	char svc_name[12];
-	int ret = 0;
-	int minorversion_setup;
-	struct net *net = &init_net;
+	int ret;
 
-	mutex_lock(&nfs_callback_mutex);
-	if (cb_info->users++ || cb_info->task != NULL) {
-		nfs_callback_bc_serv(minorversion, xprt, cb_info);
-		goto out;
-	}
-	serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, NULL);
-	if (!serv) {
-		ret = -ENOMEM;
-		goto out_err;
-	}
-	/* As there is only one thread we need to over-ride the
-	 * default maximum of 80 connections
-	 */
-	serv->sv_maxconn = 1024;
+	nfs_callback_bc_serv(minorversion, xprt, serv);
 
-	ret = svc_bind(serv, net);
-	if (ret < 0) {
-		printk(KERN_WARNING "NFS: bind callback service failed\n");
-		goto out_err;
-	}
+	if (cb_info->task)
+		return 0;
 
-	minorversion_setup =  nfs_minorversion_callback_svc_setup(minorversion,
-					serv, xprt, &rqstp, &callback_svc);
-	if (!minorversion_setup) {
+	switch (minorversion) {
+	case 0:
 		/* v4.0 callback setup */
-		rqstp = nfs4_callback_up(serv, xprt);
+		rqstp = nfs4_callback_up(serv);
 		callback_svc = nfs4_callback_svc;
+		break;
+	default:
+		nfs_minorversion_callback_svc_setup(serv,
+				&rqstp, &callback_svc);
 	}
 
-	if (IS_ERR(rqstp)) {
-		ret = PTR_ERR(rqstp);
-		goto out_err;
-	}
+	if (IS_ERR(rqstp))
+		return PTR_ERR(rqstp);
 
 	svc_sock_update_bufs(serv);
 
@@ -276,41 +253,165 @@
 		svc_exit_thread(cb_info->rqst);
 		cb_info->rqst = NULL;
 		cb_info->task = NULL;
-		goto out_err;
+		return PTR_ERR(cb_info->task);
 	}
-out:
+	dprintk("nfs_callback_up: service started\n");
+	return 0;
+}
+
+static void nfs_callback_down_net(u32 minorversion, struct svc_serv *serv, struct net *net)
+{
+	struct nfs_net *nn = net_generic(net, nfs_net_id);
+
+	if (--nn->cb_users[minorversion])
+		return;
+
+	dprintk("NFS: destroy per-net callback data; net=%p\n", net);
+	svc_shutdown_net(serv, net);
+}
+
+static int nfs_callback_up_net(int minorversion, struct svc_serv *serv, struct net *net)
+{
+	struct nfs_net *nn = net_generic(net, nfs_net_id);
+	int ret;
+
+	if (nn->cb_users[minorversion]++)
+		return 0;
+
+	dprintk("NFS: create per-net callback data; net=%p\n", net);
+
+	ret = svc_bind(serv, net);
+	if (ret < 0) {
+		printk(KERN_WARNING "NFS: bind callback service failed\n");
+		goto err_bind;
+	}
+
+	switch (minorversion) {
+		case 0:
+			ret = nfs4_callback_up_net(serv, net);
+			break;
+		case 1:
+			ret = nfs41_callback_up_net(serv, net);
+			break;
+		default:
+			printk(KERN_ERR "NFS: unknown callback version: %d\n",
+					minorversion);
+			ret = -EINVAL;
+			break;
+	}
+
+	if (ret < 0) {
+		printk(KERN_ERR "NFS: callback service start failed\n");
+		goto err_socks;
+	}
+	return 0;
+
+err_socks:
+	svc_rpcb_cleanup(serv, net);
+err_bind:
+	dprintk("NFS: Couldn't create callback socket: err = %d; "
+			"net = %p\n", ret, net);
+	return ret;
+}
+
+static struct svc_serv *nfs_callback_create_svc(int minorversion)
+{
+	struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion];
+	struct svc_serv *serv;
+
+	/*
+	 * Check whether we're already up and running.
+	 */
+	if (cb_info->task) {
+		/*
+		 * Note: increase service usage, because later in case of error
+		 * svc_destroy() will be called.
+		 */
+		svc_get(cb_info->serv);
+		return cb_info->serv;
+	}
+
+	/*
+	 * Sanity check: if there's no task,
+	 * we should be the first user ...
+	 */
+	if (cb_info->users)
+		printk(KERN_WARNING "nfs_callback_create_svc: no kthread, %d users??\n",
+			cb_info->users);
+
+	serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, NULL);
+	if (!serv) {
+		printk(KERN_ERR "nfs_callback_create_svc: create service failed\n");
+		return ERR_PTR(-ENOMEM);
+	}
+	/* As there is only one thread we need to over-ride the
+	 * default maximum of 80 connections
+	 */
+	serv->sv_maxconn = 1024;
+	dprintk("nfs_callback_create_svc: service created\n");
+	return serv;
+}
+
+/*
+ * Bring up the callback thread if it is not already up.
+ */
+int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt)
+{
+	struct svc_serv *serv;
+	struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion];
+	int ret;
+	struct net *net = xprt->xprt_net;
+
+	mutex_lock(&nfs_callback_mutex);
+
+	serv = nfs_callback_create_svc(minorversion);
+	if (IS_ERR(serv)) {
+		ret = PTR_ERR(serv);
+		goto err_create;
+	}
+
+	ret = nfs_callback_up_net(minorversion, serv, net);
+	if (ret < 0)
+		goto err_net;
+
+	ret = nfs_callback_start_svc(minorversion, xprt, serv);
+	if (ret < 0)
+		goto err_start;
+
+	cb_info->users++;
 	/*
 	 * svc_create creates the svc_serv with sv_nrthreads == 1, and then
 	 * svc_prepare_thread increments that. So we need to call svc_destroy
 	 * on both success and failure so that the refcount is 1 when the
 	 * thread exits.
 	 */
-	if (serv)
-		svc_destroy(serv);
+err_net:
+	svc_destroy(serv);
+err_create:
 	mutex_unlock(&nfs_callback_mutex);
 	return ret;
-out_err:
-	dprintk("NFS: Couldn't create callback socket or server thread; "
-		"err = %d\n", ret);
-	cb_info->users--;
-	if (serv)
-		svc_shutdown_net(serv, net);
-	goto out;
+
+err_start:
+	nfs_callback_down_net(minorversion, serv, net);
+	dprintk("NFS: Couldn't create server thread; err = %d\n", ret);
+	goto err_net;
 }
 
 /*
  * Kill the callback thread if it's no longer being used.
  */
-void nfs_callback_down(int minorversion)
+void nfs_callback_down(int minorversion, struct net *net)
 {
 	struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion];
 
 	mutex_lock(&nfs_callback_mutex);
+	nfs_callback_down_net(minorversion, cb_info->serv, net);
 	cb_info->users--;
 	if (cb_info->users == 0 && cb_info->task != NULL) {
 		kthread_stop(cb_info->task);
-		svc_shutdown_net(cb_info->serv, &init_net);
+		dprintk("nfs_callback_down: service stopped\n");
 		svc_exit_thread(cb_info->rqst);
+		dprintk("nfs_callback_down: service destroyed\n");
 		cb_info->serv = NULL;
 		cb_info->rqst = NULL;
 		cb_info->task = NULL;
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h
index b44d7b1..4251c2ae 100644
--- a/fs/nfs/callback.h
+++ b/fs/nfs/callback.h
@@ -194,7 +194,7 @@
 				   struct cb_process_state *cps);
 #if IS_ENABLED(CONFIG_NFS_V4)
 extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt);
-extern void nfs_callback_down(int minorversion);
+extern void nfs_callback_down(int minorversion, struct net *net);
 extern int nfs4_validate_delegation_stateid(struct nfs_delegation *delegation,
 					    const nfs4_stateid *stateid);
 extern int nfs4_set_callback_sessionid(struct nfs_client *clp);
@@ -209,6 +209,5 @@
 
 extern unsigned int nfs_callback_set_tcpport;
 extern unsigned short nfs_callback_tcpport;
-extern unsigned short nfs_callback_tcpport6;
 
 #endif /* __LINUX_FS_NFS_CALLBACK_H */
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index 1b5d809..76b4a7a 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -122,7 +122,15 @@
 			ino = igrab(lo->plh_inode);
 			if (!ino)
 				continue;
-			get_layout_hdr(lo);
+			spin_lock(&ino->i_lock);
+			/* Is this layout in the process of being freed? */
+			if (NFS_I(ino)->layout != lo) {
+				spin_unlock(&ino->i_lock);
+				iput(ino);
+				continue;
+			}
+			pnfs_get_layout_hdr(lo);
+			spin_unlock(&ino->i_lock);
 			return lo;
 		}
 	}
@@ -158,7 +166,7 @@
 	ino = lo->plh_inode;
 	spin_lock(&ino->i_lock);
 	if (test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags) ||
-	    mark_matching_lsegs_invalid(lo, &free_me_list,
+	    pnfs_mark_matching_lsegs_invalid(lo, &free_me_list,
 					&args->cbl_range))
 		rv = NFS4ERR_DELAY;
 	else
@@ -166,7 +174,7 @@
 	pnfs_set_layout_stateid(lo, &args->cbl_stateid, true);
 	spin_unlock(&ino->i_lock);
 	pnfs_free_lseg_list(&free_me_list);
-	put_layout_hdr(lo);
+	pnfs_put_layout_hdr(lo);
 	iput(ino);
 	return rv;
 }
@@ -196,9 +204,18 @@
 			continue;
 
 		list_for_each_entry(lo, &server->layouts, plh_layouts) {
-			if (!igrab(lo->plh_inode))
+			ino = igrab(lo->plh_inode);
+			if (ino)
 				continue;
-			get_layout_hdr(lo);
+			spin_lock(&ino->i_lock);
+			/* Is this layout in the process of being freed? */
+			if (NFS_I(ino)->layout != lo) {
+				spin_unlock(&ino->i_lock);
+				iput(ino);
+				continue;
+			}
+			pnfs_get_layout_hdr(lo);
+			spin_unlock(&ino->i_lock);
 			BUG_ON(!list_empty(&lo->plh_bulk_recall));
 			list_add(&lo->plh_bulk_recall, &recall_list);
 		}
@@ -211,12 +228,12 @@
 		ino = lo->plh_inode;
 		spin_lock(&ino->i_lock);
 		set_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags);
-		if (mark_matching_lsegs_invalid(lo, &free_me_list, &range))
+		if (pnfs_mark_matching_lsegs_invalid(lo, &free_me_list, &range))
 			rv = NFS4ERR_DELAY;
 		list_del_init(&lo->plh_bulk_recall);
 		spin_unlock(&ino->i_lock);
 		pnfs_free_lseg_list(&free_me_list);
-		put_layout_hdr(lo);
+		pnfs_put_layout_hdr(lo);
 		iput(ino);
 	}
 	return rv;
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 9969444..8b39a42 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -93,10 +93,10 @@
 			spin_unlock(&nfs_version_lock);
 			return nfs;
 		}
-	};
+	}
 
 	spin_unlock(&nfs_version_lock);
-	return ERR_PTR(-EPROTONOSUPPORT);;
+	return ERR_PTR(-EPROTONOSUPPORT);
 }
 
 struct nfs_subversion *get_nfs_version(unsigned int version)
@@ -498,7 +498,8 @@
 			return nfs_found_client(cl_init, clp);
 		}
 		if (new) {
-			list_add(&new->cl_share_link, &nn->nfs_client_list);
+			list_add_tail(&new->cl_share_link,
+					&nn->nfs_client_list);
 			spin_unlock(&nn->nfs_client_lock);
 			new->cl_flags = cl_init->init_flags;
 			return rpc_ops->init_client(new, timeparms, ip_addr,
@@ -668,7 +669,8 @@
 {
 	struct nfs_client *clp = server->nfs_client;
 
-	server->client = rpc_clone_client(clp->cl_rpcclient);
+	server->client = rpc_clone_client_set_auth(clp->cl_rpcclient,
+							pseudoflavour);
 	if (IS_ERR(server->client)) {
 		dprintk("%s: couldn't create rpc_client!\n", __func__);
 		return PTR_ERR(server->client);
@@ -678,16 +680,6 @@
 			timeo,
 			sizeof(server->client->cl_timeout_default));
 	server->client->cl_timeout = &server->client->cl_timeout_default;
-
-	if (pseudoflavour != clp->cl_rpcclient->cl_auth->au_flavor) {
-		struct rpc_auth *auth;
-
-		auth = rpcauth_create(pseudoflavour, server->client);
-		if (IS_ERR(auth)) {
-			dprintk("%s: couldn't create credcache!\n", __func__);
-			return PTR_ERR(auth);
-		}
-	}
 	server->client->cl_softrtry = 0;
 	if (server->flags & NFS_MOUNT_SOFT)
 		server->client->cl_softrtry = 1;
@@ -761,6 +753,8 @@
 			data->timeo, data->retrans);
 	if (data->flags & NFS_MOUNT_NORESVPORT)
 		set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
+	if (server->options & NFS_OPTION_MIGRATION)
+		set_bit(NFS_CS_MIGRATION, &cl_init.init_flags);
 
 	/* Allocate or find a client reference we can use */
 	clp = nfs_get_client(&cl_init, &timeparms, NULL, RPC_AUTH_UNIX);
@@ -855,7 +849,6 @@
 	if (server->wsize > NFS_MAX_FILE_IO_SIZE)
 		server->wsize = NFS_MAX_FILE_IO_SIZE;
 	server->wpages = (server->wsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
-	server->pnfs_blksize = fsinfo->blksize;
 
 	server->wtmult = nfs_block_bits(fsinfo->wtmult, NULL);
 
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 627f108..ce8cb92 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -2072,7 +2072,7 @@
 	nfs_access_free_entry(entry);
 }
 
-static void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set)
+void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set)
 {
 	struct nfs_access_entry *cache = kmalloc(sizeof(*cache), GFP_KERNEL);
 	if (cache == NULL)
@@ -2098,6 +2098,20 @@
 		spin_unlock(&nfs_access_lru_lock);
 	}
 }
+EXPORT_SYMBOL_GPL(nfs_access_add_cache);
+
+void nfs_access_set_mask(struct nfs_access_entry *entry, u32 access_result)
+{
+	entry->mask = 0;
+	if (access_result & NFS4_ACCESS_READ)
+		entry->mask |= MAY_READ;
+	if (access_result &
+	    (NFS4_ACCESS_MODIFY | NFS4_ACCESS_EXTEND | NFS4_ACCESS_DELETE))
+		entry->mask |= MAY_WRITE;
+	if (access_result & (NFS4_ACCESS_LOOKUP|NFS4_ACCESS_EXECUTE))
+		entry->mask |= MAY_EXEC;
+}
+EXPORT_SYMBOL_GPL(nfs_access_set_mask);
 
 static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
 {
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 1ba385b..cae26cb 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -46,6 +46,7 @@
 #include <linux/kref.h>
 #include <linux/slab.h>
 #include <linux/task_io_accounting_ops.h>
+#include <linux/module.h>
 
 #include <linux/nfs_fs.h>
 #include <linux/nfs_page.h>
@@ -78,6 +79,7 @@
 	atomic_t		io_count;	/* i/os we're waiting for */
 	spinlock_t		lock;		/* protect completion state */
 	ssize_t			count,		/* bytes actually processed */
+				bytes_left,	/* bytes left to be sent */
 				error;		/* any reported error */
 	struct completion	completion;	/* wait for i/o completion */
 
@@ -190,6 +192,12 @@
 	kref_put(&dreq->kref, nfs_direct_req_free);
 }
 
+ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq)
+{
+	return dreq->bytes_left;
+}
+EXPORT_SYMBOL_GPL(nfs_dreq_bytes_left);
+
 /*
  * Collects and returns the final error value/byte-count.
  */
@@ -390,6 +398,7 @@
 			user_addr += req_len;
 			pos += req_len;
 			count -= req_len;
+			dreq->bytes_left -= req_len;
 		}
 		/* The nfs_page now hold references to these pages */
 		nfs_direct_release_pages(pagevec, npages);
@@ -450,23 +459,28 @@
 	ssize_t result = -ENOMEM;
 	struct inode *inode = iocb->ki_filp->f_mapping->host;
 	struct nfs_direct_req *dreq;
+	struct nfs_lock_context *l_ctx;
 
 	dreq = nfs_direct_req_alloc();
 	if (dreq == NULL)
 		goto out;
 
 	dreq->inode = inode;
+	dreq->bytes_left = iov_length(iov, nr_segs);
 	dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp));
-	dreq->l_ctx = nfs_get_lock_context(dreq->ctx);
-	if (dreq->l_ctx == NULL)
+	l_ctx = nfs_get_lock_context(dreq->ctx);
+	if (IS_ERR(l_ctx)) {
+		result = PTR_ERR(l_ctx);
 		goto out_release;
+	}
+	dreq->l_ctx = l_ctx;
 	if (!is_sync_kiocb(iocb))
 		dreq->iocb = iocb;
 
+	NFS_I(inode)->read_io += iov_length(iov, nr_segs);
 	result = nfs_direct_read_schedule_iovec(dreq, iov, nr_segs, pos, uio);
 	if (!result)
 		result = nfs_direct_wait(dreq);
-	NFS_I(inode)->read_io += result;
 out_release:
 	nfs_direct_req_release(dreq);
 out:
@@ -706,6 +720,7 @@
 			user_addr += req_len;
 			pos += req_len;
 			count -= req_len;
+			dreq->bytes_left -= req_len;
 		}
 		/* The nfs_page now hold references to these pages */
 		nfs_direct_release_pages(pagevec, npages);
@@ -814,6 +829,7 @@
 	get_dreq(dreq);
 	atomic_inc(&inode->i_dio_count);
 
+	NFS_I(dreq->inode)->write_io += iov_length(iov, nr_segs);
 	for (seg = 0; seg < nr_segs; seg++) {
 		const struct iovec *vec = &iov[seg];
 		result = nfs_direct_write_schedule_segment(&desc, vec, pos, uio);
@@ -825,7 +841,6 @@
 		pos += vec->iov_len;
 	}
 	nfs_pageio_complete(&desc);
-	NFS_I(dreq->inode)->write_io += desc.pg_bytes_written;
 
 	/*
 	 * If no bytes were started, return the error, and let the
@@ -849,16 +864,21 @@
 	ssize_t result = -ENOMEM;
 	struct inode *inode = iocb->ki_filp->f_mapping->host;
 	struct nfs_direct_req *dreq;
+	struct nfs_lock_context *l_ctx;
 
 	dreq = nfs_direct_req_alloc();
 	if (!dreq)
 		goto out;
 
 	dreq->inode = inode;
+	dreq->bytes_left = count;
 	dreq->ctx = get_nfs_open_context(nfs_file_open_context(iocb->ki_filp));
-	dreq->l_ctx = nfs_get_lock_context(dreq->ctx);
-	if (dreq->l_ctx == NULL)
+	l_ctx = nfs_get_lock_context(dreq->ctx);
+	if (IS_ERR(l_ctx)) {
+		result = PTR_ERR(l_ctx);
 		goto out_release;
+	}
+	dreq->l_ctx = l_ctx;
 	if (!is_sync_kiocb(iocb))
 		dreq->iocb = iocb;
 
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 6a7fcab..582bb88 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -259,7 +259,7 @@
 	struct dentry *dentry = file->f_path.dentry;
 	struct nfs_open_context *ctx = nfs_file_open_context(file);
 	struct inode *inode = dentry->d_inode;
-	int have_error, status;
+	int have_error, do_resend, status;
 	int ret = 0;
 
 	dprintk("NFS: fsync file(%s/%s) datasync %d\n",
@@ -267,15 +267,23 @@
 			datasync);
 
 	nfs_inc_stats(inode, NFSIOS_VFSFSYNC);
+	do_resend = test_and_clear_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags);
 	have_error = test_and_clear_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
 	status = nfs_commit_inode(inode, FLUSH_SYNC);
-	if (status >= 0 && ret < 0)
-		status = ret;
 	have_error |= test_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
-	if (have_error)
+	if (have_error) {
 		ret = xchg(&ctx->error, 0);
-	if (!ret && status < 0)
+		if (ret)
+			goto out;
+	}
+	if (status < 0) {
 		ret = status;
+		goto out;
+	}
+	do_resend |= test_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags);
+	if (do_resend)
+		ret = -EAGAIN;
+out:
 	return ret;
 }
 EXPORT_SYMBOL_GPL(nfs_file_fsync_commit);
@@ -286,13 +294,22 @@
 	int ret;
 	struct inode *inode = file->f_path.dentry->d_inode;
 
-	ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
-	if (ret != 0)
-		goto out;
-	mutex_lock(&inode->i_mutex);
-	ret = nfs_file_fsync_commit(file, start, end, datasync);
-	mutex_unlock(&inode->i_mutex);
-out:
+	do {
+		ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
+		if (ret != 0)
+			break;
+		mutex_lock(&inode->i_mutex);
+		ret = nfs_file_fsync_commit(file, start, end, datasync);
+		mutex_unlock(&inode->i_mutex);
+		/*
+		 * If nfs_file_fsync_commit detected a server reboot, then
+		 * resend all dirty pages that might have been covered by
+		 * the NFS_CONTEXT_RESEND_WRITES flag
+		 */
+		start = 0;
+		end = LLONG_MAX;
+	} while (ret == -EAGAIN);
+
 	return ret;
 }
 
@@ -578,6 +595,7 @@
 static const struct vm_operations_struct nfs_file_vm_ops = {
 	.fault = filemap_fault,
 	.page_mkwrite = nfs_vm_page_mkwrite,
+	.remap_pages = generic_file_remap_pages,
 };
 
 static int nfs_need_sync_write(struct file *filp, struct inode *inode)
diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c
index 4654ced..033803c 100644
--- a/fs/nfs/getroot.c
+++ b/fs/nfs/getroot.c
@@ -32,6 +32,8 @@
 
 #include <asm/uaccess.h>
 
+#include "internal.h"
+
 #define NFSDBG_FACILITY		NFSDBG_CLIENT
 
 /*
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index a850079..9cc4a3f 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -55,18 +55,19 @@
 static const struct cred *id_resolver_cache;
 static struct key_type key_type_id_resolver_legacy;
 
-struct idmap {
-	struct rpc_pipe		*idmap_pipe;
-	struct key_construction	*idmap_key_cons;
-	struct mutex		idmap_mutex;
-};
-
 struct idmap_legacy_upcalldata {
 	struct rpc_pipe_msg pipe_msg;
 	struct idmap_msg idmap_msg;
+	struct key_construction	*key_cons;
 	struct idmap *idmap;
 };
 
+struct idmap {
+	struct rpc_pipe		*idmap_pipe;
+	struct idmap_legacy_upcalldata *idmap_upcall_data;
+	struct mutex		idmap_mutex;
+};
+
 /**
  * nfs_fattr_init_names - initialise the nfs_fattr owner_name/group_name fields
  * @fattr: fully initialised struct nfs_fattr
@@ -158,7 +159,7 @@
 		return 0;
 	memcpy(buf, name, namelen);
 	buf[namelen] = '\0';
-	if (strict_strtoul(buf, 0, &val) != 0)
+	if (kstrtoul(buf, 0, &val) != 0)
 		return 0;
 	*res = val;
 	return 1;
@@ -330,7 +331,6 @@
 		ret = nfs_idmap_request_key(&key_type_id_resolver_legacy,
 					    name, namelen, type, data,
 					    data_size, idmap);
-		idmap->idmap_key_cons = NULL;
 		mutex_unlock(&idmap->idmap_mutex);
 	}
 	return ret;
@@ -364,7 +364,7 @@
 	if (data_size <= 0) {
 		ret = -EINVAL;
 	} else {
-		ret = strict_strtol(id_str, 10, &id_long);
+		ret = kstrtol(id_str, 10, &id_long);
 		*id = (__u32)id_long;
 	}
 	return ret;
@@ -465,8 +465,6 @@
 	struct rpc_pipe *pipe;
 	int error;
 
-	BUG_ON(clp->cl_idmap != NULL);
-
 	idmap = kzalloc(sizeof(*idmap), GFP_KERNEL);
 	if (idmap == NULL)
 		return -ENOMEM;
@@ -510,7 +508,6 @@
 
 	switch (event) {
 	case RPC_PIPEFS_MOUNT:
-		BUG_ON(clp->cl_rpcclient->cl_dentry == NULL);
 		err = __nfs_idmap_register(clp->cl_rpcclient->cl_dentry,
 						clp->cl_idmap,
 						clp->cl_idmap->idmap_pipe);
@@ -632,9 +629,6 @@
 	substring_t substr;
 	int token, ret;
 
-	memset(im,  0, sizeof(*im));
-	memset(msg, 0, sizeof(*msg));
-
 	im->im_type = IDMAP_TYPE_GROUP;
 	token = match_token(desc, nfs_idmap_tokens, &substr);
 
@@ -665,6 +659,35 @@
 	return ret;
 }
 
+static bool
+nfs_idmap_prepare_pipe_upcall(struct idmap *idmap,
+		struct idmap_legacy_upcalldata *data)
+{
+	if (idmap->idmap_upcall_data != NULL) {
+		WARN_ON_ONCE(1);
+		return false;
+	}
+	idmap->idmap_upcall_data = data;
+	return true;
+}
+
+static void
+nfs_idmap_complete_pipe_upcall_locked(struct idmap *idmap, int ret)
+{
+	struct key_construction *cons = idmap->idmap_upcall_data->key_cons;
+
+	kfree(idmap->idmap_upcall_data);
+	idmap->idmap_upcall_data = NULL;
+	complete_request_key(cons, ret);
+}
+
+static void
+nfs_idmap_abort_pipe_upcall(struct idmap *idmap, int ret)
+{
+	if (idmap->idmap_upcall_data != NULL)
+		nfs_idmap_complete_pipe_upcall_locked(idmap, ret);
+}
+
 static int nfs_idmap_legacy_upcall(struct key_construction *cons,
 				   const char *op,
 				   void *aux)
@@ -677,29 +700,28 @@
 	int ret = -ENOMEM;
 
 	/* msg and im are freed in idmap_pipe_destroy_msg */
-	data = kmalloc(sizeof(*data), GFP_KERNEL);
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
 	if (!data)
 		goto out1;
 
 	msg = &data->pipe_msg;
 	im = &data->idmap_msg;
 	data->idmap = idmap;
+	data->key_cons = cons;
 
 	ret = nfs_idmap_prepare_message(key->description, idmap, im, msg);
 	if (ret < 0)
 		goto out2;
 
-	BUG_ON(idmap->idmap_key_cons != NULL);
-	idmap->idmap_key_cons = cons;
+	ret = -EAGAIN;
+	if (!nfs_idmap_prepare_pipe_upcall(idmap, data))
+		goto out2;
 
 	ret = rpc_queue_upcall(idmap->idmap_pipe, msg);
 	if (ret < 0)
-		goto out3;
+		nfs_idmap_abort_pipe_upcall(idmap, ret);
 
 	return ret;
-
-out3:
-	idmap->idmap_key_cons = NULL;
 out2:
 	kfree(data);
 out1:
@@ -714,21 +736,32 @@
 					authkey);
 }
 
-static int nfs_idmap_read_message(struct idmap_msg *im, struct key *key, struct key *authkey)
+static int nfs_idmap_read_and_verify_message(struct idmap_msg *im,
+		struct idmap_msg *upcall,
+		struct key *key, struct key *authkey)
 {
 	char id_str[NFS_UINT_MAXLEN];
-	int ret = -EINVAL;
+	int ret = -ENOKEY;
 
+	/* ret = -ENOKEY */
+	if (upcall->im_type != im->im_type || upcall->im_conv != im->im_conv)
+		goto out;
 	switch (im->im_conv) {
 	case IDMAP_CONV_NAMETOID:
+		if (strcmp(upcall->im_name, im->im_name) != 0)
+			break;
 		sprintf(id_str, "%d", im->im_id);
 		ret = nfs_idmap_instantiate(key, authkey, id_str);
 		break;
 	case IDMAP_CONV_IDTONAME:
+		if (upcall->im_id != im->im_id)
+			break;
 		ret = nfs_idmap_instantiate(key, authkey, im->im_name);
 		break;
+	default:
+		ret = -EINVAL;
 	}
-
+out:
 	return ret;
 }
 
@@ -740,14 +773,16 @@
 	struct key_construction *cons;
 	struct idmap_msg im;
 	size_t namelen_in;
-	int ret;
+	int ret = -ENOKEY;
 
 	/* If instantiation is successful, anyone waiting for key construction
 	 * will have been woken up and someone else may now have used
 	 * idmap_key_cons - so after this point we may no longer touch it.
 	 */
-	cons = ACCESS_ONCE(idmap->idmap_key_cons);
-	idmap->idmap_key_cons = NULL;
+	if (idmap->idmap_upcall_data == NULL)
+		goto out_noupcall;
+
+	cons = idmap->idmap_upcall_data->key_cons;
 
 	if (mlen != sizeof(im)) {
 		ret = -ENOSPC;
@@ -768,16 +803,19 @@
 	if (namelen_in == 0 || namelen_in == IDMAP_NAMESZ) {
 		ret = -EINVAL;
 		goto out;
-	}
+}
 
-	ret = nfs_idmap_read_message(&im, cons->key, cons->authkey);
+	ret = nfs_idmap_read_and_verify_message(&im,
+			&idmap->idmap_upcall_data->idmap_msg,
+			cons->key, cons->authkey);
 	if (ret >= 0) {
 		key_set_timeout(cons->key, nfs_idmap_cache_timeout);
 		ret = mlen;
 	}
 
 out:
-	complete_request_key(cons, ret);
+	nfs_idmap_complete_pipe_upcall_locked(idmap, ret);
+out_noupcall:
 	return ret;
 }
 
@@ -788,14 +826,9 @@
 			struct idmap_legacy_upcalldata,
 			pipe_msg);
 	struct idmap *idmap = data->idmap;
-	struct key_construction *cons;
-	if (msg->errno) {
-		cons = ACCESS_ONCE(idmap->idmap_key_cons);
-		idmap->idmap_key_cons = NULL;
-		complete_request_key(cons, msg->errno);
-	}
-	/* Free memory allocated in nfs_idmap_legacy_upcall() */
-	kfree(data);
+
+	if (msg->errno)
+		nfs_idmap_abort_pipe_upcall(idmap, msg->errno);
 }
 
 static void
@@ -803,7 +836,8 @@
 {
 	struct rpc_inode *rpci = RPC_I(inode);
 	struct idmap *idmap = (struct idmap *)rpci->private;
-	idmap->idmap_key_cons = NULL;
+
+	nfs_idmap_abort_pipe_upcall(idmap, -EPIPE);
 }
 
 int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_t namelen, __u32 *uid)
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index e4c716d..5c7325c 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -547,8 +547,8 @@
 static void nfs_init_lock_context(struct nfs_lock_context *l_ctx)
 {
 	atomic_set(&l_ctx->count, 1);
-	l_ctx->lockowner = current->files;
-	l_ctx->pid = current->tgid;
+	l_ctx->lockowner.l_owner = current->files;
+	l_ctx->lockowner.l_pid = current->tgid;
 	INIT_LIST_HEAD(&l_ctx->list);
 }
 
@@ -557,9 +557,9 @@
 	struct nfs_lock_context *pos;
 
 	list_for_each_entry(pos, &ctx->lock_context.list, list) {
-		if (pos->lockowner != current->files)
+		if (pos->lockowner.l_owner != current->files)
 			continue;
-		if (pos->pid != current->tgid)
+		if (pos->lockowner.l_pid != current->tgid)
 			continue;
 		atomic_inc(&pos->count);
 		return pos;
@@ -578,7 +578,7 @@
 		spin_unlock(&inode->i_lock);
 		new = kmalloc(sizeof(*new), GFP_KERNEL);
 		if (new == NULL)
-			return NULL;
+			return ERR_PTR(-ENOMEM);
 		nfs_init_lock_context(new);
 		spin_lock(&inode->i_lock);
 		res = __nfs_find_lock_context(ctx);
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 31fdb03..59b133c 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -101,11 +101,11 @@
  */
 struct nfs_parsed_mount_data {
 	int			flags;
-	int			rsize, wsize;
-	int			timeo, retrans;
-	int			acregmin, acregmax,
+	unsigned int		rsize, wsize;
+	unsigned int		timeo, retrans;
+	unsigned int		acregmin, acregmax,
 				acdirmin, acdirmax;
-	int			namlen;
+	unsigned int		namlen;
 	unsigned int		options;
 	unsigned int		bsize;
 	unsigned int		auth_flavor_len;
@@ -464,6 +464,7 @@
 {
 	inode_dio_wait(inode);
 }
+extern ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq);
 
 /* nfs4proc.c */
 extern void __nfs4_read_done_cb(struct nfs_read_data *);
@@ -483,6 +484,12 @@
 				   struct nfs4_sequence_args *args,
 				   struct nfs4_sequence_res *res,
 				   int cache_reply);
+extern int nfs40_walk_client_list(struct nfs_client *clp,
+				struct nfs_client **result,
+				struct rpc_cred *cred);
+extern int nfs41_walk_client_list(struct nfs_client *clp,
+				struct nfs_client **result,
+				struct rpc_cred *cred);
 
 /*
  * Determine the device name as a string
diff --git a/fs/nfs/netns.h b/fs/nfs/netns.h
index 0539de1..8ee1fab 100644
--- a/fs/nfs/netns.h
+++ b/fs/nfs/netns.h
@@ -5,6 +5,7 @@
 #ifndef __NFS_NETNS_H__
 #define __NFS_NETNS_H__
 
+#include <linux/nfs4.h>
 #include <net/net_namespace.h>
 #include <net/netns/generic.h>
 
@@ -22,6 +23,9 @@
 	struct list_head nfs_volume_list;
 #if IS_ENABLED(CONFIG_NFS_V4)
 	struct idr cb_ident_idr; /* Protected by nfs_client_lock */
+	unsigned short nfs_callback_tcpport;
+	unsigned short nfs_callback_tcpport6;
+	int cb_users[NFS4_MAX_MINOR_VERSION + 1];
 #endif
 	spinlock_t nfs_client_lock;
 	struct timespec boot_time;
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index da0618a..a525fde 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -132,8 +132,8 @@
 struct nfs4_lock_state {
 	struct list_head	ls_locks;	/* Other lock stateids */
 	struct nfs4_state *	ls_state;	/* Pointer to open state */
-#define NFS_LOCK_INITIALIZED 1
-	int			ls_flags;
+#define NFS_LOCK_INITIALIZED 0
+	unsigned long		ls_flags;
 	struct nfs_seqid_counter	ls_seqid;
 	nfs4_stateid		ls_stateid;
 	atomic_t		ls_count;
@@ -191,6 +191,8 @@
 	int (*establish_clid)(struct nfs_client *, struct rpc_cred *);
 	struct rpc_cred * (*get_clid_cred)(struct nfs_client *);
 	int (*reclaim_complete)(struct nfs_client *);
+	int (*detect_trunking)(struct nfs_client *, struct nfs_client **,
+		struct rpc_cred *);
 };
 
 struct nfs4_state_maintenance_ops {
@@ -223,7 +225,7 @@
 extern int nfs4_destroy_clientid(struct nfs_client *clp);
 extern int nfs4_init_clientid(struct nfs_client *, struct rpc_cred *);
 extern int nfs41_init_clientid(struct nfs_client *, struct rpc_cred *);
-extern int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait, bool roc);
+extern int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait);
 extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle);
 extern int nfs4_proc_fs_locations(struct rpc_clnt *, struct inode *, const struct qstr *,
 				  struct nfs4_fs_locations *, struct page *);
@@ -320,9 +322,15 @@
 /* nfs4state.c */
 struct rpc_cred *nfs4_get_setclientid_cred(struct nfs_client *clp);
 struct rpc_cred *nfs4_get_renew_cred_locked(struct nfs_client *clp);
+int nfs4_discover_server_trunking(struct nfs_client *clp,
+			struct nfs_client **);
+int nfs40_discover_server_trunking(struct nfs_client *clp,
+			struct nfs_client **, struct rpc_cred *);
 #if defined(CONFIG_NFS_V4_1)
 struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp);
 struct rpc_cred *nfs4_get_exchange_id_cred(struct nfs_client *clp);
+int nfs41_discover_server_trunking(struct nfs_client *clp,
+			struct nfs_client **, struct rpc_cred *);
 extern void nfs4_schedule_session_recovery(struct nfs4_session *, int);
 #else
 static inline void nfs4_schedule_session_recovery(struct nfs4_session *session, int err)
@@ -351,7 +359,7 @@
 extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
 extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
 extern void nfs4_select_rw_stateid(nfs4_stateid *, struct nfs4_state *,
-		fmode_t, fl_owner_t, pid_t);
+		fmode_t, const struct nfs_lockowner *);
 
 extern struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_mask);
 extern int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task);
@@ -372,6 +380,9 @@
 extern unsigned short max_session_slots;
 extern unsigned short send_implementation_id;
 
+#define NFS4_CLIENT_ID_UNIQ_LEN		(64)
+extern char nfs4_client_id_uniquifier[NFS4_CLIENT_ID_UNIQ_LEN];
+
 /* nfs4sysctl.c */
 #ifdef CONFIG_SYSCTL
 int nfs4_register_sysctl(void);
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 24eb663..6bacfde 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -84,7 +84,7 @@
 static void nfs4_destroy_callback(struct nfs_client *clp)
 {
 	if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state))
-		nfs_callback_down(clp->cl_mvops->minor_version);
+		nfs_callback_down(clp->cl_mvops->minor_version, clp->cl_net);
 }
 
 static void nfs4_shutdown_client(struct nfs_client *clp)
@@ -185,6 +185,7 @@
 				    rpc_authflavor_t authflavour)
 {
 	char buf[INET6_ADDRSTRLEN + 1];
+	struct nfs_client *old;
 	int error;
 
 	if (clp->cl_cons_state == NFS_CS_READY) {
@@ -230,6 +231,17 @@
 
 	if (!nfs4_has_session(clp))
 		nfs_mark_client_ready(clp, NFS_CS_READY);
+
+	error = nfs4_discover_server_trunking(clp, &old);
+	if (error < 0)
+		goto error;
+	if (clp != old) {
+		clp->cl_preserve_clid = true;
+		nfs_put_client(clp);
+		clp = old;
+		atomic_inc(&clp->cl_count);
+	}
+
 	return clp;
 
 error:
@@ -239,6 +251,248 @@
 	return ERR_PTR(error);
 }
 
+/*
+ * SETCLIENTID just did a callback update with the callback ident in
+ * "drop," but server trunking discovery claims "drop" and "keep" are
+ * actually the same server.  Swap the callback IDs so that "keep"
+ * will continue to use the callback ident the server now knows about,
+ * and so that "keep"'s original callback ident is destroyed when
+ * "drop" is freed.
+ */
+static void nfs4_swap_callback_idents(struct nfs_client *keep,
+				      struct nfs_client *drop)
+{
+	struct nfs_net *nn = net_generic(keep->cl_net, nfs_net_id);
+	unsigned int save = keep->cl_cb_ident;
+
+	if (keep->cl_cb_ident == drop->cl_cb_ident)
+		return;
+
+	dprintk("%s: keeping callback ident %u and dropping ident %u\n",
+		__func__, keep->cl_cb_ident, drop->cl_cb_ident);
+
+	spin_lock(&nn->nfs_client_lock);
+
+	idr_replace(&nn->cb_ident_idr, keep, drop->cl_cb_ident);
+	keep->cl_cb_ident = drop->cl_cb_ident;
+
+	idr_replace(&nn->cb_ident_idr, drop, save);
+	drop->cl_cb_ident = save;
+
+	spin_unlock(&nn->nfs_client_lock);
+}
+
+/**
+ * nfs40_walk_client_list - Find server that recognizes a client ID
+ *
+ * @new: nfs_client with client ID to test
+ * @result: OUT: found nfs_client, or new
+ * @cred: credential to use for trunking test
+ *
+ * Returns zero, a negative errno, or a negative NFS4ERR status.
+ * If zero is returned, an nfs_client pointer is planted in "result."
+ *
+ * NB: nfs40_walk_client_list() relies on the new nfs_client being
+ *     the last nfs_client on the list.
+ */
+int nfs40_walk_client_list(struct nfs_client *new,
+			   struct nfs_client **result,
+			   struct rpc_cred *cred)
+{
+	struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id);
+	struct nfs_client *pos, *n, *prev = NULL;
+	struct nfs4_setclientid_res clid = {
+		.clientid	= new->cl_clientid,
+		.confirm	= new->cl_confirm,
+	};
+	int status;
+
+	spin_lock(&nn->nfs_client_lock);
+	list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) {
+		/* If "pos" isn't marked ready, we can't trust the
+		 * remaining fields in "pos" */
+		if (pos->cl_cons_state < NFS_CS_READY)
+			continue;
+
+		if (pos->rpc_ops != new->rpc_ops)
+			continue;
+
+		if (pos->cl_proto != new->cl_proto)
+			continue;
+
+		if (pos->cl_minorversion != new->cl_minorversion)
+			continue;
+
+		if (pos->cl_clientid != new->cl_clientid)
+			continue;
+
+		atomic_inc(&pos->cl_count);
+		spin_unlock(&nn->nfs_client_lock);
+
+		if (prev)
+			nfs_put_client(prev);
+
+		status = nfs4_proc_setclientid_confirm(pos, &clid, cred);
+		if (status == 0) {
+			nfs4_swap_callback_idents(pos, new);
+
+			nfs_put_client(pos);
+			*result = pos;
+			dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n",
+				__func__, pos, atomic_read(&pos->cl_count));
+			return 0;
+		}
+		if (status != -NFS4ERR_STALE_CLIENTID) {
+			nfs_put_client(pos);
+			dprintk("NFS: <-- %s status = %d, no result\n",
+				__func__, status);
+			return status;
+		}
+
+		spin_lock(&nn->nfs_client_lock);
+		prev = pos;
+	}
+
+	/*
+	 * No matching nfs_client found.  This should be impossible,
+	 * because the new nfs_client has already been added to
+	 * nfs_client_list by nfs_get_client().
+	 *
+	 * Don't BUG(), since the caller is holding a mutex.
+	 */
+	if (prev)
+		nfs_put_client(prev);
+	spin_unlock(&nn->nfs_client_lock);
+	pr_err("NFS: %s Error: no matching nfs_client found\n", __func__);
+	return -NFS4ERR_STALE_CLIENTID;
+}
+
+#ifdef CONFIG_NFS_V4_1
+/*
+ * Returns true if the client IDs match
+ */
+static bool nfs4_match_clientids(struct nfs_client *a, struct nfs_client *b)
+{
+	if (a->cl_clientid != b->cl_clientid) {
+		dprintk("NFS: --> %s client ID %llx does not match %llx\n",
+			__func__, a->cl_clientid, b->cl_clientid);
+		return false;
+	}
+	dprintk("NFS: --> %s client ID %llx matches %llx\n",
+		__func__, a->cl_clientid, b->cl_clientid);
+	return true;
+}
+
+/*
+ * Returns true if the server owners match
+ */
+static bool
+nfs4_match_serverowners(struct nfs_client *a, struct nfs_client *b)
+{
+	struct nfs41_server_owner *o1 = a->cl_serverowner;
+	struct nfs41_server_owner *o2 = b->cl_serverowner;
+
+	if (o1->minor_id != o2->minor_id) {
+		dprintk("NFS: --> %s server owner minor IDs do not match\n",
+			__func__);
+		return false;
+	}
+
+	if (o1->major_id_sz != o2->major_id_sz)
+		goto out_major_mismatch;
+	if (memcmp(o1->major_id, o2->major_id, o1->major_id_sz) != 0)
+		goto out_major_mismatch;
+
+	dprintk("NFS: --> %s server owners match\n", __func__);
+	return true;
+
+out_major_mismatch:
+	dprintk("NFS: --> %s server owner major IDs do not match\n",
+		__func__);
+	return false;
+}
+
+/**
+ * nfs41_walk_client_list - Find nfs_client that matches a client/server owner
+ *
+ * @new: nfs_client with client ID to test
+ * @result: OUT: found nfs_client, or new
+ * @cred: credential to use for trunking test
+ *
+ * Returns zero, a negative errno, or a negative NFS4ERR status.
+ * If zero is returned, an nfs_client pointer is planted in "result."
+ *
+ * NB: nfs41_walk_client_list() relies on the new nfs_client being
+ *     the last nfs_client on the list.
+ */
+int nfs41_walk_client_list(struct nfs_client *new,
+			   struct nfs_client **result,
+			   struct rpc_cred *cred)
+{
+	struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id);
+	struct nfs_client *pos, *n, *prev = NULL;
+	int error;
+
+	spin_lock(&nn->nfs_client_lock);
+	list_for_each_entry_safe(pos, n, &nn->nfs_client_list, cl_share_link) {
+		/* If "pos" isn't marked ready, we can't trust the
+		 * remaining fields in "pos", especially the client
+		 * ID and serverowner fields.  Wait for CREATE_SESSION
+		 * to finish. */
+		if (pos->cl_cons_state < NFS_CS_READY) {
+			atomic_inc(&pos->cl_count);
+			spin_unlock(&nn->nfs_client_lock);
+
+			if (prev)
+				nfs_put_client(prev);
+			prev = pos;
+
+			error = nfs_wait_client_init_complete(pos);
+			if (error < 0) {
+				nfs_put_client(pos);
+				spin_lock(&nn->nfs_client_lock);
+				continue;
+			}
+
+			spin_lock(&nn->nfs_client_lock);
+		}
+
+		if (pos->rpc_ops != new->rpc_ops)
+			continue;
+
+		if (pos->cl_proto != new->cl_proto)
+			continue;
+
+		if (pos->cl_minorversion != new->cl_minorversion)
+			continue;
+
+		if (!nfs4_match_clientids(pos, new))
+			continue;
+
+		if (!nfs4_match_serverowners(pos, new))
+			continue;
+
+		spin_unlock(&nn->nfs_client_lock);
+		dprintk("NFS: <-- %s using nfs_client = %p ({%d})\n",
+			__func__, pos, atomic_read(&pos->cl_count));
+
+		*result = pos;
+		return 0;
+	}
+
+	/*
+	 * No matching nfs_client found.  This should be impossible,
+	 * because the new nfs_client has already been added to
+	 * nfs_client_list by nfs_get_client().
+	 *
+	 * Don't BUG(), since the caller is holding a mutex.
+	 */
+	spin_unlock(&nn->nfs_client_lock);
+	pr_err("NFS: %s Error: no matching nfs_client found\n", __func__);
+	return -NFS4ERR_STALE_CLIENTID;
+}
+#endif	/* CONFIG_NFS_V4_1 */
+
 static void nfs4_destroy_server(struct nfs_server *server)
 {
 	nfs_server_return_all_delegations(server);
diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c
index eb5eb8e..afddd66 100644
--- a/fs/nfs/nfs4file.c
+++ b/fs/nfs/nfs4file.c
@@ -95,16 +95,25 @@
 	int ret;
 	struct inode *inode = file->f_path.dentry->d_inode;
 
-	ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
-	if (ret != 0)
-		goto out;
-	mutex_lock(&inode->i_mutex);
-	ret = nfs_file_fsync_commit(file, start, end, datasync);
-	if (!ret && !datasync)
-		/* application has asked for meta-data sync */
-		ret = pnfs_layoutcommit_inode(inode, true);
-	mutex_unlock(&inode->i_mutex);
-out:
+	do {
+		ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
+		if (ret != 0)
+			break;
+		mutex_lock(&inode->i_mutex);
+		ret = nfs_file_fsync_commit(file, start, end, datasync);
+		if (!ret && !datasync)
+			/* application has asked for meta-data sync */
+			ret = pnfs_layoutcommit_inode(inode, true);
+		mutex_unlock(&inode->i_mutex);
+		/*
+		 * If nfs_file_fsync_commit detected a server reboot, then
+		 * resend all dirty pages that might have been covered by
+		 * the NFS_CONTEXT_RESEND_WRITES flag
+		 */
+		start = 0;
+		end = LLONG_MAX;
+	} while (ret == -EAGAIN);
+
 	return ret;
 }
 
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c
index 53f94d9..52d8472 100644
--- a/fs/nfs/nfs4filelayout.c
+++ b/fs/nfs/nfs4filelayout.c
@@ -190,8 +190,6 @@
 		 * i/o and all i/o waiting on the slot table to the MDS until
 		 * layout is destroyed and a new valid layout is obtained.
 		 */
-		set_bit(NFS_LAYOUT_INVALID,
-				&NFS_I(inode)->layout->plh_flags);
 		pnfs_destroy_layout(NFS_I(inode));
 		rpc_wake_up(&tbl->slot_tbl_waitq);
 		goto reset;
@@ -205,7 +203,7 @@
 	case -EPIPE:
 		dprintk("%s DS connection error %d\n", __func__,
 			task->tk_status);
-		filelayout_mark_devid_invalid(devid);
+		nfs4_mark_deviceid_unavailable(devid);
 		clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(inode)->flags);
 		_pnfs_return_layout(inode);
 		rpc_wake_up(&tbl->slot_tbl_waitq);
@@ -269,6 +267,21 @@
 		(unsigned long) NFS_I(hdr->inode)->layout->plh_lwb);
 }
 
+bool
+filelayout_test_devid_unavailable(struct nfs4_deviceid_node *node)
+{
+	return filelayout_test_devid_invalid(node) ||
+		nfs4_test_deviceid_unavailable(node);
+}
+
+static bool
+filelayout_reset_to_mds(struct pnfs_layout_segment *lseg)
+{
+	struct nfs4_deviceid_node *node = FILELAYOUT_DEVID_NODE(lseg);
+
+	return filelayout_test_devid_unavailable(node);
+}
+
 /*
  * Call ops for the async read/write cases
  * In the case of dense layouts, the offset needs to be reset to its
@@ -453,7 +466,7 @@
 	struct nfs_commit_data *data = calldata;
 
 	data->completion_ops->completion(data);
-	put_lseg(data->lseg);
+	pnfs_put_lseg(data->lseg);
 	nfs_put_client(data->ds_clp);
 	nfs_commitdata_release(data);
 }
@@ -608,13 +621,13 @@
 	d = nfs4_find_get_deviceid(NFS_SERVER(lo->plh_inode)->pnfs_curr_ld,
 				   NFS_SERVER(lo->plh_inode)->nfs_client, id);
 	if (d == NULL) {
-		dsaddr = get_device_info(lo->plh_inode, id, gfp_flags);
+		dsaddr = filelayout_get_device_info(lo->plh_inode, id, gfp_flags);
 		if (dsaddr == NULL)
 			goto out;
 	} else
 		dsaddr = container_of(d, struct nfs4_file_layout_dsaddr, id_node);
-	/* Found deviceid is being reaped */
-	if (test_bit(NFS_DEVICEID_INVALID, &dsaddr->id_node.flags))
+	/* Found deviceid is unavailable */
+	if (filelayout_test_devid_unavailable(&dsaddr->id_node))
 			goto out_put;
 
 	fl->dsaddr = dsaddr;
@@ -931,7 +944,7 @@
 	nfs_init_cinfo(&cinfo, pgio->pg_inode, pgio->pg_dreq);
 	status = filelayout_alloc_commit_info(pgio->pg_lseg, &cinfo, GFP_NOFS);
 	if (status < 0) {
-		put_lseg(pgio->pg_lseg);
+		pnfs_put_lseg(pgio->pg_lseg);
 		pgio->pg_lseg = NULL;
 		goto out_mds;
 	}
@@ -985,7 +998,7 @@
 out:
 	nfs_request_remove_commit_list(req, cinfo);
 	spin_unlock(cinfo->lock);
-	put_lseg(freeme);
+	pnfs_put_lseg(freeme);
 }
 
 static struct list_head *
@@ -1018,7 +1031,7 @@
 		 * off due to a rewrite, in which case it will be done in
 		 * filelayout_clear_request_commit
 		 */
-		buckets[i].wlseg = get_lseg(lseg);
+		buckets[i].wlseg = pnfs_get_lseg(lseg);
 	}
 	set_bit(PG_COMMIT_TO_DS, &req->wb_flags);
 	cinfo->ds->nwritten++;
@@ -1128,7 +1141,7 @@
 		if (list_empty(src))
 			bucket->wlseg = NULL;
 		else
-			get_lseg(bucket->clseg);
+			pnfs_get_lseg(bucket->clseg);
 	}
 	return ret;
 }
@@ -1159,12 +1172,12 @@
 
 	/* NOTE cinfo->lock is NOT held, relying on fact that this is
 	 * only called on single thread per dreq.
-	 * Can't take the lock because need to do put_lseg
+	 * Can't take the lock because need to do pnfs_put_lseg
 	 */
 	for (i = 0, b = cinfo->ds->buckets; i < cinfo->ds->nbuckets; i++, b++) {
 		if (transfer_commit_list(&b->written, dst, cinfo, 0)) {
 			BUG_ON(!list_empty(&b->written));
-			put_lseg(b->wlseg);
+			pnfs_put_lseg(b->wlseg);
 			b->wlseg = NULL;
 		}
 	}
@@ -1200,7 +1213,7 @@
 		if (list_empty(&bucket->committing))
 			continue;
 		nfs_retry_commit(&bucket->committing, bucket->clseg, cinfo);
-		put_lseg(bucket->clseg);
+		pnfs_put_lseg(bucket->clseg);
 		bucket->clseg = NULL;
 	}
 	/* Caller will clean up entries put on list */
diff --git a/fs/nfs/nfs4filelayout.h b/fs/nfs/nfs4filelayout.h
index 43fe802..dca47d78 100644
--- a/fs/nfs/nfs4filelayout.h
+++ b/fs/nfs/nfs4filelayout.h
@@ -129,23 +129,13 @@
 }
 
 static inline bool
-filelayout_test_layout_invalid(struct pnfs_layout_hdr *lo)
-{
-	return test_bit(NFS_LAYOUT_INVALID, &lo->plh_flags);
-}
-
-static inline bool
 filelayout_test_devid_invalid(struct nfs4_deviceid_node *node)
 {
 	return test_bit(NFS_DEVICEID_INVALID, &node->flags);
 }
 
-static inline bool
-filelayout_reset_to_mds(struct pnfs_layout_segment *lseg)
-{
-	return filelayout_test_devid_invalid(FILELAYOUT_DEVID_NODE(lseg)) ||
-		filelayout_test_layout_invalid(lseg->pls_layout);
-}
+extern bool
+filelayout_test_devid_unavailable(struct nfs4_deviceid_node *node);
 
 extern struct nfs_fh *
 nfs4_fl_select_ds_fh(struct pnfs_layout_segment *lseg, u32 j);
@@ -158,7 +148,7 @@
 extern void nfs4_fl_put_deviceid(struct nfs4_file_layout_dsaddr *dsaddr);
 extern void nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr);
 struct nfs4_file_layout_dsaddr *
-get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags);
+filelayout_get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags);
 void nfs4_ds_disconnect(struct nfs_client *clp);
 
 #endif /* FS_NFS_NFS4FILELAYOUT_H */
diff --git a/fs/nfs/nfs4filelayoutdev.c b/fs/nfs/nfs4filelayoutdev.c
index f81231f..3336d5e 100644
--- a/fs/nfs/nfs4filelayoutdev.c
+++ b/fs/nfs/nfs4filelayoutdev.c
@@ -690,7 +690,7 @@
  * of available devices, and return it.
  */
 struct nfs4_file_layout_dsaddr *
-get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags)
+filelayout_get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_flags)
 {
 	struct pnfs_device *pdev = NULL;
 	u32 max_resp_sz;
@@ -804,13 +804,14 @@
 	struct nfs4_pnfs_ds *ds = dsaddr->ds_list[ds_idx];
 	struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg);
 
-	if (filelayout_test_devid_invalid(devid))
+	if (filelayout_test_devid_unavailable(devid))
 		return NULL;
 
 	if (ds == NULL) {
 		printk(KERN_ERR "NFS: %s: No data server for offset index %d\n",
 			__func__, ds_idx);
-		goto mark_dev_invalid;
+		filelayout_mark_devid_invalid(devid);
+		return NULL;
 	}
 
 	if (!ds->ds_clp) {
@@ -818,14 +819,12 @@
 		int err;
 
 		err = nfs4_ds_connect(s, ds);
-		if (err)
-			goto mark_dev_invalid;
+		if (err) {
+			nfs4_mark_deviceid_unavailable(devid);
+			return NULL;
+		}
 	}
 	return ds;
-
-mark_dev_invalid:
-	filelayout_mark_devid_invalid(devid);
-	return NULL;
 }
 
 module_param(dataserver_retrans, uint, 0644);
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
index 017b4b0..79fbb61 100644
--- a/fs/nfs/nfs4namespace.c
+++ b/fs/nfs/nfs4namespace.c
@@ -192,25 +192,13 @@
 struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *clnt, struct inode *inode,
 					struct qstr *name)
 {
-	struct rpc_clnt *clone;
-	struct rpc_auth *auth;
 	rpc_authflavor_t flavor;
 
 	flavor = nfs4_negotiate_security(inode, name);
 	if ((int)flavor < 0)
-		return ERR_PTR(flavor);
+		return ERR_PTR((int)flavor);
 
-	clone = rpc_clone_client(clnt);
-	if (IS_ERR(clone))
-		return clone;
-
-	auth = rpcauth_create(flavor, clone);
-	if (!auth) {
-		rpc_shutdown_client(clone);
-		clone = ERR_PTR(-EIO);
-	}
-
-	return clone;
+	return rpc_clone_client_set_auth(clnt, flavor);
 }
 
 static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 1e50326..68b21d8 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -104,6 +104,8 @@
 		return -EACCES;
 	case -NFS4ERR_MINOR_VERS_MISMATCH:
 		return -EPROTONOSUPPORT;
+	case -NFS4ERR_ACCESS:
+		return -EACCES;
 	default:
 		dprintk("%s could not handle NFSv4 error %d\n",
 				__func__, -err);
@@ -150,6 +152,12 @@
 	FATTR4_WORD2_MDSTHRESHOLD
 };
 
+static const u32 nfs4_open_noattr_bitmap[3] = {
+	FATTR4_WORD0_TYPE
+	| FATTR4_WORD0_CHANGE
+	| FATTR4_WORD0_FILEID,
+};
+
 const u32 nfs4_statfs_bitmap[2] = {
 	FATTR4_WORD0_FILES_AVAIL
 	| FATTR4_WORD0_FILES_FREE
@@ -832,6 +840,7 @@
 	p->o_res.seqid = p->o_arg.seqid;
 	p->c_res.seqid = p->c_arg.seqid;
 	p->o_res.server = p->o_arg.server;
+	p->o_res.access_request = p->o_arg.access;
 	nfs_fattr_init(&p->f_attr);
 	nfs_fattr_init_names(&p->f_attr, &p->owner_name, &p->group_name);
 }
@@ -860,6 +869,14 @@
 	p->o_arg.fh = NFS_FH(dir);
 	p->o_arg.open_flags = flags;
 	p->o_arg.fmode = fmode & (FMODE_READ|FMODE_WRITE);
+	/* don't put an ACCESS op in OPEN compound if O_EXCL, because ACCESS
+	 * will return permission denied for all bits until close */
+	if (!(flags & O_EXCL)) {
+		/* ask server to check for all possible rights as results
+		 * are cached */
+		p->o_arg.access = NFS4_ACCESS_READ | NFS4_ACCESS_MODIFY |
+				  NFS4_ACCESS_EXTEND | NFS4_ACCESS_EXECUTE;
+	}
 	p->o_arg.clientid = server->nfs_client->cl_clientid;
 	p->o_arg.id.create_time = ktime_to_ns(sp->so_seqid.create_time);
 	p->o_arg.id.uniquifier = sp->so_seqid.owner_id;
@@ -1115,11 +1132,80 @@
 	return state;
 }
 
-static struct nfs4_state *nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data)
+static void
+nfs4_opendata_check_deleg(struct nfs4_opendata *data, struct nfs4_state *state)
+{
+	struct nfs_client *clp = NFS_SERVER(state->inode)->nfs_client;
+	struct nfs_delegation *delegation;
+	int delegation_flags = 0;
+
+	rcu_read_lock();
+	delegation = rcu_dereference(NFS_I(state->inode)->delegation);
+	if (delegation)
+		delegation_flags = delegation->flags;
+	rcu_read_unlock();
+	if (data->o_arg.claim == NFS4_OPEN_CLAIM_DELEGATE_CUR) {
+		pr_err_ratelimited("NFS: Broken NFSv4 server %s is "
+				   "returning a delegation for "
+				   "OPEN(CLAIM_DELEGATE_CUR)\n",
+				   clp->cl_hostname);
+	} else if ((delegation_flags & 1UL<<NFS_DELEGATION_NEED_RECLAIM) == 0)
+		nfs_inode_set_delegation(state->inode,
+					 data->owner->so_cred,
+					 &data->o_res);
+	else
+		nfs_inode_reclaim_delegation(state->inode,
+					     data->owner->so_cred,
+					     &data->o_res);
+}
+
+/*
+ * Check the inode attributes against the CLAIM_PREVIOUS returned attributes
+ * and update the nfs4_state.
+ */
+static struct nfs4_state *
+_nfs4_opendata_reclaim_to_nfs4_state(struct nfs4_opendata *data)
+{
+	struct inode *inode = data->state->inode;
+	struct nfs4_state *state = data->state;
+	int ret;
+
+	if (!data->rpc_done) {
+		ret = data->rpc_status;
+		goto err;
+	}
+
+	ret = -ESTALE;
+	if (!(data->f_attr.valid & NFS_ATTR_FATTR_TYPE) ||
+	    !(data->f_attr.valid & NFS_ATTR_FATTR_FILEID) ||
+	    !(data->f_attr.valid & NFS_ATTR_FATTR_CHANGE))
+		goto err;
+
+	ret = -ENOMEM;
+	state = nfs4_get_open_state(inode, data->owner);
+	if (state == NULL)
+		goto err;
+
+	ret = nfs_refresh_inode(inode, &data->f_attr);
+	if (ret)
+		goto err;
+
+	if (data->o_res.delegation_type != 0)
+		nfs4_opendata_check_deleg(data, state);
+	update_open_stateid(state, &data->o_res.stateid, NULL,
+			    data->o_arg.fmode);
+
+	return state;
+err:
+	return ERR_PTR(ret);
+
+}
+
+static struct nfs4_state *
+_nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data)
 {
 	struct inode *inode;
 	struct nfs4_state *state = NULL;
-	struct nfs_delegation *delegation;
 	int ret;
 
 	if (!data->rpc_done) {
@@ -1138,30 +1224,8 @@
 	state = nfs4_get_open_state(inode, data->owner);
 	if (state == NULL)
 		goto err_put_inode;
-	if (data->o_res.delegation_type != 0) {
-		struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
-		int delegation_flags = 0;
-
-		rcu_read_lock();
-		delegation = rcu_dereference(NFS_I(inode)->delegation);
-		if (delegation)
-			delegation_flags = delegation->flags;
-		rcu_read_unlock();
-		if (data->o_arg.claim == NFS4_OPEN_CLAIM_DELEGATE_CUR) {
-			pr_err_ratelimited("NFS: Broken NFSv4 server %s is "
-					"returning a delegation for "
-					"OPEN(CLAIM_DELEGATE_CUR)\n",
-					clp->cl_hostname);
-		} else if ((delegation_flags & 1UL<<NFS_DELEGATION_NEED_RECLAIM) == 0)
-			nfs_inode_set_delegation(state->inode,
-					data->owner->so_cred,
-					&data->o_res);
-		else
-			nfs_inode_reclaim_delegation(state->inode,
-					data->owner->so_cred,
-					&data->o_res);
-	}
-
+	if (data->o_res.delegation_type != 0)
+		nfs4_opendata_check_deleg(data, state);
 	update_open_stateid(state, &data->o_res.stateid, NULL,
 			data->o_arg.fmode);
 	iput(inode);
@@ -1173,6 +1237,14 @@
 	return ERR_PTR(ret);
 }
 
+static struct nfs4_state *
+nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data)
+{
+	if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS)
+		return _nfs4_opendata_reclaim_to_nfs4_state(data);
+	return _nfs4_opendata_to_nfs4_state(data);
+}
+
 static struct nfs_open_context *nfs4_state_find_open_context(struct nfs4_state *state)
 {
 	struct nfs_inode *nfsi = NFS_I(state->inode);
@@ -1494,6 +1566,7 @@
 	data->o_arg.clientid = sp->so_server->nfs_client->cl_clientid;
 	if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS) {
 		task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR];
+		data->o_arg.open_bitmap = &nfs4_open_noattr_bitmap[0];
 		nfs_copy_fh(&data->o_res.fh, data->o_arg.fh);
 	}
 	data->timestamp = jiffies;
@@ -1526,7 +1599,8 @@
 		return;
 
 	if (task->tk_status == 0) {
-		switch (data->o_res.f_attr->mode & S_IFMT) {
+		if (data->o_res.f_attr->valid & NFS_ATTR_FATTR_TYPE) {
+			switch (data->o_res.f_attr->mode & S_IFMT) {
 			case S_IFREG:
 				break;
 			case S_IFLNK:
@@ -1537,6 +1611,7 @@
 				break;
 			default:
 				data->rpc_status = -ENOTDIR;
+			}
 		}
 		renew_lease(data->o_res.server, data->timestamp);
 		if (!(data->o_res.rflags & NFS4_OPEN_RESULT_CONFIRM))
@@ -1643,6 +1718,39 @@
 	return status;
 }
 
+static int nfs4_opendata_access(struct rpc_cred *cred,
+				struct nfs4_opendata *opendata,
+				struct nfs4_state *state, fmode_t fmode)
+{
+	struct nfs_access_entry cache;
+	u32 mask;
+
+	/* access call failed or for some reason the server doesn't
+	 * support any access modes -- defer access call until later */
+	if (opendata->o_res.access_supported == 0)
+		return 0;
+
+	mask = 0;
+	/* don't check MAY_WRITE - a newly created file may not have
+	 * write mode bits, but POSIX allows the creating process to write */
+	if (fmode & FMODE_READ)
+		mask |= MAY_READ;
+	if (fmode & FMODE_EXEC)
+		mask |= MAY_EXEC;
+
+	cache.cred = cred;
+	cache.jiffies = jiffies;
+	nfs_access_set_mask(&cache, opendata->o_res.access_result);
+	nfs_access_add_cache(state->inode, &cache);
+
+	if ((mask & ~cache.mask & (MAY_READ | MAY_EXEC)) == 0)
+		return 0;
+
+	/* even though OPEN succeeded, access is denied. Close the file */
+	nfs4_close_state(state, fmode);
+	return -NFS4ERR_ACCESS;
+}
+
 /*
  * Note: On error, nfs4_proc_open will free the struct nfs4_opendata
  */
@@ -1774,7 +1882,11 @@
 		 * informs us the stateid is unrecognized. */
 		if (status != -NFS4ERR_BAD_STATEID)
 			nfs41_free_stateid(server, stateid);
+		nfs_remove_bad_delegation(state->inode);
 
+		write_seqlock(&state->seqlock);
+		nfs4_stateid_copy(&state->stateid, &state->open_stateid);
+		write_sequnlock(&state->seqlock);
 		clear_bit(NFS_DELEGATED_STATE, &state->flags);
 	}
 }
@@ -1790,7 +1902,7 @@
 static int nfs41_check_open_stateid(struct nfs4_state *state)
 {
 	struct nfs_server *server = NFS_SERVER(state->inode);
-	nfs4_stateid *stateid = &state->stateid;
+	nfs4_stateid *stateid = &state->open_stateid;
 	int status;
 
 	/* If a state reset has been done, test_stateid is unneeded */
@@ -1896,6 +2008,10 @@
 	if (server->caps & NFS_CAP_POSIX_LOCK)
 		set_bit(NFS_STATE_POSIX_LOCKS, &state->flags);
 
+	status = nfs4_opendata_access(cred, opendata, state, fmode);
+	if (status != 0)
+		goto err_opendata_put;
+
 	if (opendata->o_arg.open_flags & O_EXCL) {
 		nfs4_exclusive_attrset(opendata, sattr);
 
@@ -1941,7 +2057,7 @@
 	struct nfs4_state *res;
 	int status;
 
-	fmode &= FMODE_READ|FMODE_WRITE;
+	fmode &= FMODE_READ|FMODE_WRITE|FMODE_EXEC;
 	do {
 		status = _nfs4_do_open(dir, dentry, fmode, flags, sattr, cred,
 				       &res, ctx_th);
@@ -2013,8 +2129,12 @@
 	nfs_fattr_init(fattr);
 
 	if (state != NULL) {
+		struct nfs_lockowner lockowner = {
+			.l_owner = current->files,
+			.l_pid = current->tgid,
+		};
 		nfs4_select_rw_stateid(&arg.stateid, state, FMODE_WRITE,
-				current->files, current->tgid);
+				&lockowner);
 	} else if (nfs4_copy_delegation_stateid(&arg.stateid, inode,
 				FMODE_WRITE)) {
 		/* Use that stateid */
@@ -2133,6 +2253,7 @@
 {
 	struct nfs4_closedata *calldata = data;
 	struct nfs4_state *state = calldata->state;
+	struct inode *inode = calldata->inode;
 	int call_close = 0;
 
 	dprintk("%s: begin!\n", __func__);
@@ -2166,16 +2287,13 @@
 	if (calldata->arg.fmode == 0) {
 		task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE];
 		if (calldata->roc &&
-		    pnfs_roc_drain(calldata->inode, &calldata->roc_barrier)) {
-			rpc_sleep_on(&NFS_SERVER(calldata->inode)->roc_rpcwaitq,
-				     task, NULL);
+		    pnfs_roc_drain(inode, &calldata->roc_barrier, task))
 			goto out;
-		}
 	}
 
 	nfs_fattr_init(calldata->res.fattr);
 	calldata->timestamp = jiffies;
-	if (nfs4_setup_sequence(NFS_SERVER(calldata->inode),
+	if (nfs4_setup_sequence(NFS_SERVER(inode),
 				&calldata->arg.seq_args,
 				&calldata->res.seq_res,
 				task))
@@ -2202,7 +2320,7 @@
  *
  * NOTE: Caller must be holding the sp->so_owner semaphore!
  */
-int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait, bool roc)
+int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait)
 {
 	struct nfs_server *server = NFS_SERVER(state->inode);
 	struct nfs4_closedata *calldata;
@@ -2238,7 +2356,7 @@
 	calldata->res.fattr = &calldata->fattr;
 	calldata->res.seqid = calldata->arg.seqid;
 	calldata->res.server = server;
-	calldata->roc = roc;
+	calldata->roc = pnfs_roc(state->inode);
 	nfs_sb_active(calldata->inode->i_sb);
 
 	msg.rpc_argp = &calldata->arg;
@@ -2255,8 +2373,6 @@
 out_free_calldata:
 	kfree(calldata);
 out:
-	if (roc)
-		pnfs_roc_release(state->inode);
 	nfs4_put_open_state(state);
 	nfs4_put_state_owner(sp);
 	return status;
@@ -2399,7 +2515,7 @@
 	int ret;
 
 	auth = rpcauth_create(flavor, server->client);
-	if (!auth) {
+	if (IS_ERR(auth)) {
 		ret = -EIO;
 		goto out;
 	}
@@ -2767,13 +2883,7 @@
 
 	status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
 	if (!status) {
-		entry->mask = 0;
-		if (res.access & NFS4_ACCESS_READ)
-			entry->mask |= MAY_READ;
-		if (res.access & (NFS4_ACCESS_MODIFY | NFS4_ACCESS_EXTEND | NFS4_ACCESS_DELETE))
-			entry->mask |= MAY_WRITE;
-		if (res.access & (NFS4_ACCESS_LOOKUP|NFS4_ACCESS_EXECUTE))
-			entry->mask |= MAY_EXEC;
+		nfs_access_set_mask(entry, res.access);
 		nfs_refresh_inode(inode, res.fattr);
 	}
 	nfs_free_fattr(res.fattr);
@@ -3362,8 +3472,11 @@
 
 	nfs_fattr_init(fsinfo->fattr);
 	error = nfs4_do_fsinfo(server, fhandle, fsinfo);
-	if (error == 0)
+	if (error == 0) {
+		/* block layout checks this! */
+		server->pnfs_blksize = fsinfo->blksize;
 		set_pnfs_layoutdriver(server, fhandle, fsinfo->layouttype);
+	}
 
 	return error;
 }
@@ -4007,6 +4120,36 @@
 	memcpy(bootverf->data, verf, sizeof(bootverf->data));
 }
 
+static unsigned int
+nfs4_init_nonuniform_client_string(const struct nfs_client *clp,
+				   char *buf, size_t len)
+{
+	unsigned int result;
+
+	rcu_read_lock();
+	result = scnprintf(buf, len, "Linux NFSv4.0 %s/%s %s",
+				clp->cl_ipaddr,
+				rpc_peeraddr2str(clp->cl_rpcclient,
+							RPC_DISPLAY_ADDR),
+				rpc_peeraddr2str(clp->cl_rpcclient,
+							RPC_DISPLAY_PROTO));
+	rcu_read_unlock();
+	return result;
+}
+
+static unsigned int
+nfs4_init_uniform_client_string(const struct nfs_client *clp,
+				char *buf, size_t len)
+{
+	char *nodename = clp->cl_rpcclient->cl_nodename;
+
+	if (nfs4_client_id_uniquifier[0] != '\0')
+		nodename = nfs4_client_id_uniquifier;
+	return scnprintf(buf, len, "Linux NFSv%u.%u %s",
+				clp->rpc_ops->version, clp->cl_minorversion,
+				nodename);
+}
+
 /**
  * nfs4_proc_setclientid - Negotiate client ID
  * @clp: state data structure
@@ -4037,15 +4180,18 @@
 
 	/* nfs_client_id4 */
 	nfs4_init_boot_verifier(clp, &sc_verifier);
-	rcu_read_lock();
-	setclientid.sc_name_len = scnprintf(setclientid.sc_name,
-			sizeof(setclientid.sc_name), "%s/%s %s",
-			clp->cl_ipaddr,
-			rpc_peeraddr2str(clp->cl_rpcclient,
-						RPC_DISPLAY_ADDR),
-			rpc_peeraddr2str(clp->cl_rpcclient,
-						RPC_DISPLAY_PROTO));
+	if (test_bit(NFS_CS_MIGRATION, &clp->cl_flags))
+		setclientid.sc_name_len =
+				nfs4_init_uniform_client_string(clp,
+						setclientid.sc_name,
+						sizeof(setclientid.sc_name));
+	else
+		setclientid.sc_name_len =
+				nfs4_init_nonuniform_client_string(clp,
+						setclientid.sc_name,
+						sizeof(setclientid.sc_name));
 	/* cb_client4 */
+	rcu_read_lock();
 	setclientid.sc_netid_len = scnprintf(setclientid.sc_netid,
 				sizeof(setclientid.sc_netid),
 				rpc_peeraddr2str(clp->cl_rpcclient,
@@ -4391,7 +4537,7 @@
 
 	if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0)
 		return;
-	if ((calldata->lsp->ls_flags & NFS_LOCK_INITIALIZED) == 0) {
+	if (test_bit(NFS_LOCK_INITIALIZED, &calldata->lsp->ls_flags) == 0) {
 		/* Note: exit _without_ running nfs4_locku_done */
 		task->tk_action = NULL;
 		return;
@@ -4585,7 +4731,7 @@
 	}
 	if (data->rpc_status == 0) {
 		nfs4_stateid_copy(&data->lsp->ls_stateid, &data->res.stateid);
-		data->lsp->ls_flags |= NFS_LOCK_INITIALIZED;
+		set_bit(NFS_LOCK_INITIALIZED, &data->lsp->ls_flags);
 		renew_lease(NFS_SERVER(data->ctx->dentry->d_inode), data->timestamp);
 	}
 out:
@@ -4632,7 +4778,7 @@
 	case -NFS4ERR_BAD_STATEID:
 		lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED;
 		if (new_lock_owner != 0 ||
-		   (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0)
+		   test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags) != 0)
 			nfs4_schedule_stateid_recovery(server, lsp->ls_state);
 		break;
 	case -NFS4ERR_STALE_STATEID:
@@ -4756,7 +4902,7 @@
 	struct nfs_server *server = NFS_SERVER(state->inode);
 
 	list_for_each_entry(lsp, &state->lock_states, ls_locks) {
-		if (lsp->ls_flags & NFS_LOCK_INITIALIZED) {
+		if (test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags)) {
 			status = nfs41_test_stateid(server, &lsp->ls_stateid);
 			if (status != NFS_OK) {
 				/* Free the stateid unless the server
@@ -4764,7 +4910,7 @@
 				if (status != -NFS4ERR_BAD_STATEID)
 					nfs41_free_stateid(server,
 							&lsp->ls_stateid);
-				lsp->ls_flags &= ~NFS_LOCK_INITIALIZED;
+				clear_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags);
 				ret = status;
 			}
 		}
@@ -5267,10 +5413,8 @@
 	};
 
 	nfs4_init_boot_verifier(clp, &verifier);
-	args.id_len = scnprintf(args.id, sizeof(args.id),
-				"%s/%s",
-				clp->cl_ipaddr,
-				clp->cl_rpcclient->cl_nodename);
+	args.id_len = nfs4_init_uniform_client_string(clp, args.id,
+							sizeof(args.id));
 	dprintk("NFS call  exchange_id auth=%s, '%.*s'\n",
 		clp->cl_rpcclient->cl_auth->au_ops->au_name,
 		args.id_len, args.id);
@@ -5391,6 +5535,8 @@
 		goto out;
 	if (clp->cl_exchange_flags == 0)
 		goto out;
+	if (clp->cl_preserve_clid)
+		goto out;
 	cred = nfs4_get_exchange_id_cred(clp);
 	ret = nfs4_proc_destroy_clientid(clp, cred);
 	if (cred)
@@ -6196,26 +6342,44 @@
 static void nfs4_layoutget_done(struct rpc_task *task, void *calldata)
 {
 	struct nfs4_layoutget *lgp = calldata;
-	struct nfs_server *server = NFS_SERVER(lgp->args.inode);
+	struct inode *inode = lgp->args.inode;
+	struct nfs_server *server = NFS_SERVER(inode);
+	struct pnfs_layout_hdr *lo;
+	struct nfs4_state *state = NULL;
 
 	dprintk("--> %s\n", __func__);
 
 	if (!nfs4_sequence_done(task, &lgp->res.seq_res))
-		return;
+		goto out;
 
 	switch (task->tk_status) {
 	case 0:
-		break;
+		goto out;
 	case -NFS4ERR_LAYOUTTRYLATER:
 	case -NFS4ERR_RECALLCONFLICT:
 		task->tk_status = -NFS4ERR_DELAY;
-		/* Fall through */
-	default:
-		if (nfs4_async_handle_error(task, server, NULL) == -EAGAIN) {
-			rpc_restart_call_prepare(task);
-			return;
+		break;
+	case -NFS4ERR_EXPIRED:
+	case -NFS4ERR_BAD_STATEID:
+		spin_lock(&inode->i_lock);
+		lo = NFS_I(inode)->layout;
+		if (!lo || list_empty(&lo->plh_segs)) {
+			spin_unlock(&inode->i_lock);
+			/* If the open stateid was bad, then recover it. */
+			state = lgp->args.ctx->state;
+		} else {
+			LIST_HEAD(head);
+
+			pnfs_mark_matching_lsegs_invalid(lo, &head, NULL);
+			spin_unlock(&inode->i_lock);
+			/* Mark the bad layout state as invalid, then
+			 * retry using the open stateid. */
+			pnfs_free_lseg_list(&head);
 		}
 	}
+	if (nfs4_async_handle_error(task, server, state) == -EAGAIN)
+		rpc_restart_call_prepare(task);
+out:
 	dprintk("<-- %s\n", __func__);
 }
 
@@ -6282,7 +6446,8 @@
 	.rpc_release = nfs4_layoutget_release,
 };
 
-void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
+struct pnfs_layout_segment *
+nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags)
 {
 	struct nfs_server *server = NFS_SERVER(lgp->args.inode);
 	size_t max_pages = max_response_pages(server);
@@ -6299,6 +6464,7 @@
 		.callback_data = lgp,
 		.flags = RPC_TASK_ASYNC,
 	};
+	struct pnfs_layout_segment *lseg = NULL;
 	int status = 0;
 
 	dprintk("--> %s\n", __func__);
@@ -6306,7 +6472,7 @@
 	lgp->args.layout.pages = nfs4_alloc_pages(max_pages, gfp_flags);
 	if (!lgp->args.layout.pages) {
 		nfs4_layoutget_release(lgp);
-		return;
+		return ERR_PTR(-ENOMEM);
 	}
 	lgp->args.layout.pglen = max_pages * PAGE_SIZE;
 
@@ -6315,15 +6481,17 @@
 	nfs41_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0);
 	task = rpc_run_task(&task_setup_data);
 	if (IS_ERR(task))
-		return;
+		return ERR_CAST(task);
 	status = nfs4_wait_for_completion_rpc_task(task);
 	if (status == 0)
 		status = task->tk_status;
 	if (status == 0)
-		status = pnfs_layout_process(lgp);
+		lseg = pnfs_layout_process(lgp);
 	rpc_put_task(task);
 	dprintk("<-- %s status=%d\n", __func__, status);
-	return;
+	if (status)
+		return ERR_PTR(status);
+	return lseg;
 }
 
 static void
@@ -6342,7 +6510,6 @@
 {
 	struct nfs4_layoutreturn *lrp = calldata;
 	struct nfs_server *server;
-	struct pnfs_layout_hdr *lo = lrp->args.layout;
 
 	dprintk("--> %s\n", __func__);
 
@@ -6354,20 +6521,21 @@
 		rpc_restart_call_prepare(task);
 		return;
 	}
-	spin_lock(&lo->plh_inode->i_lock);
-	if (task->tk_status == 0 && lrp->res.lrs_present)
-		pnfs_set_layout_stateid(lo, &lrp->res.stateid, true);
-	lo->plh_block_lgets--;
-	spin_unlock(&lo->plh_inode->i_lock);
 	dprintk("<-- %s\n", __func__);
 }
 
 static void nfs4_layoutreturn_release(void *calldata)
 {
 	struct nfs4_layoutreturn *lrp = calldata;
+	struct pnfs_layout_hdr *lo = lrp->args.layout;
 
 	dprintk("--> %s\n", __func__);
-	put_layout_hdr(lrp->args.layout);
+	spin_lock(&lo->plh_inode->i_lock);
+	if (lrp->res.lrs_present)
+		pnfs_set_layout_stateid(lo, &lrp->res.stateid, true);
+	lo->plh_block_lgets--;
+	spin_unlock(&lo->plh_inode->i_lock);
+	pnfs_put_layout_hdr(lrp->args.layout);
 	kfree(calldata);
 	dprintk("<-- %s\n", __func__);
 }
@@ -6541,7 +6709,7 @@
 		list_del_init(&lseg->pls_lc_list);
 		if (test_and_clear_bit(NFS_LSEG_LAYOUTCOMMIT,
 				       &lseg->pls_flags))
-			put_lseg(lseg);
+			pnfs_put_lseg(lseg);
 	}
 
 	clear_bit_unlock(NFS_INO_LAYOUTCOMMITTING, bitlock);
@@ -6800,6 +6968,7 @@
 	.recover_lock	= nfs4_lock_reclaim,
 	.establish_clid = nfs4_init_clientid,
 	.get_clid_cred	= nfs4_get_setclientid_cred,
+	.detect_trunking = nfs40_discover_server_trunking,
 };
 
 #if defined(CONFIG_NFS_V4_1)
@@ -6811,6 +6980,7 @@
 	.establish_clid = nfs41_init_clientid,
 	.get_clid_cred	= nfs4_get_exchange_id_cred,
 	.reclaim_complete = nfs41_proc_reclaim_complete,
+	.detect_trunking = nfs41_discover_server_trunking,
 };
 #endif /* CONFIG_NFS_V4_1 */
 
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 55148de..c351e6b 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -51,18 +51,21 @@
 #include <linux/bitops.h>
 #include <linux/jiffies.h>
 
+#include <linux/sunrpc/clnt.h>
+
 #include "nfs4_fs.h"
 #include "callback.h"
 #include "delegation.h"
 #include "internal.h"
 #include "pnfs.h"
+#include "netns.h"
 
 #define NFSDBG_FACILITY		NFSDBG_STATE
 
 #define OPENOWNER_POOL_SIZE	8
 
 const nfs4_stateid zero_stateid;
-
+static DEFINE_MUTEX(nfs_clid_init_mutex);
 static LIST_HEAD(nfs4_clientid_list);
 
 int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
@@ -73,12 +76,13 @@
 	};
 	unsigned short port;
 	int status;
+	struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id);
 
 	if (test_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state))
 		goto do_confirm;
-	port = nfs_callback_tcpport;
+	port = nn->nfs_callback_tcpport;
 	if (clp->cl_addr.ss_family == AF_INET6)
-		port = nfs_callback_tcpport6;
+		port = nn->nfs_callback_tcpport6;
 
 	status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, port, cred, &clid);
 	if (status != 0)
@@ -96,6 +100,56 @@
 	return status;
 }
 
+/**
+ * nfs40_discover_server_trunking - Detect server IP address trunking (mv0)
+ *
+ * @clp: nfs_client under test
+ * @result: OUT: found nfs_client, or clp
+ * @cred: credential to use for trunking test
+ *
+ * Returns zero, a negative errno, or a negative NFS4ERR status.
+ * If zero is returned, an nfs_client pointer is planted in
+ * "result".
+ *
+ * Note: The returned client may not yet be marked ready.
+ */
+int nfs40_discover_server_trunking(struct nfs_client *clp,
+				   struct nfs_client **result,
+				   struct rpc_cred *cred)
+{
+	struct nfs4_setclientid_res clid = {
+		.clientid = clp->cl_clientid,
+		.confirm = clp->cl_confirm,
+	};
+	struct nfs_net *nn = net_generic(clp->cl_net, nfs_net_id);
+	unsigned short port;
+	int status;
+
+	port = nn->nfs_callback_tcpport;
+	if (clp->cl_addr.ss_family == AF_INET6)
+		port = nn->nfs_callback_tcpport6;
+
+	status = nfs4_proc_setclientid(clp, NFS4_CALLBACK, port, cred, &clid);
+	if (status != 0)
+		goto out;
+	clp->cl_clientid = clid.clientid;
+	clp->cl_confirm = clid.confirm;
+
+	status = nfs40_walk_client_list(clp, result, cred);
+	switch (status) {
+	case -NFS4ERR_STALE_CLIENTID:
+		set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
+	case 0:
+		/* Sustain the lease, even if it's empty.  If the clientid4
+		 * goes stale it's of no use for trunking discovery. */
+		nfs4_schedule_state_renewal(*result);
+		break;
+	}
+
+out:
+	return status;
+}
+
 struct rpc_cred *nfs4_get_machine_cred_locked(struct nfs_client *clp)
 {
 	struct rpc_cred *cred = NULL;
@@ -275,6 +329,33 @@
 	return status;
 }
 
+/**
+ * nfs41_discover_server_trunking - Detect server IP address trunking (mv1)
+ *
+ * @clp: nfs_client under test
+ * @result: OUT: found nfs_client, or clp
+ * @cred: credential to use for trunking test
+ *
+ * Returns NFS4_OK, a negative errno, or a negative NFS4ERR status.
+ * If NFS4_OK is returned, an nfs_client pointer is planted in
+ * "result".
+ *
+ * Note: The returned client may not yet be marked ready.
+ */
+int nfs41_discover_server_trunking(struct nfs_client *clp,
+				   struct nfs_client **result,
+				   struct rpc_cred *cred)
+{
+	int status;
+
+	status = nfs4_proc_exchange_id(clp, cred);
+	if (status != NFS4_OK)
+		return status;
+	set_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
+
+	return nfs41_walk_client_list(clp, result, cred);
+}
+
 struct rpc_cred *nfs4_get_exchange_id_cred(struct nfs_client *clp)
 {
 	struct rpc_cred *cred;
@@ -729,11 +810,8 @@
 	if (!call_close) {
 		nfs4_put_open_state(state);
 		nfs4_put_state_owner(owner);
-	} else {
-		bool roc = pnfs_roc(state->inode);
-
-		nfs4_do_close(state, gfp_mask, wait, roc);
-	}
+	} else
+		nfs4_do_close(state, gfp_mask, wait);
 }
 
 void nfs4_close_state(struct nfs4_state *state, fmode_t fmode)
@@ -865,7 +943,7 @@
 	if (list_empty(&state->lock_states))
 		clear_bit(LK_STATE_IN_USE, &state->flags);
 	spin_unlock(&state->state_lock);
-	if (lsp->ls_flags & NFS_LOCK_INITIALIZED) {
+	if (test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags)) {
 		if (nfs4_release_lockowner(lsp) == 0)
 			return;
 	}
@@ -911,17 +989,25 @@
 }
 
 static bool nfs4_copy_lock_stateid(nfs4_stateid *dst, struct nfs4_state *state,
-		fl_owner_t fl_owner, pid_t fl_pid)
+		const struct nfs_lockowner *lockowner)
 {
 	struct nfs4_lock_state *lsp;
+	fl_owner_t fl_owner;
+	pid_t fl_pid;
 	bool ret = false;
 
+
+	if (lockowner == NULL)
+		goto out;
+
 	if (test_bit(LK_STATE_IN_USE, &state->flags) == 0)
 		goto out;
 
+	fl_owner = lockowner->l_owner;
+	fl_pid = lockowner->l_pid;
 	spin_lock(&state->state_lock);
 	lsp = __nfs4_find_lock_state(state, fl_owner, fl_pid, NFS4_ANY_LOCK_TYPE);
-	if (lsp != NULL && (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0) {
+	if (lsp != NULL && test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags) != 0) {
 		nfs4_stateid_copy(dst, &lsp->ls_stateid);
 		ret = true;
 	}
@@ -946,11 +1032,11 @@
  * requests.
  */
 void nfs4_select_rw_stateid(nfs4_stateid *dst, struct nfs4_state *state,
-		fmode_t fmode, fl_owner_t fl_owner, pid_t fl_pid)
+		fmode_t fmode, const struct nfs_lockowner *lockowner)
 {
 	if (nfs4_copy_delegation_stateid(dst, state->inode, fmode))
 		return;
-	if (nfs4_copy_lock_stateid(dst, state, fl_owner, fl_pid))
+	if (nfs4_copy_lock_stateid(dst, state, lockowner))
 		return;
 	nfs4_copy_open_stateid(dst, state);
 }
@@ -1289,7 +1375,7 @@
 			if (status >= 0) {
 				spin_lock(&state->state_lock);
 				list_for_each_entry(lock, &state->lock_states, ls_locks) {
-					if (!(lock->ls_flags & NFS_LOCK_INITIALIZED))
+					if (!test_bit(NFS_LOCK_INITIALIZED, &lock->ls_flags))
 						pr_warn_ratelimited("NFS: "
 							"%s: Lock reclaim "
 							"failed!\n", __func__);
@@ -1361,7 +1447,7 @@
 	spin_lock(&state->state_lock);
 	list_for_each_entry(lock, &state->lock_states, ls_locks) {
 		lock->ls_seqid.flags = 0;
-		lock->ls_flags &= ~NFS_LOCK_INITIALIZED;
+		clear_bit(NFS_LOCK_INITIALIZED, &lock->ls_flags);
 	}
 	spin_unlock(&state->state_lock);
 }
@@ -1595,8 +1681,8 @@
 	return nfs4_recovery_handle_error(clp, status);
 }
 
-/* Set NFS4CLNT_LEASE_EXPIRED for all v4.0 errors and for recoverable errors
- * on EXCHANGE_ID for v4.1
+/* Set NFS4CLNT_LEASE_EXPIRED and reclaim reboot state for all v4.0 errors
+ * and for recoverable errors on EXCHANGE_ID for v4.1
  */
 static int nfs4_handle_reclaim_lease_error(struct nfs_client *clp, int status)
 {
@@ -1606,8 +1692,12 @@
 			return -ESERVERFAULT;
 		/* Lease confirmation error: retry after purging the lease */
 		ssleep(1);
+		clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
+		break;
 	case -NFS4ERR_STALE_CLIENTID:
 		clear_bit(NFS4CLNT_LEASE_CONFIRM, &clp->cl_state);
+		nfs4_state_clear_reclaim_reboot(clp);
+		nfs4_state_start_reclaim_reboot(clp);
 		break;
 	case -NFS4ERR_CLID_INUSE:
 		pr_err("NFS: Server %s reports our clientid is in use\n",
@@ -1698,6 +1788,109 @@
 	return 0;
 }
 
+/**
+ * nfs4_discover_server_trunking - Detect server IP address trunking
+ *
+ * @clp: nfs_client under test
+ * @result: OUT: found nfs_client, or clp
+ *
+ * Returns zero or a negative errno.  If zero is returned,
+ * an nfs_client pointer is planted in "result".
+ *
+ * Note: since we are invoked in process context, and
+ * not from inside the state manager, we cannot use
+ * nfs4_handle_reclaim_lease_error().
+ */
+int nfs4_discover_server_trunking(struct nfs_client *clp,
+				  struct nfs_client **result)
+{
+	const struct nfs4_state_recovery_ops *ops =
+				clp->cl_mvops->reboot_recovery_ops;
+	rpc_authflavor_t *flavors, flav, save;
+	struct rpc_clnt *clnt;
+	struct rpc_cred *cred;
+	int i, len, status;
+
+	dprintk("NFS: %s: testing '%s'\n", __func__, clp->cl_hostname);
+
+	len = NFS_MAX_SECFLAVORS;
+	flavors = kcalloc(len, sizeof(*flavors), GFP_KERNEL);
+	if (flavors == NULL) {
+		status = -ENOMEM;
+		goto out;
+	}
+	len = rpcauth_list_flavors(flavors, len);
+	if (len < 0) {
+		status = len;
+		goto out_free;
+	}
+	clnt = clp->cl_rpcclient;
+	save = clnt->cl_auth->au_flavor;
+	i = 0;
+
+	mutex_lock(&nfs_clid_init_mutex);
+	status  = -ENOENT;
+again:
+	cred = ops->get_clid_cred(clp);
+	if (cred == NULL)
+		goto out_unlock;
+
+	status = ops->detect_trunking(clp, result, cred);
+	put_rpccred(cred);
+	switch (status) {
+	case 0:
+		break;
+
+	case -EACCES:
+		if (clp->cl_machine_cred == NULL)
+			break;
+		/* Handle case where the user hasn't set up machine creds */
+		nfs4_clear_machine_cred(clp);
+	case -NFS4ERR_DELAY:
+	case -ETIMEDOUT:
+	case -EAGAIN:
+		ssleep(1);
+		dprintk("NFS: %s after status %d, retrying\n",
+			__func__, status);
+		goto again;
+
+	case -NFS4ERR_CLID_INUSE:
+	case -NFS4ERR_WRONGSEC:
+		status = -EPERM;
+		if (i >= len)
+			break;
+
+		flav = flavors[i++];
+		if (flav == save)
+			flav = flavors[i++];
+		clnt = rpc_clone_client_set_auth(clnt, flav);
+		if (IS_ERR(clnt)) {
+			status = PTR_ERR(clnt);
+			break;
+		}
+		clp->cl_rpcclient = clnt;
+		goto again;
+
+	case -NFS4ERR_MINOR_VERS_MISMATCH:
+		status = -EPROTONOSUPPORT;
+		break;
+
+	case -EKEYEXPIRED:
+		nfs4_warn_keyexpired(clp->cl_hostname);
+	case -NFS4ERR_NOT_SAME: /* FixMe: implement recovery
+				 * in nfs4_exchange_id */
+		status = -EKEYEXPIRED;
+	}
+
+out_unlock:
+	mutex_unlock(&nfs_clid_init_mutex);
+out_free:
+	kfree(flavors);
+out:
+	dprintk("NFS: %s: status = %d\n", __func__, status);
+	return status;
+}
+
 #ifdef CONFIG_NFS_V4_1
 void nfs4_schedule_session_recovery(struct nfs4_session *session, int err)
 {
@@ -2008,6 +2201,7 @@
 	pr_warn_ratelimited("NFS: state manager%s%s failed on NFSv4 server %s"
 			" with error %d\n", section_sep, section,
 			clp->cl_hostname, -status);
+	ssleep(1);
 	nfs4_end_drain_session(clp);
 	nfs4_clear_state_manager_bit(clp);
 }
diff --git a/fs/nfs/nfs4sysctl.c b/fs/nfs/nfs4sysctl.c
index 5729bc8..2628d92 100644
--- a/fs/nfs/nfs4sysctl.c
+++ b/fs/nfs/nfs4sysctl.c
@@ -9,6 +9,7 @@
 #include <linux/nfs_idmap.h>
 #include <linux/nfs_fs.h>
 
+#include "nfs4_fs.h"
 #include "callback.h"
 
 static const int nfs_set_port_min = 0;
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 8dba6bd..40836ee 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -447,12 +447,14 @@
 				encode_sequence_maxsz + \
 				encode_putfh_maxsz + \
 				encode_open_maxsz + \
+				encode_access_maxsz + \
 				encode_getfh_maxsz + \
 				encode_getattr_maxsz)
 #define NFS4_dec_open_sz        (compound_decode_hdr_maxsz + \
 				decode_sequence_maxsz + \
 				decode_putfh_maxsz + \
 				decode_open_maxsz + \
+				decode_access_maxsz + \
 				decode_getfh_maxsz + \
 				decode_getattr_maxsz)
 #define NFS4_enc_open_confirm_sz \
@@ -467,11 +469,13 @@
 					encode_sequence_maxsz + \
 					encode_putfh_maxsz + \
 					encode_open_maxsz + \
+					encode_access_maxsz + \
 					encode_getattr_maxsz)
 #define NFS4_dec_open_noattr_sz	(compound_decode_hdr_maxsz + \
 					decode_sequence_maxsz + \
 					decode_putfh_maxsz + \
 					decode_open_maxsz + \
+					decode_access_maxsz + \
 					decode_getattr_maxsz)
 #define NFS4_enc_open_downgrade_sz \
 				(compound_encode_hdr_maxsz + \
@@ -1509,8 +1513,12 @@
 	nfs4_stateid stateid;
 
 	if (ctx->state != NULL) {
+		const struct nfs_lockowner *lockowner = NULL;
+
+		if (l_ctx != NULL)
+			lockowner = &l_ctx->lockowner;
 		nfs4_select_rw_stateid(&stateid, ctx->state,
-				fmode, l_ctx->lockowner, l_ctx->pid);
+				fmode, lockowner);
 		if (zero_seqid)
 			stateid.seqid = 0;
 		encode_nfs4_stateid(xdr, &stateid);
@@ -2216,6 +2224,8 @@
 	encode_putfh(xdr, args->fh, &hdr);
 	encode_open(xdr, args, &hdr);
 	encode_getfh(xdr, &hdr);
+	if (args->access)
+		encode_access(xdr, args->access, &hdr);
 	encode_getfattr_open(xdr, args->bitmask, args->open_bitmap, &hdr);
 	encode_nops(&hdr);
 }
@@ -2252,7 +2262,9 @@
 	encode_sequence(xdr, &args->seq_args, &hdr);
 	encode_putfh(xdr, args->fh, &hdr);
 	encode_open(xdr, args, &hdr);
-	encode_getfattr(xdr, args->bitmask, &hdr);
+	if (args->access)
+		encode_access(xdr, args->access, &hdr);
+	encode_getfattr_open(xdr, args->bitmask, args->open_bitmap, &hdr);
 	encode_nops(&hdr);
 }
 
@@ -4095,7 +4107,7 @@
 	return -EIO;
 }
 
-static int decode_access(struct xdr_stream *xdr, struct nfs4_accessres *access)
+static int decode_access(struct xdr_stream *xdr, u32 *supported, u32 *access)
 {
 	__be32 *p;
 	uint32_t supp, acc;
@@ -4109,8 +4121,8 @@
 		goto out_overflow;
 	supp = be32_to_cpup(p++);
 	acc = be32_to_cpup(p);
-	access->supported = supp;
-	access->access = acc;
+	*supported = supp;
+	*access = acc;
 	return 0;
 out_overflow:
 	print_overflow_msg(__func__, xdr);
@@ -5642,7 +5654,8 @@
 	 * and places the remaining xdr data in xdr_buf->tail
 	 */
 	pdev->mincount = be32_to_cpup(p);
-	xdr_read_pages(xdr, pdev->mincount); /* include space for the length */
+	if (xdr_read_pages(xdr, pdev->mincount) != pdev->mincount)
+		goto out_overflow;
 
 	/* Parse notification bitmap, verifying that it is zero. */
 	p = xdr_inline_decode(xdr, 4);
@@ -5887,7 +5900,7 @@
 	status = decode_putfh(xdr);
 	if (status != 0)
 		goto out;
-	status = decode_access(xdr, res);
+	status = decode_access(xdr, &res->supported, &res->access);
 	if (status != 0)
 		goto out;
 	decode_getfattr(xdr, res->fattr, res->server);
@@ -6228,6 +6241,8 @@
 	status = decode_getfh(xdr, &res->fh);
 	if (status)
 		goto out;
+	if (res->access_request)
+		decode_access(xdr, &res->access_supported, &res->access_result);
 	decode_getfattr(xdr, res->f_attr, res->server);
 out:
 	return status;
@@ -6276,6 +6291,8 @@
 	status = decode_open(xdr, res);
 	if (status)
 		goto out;
+	if (res->access_request)
+		decode_access(xdr, &res->access_supported, &res->access_result);
 	decode_getfattr(xdr, res->f_attr, res->server);
 out:
 	return status;
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c
index ea6d111..be731e6 100644
--- a/fs/nfs/objlayout/objio_osd.c
+++ b/fs/nfs/objlayout/objio_osd.c
@@ -41,6 +41,7 @@
 #include <scsi/osd_ore.h>
 
 #include "objlayout.h"
+#include "../internal.h"
 
 #define NFSDBG_FACILITY         NFSDBG_PNFS_LD
 
@@ -606,8 +607,14 @@
 void objio_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
 {
 	unsigned long stripe_end = 0;
+	u64 wb_size;
 
-	pnfs_generic_pg_init_write(pgio, req);
+	if (pgio->pg_dreq == NULL)
+		wb_size = i_size_read(pgio->pg_inode) - req_offset(req);
+	else
+		wb_size = nfs_dreq_bytes_left(pgio->pg_dreq);
+
+	pnfs_generic_pg_init_write(pgio, req, wb_size);
 	if (unlikely(pgio->pg_lseg == NULL))
 		return; /* Not pNFS */
 
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 311a796..e56e846 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -102,6 +102,7 @@
 		   unsigned int offset, unsigned int count)
 {
 	struct nfs_page		*req;
+	struct nfs_lock_context *l_ctx;
 
 	/* try to allocate the request struct */
 	req = nfs_page_alloc();
@@ -109,11 +110,12 @@
 		return ERR_PTR(-ENOMEM);
 
 	/* get lock context early so we can deal with alloc failures */
-	req->wb_lock_context = nfs_get_lock_context(ctx);
-	if (req->wb_lock_context == NULL) {
+	l_ctx = nfs_get_lock_context(ctx);
+	if (IS_ERR(l_ctx)) {
 		nfs_page_free(req);
-		return ERR_PTR(-ENOMEM);
+		return ERR_CAST(l_ctx);
 	}
+	req->wb_lock_context = l_ctx;
 
 	/* Initialize the request struct. Initially, we assume a
 	 * long write-back delay. This will be adjusted in
@@ -290,7 +292,9 @@
 {
 	if (req->wb_context->cred != prev->wb_context->cred)
 		return false;
-	if (req->wb_lock_context->lockowner != prev->wb_lock_context->lockowner)
+	if (req->wb_lock_context->lockowner.l_owner != prev->wb_lock_context->lockowner.l_owner)
+		return false;
+	if (req->wb_lock_context->lockowner.l_pid != prev->wb_lock_context->lockowner.l_pid)
 		return false;
 	if (req->wb_context->state != prev->wb_context->state)
 		return false;
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 2e00fea..fe624c9 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -35,6 +35,7 @@
 #include "iostat.h"
 
 #define NFSDBG_FACILITY		NFSDBG_PNFS
+#define PNFS_LAYOUTGET_RETRY_TIMEOUT (120*HZ)
 
 /* Locking:
  *
@@ -190,7 +191,7 @@
 
 /* Need to hold i_lock if caller does not already hold reference */
 void
-get_layout_hdr(struct pnfs_layout_hdr *lo)
+pnfs_get_layout_hdr(struct pnfs_layout_hdr *lo)
 {
 	atomic_inc(&lo->plh_refcount);
 }
@@ -199,45 +200,109 @@
 pnfs_alloc_layout_hdr(struct inode *ino, gfp_t gfp_flags)
 {
 	struct pnfs_layoutdriver_type *ld = NFS_SERVER(ino)->pnfs_curr_ld;
-	return ld->alloc_layout_hdr ? ld->alloc_layout_hdr(ino, gfp_flags) :
-		kzalloc(sizeof(struct pnfs_layout_hdr), gfp_flags);
+	return ld->alloc_layout_hdr(ino, gfp_flags);
 }
 
 static void
 pnfs_free_layout_hdr(struct pnfs_layout_hdr *lo)
 {
-	struct pnfs_layoutdriver_type *ld = NFS_SERVER(lo->plh_inode)->pnfs_curr_ld;
+	struct nfs_server *server = NFS_SERVER(lo->plh_inode);
+	struct pnfs_layoutdriver_type *ld = server->pnfs_curr_ld;
+
+	if (!list_empty(&lo->plh_layouts)) {
+		struct nfs_client *clp = server->nfs_client;
+
+		spin_lock(&clp->cl_lock);
+		list_del_init(&lo->plh_layouts);
+		spin_unlock(&clp->cl_lock);
+	}
 	put_rpccred(lo->plh_lc_cred);
-	return ld->alloc_layout_hdr ? ld->free_layout_hdr(lo) : kfree(lo);
+	return ld->free_layout_hdr(lo);
 }
 
 static void
-destroy_layout_hdr(struct pnfs_layout_hdr *lo)
+pnfs_detach_layout_hdr(struct pnfs_layout_hdr *lo)
 {
+	struct nfs_inode *nfsi = NFS_I(lo->plh_inode);
 	dprintk("%s: freeing layout cache %p\n", __func__, lo);
-	BUG_ON(!list_empty(&lo->plh_layouts));
-	NFS_I(lo->plh_inode)->layout = NULL;
-	pnfs_free_layout_hdr(lo);
-}
-
-static void
-put_layout_hdr_locked(struct pnfs_layout_hdr *lo)
-{
-	if (atomic_dec_and_test(&lo->plh_refcount))
-		destroy_layout_hdr(lo);
+	nfsi->layout = NULL;
+	/* Reset MDS Threshold I/O counters */
+	nfsi->write_io = 0;
+	nfsi->read_io = 0;
 }
 
 void
-put_layout_hdr(struct pnfs_layout_hdr *lo)
+pnfs_put_layout_hdr(struct pnfs_layout_hdr *lo)
 {
 	struct inode *inode = lo->plh_inode;
 
 	if (atomic_dec_and_lock(&lo->plh_refcount, &inode->i_lock)) {
-		destroy_layout_hdr(lo);
+		pnfs_detach_layout_hdr(lo);
 		spin_unlock(&inode->i_lock);
+		pnfs_free_layout_hdr(lo);
 	}
 }
 
+static int
+pnfs_iomode_to_fail_bit(u32 iomode)
+{
+	return iomode == IOMODE_RW ?
+		NFS_LAYOUT_RW_FAILED : NFS_LAYOUT_RO_FAILED;
+}
+
+static void
+pnfs_layout_set_fail_bit(struct pnfs_layout_hdr *lo, int fail_bit)
+{
+	lo->plh_retry_timestamp = jiffies;
+	if (test_and_set_bit(fail_bit, &lo->plh_flags))
+		atomic_inc(&lo->plh_refcount);
+}
+
+static void
+pnfs_layout_clear_fail_bit(struct pnfs_layout_hdr *lo, int fail_bit)
+{
+	if (test_and_clear_bit(fail_bit, &lo->plh_flags))
+		atomic_dec(&lo->plh_refcount);
+}
+
+static void
+pnfs_layout_io_set_failed(struct pnfs_layout_hdr *lo, u32 iomode)
+{
+	struct inode *inode = lo->plh_inode;
+	struct pnfs_layout_range range = {
+		.iomode = iomode,
+		.offset = 0,
+		.length = NFS4_MAX_UINT64,
+	};
+	LIST_HEAD(head);
+
+	spin_lock(&inode->i_lock);
+	pnfs_layout_set_fail_bit(lo, pnfs_iomode_to_fail_bit(iomode));
+	pnfs_mark_matching_lsegs_invalid(lo, &head, &range);
+	spin_unlock(&inode->i_lock);
+	pnfs_free_lseg_list(&head);
+	dprintk("%s Setting layout IOMODE_%s fail bit\n", __func__,
+			iomode == IOMODE_RW ?  "RW" : "READ");
+}
+
+static bool
+pnfs_layout_io_test_failed(struct pnfs_layout_hdr *lo, u32 iomode)
+{
+	unsigned long start, end;
+	int fail_bit = pnfs_iomode_to_fail_bit(iomode);
+
+	if (test_bit(fail_bit, &lo->plh_flags) == 0)
+		return false;
+	end = jiffies;
+	start = end - PNFS_LAYOUTGET_RETRY_TIMEOUT;
+	if (!time_in_range(lo->plh_retry_timestamp, start, end)) {
+		/* It is time to retry the failed layoutgets */
+		pnfs_layout_clear_fail_bit(lo, fail_bit);
+		return false;
+	}
+	return true;
+}
+
 static void
 init_lseg(struct pnfs_layout_hdr *lo, struct pnfs_layout_segment *lseg)
 {
@@ -249,33 +314,32 @@
 	lseg->pls_layout = lo;
 }
 
-static void free_lseg(struct pnfs_layout_segment *lseg)
+static void pnfs_free_lseg(struct pnfs_layout_segment *lseg)
 {
 	struct inode *ino = lseg->pls_layout->plh_inode;
 
 	NFS_SERVER(ino)->pnfs_curr_ld->free_lseg(lseg);
-	/* Matched by get_layout_hdr in pnfs_insert_layout */
-	put_layout_hdr(NFS_I(ino)->layout);
 }
 
 static void
-put_lseg_common(struct pnfs_layout_segment *lseg)
+pnfs_layout_remove_lseg(struct pnfs_layout_hdr *lo,
+		struct pnfs_layout_segment *lseg)
 {
-	struct inode *inode = lseg->pls_layout->plh_inode;
+	struct inode *inode = lo->plh_inode;
 
 	WARN_ON(test_bit(NFS_LSEG_VALID, &lseg->pls_flags));
 	list_del_init(&lseg->pls_list);
-	if (list_empty(&lseg->pls_layout->plh_segs)) {
-		set_bit(NFS_LAYOUT_DESTROYED, &lseg->pls_layout->plh_flags);
-		/* Matched by initial refcount set in alloc_init_layout_hdr */
-		put_layout_hdr_locked(lseg->pls_layout);
-	}
+	/* Matched by pnfs_get_layout_hdr in pnfs_layout_insert_lseg */
+	atomic_dec(&lo->plh_refcount);
+	if (list_empty(&lo->plh_segs))
+		clear_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags);
 	rpc_wake_up(&NFS_SERVER(inode)->roc_rpcwaitq);
 }
 
 void
-put_lseg(struct pnfs_layout_segment *lseg)
+pnfs_put_lseg(struct pnfs_layout_segment *lseg)
 {
+	struct pnfs_layout_hdr *lo;
 	struct inode *inode;
 
 	if (!lseg)
@@ -284,17 +348,17 @@
 	dprintk("%s: lseg %p ref %d valid %d\n", __func__, lseg,
 		atomic_read(&lseg->pls_refcount),
 		test_bit(NFS_LSEG_VALID, &lseg->pls_flags));
-	inode = lseg->pls_layout->plh_inode;
+	lo = lseg->pls_layout;
+	inode = lo->plh_inode;
 	if (atomic_dec_and_lock(&lseg->pls_refcount, &inode->i_lock)) {
-		LIST_HEAD(free_me);
-
-		put_lseg_common(lseg);
-		list_add(&lseg->pls_list, &free_me);
+		pnfs_get_layout_hdr(lo);
+		pnfs_layout_remove_lseg(lo, lseg);
 		spin_unlock(&inode->i_lock);
-		pnfs_free_lseg_list(&free_me);
+		pnfs_free_lseg(lseg);
+		pnfs_put_layout_hdr(lo);
 	}
 }
-EXPORT_SYMBOL_GPL(put_lseg);
+EXPORT_SYMBOL_GPL(pnfs_put_lseg);
 
 static inline u64
 end_offset(u64 start, u64 len)
@@ -378,7 +442,7 @@
 		dprintk("%s: lseg %p ref %d\n", __func__, lseg,
 			atomic_read(&lseg->pls_refcount));
 		if (atomic_dec_and_test(&lseg->pls_refcount)) {
-			put_lseg_common(lseg);
+			pnfs_layout_remove_lseg(lseg->pls_layout, lseg);
 			list_add(&lseg->pls_list, tmp_list);
 			rv = 1;
 		}
@@ -390,7 +454,7 @@
  * after call.
  */
 int
-mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo,
+pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo,
 			    struct list_head *tmp_list,
 			    struct pnfs_layout_range *recall_range)
 {
@@ -399,14 +463,8 @@
 
 	dprintk("%s:Begin lo %p\n", __func__, lo);
 
-	if (list_empty(&lo->plh_segs)) {
-		/* Reset MDS Threshold I/O counters */
-		NFS_I(lo->plh_inode)->write_io = 0;
-		NFS_I(lo->plh_inode)->read_io = 0;
-		if (!test_and_set_bit(NFS_LAYOUT_DESTROYED, &lo->plh_flags))
-			put_layout_hdr_locked(lo);
+	if (list_empty(&lo->plh_segs))
 		return 0;
-	}
 	list_for_each_entry_safe(lseg, next, &lo->plh_segs, pls_list)
 		if (!recall_range ||
 		    should_free_lseg(&lseg->pls_range, recall_range)) {
@@ -426,25 +484,13 @@
 pnfs_free_lseg_list(struct list_head *free_me)
 {
 	struct pnfs_layout_segment *lseg, *tmp;
-	struct pnfs_layout_hdr *lo;
 
 	if (list_empty(free_me))
 		return;
 
-	lo = list_first_entry(free_me, struct pnfs_layout_segment,
-			      pls_list)->pls_layout;
-
-	if (test_bit(NFS_LAYOUT_DESTROYED, &lo->plh_flags)) {
-		struct nfs_client *clp;
-
-		clp = NFS_SERVER(lo->plh_inode)->nfs_client;
-		spin_lock(&clp->cl_lock);
-		list_del_init(&lo->plh_layouts);
-		spin_unlock(&clp->cl_lock);
-	}
 	list_for_each_entry_safe(lseg, tmp, free_me, pls_list) {
 		list_del(&lseg->pls_list);
-		free_lseg(lseg);
+		pnfs_free_lseg(lseg);
 	}
 }
 
@@ -458,10 +504,15 @@
 	lo = nfsi->layout;
 	if (lo) {
 		lo->plh_block_lgets++; /* permanently block new LAYOUTGETs */
-		mark_matching_lsegs_invalid(lo, &tmp_list, NULL);
-	}
-	spin_unlock(&nfsi->vfs_inode.i_lock);
-	pnfs_free_lseg_list(&tmp_list);
+		pnfs_mark_matching_lsegs_invalid(lo, &tmp_list, NULL);
+		pnfs_get_layout_hdr(lo);
+		pnfs_layout_clear_fail_bit(lo, NFS_LAYOUT_RO_FAILED);
+		pnfs_layout_clear_fail_bit(lo, NFS_LAYOUT_RW_FAILED);
+		spin_unlock(&nfsi->vfs_inode.i_lock);
+		pnfs_free_lseg_list(&tmp_list);
+		pnfs_put_layout_hdr(lo);
+	} else
+		spin_unlock(&nfsi->vfs_inode.i_lock);
 }
 EXPORT_SYMBOL_GPL(pnfs_destroy_layout);
 
@@ -498,46 +549,54 @@
 	}
 }
 
+/*
+ * Compare 2 layout stateid sequence ids, to see which is newer,
+ * taking into account wraparound issues.
+ */
+static bool pnfs_seqid_is_newer(u32 s1, u32 s2)
+{
+	return (s32)s1 - (s32)s2 > 0;
+}
+
 /* update lo->plh_stateid with new if is more recent */
 void
 pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, const nfs4_stateid *new,
 			bool update_barrier)
 {
-	u32 oldseq, newseq;
+	u32 oldseq, newseq, new_barrier;
+	int empty = list_empty(&lo->plh_segs);
 
 	oldseq = be32_to_cpu(lo->plh_stateid.seqid);
 	newseq = be32_to_cpu(new->seqid);
-	if ((int)(newseq - oldseq) > 0) {
+	if (empty || pnfs_seqid_is_newer(newseq, oldseq)) {
 		nfs4_stateid_copy(&lo->plh_stateid, new);
 		if (update_barrier) {
-			u32 new_barrier = be32_to_cpu(new->seqid);
-
-			if ((int)(new_barrier - lo->plh_barrier))
-				lo->plh_barrier = new_barrier;
+			new_barrier = be32_to_cpu(new->seqid);
 		} else {
 			/* Because of wraparound, we want to keep the barrier
-			 * "close" to the current seqids.  It needs to be
-			 * within 2**31 to count as "behind", so if it
-			 * gets too near that limit, give us a litle leeway
-			 * and bring it to within 2**30.
-			 * NOTE - and yes, this is all unsigned arithmetic.
+			 * "close" to the current seqids.
 			 */
-			if (unlikely((newseq - lo->plh_barrier) > (3 << 29)))
-				lo->plh_barrier = newseq - (1 << 30);
+			new_barrier = newseq - atomic_read(&lo->plh_outstanding);
 		}
+		if (empty || pnfs_seqid_is_newer(new_barrier, lo->plh_barrier))
+			lo->plh_barrier = new_barrier;
 	}
 }
 
+static bool
+pnfs_layout_stateid_blocked(const struct pnfs_layout_hdr *lo,
+		const nfs4_stateid *stateid)
+{
+	u32 seqid = be32_to_cpu(stateid->seqid);
+
+	return !pnfs_seqid_is_newer(seqid, lo->plh_barrier);
+}
+
 /* lget is set to 1 if called from inside send_layoutget call chain */
 static bool
-pnfs_layoutgets_blocked(struct pnfs_layout_hdr *lo, nfs4_stateid *stateid,
-			int lget)
+pnfs_layoutgets_blocked(const struct pnfs_layout_hdr *lo, int lget)
 {
-	if ((stateid) &&
-	    (int)(lo->plh_barrier - be32_to_cpu(stateid->seqid)) >= 0)
-		return true;
 	return lo->plh_block_lgets ||
-		test_bit(NFS_LAYOUT_DESTROYED, &lo->plh_flags) ||
 		test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags) ||
 		(list_empty(&lo->plh_segs) &&
 		 (atomic_read(&lo->plh_outstanding) > lget));
@@ -551,7 +610,7 @@
 
 	dprintk("--> %s\n", __func__);
 	spin_lock(&lo->plh_inode->i_lock);
-	if (pnfs_layoutgets_blocked(lo, NULL, 1)) {
+	if (pnfs_layoutgets_blocked(lo, 1)) {
 		status = -EAGAIN;
 	} else if (list_empty(&lo->plh_segs)) {
 		int seq;
@@ -582,7 +641,7 @@
 	struct inode *ino = lo->plh_inode;
 	struct nfs_server *server = NFS_SERVER(ino);
 	struct nfs4_layoutget *lgp;
-	struct pnfs_layout_segment *lseg = NULL;
+	struct pnfs_layout_segment *lseg;
 
 	dprintk("--> %s\n", __func__);
 
@@ -599,16 +658,22 @@
 	lgp->args.type = server->pnfs_curr_ld->id;
 	lgp->args.inode = ino;
 	lgp->args.ctx = get_nfs_open_context(ctx);
-	lgp->lsegpp = &lseg;
 	lgp->gfp_flags = gfp_flags;
 
 	/* Synchronously retrieve layout information from server and
 	 * store in lseg.
 	 */
-	nfs4_proc_layoutget(lgp, gfp_flags);
-	if (!lseg) {
-		/* remember that LAYOUTGET failed and suspend trying */
-		set_bit(lo_fail_bit(range->iomode), &lo->plh_flags);
+	lseg = nfs4_proc_layoutget(lgp, gfp_flags);
+	if (IS_ERR(lseg)) {
+		switch (PTR_ERR(lseg)) {
+		case -ENOMEM:
+		case -ERESTARTSYS:
+			break;
+		default:
+			/* remember that LAYOUTGET failed and suspend trying */
+			pnfs_layout_io_set_failed(lo, range->iomode);
+		}
+		return NULL;
 	}
 
 	return lseg;
@@ -636,25 +701,24 @@
 
 	spin_lock(&ino->i_lock);
 	lo = nfsi->layout;
-	if (!lo || pnfs_test_layout_returned(lo)) {
+	if (!lo) {
 		spin_unlock(&ino->i_lock);
 		dprintk("NFS: %s no layout to return\n", __func__);
 		goto out;
 	}
 	stateid = nfsi->layout->plh_stateid;
 	/* Reference matched in nfs4_layoutreturn_release */
-	get_layout_hdr(lo);
+	pnfs_get_layout_hdr(lo);
 	empty = list_empty(&lo->plh_segs);
-	mark_matching_lsegs_invalid(lo, &tmp_list, NULL);
+	pnfs_mark_matching_lsegs_invalid(lo, &tmp_list, NULL);
 	/* Don't send a LAYOUTRETURN if list was initially empty */
 	if (empty) {
 		spin_unlock(&ino->i_lock);
-		put_layout_hdr(lo);
+		pnfs_put_layout_hdr(lo);
 		dprintk("NFS: %s no layout segments to return\n", __func__);
 		goto out;
 	}
 	lo->plh_block_lgets++;
-	pnfs_mark_layout_returned(lo);
 	spin_unlock(&ino->i_lock);
 	pnfs_free_lseg_list(&tmp_list);
 
@@ -663,10 +727,10 @@
 	lrp = kzalloc(sizeof(*lrp), GFP_KERNEL);
 	if (unlikely(lrp == NULL)) {
 		status = -ENOMEM;
-		set_bit(NFS_LAYOUT_RW_FAILED, &lo->plh_flags);
-		set_bit(NFS_LAYOUT_RO_FAILED, &lo->plh_flags);
-		pnfs_clear_layout_returned(lo);
-		put_layout_hdr(lo);
+		spin_lock(&ino->i_lock);
+		lo->plh_block_lgets--;
+		spin_unlock(&ino->i_lock);
+		pnfs_put_layout_hdr(lo);
 		goto out;
 	}
 
@@ -703,7 +767,7 @@
 	if (!found)
 		goto out_nolayout;
 	lo->plh_block_lgets++;
-	get_layout_hdr(lo); /* matched in pnfs_roc_release */
+	pnfs_get_layout_hdr(lo); /* matched in pnfs_roc_release */
 	spin_unlock(&ino->i_lock);
 	pnfs_free_lseg_list(&tmp_list);
 	return true;
@@ -720,8 +784,12 @@
 	spin_lock(&ino->i_lock);
 	lo = NFS_I(ino)->layout;
 	lo->plh_block_lgets--;
-	put_layout_hdr_locked(lo);
-	spin_unlock(&ino->i_lock);
+	if (atomic_dec_and_test(&lo->plh_refcount)) {
+		pnfs_detach_layout_hdr(lo);
+		spin_unlock(&ino->i_lock);
+		pnfs_free_layout_hdr(lo);
+	} else
+		spin_unlock(&ino->i_lock);
 }
 
 void pnfs_roc_set_barrier(struct inode *ino, u32 barrier)
@@ -730,32 +798,34 @@
 
 	spin_lock(&ino->i_lock);
 	lo = NFS_I(ino)->layout;
-	if ((int)(barrier - lo->plh_barrier) > 0)
+	if (pnfs_seqid_is_newer(barrier, lo->plh_barrier))
 		lo->plh_barrier = barrier;
 	spin_unlock(&ino->i_lock);
 }
 
-bool pnfs_roc_drain(struct inode *ino, u32 *barrier)
+bool pnfs_roc_drain(struct inode *ino, u32 *barrier, struct rpc_task *task)
 {
 	struct nfs_inode *nfsi = NFS_I(ino);
+	struct pnfs_layout_hdr *lo;
 	struct pnfs_layout_segment *lseg;
+	u32 current_seqid;
 	bool found = false;
 
 	spin_lock(&ino->i_lock);
 	list_for_each_entry(lseg, &nfsi->layout->plh_segs, pls_list)
 		if (test_bit(NFS_LSEG_ROC, &lseg->pls_flags)) {
+			rpc_sleep_on(&NFS_SERVER(ino)->roc_rpcwaitq, task, NULL);
 			found = true;
-			break;
+			goto out;
 		}
-	if (!found) {
-		struct pnfs_layout_hdr *lo = nfsi->layout;
-		u32 current_seqid = be32_to_cpu(lo->plh_stateid.seqid);
+	lo = nfsi->layout;
+	current_seqid = be32_to_cpu(lo->plh_stateid.seqid);
 
-		/* Since close does not return a layout stateid for use as
-		 * a barrier, we choose the worst-case barrier.
-		 */
-		*barrier = current_seqid + atomic_read(&lo->plh_outstanding);
-	}
+	/* Since close does not return a layout stateid for use as
+	 * a barrier, we choose the worst-case barrier.
+	 */
+	*barrier = current_seqid + atomic_read(&lo->plh_outstanding);
+out:
 	spin_unlock(&ino->i_lock);
 	return found;
 }
@@ -786,14 +856,13 @@
 }
 
 static void
-pnfs_insert_layout(struct pnfs_layout_hdr *lo,
+pnfs_layout_insert_lseg(struct pnfs_layout_hdr *lo,
 		   struct pnfs_layout_segment *lseg)
 {
 	struct pnfs_layout_segment *lp;
 
 	dprintk("%s:Begin\n", __func__);
 
-	assert_spin_locked(&lo->plh_inode->i_lock);
 	list_for_each_entry(lp, &lo->plh_segs, pls_list) {
 		if (cmp_layout(&lseg->pls_range, &lp->pls_range) > 0)
 			continue;
@@ -813,7 +882,7 @@
 		__func__, lseg, lseg->pls_range.iomode,
 		lseg->pls_range.offset, lseg->pls_range.length);
 out:
-	get_layout_hdr(lo);
+	pnfs_get_layout_hdr(lo);
 
 	dprintk("%s:Return\n", __func__);
 }
@@ -847,21 +916,19 @@
 
 	dprintk("%s Begin ino=%p layout=%p\n", __func__, ino, nfsi->layout);
 
-	assert_spin_locked(&ino->i_lock);
-	if (nfsi->layout) {
-		if (test_bit(NFS_LAYOUT_DESTROYED, &nfsi->layout->plh_flags))
-			return NULL;
-		else
-			return nfsi->layout;
-	}
+	if (nfsi->layout != NULL)
+		goto out_existing;
 	spin_unlock(&ino->i_lock);
 	new = alloc_init_layout_hdr(ino, ctx, gfp_flags);
 	spin_lock(&ino->i_lock);
 
-	if (likely(nfsi->layout == NULL))	/* Won the race? */
+	if (likely(nfsi->layout == NULL)) {	/* Won the race? */
 		nfsi->layout = new;
-	else
-		pnfs_free_layout_hdr(new);
+		return new;
+	}
+	pnfs_free_layout_hdr(new);
+out_existing:
+	pnfs_get_layout_hdr(nfsi->layout);
 	return nfsi->layout;
 }
 
@@ -904,11 +971,10 @@
 
 	dprintk("%s:Begin\n", __func__);
 
-	assert_spin_locked(&lo->plh_inode->i_lock);
 	list_for_each_entry(lseg, &lo->plh_segs, pls_list) {
 		if (test_bit(NFS_LSEG_VALID, &lseg->pls_flags) &&
 		    is_matching_lseg(&lseg->pls_range, range)) {
-			ret = get_lseg(lseg);
+			ret = pnfs_get_lseg(lseg);
 			break;
 		}
 		if (lseg->pls_range.offset > range->offset)
@@ -1013,7 +1079,6 @@
 		.length = count,
 	};
 	unsigned pg_offset;
-	struct nfs_inode *nfsi = NFS_I(ino);
 	struct nfs_server *server = NFS_SERVER(ino);
 	struct nfs_client *clp = server->nfs_client;
 	struct pnfs_layout_hdr *lo;
@@ -1021,16 +1086,16 @@
 	bool first = false;
 
 	if (!pnfs_enabled_sb(NFS_SERVER(ino)))
-		return NULL;
+		goto out;
 
 	if (pnfs_within_mdsthreshold(ctx, ino, iomode))
-		return NULL;
+		goto out;
 
 	spin_lock(&ino->i_lock);
 	lo = pnfs_find_alloc_layout(ino, ctx, gfp_flags);
 	if (lo == NULL) {
-		dprintk("%s ERROR: can't get pnfs_layout_hdr\n", __func__);
-		goto out_unlock;
+		spin_unlock(&ino->i_lock);
+		goto out;
 	}
 
 	/* Do we even need to bother with this? */
@@ -1040,7 +1105,7 @@
 	}
 
 	/* if LAYOUTGET already failed once we don't try again */
-	if (test_bit(lo_fail_bit(iomode), &nfsi->layout->plh_flags))
+	if (pnfs_layout_io_test_failed(lo, iomode))
 		goto out_unlock;
 
 	/* Check to see if the layout for the given range already exists */
@@ -1048,17 +1113,13 @@
 	if (lseg)
 		goto out_unlock;
 
-	if (pnfs_layoutgets_blocked(lo, NULL, 0))
+	if (pnfs_layoutgets_blocked(lo, 0))
 		goto out_unlock;
 	atomic_inc(&lo->plh_outstanding);
 
-	get_layout_hdr(lo);
 	if (list_empty(&lo->plh_segs))
 		first = true;
 
-	/* Enable LAYOUTRETURNs */
-	pnfs_clear_layout_returned(lo);
-
 	spin_unlock(&ino->i_lock);
 	if (first) {
 		/* The lo must be on the clp list if there is any
@@ -1079,24 +1140,26 @@
 		arg.length = PAGE_CACHE_ALIGN(arg.length);
 
 	lseg = send_layoutget(lo, ctx, &arg, gfp_flags);
-	if (!lseg && first) {
-		spin_lock(&clp->cl_lock);
-		list_del_init(&lo->plh_layouts);
-		spin_unlock(&clp->cl_lock);
-	}
 	atomic_dec(&lo->plh_outstanding);
-	put_layout_hdr(lo);
+out_put_layout_hdr:
+	pnfs_put_layout_hdr(lo);
 out:
-	dprintk("%s end, state 0x%lx lseg %p\n", __func__,
-		nfsi->layout ? nfsi->layout->plh_flags : -1, lseg);
+	dprintk("%s: inode %s/%llu pNFS layout segment %s for "
+			"(%s, offset: %llu, length: %llu)\n",
+			__func__, ino->i_sb->s_id,
+			(unsigned long long)NFS_FILEID(ino),
+			lseg == NULL ? "not found" : "found",
+			iomode==IOMODE_RW ?  "read/write" : "read-only",
+			(unsigned long long)pos,
+			(unsigned long long)count);
 	return lseg;
 out_unlock:
 	spin_unlock(&ino->i_lock);
-	goto out;
+	goto out_put_layout_hdr;
 }
 EXPORT_SYMBOL_GPL(pnfs_update_layout);
 
-int
+struct pnfs_layout_segment *
 pnfs_layout_process(struct nfs4_layoutget *lgp)
 {
 	struct pnfs_layout_hdr *lo = NFS_I(lgp->args.inode)->layout;
@@ -1123,25 +1186,29 @@
 		goto out_forget_reply;
 	}
 
-	if (pnfs_layoutgets_blocked(lo, &res->stateid, 1)) {
+	if (pnfs_layoutgets_blocked(lo, 1) ||
+	    pnfs_layout_stateid_blocked(lo, &res->stateid)) {
 		dprintk("%s forget reply due to state\n", __func__);
 		goto out_forget_reply;
 	}
+
+	/* Done processing layoutget. Set the layout stateid */
+	pnfs_set_layout_stateid(lo, &res->stateid, false);
+
 	init_lseg(lo, lseg);
 	lseg->pls_range = res->range;
-	*lgp->lsegpp = get_lseg(lseg);
-	pnfs_insert_layout(lo, lseg);
+	pnfs_get_lseg(lseg);
+	pnfs_layout_insert_lseg(lo, lseg);
 
 	if (res->return_on_close) {
 		set_bit(NFS_LSEG_ROC, &lseg->pls_flags);
 		set_bit(NFS_LAYOUT_ROC, &lo->plh_flags);
 	}
 
-	/* Done processing layoutget. Set the layout stateid */
-	pnfs_set_layout_stateid(lo, &res->stateid, false);
 	spin_unlock(&ino->i_lock);
+	return lseg;
 out:
-	return status;
+	return ERR_PTR(status);
 
 out_forget_reply:
 	spin_unlock(&ino->i_lock);
@@ -1153,16 +1220,24 @@
 void
 pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
 {
+	u64 rd_size = req->wb_bytes;
+
 	BUG_ON(pgio->pg_lseg != NULL);
 
 	if (req->wb_offset != req->wb_pgbase) {
 		nfs_pageio_reset_read_mds(pgio);
 		return;
 	}
+
+	if (pgio->pg_dreq == NULL)
+		rd_size = i_size_read(pgio->pg_inode) - req_offset(req);
+	else
+		rd_size = nfs_dreq_bytes_left(pgio->pg_dreq);
+
 	pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
 					   req->wb_context,
 					   req_offset(req),
-					   req->wb_bytes,
+					   rd_size,
 					   IOMODE_READ,
 					   GFP_KERNEL);
 	/* If no lseg, fall back to read through mds */
@@ -1173,7 +1248,8 @@
 EXPORT_SYMBOL_GPL(pnfs_generic_pg_init_read);
 
 void
-pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
+pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio,
+			   struct nfs_page *req, u64 wb_size)
 {
 	BUG_ON(pgio->pg_lseg != NULL);
 
@@ -1181,10 +1257,11 @@
 		nfs_pageio_reset_write_mds(pgio);
 		return;
 	}
+
 	pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
 					   req->wb_context,
 					   req_offset(req),
-					   req->wb_bytes,
+					   wb_size,
 					   IOMODE_RW,
 					   GFP_NOFS);
 	/* If no lseg, fall back to write through mds */
@@ -1362,12 +1439,12 @@
 		if (trypnfs == PNFS_NOT_ATTEMPTED)
 			pnfs_write_through_mds(desc, data);
 	}
-	put_lseg(lseg);
+	pnfs_put_lseg(lseg);
 }
 
 static void pnfs_writehdr_free(struct nfs_pgio_header *hdr)
 {
-	put_lseg(hdr->lseg);
+	pnfs_put_lseg(hdr->lseg);
 	nfs_writehdr_free(hdr);
 }
 EXPORT_SYMBOL_GPL(pnfs_writehdr_free);
@@ -1382,17 +1459,17 @@
 	whdr = nfs_writehdr_alloc();
 	if (!whdr) {
 		desc->pg_completion_ops->error_cleanup(&desc->pg_list);
-		put_lseg(desc->pg_lseg);
+		pnfs_put_lseg(desc->pg_lseg);
 		desc->pg_lseg = NULL;
 		return -ENOMEM;
 	}
 	hdr = &whdr->header;
 	nfs_pgheader_init(desc, hdr, pnfs_writehdr_free);
-	hdr->lseg = get_lseg(desc->pg_lseg);
+	hdr->lseg = pnfs_get_lseg(desc->pg_lseg);
 	atomic_inc(&hdr->refcnt);
 	ret = nfs_generic_flush(desc, hdr);
 	if (ret != 0) {
-		put_lseg(desc->pg_lseg);
+		pnfs_put_lseg(desc->pg_lseg);
 		desc->pg_lseg = NULL;
 	} else
 		pnfs_do_multiple_writes(desc, &hdr->rpc_list, desc->pg_ioflags);
@@ -1517,12 +1594,12 @@
 		if (trypnfs == PNFS_NOT_ATTEMPTED)
 			pnfs_read_through_mds(desc, data);
 	}
-	put_lseg(lseg);
+	pnfs_put_lseg(lseg);
 }
 
 static void pnfs_readhdr_free(struct nfs_pgio_header *hdr)
 {
-	put_lseg(hdr->lseg);
+	pnfs_put_lseg(hdr->lseg);
 	nfs_readhdr_free(hdr);
 }
 EXPORT_SYMBOL_GPL(pnfs_readhdr_free);
@@ -1538,17 +1615,17 @@
 	if (!rhdr) {
 		desc->pg_completion_ops->error_cleanup(&desc->pg_list);
 		ret = -ENOMEM;
-		put_lseg(desc->pg_lseg);
+		pnfs_put_lseg(desc->pg_lseg);
 		desc->pg_lseg = NULL;
 		return ret;
 	}
 	hdr = &rhdr->header;
 	nfs_pgheader_init(desc, hdr, pnfs_readhdr_free);
-	hdr->lseg = get_lseg(desc->pg_lseg);
+	hdr->lseg = pnfs_get_lseg(desc->pg_lseg);
 	atomic_inc(&hdr->refcnt);
 	ret = nfs_generic_pagein(desc, hdr);
 	if (ret != 0) {
-		put_lseg(desc->pg_lseg);
+		pnfs_put_lseg(desc->pg_lseg);
 		desc->pg_lseg = NULL;
 	} else
 		pnfs_do_multiple_reads(desc, &hdr->rpc_list);
@@ -1574,13 +1651,7 @@
 
 void pnfs_set_lo_fail(struct pnfs_layout_segment *lseg)
 {
-	if (lseg->pls_range.iomode == IOMODE_RW) {
-		dprintk("%s Setting layout IOMODE_RW fail bit\n", __func__);
-		set_bit(lo_fail_bit(IOMODE_RW), &lseg->pls_layout->plh_flags);
-	} else {
-		dprintk("%s Setting layout IOMODE_READ fail bit\n", __func__);
-		set_bit(lo_fail_bit(IOMODE_READ), &lseg->pls_layout->plh_flags);
-	}
+	pnfs_layout_io_set_failed(lseg->pls_layout, lseg->pls_range.iomode);
 }
 EXPORT_SYMBOL_GPL(pnfs_set_lo_fail);
 
@@ -1601,7 +1672,7 @@
 	}
 	if (!test_and_set_bit(NFS_LSEG_LAYOUTCOMMIT, &hdr->lseg->pls_flags)) {
 		/* references matched in nfs4_layoutcommit_release */
-		get_lseg(hdr->lseg);
+		pnfs_get_lseg(hdr->lseg);
 	}
 	if (end_pos > nfsi->layout->plh_lwb)
 		nfsi->layout->plh_lwb = end_pos;
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index 745aa1b..2d722db 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -62,9 +62,6 @@
 	NFS_LAYOUT_RW_FAILED,		/* get rw layout failed stop trying */
 	NFS_LAYOUT_BULK_RECALL,		/* bulk recall affecting layout */
 	NFS_LAYOUT_ROC,			/* some lseg had roc bit set */
-	NFS_LAYOUT_DESTROYED,		/* no new use of layout allowed */
-	NFS_LAYOUT_INVALID,		/* layout is being destroyed */
-	NFS_LAYOUT_RETURNED,		/* layout has already been returned */
 };
 
 enum layoutdriver_policy_flags {
@@ -140,6 +137,7 @@
 	atomic_t		plh_outstanding; /* number of RPCs out */
 	unsigned long		plh_block_lgets; /* block LAYOUTGET if >0 */
 	u32			plh_barrier; /* ignore lower seqids */
+	unsigned long		plh_retry_timestamp;
 	unsigned long		plh_flags;
 	loff_t			plh_lwb; /* last write byte for layoutcommit */
 	struct rpc_cred		*plh_lc_cred; /* layoutcommit cred */
@@ -172,12 +170,12 @@
 				   struct pnfs_devicelist *devlist);
 extern int nfs4_proc_getdeviceinfo(struct nfs_server *server,
 				   struct pnfs_device *dev);
-extern void nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags);
+extern struct pnfs_layout_segment* nfs4_proc_layoutget(struct nfs4_layoutget *lgp, gfp_t gfp_flags);
 extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp);
 
 /* pnfs.c */
-void get_layout_hdr(struct pnfs_layout_hdr *lo);
-void put_lseg(struct pnfs_layout_segment *lseg);
+void pnfs_get_layout_hdr(struct pnfs_layout_hdr *lo);
+void pnfs_put_lseg(struct pnfs_layout_segment *lseg);
 
 void pnfs_pageio_init_read(struct nfs_pageio_descriptor *, struct inode *,
 			   const struct nfs_pgio_completion_ops *);
@@ -188,28 +186,29 @@
 void unset_pnfs_layoutdriver(struct nfs_server *);
 void pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *, struct nfs_page *);
 int pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc);
-void pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *, struct nfs_page *);
+void pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio,
+			        struct nfs_page *req, u64 wb_size);
 int pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc);
 bool pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, struct nfs_page *req);
 void pnfs_set_lo_fail(struct pnfs_layout_segment *lseg);
-int pnfs_layout_process(struct nfs4_layoutget *lgp);
+struct pnfs_layout_segment *pnfs_layout_process(struct nfs4_layoutget *lgp);
 void pnfs_free_lseg_list(struct list_head *tmp_list);
 void pnfs_destroy_layout(struct nfs_inode *);
 void pnfs_destroy_all_layouts(struct nfs_client *);
-void put_layout_hdr(struct pnfs_layout_hdr *lo);
+void pnfs_put_layout_hdr(struct pnfs_layout_hdr *lo);
 void pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo,
 			     const nfs4_stateid *new,
 			     bool update_barrier);
 int pnfs_choose_layoutget_stateid(nfs4_stateid *dst,
 				  struct pnfs_layout_hdr *lo,
 				  struct nfs4_state *open_state);
-int mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo,
+int pnfs_mark_matching_lsegs_invalid(struct pnfs_layout_hdr *lo,
 				struct list_head *tmp_list,
 				struct pnfs_layout_range *recall_range);
 bool pnfs_roc(struct inode *ino);
 void pnfs_roc_release(struct inode *ino);
 void pnfs_roc_set_barrier(struct inode *ino, u32 barrier);
-bool pnfs_roc_drain(struct inode *ino, u32 *barrier);
+bool pnfs_roc_drain(struct inode *ino, u32 *barrier, struct rpc_task *task);
 void pnfs_set_layoutcommit(struct nfs_write_data *wdata);
 void pnfs_cleanup_layoutcommit(struct nfs4_layoutcommit_data *data);
 int pnfs_layoutcommit_inode(struct inode *inode, bool sync);
@@ -233,6 +232,7 @@
 /* nfs4_deviceid_flags */
 enum {
 	NFS_DEVICEID_INVALID = 0,       /* set when MDS clientid recalled */
+	NFS_DEVICEID_UNAVAILABLE,	/* device temporarily unavailable */
 };
 
 /* pnfs_dev.c */
@@ -242,6 +242,7 @@
 	const struct pnfs_layoutdriver_type *ld;
 	const struct nfs_client		*nfs_client;
 	unsigned long 			flags;
+	unsigned long			timestamp_unavailable;
 	struct nfs4_deviceid		deviceid;
 	atomic_t			ref;
 };
@@ -254,34 +255,12 @@
 			     const struct nfs4_deviceid *);
 struct nfs4_deviceid_node *nfs4_insert_deviceid_node(struct nfs4_deviceid_node *);
 bool nfs4_put_deviceid_node(struct nfs4_deviceid_node *);
+void nfs4_mark_deviceid_unavailable(struct nfs4_deviceid_node *node);
+bool nfs4_test_deviceid_unavailable(struct nfs4_deviceid_node *node);
 void nfs4_deviceid_purge_client(const struct nfs_client *);
 
-static inline void
-pnfs_mark_layout_returned(struct pnfs_layout_hdr *lo)
-{
-	set_bit(NFS_LAYOUT_RETURNED, &lo->plh_flags);
-}
-
-static inline void
-pnfs_clear_layout_returned(struct pnfs_layout_hdr *lo)
-{
-	clear_bit(NFS_LAYOUT_RETURNED, &lo->plh_flags);
-}
-
-static inline bool
-pnfs_test_layout_returned(struct pnfs_layout_hdr *lo)
-{
-	return test_bit(NFS_LAYOUT_RETURNED, &lo->plh_flags);
-}
-
-static inline int lo_fail_bit(u32 iomode)
-{
-	return iomode == IOMODE_RW ?
-			 NFS_LAYOUT_RW_FAILED : NFS_LAYOUT_RO_FAILED;
-}
-
 static inline struct pnfs_layout_segment *
-get_lseg(struct pnfs_layout_segment *lseg)
+pnfs_get_lseg(struct pnfs_layout_segment *lseg)
 {
 	if (lseg) {
 		atomic_inc(&lseg->pls_refcount);
@@ -406,12 +385,12 @@
 }
 
 static inline struct pnfs_layout_segment *
-get_lseg(struct pnfs_layout_segment *lseg)
+pnfs_get_lseg(struct pnfs_layout_segment *lseg)
 {
 	return NULL;
 }
 
-static inline void put_lseg(struct pnfs_layout_segment *lseg)
+static inline void pnfs_put_lseg(struct pnfs_layout_segment *lseg)
 {
 }
 
@@ -443,7 +422,7 @@
 }
 
 static inline bool
-pnfs_roc_drain(struct inode *ino, u32 *barrier)
+pnfs_roc_drain(struct inode *ino, u32 *barrier, struct rpc_task *task)
 {
 	return false;
 }
diff --git a/fs/nfs/pnfs_dev.c b/fs/nfs/pnfs_dev.c
index 73f701f..d35b62e 100644
--- a/fs/nfs/pnfs_dev.c
+++ b/fs/nfs/pnfs_dev.c
@@ -40,6 +40,8 @@
 #define NFS4_DEVICE_ID_HASH_SIZE	(1 << NFS4_DEVICE_ID_HASH_BITS)
 #define NFS4_DEVICE_ID_HASH_MASK	(NFS4_DEVICE_ID_HASH_SIZE - 1)
 
+#define PNFS_DEVICE_RETRY_TIMEOUT (120*HZ)
+
 static struct hlist_head nfs4_deviceid_cache[NFS4_DEVICE_ID_HASH_SIZE];
 static DEFINE_SPINLOCK(nfs4_deviceid_lock);
 
@@ -218,6 +220,30 @@
 }
 EXPORT_SYMBOL_GPL(nfs4_put_deviceid_node);
 
+void
+nfs4_mark_deviceid_unavailable(struct nfs4_deviceid_node *node)
+{
+	node->timestamp_unavailable = jiffies;
+	set_bit(NFS_DEVICEID_UNAVAILABLE, &node->flags);
+}
+EXPORT_SYMBOL_GPL(nfs4_mark_deviceid_unavailable);
+
+bool
+nfs4_test_deviceid_unavailable(struct nfs4_deviceid_node *node)
+{
+	if (test_bit(NFS_DEVICEID_UNAVAILABLE, &node->flags)) {
+		unsigned long start, end;
+
+		end = jiffies;
+		start = end - PNFS_DEVICE_RETRY_TIMEOUT;
+		if (time_in_range(node->timestamp_unavailable, start, end))
+			return true;
+		clear_bit(NFS_DEVICEID_UNAVAILABLE, &node->flags);
+	}
+	return false;
+}
+EXPORT_SYMBOL_GPL(nfs4_test_deviceid_unavailable);
+
 static void
 _deviceid_purge_client(const struct nfs_client *clp, long hash)
 {
@@ -276,3 +302,4 @@
 	}
 	rcu_read_unlock();
 }
+
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index d2c7f5d..e831bce 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -88,6 +88,7 @@
 	Opt_sharecache, Opt_nosharecache,
 	Opt_resvport, Opt_noresvport,
 	Opt_fscache, Opt_nofscache,
+	Opt_migration, Opt_nomigration,
 
 	/* Mount options that take integer arguments */
 	Opt_port,
@@ -147,6 +148,8 @@
 	{ Opt_noresvport, "noresvport" },
 	{ Opt_fscache, "fsc" },
 	{ Opt_nofscache, "nofsc" },
+	{ Opt_migration, "migration" },
+	{ Opt_nomigration, "nomigration" },
 
 	{ Opt_port, "port=%s" },
 	{ Opt_rsize, "rsize=%s" },
@@ -676,6 +679,9 @@
 	if (nfss->options & NFS_OPTION_FSCACHE)
 		seq_printf(m, ",fsc");
 
+	if (nfss->options & NFS_OPTION_MIGRATION)
+		seq_printf(m, ",migration");
+
 	if (nfss->flags & NFS_MOUNT_LOOKUP_CACHE_NONEG) {
 		if (nfss->flags & NFS_MOUNT_LOOKUP_CACHE_NONE)
 			seq_printf(m, ",lookupcache=none");
@@ -1106,7 +1112,7 @@
 	string = match_strdup(args);
 	if (string == NULL)
 		return -ENOMEM;
-	rc = strict_strtoul(string, 10, option);
+	rc = kstrtoul(string, 10, option);
 	kfree(string);
 
 	return rc;
@@ -1243,6 +1249,12 @@
 			kfree(mnt->fscache_uniq);
 			mnt->fscache_uniq = NULL;
 			break;
+		case Opt_migration:
+			mnt->options |= NFS_OPTION_MIGRATION;
+			break;
+		case Opt_nomigration:
+			mnt->options &= NFS_OPTION_MIGRATION;
+			break;
 
 		/*
 		 * options that take numeric values
@@ -1535,6 +1547,10 @@
 	if (mnt->minorversion && mnt->version != 4)
 		goto out_minorversion_mismatch;
 
+	if (mnt->options & NFS_OPTION_MIGRATION &&
+	    mnt->version != 4 && mnt->minorversion != 0)
+		goto out_migration_misuse;
+
 	/*
 	 * verify that any proto=/mountproto= options match the address
 	 * families in the addr=/mountaddr= options.
@@ -1572,6 +1588,10 @@
 	printk(KERN_INFO "NFS: mount option vers=%u does not support "
 			 "minorversion=%u\n", mnt->version, mnt->minorversion);
 	return 0;
+out_migration_misuse:
+	printk(KERN_INFO
+		"NFS: 'migration' not supported for this NFS version\n");
+	return 0;
 out_nomem:
 	printk(KERN_INFO "NFS: not enough memory to parse option\n");
 	return 0;
@@ -2494,7 +2514,7 @@
 /*
  * Clone an NFS2/3/4 server record on xdev traversal (FSID-change)
  */
-struct dentry *
+static struct dentry *
 nfs_xdev_mount(struct file_system_type *fs_type, int flags,
 		const char *dev_name, void *raw_data)
 {
@@ -2642,6 +2662,7 @@
 bool nfs4_disable_idmapping = true;
 unsigned short max_session_slots = NFS4_DEF_SLOT_TABLE_SIZE;
 unsigned short send_implementation_id = 1;
+char nfs4_client_id_uniquifier[NFS4_CLIENT_ID_UNIQ_LEN] = "";
 
 EXPORT_SYMBOL_GPL(nfs_callback_set_tcpport);
 EXPORT_SYMBOL_GPL(nfs_callback_tcpport);
@@ -2649,6 +2670,7 @@
 EXPORT_SYMBOL_GPL(nfs4_disable_idmapping);
 EXPORT_SYMBOL_GPL(max_session_slots);
 EXPORT_SYMBOL_GPL(send_implementation_id);
+EXPORT_SYMBOL_GPL(nfs4_client_id_uniquifier);
 
 #define NFS_CALLBACK_MAXPORTNR (65535U)
 
@@ -2659,7 +2681,7 @@
 
 	if (!val)
 		return -EINVAL;
-	ret = strict_strtoul(val, 0, &num);
+	ret = kstrtoul(val, 0, &num);
 	if (ret == -EINVAL || num > NFS_CALLBACK_MAXPORTNR)
 		return -EINVAL;
 	*((unsigned int *)kp->arg) = num;
@@ -2674,6 +2696,8 @@
 module_param_named(callback_tcpport, nfs_callback_set_tcpport, portnr, 0644);
 module_param(nfs_idmap_cache_timeout, int, 0644);
 module_param(nfs4_disable_idmapping, bool, 0644);
+module_param_string(nfs4_unique_id, nfs4_client_id_uniquifier,
+			NFS4_CLIENT_ID_UNIQ_LEN, 0600);
 MODULE_PARM_DESC(nfs4_disable_idmapping,
 		"Turn off NFSv4 idmapping when using 'sec=sys'");
 module_param(max_session_slots, ushort, 0644);
@@ -2682,6 +2706,7 @@
 module_param(send_implementation_id, ushort, 0644);
 MODULE_PARM_DESC(send_implementation_id,
 		"Send implementation ID with NFSv4.1 exchange_id");
+MODULE_PARM_DESC(nfs4_unique_id, "nfs_client_id4 uniquifier string");
 MODULE_ALIAS("nfs4");
 
 #endif /* CONFIG_NFS_V4 */
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index e3b5537..9347ab7 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -846,6 +846,7 @@
 int nfs_flush_incompatible(struct file *file, struct page *page)
 {
 	struct nfs_open_context *ctx = nfs_file_open_context(file);
+	struct nfs_lock_context *l_ctx;
 	struct nfs_page	*req;
 	int do_flush, status;
 	/*
@@ -860,9 +861,12 @@
 		req = nfs_page_find_request(page);
 		if (req == NULL)
 			return 0;
-		do_flush = req->wb_page != page || req->wb_context != ctx ||
-			req->wb_lock_context->lockowner != current->files ||
-			req->wb_lock_context->pid != current->tgid;
+		l_ctx = req->wb_lock_context;
+		do_flush = req->wb_page != page || req->wb_context != ctx;
+		if (l_ctx) {
+			do_flush |= l_ctx->lockowner.l_owner != current->files
+				|| l_ctx->lockowner.l_pid != current->tgid;
+		}
 		nfs_release_request(req);
 		if (!do_flush)
 			return 0;
@@ -1576,6 +1580,7 @@
 		/* We have a mismatch. Write the page again */
 		dprintk(" mismatch\n");
 		nfs_mark_request_dirty(req);
+		set_bit(NFS_CONTEXT_RESEND_WRITES, &req->wb_context->flags);
 	next:
 		nfs_unlock_and_release_request(req);
 	}
diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c
index a4d56ac..16f35f7 100644
--- a/fs/nilfs2/file.c
+++ b/fs/nilfs2/file.c
@@ -116,6 +116,7 @@
 	if (unlikely(ret))
 		goto out;
 
+	file_update_time(vma->vm_file);
 	ret = __block_page_mkwrite(vma, vmf, nilfs_get_block);
 	if (ret) {
 		nilfs_transaction_abort(inode->i_sb);
@@ -134,13 +135,13 @@
 static const struct vm_operations_struct nilfs_file_vm_ops = {
 	.fault		= filemap_fault,
 	.page_mkwrite	= nilfs_page_mkwrite,
+	.remap_pages	= generic_file_remap_pages,
 };
 
 static int nilfs_file_mmap(struct file *file, struct vm_area_struct *vma)
 {
 	file_accessed(file);
 	vma->vm_ops = &nilfs_file_vm_ops;
-	vma->vm_flags |= VM_CAN_NONLINEAR;
 	return 0;
 }
 
diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c
index d150372..47a87dd 100644
--- a/fs/ocfs2/mmap.c
+++ b/fs/ocfs2/mmap.c
@@ -173,6 +173,7 @@
 static const struct vm_operations_struct ocfs2_file_vm_ops = {
 	.fault		= ocfs2_fault,
 	.page_mkwrite	= ocfs2_page_mkwrite,
+	.remap_pages	= generic_file_remap_pages,
 };
 
 int ocfs2_mmap(struct file *file, struct vm_area_struct *vma)
@@ -188,7 +189,6 @@
 	ocfs2_inode_unlock(file->f_dentry->d_inode, lock_level);
 out:
 	vma->vm_ops = &ocfs2_file_vm_ops;
-	vma->vm_flags |= VM_CAN_NONLINEAR;
 	return 0;
 }
 
diff --git a/fs/proc/base.c b/fs/proc/base.c
index d295af99..ef5c84b 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -873,111 +873,6 @@
 	.release	= mem_release,
 };
 
-static ssize_t oom_adjust_read(struct file *file, char __user *buf,
-				size_t count, loff_t *ppos)
-{
-	struct task_struct *task = get_proc_task(file->f_path.dentry->d_inode);
-	char buffer[PROC_NUMBUF];
-	size_t len;
-	int oom_adjust = OOM_DISABLE;
-	unsigned long flags;
-
-	if (!task)
-		return -ESRCH;
-
-	if (lock_task_sighand(task, &flags)) {
-		oom_adjust = task->signal->oom_adj;
-		unlock_task_sighand(task, &flags);
-	}
-
-	put_task_struct(task);
-
-	len = snprintf(buffer, sizeof(buffer), "%i\n", oom_adjust);
-
-	return simple_read_from_buffer(buf, count, ppos, buffer, len);
-}
-
-static ssize_t oom_adjust_write(struct file *file, const char __user *buf,
-				size_t count, loff_t *ppos)
-{
-	struct task_struct *task;
-	char buffer[PROC_NUMBUF];
-	int oom_adjust;
-	unsigned long flags;
-	int err;
-
-	memset(buffer, 0, sizeof(buffer));
-	if (count > sizeof(buffer) - 1)
-		count = sizeof(buffer) - 1;
-	if (copy_from_user(buffer, buf, count)) {
-		err = -EFAULT;
-		goto out;
-	}
-
-	err = kstrtoint(strstrip(buffer), 0, &oom_adjust);
-	if (err)
-		goto out;
-	if ((oom_adjust < OOM_ADJUST_MIN || oom_adjust > OOM_ADJUST_MAX) &&
-	     oom_adjust != OOM_DISABLE) {
-		err = -EINVAL;
-		goto out;
-	}
-
-	task = get_proc_task(file->f_path.dentry->d_inode);
-	if (!task) {
-		err = -ESRCH;
-		goto out;
-	}
-
-	task_lock(task);
-	if (!task->mm) {
-		err = -EINVAL;
-		goto err_task_lock;
-	}
-
-	if (!lock_task_sighand(task, &flags)) {
-		err = -ESRCH;
-		goto err_task_lock;
-	}
-
-	if (oom_adjust < task->signal->oom_adj && !capable(CAP_SYS_RESOURCE)) {
-		err = -EACCES;
-		goto err_sighand;
-	}
-
-	/*
-	 * Warn that /proc/pid/oom_adj is deprecated, see
-	 * Documentation/feature-removal-schedule.txt.
-	 */
-	printk_once(KERN_WARNING "%s (%d): /proc/%d/oom_adj is deprecated, please use /proc/%d/oom_score_adj instead.\n",
-		  current->comm, task_pid_nr(current), task_pid_nr(task),
-		  task_pid_nr(task));
-	task->signal->oom_adj = oom_adjust;
-	/*
-	 * Scale /proc/pid/oom_score_adj appropriately ensuring that a maximum
-	 * value is always attainable.
-	 */
-	if (task->signal->oom_adj == OOM_ADJUST_MAX)
-		task->signal->oom_score_adj = OOM_SCORE_ADJ_MAX;
-	else
-		task->signal->oom_score_adj = (oom_adjust * OOM_SCORE_ADJ_MAX) /
-								-OOM_DISABLE;
-	trace_oom_score_adj_update(task);
-err_sighand:
-	unlock_task_sighand(task, &flags);
-err_task_lock:
-	task_unlock(task);
-	put_task_struct(task);
-out:
-	return err < 0 ? err : count;
-}
-
-static const struct file_operations proc_oom_adjust_operations = {
-	.read		= oom_adjust_read,
-	.write		= oom_adjust_write,
-	.llseek		= generic_file_llseek,
-};
-
 static ssize_t oom_score_adj_read(struct file *file, char __user *buf,
 					size_t count, loff_t *ppos)
 {
@@ -1051,15 +946,7 @@
 	if (has_capability_noaudit(current, CAP_SYS_RESOURCE))
 		task->signal->oom_score_adj_min = oom_score_adj;
 	trace_oom_score_adj_update(task);
-	/*
-	 * Scale /proc/pid/oom_adj appropriately ensuring that OOM_DISABLE is
-	 * always attainable.
-	 */
-	if (task->signal->oom_score_adj == OOM_SCORE_ADJ_MIN)
-		task->signal->oom_adj = OOM_DISABLE;
-	else
-		task->signal->oom_adj = (oom_score_adj * OOM_ADJUST_MAX) /
-							OOM_SCORE_ADJ_MAX;
+
 err_sighand:
 	unlock_task_sighand(task, &flags);
 err_task_lock:
@@ -2710,7 +2597,6 @@
 	REG("cgroup",  S_IRUGO, proc_cgroup_operations),
 #endif
 	INF("oom_score",  S_IRUGO, proc_oom_score),
-	REG("oom_adj",    S_IRUGO|S_IWUSR, proc_oom_adjust_operations),
 	REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
 #ifdef CONFIG_AUDITSYSCALL
 	REG("loginuid",   S_IWUSR|S_IRUGO, proc_loginuid_operations),
@@ -3077,7 +2963,6 @@
 	REG("cgroup",  S_IRUGO, proc_cgroup_operations),
 #endif
 	INF("oom_score", S_IRUGO, proc_oom_score),
-	REG("oom_adj",   S_IRUGO|S_IWUSR, proc_oom_adjust_operations),
 	REG("oom_score_adj", S_IRUGO|S_IWUSR, proc_oom_score_adj_operations),
 #ifdef CONFIG_AUDITSYSCALL
 	REG("loginuid",  S_IWUSR|S_IRUGO, proc_loginuid_operations),
diff --git a/fs/proc/page.c b/fs/proc/page.c
index 7fcd0d6..b8730d9 100644
--- a/fs/proc/page.c
+++ b/fs/proc/page.c
@@ -115,7 +115,13 @@
 		u |= 1 << KPF_COMPOUND_TAIL;
 	if (PageHuge(page))
 		u |= 1 << KPF_HUGE;
-	else if (PageTransCompound(page))
+	/*
+	 * PageTransCompound can be true for non-huge compound pages (slab
+	 * pages or pages allocated by drivers with __GFP_COMP) because it
+	 * just checks PG_head/PG_tail, so we need to check PageLRU to make
+	 * sure a given page is a thp, not a non-huge compound page.
+	 */
+	else if (PageTransCompound(page) && PageLRU(compound_trans_head(page)))
 		u |= 1 << KPF_THP;
 
 	/*
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index dcd56f84..a781bdf 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -142,6 +142,7 @@
 	}
 
 	rb_link_node(node, parent, p);
+	rb_insert_color(node, &head->parent->root);
 	return 0;
 }
 
@@ -168,10 +169,8 @@
 	head->node = node;
 	if (node) {
 		struct ctl_table *entry;
-		for (entry = table; entry->procname; entry++, node++) {
-			rb_init_node(&node->node);
+		for (entry = table; entry->procname; entry++, node++)
 			node->header = head;
-		}
 	}
 }
 
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 4540b8f..79827ce 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -54,7 +54,7 @@
 		"VmPTE:\t%8lu kB\n"
 		"VmSwap:\t%8lu kB\n",
 		hiwater_vm << (PAGE_SHIFT-10),
-		(total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
+		total_vm << (PAGE_SHIFT-10),
 		mm->locked_vm << (PAGE_SHIFT-10),
 		mm->pinned_vm << (PAGE_SHIFT-10),
 		hiwater_rss << (PAGE_SHIFT-10),
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 4648555..f27f01a 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -1573,8 +1573,10 @@
 			reiserfs_warning(sb, "reiserfs-13077",
 				"nfsd/reiserfs, fhtype=%d, len=%d - odd",
 				fh_type, fh_len);
-		fh_type = 5;
+		fh_type = fh_len;
 	}
+	if (fh_len < 2)
+		return NULL;
 
 	return reiserfs_get_dentry(sb, fid->raw[0], fid->raw[1],
 		(fh_type == 3 || fh_type >= 5) ? fid->raw[2] : 0);
@@ -1583,6 +1585,8 @@
 struct dentry *reiserfs_fh_to_parent(struct super_block *sb, struct fid *fid,
 		int fh_len, int fh_type)
 {
+	if (fh_type > fh_len)
+		fh_type = fh_len;
 	if (fh_type < 4)
 		return NULL;
 
diff --git a/fs/super.c b/fs/super.c
index a3bc935..12f1237 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -186,15 +186,8 @@
 		spin_lock_init(&s->s_inode_lru_lock);
 		INIT_LIST_HEAD(&s->s_mounts);
 		init_rwsem(&s->s_umount);
-		mutex_init(&s->s_lock);
 		lockdep_set_class(&s->s_umount, &type->s_umount_key);
 		/*
-		 * The locking rules for s_lock are up to the
-		 * filesystem. For example ext3fs has different
-		 * lock ordering than usbfs:
-		 */
-		lockdep_set_class(&s->s_lock, &type->s_lock_key);
-		/*
 		 * sget() can have s_umount recursion.
 		 *
 		 * When it cannot find a suitable sb, it allocates a new
@@ -394,22 +387,6 @@
 	return false;
 }
 
-/*
- * Superblock locking.  We really ought to get rid of these two.
- */
-void lock_super(struct super_block * sb)
-{
-	mutex_lock(&sb->s_lock);
-}
-
-void unlock_super(struct super_block * sb)
-{
-	mutex_unlock(&sb->s_lock);
-}
-
-EXPORT_SYMBOL(lock_super);
-EXPORT_SYMBOL(unlock_super);
-
 /**
  *	generic_shutdown_super	-	common helper for ->kill_sb()
  *	@sb: superblock to kill
diff --git a/fs/sysv/balloc.c b/fs/sysv/balloc.c
index 9a6ad96a..921c053 100644
--- a/fs/sysv/balloc.c
+++ b/fs/sysv/balloc.c
@@ -60,12 +60,12 @@
 		return;
 	}
 
-	lock_super(sb);
+	mutex_lock(&sbi->s_lock);
 	count = fs16_to_cpu(sbi, *sbi->s_bcache_count);
 
 	if (count > sbi->s_flc_size) {
 		printk("sysv_free_block: flc_count > flc_size\n");
-		unlock_super(sb);
+		mutex_unlock(&sbi->s_lock);
 		return;
 	}
 	/* If the free list head in super-block is full, it is copied
@@ -77,7 +77,7 @@
 		bh = sb_getblk(sb, block);
 		if (!bh) {
 			printk("sysv_free_block: getblk() failed\n");
-			unlock_super(sb);
+			mutex_unlock(&sbi->s_lock);
 			return;
 		}
 		memset(bh->b_data, 0, sb->s_blocksize);
@@ -93,7 +93,7 @@
 	*sbi->s_bcache_count = cpu_to_fs16(sbi, count);
 	fs32_add(sbi, sbi->s_free_blocks, 1);
 	dirty_sb(sb);
-	unlock_super(sb);
+	mutex_unlock(&sbi->s_lock);
 }
 
 sysv_zone_t sysv_new_block(struct super_block * sb)
@@ -104,7 +104,7 @@
 	struct buffer_head * bh;
 	unsigned count;
 
-	lock_super(sb);
+	mutex_lock(&sbi->s_lock);
 	count = fs16_to_cpu(sbi, *sbi->s_bcache_count);
 
 	if (count == 0) /* Applies only to Coherent FS */
@@ -147,11 +147,11 @@
 	/* Now the free list head in the superblock is valid again. */
 	fs32_add(sbi, sbi->s_free_blocks, -1);
 	dirty_sb(sb);
-	unlock_super(sb);
+	mutex_unlock(&sbi->s_lock);
 	return nr;
 
 Enospc:
-	unlock_super(sb);
+	mutex_unlock(&sbi->s_lock);
 	return 0;
 }
 
@@ -173,7 +173,7 @@
 	if (sbi->s_type == FSTYPE_AFS)
 		return 0;
 
-	lock_super(sb);
+	mutex_lock(&sbi->s_lock);
 	sb_count = fs32_to_cpu(sbi, *sbi->s_free_blocks);
 
 	if (0)
@@ -211,7 +211,7 @@
 	if (count != sb_count)
 		goto Ecount;
 done:
-	unlock_super(sb);
+	mutex_unlock(&sbi->s_lock);
 	return count;
 
 Einval:
diff --git a/fs/sysv/ialloc.c b/fs/sysv/ialloc.c
index 8233b02..f9db4eb 100644
--- a/fs/sysv/ialloc.c
+++ b/fs/sysv/ialloc.c
@@ -118,7 +118,7 @@
 		       "%s\n", inode->i_sb->s_id);
 		return;
 	}
-	lock_super(sb);
+	mutex_lock(&sbi->s_lock);
 	count = fs16_to_cpu(sbi, *sbi->s_sb_fic_count);
 	if (count < sbi->s_fic_size) {
 		*sv_sb_fic_inode(sb,count++) = cpu_to_fs16(sbi, ino);
@@ -128,7 +128,7 @@
 	dirty_sb(sb);
 	memset(raw_inode, 0, sizeof(struct sysv_inode));
 	mark_buffer_dirty(bh);
-	unlock_super(sb);
+	mutex_unlock(&sbi->s_lock);
 	brelse(bh);
 }
 
@@ -147,13 +147,13 @@
 	if (!inode)
 		return ERR_PTR(-ENOMEM);
 
-	lock_super(sb);
+	mutex_lock(&sbi->s_lock);
 	count = fs16_to_cpu(sbi, *sbi->s_sb_fic_count);
 	if (count == 0 || (*sv_sb_fic_inode(sb,count-1) == 0)) {
 		count = refill_free_cache(sb);
 		if (count == 0) {
 			iput(inode);
-			unlock_super(sb);
+			mutex_unlock(&sbi->s_lock);
 			return ERR_PTR(-ENOSPC);
 		}
 	}
@@ -174,7 +174,7 @@
 	sysv_write_inode(inode, &wbc);	/* ensure inode not allocated again */
 	mark_inode_dirty(inode);	/* cleared by sysv_write_inode() */
 	/* That's it. */
-	unlock_super(sb);
+	mutex_unlock(&sbi->s_lock);
 	return inode;
 }
 
@@ -185,7 +185,7 @@
 	struct sysv_inode * raw_inode;
 	int ino, count, sb_count;
 
-	lock_super(sb);
+	mutex_lock(&sbi->s_lock);
 
 	sb_count = fs16_to_cpu(sbi, *sbi->s_sb_total_free_inodes);
 
@@ -213,7 +213,7 @@
 	if (count != sb_count)
 		goto Einval;
 out:
-	unlock_super(sb);
+	mutex_unlock(&sbi->s_lock);
 	return count;
 
 Einval:
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index d33e506..c327d4e 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -36,7 +36,7 @@
 	struct sysv_sb_info *sbi = SYSV_SB(sb);
 	unsigned long time = get_seconds(), old_time;
 
-	lock_super(sb);
+	mutex_lock(&sbi->s_lock);
 
 	/*
 	 * If we are going to write out the super block,
@@ -51,7 +51,7 @@
 		mark_buffer_dirty(sbi->s_bh2);
 	}
 
-	unlock_super(sb);
+	mutex_unlock(&sbi->s_lock);
 
 	return 0;
 }
diff --git a/fs/sysv/super.c b/fs/sysv/super.c
index 7491c33..a38e87b 100644
--- a/fs/sysv/super.c
+++ b/fs/sysv/super.c
@@ -368,6 +368,7 @@
 
 	sbi->s_sb = sb;
 	sbi->s_block_base = 0;
+	mutex_init(&sbi->s_lock);
 	sb->s_fs_info = sbi;
 
 	sb_set_blocksize(sb, BLOCK_SIZE);
diff --git a/fs/sysv/sysv.h b/fs/sysv/sysv.h
index 0bc35fd..69d4889 100644
--- a/fs/sysv/sysv.h
+++ b/fs/sysv/sysv.h
@@ -58,6 +58,7 @@
 	u32            s_nzones;	/* same as s_sbd->s_fsize */
 	u16	       s_namelen;       /* max length of dir entry */
 	int	       s_forced_ro;
+	struct mutex s_lock;
 };
 
 /*
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index ff48c5a..5bc7781 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1536,6 +1536,7 @@
 static const struct vm_operations_struct ubifs_file_vm_ops = {
 	.fault        = filemap_fault,
 	.page_mkwrite = ubifs_vm_page_mkwrite,
+	.remap_pages = generic_file_remap_pages,
 };
 
 static int ubifs_file_mmap(struct file *file, struct vm_area_struct *vma)
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c
index 1b3e410..a7ea492 100644
--- a/fs/ufs/balloc.c
+++ b/fs/ufs/balloc.c
@@ -54,7 +54,7 @@
 	if (ufs_fragnum(fragment) + count > uspi->s_fpg)
 		ufs_error (sb, "ufs_free_fragments", "internal error");
 	
-	lock_super(sb);
+	mutex_lock(&UFS_SB(sb)->s_lock);
 	
 	cgno = ufs_dtog(uspi, fragment);
 	bit = ufs_dtogd(uspi, fragment);
@@ -118,12 +118,12 @@
 		ubh_sync_block(UCPI_UBH(ucpi));
 	ufs_mark_sb_dirty(sb);
 	
-	unlock_super (sb);
+	mutex_unlock(&UFS_SB(sb)->s_lock);
 	UFSD("EXIT\n");
 	return;
 
 failed:
-	unlock_super (sb);
+	mutex_unlock(&UFS_SB(sb)->s_lock);
 	UFSD("EXIT (FAILED)\n");
 	return;
 }
@@ -155,7 +155,7 @@
 		goto failed;
 	}
 
-	lock_super(sb);
+	mutex_lock(&UFS_SB(sb)->s_lock);
 	
 do_more:
 	overflow = 0;
@@ -215,12 +215,12 @@
 	}
 
 	ufs_mark_sb_dirty(sb);
-	unlock_super (sb);
+	mutex_unlock(&UFS_SB(sb)->s_lock);
 	UFSD("EXIT\n");
 	return;
 
 failed_unlock:
-	unlock_super (sb);
+	mutex_unlock(&UFS_SB(sb)->s_lock);
 failed:
 	UFSD("EXIT (FAILED)\n");
 	return;
@@ -361,7 +361,7 @@
 	usb1 = ubh_get_usb_first(uspi);
 	*err = -ENOSPC;
 
-	lock_super (sb);
+	mutex_lock(&UFS_SB(sb)->s_lock);
 	tmp = ufs_data_ptr_to_cpu(sb, p);
 
 	if (count + ufs_fragnum(fragment) > uspi->s_fpb) {
@@ -382,19 +382,19 @@
 				  "fragment %llu, tmp %llu\n",
 				  (unsigned long long)fragment,
 				  (unsigned long long)tmp);
-			unlock_super(sb);
+			mutex_unlock(&UFS_SB(sb)->s_lock);
 			return INVBLOCK;
 		}
 		if (fragment < UFS_I(inode)->i_lastfrag) {
 			UFSD("EXIT (ALREADY ALLOCATED)\n");
-			unlock_super (sb);
+			mutex_unlock(&UFS_SB(sb)->s_lock);
 			return 0;
 		}
 	}
 	else {
 		if (tmp) {
 			UFSD("EXIT (ALREADY ALLOCATED)\n");
-			unlock_super(sb);
+			mutex_unlock(&UFS_SB(sb)->s_lock);
 			return 0;
 		}
 	}
@@ -403,7 +403,7 @@
 	 * There is not enough space for user on the device
 	 */
 	if (!capable(CAP_SYS_RESOURCE) && ufs_freespace(uspi, UFS_MINFREE) <= 0) {
-		unlock_super (sb);
+		mutex_unlock(&UFS_SB(sb)->s_lock);
 		UFSD("EXIT (FAILED)\n");
 		return 0;
 	}
@@ -428,7 +428,7 @@
 			ufs_clear_frags(inode, result + oldcount,
 					newcount - oldcount, locked_page != NULL);
 		}
-		unlock_super(sb);
+		mutex_unlock(&UFS_SB(sb)->s_lock);
 		UFSD("EXIT, result %llu\n", (unsigned long long)result);
 		return result;
 	}
@@ -443,7 +443,7 @@
 						fragment + count);
 		ufs_clear_frags(inode, result + oldcount, newcount - oldcount,
 				locked_page != NULL);
-		unlock_super(sb);
+		mutex_unlock(&UFS_SB(sb)->s_lock);
 		UFSD("EXIT, result %llu\n", (unsigned long long)result);
 		return result;
 	}
@@ -481,7 +481,7 @@
 		*err = 0;
 		UFS_I(inode)->i_lastfrag = max(UFS_I(inode)->i_lastfrag,
 						fragment + count);
-		unlock_super(sb);
+		mutex_unlock(&UFS_SB(sb)->s_lock);
 		if (newcount < request)
 			ufs_free_fragments (inode, result + newcount, request - newcount);
 		ufs_free_fragments (inode, tmp, oldcount);
@@ -489,7 +489,7 @@
 		return result;
 	}
 
-	unlock_super(sb);
+	mutex_unlock(&UFS_SB(sb)->s_lock);
 	UFSD("EXIT (FAILED)\n");
 	return 0;
 }		
diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c
index e84cbe2..d0426d7 100644
--- a/fs/ufs/ialloc.c
+++ b/fs/ufs/ialloc.c
@@ -71,11 +71,11 @@
 	
 	ino = inode->i_ino;
 
-	lock_super (sb);
+	mutex_lock(&UFS_SB(sb)->s_lock);
 
 	if (!((ino > 1) && (ino < (uspi->s_ncg * uspi->s_ipg )))) {
 		ufs_warning(sb, "ufs_free_inode", "reserved inode or nonexistent inode %u\n", ino);
-		unlock_super (sb);
+		mutex_unlock(&UFS_SB(sb)->s_lock);
 		return;
 	}
 	
@@ -83,7 +83,7 @@
 	bit = ufs_inotocgoff (ino);
 	ucpi = ufs_load_cylinder (sb, cg);
 	if (!ucpi) {
-		unlock_super (sb);
+		mutex_unlock(&UFS_SB(sb)->s_lock);
 		return;
 	}
 	ucg = ubh_get_ucg(UCPI_UBH(ucpi));
@@ -117,7 +117,7 @@
 		ubh_sync_block(UCPI_UBH(ucpi));
 	
 	ufs_mark_sb_dirty(sb);
-	unlock_super (sb);
+	mutex_unlock(&UFS_SB(sb)->s_lock);
 	UFSD("EXIT\n");
 }
 
@@ -197,7 +197,7 @@
 	uspi = sbi->s_uspi;
 	usb1 = ubh_get_usb_first(uspi);
 
-	lock_super (sb);
+	mutex_lock(&sbi->s_lock);
 
 	/*
 	 * Try to place the inode in its parent directory
@@ -333,20 +333,20 @@
 		brelse(bh);
 	}
 
-	unlock_super (sb);
+	mutex_unlock(&sbi->s_lock);
 
 	UFSD("allocating inode %lu\n", inode->i_ino);
 	UFSD("EXIT\n");
 	return inode;
 
 fail_remove_inode:
-	unlock_super(sb);
+	mutex_unlock(&sbi->s_lock);
 	clear_nlink(inode);
 	iput(inode);
 	UFSD("EXIT (FAILED): err %d\n", err);
 	return ERR_PTR(err);
 failed:
-	unlock_super (sb);
+	mutex_unlock(&sbi->s_lock);
 	make_bad_inode(inode);
 	iput (inode);
 	UFSD("EXIT (FAILED): err %d\n", err);
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index f7cfecf..dc8e3a8 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -699,7 +699,7 @@
 	unsigned flags;
 
 	lock_ufs(sb);
-	lock_super(sb);
+	mutex_lock(&UFS_SB(sb)->s_lock);
 
 	UFSD("ENTER\n");
 
@@ -717,7 +717,7 @@
 	ufs_put_cstotal(sb);
 
 	UFSD("EXIT\n");
-	unlock_super(sb);
+	mutex_unlock(&UFS_SB(sb)->s_lock);
 	unlock_ufs(sb);
 
 	return 0;
@@ -805,6 +805,7 @@
 	}
 #endif
 	mutex_init(&sbi->mutex);
+	mutex_init(&sbi->s_lock);
 	spin_lock_init(&sbi->work_lock);
 	INIT_DELAYED_WORK(&sbi->sync_work, delayed_sync_fs);
 	/*
@@ -1280,7 +1281,7 @@
 	unsigned flags;
 
 	lock_ufs(sb);
-	lock_super(sb);
+	mutex_lock(&UFS_SB(sb)->s_lock);
 	uspi = UFS_SB(sb)->s_uspi;
 	flags = UFS_SB(sb)->s_flags;
 	usb1 = ubh_get_usb_first(uspi);
@@ -1294,7 +1295,7 @@
 	new_mount_opt = 0;
 	ufs_set_opt (new_mount_opt, ONERROR_LOCK);
 	if (!ufs_parse_options (data, &new_mount_opt)) {
-		unlock_super(sb);
+		mutex_unlock(&UFS_SB(sb)->s_lock);
 		unlock_ufs(sb);
 		return -EINVAL;
 	}
@@ -1302,14 +1303,14 @@
 		new_mount_opt |= ufstype;
 	} else if ((new_mount_opt & UFS_MOUNT_UFSTYPE) != ufstype) {
 		printk("ufstype can't be changed during remount\n");
-		unlock_super(sb);
+		mutex_unlock(&UFS_SB(sb)->s_lock);
 		unlock_ufs(sb);
 		return -EINVAL;
 	}
 
 	if ((*mount_flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) {
 		UFS_SB(sb)->s_mount_opt = new_mount_opt;
-		unlock_super(sb);
+		mutex_unlock(&UFS_SB(sb)->s_lock);
 		unlock_ufs(sb);
 		return 0;
 	}
@@ -1334,7 +1335,7 @@
 #ifndef CONFIG_UFS_FS_WRITE
 		printk("ufs was compiled with read-only support, "
 		"can't be mounted as read-write\n");
-		unlock_super(sb);
+		mutex_unlock(&UFS_SB(sb)->s_lock);
 		unlock_ufs(sb);
 		return -EINVAL;
 #else
@@ -1344,13 +1345,13 @@
 		    ufstype != UFS_MOUNT_UFSTYPE_SUNx86 &&
 		    ufstype != UFS_MOUNT_UFSTYPE_UFS2) {
 			printk("this ufstype is read-only supported\n");
-			unlock_super(sb);
+			mutex_unlock(&UFS_SB(sb)->s_lock);
 			unlock_ufs(sb);
 			return -EINVAL;
 		}
 		if (!ufs_read_cylinder_structures(sb)) {
 			printk("failed during remounting\n");
-			unlock_super(sb);
+			mutex_unlock(&UFS_SB(sb)->s_lock);
 			unlock_ufs(sb);
 			return -EPERM;
 		}
@@ -1358,7 +1359,7 @@
 #endif
 	}
 	UFS_SB(sb)->s_mount_opt = new_mount_opt;
-	unlock_super(sb);
+	mutex_unlock(&UFS_SB(sb)->s_lock);
 	unlock_ufs(sb);
 	return 0;
 }
diff --git a/fs/ufs/ufs.h b/fs/ufs/ufs.h
index 343e6fc..ff2c15a 100644
--- a/fs/ufs/ufs.h
+++ b/fs/ufs/ufs.h
@@ -24,6 +24,7 @@
 	int work_queued; /* non-zero if the delayed work is queued */
 	struct delayed_work sync_work; /* FS sync delayed work */
 	spinlock_t work_lock; /* protects sync_work and work_queued */
+	struct mutex s_lock;
 };
 
 struct ufs_inode_info {
diff --git a/fs/xfs/xfs_export.c b/fs/xfs/xfs_export.c
index 4267922..8c6d1d7 100644
--- a/fs/xfs/xfs_export.c
+++ b/fs/xfs/xfs_export.c
@@ -189,6 +189,9 @@
 	struct xfs_fid64	*fid64 = (struct xfs_fid64 *)fid;
 	struct inode		*inode = NULL;
 
+	if (fh_len < xfs_fileid_length(fileid_type))
+		return NULL;
+
 	switch (fileid_type) {
 	case FILEID_INO32_GEN_PARENT:
 		inode = xfs_nfs_get_inode(sb, fid->i32.parent_ino,
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 1eaeb8b..aa473fa 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -940,7 +940,6 @@
 	struct vm_area_struct *vma)
 {
 	vma->vm_ops = &xfs_file_vm_ops;
-	vma->vm_flags |= VM_CAN_NONLINEAR;
 
 	file_accessed(filp);
 	return 0;
@@ -1443,4 +1442,5 @@
 static const struct vm_operations_struct xfs_file_vm_ops = {
 	.fault		= filemap_fault,
 	.page_mkwrite	= xfs_vm_page_mkwrite,
+	.remap_pages	= generic_file_remap_pages,
 };
diff --git a/include/acpi/acbuffer.h b/include/acpi/acbuffer.h
new file mode 100644
index 0000000..a1e45cd
--- /dev/null
+++ b/include/acpi/acbuffer.h
@@ -0,0 +1,235 @@
+/******************************************************************************
+ *
+ * Name: acbuffer.h - Support for buffers returned by ACPI predefined names
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2012, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#ifndef __ACBUFFER_H__
+#define __ACBUFFER_H__
+
+/*
+ * Contains buffer structures for these predefined names:
+ * _FDE, _GRT, _GTM, _PLD, _SRT
+ */
+
+/*
+ * Note: C bitfields are not used for this reason:
+ *
+ * "Bitfields are great and easy to read, but unfortunately the C language
+ * does not specify the layout of bitfields in memory, which means they are
+ * essentially useless for dealing with packed data in on-disk formats or
+ * binary wire protocols." (Or ACPI tables and buffers.) "If you ask me,
+ * this decision was a design error in C. Ritchie could have picked an order
+ * and stuck with it." Norman Ramsey.
+ * See http://stackoverflow.com/a/1053662/41661
+ */
+
+/* _FDE return value */
+
+struct acpi_fde_info {
+	u32 floppy0;
+	u32 floppy1;
+	u32 floppy2;
+	u32 floppy3;
+	u32 tape;
+};
+
+/*
+ * _GRT return value
+ * _SRT input value
+ */
+struct acpi_grt_info {
+	u16 year;
+	u8 month;
+	u8 day;
+	u8 hour;
+	u8 minute;
+	u8 second;
+	u8 valid;
+	u16 milliseconds;
+	u16 timezone;
+	u8 daylight;
+	u8 reserved[3];
+};
+
+/* _GTM return value */
+
+struct acpi_gtm_info {
+	u32 pio_speed0;
+	u32 dma_speed0;
+	u32 pio_speed1;
+	u32 dma_speed1;
+	u32 flags;
+};
+
+/*
+ * Formatted _PLD return value. The minimum size is a package containing
+ * one buffer.
+ * Revision 1: Buffer is 16 bytes (128 bits)
+ * Revision 2: Buffer is 20 bytes (160 bits)
+ *
+ * Note: This structure is returned from the acpi_decode_pld_buffer
+ * interface.
+ */
+struct acpi_pld_info {
+	u8 revision;
+	u8 ignore_color;
+	u32 color;
+	u16 width;
+	u16 height;
+	u8 user_visible;
+	u8 dock;
+	u8 lid;
+	u8 panel;
+	u8 vertical_position;
+	u8 horizontal_position;
+	u8 shape;
+	u8 group_orientation;
+	u8 group_token;
+	u8 group_position;
+	u8 bay;
+	u8 ejectable;
+	u8 ospm_eject_required;
+	u8 cabinet_number;
+	u8 card_cage_number;
+	u8 reference;
+	u8 rotation;
+	u8 order;
+	u8 reserved;
+	u16 vertical_offset;
+	u16 horizontal_offset;
+};
+
+/*
+ * Macros to:
+ *     1) Convert a _PLD buffer to internal struct acpi_pld_info format - ACPI_PLD_GET*
+ *        (Used by acpi_decode_pld_buffer)
+ *     2) Construct a _PLD buffer - ACPI_PLD_SET*
+ *        (Intended for BIOS use only)
+ */
+#define ACPI_PLD_REV1_BUFFER_SIZE               16	/* For Revision 1 of the buffer (From ACPI spec) */
+#define ACPI_PLD_BUFFER_SIZE                    20	/* For Revision 2 of the buffer (From ACPI spec) */
+
+/* First 32-bit dword, bits 0:32 */
+
+#define ACPI_PLD_GET_REVISION(dword)            ACPI_GET_BITS (dword, 0, ACPI_7BIT_MASK)
+#define ACPI_PLD_SET_REVISION(dword,value)      ACPI_SET_BITS (dword, 0, ACPI_7BIT_MASK, value)	/* Offset 0, Len 7 */
+
+#define ACPI_PLD_GET_IGNORE_COLOR(dword)        ACPI_GET_BITS (dword, 7, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_IGNORE_COLOR(dword,value)  ACPI_SET_BITS (dword, 7, ACPI_1BIT_MASK, value)	/* Offset 7, Len 1 */
+
+#define ACPI_PLD_GET_COLOR(dword)               ACPI_GET_BITS (dword, 8, ACPI_24BIT_MASK)
+#define ACPI_PLD_SET_COLOR(dword,value)         ACPI_SET_BITS (dword, 8, ACPI_24BIT_MASK, value)	/* Offset 8, Len 24 */
+
+/* Second 32-bit dword, bits 33:63 */
+
+#define ACPI_PLD_GET_WIDTH(dword)               ACPI_GET_BITS (dword, 0, ACPI_16BIT_MASK)
+#define ACPI_PLD_SET_WIDTH(dword,value)         ACPI_SET_BITS (dword, 0, ACPI_16BIT_MASK, value)	/* Offset 32+0=32, Len 16 */
+
+#define ACPI_PLD_GET_HEIGHT(dword)              ACPI_GET_BITS (dword, 16, ACPI_16BIT_MASK)
+#define ACPI_PLD_SET_HEIGHT(dword,value)        ACPI_SET_BITS (dword, 16, ACPI_16BIT_MASK, value)	/* Offset 32+16=48, Len 16 */
+
+/* Third 32-bit dword, bits 64:95 */
+
+#define ACPI_PLD_GET_USER_VISIBLE(dword)        ACPI_GET_BITS (dword, 0, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_USER_VISIBLE(dword,value)  ACPI_SET_BITS (dword, 0, ACPI_1BIT_MASK, value)	/* Offset 64+0=64, Len 1 */
+
+#define ACPI_PLD_GET_DOCK(dword)                ACPI_GET_BITS (dword, 1, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_DOCK(dword,value)          ACPI_SET_BITS (dword, 1, ACPI_1BIT_MASK, value)	/* Offset 64+1=65, Len 1 */
+
+#define ACPI_PLD_GET_LID(dword)                 ACPI_GET_BITS (dword, 2, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_LID(dword,value)           ACPI_SET_BITS (dword, 2, ACPI_1BIT_MASK, value)	/* Offset 64+2=66, Len 1 */
+
+#define ACPI_PLD_GET_PANEL(dword)               ACPI_GET_BITS (dword, 3, ACPI_3BIT_MASK)
+#define ACPI_PLD_SET_PANEL(dword,value)         ACPI_SET_BITS (dword, 3, ACPI_3BIT_MASK, value)	/* Offset 64+3=67, Len 3 */
+
+#define ACPI_PLD_GET_VERTICAL(dword)            ACPI_GET_BITS (dword, 6, ACPI_2BIT_MASK)
+#define ACPI_PLD_SET_VERTICAL(dword,value)      ACPI_SET_BITS (dword, 6, ACPI_2BIT_MASK, value)	/* Offset 64+6=70, Len 2 */
+
+#define ACPI_PLD_GET_HORIZONTAL(dword)          ACPI_GET_BITS (dword, 8, ACPI_2BIT_MASK)
+#define ACPI_PLD_SET_HORIZONTAL(dword,value)    ACPI_SET_BITS (dword, 8, ACPI_2BIT_MASK, value)	/* Offset 64+8=72, Len 2 */
+
+#define ACPI_PLD_GET_SHAPE(dword)               ACPI_GET_BITS (dword, 10, ACPI_4BIT_MASK)
+#define ACPI_PLD_SET_SHAPE(dword,value)         ACPI_SET_BITS (dword, 10, ACPI_4BIT_MASK, value)	/* Offset 64+10=74, Len 4 */
+
+#define ACPI_PLD_GET_ORIENTATION(dword)         ACPI_GET_BITS (dword, 14, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_ORIENTATION(dword,value)   ACPI_SET_BITS (dword, 14, ACPI_1BIT_MASK, value)	/* Offset 64+14=78, Len 1 */
+
+#define ACPI_PLD_GET_TOKEN(dword)               ACPI_GET_BITS (dword, 15, ACPI_8BIT_MASK)
+#define ACPI_PLD_SET_TOKEN(dword,value)         ACPI_SET_BITS (dword, 15, ACPI_8BIT_MASK, value)	/* Offset 64+15=79, Len 8 */
+
+#define ACPI_PLD_GET_POSITION(dword)            ACPI_GET_BITS (dword, 23, ACPI_8BIT_MASK)
+#define ACPI_PLD_SET_POSITION(dword,value)      ACPI_SET_BITS (dword, 23, ACPI_8BIT_MASK, value)	/* Offset 64+23=87, Len 8 */
+
+#define ACPI_PLD_GET_BAY(dword)                 ACPI_GET_BITS (dword, 31, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_BAY(dword,value)           ACPI_SET_BITS (dword, 31, ACPI_1BIT_MASK, value)	/* Offset 64+31=95, Len 1 */
+
+/* Fourth 32-bit dword, bits 96:127 */
+
+#define ACPI_PLD_GET_EJECTABLE(dword)           ACPI_GET_BITS (dword, 0, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_EJECTABLE(dword,value)     ACPI_SET_BITS (dword, 0, ACPI_1BIT_MASK, value)	/* Offset 96+0=96, Len 1 */
+
+#define ACPI_PLD_GET_OSPM_EJECT(dword)          ACPI_GET_BITS (dword, 1, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_OSPM_EJECT(dword,value)    ACPI_SET_BITS (dword, 1, ACPI_1BIT_MASK, value)	/* Offset 96+1=97, Len 1 */
+
+#define ACPI_PLD_GET_CABINET(dword)             ACPI_GET_BITS (dword, 2, ACPI_8BIT_MASK)
+#define ACPI_PLD_SET_CABINET(dword,value)       ACPI_SET_BITS (dword, 2, ACPI_8BIT_MASK, value)	/* Offset 96+2=98, Len 8 */
+
+#define ACPI_PLD_GET_CARD_CAGE(dword)           ACPI_GET_BITS (dword, 10, ACPI_8BIT_MASK)
+#define ACPI_PLD_SET_CARD_CAGE(dword,value)     ACPI_SET_BITS (dword, 10, ACPI_8BIT_MASK, value)	/* Offset 96+10=106, Len 8 */
+
+#define ACPI_PLD_GET_REFERENCE(dword)           ACPI_GET_BITS (dword, 18, ACPI_1BIT_MASK)
+#define ACPI_PLD_SET_REFERENCE(dword,value)     ACPI_SET_BITS (dword, 18, ACPI_1BIT_MASK, value)	/* Offset 96+18=114, Len 1 */
+
+#define ACPI_PLD_GET_ROTATION(dword)            ACPI_GET_BITS (dword, 19, ACPI_4BIT_MASK)
+#define ACPI_PLD_SET_ROTATION(dword,value)      ACPI_SET_BITS (dword, 19, ACPI_4BIT_MASK, value)	/* Offset 96+19=115, Len 4 */
+
+#define ACPI_PLD_GET_ORDER(dword)               ACPI_GET_BITS (dword, 23, ACPI_5BIT_MASK)
+#define ACPI_PLD_SET_ORDER(dword,value)         ACPI_SET_BITS (dword, 23, ACPI_5BIT_MASK, value)	/* Offset 96+23=119, Len 5 */
+
+/* Fifth 32-bit dword, bits 128:159 (Revision 2 of _PLD only) */
+
+#define ACPI_PLD_GET_VERT_OFFSET(dword)         ACPI_GET_BITS (dword, 0, ACPI_16BIT_MASK)
+#define ACPI_PLD_SET_VERT_OFFSET(dword,value)   ACPI_SET_BITS (dword, 0, ACPI_16BIT_MASK, value)	/* Offset 128+0=128, Len 16 */
+
+#define ACPI_PLD_GET_HORIZ_OFFSET(dword)        ACPI_GET_BITS (dword, 16, ACPI_16BIT_MASK)
+#define ACPI_PLD_SET_HORIZ_OFFSET(dword,value)  ACPI_SET_BITS (dword, 16, ACPI_16BIT_MASK, value)	/* Offset 128+16=144, Len 16 */
+
+#endif				/* ACBUFFER_H */
diff --git a/include/acpi/acnames.h b/include/acpi/acnames.h
index d988ac5..745dd24e 100644
--- a/include/acpi/acnames.h
+++ b/include/acpi/acnames.h
@@ -63,11 +63,10 @@
 #define METHOD_NAME__PRW        "_PRW"
 #define METHOD_NAME__SRS        "_SRS"
 #define METHOD_NAME__CBA        "_CBA"
+#define METHOD_NAME__PLD        "_PLD"
 
 /* Method names - these methods must appear at the namespace root */
 
-#define METHOD_PATHNAME__BFS    "\\_BFS"
-#define METHOD_PATHNAME__GTS    "\\_GTS"
 #define METHOD_PATHNAME__PTS    "\\_PTS"
 #define METHOD_PATHNAME__SST    "\\_SI._SST"
 #define METHOD_PATHNAME__WAK    "\\_WAK"
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index bde976e..0daa0fb 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -54,37 +54,8 @@
 acpi_evaluate_hotplug_ost(acpi_handle handle, u32 source_event,
 			u32 status_code, struct acpi_buffer *status_buf);
 
-struct acpi_pld {
-	unsigned int revision:7; /* 0 */
-	unsigned int ignore_colour:1; /* 7 */
-	unsigned int colour:24; /* 8 */
-	unsigned int width:16; /* 32 */
-	unsigned int height:16; /* 48 */
-	unsigned int user_visible:1; /* 64 */
-	unsigned int dock:1; /* 65 */
-	unsigned int lid:1; /* 66 */
-	unsigned int panel:3; /* 67 */
-	unsigned int vertical_pos:2; /* 70 */
-	unsigned int horizontal_pos:2; /* 72 */
-	unsigned int shape:4; /* 74 */
-	unsigned int group_orientation:1; /* 78 */
-	unsigned int group_token:8; /* 79 */
-	unsigned int group_position:8; /* 87 */
-	unsigned int bay:1; /* 95 */
-	unsigned int ejectable:1; /* 96 */
-	unsigned int ospm_eject_required:1; /* 97 */
-	unsigned int cabinet_number:8; /* 98 */
-	unsigned int card_cage_number:8; /* 106 */
-	unsigned int reference:1; /* 114 */
-	unsigned int rotation:4; /* 115 */
-	unsigned int order:5; /* 119 */
-	unsigned int reserved:4; /* 124 */
-	unsigned int vertical_offset:16; /* 128 */
-	unsigned int horizontal_offset:16; /* 144 */
-} __attribute__((__packed__));
-
 acpi_status
-acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld *pld);
+acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld);
 #ifdef CONFIG_ACPI
 
 #include <linux/proc_fs.h>
@@ -208,6 +179,7 @@
 	struct list_head ids;		/* _HID and _CIDs */
 	acpi_device_name device_name;	/* Driver-determined */
 	acpi_device_class device_class;	/*        "          */
+	union acpi_object *str_obj;	/* unicode string for _STR method */
 };
 
 #define acpi_device_bid(d)	((d)->pnp.bus_id)
@@ -282,8 +254,16 @@
 	int prepare_count;
 };
 
-/* Device */
+struct acpi_device_physical_node {
+	u8 node_id;
+	struct list_head node;
+	struct device *dev;
+};
 
+/* set maximum of physical nodes to 32 for expansibility */
+#define ACPI_MAX_PHYSICAL_NODE	32
+
+/* Device */
 struct acpi_device {
 	int device_type;
 	acpi_handle handle;		/* no handle for fixed hardware */
@@ -304,6 +284,10 @@
 	struct device dev;
 	struct acpi_bus_ops bus_ops;	/* workaround for different code path for hotplug */
 	enum acpi_bus_removal_type removal_type;	/* indicate for different removal type */
+	u8 physical_node_count;
+	struct list_head physical_node_list;
+	struct mutex physical_node_lock;
+	DECLARE_BITMAP(physical_node_id_bitmap, ACPI_MAX_PHYSICAL_NODE);
 };
 
 static inline void *acpi_driver_data(struct acpi_device *d)
@@ -381,6 +365,19 @@
 int acpi_create_dir(struct acpi_device *);
 void acpi_remove_dir(struct acpi_device *);
 
+
+/**
+ * module_acpi_driver(acpi_driver) - Helper macro for registering an ACPI driver
+ * @__acpi_driver: acpi_driver struct
+ *
+ * Helper macro for ACPI drivers which do not do anything special in module
+ * init/exit. This eliminates a lot of boilerplate. Each module may only
+ * use this macro once, and calling it replaces module_init() and module_exit()
+ */
+#define module_acpi_driver(__acpi_driver) \
+	module_driver(__acpi_driver, acpi_bus_register_driver, \
+		      acpi_bus_unregister_driver)
+
 /*
  * Bind physical devices with ACPI devices
  */
@@ -394,7 +391,6 @@
 };
 int register_acpi_bus_type(struct acpi_bus_type *);
 int unregister_acpi_bus_type(struct acpi_bus_type *);
-struct device *acpi_get_physical_device(acpi_handle);
 
 struct acpi_pci_root {
 	struct list_head node;
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 51405d3..8b891db 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -47,11 +47,12 @@
 
 /* Current ACPICA subsystem version in YYYYMMDD format */
 
-#define ACPI_CA_VERSION                 0x20120711
+#define ACPI_CA_VERSION                 0x20120913
 
 #include <acpi/acconfig.h>
 #include <acpi/actypes.h>
 #include <acpi/actbl.h>
+#include <acpi/acbuffer.h>
 
 extern u8 acpi_gbl_permanent_mmap;
 
@@ -144,6 +145,10 @@
 			 acpi_physical_address address,
 			 acpi_size length, u8 warn);
 
+acpi_status
+acpi_decode_pld_buffer(u8 *in_buffer,
+		       acpi_size length, struct acpi_pld_info **return_buffer);
+
 /*
  * ACPI Memory management
  */
diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h
index 59a73e1..4f94b1d 100644
--- a/include/acpi/actbl.h
+++ b/include/acpi/actbl.h
@@ -79,9 +79,15 @@
 #pragma pack(1)
 
 /*
- * Note about bitfields: The u8 type is used for bitfields in ACPI tables.
- * This is the only type that is even remotely portable. Anything else is not
- * portable, so do not use any other bitfield types.
+ * Note: C bitfields are not used for this reason:
+ *
+ * "Bitfields are great and easy to read, but unfortunately the C language
+ * does not specify the layout of bitfields in memory, which means they are
+ * essentially useless for dealing with packed data in on-disk formats or
+ * binary wire protocols." (Or ACPI tables and buffers.) "If you ask me,
+ * this decision was a design error in C. Ritchie could have picked an order
+ * and stuck with it." Norman Ramsey.
+ * See http://stackoverflow.com/a/1053662/41661
  */
 
 /*******************************************************************************
@@ -94,7 +100,7 @@
 struct acpi_table_header {
 	char signature[ACPI_NAME_SIZE];	/* ASCII table signature */
 	u32 length;		/* Length of table in bytes, including this header */
-	u8 revision;		/* ACPI Specification minor version # */
+	u8 revision;		/* ACPI Specification minor version number */
 	u8 checksum;		/* To make sum of entire table == 0 */
 	char oem_id[ACPI_OEM_ID_SIZE];	/* ASCII OEM identification */
 	char oem_table_id[ACPI_OEM_TABLE_ID_SIZE];	/* ASCII OEM table identification */
@@ -108,7 +114,7 @@
  * GAS - Generic Address Structure (ACPI 2.0+)
  *
  * Note: Since this structure is used in the ACPI tables, it is byte aligned.
- * If misaliged access is not supported by the hardware, accesses to the
+ * If misaligned access is not supported by the hardware, accesses to the
  * 64-bit Address field must be performed with care.
  *
  ******************************************************************************/
@@ -210,18 +216,18 @@
 	u8 preferred_profile;	/* Conveys preferred power management profile to OSPM. */
 	u16 sci_interrupt;	/* System vector of SCI interrupt */
 	u32 smi_command;	/* 32-bit Port address of SMI command port */
-	u8 acpi_enable;		/* Value to write to smi_cmd to enable ACPI */
-	u8 acpi_disable;	/* Value to write to smi_cmd to disable ACPI */
-	u8 s4_bios_request;	/* Value to write to SMI CMD to enter S4BIOS state */
+	u8 acpi_enable;		/* Value to write to SMI_CMD to enable ACPI */
+	u8 acpi_disable;	/* Value to write to SMI_CMD to disable ACPI */
+	u8 s4_bios_request;	/* Value to write to SMI_CMD to enter S4BIOS state */
 	u8 pstate_control;	/* Processor performance state control */
-	u32 pm1a_event_block;	/* 32-bit Port address of Power Mgt 1a Event Reg Blk */
-	u32 pm1b_event_block;	/* 32-bit Port address of Power Mgt 1b Event Reg Blk */
-	u32 pm1a_control_block;	/* 32-bit Port address of Power Mgt 1a Control Reg Blk */
-	u32 pm1b_control_block;	/* 32-bit Port address of Power Mgt 1b Control Reg Blk */
-	u32 pm2_control_block;	/* 32-bit Port address of Power Mgt 2 Control Reg Blk */
-	u32 pm_timer_block;	/* 32-bit Port address of Power Mgt Timer Ctrl Reg Blk */
-	u32 gpe0_block;		/* 32-bit Port address of General Purpose Event 0 Reg Blk */
-	u32 gpe1_block;		/* 32-bit Port address of General Purpose Event 1 Reg Blk */
+	u32 pm1a_event_block;	/* 32-bit port address of Power Mgt 1a Event Reg Blk */
+	u32 pm1b_event_block;	/* 32-bit port address of Power Mgt 1b Event Reg Blk */
+	u32 pm1a_control_block;	/* 32-bit port address of Power Mgt 1a Control Reg Blk */
+	u32 pm1b_control_block;	/* 32-bit port address of Power Mgt 1b Control Reg Blk */
+	u32 pm2_control_block;	/* 32-bit port address of Power Mgt 2 Control Reg Blk */
+	u32 pm_timer_block;	/* 32-bit port address of Power Mgt Timer Ctrl Reg Blk */
+	u32 gpe0_block;		/* 32-bit port address of General Purpose Event 0 Reg Blk */
+	u32 gpe1_block;		/* 32-bit port address of General Purpose Event 1 Reg Blk */
 	u8 pm1_event_length;	/* Byte Length of ports at pm1x_event_block */
 	u8 pm1_control_length;	/* Byte Length of ports at pm1x_control_block */
 	u8 pm2_control_length;	/* Byte Length of ports at pm2_control_block */
@@ -229,12 +235,12 @@
 	u8 gpe0_block_length;	/* Byte Length of ports at gpe0_block */
 	u8 gpe1_block_length;	/* Byte Length of ports at gpe1_block */
 	u8 gpe1_base;		/* Offset in GPE number space where GPE1 events start */
-	u8 cst_control;		/* Support for the _CST object and C States change notification */
+	u8 cst_control;		/* Support for the _CST object and C-States change notification */
 	u16 c2_latency;		/* Worst case HW latency to enter/exit C2 state */
 	u16 c3_latency;		/* Worst case HW latency to enter/exit C3 state */
-	u16 flush_size;		/* Processor's memory cache line width, in bytes */
+	u16 flush_size;		/* Processor memory cache line width, in bytes */
 	u16 flush_stride;	/* Number of flush strides that need to be read */
-	u8 duty_offset;		/* Processor duty cycle index in processor's P_CNT reg */
+	u8 duty_offset;		/* Processor duty cycle index in processor P_CNT reg */
 	u8 duty_width;		/* Processor duty cycle value bit width in P_CNT register */
 	u8 day_alarm;		/* Index to day-of-month alarm in RTC CMOS RAM */
 	u8 month_alarm;		/* Index to month-of-year alarm in RTC CMOS RAM */
@@ -255,11 +261,11 @@
 	struct acpi_generic_address xpm_timer_block;	/* 64-bit Extended Power Mgt Timer Ctrl Reg Blk address */
 	struct acpi_generic_address xgpe0_block;	/* 64-bit Extended General Purpose Event 0 Reg Blk address */
 	struct acpi_generic_address xgpe1_block;	/* 64-bit Extended General Purpose Event 1 Reg Blk address */
-	struct acpi_generic_address sleep_control;	/* 64-bit Sleep Control register */
-	struct acpi_generic_address sleep_status;	/* 64-bit Sleep Status register */
+	struct acpi_generic_address sleep_control;	/* 64-bit Sleep Control register (ACPI 5.0) */
+	struct acpi_generic_address sleep_status;	/* 64-bit Sleep Status register (ACPI 5.0) */
 };
 
-/* Masks for FADT Boot Architecture Flags (boot_flags) */
+/* Masks for FADT Boot Architecture Flags (boot_flags) [Vx]=Introduced in this FADT revision */
 
 #define ACPI_FADT_LEGACY_DEVICES    (1)  	/* 00: [V2] System has LPC or ISA bus devices */
 #define ACPI_FADT_8042              (1<<1)	/* 01: [V3] System has an 8042 controller on port 60/64 */
@@ -272,13 +278,13 @@
 
 /* Masks for FADT flags */
 
-#define ACPI_FADT_WBINVD            (1)	/* 00: [V1] The wbinvd instruction works properly */
-#define ACPI_FADT_WBINVD_FLUSH      (1<<1)	/* 01: [V1] wbinvd flushes but does not invalidate caches */
+#define ACPI_FADT_WBINVD            (1)	/* 00: [V1] The WBINVD instruction works properly */
+#define ACPI_FADT_WBINVD_FLUSH      (1<<1)	/* 01: [V1] WBINVD flushes but does not invalidate caches */
 #define ACPI_FADT_C1_SUPPORTED      (1<<2)	/* 02: [V1] All processors support C1 state */
 #define ACPI_FADT_C2_MP_SUPPORTED   (1<<3)	/* 03: [V1] C2 state works on MP system */
 #define ACPI_FADT_POWER_BUTTON      (1<<4)	/* 04: [V1] Power button is handled as a control method device */
 #define ACPI_FADT_SLEEP_BUTTON      (1<<5)	/* 05: [V1] Sleep button is handled as a control method device */
-#define ACPI_FADT_FIXED_RTC         (1<<6)	/* 06: [V1] RTC wakeup status not in fixed register space */
+#define ACPI_FADT_FIXED_RTC         (1<<6)	/* 06: [V1] RTC wakeup status is not in fixed register space */
 #define ACPI_FADT_S4_RTC_WAKE       (1<<7)	/* 07: [V1] RTC alarm can wake system from S4 */
 #define ACPI_FADT_32BIT_TIMER       (1<<8)	/* 08: [V1] ACPI timer width is 32-bit (0=24-bit) */
 #define ACPI_FADT_DOCKING_SUPPORTED (1<<9)	/* 09: [V1] Docking supported */
@@ -297,7 +303,7 @@
 
 /* Values for preferred_profile (Preferred Power Management Profiles) */
 
-enum acpi_prefered_pm_profiles {
+enum acpi_preferred_pm_profiles {
 	PM_UNSPECIFIED = 0,
 	PM_DESKTOP = 1,
 	PM_MOBILE = 2,
@@ -335,7 +341,7 @@
 struct acpi_table_desc {
 	acpi_physical_address address;
 	struct acpi_table_header *pointer;
-	u32 length;		/* Length fixed at 32 bits */
+	u32 length;		/* Length fixed at 32 bits (fixed in table header) */
 	union acpi_name_union signature;
 	acpi_owner_id owner_id;
 	u8 flags;
diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h
index 300d14e..280fc45 100644
--- a/include/acpi/actbl1.h
+++ b/include/acpi/actbl1.h
@@ -79,9 +79,15 @@
 #pragma pack(1)
 
 /*
- * Note about bitfields: The u8 type is used for bitfields in ACPI tables.
- * This is the only type that is even remotely portable. Anything else is not
- * portable, so do not use any other bitfield types.
+ * Note: C bitfields are not used for this reason:
+ *
+ * "Bitfields are great and easy to read, but unfortunately the C language
+ * does not specify the layout of bitfields in memory, which means they are
+ * essentially useless for dealing with packed data in on-disk formats or
+ * binary wire protocols." (Or ACPI tables and buffers.) "If you ask me,
+ * this decision was a design error in C. Ritchie could have picked an order
+ * and stuck with it." Norman Ramsey.
+ * See http://stackoverflow.com/a/1053662/41661
  */
 
 /*******************************************************************************
@@ -489,7 +495,9 @@
 	ACPI_HEST_NOTIFY_LOCAL = 2,
 	ACPI_HEST_NOTIFY_SCI = 3,
 	ACPI_HEST_NOTIFY_NMI = 4,
-	ACPI_HEST_NOTIFY_RESERVED = 5	/* 5 and greater are reserved */
+	ACPI_HEST_NOTIFY_CMCI = 5,	/* ACPI 5.0 */
+	ACPI_HEST_NOTIFY_MCE = 6,	/* ACPI 5.0 */
+	ACPI_HEST_NOTIFY_RESERVED = 7	/* 7 and greater are reserved */
 };
 
 /* Values for config_write_enable bitfield above */
diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h
index d9ceb3d..1b2b356 100644
--- a/include/acpi/actbl2.h
+++ b/include/acpi/actbl2.h
@@ -63,6 +63,8 @@
  */
 #define ACPI_SIG_ASF            "ASF!"	/* Alert Standard Format table */
 #define ACPI_SIG_BOOT           "BOOT"	/* Simple Boot Flag Table */
+#define ACPI_SIG_CSRT           "CSRT"	/* Core System Resource Table */
+#define ACPI_SIG_DBG2           "DBG2"	/* Debug Port table type 2 */
 #define ACPI_SIG_DBGP           "DBGP"	/* Debug Port table */
 #define ACPI_SIG_DMAR           "DMAR"	/* DMA Remapping table */
 #define ACPI_SIG_HPET           "HPET"	/* High Precision Event Timer table */
@@ -96,9 +98,15 @@
 #pragma pack(1)
 
 /*
- * Note about bitfields: The u8 type is used for bitfields in ACPI tables.
- * This is the only type that is even remotely portable. Anything else is not
- * portable, so do not use any other bitfield types.
+ * Note: C bitfields are not used for this reason:
+ *
+ * "Bitfields are great and easy to read, but unfortunately the C language
+ * does not specify the layout of bitfields in memory, which means they are
+ * essentially useless for dealing with packed data in on-disk formats or
+ * binary wire protocols." (Or ACPI tables and buffers.) "If you ask me,
+ * this decision was a design error in C. Ritchie could have picked an order
+ * and stuck with it." Norman Ramsey.
+ * See http://stackoverflow.com/a/1053662/41661
  */
 
 /*******************************************************************************
@@ -232,6 +240,115 @@
 
 /*******************************************************************************
  *
+ * CSRT - Core System Resource Table
+ *        Version 0
+ *
+ * Conforms to the "Core System Resource Table (CSRT)", November 14, 2011
+ *
+ ******************************************************************************/
+
+struct acpi_table_csrt {
+	struct acpi_table_header header;	/* Common ACPI table header */
+};
+
+/* Resource Group subtable */
+
+struct acpi_csrt_group {
+	u32 length;
+	u32 vendor_id;
+	u32 subvendor_id;
+	u16 device_id;
+	u16 subdevice_id;
+	u16 revision;
+	u16 reserved;
+	u32 info_length;
+
+	/* Shared data (length = info_length) immediately follows */
+};
+
+/* Resource Descriptor subtable */
+
+struct acpi_csrt_descriptor {
+	u32 length;
+	u16 type;
+	u16 subtype;
+	u32 uid;
+
+	/* Resource-specific information immediately follows */
+};
+
+/* Resource Types */
+
+#define ACPI_CSRT_TYPE_INTERRUPT    0x0001
+#define ACPI_CSRT_TYPE_TIMER        0x0002
+#define ACPI_CSRT_TYPE_DMA          0x0003
+
+/* Resource Subtypes */
+
+#define ACPI_CSRT_XRUPT_LINE        0x0000
+#define ACPI_CSRT_XRUPT_CONTROLLER  0x0001
+#define ACPI_CSRT_TIMER             0x0000
+#define ACPI_CSRT_DMA_CHANNEL       0x0000
+#define ACPI_CSRT_DMA_CONTROLLER    0x0001
+
+/*******************************************************************************
+ *
+ * DBG2 - Debug Port Table 2
+ *        Version 0 (Both main table and subtables)
+ *
+ * Conforms to "Microsoft Debug Port Table 2 (DBG2)", May 22 2012.
+ *
+ ******************************************************************************/
+
+struct acpi_table_dbg2 {
+	struct acpi_table_header header;	/* Common ACPI table header */
+	u32 info_offset;
+	u32 info_count;
+};
+
+/* Debug Device Information Subtable */
+
+struct acpi_dbg2_device {
+	u8 revision;
+	u16 length;
+	u8 register_count;	/* Number of base_address registers */
+	u16 namepath_length;
+	u16 namepath_offset;
+	u16 oem_data_length;
+	u16 oem_data_offset;
+	u16 port_type;
+	u16 port_subtype;
+	u16 reserved;
+	u16 base_address_offset;
+	u16 address_size_offset;
+	/*
+	 * Data that follows:
+	 *    base_address (required) - Each in 12-byte Generic Address Structure format.
+	 *    address_size (required) - Array of u32 sizes corresponding to each base_address register.
+	 *    Namepath    (required) - Null terminated string. Single dot if not supported.
+	 *    oem_data    (optional) - Length is oem_data_length.
+	 */
+};
+
+/* Types for port_type field above */
+
+#define ACPI_DBG2_SERIAL_PORT       0x8000
+#define ACPI_DBG2_1394_PORT         0x8001
+#define ACPI_DBG2_USB_PORT          0x8002
+#define ACPI_DBG2_NET_PORT          0x8003
+
+/* Subtypes for port_subtype field above */
+
+#define ACPI_DBG2_16550_COMPATIBLE  0x0000
+#define ACPI_DBG2_16550_SUBSET      0x0001
+
+#define ACPI_DBG2_1394_STANDARD     0x0000
+
+#define ACPI_DBG2_USB_XHCI          0x0000
+#define ACPI_DBG2_USB_EHCI          0x0001
+
+/*******************************************************************************
+ *
  * DBGP - Debug Port table
  *        Version 1
  *
diff --git a/include/acpi/actbl3.h b/include/acpi/actbl3.h
index f65a0ed..8c61b5f 100644
--- a/include/acpi/actbl3.h
+++ b/include/acpi/actbl3.h
@@ -75,7 +75,6 @@
 /* Reserved table signatures */
 
 #define ACPI_SIG_CSRT           "CSRT"	/* Core System Resources Table */
-#define ACPI_SIG_DBG2           "DBG2"	/* Debug Port table 2 */
 #define ACPI_SIG_MATR           "MATR"	/* Memory Address Translation Table */
 #define ACPI_SIG_MSDM           "MSDM"	/* Microsoft Data Management Table */
 #define ACPI_SIG_WPBT           "WPBT"	/* Windows Platform Binary Table */
@@ -87,9 +86,15 @@
 #pragma pack(1)
 
 /*
- * Note about bitfields: The u8 type is used for bitfields in ACPI tables.
- * This is the only type that is even remotely portable. Anything else is not
- * portable, so do not use any other bitfield types.
+ * Note: C bitfields are not used for this reason:
+ *
+ * "Bitfields are great and easy to read, but unfortunately the C language
+ * does not specify the layout of bitfields in memory, which means they are
+ * essentially useless for dealing with packed data in on-disk formats or
+ * binary wire protocols." (Or ACPI tables and buffers.) "If you ask me,
+ * this decision was a design error in C. Ritchie could have picked an order
+ * and stuck with it." Norman Ramsey.
+ * See http://stackoverflow.com/a/1053662/41661
  */
 
 /*******************************************************************************
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h
index 3d00bd5..a85bae9 100644
--- a/include/acpi/actypes.h
+++ b/include/acpi/actypes.h
@@ -519,13 +519,6 @@
 #define ACPI_SLEEP_TYPE_INVALID         0xFF
 
 /*
- * Sleep/Wake flags
- */
-#define ACPI_NO_OPTIONAL_METHODS        0x00	/* Do not execute any optional methods */
-#define ACPI_EXECUTE_GTS                0x01	/* For enter sleep interface */
-#define ACPI_EXECUTE_BFS                0x02	/* For leave sleep prep interface */
-
-/*
  * Standard notify values
  */
 #define ACPI_NOTIFY_BUS_CHECK           (u8) 0x00
diff --git a/include/asm-generic/Kbuild b/include/asm-generic/Kbuild
index 2c85a0f..e69de29 100644
--- a/include/asm-generic/Kbuild
+++ b/include/asm-generic/Kbuild
@@ -1,35 +0,0 @@
-header-y += auxvec.h
-header-y += bitsperlong.h
-header-y += errno-base.h
-header-y += errno.h
-header-y += fcntl.h
-header-y += int-l64.h
-header-y += int-ll64.h
-header-y += ioctl.h
-header-y += ioctls.h
-header-y += ipcbuf.h
-header-y += kvm_para.h
-header-y += mman-common.h
-header-y += mman.h
-header-y += msgbuf.h
-header-y += param.h
-header-y += poll.h
-header-y += posix_types.h
-header-y += resource.h
-header-y += sembuf.h
-header-y += setup.h
-header-y += shmbuf.h
-header-y += shmparam.h
-header-y += siginfo.h
-header-y += signal-defs.h
-header-y += signal.h
-header-y += socket.h
-header-y += sockios.h
-header-y += stat.h
-header-y += statfs.h
-header-y += swab.h
-header-y += termbits.h
-header-y += termios.h
-header-y += types.h
-header-y += ucontext.h
-header-y += unistd.h
diff --git a/include/asm-generic/bitsperlong.h b/include/asm-generic/bitsperlong.h
index a7b0914..d1d70aa1 100644
--- a/include/asm-generic/bitsperlong.h
+++ b/include/asm-generic/bitsperlong.h
@@ -1,18 +1,8 @@
 #ifndef __ASM_GENERIC_BITS_PER_LONG
 #define __ASM_GENERIC_BITS_PER_LONG
 
-/*
- * There seems to be no way of detecting this automatically from user
- * space, so 64 bit architectures should override this in their
- * bitsperlong.h. In particular, an architecture that supports
- * both 32 and 64 bit user space must not rely on CONFIG_64BIT
- * to decide it, but rather check a compiler provided macro.
- */
-#ifndef __BITS_PER_LONG
-#define __BITS_PER_LONG 32
-#endif
+#include <uapi/asm-generic/bitsperlong.h>
 
-#ifdef __KERNEL__
 
 #ifdef CONFIG_64BIT
 #define BITS_PER_LONG 64
@@ -32,5 +22,4 @@
 #define BITS_PER_LONG_LONG 64
 #endif
 
-#endif /* __KERNEL__ */
 #endif /* __ASM_GENERIC_BITS_PER_LONG */
diff --git a/include/asm-generic/clkdev.h b/include/asm-generic/clkdev.h
new file mode 100644
index 0000000..90a32a6
--- /dev/null
+++ b/include/asm-generic/clkdev.h
@@ -0,0 +1,28 @@
+/*
+ *  include/asm-generic/clkdev.h
+ *
+ * Based on the ARM clkdev.h:
+ *  Copyright (C) 2008 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Helper for the clk API to assist looking up a struct clk.
+ */
+#ifndef __ASM_CLKDEV_H
+#define __ASM_CLKDEV_H
+
+#include <linux/slab.h>
+
+struct clk;
+
+static inline int __clk_get(struct clk *clk) { return 1; }
+static inline void __clk_put(struct clk *clk) { }
+
+static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size)
+{
+	return kzalloc(size, GFP_KERNEL);
+}
+
+#endif
diff --git a/include/asm-generic/int-l64.h b/include/asm-generic/int-l64.h
index 1ca3efc..27d4ec0 100644
--- a/include/asm-generic/int-l64.h
+++ b/include/asm-generic/int-l64.h
@@ -4,33 +4,11 @@
  * Integer declarations for architectures which use "long"
  * for 64-bit types.
  */
-
 #ifndef _ASM_GENERIC_INT_L64_H
 #define _ASM_GENERIC_INT_L64_H
 
-#include <asm/bitsperlong.h>
+#include <uapi/asm-generic/int-l64.h>
 
-#ifndef __ASSEMBLY__
-/*
- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space
- */
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-typedef __signed__ long __s64;
-typedef unsigned long __u64;
-
-#endif /* __ASSEMBLY__ */
-
-#ifdef __KERNEL__
 
 #ifndef __ASSEMBLY__
 
@@ -68,6 +46,4 @@
 
 #endif /* __ASSEMBLY__ */
 
-#endif /* __KERNEL__ */
-
 #endif /* _ASM_GENERIC_INT_L64_H */
diff --git a/include/asm-generic/int-ll64.h b/include/asm-generic/int-ll64.h
index f394147..4cd8485 100644
--- a/include/asm-generic/int-ll64.h
+++ b/include/asm-generic/int-ll64.h
@@ -4,38 +4,11 @@
  * Integer declarations for architectures which use "long long"
  * for 64-bit types.
  */
-
 #ifndef _ASM_GENERIC_INT_LL64_H
 #define _ASM_GENERIC_INT_LL64_H
 
-#include <asm/bitsperlong.h>
+#include <uapi/asm-generic/int-ll64.h>
 
-#ifndef __ASSEMBLY__
-/*
- * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
- * header files exported to user space
- */
-
-typedef __signed__ char __s8;
-typedef unsigned char __u8;
-
-typedef __signed__ short __s16;
-typedef unsigned short __u16;
-
-typedef __signed__ int __s32;
-typedef unsigned int __u32;
-
-#ifdef __GNUC__
-__extension__ typedef __signed__ long long __s64;
-__extension__ typedef unsigned long long __u64;
-#else
-typedef __signed__ long long __s64;
-typedef unsigned long long __u64;
-#endif
-
-#endif /* __ASSEMBLY__ */
-
-#ifdef __KERNEL__
 
 #ifndef __ASSEMBLY__
 
@@ -73,6 +46,4 @@
 
 #endif /* __ASSEMBLY__ */
 
-#endif /* __KERNEL__ */
-
 #endif /* _ASM_GENERIC_INT_LL64_H */
diff --git a/include/asm-generic/ioctl.h b/include/asm-generic/ioctl.h
index 15828b2..d17295b 100644
--- a/include/asm-generic/ioctl.h
+++ b/include/asm-generic/ioctl.h
@@ -1,105 +1,12 @@
 #ifndef _ASM_GENERIC_IOCTL_H
 #define _ASM_GENERIC_IOCTL_H
 
-/* ioctl command encoding: 32 bits total, command in lower 16 bits,
- * size of the parameter structure in the lower 14 bits of the
- * upper 16 bits.
- * Encoding the size of the parameter structure in the ioctl request
- * is useful for catching programs compiled with old versions
- * and to avoid overwriting user space outside the user buffer area.
- * The highest 2 bits are reserved for indicating the ``access mode''.
- * NOTE: This limits the max parameter size to 16kB -1 !
- */
+#include <uapi/asm-generic/ioctl.h>
 
-/*
- * The following is for compatibility across the various Linux
- * platforms.  The generic ioctl numbering scheme doesn't really enforce
- * a type field.  De facto, however, the top 8 bits of the lower 16
- * bits are indeed used as a type field, so we might just as well make
- * this explicit here.  Please be sure to use the decoding macros
- * below from now on.
- */
-#define _IOC_NRBITS	8
-#define _IOC_TYPEBITS	8
-
-/*
- * Let any architecture override either of the following before
- * including this file.
- */
-
-#ifndef _IOC_SIZEBITS
-# define _IOC_SIZEBITS	14
-#endif
-
-#ifndef _IOC_DIRBITS
-# define _IOC_DIRBITS	2
-#endif
-
-#define _IOC_NRMASK	((1 << _IOC_NRBITS)-1)
-#define _IOC_TYPEMASK	((1 << _IOC_TYPEBITS)-1)
-#define _IOC_SIZEMASK	((1 << _IOC_SIZEBITS)-1)
-#define _IOC_DIRMASK	((1 << _IOC_DIRBITS)-1)
-
-#define _IOC_NRSHIFT	0
-#define _IOC_TYPESHIFT	(_IOC_NRSHIFT+_IOC_NRBITS)
-#define _IOC_SIZESHIFT	(_IOC_TYPESHIFT+_IOC_TYPEBITS)
-#define _IOC_DIRSHIFT	(_IOC_SIZESHIFT+_IOC_SIZEBITS)
-
-/*
- * Direction bits, which any architecture can choose to override
- * before including this file.
- */
-
-#ifndef _IOC_NONE
-# define _IOC_NONE	0U
-#endif
-
-#ifndef _IOC_WRITE
-# define _IOC_WRITE	1U
-#endif
-
-#ifndef _IOC_READ
-# define _IOC_READ	2U
-#endif
-
-#define _IOC(dir,type,nr,size) \
-	(((dir)  << _IOC_DIRSHIFT) | \
-	 ((type) << _IOC_TYPESHIFT) | \
-	 ((nr)   << _IOC_NRSHIFT) | \
-	 ((size) << _IOC_SIZESHIFT))
-
-#ifdef __KERNEL__
 /* provoke compile error for invalid uses of size argument */
 extern unsigned int __invalid_size_argument_for_IOC;
 #define _IOC_TYPECHECK(t) \
 	((sizeof(t) == sizeof(t[1]) && \
 	  sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
 	  sizeof(t) : __invalid_size_argument_for_IOC)
-#else
-#define _IOC_TYPECHECK(t) (sizeof(t))
-#endif
-
-/* used to create numbers */
-#define _IO(type,nr)		_IOC(_IOC_NONE,(type),(nr),0)
-#define _IOR(type,nr,size)	_IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
-#define _IOW(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
-#define _IOWR(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
-#define _IOR_BAD(type,nr,size)	_IOC(_IOC_READ,(type),(nr),sizeof(size))
-#define _IOW_BAD(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),sizeof(size))
-#define _IOWR_BAD(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
-
-/* used to decode ioctl numbers.. */
-#define _IOC_DIR(nr)		(((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
-#define _IOC_TYPE(nr)		(((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
-#define _IOC_NR(nr)		(((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
-#define _IOC_SIZE(nr)		(((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
-
-/* ...and for the drivers/sound files... */
-
-#define IOC_IN		(_IOC_WRITE << _IOC_DIRSHIFT)
-#define IOC_OUT		(_IOC_READ << _IOC_DIRSHIFT)
-#define IOC_INOUT	((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
-#define IOCSIZE_MASK	(_IOC_SIZEMASK << _IOC_SIZESHIFT)
-#define IOCSIZE_SHIFT	(_IOC_SIZESHIFT)
-
 #endif /* _ASM_GENERIC_IOCTL_H */
diff --git a/include/asm-generic/kvm_para.h b/include/asm-generic/kvm_para.h
index 5cba37f..9d96605 100644
--- a/include/asm-generic/kvm_para.h
+++ b/include/asm-generic/kvm_para.h
@@ -1,7 +1,8 @@
 #ifndef _ASM_GENERIC_KVM_PARA_H
 #define _ASM_GENERIC_KVM_PARA_H
 
-#ifdef __KERNEL__
+#include <uapi/asm-generic/kvm_para.h>
+
 
 /*
  * This function is used by architectures that support kvm to avoid issuing
@@ -17,6 +18,4 @@
 	return 0;
 }
 
-#endif	/* _KERNEL__ */
-
 #endif
diff --git a/include/asm-generic/param.h b/include/asm-generic/param.h
index 835632a..04e715b 100644
--- a/include/asm-generic/param.h
+++ b/include/asm-generic/param.h
@@ -1,25 +1,10 @@
 #ifndef __ASM_GENERIC_PARAM_H
 #define __ASM_GENERIC_PARAM_H
 
-#ifndef HZ
-#define HZ 100
-#endif
+#include <uapi/asm-generic/param.h>
 
-#ifndef EXEC_PAGESIZE
-#define EXEC_PAGESIZE	4096
-#endif
-
-#ifndef NOGROUP
-#define NOGROUP		(-1)
-#endif
-
-#define MAXHOSTNAMELEN	64	/* max length of hostname */
-
-#ifdef __KERNEL__
 # undef HZ
 # define HZ		CONFIG_HZ	/* Internal kernel timer frequency */
 # define USER_HZ	100		/* some user interfaces are */
 # define CLOCKS_PER_SEC	(USER_HZ)       /* in "ticks" like times() */
-#endif
-
 #endif /* __ASM_GENERIC_PARAM_H */
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index ff4947b..b36ce40 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -87,7 +87,7 @@
 				       pmd_t *pmdp)
 {
 	pmd_t pmd = *pmdp;
-	pmd_clear(mm, address, pmdp);
+	pmd_clear(pmdp);
 	return pmd;
 }
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
@@ -162,6 +162,19 @@
 				 unsigned long address, pmd_t *pmdp);
 #endif
 
+#ifndef __HAVE_ARCH_PGTABLE_DEPOSIT
+extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable);
+#endif
+
+#ifndef __HAVE_ARCH_PGTABLE_WITHDRAW
+extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm);
+#endif
+
+#ifndef __HAVE_ARCH_PMDP_INVALIDATE
+extern void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
+			    pmd_t *pmdp);
+#endif
+
 #ifndef __HAVE_ARCH_PTE_SAME
 static inline int pte_same(pte_t pte_a, pte_t pte_b)
 {
@@ -381,48 +394,59 @@
 
 #ifndef __HAVE_PFNMAP_TRACKING
 /*
- * Interface that can be used by architecture code to keep track of
- * memory type of pfn mappings (remap_pfn_range, vm_insert_pfn)
- *
- * track_pfn_vma_new is called when a _new_ pfn mapping is being established
- * for physical range indicated by pfn and size.
+ * Interfaces that can be used by architecture code to keep track of
+ * memory type of pfn mappings specified by the remap_pfn_range,
+ * vm_insert_pfn.
  */
-static inline int track_pfn_vma_new(struct vm_area_struct *vma, pgprot_t *prot,
-					unsigned long pfn, unsigned long size)
+
+/*
+ * track_pfn_remap is called when a _new_ pfn mapping is being established
+ * by remap_pfn_range() for physical range indicated by pfn and size.
+ */
+static inline int track_pfn_remap(struct vm_area_struct *vma, pgprot_t *prot,
+				  unsigned long pfn, unsigned long addr,
+				  unsigned long size)
 {
 	return 0;
 }
 
 /*
- * Interface that can be used by architecture code to keep track of
- * memory type of pfn mappings (remap_pfn_range, vm_insert_pfn)
- *
- * track_pfn_vma_copy is called when vma that is covering the pfnmap gets
+ * track_pfn_insert is called when a _new_ single pfn is established
+ * by vm_insert_pfn().
+ */
+static inline int track_pfn_insert(struct vm_area_struct *vma, pgprot_t *prot,
+				   unsigned long pfn)
+{
+	return 0;
+}
+
+/*
+ * track_pfn_copy is called when vma that is covering the pfnmap gets
  * copied through copy_page_range().
  */
-static inline int track_pfn_vma_copy(struct vm_area_struct *vma)
+static inline int track_pfn_copy(struct vm_area_struct *vma)
 {
 	return 0;
 }
 
 /*
- * Interface that can be used by architecture code to keep track of
- * memory type of pfn mappings (remap_pfn_range, vm_insert_pfn)
- *
  * untrack_pfn_vma is called while unmapping a pfnmap for a region.
  * untrack can be called for a specific region indicated by pfn and size or
- * can be for the entire vma (in which case size can be zero).
+ * can be for the entire vma (in which case pfn, size are zero).
  */
-static inline void untrack_pfn_vma(struct vm_area_struct *vma,
-					unsigned long pfn, unsigned long size)
+static inline void untrack_pfn(struct vm_area_struct *vma,
+			       unsigned long pfn, unsigned long size)
 {
 }
 #else
-extern int track_pfn_vma_new(struct vm_area_struct *vma, pgprot_t *prot,
-				unsigned long pfn, unsigned long size);
-extern int track_pfn_vma_copy(struct vm_area_struct *vma);
-extern void untrack_pfn_vma(struct vm_area_struct *vma, unsigned long pfn,
-				unsigned long size);
+extern int track_pfn_remap(struct vm_area_struct *vma, pgprot_t *prot,
+			   unsigned long pfn, unsigned long addr,
+			   unsigned long size);
+extern int track_pfn_insert(struct vm_area_struct *vma, pgprot_t *prot,
+			    unsigned long pfn);
+extern int track_pfn_copy(struct vm_area_struct *vma);
+extern void untrack_pfn(struct vm_area_struct *vma, unsigned long pfn,
+			unsigned long size);
 #endif
 
 #ifdef CONFIG_MMU
diff --git a/include/asm-generic/resource.h b/include/asm-generic/resource.h
index 61fa862..b4ea8f5 100644
--- a/include/asm-generic/resource.h
+++ b/include/asm-generic/resource.h
@@ -1,70 +1,8 @@
 #ifndef _ASM_GENERIC_RESOURCE_H
 #define _ASM_GENERIC_RESOURCE_H
 
-/*
- * Resource limit IDs
- *
- * ( Compatibility detail: there are architectures that have
- *   a different rlimit ID order in the 5-9 range and want
- *   to keep that order for binary compatibility. The reasons
- *   are historic and all new rlimits are identical across all
- *   arches. If an arch has such special order for some rlimits
- *   then it defines them prior including asm-generic/resource.h. )
- */
+#include <uapi/asm-generic/resource.h>
 
-#define RLIMIT_CPU		0	/* CPU time in sec */
-#define RLIMIT_FSIZE		1	/* Maximum filesize */
-#define RLIMIT_DATA		2	/* max data size */
-#define RLIMIT_STACK		3	/* max stack size */
-#define RLIMIT_CORE		4	/* max core file size */
-
-#ifndef RLIMIT_RSS
-# define RLIMIT_RSS		5	/* max resident set size */
-#endif
-
-#ifndef RLIMIT_NPROC
-# define RLIMIT_NPROC		6	/* max number of processes */
-#endif
-
-#ifndef RLIMIT_NOFILE
-# define RLIMIT_NOFILE		7	/* max number of open files */
-#endif
-
-#ifndef RLIMIT_MEMLOCK
-# define RLIMIT_MEMLOCK		8	/* max locked-in-memory address space */
-#endif
-
-#ifndef RLIMIT_AS
-# define RLIMIT_AS		9	/* address space limit */
-#endif
-
-#define RLIMIT_LOCKS		10	/* maximum file locks held */
-#define RLIMIT_SIGPENDING	11	/* max number of pending signals */
-#define RLIMIT_MSGQUEUE		12	/* maximum bytes in POSIX mqueues */
-#define RLIMIT_NICE		13	/* max nice prio allowed to raise to
-					   0-39 for nice level 19 .. -20 */
-#define RLIMIT_RTPRIO		14	/* maximum realtime priority */
-#define RLIMIT_RTTIME		15	/* timeout for RT tasks in us */
-#define RLIM_NLIMITS		16
-
-/*
- * SuS says limits have to be unsigned.
- * Which makes a ton more sense anyway.
- *
- * Some architectures override this (for compatibility reasons):
- */
-#ifndef RLIM_INFINITY
-# define RLIM_INFINITY		(~0UL)
-#endif
-
-/*
- * RLIMIT_STACK default maximum - some architectures override it:
- */
-#ifndef _STK_LIM_MAX
-# define _STK_LIM_MAX		RLIM_INFINITY
-#endif
-
-#ifdef __KERNEL__
 
 /*
  * boot-time rlimit defaults for the init task:
@@ -89,6 +27,4 @@
 	[RLIMIT_RTTIME]		= {  RLIM_INFINITY,  RLIM_INFINITY },	\
 }
 
-#endif	/* __KERNEL__ */
-
 #endif
diff --git a/include/asm-generic/siginfo.h b/include/asm-generic/siginfo.h
index 8ed6777..b685d3b 100644
--- a/include/asm-generic/siginfo.h
+++ b/include/asm-generic/siginfo.h
@@ -1,145 +1,8 @@
 #ifndef _ASM_GENERIC_SIGINFO_H
 #define _ASM_GENERIC_SIGINFO_H
 
-#include <linux/compiler.h>
-#include <linux/types.h>
+#include <uapi/asm-generic/siginfo.h>
 
-typedef union sigval {
-	int sival_int;
-	void __user *sival_ptr;
-} sigval_t;
-
-/*
- * This is the size (including padding) of the part of the
- * struct siginfo that is before the union.
- */
-#ifndef __ARCH_SI_PREAMBLE_SIZE
-#define __ARCH_SI_PREAMBLE_SIZE	(3 * sizeof(int))
-#endif
-
-#define SI_MAX_SIZE	128
-#ifndef SI_PAD_SIZE
-#define SI_PAD_SIZE	((SI_MAX_SIZE - __ARCH_SI_PREAMBLE_SIZE) / sizeof(int))
-#endif
-
-#ifndef __ARCH_SI_UID_T
-#define __ARCH_SI_UID_T	__kernel_uid32_t
-#endif
-
-/*
- * The default "si_band" type is "long", as specified by POSIX.
- * However, some architectures want to override this to "int"
- * for historical compatibility reasons, so we allow that.
- */
-#ifndef __ARCH_SI_BAND_T
-#define __ARCH_SI_BAND_T long
-#endif
-
-#ifndef __ARCH_SI_CLOCK_T
-#define __ARCH_SI_CLOCK_T __kernel_clock_t
-#endif
-
-#ifndef __ARCH_SI_ATTRIBUTES
-#define __ARCH_SI_ATTRIBUTES
-#endif
-
-#ifndef HAVE_ARCH_SIGINFO_T
-
-typedef struct siginfo {
-	int si_signo;
-	int si_errno;
-	int si_code;
-
-	union {
-		int _pad[SI_PAD_SIZE];
-
-		/* kill() */
-		struct {
-			__kernel_pid_t _pid;	/* sender's pid */
-			__ARCH_SI_UID_T _uid;	/* sender's uid */
-		} _kill;
-
-		/* POSIX.1b timers */
-		struct {
-			__kernel_timer_t _tid;	/* timer id */
-			int _overrun;		/* overrun count */
-			char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)];
-			sigval_t _sigval;	/* same as below */
-			int _sys_private;       /* not to be passed to user */
-		} _timer;
-
-		/* POSIX.1b signals */
-		struct {
-			__kernel_pid_t _pid;	/* sender's pid */
-			__ARCH_SI_UID_T _uid;	/* sender's uid */
-			sigval_t _sigval;
-		} _rt;
-
-		/* SIGCHLD */
-		struct {
-			__kernel_pid_t _pid;	/* which child */
-			__ARCH_SI_UID_T _uid;	/* sender's uid */
-			int _status;		/* exit code */
-			__ARCH_SI_CLOCK_T _utime;
-			__ARCH_SI_CLOCK_T _stime;
-		} _sigchld;
-
-		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
-		struct {
-			void __user *_addr; /* faulting insn/memory ref. */
-#ifdef __ARCH_SI_TRAPNO
-			int _trapno;	/* TRAP # which caused the signal */
-#endif
-			short _addr_lsb; /* LSB of the reported address */
-		} _sigfault;
-
-		/* SIGPOLL */
-		struct {
-			__ARCH_SI_BAND_T _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
-			int _fd;
-		} _sigpoll;
-
-		/* SIGSYS */
-		struct {
-			void __user *_call_addr; /* calling user insn */
-			int _syscall;	/* triggering system call number */
-			unsigned int _arch;	/* AUDIT_ARCH_* of syscall */
-		} _sigsys;
-	} _sifields;
-} __ARCH_SI_ATTRIBUTES siginfo_t;
-
-/* If the arch shares siginfo, then it has SIGSYS. */
-#define __ARCH_SIGSYS
-#endif
-
-/*
- * How these fields are to be accessed.
- */
-#define si_pid		_sifields._kill._pid
-#define si_uid		_sifields._kill._uid
-#define si_tid		_sifields._timer._tid
-#define si_overrun	_sifields._timer._overrun
-#define si_sys_private  _sifields._timer._sys_private
-#define si_status	_sifields._sigchld._status
-#define si_utime	_sifields._sigchld._utime
-#define si_stime	_sifields._sigchld._stime
-#define si_value	_sifields._rt._sigval
-#define si_int		_sifields._rt._sigval.sival_int
-#define si_ptr		_sifields._rt._sigval.sival_ptr
-#define si_addr		_sifields._sigfault._addr
-#ifdef __ARCH_SI_TRAPNO
-#define si_trapno	_sifields._sigfault._trapno
-#endif
-#define si_addr_lsb	_sifields._sigfault._addr_lsb
-#define si_band		_sifields._sigpoll._band
-#define si_fd		_sifields._sigpoll._fd
-#ifdef __ARCH_SIGSYS
-#define si_call_addr	_sifields._sigsys._call_addr
-#define si_syscall	_sifields._sigsys._syscall
-#define si_arch		_sifields._sigsys._arch
-#endif
-
-#ifdef __KERNEL__
 #define __SI_MASK	0xffff0000u
 #define __SI_KILL	(0 << 16)
 #define __SI_TIMER	(1 << 16)
@@ -150,162 +13,6 @@
 #define __SI_MESGQ	(6 << 16)
 #define __SI_SYS	(7 << 16)
 #define __SI_CODE(T,N)	((T) | ((N) & 0xffff))
-#else
-#define __SI_KILL	0
-#define __SI_TIMER	0
-#define __SI_POLL	0
-#define __SI_FAULT	0
-#define __SI_CHLD	0
-#define __SI_RT		0
-#define __SI_MESGQ	0
-#define __SI_SYS	0
-#define __SI_CODE(T,N)	(N)
-#endif
-
-/*
- * si_code values
- * Digital reserves positive values for kernel-generated signals.
- */
-#define SI_USER		0		/* sent by kill, sigsend, raise */
-#define SI_KERNEL	0x80		/* sent by the kernel from somewhere */
-#define SI_QUEUE	-1		/* sent by sigqueue */
-#define SI_TIMER __SI_CODE(__SI_TIMER,-2) /* sent by timer expiration */
-#define SI_MESGQ __SI_CODE(__SI_MESGQ,-3) /* sent by real time mesq state change */
-#define SI_ASYNCIO	-4		/* sent by AIO completion */
-#define SI_SIGIO	-5		/* sent by queued SIGIO */
-#define SI_TKILL	-6		/* sent by tkill system call */
-#define SI_DETHREAD	-7		/* sent by execve() killing subsidiary threads */
-
-#define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
-#define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
-
-/*
- * SIGILL si_codes
- */
-#define ILL_ILLOPC	(__SI_FAULT|1)	/* illegal opcode */
-#define ILL_ILLOPN	(__SI_FAULT|2)	/* illegal operand */
-#define ILL_ILLADR	(__SI_FAULT|3)	/* illegal addressing mode */
-#define ILL_ILLTRP	(__SI_FAULT|4)	/* illegal trap */
-#define ILL_PRVOPC	(__SI_FAULT|5)	/* privileged opcode */
-#define ILL_PRVREG	(__SI_FAULT|6)	/* privileged register */
-#define ILL_COPROC	(__SI_FAULT|7)	/* coprocessor error */
-#define ILL_BADSTK	(__SI_FAULT|8)	/* internal stack error */
-#define NSIGILL		8
-
-/*
- * SIGFPE si_codes
- */
-#define FPE_INTDIV	(__SI_FAULT|1)	/* integer divide by zero */
-#define FPE_INTOVF	(__SI_FAULT|2)	/* integer overflow */
-#define FPE_FLTDIV	(__SI_FAULT|3)	/* floating point divide by zero */
-#define FPE_FLTOVF	(__SI_FAULT|4)	/* floating point overflow */
-#define FPE_FLTUND	(__SI_FAULT|5)	/* floating point underflow */
-#define FPE_FLTRES	(__SI_FAULT|6)	/* floating point inexact result */
-#define FPE_FLTINV	(__SI_FAULT|7)	/* floating point invalid operation */
-#define FPE_FLTSUB	(__SI_FAULT|8)	/* subscript out of range */
-#define NSIGFPE		8
-
-/*
- * SIGSEGV si_codes
- */
-#define SEGV_MAPERR	(__SI_FAULT|1)	/* address not mapped to object */
-#define SEGV_ACCERR	(__SI_FAULT|2)	/* invalid permissions for mapped object */
-#define NSIGSEGV	2
-
-/*
- * SIGBUS si_codes
- */
-#define BUS_ADRALN	(__SI_FAULT|1)	/* invalid address alignment */
-#define BUS_ADRERR	(__SI_FAULT|2)	/* non-existent physical address */
-#define BUS_OBJERR	(__SI_FAULT|3)	/* object specific hardware error */
-/* hardware memory error consumed on a machine check: action required */
-#define BUS_MCEERR_AR	(__SI_FAULT|4)
-/* hardware memory error detected in process but not consumed: action optional*/
-#define BUS_MCEERR_AO	(__SI_FAULT|5)
-#define NSIGBUS		5
-
-/*
- * SIGTRAP si_codes
- */
-#define TRAP_BRKPT	(__SI_FAULT|1)	/* process breakpoint */
-#define TRAP_TRACE	(__SI_FAULT|2)	/* process trace trap */
-#define TRAP_BRANCH     (__SI_FAULT|3)  /* process taken branch trap */
-#define TRAP_HWBKPT     (__SI_FAULT|4)  /* hardware breakpoint/watchpoint */
-#define NSIGTRAP	4
-
-/*
- * SIGCHLD si_codes
- */
-#define CLD_EXITED	(__SI_CHLD|1)	/* child has exited */
-#define CLD_KILLED	(__SI_CHLD|2)	/* child was killed */
-#define CLD_DUMPED	(__SI_CHLD|3)	/* child terminated abnormally */
-#define CLD_TRAPPED	(__SI_CHLD|4)	/* traced child has trapped */
-#define CLD_STOPPED	(__SI_CHLD|5)	/* child has stopped */
-#define CLD_CONTINUED	(__SI_CHLD|6)	/* stopped child has continued */
-#define NSIGCHLD	6
-
-/*
- * SIGPOLL si_codes
- */
-#define POLL_IN		(__SI_POLL|1)	/* data input available */
-#define POLL_OUT	(__SI_POLL|2)	/* output buffers available */
-#define POLL_MSG	(__SI_POLL|3)	/* input message available */
-#define POLL_ERR	(__SI_POLL|4)	/* i/o error */
-#define POLL_PRI	(__SI_POLL|5)	/* high priority input available */
-#define POLL_HUP	(__SI_POLL|6)	/* device disconnected */
-#define NSIGPOLL	6
-
-/*
- * SIGSYS si_codes
- */
-#define SYS_SECCOMP		(__SI_SYS|1)	/* seccomp triggered */
-#define NSIGSYS	1
-
-/*
- * sigevent definitions
- * 
- * It seems likely that SIGEV_THREAD will have to be handled from 
- * userspace, libpthread transmuting it to SIGEV_SIGNAL, which the
- * thread manager then catches and does the appropriate nonsense.
- * However, everything is written out here so as to not get lost.
- */
-#define SIGEV_SIGNAL	0	/* notify via signal */
-#define SIGEV_NONE	1	/* other notification: meaningless */
-#define SIGEV_THREAD	2	/* deliver via thread creation */
-#define SIGEV_THREAD_ID 4	/* deliver to thread */
-
-/*
- * This works because the alignment is ok on all current architectures
- * but we leave open this being overridden in the future
- */
-#ifndef __ARCH_SIGEV_PREAMBLE_SIZE
-#define __ARCH_SIGEV_PREAMBLE_SIZE	(sizeof(int) * 2 + sizeof(sigval_t))
-#endif
-
-#define SIGEV_MAX_SIZE	64
-#define SIGEV_PAD_SIZE	((SIGEV_MAX_SIZE - __ARCH_SIGEV_PREAMBLE_SIZE) \
-		/ sizeof(int))
-
-typedef struct sigevent {
-	sigval_t sigev_value;
-	int sigev_signo;
-	int sigev_notify;
-	union {
-		int _pad[SIGEV_PAD_SIZE];
-		 int _tid;
-
-		struct {
-			void (*_function)(sigval_t);
-			void *_attribute;	/* really pthread_attr_t */
-		} _sigev_thread;
-	} _sigev_un;
-} sigevent_t;
-
-#define sigev_notify_function	_sigev_un._sigev_thread._function
-#define sigev_notify_attributes	_sigev_un._sigev_thread._attribute
-#define sigev_notify_thread_id	 _sigev_un._tid
-
-#ifdef __KERNEL__
 
 struct siginfo;
 void do_schedule_next_timer(struct siginfo *info);
@@ -327,6 +34,4 @@
 
 extern int copy_siginfo_to_user(struct siginfo __user *to, struct siginfo *from);
 
-#endif /* __KERNEL__ */
-
 #endif
diff --git a/include/asm-generic/signal.h b/include/asm-generic/signal.h
index 555c0ae..98caa30 100644
--- a/include/asm-generic/signal.h
+++ b/include/asm-generic/signal.h
@@ -1,131 +1,16 @@
 #ifndef __ASM_GENERIC_SIGNAL_H
 #define __ASM_GENERIC_SIGNAL_H
 
-#include <linux/types.h>
-
-#define _NSIG		64
-#define _NSIG_BPW	__BITS_PER_LONG
-#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
-
-#define SIGHUP		 1
-#define SIGINT		 2
-#define SIGQUIT		 3
-#define SIGILL		 4
-#define SIGTRAP		 5
-#define SIGABRT		 6
-#define SIGIOT		 6
-#define SIGBUS		 7
-#define SIGFPE		 8
-#define SIGKILL		 9
-#define SIGUSR1		10
-#define SIGSEGV		11
-#define SIGUSR2		12
-#define SIGPIPE		13
-#define SIGALRM		14
-#define SIGTERM		15
-#define SIGSTKFLT	16
-#define SIGCHLD		17
-#define SIGCONT		18
-#define SIGSTOP		19
-#define SIGTSTP		20
-#define SIGTTIN		21
-#define SIGTTOU		22
-#define SIGURG		23
-#define SIGXCPU		24
-#define SIGXFSZ		25
-#define SIGVTALRM	26
-#define SIGPROF		27
-#define SIGWINCH	28
-#define SIGIO		29
-#define SIGPOLL		SIGIO
-/*
-#define SIGLOST		29
-*/
-#define SIGPWR		30
-#define SIGSYS		31
-#define	SIGUNUSED	31
-
-/* These should not be considered constants from userland.  */
-#define SIGRTMIN	32
-#ifndef SIGRTMAX
-#define SIGRTMAX	_NSIG
-#endif
-
-/*
- * SA_FLAGS values:
- *
- * SA_ONSTACK indicates that a registered stack_t will be used.
- * SA_RESTART flag to get restarting signals (which were the default long ago)
- * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
- * SA_RESETHAND clears the handler when the signal is delivered.
- * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
- * SA_NODEFER prevents the current signal from being masked in the handler.
- *
- * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
- * Unix names RESETHAND and NODEFER respectively.
- */
-#define SA_NOCLDSTOP	0x00000001
-#define SA_NOCLDWAIT	0x00000002
-#define SA_SIGINFO	0x00000004
-#define SA_ONSTACK	0x08000000
-#define SA_RESTART	0x10000000
-#define SA_NODEFER	0x40000000
-#define SA_RESETHAND	0x80000000
-
-#define SA_NOMASK	SA_NODEFER
-#define SA_ONESHOT	SA_RESETHAND
-
-/*
- * New architectures should not define the obsolete
- *	SA_RESTORER	0x04000000
- */
-
-/*
- * sigaltstack controls
- */
-#define SS_ONSTACK	1
-#define SS_DISABLE	2
-
-#define MINSIGSTKSZ	2048
-#define SIGSTKSZ	8192
+#include <uapi/asm-generic/signal.h>
 
 #ifndef __ASSEMBLY__
-typedef struct {
-	unsigned long sig[_NSIG_WORDS];
-} sigset_t;
-
-/* not actually used, but required for linux/syscalls.h */
-typedef unsigned long old_sigset_t;
-
-#include <asm-generic/signal-defs.h>
-
-struct sigaction {
-	__sighandler_t sa_handler;
-	unsigned long sa_flags;
 #ifdef SA_RESTORER
-	__sigrestore_t sa_restorer;
 #endif
-	sigset_t sa_mask;		/* mask last for extensibility */
-};
-
-struct k_sigaction {
-	struct sigaction sa;
-};
-
-typedef struct sigaltstack {
-	void __user *ss_sp;
-	int ss_flags;
-	size_t ss_size;
-} stack_t;
-
-#ifdef __KERNEL__
 
 #include <asm/sigcontext.h>
 #undef __HAVE_ARCH_SIG_BITOPS
 
 #define ptrace_signal_deliver(regs, cookie) do { } while (0)
 
-#endif /* __KERNEL__ */
 #endif /* __ASSEMBLY__ */
-
 #endif /* _ASM_GENERIC_SIGNAL_H */
diff --git a/include/asm-generic/statfs.h b/include/asm-generic/statfs.h
index c749af9..4b934e9 100644
--- a/include/asm-generic/statfs.h
+++ b/include/asm-generic/statfs.h
@@ -1,86 +1,7 @@
 #ifndef _GENERIC_STATFS_H
 #define _GENERIC_STATFS_H
 
-#include <linux/types.h>
+#include <uapi/asm-generic/statfs.h>
 
-#ifdef __KERNEL__
 typedef __kernel_fsid_t	fsid_t;
 #endif
-
-/*
- * Most 64-bit platforms use 'long', while most 32-bit platforms use '__u32'.
- * Yes, they differ in signedness as well as size.
- * Special cases can override it for themselves -- except for S390x, which
- * is just a little too special for us. And MIPS, which I'm not touching
- * with a 10' pole.
- */
-#ifndef __statfs_word
-#if __BITS_PER_LONG == 64
-#define __statfs_word long
-#else
-#define __statfs_word __u32
-#endif
-#endif
-
-struct statfs {
-	__statfs_word f_type;
-	__statfs_word f_bsize;
-	__statfs_word f_blocks;
-	__statfs_word f_bfree;
-	__statfs_word f_bavail;
-	__statfs_word f_files;
-	__statfs_word f_ffree;
-	__kernel_fsid_t f_fsid;
-	__statfs_word f_namelen;
-	__statfs_word f_frsize;
-	__statfs_word f_flags;
-	__statfs_word f_spare[4];
-};
-
-/*
- * ARM needs to avoid the 32-bit padding at the end, for consistency
- * between EABI and OABI 
- */
-#ifndef ARCH_PACK_STATFS64
-#define ARCH_PACK_STATFS64
-#endif
-
-struct statfs64 {
-	__statfs_word f_type;
-	__statfs_word f_bsize;
-	__u64 f_blocks;
-	__u64 f_bfree;
-	__u64 f_bavail;
-	__u64 f_files;
-	__u64 f_ffree;
-	__kernel_fsid_t f_fsid;
-	__statfs_word f_namelen;
-	__statfs_word f_frsize;
-	__statfs_word f_flags;
-	__statfs_word f_spare[4];
-} ARCH_PACK_STATFS64;
-
-/* 
- * IA64 and x86_64 need to avoid the 32-bit padding at the end,
- * to be compatible with the i386 ABI
- */
-#ifndef ARCH_PACK_COMPAT_STATFS64
-#define ARCH_PACK_COMPAT_STATFS64
-#endif
-
-struct compat_statfs64 {
-	__u32 f_type;
-	__u32 f_bsize;
-	__u64 f_blocks;
-	__u64 f_bfree;
-	__u64 f_bavail;
-	__u64 f_files;
-	__u64 f_ffree;
-	__kernel_fsid_t f_fsid;
-	__u32 f_namelen;
-	__u32 f_frsize;
-	__u32 f_flags;
-	__u32 f_spare[4];
-} ARCH_PACK_COMPAT_STATFS64;
-
-#endif
diff --git a/include/asm-generic/termios.h b/include/asm-generic/termios.h
index d0922ad..4fa6fe0 100644
--- a/include/asm-generic/termios.h
+++ b/include/asm-generic/termios.h
@@ -1,54 +1,9 @@
 #ifndef _ASM_GENERIC_TERMIOS_H
 #define _ASM_GENERIC_TERMIOS_H
-/*
- * Most architectures have straight copies of the x86 code, with
- * varying levels of bug fixes on top. Usually it's a good idea
- * to use this generic version instead, but be careful to avoid
- * ABI changes.
- * New architectures should not provide their own version.
- */
 
-#include <asm/termbits.h>
-#include <asm/ioctls.h>
-
-struct winsize {
-	unsigned short ws_row;
-	unsigned short ws_col;
-	unsigned short ws_xpixel;
-	unsigned short ws_ypixel;
-};
-
-#define NCC 8
-struct termio {
-	unsigned short c_iflag;		/* input mode flags */
-	unsigned short c_oflag;		/* output mode flags */
-	unsigned short c_cflag;		/* control mode flags */
-	unsigned short c_lflag;		/* local mode flags */
-	unsigned char c_line;		/* line discipline */
-	unsigned char c_cc[NCC];	/* control characters */
-};
-
-/* modem lines */
-#define TIOCM_LE	0x001
-#define TIOCM_DTR	0x002
-#define TIOCM_RTS	0x004
-#define TIOCM_ST	0x008
-#define TIOCM_SR	0x010
-#define TIOCM_CTS	0x020
-#define TIOCM_CAR	0x040
-#define TIOCM_RNG	0x080
-#define TIOCM_DSR	0x100
-#define TIOCM_CD	TIOCM_CAR
-#define TIOCM_RI	TIOCM_RNG
-#define TIOCM_OUT1	0x2000
-#define TIOCM_OUT2	0x4000
-#define TIOCM_LOOP	0x8000
-
-/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
-
-#ifdef __KERNEL__
 
 #include <asm/uaccess.h>
+#include <uapi/asm-generic/termios.h>
 
 /*	intr=^C		quit=^\		erase=del	kill=^U
 	eof=^D		vtime=\0	vmin=\1		sxtc=\0
@@ -149,6 +104,4 @@
 }
 #endif /* TCGETS2 */
 
-#endif	/* __KERNEL__ */
-
 #endif /* _ASM_GENERIC_TERMIOS_H */
diff --git a/include/asm-generic/unistd.h b/include/asm-generic/unistd.h
index cf22fae..a36991a 100644
--- a/include/asm-generic/unistd.h
+++ b/include/asm-generic/unistd.h
@@ -1,907 +1,4 @@
-#include <asm/bitsperlong.h>
-
-/*
- * This file contains the system call numbers, based on the
- * layout of the x86-64 architecture, which embeds the
- * pointer to the syscall in the table.
- *
- * As a basic principle, no duplication of functionality
- * should be added, e.g. we don't use lseek when llseek
- * is present. New architectures should use this file
- * and implement the less feature-full calls in user space.
- */
-
-#ifndef __SYSCALL
-#define __SYSCALL(x, y)
-#endif
-
-#if __BITS_PER_LONG == 32 || defined(__SYSCALL_COMPAT)
-#define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _32)
-#else
-#define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _64)
-#endif
-
-#ifdef __SYSCALL_COMPAT
-#define __SC_COMP(_nr, _sys, _comp) __SYSCALL(_nr, _comp)
-#define __SC_COMP_3264(_nr, _32, _64, _comp) __SYSCALL(_nr, _comp)
-#else
-#define __SC_COMP(_nr, _sys, _comp) __SYSCALL(_nr, _sys)
-#define __SC_COMP_3264(_nr, _32, _64, _comp) __SC_3264(_nr, _32, _64)
-#endif
-
-#define __NR_io_setup 0
-__SC_COMP(__NR_io_setup, sys_io_setup, compat_sys_io_setup)
-#define __NR_io_destroy 1
-__SYSCALL(__NR_io_destroy, sys_io_destroy)
-#define __NR_io_submit 2
-__SC_COMP(__NR_io_submit, sys_io_submit, compat_sys_io_submit)
-#define __NR_io_cancel 3
-__SYSCALL(__NR_io_cancel, sys_io_cancel)
-#define __NR_io_getevents 4
-__SC_COMP(__NR_io_getevents, sys_io_getevents, compat_sys_io_getevents)
-
-/* fs/xattr.c */
-#define __NR_setxattr 5
-__SYSCALL(__NR_setxattr, sys_setxattr)
-#define __NR_lsetxattr 6
-__SYSCALL(__NR_lsetxattr, sys_lsetxattr)
-#define __NR_fsetxattr 7
-__SYSCALL(__NR_fsetxattr, sys_fsetxattr)
-#define __NR_getxattr 8
-__SYSCALL(__NR_getxattr, sys_getxattr)
-#define __NR_lgetxattr 9
-__SYSCALL(__NR_lgetxattr, sys_lgetxattr)
-#define __NR_fgetxattr 10
-__SYSCALL(__NR_fgetxattr, sys_fgetxattr)
-#define __NR_listxattr 11
-__SYSCALL(__NR_listxattr, sys_listxattr)
-#define __NR_llistxattr 12
-__SYSCALL(__NR_llistxattr, sys_llistxattr)
-#define __NR_flistxattr 13
-__SYSCALL(__NR_flistxattr, sys_flistxattr)
-#define __NR_removexattr 14
-__SYSCALL(__NR_removexattr, sys_removexattr)
-#define __NR_lremovexattr 15
-__SYSCALL(__NR_lremovexattr, sys_lremovexattr)
-#define __NR_fremovexattr 16
-__SYSCALL(__NR_fremovexattr, sys_fremovexattr)
-
-/* fs/dcache.c */
-#define __NR_getcwd 17
-__SYSCALL(__NR_getcwd, sys_getcwd)
-
-/* fs/cookies.c */
-#define __NR_lookup_dcookie 18
-__SC_COMP(__NR_lookup_dcookie, sys_lookup_dcookie, compat_sys_lookup_dcookie)
-
-/* fs/eventfd.c */
-#define __NR_eventfd2 19
-__SYSCALL(__NR_eventfd2, sys_eventfd2)
-
-/* fs/eventpoll.c */
-#define __NR_epoll_create1 20
-__SYSCALL(__NR_epoll_create1, sys_epoll_create1)
-#define __NR_epoll_ctl 21
-__SYSCALL(__NR_epoll_ctl, sys_epoll_ctl)
-#define __NR_epoll_pwait 22
-__SC_COMP(__NR_epoll_pwait, sys_epoll_pwait, compat_sys_epoll_pwait)
-
-/* fs/fcntl.c */
-#define __NR_dup 23
-__SYSCALL(__NR_dup, sys_dup)
-#define __NR_dup3 24
-__SYSCALL(__NR_dup3, sys_dup3)
-#define __NR3264_fcntl 25
-__SC_COMP_3264(__NR3264_fcntl, sys_fcntl64, sys_fcntl, compat_sys_fcntl64)
-
-/* fs/inotify_user.c */
-#define __NR_inotify_init1 26
-__SYSCALL(__NR_inotify_init1, sys_inotify_init1)
-#define __NR_inotify_add_watch 27
-__SYSCALL(__NR_inotify_add_watch, sys_inotify_add_watch)
-#define __NR_inotify_rm_watch 28
-__SYSCALL(__NR_inotify_rm_watch, sys_inotify_rm_watch)
-
-/* fs/ioctl.c */
-#define __NR_ioctl 29
-__SC_COMP(__NR_ioctl, sys_ioctl, compat_sys_ioctl)
-
-/* fs/ioprio.c */
-#define __NR_ioprio_set 30
-__SYSCALL(__NR_ioprio_set, sys_ioprio_set)
-#define __NR_ioprio_get 31
-__SYSCALL(__NR_ioprio_get, sys_ioprio_get)
-
-/* fs/locks.c */
-#define __NR_flock 32
-__SYSCALL(__NR_flock, sys_flock)
-
-/* fs/namei.c */
-#define __NR_mknodat 33
-__SYSCALL(__NR_mknodat, sys_mknodat)
-#define __NR_mkdirat 34
-__SYSCALL(__NR_mkdirat, sys_mkdirat)
-#define __NR_unlinkat 35
-__SYSCALL(__NR_unlinkat, sys_unlinkat)
-#define __NR_symlinkat 36
-__SYSCALL(__NR_symlinkat, sys_symlinkat)
-#define __NR_linkat 37
-__SYSCALL(__NR_linkat, sys_linkat)
-#define __NR_renameat 38
-__SYSCALL(__NR_renameat, sys_renameat)
-
-/* fs/namespace.c */
-#define __NR_umount2 39
-__SYSCALL(__NR_umount2, sys_umount)
-#define __NR_mount 40
-__SC_COMP(__NR_mount, sys_mount, compat_sys_mount)
-#define __NR_pivot_root 41
-__SYSCALL(__NR_pivot_root, sys_pivot_root)
-
-/* fs/nfsctl.c */
-#define __NR_nfsservctl 42
-__SYSCALL(__NR_nfsservctl, sys_ni_syscall)
-
-/* fs/open.c */
-#define __NR3264_statfs 43
-__SC_COMP_3264(__NR3264_statfs, sys_statfs64, sys_statfs, \
-	       compat_sys_statfs64)
-#define __NR3264_fstatfs 44
-__SC_COMP_3264(__NR3264_fstatfs, sys_fstatfs64, sys_fstatfs, \
-	       compat_sys_fstatfs64)
-#define __NR3264_truncate 45
-__SC_COMP_3264(__NR3264_truncate, sys_truncate64, sys_truncate, \
-	       compat_sys_truncate64)
-#define __NR3264_ftruncate 46
-__SC_COMP_3264(__NR3264_ftruncate, sys_ftruncate64, sys_ftruncate, \
-	       compat_sys_ftruncate64)
-
-#define __NR_fallocate 47
-__SC_COMP(__NR_fallocate, sys_fallocate, compat_sys_fallocate)
-#define __NR_faccessat 48
-__SYSCALL(__NR_faccessat, sys_faccessat)
-#define __NR_chdir 49
-__SYSCALL(__NR_chdir, sys_chdir)
-#define __NR_fchdir 50
-__SYSCALL(__NR_fchdir, sys_fchdir)
-#define __NR_chroot 51
-__SYSCALL(__NR_chroot, sys_chroot)
-#define __NR_fchmod 52
-__SYSCALL(__NR_fchmod, sys_fchmod)
-#define __NR_fchmodat 53
-__SYSCALL(__NR_fchmodat, sys_fchmodat)
-#define __NR_fchownat 54
-__SYSCALL(__NR_fchownat, sys_fchownat)
-#define __NR_fchown 55
-__SYSCALL(__NR_fchown, sys_fchown)
-#define __NR_openat 56
-__SC_COMP(__NR_openat, sys_openat, compat_sys_openat)
-#define __NR_close 57
-__SYSCALL(__NR_close, sys_close)
-#define __NR_vhangup 58
-__SYSCALL(__NR_vhangup, sys_vhangup)
-
-/* fs/pipe.c */
-#define __NR_pipe2 59
-__SYSCALL(__NR_pipe2, sys_pipe2)
-
-/* fs/quota.c */
-#define __NR_quotactl 60
-__SYSCALL(__NR_quotactl, sys_quotactl)
-
-/* fs/readdir.c */
-#define __NR_getdents64 61
-__SC_COMP(__NR_getdents64, sys_getdents64, compat_sys_getdents64)
-
-/* fs/read_write.c */
-#define __NR3264_lseek 62
-__SC_3264(__NR3264_lseek, sys_llseek, sys_lseek)
-#define __NR_read 63
-__SYSCALL(__NR_read, sys_read)
-#define __NR_write 64
-__SYSCALL(__NR_write, sys_write)
-#define __NR_readv 65
-__SC_COMP(__NR_readv, sys_readv, compat_sys_readv)
-#define __NR_writev 66
-__SC_COMP(__NR_writev, sys_writev, compat_sys_writev)
-#define __NR_pread64 67
-__SC_COMP(__NR_pread64, sys_pread64, compat_sys_pread64)
-#define __NR_pwrite64 68
-__SC_COMP(__NR_pwrite64, sys_pwrite64, compat_sys_pwrite64)
-#define __NR_preadv 69
-__SC_COMP(__NR_preadv, sys_preadv, compat_sys_preadv)
-#define __NR_pwritev 70
-__SC_COMP(__NR_pwritev, sys_pwritev, compat_sys_pwritev)
-
-/* fs/sendfile.c */
-#define __NR3264_sendfile 71
-__SYSCALL(__NR3264_sendfile, sys_sendfile64)
-
-/* fs/select.c */
-#define __NR_pselect6 72
-__SC_COMP(__NR_pselect6, sys_pselect6, compat_sys_pselect6)
-#define __NR_ppoll 73
-__SC_COMP(__NR_ppoll, sys_ppoll, compat_sys_ppoll)
-
-/* fs/signalfd.c */
-#define __NR_signalfd4 74
-__SC_COMP(__NR_signalfd4, sys_signalfd4, compat_sys_signalfd4)
-
-/* fs/splice.c */
-#define __NR_vmsplice 75
-__SC_COMP(__NR_vmsplice, sys_vmsplice, compat_sys_vmsplice)
-#define __NR_splice 76
-__SYSCALL(__NR_splice, sys_splice)
-#define __NR_tee 77
-__SYSCALL(__NR_tee, sys_tee)
-
-/* fs/stat.c */
-#define __NR_readlinkat 78
-__SYSCALL(__NR_readlinkat, sys_readlinkat)
-#define __NR3264_fstatat 79
-__SC_3264(__NR3264_fstatat, sys_fstatat64, sys_newfstatat)
-#define __NR3264_fstat 80
-__SC_3264(__NR3264_fstat, sys_fstat64, sys_newfstat)
-
-/* fs/sync.c */
-#define __NR_sync 81
-__SYSCALL(__NR_sync, sys_sync)
-#define __NR_fsync 82
-__SYSCALL(__NR_fsync, sys_fsync)
-#define __NR_fdatasync 83
-__SYSCALL(__NR_fdatasync, sys_fdatasync)
-#ifdef __ARCH_WANT_SYNC_FILE_RANGE2
-#define __NR_sync_file_range2 84
-__SC_COMP(__NR_sync_file_range2, sys_sync_file_range2, \
-	  compat_sys_sync_file_range2)
-#else
-#define __NR_sync_file_range 84
-__SC_COMP(__NR_sync_file_range, sys_sync_file_range, \
-	  compat_sys_sync_file_range)
-#endif
-
-/* fs/timerfd.c */
-#define __NR_timerfd_create 85
-__SYSCALL(__NR_timerfd_create, sys_timerfd_create)
-#define __NR_timerfd_settime 86
-__SC_COMP(__NR_timerfd_settime, sys_timerfd_settime, \
-	  compat_sys_timerfd_settime)
-#define __NR_timerfd_gettime 87
-__SC_COMP(__NR_timerfd_gettime, sys_timerfd_gettime, \
-	  compat_sys_timerfd_gettime)
-
-/* fs/utimes.c */
-#define __NR_utimensat 88
-__SC_COMP(__NR_utimensat, sys_utimensat, compat_sys_utimensat)
-
-/* kernel/acct.c */
-#define __NR_acct 89
-__SYSCALL(__NR_acct, sys_acct)
-
-/* kernel/capability.c */
-#define __NR_capget 90
-__SYSCALL(__NR_capget, sys_capget)
-#define __NR_capset 91
-__SYSCALL(__NR_capset, sys_capset)
-
-/* kernel/exec_domain.c */
-#define __NR_personality 92
-__SYSCALL(__NR_personality, sys_personality)
-
-/* kernel/exit.c */
-#define __NR_exit 93
-__SYSCALL(__NR_exit, sys_exit)
-#define __NR_exit_group 94
-__SYSCALL(__NR_exit_group, sys_exit_group)
-#define __NR_waitid 95
-__SC_COMP(__NR_waitid, sys_waitid, compat_sys_waitid)
-
-/* kernel/fork.c */
-#define __NR_set_tid_address 96
-__SYSCALL(__NR_set_tid_address, sys_set_tid_address)
-#define __NR_unshare 97
-__SYSCALL(__NR_unshare, sys_unshare)
-
-/* kernel/futex.c */
-#define __NR_futex 98
-__SC_COMP(__NR_futex, sys_futex, compat_sys_futex)
-#define __NR_set_robust_list 99
-__SC_COMP(__NR_set_robust_list, sys_set_robust_list, \
-	  compat_sys_set_robust_list)
-#define __NR_get_robust_list 100
-__SC_COMP(__NR_get_robust_list, sys_get_robust_list, \
-	  compat_sys_get_robust_list)
-
-/* kernel/hrtimer.c */
-#define __NR_nanosleep 101
-__SC_COMP(__NR_nanosleep, sys_nanosleep, compat_sys_nanosleep)
-
-/* kernel/itimer.c */
-#define __NR_getitimer 102
-__SC_COMP(__NR_getitimer, sys_getitimer, compat_sys_getitimer)
-#define __NR_setitimer 103
-__SC_COMP(__NR_setitimer, sys_setitimer, compat_sys_setitimer)
-
-/* kernel/kexec.c */
-#define __NR_kexec_load 104
-__SC_COMP(__NR_kexec_load, sys_kexec_load, compat_sys_kexec_load)
-
-/* kernel/module.c */
-#define __NR_init_module 105
-__SYSCALL(__NR_init_module, sys_init_module)
-#define __NR_delete_module 106
-__SYSCALL(__NR_delete_module, sys_delete_module)
-
-/* kernel/posix-timers.c */
-#define __NR_timer_create 107
-__SC_COMP(__NR_timer_create, sys_timer_create, compat_sys_timer_create)
-#define __NR_timer_gettime 108
-__SC_COMP(__NR_timer_gettime, sys_timer_gettime, compat_sys_timer_gettime)
-#define __NR_timer_getoverrun 109
-__SYSCALL(__NR_timer_getoverrun, sys_timer_getoverrun)
-#define __NR_timer_settime 110
-__SC_COMP(__NR_timer_settime, sys_timer_settime, compat_sys_timer_settime)
-#define __NR_timer_delete 111
-__SYSCALL(__NR_timer_delete, sys_timer_delete)
-#define __NR_clock_settime 112
-__SC_COMP(__NR_clock_settime, sys_clock_settime, compat_sys_clock_settime)
-#define __NR_clock_gettime 113
-__SC_COMP(__NR_clock_gettime, sys_clock_gettime, compat_sys_clock_gettime)
-#define __NR_clock_getres 114
-__SC_COMP(__NR_clock_getres, sys_clock_getres, compat_sys_clock_getres)
-#define __NR_clock_nanosleep 115
-__SC_COMP(__NR_clock_nanosleep, sys_clock_nanosleep, \
-	  compat_sys_clock_nanosleep)
-
-/* kernel/printk.c */
-#define __NR_syslog 116
-__SYSCALL(__NR_syslog, sys_syslog)
-
-/* kernel/ptrace.c */
-#define __NR_ptrace 117
-__SYSCALL(__NR_ptrace, sys_ptrace)
-
-/* kernel/sched.c */
-#define __NR_sched_setparam 118
-__SYSCALL(__NR_sched_setparam, sys_sched_setparam)
-#define __NR_sched_setscheduler 119
-__SYSCALL(__NR_sched_setscheduler, sys_sched_setscheduler)
-#define __NR_sched_getscheduler 120
-__SYSCALL(__NR_sched_getscheduler, sys_sched_getscheduler)
-#define __NR_sched_getparam 121
-__SYSCALL(__NR_sched_getparam, sys_sched_getparam)
-#define __NR_sched_setaffinity 122
-__SC_COMP(__NR_sched_setaffinity, sys_sched_setaffinity, \
-	  compat_sys_sched_setaffinity)
-#define __NR_sched_getaffinity 123
-__SC_COMP(__NR_sched_getaffinity, sys_sched_getaffinity, \
-	  compat_sys_sched_getaffinity)
-#define __NR_sched_yield 124
-__SYSCALL(__NR_sched_yield, sys_sched_yield)
-#define __NR_sched_get_priority_max 125
-__SYSCALL(__NR_sched_get_priority_max, sys_sched_get_priority_max)
-#define __NR_sched_get_priority_min 126
-__SYSCALL(__NR_sched_get_priority_min, sys_sched_get_priority_min)
-#define __NR_sched_rr_get_interval 127
-__SC_COMP(__NR_sched_rr_get_interval, sys_sched_rr_get_interval, \
-	  compat_sys_sched_rr_get_interval)
-
-/* kernel/signal.c */
-#define __NR_restart_syscall 128
-__SYSCALL(__NR_restart_syscall, sys_restart_syscall)
-#define __NR_kill 129
-__SYSCALL(__NR_kill, sys_kill)
-#define __NR_tkill 130
-__SYSCALL(__NR_tkill, sys_tkill)
-#define __NR_tgkill 131
-__SYSCALL(__NR_tgkill, sys_tgkill)
-#define __NR_sigaltstack 132
-__SC_COMP(__NR_sigaltstack, sys_sigaltstack, compat_sys_sigaltstack)
-#define __NR_rt_sigsuspend 133
-__SC_COMP(__NR_rt_sigsuspend, sys_rt_sigsuspend, compat_sys_rt_sigsuspend)
-#define __NR_rt_sigaction 134
-__SC_COMP(__NR_rt_sigaction, sys_rt_sigaction, compat_sys_rt_sigaction)
-#define __NR_rt_sigprocmask 135
-__SYSCALL(__NR_rt_sigprocmask, sys_rt_sigprocmask)
-#define __NR_rt_sigpending 136
-__SYSCALL(__NR_rt_sigpending, sys_rt_sigpending)
-#define __NR_rt_sigtimedwait 137
-__SC_COMP(__NR_rt_sigtimedwait, sys_rt_sigtimedwait, \
-	  compat_sys_rt_sigtimedwait)
-#define __NR_rt_sigqueueinfo 138
-__SC_COMP(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo, \
-	  compat_sys_rt_sigqueueinfo)
-#define __NR_rt_sigreturn 139
-__SC_COMP(__NR_rt_sigreturn, sys_rt_sigreturn, compat_sys_rt_sigreturn)
-
-/* kernel/sys.c */
-#define __NR_setpriority 140
-__SYSCALL(__NR_setpriority, sys_setpriority)
-#define __NR_getpriority 141
-__SYSCALL(__NR_getpriority, sys_getpriority)
-#define __NR_reboot 142
-__SYSCALL(__NR_reboot, sys_reboot)
-#define __NR_setregid 143
-__SYSCALL(__NR_setregid, sys_setregid)
-#define __NR_setgid 144
-__SYSCALL(__NR_setgid, sys_setgid)
-#define __NR_setreuid 145
-__SYSCALL(__NR_setreuid, sys_setreuid)
-#define __NR_setuid 146
-__SYSCALL(__NR_setuid, sys_setuid)
-#define __NR_setresuid 147
-__SYSCALL(__NR_setresuid, sys_setresuid)
-#define __NR_getresuid 148
-__SYSCALL(__NR_getresuid, sys_getresuid)
-#define __NR_setresgid 149
-__SYSCALL(__NR_setresgid, sys_setresgid)
-#define __NR_getresgid 150
-__SYSCALL(__NR_getresgid, sys_getresgid)
-#define __NR_setfsuid 151
-__SYSCALL(__NR_setfsuid, sys_setfsuid)
-#define __NR_setfsgid 152
-__SYSCALL(__NR_setfsgid, sys_setfsgid)
-#define __NR_times 153
-__SC_COMP(__NR_times, sys_times, compat_sys_times)
-#define __NR_setpgid 154
-__SYSCALL(__NR_setpgid, sys_setpgid)
-#define __NR_getpgid 155
-__SYSCALL(__NR_getpgid, sys_getpgid)
-#define __NR_getsid 156
-__SYSCALL(__NR_getsid, sys_getsid)
-#define __NR_setsid 157
-__SYSCALL(__NR_setsid, sys_setsid)
-#define __NR_getgroups 158
-__SYSCALL(__NR_getgroups, sys_getgroups)
-#define __NR_setgroups 159
-__SYSCALL(__NR_setgroups, sys_setgroups)
-#define __NR_uname 160
-__SYSCALL(__NR_uname, sys_newuname)
-#define __NR_sethostname 161
-__SYSCALL(__NR_sethostname, sys_sethostname)
-#define __NR_setdomainname 162
-__SYSCALL(__NR_setdomainname, sys_setdomainname)
-#define __NR_getrlimit 163
-__SC_COMP(__NR_getrlimit, sys_getrlimit, compat_sys_getrlimit)
-#define __NR_setrlimit 164
-__SC_COMP(__NR_setrlimit, sys_setrlimit, compat_sys_setrlimit)
-#define __NR_getrusage 165
-__SC_COMP(__NR_getrusage, sys_getrusage, compat_sys_getrusage)
-#define __NR_umask 166
-__SYSCALL(__NR_umask, sys_umask)
-#define __NR_prctl 167
-__SYSCALL(__NR_prctl, sys_prctl)
-#define __NR_getcpu 168
-__SYSCALL(__NR_getcpu, sys_getcpu)
-
-/* kernel/time.c */
-#define __NR_gettimeofday 169
-__SC_COMP(__NR_gettimeofday, sys_gettimeofday, compat_sys_gettimeofday)
-#define __NR_settimeofday 170
-__SC_COMP(__NR_settimeofday, sys_settimeofday, compat_sys_settimeofday)
-#define __NR_adjtimex 171
-__SC_COMP(__NR_adjtimex, sys_adjtimex, compat_sys_adjtimex)
-
-/* kernel/timer.c */
-#define __NR_getpid 172
-__SYSCALL(__NR_getpid, sys_getpid)
-#define __NR_getppid 173
-__SYSCALL(__NR_getppid, sys_getppid)
-#define __NR_getuid 174
-__SYSCALL(__NR_getuid, sys_getuid)
-#define __NR_geteuid 175
-__SYSCALL(__NR_geteuid, sys_geteuid)
-#define __NR_getgid 176
-__SYSCALL(__NR_getgid, sys_getgid)
-#define __NR_getegid 177
-__SYSCALL(__NR_getegid, sys_getegid)
-#define __NR_gettid 178
-__SYSCALL(__NR_gettid, sys_gettid)
-#define __NR_sysinfo 179
-__SC_COMP(__NR_sysinfo, sys_sysinfo, compat_sys_sysinfo)
-
-/* ipc/mqueue.c */
-#define __NR_mq_open 180
-__SC_COMP(__NR_mq_open, sys_mq_open, compat_sys_mq_open)
-#define __NR_mq_unlink 181
-__SYSCALL(__NR_mq_unlink, sys_mq_unlink)
-#define __NR_mq_timedsend 182
-__SC_COMP(__NR_mq_timedsend, sys_mq_timedsend, compat_sys_mq_timedsend)
-#define __NR_mq_timedreceive 183
-__SC_COMP(__NR_mq_timedreceive, sys_mq_timedreceive, \
-	  compat_sys_mq_timedreceive)
-#define __NR_mq_notify 184
-__SC_COMP(__NR_mq_notify, sys_mq_notify, compat_sys_mq_notify)
-#define __NR_mq_getsetattr 185
-__SC_COMP(__NR_mq_getsetattr, sys_mq_getsetattr, compat_sys_mq_getsetattr)
-
-/* ipc/msg.c */
-#define __NR_msgget 186
-__SYSCALL(__NR_msgget, sys_msgget)
-#define __NR_msgctl 187
-__SC_COMP(__NR_msgctl, sys_msgctl, compat_sys_msgctl)
-#define __NR_msgrcv 188
-__SC_COMP(__NR_msgrcv, sys_msgrcv, compat_sys_msgrcv)
-#define __NR_msgsnd 189
-__SC_COMP(__NR_msgsnd, sys_msgsnd, compat_sys_msgsnd)
-
-/* ipc/sem.c */
-#define __NR_semget 190
-__SYSCALL(__NR_semget, sys_semget)
-#define __NR_semctl 191
-__SC_COMP(__NR_semctl, sys_semctl, compat_sys_semctl)
-#define __NR_semtimedop 192
-__SC_COMP(__NR_semtimedop, sys_semtimedop, compat_sys_semtimedop)
-#define __NR_semop 193
-__SYSCALL(__NR_semop, sys_semop)
-
-/* ipc/shm.c */
-#define __NR_shmget 194
-__SYSCALL(__NR_shmget, sys_shmget)
-#define __NR_shmctl 195
-__SC_COMP(__NR_shmctl, sys_shmctl, compat_sys_shmctl)
-#define __NR_shmat 196
-__SC_COMP(__NR_shmat, sys_shmat, compat_sys_shmat)
-#define __NR_shmdt 197
-__SYSCALL(__NR_shmdt, sys_shmdt)
-
-/* net/socket.c */
-#define __NR_socket 198
-__SYSCALL(__NR_socket, sys_socket)
-#define __NR_socketpair 199
-__SYSCALL(__NR_socketpair, sys_socketpair)
-#define __NR_bind 200
-__SYSCALL(__NR_bind, sys_bind)
-#define __NR_listen 201
-__SYSCALL(__NR_listen, sys_listen)
-#define __NR_accept 202
-__SYSCALL(__NR_accept, sys_accept)
-#define __NR_connect 203
-__SYSCALL(__NR_connect, sys_connect)
-#define __NR_getsockname 204
-__SYSCALL(__NR_getsockname, sys_getsockname)
-#define __NR_getpeername 205
-__SYSCALL(__NR_getpeername, sys_getpeername)
-#define __NR_sendto 206
-__SYSCALL(__NR_sendto, sys_sendto)
-#define __NR_recvfrom 207
-__SC_COMP(__NR_recvfrom, sys_recvfrom, compat_sys_recvfrom)
-#define __NR_setsockopt 208
-__SC_COMP(__NR_setsockopt, sys_setsockopt, compat_sys_setsockopt)
-#define __NR_getsockopt 209
-__SC_COMP(__NR_getsockopt, sys_getsockopt, compat_sys_getsockopt)
-#define __NR_shutdown 210
-__SYSCALL(__NR_shutdown, sys_shutdown)
-#define __NR_sendmsg 211
-__SC_COMP(__NR_sendmsg, sys_sendmsg, compat_sys_sendmsg)
-#define __NR_recvmsg 212
-__SC_COMP(__NR_recvmsg, sys_recvmsg, compat_sys_recvmsg)
-
-/* mm/filemap.c */
-#define __NR_readahead 213
-__SC_COMP(__NR_readahead, sys_readahead, compat_sys_readahead)
-
-/* mm/nommu.c, also with MMU */
-#define __NR_brk 214
-__SYSCALL(__NR_brk, sys_brk)
-#define __NR_munmap 215
-__SYSCALL(__NR_munmap, sys_munmap)
-#define __NR_mremap 216
-__SYSCALL(__NR_mremap, sys_mremap)
-
-/* security/keys/keyctl.c */
-#define __NR_add_key 217
-__SYSCALL(__NR_add_key, sys_add_key)
-#define __NR_request_key 218
-__SYSCALL(__NR_request_key, sys_request_key)
-#define __NR_keyctl 219
-__SC_COMP(__NR_keyctl, sys_keyctl, compat_sys_keyctl)
-
-/* arch/example/kernel/sys_example.c */
-#define __NR_clone 220
-__SYSCALL(__NR_clone, sys_clone)
-#define __NR_execve 221
-__SC_COMP(__NR_execve, sys_execve, compat_sys_execve)
-
-#define __NR3264_mmap 222
-__SC_3264(__NR3264_mmap, sys_mmap2, sys_mmap)
-/* mm/fadvise.c */
-#define __NR3264_fadvise64 223
-__SC_COMP(__NR3264_fadvise64, sys_fadvise64_64, compat_sys_fadvise64_64)
-
-/* mm/, CONFIG_MMU only */
-#ifndef __ARCH_NOMMU
-#define __NR_swapon 224
-__SYSCALL(__NR_swapon, sys_swapon)
-#define __NR_swapoff 225
-__SYSCALL(__NR_swapoff, sys_swapoff)
-#define __NR_mprotect 226
-__SYSCALL(__NR_mprotect, sys_mprotect)
-#define __NR_msync 227
-__SYSCALL(__NR_msync, sys_msync)
-#define __NR_mlock 228
-__SYSCALL(__NR_mlock, sys_mlock)
-#define __NR_munlock 229
-__SYSCALL(__NR_munlock, sys_munlock)
-#define __NR_mlockall 230
-__SYSCALL(__NR_mlockall, sys_mlockall)
-#define __NR_munlockall 231
-__SYSCALL(__NR_munlockall, sys_munlockall)
-#define __NR_mincore 232
-__SYSCALL(__NR_mincore, sys_mincore)
-#define __NR_madvise 233
-__SYSCALL(__NR_madvise, sys_madvise)
-#define __NR_remap_file_pages 234
-__SYSCALL(__NR_remap_file_pages, sys_remap_file_pages)
-#define __NR_mbind 235
-__SC_COMP(__NR_mbind, sys_mbind, compat_sys_mbind)
-#define __NR_get_mempolicy 236
-__SC_COMP(__NR_get_mempolicy, sys_get_mempolicy, compat_sys_get_mempolicy)
-#define __NR_set_mempolicy 237
-__SC_COMP(__NR_set_mempolicy, sys_set_mempolicy, compat_sys_set_mempolicy)
-#define __NR_migrate_pages 238
-__SC_COMP(__NR_migrate_pages, sys_migrate_pages, compat_sys_migrate_pages)
-#define __NR_move_pages 239
-__SC_COMP(__NR_move_pages, sys_move_pages, compat_sys_move_pages)
-#endif
-
-#define __NR_rt_tgsigqueueinfo 240
-__SC_COMP(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo, \
-	  compat_sys_rt_tgsigqueueinfo)
-#define __NR_perf_event_open 241
-__SYSCALL(__NR_perf_event_open, sys_perf_event_open)
-#define __NR_accept4 242
-__SYSCALL(__NR_accept4, sys_accept4)
-#define __NR_recvmmsg 243
-__SC_COMP(__NR_recvmmsg, sys_recvmmsg, compat_sys_recvmmsg)
-
-/*
- * Architectures may provide up to 16 syscalls of their own
- * starting with this value.
- */
-#define __NR_arch_specific_syscall 244
-
-#define __NR_wait4 260
-__SC_COMP(__NR_wait4, sys_wait4, compat_sys_wait4)
-#define __NR_prlimit64 261
-__SYSCALL(__NR_prlimit64, sys_prlimit64)
-#define __NR_fanotify_init 262
-__SYSCALL(__NR_fanotify_init, sys_fanotify_init)
-#define __NR_fanotify_mark 263
-__SYSCALL(__NR_fanotify_mark, sys_fanotify_mark)
-#define __NR_name_to_handle_at         264
-__SYSCALL(__NR_name_to_handle_at, sys_name_to_handle_at)
-#define __NR_open_by_handle_at         265
-__SC_COMP(__NR_open_by_handle_at, sys_open_by_handle_at, \
-	  compat_sys_open_by_handle_at)
-#define __NR_clock_adjtime 266
-__SC_COMP(__NR_clock_adjtime, sys_clock_adjtime, compat_sys_clock_adjtime)
-#define __NR_syncfs 267
-__SYSCALL(__NR_syncfs, sys_syncfs)
-#define __NR_setns 268
-__SYSCALL(__NR_setns, sys_setns)
-#define __NR_sendmmsg 269
-__SC_COMP(__NR_sendmmsg, sys_sendmmsg, compat_sys_sendmmsg)
-#define __NR_process_vm_readv 270
-__SC_COMP(__NR_process_vm_readv, sys_process_vm_readv, \
-          compat_sys_process_vm_readv)
-#define __NR_process_vm_writev 271
-__SC_COMP(__NR_process_vm_writev, sys_process_vm_writev, \
-          compat_sys_process_vm_writev)
-#define __NR_kcmp 272
-__SYSCALL(__NR_kcmp, sys_kcmp)
-
-#undef __NR_syscalls
-#define __NR_syscalls 273
-
-/*
- * All syscalls below here should go away really,
- * these are provided for both review and as a porting
- * help for the C library version.
-*
- * Last chance: are any of these important enough to
- * enable by default?
- */
-#ifdef __ARCH_WANT_SYSCALL_NO_AT
-#define __NR_open 1024
-__SYSCALL(__NR_open, sys_open)
-#define __NR_link 1025
-__SYSCALL(__NR_link, sys_link)
-#define __NR_unlink 1026
-__SYSCALL(__NR_unlink, sys_unlink)
-#define __NR_mknod 1027
-__SYSCALL(__NR_mknod, sys_mknod)
-#define __NR_chmod 1028
-__SYSCALL(__NR_chmod, sys_chmod)
-#define __NR_chown 1029
-__SYSCALL(__NR_chown, sys_chown)
-#define __NR_mkdir 1030
-__SYSCALL(__NR_mkdir, sys_mkdir)
-#define __NR_rmdir 1031
-__SYSCALL(__NR_rmdir, sys_rmdir)
-#define __NR_lchown 1032
-__SYSCALL(__NR_lchown, sys_lchown)
-#define __NR_access 1033
-__SYSCALL(__NR_access, sys_access)
-#define __NR_rename 1034
-__SYSCALL(__NR_rename, sys_rename)
-#define __NR_readlink 1035
-__SYSCALL(__NR_readlink, sys_readlink)
-#define __NR_symlink 1036
-__SYSCALL(__NR_symlink, sys_symlink)
-#define __NR_utimes 1037
-__SYSCALL(__NR_utimes, sys_utimes)
-#define __NR3264_stat 1038
-__SC_3264(__NR3264_stat, sys_stat64, sys_newstat)
-#define __NR3264_lstat 1039
-__SC_3264(__NR3264_lstat, sys_lstat64, sys_newlstat)
-
-#undef __NR_syscalls
-#define __NR_syscalls (__NR3264_lstat+1)
-#endif /* __ARCH_WANT_SYSCALL_NO_AT */
-
-#ifdef __ARCH_WANT_SYSCALL_NO_FLAGS
-#define __NR_pipe 1040
-__SYSCALL(__NR_pipe, sys_pipe)
-#define __NR_dup2 1041
-__SYSCALL(__NR_dup2, sys_dup2)
-#define __NR_epoll_create 1042
-__SYSCALL(__NR_epoll_create, sys_epoll_create)
-#define __NR_inotify_init 1043
-__SYSCALL(__NR_inotify_init, sys_inotify_init)
-#define __NR_eventfd 1044
-__SYSCALL(__NR_eventfd, sys_eventfd)
-#define __NR_signalfd 1045
-__SYSCALL(__NR_signalfd, sys_signalfd)
-
-#undef __NR_syscalls
-#define __NR_syscalls (__NR_signalfd+1)
-#endif /* __ARCH_WANT_SYSCALL_NO_FLAGS */
-
-#if (__BITS_PER_LONG == 32 || defined(__SYSCALL_COMPAT)) && \
-     defined(__ARCH_WANT_SYSCALL_OFF_T)
-#define __NR_sendfile 1046
-__SYSCALL(__NR_sendfile, sys_sendfile)
-#define __NR_ftruncate 1047
-__SYSCALL(__NR_ftruncate, sys_ftruncate)
-#define __NR_truncate 1048
-__SYSCALL(__NR_truncate, sys_truncate)
-#define __NR_stat 1049
-__SYSCALL(__NR_stat, sys_newstat)
-#define __NR_lstat 1050
-__SYSCALL(__NR_lstat, sys_newlstat)
-#define __NR_fstat 1051
-__SYSCALL(__NR_fstat, sys_newfstat)
-#define __NR_fcntl 1052
-__SYSCALL(__NR_fcntl, sys_fcntl)
-#define __NR_fadvise64 1053
-#define __ARCH_WANT_SYS_FADVISE64
-__SYSCALL(__NR_fadvise64, sys_fadvise64)
-#define __NR_newfstatat 1054
-#define __ARCH_WANT_SYS_NEWFSTATAT
-__SYSCALL(__NR_newfstatat, sys_newfstatat)
-#define __NR_fstatfs 1055
-__SYSCALL(__NR_fstatfs, sys_fstatfs)
-#define __NR_statfs 1056
-__SYSCALL(__NR_statfs, sys_statfs)
-#define __NR_lseek 1057
-__SYSCALL(__NR_lseek, sys_lseek)
-#define __NR_mmap 1058
-__SYSCALL(__NR_mmap, sys_mmap)
-
-#undef __NR_syscalls
-#define __NR_syscalls (__NR_mmap+1)
-#endif /* 32 bit off_t syscalls */
-
-#ifdef __ARCH_WANT_SYSCALL_DEPRECATED
-#define __NR_alarm 1059
-#define __ARCH_WANT_SYS_ALARM
-__SYSCALL(__NR_alarm, sys_alarm)
-#define __NR_getpgrp 1060
-#define __ARCH_WANT_SYS_GETPGRP
-__SYSCALL(__NR_getpgrp, sys_getpgrp)
-#define __NR_pause 1061
-#define __ARCH_WANT_SYS_PAUSE
-__SYSCALL(__NR_pause, sys_pause)
-#define __NR_time 1062
-#define __ARCH_WANT_SYS_TIME
-#define __ARCH_WANT_COMPAT_SYS_TIME
-__SYSCALL(__NR_time, sys_time)
-#define __NR_utime 1063
-#define __ARCH_WANT_SYS_UTIME
-__SYSCALL(__NR_utime, sys_utime)
-
-#define __NR_creat 1064
-__SYSCALL(__NR_creat, sys_creat)
-#define __NR_getdents 1065
-#define __ARCH_WANT_SYS_GETDENTS
-__SYSCALL(__NR_getdents, sys_getdents)
-#define __NR_futimesat 1066
-__SYSCALL(__NR_futimesat, sys_futimesat)
-#define __NR_select 1067
-#define __ARCH_WANT_SYS_SELECT
-__SYSCALL(__NR_select, sys_select)
-#define __NR_poll 1068
-__SYSCALL(__NR_poll, sys_poll)
-#define __NR_epoll_wait 1069
-__SYSCALL(__NR_epoll_wait, sys_epoll_wait)
-#define __NR_ustat 1070
-__SYSCALL(__NR_ustat, sys_ustat)
-#define __NR_vfork 1071
-__SYSCALL(__NR_vfork, sys_vfork)
-#define __NR_oldwait4 1072
-__SYSCALL(__NR_oldwait4, sys_wait4)
-#define __NR_recv 1073
-__SYSCALL(__NR_recv, sys_recv)
-#define __NR_send 1074
-__SYSCALL(__NR_send, sys_send)
-#define __NR_bdflush 1075
-__SYSCALL(__NR_bdflush, sys_bdflush)
-#define __NR_umount 1076
-__SYSCALL(__NR_umount, sys_oldumount)
-#define __ARCH_WANT_SYS_OLDUMOUNT
-#define __NR_uselib 1077
-__SYSCALL(__NR_uselib, sys_uselib)
-#define __NR__sysctl 1078
-__SYSCALL(__NR__sysctl, sys_sysctl)
-
-#define __NR_fork 1079
-#ifdef CONFIG_MMU
-__SYSCALL(__NR_fork, sys_fork)
-#else
-__SYSCALL(__NR_fork, sys_ni_syscall)
-#endif /* CONFIG_MMU */
-
-#undef __NR_syscalls
-#define __NR_syscalls (__NR_fork+1)
-
-#endif /* __ARCH_WANT_SYSCALL_DEPRECATED */
-
-/*
- * 32 bit systems traditionally used different
- * syscalls for off_t and loff_t arguments, while
- * 64 bit systems only need the off_t version.
- * For new 32 bit platforms, there is no need to
- * implement the old 32 bit off_t syscalls, so
- * they take different names.
- * Here we map the numbers so that both versions
- * use the same syscall table layout.
- */
-#if __BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)
-#define __NR_fcntl __NR3264_fcntl
-#define __NR_statfs __NR3264_statfs
-#define __NR_fstatfs __NR3264_fstatfs
-#define __NR_truncate __NR3264_truncate
-#define __NR_ftruncate __NR3264_ftruncate
-#define __NR_lseek __NR3264_lseek
-#define __NR_sendfile __NR3264_sendfile
-#define __NR_newfstatat __NR3264_fstatat
-#define __NR_fstat __NR3264_fstat
-#define __NR_mmap __NR3264_mmap
-#define __NR_fadvise64 __NR3264_fadvise64
-#ifdef __NR3264_stat
-#define __NR_stat __NR3264_stat
-#define __NR_lstat __NR3264_lstat
-#endif
-#else
-#define __NR_fcntl64 __NR3264_fcntl
-#define __NR_statfs64 __NR3264_statfs
-#define __NR_fstatfs64 __NR3264_fstatfs
-#define __NR_truncate64 __NR3264_truncate
-#define __NR_ftruncate64 __NR3264_ftruncate
-#define __NR_llseek __NR3264_lseek
-#define __NR_sendfile64 __NR3264_sendfile
-#define __NR_fstatat64 __NR3264_fstatat
-#define __NR_fstat64 __NR3264_fstat
-#define __NR_mmap2 __NR3264_mmap
-#define __NR_fadvise64_64 __NR3264_fadvise64
-#ifdef __NR3264_stat
-#define __NR_stat64 __NR3264_stat
-#define __NR_lstat64 __NR3264_lstat
-#endif
-#endif
-
-#ifdef __KERNEL__
+#include <uapi/asm-generic/unistd.h>
 
 /*
  * These are required system calls, we should
@@ -925,5 +22,3 @@
 #ifndef cond_syscall
 #define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
 #endif
-
-#endif /* __KERNEL__ */
diff --git a/include/asm-generic/xor.h b/include/asm-generic/xor.h
index 6028fb8..b4d8432 100644
--- a/include/asm-generic/xor.h
+++ b/include/asm-generic/xor.h
@@ -693,7 +693,7 @@
 	.do_5 = xor_32regs_5,
 };
 
-static struct xor_block_template xor_block_8regs_p = {
+static struct xor_block_template xor_block_8regs_p __maybe_unused = {
 	.name = "8regs_prefetch",
 	.do_2 = xor_8regs_p_2,
 	.do_3 = xor_8regs_p_3,
@@ -701,7 +701,7 @@
 	.do_5 = xor_8regs_p_5,
 };
 
-static struct xor_block_template xor_block_32regs_p = {
+static struct xor_block_template xor_block_32regs_p __maybe_unused = {
 	.name = "32regs_prefetch",
 	.do_2 = xor_32regs_p_2,
 	.do_3 = xor_32regs_p_3,
diff --git a/include/drm/Kbuild b/include/drm/Kbuild
index 1e38a19..e69de29 100644
--- a/include/drm/Kbuild
+++ b/include/drm/Kbuild
@@ -1,15 +0,0 @@
-header-y += drm.h
-header-y += drm_fourcc.h
-header-y += drm_mode.h
-header-y += drm_sarea.h
-header-y += exynos_drm.h
-header-y += i810_drm.h
-header-y += i915_drm.h
-header-y += mga_drm.h
-header-y += nouveau_drm.h
-header-y += r128_drm.h
-header-y += radeon_drm.h
-header-y += savage_drm.h
-header-y += sis_drm.h
-header-y += via_drm.h
-header-y += vmwgfx_drm.h
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 1816bb3..3fa18b7 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -878,6 +878,7 @@
 extern char *drm_get_tv_select_name(int val);
 extern void drm_fb_release(struct drm_file *file_priv);
 extern int drm_mode_group_init_legacy_group(struct drm_device *dev, struct drm_mode_group *group);
+extern bool drm_probe_ddc(struct i2c_adapter *adapter);
 extern struct edid *drm_get_edid(struct drm_connector *connector,
 				 struct i2c_adapter *adapter);
 extern int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid);
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 1744b18c..fe06148 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -26,7 +26,19 @@
 #include <linux/types.h>
 #include <linux/i2c.h>
 
-/* From the VESA DisplayPort spec */
+/*
+ * Unless otherwise noted, all values are from the DP 1.1a spec.  Note that
+ * DP and DPCD versions are independent.  Differences from 1.0 are not noted,
+ * 1.0 devices basically don't exist in the wild.
+ *
+ * Abbreviations, in chronological order:
+ *
+ * eDP: Embedded DisplayPort version 1
+ * DPI: DisplayPort Interoperability Guideline v1.1a
+ * 1.2: DisplayPort 1.2
+ *
+ * 1.2 formally includes both eDP and DPI definitions.
+ */
 
 #define AUX_NATIVE_WRITE	0x8
 #define AUX_NATIVE_READ		0x9
@@ -53,7 +65,7 @@
 
 #define DP_MAX_LANE_COUNT                   0x002
 # define DP_MAX_LANE_COUNT_MASK		    0x1f
-# define DP_TPS3_SUPPORTED		    (1 << 6)
+# define DP_TPS3_SUPPORTED		    (1 << 6) /* 1.2 */
 # define DP_ENHANCED_FRAME_CAP		    (1 << 7)
 
 #define DP_MAX_DOWNSPREAD                   0x003
@@ -69,19 +81,33 @@
 /* 10b = TMDS or HDMI */
 /* 11b = Other */
 # define DP_FORMAT_CONVERSION               (1 << 3)
+# define DP_DETAILED_CAP_INFO_AVAILABLE	    (1 << 4) /* DPI */
 
 #define DP_MAIN_LINK_CHANNEL_CODING         0x006
 
 #define DP_DOWN_STREAM_PORT_COUNT	    0x007
-#define  DP_PORT_COUNT_MASK		    0x0f
-#define  DP_OUI_SUPPORT			    (1 << 7)
+# define DP_PORT_COUNT_MASK		    0x0f
+# define DP_MSA_TIMING_PAR_IGNORED	    (1 << 6) /* eDP */
+# define DP_OUI_SUPPORT			    (1 << 7)
 
-#define DP_EDP_CONFIGURATION_CAP            0x00d
-#define DP_TRAINING_AUX_RD_INTERVAL         0x00e
+#define DP_I2C_SPEED_CAP		    0x00c    /* DPI */
+# define DP_I2C_SPEED_1K		    0x01
+# define DP_I2C_SPEED_5K		    0x02
+# define DP_I2C_SPEED_10K		    0x04
+# define DP_I2C_SPEED_100K		    0x08
+# define DP_I2C_SPEED_400K		    0x10
+# define DP_I2C_SPEED_1M		    0x20
 
-#define DP_PSR_SUPPORT                      0x070
+#define DP_EDP_CONFIGURATION_CAP            0x00d   /* XXX 1.2? */
+#define DP_TRAINING_AUX_RD_INTERVAL         0x00e   /* XXX 1.2? */
+
+/* Multiple stream transport */
+#define DP_MSTM_CAP			    0x021   /* 1.2 */
+# define DP_MST_CAP			    (1 << 0)
+
+#define DP_PSR_SUPPORT                      0x070   /* XXX 1.2? */
 # define DP_PSR_IS_SUPPORTED                1
-#define DP_PSR_CAPS                         0x071
+#define DP_PSR_CAPS                         0x071   /* XXX 1.2? */
 # define DP_PSR_NO_TRAIN_ON_EXIT            1
 # define DP_PSR_SETUP_TIME_330              (0 << 1)
 # define DP_PSR_SETUP_TIME_275              (1 << 1)
@@ -93,11 +119,36 @@
 # define DP_PSR_SETUP_TIME_MASK             (7 << 1)
 # define DP_PSR_SETUP_TIME_SHIFT            1
 
+/*
+ * 0x80-0x8f describe downstream port capabilities, but there are two layouts
+ * based on whether DP_DETAILED_CAP_INFO_AVAILABLE was set.  If it was not,
+ * each port's descriptor is one byte wide.  If it was set, each port's is
+ * four bytes wide, starting with the one byte from the base info.  As of
+ * DP interop v1.1a only VGA defines additional detail.
+ */
+
+/* offset 0 */
+#define DP_DOWNSTREAM_PORT_0		    0x80
+# define DP_DS_PORT_TYPE_MASK		    (7 << 0)
+# define DP_DS_PORT_TYPE_DP		    0
+# define DP_DS_PORT_TYPE_VGA		    1
+# define DP_DS_PORT_TYPE_DVI		    2
+# define DP_DS_PORT_TYPE_HDMI		    3
+# define DP_DS_PORT_TYPE_NON_EDID	    4
+# define DP_DS_PORT_HPD			    (1 << 3)
+/* offset 1 for VGA is maximum megapixels per second / 8 */
+/* offset 2 */
+# define DP_DS_VGA_MAX_BPC_MASK		    (3 << 0)
+# define DP_DS_VGA_8BPC			    0
+# define DP_DS_VGA_10BPC		    1
+# define DP_DS_VGA_12BPC		    2
+# define DP_DS_VGA_16BPC		    3
+
 /* link configuration */
 #define	DP_LINK_BW_SET		            0x100
 # define DP_LINK_BW_1_62		    0x06
 # define DP_LINK_BW_2_7			    0x0a
-# define DP_LINK_BW_5_4			    0x14
+# define DP_LINK_BW_5_4			    0x14    /* 1.2 */
 
 #define DP_LANE_COUNT_SET	            0x101
 # define DP_LANE_COUNT_MASK		    0x0f
@@ -107,7 +158,7 @@
 # define DP_TRAINING_PATTERN_DISABLE	    0
 # define DP_TRAINING_PATTERN_1		    1
 # define DP_TRAINING_PATTERN_2		    2
-# define DP_TRAINING_PATTERN_3		    3
+# define DP_TRAINING_PATTERN_3		    3	    /* 1.2 */
 # define DP_TRAINING_PATTERN_MASK	    0x3
 
 # define DP_LINK_QUAL_PATTERN_DISABLE	    (0 << 2)
@@ -148,24 +199,38 @@
 
 #define DP_DOWNSPREAD_CTRL		    0x107
 # define DP_SPREAD_AMP_0_5		    (1 << 4)
+# define DP_MSA_TIMING_PAR_IGNORE_EN	    (1 << 7) /* eDP */
 
 #define DP_MAIN_LINK_CHANNEL_CODING_SET	    0x108
 # define DP_SET_ANSI_8B10B		    (1 << 0)
 
-#define DP_PSR_EN_CFG			    0x170
+#define DP_I2C_SPEED_CONTROL_STATUS	    0x109   /* DPI */
+/* bitmask as for DP_I2C_SPEED_CAP */
+
+#define DP_EDP_CONFIGURATION_SET            0x10a   /* XXX 1.2? */
+
+#define DP_MSTM_CTRL			    0x111   /* 1.2 */
+# define DP_MST_EN			    (1 << 0)
+# define DP_UP_REQ_EN			    (1 << 1)
+# define DP_UPSTREAM_IS_SRC		    (1 << 2)
+
+#define DP_PSR_EN_CFG			    0x170   /* XXX 1.2? */
 # define DP_PSR_ENABLE			    (1 << 0)
 # define DP_PSR_MAIN_LINK_ACTIVE	    (1 << 1)
 # define DP_PSR_CRC_VERIFICATION	    (1 << 2)
 # define DP_PSR_FRAME_CAPTURE		    (1 << 3)
 
+#define DP_SINK_COUNT			    0x200
+/* prior to 1.2 bit 7 was reserved mbz */
+# define DP_GET_SINK_COUNT(x)		    ((((x) & 0x80) >> 1) | ((x) & 0x3f))
+# define DP_SINK_CP_READY		    (1 << 6)
+
 #define DP_DEVICE_SERVICE_IRQ_VECTOR	    0x201
 # define DP_REMOTE_CONTROL_COMMAND_PENDING  (1 << 0)
 # define DP_AUTOMATED_TEST_REQUEST	    (1 << 1)
 # define DP_CP_IRQ			    (1 << 2)
 # define DP_SINK_SPECIFIC_IRQ		    (1 << 6)
 
-#define DP_EDP_CONFIGURATION_SET            0x10a
-
 #define DP_LANE0_1_STATUS		    0x202
 #define DP_LANE2_3_STATUS		    0x203
 # define DP_LANE_CR_DONE		    (1 << 0)
@@ -225,14 +290,14 @@
 # define DP_SET_POWER_D0                    0x1
 # define DP_SET_POWER_D3                    0x2
 
-#define DP_PSR_ERROR_STATUS                 0x2006
+#define DP_PSR_ERROR_STATUS                 0x2006  /* XXX 1.2? */
 # define DP_PSR_LINK_CRC_ERROR              (1 << 0)
 # define DP_PSR_RFB_STORAGE_ERROR           (1 << 1)
 
-#define DP_PSR_ESI                          0x2007
+#define DP_PSR_ESI                          0x2007  /* XXX 1.2? */
 # define DP_PSR_CAPS_CHANGE                 (1 << 0)
 
-#define DP_PSR_STATUS                       0x2008
+#define DP_PSR_STATUS                       0x2008  /* XXX 1.2? */
 # define DP_PSR_SINK_INACTIVE               0
 # define DP_PSR_SINK_ACTIVE_SRC_SYNCED      1
 # define DP_PSR_SINK_ACTIVE_RFB             2
diff --git a/include/drm/exynos_drm.h b/include/drm/exynos_drm.h
index 1f2acdf..3c13a3a 100644
--- a/include/drm/exynos_drm.h
+++ b/include/drm/exynos_drm.h
@@ -25,182 +25,10 @@
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  * OTHER DEALINGS IN THE SOFTWARE.
  */
-
 #ifndef _EXYNOS_DRM_H_
 #define _EXYNOS_DRM_H_
 
-#include <drm/drm.h>
-
-/**
- * User-desired buffer creation information structure.
- *
- * @size: user-desired memory allocation size.
- *	- this size value would be page-aligned internally.
- * @flags: user request for setting memory type or cache attributes.
- * @handle: returned a handle to created gem object.
- *	- this handle will be set by gem module of kernel side.
- */
-struct drm_exynos_gem_create {
-	uint64_t size;
-	unsigned int flags;
-	unsigned int handle;
-};
-
-/**
- * A structure for getting buffer offset.
- *
- * @handle: a pointer to gem object created.
- * @pad: just padding to be 64-bit aligned.
- * @offset: relatived offset value of the memory region allocated.
- *	- this value should be set by user.
- */
-struct drm_exynos_gem_map_off {
-	unsigned int handle;
-	unsigned int pad;
-	uint64_t offset;
-};
-
-/**
- * A structure for mapping buffer.
- *
- * @handle: a handle to gem object created.
- * @pad: just padding to be 64-bit aligned.
- * @size: memory size to be mapped.
- * @mapped: having user virtual address mmaped.
- *	- this variable would be filled by exynos gem module
- *	of kernel side with user virtual address which is allocated
- *	by do_mmap().
- */
-struct drm_exynos_gem_mmap {
-	unsigned int handle;
-	unsigned int pad;
-	uint64_t size;
-	uint64_t mapped;
-};
-
-/**
- * A structure to gem information.
- *
- * @handle: a handle to gem object created.
- * @flags: flag value including memory type and cache attribute and
- *	this value would be set by driver.
- * @size: size to memory region allocated by gem and this size would
- *	be set by driver.
- */
-struct drm_exynos_gem_info {
-	unsigned int handle;
-	unsigned int flags;
-	uint64_t size;
-};
-
-/**
- * A structure for user connection request of virtual display.
- *
- * @connection: indicate whether doing connetion or not by user.
- * @extensions: if this value is 1 then the vidi driver would need additional
- *	128bytes edid data.
- * @edid: the edid data pointer from user side.
- */
-struct drm_exynos_vidi_connection {
-	unsigned int connection;
-	unsigned int extensions;
-	uint64_t edid;
-};
-
-/* memory type definitions. */
-enum e_drm_exynos_gem_mem_type {
-	/* Physically Continuous memory and used as default. */
-	EXYNOS_BO_CONTIG	= 0 << 0,
-	/* Physically Non-Continuous memory. */
-	EXYNOS_BO_NONCONTIG	= 1 << 0,
-	/* non-cachable mapping and used as default. */
-	EXYNOS_BO_NONCACHABLE	= 0 << 1,
-	/* cachable mapping. */
-	EXYNOS_BO_CACHABLE	= 1 << 1,
-	/* write-combine mapping. */
-	EXYNOS_BO_WC		= 1 << 2,
-	EXYNOS_BO_MASK		= EXYNOS_BO_NONCONTIG | EXYNOS_BO_CACHABLE |
-					EXYNOS_BO_WC
-};
-
-struct drm_exynos_g2d_get_ver {
-	__u32	major;
-	__u32	minor;
-};
-
-struct drm_exynos_g2d_cmd {
-	__u32	offset;
-	__u32	data;
-};
-
-enum drm_exynos_g2d_event_type {
-	G2D_EVENT_NOT,
-	G2D_EVENT_NONSTOP,
-	G2D_EVENT_STOP,		/* not yet */
-};
-
-struct drm_exynos_g2d_set_cmdlist {
-	__u64					cmd;
-	__u64					cmd_gem;
-	__u32					cmd_nr;
-	__u32					cmd_gem_nr;
-
-	/* for g2d event */
-	__u64					event_type;
-	__u64					user_data;
-};
-
-struct drm_exynos_g2d_exec {
-	__u64					async;
-};
-
-#define DRM_EXYNOS_GEM_CREATE		0x00
-#define DRM_EXYNOS_GEM_MAP_OFFSET	0x01
-#define DRM_EXYNOS_GEM_MMAP		0x02
-/* Reserved 0x03 ~ 0x05 for exynos specific gem ioctl */
-#define DRM_EXYNOS_GEM_GET		0x04
-#define DRM_EXYNOS_VIDI_CONNECTION	0x07
-
-/* G2D */
-#define DRM_EXYNOS_G2D_GET_VER		0x20
-#define DRM_EXYNOS_G2D_SET_CMDLIST	0x21
-#define DRM_EXYNOS_G2D_EXEC		0x22
-
-#define DRM_IOCTL_EXYNOS_GEM_CREATE		DRM_IOWR(DRM_COMMAND_BASE + \
-		DRM_EXYNOS_GEM_CREATE, struct drm_exynos_gem_create)
-
-#define DRM_IOCTL_EXYNOS_GEM_MAP_OFFSET	DRM_IOWR(DRM_COMMAND_BASE + \
-		DRM_EXYNOS_GEM_MAP_OFFSET, struct drm_exynos_gem_map_off)
-
-#define DRM_IOCTL_EXYNOS_GEM_MMAP	DRM_IOWR(DRM_COMMAND_BASE + \
-		DRM_EXYNOS_GEM_MMAP, struct drm_exynos_gem_mmap)
-
-#define DRM_IOCTL_EXYNOS_GEM_GET	DRM_IOWR(DRM_COMMAND_BASE + \
-		DRM_EXYNOS_GEM_GET,	struct drm_exynos_gem_info)
-
-#define DRM_IOCTL_EXYNOS_VIDI_CONNECTION	DRM_IOWR(DRM_COMMAND_BASE + \
-		DRM_EXYNOS_VIDI_CONNECTION, struct drm_exynos_vidi_connection)
-
-#define DRM_IOCTL_EXYNOS_G2D_GET_VER		DRM_IOWR(DRM_COMMAND_BASE + \
-		DRM_EXYNOS_G2D_GET_VER, struct drm_exynos_g2d_get_ver)
-#define DRM_IOCTL_EXYNOS_G2D_SET_CMDLIST	DRM_IOWR(DRM_COMMAND_BASE + \
-		DRM_EXYNOS_G2D_SET_CMDLIST, struct drm_exynos_g2d_set_cmdlist)
-#define DRM_IOCTL_EXYNOS_G2D_EXEC		DRM_IOWR(DRM_COMMAND_BASE + \
-		DRM_EXYNOS_G2D_EXEC, struct drm_exynos_g2d_exec)
-
-/* EXYNOS specific events */
-#define DRM_EXYNOS_G2D_EVENT		0x80000000
-
-struct drm_exynos_g2d_event {
-	struct drm_event	base;
-	__u64			user_data;
-	__u32			tv_sec;
-	__u32			tv_usec;
-	__u32			cmdlist_no;
-	__u32			reserved;
-};
-
-#ifdef __KERNEL__
+#include <uapi/drm/exynos_drm.h>
 
 /**
  * A structure for lcd panel information.
@@ -257,5 +85,4 @@
 	int (*get_hpd)(void);
 };
 
-#endif	/* __KERNEL__ */
 #endif	/* _EXYNOS_DRM_H_ */
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
index a940d4e..63d609d 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/i915_drm.h
@@ -23,933 +23,15 @@
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  *
  */
-
 #ifndef _I915_DRM_H_
 #define _I915_DRM_H_
 
-#include <drm/drm.h>
+#include <uapi/drm/i915_drm.h>
 
-/* Please note that modifications to all structs defined here are
- * subject to backwards-compatibility constraints.
- */
-
-#ifdef __KERNEL__
 /* For use by IPS driver */
 extern unsigned long i915_read_mch_val(void);
 extern bool i915_gpu_raise(void);
 extern bool i915_gpu_lower(void);
 extern bool i915_gpu_busy(void);
 extern bool i915_gpu_turbo_disable(void);
-#endif
-
-/* Each region is a minimum of 16k, and there are at most 255 of them.
- */
-#define I915_NR_TEX_REGIONS 255	/* table size 2k - maximum due to use
-				 * of chars for next/prev indices */
-#define I915_LOG_MIN_TEX_REGION_SIZE 14
-
-typedef struct _drm_i915_init {
-	enum {
-		I915_INIT_DMA = 0x01,
-		I915_CLEANUP_DMA = 0x02,
-		I915_RESUME_DMA = 0x03
-	} func;
-	unsigned int mmio_offset;
-	int sarea_priv_offset;
-	unsigned int ring_start;
-	unsigned int ring_end;
-	unsigned int ring_size;
-	unsigned int front_offset;
-	unsigned int back_offset;
-	unsigned int depth_offset;
-	unsigned int w;
-	unsigned int h;
-	unsigned int pitch;
-	unsigned int pitch_bits;
-	unsigned int back_pitch;
-	unsigned int depth_pitch;
-	unsigned int cpp;
-	unsigned int chipset;
-} drm_i915_init_t;
-
-typedef struct _drm_i915_sarea {
-	struct drm_tex_region texList[I915_NR_TEX_REGIONS + 1];
-	int last_upload;	/* last time texture was uploaded */
-	int last_enqueue;	/* last time a buffer was enqueued */
-	int last_dispatch;	/* age of the most recently dispatched buffer */
-	int ctxOwner;		/* last context to upload state */
-	int texAge;
-	int pf_enabled;		/* is pageflipping allowed? */
-	int pf_active;
-	int pf_current_page;	/* which buffer is being displayed? */
-	int perf_boxes;		/* performance boxes to be displayed */
-	int width, height;      /* screen size in pixels */
-
-	drm_handle_t front_handle;
-	int front_offset;
-	int front_size;
-
-	drm_handle_t back_handle;
-	int back_offset;
-	int back_size;
-
-	drm_handle_t depth_handle;
-	int depth_offset;
-	int depth_size;
-
-	drm_handle_t tex_handle;
-	int tex_offset;
-	int tex_size;
-	int log_tex_granularity;
-	int pitch;
-	int rotation;           /* 0, 90, 180 or 270 */
-	int rotated_offset;
-	int rotated_size;
-	int rotated_pitch;
-	int virtualX, virtualY;
-
-	unsigned int front_tiled;
-	unsigned int back_tiled;
-	unsigned int depth_tiled;
-	unsigned int rotated_tiled;
-	unsigned int rotated2_tiled;
-
-	int pipeA_x;
-	int pipeA_y;
-	int pipeA_w;
-	int pipeA_h;
-	int pipeB_x;
-	int pipeB_y;
-	int pipeB_w;
-	int pipeB_h;
-
-	/* fill out some space for old userspace triple buffer */
-	drm_handle_t unused_handle;
-	__u32 unused1, unused2, unused3;
-
-	/* buffer object handles for static buffers. May change
-	 * over the lifetime of the client.
-	 */
-	__u32 front_bo_handle;
-	__u32 back_bo_handle;
-	__u32 unused_bo_handle;
-	__u32 depth_bo_handle;
-
-} drm_i915_sarea_t;
-
-/* due to userspace building against these headers we need some compat here */
-#define planeA_x pipeA_x
-#define planeA_y pipeA_y
-#define planeA_w pipeA_w
-#define planeA_h pipeA_h
-#define planeB_x pipeB_x
-#define planeB_y pipeB_y
-#define planeB_w pipeB_w
-#define planeB_h pipeB_h
-
-/* Flags for perf_boxes
- */
-#define I915_BOX_RING_EMPTY    0x1
-#define I915_BOX_FLIP          0x2
-#define I915_BOX_WAIT          0x4
-#define I915_BOX_TEXTURE_LOAD  0x8
-#define I915_BOX_LOST_CONTEXT  0x10
-
-/* I915 specific ioctls
- * The device specific ioctl range is 0x40 to 0x79.
- */
-#define DRM_I915_INIT		0x00
-#define DRM_I915_FLUSH		0x01
-#define DRM_I915_FLIP		0x02
-#define DRM_I915_BATCHBUFFER	0x03
-#define DRM_I915_IRQ_EMIT	0x04
-#define DRM_I915_IRQ_WAIT	0x05
-#define DRM_I915_GETPARAM	0x06
-#define DRM_I915_SETPARAM	0x07
-#define DRM_I915_ALLOC		0x08
-#define DRM_I915_FREE		0x09
-#define DRM_I915_INIT_HEAP	0x0a
-#define DRM_I915_CMDBUFFER	0x0b
-#define DRM_I915_DESTROY_HEAP	0x0c
-#define DRM_I915_SET_VBLANK_PIPE	0x0d
-#define DRM_I915_GET_VBLANK_PIPE	0x0e
-#define DRM_I915_VBLANK_SWAP	0x0f
-#define DRM_I915_HWS_ADDR	0x11
-#define DRM_I915_GEM_INIT	0x13
-#define DRM_I915_GEM_EXECBUFFER	0x14
-#define DRM_I915_GEM_PIN	0x15
-#define DRM_I915_GEM_UNPIN	0x16
-#define DRM_I915_GEM_BUSY	0x17
-#define DRM_I915_GEM_THROTTLE	0x18
-#define DRM_I915_GEM_ENTERVT	0x19
-#define DRM_I915_GEM_LEAVEVT	0x1a
-#define DRM_I915_GEM_CREATE	0x1b
-#define DRM_I915_GEM_PREAD	0x1c
-#define DRM_I915_GEM_PWRITE	0x1d
-#define DRM_I915_GEM_MMAP	0x1e
-#define DRM_I915_GEM_SET_DOMAIN	0x1f
-#define DRM_I915_GEM_SW_FINISH	0x20
-#define DRM_I915_GEM_SET_TILING	0x21
-#define DRM_I915_GEM_GET_TILING	0x22
-#define DRM_I915_GEM_GET_APERTURE 0x23
-#define DRM_I915_GEM_MMAP_GTT	0x24
-#define DRM_I915_GET_PIPE_FROM_CRTC_ID	0x25
-#define DRM_I915_GEM_MADVISE	0x26
-#define DRM_I915_OVERLAY_PUT_IMAGE	0x27
-#define DRM_I915_OVERLAY_ATTRS	0x28
-#define DRM_I915_GEM_EXECBUFFER2	0x29
-#define DRM_I915_GET_SPRITE_COLORKEY	0x2a
-#define DRM_I915_SET_SPRITE_COLORKEY	0x2b
-#define DRM_I915_GEM_WAIT	0x2c
-#define DRM_I915_GEM_CONTEXT_CREATE	0x2d
-#define DRM_I915_GEM_CONTEXT_DESTROY	0x2e
-#define DRM_I915_GEM_SET_CACHING	0x2f
-#define DRM_I915_GEM_GET_CACHING	0x30
-#define DRM_I915_REG_READ		0x31
-
-#define DRM_IOCTL_I915_INIT		DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
-#define DRM_IOCTL_I915_FLUSH		DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
-#define DRM_IOCTL_I915_FLIP		DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLIP)
-#define DRM_IOCTL_I915_BATCHBUFFER	DRM_IOW( DRM_COMMAND_BASE + DRM_I915_BATCHBUFFER, drm_i915_batchbuffer_t)
-#define DRM_IOCTL_I915_IRQ_EMIT         DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_IRQ_EMIT, drm_i915_irq_emit_t)
-#define DRM_IOCTL_I915_IRQ_WAIT         DRM_IOW( DRM_COMMAND_BASE + DRM_I915_IRQ_WAIT, drm_i915_irq_wait_t)
-#define DRM_IOCTL_I915_GETPARAM         DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GETPARAM, drm_i915_getparam_t)
-#define DRM_IOCTL_I915_SETPARAM         DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SETPARAM, drm_i915_setparam_t)
-#define DRM_IOCTL_I915_ALLOC            DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_ALLOC, drm_i915_mem_alloc_t)
-#define DRM_IOCTL_I915_FREE             DRM_IOW( DRM_COMMAND_BASE + DRM_I915_FREE, drm_i915_mem_free_t)
-#define DRM_IOCTL_I915_INIT_HEAP        DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT_HEAP, drm_i915_mem_init_heap_t)
-#define DRM_IOCTL_I915_CMDBUFFER	DRM_IOW( DRM_COMMAND_BASE + DRM_I915_CMDBUFFER, drm_i915_cmdbuffer_t)
-#define DRM_IOCTL_I915_DESTROY_HEAP	DRM_IOW( DRM_COMMAND_BASE + DRM_I915_DESTROY_HEAP, drm_i915_mem_destroy_heap_t)
-#define DRM_IOCTL_I915_SET_VBLANK_PIPE	DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
-#define DRM_IOCTL_I915_GET_VBLANK_PIPE	DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
-#define DRM_IOCTL_I915_VBLANK_SWAP	DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t)
-#define DRM_IOCTL_I915_HWS_ADDR		DRM_IOW(DRM_COMMAND_BASE + DRM_I915_HWS_ADDR, struct drm_i915_gem_init)
-#define DRM_IOCTL_I915_GEM_INIT		DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_INIT, struct drm_i915_gem_init)
-#define DRM_IOCTL_I915_GEM_EXECBUFFER	DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER, struct drm_i915_gem_execbuffer)
-#define DRM_IOCTL_I915_GEM_EXECBUFFER2	DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER2, struct drm_i915_gem_execbuffer2)
-#define DRM_IOCTL_I915_GEM_PIN		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_PIN, struct drm_i915_gem_pin)
-#define DRM_IOCTL_I915_GEM_UNPIN	DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_UNPIN, struct drm_i915_gem_unpin)
-#define DRM_IOCTL_I915_GEM_BUSY		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_BUSY, struct drm_i915_gem_busy)
-#define DRM_IOCTL_I915_GEM_SET_CACHING		DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_SET_CACHING, struct drm_i915_gem_caching)
-#define DRM_IOCTL_I915_GEM_GET_CACHING		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_GET_CACHING, struct drm_i915_gem_caching)
-#define DRM_IOCTL_I915_GEM_THROTTLE	DRM_IO ( DRM_COMMAND_BASE + DRM_I915_GEM_THROTTLE)
-#define DRM_IOCTL_I915_GEM_ENTERVT	DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_ENTERVT)
-#define DRM_IOCTL_I915_GEM_LEAVEVT	DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_LEAVEVT)
-#define DRM_IOCTL_I915_GEM_CREATE	DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE, struct drm_i915_gem_create)
-#define DRM_IOCTL_I915_GEM_PREAD	DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PREAD, struct drm_i915_gem_pread)
-#define DRM_IOCTL_I915_GEM_PWRITE	DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite)
-#define DRM_IOCTL_I915_GEM_MMAP		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap)
-#define DRM_IOCTL_I915_GEM_MMAP_GTT	DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP_GTT, struct drm_i915_gem_mmap_gtt)
-#define DRM_IOCTL_I915_GEM_SET_DOMAIN	DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SET_DOMAIN, struct drm_i915_gem_set_domain)
-#define DRM_IOCTL_I915_GEM_SW_FINISH	DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SW_FINISH, struct drm_i915_gem_sw_finish)
-#define DRM_IOCTL_I915_GEM_SET_TILING	DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_SET_TILING, struct drm_i915_gem_set_tiling)
-#define DRM_IOCTL_I915_GEM_GET_TILING	DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling)
-#define DRM_IOCTL_I915_GEM_GET_APERTURE	DRM_IOR  (DRM_COMMAND_BASE + DRM_I915_GEM_GET_APERTURE, struct drm_i915_gem_get_aperture)
-#define DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_PIPE_FROM_CRTC_ID, struct drm_i915_get_pipe_from_crtc_id)
-#define DRM_IOCTL_I915_GEM_MADVISE	DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MADVISE, struct drm_i915_gem_madvise)
-#define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE	DRM_IOW(DRM_COMMAND_BASE + DRM_I915_OVERLAY_PUT_IMAGE, struct drm_intel_overlay_put_image)
-#define DRM_IOCTL_I915_OVERLAY_ATTRS	DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_OVERLAY_ATTRS, struct drm_intel_overlay_attrs)
-#define DRM_IOCTL_I915_SET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey)
-#define DRM_IOCTL_I915_GET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey)
-#define DRM_IOCTL_I915_GEM_WAIT		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_WAIT, struct drm_i915_gem_wait)
-#define DRM_IOCTL_I915_GEM_CONTEXT_CREATE	DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_CREATE, struct drm_i915_gem_context_create)
-#define DRM_IOCTL_I915_GEM_CONTEXT_DESTROY	DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_DESTROY, struct drm_i915_gem_context_destroy)
-#define DRM_IOCTL_I915_REG_READ			DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_REG_READ, struct drm_i915_reg_read)
-
-/* Allow drivers to submit batchbuffers directly to hardware, relying
- * on the security mechanisms provided by hardware.
- */
-typedef struct drm_i915_batchbuffer {
-	int start;		/* agp offset */
-	int used;		/* nr bytes in use */
-	int DR1;		/* hw flags for GFX_OP_DRAWRECT_INFO */
-	int DR4;		/* window origin for GFX_OP_DRAWRECT_INFO */
-	int num_cliprects;	/* mulitpass with multiple cliprects? */
-	struct drm_clip_rect __user *cliprects;	/* pointer to userspace cliprects */
-} drm_i915_batchbuffer_t;
-
-/* As above, but pass a pointer to userspace buffer which can be
- * validated by the kernel prior to sending to hardware.
- */
-typedef struct _drm_i915_cmdbuffer {
-	char __user *buf;	/* pointer to userspace command buffer */
-	int sz;			/* nr bytes in buf */
-	int DR1;		/* hw flags for GFX_OP_DRAWRECT_INFO */
-	int DR4;		/* window origin for GFX_OP_DRAWRECT_INFO */
-	int num_cliprects;	/* mulitpass with multiple cliprects? */
-	struct drm_clip_rect __user *cliprects;	/* pointer to userspace cliprects */
-} drm_i915_cmdbuffer_t;
-
-/* Userspace can request & wait on irq's:
- */
-typedef struct drm_i915_irq_emit {
-	int __user *irq_seq;
-} drm_i915_irq_emit_t;
-
-typedef struct drm_i915_irq_wait {
-	int irq_seq;
-} drm_i915_irq_wait_t;
-
-/* Ioctl to query kernel params:
- */
-#define I915_PARAM_IRQ_ACTIVE            1
-#define I915_PARAM_ALLOW_BATCHBUFFER     2
-#define I915_PARAM_LAST_DISPATCH         3
-#define I915_PARAM_CHIPSET_ID            4
-#define I915_PARAM_HAS_GEM               5
-#define I915_PARAM_NUM_FENCES_AVAIL      6
-#define I915_PARAM_HAS_OVERLAY           7
-#define I915_PARAM_HAS_PAGEFLIPPING	 8
-#define I915_PARAM_HAS_EXECBUF2          9
-#define I915_PARAM_HAS_BSD		 10
-#define I915_PARAM_HAS_BLT		 11
-#define I915_PARAM_HAS_RELAXED_FENCING	 12
-#define I915_PARAM_HAS_COHERENT_RINGS	 13
-#define I915_PARAM_HAS_EXEC_CONSTANTS	 14
-#define I915_PARAM_HAS_RELAXED_DELTA	 15
-#define I915_PARAM_HAS_GEN7_SOL_RESET	 16
-#define I915_PARAM_HAS_LLC     	 	 17
-#define I915_PARAM_HAS_ALIASING_PPGTT	 18
-#define I915_PARAM_HAS_WAIT_TIMEOUT	 19
-#define I915_PARAM_HAS_SEMAPHORES	 20
-#define I915_PARAM_HAS_PRIME_VMAP_FLUSH	 21
-#define I915_PARAM_RSVD_FOR_FUTURE_USE	 22
-
-typedef struct drm_i915_getparam {
-	int param;
-	int __user *value;
-} drm_i915_getparam_t;
-
-/* Ioctl to set kernel params:
- */
-#define I915_SETPARAM_USE_MI_BATCHBUFFER_START            1
-#define I915_SETPARAM_TEX_LRU_LOG_GRANULARITY             2
-#define I915_SETPARAM_ALLOW_BATCHBUFFER                   3
-#define I915_SETPARAM_NUM_USED_FENCES                     4
-
-typedef struct drm_i915_setparam {
-	int param;
-	int value;
-} drm_i915_setparam_t;
-
-/* A memory manager for regions of shared memory:
- */
-#define I915_MEM_REGION_AGP 1
-
-typedef struct drm_i915_mem_alloc {
-	int region;
-	int alignment;
-	int size;
-	int __user *region_offset;	/* offset from start of fb or agp */
-} drm_i915_mem_alloc_t;
-
-typedef struct drm_i915_mem_free {
-	int region;
-	int region_offset;
-} drm_i915_mem_free_t;
-
-typedef struct drm_i915_mem_init_heap {
-	int region;
-	int size;
-	int start;
-} drm_i915_mem_init_heap_t;
-
-/* Allow memory manager to be torn down and re-initialized (eg on
- * rotate):
- */
-typedef struct drm_i915_mem_destroy_heap {
-	int region;
-} drm_i915_mem_destroy_heap_t;
-
-/* Allow X server to configure which pipes to monitor for vblank signals
- */
-#define	DRM_I915_VBLANK_PIPE_A	1
-#define	DRM_I915_VBLANK_PIPE_B	2
-
-typedef struct drm_i915_vblank_pipe {
-	int pipe;
-} drm_i915_vblank_pipe_t;
-
-/* Schedule buffer swap at given vertical blank:
- */
-typedef struct drm_i915_vblank_swap {
-	drm_drawable_t drawable;
-	enum drm_vblank_seq_type seqtype;
-	unsigned int sequence;
-} drm_i915_vblank_swap_t;
-
-typedef struct drm_i915_hws_addr {
-	__u64 addr;
-} drm_i915_hws_addr_t;
-
-struct drm_i915_gem_init {
-	/**
-	 * Beginning offset in the GTT to be managed by the DRM memory
-	 * manager.
-	 */
-	__u64 gtt_start;
-	/**
-	 * Ending offset in the GTT to be managed by the DRM memory
-	 * manager.
-	 */
-	__u64 gtt_end;
-};
-
-struct drm_i915_gem_create {
-	/**
-	 * Requested size for the object.
-	 *
-	 * The (page-aligned) allocated size for the object will be returned.
-	 */
-	__u64 size;
-	/**
-	 * Returned handle for the object.
-	 *
-	 * Object handles are nonzero.
-	 */
-	__u32 handle;
-	__u32 pad;
-};
-
-struct drm_i915_gem_pread {
-	/** Handle for the object being read. */
-	__u32 handle;
-	__u32 pad;
-	/** Offset into the object to read from */
-	__u64 offset;
-	/** Length of data to read */
-	__u64 size;
-	/**
-	 * Pointer to write the data into.
-	 *
-	 * This is a fixed-size type for 32/64 compatibility.
-	 */
-	__u64 data_ptr;
-};
-
-struct drm_i915_gem_pwrite {
-	/** Handle for the object being written to. */
-	__u32 handle;
-	__u32 pad;
-	/** Offset into the object to write to */
-	__u64 offset;
-	/** Length of data to write */
-	__u64 size;
-	/**
-	 * Pointer to read the data from.
-	 *
-	 * This is a fixed-size type for 32/64 compatibility.
-	 */
-	__u64 data_ptr;
-};
-
-struct drm_i915_gem_mmap {
-	/** Handle for the object being mapped. */
-	__u32 handle;
-	__u32 pad;
-	/** Offset in the object to map. */
-	__u64 offset;
-	/**
-	 * Length of data to map.
-	 *
-	 * The value will be page-aligned.
-	 */
-	__u64 size;
-	/**
-	 * Returned pointer the data was mapped at.
-	 *
-	 * This is a fixed-size type for 32/64 compatibility.
-	 */
-	__u64 addr_ptr;
-};
-
-struct drm_i915_gem_mmap_gtt {
-	/** Handle for the object being mapped. */
-	__u32 handle;
-	__u32 pad;
-	/**
-	 * Fake offset to use for subsequent mmap call
-	 *
-	 * This is a fixed-size type for 32/64 compatibility.
-	 */
-	__u64 offset;
-};
-
-struct drm_i915_gem_set_domain {
-	/** Handle for the object */
-	__u32 handle;
-
-	/** New read domains */
-	__u32 read_domains;
-
-	/** New write domain */
-	__u32 write_domain;
-};
-
-struct drm_i915_gem_sw_finish {
-	/** Handle for the object */
-	__u32 handle;
-};
-
-struct drm_i915_gem_relocation_entry {
-	/**
-	 * Handle of the buffer being pointed to by this relocation entry.
-	 *
-	 * It's appealing to make this be an index into the mm_validate_entry
-	 * list to refer to the buffer, but this allows the driver to create
-	 * a relocation list for state buffers and not re-write it per
-	 * exec using the buffer.
-	 */
-	__u32 target_handle;
-
-	/**
-	 * Value to be added to the offset of the target buffer to make up
-	 * the relocation entry.
-	 */
-	__u32 delta;
-
-	/** Offset in the buffer the relocation entry will be written into */
-	__u64 offset;
-
-	/**
-	 * Offset value of the target buffer that the relocation entry was last
-	 * written as.
-	 *
-	 * If the buffer has the same offset as last time, we can skip syncing
-	 * and writing the relocation.  This value is written back out by
-	 * the execbuffer ioctl when the relocation is written.
-	 */
-	__u64 presumed_offset;
-
-	/**
-	 * Target memory domains read by this operation.
-	 */
-	__u32 read_domains;
-
-	/**
-	 * Target memory domains written by this operation.
-	 *
-	 * Note that only one domain may be written by the whole
-	 * execbuffer operation, so that where there are conflicts,
-	 * the application will get -EINVAL back.
-	 */
-	__u32 write_domain;
-};
-
-/** @{
- * Intel memory domains
- *
- * Most of these just align with the various caches in
- * the system and are used to flush and invalidate as
- * objects end up cached in different domains.
- */
-/** CPU cache */
-#define I915_GEM_DOMAIN_CPU		0x00000001
-/** Render cache, used by 2D and 3D drawing */
-#define I915_GEM_DOMAIN_RENDER		0x00000002
-/** Sampler cache, used by texture engine */
-#define I915_GEM_DOMAIN_SAMPLER		0x00000004
-/** Command queue, used to load batch buffers */
-#define I915_GEM_DOMAIN_COMMAND		0x00000008
-/** Instruction cache, used by shader programs */
-#define I915_GEM_DOMAIN_INSTRUCTION	0x00000010
-/** Vertex address cache */
-#define I915_GEM_DOMAIN_VERTEX		0x00000020
-/** GTT domain - aperture and scanout */
-#define I915_GEM_DOMAIN_GTT		0x00000040
-/** @} */
-
-struct drm_i915_gem_exec_object {
-	/**
-	 * User's handle for a buffer to be bound into the GTT for this
-	 * operation.
-	 */
-	__u32 handle;
-
-	/** Number of relocations to be performed on this buffer */
-	__u32 relocation_count;
-	/**
-	 * Pointer to array of struct drm_i915_gem_relocation_entry containing
-	 * the relocations to be performed in this buffer.
-	 */
-	__u64 relocs_ptr;
-
-	/** Required alignment in graphics aperture */
-	__u64 alignment;
-
-	/**
-	 * Returned value of the updated offset of the object, for future
-	 * presumed_offset writes.
-	 */
-	__u64 offset;
-};
-
-struct drm_i915_gem_execbuffer {
-	/**
-	 * List of buffers to be validated with their relocations to be
-	 * performend on them.
-	 *
-	 * This is a pointer to an array of struct drm_i915_gem_validate_entry.
-	 *
-	 * These buffers must be listed in an order such that all relocations
-	 * a buffer is performing refer to buffers that have already appeared
-	 * in the validate list.
-	 */
-	__u64 buffers_ptr;
-	__u32 buffer_count;
-
-	/** Offset in the batchbuffer to start execution from. */
-	__u32 batch_start_offset;
-	/** Bytes used in batchbuffer from batch_start_offset */
-	__u32 batch_len;
-	__u32 DR1;
-	__u32 DR4;
-	__u32 num_cliprects;
-	/** This is a struct drm_clip_rect *cliprects */
-	__u64 cliprects_ptr;
-};
-
-struct drm_i915_gem_exec_object2 {
-	/**
-	 * User's handle for a buffer to be bound into the GTT for this
-	 * operation.
-	 */
-	__u32 handle;
-
-	/** Number of relocations to be performed on this buffer */
-	__u32 relocation_count;
-	/**
-	 * Pointer to array of struct drm_i915_gem_relocation_entry containing
-	 * the relocations to be performed in this buffer.
-	 */
-	__u64 relocs_ptr;
-
-	/** Required alignment in graphics aperture */
-	__u64 alignment;
-
-	/**
-	 * Returned value of the updated offset of the object, for future
-	 * presumed_offset writes.
-	 */
-	__u64 offset;
-
-#define EXEC_OBJECT_NEEDS_FENCE (1<<0)
-	__u64 flags;
-	__u64 rsvd1;
-	__u64 rsvd2;
-};
-
-struct drm_i915_gem_execbuffer2 {
-	/**
-	 * List of gem_exec_object2 structs
-	 */
-	__u64 buffers_ptr;
-	__u32 buffer_count;
-
-	/** Offset in the batchbuffer to start execution from. */
-	__u32 batch_start_offset;
-	/** Bytes used in batchbuffer from batch_start_offset */
-	__u32 batch_len;
-	__u32 DR1;
-	__u32 DR4;
-	__u32 num_cliprects;
-	/** This is a struct drm_clip_rect *cliprects */
-	__u64 cliprects_ptr;
-#define I915_EXEC_RING_MASK              (7<<0)
-#define I915_EXEC_DEFAULT                (0<<0)
-#define I915_EXEC_RENDER                 (1<<0)
-#define I915_EXEC_BSD                    (2<<0)
-#define I915_EXEC_BLT                    (3<<0)
-
-/* Used for switching the constants addressing mode on gen4+ RENDER ring.
- * Gen6+ only supports relative addressing to dynamic state (default) and
- * absolute addressing.
- *
- * These flags are ignored for the BSD and BLT rings.
- */
-#define I915_EXEC_CONSTANTS_MASK 	(3<<6)
-#define I915_EXEC_CONSTANTS_REL_GENERAL (0<<6) /* default */
-#define I915_EXEC_CONSTANTS_ABSOLUTE 	(1<<6)
-#define I915_EXEC_CONSTANTS_REL_SURFACE (2<<6) /* gen4/5 only */
-	__u64 flags;
-	__u64 rsvd1; /* now used for context info */
-	__u64 rsvd2;
-};
-
-/** Resets the SO write offset registers for transform feedback on gen7. */
-#define I915_EXEC_GEN7_SOL_RESET	(1<<8)
-
-#define I915_EXEC_CONTEXT_ID_MASK	(0xffffffff)
-#define i915_execbuffer2_set_context_id(eb2, context) \
-	(eb2).rsvd1 = context & I915_EXEC_CONTEXT_ID_MASK
-#define i915_execbuffer2_get_context_id(eb2) \
-	((eb2).rsvd1 & I915_EXEC_CONTEXT_ID_MASK)
-
-struct drm_i915_gem_pin {
-	/** Handle of the buffer to be pinned. */
-	__u32 handle;
-	__u32 pad;
-
-	/** alignment required within the aperture */
-	__u64 alignment;
-
-	/** Returned GTT offset of the buffer. */
-	__u64 offset;
-};
-
-struct drm_i915_gem_unpin {
-	/** Handle of the buffer to be unpinned. */
-	__u32 handle;
-	__u32 pad;
-};
-
-struct drm_i915_gem_busy {
-	/** Handle of the buffer to check for busy */
-	__u32 handle;
-
-	/** Return busy status (1 if busy, 0 if idle).
-	 * The high word is used to indicate on which rings the object
-	 * currently resides:
-	 *  16:31 - busy (r or r/w) rings (16 render, 17 bsd, 18 blt, etc)
-	 */
-	__u32 busy;
-};
-
-#define I915_CACHING_NONE		0
-#define I915_CACHING_CACHED		1
-
-struct drm_i915_gem_caching {
-	/**
-	 * Handle of the buffer to set/get the caching level of. */
-	__u32 handle;
-
-	/**
-	 * Cacheing level to apply or return value
-	 *
-	 * bits0-15 are for generic caching control (i.e. the above defined
-	 * values). bits16-31 are reserved for platform-specific variations
-	 * (e.g. l3$ caching on gen7). */
-	__u32 caching;
-};
-
-#define I915_TILING_NONE	0
-#define I915_TILING_X		1
-#define I915_TILING_Y		2
-
-#define I915_BIT_6_SWIZZLE_NONE		0
-#define I915_BIT_6_SWIZZLE_9		1
-#define I915_BIT_6_SWIZZLE_9_10		2
-#define I915_BIT_6_SWIZZLE_9_11		3
-#define I915_BIT_6_SWIZZLE_9_10_11	4
-/* Not seen by userland */
-#define I915_BIT_6_SWIZZLE_UNKNOWN	5
-/* Seen by userland. */
-#define I915_BIT_6_SWIZZLE_9_17		6
-#define I915_BIT_6_SWIZZLE_9_10_17	7
-
-struct drm_i915_gem_set_tiling {
-	/** Handle of the buffer to have its tiling state updated */
-	__u32 handle;
-
-	/**
-	 * Tiling mode for the object (I915_TILING_NONE, I915_TILING_X,
-	 * I915_TILING_Y).
-	 *
-	 * This value is to be set on request, and will be updated by the
-	 * kernel on successful return with the actual chosen tiling layout.
-	 *
-	 * The tiling mode may be demoted to I915_TILING_NONE when the system
-	 * has bit 6 swizzling that can't be managed correctly by GEM.
-	 *
-	 * Buffer contents become undefined when changing tiling_mode.
-	 */
-	__u32 tiling_mode;
-
-	/**
-	 * Stride in bytes for the object when in I915_TILING_X or
-	 * I915_TILING_Y.
-	 */
-	__u32 stride;
-
-	/**
-	 * Returned address bit 6 swizzling required for CPU access through
-	 * mmap mapping.
-	 */
-	__u32 swizzle_mode;
-};
-
-struct drm_i915_gem_get_tiling {
-	/** Handle of the buffer to get tiling state for. */
-	__u32 handle;
-
-	/**
-	 * Current tiling mode for the object (I915_TILING_NONE, I915_TILING_X,
-	 * I915_TILING_Y).
-	 */
-	__u32 tiling_mode;
-
-	/**
-	 * Returned address bit 6 swizzling required for CPU access through
-	 * mmap mapping.
-	 */
-	__u32 swizzle_mode;
-};
-
-struct drm_i915_gem_get_aperture {
-	/** Total size of the aperture used by i915_gem_execbuffer, in bytes */
-	__u64 aper_size;
-
-	/**
-	 * Available space in the aperture used by i915_gem_execbuffer, in
-	 * bytes
-	 */
-	__u64 aper_available_size;
-};
-
-struct drm_i915_get_pipe_from_crtc_id {
-	/** ID of CRTC being requested **/
-	__u32 crtc_id;
-
-	/** pipe of requested CRTC **/
-	__u32 pipe;
-};
-
-#define I915_MADV_WILLNEED 0
-#define I915_MADV_DONTNEED 1
-#define __I915_MADV_PURGED 2 /* internal state */
-
-struct drm_i915_gem_madvise {
-	/** Handle of the buffer to change the backing store advice */
-	__u32 handle;
-
-	/* Advice: either the buffer will be needed again in the near future,
-	 *         or wont be and could be discarded under memory pressure.
-	 */
-	__u32 madv;
-
-	/** Whether the backing store still exists. */
-	__u32 retained;
-};
-
-/* flags */
-#define I915_OVERLAY_TYPE_MASK 		0xff
-#define I915_OVERLAY_YUV_PLANAR 	0x01
-#define I915_OVERLAY_YUV_PACKED 	0x02
-#define I915_OVERLAY_RGB		0x03
-
-#define I915_OVERLAY_DEPTH_MASK		0xff00
-#define I915_OVERLAY_RGB24		0x1000
-#define I915_OVERLAY_RGB16		0x2000
-#define I915_OVERLAY_RGB15		0x3000
-#define I915_OVERLAY_YUV422		0x0100
-#define I915_OVERLAY_YUV411		0x0200
-#define I915_OVERLAY_YUV420		0x0300
-#define I915_OVERLAY_YUV410		0x0400
-
-#define I915_OVERLAY_SWAP_MASK		0xff0000
-#define I915_OVERLAY_NO_SWAP		0x000000
-#define I915_OVERLAY_UV_SWAP		0x010000
-#define I915_OVERLAY_Y_SWAP		0x020000
-#define I915_OVERLAY_Y_AND_UV_SWAP	0x030000
-
-#define I915_OVERLAY_FLAGS_MASK		0xff000000
-#define I915_OVERLAY_ENABLE		0x01000000
-
-struct drm_intel_overlay_put_image {
-	/* various flags and src format description */
-	__u32 flags;
-	/* source picture description */
-	__u32 bo_handle;
-	/* stride values and offsets are in bytes, buffer relative */
-	__u16 stride_Y; /* stride for packed formats */
-	__u16 stride_UV;
-	__u32 offset_Y; /* offset for packet formats */
-	__u32 offset_U;
-	__u32 offset_V;
-	/* in pixels */
-	__u16 src_width;
-	__u16 src_height;
-	/* to compensate the scaling factors for partially covered surfaces */
-	__u16 src_scan_width;
-	__u16 src_scan_height;
-	/* output crtc description */
-	__u32 crtc_id;
-	__u16 dst_x;
-	__u16 dst_y;
-	__u16 dst_width;
-	__u16 dst_height;
-};
-
-/* flags */
-#define I915_OVERLAY_UPDATE_ATTRS	(1<<0)
-#define I915_OVERLAY_UPDATE_GAMMA	(1<<1)
-struct drm_intel_overlay_attrs {
-	__u32 flags;
-	__u32 color_key;
-	__s32 brightness;
-	__u32 contrast;
-	__u32 saturation;
-	__u32 gamma0;
-	__u32 gamma1;
-	__u32 gamma2;
-	__u32 gamma3;
-	__u32 gamma4;
-	__u32 gamma5;
-};
-
-/*
- * Intel sprite handling
- *
- * Color keying works with a min/mask/max tuple.  Both source and destination
- * color keying is allowed.
- *
- * Source keying:
- * Sprite pixels within the min & max values, masked against the color channels
- * specified in the mask field, will be transparent.  All other pixels will
- * be displayed on top of the primary plane.  For RGB surfaces, only the min
- * and mask fields will be used; ranged compares are not allowed.
- *
- * Destination keying:
- * Primary plane pixels that match the min value, masked against the color
- * channels specified in the mask field, will be replaced by corresponding
- * pixels from the sprite plane.
- *
- * Note that source & destination keying are exclusive; only one can be
- * active on a given plane.
- */
-
-#define I915_SET_COLORKEY_NONE		(1<<0) /* disable color key matching */
-#define I915_SET_COLORKEY_DESTINATION	(1<<1)
-#define I915_SET_COLORKEY_SOURCE	(1<<2)
-struct drm_intel_sprite_colorkey {
-	__u32 plane_id;
-	__u32 min_value;
-	__u32 channel_mask;
-	__u32 max_value;
-	__u32 flags;
-};
-
-struct drm_i915_gem_wait {
-	/** Handle of BO we shall wait on */
-	__u32 bo_handle;
-	__u32 flags;
-	/** Number of nanoseconds to wait, Returns time remaining. */
-	__s64 timeout_ns;
-};
-
-struct drm_i915_gem_context_create {
-	/*  output: id of new context*/
-	__u32 ctx_id;
-	__u32 pad;
-};
-
-struct drm_i915_gem_context_destroy {
-	__u32 ctx_id;
-	__u32 pad;
-};
-
-struct drm_i915_reg_read {
-	__u64 offset;
-	__u64 val; /* Return value */
-};
 #endif				/* _I915_DRM_H_ */
diff --git a/include/linux/atomic.h b/include/linux/atomic.h
index 70cfcb2..5b08a85 100644
--- a/include/linux/atomic.h
+++ b/include/linux/atomic.h
@@ -86,6 +86,31 @@
 }
 #endif
 
+/*
+ * atomic_dec_if_positive - decrement by 1 if old value positive
+ * @v: pointer of type atomic_t
+ *
+ * The function returns the old value of *v minus 1, even if
+ * the atomic variable, v, was not decremented.
+ */
+#ifndef atomic_dec_if_positive
+static inline int atomic_dec_if_positive(atomic_t *v)
+{
+	int c, old, dec;
+	c = atomic_read(v);
+	for (;;) {
+		dec = c - 1;
+		if (unlikely(dec < 0))
+			break;
+		old = atomic_cmpxchg((v), c, dec);
+		if (likely(old == c))
+			break;
+		c = old;
+	}
+	return dec;
+}
+#endif
+
 #ifndef CONFIG_ARCH_HAS_ATOMIC_OR
 static inline void atomic_or(int i, atomic_t *v)
 {
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h
index 6ba45d2..1cf1749 100644
--- a/include/linux/bcma/bcma_driver_chipcommon.h
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
@@ -522,6 +522,8 @@
 	u32 blocksize;
 	u16 numblocks;
 	u32 size;
+
+	struct mtd_info *mtd;
 };
 #endif
 
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index 37935c2..26531f3 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -19,6 +19,8 @@
 
 #ifdef __KERNEL__
 #include <linux/sched.h>
+#include <linux/unistd.h>
+#include <asm/exec.h>
 
 #define CORENAME_MAX_SIZE 128
 
@@ -135,5 +137,9 @@
 extern void set_binfmt(struct linux_binfmt *new);
 extern void free_bprm(struct linux_binprm *);
 
+#ifdef __ARCH_WANT_KERNEL_EXECVE
+extern void ret_from_kernel_execve(struct pt_regs *normal) __noreturn;
+#endif
+
 #endif /* __KERNEL__ */
 #endif /* _LINUX_BINFMTS_H */
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 2643589..820e7aa 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -212,20 +212,41 @@
 extern struct bio_set *bioset_create(unsigned int, unsigned int);
 extern void bioset_free(struct bio_set *);
 
-extern struct bio *bio_alloc(gfp_t, unsigned int);
-extern struct bio *bio_kmalloc(gfp_t, unsigned int);
 extern struct bio *bio_alloc_bioset(gfp_t, int, struct bio_set *);
 extern void bio_put(struct bio *);
-extern void bio_free(struct bio *, struct bio_set *);
+
+extern void __bio_clone(struct bio *, struct bio *);
+extern struct bio *bio_clone_bioset(struct bio *, gfp_t, struct bio_set *bs);
+
+extern struct bio_set *fs_bio_set;
+
+static inline struct bio *bio_alloc(gfp_t gfp_mask, unsigned int nr_iovecs)
+{
+	return bio_alloc_bioset(gfp_mask, nr_iovecs, fs_bio_set);
+}
+
+static inline struct bio *bio_clone(struct bio *bio, gfp_t gfp_mask)
+{
+	return bio_clone_bioset(bio, gfp_mask, fs_bio_set);
+}
+
+static inline struct bio *bio_kmalloc(gfp_t gfp_mask, unsigned int nr_iovecs)
+{
+	return bio_alloc_bioset(gfp_mask, nr_iovecs, NULL);
+}
+
+static inline struct bio *bio_clone_kmalloc(struct bio *bio, gfp_t gfp_mask)
+{
+	return bio_clone_bioset(bio, gfp_mask, NULL);
+
+}
 
 extern void bio_endio(struct bio *, int);
 struct request_queue;
 extern int bio_phys_segments(struct request_queue *, struct bio *);
 
-extern void __bio_clone(struct bio *, struct bio *);
-extern struct bio *bio_clone(struct bio *, gfp_t);
-
 extern void bio_init(struct bio *);
+extern void bio_reset(struct bio *);
 
 extern int bio_add_page(struct bio *, struct page *, unsigned int,unsigned int);
 extern int bio_add_pc_page(struct request_queue *, struct bio *, struct page *,
@@ -304,8 +325,6 @@
 	struct kmem_cache *slab;
 };
 
-extern struct bio_set *fs_bio_set;
-
 /*
  * a small number of entries is fine, not going to be performance critical.
  * basically we just need to survive
@@ -367,9 +386,31 @@
 /*
  * Check whether this bio carries any data or not. A NULL bio is allowed.
  */
-static inline int bio_has_data(struct bio *bio)
+static inline bool bio_has_data(struct bio *bio)
 {
-	return bio && bio->bi_io_vec != NULL;
+	if (bio && bio->bi_vcnt)
+		return true;
+
+	return false;
+}
+
+static inline bool bio_is_rw(struct bio *bio)
+{
+	if (!bio_has_data(bio))
+		return false;
+
+	if (bio->bi_rw & REQ_WRITE_SAME)
+		return false;
+
+	return true;
+}
+
+static inline bool bio_mergeable(struct bio *bio)
+{
+	if (bio->bi_rw & REQ_NOMERGE_FLAGS)
+		return false;
+
+	return true;
 }
 
 /*
@@ -505,9 +546,8 @@
 
 #define bio_integrity(bio) (bio->bi_integrity != NULL)
 
-extern struct bio_integrity_payload *bio_integrity_alloc_bioset(struct bio *, gfp_t, unsigned int, struct bio_set *);
 extern struct bio_integrity_payload *bio_integrity_alloc(struct bio *, gfp_t, unsigned int);
-extern void bio_integrity_free(struct bio *, struct bio_set *);
+extern void bio_integrity_free(struct bio *);
 extern int bio_integrity_add_page(struct bio *, struct page *, unsigned int, unsigned int);
 extern int bio_integrity_enabled(struct bio *bio);
 extern int bio_integrity_set_tag(struct bio *, void *, unsigned int);
@@ -517,7 +557,7 @@
 extern void bio_integrity_advance(struct bio *, unsigned int);
 extern void bio_integrity_trim(struct bio *, unsigned int, unsigned int);
 extern void bio_integrity_split(struct bio *, struct bio_pair *, int);
-extern int bio_integrity_clone(struct bio *, struct bio *, gfp_t, struct bio_set *);
+extern int bio_integrity_clone(struct bio *, struct bio *, gfp_t);
 extern int bioset_integrity_create(struct bio_set *, int);
 extern void bioset_integrity_free(struct bio_set *);
 extern void bio_integrity_init(void);
@@ -549,13 +589,13 @@
 	return 0;
 }
 
-static inline void bio_integrity_free(struct bio *bio, struct bio_set *bs)
+static inline void bio_integrity_free(struct bio *bio)
 {
 	return;
 }
 
 static inline int bio_integrity_clone(struct bio *bio, struct bio *bio_src,
-				      gfp_t gfp_mask, struct bio_set *bs)
+				      gfp_t gfp_mask)
 {
 	return 0;
 }
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 7b7ac9c..cdf1119 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -59,12 +59,6 @@
 	unsigned int		bi_seg_front_size;
 	unsigned int		bi_seg_back_size;
 
-	unsigned int		bi_max_vecs;	/* max bvl_vecs we can hold */
-
-	atomic_t		bi_cnt;		/* pin count */
-
-	struct bio_vec		*bi_io_vec;	/* the actual vec list */
-
 	bio_end_io_t		*bi_end_io;
 
 	void			*bi_private;
@@ -80,7 +74,17 @@
 	struct bio_integrity_payload *bi_integrity;  /* data integrity */
 #endif
 
-	bio_destructor_t	*bi_destructor;	/* destructor */
+	/*
+	 * Everything starting with bi_max_vecs will be preserved by bio_reset()
+	 */
+
+	unsigned int		bi_max_vecs;	/* max bvl_vecs we can hold */
+
+	atomic_t		bi_cnt;		/* pin count */
+
+	struct bio_vec		*bi_io_vec;	/* the actual vec list */
+
+	struct bio_set		*bi_pool;
 
 	/*
 	 * We can inline a number of vecs at the end of the bio, to avoid
@@ -90,6 +94,8 @@
 	struct bio_vec		bi_inline_vecs[0];
 };
 
+#define BIO_RESET_BYTES		offsetof(struct bio, bi_max_vecs)
+
 /*
  * bio flags
  */
@@ -105,6 +111,13 @@
 #define BIO_FS_INTEGRITY 9	/* fs owns integrity data, not block layer */
 #define BIO_QUIET	10	/* Make BIO Quiet */
 #define BIO_MAPPED_INTEGRITY 11/* integrity metadata has been remapped */
+
+/*
+ * Flags starting here get preserved by bio_reset() - this includes
+ * BIO_POOL_IDX()
+ */
+#define BIO_RESET_BITS	12
+
 #define bio_flagged(bio, flag)	((bio)->bi_flags & (1 << (flag)))
 
 /*
@@ -134,6 +147,7 @@
 	__REQ_PRIO,		/* boost priority in cfq */
 	__REQ_DISCARD,		/* request to discard sectors */
 	__REQ_SECURE,		/* secure discard (used with __REQ_DISCARD) */
+	__REQ_WRITE_SAME,	/* write same block many times */
 
 	__REQ_NOIDLE,		/* don't anticipate more IO after this one */
 	__REQ_FUA,		/* forced unit access */
@@ -172,15 +186,21 @@
 #define REQ_META		(1 << __REQ_META)
 #define REQ_PRIO		(1 << __REQ_PRIO)
 #define REQ_DISCARD		(1 << __REQ_DISCARD)
+#define REQ_WRITE_SAME		(1 << __REQ_WRITE_SAME)
 #define REQ_NOIDLE		(1 << __REQ_NOIDLE)
 
 #define REQ_FAILFAST_MASK \
 	(REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER)
 #define REQ_COMMON_MASK \
 	(REQ_WRITE | REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_PRIO | \
-	 REQ_DISCARD | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | REQ_SECURE)
+	 REQ_DISCARD | REQ_WRITE_SAME | REQ_NOIDLE | REQ_FLUSH | REQ_FUA | \
+	 REQ_SECURE)
 #define REQ_CLONE_MASK		REQ_COMMON_MASK
 
+/* This mask is used for both bio and request merge checking */
+#define REQ_NOMERGE_FLAGS \
+	(REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA)
+
 #define REQ_RAHEAD		(1 << __REQ_RAHEAD)
 #define REQ_THROTTLED		(1 << __REQ_THROTTLED)
 
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 4a2ab7c..1756001 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -270,6 +270,7 @@
 	unsigned int		io_min;
 	unsigned int		io_opt;
 	unsigned int		max_discard_sectors;
+	unsigned int		max_write_same_sectors;
 	unsigned int		discard_granularity;
 	unsigned int		discard_alignment;
 
@@ -540,8 +541,7 @@
 
 #define blk_account_rq(rq) \
 	(((rq)->cmd_flags & REQ_STARTED) && \
-	 ((rq)->cmd_type == REQ_TYPE_FS || \
-	  ((rq)->cmd_flags & REQ_DISCARD)))
+	 ((rq)->cmd_type == REQ_TYPE_FS))
 
 #define blk_pm_request(rq)	\
 	((rq)->cmd_type == REQ_TYPE_PM_SUSPEND || \
@@ -595,17 +595,39 @@
 	rl->flags &= ~flag;
 }
 
+static inline bool rq_mergeable(struct request *rq)
+{
+	if (rq->cmd_type != REQ_TYPE_FS)
+		return false;
 
-/*
- * mergeable request must not have _NOMERGE or _BARRIER bit set, nor may
- * it already be started by driver.
- */
-#define RQ_NOMERGE_FLAGS	\
-	(REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA | REQ_DISCARD)
-#define rq_mergeable(rq)	\
-	(!((rq)->cmd_flags & RQ_NOMERGE_FLAGS) && \
-	 (((rq)->cmd_flags & REQ_DISCARD) || \
-	  (rq)->cmd_type == REQ_TYPE_FS))
+	if (rq->cmd_flags & REQ_NOMERGE_FLAGS)
+		return false;
+
+	return true;
+}
+
+static inline bool blk_check_merge_flags(unsigned int flags1,
+					 unsigned int flags2)
+{
+	if ((flags1 & REQ_DISCARD) != (flags2 & REQ_DISCARD))
+		return false;
+
+	if ((flags1 & REQ_SECURE) != (flags2 & REQ_SECURE))
+		return false;
+
+	if ((flags1 & REQ_WRITE_SAME) != (flags2 & REQ_WRITE_SAME))
+		return false;
+
+	return true;
+}
+
+static inline bool blk_write_same_mergeable(struct bio *a, struct bio *b)
+{
+	if (bio_data(a) == bio_data(b))
+		return true;
+
+	return false;
+}
 
 /*
  * q->prep_rq_fn return values
@@ -802,6 +824,28 @@
 	return blk_rq_cur_bytes(rq) >> 9;
 }
 
+static inline unsigned int blk_queue_get_max_sectors(struct request_queue *q,
+						     unsigned int cmd_flags)
+{
+	if (unlikely(cmd_flags & REQ_DISCARD))
+		return q->limits.max_discard_sectors;
+
+	if (unlikely(cmd_flags & REQ_WRITE_SAME))
+		return q->limits.max_write_same_sectors;
+
+	return q->limits.max_sectors;
+}
+
+static inline unsigned int blk_rq_get_max_sectors(struct request *rq)
+{
+	struct request_queue *q = rq->q;
+
+	if (unlikely(rq->cmd_type == REQ_TYPE_BLOCK_PC))
+		return q->limits.max_hw_sectors;
+
+	return blk_queue_get_max_sectors(q, rq->cmd_flags);
+}
+
 /*
  * Request issue related functions.
  */
@@ -857,6 +901,8 @@
 extern void blk_queue_max_segment_size(struct request_queue *, unsigned int);
 extern void blk_queue_max_discard_sectors(struct request_queue *q,
 		unsigned int max_discard_sectors);
+extern void blk_queue_max_write_same_sectors(struct request_queue *q,
+		unsigned int max_write_same_sectors);
 extern void blk_queue_logical_block_size(struct request_queue *, unsigned short);
 extern void blk_queue_physical_block_size(struct request_queue *, unsigned int);
 extern void blk_queue_alignment_offset(struct request_queue *q,
@@ -987,6 +1033,8 @@
 extern int blkdev_issue_flush(struct block_device *, gfp_t, sector_t *);
 extern int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
 		sector_t nr_sects, gfp_t gfp_mask, unsigned long flags);
+extern int blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
+		sector_t nr_sects, gfp_t gfp_mask, struct page *page);
 extern int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
 			sector_t nr_sects, gfp_t gfp_mask);
 static inline int sb_issue_discard(struct super_block *sb, sector_t block,
@@ -1164,6 +1212,16 @@
 	return queue_discard_zeroes_data(bdev_get_queue(bdev));
 }
 
+static inline unsigned int bdev_write_same(struct block_device *bdev)
+{
+	struct request_queue *q = bdev_get_queue(bdev);
+
+	if (q)
+		return q->limits.max_write_same_sectors;
+
+	return 0;
+}
+
 static inline int queue_dma_alignment(struct request_queue *q)
 {
 	return q ? q->dma_alignment : 511;
diff --git a/include/linux/caif/Kbuild b/include/linux/caif/Kbuild
index a9cf250..e69de29 100644
--- a/include/linux/caif/Kbuild
+++ b/include/linux/caif/Kbuild
@@ -1,2 +0,0 @@
-header-y += caif_socket.h
-header-y += if_caif.h
diff --git a/include/linux/ceph/mon_client.h b/include/linux/ceph/mon_client.h
index 1fb93e9..a486f39 100644
--- a/include/linux/ceph/mon_client.h
+++ b/include/linux/ceph/mon_client.h
@@ -71,7 +71,6 @@
 	int cur_mon;                       /* last monitor i contacted */
 	unsigned long sub_sent, sub_renew_after;
 	struct ceph_connection con;
-	bool have_fsid;
 
 	/* pending generic requests */
 	struct rb_root generic_request_tree;
diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h
index cedfb1a..d9b880e 100644
--- a/include/linux/ceph/osd_client.h
+++ b/include/linux/ceph/osd_client.h
@@ -207,7 +207,7 @@
 extern void ceph_osdc_handle_map(struct ceph_osd_client *osdc,
 				 struct ceph_msg *msg);
 
-extern void ceph_calc_raw_layout(struct ceph_osd_client *osdc,
+extern int ceph_calc_raw_layout(struct ceph_osd_client *osdc,
 			struct ceph_file_layout *layout,
 			u64 snapid,
 			u64 off, u64 *plen, u64 *bno,
diff --git a/include/linux/ceph/osdmap.h b/include/linux/ceph/osdmap.h
index 25b930b..e37acbe 100644
--- a/include/linux/ceph/osdmap.h
+++ b/include/linux/ceph/osdmap.h
@@ -109,9 +109,9 @@
 extern void ceph_osdmap_destroy(struct ceph_osdmap *map);
 
 /* calculate mapping of a file extent to an object */
-extern void ceph_calc_file_object_mapping(struct ceph_file_layout *layout,
-					  u64 off, u64 *plen,
-					  u64 *bno, u64 *oxoff, u64 *oxlen);
+extern int ceph_calc_file_object_mapping(struct ceph_file_layout *layout,
+					 u64 off, u64 *plen,
+					 u64 *bno, u64 *oxoff, u64 *oxlen);
 
 /* calculate mapping of object to a placement group */
 extern int ceph_calc_object_layout(struct ceph_object_layout *ol,
diff --git a/include/linux/compaction.h b/include/linux/compaction.h
index ef65814..6ecb6dc 100644
--- a/include/linux/compaction.h
+++ b/include/linux/compaction.h
@@ -22,8 +22,9 @@
 extern int fragmentation_index(struct zone *zone, unsigned int order);
 extern unsigned long try_to_compact_pages(struct zonelist *zonelist,
 			int order, gfp_t gfp_mask, nodemask_t *mask,
-			bool sync, bool *contended);
+			bool sync, bool *contended, struct page **page);
 extern int compact_pgdat(pg_data_t *pgdat, int order);
+extern void reset_isolation_suitable(pg_data_t *pgdat);
 extern unsigned long compaction_suitable(struct zone *zone, int order);
 
 /* Do not skip compaction more than 64 times */
@@ -61,10 +62,20 @@
 	return zone->compact_considered < defer_limit;
 }
 
+/* Returns true if restarting compaction after many failures */
+static inline bool compaction_restarting(struct zone *zone, int order)
+{
+	if (order < zone->compact_order_failed)
+		return false;
+
+	return zone->compact_defer_shift == COMPACT_MAX_DEFER_SHIFT &&
+		zone->compact_considered >= 1UL << zone->compact_defer_shift;
+}
+
 #else
 static inline unsigned long try_to_compact_pages(struct zonelist *zonelist,
 			int order, gfp_t gfp_mask, nodemask_t *nodemask,
-			bool sync, bool *contended)
+			bool sync, bool *contended, struct page **page)
 {
 	return COMPACT_CONTINUE;
 }
@@ -74,6 +85,10 @@
 	return COMPACT_CONTINUE;
 }
 
+static inline void reset_isolation_suitable(pg_data_t *pgdat)
+{
+}
+
 static inline unsigned long compaction_suitable(struct zone *zone, int order)
 {
 	return COMPACT_SKIPPED;
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 3f53d00..d0ced10 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -284,8 +284,12 @@
 		const struct compat_iovec __user *vec,
 		unsigned long vlen, u32 pos_low, u32 pos_high);
 
-int compat_do_execve(char *filename, compat_uptr_t __user *argv,
-		     compat_uptr_t __user *envp, struct pt_regs *regs);
+int compat_do_execve(const char *filename, const compat_uptr_t __user *argv,
+		     const compat_uptr_t __user *envp, struct pt_regs *regs);
+#ifdef __ARCH_WANT_SYS_EXECVE
+asmlinkage long compat_sys_execve(const char __user *filename, const compat_uptr_t __user *argv,
+		     const compat_uptr_t __user *envp);
+#endif
 
 asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp,
 		compat_ulong_t __user *outp, compat_ulong_t __user *exp,
diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h
index 934bc34..412bc6c 100644
--- a/include/linux/compiler-gcc4.h
+++ b/include/linux/compiler-gcc4.h
@@ -59,7 +59,7 @@
 #if __GNUC_MINOR__ > 0
 #define __compiletime_object_size(obj) __builtin_object_size(obj, 0)
 #endif
-#if __GNUC_MINOR__ >= 4 && !defined(__CHECKER__)
+#if __GNUC_MINOR__ >= 3 && !defined(__CHECKER__)
 #define __compiletime_warning(message) __attribute__((warning(message)))
 #define __compiletime_error(message) __attribute__((error(message)))
 #endif
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 9c02a45..d3201e4 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -591,7 +591,7 @@
 	struct dma_async_tx_descriptor *(*device_prep_dma_cyclic)(
 		struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
 		size_t period_len, enum dma_transfer_direction direction,
-		void *context);
+		unsigned long flags, void *context);
 	struct dma_async_tx_descriptor *(*device_prep_interleaved_dma)(
 		struct dma_chan *chan, struct dma_interleaved_template *xt,
 		unsigned long flags);
@@ -653,10 +653,11 @@
 
 static inline struct dma_async_tx_descriptor *dmaengine_prep_dma_cyclic(
 		struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
-		size_t period_len, enum dma_transfer_direction dir)
+		size_t period_len, enum dma_transfer_direction dir,
+		unsigned long flags)
 {
 	return chan->device->device_prep_dma_cyclic(chan, buf_addr, buf_len,
-						period_len, dir, NULL);
+						period_len, dir, flags, NULL);
 }
 
 static inline int dmaengine_terminate_all(struct dma_chan *chan)
diff --git a/include/linux/dw_dmac.h b/include/linux/dw_dmac.h
index 2412e02..e1c8c9e 100644
--- a/include/linux/dw_dmac.h
+++ b/include/linux/dw_dmac.h
@@ -19,6 +19,10 @@
  * @nr_channels: Number of channels supported by hardware (max 8)
  * @is_private: The device channels should be marked as private and not for
  *	by the general purpose DMA channel allocator.
+ * @block_size: Maximum block size supported by the controller
+ * @nr_masters: Number of AHB masters supported by the controller
+ * @data_width: Maximum data width supported by hardware per AHB master
+ *		(0 - 8bits, 1 - 16bits, ..., 5 - 256bits)
  */
 struct dw_dma_platform_data {
 	unsigned int	nr_channels;
@@ -29,6 +33,9 @@
 #define CHAN_PRIORITY_ASCENDING		0	/* chan0 highest */
 #define CHAN_PRIORITY_DESCENDING	1	/* chan7 highest */
 	unsigned char	chan_priority;
+	unsigned short	block_size;
+	unsigned char	nr_masters;
+	unsigned char	data_width[4];
 };
 
 /* bursts size */
diff --git a/include/linux/edma.h b/include/linux/edma.h
new file mode 100644
index 0000000..a1307e7
--- /dev/null
+++ b/include/linux/edma.h
@@ -0,0 +1,29 @@
+/*
+ * TI EDMA DMA engine driver
+ *
+ * Copyright 2012 Texas Instruments
+ *
+ * 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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef __LINUX_EDMA_H
+#define __LINUX_EDMA_H
+
+struct dma_chan;
+
+#if defined(CONFIG_TI_EDMA) || defined(CONFIG_TI_EDMA_MODULE)
+bool edma_filter_fn(struct dma_chan *, void *);
+#else
+static inline bool edma_filter_fn(struct dma_chan *chan, void *param)
+{
+	return false;
+}
+#endif
+
+#endif
diff --git a/include/linux/falloc.h b/include/linux/falloc.h
index 73e0b62..d39b824 100644
--- a/include/linux/falloc.h
+++ b/include/linux/falloc.h
@@ -3,6 +3,7 @@
 
 #define FALLOC_FL_KEEP_SIZE	0x01 /* default is extend size */
 #define FALLOC_FL_PUNCH_HOLE	0x02 /* de-allocates range */
+#define FALLOC_FL_NO_HIDE_STALE	0x04 /* reserved codepoint */
 
 #ifdef __KERNEL__
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index ca6d8c8..8ef2fc9 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -335,6 +335,7 @@
 #define BLKDISCARDZEROES _IO(0x12,124)
 #define BLKSECDISCARD _IO(0x12,125)
 #define BLKROTATIONAL _IO(0x12,126)
+#define BLKZEROOUT _IO(0x12,127)
 
 #define BMAP_IOCTL 1		/* obsolete - kept for compatibility */
 #define FIBMAP	   _IO(0x00,1)	/* bmap access */
@@ -401,7 +402,7 @@
 #include <linux/cache.h>
 #include <linux/list.h>
 #include <linux/radix-tree.h>
-#include <linux/prio_tree.h>
+#include <linux/rbtree.h>
 #include <linux/init.h>
 #include <linux/pid.h>
 #include <linux/bug.h>
@@ -415,6 +416,7 @@
 #include <linux/migrate_mode.h>
 #include <linux/uidgid.h>
 #include <linux/lockdep.h>
+#include <linux/percpu-rwsem.h>
 
 #include <asm/byteorder.h>
 
@@ -669,7 +671,7 @@
 	struct radix_tree_root	page_tree;	/* radix tree of all pages */
 	spinlock_t		tree_lock;	/* and lock protecting it */
 	unsigned int		i_mmap_writable;/* count VM_SHARED mappings */
-	struct prio_tree_root	i_mmap;		/* tree of private and shared mappings */
+	struct rb_root		i_mmap;		/* tree of private and shared mappings */
 	struct list_head	i_mmap_nonlinear;/*list VM_NONLINEAR mappings */
 	struct mutex		i_mmap_mutex;	/* protect tree, count, list */
 	/* Protected by tree_lock together with the radix tree */
@@ -724,6 +726,8 @@
 	int			bd_fsfreeze_count;
 	/* Mutex for freeze */
 	struct mutex		bd_fsfreeze_mutex;
+	/* A semaphore that prevents I/O while block size is being changed */
+	struct percpu_rw_semaphore	bd_block_size_semaphore;
 };
 
 /*
@@ -741,7 +745,7 @@
  */
 static inline int mapping_mapped(struct address_space *mapping)
 {
-	return	!prio_tree_empty(&mapping->i_mmap) ||
+	return	!RB_EMPTY_ROOT(&mapping->i_mmap) ||
 		!list_empty(&mapping->i_mmap_nonlinear);
 }
 
@@ -1132,7 +1136,7 @@
 #if BITS_PER_LONG==32
 #define MAX_LFS_FILESIZE	(((loff_t)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1) 
 #elif BITS_PER_LONG==64
-#define MAX_LFS_FILESIZE 	((loff_t)0x7fffffffffffffff)
+#define MAX_LFS_FILESIZE 	((loff_t)0x7fffffffffffffffLL)
 #endif
 
 #define FL_POSIX	1
@@ -1507,7 +1511,6 @@
 	unsigned long		s_magic;
 	struct dentry		*s_root;
 	struct rw_semaphore	s_umount;
-	struct mutex		s_lock;
 	int			s_count;
 	atomic_t		s_active;
 #ifdef CONFIG_SECURITY
@@ -2076,7 +2079,7 @@
 extern void kern_unmount(struct vfsmount *mnt);
 extern int may_umount_tree(struct vfsmount *);
 extern int may_umount(struct vfsmount *);
-extern long do_mount(char *, char *, char *, unsigned long, void *);
+extern long do_mount(const char *, const char *, const char *, unsigned long, void *);
 extern struct vfsmount *collect_mounts(struct path *);
 extern void drop_collected_mounts(struct vfsmount *);
 extern int iterate_mounts(int (*)(struct vfsmount *, void *), void *,
@@ -2552,6 +2555,8 @@
 
 extern int generic_file_mmap(struct file *, struct vm_area_struct *);
 extern int generic_file_readonly_mmap(struct file *, struct vm_area_struct *);
+extern int generic_file_remap_pages(struct vm_area_struct *, unsigned long addr,
+		unsigned long size, pgoff_t pgoff);
 extern int file_read_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size);
 int generic_write_checks(struct file *file, loff_t *pos, size_t *count, int isblk);
 extern ssize_t generic_file_aio_read(struct kiocb *, const struct iovec *, unsigned long, loff_t);
@@ -2568,6 +2573,8 @@
 		unsigned long *nr_segs, size_t *count, int access_flags);
 
 /* fs/block_dev.c */
+extern ssize_t blkdev_aio_read(struct kiocb *iocb, const struct iovec *iov,
+			       unsigned long nr_segs, loff_t pos);
 extern ssize_t blkdev_aio_write(struct kiocb *iocb, const struct iovec *iov,
 				unsigned long nr_segs, loff_t pos);
 extern int blkdev_fsync(struct file *filp, loff_t start, loff_t end,
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 4883f39..02c1c97 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -30,12 +30,7 @@
 #define ___GFP_HARDWALL		0x20000u
 #define ___GFP_THISNODE		0x40000u
 #define ___GFP_RECLAIMABLE	0x80000u
-#ifdef CONFIG_KMEMCHECK
 #define ___GFP_NOTRACK		0x200000u
-#else
-#define ___GFP_NOTRACK		0
-#endif
-#define ___GFP_NO_KSWAPD	0x400000u
 #define ___GFP_OTHER_NODE	0x800000u
 #define ___GFP_WRITE		0x1000000u
 
@@ -90,7 +85,6 @@
 #define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE) /* Page is reclaimable */
 #define __GFP_NOTRACK	((__force gfp_t)___GFP_NOTRACK)  /* Don't track with kmemcheck */
 
-#define __GFP_NO_KSWAPD	((__force gfp_t)___GFP_NO_KSWAPD)
 #define __GFP_OTHER_NODE ((__force gfp_t)___GFP_OTHER_NODE) /* On behalf of other node */
 #define __GFP_WRITE	((__force gfp_t)___GFP_WRITE)	/* Allocator intends to dirty page */
 
@@ -120,8 +114,7 @@
 				 __GFP_MOVABLE)
 #define GFP_IOFS	(__GFP_IO | __GFP_FS)
 #define GFP_TRANSHUGE	(GFP_HIGHUSER_MOVABLE | __GFP_COMP | \
-			 __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN | \
-			 __GFP_NO_KSWAPD)
+			 __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN)
 
 #ifdef CONFIG_NUMA
 #define GFP_THISNODE	(__GFP_THISNODE | __GFP_NOWARN | __GFP_NORETRY)
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index 4c59b11..b31cb7d 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -11,8 +11,7 @@
 extern int do_huge_pmd_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
 			       unsigned long address, pmd_t *pmd,
 			       pmd_t orig_pmd);
-extern pgtable_t get_pmd_huge_pte(struct mm_struct *mm);
-extern struct page *follow_trans_huge_pmd(struct mm_struct *mm,
+extern struct page *follow_trans_huge_pmd(struct vm_area_struct *vma,
 					  unsigned long addr,
 					  pmd_t *pmd,
 					  unsigned int flags);
diff --git a/include/linux/i2c-algo-pca.h b/include/linux/i2c-algo-pca.h
index 1364d62..a3c3ecd 100644
--- a/include/linux/i2c-algo-pca.h
+++ b/include/linux/i2c-algo-pca.h
@@ -62,6 +62,7 @@
 	 * 330000, 288000, 217000, 146000, 88000, 59000, 44000, 36000
 	 * For PCA9665, use the frequency you want here. */
 	unsigned int			i2c_clock;
+	unsigned int			chip;
 };
 
 int i2c_pca_add_bus(struct i2c_adapter *);
diff --git a/include/linux/i2c-mux-gpio.h b/include/linux/i2c-mux-gpio.h
index a36343a3..4406108 100644
--- a/include/linux/i2c-mux-gpio.h
+++ b/include/linux/i2c-mux-gpio.h
@@ -21,6 +21,9 @@
  * @values: Array of bitmasks of GPIO settings (low/high) for each
  *	position
  * @n_values: Number of multiplexer positions (busses to instantiate)
+ * @classes: Optional I2C auto-detection classes
+ * @gpio_chip: Optional GPIO chip name; if set, GPIO pin numbers are given
+ *	relative to the base GPIO number of that chip
  * @gpios: Array of GPIO numbers used to control MUX
  * @n_gpios: Number of GPIOs used to control MUX
  * @idle: Bitmask to write to MUX when idle or GPIO_I2CMUX_NO_IDLE if not used
@@ -30,6 +33,8 @@
 	int base_nr;
 	const unsigned *values;
 	int n_values;
+	const unsigned *classes;
+	char *gpio_chip;
 	const unsigned *gpios;
 	int n_gpios;
 	unsigned idle;
diff --git a/include/linux/i2c-mux.h b/include/linux/i2c-mux.h
index c790838..40cb05a 100644
--- a/include/linux/i2c-mux.h
+++ b/include/linux/i2c-mux.h
@@ -36,6 +36,7 @@
 struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent,
 				struct device *mux_dev,
 				void *mux_priv, u32 force_nr, u32 chan_id,
+				unsigned int class,
 				int (*select) (struct i2c_adapter *,
 					       void *mux_dev, u32 chan_id),
 				int (*deselect) (struct i2c_adapter *,
diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h
index 92a0dc7..df804ba 100644
--- a/include/linux/i2c-omap.h
+++ b/include/linux/i2c-omap.h
@@ -34,7 +34,6 @@
 	u32		clkrate;
 	u32		rev;
 	u32		flags;
-	void		(*set_mpu_wkup_lat)(struct device *dev, long set);
 };
 
 #endif
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 5970266..94aed0c 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -144,7 +144,7 @@
  * The driver.owner field should be set to the module owner of this driver.
  * The driver.name field should be set to the name of this driver.
  *
- * For automatic device detection, both @detect and @address_data must
+ * For automatic device detection, both @detect and @address_list must
  * be defined. @class should also be set, otherwise only devices forced
  * with module parameters will be created. The detect function must
  * fill at least the name field of the i2c_board_info structure it is
diff --git a/include/linux/i2c/i2c-rcar.h b/include/linux/i2c/i2c-rcar.h
new file mode 100644
index 0000000..496f5c2
--- /dev/null
+++ b/include/linux/i2c/i2c-rcar.h
@@ -0,0 +1,10 @@
+#ifndef __I2C_R_CAR_H__
+#define __I2C_R_CAR_H__
+
+#include <linux/platform_device.h>
+
+struct i2c_rcar_platform_data {
+	u32 bus_speed;
+};
+
+#endif /* __I2C_R_CAR_H__ */
diff --git a/include/linux/i2c/pca954x.h b/include/linux/i2c/pca954x.h
index 28f1f8d..1712677 100644
--- a/include/linux/i2c/pca954x.h
+++ b/include/linux/i2c/pca954x.h
@@ -36,6 +36,7 @@
 struct pca954x_platform_mode {
 	int		adap_id;
 	unsigned int	deselect_on_exit:1;
+	unsigned int	class;
 };
 
 /* Per mux/switch data, used with i2c_register_board_info */
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index 1faa58f..9a5e284 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -664,7 +664,7 @@
 	unsigned int check_defaults:1;
 	unsigned int reset_registers:1;
 	unsigned int hs_extmute:1;
-	void (*set_hs_extmute)(int mute);
+	int hs_extmute_gpio;
 };
 
 struct twl4030_vibra_data {
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index e6ff12d..c0ff748 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -80,6 +80,8 @@
 }
 
 #define vlan_tx_tag_present(__skb)	((__skb)->vlan_tci & VLAN_TAG_PRESENT)
+#define vlan_tx_nonzero_tag_present(__skb) \
+	(vlan_tx_tag_present(__skb) && ((__skb)->vlan_tci & VLAN_VID_MASK))
 #define vlan_tx_tag_get(__skb)		((__skb)->vlan_tci & ~VLAN_TAG_PRESENT)
 
 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
@@ -89,7 +91,7 @@
 extern struct net_device *vlan_dev_real_dev(const struct net_device *dev);
 extern u16 vlan_dev_vlan_id(const struct net_device *dev);
 
-extern bool vlan_do_receive(struct sk_buff **skb, bool last_handler);
+extern bool vlan_do_receive(struct sk_buff **skb);
 extern struct sk_buff *vlan_untag(struct sk_buff *skb);
 
 extern int vlan_vid_add(struct net_device *dev, unsigned short vid);
@@ -120,10 +122,8 @@
 	return 0;
 }
 
-static inline bool vlan_do_receive(struct sk_buff **skb, bool last_handler)
+static inline bool vlan_do_receive(struct sk_buff **skb)
 {
-	if (((*skb)->vlan_tci & VLAN_VID_MASK) && last_handler)
-		(*skb)->pkt_type = PACKET_OTHERHOST;
 	return false;
 }
 
diff --git a/include/linux/interval_tree.h b/include/linux/interval_tree.h
new file mode 100644
index 0000000..724556a
--- /dev/null
+++ b/include/linux/interval_tree.h
@@ -0,0 +1,27 @@
+#ifndef _LINUX_INTERVAL_TREE_H
+#define _LINUX_INTERVAL_TREE_H
+
+#include <linux/rbtree.h>
+
+struct interval_tree_node {
+	struct rb_node rb;
+	unsigned long start;	/* Start of interval */
+	unsigned long last;	/* Last location _in_ interval */
+	unsigned long __subtree_last;
+};
+
+extern void
+interval_tree_insert(struct interval_tree_node *node, struct rb_root *root);
+
+extern void
+interval_tree_remove(struct interval_tree_node *node, struct rb_root *root);
+
+extern struct interval_tree_node *
+interval_tree_iter_first(struct rb_root *root,
+			 unsigned long start, unsigned long last);
+
+extern struct interval_tree_node *
+interval_tree_iter_next(struct interval_tree_node *node,
+			unsigned long start, unsigned long last);
+
+#endif	/* _LINUX_INTERVAL_TREE_H */
diff --git a/include/linux/interval_tree_generic.h b/include/linux/interval_tree_generic.h
new file mode 100644
index 0000000..58370e1
--- /dev/null
+++ b/include/linux/interval_tree_generic.h
@@ -0,0 +1,191 @@
+/*
+  Interval Trees
+  (C) 2012  Michel Lespinasse <walken@google.com>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+  include/linux/interval_tree_generic.h
+*/
+
+#include <linux/rbtree_augmented.h>
+
+/*
+ * Template for implementing interval trees
+ *
+ * ITSTRUCT:   struct type of the interval tree nodes
+ * ITRB:       name of struct rb_node field within ITSTRUCT
+ * ITTYPE:     type of the interval endpoints
+ * ITSUBTREE:  name of ITTYPE field within ITSTRUCT holding last-in-subtree
+ * ITSTART(n): start endpoint of ITSTRUCT node n
+ * ITLAST(n):  last endpoint of ITSTRUCT node n
+ * ITSTATIC:   'static' or empty
+ * ITPREFIX:   prefix to use for the inline tree definitions
+ *
+ * Note - before using this, please consider if non-generic version
+ * (interval_tree.h) would work for you...
+ */
+
+#define INTERVAL_TREE_DEFINE(ITSTRUCT, ITRB, ITTYPE, ITSUBTREE,		      \
+			     ITSTART, ITLAST, ITSTATIC, ITPREFIX)	      \
+									      \
+/* Callbacks for augmented rbtree insert and remove */			      \
+									      \
+static inline ITTYPE ITPREFIX ## _compute_subtree_last(ITSTRUCT *node)	      \
+{									      \
+	ITTYPE max = ITLAST(node), subtree_last;			      \
+	if (node->ITRB.rb_left) {					      \
+		subtree_last = rb_entry(node->ITRB.rb_left,		      \
+					ITSTRUCT, ITRB)->ITSUBTREE;	      \
+		if (max < subtree_last)					      \
+			max = subtree_last;				      \
+	}								      \
+	if (node->ITRB.rb_right) {					      \
+		subtree_last = rb_entry(node->ITRB.rb_right,		      \
+					ITSTRUCT, ITRB)->ITSUBTREE;	      \
+		if (max < subtree_last)					      \
+			max = subtree_last;				      \
+	}								      \
+	return max;							      \
+}									      \
+									      \
+RB_DECLARE_CALLBACKS(static, ITPREFIX ## _augment, ITSTRUCT, ITRB,	      \
+		     ITTYPE, ITSUBTREE, ITPREFIX ## _compute_subtree_last)    \
+									      \
+/* Insert / remove interval nodes from the tree */			      \
+									      \
+ITSTATIC void ITPREFIX ## _insert(ITSTRUCT *node, struct rb_root *root)	      \
+{									      \
+	struct rb_node **link = &root->rb_node, *rb_parent = NULL;	      \
+	ITTYPE start = ITSTART(node), last = ITLAST(node);		      \
+	ITSTRUCT *parent;						      \
+									      \
+	while (*link) {							      \
+		rb_parent = *link;					      \
+		parent = rb_entry(rb_parent, ITSTRUCT, ITRB);		      \
+		if (parent->ITSUBTREE < last)				      \
+			parent->ITSUBTREE = last;			      \
+		if (start < ITSTART(parent))				      \
+			link = &parent->ITRB.rb_left;			      \
+		else							      \
+			link = &parent->ITRB.rb_right;			      \
+	}								      \
+									      \
+	node->ITSUBTREE = last;						      \
+	rb_link_node(&node->ITRB, rb_parent, link);			      \
+	rb_insert_augmented(&node->ITRB, root, &ITPREFIX ## _augment);	      \
+}									      \
+									      \
+ITSTATIC void ITPREFIX ## _remove(ITSTRUCT *node, struct rb_root *root)	      \
+{									      \
+	rb_erase_augmented(&node->ITRB, root, &ITPREFIX ## _augment);	      \
+}									      \
+									      \
+/*									      \
+ * Iterate over intervals intersecting [start;last]			      \
+ *									      \
+ * Note that a node's interval intersects [start;last] iff:		      \
+ *   Cond1: ITSTART(node) <= last					      \
+ * and									      \
+ *   Cond2: start <= ITLAST(node)					      \
+ */									      \
+									      \
+static ITSTRUCT *							      \
+ITPREFIX ## _subtree_search(ITSTRUCT *node, ITTYPE start, ITTYPE last)	      \
+{									      \
+	while (true) {							      \
+		/*							      \
+		 * Loop invariant: start <= node->ITSUBTREE		      \
+		 * (Cond2 is satisfied by one of the subtree nodes)	      \
+		 */							      \
+		if (node->ITRB.rb_left) {				      \
+			ITSTRUCT *left = rb_entry(node->ITRB.rb_left,	      \
+						  ITSTRUCT, ITRB);	      \
+			if (start <= left->ITSUBTREE) {			      \
+				/*					      \
+				 * Some nodes in left subtree satisfy Cond2.  \
+				 * Iterate to find the leftmost such node N.  \
+				 * If it also satisfies Cond1, that's the     \
+				 * match we are looking for. Otherwise, there \
+				 * is no matching interval as nodes to the    \
+				 * right of N can't satisfy Cond1 either.     \
+				 */					      \
+				node = left;				      \
+				continue;				      \
+			}						      \
+		}							      \
+		if (ITSTART(node) <= last) {		/* Cond1 */	      \
+			if (start <= ITLAST(node))	/* Cond2 */	      \
+				return node;	/* node is leftmost match */  \
+			if (node->ITRB.rb_right) {			      \
+				node = rb_entry(node->ITRB.rb_right,	      \
+						ITSTRUCT, ITRB);	      \
+				if (start <= node->ITSUBTREE)		      \
+					continue;			      \
+			}						      \
+		}							      \
+		return NULL;	/* No match */				      \
+	}								      \
+}									      \
+									      \
+ITSTATIC ITSTRUCT *							      \
+ITPREFIX ## _iter_first(struct rb_root *root, ITTYPE start, ITTYPE last)      \
+{									      \
+	ITSTRUCT *node;							      \
+									      \
+	if (!root->rb_node)						      \
+		return NULL;						      \
+	node = rb_entry(root->rb_node, ITSTRUCT, ITRB);			      \
+	if (node->ITSUBTREE < start)					      \
+		return NULL;						      \
+	return ITPREFIX ## _subtree_search(node, start, last);		      \
+}									      \
+									      \
+ITSTATIC ITSTRUCT *							      \
+ITPREFIX ## _iter_next(ITSTRUCT *node, ITTYPE start, ITTYPE last)	      \
+{									      \
+	struct rb_node *rb = node->ITRB.rb_right, *prev;		      \
+									      \
+	while (true) {							      \
+		/*							      \
+		 * Loop invariants:					      \
+		 *   Cond1: ITSTART(node) <= last			      \
+		 *   rb == node->ITRB.rb_right				      \
+		 *							      \
+		 * First, search right subtree if suitable		      \
+		 */							      \
+		if (rb) {						      \
+			ITSTRUCT *right = rb_entry(rb, ITSTRUCT, ITRB);	      \
+			if (start <= right->ITSUBTREE)			      \
+				return ITPREFIX ## _subtree_search(right,     \
+								start, last); \
+		}							      \
+									      \
+		/* Move up the tree until we come from a node's left child */ \
+		do {							      \
+			rb = rb_parent(&node->ITRB);			      \
+			if (!rb)					      \
+				return NULL;				      \
+			prev = &node->ITRB;				      \
+			node = rb_entry(rb, ITSTRUCT, ITRB);		      \
+			rb = node->ITRB.rb_right;			      \
+		} while (prev == rb);					      \
+									      \
+		/* Check if the node intersects [start;last] */		      \
+		if (last < ITSTART(node))		/* !Cond1 */	      \
+			return NULL;					      \
+		else if (start <= ITLAST(node))		/* Cond2 */	      \
+			return node;					      \
+	}								      \
+}
diff --git a/include/linux/isdn/Kbuild b/include/linux/isdn/Kbuild
index 991cdb2..e69de29 100644
--- a/include/linux/isdn/Kbuild
+++ b/include/linux/isdn/Kbuild
@@ -1 +0,0 @@
-header-y += capicmd.h
diff --git a/include/linux/leds-lp5523.h b/include/linux/leds-lp5523.h
index 2694289..727877f 100644
--- a/include/linux/leds-lp5523.h
+++ b/include/linux/leds-lp5523.h
@@ -26,6 +26,7 @@
 /* See Documentation/leds/leds-lp5523.txt */
 
 struct lp5523_led_config {
+	const char	*name;
 	u8		chan_nr;
 	u8		led_current; /* mA x10, 0 if led is not connected */
 	u8		max_current;
diff --git a/include/linux/leds.h b/include/linux/leds.h
index c6f8dad..6e53bb3 100644
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -16,6 +16,7 @@
 #include <linux/spinlock.h>
 #include <linux/rwsem.h>
 #include <linux/timer.h>
+#include <linux/workqueue.h>
 
 struct device;
 /*
@@ -69,6 +70,9 @@
 	struct timer_list	 blink_timer;
 	int			 blink_brightness;
 
+	struct work_struct	set_brightness_work;
+	int			delayed_set_value;
+
 #ifdef CONFIG_LEDS_TRIGGERS
 	/* Protects the trigger data below */
 	struct rw_semaphore	 trigger_lock;
diff --git a/include/linux/lglock.h b/include/linux/lglock.h
index f01e5f6..0d24e93 100644
--- a/include/linux/lglock.h
+++ b/include/linux/lglock.h
@@ -32,20 +32,13 @@
 #define br_write_lock(name)	lg_global_lock(name)
 #define br_write_unlock(name)	lg_global_unlock(name)
 
-#define DEFINE_BRLOCK(name)	DEFINE_LGLOCK(name)
+#define DEFINE_BRLOCK(name)		DEFINE_LGLOCK(name)
+#define DEFINE_STATIC_BRLOCK(name)	DEFINE_STATIC_LGLOCK(name)
 
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 #define LOCKDEP_INIT_MAP lockdep_init_map
-
-#define DEFINE_LGLOCK_LOCKDEP(name)					\
- struct lock_class_key name##_lock_key;					\
- struct lockdep_map name##_lock_dep_map;				\
- EXPORT_SYMBOL(name##_lock_dep_map)
-
 #else
 #define LOCKDEP_INIT_MAP(a, b, c, d)
-
-#define DEFINE_LGLOCK_LOCKDEP(name)
 #endif
 
 struct lglock {
@@ -57,11 +50,15 @@
 };
 
 #define DEFINE_LGLOCK(name)						\
-	DEFINE_LGLOCK_LOCKDEP(name);					\
-	DEFINE_PER_CPU(arch_spinlock_t, name ## _lock)			\
+	static DEFINE_PER_CPU(arch_spinlock_t, name ## _lock)		\
 	= __ARCH_SPIN_LOCK_UNLOCKED;					\
 	struct lglock name = { .lock = &name ## _lock }
 
+#define DEFINE_STATIC_LGLOCK(name)					\
+	static DEFINE_PER_CPU(arch_spinlock_t, name ## _lock)		\
+	= __ARCH_SPIN_LOCK_UNLOCKED;					\
+	static struct lglock name = { .lock = &name ## _lock }
+
 void lg_lock_init(struct lglock *lg, char *name);
 void lg_local_lock(struct lglock *lg);
 void lg_local_unlock(struct lglock *lg);
diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index 19dc455..569d67d 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -70,8 +70,7 @@
  * @p_end: ptr to ulong for end pfn of the range, can be %NULL
  * @p_nid: ptr to int for nid of the range, can be %NULL
  *
- * Walks over configured memory ranges.  Available after early_node_map is
- * populated.
+ * Walks over configured memory ranges.
  */
 #define for_each_mem_pfn_range(i, nid, p_start, p_end, p_nid)		\
 	for (i = -1, __next_mem_pfn_range(&i, nid, p_start, p_end, p_nid); \
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 8d9489f..11ddc7f 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -84,14 +84,14 @@
 extern struct mem_cgroup *mem_cgroup_from_cont(struct cgroup *cont);
 
 static inline
-int mm_match_cgroup(const struct mm_struct *mm, const struct mem_cgroup *cgroup)
+bool mm_match_cgroup(const struct mm_struct *mm, const struct mem_cgroup *memcg)
 {
-	struct mem_cgroup *memcg;
-	int match;
+	struct mem_cgroup *task_memcg;
+	bool match;
 
 	rcu_read_lock();
-	memcg = mem_cgroup_from_task(rcu_dereference((mm)->owner));
-	match = __mem_cgroup_same_or_subtree(cgroup, memcg);
+	task_memcg = mem_cgroup_from_task(rcu_dereference(mm->owner));
+	match = __mem_cgroup_same_or_subtree(memcg, task_memcg);
 	rcu_read_unlock();
 	return match;
 }
@@ -258,10 +258,10 @@
 	return NULL;
 }
 
-static inline int mm_match_cgroup(struct mm_struct *mm,
+static inline bool mm_match_cgroup(struct mm_struct *mm,
 		struct mem_cgroup *memcg)
 {
-	return 1;
+	return true;
 }
 
 static inline int task_in_mem_cgroup(struct task_struct *task,
@@ -396,7 +396,7 @@
 };
 
 struct sock;
-#ifdef CONFIG_MEMCG_KMEM
+#if defined(CONFIG_INET) && defined(CONFIG_MEMCG_KMEM)
 void sock_update_memcg(struct sock *sk);
 void sock_release_memcg(struct sock *sk);
 #else
@@ -406,6 +406,6 @@
 static inline void sock_release_memcg(struct sock *sk)
 {
 }
-#endif /* CONFIG_MEMCG_KMEM */
+#endif /* CONFIG_INET && CONFIG_MEMCG_KMEM */
 #endif /* _LINUX_MEMCONTROL_H */
 
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
index 910550f..95573ec 100644
--- a/include/linux/memory_hotplug.h
+++ b/include/linux/memory_hotplug.h
@@ -10,6 +10,7 @@
 struct zone;
 struct pglist_data;
 struct mem_section;
+struct memory_block;
 
 #ifdef CONFIG_MEMORY_HOTPLUG
 
@@ -233,6 +234,8 @@
 extern int mem_online_node(int nid);
 extern int add_memory(int nid, u64 start, u64 size);
 extern int arch_add_memory(int nid, u64 start, u64 size);
+extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages);
+extern int offline_memory_block(struct memory_block *mem);
 extern int remove_memory(u64 start, u64 size);
 extern int sparse_add_one_section(struct zone *zone, unsigned long start_pfn,
 								int nr_pages);
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h
index 95b738c..cec5693 100644
--- a/include/linux/mempolicy.h
+++ b/include/linux/mempolicy.h
@@ -188,7 +188,7 @@
 
 struct shared_policy {
 	struct rb_root root;
-	spinlock_t lock;
+	struct mutex mutex;
 };
 
 void mpol_shared_policy_init(struct shared_policy *sp, struct mempolicy *mpol);
@@ -239,7 +239,7 @@
 /* Check if a vma is migratable */
 static inline int vma_migratable(struct vm_area_struct *vma)
 {
-	if (vma->vm_flags & (VM_IO|VM_HUGETLB|VM_PFNMAP|VM_RESERVED))
+	if (vma->vm_flags & (VM_IO | VM_HUGETLB | VM_PFNMAP))
 		return 0;
 	/*
 	 * Migration allocates pages in the highest zone. If we cannot
diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h
index f0361c0..fc87be4 100644
--- a/include/linux/mfd/wm8994/pdata.h
+++ b/include/linux/mfd/wm8994/pdata.h
@@ -164,6 +164,10 @@
 	int num_micd_rates;
 	struct wm8958_micd_rate *micd_rates;
 
+	/* Power up delays to add after microphone bias power up (ms) */
+	int micb1_delay;
+	int micb2_delay;
+
         /* LINEOUT can be differential or single ended */
         unsigned int lineout1_diff:1;
         unsigned int lineout2_diff:1;
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 311be90..fa06804 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -10,7 +10,6 @@
 #include <linux/list.h>
 #include <linux/mmzone.h>
 #include <linux/rbtree.h>
-#include <linux/prio_tree.h>
 #include <linux/atomic.h>
 #include <linux/debug_locks.h>
 #include <linux/mm_types.h>
@@ -21,6 +20,7 @@
 
 struct mempolicy;
 struct anon_vma;
+struct anon_vma_chain;
 struct file_ra_state;
 struct user_struct;
 struct writeback_control;
@@ -70,6 +70,8 @@
 /*
  * vm_flags in vm_area_struct, see mm_types.h.
  */
+#define VM_NONE		0x00000000
+
 #define VM_READ		0x00000001	/* currently active flags */
 #define VM_WRITE	0x00000002
 #define VM_EXEC		0x00000004
@@ -82,16 +84,9 @@
 #define VM_MAYSHARE	0x00000080
 
 #define VM_GROWSDOWN	0x00000100	/* general info on the segment */
-#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
-#define VM_GROWSUP	0x00000200
-#else
-#define VM_GROWSUP	0x00000000
-#define VM_NOHUGEPAGE	0x00000200	/* MADV_NOHUGEPAGE marked this vma */
-#endif
 #define VM_PFNMAP	0x00000400	/* Page-ranges managed without "struct page", just pure PFN */
 #define VM_DENYWRITE	0x00000800	/* ETXTBSY on write attempts.. */
 
-#define VM_EXECUTABLE	0x00001000
 #define VM_LOCKED	0x00002000
 #define VM_IO           0x00004000	/* Memory mapped I/O or similar */
 
@@ -101,25 +96,34 @@
 
 #define VM_DONTCOPY	0x00020000      /* Do not copy this vma on fork */
 #define VM_DONTEXPAND	0x00040000	/* Cannot expand with mremap() */
-#define VM_RESERVED	0x00080000	/* Count as reserved_vm like IO */
 #define VM_ACCOUNT	0x00100000	/* Is a VM accounted object */
 #define VM_NORESERVE	0x00200000	/* should the VM suppress accounting */
 #define VM_HUGETLB	0x00400000	/* Huge TLB Page VM */
 #define VM_NONLINEAR	0x00800000	/* Is non-linear (remap_file_pages) */
-#ifndef CONFIG_TRANSPARENT_HUGEPAGE
-#define VM_MAPPED_COPY	0x01000000	/* T if mapped copy of data (nommu mmap) */
-#else
-#define VM_HUGEPAGE	0x01000000	/* MADV_HUGEPAGE marked this vma */
-#endif
-#define VM_INSERTPAGE	0x02000000	/* The vma has had "vm_insert_page()" done on it */
-#define VM_NODUMP	0x04000000	/* Do not include in the core dump */
+#define VM_ARCH_1	0x01000000	/* Architecture-specific flag */
+#define VM_DONTDUMP	0x04000000	/* Do not include in the core dump */
 
-#define VM_CAN_NONLINEAR 0x08000000	/* Has ->fault & does nonlinear pages */
 #define VM_MIXEDMAP	0x10000000	/* Can contain "struct page" and pure PFN pages */
-#define VM_SAO		0x20000000	/* Strong Access Ordering (powerpc) */
-#define VM_PFN_AT_MMAP	0x40000000	/* PFNMAP vma that is fully mapped at mmap time */
+#define VM_HUGEPAGE	0x20000000	/* MADV_HUGEPAGE marked this vma */
+#define VM_NOHUGEPAGE	0x40000000	/* MADV_NOHUGEPAGE marked this vma */
 #define VM_MERGEABLE	0x80000000	/* KSM may merge identical pages */
 
+#if defined(CONFIG_X86)
+# define VM_PAT		VM_ARCH_1	/* PAT reserves whole VMA at once (x86) */
+#elif defined(CONFIG_PPC)
+# define VM_SAO		VM_ARCH_1	/* Strong Access Ordering (powerpc) */
+#elif defined(CONFIG_PARISC)
+# define VM_GROWSUP	VM_ARCH_1
+#elif defined(CONFIG_IA64)
+# define VM_GROWSUP	VM_ARCH_1
+#elif !defined(CONFIG_MMU)
+# define VM_MAPPED_COPY	VM_ARCH_1	/* T if mapped copy of data (nommu mmap) */
+#endif
+
+#ifndef VM_GROWSUP
+# define VM_GROWSUP	VM_NONE
+#endif
+
 /* Bits set in the VMA until the stack is in its final location */
 #define VM_STACK_INCOMPLETE_SETUP	(VM_RAND_READ | VM_SEQ_READ)
 
@@ -143,7 +147,7 @@
  * Special vmas that are non-mergable, non-mlock()able.
  * Note: mm/huge_memory.c VM_NO_THP depends on this definition.
  */
-#define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP)
+#define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_PFNMAP)
 
 /*
  * mapping from the currently active vm_flags protection bits (the
@@ -157,24 +161,7 @@
 #define FAULT_FLAG_ALLOW_RETRY	0x08	/* Retry fault if blocking */
 #define FAULT_FLAG_RETRY_NOWAIT	0x10	/* Don't drop mmap_sem and wait when retrying */
 #define FAULT_FLAG_KILLABLE	0x20	/* The fault task is in SIGKILL killable region */
-
-/*
- * This interface is used by x86 PAT code to identify a pfn mapping that is
- * linear over entire vma. This is to optimize PAT code that deals with
- * marking the physical region with a particular prot. This is not for generic
- * mm use. Note also that this check will not work if the pfn mapping is
- * linear for a vma starting at physical address 0. In which case PAT code
- * falls back to slow path of reserving physical range page by page.
- */
-static inline int is_linear_pfn_mapping(struct vm_area_struct *vma)
-{
-	return !!(vma->vm_flags & VM_PFN_AT_MMAP);
-}
-
-static inline int is_pfn_mapping(struct vm_area_struct *vma)
-{
-	return !!(vma->vm_flags & VM_PFNMAP);
-}
+#define FAULT_FLAG_TRIED	0x40	/* second try */
 
 /*
  * vm_fault is filled by the the pagefault handler and passed to the vma's
@@ -182,8 +169,7 @@
  * of VM_FAULT_xxx flags that give details about how the fault was handled.
  *
  * pgoff should be used in favour of virtual_address, if possible. If pgoff
- * is used, one may set VM_CAN_NONLINEAR in the vma->vm_flags to get nonlinear
- * mapping support.
+ * is used, one may implement ->remap_pages to get nonlinear mapping support.
  */
 struct vm_fault {
 	unsigned int flags;		/* FAULT_FLAG_xxx flags */
@@ -241,6 +227,9 @@
 	int (*migrate)(struct vm_area_struct *vma, const nodemask_t *from,
 		const nodemask_t *to, unsigned long flags);
 #endif
+	/* called by sys_remap_file_pages() to populate non-linear mapping */
+	int (*remap_pages)(struct vm_area_struct *vma, unsigned long addr,
+			   unsigned long size, pgoff_t pgoff);
 };
 
 struct mmu_gather;
@@ -249,6 +238,18 @@
 #define page_private(page)		((page)->private)
 #define set_page_private(page, v)	((page)->private = (v))
 
+/* It's valid only if the page is free path or free_list */
+static inline void set_freepage_migratetype(struct page *page, int migratetype)
+{
+	page->index = migratetype;
+}
+
+/* It's valid only if the page is free path or free_list */
+static inline int get_freepage_migratetype(struct page *page)
+{
+	return page->index;
+}
+
 /*
  * FIXME: take this include out, include page-flags.h in
  * files which need it (119 of them)
@@ -454,6 +455,7 @@
 
 void split_page(struct page *page, unsigned int order);
 int split_free_page(struct page *page);
+int capture_free_page(struct page *page, int alloc_order, int migratetype);
 
 /*
  * Compound pages have a destructor function.  Provide a
@@ -1071,7 +1073,8 @@
 
 extern unsigned long move_page_tables(struct vm_area_struct *vma,
 		unsigned long old_addr, struct vm_area_struct *new_vma,
-		unsigned long new_addr, unsigned long len);
+		unsigned long new_addr, unsigned long len,
+		bool need_rmap_locks);
 extern unsigned long do_mremap(unsigned long addr,
 			       unsigned long old_len, unsigned long new_len,
 			       unsigned long flags, unsigned long new_addr);
@@ -1366,24 +1369,45 @@
 extern atomic_long_t mmap_pages_allocated;
 extern int nommu_shrink_inode_mappings(struct inode *, size_t, size_t);
 
-/* prio_tree.c */
-void vma_prio_tree_add(struct vm_area_struct *, struct vm_area_struct *old);
-void vma_prio_tree_insert(struct vm_area_struct *, struct prio_tree_root *);
-void vma_prio_tree_remove(struct vm_area_struct *, struct prio_tree_root *);
-struct vm_area_struct *vma_prio_tree_next(struct vm_area_struct *vma,
-	struct prio_tree_iter *iter);
+/* interval_tree.c */
+void vma_interval_tree_insert(struct vm_area_struct *node,
+			      struct rb_root *root);
+void vma_interval_tree_insert_after(struct vm_area_struct *node,
+				    struct vm_area_struct *prev,
+				    struct rb_root *root);
+void vma_interval_tree_remove(struct vm_area_struct *node,
+			      struct rb_root *root);
+struct vm_area_struct *vma_interval_tree_iter_first(struct rb_root *root,
+				unsigned long start, unsigned long last);
+struct vm_area_struct *vma_interval_tree_iter_next(struct vm_area_struct *node,
+				unsigned long start, unsigned long last);
 
-#define vma_prio_tree_foreach(vma, iter, root, begin, end)	\
-	for (prio_tree_iter_init(iter, root, begin, end), vma = NULL;	\
-		(vma = vma_prio_tree_next(vma, iter)); )
+#define vma_interval_tree_foreach(vma, root, start, last)		\
+	for (vma = vma_interval_tree_iter_first(root, start, last);	\
+	     vma; vma = vma_interval_tree_iter_next(vma, start, last))
 
 static inline void vma_nonlinear_insert(struct vm_area_struct *vma,
 					struct list_head *list)
 {
-	vma->shared.vm_set.parent = NULL;
-	list_add_tail(&vma->shared.vm_set.list, list);
+	list_add_tail(&vma->shared.nonlinear, list);
 }
 
+void anon_vma_interval_tree_insert(struct anon_vma_chain *node,
+				   struct rb_root *root);
+void anon_vma_interval_tree_remove(struct anon_vma_chain *node,
+				   struct rb_root *root);
+struct anon_vma_chain *anon_vma_interval_tree_iter_first(
+	struct rb_root *root, unsigned long start, unsigned long last);
+struct anon_vma_chain *anon_vma_interval_tree_iter_next(
+	struct anon_vma_chain *node, unsigned long start, unsigned long last);
+#ifdef CONFIG_DEBUG_VM_RB
+void anon_vma_interval_tree_verify(struct anon_vma_chain *node);
+#endif
+
+#define anon_vma_interval_tree_foreach(avc, root, start, last)		 \
+	for (avc = anon_vma_interval_tree_iter_first(root, start, last); \
+	     avc; avc = anon_vma_interval_tree_iter_next(avc, start, last))
+
 /* mmap.c */
 extern int __vm_enough_memory(struct mm_struct *mm, long pages, int cap_sys_admin);
 extern int vma_adjust(struct vm_area_struct *vma, unsigned long start,
@@ -1400,15 +1424,13 @@
 	struct rb_node **, struct rb_node *);
 extern void unlink_file_vma(struct vm_area_struct *);
 extern struct vm_area_struct *copy_vma(struct vm_area_struct **,
-	unsigned long addr, unsigned long len, pgoff_t pgoff);
+	unsigned long addr, unsigned long len, pgoff_t pgoff,
+	bool *need_rmap_locks);
 extern void exit_mmap(struct mm_struct *);
 
 extern int mm_take_all_locks(struct mm_struct *mm);
 extern void mm_drop_all_locks(struct mm_struct *mm);
 
-/* From fs/proc/base.c. callers must _not_ hold the mm's exe_file_lock */
-extern void added_exe_file_vma(struct mm_struct *mm);
-extern void removed_exe_file_vma(struct mm_struct *mm);
 extern void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file);
 extern struct file *get_mm_exe_file(struct mm_struct *mm);
 
@@ -1662,5 +1684,9 @@
 static inline bool page_is_guard(struct page *page) { return false; }
 #endif /* CONFIG_DEBUG_PAGEALLOC */
 
+extern void reset_zone_present_pages(void);
+extern void fixup_zone_present_pages(int nid, unsigned long start_pfn,
+				unsigned long end_pfn);
+
 #endif /* __KERNEL__ */
 #endif /* _LINUX_MM_H */
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index bf78672..31f8a3a 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -6,7 +6,6 @@
 #include <linux/threads.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
-#include <linux/prio_tree.h>
 #include <linux/rbtree.h>
 #include <linux/rwsem.h>
 #include <linux/completion.h>
@@ -240,18 +239,15 @@
 
 	/*
 	 * For areas with an address space and backing store,
-	 * linkage into the address_space->i_mmap prio tree, or
-	 * linkage to the list of like vmas hanging off its node, or
+	 * linkage into the address_space->i_mmap interval tree, or
 	 * linkage of vma in the address_space->i_mmap_nonlinear list.
 	 */
 	union {
 		struct {
-			struct list_head list;
-			void *parent;	/* aligns with prio_tree_node parent */
-			struct vm_area_struct *head;
-		} vm_set;
-
-		struct raw_prio_tree_node prio_tree_node;
+			struct rb_node rb;
+			unsigned long rb_subtree_last;
+		} linear;
+		struct list_head nonlinear;
 	} shared;
 
 	/*
@@ -349,7 +345,6 @@
 	unsigned long shared_vm;	/* Shared pages (files) */
 	unsigned long exec_vm;		/* VM_EXEC & ~VM_WRITE */
 	unsigned long stack_vm;		/* VM_GROWSUP/DOWN */
-	unsigned long reserved_vm;	/* VM_RESERVED|VM_IO pages */
 	unsigned long def_flags;
 	unsigned long nr_ptes;		/* Page table pages */
 	unsigned long start_code, end_code, start_data, end_data;
@@ -394,7 +389,6 @@
 
 	/* store ref to file /proc/<pid>/exe symlink points to */
 	struct file *exe_file;
-	unsigned long num_exe_file_vmas;
 #ifdef CONFIG_MMU_NOTIFIER
 	struct mmu_notifier_mm *mmu_notifier_mm;
 #endif
diff --git a/include/linux/mman.h b/include/linux/mman.h
index 8b74e9b..77cec2f 100644
--- a/include/linux/mman.h
+++ b/include/linux/mman.h
@@ -86,7 +86,6 @@
 {
 	return _calc_vm_trans(flags, MAP_GROWSDOWN,  VM_GROWSDOWN ) |
 	       _calc_vm_trans(flags, MAP_DENYWRITE,  VM_DENYWRITE ) |
-	       _calc_vm_trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE) |
 	       _calc_vm_trans(flags, MAP_LOCKED,     VM_LOCKED    );
 }
 #endif /* __KERNEL__ */
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 4b27f9f..943550df 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -57,6 +57,7 @@
 	unsigned int		sa_timeout;		/* Units: 100ns */
 	unsigned int		generic_cmd6_time;	/* Units: 10ms */
 	unsigned int            power_off_longtime;     /* Units: ms */
+	u8			power_off_notification;	/* state */
 	unsigned int		hs_max_dtr;
 #define MMC_HIGH_26_MAX_DTR	26000000
 #define MMC_HIGH_52_MAX_DTR	52000000
@@ -76,10 +77,13 @@
 	bool			hpi_en;			/* HPI enablebit */
 	bool			hpi;			/* HPI support bit */
 	unsigned int		hpi_cmd;		/* cmd used as HPI */
+	bool			bkops;		/* background support bit */
+	bool			bkops_en;	/* background enable bit */
 	unsigned int            data_sector_size;       /* 512 bytes or 4KB */
 	unsigned int            data_tag_unit_size;     /* DATA TAG UNIT size */
 	unsigned int		boot_ro_lock;		/* ro lock support */
 	bool			boot_ro_lockable;
+	u8			raw_exception_status;	/* 53 */
 	u8			raw_partition_support;	/* 160 */
 	u8			raw_erased_mem_count;	/* 181 */
 	u8			raw_ext_csd_structure;	/* 194 */
@@ -93,6 +97,7 @@
 	u8			raw_sec_erase_mult;	/* 230 */
 	u8			raw_sec_feature_support;/* 231 */
 	u8			raw_trim_mult;		/* 232 */
+	u8			raw_bkops_status;	/* 246 */
 	u8			raw_sectors[4];		/* 212 - 4 bytes */
 
 	unsigned int            feature_support;
@@ -225,7 +230,7 @@
 #define MMC_CARD_SDXC		(1<<6)		/* card is SDXC */
 #define MMC_CARD_REMOVED	(1<<7)		/* card has been removed */
 #define MMC_STATE_HIGHSPEED_200	(1<<8)		/* card is in HS200 mode */
-#define MMC_STATE_SLEEP		(1<<9)		/* card is in sleep state */
+#define MMC_STATE_DOING_BKOPS	(1<<10)		/* card is doing BKOPS */
 	unsigned int		quirks; 	/* card quirks */
 #define MMC_QUIRK_LENIENT_FN0	(1<<0)		/* allow SDIO FN0 writes outside of the VS CCCR range */
 #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1)	/* use func->cur_blksize */
@@ -241,11 +246,6 @@
 #define MMC_QUIRK_LONG_READ_TIME (1<<9)		/* Data read time > CSD says */
 #define MMC_QUIRK_SEC_ERASE_TRIM_BROKEN (1<<10)	/* Skip secure for erase/trim */
 						/* byte mode */
-	unsigned int    poweroff_notify_state;	/* eMMC4.5 notify feature */
-#define MMC_NO_POWER_NOTIFICATION	0
-#define MMC_POWERED_ON			1
-#define MMC_POWEROFF_SHORT		2
-#define MMC_POWEROFF_LONG		3
 
 	unsigned int		erase_size;	/* erase size in sectors */
  	unsigned int		erase_shift;	/* if erase unit is power 2 */
@@ -392,7 +392,7 @@
 #define mmc_sd_card_uhs(c)	((c)->state & MMC_STATE_ULTRAHIGHSPEED)
 #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
 #define mmc_card_removed(c)	((c) && ((c)->state & MMC_CARD_REMOVED))
-#define mmc_card_is_sleep(c)	((c)->state & MMC_STATE_SLEEP)
+#define mmc_card_doing_bkops(c)	((c)->state & MMC_STATE_DOING_BKOPS)
 
 #define mmc_card_set_present(c)	((c)->state |= MMC_STATE_PRESENT)
 #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
@@ -404,9 +404,9 @@
 #define mmc_sd_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED)
 #define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC)
 #define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED)
-#define mmc_card_set_sleep(c)	((c)->state |= MMC_STATE_SLEEP)
+#define mmc_card_set_doing_bkops(c)	((c)->state |= MMC_STATE_DOING_BKOPS)
+#define mmc_card_clr_doing_bkops(c)	((c)->state &= ~MMC_STATE_DOING_BKOPS)
 
-#define mmc_card_clr_sleep(c)	((c)->state &= ~MMC_STATE_SLEEP)
 /*
  * Quirk add/remove for MMC products.
  */
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index 1b431c7..9b9cdaf 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -134,6 +134,8 @@
 struct mmc_card;
 struct mmc_async_req;
 
+extern int mmc_stop_bkops(struct mmc_card *);
+extern int mmc_read_bkops_status(struct mmc_card *);
 extern struct mmc_async_req *mmc_start_req(struct mmc_host *,
 					   struct mmc_async_req *, int *);
 extern int mmc_interrupt_hpi(struct mmc_card *);
@@ -142,6 +144,8 @@
 extern int mmc_app_cmd(struct mmc_host *, struct mmc_card *);
 extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *,
 	struct mmc_command *, int);
+extern void mmc_start_bkops(struct mmc_card *card, bool from_exception);
+extern int __mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int, bool);
 extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int);
 
 #define MMC_ERASE_ARG		0x00000000
diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
index 7a7ebd3..7c6a113 100644
--- a/include/linux/mmc/dw_mmc.h
+++ b/include/linux/mmc/dw_mmc.h
@@ -78,6 +78,10 @@
  * @data_offset: Set the offset of DATA register according to VERID.
  * @dev: Device associated with the MMC controller.
  * @pdata: Platform data associated with the MMC controller.
+ * @drv_data: Driver specific data for identified variant of the controller
+ * @priv: Implementation defined private data.
+ * @biu_clk: Pointer to bus interface unit clock instance.
+ * @ciu_clk: Pointer to card interface unit clock instance.
  * @slot: Slots sharing this MMC controller.
  * @fifo_depth: depth of FIFO.
  * @data_shift: log2 of FIFO item size.
@@ -156,8 +160,12 @@
 	u32			fifoth_val;
 	u16			verid;
 	u16			data_offset;
-	struct device		dev;
+	struct device		*dev;
 	struct dw_mci_board	*pdata;
+	struct dw_mci_drv_data	*drv_data;
+	void			*priv;
+	struct clk		*biu_clk;
+	struct clk		*ciu_clk;
 	struct dw_mci_slot	*slot[MAX_MCI_SLOTS];
 
 	/* FIFO push and pull */
@@ -201,7 +209,8 @@
 #define DW_MCI_QUIRK_HIGHSPEED			BIT(2)
 /* Unreliable card detection */
 #define DW_MCI_QUIRK_BROKEN_CARD_DETECTION	BIT(3)
-
+/* Write Protect detection not available */
+#define DW_MCI_QUIRK_NO_WRITE_PROTECT		BIT(4)
 
 struct dma_pdata;
 
@@ -218,7 +227,7 @@
 	u32 num_slots;
 
 	u32 quirks; /* Workaround / Quirk flags */
-	unsigned int bus_hz; /* Bus speed */
+	unsigned int bus_hz; /* Clock speed at the cclk_in pad */
 
 	unsigned int caps;	/* Capabilities */
 	unsigned int caps2;	/* More capabilities */
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index f578a71..7abb0e1 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -259,10 +259,6 @@
 #define MMC_CAP2_RO_ACTIVE_HIGH	(1 << 11)	/* Write-protect signal active high */
 
 	mmc_pm_flag_t		pm_caps;	/* supported pm features */
-	unsigned int        power_notify_type;
-#define MMC_HOST_PW_NOTIFY_NONE		0
-#define MMC_HOST_PW_NOTIFY_SHORT	1
-#define MMC_HOST_PW_NOTIFY_LONG		2
 
 #ifdef CONFIG_MMC_CLKGATE
 	int			clk_requests;	/* internal reference counter */
@@ -300,6 +296,7 @@
 #endif
 
 	int			rescan_disable;	/* disable card detection */
+	int			rescan_entered;	/* used with nonremovable devices */
 
 	struct mmc_card		*card;		/* device attached to this host */
 
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index d425cab..01e4b39 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -139,6 +139,7 @@
 #define R1_CURRENT_STATE(x)	((x & 0x00001E00) >> 9)	/* sx, b (4 bits) */
 #define R1_READY_FOR_DATA	(1 << 8)	/* sx, a */
 #define R1_SWITCH_ERROR		(1 << 7)	/* sx, c */
+#define R1_EXCEPTION_EVENT	(1 << 6)	/* sx, a */
 #define R1_APP_CMD		(1 << 5)	/* sr, c */
 
 #define R1_STATE_IDLE	0
@@ -274,12 +275,15 @@
 #define EXT_CSD_FLUSH_CACHE		32      /* W */
 #define EXT_CSD_CACHE_CTRL		33      /* R/W */
 #define EXT_CSD_POWER_OFF_NOTIFICATION	34	/* R/W */
+#define EXT_CSD_EXP_EVENTS_STATUS	54	/* RO */
 #define EXT_CSD_DATA_SECTOR_SIZE	61	/* R */
 #define EXT_CSD_GP_SIZE_MULT		143	/* R/W */
 #define EXT_CSD_PARTITION_ATTRIBUTE	156	/* R/W */
 #define EXT_CSD_PARTITION_SUPPORT	160	/* RO */
 #define EXT_CSD_HPI_MGMT		161	/* R/W */
 #define EXT_CSD_RST_N_FUNCTION		162	/* R/W */
+#define EXT_CSD_BKOPS_EN		163	/* R/W */
+#define EXT_CSD_BKOPS_START		164	/* W */
 #define EXT_CSD_SANITIZE_START		165     /* W */
 #define EXT_CSD_WR_REL_PARAM		166	/* RO */
 #define EXT_CSD_BOOT_WP			173	/* R/W */
@@ -313,11 +317,13 @@
 #define EXT_CSD_PWR_CL_200_360		237	/* RO */
 #define EXT_CSD_PWR_CL_DDR_52_195	238	/* RO */
 #define EXT_CSD_PWR_CL_DDR_52_360	239	/* RO */
+#define EXT_CSD_BKOPS_STATUS		246	/* RO */
 #define EXT_CSD_POWER_OFF_LONG_TIME	247	/* RO */
 #define EXT_CSD_GENERIC_CMD6_TIME	248	/* RO */
 #define EXT_CSD_CACHE_SIZE		249	/* RO, 4 bytes */
 #define EXT_CSD_TAG_UNIT_SIZE		498	/* RO */
 #define EXT_CSD_DATA_TAG_SUPPORT	499	/* RO */
+#define EXT_CSD_BKOPS_SUPPORT		502	/* RO */
 #define EXT_CSD_HPI_FEATURES		503	/* RO */
 
 /*
@@ -378,6 +384,19 @@
 #define EXT_CSD_PWR_CL_8BIT_SHIFT	4
 #define EXT_CSD_PWR_CL_4BIT_SHIFT	0
 /*
+ * EXCEPTION_EVENT_STATUS field
+ */
+#define EXT_CSD_URGENT_BKOPS		BIT(0)
+#define EXT_CSD_DYNCAP_NEEDED		BIT(1)
+#define EXT_CSD_SYSPOOL_EXHAUSTED	BIT(2)
+#define EXT_CSD_PACKED_FAILURE		BIT(3)
+
+/*
+ * BKOPS status level
+ */
+#define EXT_CSD_BKOPS_LEVEL_2		0x2
+
+/*
  * MMC_SWITCH access modes
  */
 
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index ac83b10..fa8529a 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -97,7 +97,8 @@
 
 	const struct sdhci_ops *ops;	/* Low level hw interface */
 
-	struct regulator *vmmc;	/* Power regulator */
+	struct regulator *vmmc;		/* Power regulator (vmmc) */
+	struct regulator *vqmmc;	/* Signaling regulator (vccq) */
 
 	/* Internal data */
 	struct mmc_host *mmc;	/* MMC structure */
diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h
index 1d1b1e1..bc823c4 100644
--- a/include/linux/mmu_notifier.h
+++ b/include/linux/mmu_notifier.h
@@ -4,6 +4,7 @@
 #include <linux/list.h>
 #include <linux/spinlock.h>
 #include <linux/mm_types.h>
+#include <linux/srcu.h>
 
 struct mmu_notifier;
 struct mmu_notifier_ops;
@@ -245,50 +246,6 @@
 		__mmu_notifier_mm_destroy(mm);
 }
 
-/*
- * These two macros will sometime replace ptep_clear_flush.
- * ptep_clear_flush is implemented as macro itself, so this also is
- * implemented as a macro until ptep_clear_flush will converted to an
- * inline function, to diminish the risk of compilation failure. The
- * invalidate_page method over time can be moved outside the PT lock
- * and these two macros can be later removed.
- */
-#define ptep_clear_flush_notify(__vma, __address, __ptep)		\
-({									\
-	pte_t __pte;							\
-	struct vm_area_struct *___vma = __vma;				\
-	unsigned long ___address = __address;				\
-	__pte = ptep_clear_flush(___vma, ___address, __ptep);		\
-	mmu_notifier_invalidate_page(___vma->vm_mm, ___address);	\
-	__pte;								\
-})
-
-#define pmdp_clear_flush_notify(__vma, __address, __pmdp)		\
-({									\
-	pmd_t __pmd;							\
-	struct vm_area_struct *___vma = __vma;				\
-	unsigned long ___address = __address;				\
-	VM_BUG_ON(__address & ~HPAGE_PMD_MASK);				\
-	mmu_notifier_invalidate_range_start(___vma->vm_mm, ___address,	\
-					    (__address)+HPAGE_PMD_SIZE);\
-	__pmd = pmdp_clear_flush(___vma, ___address, __pmdp);		\
-	mmu_notifier_invalidate_range_end(___vma->vm_mm, ___address,	\
-					  (__address)+HPAGE_PMD_SIZE);	\
-	__pmd;								\
-})
-
-#define pmdp_splitting_flush_notify(__vma, __address, __pmdp)		\
-({									\
-	struct vm_area_struct *___vma = __vma;				\
-	unsigned long ___address = __address;				\
-	VM_BUG_ON(__address & ~HPAGE_PMD_MASK);				\
-	mmu_notifier_invalidate_range_start(___vma->vm_mm, ___address,	\
-					    (__address)+HPAGE_PMD_SIZE);\
-	pmdp_splitting_flush(___vma, ___address, __pmdp);		\
-	mmu_notifier_invalidate_range_end(___vma->vm_mm, ___address,	\
-					  (__address)+HPAGE_PMD_SIZE);	\
-})
-
 #define ptep_clear_flush_young_notify(__vma, __address, __ptep)		\
 ({									\
 	int __young;							\
@@ -311,14 +268,24 @@
 	__young;							\
 })
 
+/*
+ * set_pte_at_notify() sets the pte _after_ running the notifier.
+ * This is safe to start by updating the secondary MMUs, because the primary MMU
+ * pte invalidate must have already happened with a ptep_clear_flush() before
+ * set_pte_at_notify() has been invoked.  Updating the secondary MMUs first is
+ * required when we change both the protection of the mapping from read-only to
+ * read-write and the pfn (like during copy on write page faults). Otherwise the
+ * old page would remain mapped readonly in the secondary MMUs after the new
+ * page is already writable by some CPU through the primary MMU.
+ */
 #define set_pte_at_notify(__mm, __address, __ptep, __pte)		\
 ({									\
 	struct mm_struct *___mm = __mm;					\
 	unsigned long ___address = __address;				\
 	pte_t ___pte = __pte;						\
 									\
-	set_pte_at(___mm, ___address, __ptep, ___pte);			\
 	mmu_notifier_change_pte(___mm, ___address, ___pte);		\
+	set_pte_at(___mm, ___address, __ptep, ___pte);			\
 })
 
 #else /* CONFIG_MMU_NOTIFIER */
@@ -369,9 +336,6 @@
 
 #define ptep_clear_flush_young_notify ptep_clear_flush_young
 #define pmdp_clear_flush_young_notify pmdp_clear_flush_young
-#define ptep_clear_flush_notify ptep_clear_flush
-#define pmdp_clear_flush_notify pmdp_clear_flush
-#define pmdp_splitting_flush_notify pmdp_splitting_flush
 #define set_pte_at_notify set_pte_at
 
 #endif /* CONFIG_MMU_NOTIFIER */
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 2daa54f..50aaca8 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -142,6 +142,7 @@
 	NUMA_OTHER,		/* allocation from other node */
 #endif
 	NR_ANON_TRANSPARENT_HUGEPAGES,
+	NR_FREE_CMA_PAGES,
 	NR_VM_ZONE_STAT_ITEMS };
 
 /*
@@ -217,6 +218,8 @@
 #define ISOLATE_UNMAPPED	((__force isolate_mode_t)0x2)
 /* Isolate for asynchronous migration */
 #define ISOLATE_ASYNC_MIGRATE	((__force isolate_mode_t)0x4)
+/* Isolate unevictable pages */
+#define ISOLATE_UNEVICTABLE	((__force isolate_mode_t)0x8)
 
 /* LRU Isolation modes. */
 typedef unsigned __bitwise__ isolate_mode_t;
@@ -369,8 +372,12 @@
 	spinlock_t		lock;
 	int                     all_unreclaimable; /* All pages pinned */
 #if defined CONFIG_COMPACTION || defined CONFIG_CMA
-	/* pfn where the last incremental compaction isolated free pages */
+	/* Set to true when the PG_migrate_skip bits should be cleared */
+	bool			compact_blockskip_flush;
+
+	/* pfns where compaction scanners should start */
 	unsigned long		compact_cached_free_pfn;
+	unsigned long		compact_cached_migrate_pfn;
 #endif
 #ifdef CONFIG_MEMORY_HOTPLUG
 	/* see spanned/present_pages for more description */
@@ -704,6 +711,7 @@
 	unsigned long node_spanned_pages; /* total size of physical page
 					     range, including holes */
 	int node_id;
+	nodemask_t reclaim_nodes;	/* Nodes allowed to reclaim from */
 	wait_queue_head_t kswapd_wait;
 	wait_queue_head_t pfmemalloc_wait;
 	struct task_struct *kswapd;	/* Protected by lock_memory_hotplug() */
diff --git a/include/linux/mtd/bbm.h b/include/linux/mtd/bbm.h
index 650ef35..211ff67 100644
--- a/include/linux/mtd/bbm.h
+++ b/include/linux/mtd/bbm.h
@@ -78,8 +78,6 @@
 #define NAND_BBT_LASTBLOCK	0x00000010
 /* The bbt is at the given page, else we must scan for the bbt */
 #define NAND_BBT_ABSPAGE	0x00000020
-/* The bbt is at the given page, else we must scan for the bbt */
-#define NAND_BBT_SEARCH		0x00000040
 /* bbt is stored per chip on multichip devices */
 #define NAND_BBT_PERCHIP	0x00000080
 /* bbt has a version counter at offset veroffs */
@@ -110,7 +108,10 @@
  * OOB area. This option is passed to the default bad block table function.
  */
 #define NAND_BBT_USE_FLASH	0x00020000
-/* Do not store flash based bad block table in OOB area; store it in-band */
+/*
+ * Do not store flash based bad block table marker in the OOB area; store it
+ * in-band.
+ */
 #define NAND_BBT_NO_OOB		0x00040000
 /*
  * Do not write new bad block markers to OOB; useful, e.g., when ECC covers
diff --git a/include/linux/mtd/lpc32xx_mlc.h b/include/linux/mtd/lpc32xx_mlc.h
new file mode 100644
index 0000000..d91b1e3
--- /dev/null
+++ b/include/linux/mtd/lpc32xx_mlc.h
@@ -0,0 +1,20 @@
+/*
+ * Platform data for LPC32xx SoC MLC NAND controller
+ *
+ * Copyright © 2012 Roland Stigge
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_MTD_LPC32XX_MLC_H
+#define __LINUX_MTD_LPC32XX_MLC_H
+
+#include <linux/dmaengine.h>
+
+struct lpc32xx_mlc_platform_data {
+	bool (*dma_filter)(struct dma_chan *chan, void *filter_param);
+};
+
+#endif  /* __LINUX_MTD_LPC32XX_MLC_H */
diff --git a/include/linux/mtd/lpc32xx_slc.h b/include/linux/mtd/lpc32xx_slc.h
new file mode 100644
index 0000000..1169548
--- /dev/null
+++ b/include/linux/mtd/lpc32xx_slc.h
@@ -0,0 +1,20 @@
+/*
+ * Platform data for LPC32xx SoC SLC NAND controller
+ *
+ * Copyright © 2012 Roland Stigge
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_MTD_LPC32XX_SLC_H
+#define __LINUX_MTD_LPC32XX_SLC_H
+
+#include <linux/dmaengine.h>
+
+struct lpc32xx_slc_platform_data {
+	bool (*dma_filter)(struct dma_chan *chan, void *filter_param);
+};
+
+#endif  /* __LINUX_MTD_LPC32XX_SLC_H */
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 63dadc0..81d61e7 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -265,14 +265,7 @@
 int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen,
 		    const u_char *buf);
 
-static inline int mtd_read_oob(struct mtd_info *mtd, loff_t from,
-			       struct mtd_oob_ops *ops)
-{
-	ops->retlen = ops->oobretlen = 0;
-	if (!mtd->_read_oob)
-		return -EOPNOTSUPP;
-	return mtd->_read_oob(mtd, from, ops);
-}
+int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops);
 
 static inline int mtd_write_oob(struct mtd_info *mtd, loff_t to,
 				struct mtd_oob_ops *ops)
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 57977c6..24e9159 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -56,7 +56,7 @@
  * is supported now. If you add a chip with bigger oobsize/page
  * adjust this accordingly.
  */
-#define NAND_MAX_OOBSIZE	576
+#define NAND_MAX_OOBSIZE	640
 #define NAND_MAX_PAGESIZE	8192
 
 /*
@@ -92,6 +92,8 @@
 #define NAND_CMD_READID		0x90
 #define NAND_CMD_ERASE2		0xd0
 #define NAND_CMD_PARAM		0xec
+#define NAND_CMD_GET_FEATURES	0xee
+#define NAND_CMD_SET_FEATURES	0xef
 #define NAND_CMD_RESET		0xff
 
 #define NAND_CMD_LOCK		0x2a
@@ -185,12 +187,6 @@
  * This happens with the Renesas AG-AND chips, possibly others.
  */
 #define BBT_AUTO_REFRESH	0x00000080
-/*
- * Chip does not require ready check on read. True
- * for all large page devices, as they do not support
- * autoincrement.
- */
-#define NAND_NO_READRDY		0x00000100
 /* Chip does not allow subpage writes */
 #define NAND_NO_SUBPAGE_WRITE	0x00000200
 
@@ -200,6 +196,9 @@
 /* Device behaves just like nand, but is readonly */
 #define NAND_ROM		0x00000800
 
+/* Device supports subpage reads */
+#define NAND_SUBPAGE_READ	0x00001000
+
 /* Options valid for Samsung large page devices */
 #define NAND_SAMSUNG_LP_OPTIONS \
 	(NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK)
@@ -208,12 +207,7 @@
 #define NAND_MUST_PAD(chip) (!(chip->options & NAND_NO_PADDING))
 #define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG))
 #define NAND_HAS_COPYBACK(chip) ((chip->options & NAND_COPYBACK))
-/* Large page NAND with SOFT_ECC should support subpage reads */
-#define NAND_SUBPAGE_READ(chip) ((chip->ecc.mode == NAND_ECC_SOFT) \
-					&& (chip->page_shift > 9))
-
-/* Mask to zero out the chip options, which come from the id table */
-#define NAND_CHIPOPTIONS_MSK	0x0000ffff
+#define NAND_HAS_SUBPAGE_READ(chip) ((chip->options & NAND_SUBPAGE_READ))
 
 /* Non chip related options */
 /* This option skips the bbt scan during initialization. */
@@ -237,6 +231,21 @@
 /* Keep gcc happy */
 struct nand_chip;
 
+/* ONFI timing mode, used in both asynchronous and synchronous mode */
+#define ONFI_TIMING_MODE_0		(1 << 0)
+#define ONFI_TIMING_MODE_1		(1 << 1)
+#define ONFI_TIMING_MODE_2		(1 << 2)
+#define ONFI_TIMING_MODE_3		(1 << 3)
+#define ONFI_TIMING_MODE_4		(1 << 4)
+#define ONFI_TIMING_MODE_5		(1 << 5)
+#define ONFI_TIMING_MODE_UNKNOWN	(1 << 6)
+
+/* ONFI feature address */
+#define ONFI_FEATURE_ADDR_TIMING_MODE	0x1
+
+/* ONFI subfeature parameters length */
+#define ONFI_SUBFEATURE_PARAM_LEN	4
+
 struct nand_onfi_params {
 	/* rev info and features block */
 	/* 'O' 'N' 'F' 'I'  */
@@ -334,8 +343,10 @@
  * @read_page_raw:	function to read a raw page without ECC
  * @write_page_raw:	function to write a raw page without ECC
  * @read_page:	function to read a page according to the ECC generator
- *		requirements.
- * @read_subpage:	function to read parts of the page covered by ECC.
+ *		requirements; returns maximum number of bitflips corrected in
+ *		any single ECC step, 0 if bitflips uncorrectable, -EIO hw error
+ * @read_subpage:	function to read parts of the page covered by ECC;
+ *			returns same as read_page()
  * @write_page:	function to write a page according to the ECC generator
  *		requirements.
  * @write_oob_raw:	function to write chip OOB data without ECC
@@ -361,13 +372,13 @@
 			uint8_t *calc_ecc);
 	int (*read_page_raw)(struct mtd_info *mtd, struct nand_chip *chip,
 			uint8_t *buf, int oob_required, int page);
-	void (*write_page_raw)(struct mtd_info *mtd, struct nand_chip *chip,
+	int (*write_page_raw)(struct mtd_info *mtd, struct nand_chip *chip,
 			const uint8_t *buf, int oob_required);
 	int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
 			uint8_t *buf, int oob_required, int page);
 	int (*read_subpage)(struct mtd_info *mtd, struct nand_chip *chip,
 			uint32_t offs, uint32_t len, uint8_t *buf);
-	void (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
+	int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
 			const uint8_t *buf, int oob_required);
 	int (*write_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip,
 			int page);
@@ -403,8 +414,6 @@
  * @read_word:		[REPLACEABLE] read one word from the chip
  * @write_buf:		[REPLACEABLE] write data from the buffer to the chip
  * @read_buf:		[REPLACEABLE] read data from the chip into the buffer
- * @verify_buf:		[REPLACEABLE] verify buffer contents against the chip
- *			data.
  * @select_chip:	[REPLACEABLE] select chip nr
  * @block_bad:		[REPLACEABLE] check, if the block is bad
  * @block_markbad:	[REPLACEABLE] mark the block bad
@@ -462,6 +471,8 @@
  *			non 0 if ONFI supported.
  * @onfi_params:	[INTERN] holds the ONFI page parameter when ONFI is
  *			supported, 0 otherwise.
+ * @onfi_set_features	[REPLACEABLE] set the features for ONFI nand
+ * @onfi_get_features	[REPLACEABLE] get the features for ONFI nand
  * @ecclayout:		[REPLACEABLE] the default ECC placement scheme
  * @bbt:		[INTERN] bad block table pointer
  * @bbt_td:		[REPLACEABLE] bad block table descriptor for flash
@@ -487,7 +498,6 @@
 	u16 (*read_word)(struct mtd_info *mtd);
 	void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
 	void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len);
-	int (*verify_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
 	void (*select_chip)(struct mtd_info *mtd, int chip);
 	int (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip);
 	int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
@@ -505,6 +515,10 @@
 	int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
 			const uint8_t *buf, int oob_required, int page,
 			int cached, int raw);
+	int (*onfi_set_features)(struct mtd_info *mtd, struct nand_chip *chip,
+			int feature_addr, uint8_t *subfeature_para);
+	int (*onfi_get_features)(struct mtd_info *mtd, struct nand_chip *chip,
+			int feature_addr, uint8_t *subfeature_para);
 
 	int chip_delay;
 	unsigned int options;
@@ -559,6 +573,7 @@
 #define NAND_MFR_MICRON		0x2c
 #define NAND_MFR_AMD		0x01
 #define NAND_MFR_MACRONIX	0xc2
+#define NAND_MFR_EON		0x92
 
 /**
  * struct nand_flash_dev - NAND Flash Device ID Structure
@@ -641,6 +656,7 @@
  *			ALE/CLE/nCE. Also used to write command and address
  * @write_buf:		platform specific function for write buffer
  * @read_buf:		platform specific function for read buffer
+ * @read_byte:		platform specific function to read one byte from chip
  * @priv:		private data to transport driver specific settings
  *
  * All fields are optional and depend on the hardware driver requirements
@@ -677,4 +693,20 @@
 	return chip->priv;
 }
 
+/* return the supported asynchronous timing mode. */
+static inline int onfi_get_async_timing_mode(struct nand_chip *chip)
+{
+	if (!chip->onfi_version)
+		return ONFI_TIMING_MODE_UNKNOWN;
+	return le16_to_cpu(chip->onfi_params.async_timing_mode);
+}
+
+/* return the supported synchronous timing mode. */
+static inline int onfi_get_sync_timing_mode(struct nand_chip *chip)
+{
+	if (!chip->onfi_version)
+		return ONFI_TIMING_MODE_UNKNOWN;
+	return le16_to_cpu(chip->onfi_params.src_sync_timing_mode);
+}
+
 #endif /* __LINUX_MTD_NAND_H */
diff --git a/include/linux/mtd/sh_flctl.h b/include/linux/mtd/sh_flctl.h
index a38e1fa..01e4b15 100644
--- a/include/linux/mtd/sh_flctl.h
+++ b/include/linux/mtd/sh_flctl.h
@@ -49,7 +49,6 @@
 #define	FLERRADR(f)		(f->reg + 0x98)
 
 /* FLCMNCR control bits */
-#define ECCPOS2		(0x1 << 25)
 #define _4ECCCNTEN	(0x1 << 24)
 #define _4ECCEN		(0x1 << 23)
 #define _4ECCCORRECT	(0x1 << 22)
@@ -59,9 +58,6 @@
 #define QTSEL_E		(0x1 << 17)
 #define ENDIAN		(0x1 << 16)	/* 1 = little endian */
 #define FCKSEL_E	(0x1 << 15)
-#define ECCPOS_00	(0x00 << 12)
-#define ECCPOS_01	(0x01 << 12)
-#define ECCPOS_02	(0x02 << 12)
 #define ACM_SACCES_MODE	(0x01 << 10)
 #define NANWF_E		(0x1 << 9)
 #define SE_D		(0x1 << 8)	/* Spare area disable */
@@ -107,6 +103,14 @@
 #define DOCMD2_E	(0x1 << 17)	/* 2nd cmd stage execute */
 #define DOCMD1_E	(0x1 << 16)	/* 1st cmd stage execute */
 
+/* FLINTDMACR control bits */
+#define ESTERINTE	(0x1 << 24)	/* ECC error interrupt enable */
+#define AC1CLR		(0x1 << 19)	/* ECC FIFO clear */
+#define AC0CLR		(0x1 << 18)	/* Data FIFO clear */
+#define ECERB		(0x1 << 9)	/* ECC error */
+#define STERB		(0x1 << 8)	/* Status error */
+#define STERINTE	(0x1 << 4)	/* Status error enable */
+
 /* FLTRCR control bits */
 #define TRSTRT		(0x1 << 0)	/* translation start */
 #define TREND		(0x1 << 1)	/* translation end */
@@ -125,9 +129,15 @@
 #define	_4ECCEND	(0x1 << 1)	/* 4 symbols end */
 #define	_4ECCEXST	(0x1 << 0)	/* 4 symbols exist */
 
-#define INIT_FL4ECCRESULT_VAL	0x03FF03FF
 #define LOOP_TIMEOUT_MAX	0x00010000
 
+enum flctl_ecc_res_t {
+	FL_SUCCESS,
+	FL_REPAIRABLE,
+	FL_ERROR,
+	FL_TIMEOUT
+};
+
 struct sh_flctl {
 	struct mtd_info		mtd;
 	struct nand_chip	chip;
@@ -145,8 +155,7 @@
 	uint32_t erase_ADRCNT;		/* bits of FLCMDCR in ERASE1 cmd */
 	uint32_t rw_ADRCNT;	/* bits of FLCMDCR in READ WRITE cmd */
 	uint32_t flcmncr_base;	/* base value of FLCMNCR */
-
-	int	hwecc_cant_correct[4];
+	uint32_t flintdmacr_base;	/* irq enable bits */
 
 	unsigned page_size:1;	/* NAND page size (0 = 512, 1 = 2048) */
 	unsigned hwecc:1;	/* Hardware ECC (0 = disabled, 1 = enabled) */
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 01646aa..561c8bc 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1497,19 +1497,25 @@
 	/* This indicates where we are processing relative to skb->data. */
 	int data_offset;
 
-	/* This is non-zero if the packet may be of the same flow. */
-	int same_flow;
-
 	/* This is non-zero if the packet cannot be merged with the new skb. */
 	int flush;
 
 	/* Number of segments aggregated. */
-	int count;
+	u16	count;
+
+	/* This is non-zero if the packet may be of the same flow. */
+	u8	same_flow;
 
 	/* Free the skb? */
-	int free;
+	u8	free;
 #define NAPI_GRO_FREE		  1
 #define NAPI_GRO_FREE_STOLEN_HEAD 2
+
+	/* jiffies when first packet was created/queued */
+	unsigned long age;
+
+	/* Used in ipv6_gro_receive() */
+	int	proto;
 };
 
 #define NAPI_GRO_CB(skb) ((struct napi_gro_cb *)(skb)->cb)
@@ -1663,7 +1669,6 @@
 #endif
 extern int	       skb_gro_receive(struct sk_buff **head,
 				       struct sk_buff *skb);
-extern void	       skb_gro_reset_offset(struct sk_buff *skb);
 
 static inline unsigned int skb_gro_offset(const struct sk_buff *skb)
 {
@@ -2157,7 +2162,7 @@
 extern gro_result_t	napi_skb_finish(gro_result_t ret, struct sk_buff *skb);
 extern gro_result_t	napi_gro_receive(struct napi_struct *napi,
 					 struct sk_buff *skb);
-extern void		napi_gro_flush(struct napi_struct *napi);
+extern void		napi_gro_flush(struct napi_struct *napi, bool flush_old);
 extern struct sk_buff *	napi_get_frags(struct napi_struct *napi);
 extern gro_result_t	napi_frags_finish(struct napi_struct *napi,
 					  struct sk_buff *skb,
diff --git a/include/linux/netfilter/Kbuild b/include/linux/netfilter/Kbuild
index 874ae8f..b332202 100644
--- a/include/linux/netfilter/Kbuild
+++ b/include/linux/netfilter/Kbuild
@@ -1,78 +1 @@
 header-y += ipset/
-
-header-y += nf_conntrack_common.h
-header-y += nf_conntrack_ftp.h
-header-y += nf_conntrack_sctp.h
-header-y += nf_conntrack_tcp.h
-header-y += nf_conntrack_tuple_common.h
-header-y += nf_nat.h
-header-y += nfnetlink.h
-header-y += nfnetlink_acct.h
-header-y += nfnetlink_compat.h
-header-y += nfnetlink_conntrack.h
-header-y += nfnetlink_cthelper.h
-header-y += nfnetlink_cttimeout.h
-header-y += nfnetlink_log.h
-header-y += nfnetlink_queue.h
-header-y += x_tables.h
-header-y += xt_AUDIT.h
-header-y += xt_CHECKSUM.h
-header-y += xt_CLASSIFY.h
-header-y += xt_CONNMARK.h
-header-y += xt_CONNSECMARK.h
-header-y += xt_CT.h
-header-y += xt_DSCP.h
-header-y += xt_IDLETIMER.h
-header-y += xt_LED.h
-header-y += xt_LOG.h
-header-y += xt_MARK.h
-header-y += xt_nfacct.h
-header-y += xt_NFLOG.h
-header-y += xt_NFQUEUE.h
-header-y += xt_RATEEST.h
-header-y += xt_SECMARK.h
-header-y += xt_TCPMSS.h
-header-y += xt_TCPOPTSTRIP.h
-header-y += xt_TEE.h
-header-y += xt_TPROXY.h
-header-y += xt_addrtype.h
-header-y += xt_cluster.h
-header-y += xt_comment.h
-header-y += xt_connbytes.h
-header-y += xt_connlimit.h
-header-y += xt_connmark.h
-header-y += xt_conntrack.h
-header-y += xt_cpu.h
-header-y += xt_dccp.h
-header-y += xt_devgroup.h
-header-y += xt_dscp.h
-header-y += xt_ecn.h
-header-y += xt_esp.h
-header-y += xt_hashlimit.h
-header-y += xt_helper.h
-header-y += xt_iprange.h
-header-y += xt_ipvs.h
-header-y += xt_length.h
-header-y += xt_limit.h
-header-y += xt_mac.h
-header-y += xt_mark.h
-header-y += xt_multiport.h
-header-y += xt_osf.h
-header-y += xt_owner.h
-header-y += xt_physdev.h
-header-y += xt_pkttype.h
-header-y += xt_policy.h
-header-y += xt_quota.h
-header-y += xt_rateest.h
-header-y += xt_realm.h
-header-y += xt_recent.h
-header-y += xt_set.h
-header-y += xt_sctp.h
-header-y += xt_socket.h
-header-y += xt_state.h
-header-y += xt_statistic.h
-header-y += xt_string.h
-header-y += xt_tcpmss.h
-header-y += xt_tcpudp.h
-header-y += xt_time.h
-header-y += xt_u32.h
diff --git a/include/linux/netfilter/ipset/Kbuild b/include/linux/netfilter/ipset/Kbuild
index 601fe71..e69de29 100644
--- a/include/linux/netfilter/ipset/Kbuild
+++ b/include/linux/netfilter/ipset/Kbuild
@@ -1,4 +0,0 @@
-header-y += ip_set.h
-header-y += ip_set_bitmap.h
-header-y += ip_set_hash.h
-header-y += ip_set_list.h
diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h
index 528697b..7958e84 100644
--- a/include/linux/netfilter/ipset/ip_set.h
+++ b/include/linux/netfilter/ipset/ip_set.h
@@ -1,6 +1,3 @@
-#ifndef _IP_SET_H
-#define _IP_SET_H
-
 /* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
  *                         Patrick Schaaf <bof@bof.de>
  *                         Martin Josefsson <gandalf@wlug.westbo.se>
@@ -10,199 +7,9 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#ifndef _IP_SET_H
+#define _IP_SET_H
 
-#include <linux/types.h>
-
-/* The protocol version */
-#define IPSET_PROTOCOL		6
-
-/* The max length of strings including NUL: set and type identifiers */
-#define IPSET_MAXNAMELEN	32
-
-/* Message types and commands */
-enum ipset_cmd {
-	IPSET_CMD_NONE,
-	IPSET_CMD_PROTOCOL,	/* 1: Return protocol version */
-	IPSET_CMD_CREATE,	/* 2: Create a new (empty) set */
-	IPSET_CMD_DESTROY,	/* 3: Destroy a (empty) set */
-	IPSET_CMD_FLUSH,	/* 4: Remove all elements from a set */
-	IPSET_CMD_RENAME,	/* 5: Rename a set */
-	IPSET_CMD_SWAP,		/* 6: Swap two sets */
-	IPSET_CMD_LIST,		/* 7: List sets */
-	IPSET_CMD_SAVE,		/* 8: Save sets */
-	IPSET_CMD_ADD,		/* 9: Add an element to a set */
-	IPSET_CMD_DEL,		/* 10: Delete an element from a set */
-	IPSET_CMD_TEST,		/* 11: Test an element in a set */
-	IPSET_CMD_HEADER,	/* 12: Get set header data only */
-	IPSET_CMD_TYPE,		/* 13: Get set type */
-	IPSET_MSG_MAX,		/* Netlink message commands */
-
-	/* Commands in userspace: */
-	IPSET_CMD_RESTORE = IPSET_MSG_MAX, /* 14: Enter restore mode */
-	IPSET_CMD_HELP,		/* 15: Get help */
-	IPSET_CMD_VERSION,	/* 16: Get program version */
-	IPSET_CMD_QUIT,		/* 17: Quit from interactive mode */
-
-	IPSET_CMD_MAX,
-
-	IPSET_CMD_COMMIT = IPSET_CMD_MAX, /* 18: Commit buffered commands */
-};
-
-/* Attributes at command level */
-enum {
-	IPSET_ATTR_UNSPEC,
-	IPSET_ATTR_PROTOCOL,	/* 1: Protocol version */
-	IPSET_ATTR_SETNAME,	/* 2: Name of the set */
-	IPSET_ATTR_TYPENAME,	/* 3: Typename */
-	IPSET_ATTR_SETNAME2 = IPSET_ATTR_TYPENAME, /* Setname at rename/swap */
-	IPSET_ATTR_REVISION,	/* 4: Settype revision */
-	IPSET_ATTR_FAMILY,	/* 5: Settype family */
-	IPSET_ATTR_FLAGS,	/* 6: Flags at command level */
-	IPSET_ATTR_DATA,	/* 7: Nested attributes */
-	IPSET_ATTR_ADT,		/* 8: Multiple data containers */
-	IPSET_ATTR_LINENO,	/* 9: Restore lineno */
-	IPSET_ATTR_PROTOCOL_MIN, /* 10: Minimal supported version number */
-	IPSET_ATTR_REVISION_MIN	= IPSET_ATTR_PROTOCOL_MIN, /* type rev min */
-	__IPSET_ATTR_CMD_MAX,
-};
-#define IPSET_ATTR_CMD_MAX	(__IPSET_ATTR_CMD_MAX - 1)
-
-/* CADT specific attributes */
-enum {
-	IPSET_ATTR_IP = IPSET_ATTR_UNSPEC + 1,
-	IPSET_ATTR_IP_FROM = IPSET_ATTR_IP,
-	IPSET_ATTR_IP_TO,	/* 2 */
-	IPSET_ATTR_CIDR,	/* 3 */
-	IPSET_ATTR_PORT,	/* 4 */
-	IPSET_ATTR_PORT_FROM = IPSET_ATTR_PORT,
-	IPSET_ATTR_PORT_TO,	/* 5 */
-	IPSET_ATTR_TIMEOUT,	/* 6 */
-	IPSET_ATTR_PROTO,	/* 7 */
-	IPSET_ATTR_CADT_FLAGS,	/* 8 */
-	IPSET_ATTR_CADT_LINENO = IPSET_ATTR_LINENO,	/* 9 */
-	/* Reserve empty slots */
-	IPSET_ATTR_CADT_MAX = 16,
-	/* Create-only specific attributes */
-	IPSET_ATTR_GC,
-	IPSET_ATTR_HASHSIZE,
-	IPSET_ATTR_MAXELEM,
-	IPSET_ATTR_NETMASK,
-	IPSET_ATTR_PROBES,
-	IPSET_ATTR_RESIZE,
-	IPSET_ATTR_SIZE,
-	/* Kernel-only */
-	IPSET_ATTR_ELEMENTS,
-	IPSET_ATTR_REFERENCES,
-	IPSET_ATTR_MEMSIZE,
-
-	__IPSET_ATTR_CREATE_MAX,
-};
-#define IPSET_ATTR_CREATE_MAX	(__IPSET_ATTR_CREATE_MAX - 1)
-
-/* ADT specific attributes */
-enum {
-	IPSET_ATTR_ETHER = IPSET_ATTR_CADT_MAX + 1,
-	IPSET_ATTR_NAME,
-	IPSET_ATTR_NAMEREF,
-	IPSET_ATTR_IP2,
-	IPSET_ATTR_CIDR2,
-	IPSET_ATTR_IP2_TO,
-	IPSET_ATTR_IFACE,
-	__IPSET_ATTR_ADT_MAX,
-};
-#define IPSET_ATTR_ADT_MAX	(__IPSET_ATTR_ADT_MAX - 1)
-
-/* IP specific attributes */
-enum {
-	IPSET_ATTR_IPADDR_IPV4 = IPSET_ATTR_UNSPEC + 1,
-	IPSET_ATTR_IPADDR_IPV6,
-	__IPSET_ATTR_IPADDR_MAX,
-};
-#define IPSET_ATTR_IPADDR_MAX	(__IPSET_ATTR_IPADDR_MAX - 1)
-
-/* Error codes */
-enum ipset_errno {
-	IPSET_ERR_PRIVATE = 4096,
-	IPSET_ERR_PROTOCOL,
-	IPSET_ERR_FIND_TYPE,
-	IPSET_ERR_MAX_SETS,
-	IPSET_ERR_BUSY,
-	IPSET_ERR_EXIST_SETNAME2,
-	IPSET_ERR_TYPE_MISMATCH,
-	IPSET_ERR_EXIST,
-	IPSET_ERR_INVALID_CIDR,
-	IPSET_ERR_INVALID_NETMASK,
-	IPSET_ERR_INVALID_FAMILY,
-	IPSET_ERR_TIMEOUT,
-	IPSET_ERR_REFERENCED,
-	IPSET_ERR_IPADDR_IPV4,
-	IPSET_ERR_IPADDR_IPV6,
-
-	/* Type specific error codes */
-	IPSET_ERR_TYPE_SPECIFIC = 4352,
-};
-
-/* Flags at command level */
-enum ipset_cmd_flags {
-	IPSET_FLAG_BIT_EXIST	= 0,
-	IPSET_FLAG_EXIST	= (1 << IPSET_FLAG_BIT_EXIST),
-	IPSET_FLAG_BIT_LIST_SETNAME = 1,
-	IPSET_FLAG_LIST_SETNAME	= (1 << IPSET_FLAG_BIT_LIST_SETNAME),
-	IPSET_FLAG_BIT_LIST_HEADER = 2,
-	IPSET_FLAG_LIST_HEADER	= (1 << IPSET_FLAG_BIT_LIST_HEADER),
-	IPSET_FLAG_CMD_MAX = 15,	/* Lower half */
-};
-
-/* Flags at CADT attribute level */
-enum ipset_cadt_flags {
-	IPSET_FLAG_BIT_BEFORE	= 0,
-	IPSET_FLAG_BEFORE	= (1 << IPSET_FLAG_BIT_BEFORE),
-	IPSET_FLAG_BIT_PHYSDEV	= 1,
-	IPSET_FLAG_PHYSDEV	= (1 << IPSET_FLAG_BIT_PHYSDEV),
-	IPSET_FLAG_BIT_NOMATCH	= 2,
-	IPSET_FLAG_NOMATCH	= (1 << IPSET_FLAG_BIT_NOMATCH),
-	IPSET_FLAG_CADT_MAX	= 15,	/* Upper half */
-};
-
-/* Commands with settype-specific attributes */
-enum ipset_adt {
-	IPSET_ADD,
-	IPSET_DEL,
-	IPSET_TEST,
-	IPSET_ADT_MAX,
-	IPSET_CREATE = IPSET_ADT_MAX,
-	IPSET_CADT_MAX,
-};
-
-/* Sets are identified by an index in kernel space. Tweak with ip_set_id_t
- * and IPSET_INVALID_ID if you want to increase the max number of sets.
- */
-typedef __u16 ip_set_id_t;
-
-#define IPSET_INVALID_ID		65535
-
-enum ip_set_dim {
-	IPSET_DIM_ZERO = 0,
-	IPSET_DIM_ONE,
-	IPSET_DIM_TWO,
-	IPSET_DIM_THREE,
-	/* Max dimension in elements.
-	 * If changed, new revision of iptables match/target is required.
-	 */
-	IPSET_DIM_MAX = 6,
-	IPSET_BIT_RETURN_NOMATCH = 7,
-};
-
-/* Option flags for kernel operations */
-enum ip_set_kopt {
-	IPSET_INV_MATCH = (1 << IPSET_DIM_ZERO),
-	IPSET_DIM_ONE_SRC = (1 << IPSET_DIM_ONE),
-	IPSET_DIM_TWO_SRC = (1 << IPSET_DIM_TWO),
-	IPSET_DIM_THREE_SRC = (1 << IPSET_DIM_THREE),
-	IPSET_RETURN_NOMATCH = (1 << IPSET_BIT_RETURN_NOMATCH),
-};
-
-#ifdef __KERNEL__
 #include <linux/ip.h>
 #include <linux/ipv6.h>
 #include <linux/netlink.h>
@@ -211,6 +18,7 @@
 #include <linux/stringify.h>
 #include <linux/vmalloc.h>
 #include <net/netlink.h>
+#include <uapi/linux/netfilter/ipset/ip_set.h>
 
 #define _IP_SET_MODULE_DESC(a, b, c)		\
 	MODULE_DESCRIPTION(a " type of IP sets, revisions " b "-" c)
@@ -476,31 +284,4 @@
 	return 4 * ((((b - a + 8) / 8) + 3) / 4);
 }
 
-#endif /* __KERNEL__ */
-
-/* Interface to iptables/ip6tables */
-
-#define SO_IP_SET		83
-
-union ip_set_name_index {
-	char name[IPSET_MAXNAMELEN];
-	ip_set_id_t index;
-};
-
-#define IP_SET_OP_GET_BYNAME	0x00000006	/* Get set index by name */
-struct ip_set_req_get_set {
-	unsigned int op;
-	unsigned int version;
-	union ip_set_name_index set;
-};
-
-#define IP_SET_OP_GET_BYINDEX	0x00000007	/* Get set name by index */
-/* Uses ip_set_req_get_set */
-
-#define IP_SET_OP_VERSION	0x00000100	/* Ask kernel version */
-struct ip_set_req_version {
-	unsigned int op;
-	unsigned int version;
-};
-
 #endif /*_IP_SET_H */
diff --git a/include/linux/netfilter/ipset/ip_set_bitmap.h b/include/linux/netfilter/ipset/ip_set_bitmap.h
index 61a9e87..1a30646 100644
--- a/include/linux/netfilter/ipset/ip_set_bitmap.h
+++ b/include/linux/netfilter/ipset/ip_set_bitmap.h
@@ -1,15 +1,8 @@
 #ifndef __IP_SET_BITMAP_H
 #define __IP_SET_BITMAP_H
 
-/* Bitmap type specific error codes */
-enum {
-	/* The element is out of the range of the set */
-	IPSET_ERR_BITMAP_RANGE = IPSET_ERR_TYPE_SPECIFIC,
-	/* The range exceeds the size limit of the set type */
-	IPSET_ERR_BITMAP_RANGE_SIZE,
-};
+#include <uapi/linux/netfilter/ipset/ip_set_bitmap.h>
 
-#ifdef __KERNEL__
 #define IPSET_BITMAP_MAX_RANGE	0x0000FFFF
 
 /* Common functions */
@@ -26,6 +19,4 @@
 	return mask;
 }
 
-#endif /* __KERNEL__ */
-
 #endif /* __IP_SET_BITMAP_H */
diff --git a/include/linux/netfilter/ipset/ip_set_hash.h b/include/linux/netfilter/ipset/ip_set_hash.h
index e2a9fae..f98ddfb 100644
--- a/include/linux/netfilter/ipset/ip_set_hash.h
+++ b/include/linux/netfilter/ipset/ip_set_hash.h
@@ -1,23 +1,8 @@
 #ifndef __IP_SET_HASH_H
 #define __IP_SET_HASH_H
 
-/* Hash type specific error codes */
-enum {
-	/* Hash is full */
-	IPSET_ERR_HASH_FULL = IPSET_ERR_TYPE_SPECIFIC,
-	/* Null-valued element */
-	IPSET_ERR_HASH_ELEM,
-	/* Invalid protocol */
-	IPSET_ERR_INVALID_PROTO,
-	/* Protocol missing but must be specified */
-	IPSET_ERR_MISSING_PROTO,
-	/* Range not supported */
-	IPSET_ERR_HASH_RANGE_UNSUPPORTED,
-	/* Invalid range */
-	IPSET_ERR_HASH_RANGE,
-};
+#include <uapi/linux/netfilter/ipset/ip_set_hash.h>
 
-#ifdef __KERNEL__
 
 #define IPSET_DEFAULT_HASHSIZE		1024
 #define IPSET_MIMINAL_HASHSIZE		64
@@ -25,6 +10,4 @@
 #define IPSET_DEFAULT_PROBES		4
 #define IPSET_DEFAULT_RESIZE		100
 
-#endif /* __KERNEL__ */
-
 #endif /* __IP_SET_HASH_H */
diff --git a/include/linux/netfilter/ipset/ip_set_list.h b/include/linux/netfilter/ipset/ip_set_list.h
index 40a63f3..68c2aea 100644
--- a/include/linux/netfilter/ipset/ip_set_list.h
+++ b/include/linux/netfilter/ipset/ip_set_list.h
@@ -1,27 +1,10 @@
 #ifndef __IP_SET_LIST_H
 #define __IP_SET_LIST_H
 
-/* List type specific error codes */
-enum {
-	/* Set name to be added/deleted/tested does not exist. */
-	IPSET_ERR_NAME = IPSET_ERR_TYPE_SPECIFIC,
-	/* list:set type is not permitted to add */
-	IPSET_ERR_LOOP,
-	/* Missing reference set */
-	IPSET_ERR_BEFORE,
-	/* Reference set does not exist */
-	IPSET_ERR_NAMEREF,
-	/* Set is full */
-	IPSET_ERR_LIST_FULL,
-	/* Reference set is not added to the set */
-	IPSET_ERR_REF_EXIST,
-};
+#include <uapi/linux/netfilter/ipset/ip_set_list.h>
 
-#ifdef __KERNEL__
 
 #define IP_SET_LIST_DEFAULT_SIZE	8
 #define IP_SET_LIST_MIN_SIZE		4
 
-#endif /* __KERNEL__ */
-
 #endif /* __IP_SET_LIST_H */
diff --git a/include/linux/netfilter/nf_conntrack_common.h b/include/linux/netfilter/nf_conntrack_common.h
index d146872..127d0b9 100644
--- a/include/linux/netfilter/nf_conntrack_common.h
+++ b/include/linux/netfilter/nf_conntrack_common.h
@@ -1,119 +1,8 @@
 #ifndef _NF_CONNTRACK_COMMON_H
 #define _NF_CONNTRACK_COMMON_H
-/* Connection state tracking for netfilter.  This is separated from,
-   but required by, the NAT layer; it can also be used by an iptables
-   extension. */
-enum ip_conntrack_info {
-	/* Part of an established connection (either direction). */
-	IP_CT_ESTABLISHED,
 
-	/* Like NEW, but related to an existing connection, or ICMP error
-	   (in either direction). */
-	IP_CT_RELATED,
+#include <uapi/linux/netfilter/nf_conntrack_common.h>
 
-	/* Started a new connection to track (only
-           IP_CT_DIR_ORIGINAL); may be a retransmission. */
-	IP_CT_NEW,
-
-	/* >= this indicates reply direction */
-	IP_CT_IS_REPLY,
-
-	IP_CT_ESTABLISHED_REPLY = IP_CT_ESTABLISHED + IP_CT_IS_REPLY,
-	IP_CT_RELATED_REPLY = IP_CT_RELATED + IP_CT_IS_REPLY,
-	IP_CT_NEW_REPLY = IP_CT_NEW + IP_CT_IS_REPLY,	
-	/* Number of distinct IP_CT types (no NEW in reply dirn). */
-	IP_CT_NUMBER = IP_CT_IS_REPLY * 2 - 1
-};
-
-/* Bitset representing status of connection. */
-enum ip_conntrack_status {
-	/* It's an expected connection: bit 0 set.  This bit never changed */
-	IPS_EXPECTED_BIT = 0,
-	IPS_EXPECTED = (1 << IPS_EXPECTED_BIT),
-
-	/* We've seen packets both ways: bit 1 set.  Can be set, not unset. */
-	IPS_SEEN_REPLY_BIT = 1,
-	IPS_SEEN_REPLY = (1 << IPS_SEEN_REPLY_BIT),
-
-	/* Conntrack should never be early-expired. */
-	IPS_ASSURED_BIT = 2,
-	IPS_ASSURED = (1 << IPS_ASSURED_BIT),
-
-	/* Connection is confirmed: originating packet has left box */
-	IPS_CONFIRMED_BIT = 3,
-	IPS_CONFIRMED = (1 << IPS_CONFIRMED_BIT),
-
-	/* Connection needs src nat in orig dir.  This bit never changed. */
-	IPS_SRC_NAT_BIT = 4,
-	IPS_SRC_NAT = (1 << IPS_SRC_NAT_BIT),
-
-	/* Connection needs dst nat in orig dir.  This bit never changed. */
-	IPS_DST_NAT_BIT = 5,
-	IPS_DST_NAT = (1 << IPS_DST_NAT_BIT),
-
-	/* Both together. */
-	IPS_NAT_MASK = (IPS_DST_NAT | IPS_SRC_NAT),
-
-	/* Connection needs TCP sequence adjusted. */
-	IPS_SEQ_ADJUST_BIT = 6,
-	IPS_SEQ_ADJUST = (1 << IPS_SEQ_ADJUST_BIT),
-
-	/* NAT initialization bits. */
-	IPS_SRC_NAT_DONE_BIT = 7,
-	IPS_SRC_NAT_DONE = (1 << IPS_SRC_NAT_DONE_BIT),
-
-	IPS_DST_NAT_DONE_BIT = 8,
-	IPS_DST_NAT_DONE = (1 << IPS_DST_NAT_DONE_BIT),
-
-	/* Both together */
-	IPS_NAT_DONE_MASK = (IPS_DST_NAT_DONE | IPS_SRC_NAT_DONE),
-
-	/* Connection is dying (removed from lists), can not be unset. */
-	IPS_DYING_BIT = 9,
-	IPS_DYING = (1 << IPS_DYING_BIT),
-
-	/* Connection has fixed timeout. */
-	IPS_FIXED_TIMEOUT_BIT = 10,
-	IPS_FIXED_TIMEOUT = (1 << IPS_FIXED_TIMEOUT_BIT),
-
-	/* Conntrack is a template */
-	IPS_TEMPLATE_BIT = 11,
-	IPS_TEMPLATE = (1 << IPS_TEMPLATE_BIT),
-
-	/* Conntrack is a fake untracked entry */
-	IPS_UNTRACKED_BIT = 12,
-	IPS_UNTRACKED = (1 << IPS_UNTRACKED_BIT),
-
-	/* Conntrack got a helper explicitly attached via CT target. */
-	IPS_HELPER_BIT = 13,
-	IPS_HELPER = (1 << IPS_HELPER_BIT),
-};
-
-/* Connection tracking event types */
-enum ip_conntrack_events {
-	IPCT_NEW,		/* new conntrack */
-	IPCT_RELATED,		/* related conntrack */
-	IPCT_DESTROY,		/* destroyed conntrack */
-	IPCT_REPLY,		/* connection has seen two-way traffic */
-	IPCT_ASSURED,		/* connection status has changed to assured */
-	IPCT_PROTOINFO,		/* protocol information has changed */
-	IPCT_HELPER,		/* new helper has been set */
-	IPCT_MARK,		/* new mark has been set */
-	IPCT_NATSEQADJ,		/* NAT is doing sequence adjustment */
-	IPCT_SECMARK,		/* new security mark has been set */
-};
-
-enum ip_conntrack_expect_events {
-	IPEXP_NEW,		/* new expectation */
-	IPEXP_DESTROY,		/* destroyed expectation */
-};
-
-/* expectation flags */
-#define NF_CT_EXPECT_PERMANENT		0x1
-#define NF_CT_EXPECT_INACTIVE		0x2
-#define NF_CT_EXPECT_USERSPACE		0x4
-
-#ifdef __KERNEL__
 struct ip_conntrack_stat {
 	unsigned int searched;
 	unsigned int found;
@@ -136,6 +25,4 @@
 /* call to create an explicit dependency on nf_conntrack. */
 extern void need_conntrack(void);
 
-#endif /* __KERNEL__ */
-
 #endif /* _NF_CONNTRACK_COMMON_H */
diff --git a/include/linux/netfilter/nf_conntrack_ftp.h b/include/linux/netfilter/nf_conntrack_ftp.h
index 8faf3f7..5f818b0 100644
--- a/include/linux/netfilter/nf_conntrack_ftp.h
+++ b/include/linux/netfilter/nf_conntrack_ftp.h
@@ -1,20 +1,8 @@
 #ifndef _NF_CONNTRACK_FTP_H
 #define _NF_CONNTRACK_FTP_H
-/* FTP tracking. */
 
-/* This enum is exposed to userspace */
-enum nf_ct_ftp_type {
-	/* PORT command from client */
-	NF_CT_FTP_PORT,
-	/* PASV response from server */
-	NF_CT_FTP_PASV,
-	/* EPRT command from client */
-	NF_CT_FTP_EPRT,
-	/* EPSV response from server */
-	NF_CT_FTP_EPSV,
-};
+#include <uapi/linux/netfilter/nf_conntrack_ftp.h>
 
-#ifdef __KERNEL__
 
 #define FTP_PORT	21
 
@@ -42,6 +30,4 @@
 				       unsigned int matchoff,
 				       unsigned int matchlen,
 				       struct nf_conntrack_expect *exp);
-#endif /* __KERNEL__ */
-
 #endif /* _NF_CONNTRACK_FTP_H */
diff --git a/include/linux/netfilter/nf_conntrack_tcp.h b/include/linux/netfilter/nf_conntrack_tcp.h
index e59868a..22db961 100644
--- a/include/linux/netfilter/nf_conntrack_tcp.h
+++ b/include/linux/netfilter/nf_conntrack_tcp.h
@@ -1,53 +1,8 @@
 #ifndef _NF_CONNTRACK_TCP_H
 #define _NF_CONNTRACK_TCP_H
-/* TCP tracking. */
 
-#include <linux/types.h>
+#include <uapi/linux/netfilter/nf_conntrack_tcp.h>
 
-/* This is exposed to userspace (ctnetlink) */
-enum tcp_conntrack {
-	TCP_CONNTRACK_NONE,
-	TCP_CONNTRACK_SYN_SENT,
-	TCP_CONNTRACK_SYN_RECV,
-	TCP_CONNTRACK_ESTABLISHED,
-	TCP_CONNTRACK_FIN_WAIT,
-	TCP_CONNTRACK_CLOSE_WAIT,
-	TCP_CONNTRACK_LAST_ACK,
-	TCP_CONNTRACK_TIME_WAIT,
-	TCP_CONNTRACK_CLOSE,
-	TCP_CONNTRACK_LISTEN,	/* obsolete */
-#define TCP_CONNTRACK_SYN_SENT2	TCP_CONNTRACK_LISTEN
-	TCP_CONNTRACK_MAX,
-	TCP_CONNTRACK_IGNORE,
-	TCP_CONNTRACK_RETRANS,
-	TCP_CONNTRACK_UNACK,
-	TCP_CONNTRACK_TIMEOUT_MAX
-};
-
-/* Window scaling is advertised by the sender */
-#define IP_CT_TCP_FLAG_WINDOW_SCALE		0x01
-
-/* SACK is permitted by the sender */
-#define IP_CT_TCP_FLAG_SACK_PERM		0x02
-
-/* This sender sent FIN first */
-#define IP_CT_TCP_FLAG_CLOSE_INIT		0x04
-
-/* Be liberal in window checking */
-#define IP_CT_TCP_FLAG_BE_LIBERAL		0x08
-
-/* Has unacknowledged data */
-#define IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED	0x10
-
-/* The field td_maxack has been set */
-#define IP_CT_TCP_FLAG_MAXACK_SET		0x20
-
-struct nf_ct_tcp_flags {
-	__u8 flags;
-	__u8 mask;
-};
-
-#ifdef __KERNEL__
 
 struct ip_ct_tcp_state {
 	u_int32_t	td_end;		/* max of seq + len */
@@ -74,6 +29,4 @@
 	u_int8_t	last_flags;	/* Last flags set */
 };
 
-#endif /* __KERNEL__ */
-
 #endif /* _NF_CONNTRACK_TCP_H */
diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h
index 18341cd..4966dde 100644
--- a/include/linux/netfilter/nfnetlink.h
+++ b/include/linux/netfilter/nfnetlink.h
@@ -1,63 +1,11 @@
 #ifndef _NFNETLINK_H
 #define _NFNETLINK_H
-#include <linux/types.h>
-#include <linux/netfilter/nfnetlink_compat.h>
 
-enum nfnetlink_groups {
-	NFNLGRP_NONE,
-#define NFNLGRP_NONE			NFNLGRP_NONE
-	NFNLGRP_CONNTRACK_NEW,
-#define NFNLGRP_CONNTRACK_NEW		NFNLGRP_CONNTRACK_NEW
-	NFNLGRP_CONNTRACK_UPDATE,
-#define NFNLGRP_CONNTRACK_UPDATE	NFNLGRP_CONNTRACK_UPDATE
-	NFNLGRP_CONNTRACK_DESTROY,
-#define NFNLGRP_CONNTRACK_DESTROY	NFNLGRP_CONNTRACK_DESTROY
-	NFNLGRP_CONNTRACK_EXP_NEW,
-#define	NFNLGRP_CONNTRACK_EXP_NEW	NFNLGRP_CONNTRACK_EXP_NEW
-	NFNLGRP_CONNTRACK_EXP_UPDATE,
-#define NFNLGRP_CONNTRACK_EXP_UPDATE	NFNLGRP_CONNTRACK_EXP_UPDATE
-	NFNLGRP_CONNTRACK_EXP_DESTROY,
-#define NFNLGRP_CONNTRACK_EXP_DESTROY	NFNLGRP_CONNTRACK_EXP_DESTROY
-	__NFNLGRP_MAX,
-};
-#define NFNLGRP_MAX	(__NFNLGRP_MAX - 1)
-
-/* General form of address family dependent message.
- */
-struct nfgenmsg {
-	__u8  nfgen_family;		/* AF_xxx */
-	__u8  version;		/* nfnetlink version */
-	__be16    res_id;		/* resource id */
-};
-
-#define NFNETLINK_V0	0
-
-/* netfilter netlink message types are split in two pieces:
- * 8 bit subsystem, 8bit operation.
- */
-
-#define NFNL_SUBSYS_ID(x)	((x & 0xff00) >> 8)
-#define NFNL_MSG_TYPE(x)	(x & 0x00ff)
-
-/* No enum here, otherwise __stringify() trick of MODULE_ALIAS_NFNL_SUBSYS()
- * won't work anymore */
-#define NFNL_SUBSYS_NONE 		0
-#define NFNL_SUBSYS_CTNETLINK		1
-#define NFNL_SUBSYS_CTNETLINK_EXP	2
-#define NFNL_SUBSYS_QUEUE		3
-#define NFNL_SUBSYS_ULOG		4
-#define NFNL_SUBSYS_OSF			5
-#define NFNL_SUBSYS_IPSET		6
-#define NFNL_SUBSYS_ACCT		7
-#define NFNL_SUBSYS_CTNETLINK_TIMEOUT	8
-#define NFNL_SUBSYS_CTHELPER		9
-#define NFNL_SUBSYS_COUNT		10
-
-#ifdef __KERNEL__
 
 #include <linux/netlink.h>
 #include <linux/capability.h>
 #include <net/netlink.h>
+#include <uapi/linux/netfilter/nfnetlink.h>
 
 struct nfnl_callback {
 	int (*call)(struct sock *nl, struct sk_buff *skb, 
@@ -92,5 +40,4 @@
 #define MODULE_ALIAS_NFNL_SUBSYS(subsys) \
 	MODULE_ALIAS("nfnetlink-subsys-" __stringify(subsys))
 
-#endif	/* __KERNEL__ */
 #endif	/* _NFNETLINK_H */
diff --git a/include/linux/netfilter/nfnetlink_acct.h b/include/linux/netfilter/nfnetlink_acct.h
index 7c4279b..bb4bbc9 100644
--- a/include/linux/netfilter/nfnetlink_acct.h
+++ b/include/linux/netfilter/nfnetlink_acct.h
@@ -1,29 +1,8 @@
 #ifndef _NFNL_ACCT_H_
 #define _NFNL_ACCT_H_
 
-#ifndef NFACCT_NAME_MAX
-#define NFACCT_NAME_MAX		32
-#endif
+#include <uapi/linux/netfilter/nfnetlink_acct.h>
 
-enum nfnl_acct_msg_types {
-	NFNL_MSG_ACCT_NEW,
-	NFNL_MSG_ACCT_GET,
-	NFNL_MSG_ACCT_GET_CTRZERO,
-	NFNL_MSG_ACCT_DEL,
-	NFNL_MSG_ACCT_MAX
-};
-
-enum nfnl_acct_type {
-	NFACCT_UNSPEC,
-	NFACCT_NAME,
-	NFACCT_PKTS,
-	NFACCT_BYTES,
-	NFACCT_USE,
-	__NFACCT_MAX
-};
-#define NFACCT_MAX (__NFACCT_MAX - 1)
-
-#ifdef __KERNEL__
 
 struct nf_acct;
 
@@ -31,6 +10,4 @@
 extern void nfnl_acct_put(struct nf_acct *acct);
 extern void nfnl_acct_update(const struct sk_buff *skb, struct nf_acct *nfacct);
 
-#endif /* __KERNEL__ */
-
 #endif /* _NFNL_ACCT_H */
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 8d674a7..dd49566 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -1,191 +1,9 @@
 #ifndef _X_TABLES_H
 #define _X_TABLES_H
-#include <linux/kernel.h>
-#include <linux/types.h>
 
-#define XT_FUNCTION_MAXNAMELEN 30
-#define XT_EXTENSION_MAXNAMELEN 29
-#define XT_TABLE_MAXNAMELEN 32
-
-struct xt_entry_match {
-	union {
-		struct {
-			__u16 match_size;
-
-			/* Used by userspace */
-			char name[XT_EXTENSION_MAXNAMELEN];
-			__u8 revision;
-		} user;
-		struct {
-			__u16 match_size;
-
-			/* Used inside the kernel */
-			struct xt_match *match;
-		} kernel;
-
-		/* Total length */
-		__u16 match_size;
-	} u;
-
-	unsigned char data[0];
-};
-
-struct xt_entry_target {
-	union {
-		struct {
-			__u16 target_size;
-
-			/* Used by userspace */
-			char name[XT_EXTENSION_MAXNAMELEN];
-			__u8 revision;
-		} user;
-		struct {
-			__u16 target_size;
-
-			/* Used inside the kernel */
-			struct xt_target *target;
-		} kernel;
-
-		/* Total length */
-		__u16 target_size;
-	} u;
-
-	unsigned char data[0];
-};
-
-#define XT_TARGET_INIT(__name, __size)					       \
-{									       \
-	.target.u.user = {						       \
-		.target_size	= XT_ALIGN(__size),			       \
-		.name		= __name,				       \
-	},								       \
-}
-
-struct xt_standard_target {
-	struct xt_entry_target target;
-	int verdict;
-};
-
-struct xt_error_target {
-	struct xt_entry_target target;
-	char errorname[XT_FUNCTION_MAXNAMELEN];
-};
-
-/* The argument to IPT_SO_GET_REVISION_*.  Returns highest revision
- * kernel supports, if >= revision. */
-struct xt_get_revision {
-	char name[XT_EXTENSION_MAXNAMELEN];
-	__u8 revision;
-};
-
-/* CONTINUE verdict for targets */
-#define XT_CONTINUE 0xFFFFFFFF
-
-/* For standard target */
-#define XT_RETURN (-NF_REPEAT - 1)
-
-/* this is a dummy structure to find out the alignment requirement for a struct
- * containing all the fundamental data types that are used in ipt_entry,
- * ip6t_entry and arpt_entry.  This sucks, and it is a hack.  It will be my
- * personal pleasure to remove it -HW
- */
-struct _xt_align {
-	__u8 u8;
-	__u16 u16;
-	__u32 u32;
-	__u64 u64;
-};
-
-#define XT_ALIGN(s) __ALIGN_KERNEL((s), __alignof__(struct _xt_align))
-
-/* Standard return verdict, or do jump. */
-#define XT_STANDARD_TARGET ""
-/* Error verdict. */
-#define XT_ERROR_TARGET "ERROR"
-
-#define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0)
-#define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0)
-
-struct xt_counters {
-	__u64 pcnt, bcnt;			/* Packet and byte counters */
-};
-
-/* The argument to IPT_SO_ADD_COUNTERS. */
-struct xt_counters_info {
-	/* Which table. */
-	char name[XT_TABLE_MAXNAMELEN];
-
-	unsigned int num_counters;
-
-	/* The counters (actually `number' of these). */
-	struct xt_counters counters[0];
-};
-
-#define XT_INV_PROTO		0x40	/* Invert the sense of PROTO. */
-
-#ifndef __KERNEL__
-/* fn returns 0 to continue iteration */
-#define XT_MATCH_ITERATE(type, e, fn, args...)			\
-({								\
-	unsigned int __i;					\
-	int __ret = 0;						\
-	struct xt_entry_match *__m;				\
-								\
-	for (__i = sizeof(type);				\
-	     __i < (e)->target_offset;				\
-	     __i += __m->u.match_size) {			\
-		__m = (void *)e + __i;				\
-								\
-		__ret = fn(__m , ## args);			\
-		if (__ret != 0)					\
-			break;					\
-	}							\
-	__ret;							\
-})
-
-/* fn returns 0 to continue iteration */
-#define XT_ENTRY_ITERATE_CONTINUE(type, entries, size, n, fn, args...) \
-({								\
-	unsigned int __i, __n;					\
-	int __ret = 0;						\
-	type *__entry;						\
-								\
-	for (__i = 0, __n = 0; __i < (size);			\
-	     __i += __entry->next_offset, __n++) { 		\
-		__entry = (void *)(entries) + __i;		\
-		if (__n < n)					\
-			continue;				\
-								\
-		__ret = fn(__entry , ## args);			\
-		if (__ret != 0)					\
-			break;					\
-	}							\
-	__ret;							\
-})
-
-/* fn returns 0 to continue iteration */
-#define XT_ENTRY_ITERATE(type, entries, size, fn, args...) \
-	XT_ENTRY_ITERATE_CONTINUE(type, entries, size, 0, fn, args)
-
-#endif /* !__KERNEL__ */
-
-/* pos is normally a struct ipt_entry/ip6t_entry/etc. */
-#define xt_entry_foreach(pos, ehead, esize) \
-	for ((pos) = (typeof(pos))(ehead); \
-	     (pos) < (typeof(pos))((char *)(ehead) + (esize)); \
-	     (pos) = (typeof(pos))((char *)(pos) + (pos)->next_offset))
-
-/* can only be xt_entry_match, so no use of typeof here */
-#define xt_ematch_foreach(pos, entry) \
-	for ((pos) = (struct xt_entry_match *)entry->elems; \
-	     (pos) < (struct xt_entry_match *)((char *)(entry) + \
-	             (entry)->target_offset); \
-	     (pos) = (struct xt_entry_match *)((char *)(pos) + \
-	             (pos)->u.match_size))
-
-#ifdef __KERNEL__
 
 #include <linux/netdevice.h>
+#include <uapi/linux/netfilter/x_tables.h>
 
 /**
  * struct xt_action_param - parameters for matches/targets
@@ -617,6 +435,4 @@
 				    void __user **dstptr, unsigned int *size);
 
 #endif /* CONFIG_COMPAT */
-#endif /* __KERNEL__ */
-
 #endif /* _X_TABLES_H */
diff --git a/include/linux/netfilter/xt_hashlimit.h b/include/linux/netfilter/xt_hashlimit.h
index c42e52f..074790c 100644
--- a/include/linux/netfilter/xt_hashlimit.h
+++ b/include/linux/netfilter/xt_hashlimit.h
@@ -1,78 +1,9 @@
 #ifndef _XT_HASHLIMIT_H
 #define _XT_HASHLIMIT_H
 
-#include <linux/types.h>
+#include <uapi/linux/netfilter/xt_hashlimit.h>
 
-/* timings are in milliseconds. */
-#define XT_HASHLIMIT_SCALE 10000
-/* 1/10,000 sec period => max of 10,000/sec.  Min rate is then 429490
- * seconds, or one packet every 59 hours.
- */
-
-/* packet length accounting is done in 16-byte steps */
-#define XT_HASHLIMIT_BYTE_SHIFT 4
-
-/* details of this structure hidden by the implementation */
-struct xt_hashlimit_htable;
-
-enum {
-	XT_HASHLIMIT_HASH_DIP = 1 << 0,
-	XT_HASHLIMIT_HASH_DPT = 1 << 1,
-	XT_HASHLIMIT_HASH_SIP = 1 << 2,
-	XT_HASHLIMIT_HASH_SPT = 1 << 3,
-	XT_HASHLIMIT_INVERT   = 1 << 4,
-	XT_HASHLIMIT_BYTES    = 1 << 5,
-};
-#ifdef __KERNEL__
 #define XT_HASHLIMIT_ALL (XT_HASHLIMIT_HASH_DIP | XT_HASHLIMIT_HASH_DPT | \
 			  XT_HASHLIMIT_HASH_SIP | XT_HASHLIMIT_HASH_SPT | \
 			  XT_HASHLIMIT_INVERT | XT_HASHLIMIT_BYTES)
-#endif
-
-struct hashlimit_cfg {
-	__u32 mode;	  /* bitmask of XT_HASHLIMIT_HASH_* */
-	__u32 avg;    /* Average secs between packets * scale */
-	__u32 burst;  /* Period multiplier for upper limit. */
-
-	/* user specified */
-	__u32 size;		/* how many buckets */
-	__u32 max;		/* max number of entries */
-	__u32 gc_interval;	/* gc interval */
-	__u32 expire;	/* when do entries expire? */
-};
-
-struct xt_hashlimit_info {
-	char name [IFNAMSIZ];		/* name */
-	struct hashlimit_cfg cfg;
-
-	/* Used internally by the kernel */
-	struct xt_hashlimit_htable *hinfo;
-	union {
-		void *ptr;
-		struct xt_hashlimit_info *master;
-	} u;
-};
-
-struct hashlimit_cfg1 {
-	__u32 mode;	  /* bitmask of XT_HASHLIMIT_HASH_* */
-	__u32 avg;    /* Average secs between packets * scale */
-	__u32 burst;  /* Period multiplier for upper limit. */
-
-	/* user specified */
-	__u32 size;		/* how many buckets */
-	__u32 max;		/* max number of entries */
-	__u32 gc_interval;	/* gc interval */
-	__u32 expire;	/* when do entries expire? */
-
-	__u8 srcmask, dstmask;
-};
-
-struct xt_hashlimit_mtinfo1 {
-	char name[IFNAMSIZ];
-	struct hashlimit_cfg1 cfg;
-
-	/* Used internally by the kernel */
-	struct xt_hashlimit_htable *hinfo __attribute__((aligned(8)));
-};
-
 #endif /*_XT_HASHLIMIT_H*/
diff --git a/include/linux/netfilter/xt_physdev.h b/include/linux/netfilter/xt_physdev.h
index 8555e39..5b5e417 100644
--- a/include/linux/netfilter/xt_physdev.h
+++ b/include/linux/netfilter/xt_physdev.h
@@ -1,26 +1,7 @@
 #ifndef _XT_PHYSDEV_H
 #define _XT_PHYSDEV_H
 
-#include <linux/types.h>
-
-#ifdef __KERNEL__
 #include <linux/if.h>
-#endif
-
-#define XT_PHYSDEV_OP_IN		0x01
-#define XT_PHYSDEV_OP_OUT		0x02
-#define XT_PHYSDEV_OP_BRIDGED		0x04
-#define XT_PHYSDEV_OP_ISIN		0x08
-#define XT_PHYSDEV_OP_ISOUT		0x10
-#define XT_PHYSDEV_OP_MASK		(0x20 - 1)
-
-struct xt_physdev_info {
-	char physindev[IFNAMSIZ];
-	char in_mask[IFNAMSIZ];
-	char physoutdev[IFNAMSIZ];
-	char out_mask[IFNAMSIZ];
-	__u8 invert;
-	__u8 bitmask;
-};
+#include <uapi/linux/netfilter/xt_physdev.h>
 
 #endif /*_XT_PHYSDEV_H*/
diff --git a/include/linux/netfilter_arp/Kbuild b/include/linux/netfilter_arp/Kbuild
index b27439c..e69de29 100644
--- a/include/linux/netfilter_arp/Kbuild
+++ b/include/linux/netfilter_arp/Kbuild
@@ -1,2 +0,0 @@
-header-y += arp_tables.h
-header-y += arpt_mangle.h
diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h
index e08565d..cfb7191 100644
--- a/include/linux/netfilter_arp/arp_tables.h
+++ b/include/linux/netfilter_arp/arp_tables.h
@@ -5,211 +5,14 @@
  *	network byte order.
  * 	flags are stored in host byte order (of course).
  */
-
 #ifndef _ARPTABLES_H
 #define _ARPTABLES_H
 
-#ifdef __KERNEL__
 #include <linux/if.h>
 #include <linux/in.h>
 #include <linux/if_arp.h>
 #include <linux/skbuff.h>
-#endif
-#include <linux/types.h>
-#include <linux/compiler.h>
-#include <linux/netfilter_arp.h>
-
-#include <linux/netfilter/x_tables.h>
-
-#ifndef __KERNEL__
-#define ARPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
-#define ARPT_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN
-#define arpt_entry_target xt_entry_target
-#define arpt_standard_target xt_standard_target
-#define arpt_error_target xt_error_target
-#define ARPT_CONTINUE XT_CONTINUE
-#define ARPT_RETURN XT_RETURN
-#define arpt_counters_info xt_counters_info
-#define arpt_counters xt_counters
-#define ARPT_STANDARD_TARGET XT_STANDARD_TARGET
-#define ARPT_ERROR_TARGET XT_ERROR_TARGET
-#define ARPT_ENTRY_ITERATE(entries, size, fn, args...) \
-	XT_ENTRY_ITERATE(struct arpt_entry, entries, size, fn, ## args)
-#endif
-
-#define ARPT_DEV_ADDR_LEN_MAX 16
-
-struct arpt_devaddr_info {
-	char addr[ARPT_DEV_ADDR_LEN_MAX];
-	char mask[ARPT_DEV_ADDR_LEN_MAX];
-};
-
-/* Yes, Virginia, you have to zero the padding. */
-struct arpt_arp {
-	/* Source and target IP addr */
-	struct in_addr src, tgt;
-	/* Mask for src and target IP addr */
-	struct in_addr smsk, tmsk;
-
-	/* Device hw address length, src+target device addresses */
-	__u8 arhln, arhln_mask;
-	struct arpt_devaddr_info src_devaddr;
-	struct arpt_devaddr_info tgt_devaddr;
-
-	/* ARP operation code. */
-	__be16 arpop, arpop_mask;
-
-	/* ARP hardware address and protocol address format. */
-	__be16 arhrd, arhrd_mask;
-	__be16 arpro, arpro_mask;
-
-	/* The protocol address length is only accepted if it is 4
-	 * so there is no use in offering a way to do filtering on it.
-	 */
-
-	char iniface[IFNAMSIZ], outiface[IFNAMSIZ];
-	unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];
-
-	/* Flags word */
-	__u8 flags;
-	/* Inverse flags */
-	__u16 invflags;
-};
-
-/* Values for "flag" field in struct arpt_ip (general arp structure).
- * No flags defined yet.
- */
-#define ARPT_F_MASK		0x00	/* All possible flag bits mask. */
-
-/* Values for "inv" field in struct arpt_arp. */
-#define ARPT_INV_VIA_IN		0x0001	/* Invert the sense of IN IFACE. */
-#define ARPT_INV_VIA_OUT	0x0002	/* Invert the sense of OUT IFACE */
-#define ARPT_INV_SRCIP		0x0004	/* Invert the sense of SRC IP. */
-#define ARPT_INV_TGTIP		0x0008	/* Invert the sense of TGT IP. */
-#define ARPT_INV_SRCDEVADDR	0x0010	/* Invert the sense of SRC DEV ADDR. */
-#define ARPT_INV_TGTDEVADDR	0x0020	/* Invert the sense of TGT DEV ADDR. */
-#define ARPT_INV_ARPOP		0x0040	/* Invert the sense of ARP OP. */
-#define ARPT_INV_ARPHRD		0x0080	/* Invert the sense of ARP HRD. */
-#define ARPT_INV_ARPPRO		0x0100	/* Invert the sense of ARP PRO. */
-#define ARPT_INV_ARPHLN		0x0200	/* Invert the sense of ARP HLN. */
-#define ARPT_INV_MASK		0x03FF	/* All possible flag bits mask. */
-
-/* This structure defines each of the firewall rules.  Consists of 3
-   parts which are 1) general ARP header stuff 2) match specific
-   stuff 3) the target to perform if the rule matches */
-struct arpt_entry
-{
-	struct arpt_arp arp;
-
-	/* Size of arpt_entry + matches */
-	__u16 target_offset;
-	/* Size of arpt_entry + matches + target */
-	__u16 next_offset;
-
-	/* Back pointer */
-	unsigned int comefrom;
-
-	/* Packet and byte counters. */
-	struct xt_counters counters;
-
-	/* The matches (if any), then the target. */
-	unsigned char elems[0];
-};
-
-/*
- * New IP firewall options for [gs]etsockopt at the RAW IP level.
- * Unlike BSD Linux inherits IP options so you don't have to use a raw
- * socket for this. Instead we check rights in the calls.
- *
- * ATTENTION: check linux/in.h before adding new number here.
- */
-#define ARPT_BASE_CTL		96
-
-#define ARPT_SO_SET_REPLACE		(ARPT_BASE_CTL)
-#define ARPT_SO_SET_ADD_COUNTERS	(ARPT_BASE_CTL + 1)
-#define ARPT_SO_SET_MAX			ARPT_SO_SET_ADD_COUNTERS
-
-#define ARPT_SO_GET_INFO		(ARPT_BASE_CTL)
-#define ARPT_SO_GET_ENTRIES		(ARPT_BASE_CTL + 1)
-/* #define ARPT_SO_GET_REVISION_MATCH	(APRT_BASE_CTL + 2) */
-#define ARPT_SO_GET_REVISION_TARGET	(ARPT_BASE_CTL + 3)
-#define ARPT_SO_GET_MAX			(ARPT_SO_GET_REVISION_TARGET)
-
-/* The argument to ARPT_SO_GET_INFO */
-struct arpt_getinfo {
-	/* Which table: caller fills this in. */
-	char name[XT_TABLE_MAXNAMELEN];
-
-	/* Kernel fills these in. */
-	/* Which hook entry points are valid: bitmask */
-	unsigned int valid_hooks;
-
-	/* Hook entry points: one per netfilter hook. */
-	unsigned int hook_entry[NF_ARP_NUMHOOKS];
-
-	/* Underflow points. */
-	unsigned int underflow[NF_ARP_NUMHOOKS];
-
-	/* Number of entries */
-	unsigned int num_entries;
-
-	/* Size of entries. */
-	unsigned int size;
-};
-
-/* The argument to ARPT_SO_SET_REPLACE. */
-struct arpt_replace {
-	/* Which table. */
-	char name[XT_TABLE_MAXNAMELEN];
-
-	/* Which hook entry points are valid: bitmask.  You can't
-           change this. */
-	unsigned int valid_hooks;
-
-	/* Number of entries */
-	unsigned int num_entries;
-
-	/* Total size of new entries */
-	unsigned int size;
-
-	/* Hook entry points. */
-	unsigned int hook_entry[NF_ARP_NUMHOOKS];
-
-	/* Underflow points. */
-	unsigned int underflow[NF_ARP_NUMHOOKS];
-
-	/* Information about old entries: */
-	/* Number of counters (must be equal to current number of entries). */
-	unsigned int num_counters;
-	/* The old entries' counters. */
-	struct xt_counters __user *counters;
-
-	/* The entries (hang off end: not really an array). */
-	struct arpt_entry entries[0];
-};
-
-/* The argument to ARPT_SO_GET_ENTRIES. */
-struct arpt_get_entries {
-	/* Which table: user fills this in. */
-	char name[XT_TABLE_MAXNAMELEN];
-
-	/* User fills this in: total entry size. */
-	unsigned int size;
-
-	/* The entries. */
-	struct arpt_entry entrytable[0];
-};
-
-/* Helper functions */
-static __inline__ struct xt_entry_target *arpt_get_target(struct arpt_entry *e)
-{
-	return (void *)e + e->target_offset;
-}
-
-/*
- *	Main firewall chains definitions and global var's definitions.
- */
-#ifdef __KERNEL__
+#include <uapi/linux/netfilter_arp/arp_tables.h>
 
 /* Standard entry. */
 struct arpt_standard {
@@ -274,5 +77,4 @@
 }
 
 #endif /* CONFIG_COMPAT */
-#endif /*__KERNEL__*/
 #endif /* _ARPTABLES_H */
diff --git a/include/linux/netfilter_bridge/Kbuild b/include/linux/netfilter_bridge/Kbuild
index e48f1a3..e69de29 100644
--- a/include/linux/netfilter_bridge/Kbuild
+++ b/include/linux/netfilter_bridge/Kbuild
@@ -1,18 +0,0 @@
-header-y += ebt_802_3.h
-header-y += ebt_among.h
-header-y += ebt_arp.h
-header-y += ebt_arpreply.h
-header-y += ebt_ip.h
-header-y += ebt_ip6.h
-header-y += ebt_limit.h
-header-y += ebt_log.h
-header-y += ebt_mark_m.h
-header-y += ebt_mark_t.h
-header-y += ebt_nat.h
-header-y += ebt_nflog.h
-header-y += ebt_pkttype.h
-header-y += ebt_redirect.h
-header-y += ebt_stp.h
-header-y += ebt_ulog.h
-header-y += ebt_vlan.h
-header-y += ebtables.h
diff --git a/include/linux/netfilter_bridge/ebt_802_3.h b/include/linux/netfilter_bridge/ebt_802_3.h
index be5be15..e17e8bf 100644
--- a/include/linux/netfilter_bridge/ebt_802_3.h
+++ b/include/linux/netfilter_bridge/ebt_802_3.h
@@ -1,70 +1,11 @@
 #ifndef __LINUX_BRIDGE_EBT_802_3_H
 #define __LINUX_BRIDGE_EBT_802_3_H
 
-#include <linux/types.h>
-
-#define EBT_802_3_SAP 0x01
-#define EBT_802_3_TYPE 0x02
-
-#define EBT_802_3_MATCH "802_3"
-
-/*
- * If frame has DSAP/SSAP value 0xaa you must check the SNAP type
- * to discover what kind of packet we're carrying. 
- */
-#define CHECK_TYPE 0xaa
-
-/*
- * Control field may be one or two bytes.  If the first byte has
- * the value 0x03 then the entire length is one byte, otherwise it is two.
- * One byte controls are used in Unnumbered Information frames.
- * Two byte controls are used in Numbered Information frames.
- */
-#define IS_UI 0x03
-
-#define EBT_802_3_MASK (EBT_802_3_SAP | EBT_802_3_TYPE | EBT_802_3)
-
-/* ui has one byte ctrl, ni has two */
-struct hdr_ui {
-	__u8 dsap;
-	__u8 ssap;
-	__u8 ctrl;
-	__u8 orig[3];
-	__be16 type;
-};
-
-struct hdr_ni {
-	__u8 dsap;
-	__u8 ssap;
-	__be16 ctrl;
-	__u8  orig[3];
-	__be16 type;
-};
-
-struct ebt_802_3_hdr {
-	__u8  daddr[6];
-	__u8  saddr[6];
-	__be16 len;
-	union {
-		struct hdr_ui ui;
-		struct hdr_ni ni;
-	} llc;
-};
-
-#ifdef __KERNEL__
 #include <linux/skbuff.h>
+#include <uapi/linux/netfilter_bridge/ebt_802_3.h>
 
 static inline struct ebt_802_3_hdr *ebt_802_3_hdr(const struct sk_buff *skb)
 {
 	return (struct ebt_802_3_hdr *)skb_mac_header(skb);
 }
 #endif
-
-struct ebt_802_3_info {
-	__u8  sap;
-	__be16 type;
-	__u8  bitmask;
-	__u8  invflags;
-};
-
-#endif
diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h
index 4dd5bd6..34e7a2b 100644
--- a/include/linux/netfilter_bridge/ebtables.h
+++ b/include/linux/netfilter_bridge/ebtables.h
@@ -9,191 +9,11 @@
  *  This code is stongly inspired on the iptables code which is
  *  Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
  */
-
 #ifndef __LINUX_BRIDGE_EFF_H
 #define __LINUX_BRIDGE_EFF_H
-#include <linux/if.h>
-#include <linux/netfilter_bridge.h>
-#include <linux/if_ether.h>
 
-#define EBT_TABLE_MAXNAMELEN 32
-#define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN
-#define EBT_FUNCTION_MAXNAMELEN EBT_TABLE_MAXNAMELEN
+#include <uapi/linux/netfilter_bridge/ebtables.h>
 
-/* verdicts >0 are "branches" */
-#define EBT_ACCEPT   -1
-#define EBT_DROP     -2
-#define EBT_CONTINUE -3
-#define EBT_RETURN   -4
-#define NUM_STANDARD_TARGETS   4
-/* ebtables target modules store the verdict inside an int. We can
- * reclaim a part of this int for backwards compatible extensions.
- * The 4 lsb are more than enough to store the verdict. */
-#define EBT_VERDICT_BITS 0x0000000F
-
-struct xt_match;
-struct xt_target;
-
-struct ebt_counter {
-	uint64_t pcnt;
-	uint64_t bcnt;
-};
-
-struct ebt_replace {
-	char name[EBT_TABLE_MAXNAMELEN];
-	unsigned int valid_hooks;
-	/* nr of rules in the table */
-	unsigned int nentries;
-	/* total size of the entries */
-	unsigned int entries_size;
-	/* start of the chains */
-	struct ebt_entries __user *hook_entry[NF_BR_NUMHOOKS];
-	/* nr of counters userspace expects back */
-	unsigned int num_counters;
-	/* where the kernel will put the old counters */
-	struct ebt_counter __user *counters;
-	char __user *entries;
-};
-
-struct ebt_replace_kernel {
-	char name[EBT_TABLE_MAXNAMELEN];
-	unsigned int valid_hooks;
-	/* nr of rules in the table */
-	unsigned int nentries;
-	/* total size of the entries */
-	unsigned int entries_size;
-	/* start of the chains */
-	struct ebt_entries *hook_entry[NF_BR_NUMHOOKS];
-	/* nr of counters userspace expects back */
-	unsigned int num_counters;
-	/* where the kernel will put the old counters */
-	struct ebt_counter *counters;
-	char *entries;
-};
-
-struct ebt_entries {
-	/* this field is always set to zero
-	 * See EBT_ENTRY_OR_ENTRIES.
-	 * Must be same size as ebt_entry.bitmask */
-	unsigned int distinguisher;
-	/* the chain name */
-	char name[EBT_CHAIN_MAXNAMELEN];
-	/* counter offset for this chain */
-	unsigned int counter_offset;
-	/* one standard (accept, drop, return) per hook */
-	int policy;
-	/* nr. of entries */
-	unsigned int nentries;
-	/* entry list */
-	char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
-};
-
-/* used for the bitmask of struct ebt_entry */
-
-/* This is a hack to make a difference between an ebt_entry struct and an
- * ebt_entries struct when traversing the entries from start to end.
- * Using this simplifies the code a lot, while still being able to use
- * ebt_entries.
- * Contrary, iptables doesn't use something like ebt_entries and therefore uses
- * different techniques for naming the policy and such. So, iptables doesn't
- * need a hack like this.
- */
-#define EBT_ENTRY_OR_ENTRIES 0x01
-/* these are the normal masks */
-#define EBT_NOPROTO 0x02
-#define EBT_802_3 0x04
-#define EBT_SOURCEMAC 0x08
-#define EBT_DESTMAC 0x10
-#define EBT_F_MASK (EBT_NOPROTO | EBT_802_3 | EBT_SOURCEMAC | EBT_DESTMAC \
-   | EBT_ENTRY_OR_ENTRIES)
-
-#define EBT_IPROTO 0x01
-#define EBT_IIN 0x02
-#define EBT_IOUT 0x04
-#define EBT_ISOURCE 0x8
-#define EBT_IDEST 0x10
-#define EBT_ILOGICALIN 0x20
-#define EBT_ILOGICALOUT 0x40
-#define EBT_INV_MASK (EBT_IPROTO | EBT_IIN | EBT_IOUT | EBT_ILOGICALIN \
-   | EBT_ILOGICALOUT | EBT_ISOURCE | EBT_IDEST)
-
-struct ebt_entry_match {
-	union {
-		char name[EBT_FUNCTION_MAXNAMELEN];
-		struct xt_match *match;
-	} u;
-	/* size of data */
-	unsigned int match_size;
-	unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
-};
-
-struct ebt_entry_watcher {
-	union {
-		char name[EBT_FUNCTION_MAXNAMELEN];
-		struct xt_target *watcher;
-	} u;
-	/* size of data */
-	unsigned int watcher_size;
-	unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
-};
-
-struct ebt_entry_target {
-	union {
-		char name[EBT_FUNCTION_MAXNAMELEN];
-		struct xt_target *target;
-	} u;
-	/* size of data */
-	unsigned int target_size;
-	unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
-};
-
-#define EBT_STANDARD_TARGET "standard"
-struct ebt_standard_target {
-	struct ebt_entry_target target;
-	int verdict;
-};
-
-/* one entry */
-struct ebt_entry {
-	/* this needs to be the first field */
-	unsigned int bitmask;
-	unsigned int invflags;
-	__be16 ethproto;
-	/* the physical in-dev */
-	char in[IFNAMSIZ];
-	/* the logical in-dev */
-	char logical_in[IFNAMSIZ];
-	/* the physical out-dev */
-	char out[IFNAMSIZ];
-	/* the logical out-dev */
-	char logical_out[IFNAMSIZ];
-	unsigned char sourcemac[ETH_ALEN];
-	unsigned char sourcemsk[ETH_ALEN];
-	unsigned char destmac[ETH_ALEN];
-	unsigned char destmsk[ETH_ALEN];
-	/* sizeof ebt_entry + matches */
-	unsigned int watchers_offset;
-	/* sizeof ebt_entry + matches + watchers */
-	unsigned int target_offset;
-	/* sizeof ebt_entry + matches + watchers + target */
-	unsigned int next_offset;
-	unsigned char elems[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
-};
-
-/* {g,s}etsockopt numbers */
-#define EBT_BASE_CTL            128
-
-#define EBT_SO_SET_ENTRIES      (EBT_BASE_CTL)
-#define EBT_SO_SET_COUNTERS     (EBT_SO_SET_ENTRIES+1)
-#define EBT_SO_SET_MAX          (EBT_SO_SET_COUNTERS+1)
-
-#define EBT_SO_GET_INFO         (EBT_BASE_CTL)
-#define EBT_SO_GET_ENTRIES      (EBT_SO_GET_INFO+1)
-#define EBT_SO_GET_INIT_INFO    (EBT_SO_GET_ENTRIES+1)
-#define EBT_SO_GET_INIT_ENTRIES (EBT_SO_GET_INIT_INFO+1)
-#define EBT_SO_GET_MAX          (EBT_SO_GET_INIT_ENTRIES+1)
-
-#ifdef __KERNEL__
 
 /* return values for match() functions */
 #define EBT_MATCH 0
@@ -304,77 +124,4 @@
 /* True if the target is not a standard target */
 #define INVALID_TARGET (info->target < -NUM_STANDARD_TARGETS || info->target >= 0)
 
-#endif /* __KERNEL__ */
-
-/* blatently stolen from ip_tables.h
- * fn returns 0 to continue iteration */
-#define EBT_MATCH_ITERATE(e, fn, args...)                   \
-({                                                          \
-	unsigned int __i;                                   \
-	int __ret = 0;                                      \
-	struct ebt_entry_match *__match;                    \
-	                                                    \
-	for (__i = sizeof(struct ebt_entry);                \
-	     __i < (e)->watchers_offset;                    \
-	     __i += __match->match_size +                   \
-	     sizeof(struct ebt_entry_match)) {              \
-		__match = (void *)(e) + __i;                \
-		                                            \
-		__ret = fn(__match , ## args);              \
-		if (__ret != 0)                             \
-			break;                              \
-	}                                                   \
-	if (__ret == 0) {                                   \
-		if (__i != (e)->watchers_offset)            \
-			__ret = -EINVAL;                    \
-	}                                                   \
-	__ret;                                              \
-})
-
-#define EBT_WATCHER_ITERATE(e, fn, args...)                 \
-({                                                          \
-	unsigned int __i;                                   \
-	int __ret = 0;                                      \
-	struct ebt_entry_watcher *__watcher;                \
-	                                                    \
-	for (__i = e->watchers_offset;                      \
-	     __i < (e)->target_offset;                      \
-	     __i += __watcher->watcher_size +               \
-	     sizeof(struct ebt_entry_watcher)) {            \
-		__watcher = (void *)(e) + __i;              \
-		                                            \
-		__ret = fn(__watcher , ## args);            \
-		if (__ret != 0)                             \
-			break;                              \
-	}                                                   \
-	if (__ret == 0) {                                   \
-		if (__i != (e)->target_offset)              \
-			__ret = -EINVAL;                    \
-	}                                                   \
-	__ret;                                              \
-})
-
-#define EBT_ENTRY_ITERATE(entries, size, fn, args...)       \
-({                                                          \
-	unsigned int __i;                                   \
-	int __ret = 0;                                      \
-	struct ebt_entry *__entry;                          \
-	                                                    \
-	for (__i = 0; __i < (size);) {                      \
-		__entry = (void *)(entries) + __i;          \
-		__ret = fn(__entry , ## args);              \
-		if (__ret != 0)                             \
-			break;                              \
-		if (__entry->bitmask != 0)                  \
-			__i += __entry->next_offset;        \
-		else                                        \
-			__i += sizeof(struct ebt_entries);  \
-	}                                                   \
-	if (__ret == 0) {                                   \
-		if (__i != (size))                          \
-			__ret = -EINVAL;                    \
-	}                                                   \
-	__ret;                                              \
-})
-
 #endif
diff --git a/include/linux/netfilter_ipv4/Kbuild b/include/linux/netfilter_ipv4/Kbuild
index 8ba0c5b..e69de29 100644
--- a/include/linux/netfilter_ipv4/Kbuild
+++ b/include/linux/netfilter_ipv4/Kbuild
@@ -1,10 +0,0 @@
-header-y += ip_tables.h
-header-y += ipt_CLUSTERIP.h
-header-y += ipt_ECN.h
-header-y += ipt_LOG.h
-header-y += ipt_REJECT.h
-header-y += ipt_TTL.h
-header-y += ipt_ULOG.h
-header-y += ipt_ah.h
-header-y += ipt_ecn.h
-header-y += ipt_ttl.h
diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h
index db79231..901e84d 100644
--- a/include/linux/netfilter_ipv4/ip_tables.h
+++ b/include/linux/netfilter_ipv4/ip_tables.h
@@ -11,230 +11,17 @@
  * 	flags are stored in host byte order (of course).
  * 	Port numbers are stored in HOST byte order.
  */
-
 #ifndef _IPTABLES_H
 #define _IPTABLES_H
 
-#ifdef __KERNEL__
 #include <linux/if.h>
 #include <linux/in.h>
 #include <linux/ip.h>
 #include <linux/skbuff.h>
-#endif
-#include <linux/types.h>
-#include <linux/compiler.h>
-#include <linux/netfilter_ipv4.h>
-
-#include <linux/netfilter/x_tables.h>
-
-#ifndef __KERNEL__
-#define IPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
-#define IPT_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN
-#define ipt_match xt_match
-#define ipt_target xt_target
-#define ipt_table xt_table
-#define ipt_get_revision xt_get_revision
-#define ipt_entry_match xt_entry_match
-#define ipt_entry_target xt_entry_target
-#define ipt_standard_target xt_standard_target
-#define ipt_error_target xt_error_target
-#define ipt_counters xt_counters
-#define IPT_CONTINUE XT_CONTINUE
-#define IPT_RETURN XT_RETURN
-
-/* This group is older than old (iptables < v1.4.0-rc1~89) */
-#include <linux/netfilter/xt_tcpudp.h>
-#define ipt_udp xt_udp
-#define ipt_tcp xt_tcp
-#define IPT_TCP_INV_SRCPT	XT_TCP_INV_SRCPT
-#define IPT_TCP_INV_DSTPT	XT_TCP_INV_DSTPT
-#define IPT_TCP_INV_FLAGS	XT_TCP_INV_FLAGS
-#define IPT_TCP_INV_OPTION	XT_TCP_INV_OPTION
-#define IPT_TCP_INV_MASK	XT_TCP_INV_MASK
-#define IPT_UDP_INV_SRCPT	XT_UDP_INV_SRCPT
-#define IPT_UDP_INV_DSTPT	XT_UDP_INV_DSTPT
-#define IPT_UDP_INV_MASK	XT_UDP_INV_MASK
-
-/* The argument to IPT_SO_ADD_COUNTERS. */
-#define ipt_counters_info xt_counters_info
-/* Standard return verdict, or do jump. */
-#define IPT_STANDARD_TARGET XT_STANDARD_TARGET
-/* Error verdict. */
-#define IPT_ERROR_TARGET XT_ERROR_TARGET
-
-/* fn returns 0 to continue iteration */
-#define IPT_MATCH_ITERATE(e, fn, args...) \
-	XT_MATCH_ITERATE(struct ipt_entry, e, fn, ## args)
-
-/* fn returns 0 to continue iteration */
-#define IPT_ENTRY_ITERATE(entries, size, fn, args...) \
-	XT_ENTRY_ITERATE(struct ipt_entry, entries, size, fn, ## args)
-#endif
-
-/* Yes, Virginia, you have to zero the padding. */
-struct ipt_ip {
-	/* Source and destination IP addr */
-	struct in_addr src, dst;
-	/* Mask for src and dest IP addr */
-	struct in_addr smsk, dmsk;
-	char iniface[IFNAMSIZ], outiface[IFNAMSIZ];
-	unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];
-
-	/* Protocol, 0 = ANY */
-	__u16 proto;
-
-	/* Flags word */
-	__u8 flags;
-	/* Inverse flags */
-	__u8 invflags;
-};
-
-/* Values for "flag" field in struct ipt_ip (general ip structure). */
-#define IPT_F_FRAG		0x01	/* Set if rule is a fragment rule */
-#define IPT_F_GOTO		0x02	/* Set if jump is a goto */
-#define IPT_F_MASK		0x03	/* All possible flag bits mask. */
-
-/* Values for "inv" field in struct ipt_ip. */
-#define IPT_INV_VIA_IN		0x01	/* Invert the sense of IN IFACE. */
-#define IPT_INV_VIA_OUT		0x02	/* Invert the sense of OUT IFACE */
-#define IPT_INV_TOS		0x04	/* Invert the sense of TOS. */
-#define IPT_INV_SRCIP		0x08	/* Invert the sense of SRC IP. */
-#define IPT_INV_DSTIP		0x10	/* Invert the sense of DST OP. */
-#define IPT_INV_FRAG		0x20	/* Invert the sense of FRAG. */
-#define IPT_INV_PROTO		XT_INV_PROTO
-#define IPT_INV_MASK		0x7F	/* All possible flag bits mask. */
-
-/* This structure defines each of the firewall rules.  Consists of 3
-   parts which are 1) general IP header stuff 2) match specific
-   stuff 3) the target to perform if the rule matches */
-struct ipt_entry {
-	struct ipt_ip ip;
-
-	/* Mark with fields that we care about. */
-	unsigned int nfcache;
-
-	/* Size of ipt_entry + matches */
-	__u16 target_offset;
-	/* Size of ipt_entry + matches + target */
-	__u16 next_offset;
-
-	/* Back pointer */
-	unsigned int comefrom;
-
-	/* Packet and byte counters. */
-	struct xt_counters counters;
-
-	/* The matches (if any), then the target. */
-	unsigned char elems[0];
-};
-
-/*
- * New IP firewall options for [gs]etsockopt at the RAW IP level.
- * Unlike BSD Linux inherits IP options so you don't have to use a raw
- * socket for this. Instead we check rights in the calls.
- *
- * ATTENTION: check linux/in.h before adding new number here.
- */
-#define IPT_BASE_CTL		64
-
-#define IPT_SO_SET_REPLACE	(IPT_BASE_CTL)
-#define IPT_SO_SET_ADD_COUNTERS	(IPT_BASE_CTL + 1)
-#define IPT_SO_SET_MAX		IPT_SO_SET_ADD_COUNTERS
-
-#define IPT_SO_GET_INFO			(IPT_BASE_CTL)
-#define IPT_SO_GET_ENTRIES		(IPT_BASE_CTL + 1)
-#define IPT_SO_GET_REVISION_MATCH	(IPT_BASE_CTL + 2)
-#define IPT_SO_GET_REVISION_TARGET	(IPT_BASE_CTL + 3)
-#define IPT_SO_GET_MAX			IPT_SO_GET_REVISION_TARGET
-
-/* ICMP matching stuff */
-struct ipt_icmp {
-	__u8 type;				/* type to match */
-	__u8 code[2];				/* range of code */
-	__u8 invflags;				/* Inverse flags */
-};
-
-/* Values for "inv" field for struct ipt_icmp. */
-#define IPT_ICMP_INV	0x01	/* Invert the sense of type/code test */
-
-/* The argument to IPT_SO_GET_INFO */
-struct ipt_getinfo {
-	/* Which table: caller fills this in. */
-	char name[XT_TABLE_MAXNAMELEN];
-
-	/* Kernel fills these in. */
-	/* Which hook entry points are valid: bitmask */
-	unsigned int valid_hooks;
-
-	/* Hook entry points: one per netfilter hook. */
-	unsigned int hook_entry[NF_INET_NUMHOOKS];
-
-	/* Underflow points. */
-	unsigned int underflow[NF_INET_NUMHOOKS];
-
-	/* Number of entries */
-	unsigned int num_entries;
-
-	/* Size of entries. */
-	unsigned int size;
-};
-
-/* The argument to IPT_SO_SET_REPLACE. */
-struct ipt_replace {
-	/* Which table. */
-	char name[XT_TABLE_MAXNAMELEN];
-
-	/* Which hook entry points are valid: bitmask.  You can't
-           change this. */
-	unsigned int valid_hooks;
-
-	/* Number of entries */
-	unsigned int num_entries;
-
-	/* Total size of new entries */
-	unsigned int size;
-
-	/* Hook entry points. */
-	unsigned int hook_entry[NF_INET_NUMHOOKS];
-
-	/* Underflow points. */
-	unsigned int underflow[NF_INET_NUMHOOKS];
-
-	/* Information about old entries: */
-	/* Number of counters (must be equal to current number of entries). */
-	unsigned int num_counters;
-	/* The old entries' counters. */
-	struct xt_counters __user *counters;
-
-	/* The entries (hang off end: not really an array). */
-	struct ipt_entry entries[0];
-};
-
-/* The argument to IPT_SO_GET_ENTRIES. */
-struct ipt_get_entries {
-	/* Which table: user fills this in. */
-	char name[XT_TABLE_MAXNAMELEN];
-
-	/* User fills this in: total entry size. */
-	unsigned int size;
-
-	/* The entries. */
-	struct ipt_entry entrytable[0];
-};
-
-/* Helper functions */
-static __inline__ struct xt_entry_target *
-ipt_get_target(struct ipt_entry *e)
-{
-	return (void *)e + e->target_offset;
-}
-
-/*
- *	Main firewall chains definitions and global var's definitions.
- */
-#ifdef __KERNEL__
 
 #include <linux/init.h>
+#include <uapi/linux/netfilter_ipv4/ip_tables.h>
+
 extern void ipt_init(void) __init;
 
 extern struct xt_table *ipt_register_table(struct net *net,
@@ -303,5 +90,4 @@
 }
 
 #endif /* CONFIG_COMPAT */
-#endif /*__KERNEL__*/
 #endif /* _IPTABLES_H */
diff --git a/include/linux/netfilter_ipv6/Kbuild b/include/linux/netfilter_ipv6/Kbuild
index b88c005..e69de29 100644
--- a/include/linux/netfilter_ipv6/Kbuild
+++ b/include/linux/netfilter_ipv6/Kbuild
@@ -1,12 +0,0 @@
-header-y += ip6_tables.h
-header-y += ip6t_HL.h
-header-y += ip6t_LOG.h
-header-y += ip6t_NPT.h
-header-y += ip6t_REJECT.h
-header-y += ip6t_ah.h
-header-y += ip6t_frag.h
-header-y += ip6t_hl.h
-header-y += ip6t_ipv6header.h
-header-y += ip6t_mh.h
-header-y += ip6t_opts.h
-header-y += ip6t_rt.h
diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h
index 08c2cbb..5f84c62 100644
--- a/include/linux/netfilter_ipv6/ip6_tables.h
+++ b/include/linux/netfilter_ipv6/ip6_tables.h
@@ -11,268 +11,17 @@
  * 	flags are stored in host byte order (of course).
  * 	Port numbers are stored in HOST byte order.
  */
-
 #ifndef _IP6_TABLES_H
 #define _IP6_TABLES_H
 
-#ifdef __KERNEL__
 #include <linux/if.h>
 #include <linux/in6.h>
 #include <linux/ipv6.h>
 #include <linux/skbuff.h>
-#endif
-#include <linux/types.h>
-#include <linux/compiler.h>
-#include <linux/netfilter_ipv6.h>
-
-#include <linux/netfilter/x_tables.h>
-
-#ifndef __KERNEL__
-#define IP6T_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
-#define IP6T_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN
-#define ip6t_match xt_match
-#define ip6t_target xt_target
-#define ip6t_table xt_table
-#define ip6t_get_revision xt_get_revision
-#define ip6t_entry_match xt_entry_match
-#define ip6t_entry_target xt_entry_target
-#define ip6t_standard_target xt_standard_target
-#define ip6t_error_target xt_error_target
-#define ip6t_counters xt_counters
-#define IP6T_CONTINUE XT_CONTINUE
-#define IP6T_RETURN XT_RETURN
-
-/* Pre-iptables-1.4.0 */
-#include <linux/netfilter/xt_tcpudp.h>
-#define ip6t_tcp xt_tcp
-#define ip6t_udp xt_udp
-#define IP6T_TCP_INV_SRCPT	XT_TCP_INV_SRCPT
-#define IP6T_TCP_INV_DSTPT	XT_TCP_INV_DSTPT
-#define IP6T_TCP_INV_FLAGS	XT_TCP_INV_FLAGS
-#define IP6T_TCP_INV_OPTION	XT_TCP_INV_OPTION
-#define IP6T_TCP_INV_MASK	XT_TCP_INV_MASK
-#define IP6T_UDP_INV_SRCPT	XT_UDP_INV_SRCPT
-#define IP6T_UDP_INV_DSTPT	XT_UDP_INV_DSTPT
-#define IP6T_UDP_INV_MASK	XT_UDP_INV_MASK
-
-#define ip6t_counters_info xt_counters_info
-#define IP6T_STANDARD_TARGET XT_STANDARD_TARGET
-#define IP6T_ERROR_TARGET XT_ERROR_TARGET
-#define IP6T_MATCH_ITERATE(e, fn, args...) \
-	XT_MATCH_ITERATE(struct ip6t_entry, e, fn, ## args)
-#define IP6T_ENTRY_ITERATE(entries, size, fn, args...) \
-	XT_ENTRY_ITERATE(struct ip6t_entry, entries, size, fn, ## args)
-#endif
-
-/* Yes, Virginia, you have to zero the padding. */
-struct ip6t_ip6 {
-	/* Source and destination IP6 addr */
-	struct in6_addr src, dst;		
-	/* Mask for src and dest IP6 addr */
-	struct in6_addr smsk, dmsk;
-	char iniface[IFNAMSIZ], outiface[IFNAMSIZ];
-	unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];
-
-	/* Upper protocol number
-	 * - The allowed value is 0 (any) or protocol number of last parsable
-	 *   header, which is 50 (ESP), 59 (No Next Header), 135 (MH), or
-	 *   the non IPv6 extension headers.
-	 * - The protocol numbers of IPv6 extension headers except of ESP and
-	 *   MH do not match any packets.
-	 * - You also need to set IP6T_FLAGS_PROTO to "flags" to check protocol.
-	 */
-	__u16 proto;
-	/* TOS to match iff flags & IP6T_F_TOS */
-	__u8 tos;
-
-	/* Flags word */
-	__u8 flags;
-	/* Inverse flags */
-	__u8 invflags;
-};
-
-/* Values for "flag" field in struct ip6t_ip6 (general ip6 structure). */
-#define IP6T_F_PROTO		0x01	/* Set if rule cares about upper 
-					   protocols */
-#define IP6T_F_TOS		0x02	/* Match the TOS. */
-#define IP6T_F_GOTO		0x04	/* Set if jump is a goto */
-#define IP6T_F_MASK		0x07	/* All possible flag bits mask. */
-
-/* Values for "inv" field in struct ip6t_ip6. */
-#define IP6T_INV_VIA_IN		0x01	/* Invert the sense of IN IFACE. */
-#define IP6T_INV_VIA_OUT		0x02	/* Invert the sense of OUT IFACE */
-#define IP6T_INV_TOS		0x04	/* Invert the sense of TOS. */
-#define IP6T_INV_SRCIP		0x08	/* Invert the sense of SRC IP. */
-#define IP6T_INV_DSTIP		0x10	/* Invert the sense of DST OP. */
-#define IP6T_INV_FRAG		0x20	/* Invert the sense of FRAG. */
-#define IP6T_INV_PROTO		XT_INV_PROTO
-#define IP6T_INV_MASK		0x7F	/* All possible flag bits mask. */
-
-/* This structure defines each of the firewall rules.  Consists of 3
-   parts which are 1) general IP header stuff 2) match specific
-   stuff 3) the target to perform if the rule matches */
-struct ip6t_entry {
-	struct ip6t_ip6 ipv6;
-
-	/* Mark with fields that we care about. */
-	unsigned int nfcache;
-
-	/* Size of ipt_entry + matches */
-	__u16 target_offset;
-	/* Size of ipt_entry + matches + target */
-	__u16 next_offset;
-
-	/* Back pointer */
-	unsigned int comefrom;
-
-	/* Packet and byte counters. */
-	struct xt_counters counters;
-
-	/* The matches (if any), then the target. */
-	unsigned char elems[0];
-};
-
-/* Standard entry */
-struct ip6t_standard {
-	struct ip6t_entry entry;
-	struct xt_standard_target target;
-};
-
-struct ip6t_error {
-	struct ip6t_entry entry;
-	struct xt_error_target target;
-};
-
-#define IP6T_ENTRY_INIT(__size)						       \
-{									       \
-	.target_offset	= sizeof(struct ip6t_entry),			       \
-	.next_offset	= (__size),					       \
-}
-
-#define IP6T_STANDARD_INIT(__verdict)					       \
-{									       \
-	.entry		= IP6T_ENTRY_INIT(sizeof(struct ip6t_standard)),       \
-	.target		= XT_TARGET_INIT(XT_STANDARD_TARGET,		       \
-					 sizeof(struct xt_standard_target)),   \
-	.target.verdict	= -(__verdict) - 1,				       \
-}
-
-#define IP6T_ERROR_INIT							       \
-{									       \
-	.entry		= IP6T_ENTRY_INIT(sizeof(struct ip6t_error)),	       \
-	.target		= XT_TARGET_INIT(XT_ERROR_TARGET,		       \
-					 sizeof(struct xt_error_target)),      \
-	.target.errorname = "ERROR",					       \
-}
-
-/*
- * New IP firewall options for [gs]etsockopt at the RAW IP level.
- * Unlike BSD Linux inherits IP options so you don't have to use
- * a raw socket for this. Instead we check rights in the calls.
- *
- * ATTENTION: check linux/in6.h before adding new number here.
- */
-#define IP6T_BASE_CTL			64
-
-#define IP6T_SO_SET_REPLACE		(IP6T_BASE_CTL)
-#define IP6T_SO_SET_ADD_COUNTERS	(IP6T_BASE_CTL + 1)
-#define IP6T_SO_SET_MAX			IP6T_SO_SET_ADD_COUNTERS
-
-#define IP6T_SO_GET_INFO		(IP6T_BASE_CTL)
-#define IP6T_SO_GET_ENTRIES		(IP6T_BASE_CTL + 1)
-#define IP6T_SO_GET_REVISION_MATCH	(IP6T_BASE_CTL + 4)
-#define IP6T_SO_GET_REVISION_TARGET	(IP6T_BASE_CTL + 5)
-#define IP6T_SO_GET_MAX			IP6T_SO_GET_REVISION_TARGET
-
-/* ICMP matching stuff */
-struct ip6t_icmp {
-	__u8 type;				/* type to match */
-	__u8 code[2];				/* range of code */
-	__u8 invflags;				/* Inverse flags */
-};
-
-/* Values for "inv" field for struct ipt_icmp. */
-#define IP6T_ICMP_INV	0x01	/* Invert the sense of type/code test */
-
-/* The argument to IP6T_SO_GET_INFO */
-struct ip6t_getinfo {
-	/* Which table: caller fills this in. */
-	char name[XT_TABLE_MAXNAMELEN];
-
-	/* Kernel fills these in. */
-	/* Which hook entry points are valid: bitmask */
-	unsigned int valid_hooks;
-
-	/* Hook entry points: one per netfilter hook. */
-	unsigned int hook_entry[NF_INET_NUMHOOKS];
-
-	/* Underflow points. */
-	unsigned int underflow[NF_INET_NUMHOOKS];
-
-	/* Number of entries */
-	unsigned int num_entries;
-
-	/* Size of entries. */
-	unsigned int size;
-};
-
-/* The argument to IP6T_SO_SET_REPLACE. */
-struct ip6t_replace {
-	/* Which table. */
-	char name[XT_TABLE_MAXNAMELEN];
-
-	/* Which hook entry points are valid: bitmask.  You can't
-           change this. */
-	unsigned int valid_hooks;
-
-	/* Number of entries */
-	unsigned int num_entries;
-
-	/* Total size of new entries */
-	unsigned int size;
-
-	/* Hook entry points. */
-	unsigned int hook_entry[NF_INET_NUMHOOKS];
-
-	/* Underflow points. */
-	unsigned int underflow[NF_INET_NUMHOOKS];
-
-	/* Information about old entries: */
-	/* Number of counters (must be equal to current number of entries). */
-	unsigned int num_counters;
-	/* The old entries' counters. */
-	struct xt_counters __user *counters;
-
-	/* The entries (hang off end: not really an array). */
-	struct ip6t_entry entries[0];
-};
-
-/* The argument to IP6T_SO_GET_ENTRIES. */
-struct ip6t_get_entries {
-	/* Which table: user fills this in. */
-	char name[XT_TABLE_MAXNAMELEN];
-
-	/* User fills this in: total entry size. */
-	unsigned int size;
-
-	/* The entries. */
-	struct ip6t_entry entrytable[0];
-};
-
-/* Helper functions */
-static __inline__ struct xt_entry_target *
-ip6t_get_target(struct ip6t_entry *e)
-{
-	return (void *)e + e->target_offset;
-}
-
-/*
- *	Main firewall chains definitions and global var's definitions.
- */
-
-#ifdef __KERNEL__
 
 #include <linux/init.h>
+#include <uapi/linux/netfilter_ipv6/ip6_tables.h>
+
 extern void ip6t_init(void) __init;
 
 extern void *ip6t_alloc_initial_table(const struct xt_table *);
@@ -327,5 +76,4 @@
 }
 
 #endif /* CONFIG_COMPAT */
-#endif /*__KERNEL__*/
 #endif /* _IP6_TABLES_H */
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index f80c56a..6d3af05c 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -245,6 +245,8 @@
 					struct netlink_callback *cb);
 	int			(*done)(struct netlink_callback *cb);
 	void			*data;
+	/* the module that dump function belong to */
+	struct module		*module;
 	u16			family;
 	u16			min_dump_alloc;
 	unsigned int		prev_seq, seq;
@@ -262,14 +264,24 @@
 
 struct netlink_dump_control {
 	int (*dump)(struct sk_buff *skb, struct netlink_callback *);
-	int (*done)(struct netlink_callback*);
+	int (*done)(struct netlink_callback *);
 	void *data;
+	struct module *module;
 	u16 min_dump_alloc;
 };
 
-extern int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
-			      const struct nlmsghdr *nlh,
-			      struct netlink_dump_control *control);
+extern int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
+				const struct nlmsghdr *nlh,
+				struct netlink_dump_control *control);
+static inline int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
+				     const struct nlmsghdr *nlh,
+				     struct netlink_dump_control *control)
+{
+	if (!control->module)
+		control->module = THIS_MODULE;
+
+	return __netlink_dump_start(ssk, skb, nlh, control);
+}
 
 #endif /* __KERNEL__ */
 
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 4b03f56..334a2f5 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -81,12 +81,16 @@
 	int			mask;
 };
 
+struct nfs_lockowner {
+	fl_owner_t l_owner;
+	pid_t l_pid;
+};
+
 struct nfs_lock_context {
 	atomic_t count;
 	struct list_head list;
 	struct nfs_open_context *open_context;
-	fl_owner_t lockowner;
-	pid_t pid;
+	struct nfs_lockowner lockowner;
 };
 
 struct nfs4_state;
@@ -99,6 +103,7 @@
 
 	unsigned long flags;
 #define NFS_CONTEXT_ERROR_WRITE		(0)
+#define NFS_CONTEXT_RESEND_WRITES	(1)
 	int error;
 
 	struct list_head list;
@@ -355,6 +360,8 @@
 extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr);
 extern int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr);
 extern int nfs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
+extern void nfs_access_add_cache(struct inode *, struct nfs_access_entry *);
+extern void nfs_access_set_mask(struct nfs_access_entry *, u32);
 extern int nfs_permission(struct inode *, int);
 extern int nfs_open(struct inode *, struct file *);
 extern int nfs_release(struct inode *, struct file *);
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 310c63c..a9e76ee 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -39,6 +39,7 @@
 	unsigned long		cl_flags;	/* behavior switches */
 #define NFS_CS_NORESVPORT	0		/* - use ephemeral src port */
 #define NFS_CS_DISCRTRY		1		/* - disconnect on RPC retry */
+#define NFS_CS_MIGRATION	2		/* - transparent state migr */
 	struct sockaddr_storage	cl_addr;	/* server identifier */
 	size_t			cl_addrlen;
 	char *			cl_hostname;	/* hostname of server */
@@ -81,6 +82,7 @@
 	/* The flags used for obtaining the clientid during EXCHANGE_ID */
 	u32			cl_exchange_flags;
 	struct nfs4_session	*cl_session;	/* shared session */
+	bool			cl_preserve_clid;
 	struct nfs41_server_owner *cl_serverowner;
 	struct nfs41_server_scope *cl_serverscope;
 	struct nfs41_impl_id	*cl_implid;
@@ -125,6 +127,7 @@
 	unsigned int		namelen;
 	unsigned int		options;	/* extra options enabled by mount */
 #define NFS_OPTION_FSCACHE	0x00000001	/* - local caching enabled */
+#define NFS_OPTION_MIGRATION	0x00000002	/* - NFSv4 migration enabled */
 
 	struct nfs_fsid		fsid;
 	__u64			maxfilesize;	/* maximum file size */
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index be9cf3c..a73ea89 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -251,7 +251,6 @@
 struct nfs4_layoutget {
 	struct nfs4_layoutget_args args;
 	struct nfs4_layoutget_res res;
-	struct pnfs_layout_segment **lsegpp;
 	gfp_t gfp_flags;
 };
 
@@ -335,6 +334,7 @@
 	struct nfs_seqid *	seqid;
 	int			open_flags;
 	fmode_t			fmode;
+	u32			access;
 	__u64                   clientid;
 	struct stateowner_id	id;
 	union {
@@ -369,6 +369,9 @@
 	struct nfs4_string	*owner;
 	struct nfs4_string	*group_owner;
 	struct nfs4_sequence_res	seq_res;
+	__u32			access_request;
+	__u32			access_supported;
+	__u32			access_result;
 };
 
 /*
diff --git a/include/linux/oom.h b/include/linux/oom.h
index 49a3031..d36a822 100644
--- a/include/linux/oom.h
+++ b/include/linux/oom.h
@@ -2,17 +2,6 @@
 #define __INCLUDE_LINUX_OOM_H
 
 /*
- * /proc/<pid>/oom_adj is deprecated, see
- * Documentation/feature-removal-schedule.txt.
- *
- * /proc/<pid>/oom_adj set to -17 protects from the oom-killer
- */
-#define OOM_DISABLE (-17)
-/* inclusive */
-#define OOM_ADJUST_MIN (-16)
-#define OOM_ADJUST_MAX 15
-
-/*
  * /proc/<pid>/oom_score_adj set to OOM_SCORE_ADJ_MIN disables oom killing for
  * pid.
  */
diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h
index 105077a..76a9539 100644
--- a/include/linux/page-isolation.h
+++ b/include/linux/page-isolation.h
@@ -6,6 +6,10 @@
 void set_pageblock_migratetype(struct page *page, int migratetype);
 int move_freepages_block(struct zone *zone, struct page *page,
 				int migratetype);
+int move_freepages(struct zone *zone,
+			  struct page *start_page, struct page *end_page,
+			  int migratetype);
+
 /*
  * Changes migrate type in [start_pfn, end_pfn) to be MIGRATE_ISOLATE.
  * If specified range includes migrate types other than MOVABLE or CMA,
@@ -37,6 +41,7 @@
  */
 int set_migratetype_isolate(struct page *page);
 void unset_migratetype_isolate(struct page *page, unsigned migratetype);
-
+struct page *alloc_migrate_target(struct page *page, unsigned long private,
+				int **resultp);
 
 #endif
diff --git a/include/linux/pageblock-flags.h b/include/linux/pageblock-flags.h
index 19ef95d..be655e4 100644
--- a/include/linux/pageblock-flags.h
+++ b/include/linux/pageblock-flags.h
@@ -30,6 +30,9 @@
 	PB_migrate,
 	PB_migrate_end = PB_migrate + 3 - 1,
 			/* 3 bits required for migrate types */
+#ifdef CONFIG_COMPACTION
+	PB_migrate_skip,/* If set the block is skipped by compaction */
+#endif /* CONFIG_COMPACTION */
 	NR_PAGEBLOCK_BITS
 };
 
@@ -65,10 +68,22 @@
 void set_pageblock_flags_group(struct page *page, unsigned long flags,
 					int start_bitidx, int end_bitidx);
 
+#ifdef CONFIG_COMPACTION
+#define get_pageblock_skip(page) \
+			get_pageblock_flags_group(page, PB_migrate_skip,     \
+							PB_migrate_skip)
+#define clear_pageblock_skip(page) \
+			set_pageblock_flags_group(page, 0, PB_migrate_skip,  \
+							PB_migrate_skip)
+#define set_pageblock_skip(page) \
+			set_pageblock_flags_group(page, 1, PB_migrate_skip,  \
+							PB_migrate_skip)
+#endif /* CONFIG_COMPACTION */
+
 #define get_pageblock_flags(page) \
-			get_pageblock_flags_group(page, 0, NR_PAGEBLOCK_BITS-1)
+			get_pageblock_flags_group(page, 0, PB_migrate_end)
 #define set_pageblock_flags(page, flags) \
 			set_pageblock_flags_group(page, flags,	\
-						  0, NR_PAGEBLOCK_BITS-1)
+						  0, PB_migrate_end)
 
 #endif	/* PAGEBLOCK_FLAGS_H */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 33880f6..9d36b82 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1427,6 +1427,7 @@
 #define PCI_DEVICE_ID_VIA_CX700_IDE	0x0581
 #define PCI_DEVICE_ID_VIA_VX800		0x8353
 #define PCI_DEVICE_ID_VIA_VX855		0x8409
+#define PCI_DEVICE_ID_VIA_VX900		0x8410
 #define PCI_DEVICE_ID_VIA_8371_1	0x8391
 #define PCI_DEVICE_ID_VIA_82C598_1	0x8598
 #define PCI_DEVICE_ID_VIA_838X_1	0xB188
diff --git a/include/linux/percpu-rwsem.h b/include/linux/percpu-rwsem.h
new file mode 100644
index 0000000..cf80f7e
--- /dev/null
+++ b/include/linux/percpu-rwsem.h
@@ -0,0 +1,89 @@
+#ifndef _LINUX_PERCPU_RWSEM_H
+#define _LINUX_PERCPU_RWSEM_H
+
+#include <linux/mutex.h>
+#include <linux/percpu.h>
+#include <linux/rcupdate.h>
+#include <linux/delay.h>
+
+struct percpu_rw_semaphore {
+	unsigned __percpu *counters;
+	bool locked;
+	struct mutex mtx;
+};
+
+static inline void percpu_down_read(struct percpu_rw_semaphore *p)
+{
+	rcu_read_lock();
+	if (unlikely(p->locked)) {
+		rcu_read_unlock();
+		mutex_lock(&p->mtx);
+		this_cpu_inc(*p->counters);
+		mutex_unlock(&p->mtx);
+		return;
+	}
+	this_cpu_inc(*p->counters);
+	rcu_read_unlock();
+}
+
+static inline void percpu_up_read(struct percpu_rw_semaphore *p)
+{
+	/*
+	 * On X86, write operation in this_cpu_dec serves as a memory unlock
+	 * barrier (i.e. memory accesses may be moved before the write, but
+	 * no memory accesses are moved past the write).
+	 * On other architectures this may not be the case, so we need smp_mb()
+	 * there.
+	 */
+#if defined(CONFIG_X86) && (!defined(CONFIG_X86_PPRO_FENCE) && !defined(CONFIG_X86_OOSTORE))
+	barrier();
+#else
+	smp_mb();
+#endif
+	this_cpu_dec(*p->counters);
+}
+
+static inline unsigned __percpu_count(unsigned __percpu *counters)
+{
+	unsigned total = 0;
+	int cpu;
+
+	for_each_possible_cpu(cpu)
+		total += ACCESS_ONCE(*per_cpu_ptr(counters, cpu));
+
+	return total;
+}
+
+static inline void percpu_down_write(struct percpu_rw_semaphore *p)
+{
+	mutex_lock(&p->mtx);
+	p->locked = true;
+	synchronize_rcu();
+	while (__percpu_count(p->counters))
+		msleep(1);
+	smp_rmb(); /* paired with smp_mb() in percpu_sem_up_read() */
+}
+
+static inline void percpu_up_write(struct percpu_rw_semaphore *p)
+{
+	p->locked = false;
+	mutex_unlock(&p->mtx);
+}
+
+static inline int percpu_init_rwsem(struct percpu_rw_semaphore *p)
+{
+	p->counters = alloc_percpu(unsigned);
+	if (unlikely(!p->counters))
+		return -ENOMEM;
+	p->locked = false;
+	mutex_init(&p->mtx);
+	return 0;
+}
+
+static inline void percpu_free_rwsem(struct percpu_rw_semaphore *p)
+{
+	free_percpu(p->counters);
+	p->counters = NULL; /* catch use after free bugs */
+}
+
+#endif
diff --git a/include/linux/platform_data/asoc-mx27vis.h b/include/linux/platform_data/asoc-mx27vis.h
new file mode 100644
index 0000000..409adcd
--- /dev/null
+++ b/include/linux/platform_data/asoc-mx27vis.h
@@ -0,0 +1,11 @@
+#ifndef __PLATFORM_DATA_ASOC_MX27VIS_H
+#define __PLATFORM_DATA_ASOC_MX27VIS_H
+
+struct snd_mx27vis_platform_data {
+	int amp_gain0_gpio;
+	int amp_gain1_gpio;
+	int amp_mutel_gpio;
+	int amp_muter_gpio;
+};
+
+#endif /* __PLATFORM_DATA_ASOC_MX27VIS_H */
diff --git a/include/linux/platform_data/asoc-ti-mcbsp.h b/include/linux/platform_data/asoc-ti-mcbsp.h
index 1881412..c78d90b 100644
--- a/include/linux/platform_data/asoc-ti-mcbsp.h
+++ b/include/linux/platform_data/asoc-ti-mcbsp.h
@@ -47,8 +47,6 @@
 	bool has_wakeup; /* Wakeup capability */
 	bool has_ccr; /* Transceiver has configuration control registers */
 	int (*enable_st_clock)(unsigned int, bool);
-	int (*set_clk_src)(struct device *dev, struct clk *clk, const char *src);
-	int (*mux_signal)(struct device *dev, const char *signal, const char *src);
 };
 
 /**
diff --git a/include/linux/platform_data/davinci_asp.h b/include/linux/platform_data/davinci_asp.h
new file mode 100644
index 0000000..d0c5825
--- /dev/null
+++ b/include/linux/platform_data/davinci_asp.h
@@ -0,0 +1,105 @@
+/*
+ * TI DaVinci Audio Serial Port support
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __DAVINCI_ASP_H
+#define __DAVINCI_ASP_H
+
+struct snd_platform_data {
+	u32 tx_dma_offset;
+	u32 rx_dma_offset;
+	int asp_chan_q;	/* event queue number for ASP channel */
+	int ram_chan_q;	/* event queue number for RAM channel */
+	unsigned int codec_fmt;
+	/*
+	 * Allowing this is more efficient and eliminates left and right swaps
+	 * caused by underruns, but will swap the left and right channels
+	 * when compared to previous behavior.
+	 */
+	unsigned enable_channel_combine:1;
+	unsigned sram_size_playback;
+	unsigned sram_size_capture;
+
+	/*
+	 * If McBSP peripheral gets the clock from an external pin,
+	 * there are three chooses, that are MCBSP_CLKX, MCBSP_CLKR
+	 * and MCBSP_CLKS.
+	 * Depending on different hardware connections it is possible
+	 * to use this setting to change the behaviour of McBSP
+	 * driver.
+	 */
+	int clk_input_pin;
+
+	/*
+	 * This flag works when both clock and FS are outputs for the cpu
+	 * and makes clock more accurate (FS is not symmetrical and the
+	 * clock is very fast.
+	 * The clock becoming faster is named
+	 * i2s continuous serial clock (I2S_SCK) and it is an externally
+	 * visible bit clock.
+	 *
+	 * first line : WordSelect
+	 * second line : ContinuousSerialClock
+	 * third line: SerialData
+	 *
+	 * SYMMETRICAL APPROACH:
+	 *   _______________________          LEFT
+	 * _|         RIGHT         |______________________|
+	 *     _   _         _   _   _   _         _   _
+	 *   _| |_| |_ x16 _| |_| |_| |_| |_ x16 _| |_| |_
+	 *     _   _         _   _   _   _         _   _
+	 *   _/ \_/ \_ ... _/ \_/ \_/ \_/ \_ ... _/ \_/ \_
+	 *    \_/ \_/       \_/ \_/ \_/ \_/       \_/ \_/
+	 *
+	 * ACCURATE CLOCK APPROACH:
+	 *   ______________          LEFT
+	 * _|     RIGHT    |_______________________________|
+	 *     _         _   _         _   _   _   _   _   _
+	 *   _| |_ x16 _| |_| |_ x16 _| |_| |_| |_| |_| |_| |
+	 *     _         _   _          _      dummy cycles
+	 *   _/ \_ ... _/ \_/ \_  ... _/ \__________________
+	 *    \_/       \_/ \_/        \_/
+	 *
+	 */
+	bool i2s_accurate_sck;
+
+	/* McASP specific fields */
+	int tdm_slots;
+	u8 op_mode;
+	u8 num_serializer;
+	u8 *serial_dir;
+	u8 version;
+	u8 txnumevt;
+	u8 rxnumevt;
+};
+
+enum {
+	MCASP_VERSION_1 = 0,	/* DM646x */
+	MCASP_VERSION_2,	/* DA8xx/OMAPL1x */
+	MCASP_VERSION_3,        /* TI81xx/AM33xx */
+};
+
+enum mcbsp_clk_input_pin {
+	MCBSP_CLKR = 0,		/* as in DM365 */
+	MCBSP_CLKS,
+};
+
+#define INACTIVE_MODE	0
+#define TX_MODE		1
+#define RX_MODE		2
+
+#define DAVINCI_MCASP_IIS_MODE	0
+#define DAVINCI_MCASP_DIT_MODE	1
+
+#endif
diff --git a/include/linux/platform_data/i2c-nomadik.h b/include/linux/platform_data/i2c-nomadik.h
index c2303c3..3a8be9c 100644
--- a/include/linux/platform_data/i2c-nomadik.h
+++ b/include/linux/platform_data/i2c-nomadik.h
@@ -28,7 +28,7 @@
  * @sm:		speed mode
  */
 struct nmk_i2c_controller {
-	unsigned long	clk_freq;
+	u32             clk_freq;
 	unsigned short	slsu;
 	unsigned char	tft;
 	unsigned char	rft;
diff --git a/include/linux/platform_data/leds-lm3556.h b/include/linux/platform_data/leds-lm3556.h
deleted file mode 100644
index 4b4e7d6..0000000
--- a/include/linux/platform_data/leds-lm3556.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Simple driver for Texas Instruments LM3556 LED Flash driver chip (Rev0x03)
- * Copyright (C) 2012 Texas Instruments
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#ifndef __LINUX_LM3556_H
-#define __LINUX_LM3556_H
-
-#define LM3556_NAME "leds-lm3556"
-
-enum lm3556_pin_polarity {
-	PIN_LOW_ACTIVE = 0,
-	PIN_HIGH_ACTIVE,
-};
-
-enum lm3556_pin_enable {
-	PIN_DISABLED = 0,
-	PIN_ENABLED,
-};
-
-enum lm3556_strobe_usuage {
-	STROBE_EDGE_DETECT = 0,
-	STROBE_LEVEL_DETECT,
-};
-
-enum lm3556_indic_mode {
-	INDIC_MODE_INTERNAL = 0,
-	INDIC_MODE_EXTERNAL,
-};
-
-struct lm3556_platform_data {
-	enum lm3556_pin_enable torch_pin_en;
-	enum lm3556_pin_polarity torch_pin_polarity;
-
-	enum lm3556_strobe_usuage strobe_usuage;
-	enum lm3556_pin_enable strobe_pin_en;
-	enum lm3556_pin_polarity strobe_pin_polarity;
-
-	enum lm3556_pin_enable tx_pin_en;
-	enum lm3556_pin_polarity tx_pin_polarity;
-
-	enum lm3556_indic_mode indicator_mode;
-};
-
-#endif /* __LINUX_LM3556_H */
diff --git a/include/linux/platform_data/leds-lm355x.h b/include/linux/platform_data/leds-lm355x.h
new file mode 100644
index 0000000..b88724b
--- /dev/null
+++ b/include/linux/platform_data/leds-lm355x.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2012 Texas Instruments
+ *
+ * License Terms: GNU General Public License v2
+ *
+ * Simple driver for Texas Instruments LM355x LED driver chip
+ *
+ * Author: G.Shark Jeong <gshark.jeong@gmail.com>
+ *         Daniel Jeong <daniel.jeong@ti.com>
+ */
+
+#define LM355x_NAME "leds-lm355x"
+#define LM3554_NAME "leds-lm3554"
+#define LM3556_NAME "leds-lm3556"
+
+/* lm3554 : strobe def. on */
+enum lm355x_strobe {
+	LM355x_PIN_STROBE_DISABLE = 0x00,
+	LM355x_PIN_STROBE_ENABLE = 0x01,
+};
+
+enum lm355x_torch {
+	LM355x_PIN_TORCH_DISABLE = 0,
+	LM3554_PIN_TORCH_ENABLE = 0x80,
+	LM3556_PIN_TORCH_ENABLE = 0x10,
+};
+
+enum lm355x_tx2 {
+	LM355x_PIN_TX_DISABLE = 0,
+	LM3554_PIN_TX_ENABLE = 0x20,
+	LM3556_PIN_TX_ENABLE = 0x40,
+};
+
+enum lm355x_ntc {
+	LM355x_PIN_NTC_DISABLE = 0,
+	LM3554_PIN_NTC_ENABLE = 0x08,
+	LM3556_PIN_NTC_ENABLE = 0x80,
+};
+
+enum lm355x_pmode {
+	LM355x_PMODE_DISABLE = 0,
+	LM355x_PMODE_ENABLE = 0x04,
+};
+
+/*
+ * struct lm3554_platform_data
+ * @pin_strobe: strobe input
+ * @pin_torch : input pin
+ *              lm3554-tx1/torch/gpio1
+ *              lm3556-torch
+ * @pin_tx2   : input pin
+ *              lm3554-envm/tx2/gpio2
+ *              lm3556-tx pin
+ * @ntc_pin  : output pin
+ *              lm3554-ledi/ntc
+ *              lm3556-temp pin
+ * @pass_mode : pass mode
+ */
+struct lm355x_platform_data {
+	enum lm355x_strobe pin_strobe;
+	enum lm355x_torch pin_tx1;
+	enum lm355x_tx2 pin_tx2;
+	enum lm355x_ntc ntc_pin;
+
+	enum lm355x_pmode pass_mode;
+};
diff --git a/include/linux/platform_data/leds-lm3642.h b/include/linux/platform_data/leds-lm3642.h
new file mode 100644
index 0000000..72d6ee6
--- /dev/null
+++ b/include/linux/platform_data/leds-lm3642.h
@@ -0,0 +1,38 @@
+/*
+* Copyright (C) 2012 Texas Instruments
+*
+* License Terms: GNU General Public License v2
+*
+* Simple driver for Texas Instruments LM3642 LED driver chip
+*
+* Author: G.Shark Jeong <gshark.jeong@gmail.com>
+*         Daniel Jeong <daniel.jeong@ti.com>
+*/
+
+#ifndef __LINUX_LM3642_H
+#define __LINUX_LM3642_H
+
+#define LM3642_NAME "leds-lm3642"
+
+enum lm3642_torch_pin_enable {
+	LM3642_TORCH_PIN_DISABLE = 0x00,
+	LM3642_TORCH_PIN_ENABLE = 0x10,
+};
+
+enum lm3642_strobe_pin_enable {
+	LM3642_STROBE_PIN_DISABLE = 0x00,
+	LM3642_STROBE_PIN_ENABLE = 0x20,
+};
+
+enum lm3642_tx_pin_enable {
+	LM3642_TX_PIN_DISABLE = 0x00,
+	LM3642_TX_PIN_ENABLE = 0x40,
+};
+
+struct lm3642_platform_data {
+	enum lm3642_torch_pin_enable torch_pin;
+	enum lm3642_strobe_pin_enable strobe_pin;
+	enum lm3642_tx_pin_enable tx_pin;
+};
+
+#endif /* __LINUX_LM3642_H */
diff --git a/include/linux/platform_data/leds-pca9633.h b/include/linux/platform_data/leds-pca9633.h
new file mode 100644
index 0000000..c5bf29b
--- /dev/null
+++ b/include/linux/platform_data/leds-pca9633.h
@@ -0,0 +1,35 @@
+/*
+ * PCA9633 LED chip driver.
+ *
+ * Copyright 2012 bct electronic GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef __LINUX_PCA9633_H
+#define __LINUX_PCA9633_H
+#include <linux/leds.h>
+
+enum pca9633_outdrv {
+	PCA9633_OPEN_DRAIN,
+	PCA9633_TOTEM_POLE, /* aka push-pull */
+};
+
+struct pca9633_platform_data {
+	struct led_platform_data leds;
+	enum pca9633_outdrv outdrv;
+};
+
+#endif /* __LINUX_PCA9633_H*/
diff --git a/include/linux/platform_data/mmp_dma.h b/include/linux/platform_data/mmp_dma.h
new file mode 100644
index 0000000..2a330ec
--- /dev/null
+++ b/include/linux/platform_data/mmp_dma.h
@@ -0,0 +1,19 @@
+/*
+ *  MMP Platform DMA Management
+ *
+ *  Copyright (c) 2011 Marvell Semiconductors Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ */
+
+#ifndef MMP_DMA_H
+#define MMP_DMA_H
+
+struct mmp_dma_platdata {
+	int dma_channels;
+};
+
+#endif /* MMP_DMA_H */
diff --git a/include/linux/platform_data/omap-twl4030.h b/include/linux/platform_data/omap-twl4030.h
new file mode 100644
index 0000000..c7bef78
--- /dev/null
+++ b/include/linux/platform_data/omap-twl4030.h
@@ -0,0 +1,32 @@
+/**
+ * omap-twl4030.h - ASoC machine driver for TI SoC based boards with twl4030
+ *		    codec, header.
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com
+ * All rights reserved.
+ *
+ * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef _OMAP_TWL4030_H_
+#define _OMAP_TWL4030_H_
+
+struct omap_tw4030_pdata {
+	const char *card_name;
+};
+
+#endif /* _OMAP_TWL4030_H_ */
diff --git a/include/linux/platform_data/pxa_sdhci.h b/include/linux/platform_data/pxa_sdhci.h
index 51ad099..59acd98 100644
--- a/include/linux/platform_data/pxa_sdhci.h
+++ b/include/linux/platform_data/pxa_sdhci.h
@@ -49,6 +49,7 @@
 	bool		ext_cd_gpio_invert;
 	unsigned int	max_speed;
 	unsigned int	host_caps;
+	unsigned int	host_caps2;
 	unsigned int	quirks;
 	unsigned int	pm_caps;
 };
diff --git a/include/linux/pnfs_osd_xdr.h b/include/linux/pnfs_osd_xdr.h
index 435dd5f..fe25876 100644
--- a/include/linux/pnfs_osd_xdr.h
+++ b/include/linux/pnfs_osd_xdr.h
@@ -40,7 +40,6 @@
 #define __PNFS_OSD_XDR_H__
 
 #include <linux/nfs_fs.h>
-#include <linux/nfs_page.h>
 
 /*
  * draft-ietf-nfsv4-minorversion-22
diff --git a/include/linux/prio_tree.h b/include/linux/prio_tree.h
deleted file mode 100644
index db04abb..0000000
--- a/include/linux/prio_tree.h
+++ /dev/null
@@ -1,120 +0,0 @@
-#ifndef _LINUX_PRIO_TREE_H
-#define _LINUX_PRIO_TREE_H
-
-/*
- * K&R 2nd ed. A8.3 somewhat obliquely hints that initial sequences of struct
- * fields with identical types should end up at the same location. We'll use
- * this until we can scrap struct raw_prio_tree_node.
- *
- * Note: all this could be done more elegantly by using unnamed union/struct
- * fields. However, gcc 2.95.3 and apparently also gcc 3.0.4 don't support this
- * language extension.
- */
-
-struct raw_prio_tree_node {
-	struct prio_tree_node	*left;
-	struct prio_tree_node	*right;
-	struct prio_tree_node	*parent;
-};
-
-struct prio_tree_node {
-	struct prio_tree_node	*left;
-	struct prio_tree_node	*right;
-	struct prio_tree_node	*parent;
-	unsigned long		start;
-	unsigned long		last;	/* last location _in_ interval */
-};
-
-struct prio_tree_root {
-	struct prio_tree_node	*prio_tree_node;
-	unsigned short 		index_bits;
-	unsigned short		raw;
-		/*
-		 * 0: nodes are of type struct prio_tree_node
-		 * 1: nodes are of type raw_prio_tree_node
-		 */
-};
-
-struct prio_tree_iter {
-	struct prio_tree_node	*cur;
-	unsigned long		mask;
-	unsigned long		value;
-	int			size_level;
-
-	struct prio_tree_root	*root;
-	pgoff_t			r_index;
-	pgoff_t			h_index;
-};
-
-static inline void prio_tree_iter_init(struct prio_tree_iter *iter,
-		struct prio_tree_root *root, pgoff_t r_index, pgoff_t h_index)
-{
-	iter->root = root;
-	iter->r_index = r_index;
-	iter->h_index = h_index;
-	iter->cur = NULL;
-}
-
-#define __INIT_PRIO_TREE_ROOT(ptr, _raw)	\
-do {					\
-	(ptr)->prio_tree_node = NULL;	\
-	(ptr)->index_bits = 1;		\
-	(ptr)->raw = (_raw);		\
-} while (0)
-
-#define INIT_PRIO_TREE_ROOT(ptr)	__INIT_PRIO_TREE_ROOT(ptr, 0)
-#define INIT_RAW_PRIO_TREE_ROOT(ptr)	__INIT_PRIO_TREE_ROOT(ptr, 1)
-
-#define INIT_PRIO_TREE_NODE(ptr)				\
-do {								\
-	(ptr)->left = (ptr)->right = (ptr)->parent = (ptr);	\
-} while (0)
-
-#define INIT_PRIO_TREE_ITER(ptr)	\
-do {					\
-	(ptr)->cur = NULL;		\
-	(ptr)->mask = 0UL;		\
-	(ptr)->value = 0UL;		\
-	(ptr)->size_level = 0;		\
-} while (0)
-
-#define prio_tree_entry(ptr, type, member) \
-       ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
-
-static inline int prio_tree_empty(const struct prio_tree_root *root)
-{
-	return root->prio_tree_node == NULL;
-}
-
-static inline int prio_tree_root(const struct prio_tree_node *node)
-{
-	return node->parent == node;
-}
-
-static inline int prio_tree_left_empty(const struct prio_tree_node *node)
-{
-	return node->left == node;
-}
-
-static inline int prio_tree_right_empty(const struct prio_tree_node *node)
-{
-	return node->right == node;
-}
-
-
-struct prio_tree_node *prio_tree_replace(struct prio_tree_root *root,
-                struct prio_tree_node *old, struct prio_tree_node *node);
-struct prio_tree_node *prio_tree_insert(struct prio_tree_root *root,
-                struct prio_tree_node *node);
-void prio_tree_remove(struct prio_tree_root *root, struct prio_tree_node *node);
-struct prio_tree_node *prio_tree_next(struct prio_tree_iter *iter);
-
-#define raw_prio_tree_replace(root, old, node) \
-	prio_tree_replace(root, (struct prio_tree_node *) (old), \
-	    (struct prio_tree_node *) (node))
-#define raw_prio_tree_insert(root, node) \
-	prio_tree_insert(root, (struct prio_tree_node *) (node))
-#define raw_prio_tree_remove(root, node) \
-	prio_tree_remove(root, (struct prio_tree_node *) (node))
-
-#endif /* _LINUX_PRIO_TREE_H */
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index 3db698a..1d24ffa 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -401,6 +401,10 @@
 #define arch_ptrace_stop(code, info)		do { } while (0)
 #endif
 
+#ifndef current_pt_regs
+#define current_pt_regs() task_pt_regs(current)
+#endif
+
 extern int task_current_syscall(struct task_struct *target, long *callno,
 				unsigned long args[6], unsigned int maxargs,
 				unsigned long *sp, unsigned long *pc);
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index 21d076c..112b314 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -1,11 +1,13 @@
 #ifndef __LINUX_PWM_H
 #define __LINUX_PWM_H
 
+#include <linux/err.h>
 #include <linux/of.h>
 
 struct pwm_device;
 struct seq_file;
 
+#if IS_ENABLED(CONFIG_PWM) || IS_ENABLED(CONFIG_HAVE_PWM)
 /*
  * pwm_request - request a PWM device
  */
@@ -30,10 +32,47 @@
  * pwm_disable - stop a PWM output toggling
  */
 void pwm_disable(struct pwm_device *pwm);
+#else
+static inline struct pwm_device *pwm_request(int pwm_id, const char *label)
+{
+	return ERR_PTR(-ENODEV);
+}
 
-#ifdef CONFIG_PWM
+static inline void pwm_free(struct pwm_device *pwm)
+{
+}
+
+static inline int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
+{
+	return -EINVAL;
+}
+
+static inline int pwm_enable(struct pwm_device *pwm)
+{
+	return -EINVAL;
+}
+
+static inline void pwm_disable(struct pwm_device *pwm)
+{
+}
+#endif
+
 struct pwm_chip;
 
+/**
+ * enum pwm_polarity - polarity of a PWM signal
+ * @PWM_POLARITY_NORMAL: a high signal for the duration of the duty-
+ * cycle, followed by a low signal for the remainder of the pulse
+ * period
+ * @PWM_POLARITY_INVERSED: a low signal for the duration of the duty-
+ * cycle, followed by a high signal for the remainder of the pulse
+ * period
+ */
+enum pwm_polarity {
+	PWM_POLARITY_NORMAL,
+	PWM_POLARITY_INVERSED,
+};
+
 enum {
 	PWMF_REQUESTED = 1 << 0,
 	PWMF_ENABLED = 1 << 1,
@@ -61,11 +100,17 @@
 	return pwm ? pwm->period : 0;
 }
 
+/*
+ * pwm_set_polarity - configure the polarity of a PWM signal
+ */
+int pwm_set_polarity(struct pwm_device *pwm, enum pwm_polarity polarity);
+
 /**
  * struct pwm_ops - PWM controller operations
  * @request: optional hook for requesting a PWM
  * @free: optional hook for freeing a PWM
  * @config: configure duty cycles and period length for this PWM
+ * @set_polarity: configure the polarity of this PWM
  * @enable: enable PWM output toggling
  * @disable: disable PWM output toggling
  * @dbg_show: optional routine to show contents in debugfs
@@ -79,6 +124,9 @@
 	int			(*config)(struct pwm_chip *chip,
 					  struct pwm_device *pwm,
 					  int duty_ns, int period_ns);
+	int			(*set_polarity)(struct pwm_chip *chip,
+					  struct pwm_device *pwm,
+					  enum pwm_polarity polarity);
 	int			(*enable)(struct pwm_chip *chip,
 					  struct pwm_device *pwm);
 	void			(*disable)(struct pwm_chip *chip,
@@ -113,6 +161,7 @@
 	unsigned int		of_pwm_n_cells;
 };
 
+#if IS_ENABLED(CONFIG_PWM)
 int pwm_set_chip_data(struct pwm_device *pwm, void *data);
 void *pwm_get_chip_data(struct pwm_device *pwm);
 
@@ -125,6 +174,57 @@
 struct pwm_device *pwm_get(struct device *dev, const char *consumer);
 void pwm_put(struct pwm_device *pwm);
 
+struct pwm_device *devm_pwm_get(struct device *dev, const char *consumer);
+void devm_pwm_put(struct device *dev, struct pwm_device *pwm);
+#else
+static inline int pwm_set_chip_data(struct pwm_device *pwm, void *data)
+{
+	return -EINVAL;
+}
+
+static inline void *pwm_get_chip_data(struct pwm_device *pwm)
+{
+	return NULL;
+}
+
+static inline int pwmchip_add(struct pwm_chip *chip)
+{
+	return -EINVAL;
+}
+
+static inline int pwmchip_remove(struct pwm_chip *chip)
+{
+	return -EINVAL;
+}
+
+static inline struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip,
+						       unsigned int index,
+						       const char *label)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline struct pwm_device *pwm_get(struct device *dev,
+					 const char *consumer)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline void pwm_put(struct pwm_device *pwm)
+{
+}
+
+static inline struct pwm_device *devm_pwm_get(struct device *dev,
+					      const char *consumer)
+{
+	return ERR_PTR(-ENODEV);
+}
+
+static inline void devm_pwm_put(struct device *dev, struct pwm_device *pwm)
+{
+}
+#endif
+
 struct pwm_lookup {
 	struct list_head list;
 	const char *provider;
@@ -141,8 +241,12 @@
 		.con_id = _con_id,			\
 	}
 
+#if IS_ENABLED(CONFIG_PWM)
 void pwm_add_table(struct pwm_lookup *table, size_t num);
-
+#else
+static inline void pwm_add_table(struct pwm_lookup *table, size_t num)
+{
+}
 #endif
 
 #endif /* __LINUX_PWM_H */
diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h
index 033b507..0022c1b 100644
--- a/include/linux/rbtree.h
+++ b/include/linux/rbtree.h
@@ -23,72 +23,7 @@
   I know it's not the cleaner way,  but in C (not in C++) to get
   performances and genericity...
 
-  Some example of insert and search follows here. The search is a plain
-  normal search over an ordered tree. The insert instead must be implemented
-  in two steps: First, the code must insert the element in order as a red leaf
-  in the tree, and then the support library function rb_insert_color() must
-  be called. Such function will do the not trivial work to rebalance the
-  rbtree, if necessary.
-
------------------------------------------------------------------------
-static inline struct page * rb_search_page_cache(struct inode * inode,
-						 unsigned long offset)
-{
-	struct rb_node * n = inode->i_rb_page_cache.rb_node;
-	struct page * page;
-
-	while (n)
-	{
-		page = rb_entry(n, struct page, rb_page_cache);
-
-		if (offset < page->offset)
-			n = n->rb_left;
-		else if (offset > page->offset)
-			n = n->rb_right;
-		else
-			return page;
-	}
-	return NULL;
-}
-
-static inline struct page * __rb_insert_page_cache(struct inode * inode,
-						   unsigned long offset,
-						   struct rb_node * node)
-{
-	struct rb_node ** p = &inode->i_rb_page_cache.rb_node;
-	struct rb_node * parent = NULL;
-	struct page * page;
-
-	while (*p)
-	{
-		parent = *p;
-		page = rb_entry(parent, struct page, rb_page_cache);
-
-		if (offset < page->offset)
-			p = &(*p)->rb_left;
-		else if (offset > page->offset)
-			p = &(*p)->rb_right;
-		else
-			return page;
-	}
-
-	rb_link_node(node, parent, p);
-
-	return NULL;
-}
-
-static inline struct page * rb_insert_page_cache(struct inode * inode,
-						 unsigned long offset,
-						 struct rb_node * node)
-{
-	struct page * ret;
-	if ((ret = __rb_insert_page_cache(inode, offset, node)))
-		goto out;
-	rb_insert_color(node, &inode->i_rb_page_cache);
- out:
-	return ret;
-}
------------------------------------------------------------------------
+  See Documentation/rbtree.txt for documentation and samples.
 */
 
 #ifndef	_LINUX_RBTREE_H
@@ -97,63 +32,35 @@
 #include <linux/kernel.h>
 #include <linux/stddef.h>
 
-struct rb_node
-{
-	unsigned long  rb_parent_color;
-#define	RB_RED		0
-#define	RB_BLACK	1
+struct rb_node {
+	unsigned long  __rb_parent_color;
 	struct rb_node *rb_right;
 	struct rb_node *rb_left;
 } __attribute__((aligned(sizeof(long))));
     /* The alignment might seem pointless, but allegedly CRIS needs it */
 
-struct rb_root
-{
+struct rb_root {
 	struct rb_node *rb_node;
 };
 
 
-#define rb_parent(r)   ((struct rb_node *)((r)->rb_parent_color & ~3))
-#define rb_color(r)   ((r)->rb_parent_color & 1)
-#define rb_is_red(r)   (!rb_color(r))
-#define rb_is_black(r) rb_color(r)
-#define rb_set_red(r)  do { (r)->rb_parent_color &= ~1; } while (0)
-#define rb_set_black(r)  do { (r)->rb_parent_color |= 1; } while (0)
-
-static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
-{
-	rb->rb_parent_color = (rb->rb_parent_color & 3) | (unsigned long)p;
-}
-static inline void rb_set_color(struct rb_node *rb, int color)
-{
-	rb->rb_parent_color = (rb->rb_parent_color & ~1) | color;
-}
+#define rb_parent(r)   ((struct rb_node *)((r)->__rb_parent_color & ~3))
 
 #define RB_ROOT	(struct rb_root) { NULL, }
 #define	rb_entry(ptr, type, member) container_of(ptr, type, member)
 
-#define RB_EMPTY_ROOT(root)	((root)->rb_node == NULL)
-#define RB_EMPTY_NODE(node)	(rb_parent(node) == node)
-#define RB_CLEAR_NODE(node)	(rb_set_parent(node, node))
+#define RB_EMPTY_ROOT(root)  ((root)->rb_node == NULL)
 
-static inline void rb_init_node(struct rb_node *rb)
-{
-	rb->rb_parent_color = 0;
-	rb->rb_right = NULL;
-	rb->rb_left = NULL;
-	RB_CLEAR_NODE(rb);
-}
+/* 'empty' nodes are nodes that are known not to be inserted in an rbree */
+#define RB_EMPTY_NODE(node)  \
+	((node)->__rb_parent_color == (unsigned long)(node))
+#define RB_CLEAR_NODE(node)  \
+	((node)->__rb_parent_color = (unsigned long)(node))
+
 
 extern void rb_insert_color(struct rb_node *, struct rb_root *);
 extern void rb_erase(struct rb_node *, struct rb_root *);
 
-typedef void (*rb_augment_f)(struct rb_node *node, void *data);
-
-extern void rb_augment_insert(struct rb_node *node,
-			      rb_augment_f func, void *data);
-extern struct rb_node *rb_augment_erase_begin(struct rb_node *node);
-extern void rb_augment_erase_end(struct rb_node *node,
-				 rb_augment_f func, void *data);
 
 /* Find logical next and previous nodes in a tree */
 extern struct rb_node *rb_next(const struct rb_node *);
@@ -168,7 +75,7 @@
 static inline void rb_link_node(struct rb_node * node, struct rb_node * parent,
 				struct rb_node ** rb_link)
 {
-	node->rb_parent_color = (unsigned long )parent;
+	node->__rb_parent_color = (unsigned long)parent;
 	node->rb_left = node->rb_right = NULL;
 
 	*rb_link = node;
diff --git a/include/linux/rbtree_augmented.h b/include/linux/rbtree_augmented.h
new file mode 100644
index 0000000..214caa3
--- /dev/null
+++ b/include/linux/rbtree_augmented.h
@@ -0,0 +1,223 @@
+/*
+  Red Black Trees
+  (C) 1999  Andrea Arcangeli <andrea@suse.de>
+  (C) 2002  David Woodhouse <dwmw2@infradead.org>
+  (C) 2012  Michel Lespinasse <walken@google.com>
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+  linux/include/linux/rbtree_augmented.h
+*/
+
+#ifndef _LINUX_RBTREE_AUGMENTED_H
+#define _LINUX_RBTREE_AUGMENTED_H
+
+#include <linux/rbtree.h>
+
+/*
+ * Please note - only struct rb_augment_callbacks and the prototypes for
+ * rb_insert_augmented() and rb_erase_augmented() are intended to be public.
+ * The rest are implementation details you are not expected to depend on.
+ *
+ * See Documentation/rbtree.txt for documentation and samples.
+ */
+
+struct rb_augment_callbacks {
+	void (*propagate)(struct rb_node *node, struct rb_node *stop);
+	void (*copy)(struct rb_node *old, struct rb_node *new);
+	void (*rotate)(struct rb_node *old, struct rb_node *new);
+};
+
+extern void __rb_insert_augmented(struct rb_node *node, struct rb_root *root,
+	void (*augment_rotate)(struct rb_node *old, struct rb_node *new));
+static inline void
+rb_insert_augmented(struct rb_node *node, struct rb_root *root,
+		    const struct rb_augment_callbacks *augment)
+{
+	__rb_insert_augmented(node, root, augment->rotate);
+}
+
+#define RB_DECLARE_CALLBACKS(rbstatic, rbname, rbstruct, rbfield,	\
+			     rbtype, rbaugmented, rbcompute)		\
+static inline void							\
+rbname ## _propagate(struct rb_node *rb, struct rb_node *stop)		\
+{									\
+	while (rb != stop) {						\
+		rbstruct *node = rb_entry(rb, rbstruct, rbfield);	\
+		rbtype augmented = rbcompute(node);			\
+		if (node->rbaugmented == augmented)			\
+			break;						\
+		node->rbaugmented = augmented;				\
+		rb = rb_parent(&node->rbfield);				\
+	}								\
+}									\
+static inline void							\
+rbname ## _copy(struct rb_node *rb_old, struct rb_node *rb_new)		\
+{									\
+	rbstruct *old = rb_entry(rb_old, rbstruct, rbfield);		\
+	rbstruct *new = rb_entry(rb_new, rbstruct, rbfield);		\
+	new->rbaugmented = old->rbaugmented;				\
+}									\
+static void								\
+rbname ## _rotate(struct rb_node *rb_old, struct rb_node *rb_new)	\
+{									\
+	rbstruct *old = rb_entry(rb_old, rbstruct, rbfield);		\
+	rbstruct *new = rb_entry(rb_new, rbstruct, rbfield);		\
+	new->rbaugmented = old->rbaugmented;				\
+	old->rbaugmented = rbcompute(old);				\
+}									\
+rbstatic const struct rb_augment_callbacks rbname = {			\
+	rbname ## _propagate, rbname ## _copy, rbname ## _rotate	\
+};
+
+
+#define	RB_RED		0
+#define	RB_BLACK	1
+
+#define __rb_parent(pc)    ((struct rb_node *)(pc & ~3))
+
+#define __rb_color(pc)     ((pc) & 1)
+#define __rb_is_black(pc)  __rb_color(pc)
+#define __rb_is_red(pc)    (!__rb_color(pc))
+#define rb_color(rb)       __rb_color((rb)->__rb_parent_color)
+#define rb_is_red(rb)      __rb_is_red((rb)->__rb_parent_color)
+#define rb_is_black(rb)    __rb_is_black((rb)->__rb_parent_color)
+
+static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
+{
+	rb->__rb_parent_color = rb_color(rb) | (unsigned long)p;
+}
+
+static inline void rb_set_parent_color(struct rb_node *rb,
+				       struct rb_node *p, int color)
+{
+	rb->__rb_parent_color = (unsigned long)p | color;
+}
+
+static inline void
+__rb_change_child(struct rb_node *old, struct rb_node *new,
+		  struct rb_node *parent, struct rb_root *root)
+{
+	if (parent) {
+		if (parent->rb_left == old)
+			parent->rb_left = new;
+		else
+			parent->rb_right = new;
+	} else
+		root->rb_node = new;
+}
+
+extern void __rb_erase_color(struct rb_node *parent, struct rb_root *root,
+	void (*augment_rotate)(struct rb_node *old, struct rb_node *new));
+
+static __always_inline void
+rb_erase_augmented(struct rb_node *node, struct rb_root *root,
+		   const struct rb_augment_callbacks *augment)
+{
+	struct rb_node *child = node->rb_right, *tmp = node->rb_left;
+	struct rb_node *parent, *rebalance;
+	unsigned long pc;
+
+	if (!tmp) {
+		/*
+		 * Case 1: node to erase has no more than 1 child (easy!)
+		 *
+		 * Note that if there is one child it must be red due to 5)
+		 * and node must be black due to 4). We adjust colors locally
+		 * so as to bypass __rb_erase_color() later on.
+		 */
+		pc = node->__rb_parent_color;
+		parent = __rb_parent(pc);
+		__rb_change_child(node, child, parent, root);
+		if (child) {
+			child->__rb_parent_color = pc;
+			rebalance = NULL;
+		} else
+			rebalance = __rb_is_black(pc) ? parent : NULL;
+		tmp = parent;
+	} else if (!child) {
+		/* Still case 1, but this time the child is node->rb_left */
+		tmp->__rb_parent_color = pc = node->__rb_parent_color;
+		parent = __rb_parent(pc);
+		__rb_change_child(node, tmp, parent, root);
+		rebalance = NULL;
+		tmp = parent;
+	} else {
+		struct rb_node *successor = child, *child2;
+		tmp = child->rb_left;
+		if (!tmp) {
+			/*
+			 * Case 2: node's successor is its right child
+			 *
+			 *    (n)          (s)
+			 *    / \          / \
+			 *  (x) (s)  ->  (x) (c)
+			 *        \
+			 *        (c)
+			 */
+			parent = successor;
+			child2 = successor->rb_right;
+			augment->copy(node, successor);
+		} else {
+			/*
+			 * Case 3: node's successor is leftmost under
+			 * node's right child subtree
+			 *
+			 *    (n)          (s)
+			 *    / \          / \
+			 *  (x) (y)  ->  (x) (y)
+			 *      /            /
+			 *    (p)          (p)
+			 *    /            /
+			 *  (s)          (c)
+			 *    \
+			 *    (c)
+			 */
+			do {
+				parent = successor;
+				successor = tmp;
+				tmp = tmp->rb_left;
+			} while (tmp);
+			parent->rb_left = child2 = successor->rb_right;
+			successor->rb_right = child;
+			rb_set_parent(child, successor);
+			augment->copy(node, successor);
+			augment->propagate(parent, successor);
+		}
+
+		successor->rb_left = tmp = node->rb_left;
+		rb_set_parent(tmp, successor);
+
+		pc = node->__rb_parent_color;
+		tmp = __rb_parent(pc);
+		__rb_change_child(node, successor, tmp, root);
+		if (child2) {
+			successor->__rb_parent_color = pc;
+			rb_set_parent_color(child2, parent, RB_BLACK);
+			rebalance = NULL;
+		} else {
+			unsigned long pc2 = successor->__rb_parent_color;
+			successor->__rb_parent_color = pc;
+			rebalance = __rb_is_black(pc2) ? parent : NULL;
+		}
+		tmp = successor;
+	}
+
+	augment->propagate(tmp, NULL);
+	if (rebalance)
+		__rb_erase_color(rebalance, root, augment->rotate);
+}
+
+#endif	/* _LINUX_RBTREE_AUGMENTED_H */
diff --git a/include/linux/rio.h b/include/linux/rio.h
index d2dff22..4187da5 100644
--- a/include/linux/rio.h
+++ b/include/linux/rio.h
@@ -63,7 +63,7 @@
  *
  *	0	RapidIO inbound doorbells
  *	1	RapidIO inbound mailboxes
- *	1	RapidIO outbound mailboxes
+ *	2	RapidIO outbound mailboxes
  */
 #define RIO_DOORBELL_RESOURCE	0
 #define RIO_INB_MBOX_RESOURCE	1
@@ -266,7 +266,6 @@
 
 struct rio_id_table {
 	u16 start;	/* logical minimal id */
-	u16 next;	/* hint for find */
 	u32 max;	/* max number of IDs in table */
 	spinlock_t lock;
 	unsigned long *table;
diff --git a/include/linux/rmap.h b/include/linux/rmap.h
index 3fce545..bfe1f47 100644
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -37,14 +37,14 @@
 	atomic_t refcount;
 
 	/*
-	 * NOTE: the LSB of the head.next is set by
+	 * NOTE: the LSB of the rb_root.rb_node is set by
 	 * mm_take_all_locks() _after_ taking the above lock. So the
-	 * head must only be read/written after taking the above lock
+	 * rb_root must only be read/written after taking the above lock
 	 * to be sure to see a valid next pointer. The LSB bit itself
 	 * is serialized by a system wide lock only visible to
 	 * mm_take_all_locks() (mm_all_locks_mutex).
 	 */
-	struct list_head head;	/* Chain of private "related" vmas */
+	struct rb_root rb_root;	/* Interval tree of private "related" vmas */
 };
 
 /*
@@ -57,14 +57,29 @@
  * with a VMA, or the VMAs associated with an anon_vma.
  * The "same_vma" list contains the anon_vma_chains linking
  * all the anon_vmas associated with this VMA.
- * The "same_anon_vma" list contains the anon_vma_chains
+ * The "rb" field indexes on an interval tree the anon_vma_chains
  * which link all the VMAs associated with this anon_vma.
  */
 struct anon_vma_chain {
 	struct vm_area_struct *vma;
 	struct anon_vma *anon_vma;
 	struct list_head same_vma;   /* locked by mmap_sem & page_table_lock */
-	struct list_head same_anon_vma;	/* locked by anon_vma->mutex */
+	struct rb_node rb;			/* locked by anon_vma->mutex */
+	unsigned long rb_subtree_last;
+#ifdef CONFIG_DEBUG_VM_RB
+	unsigned long cached_vma_start, cached_vma_last;
+#endif
+};
+
+enum ttu_flags {
+	TTU_UNMAP = 0,			/* unmap mode */
+	TTU_MIGRATION = 1,		/* migration mode */
+	TTU_MUNLOCK = 2,		/* munlock mode */
+	TTU_ACTION_MASK = 0xff,
+
+	TTU_IGNORE_MLOCK = (1 << 8),	/* ignore mlock */
+	TTU_IGNORE_ACCESS = (1 << 9),	/* don't age */
+	TTU_IGNORE_HWPOISON = (1 << 10),/* corrupted page is recoverable */
 };
 
 #ifdef CONFIG_MMU
@@ -120,7 +135,6 @@
 int  anon_vma_prepare(struct vm_area_struct *);
 void unlink_anon_vmas(struct vm_area_struct *);
 int anon_vma_clone(struct vm_area_struct *, struct vm_area_struct *);
-void anon_vma_moveto_tail(struct vm_area_struct *);
 int anon_vma_fork(struct vm_area_struct *, struct vm_area_struct *);
 
 static inline void anon_vma_merge(struct vm_area_struct *vma,
@@ -161,16 +175,6 @@
 int page_referenced_one(struct page *, struct vm_area_struct *,
 	unsigned long address, unsigned int *mapcount, unsigned long *vm_flags);
 
-enum ttu_flags {
-	TTU_UNMAP = 0,			/* unmap mode */
-	TTU_MIGRATION = 1,		/* migration mode */
-	TTU_MUNLOCK = 2,		/* munlock mode */
-	TTU_ACTION_MASK = 0xff,
-
-	TTU_IGNORE_MLOCK = (1 << 8),	/* ignore mlock */
-	TTU_IGNORE_ACCESS = (1 << 9),	/* don't age */
-	TTU_IGNORE_HWPOISON = (1 << 10),/* corrupted page is recoverable */
-};
 #define TTU_ACTION(x) ((x) & TTU_ACTION_MASK)
 
 int try_to_unmap(struct page *, enum ttu_flags flags);
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index 7b600da..4bd6c06 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -201,6 +201,7 @@
 	return page_address(sg_page(sg)) + sg->offset;
 }
 
+int sg_nents(struct scatterlist *sg);
 struct scatterlist *sg_next(struct scatterlist *);
 struct scatterlist *sg_last(struct scatterlist *s, unsigned int);
 void sg_init_table(struct scatterlist *, unsigned int);
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 9c5612f..a83ca58 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -671,7 +671,6 @@
 	struct rw_semaphore group_rwsem;
 #endif
 
-	int oom_adj;		/* OOM kill score adjustment (bit shift) */
 	int oom_score_adj;	/* OOM kill score adjustment */
 	int oom_score_adj_min;	/* OOM kill score adjustment minimum value.
 				 * Only settable by CAP_SYS_RESOURCE. */
@@ -2333,6 +2332,9 @@
 		     const char __user * const __user *, struct pt_regs *);
 extern long do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long, int __user *, int __user *);
 struct task_struct *fork_idle(int);
+#ifdef CONFIG_GENERIC_KERNEL_THREAD
+extern pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+#endif
 
 extern void set_task_comm(struct task_struct *tsk, char *from);
 extern char *get_task_comm(char *to, struct task_struct *tsk);
diff --git a/include/linux/security.h b/include/linux/security.h
index 5b50c4e..05e88bd 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1411,8 +1411,8 @@
 	int (*sb_kern_mount) (struct super_block *sb, int flags, void *data);
 	int (*sb_show_options) (struct seq_file *m, struct super_block *sb);
 	int (*sb_statfs) (struct dentry *dentry);
-	int (*sb_mount) (char *dev_name, struct path *path,
-			 char *type, unsigned long flags, void *data);
+	int (*sb_mount) (const char *dev_name, struct path *path,
+			 const char *type, unsigned long flags, void *data);
 	int (*sb_umount) (struct vfsmount *mnt, int flags);
 	int (*sb_pivotroot) (struct path *old_path,
 			     struct path *new_path);
@@ -1694,8 +1694,8 @@
 int security_sb_kern_mount(struct super_block *sb, int flags, void *data);
 int security_sb_show_options(struct seq_file *m, struct super_block *sb);
 int security_sb_statfs(struct dentry *dentry);
-int security_sb_mount(char *dev_name, struct path *path,
-		      char *type, unsigned long flags, void *data);
+int security_sb_mount(const char *dev_name, struct path *path,
+		      const char *type, unsigned long flags, void *data);
 int security_sb_umount(struct vfsmount *mnt, int flags);
 int security_sb_pivotroot(struct path *old_path, struct path *new_path);
 int security_sb_set_mnt_opts(struct super_block *sb, struct security_mnt_opts *opts);
@@ -1964,8 +1964,8 @@
 	return 0;
 }
 
-static inline int security_sb_mount(char *dev_name, struct path *path,
-				    char *type, unsigned long flags,
+static inline int security_sb_mount(const char *dev_name, struct path *path,
+				    const char *type, unsigned long flags,
 				    void *data)
 {
 	return 0;
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index b33a3a1..6a2c34e 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -589,9 +589,6 @@
 	return __alloc_skb(size, priority, SKB_ALLOC_FCLONE, NUMA_NO_NODE);
 }
 
-extern void skb_recycle(struct sk_buff *skb);
-extern bool skb_recycle_check(struct sk_buff *skb, int skb_size);
-
 extern struct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src);
 extern int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask);
 extern struct sk_buff *skb_clone(struct sk_buff *skb,
@@ -2645,27 +2642,6 @@
 
 bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off);
 
-static inline bool skb_is_recycleable(const struct sk_buff *skb, int skb_size)
-{
-	if (irqs_disabled())
-		return false;
-
-	if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY)
-		return false;
-
-	if (skb_is_nonlinear(skb) || skb->fclone != SKB_FCLONE_UNAVAILABLE)
-		return false;
-
-	skb_size = SKB_DATA_ALIGN(skb_size + NET_SKB_PAD);
-	if (skb_end_offset(skb) < skb_size)
-		return false;
-
-	if (skb_shared(skb) || skb_cloned(skb))
-		return false;
-
-	return true;
-}
-
 /**
  * skb_head_is_locked - Determine if the skb->head is locked down
  * @skb: skb to check
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index 523547e..34206b8 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -130,6 +130,8 @@
 				const struct rpc_program *, u32);
 void rpc_task_reset_client(struct rpc_task *task, struct rpc_clnt *clnt);
 struct rpc_clnt *rpc_clone_client(struct rpc_clnt *);
+struct rpc_clnt *rpc_clone_client_set_auth(struct rpc_clnt *,
+				rpc_authflavor_t);
 void		rpc_shutdown_client(struct rpc_clnt *);
 void		rpc_release_client(struct rpc_clnt *);
 void		rpc_task_release_client(struct rpc_task *);
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index bf8c49f..951cb9b 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -173,8 +173,7 @@
 	unsigned int		min_reqs;	/* min number of slots */
 	atomic_t		num_reqs;	/* total slots */
 	unsigned long		state;		/* transport state */
-	unsigned char		shutdown   : 1,	/* being shut down */
-				resvport   : 1; /* use a reserved port */
+	unsigned char		resvport   : 1; /* use a reserved port */
 	unsigned int		swapper;	/* we're swapping over this
 						   transport */
 	unsigned int		bind_index;	/* bind function index */
diff --git a/include/linux/swap.h b/include/linux/swap.h
index 388e706..68df9c1 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -281,7 +281,7 @@
 }
 #endif
 
-extern int page_evictable(struct page *page, struct vm_area_struct *vma);
+extern int page_evictable(struct page *page);
 extern void check_move_unevictable_pages(struct page **, int nr_pages);
 
 extern unsigned long scan_unevictable_pages;
diff --git a/include/linux/tc_act/Kbuild b/include/linux/tc_act/Kbuild
index 67b501c3..e69de29 100644
--- a/include/linux/tc_act/Kbuild
+++ b/include/linux/tc_act/Kbuild
@@ -1,7 +0,0 @@
-header-y += tc_gact.h
-header-y += tc_ipt.h
-header-y += tc_mirred.h
-header-y += tc_pedit.h
-header-y += tc_nat.h
-header-y += tc_skbedit.h
-header-y += tc_csum.h
diff --git a/include/linux/tc_ematch/Kbuild b/include/linux/tc_ematch/Kbuild
index 4a58a1c..e69de29 100644
--- a/include/linux/tc_ematch/Kbuild
+++ b/include/linux/tc_ematch/Kbuild
@@ -1,4 +0,0 @@
-header-y += tc_em_cmp.h
-header-y += tc_em_meta.h
-header-y += tc_em_nbyte.h
-header-y += tc_em_text.h
diff --git a/include/linux/timerqueue.h b/include/linux/timerqueue.h
index 5088727..a520fd7 100644
--- a/include/linux/timerqueue.h
+++ b/include/linux/timerqueue.h
@@ -39,7 +39,7 @@
 
 static inline void timerqueue_init(struct timerqueue_node *node)
 {
-	rb_init_node(&node->node);
+	RB_CLEAR_NODE(&node->node);
 }
 
 static inline void timerqueue_init_head(struct timerqueue_head *head)
diff --git a/include/linux/vm_event_item.h b/include/linux/vm_event_item.h
index 57f7b10..3d31145 100644
--- a/include/linux/vm_event_item.h
+++ b/include/linux/vm_event_item.h
@@ -52,7 +52,6 @@
 		UNEVICTABLE_PGMUNLOCKED,
 		UNEVICTABLE_PGCLEARED,	/* on COW, page truncate */
 		UNEVICTABLE_PGSTRANDED,	/* unable to isolate on unlock */
-		UNEVICTABLE_MLOCKFREED,
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 		THP_FAULT_ALLOC,
 		THP_FAULT_FALLBACK,
diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h
index ad2cfd5..92a86b2 100644
--- a/include/linux/vmstat.h
+++ b/include/linux/vmstat.h
@@ -198,6 +198,8 @@
 void refresh_cpu_vm_stats(int);
 void refresh_zone_stat_thresholds(void);
 
+void drain_zonestat(struct zone *zone, struct per_cpu_pageset *);
+
 int calculate_pressure_threshold(struct zone *zone);
 int calculate_normal_threshold(struct zone *zone);
 void set_pgdat_percpu_threshold(pg_data_t *pgdat,
@@ -251,8 +253,18 @@
 static inline void refresh_cpu_vm_stats(int cpu) { }
 static inline void refresh_zone_stat_thresholds(void) { }
 
+static inline void drain_zonestat(struct zone *zone,
+			struct per_cpu_pageset *pset) { }
 #endif		/* CONFIG_SMP */
 
+static inline void __mod_zone_freepage_state(struct zone *zone, int nr_pages,
+					     int migratetype)
+{
+	__mod_zone_page_state(zone, NR_FREE_PAGES, nr_pages);
+	if (is_migrate_cma(migratetype))
+		__mod_zone_page_state(zone, NR_FREE_CMA_PAGES, nr_pages);
+}
+
 extern const char * const vmstat_text[];
 
 #endif /* _LINUX_VMSTAT_H */
diff --git a/include/mtd/Kbuild b/include/mtd/Kbuild
index 192f8fb..e69de29 100644
--- a/include/mtd/Kbuild
+++ b/include/mtd/Kbuild
@@ -1,5 +0,0 @@
-header-y += inftl-user.h
-header-y += mtd-abi.h
-header-y += mtd-user.h
-header-y += nftl-user.h
-header-y += ubi-user.h
diff --git a/include/net/flow.h b/include/net/flow.h
index e1dd508..628e11b 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -21,6 +21,7 @@
 	__u8	flowic_flags;
 #define FLOWI_FLAG_ANYSRC		0x01
 #define FLOWI_FLAG_CAN_SLEEP		0x02
+#define FLOWI_FLAG_KNOWN_NH		0x04
 	__u32	flowic_secid;
 };
 
diff --git a/include/net/route.h b/include/net/route.h
index da22243..bc40b63 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -48,7 +48,8 @@
 	int			rt_genid;
 	unsigned int		rt_flags;
 	__u16			rt_type;
-	__u16			rt_is_input;
+	__u8			rt_is_input;
+	__u8			rt_uses_gateway;
 
 	int			rt_iif;
 
diff --git a/include/rdma/rdma_netlink.h b/include/rdma/rdma_netlink.h
index 3c5363a..bd3d8b2 100644
--- a/include/rdma/rdma_netlink.h
+++ b/include/rdma/rdma_netlink.h
@@ -39,6 +39,7 @@
 
 struct ibnl_client_cbs {
 	int (*dump)(struct sk_buff *skb, struct netlink_callback *nlcb);
+	struct module *module;
 };
 
 int ibnl_init(void);
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
index fdeb8dc..d315a08 100644
--- a/include/sound/ac97_codec.h
+++ b/include/sound/ac97_codec.h
@@ -422,6 +422,7 @@
  */
 
 struct snd_ac97;
+struct snd_pcm_chmap;
 
 struct snd_ac97_build_ops {
 	int (*build_3d) (struct snd_ac97 *ac97);
@@ -528,6 +529,8 @@
 	struct delayed_work power_work;
 #endif
 	struct device dev;
+
+	struct snd_pcm_chmap *chmaps[2]; /* channel-maps (optional) */
 };
 
 #define to_ac97_t(d) container_of(d, struct snd_ac97, dev)
diff --git a/include/sound/ad1816a.h b/include/sound/ad1816a.h
index a7d8dc7..abdf609 100644
--- a/include/sound/ad1816a.h
+++ b/include/sound/ad1816a.h
@@ -147,6 +147,9 @@
 	unsigned int c_dma_size;
 
 	struct snd_timer *timer;
+#ifdef CONFIG_PM
+	unsigned short image[48];
+#endif
 };
 
 
@@ -165,11 +168,15 @@
 
 extern int snd_ad1816a_create(struct snd_card *card, unsigned long port,
 			      int irq, int dma1, int dma2,
-			      struct snd_ad1816a **chip);
+			      struct snd_ad1816a *chip);
 
 extern int snd_ad1816a_pcm(struct snd_ad1816a *chip, int device, struct snd_pcm **rpcm);
 extern int snd_ad1816a_mixer(struct snd_ad1816a *chip);
 extern int snd_ad1816a_timer(struct snd_ad1816a *chip, int device,
 			     struct snd_timer **rtimer);
+#ifdef CONFIG_PM
+extern void snd_ad1816a_suspend(struct snd_ad1816a *chip);
+extern void snd_ad1816a_resume(struct snd_ad1816a *chip);
+#endif
 
 #endif	/* __SOUND_AD1816A_H */
diff --git a/include/sound/asound.h b/include/sound/asound.h
index 0876a1e..dfe7d44 100644
--- a/include/sound/asound.h
+++ b/include/sound/asound.h
@@ -472,6 +472,45 @@
 	SNDRV_PCM_TSTAMP_TYPE_LAST = SNDRV_PCM_TSTAMP_TYPE_MONOTONIC,
 };
 
+/* channel positions */
+enum {
+	SNDRV_CHMAP_UNKNOWN = 0,
+	SNDRV_CHMAP_NA,		/* N/A, silent */
+	SNDRV_CHMAP_MONO,	/* mono stream */
+	/* this follows the alsa-lib mixer channel value + 3 */
+	SNDRV_CHMAP_FL,		/* front left */
+	SNDRV_CHMAP_FR,		/* front right */
+	SNDRV_CHMAP_RL,		/* rear left */
+	SNDRV_CHMAP_RR,		/* rear right */
+	SNDRV_CHMAP_FC,		/* front center */
+	SNDRV_CHMAP_LFE,	/* LFE */
+	SNDRV_CHMAP_SL,		/* side left */
+	SNDRV_CHMAP_SR,		/* side right */
+	SNDRV_CHMAP_RC,		/* rear center */
+	/* new definitions */
+	SNDRV_CHMAP_FLC,	/* front left center */
+	SNDRV_CHMAP_FRC,	/* front right center */
+	SNDRV_CHMAP_RLC,	/* rear left center */
+	SNDRV_CHMAP_RRC,	/* rear right center */
+	SNDRV_CHMAP_FLW,	/* front left wide */
+	SNDRV_CHMAP_FRW,	/* front right wide */
+	SNDRV_CHMAP_FLH,	/* front left high */
+	SNDRV_CHMAP_FCH,	/* front center high */
+	SNDRV_CHMAP_FRH,	/* front right high */
+	SNDRV_CHMAP_TC,		/* top center */
+	SNDRV_CHMAP_TFL,	/* top front left */
+	SNDRV_CHMAP_TFR,	/* top front right */
+	SNDRV_CHMAP_TFC,	/* top front center */
+	SNDRV_CHMAP_TRL,	/* top rear left */
+	SNDRV_CHMAP_TRR,	/* top rear right */
+	SNDRV_CHMAP_TRC,	/* top rear center */
+	SNDRV_CHMAP_LAST = SNDRV_CHMAP_TRC,
+};
+
+#define SNDRV_CHMAP_POSITION_MASK	0xffff
+#define SNDRV_CHMAP_PHASE_INVERSE	(0x01 << 16)
+#define SNDRV_CHMAP_DRIVER_SPEC		(0x02 << 16)
+
 #define SNDRV_PCM_IOCTL_PVERSION	_IOR('A', 0x00, int)
 #define SNDRV_PCM_IOCTL_INFO		_IOR('A', 0x01, struct snd_pcm_info)
 #define SNDRV_PCM_IOCTL_TSTAMP		_IOW('A', 0x02, int)
diff --git a/include/sound/compress_driver.h b/include/sound/compress_driver.h
index 48f2a1f..f2912ab 100644
--- a/include/sound/compress_driver.h
+++ b/include/sound/compress_driver.h
@@ -61,6 +61,7 @@
 	u64 total_bytes_available;
 	u64 total_bytes_transferred;
 	wait_queue_head_t sleep;
+	void *private_data;
 };
 
 /**
diff --git a/include/sound/compress_params.h b/include/sound/compress_params.h
index da4a456..602dc6c 100644
--- a/include/sound/compress_params.h
+++ b/include/sound/compress_params.h
@@ -72,6 +72,7 @@
 #define SND_AUDIOCODEC_IEC61937              ((__u32) 0x0000000B)
 #define SND_AUDIOCODEC_G723_1                ((__u32) 0x0000000C)
 #define SND_AUDIOCODEC_G729                  ((__u32) 0x0000000D)
+#define SND_AUDIOCODEC_MAX                   SND_AUDIOCODEC_G729
 
 /*
  * Profile and modes are listed with bit masks. This allows for a
diff --git a/include/sound/da9055.h b/include/sound/da9055.h
new file mode 100644
index 0000000..cf1241b
--- /dev/null
+++ b/include/sound/da9055.h
@@ -0,0 +1,33 @@
+/*
+ * DA9055 ALSA Soc codec driver
+ *
+ * Copyright (c) 2012 Dialog Semiconductor
+ *
+ * Tested on (Samsung SMDK6410 board + DA9055 EVB) using I2S and I2C
+ * Written by David Chen <david.chen@diasemi.com> and
+ * Ashish Chavan <ashish.chavan@kpitcummins.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __SOUND_DA9055_H__
+#define __SOUND_DA9055_H__
+
+enum da9055_micbias_voltage {
+	DA9055_MICBIAS_1_6V = 0,
+	DA9055_MICBIAS_1_8V = 1,
+	DA9055_MICBIAS_2_1V = 2,
+	DA9055_MICBIAS_2_2V = 3,
+};
+
+struct da9055_platform_data {
+	/* Selects which of the two MicBias pins acts as the bias source */
+	bool micbias_source;
+	/* Selects the micbias voltage */
+	enum da9055_micbias_voltage micbias;
+};
+
+#endif
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index 4f865df..1a33f48 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -1788,7 +1788,7 @@
 	unsigned int efx_voices_mask[2];
 	unsigned int next_free_voice;
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	unsigned int *saved_ptr;
 	unsigned int *saved_gpr;
 	unsigned int *tram_val_saved;
@@ -1856,7 +1856,7 @@
 void snd_emu10k1_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short data);
 unsigned int snd_emu10k1_rate_to_pitch(unsigned int rate);
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 void snd_emu10k1_suspend_regs(struct snd_emu10k1 *emu);
 void snd_emu10k1_resume_init(struct snd_emu10k1 *emu);
 void snd_emu10k1_resume_regs(struct snd_emu10k1 *emu);
diff --git a/include/sound/initval.h b/include/sound/initval.h
index f99a0d2..ac62c67 100644
--- a/include/sound/initval.h
+++ b/include/sound/initval.h
@@ -50,6 +50,20 @@
 #define SNDRV_DEFAULT_DMA_SIZE	{ [0 ... (SNDRV_CARDS-1)] = SNDRV_AUTO_DMA_SIZE }
 #define SNDRV_DEFAULT_PTR	SNDRV_DEFAULT_STR
 
+#ifdef SNDRV_LEGACY_FIND_FREE_IOPORT
+static long snd_legacy_find_free_ioport(long *port_table, long size)
+{
+	while (*port_table != -1) {
+		if (request_region(*port_table, size, "ALSA test")) {
+			release_region(*port_table, size);
+			return *port_table;
+		}
+		port_table++;
+	}
+	return -1;
+}
+#endif
+
 #ifdef SNDRV_LEGACY_FIND_FREE_IRQ
 #include <linux/interrupt.h>
 
diff --git a/include/sound/memalloc.h b/include/sound/memalloc.h
index c425062..844af65 100644
--- a/include/sound/memalloc.h
+++ b/include/sound/memalloc.h
@@ -98,8 +98,10 @@
 /*
  * return the physical address at the corresponding offset
  */
-static inline dma_addr_t snd_sgbuf_get_addr(struct snd_sg_buf *sgbuf, size_t offset)
+static inline dma_addr_t snd_sgbuf_get_addr(struct snd_dma_buffer *dmab,
+					   size_t offset)
 {
+	struct snd_sg_buf *sgbuf = dmab->private_data;
 	dma_addr_t addr = sgbuf->table[offset >> PAGE_SHIFT].addr;
 	addr &= PAGE_MASK;
 	return addr + offset % PAGE_SIZE;
@@ -108,10 +110,31 @@
 /*
  * return the virtual address at the corresponding offset
  */
-static inline void *snd_sgbuf_get_ptr(struct snd_sg_buf *sgbuf, size_t offset)
+static inline void *snd_sgbuf_get_ptr(struct snd_dma_buffer *dmab,
+				     size_t offset)
 {
+	struct snd_sg_buf *sgbuf = dmab->private_data;
 	return sgbuf->table[offset >> PAGE_SHIFT].buf + offset % PAGE_SIZE;
 }
+
+unsigned int snd_sgbuf_get_chunk_size(struct snd_dma_buffer *dmab,
+				      unsigned int ofs, unsigned int size);
+#else
+/* non-SG versions */
+static inline dma_addr_t snd_sgbuf_get_addr(struct snd_dma_buffer *dmab,
+					    size_t offset)
+{
+	return dmab->addr + offset;
+}
+
+static inline void *snd_sgbuf_get_ptr(struct snd_dma_buffer *dmab,
+				      size_t offset)
+{
+	return dmab->area + offset;
+}
+
+#define snd_sgbuf_get_chunk_size(dmab, ofs, size)	(size)
+
 #endif /* CONFIG_SND_DMA_SGBUF */
 
 /* allocate/release a buffer */
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index d0711bc..6268a41 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -437,6 +437,7 @@
 	struct snd_info_entry *proc_xrun_debug_entry;
 #endif
 #endif
+	struct snd_kcontrol *chmap_kctl; /* channel-mapping controls */
 };
 
 struct snd_pcm {
@@ -982,53 +983,42 @@
 	_snd_pcm_lib_alloc_vmalloc_buffer \
 			(subs, size, GFP_KERNEL | GFP_DMA32 | __GFP_ZERO)
 
+#define snd_pcm_get_dma_buf(substream) ((substream)->runtime->dma_buffer_p)
+
 #ifdef CONFIG_SND_DMA_SGBUF
 /*
  * SG-buffer handling
  */
 #define snd_pcm_substream_sgbuf(substream) \
-	((substream)->runtime->dma_buffer_p->private_data)
-
-static inline dma_addr_t
-snd_pcm_sgbuf_get_addr(struct snd_pcm_substream *substream, unsigned int ofs)
-{
-	struct snd_sg_buf *sg = snd_pcm_substream_sgbuf(substream);
-	return snd_sgbuf_get_addr(sg, ofs);
-}
-
-static inline void *
-snd_pcm_sgbuf_get_ptr(struct snd_pcm_substream *substream, unsigned int ofs)
-{
-	struct snd_sg_buf *sg = snd_pcm_substream_sgbuf(substream);
-	return snd_sgbuf_get_ptr(sg, ofs);
-}
+	snd_pcm_get_dma_buf(substream)->private_data
 
 struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream,
 				    unsigned long offset);
-unsigned int snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream,
-					  unsigned int ofs, unsigned int size);
-
 #else /* !SND_DMA_SGBUF */
 /*
  * fake using a continuous buffer
  */
+#define snd_pcm_sgbuf_ops_page	NULL
+#endif /* SND_DMA_SGBUF */
+
 static inline dma_addr_t
 snd_pcm_sgbuf_get_addr(struct snd_pcm_substream *substream, unsigned int ofs)
 {
-	return substream->runtime->dma_addr + ofs;
+	return snd_sgbuf_get_addr(snd_pcm_get_dma_buf(substream), ofs);
 }
 
 static inline void *
 snd_pcm_sgbuf_get_ptr(struct snd_pcm_substream *substream, unsigned int ofs)
 {
-	return substream->runtime->dma_area + ofs;
+	return snd_sgbuf_get_ptr(snd_pcm_get_dma_buf(substream), ofs);
 }
 
-#define snd_pcm_sgbuf_ops_page	NULL
-
-#define snd_pcm_sgbuf_get_chunk_size(subs, ofs, size)	(size)
-
-#endif /* SND_DMA_SGBUF */
+static inline unsigned int
+snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream,
+			     unsigned int ofs, unsigned int size)
+{
+	return snd_sgbuf_get_chunk_size(snd_pcm_get_dma_buf(substream), ofs, size);
+}
 
 /* handle mmap counter - PCM mmap callback should handle this counter properly */
 static inline void snd_pcm_mmap_data_open(struct vm_area_struct *area)
@@ -1086,4 +1076,51 @@
 		return "Capture";
 }
 
+/*
+ * PCM channel-mapping control API
+ */
+/* array element of channel maps */
+struct snd_pcm_chmap_elem {
+	unsigned char channels;
+	unsigned char map[15];
+};
+
+/* channel map information; retrieved via snd_kcontrol_chip() */
+struct snd_pcm_chmap {
+	struct snd_pcm *pcm;	/* assigned PCM instance */
+	int stream;		/* PLAYBACK or CAPTURE */
+	struct snd_kcontrol *kctl;
+	const struct snd_pcm_chmap_elem *chmap;
+	unsigned int max_channels;
+	unsigned int channel_mask;	/* optional: active channels bitmask */
+	void *private_data;	/* optional: private data pointer */
+};
+
+/* get the PCM substream assigned to the given chmap info */
+static inline struct snd_pcm_substream *
+snd_pcm_chmap_substream(struct snd_pcm_chmap *info, unsigned int idx)
+{
+	struct snd_pcm_substream *s;
+	for (s = info->pcm->streams[info->stream].substream; s; s = s->next)
+		if (s->number == idx)
+			return s;
+	return NULL;
+}
+
+/* ALSA-standard channel maps (RL/RR prior to C/LFE) */
+extern const struct snd_pcm_chmap_elem snd_pcm_std_chmaps[];
+/* Other world's standard channel maps (C/LFE prior to RL/RR) */
+extern const struct snd_pcm_chmap_elem snd_pcm_alt_chmaps[];
+
+/* bit masks to be passed to snd_pcm_chmap.channel_mask field */
+#define SND_PCM_CHMAP_MASK_24	((1U << 2) | (1U << 4))
+#define SND_PCM_CHMAP_MASK_246	(SND_PCM_CHMAP_MASK_24 | (1U << 6))
+#define SND_PCM_CHMAP_MASK_2468	(SND_PCM_CHMAP_MASK_246 | (1U << 8))
+
+int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
+			   const struct snd_pcm_chmap_elem *chmap,
+			   int max_channels,
+			   unsigned long private_value,
+			   struct snd_pcm_chmap **info_ret);
+
 #endif /* __SOUND_PCM_H */
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 1f69e0a..628db7b 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -18,6 +18,7 @@
 
 struct snd_pcm_substream;
 struct snd_soc_dapm_widget;
+struct snd_compr_stream;
 
 /*
  * DAI hardware audio formats.
@@ -205,6 +206,8 @@
 	int (*remove)(struct snd_soc_dai *dai);
 	int (*suspend)(struct snd_soc_dai *dai);
 	int (*resume)(struct snd_soc_dai *dai);
+	/* compress dai */
+	bool compress_dai;
 
 	/* ops */
 	const struct snd_soc_dai_ops *ops;
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index abe373d..e1ef63d 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -244,10 +244,11 @@
 {	.id = snd_soc_dapm_supply, .name = wname, .reg = wreg,	\
 	.shift = wshift, .invert = winvert, .event = wevent, \
 	.event_flags = wflags}
-#define SND_SOC_DAPM_REGULATOR_SUPPLY(wname, wdelay) \
+#define SND_SOC_DAPM_REGULATOR_SUPPLY(wname, wdelay, wflags)	    \
 {	.id = snd_soc_dapm_regulator_supply, .name = wname, \
 	.reg = SND_SOC_NOPM, .shift = wdelay, .event = dapm_regulator_event, \
-	.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }
+	.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \
+	.invert = wflags}
 
 
 /* dapm kcontrol types */
@@ -319,6 +320,9 @@
 #define SND_SOC_DAPM_EVENT_OFF(e)	\
 	(e & (SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD))
 
+/* regulator widget flags */
+#define SND_SOC_DAPM_REGULATOR_BYPASS     0x1     /* bypass when disabled */
+
 struct snd_soc_dapm_widget;
 enum snd_soc_dapm_type;
 struct snd_soc_dapm_path;
@@ -412,6 +416,7 @@
 
 /* Mostly internal - should not normally be used */
 void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason);
+void dapm_mark_io_dirty(struct snd_soc_dapm_context *dapm);
 
 /* dapm path query */
 int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream,
@@ -510,7 +515,6 @@
 	/* dapm control */
 	int reg;				/* negative reg = no direct dapm */
 	unsigned char shift;			/* bits to shift */
-	unsigned int saved_value;		/* widget saved value */
 	unsigned int value;				/* widget current value */
 	unsigned int mask;			/* non-shifted mask */
 	unsigned int on_val;			/* on state value */
diff --git a/include/sound/soc.h b/include/sound/soc.h
index e063380..91244a0 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -20,8 +20,10 @@
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/regmap.h>
+#include <linux/log2.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
+#include <sound/compress_driver.h>
 #include <sound/control.h>
 #include <sound/ac97_codec.h>
 
@@ -159,7 +161,8 @@
 		 .platform_max = xmax} }
 #define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmax, xtexts) \
 {	.reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \
-	.max = xmax, .texts = xtexts }
+	.max = xmax, .texts = xtexts, \
+	.mask = xmax ? roundup_pow_of_two(xmax) - 1 : 0}
 #define SOC_ENUM_SINGLE(xreg, xshift, xmax, xtexts) \
 	SOC_ENUM_DOUBLE(xreg, xshift, xshift, xmax, xtexts)
 #define SOC_ENUM_SINGLE_EXT(xmax, xtexts) \
@@ -399,6 +402,7 @@
 int snd_soc_platform_write(struct snd_soc_platform *platform,
 					unsigned int reg, unsigned int val);
 int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num);
+int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num);
 
 struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card,
 		const char *dai_link, int stream);
@@ -632,6 +636,13 @@
 	int (*trigger)(struct snd_pcm_substream *, int);
 };
 
+struct snd_soc_compr_ops {
+	int (*startup)(struct snd_compr_stream *);
+	void (*shutdown)(struct snd_compr_stream *);
+	int (*set_params)(struct snd_compr_stream *);
+	int (*trigger)(struct snd_compr_stream *);
+};
+
 /* SoC cache ops */
 struct snd_soc_cache_ops {
 	const char *name;
@@ -787,9 +798,12 @@
 	snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *,
 		struct snd_soc_dai *);
 
-	/* platform stream ops */
+	/* platform stream pcm ops */
 	struct snd_pcm_ops *ops;
 
+	/* platform stream compress ops */
+	struct snd_compr_ops *compr_ops;
+
 	/* platform stream completion event */
 	int (*stream_event)(struct snd_soc_dapm_context *dapm, int event);
 
@@ -891,6 +905,7 @@
 
 	/* machine stream operations */
 	struct snd_soc_ops *ops;
+	struct snd_soc_compr_ops *compr_ops;
 };
 
 struct snd_soc_codec_conf {
@@ -1027,6 +1042,7 @@
 
 	/* runtime devices */
 	struct snd_pcm *pcm;
+	struct snd_compr *compr;
 	struct snd_soc_codec *codec;
 	struct snd_soc_platform *platform;
 	struct snd_soc_dai *codec_dai;
diff --git a/arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h b/include/sound/tegra_wm8903.h
similarity index 88%
rename from arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h
rename to include/sound/tegra_wm8903.h
index 9d29334..57b202e 100644
--- a/arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h
+++ b/include/sound/tegra_wm8903.h
@@ -1,6 +1,4 @@
 /*
- * arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h
- *
  * Copyright 2011 NVIDIA, Inc.
  *
  * This software is licensed under the terms of the GNU General Public
@@ -14,6 +12,9 @@
  *
  */
 
+#ifndef __SOUND_TEGRA_WM38903_H
+#define __SOUND_TEGRA_WM38903_H
+
 struct tegra_wm8903_platform_data {
 	int gpio_spkr_en;
 	int gpio_hp_det;
@@ -21,3 +22,5 @@
 	int gpio_int_mic_en;
 	int gpio_ext_mic_en;
 };
+
+#endif
diff --git a/include/sound/tlv.h b/include/sound/tlv.h
index a64d8fe..28c65e1 100644
--- a/include/sound/tlv.h
+++ b/include/sound/tlv.h
@@ -86,4 +86,12 @@
 
 #define TLV_DB_GAIN_MUTE	-9999999
 
+/*
+ * channel-mapping TLV items
+ *  TLV length must match with num_channels
+ */
+#define SNDRV_CTL_TLVT_CHMAP_FIXED	0x101	/* fixed channel position */
+#define SNDRV_CTL_TLVT_CHMAP_VAR	0x102	/* channels freely swappable */
+#define SNDRV_CTL_TLVT_CHMAP_PAIRED	0x103	/* pair-wise swappable */
+
 #endif /* __SOUND_TLV_H */
diff --git a/include/sound/version.h b/include/sound/version.h
deleted file mode 100644
index cc75024..0000000
--- a/include/sound/version.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* include/version.h */
-#define CONFIG_SND_VERSION "1.0.25"
-#define CONFIG_SND_DATE ""
diff --git a/include/sound/wm0010.h b/include/sound/wm0010.h
new file mode 100644
index 0000000..3261e90
--- /dev/null
+++ b/include/sound/wm0010.h
@@ -0,0 +1,27 @@
+/*
+ * wm0010.h -- Platform data for WM0010 DSP Driver
+ *
+ * Copyright 2012 Wolfson Microelectronics PLC.
+ *
+ * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef WM0010_PDATA_H
+#define WM0010_PDATA_H
+
+struct wm0010_pdata {
+	int gpio_reset;
+
+	/* Set if there is an inverter between the GPIO controlling
+	 * the reset signal and the device.
+	 */
+	int reset_active_high;
+	int irq_flags;
+};
+
+#endif
diff --git a/include/sound/wm8960.h b/include/sound/wm8960.h
index 74e9a95..e8ce8ee 100644
--- a/include/sound/wm8960.h
+++ b/include/sound/wm8960.h
@@ -18,7 +18,7 @@
 struct wm8960_data {
 	bool capless;  /* Headphone outputs configured in capless mode */
 
-	int dres;  /* Discharge resistance for headphone outputs */
+	bool shared_lrclk;  /* DAC and ADC LRCLKs are wired together */
 };
 
 #endif
diff --git a/include/sound/wm8993.h b/include/sound/wm8993.h
index eee19f6..8016fd8 100644
--- a/include/sound/wm8993.h
+++ b/include/sound/wm8993.h
@@ -32,6 +32,10 @@
 	unsigned int lineout1fb:1;
 	unsigned int lineout2fb:1;
 
+	/* Delay to add for microphones to stabalise after power up */
+	int micbias1_delay;
+	int micbias2_delay;
+
 	/* Microphone biases: 0=0.9*AVDD1 1=0.65*AVVD1 */
 	unsigned int micbias1_lvl:1;
 	unsigned int micbias2_lvl:1;
diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h
index 941c84bf..2acd540 100644
--- a/include/target/target_core_backend.h
+++ b/include/target/target_core_backend.h
@@ -13,9 +13,6 @@
 
 	u8 transport_type;
 
-	unsigned int fua_write_emulated : 1;
-	unsigned int write_cache_emulated : 1;
-
 	int (*attach_hba)(struct se_hba *, u32);
 	void (*detach_hba)(struct se_hba *);
 	int (*pmode_enable_hba)(struct se_hba *, unsigned long);
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h
index 69fb3cfd..81ddb4a 100644
--- a/include/target/target_core_fabric.h
+++ b/include/target/target_core_fabric.h
@@ -62,8 +62,6 @@
 	int (*queue_data_in)(struct se_cmd *);
 	int (*queue_status)(struct se_cmd *);
 	int (*queue_tm_rsp)(struct se_cmd *);
-	u16 (*set_fabric_sense_len)(struct se_cmd *, u32);
-	u16 (*get_fabric_sense_len)(void);
 	/*
 	 * fabric module calls for target_core_fabric_configfs.c
 	 */
@@ -102,6 +100,9 @@
 		struct se_session *, u32, int, int, unsigned char *);
 int	transport_lookup_cmd_lun(struct se_cmd *, u32);
 int	target_setup_cmd_from_cdb(struct se_cmd *, unsigned char *);
+int	target_submit_cmd_map_sgls(struct se_cmd *, struct se_session *,
+		unsigned char *, unsigned char *, u32, u32, int, int, int,
+		struct scatterlist *, u32, struct scatterlist *, u32);
 int	target_submit_cmd(struct se_cmd *, struct se_session *, unsigned char *,
 		unsigned char *, u32, u32, int, int, int);
 int	target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess,
diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h
index 91b91e8..54fab04 100644
--- a/include/trace/events/btrfs.h
+++ b/include/trace/events/btrfs.h
@@ -445,6 +445,7 @@
 		__field(	u64,  ref_root		)
 		__field(	int,  level		)
 		__field(	int,  type		)
+		__field(	u64,  seq		)
 	),
 
 	TP_fast_assign(
@@ -455,17 +456,19 @@
 		__entry->ref_root	= full_ref->root;
 		__entry->level		= full_ref->level;
 		__entry->type		= ref->type;
+		__entry->seq		= ref->seq;
 	),
 
 	TP_printk("bytenr = %llu, num_bytes = %llu, action = %s, "
 		  "parent = %llu(%s), ref_root = %llu(%s), level = %d, "
-		  "type = %s",
+		  "type = %s, seq = %llu",
 		  (unsigned long long)__entry->bytenr,
 		  (unsigned long long)__entry->num_bytes,
 		  show_ref_action(__entry->action),
 		  show_root_type(__entry->parent),
 		  show_root_type(__entry->ref_root),
-		  __entry->level, show_ref_type(__entry->type))
+		  __entry->level, show_ref_type(__entry->type),
+		  (unsigned long long)__entry->seq)
 );
 
 TRACE_EVENT(btrfs_delayed_data_ref,
@@ -485,6 +488,7 @@
 		__field(	u64,  owner		)
 		__field(	u64,  offset		)
 		__field(	int,  type		)
+		__field(	u64,  seq		)
 	),
 
 	TP_fast_assign(
@@ -496,11 +500,12 @@
 		__entry->owner		= full_ref->objectid;
 		__entry->offset		= full_ref->offset;
 		__entry->type		= ref->type;
+		__entry->seq		= ref->seq;
 	),
 
 	TP_printk("bytenr = %llu, num_bytes = %llu, action = %s, "
 		  "parent = %llu(%s), ref_root = %llu(%s), owner = %llu, "
-		  "offset = %llu, type = %s",
+		  "offset = %llu, type = %s, seq = %llu",
 		  (unsigned long long)__entry->bytenr,
 		  (unsigned long long)__entry->num_bytes,
 		  show_ref_action(__entry->action),
@@ -508,7 +513,8 @@
 		  show_root_type(__entry->ref_root),
 		  (unsigned long long)__entry->owner,
 		  (unsigned long long)__entry->offset,
-		  show_ref_type(__entry->type))
+		  show_ref_type(__entry->type),
+		  (unsigned long long)__entry->seq)
 );
 
 TRACE_EVENT(btrfs_delayed_ref_head,
diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
index 69d8a69..d49b285 100644
--- a/include/trace/events/ext4.h
+++ b/include/trace/events/ext4.h
@@ -26,19 +26,19 @@
 	TP_STRUCT__entry(
 		__field(	dev_t,	dev			)
 		__field(	ino_t,	ino			)
-		__field(	__u16, mode			)
 		__field(	uid_t,	uid			)
 		__field(	gid_t,	gid			)
 		__field(	__u64, blocks			)
+		__field(	__u16, mode			)
 	),
 
 	TP_fast_assign(
 		__entry->dev	= inode->i_sb->s_dev;
 		__entry->ino	= inode->i_ino;
-		__entry->mode	= inode->i_mode;
 		__entry->uid	= i_uid_read(inode);
 		__entry->gid	= i_gid_read(inode);
 		__entry->blocks	= inode->i_blocks;
+		__entry->mode	= inode->i_mode;
 	),
 
 	TP_printk("dev %d,%d ino %lu mode 0%o uid %u gid %u blocks %llu",
@@ -300,10 +300,10 @@
 		__field(	long,	pages_skipped		)
 		__field(	loff_t,	range_start		)
 		__field(	loff_t,	range_end		)
+		__field(       pgoff_t,	writeback_index		)
 		__field(	int,	sync_mode		)
 		__field(	char,	for_kupdate		)
 		__field(	char,	range_cyclic		)
-		__field(       pgoff_t,	writeback_index		)
 	),
 
 	TP_fast_assign(
@@ -313,14 +313,14 @@
 		__entry->pages_skipped	= wbc->pages_skipped;
 		__entry->range_start	= wbc->range_start;
 		__entry->range_end	= wbc->range_end;
+		__entry->writeback_index = inode->i_mapping->writeback_index;
 		__entry->sync_mode	= wbc->sync_mode;
 		__entry->for_kupdate	= wbc->for_kupdate;
 		__entry->range_cyclic	= wbc->range_cyclic;
-		__entry->writeback_index = inode->i_mapping->writeback_index;
 	),
 
 	TP_printk("dev %d,%d ino %lu nr_to_write %ld pages_skipped %ld "
-		  "range_start %lld range_end %lld sync_mode %d"
+		  "range_start %lld range_end %lld sync_mode %d "
 		  "for_kupdate %d range_cyclic %d writeback_index %lu",
 		  MAJOR(__entry->dev), MINOR(__entry->dev),
 		  (unsigned long) __entry->ino, __entry->nr_to_write,
@@ -382,8 +382,8 @@
 		__field(	int,	ret			)
 		__field(	int,	pages_written		)
 		__field(	long,	pages_skipped		)
-		__field(	int,	sync_mode		)
 		__field(       pgoff_t,	writeback_index		)
+		__field(	int,	sync_mode		)
 	),
 
 	TP_fast_assign(
@@ -392,8 +392,8 @@
 		__entry->ret		= ret;
 		__entry->pages_written	= pages_written;
 		__entry->pages_skipped	= wbc->pages_skipped;
-		__entry->sync_mode	= wbc->sync_mode;
 		__entry->writeback_index = inode->i_mapping->writeback_index;
+		__entry->sync_mode	= wbc->sync_mode;
 	),
 
 	TP_printk("dev %d,%d ino %lu ret %d pages_written %d pages_skipped %ld "
@@ -411,16 +411,16 @@
 	TP_ARGS(page),
 
 	TP_STRUCT__entry(
-		__field(	pgoff_t, index			)
-		__field(	ino_t,	ino			)
 		__field(	dev_t,	dev			)
+		__field(	ino_t,	ino			)
+		__field(	pgoff_t, index			)
 
 	),
 
 	TP_fast_assign(
-		__entry->index	= page->index;
-		__entry->ino	= page->mapping->host->i_ino;
 		__entry->dev	= page->mapping->host->i_sb->s_dev;
+		__entry->ino	= page->mapping->host->i_ino;
+		__entry->index	= page->index;
 	),
 
 	TP_printk("dev %d,%d ino %lu page_index %lu",
@@ -456,18 +456,18 @@
 	TP_ARGS(page, offset),
 
 	TP_STRUCT__entry(
+		__field(	dev_t,	dev			)
+		__field(	ino_t,	ino			)
 		__field(	pgoff_t, index			)
 		__field(	unsigned long, offset		)
-		__field(	ino_t,	ino			)
-		__field(	dev_t,	dev			)
 
 	),
 
 	TP_fast_assign(
+		__entry->dev	= page->mapping->host->i_sb->s_dev;
+		__entry->ino	= page->mapping->host->i_ino;
 		__entry->index	= page->index;
 		__entry->offset	= offset;
-		__entry->ino	= page->mapping->host->i_ino;
-		__entry->dev	= page->mapping->host->i_sb->s_dev;
 	),
 
 	TP_printk("dev %d,%d ino %lu page_index %lu offset %lu",
@@ -510,8 +510,8 @@
 		__field(	dev_t,	dev			)
 		__field(	ino_t,	ino			)
 		__field(	__u64,	pa_pstart		)
-		__field(	__u32,	pa_len			)
 		__field(	__u64,	pa_lstart		)
+		__field(	__u32,	pa_len			)
 
 	),
 
@@ -519,8 +519,8 @@
 		__entry->dev		= ac->ac_sb->s_dev;
 		__entry->ino		= ac->ac_inode->i_ino;
 		__entry->pa_pstart	= pa->pa_pstart;
-		__entry->pa_len		= pa->pa_len;
 		__entry->pa_lstart	= pa->pa_lstart;
+		__entry->pa_len		= pa->pa_len;
 	),
 
 	TP_printk("dev %d,%d ino %lu pstart %llu len %u lstart %llu",
@@ -645,7 +645,6 @@
 	TP_STRUCT__entry(
 		__field(	dev_t,	dev			)
 		__field(	ino_t,	ino			)
-		__field(	unsigned int, flags		)
 		__field(	unsigned int, len		)
 		__field(	__u32,  logical			)
 		__field(	__u32,	lleft			)
@@ -653,12 +652,12 @@
 		__field(	__u64,	goal			)
 		__field(	__u64,	pleft			)
 		__field(	__u64,	pright			)
+		__field(	unsigned int, flags		)
 	),
 
 	TP_fast_assign(
 		__entry->dev	= ar->inode->i_sb->s_dev;
 		__entry->ino	= ar->inode->i_ino;
-		__entry->flags	= ar->flags;
 		__entry->len	= ar->len;
 		__entry->logical = ar->logical;
 		__entry->goal	= ar->goal;
@@ -666,6 +665,7 @@
 		__entry->lright	= ar->lright;
 		__entry->pleft	= ar->pleft;
 		__entry->pright	= ar->pright;
+		__entry->flags	= ar->flags;
 	),
 
 	TP_printk("dev %d,%d ino %lu flags %u len %u lblk %u goal %llu "
@@ -686,7 +686,6 @@
 		__field(	dev_t,	dev			)
 		__field(	ino_t,	ino			)
 		__field(	__u64,	block			)
-		__field(	unsigned int, flags		)
 		__field(	unsigned int, len		)
 		__field(	__u32,  logical			)
 		__field(	__u32,	lleft			)
@@ -694,13 +693,13 @@
 		__field(	__u64,	goal			)
 		__field(	__u64,	pleft			)
 		__field(	__u64,	pright			)
+		__field(	unsigned int, flags		)
 	),
 
 	TP_fast_assign(
 		__entry->dev	= ar->inode->i_sb->s_dev;
 		__entry->ino	= ar->inode->i_ino;
 		__entry->block	= block;
-		__entry->flags	= ar->flags;
 		__entry->len	= ar->len;
 		__entry->logical = ar->logical;
 		__entry->goal	= ar->goal;
@@ -708,6 +707,7 @@
 		__entry->lright	= ar->lright;
 		__entry->pleft	= ar->pleft;
 		__entry->pright	= ar->pright;
+		__entry->flags	= ar->flags;
 	),
 
 	TP_printk("dev %d,%d ino %lu flags %u len %u block %llu lblk %u "
@@ -728,19 +728,19 @@
 	TP_STRUCT__entry(
 		__field(	dev_t,	dev			)
 		__field(	ino_t,	ino			)
-		__field(	__u16,	mode			)
 		__field(	__u64,	block			)
 		__field(	unsigned long,	count		)
 		__field(	int,	flags			)
+		__field(	__u16,	mode			)
 	),
 
 	TP_fast_assign(
 		__entry->dev		= inode->i_sb->s_dev;
 		__entry->ino		= inode->i_ino;
-		__entry->mode		= inode->i_mode;
 		__entry->block		= block;
 		__entry->count		= count;
 		__entry->flags		= flags;
+		__entry->mode		= inode->i_mode;
 	),
 
 	TP_printk("dev %d,%d ino %lu mode 0%o block %llu count %lu flags %d",
@@ -783,15 +783,15 @@
 	TP_ARGS(inode, ret),
 
 	TP_STRUCT__entry(
-		__field(	int,	ret			)
-		__field(	ino_t,	ino			)
 		__field(	dev_t,	dev			)
+		__field(	ino_t,	ino			)
+		__field(	int,	ret			)
 	),
 
 	TP_fast_assign(
-		__entry->ret		= ret;
-		__entry->ino		= inode->i_ino;
 		__entry->dev		= inode->i_sb->s_dev;
+		__entry->ino		= inode->i_ino;
+		__entry->ret		= ret;
 	),
 
 	TP_printk("dev %d,%d ino %lu ret %d",
@@ -854,12 +854,6 @@
 	TP_STRUCT__entry(
 		__field(	dev_t,	dev			)
 		__field(	ino_t,	ino			)
-		__field(	__u16,	found			)
-		__field(	__u16,	groups			)
-		__field(	__u16,	buddy			)
-		__field(	__u16,	flags			)
-		__field(	__u16,	tail			)
-		__field(	__u8,	cr			)
 		__field(	__u32, 	orig_logical		)
 		__field(	  int,	orig_start		)
 		__field(	__u32, 	orig_group		)
@@ -872,17 +866,17 @@
 		__field(	  int,	result_start		)
 		__field(	__u32, 	result_group		)
 		__field(	  int,	result_len		)
+		__field(	__u16,	found			)
+		__field(	__u16,	groups			)
+		__field(	__u16,	buddy			)
+		__field(	__u16,	flags			)
+		__field(	__u16,	tail			)
+		__field(	__u8,	cr			)
 	),
 
 	TP_fast_assign(
 		__entry->dev		= ac->ac_inode->i_sb->s_dev;
 		__entry->ino		= ac->ac_inode->i_ino;
-		__entry->found		= ac->ac_found;
-		__entry->flags		= ac->ac_flags;
-		__entry->groups		= ac->ac_groups_scanned;
-		__entry->buddy		= ac->ac_buddy;
-		__entry->tail		= ac->ac_tail;
-		__entry->cr		= ac->ac_criteria;
 		__entry->orig_logical	= ac->ac_o_ex.fe_logical;
 		__entry->orig_start	= ac->ac_o_ex.fe_start;
 		__entry->orig_group	= ac->ac_o_ex.fe_group;
@@ -895,6 +889,12 @@
 		__entry->result_start	= ac->ac_f_ex.fe_start;
 		__entry->result_group	= ac->ac_f_ex.fe_group;
 		__entry->result_len	= ac->ac_f_ex.fe_len;
+		__entry->found		= ac->ac_found;
+		__entry->flags		= ac->ac_flags;
+		__entry->groups		= ac->ac_groups_scanned;
+		__entry->buddy		= ac->ac_buddy;
+		__entry->tail		= ac->ac_tail;
+		__entry->cr		= ac->ac_criteria;
 	),
 
 	TP_printk("dev %d,%d inode %lu orig %u/%d/%u@%u goal %u/%d/%u@%u "
@@ -1015,17 +1015,17 @@
 	TP_STRUCT__entry(
 		__field(	dev_t,	dev			)
 		__field(	ino_t,	ino			)
-		__field(	__u16,	mode			)
-		__field(	int,	is_metadata		)
 		__field(	__u64,	block			)
+		__field(	int,	is_metadata		)
+		__field(	__u16,	mode			)
 	),
 
 	TP_fast_assign(
 		__entry->dev	= inode->i_sb->s_dev;
 		__entry->ino	= inode->i_ino;
-		__entry->mode	= inode->i_mode;
-		__entry->is_metadata = is_metadata;
 		__entry->block	= block;
+		__entry->is_metadata = is_metadata;
+		__entry->mode	= inode->i_mode;
 	),
 
 	TP_printk("dev %d,%d ino %lu mode 0%o is_metadata %d block %llu",
@@ -1042,19 +1042,18 @@
 	TP_STRUCT__entry(
 		__field(	dev_t,	dev			)
 		__field(	ino_t,	ino			)
-		__field(	__u16,	mode			)
 		__field(	__u64,	i_blocks		)
 		__field(	int,	used_blocks		)
 		__field(	int,	reserved_data_blocks	)
 		__field(	int,	reserved_meta_blocks	)
 		__field(	int,	allocated_meta_blocks	)
 		__field(	int,	quota_claim		)
+		__field(	__u16,	mode			)
 	),
 
 	TP_fast_assign(
 		__entry->dev	= inode->i_sb->s_dev;
 		__entry->ino	= inode->i_ino;
-		__entry->mode	= inode->i_mode;
 		__entry->i_blocks = inode->i_blocks;
 		__entry->used_blocks = used_blocks;
 		__entry->reserved_data_blocks =
@@ -1064,6 +1063,7 @@
 		__entry->allocated_meta_blocks =
 				EXT4_I(inode)->i_allocated_meta_blocks;
 		__entry->quota_claim = quota_claim;
+		__entry->mode	= inode->i_mode;
 	),
 
 	TP_printk("dev %d,%d ino %lu mode 0%o i_blocks %llu used_blocks %d "
@@ -1085,21 +1085,21 @@
 	TP_STRUCT__entry(
 		__field(	dev_t,	dev			)
 		__field(	ino_t,	ino			)
-		__field(	__u16,  mode			)
 		__field(	__u64,	i_blocks		)
 		__field(	int,	md_needed		)
 		__field(	int,	reserved_data_blocks	)
 		__field(	int,	reserved_meta_blocks	)
+		__field(	__u16,  mode			)
 	),
 
 	TP_fast_assign(
 		__entry->dev	= inode->i_sb->s_dev;
 		__entry->ino	= inode->i_ino;
-		__entry->mode	= inode->i_mode;
 		__entry->i_blocks = inode->i_blocks;
 		__entry->md_needed = md_needed;
 		__entry->reserved_data_blocks = EXT4_I(inode)->i_reserved_data_blocks;
 		__entry->reserved_meta_blocks = EXT4_I(inode)->i_reserved_meta_blocks;
+		__entry->mode	= inode->i_mode;
 	),
 
 	TP_printk("dev %d,%d ino %lu mode 0%o i_blocks %llu md_needed %d "
@@ -1119,23 +1119,23 @@
 	TP_STRUCT__entry(
 		__field(	dev_t,	dev			)
 		__field(	ino_t,	ino			)
-		__field(	__u16,  mode			)
 		__field(	__u64,	i_blocks		)
 		__field(	int,	freed_blocks		)
 		__field(	int,	reserved_data_blocks	)
 		__field(	int,	reserved_meta_blocks	)
 		__field(	int,	allocated_meta_blocks	)
+		__field(	__u16,  mode			)
 	),
 
 	TP_fast_assign(
 		__entry->dev	= inode->i_sb->s_dev;
 		__entry->ino	= inode->i_ino;
-		__entry->mode	= inode->i_mode;
 		__entry->i_blocks = inode->i_blocks;
 		__entry->freed_blocks = freed_blocks;
 		__entry->reserved_data_blocks = EXT4_I(inode)->i_reserved_data_blocks;
 		__entry->reserved_meta_blocks = EXT4_I(inode)->i_reserved_meta_blocks;
 		__entry->allocated_meta_blocks = EXT4_I(inode)->i_allocated_meta_blocks;
+		__entry->mode	= inode->i_mode;
 	),
 
 	TP_printk("dev %d,%d ino %lu mode 0%o i_blocks %llu freed_blocks %d "
@@ -1203,16 +1203,16 @@
 	TP_ARGS(inode, offset, len, rw),
 
 	TP_STRUCT__entry(
-		__field(	ino_t,	ino			)
 		__field(	dev_t,	dev			)
+		__field(	ino_t,	ino			)
 		__field(	loff_t,	pos			)
 		__field(	unsigned long,	len		)
 		__field(	int,	rw			)
 	),
 
 	TP_fast_assign(
-		__entry->ino	= inode->i_ino;
 		__entry->dev	= inode->i_sb->s_dev;
+		__entry->ino	= inode->i_ino;
 		__entry->pos	= offset;
 		__entry->len	= len;
 		__entry->rw	= rw;
@@ -1231,8 +1231,8 @@
 	TP_ARGS(inode, offset, len, rw, ret),
 
 	TP_STRUCT__entry(
-		__field(	ino_t,	ino			)
 		__field(	dev_t,	dev			)
+		__field(	ino_t,	ino			)
 		__field(	loff_t,	pos			)
 		__field(	unsigned long,	len		)
 		__field(	int,	rw			)
@@ -1240,8 +1240,8 @@
 	),
 
 	TP_fast_assign(
-		__entry->ino	= inode->i_ino;
 		__entry->dev	= inode->i_sb->s_dev;
+		__entry->ino	= inode->i_ino;
 		__entry->pos	= offset;
 		__entry->len	= len;
 		__entry->rw	= rw;
@@ -1261,16 +1261,16 @@
 	TP_ARGS(inode, offset, len, mode),
 
 	TP_STRUCT__entry(
-		__field(	ino_t,	ino			)
 		__field(	dev_t,	dev			)
+		__field(	ino_t,	ino			)
 		__field(	loff_t,	pos			)
 		__field(	loff_t,	len			)
 		__field(	int,	mode			)
 	),
 
 	TP_fast_assign(
-		__entry->ino	= inode->i_ino;
 		__entry->dev	= inode->i_sb->s_dev;
+		__entry->ino	= inode->i_ino;
 		__entry->pos	= offset;
 		__entry->len	= len;
 		__entry->mode	= mode;
@@ -1289,16 +1289,16 @@
 	TP_ARGS(inode, offset, max_blocks, ret),
 
 	TP_STRUCT__entry(
-		__field(	ino_t,	ino			)
 		__field(	dev_t,	dev			)
+		__field(	ino_t,	ino			)
 		__field(	loff_t,	pos			)
 		__field(	unsigned int,	blocks		)
 		__field(	int, 	ret			)
 	),
 
 	TP_fast_assign(
-		__entry->ino	= inode->i_ino;
 		__entry->dev	= inode->i_sb->s_dev;
+		__entry->ino	= inode->i_ino;
 		__entry->pos	= offset;
 		__entry->blocks	= max_blocks;
 		__entry->ret	= ret;
@@ -1317,17 +1317,17 @@
 	TP_ARGS(parent, dentry),
 
 	TP_STRUCT__entry(
-		__field(	ino_t,	parent			)
-		__field(	ino_t,	ino			)
-		__field(	loff_t,	size			)
 		__field(	dev_t,	dev			)
+		__field(	ino_t,	ino			)
+		__field(	ino_t,	parent			)
+		__field(	loff_t,	size			)
 	),
 
 	TP_fast_assign(
-		__entry->parent		= parent->i_ino;
-		__entry->ino		= dentry->d_inode->i_ino;
-		__entry->size		= dentry->d_inode->i_size;
 		__entry->dev		= dentry->d_inode->i_sb->s_dev;
+		__entry->ino		= dentry->d_inode->i_ino;
+		__entry->parent		= parent->i_ino;
+		__entry->size		= dentry->d_inode->i_size;
 	),
 
 	TP_printk("dev %d,%d ino %lu size %lld parent %lu",
@@ -1342,14 +1342,14 @@
 	TP_ARGS(dentry, ret),
 
 	TP_STRUCT__entry(
-		__field(	ino_t,	ino			)
 		__field(	dev_t,	dev			)
+		__field(	ino_t,	ino			)
 		__field(	int,	ret			)
 	),
 
 	TP_fast_assign(
-		__entry->ino		= dentry->d_inode->i_ino;
 		__entry->dev		= dentry->d_inode->i_sb->s_dev;
+		__entry->ino		= dentry->d_inode->i_ino;
 		__entry->ret		= ret;
 	),
 
@@ -1365,14 +1365,14 @@
 	TP_ARGS(inode),
 
 	TP_STRUCT__entry(
-		__field(	ino_t,  	ino		)
-		__field(	dev_t,  	dev		)
+		__field(	dev_t,		dev		)
+		__field(	ino_t,		ino		)
 		__field(	__u64,		blocks		)
 	),
 
 	TP_fast_assign(
-		__entry->ino    = inode->i_ino;
 		__entry->dev    = inode->i_sb->s_dev;
+		__entry->ino    = inode->i_ino;
 		__entry->blocks	= inode->i_blocks;
 	),
 
@@ -1403,8 +1403,8 @@
 	TP_ARGS(inode, map, ux),
 
 	TP_STRUCT__entry(
-		__field(	ino_t,		ino	)
 		__field(	dev_t,		dev	)
+		__field(	ino_t,		ino	)
 		__field(	ext4_lblk_t,	m_lblk	)
 		__field(	unsigned,	m_len	)
 		__field(	ext4_lblk_t,	u_lblk	)
@@ -1413,8 +1413,8 @@
 	),
 
 	TP_fast_assign(
-		__entry->ino		= inode->i_ino;
 		__entry->dev		= inode->i_sb->s_dev;
+		__entry->ino		= inode->i_ino;
 		__entry->m_lblk		= map->m_lblk;
 		__entry->m_len		= map->m_len;
 		__entry->u_lblk		= le32_to_cpu(ux->ee_block);
@@ -1441,8 +1441,8 @@
 	TP_ARGS(inode, map, ux, ix),
 
 	TP_STRUCT__entry(
-		__field(	ino_t,		ino	)
 		__field(	dev_t,		dev	)
+		__field(	ino_t,		ino	)
 		__field(	ext4_lblk_t,	m_lblk	)
 		__field(	unsigned,	m_len	)
 		__field(	ext4_lblk_t,	u_lblk	)
@@ -1454,8 +1454,8 @@
 	),
 
 	TP_fast_assign(
-		__entry->ino		= inode->i_ino;
 		__entry->dev		= inode->i_sb->s_dev;
+		__entry->ino		= inode->i_ino;
 		__entry->m_lblk		= map->m_lblk;
 		__entry->m_len		= map->m_len;
 		__entry->u_lblk		= le32_to_cpu(ux->ee_block);
@@ -1483,16 +1483,16 @@
 	TP_ARGS(inode, lblk, len, flags),
 
 	TP_STRUCT__entry(
-		__field(	ino_t,  	ino		)
-		__field(	dev_t,  	dev		)
+		__field(	dev_t,		dev		)
+		__field(	ino_t,		ino		)
 		__field(	ext4_lblk_t,	lblk		)
 		__field(	unsigned int,	len		)
 		__field(	unsigned int,	flags		)
 	),
 
 	TP_fast_assign(
-		__entry->ino    = inode->i_ino;
 		__entry->dev    = inode->i_sb->s_dev;
+		__entry->ino    = inode->i_ino;
 		__entry->lblk	= lblk;
 		__entry->len	= len;
 		__entry->flags	= flags;
@@ -1525,19 +1525,19 @@
 	TP_ARGS(inode, lblk, pblk, len, ret),
 
 	TP_STRUCT__entry(
-		__field(	ino_t,		ino		)
 		__field(	dev_t,		dev		)
-		__field(	ext4_lblk_t,	lblk		)
+		__field(	ino_t,		ino		)
 		__field(	ext4_fsblk_t,	pblk		)
+		__field(	ext4_lblk_t,	lblk		)
 		__field(	unsigned int,	len		)
 		__field(	int,		ret		)
 	),
 
 	TP_fast_assign(
-		__entry->ino    = inode->i_ino;
 		__entry->dev    = inode->i_sb->s_dev;
-		__entry->lblk	= lblk;
+		__entry->ino    = inode->i_ino;
 		__entry->pblk	= pblk;
+		__entry->lblk	= lblk;
 		__entry->len	= len;
 		__entry->ret	= ret;
 	),
@@ -1569,17 +1569,17 @@
 	TP_ARGS(inode, lblk, pblk),
 
 	TP_STRUCT__entry(
-		__field(	ino_t,		ino		)
 		__field(	dev_t,		dev		)
-		__field(	ext4_lblk_t,	lblk		)
+		__field(	ino_t,		ino		)
 		__field(	ext4_fsblk_t,	pblk		)
+		__field(	ext4_lblk_t,	lblk		)
 	),
 
 	TP_fast_assign(
-		__entry->ino    = inode->i_ino;
 		__entry->dev    = inode->i_sb->s_dev;
-		__entry->lblk	= lblk;
+		__entry->ino    = inode->i_ino;
 		__entry->pblk	= pblk;
+		__entry->lblk	= lblk;
 	),
 
 	TP_printk("dev %d,%d ino %lu lblk %u pblk %llu",
@@ -1594,13 +1594,13 @@
 	TP_ARGS(inode),
 
 	TP_STRUCT__entry(
-		__field(	ino_t,	ino		)
 		__field(	dev_t,	dev		)
+		__field(	ino_t,	ino		)
 	),
 
 	TP_fast_assign(
-		__entry->ino		= inode->i_ino;
 		__entry->dev		= inode->i_sb->s_dev;
+		__entry->ino		= inode->i_ino;
 	),
 
 	TP_printk("dev %d,%d ino %ld",
@@ -1615,14 +1615,14 @@
 
 	TP_STRUCT__entry(
 		__field(	dev_t,	dev			)
-		__field(	  int, 	nblocks			)
 		__field(unsigned long,	ip			)
+		__field(	int,	nblocks			)
 	),
 
 	TP_fast_assign(
 		__entry->dev	 = sb->s_dev;
-		__entry->nblocks = nblocks;
 		__entry->ip	 = IP;
+		__entry->nblocks = nblocks;
 	),
 
 	TP_printk("dev %d,%d nblocks %d caller %pF",
@@ -1686,23 +1686,23 @@
 	TP_ARGS(inode, map, allocated, newblock),
 
 	TP_STRUCT__entry(
-		__field(	ino_t,		ino		)
 		__field(	dev_t,		dev		)
+		__field(	ino_t,		ino		)
+		__field(	int,		flags		)
 		__field(	ext4_lblk_t,	lblk		)
 		__field(	ext4_fsblk_t,	pblk		)
 		__field(	unsigned int,	len		)
-		__field(	int,		flags		)
 		__field(	unsigned int,	allocated	)
 		__field(	ext4_fsblk_t,	newblk		)
 	),
 
 	TP_fast_assign(
-		__entry->ino		= inode->i_ino;
 		__entry->dev		= inode->i_sb->s_dev;
+		__entry->ino		= inode->i_ino;
+		__entry->flags		= map->m_flags;
 		__entry->lblk		= map->m_lblk;
 		__entry->pblk		= map->m_pblk;
 		__entry->len		= map->m_len;
-		__entry->flags		= map->m_flags;
 		__entry->allocated	= allocated;
 		__entry->newblk		= newblock;
 	),
@@ -1724,19 +1724,19 @@
 
 	TP_STRUCT__entry(
 		__field(	dev_t,		dev	)
+		__field(	unsigned int,	flags	)
 		__field(	ext4_lblk_t,	lblk	)
 		__field(	ext4_fsblk_t,	pblk	)
 		__field(	unsigned int,	len	)
-		__field(	unsigned int,	flags	)
 		__field(	int,		ret	)
 	),
 
 	TP_fast_assign(
 		__entry->dev	= sb->s_dev;
+		__entry->flags	= map->m_flags;
 		__entry->lblk	= map->m_lblk;
 		__entry->pblk	= map->m_pblk;
 		__entry->len	= map->m_len;
-		__entry->flags	= map->m_flags;
 		__entry->ret	= ret;
 	),
 
@@ -1753,16 +1753,16 @@
 	TP_ARGS(inode, lblk, len, start),
 
 	TP_STRUCT__entry(
-		__field(	ino_t,		ino	)
 		__field(	dev_t,		dev	)
+		__field(	ino_t,		ino	)
 		__field(	ext4_lblk_t,	lblk	)
 		__field(	unsigned int,	len	)
 		__field(	ext4_fsblk_t,	start	)
 	),
 
 	TP_fast_assign(
-		__entry->ino	= inode->i_ino;
 		__entry->dev	= inode->i_sb->s_dev;
+		__entry->ino	= inode->i_ino;
 		__entry->lblk	= lblk;
 		__entry->len	= len;
 		__entry->start	= start;
@@ -1782,15 +1782,15 @@
 	TP_ARGS(inode, lblk, ret),
 
 	TP_STRUCT__entry(
-		__field(	ino_t,		ino	)
 		__field(	dev_t,		dev	)
+		__field(	ino_t,		ino	)
 		__field(	ext4_lblk_t,	lblk	)
 		__field(	int,		ret	)
 	),
 
 	TP_fast_assign(
-		__entry->ino	= inode->i_ino;
 		__entry->dev	= inode->i_sb->s_dev;
+		__entry->ino	= inode->i_ino;
 		__entry->lblk	= lblk;
 		__entry->ret	= ret;
 	),
@@ -1810,8 +1810,8 @@
 	TP_ARGS(inode, from, to, reverse, found, found_blk),
 
 	TP_STRUCT__entry(
-		__field(	ino_t,		ino		)
 		__field(	dev_t,		dev		)
+		__field(	ino_t,		ino		)
 		__field(	ext4_lblk_t,	from		)
 		__field(	ext4_lblk_t,	to		)
 		__field(	int,		reverse		)
@@ -1820,8 +1820,8 @@
 	),
 
 	TP_fast_assign(
-		__entry->ino		= inode->i_ino;
 		__entry->dev		= inode->i_sb->s_dev;
+		__entry->ino		= inode->i_ino;
 		__entry->from		= from;
 		__entry->to		= to;
 		__entry->reverse	= reverse;
@@ -1844,15 +1844,15 @@
 	TP_ARGS(inode, lblk, len),
 
 	TP_STRUCT__entry(
-		__field(	ino_t,		ino	)
 		__field(	dev_t,		dev	)
+		__field(	ino_t,		ino	)
 		__field(	ext4_lblk_t,	lblk	)
 		__field(	unsigned int,	len	)
 	),
 
 	TP_fast_assign(
-		__entry->ino	= inode->i_ino;
 		__entry->dev	= inode->i_sb->s_dev;
+		__entry->ino	= inode->i_ino;
 		__entry->lblk	= lblk;
 		__entry->len	= len;
 	),
@@ -1871,18 +1871,18 @@
 	TP_ARGS(inode, lblk, pblk, len),
 
 	TP_STRUCT__entry(
-		__field(	ino_t,		ino	)
 		__field(	dev_t,		dev	)
-		__field(	ext4_lblk_t,	lblk	)
+		__field(	ino_t,		ino	)
 		__field(	ext4_fsblk_t,	pblk	)
+		__field(	ext4_lblk_t,	lblk	)
 		__field(	unsigned short,	len	)
 	),
 
 	TP_fast_assign(
-		__entry->ino	= inode->i_ino;
 		__entry->dev	= inode->i_sb->s_dev;
-		__entry->lblk	= lblk;
+		__entry->ino	= inode->i_ino;
 		__entry->pblk	= pblk;
+		__entry->lblk	= lblk;
 		__entry->len	= len;
 	),
 
@@ -1902,25 +1902,25 @@
 	TP_ARGS(inode, ex, from, to, partial_cluster),
 
 	TP_STRUCT__entry(
-		__field(	ino_t,		ino	)
 		__field(	dev_t,		dev	)
-		__field(	ext4_lblk_t,	ee_lblk	)
-		__field(	ext4_fsblk_t,	ee_pblk	)
-		__field(	unsigned short,	ee_len	)
+		__field(	ino_t,		ino	)
 		__field(	ext4_lblk_t,	from	)
 		__field(	ext4_lblk_t,	to	)
 		__field(	ext4_fsblk_t,	partial	)
+		__field(	ext4_fsblk_t,	ee_pblk	)
+		__field(	ext4_lblk_t,	ee_lblk	)
+		__field(	unsigned short,	ee_len	)
 	),
 
 	TP_fast_assign(
-		__entry->ino		= inode->i_ino;
 		__entry->dev		= inode->i_sb->s_dev;
-		__entry->ee_lblk	= cpu_to_le32(ex->ee_block);
-		__entry->ee_pblk	= ext4_ext_pblock(ex);
-		__entry->ee_len		= ext4_ext_get_actual_len(ex);
+		__entry->ino		= inode->i_ino;
 		__entry->from		= from;
 		__entry->to		= to;
 		__entry->partial	= partial_cluster;
+		__entry->ee_pblk	= ext4_ext_pblock(ex);
+		__entry->ee_lblk	= cpu_to_le32(ex->ee_block);
+		__entry->ee_len		= ext4_ext_get_actual_len(ex);
 	),
 
 	TP_printk("dev %d,%d ino %lu extent [%u(%llu), %u]"
@@ -1942,23 +1942,23 @@
 	TP_ARGS(inode, start, ex, partial_cluster),
 
 	TP_STRUCT__entry(
-		__field(	ino_t,		ino	)
 		__field(	dev_t,		dev	)
+		__field(	ino_t,		ino	)
+		__field(	ext4_fsblk_t,	partial	)
 		__field(	ext4_lblk_t,	start	)
 		__field(	ext4_lblk_t,	ee_lblk	)
 		__field(	ext4_fsblk_t,	ee_pblk	)
 		__field(	short,		ee_len	)
-		__field(	ext4_fsblk_t,	partial	)
 	),
 
 	TP_fast_assign(
-		__entry->ino		= inode->i_ino;
 		__entry->dev		= inode->i_sb->s_dev;
+		__entry->ino		= inode->i_ino;
+		__entry->partial	= partial_cluster;
 		__entry->start		= start;
 		__entry->ee_lblk	= le32_to_cpu(ex->ee_block);
 		__entry->ee_pblk	= ext4_ext_pblock(ex);
 		__entry->ee_len		= ext4_ext_get_actual_len(ex);
-		__entry->partial	= partial_cluster;
 	),
 
 	TP_printk("dev %d,%d ino %lu start_lblk %u last_extent [%u(%llu), %u]"
@@ -1978,14 +1978,14 @@
 	TP_ARGS(inode, pblk),
 
 	TP_STRUCT__entry(
-		__field(	ino_t,		ino	)
 		__field(	dev_t,		dev	)
+		__field(	ino_t,		ino	)
 		__field(	ext4_fsblk_t,	pblk	)
 	),
 
 	TP_fast_assign(
-		__entry->ino	= inode->i_ino;
 		__entry->dev	= inode->i_sb->s_dev;
+		__entry->ino	= inode->i_ino;
 		__entry->pblk	= pblk;
 	),
 
@@ -2001,15 +2001,15 @@
 	TP_ARGS(inode, start, depth),
 
 	TP_STRUCT__entry(
-		__field(	ino_t,		ino	)
 		__field(	dev_t,		dev	)
+		__field(	ino_t,		ino	)
 		__field(	ext4_lblk_t,	start	)
 		__field(	int,		depth	)
 	),
 
 	TP_fast_assign(
-		__entry->ino	= inode->i_ino;
 		__entry->dev	= inode->i_sb->s_dev;
+		__entry->ino	= inode->i_ino;
 		__entry->start	= start;
 		__entry->depth	= depth;
 	),
@@ -2028,8 +2028,8 @@
 	TP_ARGS(inode, start, depth, partial, eh_entries),
 
 	TP_STRUCT__entry(
-		__field(	ino_t,		ino		)
 		__field(	dev_t,		dev		)
+		__field(	ino_t,		ino		)
 		__field(	ext4_lblk_t,	start		)
 		__field(	int,		depth		)
 		__field(	ext4_lblk_t,	partial		)
@@ -2037,8 +2037,8 @@
 	),
 
 	TP_fast_assign(
-		__entry->ino		= inode->i_ino;
 		__entry->dev		= inode->i_sb->s_dev;
+		__entry->ino		= inode->i_ino;
 		__entry->start		= start;
 		__entry->depth		= depth;
 		__entry->partial	= partial;
diff --git a/include/trace/events/gfpflags.h b/include/trace/events/gfpflags.h
index d6fd8e5..9391706 100644
--- a/include/trace/events/gfpflags.h
+++ b/include/trace/events/gfpflags.h
@@ -36,7 +36,6 @@
 	{(unsigned long)__GFP_RECLAIMABLE,	"GFP_RECLAIMABLE"},	\
 	{(unsigned long)__GFP_MOVABLE,		"GFP_MOVABLE"},		\
 	{(unsigned long)__GFP_NOTRACK,		"GFP_NOTRACK"},		\
-	{(unsigned long)__GFP_NO_KSWAPD,	"GFP_NO_KSWAPD"},	\
 	{(unsigned long)__GFP_OTHER_NODE,	"GFP_OTHER_NODE"}	\
 	) : "GFP_NOWAIT"
 
diff --git a/include/uapi/asm-generic/Kbuild b/include/uapi/asm-generic/Kbuild
index aafaa5a..b73de7b 100644
--- a/include/uapi/asm-generic/Kbuild
+++ b/include/uapi/asm-generic/Kbuild
@@ -1 +1,36 @@
 # UAPI Header export list
+header-y += auxvec.h
+header-y += bitsperlong.h
+header-y += errno-base.h
+header-y += errno.h
+header-y += fcntl.h
+header-y += int-l64.h
+header-y += int-ll64.h
+header-y += ioctl.h
+header-y += ioctls.h
+header-y += ipcbuf.h
+header-y += kvm_para.h
+header-y += mman-common.h
+header-y += mman.h
+header-y += msgbuf.h
+header-y += param.h
+header-y += poll.h
+header-y += posix_types.h
+header-y += resource.h
+header-y += sembuf.h
+header-y += setup.h
+header-y += shmbuf.h
+header-y += shmparam.h
+header-y += siginfo.h
+header-y += signal-defs.h
+header-y += signal.h
+header-y += socket.h
+header-y += sockios.h
+header-y += stat.h
+header-y += statfs.h
+header-y += swab.h
+header-y += termbits.h
+header-y += termios.h
+header-y += types.h
+header-y += ucontext.h
+header-y += unistd.h
diff --git a/include/asm-generic/auxvec.h b/include/uapi/asm-generic/auxvec.h
similarity index 100%
rename from include/asm-generic/auxvec.h
rename to include/uapi/asm-generic/auxvec.h
diff --git a/include/uapi/asm-generic/bitsperlong.h b/include/uapi/asm-generic/bitsperlong.h
new file mode 100644
index 0000000..23e6c41
--- /dev/null
+++ b/include/uapi/asm-generic/bitsperlong.h
@@ -0,0 +1,15 @@
+#ifndef _UAPI__ASM_GENERIC_BITS_PER_LONG
+#define _UAPI__ASM_GENERIC_BITS_PER_LONG
+
+/*
+ * There seems to be no way of detecting this automatically from user
+ * space, so 64 bit architectures should override this in their
+ * bitsperlong.h. In particular, an architecture that supports
+ * both 32 and 64 bit user space must not rely on CONFIG_64BIT
+ * to decide it, but rather check a compiler provided macro.
+ */
+#ifndef __BITS_PER_LONG
+#define __BITS_PER_LONG 32
+#endif
+
+#endif /* _UAPI__ASM_GENERIC_BITS_PER_LONG */
diff --git a/include/asm-generic/errno-base.h b/include/uapi/asm-generic/errno-base.h
similarity index 100%
rename from include/asm-generic/errno-base.h
rename to include/uapi/asm-generic/errno-base.h
diff --git a/include/asm-generic/errno.h b/include/uapi/asm-generic/errno.h
similarity index 100%
rename from include/asm-generic/errno.h
rename to include/uapi/asm-generic/errno.h
diff --git a/include/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h
similarity index 100%
rename from include/asm-generic/fcntl.h
rename to include/uapi/asm-generic/fcntl.h
diff --git a/include/uapi/asm-generic/int-l64.h b/include/uapi/asm-generic/int-l64.h
new file mode 100644
index 0000000..978f21c
--- /dev/null
+++ b/include/uapi/asm-generic/int-l64.h
@@ -0,0 +1,34 @@
+/*
+ * asm-generic/int-l64.h
+ *
+ * Integer declarations for architectures which use "long"
+ * for 64-bit types.
+ */
+
+#ifndef _UAPI_ASM_GENERIC_INT_L64_H
+#define _UAPI_ASM_GENERIC_INT_L64_H
+
+#include <asm/bitsperlong.h>
+
+#ifndef __ASSEMBLY__
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+typedef __signed__ long __s64;
+typedef unsigned long __u64;
+
+#endif /* __ASSEMBLY__ */
+
+
+#endif /* _UAPI_ASM_GENERIC_INT_L64_H */
diff --git a/include/uapi/asm-generic/int-ll64.h b/include/uapi/asm-generic/int-ll64.h
new file mode 100644
index 0000000..a8658b2
--- /dev/null
+++ b/include/uapi/asm-generic/int-ll64.h
@@ -0,0 +1,39 @@
+/*
+ * asm-generic/int-ll64.h
+ *
+ * Integer declarations for architectures which use "long long"
+ * for 64-bit types.
+ */
+
+#ifndef _UAPI_ASM_GENERIC_INT_LL64_H
+#define _UAPI_ASM_GENERIC_INT_LL64_H
+
+#include <asm/bitsperlong.h>
+
+#ifndef __ASSEMBLY__
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#ifdef __GNUC__
+__extension__ typedef __signed__ long long __s64;
+__extension__ typedef unsigned long long __u64;
+#else
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+
+#endif /* _UAPI_ASM_GENERIC_INT_LL64_H */
diff --git a/include/uapi/asm-generic/ioctl.h b/include/uapi/asm-generic/ioctl.h
new file mode 100644
index 0000000..7e7c11b
--- /dev/null
+++ b/include/uapi/asm-generic/ioctl.h
@@ -0,0 +1,98 @@
+#ifndef _UAPI_ASM_GENERIC_IOCTL_H
+#define _UAPI_ASM_GENERIC_IOCTL_H
+
+/* ioctl command encoding: 32 bits total, command in lower 16 bits,
+ * size of the parameter structure in the lower 14 bits of the
+ * upper 16 bits.
+ * Encoding the size of the parameter structure in the ioctl request
+ * is useful for catching programs compiled with old versions
+ * and to avoid overwriting user space outside the user buffer area.
+ * The highest 2 bits are reserved for indicating the ``access mode''.
+ * NOTE: This limits the max parameter size to 16kB -1 !
+ */
+
+/*
+ * The following is for compatibility across the various Linux
+ * platforms.  The generic ioctl numbering scheme doesn't really enforce
+ * a type field.  De facto, however, the top 8 bits of the lower 16
+ * bits are indeed used as a type field, so we might just as well make
+ * this explicit here.  Please be sure to use the decoding macros
+ * below from now on.
+ */
+#define _IOC_NRBITS	8
+#define _IOC_TYPEBITS	8
+
+/*
+ * Let any architecture override either of the following before
+ * including this file.
+ */
+
+#ifndef _IOC_SIZEBITS
+# define _IOC_SIZEBITS	14
+#endif
+
+#ifndef _IOC_DIRBITS
+# define _IOC_DIRBITS	2
+#endif
+
+#define _IOC_NRMASK	((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK	((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK	((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK	((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT	0
+#define _IOC_TYPESHIFT	(_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT	(_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT	(_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+/*
+ * Direction bits, which any architecture can choose to override
+ * before including this file.
+ */
+
+#ifndef _IOC_NONE
+# define _IOC_NONE	0U
+#endif
+
+#ifndef _IOC_WRITE
+# define _IOC_WRITE	1U
+#endif
+
+#ifndef _IOC_READ
+# define _IOC_READ	2U
+#endif
+
+#define _IOC(dir,type,nr,size) \
+	(((dir)  << _IOC_DIRSHIFT) | \
+	 ((type) << _IOC_TYPESHIFT) | \
+	 ((nr)   << _IOC_NRSHIFT) | \
+	 ((size) << _IOC_SIZESHIFT))
+
+#ifndef __KERNEL__
+#define _IOC_TYPECHECK(t) (sizeof(t))
+#endif
+
+/* used to create numbers */
+#define _IO(type,nr)		_IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size)	_IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
+#define _IOW(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
+#define _IOWR(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
+#define _IOR_BAD(type,nr,size)	_IOC(_IOC_READ,(type),(nr),sizeof(size))
+#define _IOW_BAD(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+#define _IOWR_BAD(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+/* used to decode ioctl numbers.. */
+#define _IOC_DIR(nr)		(((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr)		(((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr)		(((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr)		(((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+/* ...and for the drivers/sound files... */
+
+#define IOC_IN		(_IOC_WRITE << _IOC_DIRSHIFT)
+#define IOC_OUT		(_IOC_READ << _IOC_DIRSHIFT)
+#define IOC_INOUT	((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
+#define IOCSIZE_MASK	(_IOC_SIZEMASK << _IOC_SIZESHIFT)
+#define IOCSIZE_SHIFT	(_IOC_SIZESHIFT)
+
+#endif /* _UAPI_ASM_GENERIC_IOCTL_H */
diff --git a/include/asm-generic/ioctls.h b/include/uapi/asm-generic/ioctls.h
similarity index 100%
rename from include/asm-generic/ioctls.h
rename to include/uapi/asm-generic/ioctls.h
diff --git a/include/asm-generic/ipcbuf.h b/include/uapi/asm-generic/ipcbuf.h
similarity index 100%
rename from include/asm-generic/ipcbuf.h
rename to include/uapi/asm-generic/ipcbuf.h
diff --git a/include/uapi/asm-generic/kvm_para.h b/include/uapi/asm-generic/kvm_para.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/include/uapi/asm-generic/kvm_para.h
diff --git a/include/asm-generic/mman-common.h b/include/uapi/asm-generic/mman-common.h
similarity index 100%
rename from include/asm-generic/mman-common.h
rename to include/uapi/asm-generic/mman-common.h
diff --git a/include/asm-generic/mman.h b/include/uapi/asm-generic/mman.h
similarity index 100%
rename from include/asm-generic/mman.h
rename to include/uapi/asm-generic/mman.h
diff --git a/include/asm-generic/msgbuf.h b/include/uapi/asm-generic/msgbuf.h
similarity index 100%
rename from include/asm-generic/msgbuf.h
rename to include/uapi/asm-generic/msgbuf.h
diff --git a/include/uapi/asm-generic/param.h b/include/uapi/asm-generic/param.h
new file mode 100644
index 0000000..5becc84
--- /dev/null
+++ b/include/uapi/asm-generic/param.h
@@ -0,0 +1,19 @@
+#ifndef _UAPI__ASM_GENERIC_PARAM_H
+#define _UAPI__ASM_GENERIC_PARAM_H
+
+#ifndef HZ
+#define HZ 100
+#endif
+
+#ifndef EXEC_PAGESIZE
+#define EXEC_PAGESIZE	4096
+#endif
+
+#ifndef NOGROUP
+#define NOGROUP		(-1)
+#endif
+
+#define MAXHOSTNAMELEN	64	/* max length of hostname */
+
+
+#endif /* _UAPI__ASM_GENERIC_PARAM_H */
diff --git a/include/asm-generic/poll.h b/include/uapi/asm-generic/poll.h
similarity index 100%
rename from include/asm-generic/poll.h
rename to include/uapi/asm-generic/poll.h
diff --git a/include/asm-generic/posix_types.h b/include/uapi/asm-generic/posix_types.h
similarity index 100%
rename from include/asm-generic/posix_types.h
rename to include/uapi/asm-generic/posix_types.h
diff --git a/include/uapi/asm-generic/resource.h b/include/uapi/asm-generic/resource.h
new file mode 100644
index 0000000..f863428
--- /dev/null
+++ b/include/uapi/asm-generic/resource.h
@@ -0,0 +1,68 @@
+#ifndef _UAPI_ASM_GENERIC_RESOURCE_H
+#define _UAPI_ASM_GENERIC_RESOURCE_H
+
+/*
+ * Resource limit IDs
+ *
+ * ( Compatibility detail: there are architectures that have
+ *   a different rlimit ID order in the 5-9 range and want
+ *   to keep that order for binary compatibility. The reasons
+ *   are historic and all new rlimits are identical across all
+ *   arches. If an arch has such special order for some rlimits
+ *   then it defines them prior including asm-generic/resource.h. )
+ */
+
+#define RLIMIT_CPU		0	/* CPU time in sec */
+#define RLIMIT_FSIZE		1	/* Maximum filesize */
+#define RLIMIT_DATA		2	/* max data size */
+#define RLIMIT_STACK		3	/* max stack size */
+#define RLIMIT_CORE		4	/* max core file size */
+
+#ifndef RLIMIT_RSS
+# define RLIMIT_RSS		5	/* max resident set size */
+#endif
+
+#ifndef RLIMIT_NPROC
+# define RLIMIT_NPROC		6	/* max number of processes */
+#endif
+
+#ifndef RLIMIT_NOFILE
+# define RLIMIT_NOFILE		7	/* max number of open files */
+#endif
+
+#ifndef RLIMIT_MEMLOCK
+# define RLIMIT_MEMLOCK		8	/* max locked-in-memory address space */
+#endif
+
+#ifndef RLIMIT_AS
+# define RLIMIT_AS		9	/* address space limit */
+#endif
+
+#define RLIMIT_LOCKS		10	/* maximum file locks held */
+#define RLIMIT_SIGPENDING	11	/* max number of pending signals */
+#define RLIMIT_MSGQUEUE		12	/* maximum bytes in POSIX mqueues */
+#define RLIMIT_NICE		13	/* max nice prio allowed to raise to
+					   0-39 for nice level 19 .. -20 */
+#define RLIMIT_RTPRIO		14	/* maximum realtime priority */
+#define RLIMIT_RTTIME		15	/* timeout for RT tasks in us */
+#define RLIM_NLIMITS		16
+
+/*
+ * SuS says limits have to be unsigned.
+ * Which makes a ton more sense anyway.
+ *
+ * Some architectures override this (for compatibility reasons):
+ */
+#ifndef RLIM_INFINITY
+# define RLIM_INFINITY		(~0UL)
+#endif
+
+/*
+ * RLIMIT_STACK default maximum - some architectures override it:
+ */
+#ifndef _STK_LIM_MAX
+# define _STK_LIM_MAX		RLIM_INFINITY
+#endif
+
+
+#endif /* _UAPI_ASM_GENERIC_RESOURCE_H */
diff --git a/include/asm-generic/sembuf.h b/include/uapi/asm-generic/sembuf.h
similarity index 100%
rename from include/asm-generic/sembuf.h
rename to include/uapi/asm-generic/sembuf.h
diff --git a/include/asm-generic/setup.h b/include/uapi/asm-generic/setup.h
similarity index 100%
rename from include/asm-generic/setup.h
rename to include/uapi/asm-generic/setup.h
diff --git a/include/asm-generic/shmbuf.h b/include/uapi/asm-generic/shmbuf.h
similarity index 100%
rename from include/asm-generic/shmbuf.h
rename to include/uapi/asm-generic/shmbuf.h
diff --git a/include/asm-generic/shmparam.h b/include/uapi/asm-generic/shmparam.h
similarity index 100%
rename from include/asm-generic/shmparam.h
rename to include/uapi/asm-generic/shmparam.h
diff --git a/include/uapi/asm-generic/siginfo.h b/include/uapi/asm-generic/siginfo.h
new file mode 100644
index 0000000..ba5be7f
--- /dev/null
+++ b/include/uapi/asm-generic/siginfo.h
@@ -0,0 +1,298 @@
+#ifndef _UAPI_ASM_GENERIC_SIGINFO_H
+#define _UAPI_ASM_GENERIC_SIGINFO_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+typedef union sigval {
+	int sival_int;
+	void __user *sival_ptr;
+} sigval_t;
+
+/*
+ * This is the size (including padding) of the part of the
+ * struct siginfo that is before the union.
+ */
+#ifndef __ARCH_SI_PREAMBLE_SIZE
+#define __ARCH_SI_PREAMBLE_SIZE	(3 * sizeof(int))
+#endif
+
+#define SI_MAX_SIZE	128
+#ifndef SI_PAD_SIZE
+#define SI_PAD_SIZE	((SI_MAX_SIZE - __ARCH_SI_PREAMBLE_SIZE) / sizeof(int))
+#endif
+
+#ifndef __ARCH_SI_UID_T
+#define __ARCH_SI_UID_T	__kernel_uid32_t
+#endif
+
+/*
+ * The default "si_band" type is "long", as specified by POSIX.
+ * However, some architectures want to override this to "int"
+ * for historical compatibility reasons, so we allow that.
+ */
+#ifndef __ARCH_SI_BAND_T
+#define __ARCH_SI_BAND_T long
+#endif
+
+#ifndef __ARCH_SI_CLOCK_T
+#define __ARCH_SI_CLOCK_T __kernel_clock_t
+#endif
+
+#ifndef __ARCH_SI_ATTRIBUTES
+#define __ARCH_SI_ATTRIBUTES
+#endif
+
+#ifndef HAVE_ARCH_SIGINFO_T
+
+typedef struct siginfo {
+	int si_signo;
+	int si_errno;
+	int si_code;
+
+	union {
+		int _pad[SI_PAD_SIZE];
+
+		/* kill() */
+		struct {
+			__kernel_pid_t _pid;	/* sender's pid */
+			__ARCH_SI_UID_T _uid;	/* sender's uid */
+		} _kill;
+
+		/* POSIX.1b timers */
+		struct {
+			__kernel_timer_t _tid;	/* timer id */
+			int _overrun;		/* overrun count */
+			char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)];
+			sigval_t _sigval;	/* same as below */
+			int _sys_private;       /* not to be passed to user */
+		} _timer;
+
+		/* POSIX.1b signals */
+		struct {
+			__kernel_pid_t _pid;	/* sender's pid */
+			__ARCH_SI_UID_T _uid;	/* sender's uid */
+			sigval_t _sigval;
+		} _rt;
+
+		/* SIGCHLD */
+		struct {
+			__kernel_pid_t _pid;	/* which child */
+			__ARCH_SI_UID_T _uid;	/* sender's uid */
+			int _status;		/* exit code */
+			__ARCH_SI_CLOCK_T _utime;
+			__ARCH_SI_CLOCK_T _stime;
+		} _sigchld;
+
+		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+		struct {
+			void __user *_addr; /* faulting insn/memory ref. */
+#ifdef __ARCH_SI_TRAPNO
+			int _trapno;	/* TRAP # which caused the signal */
+#endif
+			short _addr_lsb; /* LSB of the reported address */
+		} _sigfault;
+
+		/* SIGPOLL */
+		struct {
+			__ARCH_SI_BAND_T _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			int _fd;
+		} _sigpoll;
+
+		/* SIGSYS */
+		struct {
+			void __user *_call_addr; /* calling user insn */
+			int _syscall;	/* triggering system call number */
+			unsigned int _arch;	/* AUDIT_ARCH_* of syscall */
+		} _sigsys;
+	} _sifields;
+} __ARCH_SI_ATTRIBUTES siginfo_t;
+
+/* If the arch shares siginfo, then it has SIGSYS. */
+#define __ARCH_SIGSYS
+#endif
+
+/*
+ * How these fields are to be accessed.
+ */
+#define si_pid		_sifields._kill._pid
+#define si_uid		_sifields._kill._uid
+#define si_tid		_sifields._timer._tid
+#define si_overrun	_sifields._timer._overrun
+#define si_sys_private  _sifields._timer._sys_private
+#define si_status	_sifields._sigchld._status
+#define si_utime	_sifields._sigchld._utime
+#define si_stime	_sifields._sigchld._stime
+#define si_value	_sifields._rt._sigval
+#define si_int		_sifields._rt._sigval.sival_int
+#define si_ptr		_sifields._rt._sigval.sival_ptr
+#define si_addr		_sifields._sigfault._addr
+#ifdef __ARCH_SI_TRAPNO
+#define si_trapno	_sifields._sigfault._trapno
+#endif
+#define si_addr_lsb	_sifields._sigfault._addr_lsb
+#define si_band		_sifields._sigpoll._band
+#define si_fd		_sifields._sigpoll._fd
+#ifdef __ARCH_SIGSYS
+#define si_call_addr	_sifields._sigsys._call_addr
+#define si_syscall	_sifields._sigsys._syscall
+#define si_arch		_sifields._sigsys._arch
+#endif
+
+#ifndef __KERNEL__
+#define __SI_KILL	0
+#define __SI_TIMER	0
+#define __SI_POLL	0
+#define __SI_FAULT	0
+#define __SI_CHLD	0
+#define __SI_RT		0
+#define __SI_MESGQ	0
+#define __SI_SYS	0
+#define __SI_CODE(T,N)	(N)
+#endif
+
+/*
+ * si_code values
+ * Digital reserves positive values for kernel-generated signals.
+ */
+#define SI_USER		0		/* sent by kill, sigsend, raise */
+#define SI_KERNEL	0x80		/* sent by the kernel from somewhere */
+#define SI_QUEUE	-1		/* sent by sigqueue */
+#define SI_TIMER __SI_CODE(__SI_TIMER,-2) /* sent by timer expiration */
+#define SI_MESGQ __SI_CODE(__SI_MESGQ,-3) /* sent by real time mesq state change */
+#define SI_ASYNCIO	-4		/* sent by AIO completion */
+#define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
+#define SI_DETHREAD	-7		/* sent by execve() killing subsidiary threads */
+
+#define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
+#define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
+
+/*
+ * SIGILL si_codes
+ */
+#define ILL_ILLOPC	(__SI_FAULT|1)	/* illegal opcode */
+#define ILL_ILLOPN	(__SI_FAULT|2)	/* illegal operand */
+#define ILL_ILLADR	(__SI_FAULT|3)	/* illegal addressing mode */
+#define ILL_ILLTRP	(__SI_FAULT|4)	/* illegal trap */
+#define ILL_PRVOPC	(__SI_FAULT|5)	/* privileged opcode */
+#define ILL_PRVREG	(__SI_FAULT|6)	/* privileged register */
+#define ILL_COPROC	(__SI_FAULT|7)	/* coprocessor error */
+#define ILL_BADSTK	(__SI_FAULT|8)	/* internal stack error */
+#define NSIGILL		8
+
+/*
+ * SIGFPE si_codes
+ */
+#define FPE_INTDIV	(__SI_FAULT|1)	/* integer divide by zero */
+#define FPE_INTOVF	(__SI_FAULT|2)	/* integer overflow */
+#define FPE_FLTDIV	(__SI_FAULT|3)	/* floating point divide by zero */
+#define FPE_FLTOVF	(__SI_FAULT|4)	/* floating point overflow */
+#define FPE_FLTUND	(__SI_FAULT|5)	/* floating point underflow */
+#define FPE_FLTRES	(__SI_FAULT|6)	/* floating point inexact result */
+#define FPE_FLTINV	(__SI_FAULT|7)	/* floating point invalid operation */
+#define FPE_FLTSUB	(__SI_FAULT|8)	/* subscript out of range */
+#define NSIGFPE		8
+
+/*
+ * SIGSEGV si_codes
+ */
+#define SEGV_MAPERR	(__SI_FAULT|1)	/* address not mapped to object */
+#define SEGV_ACCERR	(__SI_FAULT|2)	/* invalid permissions for mapped object */
+#define NSIGSEGV	2
+
+/*
+ * SIGBUS si_codes
+ */
+#define BUS_ADRALN	(__SI_FAULT|1)	/* invalid address alignment */
+#define BUS_ADRERR	(__SI_FAULT|2)	/* non-existent physical address */
+#define BUS_OBJERR	(__SI_FAULT|3)	/* object specific hardware error */
+/* hardware memory error consumed on a machine check: action required */
+#define BUS_MCEERR_AR	(__SI_FAULT|4)
+/* hardware memory error detected in process but not consumed: action optional*/
+#define BUS_MCEERR_AO	(__SI_FAULT|5)
+#define NSIGBUS		5
+
+/*
+ * SIGTRAP si_codes
+ */
+#define TRAP_BRKPT	(__SI_FAULT|1)	/* process breakpoint */
+#define TRAP_TRACE	(__SI_FAULT|2)	/* process trace trap */
+#define TRAP_BRANCH     (__SI_FAULT|3)  /* process taken branch trap */
+#define TRAP_HWBKPT     (__SI_FAULT|4)  /* hardware breakpoint/watchpoint */
+#define NSIGTRAP	4
+
+/*
+ * SIGCHLD si_codes
+ */
+#define CLD_EXITED	(__SI_CHLD|1)	/* child has exited */
+#define CLD_KILLED	(__SI_CHLD|2)	/* child was killed */
+#define CLD_DUMPED	(__SI_CHLD|3)	/* child terminated abnormally */
+#define CLD_TRAPPED	(__SI_CHLD|4)	/* traced child has trapped */
+#define CLD_STOPPED	(__SI_CHLD|5)	/* child has stopped */
+#define CLD_CONTINUED	(__SI_CHLD|6)	/* stopped child has continued */
+#define NSIGCHLD	6
+
+/*
+ * SIGPOLL si_codes
+ */
+#define POLL_IN		(__SI_POLL|1)	/* data input available */
+#define POLL_OUT	(__SI_POLL|2)	/* output buffers available */
+#define POLL_MSG	(__SI_POLL|3)	/* input message available */
+#define POLL_ERR	(__SI_POLL|4)	/* i/o error */
+#define POLL_PRI	(__SI_POLL|5)	/* high priority input available */
+#define POLL_HUP	(__SI_POLL|6)	/* device disconnected */
+#define NSIGPOLL	6
+
+/*
+ * SIGSYS si_codes
+ */
+#define SYS_SECCOMP		(__SI_SYS|1)	/* seccomp triggered */
+#define NSIGSYS	1
+
+/*
+ * sigevent definitions
+ * 
+ * It seems likely that SIGEV_THREAD will have to be handled from 
+ * userspace, libpthread transmuting it to SIGEV_SIGNAL, which the
+ * thread manager then catches and does the appropriate nonsense.
+ * However, everything is written out here so as to not get lost.
+ */
+#define SIGEV_SIGNAL	0	/* notify via signal */
+#define SIGEV_NONE	1	/* other notification: meaningless */
+#define SIGEV_THREAD	2	/* deliver via thread creation */
+#define SIGEV_THREAD_ID 4	/* deliver to thread */
+
+/*
+ * This works because the alignment is ok on all current architectures
+ * but we leave open this being overridden in the future
+ */
+#ifndef __ARCH_SIGEV_PREAMBLE_SIZE
+#define __ARCH_SIGEV_PREAMBLE_SIZE	(sizeof(int) * 2 + sizeof(sigval_t))
+#endif
+
+#define SIGEV_MAX_SIZE	64
+#define SIGEV_PAD_SIZE	((SIGEV_MAX_SIZE - __ARCH_SIGEV_PREAMBLE_SIZE) \
+		/ sizeof(int))
+
+typedef struct sigevent {
+	sigval_t sigev_value;
+	int sigev_signo;
+	int sigev_notify;
+	union {
+		int _pad[SIGEV_PAD_SIZE];
+		 int _tid;
+
+		struct {
+			void (*_function)(sigval_t);
+			void *_attribute;	/* really pthread_attr_t */
+		} _sigev_thread;
+	} _sigev_un;
+} sigevent_t;
+
+#define sigev_notify_function	_sigev_un._sigev_thread._function
+#define sigev_notify_attributes	_sigev_un._sigev_thread._attribute
+#define sigev_notify_thread_id	 _sigev_un._tid
+
+
+#endif /* _UAPI_ASM_GENERIC_SIGINFO_H */
diff --git a/include/asm-generic/signal-defs.h b/include/uapi/asm-generic/signal-defs.h
similarity index 100%
rename from include/asm-generic/signal-defs.h
rename to include/uapi/asm-generic/signal-defs.h
diff --git a/include/uapi/asm-generic/signal.h b/include/uapi/asm-generic/signal.h
new file mode 100644
index 0000000..0a78028
--- /dev/null
+++ b/include/uapi/asm-generic/signal.h
@@ -0,0 +1,123 @@
+#ifndef _UAPI__ASM_GENERIC_SIGNAL_H
+#define _UAPI__ASM_GENERIC_SIGNAL_H
+
+#include <linux/types.h>
+
+#define _NSIG		64
+#define _NSIG_BPW	__BITS_PER_LONG
+#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
+
+#define SIGHUP		 1
+#define SIGINT		 2
+#define SIGQUIT		 3
+#define SIGILL		 4
+#define SIGTRAP		 5
+#define SIGABRT		 6
+#define SIGIOT		 6
+#define SIGBUS		 7
+#define SIGFPE		 8
+#define SIGKILL		 9
+#define SIGUSR1		10
+#define SIGSEGV		11
+#define SIGUSR2		12
+#define SIGPIPE		13
+#define SIGALRM		14
+#define SIGTERM		15
+#define SIGSTKFLT	16
+#define SIGCHLD		17
+#define SIGCONT		18
+#define SIGSTOP		19
+#define SIGTSTP		20
+#define SIGTTIN		21
+#define SIGTTOU		22
+#define SIGURG		23
+#define SIGXCPU		24
+#define SIGXFSZ		25
+#define SIGVTALRM	26
+#define SIGPROF		27
+#define SIGWINCH	28
+#define SIGIO		29
+#define SIGPOLL		SIGIO
+/*
+#define SIGLOST		29
+*/
+#define SIGPWR		30
+#define SIGSYS		31
+#define	SIGUNUSED	31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN	32
+#ifndef SIGRTMAX
+#define SIGRTMAX	_NSIG
+#endif
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP	0x00000001
+#define SA_NOCLDWAIT	0x00000002
+#define SA_SIGINFO	0x00000004
+#define SA_ONSTACK	0x08000000
+#define SA_RESTART	0x10000000
+#define SA_NODEFER	0x40000000
+#define SA_RESETHAND	0x80000000
+
+#define SA_NOMASK	SA_NODEFER
+#define SA_ONESHOT	SA_RESETHAND
+
+/*
+ * New architectures should not define the obsolete
+ *	SA_RESTORER	0x04000000
+ */
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK	1
+#define SS_DISABLE	2
+
+#define MINSIGSTKSZ	2048
+#define SIGSTKSZ	8192
+
+#ifndef __ASSEMBLY__
+typedef struct {
+	unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+/* not actually used, but required for linux/syscalls.h */
+typedef unsigned long old_sigset_t;
+
+#include <asm-generic/signal-defs.h>
+
+struct sigaction {
+	__sighandler_t sa_handler;
+	unsigned long sa_flags;
+#ifdef SA_RESTORER
+	__sigrestore_t sa_restorer;
+#endif
+	sigset_t sa_mask;		/* mask last for extensibility */
+};
+
+struct k_sigaction {
+	struct sigaction sa;
+};
+
+typedef struct sigaltstack {
+	void __user *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+} stack_t;
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _UAPI__ASM_GENERIC_SIGNAL_H */
diff --git a/include/asm-generic/socket.h b/include/uapi/asm-generic/socket.h
similarity index 100%
rename from include/asm-generic/socket.h
rename to include/uapi/asm-generic/socket.h
diff --git a/include/asm-generic/sockios.h b/include/uapi/asm-generic/sockios.h
similarity index 100%
rename from include/asm-generic/sockios.h
rename to include/uapi/asm-generic/sockios.h
diff --git a/include/asm-generic/stat.h b/include/uapi/asm-generic/stat.h
similarity index 100%
rename from include/asm-generic/stat.h
rename to include/uapi/asm-generic/stat.h
diff --git a/include/uapi/asm-generic/statfs.h b/include/uapi/asm-generic/statfs.h
new file mode 100644
index 0000000..0999647
--- /dev/null
+++ b/include/uapi/asm-generic/statfs.h
@@ -0,0 +1,83 @@
+#ifndef _UAPI_GENERIC_STATFS_H
+#define _UAPI_GENERIC_STATFS_H
+
+#include <linux/types.h>
+
+
+/*
+ * Most 64-bit platforms use 'long', while most 32-bit platforms use '__u32'.
+ * Yes, they differ in signedness as well as size.
+ * Special cases can override it for themselves -- except for S390x, which
+ * is just a little too special for us. And MIPS, which I'm not touching
+ * with a 10' pole.
+ */
+#ifndef __statfs_word
+#if __BITS_PER_LONG == 64
+#define __statfs_word long
+#else
+#define __statfs_word __u32
+#endif
+#endif
+
+struct statfs {
+	__statfs_word f_type;
+	__statfs_word f_bsize;
+	__statfs_word f_blocks;
+	__statfs_word f_bfree;
+	__statfs_word f_bavail;
+	__statfs_word f_files;
+	__statfs_word f_ffree;
+	__kernel_fsid_t f_fsid;
+	__statfs_word f_namelen;
+	__statfs_word f_frsize;
+	__statfs_word f_flags;
+	__statfs_word f_spare[4];
+};
+
+/*
+ * ARM needs to avoid the 32-bit padding at the end, for consistency
+ * between EABI and OABI 
+ */
+#ifndef ARCH_PACK_STATFS64
+#define ARCH_PACK_STATFS64
+#endif
+
+struct statfs64 {
+	__statfs_word f_type;
+	__statfs_word f_bsize;
+	__u64 f_blocks;
+	__u64 f_bfree;
+	__u64 f_bavail;
+	__u64 f_files;
+	__u64 f_ffree;
+	__kernel_fsid_t f_fsid;
+	__statfs_word f_namelen;
+	__statfs_word f_frsize;
+	__statfs_word f_flags;
+	__statfs_word f_spare[4];
+} ARCH_PACK_STATFS64;
+
+/* 
+ * IA64 and x86_64 need to avoid the 32-bit padding at the end,
+ * to be compatible with the i386 ABI
+ */
+#ifndef ARCH_PACK_COMPAT_STATFS64
+#define ARCH_PACK_COMPAT_STATFS64
+#endif
+
+struct compat_statfs64 {
+	__u32 f_type;
+	__u32 f_bsize;
+	__u64 f_blocks;
+	__u64 f_bfree;
+	__u64 f_bavail;
+	__u64 f_files;
+	__u64 f_ffree;
+	__kernel_fsid_t f_fsid;
+	__u32 f_namelen;
+	__u32 f_frsize;
+	__u32 f_flags;
+	__u32 f_spare[4];
+} ARCH_PACK_COMPAT_STATFS64;
+
+#endif /* _UAPI_GENERIC_STATFS_H */
diff --git a/include/asm-generic/swab.h b/include/uapi/asm-generic/swab.h
similarity index 100%
rename from include/asm-generic/swab.h
rename to include/uapi/asm-generic/swab.h
diff --git a/include/asm-generic/termbits.h b/include/uapi/asm-generic/termbits.h
similarity index 100%
rename from include/asm-generic/termbits.h
rename to include/uapi/asm-generic/termbits.h
diff --git a/include/uapi/asm-generic/termios.h b/include/uapi/asm-generic/termios.h
new file mode 100644
index 0000000..0881760
--- /dev/null
+++ b/include/uapi/asm-generic/termios.h
@@ -0,0 +1,50 @@
+#ifndef _UAPI_ASM_GENERIC_TERMIOS_H
+#define _UAPI_ASM_GENERIC_TERMIOS_H
+/*
+ * Most architectures have straight copies of the x86 code, with
+ * varying levels of bug fixes on top. Usually it's a good idea
+ * to use this generic version instead, but be careful to avoid
+ * ABI changes.
+ * New architectures should not provide their own version.
+ */
+
+#include <asm/termbits.h>
+#include <asm/ioctls.h>
+
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+	unsigned short c_iflag;		/* input mode flags */
+	unsigned short c_oflag;		/* output mode flags */
+	unsigned short c_cflag;		/* control mode flags */
+	unsigned short c_lflag;		/* local mode flags */
+	unsigned char c_line;		/* line discipline */
+	unsigned char c_cc[NCC];	/* control characters */
+};
+
+/* modem lines */
+#define TIOCM_LE	0x001
+#define TIOCM_DTR	0x002
+#define TIOCM_RTS	0x004
+#define TIOCM_ST	0x008
+#define TIOCM_SR	0x010
+#define TIOCM_CTS	0x020
+#define TIOCM_CAR	0x040
+#define TIOCM_RNG	0x080
+#define TIOCM_DSR	0x100
+#define TIOCM_CD	TIOCM_CAR
+#define TIOCM_RI	TIOCM_RNG
+#define TIOCM_OUT1	0x2000
+#define TIOCM_OUT2	0x4000
+#define TIOCM_LOOP	0x8000
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+
+
+#endif /* _UAPI_ASM_GENERIC_TERMIOS_H */
diff --git a/include/asm-generic/types.h b/include/uapi/asm-generic/types.h
similarity index 100%
rename from include/asm-generic/types.h
rename to include/uapi/asm-generic/types.h
diff --git a/include/asm-generic/ucontext.h b/include/uapi/asm-generic/ucontext.h
similarity index 100%
rename from include/asm-generic/ucontext.h
rename to include/uapi/asm-generic/ucontext.h
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
new file mode 100644
index 0000000..6e595ba
--- /dev/null
+++ b/include/uapi/asm-generic/unistd.h
@@ -0,0 +1,902 @@
+#include <asm/bitsperlong.h>
+
+/*
+ * This file contains the system call numbers, based on the
+ * layout of the x86-64 architecture, which embeds the
+ * pointer to the syscall in the table.
+ *
+ * As a basic principle, no duplication of functionality
+ * should be added, e.g. we don't use lseek when llseek
+ * is present. New architectures should use this file
+ * and implement the less feature-full calls in user space.
+ */
+
+#ifndef __SYSCALL
+#define __SYSCALL(x, y)
+#endif
+
+#if __BITS_PER_LONG == 32 || defined(__SYSCALL_COMPAT)
+#define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _32)
+#else
+#define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _64)
+#endif
+
+#ifdef __SYSCALL_COMPAT
+#define __SC_COMP(_nr, _sys, _comp) __SYSCALL(_nr, _comp)
+#define __SC_COMP_3264(_nr, _32, _64, _comp) __SYSCALL(_nr, _comp)
+#else
+#define __SC_COMP(_nr, _sys, _comp) __SYSCALL(_nr, _sys)
+#define __SC_COMP_3264(_nr, _32, _64, _comp) __SC_3264(_nr, _32, _64)
+#endif
+
+#define __NR_io_setup 0
+__SC_COMP(__NR_io_setup, sys_io_setup, compat_sys_io_setup)
+#define __NR_io_destroy 1
+__SYSCALL(__NR_io_destroy, sys_io_destroy)
+#define __NR_io_submit 2
+__SC_COMP(__NR_io_submit, sys_io_submit, compat_sys_io_submit)
+#define __NR_io_cancel 3
+__SYSCALL(__NR_io_cancel, sys_io_cancel)
+#define __NR_io_getevents 4
+__SC_COMP(__NR_io_getevents, sys_io_getevents, compat_sys_io_getevents)
+
+/* fs/xattr.c */
+#define __NR_setxattr 5
+__SYSCALL(__NR_setxattr, sys_setxattr)
+#define __NR_lsetxattr 6
+__SYSCALL(__NR_lsetxattr, sys_lsetxattr)
+#define __NR_fsetxattr 7
+__SYSCALL(__NR_fsetxattr, sys_fsetxattr)
+#define __NR_getxattr 8
+__SYSCALL(__NR_getxattr, sys_getxattr)
+#define __NR_lgetxattr 9
+__SYSCALL(__NR_lgetxattr, sys_lgetxattr)
+#define __NR_fgetxattr 10
+__SYSCALL(__NR_fgetxattr, sys_fgetxattr)
+#define __NR_listxattr 11
+__SYSCALL(__NR_listxattr, sys_listxattr)
+#define __NR_llistxattr 12
+__SYSCALL(__NR_llistxattr, sys_llistxattr)
+#define __NR_flistxattr 13
+__SYSCALL(__NR_flistxattr, sys_flistxattr)
+#define __NR_removexattr 14
+__SYSCALL(__NR_removexattr, sys_removexattr)
+#define __NR_lremovexattr 15
+__SYSCALL(__NR_lremovexattr, sys_lremovexattr)
+#define __NR_fremovexattr 16
+__SYSCALL(__NR_fremovexattr, sys_fremovexattr)
+
+/* fs/dcache.c */
+#define __NR_getcwd 17
+__SYSCALL(__NR_getcwd, sys_getcwd)
+
+/* fs/cookies.c */
+#define __NR_lookup_dcookie 18
+__SC_COMP(__NR_lookup_dcookie, sys_lookup_dcookie, compat_sys_lookup_dcookie)
+
+/* fs/eventfd.c */
+#define __NR_eventfd2 19
+__SYSCALL(__NR_eventfd2, sys_eventfd2)
+
+/* fs/eventpoll.c */
+#define __NR_epoll_create1 20
+__SYSCALL(__NR_epoll_create1, sys_epoll_create1)
+#define __NR_epoll_ctl 21
+__SYSCALL(__NR_epoll_ctl, sys_epoll_ctl)
+#define __NR_epoll_pwait 22
+__SC_COMP(__NR_epoll_pwait, sys_epoll_pwait, compat_sys_epoll_pwait)
+
+/* fs/fcntl.c */
+#define __NR_dup 23
+__SYSCALL(__NR_dup, sys_dup)
+#define __NR_dup3 24
+__SYSCALL(__NR_dup3, sys_dup3)
+#define __NR3264_fcntl 25
+__SC_COMP_3264(__NR3264_fcntl, sys_fcntl64, sys_fcntl, compat_sys_fcntl64)
+
+/* fs/inotify_user.c */
+#define __NR_inotify_init1 26
+__SYSCALL(__NR_inotify_init1, sys_inotify_init1)
+#define __NR_inotify_add_watch 27
+__SYSCALL(__NR_inotify_add_watch, sys_inotify_add_watch)
+#define __NR_inotify_rm_watch 28
+__SYSCALL(__NR_inotify_rm_watch, sys_inotify_rm_watch)
+
+/* fs/ioctl.c */
+#define __NR_ioctl 29
+__SC_COMP(__NR_ioctl, sys_ioctl, compat_sys_ioctl)
+
+/* fs/ioprio.c */
+#define __NR_ioprio_set 30
+__SYSCALL(__NR_ioprio_set, sys_ioprio_set)
+#define __NR_ioprio_get 31
+__SYSCALL(__NR_ioprio_get, sys_ioprio_get)
+
+/* fs/locks.c */
+#define __NR_flock 32
+__SYSCALL(__NR_flock, sys_flock)
+
+/* fs/namei.c */
+#define __NR_mknodat 33
+__SYSCALL(__NR_mknodat, sys_mknodat)
+#define __NR_mkdirat 34
+__SYSCALL(__NR_mkdirat, sys_mkdirat)
+#define __NR_unlinkat 35
+__SYSCALL(__NR_unlinkat, sys_unlinkat)
+#define __NR_symlinkat 36
+__SYSCALL(__NR_symlinkat, sys_symlinkat)
+#define __NR_linkat 37
+__SYSCALL(__NR_linkat, sys_linkat)
+#define __NR_renameat 38
+__SYSCALL(__NR_renameat, sys_renameat)
+
+/* fs/namespace.c */
+#define __NR_umount2 39
+__SYSCALL(__NR_umount2, sys_umount)
+#define __NR_mount 40
+__SC_COMP(__NR_mount, sys_mount, compat_sys_mount)
+#define __NR_pivot_root 41
+__SYSCALL(__NR_pivot_root, sys_pivot_root)
+
+/* fs/nfsctl.c */
+#define __NR_nfsservctl 42
+__SYSCALL(__NR_nfsservctl, sys_ni_syscall)
+
+/* fs/open.c */
+#define __NR3264_statfs 43
+__SC_COMP_3264(__NR3264_statfs, sys_statfs64, sys_statfs, \
+	       compat_sys_statfs64)
+#define __NR3264_fstatfs 44
+__SC_COMP_3264(__NR3264_fstatfs, sys_fstatfs64, sys_fstatfs, \
+	       compat_sys_fstatfs64)
+#define __NR3264_truncate 45
+__SC_COMP_3264(__NR3264_truncate, sys_truncate64, sys_truncate, \
+	       compat_sys_truncate64)
+#define __NR3264_ftruncate 46
+__SC_COMP_3264(__NR3264_ftruncate, sys_ftruncate64, sys_ftruncate, \
+	       compat_sys_ftruncate64)
+
+#define __NR_fallocate 47
+__SC_COMP(__NR_fallocate, sys_fallocate, compat_sys_fallocate)
+#define __NR_faccessat 48
+__SYSCALL(__NR_faccessat, sys_faccessat)
+#define __NR_chdir 49
+__SYSCALL(__NR_chdir, sys_chdir)
+#define __NR_fchdir 50
+__SYSCALL(__NR_fchdir, sys_fchdir)
+#define __NR_chroot 51
+__SYSCALL(__NR_chroot, sys_chroot)
+#define __NR_fchmod 52
+__SYSCALL(__NR_fchmod, sys_fchmod)
+#define __NR_fchmodat 53
+__SYSCALL(__NR_fchmodat, sys_fchmodat)
+#define __NR_fchownat 54
+__SYSCALL(__NR_fchownat, sys_fchownat)
+#define __NR_fchown 55
+__SYSCALL(__NR_fchown, sys_fchown)
+#define __NR_openat 56
+__SC_COMP(__NR_openat, sys_openat, compat_sys_openat)
+#define __NR_close 57
+__SYSCALL(__NR_close, sys_close)
+#define __NR_vhangup 58
+__SYSCALL(__NR_vhangup, sys_vhangup)
+
+/* fs/pipe.c */
+#define __NR_pipe2 59
+__SYSCALL(__NR_pipe2, sys_pipe2)
+
+/* fs/quota.c */
+#define __NR_quotactl 60
+__SYSCALL(__NR_quotactl, sys_quotactl)
+
+/* fs/readdir.c */
+#define __NR_getdents64 61
+__SC_COMP(__NR_getdents64, sys_getdents64, compat_sys_getdents64)
+
+/* fs/read_write.c */
+#define __NR3264_lseek 62
+__SC_3264(__NR3264_lseek, sys_llseek, sys_lseek)
+#define __NR_read 63
+__SYSCALL(__NR_read, sys_read)
+#define __NR_write 64
+__SYSCALL(__NR_write, sys_write)
+#define __NR_readv 65
+__SC_COMP(__NR_readv, sys_readv, compat_sys_readv)
+#define __NR_writev 66
+__SC_COMP(__NR_writev, sys_writev, compat_sys_writev)
+#define __NR_pread64 67
+__SC_COMP(__NR_pread64, sys_pread64, compat_sys_pread64)
+#define __NR_pwrite64 68
+__SC_COMP(__NR_pwrite64, sys_pwrite64, compat_sys_pwrite64)
+#define __NR_preadv 69
+__SC_COMP(__NR_preadv, sys_preadv, compat_sys_preadv)
+#define __NR_pwritev 70
+__SC_COMP(__NR_pwritev, sys_pwritev, compat_sys_pwritev)
+
+/* fs/sendfile.c */
+#define __NR3264_sendfile 71
+__SYSCALL(__NR3264_sendfile, sys_sendfile64)
+
+/* fs/select.c */
+#define __NR_pselect6 72
+__SC_COMP(__NR_pselect6, sys_pselect6, compat_sys_pselect6)
+#define __NR_ppoll 73
+__SC_COMP(__NR_ppoll, sys_ppoll, compat_sys_ppoll)
+
+/* fs/signalfd.c */
+#define __NR_signalfd4 74
+__SC_COMP(__NR_signalfd4, sys_signalfd4, compat_sys_signalfd4)
+
+/* fs/splice.c */
+#define __NR_vmsplice 75
+__SC_COMP(__NR_vmsplice, sys_vmsplice, compat_sys_vmsplice)
+#define __NR_splice 76
+__SYSCALL(__NR_splice, sys_splice)
+#define __NR_tee 77
+__SYSCALL(__NR_tee, sys_tee)
+
+/* fs/stat.c */
+#define __NR_readlinkat 78
+__SYSCALL(__NR_readlinkat, sys_readlinkat)
+#define __NR3264_fstatat 79
+__SC_3264(__NR3264_fstatat, sys_fstatat64, sys_newfstatat)
+#define __NR3264_fstat 80
+__SC_3264(__NR3264_fstat, sys_fstat64, sys_newfstat)
+
+/* fs/sync.c */
+#define __NR_sync 81
+__SYSCALL(__NR_sync, sys_sync)
+#define __NR_fsync 82
+__SYSCALL(__NR_fsync, sys_fsync)
+#define __NR_fdatasync 83
+__SYSCALL(__NR_fdatasync, sys_fdatasync)
+#ifdef __ARCH_WANT_SYNC_FILE_RANGE2
+#define __NR_sync_file_range2 84
+__SC_COMP(__NR_sync_file_range2, sys_sync_file_range2, \
+	  compat_sys_sync_file_range2)
+#else
+#define __NR_sync_file_range 84
+__SC_COMP(__NR_sync_file_range, sys_sync_file_range, \
+	  compat_sys_sync_file_range)
+#endif
+
+/* fs/timerfd.c */
+#define __NR_timerfd_create 85
+__SYSCALL(__NR_timerfd_create, sys_timerfd_create)
+#define __NR_timerfd_settime 86
+__SC_COMP(__NR_timerfd_settime, sys_timerfd_settime, \
+	  compat_sys_timerfd_settime)
+#define __NR_timerfd_gettime 87
+__SC_COMP(__NR_timerfd_gettime, sys_timerfd_gettime, \
+	  compat_sys_timerfd_gettime)
+
+/* fs/utimes.c */
+#define __NR_utimensat 88
+__SC_COMP(__NR_utimensat, sys_utimensat, compat_sys_utimensat)
+
+/* kernel/acct.c */
+#define __NR_acct 89
+__SYSCALL(__NR_acct, sys_acct)
+
+/* kernel/capability.c */
+#define __NR_capget 90
+__SYSCALL(__NR_capget, sys_capget)
+#define __NR_capset 91
+__SYSCALL(__NR_capset, sys_capset)
+
+/* kernel/exec_domain.c */
+#define __NR_personality 92
+__SYSCALL(__NR_personality, sys_personality)
+
+/* kernel/exit.c */
+#define __NR_exit 93
+__SYSCALL(__NR_exit, sys_exit)
+#define __NR_exit_group 94
+__SYSCALL(__NR_exit_group, sys_exit_group)
+#define __NR_waitid 95
+__SC_COMP(__NR_waitid, sys_waitid, compat_sys_waitid)
+
+/* kernel/fork.c */
+#define __NR_set_tid_address 96
+__SYSCALL(__NR_set_tid_address, sys_set_tid_address)
+#define __NR_unshare 97
+__SYSCALL(__NR_unshare, sys_unshare)
+
+/* kernel/futex.c */
+#define __NR_futex 98
+__SC_COMP(__NR_futex, sys_futex, compat_sys_futex)
+#define __NR_set_robust_list 99
+__SC_COMP(__NR_set_robust_list, sys_set_robust_list, \
+	  compat_sys_set_robust_list)
+#define __NR_get_robust_list 100
+__SC_COMP(__NR_get_robust_list, sys_get_robust_list, \
+	  compat_sys_get_robust_list)
+
+/* kernel/hrtimer.c */
+#define __NR_nanosleep 101
+__SC_COMP(__NR_nanosleep, sys_nanosleep, compat_sys_nanosleep)
+
+/* kernel/itimer.c */
+#define __NR_getitimer 102
+__SC_COMP(__NR_getitimer, sys_getitimer, compat_sys_getitimer)
+#define __NR_setitimer 103
+__SC_COMP(__NR_setitimer, sys_setitimer, compat_sys_setitimer)
+
+/* kernel/kexec.c */
+#define __NR_kexec_load 104
+__SC_COMP(__NR_kexec_load, sys_kexec_load, compat_sys_kexec_load)
+
+/* kernel/module.c */
+#define __NR_init_module 105
+__SYSCALL(__NR_init_module, sys_init_module)
+#define __NR_delete_module 106
+__SYSCALL(__NR_delete_module, sys_delete_module)
+
+/* kernel/posix-timers.c */
+#define __NR_timer_create 107
+__SC_COMP(__NR_timer_create, sys_timer_create, compat_sys_timer_create)
+#define __NR_timer_gettime 108
+__SC_COMP(__NR_timer_gettime, sys_timer_gettime, compat_sys_timer_gettime)
+#define __NR_timer_getoverrun 109
+__SYSCALL(__NR_timer_getoverrun, sys_timer_getoverrun)
+#define __NR_timer_settime 110
+__SC_COMP(__NR_timer_settime, sys_timer_settime, compat_sys_timer_settime)
+#define __NR_timer_delete 111
+__SYSCALL(__NR_timer_delete, sys_timer_delete)
+#define __NR_clock_settime 112
+__SC_COMP(__NR_clock_settime, sys_clock_settime, compat_sys_clock_settime)
+#define __NR_clock_gettime 113
+__SC_COMP(__NR_clock_gettime, sys_clock_gettime, compat_sys_clock_gettime)
+#define __NR_clock_getres 114
+__SC_COMP(__NR_clock_getres, sys_clock_getres, compat_sys_clock_getres)
+#define __NR_clock_nanosleep 115
+__SC_COMP(__NR_clock_nanosleep, sys_clock_nanosleep, \
+	  compat_sys_clock_nanosleep)
+
+/* kernel/printk.c */
+#define __NR_syslog 116
+__SYSCALL(__NR_syslog, sys_syslog)
+
+/* kernel/ptrace.c */
+#define __NR_ptrace 117
+__SYSCALL(__NR_ptrace, sys_ptrace)
+
+/* kernel/sched.c */
+#define __NR_sched_setparam 118
+__SYSCALL(__NR_sched_setparam, sys_sched_setparam)
+#define __NR_sched_setscheduler 119
+__SYSCALL(__NR_sched_setscheduler, sys_sched_setscheduler)
+#define __NR_sched_getscheduler 120
+__SYSCALL(__NR_sched_getscheduler, sys_sched_getscheduler)
+#define __NR_sched_getparam 121
+__SYSCALL(__NR_sched_getparam, sys_sched_getparam)
+#define __NR_sched_setaffinity 122
+__SC_COMP(__NR_sched_setaffinity, sys_sched_setaffinity, \
+	  compat_sys_sched_setaffinity)
+#define __NR_sched_getaffinity 123
+__SC_COMP(__NR_sched_getaffinity, sys_sched_getaffinity, \
+	  compat_sys_sched_getaffinity)
+#define __NR_sched_yield 124
+__SYSCALL(__NR_sched_yield, sys_sched_yield)
+#define __NR_sched_get_priority_max 125
+__SYSCALL(__NR_sched_get_priority_max, sys_sched_get_priority_max)
+#define __NR_sched_get_priority_min 126
+__SYSCALL(__NR_sched_get_priority_min, sys_sched_get_priority_min)
+#define __NR_sched_rr_get_interval 127
+__SC_COMP(__NR_sched_rr_get_interval, sys_sched_rr_get_interval, \
+	  compat_sys_sched_rr_get_interval)
+
+/* kernel/signal.c */
+#define __NR_restart_syscall 128
+__SYSCALL(__NR_restart_syscall, sys_restart_syscall)
+#define __NR_kill 129
+__SYSCALL(__NR_kill, sys_kill)
+#define __NR_tkill 130
+__SYSCALL(__NR_tkill, sys_tkill)
+#define __NR_tgkill 131
+__SYSCALL(__NR_tgkill, sys_tgkill)
+#define __NR_sigaltstack 132
+__SC_COMP(__NR_sigaltstack, sys_sigaltstack, compat_sys_sigaltstack)
+#define __NR_rt_sigsuspend 133
+__SC_COMP(__NR_rt_sigsuspend, sys_rt_sigsuspend, compat_sys_rt_sigsuspend)
+#define __NR_rt_sigaction 134
+__SC_COMP(__NR_rt_sigaction, sys_rt_sigaction, compat_sys_rt_sigaction)
+#define __NR_rt_sigprocmask 135
+__SYSCALL(__NR_rt_sigprocmask, sys_rt_sigprocmask)
+#define __NR_rt_sigpending 136
+__SYSCALL(__NR_rt_sigpending, sys_rt_sigpending)
+#define __NR_rt_sigtimedwait 137
+__SC_COMP(__NR_rt_sigtimedwait, sys_rt_sigtimedwait, \
+	  compat_sys_rt_sigtimedwait)
+#define __NR_rt_sigqueueinfo 138
+__SC_COMP(__NR_rt_sigqueueinfo, sys_rt_sigqueueinfo, \
+	  compat_sys_rt_sigqueueinfo)
+#define __NR_rt_sigreturn 139
+__SC_COMP(__NR_rt_sigreturn, sys_rt_sigreturn, compat_sys_rt_sigreturn)
+
+/* kernel/sys.c */
+#define __NR_setpriority 140
+__SYSCALL(__NR_setpriority, sys_setpriority)
+#define __NR_getpriority 141
+__SYSCALL(__NR_getpriority, sys_getpriority)
+#define __NR_reboot 142
+__SYSCALL(__NR_reboot, sys_reboot)
+#define __NR_setregid 143
+__SYSCALL(__NR_setregid, sys_setregid)
+#define __NR_setgid 144
+__SYSCALL(__NR_setgid, sys_setgid)
+#define __NR_setreuid 145
+__SYSCALL(__NR_setreuid, sys_setreuid)
+#define __NR_setuid 146
+__SYSCALL(__NR_setuid, sys_setuid)
+#define __NR_setresuid 147
+__SYSCALL(__NR_setresuid, sys_setresuid)
+#define __NR_getresuid 148
+__SYSCALL(__NR_getresuid, sys_getresuid)
+#define __NR_setresgid 149
+__SYSCALL(__NR_setresgid, sys_setresgid)
+#define __NR_getresgid 150
+__SYSCALL(__NR_getresgid, sys_getresgid)
+#define __NR_setfsuid 151
+__SYSCALL(__NR_setfsuid, sys_setfsuid)
+#define __NR_setfsgid 152
+__SYSCALL(__NR_setfsgid, sys_setfsgid)
+#define __NR_times 153
+__SC_COMP(__NR_times, sys_times, compat_sys_times)
+#define __NR_setpgid 154
+__SYSCALL(__NR_setpgid, sys_setpgid)
+#define __NR_getpgid 155
+__SYSCALL(__NR_getpgid, sys_getpgid)
+#define __NR_getsid 156
+__SYSCALL(__NR_getsid, sys_getsid)
+#define __NR_setsid 157
+__SYSCALL(__NR_setsid, sys_setsid)
+#define __NR_getgroups 158
+__SYSCALL(__NR_getgroups, sys_getgroups)
+#define __NR_setgroups 159
+__SYSCALL(__NR_setgroups, sys_setgroups)
+#define __NR_uname 160
+__SYSCALL(__NR_uname, sys_newuname)
+#define __NR_sethostname 161
+__SYSCALL(__NR_sethostname, sys_sethostname)
+#define __NR_setdomainname 162
+__SYSCALL(__NR_setdomainname, sys_setdomainname)
+#define __NR_getrlimit 163
+__SC_COMP(__NR_getrlimit, sys_getrlimit, compat_sys_getrlimit)
+#define __NR_setrlimit 164
+__SC_COMP(__NR_setrlimit, sys_setrlimit, compat_sys_setrlimit)
+#define __NR_getrusage 165
+__SC_COMP(__NR_getrusage, sys_getrusage, compat_sys_getrusage)
+#define __NR_umask 166
+__SYSCALL(__NR_umask, sys_umask)
+#define __NR_prctl 167
+__SYSCALL(__NR_prctl, sys_prctl)
+#define __NR_getcpu 168
+__SYSCALL(__NR_getcpu, sys_getcpu)
+
+/* kernel/time.c */
+#define __NR_gettimeofday 169
+__SC_COMP(__NR_gettimeofday, sys_gettimeofday, compat_sys_gettimeofday)
+#define __NR_settimeofday 170
+__SC_COMP(__NR_settimeofday, sys_settimeofday, compat_sys_settimeofday)
+#define __NR_adjtimex 171
+__SC_COMP(__NR_adjtimex, sys_adjtimex, compat_sys_adjtimex)
+
+/* kernel/timer.c */
+#define __NR_getpid 172
+__SYSCALL(__NR_getpid, sys_getpid)
+#define __NR_getppid 173
+__SYSCALL(__NR_getppid, sys_getppid)
+#define __NR_getuid 174
+__SYSCALL(__NR_getuid, sys_getuid)
+#define __NR_geteuid 175
+__SYSCALL(__NR_geteuid, sys_geteuid)
+#define __NR_getgid 176
+__SYSCALL(__NR_getgid, sys_getgid)
+#define __NR_getegid 177
+__SYSCALL(__NR_getegid, sys_getegid)
+#define __NR_gettid 178
+__SYSCALL(__NR_gettid, sys_gettid)
+#define __NR_sysinfo 179
+__SC_COMP(__NR_sysinfo, sys_sysinfo, compat_sys_sysinfo)
+
+/* ipc/mqueue.c */
+#define __NR_mq_open 180
+__SC_COMP(__NR_mq_open, sys_mq_open, compat_sys_mq_open)
+#define __NR_mq_unlink 181
+__SYSCALL(__NR_mq_unlink, sys_mq_unlink)
+#define __NR_mq_timedsend 182
+__SC_COMP(__NR_mq_timedsend, sys_mq_timedsend, compat_sys_mq_timedsend)
+#define __NR_mq_timedreceive 183
+__SC_COMP(__NR_mq_timedreceive, sys_mq_timedreceive, \
+	  compat_sys_mq_timedreceive)
+#define __NR_mq_notify 184
+__SC_COMP(__NR_mq_notify, sys_mq_notify, compat_sys_mq_notify)
+#define __NR_mq_getsetattr 185
+__SC_COMP(__NR_mq_getsetattr, sys_mq_getsetattr, compat_sys_mq_getsetattr)
+
+/* ipc/msg.c */
+#define __NR_msgget 186
+__SYSCALL(__NR_msgget, sys_msgget)
+#define __NR_msgctl 187
+__SC_COMP(__NR_msgctl, sys_msgctl, compat_sys_msgctl)
+#define __NR_msgrcv 188
+__SC_COMP(__NR_msgrcv, sys_msgrcv, compat_sys_msgrcv)
+#define __NR_msgsnd 189
+__SC_COMP(__NR_msgsnd, sys_msgsnd, compat_sys_msgsnd)
+
+/* ipc/sem.c */
+#define __NR_semget 190
+__SYSCALL(__NR_semget, sys_semget)
+#define __NR_semctl 191
+__SC_COMP(__NR_semctl, sys_semctl, compat_sys_semctl)
+#define __NR_semtimedop 192
+__SC_COMP(__NR_semtimedop, sys_semtimedop, compat_sys_semtimedop)
+#define __NR_semop 193
+__SYSCALL(__NR_semop, sys_semop)
+
+/* ipc/shm.c */
+#define __NR_shmget 194
+__SYSCALL(__NR_shmget, sys_shmget)
+#define __NR_shmctl 195
+__SC_COMP(__NR_shmctl, sys_shmctl, compat_sys_shmctl)
+#define __NR_shmat 196
+__SC_COMP(__NR_shmat, sys_shmat, compat_sys_shmat)
+#define __NR_shmdt 197
+__SYSCALL(__NR_shmdt, sys_shmdt)
+
+/* net/socket.c */
+#define __NR_socket 198
+__SYSCALL(__NR_socket, sys_socket)
+#define __NR_socketpair 199
+__SYSCALL(__NR_socketpair, sys_socketpair)
+#define __NR_bind 200
+__SYSCALL(__NR_bind, sys_bind)
+#define __NR_listen 201
+__SYSCALL(__NR_listen, sys_listen)
+#define __NR_accept 202
+__SYSCALL(__NR_accept, sys_accept)
+#define __NR_connect 203
+__SYSCALL(__NR_connect, sys_connect)
+#define __NR_getsockname 204
+__SYSCALL(__NR_getsockname, sys_getsockname)
+#define __NR_getpeername 205
+__SYSCALL(__NR_getpeername, sys_getpeername)
+#define __NR_sendto 206
+__SYSCALL(__NR_sendto, sys_sendto)
+#define __NR_recvfrom 207
+__SC_COMP(__NR_recvfrom, sys_recvfrom, compat_sys_recvfrom)
+#define __NR_setsockopt 208
+__SC_COMP(__NR_setsockopt, sys_setsockopt, compat_sys_setsockopt)
+#define __NR_getsockopt 209
+__SC_COMP(__NR_getsockopt, sys_getsockopt, compat_sys_getsockopt)
+#define __NR_shutdown 210
+__SYSCALL(__NR_shutdown, sys_shutdown)
+#define __NR_sendmsg 211
+__SC_COMP(__NR_sendmsg, sys_sendmsg, compat_sys_sendmsg)
+#define __NR_recvmsg 212
+__SC_COMP(__NR_recvmsg, sys_recvmsg, compat_sys_recvmsg)
+
+/* mm/filemap.c */
+#define __NR_readahead 213
+__SC_COMP(__NR_readahead, sys_readahead, compat_sys_readahead)
+
+/* mm/nommu.c, also with MMU */
+#define __NR_brk 214
+__SYSCALL(__NR_brk, sys_brk)
+#define __NR_munmap 215
+__SYSCALL(__NR_munmap, sys_munmap)
+#define __NR_mremap 216
+__SYSCALL(__NR_mremap, sys_mremap)
+
+/* security/keys/keyctl.c */
+#define __NR_add_key 217
+__SYSCALL(__NR_add_key, sys_add_key)
+#define __NR_request_key 218
+__SYSCALL(__NR_request_key, sys_request_key)
+#define __NR_keyctl 219
+__SC_COMP(__NR_keyctl, sys_keyctl, compat_sys_keyctl)
+
+/* arch/example/kernel/sys_example.c */
+#define __NR_clone 220
+__SYSCALL(__NR_clone, sys_clone)
+#define __NR_execve 221
+__SC_COMP(__NR_execve, sys_execve, compat_sys_execve)
+
+#define __NR3264_mmap 222
+__SC_3264(__NR3264_mmap, sys_mmap2, sys_mmap)
+/* mm/fadvise.c */
+#define __NR3264_fadvise64 223
+__SC_COMP(__NR3264_fadvise64, sys_fadvise64_64, compat_sys_fadvise64_64)
+
+/* mm/, CONFIG_MMU only */
+#ifndef __ARCH_NOMMU
+#define __NR_swapon 224
+__SYSCALL(__NR_swapon, sys_swapon)
+#define __NR_swapoff 225
+__SYSCALL(__NR_swapoff, sys_swapoff)
+#define __NR_mprotect 226
+__SYSCALL(__NR_mprotect, sys_mprotect)
+#define __NR_msync 227
+__SYSCALL(__NR_msync, sys_msync)
+#define __NR_mlock 228
+__SYSCALL(__NR_mlock, sys_mlock)
+#define __NR_munlock 229
+__SYSCALL(__NR_munlock, sys_munlock)
+#define __NR_mlockall 230
+__SYSCALL(__NR_mlockall, sys_mlockall)
+#define __NR_munlockall 231
+__SYSCALL(__NR_munlockall, sys_munlockall)
+#define __NR_mincore 232
+__SYSCALL(__NR_mincore, sys_mincore)
+#define __NR_madvise 233
+__SYSCALL(__NR_madvise, sys_madvise)
+#define __NR_remap_file_pages 234
+__SYSCALL(__NR_remap_file_pages, sys_remap_file_pages)
+#define __NR_mbind 235
+__SC_COMP(__NR_mbind, sys_mbind, compat_sys_mbind)
+#define __NR_get_mempolicy 236
+__SC_COMP(__NR_get_mempolicy, sys_get_mempolicy, compat_sys_get_mempolicy)
+#define __NR_set_mempolicy 237
+__SC_COMP(__NR_set_mempolicy, sys_set_mempolicy, compat_sys_set_mempolicy)
+#define __NR_migrate_pages 238
+__SC_COMP(__NR_migrate_pages, sys_migrate_pages, compat_sys_migrate_pages)
+#define __NR_move_pages 239
+__SC_COMP(__NR_move_pages, sys_move_pages, compat_sys_move_pages)
+#endif
+
+#define __NR_rt_tgsigqueueinfo 240
+__SC_COMP(__NR_rt_tgsigqueueinfo, sys_rt_tgsigqueueinfo, \
+	  compat_sys_rt_tgsigqueueinfo)
+#define __NR_perf_event_open 241
+__SYSCALL(__NR_perf_event_open, sys_perf_event_open)
+#define __NR_accept4 242
+__SYSCALL(__NR_accept4, sys_accept4)
+#define __NR_recvmmsg 243
+__SC_COMP(__NR_recvmmsg, sys_recvmmsg, compat_sys_recvmmsg)
+
+/*
+ * Architectures may provide up to 16 syscalls of their own
+ * starting with this value.
+ */
+#define __NR_arch_specific_syscall 244
+
+#define __NR_wait4 260
+__SC_COMP(__NR_wait4, sys_wait4, compat_sys_wait4)
+#define __NR_prlimit64 261
+__SYSCALL(__NR_prlimit64, sys_prlimit64)
+#define __NR_fanotify_init 262
+__SYSCALL(__NR_fanotify_init, sys_fanotify_init)
+#define __NR_fanotify_mark 263
+__SYSCALL(__NR_fanotify_mark, sys_fanotify_mark)
+#define __NR_name_to_handle_at         264
+__SYSCALL(__NR_name_to_handle_at, sys_name_to_handle_at)
+#define __NR_open_by_handle_at         265
+__SC_COMP(__NR_open_by_handle_at, sys_open_by_handle_at, \
+	  compat_sys_open_by_handle_at)
+#define __NR_clock_adjtime 266
+__SC_COMP(__NR_clock_adjtime, sys_clock_adjtime, compat_sys_clock_adjtime)
+#define __NR_syncfs 267
+__SYSCALL(__NR_syncfs, sys_syncfs)
+#define __NR_setns 268
+__SYSCALL(__NR_setns, sys_setns)
+#define __NR_sendmmsg 269
+__SC_COMP(__NR_sendmmsg, sys_sendmmsg, compat_sys_sendmmsg)
+#define __NR_process_vm_readv 270
+__SC_COMP(__NR_process_vm_readv, sys_process_vm_readv, \
+          compat_sys_process_vm_readv)
+#define __NR_process_vm_writev 271
+__SC_COMP(__NR_process_vm_writev, sys_process_vm_writev, \
+          compat_sys_process_vm_writev)
+#define __NR_kcmp 272
+__SYSCALL(__NR_kcmp, sys_kcmp)
+
+#undef __NR_syscalls
+#define __NR_syscalls 273
+
+/*
+ * All syscalls below here should go away really,
+ * these are provided for both review and as a porting
+ * help for the C library version.
+*
+ * Last chance: are any of these important enough to
+ * enable by default?
+ */
+#ifdef __ARCH_WANT_SYSCALL_NO_AT
+#define __NR_open 1024
+__SYSCALL(__NR_open, sys_open)
+#define __NR_link 1025
+__SYSCALL(__NR_link, sys_link)
+#define __NR_unlink 1026
+__SYSCALL(__NR_unlink, sys_unlink)
+#define __NR_mknod 1027
+__SYSCALL(__NR_mknod, sys_mknod)
+#define __NR_chmod 1028
+__SYSCALL(__NR_chmod, sys_chmod)
+#define __NR_chown 1029
+__SYSCALL(__NR_chown, sys_chown)
+#define __NR_mkdir 1030
+__SYSCALL(__NR_mkdir, sys_mkdir)
+#define __NR_rmdir 1031
+__SYSCALL(__NR_rmdir, sys_rmdir)
+#define __NR_lchown 1032
+__SYSCALL(__NR_lchown, sys_lchown)
+#define __NR_access 1033
+__SYSCALL(__NR_access, sys_access)
+#define __NR_rename 1034
+__SYSCALL(__NR_rename, sys_rename)
+#define __NR_readlink 1035
+__SYSCALL(__NR_readlink, sys_readlink)
+#define __NR_symlink 1036
+__SYSCALL(__NR_symlink, sys_symlink)
+#define __NR_utimes 1037
+__SYSCALL(__NR_utimes, sys_utimes)
+#define __NR3264_stat 1038
+__SC_3264(__NR3264_stat, sys_stat64, sys_newstat)
+#define __NR3264_lstat 1039
+__SC_3264(__NR3264_lstat, sys_lstat64, sys_newlstat)
+
+#undef __NR_syscalls
+#define __NR_syscalls (__NR3264_lstat+1)
+#endif /* __ARCH_WANT_SYSCALL_NO_AT */
+
+#ifdef __ARCH_WANT_SYSCALL_NO_FLAGS
+#define __NR_pipe 1040
+__SYSCALL(__NR_pipe, sys_pipe)
+#define __NR_dup2 1041
+__SYSCALL(__NR_dup2, sys_dup2)
+#define __NR_epoll_create 1042
+__SYSCALL(__NR_epoll_create, sys_epoll_create)
+#define __NR_inotify_init 1043
+__SYSCALL(__NR_inotify_init, sys_inotify_init)
+#define __NR_eventfd 1044
+__SYSCALL(__NR_eventfd, sys_eventfd)
+#define __NR_signalfd 1045
+__SYSCALL(__NR_signalfd, sys_signalfd)
+
+#undef __NR_syscalls
+#define __NR_syscalls (__NR_signalfd+1)
+#endif /* __ARCH_WANT_SYSCALL_NO_FLAGS */
+
+#if (__BITS_PER_LONG == 32 || defined(__SYSCALL_COMPAT)) && \
+     defined(__ARCH_WANT_SYSCALL_OFF_T)
+#define __NR_sendfile 1046
+__SYSCALL(__NR_sendfile, sys_sendfile)
+#define __NR_ftruncate 1047
+__SYSCALL(__NR_ftruncate, sys_ftruncate)
+#define __NR_truncate 1048
+__SYSCALL(__NR_truncate, sys_truncate)
+#define __NR_stat 1049
+__SYSCALL(__NR_stat, sys_newstat)
+#define __NR_lstat 1050
+__SYSCALL(__NR_lstat, sys_newlstat)
+#define __NR_fstat 1051
+__SYSCALL(__NR_fstat, sys_newfstat)
+#define __NR_fcntl 1052
+__SYSCALL(__NR_fcntl, sys_fcntl)
+#define __NR_fadvise64 1053
+#define __ARCH_WANT_SYS_FADVISE64
+__SYSCALL(__NR_fadvise64, sys_fadvise64)
+#define __NR_newfstatat 1054
+#define __ARCH_WANT_SYS_NEWFSTATAT
+__SYSCALL(__NR_newfstatat, sys_newfstatat)
+#define __NR_fstatfs 1055
+__SYSCALL(__NR_fstatfs, sys_fstatfs)
+#define __NR_statfs 1056
+__SYSCALL(__NR_statfs, sys_statfs)
+#define __NR_lseek 1057
+__SYSCALL(__NR_lseek, sys_lseek)
+#define __NR_mmap 1058
+__SYSCALL(__NR_mmap, sys_mmap)
+
+#undef __NR_syscalls
+#define __NR_syscalls (__NR_mmap+1)
+#endif /* 32 bit off_t syscalls */
+
+#ifdef __ARCH_WANT_SYSCALL_DEPRECATED
+#define __NR_alarm 1059
+#define __ARCH_WANT_SYS_ALARM
+__SYSCALL(__NR_alarm, sys_alarm)
+#define __NR_getpgrp 1060
+#define __ARCH_WANT_SYS_GETPGRP
+__SYSCALL(__NR_getpgrp, sys_getpgrp)
+#define __NR_pause 1061
+#define __ARCH_WANT_SYS_PAUSE
+__SYSCALL(__NR_pause, sys_pause)
+#define __NR_time 1062
+#define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_COMPAT_SYS_TIME
+__SYSCALL(__NR_time, sys_time)
+#define __NR_utime 1063
+#define __ARCH_WANT_SYS_UTIME
+__SYSCALL(__NR_utime, sys_utime)
+
+#define __NR_creat 1064
+__SYSCALL(__NR_creat, sys_creat)
+#define __NR_getdents 1065
+#define __ARCH_WANT_SYS_GETDENTS
+__SYSCALL(__NR_getdents, sys_getdents)
+#define __NR_futimesat 1066
+__SYSCALL(__NR_futimesat, sys_futimesat)
+#define __NR_select 1067
+#define __ARCH_WANT_SYS_SELECT
+__SYSCALL(__NR_select, sys_select)
+#define __NR_poll 1068
+__SYSCALL(__NR_poll, sys_poll)
+#define __NR_epoll_wait 1069
+__SYSCALL(__NR_epoll_wait, sys_epoll_wait)
+#define __NR_ustat 1070
+__SYSCALL(__NR_ustat, sys_ustat)
+#define __NR_vfork 1071
+__SYSCALL(__NR_vfork, sys_vfork)
+#define __NR_oldwait4 1072
+__SYSCALL(__NR_oldwait4, sys_wait4)
+#define __NR_recv 1073
+__SYSCALL(__NR_recv, sys_recv)
+#define __NR_send 1074
+__SYSCALL(__NR_send, sys_send)
+#define __NR_bdflush 1075
+__SYSCALL(__NR_bdflush, sys_bdflush)
+#define __NR_umount 1076
+__SYSCALL(__NR_umount, sys_oldumount)
+#define __ARCH_WANT_SYS_OLDUMOUNT
+#define __NR_uselib 1077
+__SYSCALL(__NR_uselib, sys_uselib)
+#define __NR__sysctl 1078
+__SYSCALL(__NR__sysctl, sys_sysctl)
+
+#define __NR_fork 1079
+#ifdef CONFIG_MMU
+__SYSCALL(__NR_fork, sys_fork)
+#else
+__SYSCALL(__NR_fork, sys_ni_syscall)
+#endif /* CONFIG_MMU */
+
+#undef __NR_syscalls
+#define __NR_syscalls (__NR_fork+1)
+
+#endif /* __ARCH_WANT_SYSCALL_DEPRECATED */
+
+/*
+ * 32 bit systems traditionally used different
+ * syscalls for off_t and loff_t arguments, while
+ * 64 bit systems only need the off_t version.
+ * For new 32 bit platforms, there is no need to
+ * implement the old 32 bit off_t syscalls, so
+ * they take different names.
+ * Here we map the numbers so that both versions
+ * use the same syscall table layout.
+ */
+#if __BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)
+#define __NR_fcntl __NR3264_fcntl
+#define __NR_statfs __NR3264_statfs
+#define __NR_fstatfs __NR3264_fstatfs
+#define __NR_truncate __NR3264_truncate
+#define __NR_ftruncate __NR3264_ftruncate
+#define __NR_lseek __NR3264_lseek
+#define __NR_sendfile __NR3264_sendfile
+#define __NR_newfstatat __NR3264_fstatat
+#define __NR_fstat __NR3264_fstat
+#define __NR_mmap __NR3264_mmap
+#define __NR_fadvise64 __NR3264_fadvise64
+#ifdef __NR3264_stat
+#define __NR_stat __NR3264_stat
+#define __NR_lstat __NR3264_lstat
+#endif
+#else
+#define __NR_fcntl64 __NR3264_fcntl
+#define __NR_statfs64 __NR3264_statfs
+#define __NR_fstatfs64 __NR3264_fstatfs
+#define __NR_truncate64 __NR3264_truncate
+#define __NR_ftruncate64 __NR3264_ftruncate
+#define __NR_llseek __NR3264_lseek
+#define __NR_sendfile64 __NR3264_sendfile
+#define __NR_fstatat64 __NR3264_fstatat
+#define __NR_fstat64 __NR3264_fstat
+#define __NR_mmap2 __NR3264_mmap
+#define __NR_fadvise64_64 __NR3264_fadvise64
+#ifdef __NR3264_stat
+#define __NR_stat64 __NR3264_stat
+#define __NR_lstat64 __NR3264_lstat
+#endif
+#endif
diff --git a/include/uapi/drm/Kbuild b/include/uapi/drm/Kbuild
index aafaa5a..ba99ce3 100644
--- a/include/uapi/drm/Kbuild
+++ b/include/uapi/drm/Kbuild
@@ -1 +1,16 @@
 # UAPI Header export list
+header-y += drm.h
+header-y += drm_fourcc.h
+header-y += drm_mode.h
+header-y += drm_sarea.h
+header-y += exynos_drm.h
+header-y += i810_drm.h
+header-y += i915_drm.h
+header-y += mga_drm.h
+header-y += nouveau_drm.h
+header-y += r128_drm.h
+header-y += radeon_drm.h
+header-y += savage_drm.h
+header-y += sis_drm.h
+header-y += via_drm.h
+header-y += vmwgfx_drm.h
diff --git a/include/drm/drm.h b/include/uapi/drm/drm.h
similarity index 100%
rename from include/drm/drm.h
rename to include/uapi/drm/drm.h
diff --git a/include/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
similarity index 100%
rename from include/drm/drm_fourcc.h
rename to include/uapi/drm/drm_fourcc.h
diff --git a/include/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
similarity index 100%
rename from include/drm/drm_mode.h
rename to include/uapi/drm/drm_mode.h
diff --git a/include/drm/drm_sarea.h b/include/uapi/drm/drm_sarea.h
similarity index 100%
rename from include/drm/drm_sarea.h
rename to include/uapi/drm/drm_sarea.h
diff --git a/include/uapi/drm/exynos_drm.h b/include/uapi/drm/exynos_drm.h
new file mode 100644
index 0000000..c0494d5
--- /dev/null
+++ b/include/uapi/drm/exynos_drm.h
@@ -0,0 +1,203 @@
+/* exynos_drm.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * Authors:
+ *	Inki Dae <inki.dae@samsung.com>
+ *	Joonyoung Shim <jy0922.shim@samsung.com>
+ *	Seung-Woo Kim <sw0312.kim@samsung.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _UAPI_EXYNOS_DRM_H_
+#define _UAPI_EXYNOS_DRM_H_
+
+#include <drm/drm.h>
+
+/**
+ * User-desired buffer creation information structure.
+ *
+ * @size: user-desired memory allocation size.
+ *	- this size value would be page-aligned internally.
+ * @flags: user request for setting memory type or cache attributes.
+ * @handle: returned a handle to created gem object.
+ *	- this handle will be set by gem module of kernel side.
+ */
+struct drm_exynos_gem_create {
+	uint64_t size;
+	unsigned int flags;
+	unsigned int handle;
+};
+
+/**
+ * A structure for getting buffer offset.
+ *
+ * @handle: a pointer to gem object created.
+ * @pad: just padding to be 64-bit aligned.
+ * @offset: relatived offset value of the memory region allocated.
+ *	- this value should be set by user.
+ */
+struct drm_exynos_gem_map_off {
+	unsigned int handle;
+	unsigned int pad;
+	uint64_t offset;
+};
+
+/**
+ * A structure for mapping buffer.
+ *
+ * @handle: a handle to gem object created.
+ * @pad: just padding to be 64-bit aligned.
+ * @size: memory size to be mapped.
+ * @mapped: having user virtual address mmaped.
+ *	- this variable would be filled by exynos gem module
+ *	of kernel side with user virtual address which is allocated
+ *	by do_mmap().
+ */
+struct drm_exynos_gem_mmap {
+	unsigned int handle;
+	unsigned int pad;
+	uint64_t size;
+	uint64_t mapped;
+};
+
+/**
+ * A structure to gem information.
+ *
+ * @handle: a handle to gem object created.
+ * @flags: flag value including memory type and cache attribute and
+ *	this value would be set by driver.
+ * @size: size to memory region allocated by gem and this size would
+ *	be set by driver.
+ */
+struct drm_exynos_gem_info {
+	unsigned int handle;
+	unsigned int flags;
+	uint64_t size;
+};
+
+/**
+ * A structure for user connection request of virtual display.
+ *
+ * @connection: indicate whether doing connetion or not by user.
+ * @extensions: if this value is 1 then the vidi driver would need additional
+ *	128bytes edid data.
+ * @edid: the edid data pointer from user side.
+ */
+struct drm_exynos_vidi_connection {
+	unsigned int connection;
+	unsigned int extensions;
+	uint64_t edid;
+};
+
+/* memory type definitions. */
+enum e_drm_exynos_gem_mem_type {
+	/* Physically Continuous memory and used as default. */
+	EXYNOS_BO_CONTIG	= 0 << 0,
+	/* Physically Non-Continuous memory. */
+	EXYNOS_BO_NONCONTIG	= 1 << 0,
+	/* non-cachable mapping and used as default. */
+	EXYNOS_BO_NONCACHABLE	= 0 << 1,
+	/* cachable mapping. */
+	EXYNOS_BO_CACHABLE	= 1 << 1,
+	/* write-combine mapping. */
+	EXYNOS_BO_WC		= 1 << 2,
+	EXYNOS_BO_MASK		= EXYNOS_BO_NONCONTIG | EXYNOS_BO_CACHABLE |
+					EXYNOS_BO_WC
+};
+
+struct drm_exynos_g2d_get_ver {
+	__u32	major;
+	__u32	minor;
+};
+
+struct drm_exynos_g2d_cmd {
+	__u32	offset;
+	__u32	data;
+};
+
+enum drm_exynos_g2d_event_type {
+	G2D_EVENT_NOT,
+	G2D_EVENT_NONSTOP,
+	G2D_EVENT_STOP,		/* not yet */
+};
+
+struct drm_exynos_g2d_set_cmdlist {
+	__u64					cmd;
+	__u64					cmd_gem;
+	__u32					cmd_nr;
+	__u32					cmd_gem_nr;
+
+	/* for g2d event */
+	__u64					event_type;
+	__u64					user_data;
+};
+
+struct drm_exynos_g2d_exec {
+	__u64					async;
+};
+
+#define DRM_EXYNOS_GEM_CREATE		0x00
+#define DRM_EXYNOS_GEM_MAP_OFFSET	0x01
+#define DRM_EXYNOS_GEM_MMAP		0x02
+/* Reserved 0x03 ~ 0x05 for exynos specific gem ioctl */
+#define DRM_EXYNOS_GEM_GET		0x04
+#define DRM_EXYNOS_VIDI_CONNECTION	0x07
+
+/* G2D */
+#define DRM_EXYNOS_G2D_GET_VER		0x20
+#define DRM_EXYNOS_G2D_SET_CMDLIST	0x21
+#define DRM_EXYNOS_G2D_EXEC		0x22
+
+#define DRM_IOCTL_EXYNOS_GEM_CREATE		DRM_IOWR(DRM_COMMAND_BASE + \
+		DRM_EXYNOS_GEM_CREATE, struct drm_exynos_gem_create)
+
+#define DRM_IOCTL_EXYNOS_GEM_MAP_OFFSET	DRM_IOWR(DRM_COMMAND_BASE + \
+		DRM_EXYNOS_GEM_MAP_OFFSET, struct drm_exynos_gem_map_off)
+
+#define DRM_IOCTL_EXYNOS_GEM_MMAP	DRM_IOWR(DRM_COMMAND_BASE + \
+		DRM_EXYNOS_GEM_MMAP, struct drm_exynos_gem_mmap)
+
+#define DRM_IOCTL_EXYNOS_GEM_GET	DRM_IOWR(DRM_COMMAND_BASE + \
+		DRM_EXYNOS_GEM_GET,	struct drm_exynos_gem_info)
+
+#define DRM_IOCTL_EXYNOS_VIDI_CONNECTION	DRM_IOWR(DRM_COMMAND_BASE + \
+		DRM_EXYNOS_VIDI_CONNECTION, struct drm_exynos_vidi_connection)
+
+#define DRM_IOCTL_EXYNOS_G2D_GET_VER		DRM_IOWR(DRM_COMMAND_BASE + \
+		DRM_EXYNOS_G2D_GET_VER, struct drm_exynos_g2d_get_ver)
+#define DRM_IOCTL_EXYNOS_G2D_SET_CMDLIST	DRM_IOWR(DRM_COMMAND_BASE + \
+		DRM_EXYNOS_G2D_SET_CMDLIST, struct drm_exynos_g2d_set_cmdlist)
+#define DRM_IOCTL_EXYNOS_G2D_EXEC		DRM_IOWR(DRM_COMMAND_BASE + \
+		DRM_EXYNOS_G2D_EXEC, struct drm_exynos_g2d_exec)
+
+/* EXYNOS specific events */
+#define DRM_EXYNOS_G2D_EVENT		0x80000000
+
+struct drm_exynos_g2d_event {
+	struct drm_event	base;
+	__u64			user_data;
+	__u32			tv_sec;
+	__u32			tv_usec;
+	__u32			cmdlist_no;
+	__u32			reserved;
+};
+
+#endif /* _UAPI_EXYNOS_DRM_H_ */
diff --git a/include/drm/i810_drm.h b/include/uapi/drm/i810_drm.h
similarity index 100%
rename from include/drm/i810_drm.h
rename to include/uapi/drm/i810_drm.h
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
new file mode 100644
index 0000000..4322b1e
--- /dev/null
+++ b/include/uapi/drm/i915_drm.h
@@ -0,0 +1,947 @@
+/*
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef _UAPI_I915_DRM_H_
+#define _UAPI_I915_DRM_H_
+
+#include <drm/drm.h>
+
+/* Please note that modifications to all structs defined here are
+ * subject to backwards-compatibility constraints.
+ */
+
+
+/* Each region is a minimum of 16k, and there are at most 255 of them.
+ */
+#define I915_NR_TEX_REGIONS 255	/* table size 2k - maximum due to use
+				 * of chars for next/prev indices */
+#define I915_LOG_MIN_TEX_REGION_SIZE 14
+
+typedef struct _drm_i915_init {
+	enum {
+		I915_INIT_DMA = 0x01,
+		I915_CLEANUP_DMA = 0x02,
+		I915_RESUME_DMA = 0x03
+	} func;
+	unsigned int mmio_offset;
+	int sarea_priv_offset;
+	unsigned int ring_start;
+	unsigned int ring_end;
+	unsigned int ring_size;
+	unsigned int front_offset;
+	unsigned int back_offset;
+	unsigned int depth_offset;
+	unsigned int w;
+	unsigned int h;
+	unsigned int pitch;
+	unsigned int pitch_bits;
+	unsigned int back_pitch;
+	unsigned int depth_pitch;
+	unsigned int cpp;
+	unsigned int chipset;
+} drm_i915_init_t;
+
+typedef struct _drm_i915_sarea {
+	struct drm_tex_region texList[I915_NR_TEX_REGIONS + 1];
+	int last_upload;	/* last time texture was uploaded */
+	int last_enqueue;	/* last time a buffer was enqueued */
+	int last_dispatch;	/* age of the most recently dispatched buffer */
+	int ctxOwner;		/* last context to upload state */
+	int texAge;
+	int pf_enabled;		/* is pageflipping allowed? */
+	int pf_active;
+	int pf_current_page;	/* which buffer is being displayed? */
+	int perf_boxes;		/* performance boxes to be displayed */
+	int width, height;      /* screen size in pixels */
+
+	drm_handle_t front_handle;
+	int front_offset;
+	int front_size;
+
+	drm_handle_t back_handle;
+	int back_offset;
+	int back_size;
+
+	drm_handle_t depth_handle;
+	int depth_offset;
+	int depth_size;
+
+	drm_handle_t tex_handle;
+	int tex_offset;
+	int tex_size;
+	int log_tex_granularity;
+	int pitch;
+	int rotation;           /* 0, 90, 180 or 270 */
+	int rotated_offset;
+	int rotated_size;
+	int rotated_pitch;
+	int virtualX, virtualY;
+
+	unsigned int front_tiled;
+	unsigned int back_tiled;
+	unsigned int depth_tiled;
+	unsigned int rotated_tiled;
+	unsigned int rotated2_tiled;
+
+	int pipeA_x;
+	int pipeA_y;
+	int pipeA_w;
+	int pipeA_h;
+	int pipeB_x;
+	int pipeB_y;
+	int pipeB_w;
+	int pipeB_h;
+
+	/* fill out some space for old userspace triple buffer */
+	drm_handle_t unused_handle;
+	__u32 unused1, unused2, unused3;
+
+	/* buffer object handles for static buffers. May change
+	 * over the lifetime of the client.
+	 */
+	__u32 front_bo_handle;
+	__u32 back_bo_handle;
+	__u32 unused_bo_handle;
+	__u32 depth_bo_handle;
+
+} drm_i915_sarea_t;
+
+/* due to userspace building against these headers we need some compat here */
+#define planeA_x pipeA_x
+#define planeA_y pipeA_y
+#define planeA_w pipeA_w
+#define planeA_h pipeA_h
+#define planeB_x pipeB_x
+#define planeB_y pipeB_y
+#define planeB_w pipeB_w
+#define planeB_h pipeB_h
+
+/* Flags for perf_boxes
+ */
+#define I915_BOX_RING_EMPTY    0x1
+#define I915_BOX_FLIP          0x2
+#define I915_BOX_WAIT          0x4
+#define I915_BOX_TEXTURE_LOAD  0x8
+#define I915_BOX_LOST_CONTEXT  0x10
+
+/* I915 specific ioctls
+ * The device specific ioctl range is 0x40 to 0x79.
+ */
+#define DRM_I915_INIT		0x00
+#define DRM_I915_FLUSH		0x01
+#define DRM_I915_FLIP		0x02
+#define DRM_I915_BATCHBUFFER	0x03
+#define DRM_I915_IRQ_EMIT	0x04
+#define DRM_I915_IRQ_WAIT	0x05
+#define DRM_I915_GETPARAM	0x06
+#define DRM_I915_SETPARAM	0x07
+#define DRM_I915_ALLOC		0x08
+#define DRM_I915_FREE		0x09
+#define DRM_I915_INIT_HEAP	0x0a
+#define DRM_I915_CMDBUFFER	0x0b
+#define DRM_I915_DESTROY_HEAP	0x0c
+#define DRM_I915_SET_VBLANK_PIPE	0x0d
+#define DRM_I915_GET_VBLANK_PIPE	0x0e
+#define DRM_I915_VBLANK_SWAP	0x0f
+#define DRM_I915_HWS_ADDR	0x11
+#define DRM_I915_GEM_INIT	0x13
+#define DRM_I915_GEM_EXECBUFFER	0x14
+#define DRM_I915_GEM_PIN	0x15
+#define DRM_I915_GEM_UNPIN	0x16
+#define DRM_I915_GEM_BUSY	0x17
+#define DRM_I915_GEM_THROTTLE	0x18
+#define DRM_I915_GEM_ENTERVT	0x19
+#define DRM_I915_GEM_LEAVEVT	0x1a
+#define DRM_I915_GEM_CREATE	0x1b
+#define DRM_I915_GEM_PREAD	0x1c
+#define DRM_I915_GEM_PWRITE	0x1d
+#define DRM_I915_GEM_MMAP	0x1e
+#define DRM_I915_GEM_SET_DOMAIN	0x1f
+#define DRM_I915_GEM_SW_FINISH	0x20
+#define DRM_I915_GEM_SET_TILING	0x21
+#define DRM_I915_GEM_GET_TILING	0x22
+#define DRM_I915_GEM_GET_APERTURE 0x23
+#define DRM_I915_GEM_MMAP_GTT	0x24
+#define DRM_I915_GET_PIPE_FROM_CRTC_ID	0x25
+#define DRM_I915_GEM_MADVISE	0x26
+#define DRM_I915_OVERLAY_PUT_IMAGE	0x27
+#define DRM_I915_OVERLAY_ATTRS	0x28
+#define DRM_I915_GEM_EXECBUFFER2	0x29
+#define DRM_I915_GET_SPRITE_COLORKEY	0x2a
+#define DRM_I915_SET_SPRITE_COLORKEY	0x2b
+#define DRM_I915_GEM_WAIT	0x2c
+#define DRM_I915_GEM_CONTEXT_CREATE	0x2d
+#define DRM_I915_GEM_CONTEXT_DESTROY	0x2e
+#define DRM_I915_GEM_SET_CACHING	0x2f
+#define DRM_I915_GEM_GET_CACHING	0x30
+#define DRM_I915_REG_READ		0x31
+
+#define DRM_IOCTL_I915_INIT		DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
+#define DRM_IOCTL_I915_FLUSH		DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
+#define DRM_IOCTL_I915_FLIP		DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLIP)
+#define DRM_IOCTL_I915_BATCHBUFFER	DRM_IOW( DRM_COMMAND_BASE + DRM_I915_BATCHBUFFER, drm_i915_batchbuffer_t)
+#define DRM_IOCTL_I915_IRQ_EMIT         DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_IRQ_EMIT, drm_i915_irq_emit_t)
+#define DRM_IOCTL_I915_IRQ_WAIT         DRM_IOW( DRM_COMMAND_BASE + DRM_I915_IRQ_WAIT, drm_i915_irq_wait_t)
+#define DRM_IOCTL_I915_GETPARAM         DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GETPARAM, drm_i915_getparam_t)
+#define DRM_IOCTL_I915_SETPARAM         DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SETPARAM, drm_i915_setparam_t)
+#define DRM_IOCTL_I915_ALLOC            DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_ALLOC, drm_i915_mem_alloc_t)
+#define DRM_IOCTL_I915_FREE             DRM_IOW( DRM_COMMAND_BASE + DRM_I915_FREE, drm_i915_mem_free_t)
+#define DRM_IOCTL_I915_INIT_HEAP        DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT_HEAP, drm_i915_mem_init_heap_t)
+#define DRM_IOCTL_I915_CMDBUFFER	DRM_IOW( DRM_COMMAND_BASE + DRM_I915_CMDBUFFER, drm_i915_cmdbuffer_t)
+#define DRM_IOCTL_I915_DESTROY_HEAP	DRM_IOW( DRM_COMMAND_BASE + DRM_I915_DESTROY_HEAP, drm_i915_mem_destroy_heap_t)
+#define DRM_IOCTL_I915_SET_VBLANK_PIPE	DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
+#define DRM_IOCTL_I915_GET_VBLANK_PIPE	DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
+#define DRM_IOCTL_I915_VBLANK_SWAP	DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t)
+#define DRM_IOCTL_I915_HWS_ADDR		DRM_IOW(DRM_COMMAND_BASE + DRM_I915_HWS_ADDR, struct drm_i915_gem_init)
+#define DRM_IOCTL_I915_GEM_INIT		DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_INIT, struct drm_i915_gem_init)
+#define DRM_IOCTL_I915_GEM_EXECBUFFER	DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER, struct drm_i915_gem_execbuffer)
+#define DRM_IOCTL_I915_GEM_EXECBUFFER2	DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER2, struct drm_i915_gem_execbuffer2)
+#define DRM_IOCTL_I915_GEM_PIN		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_PIN, struct drm_i915_gem_pin)
+#define DRM_IOCTL_I915_GEM_UNPIN	DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_UNPIN, struct drm_i915_gem_unpin)
+#define DRM_IOCTL_I915_GEM_BUSY		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_BUSY, struct drm_i915_gem_busy)
+#define DRM_IOCTL_I915_GEM_SET_CACHING		DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_SET_CACHING, struct drm_i915_gem_caching)
+#define DRM_IOCTL_I915_GEM_GET_CACHING		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_GET_CACHING, struct drm_i915_gem_caching)
+#define DRM_IOCTL_I915_GEM_THROTTLE	DRM_IO ( DRM_COMMAND_BASE + DRM_I915_GEM_THROTTLE)
+#define DRM_IOCTL_I915_GEM_ENTERVT	DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_ENTERVT)
+#define DRM_IOCTL_I915_GEM_LEAVEVT	DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_LEAVEVT)
+#define DRM_IOCTL_I915_GEM_CREATE	DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE, struct drm_i915_gem_create)
+#define DRM_IOCTL_I915_GEM_PREAD	DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PREAD, struct drm_i915_gem_pread)
+#define DRM_IOCTL_I915_GEM_PWRITE	DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite)
+#define DRM_IOCTL_I915_GEM_MMAP		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap)
+#define DRM_IOCTL_I915_GEM_MMAP_GTT	DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP_GTT, struct drm_i915_gem_mmap_gtt)
+#define DRM_IOCTL_I915_GEM_SET_DOMAIN	DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SET_DOMAIN, struct drm_i915_gem_set_domain)
+#define DRM_IOCTL_I915_GEM_SW_FINISH	DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SW_FINISH, struct drm_i915_gem_sw_finish)
+#define DRM_IOCTL_I915_GEM_SET_TILING	DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_SET_TILING, struct drm_i915_gem_set_tiling)
+#define DRM_IOCTL_I915_GEM_GET_TILING	DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling)
+#define DRM_IOCTL_I915_GEM_GET_APERTURE	DRM_IOR  (DRM_COMMAND_BASE + DRM_I915_GEM_GET_APERTURE, struct drm_i915_gem_get_aperture)
+#define DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_PIPE_FROM_CRTC_ID, struct drm_i915_get_pipe_from_crtc_id)
+#define DRM_IOCTL_I915_GEM_MADVISE	DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MADVISE, struct drm_i915_gem_madvise)
+#define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE	DRM_IOW(DRM_COMMAND_BASE + DRM_I915_OVERLAY_PUT_IMAGE, struct drm_intel_overlay_put_image)
+#define DRM_IOCTL_I915_OVERLAY_ATTRS	DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_OVERLAY_ATTRS, struct drm_intel_overlay_attrs)
+#define DRM_IOCTL_I915_SET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey)
+#define DRM_IOCTL_I915_GET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_COLORKEY, struct drm_intel_sprite_colorkey)
+#define DRM_IOCTL_I915_GEM_WAIT		DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_WAIT, struct drm_i915_gem_wait)
+#define DRM_IOCTL_I915_GEM_CONTEXT_CREATE	DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_CREATE, struct drm_i915_gem_context_create)
+#define DRM_IOCTL_I915_GEM_CONTEXT_DESTROY	DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_DESTROY, struct drm_i915_gem_context_destroy)
+#define DRM_IOCTL_I915_REG_READ			DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_REG_READ, struct drm_i915_reg_read)
+
+/* Allow drivers to submit batchbuffers directly to hardware, relying
+ * on the security mechanisms provided by hardware.
+ */
+typedef struct drm_i915_batchbuffer {
+	int start;		/* agp offset */
+	int used;		/* nr bytes in use */
+	int DR1;		/* hw flags for GFX_OP_DRAWRECT_INFO */
+	int DR4;		/* window origin for GFX_OP_DRAWRECT_INFO */
+	int num_cliprects;	/* mulitpass with multiple cliprects? */
+	struct drm_clip_rect __user *cliprects;	/* pointer to userspace cliprects */
+} drm_i915_batchbuffer_t;
+
+/* As above, but pass a pointer to userspace buffer which can be
+ * validated by the kernel prior to sending to hardware.
+ */
+typedef struct _drm_i915_cmdbuffer {
+	char __user *buf;	/* pointer to userspace command buffer */
+	int sz;			/* nr bytes in buf */
+	int DR1;		/* hw flags for GFX_OP_DRAWRECT_INFO */
+	int DR4;		/* window origin for GFX_OP_DRAWRECT_INFO */
+	int num_cliprects;	/* mulitpass with multiple cliprects? */
+	struct drm_clip_rect __user *cliprects;	/* pointer to userspace cliprects */
+} drm_i915_cmdbuffer_t;
+
+/* Userspace can request & wait on irq's:
+ */
+typedef struct drm_i915_irq_emit {
+	int __user *irq_seq;
+} drm_i915_irq_emit_t;
+
+typedef struct drm_i915_irq_wait {
+	int irq_seq;
+} drm_i915_irq_wait_t;
+
+/* Ioctl to query kernel params:
+ */
+#define I915_PARAM_IRQ_ACTIVE            1
+#define I915_PARAM_ALLOW_BATCHBUFFER     2
+#define I915_PARAM_LAST_DISPATCH         3
+#define I915_PARAM_CHIPSET_ID            4
+#define I915_PARAM_HAS_GEM               5
+#define I915_PARAM_NUM_FENCES_AVAIL      6
+#define I915_PARAM_HAS_OVERLAY           7
+#define I915_PARAM_HAS_PAGEFLIPPING	 8
+#define I915_PARAM_HAS_EXECBUF2          9
+#define I915_PARAM_HAS_BSD		 10
+#define I915_PARAM_HAS_BLT		 11
+#define I915_PARAM_HAS_RELAXED_FENCING	 12
+#define I915_PARAM_HAS_COHERENT_RINGS	 13
+#define I915_PARAM_HAS_EXEC_CONSTANTS	 14
+#define I915_PARAM_HAS_RELAXED_DELTA	 15
+#define I915_PARAM_HAS_GEN7_SOL_RESET	 16
+#define I915_PARAM_HAS_LLC     	 	 17
+#define I915_PARAM_HAS_ALIASING_PPGTT	 18
+#define I915_PARAM_HAS_WAIT_TIMEOUT	 19
+#define I915_PARAM_HAS_SEMAPHORES	 20
+#define I915_PARAM_HAS_PRIME_VMAP_FLUSH	 21
+#define I915_PARAM_RSVD_FOR_FUTURE_USE	 22
+
+typedef struct drm_i915_getparam {
+	int param;
+	int __user *value;
+} drm_i915_getparam_t;
+
+/* Ioctl to set kernel params:
+ */
+#define I915_SETPARAM_USE_MI_BATCHBUFFER_START            1
+#define I915_SETPARAM_TEX_LRU_LOG_GRANULARITY             2
+#define I915_SETPARAM_ALLOW_BATCHBUFFER                   3
+#define I915_SETPARAM_NUM_USED_FENCES                     4
+
+typedef struct drm_i915_setparam {
+	int param;
+	int value;
+} drm_i915_setparam_t;
+
+/* A memory manager for regions of shared memory:
+ */
+#define I915_MEM_REGION_AGP 1
+
+typedef struct drm_i915_mem_alloc {
+	int region;
+	int alignment;
+	int size;
+	int __user *region_offset;	/* offset from start of fb or agp */
+} drm_i915_mem_alloc_t;
+
+typedef struct drm_i915_mem_free {
+	int region;
+	int region_offset;
+} drm_i915_mem_free_t;
+
+typedef struct drm_i915_mem_init_heap {
+	int region;
+	int size;
+	int start;
+} drm_i915_mem_init_heap_t;
+
+/* Allow memory manager to be torn down and re-initialized (eg on
+ * rotate):
+ */
+typedef struct drm_i915_mem_destroy_heap {
+	int region;
+} drm_i915_mem_destroy_heap_t;
+
+/* Allow X server to configure which pipes to monitor for vblank signals
+ */
+#define	DRM_I915_VBLANK_PIPE_A	1
+#define	DRM_I915_VBLANK_PIPE_B	2
+
+typedef struct drm_i915_vblank_pipe {
+	int pipe;
+} drm_i915_vblank_pipe_t;
+
+/* Schedule buffer swap at given vertical blank:
+ */
+typedef struct drm_i915_vblank_swap {
+	drm_drawable_t drawable;
+	enum drm_vblank_seq_type seqtype;
+	unsigned int sequence;
+} drm_i915_vblank_swap_t;
+
+typedef struct drm_i915_hws_addr {
+	__u64 addr;
+} drm_i915_hws_addr_t;
+
+struct drm_i915_gem_init {
+	/**
+	 * Beginning offset in the GTT to be managed by the DRM memory
+	 * manager.
+	 */
+	__u64 gtt_start;
+	/**
+	 * Ending offset in the GTT to be managed by the DRM memory
+	 * manager.
+	 */
+	__u64 gtt_end;
+};
+
+struct drm_i915_gem_create {
+	/**
+	 * Requested size for the object.
+	 *
+	 * The (page-aligned) allocated size for the object will be returned.
+	 */
+	__u64 size;
+	/**
+	 * Returned handle for the object.
+	 *
+	 * Object handles are nonzero.
+	 */
+	__u32 handle;
+	__u32 pad;
+};
+
+struct drm_i915_gem_pread {
+	/** Handle for the object being read. */
+	__u32 handle;
+	__u32 pad;
+	/** Offset into the object to read from */
+	__u64 offset;
+	/** Length of data to read */
+	__u64 size;
+	/**
+	 * Pointer to write the data into.
+	 *
+	 * This is a fixed-size type for 32/64 compatibility.
+	 */
+	__u64 data_ptr;
+};
+
+struct drm_i915_gem_pwrite {
+	/** Handle for the object being written to. */
+	__u32 handle;
+	__u32 pad;
+	/** Offset into the object to write to */
+	__u64 offset;
+	/** Length of data to write */
+	__u64 size;
+	/**
+	 * Pointer to read the data from.
+	 *
+	 * This is a fixed-size type for 32/64 compatibility.
+	 */
+	__u64 data_ptr;
+};
+
+struct drm_i915_gem_mmap {
+	/** Handle for the object being mapped. */
+	__u32 handle;
+	__u32 pad;
+	/** Offset in the object to map. */
+	__u64 offset;
+	/**
+	 * Length of data to map.
+	 *
+	 * The value will be page-aligned.
+	 */
+	__u64 size;
+	/**
+	 * Returned pointer the data was mapped at.
+	 *
+	 * This is a fixed-size type for 32/64 compatibility.
+	 */
+	__u64 addr_ptr;
+};
+
+struct drm_i915_gem_mmap_gtt {
+	/** Handle for the object being mapped. */
+	__u32 handle;
+	__u32 pad;
+	/**
+	 * Fake offset to use for subsequent mmap call
+	 *
+	 * This is a fixed-size type for 32/64 compatibility.
+	 */
+	__u64 offset;
+};
+
+struct drm_i915_gem_set_domain {
+	/** Handle for the object */
+	__u32 handle;
+
+	/** New read domains */
+	__u32 read_domains;
+
+	/** New write domain */
+	__u32 write_domain;
+};
+
+struct drm_i915_gem_sw_finish {
+	/** Handle for the object */
+	__u32 handle;
+};
+
+struct drm_i915_gem_relocation_entry {
+	/**
+	 * Handle of the buffer being pointed to by this relocation entry.
+	 *
+	 * It's appealing to make this be an index into the mm_validate_entry
+	 * list to refer to the buffer, but this allows the driver to create
+	 * a relocation list for state buffers and not re-write it per
+	 * exec using the buffer.
+	 */
+	__u32 target_handle;
+
+	/**
+	 * Value to be added to the offset of the target buffer to make up
+	 * the relocation entry.
+	 */
+	__u32 delta;
+
+	/** Offset in the buffer the relocation entry will be written into */
+	__u64 offset;
+
+	/**
+	 * Offset value of the target buffer that the relocation entry was last
+	 * written as.
+	 *
+	 * If the buffer has the same offset as last time, we can skip syncing
+	 * and writing the relocation.  This value is written back out by
+	 * the execbuffer ioctl when the relocation is written.
+	 */
+	__u64 presumed_offset;
+
+	/**
+	 * Target memory domains read by this operation.
+	 */
+	__u32 read_domains;
+
+	/**
+	 * Target memory domains written by this operation.
+	 *
+	 * Note that only one domain may be written by the whole
+	 * execbuffer operation, so that where there are conflicts,
+	 * the application will get -EINVAL back.
+	 */
+	__u32 write_domain;
+};
+
+/** @{
+ * Intel memory domains
+ *
+ * Most of these just align with the various caches in
+ * the system and are used to flush and invalidate as
+ * objects end up cached in different domains.
+ */
+/** CPU cache */
+#define I915_GEM_DOMAIN_CPU		0x00000001
+/** Render cache, used by 2D and 3D drawing */
+#define I915_GEM_DOMAIN_RENDER		0x00000002
+/** Sampler cache, used by texture engine */
+#define I915_GEM_DOMAIN_SAMPLER		0x00000004
+/** Command queue, used to load batch buffers */
+#define I915_GEM_DOMAIN_COMMAND		0x00000008
+/** Instruction cache, used by shader programs */
+#define I915_GEM_DOMAIN_INSTRUCTION	0x00000010
+/** Vertex address cache */
+#define I915_GEM_DOMAIN_VERTEX		0x00000020
+/** GTT domain - aperture and scanout */
+#define I915_GEM_DOMAIN_GTT		0x00000040
+/** @} */
+
+struct drm_i915_gem_exec_object {
+	/**
+	 * User's handle for a buffer to be bound into the GTT for this
+	 * operation.
+	 */
+	__u32 handle;
+
+	/** Number of relocations to be performed on this buffer */
+	__u32 relocation_count;
+	/**
+	 * Pointer to array of struct drm_i915_gem_relocation_entry containing
+	 * the relocations to be performed in this buffer.
+	 */
+	__u64 relocs_ptr;
+
+	/** Required alignment in graphics aperture */
+	__u64 alignment;
+
+	/**
+	 * Returned value of the updated offset of the object, for future
+	 * presumed_offset writes.
+	 */
+	__u64 offset;
+};
+
+struct drm_i915_gem_execbuffer {
+	/**
+	 * List of buffers to be validated with their relocations to be
+	 * performend on them.
+	 *
+	 * This is a pointer to an array of struct drm_i915_gem_validate_entry.
+	 *
+	 * These buffers must be listed in an order such that all relocations
+	 * a buffer is performing refer to buffers that have already appeared
+	 * in the validate list.
+	 */
+	__u64 buffers_ptr;
+	__u32 buffer_count;
+
+	/** Offset in the batchbuffer to start execution from. */
+	__u32 batch_start_offset;
+	/** Bytes used in batchbuffer from batch_start_offset */
+	__u32 batch_len;
+	__u32 DR1;
+	__u32 DR4;
+	__u32 num_cliprects;
+	/** This is a struct drm_clip_rect *cliprects */
+	__u64 cliprects_ptr;
+};
+
+struct drm_i915_gem_exec_object2 {
+	/**
+	 * User's handle for a buffer to be bound into the GTT for this
+	 * operation.
+	 */
+	__u32 handle;
+
+	/** Number of relocations to be performed on this buffer */
+	__u32 relocation_count;
+	/**
+	 * Pointer to array of struct drm_i915_gem_relocation_entry containing
+	 * the relocations to be performed in this buffer.
+	 */
+	__u64 relocs_ptr;
+
+	/** Required alignment in graphics aperture */
+	__u64 alignment;
+
+	/**
+	 * Returned value of the updated offset of the object, for future
+	 * presumed_offset writes.
+	 */
+	__u64 offset;
+
+#define EXEC_OBJECT_NEEDS_FENCE (1<<0)
+	__u64 flags;
+	__u64 rsvd1;
+	__u64 rsvd2;
+};
+
+struct drm_i915_gem_execbuffer2 {
+	/**
+	 * List of gem_exec_object2 structs
+	 */
+	__u64 buffers_ptr;
+	__u32 buffer_count;
+
+	/** Offset in the batchbuffer to start execution from. */
+	__u32 batch_start_offset;
+	/** Bytes used in batchbuffer from batch_start_offset */
+	__u32 batch_len;
+	__u32 DR1;
+	__u32 DR4;
+	__u32 num_cliprects;
+	/** This is a struct drm_clip_rect *cliprects */
+	__u64 cliprects_ptr;
+#define I915_EXEC_RING_MASK              (7<<0)
+#define I915_EXEC_DEFAULT                (0<<0)
+#define I915_EXEC_RENDER                 (1<<0)
+#define I915_EXEC_BSD                    (2<<0)
+#define I915_EXEC_BLT                    (3<<0)
+
+/* Used for switching the constants addressing mode on gen4+ RENDER ring.
+ * Gen6+ only supports relative addressing to dynamic state (default) and
+ * absolute addressing.
+ *
+ * These flags are ignored for the BSD and BLT rings.
+ */
+#define I915_EXEC_CONSTANTS_MASK 	(3<<6)
+#define I915_EXEC_CONSTANTS_REL_GENERAL (0<<6) /* default */
+#define I915_EXEC_CONSTANTS_ABSOLUTE 	(1<<6)
+#define I915_EXEC_CONSTANTS_REL_SURFACE (2<<6) /* gen4/5 only */
+	__u64 flags;
+	__u64 rsvd1; /* now used for context info */
+	__u64 rsvd2;
+};
+
+/** Resets the SO write offset registers for transform feedback on gen7. */
+#define I915_EXEC_GEN7_SOL_RESET	(1<<8)
+
+#define I915_EXEC_CONTEXT_ID_MASK	(0xffffffff)
+#define i915_execbuffer2_set_context_id(eb2, context) \
+	(eb2).rsvd1 = context & I915_EXEC_CONTEXT_ID_MASK
+#define i915_execbuffer2_get_context_id(eb2) \
+	((eb2).rsvd1 & I915_EXEC_CONTEXT_ID_MASK)
+
+struct drm_i915_gem_pin {
+	/** Handle of the buffer to be pinned. */
+	__u32 handle;
+	__u32 pad;
+
+	/** alignment required within the aperture */
+	__u64 alignment;
+
+	/** Returned GTT offset of the buffer. */
+	__u64 offset;
+};
+
+struct drm_i915_gem_unpin {
+	/** Handle of the buffer to be unpinned. */
+	__u32 handle;
+	__u32 pad;
+};
+
+struct drm_i915_gem_busy {
+	/** Handle of the buffer to check for busy */
+	__u32 handle;
+
+	/** Return busy status (1 if busy, 0 if idle).
+	 * The high word is used to indicate on which rings the object
+	 * currently resides:
+	 *  16:31 - busy (r or r/w) rings (16 render, 17 bsd, 18 blt, etc)
+	 */
+	__u32 busy;
+};
+
+#define I915_CACHING_NONE		0
+#define I915_CACHING_CACHED		1
+
+struct drm_i915_gem_caching {
+	/**
+	 * Handle of the buffer to set/get the caching level of. */
+	__u32 handle;
+
+	/**
+	 * Cacheing level to apply or return value
+	 *
+	 * bits0-15 are for generic caching control (i.e. the above defined
+	 * values). bits16-31 are reserved for platform-specific variations
+	 * (e.g. l3$ caching on gen7). */
+	__u32 caching;
+};
+
+#define I915_TILING_NONE	0
+#define I915_TILING_X		1
+#define I915_TILING_Y		2
+
+#define I915_BIT_6_SWIZZLE_NONE		0
+#define I915_BIT_6_SWIZZLE_9		1
+#define I915_BIT_6_SWIZZLE_9_10		2
+#define I915_BIT_6_SWIZZLE_9_11		3
+#define I915_BIT_6_SWIZZLE_9_10_11	4
+/* Not seen by userland */
+#define I915_BIT_6_SWIZZLE_UNKNOWN	5
+/* Seen by userland. */
+#define I915_BIT_6_SWIZZLE_9_17		6
+#define I915_BIT_6_SWIZZLE_9_10_17	7
+
+struct drm_i915_gem_set_tiling {
+	/** Handle of the buffer to have its tiling state updated */
+	__u32 handle;
+
+	/**
+	 * Tiling mode for the object (I915_TILING_NONE, I915_TILING_X,
+	 * I915_TILING_Y).
+	 *
+	 * This value is to be set on request, and will be updated by the
+	 * kernel on successful return with the actual chosen tiling layout.
+	 *
+	 * The tiling mode may be demoted to I915_TILING_NONE when the system
+	 * has bit 6 swizzling that can't be managed correctly by GEM.
+	 *
+	 * Buffer contents become undefined when changing tiling_mode.
+	 */
+	__u32 tiling_mode;
+
+	/**
+	 * Stride in bytes for the object when in I915_TILING_X or
+	 * I915_TILING_Y.
+	 */
+	__u32 stride;
+
+	/**
+	 * Returned address bit 6 swizzling required for CPU access through
+	 * mmap mapping.
+	 */
+	__u32 swizzle_mode;
+};
+
+struct drm_i915_gem_get_tiling {
+	/** Handle of the buffer to get tiling state for. */
+	__u32 handle;
+
+	/**
+	 * Current tiling mode for the object (I915_TILING_NONE, I915_TILING_X,
+	 * I915_TILING_Y).
+	 */
+	__u32 tiling_mode;
+
+	/**
+	 * Returned address bit 6 swizzling required for CPU access through
+	 * mmap mapping.
+	 */
+	__u32 swizzle_mode;
+};
+
+struct drm_i915_gem_get_aperture {
+	/** Total size of the aperture used by i915_gem_execbuffer, in bytes */
+	__u64 aper_size;
+
+	/**
+	 * Available space in the aperture used by i915_gem_execbuffer, in
+	 * bytes
+	 */
+	__u64 aper_available_size;
+};
+
+struct drm_i915_get_pipe_from_crtc_id {
+	/** ID of CRTC being requested **/
+	__u32 crtc_id;
+
+	/** pipe of requested CRTC **/
+	__u32 pipe;
+};
+
+#define I915_MADV_WILLNEED 0
+#define I915_MADV_DONTNEED 1
+#define __I915_MADV_PURGED 2 /* internal state */
+
+struct drm_i915_gem_madvise {
+	/** Handle of the buffer to change the backing store advice */
+	__u32 handle;
+
+	/* Advice: either the buffer will be needed again in the near future,
+	 *         or wont be and could be discarded under memory pressure.
+	 */
+	__u32 madv;
+
+	/** Whether the backing store still exists. */
+	__u32 retained;
+};
+
+/* flags */
+#define I915_OVERLAY_TYPE_MASK 		0xff
+#define I915_OVERLAY_YUV_PLANAR 	0x01
+#define I915_OVERLAY_YUV_PACKED 	0x02
+#define I915_OVERLAY_RGB		0x03
+
+#define I915_OVERLAY_DEPTH_MASK		0xff00
+#define I915_OVERLAY_RGB24		0x1000
+#define I915_OVERLAY_RGB16		0x2000
+#define I915_OVERLAY_RGB15		0x3000
+#define I915_OVERLAY_YUV422		0x0100
+#define I915_OVERLAY_YUV411		0x0200
+#define I915_OVERLAY_YUV420		0x0300
+#define I915_OVERLAY_YUV410		0x0400
+
+#define I915_OVERLAY_SWAP_MASK		0xff0000
+#define I915_OVERLAY_NO_SWAP		0x000000
+#define I915_OVERLAY_UV_SWAP		0x010000
+#define I915_OVERLAY_Y_SWAP		0x020000
+#define I915_OVERLAY_Y_AND_UV_SWAP	0x030000
+
+#define I915_OVERLAY_FLAGS_MASK		0xff000000
+#define I915_OVERLAY_ENABLE		0x01000000
+
+struct drm_intel_overlay_put_image {
+	/* various flags and src format description */
+	__u32 flags;
+	/* source picture description */
+	__u32 bo_handle;
+	/* stride values and offsets are in bytes, buffer relative */
+	__u16 stride_Y; /* stride for packed formats */
+	__u16 stride_UV;
+	__u32 offset_Y; /* offset for packet formats */
+	__u32 offset_U;
+	__u32 offset_V;
+	/* in pixels */
+	__u16 src_width;
+	__u16 src_height;
+	/* to compensate the scaling factors for partially covered surfaces */
+	__u16 src_scan_width;
+	__u16 src_scan_height;
+	/* output crtc description */
+	__u32 crtc_id;
+	__u16 dst_x;
+	__u16 dst_y;
+	__u16 dst_width;
+	__u16 dst_height;
+};
+
+/* flags */
+#define I915_OVERLAY_UPDATE_ATTRS	(1<<0)
+#define I915_OVERLAY_UPDATE_GAMMA	(1<<1)
+struct drm_intel_overlay_attrs {
+	__u32 flags;
+	__u32 color_key;
+	__s32 brightness;
+	__u32 contrast;
+	__u32 saturation;
+	__u32 gamma0;
+	__u32 gamma1;
+	__u32 gamma2;
+	__u32 gamma3;
+	__u32 gamma4;
+	__u32 gamma5;
+};
+
+/*
+ * Intel sprite handling
+ *
+ * Color keying works with a min/mask/max tuple.  Both source and destination
+ * color keying is allowed.
+ *
+ * Source keying:
+ * Sprite pixels within the min & max values, masked against the color channels
+ * specified in the mask field, will be transparent.  All other pixels will
+ * be displayed on top of the primary plane.  For RGB surfaces, only the min
+ * and mask fields will be used; ranged compares are not allowed.
+ *
+ * Destination keying:
+ * Primary plane pixels that match the min value, masked against the color
+ * channels specified in the mask field, will be replaced by corresponding
+ * pixels from the sprite plane.
+ *
+ * Note that source & destination keying are exclusive; only one can be
+ * active on a given plane.
+ */
+
+#define I915_SET_COLORKEY_NONE		(1<<0) /* disable color key matching */
+#define I915_SET_COLORKEY_DESTINATION	(1<<1)
+#define I915_SET_COLORKEY_SOURCE	(1<<2)
+struct drm_intel_sprite_colorkey {
+	__u32 plane_id;
+	__u32 min_value;
+	__u32 channel_mask;
+	__u32 max_value;
+	__u32 flags;
+};
+
+struct drm_i915_gem_wait {
+	/** Handle of BO we shall wait on */
+	__u32 bo_handle;
+	__u32 flags;
+	/** Number of nanoseconds to wait, Returns time remaining. */
+	__s64 timeout_ns;
+};
+
+struct drm_i915_gem_context_create {
+	/*  output: id of new context*/
+	__u32 ctx_id;
+	__u32 pad;
+};
+
+struct drm_i915_gem_context_destroy {
+	__u32 ctx_id;
+	__u32 pad;
+};
+
+struct drm_i915_reg_read {
+	__u64 offset;
+	__u64 val; /* Return value */
+};
+#endif /* _UAPI_I915_DRM_H_ */
diff --git a/include/drm/mga_drm.h b/include/uapi/drm/mga_drm.h
similarity index 100%
rename from include/drm/mga_drm.h
rename to include/uapi/drm/mga_drm.h
diff --git a/include/drm/nouveau_drm.h b/include/uapi/drm/nouveau_drm.h
similarity index 100%
rename from include/drm/nouveau_drm.h
rename to include/uapi/drm/nouveau_drm.h
diff --git a/include/drm/r128_drm.h b/include/uapi/drm/r128_drm.h
similarity index 100%
rename from include/drm/r128_drm.h
rename to include/uapi/drm/r128_drm.h
diff --git a/include/drm/radeon_drm.h b/include/uapi/drm/radeon_drm.h
similarity index 100%
rename from include/drm/radeon_drm.h
rename to include/uapi/drm/radeon_drm.h
diff --git a/include/drm/savage_drm.h b/include/uapi/drm/savage_drm.h
similarity index 100%
rename from include/drm/savage_drm.h
rename to include/uapi/drm/savage_drm.h
diff --git a/include/drm/sis_drm.h b/include/uapi/drm/sis_drm.h
similarity index 100%
rename from include/drm/sis_drm.h
rename to include/uapi/drm/sis_drm.h
diff --git a/include/drm/via_drm.h b/include/uapi/drm/via_drm.h
similarity index 100%
rename from include/drm/via_drm.h
rename to include/uapi/drm/via_drm.h
diff --git a/include/drm/vmwgfx_drm.h b/include/uapi/drm/vmwgfx_drm.h
similarity index 100%
rename from include/drm/vmwgfx_drm.h
rename to include/uapi/drm/vmwgfx_drm.h
diff --git a/include/uapi/linux/caif/Kbuild b/include/uapi/linux/caif/Kbuild
index aafaa5a..4339661 100644
--- a/include/uapi/linux/caif/Kbuild
+++ b/include/uapi/linux/caif/Kbuild
@@ -1 +1,3 @@
 # UAPI Header export list
+header-y += caif_socket.h
+header-y += if_caif.h
diff --git a/include/linux/caif/caif_socket.h b/include/uapi/linux/caif/caif_socket.h
similarity index 100%
rename from include/linux/caif/caif_socket.h
rename to include/uapi/linux/caif/caif_socket.h
diff --git a/include/linux/caif/if_caif.h b/include/uapi/linux/caif/if_caif.h
similarity index 100%
rename from include/linux/caif/if_caif.h
rename to include/uapi/linux/caif/if_caif.h
diff --git a/include/uapi/linux/isdn/Kbuild b/include/uapi/linux/isdn/Kbuild
index aafaa5a..89e5285 100644
--- a/include/uapi/linux/isdn/Kbuild
+++ b/include/uapi/linux/isdn/Kbuild
@@ -1 +1,2 @@
 # UAPI Header export list
+header-y += capicmd.h
diff --git a/include/linux/isdn/capicmd.h b/include/uapi/linux/isdn/capicmd.h
similarity index 100%
rename from include/linux/isdn/capicmd.h
rename to include/uapi/linux/isdn/capicmd.h
diff --git a/include/uapi/linux/netfilter/Kbuild b/include/uapi/linux/netfilter/Kbuild
index 4afbace..08f555f 100644
--- a/include/uapi/linux/netfilter/Kbuild
+++ b/include/uapi/linux/netfilter/Kbuild
@@ -1,2 +1,78 @@
 # UAPI Header export list
 header-y += ipset/
+header-y += nf_conntrack_common.h
+header-y += nf_conntrack_ftp.h
+header-y += nf_conntrack_sctp.h
+header-y += nf_conntrack_tcp.h
+header-y += nf_conntrack_tuple_common.h
+header-y += nf_nat.h
+header-y += nfnetlink.h
+header-y += nfnetlink_acct.h
+header-y += nfnetlink_compat.h
+header-y += nfnetlink_conntrack.h
+header-y += nfnetlink_cthelper.h
+header-y += nfnetlink_cttimeout.h
+header-y += nfnetlink_log.h
+header-y += nfnetlink_queue.h
+header-y += x_tables.h
+header-y += xt_AUDIT.h
+header-y += xt_CHECKSUM.h
+header-y += xt_CLASSIFY.h
+header-y += xt_CONNMARK.h
+header-y += xt_CONNSECMARK.h
+header-y += xt_CT.h
+header-y += xt_DSCP.h
+header-y += xt_IDLETIMER.h
+header-y += xt_LED.h
+header-y += xt_LOG.h
+header-y += xt_MARK.h
+header-y += xt_NFLOG.h
+header-y += xt_NFQUEUE.h
+header-y += xt_RATEEST.h
+header-y += xt_SECMARK.h
+header-y += xt_TCPMSS.h
+header-y += xt_TCPOPTSTRIP.h
+header-y += xt_TEE.h
+header-y += xt_TPROXY.h
+header-y += xt_addrtype.h
+header-y += xt_cluster.h
+header-y += xt_comment.h
+header-y += xt_connbytes.h
+header-y += xt_connlimit.h
+header-y += xt_connmark.h
+header-y += xt_conntrack.h
+header-y += xt_cpu.h
+header-y += xt_dccp.h
+header-y += xt_devgroup.h
+header-y += xt_dscp.h
+header-y += xt_ecn.h
+header-y += xt_esp.h
+header-y += xt_hashlimit.h
+header-y += xt_helper.h
+header-y += xt_iprange.h
+header-y += xt_ipvs.h
+header-y += xt_length.h
+header-y += xt_limit.h
+header-y += xt_mac.h
+header-y += xt_mark.h
+header-y += xt_multiport.h
+header-y += xt_nfacct.h
+header-y += xt_osf.h
+header-y += xt_owner.h
+header-y += xt_physdev.h
+header-y += xt_pkttype.h
+header-y += xt_policy.h
+header-y += xt_quota.h
+header-y += xt_rateest.h
+header-y += xt_realm.h
+header-y += xt_recent.h
+header-y += xt_sctp.h
+header-y += xt_set.h
+header-y += xt_socket.h
+header-y += xt_state.h
+header-y += xt_statistic.h
+header-y += xt_string.h
+header-y += xt_tcpmss.h
+header-y += xt_tcpudp.h
+header-y += xt_time.h
+header-y += xt_u32.h
diff --git a/include/uapi/linux/netfilter/ipset/Kbuild b/include/uapi/linux/netfilter/ipset/Kbuild
index aafaa5a..d268042 100644
--- a/include/uapi/linux/netfilter/ipset/Kbuild
+++ b/include/uapi/linux/netfilter/ipset/Kbuild
@@ -1 +1,5 @@
 # UAPI Header export list
+header-y += ip_set.h
+header-y += ip_set_bitmap.h
+header-y += ip_set_hash.h
+header-y += ip_set_list.h
diff --git a/include/uapi/linux/netfilter/ipset/ip_set.h b/include/uapi/linux/netfilter/ipset/ip_set.h
new file mode 100644
index 0000000..fbee428
--- /dev/null
+++ b/include/uapi/linux/netfilter/ipset/ip_set.h
@@ -0,0 +1,231 @@
+/* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
+ *                         Patrick Schaaf <bof@bof.de>
+ *                         Martin Josefsson <gandalf@wlug.westbo.se>
+ * Copyright (C) 2003-2011 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef _UAPI_IP_SET_H
+#define _UAPI_IP_SET_H
+
+
+#include <linux/types.h>
+
+/* The protocol version */
+#define IPSET_PROTOCOL		6
+
+/* The max length of strings including NUL: set and type identifiers */
+#define IPSET_MAXNAMELEN	32
+
+/* Message types and commands */
+enum ipset_cmd {
+	IPSET_CMD_NONE,
+	IPSET_CMD_PROTOCOL,	/* 1: Return protocol version */
+	IPSET_CMD_CREATE,	/* 2: Create a new (empty) set */
+	IPSET_CMD_DESTROY,	/* 3: Destroy a (empty) set */
+	IPSET_CMD_FLUSH,	/* 4: Remove all elements from a set */
+	IPSET_CMD_RENAME,	/* 5: Rename a set */
+	IPSET_CMD_SWAP,		/* 6: Swap two sets */
+	IPSET_CMD_LIST,		/* 7: List sets */
+	IPSET_CMD_SAVE,		/* 8: Save sets */
+	IPSET_CMD_ADD,		/* 9: Add an element to a set */
+	IPSET_CMD_DEL,		/* 10: Delete an element from a set */
+	IPSET_CMD_TEST,		/* 11: Test an element in a set */
+	IPSET_CMD_HEADER,	/* 12: Get set header data only */
+	IPSET_CMD_TYPE,		/* 13: Get set type */
+	IPSET_MSG_MAX,		/* Netlink message commands */
+
+	/* Commands in userspace: */
+	IPSET_CMD_RESTORE = IPSET_MSG_MAX, /* 14: Enter restore mode */
+	IPSET_CMD_HELP,		/* 15: Get help */
+	IPSET_CMD_VERSION,	/* 16: Get program version */
+	IPSET_CMD_QUIT,		/* 17: Quit from interactive mode */
+
+	IPSET_CMD_MAX,
+
+	IPSET_CMD_COMMIT = IPSET_CMD_MAX, /* 18: Commit buffered commands */
+};
+
+/* Attributes at command level */
+enum {
+	IPSET_ATTR_UNSPEC,
+	IPSET_ATTR_PROTOCOL,	/* 1: Protocol version */
+	IPSET_ATTR_SETNAME,	/* 2: Name of the set */
+	IPSET_ATTR_TYPENAME,	/* 3: Typename */
+	IPSET_ATTR_SETNAME2 = IPSET_ATTR_TYPENAME, /* Setname at rename/swap */
+	IPSET_ATTR_REVISION,	/* 4: Settype revision */
+	IPSET_ATTR_FAMILY,	/* 5: Settype family */
+	IPSET_ATTR_FLAGS,	/* 6: Flags at command level */
+	IPSET_ATTR_DATA,	/* 7: Nested attributes */
+	IPSET_ATTR_ADT,		/* 8: Multiple data containers */
+	IPSET_ATTR_LINENO,	/* 9: Restore lineno */
+	IPSET_ATTR_PROTOCOL_MIN, /* 10: Minimal supported version number */
+	IPSET_ATTR_REVISION_MIN	= IPSET_ATTR_PROTOCOL_MIN, /* type rev min */
+	__IPSET_ATTR_CMD_MAX,
+};
+#define IPSET_ATTR_CMD_MAX	(__IPSET_ATTR_CMD_MAX - 1)
+
+/* CADT specific attributes */
+enum {
+	IPSET_ATTR_IP = IPSET_ATTR_UNSPEC + 1,
+	IPSET_ATTR_IP_FROM = IPSET_ATTR_IP,
+	IPSET_ATTR_IP_TO,	/* 2 */
+	IPSET_ATTR_CIDR,	/* 3 */
+	IPSET_ATTR_PORT,	/* 4 */
+	IPSET_ATTR_PORT_FROM = IPSET_ATTR_PORT,
+	IPSET_ATTR_PORT_TO,	/* 5 */
+	IPSET_ATTR_TIMEOUT,	/* 6 */
+	IPSET_ATTR_PROTO,	/* 7 */
+	IPSET_ATTR_CADT_FLAGS,	/* 8 */
+	IPSET_ATTR_CADT_LINENO = IPSET_ATTR_LINENO,	/* 9 */
+	/* Reserve empty slots */
+	IPSET_ATTR_CADT_MAX = 16,
+	/* Create-only specific attributes */
+	IPSET_ATTR_GC,
+	IPSET_ATTR_HASHSIZE,
+	IPSET_ATTR_MAXELEM,
+	IPSET_ATTR_NETMASK,
+	IPSET_ATTR_PROBES,
+	IPSET_ATTR_RESIZE,
+	IPSET_ATTR_SIZE,
+	/* Kernel-only */
+	IPSET_ATTR_ELEMENTS,
+	IPSET_ATTR_REFERENCES,
+	IPSET_ATTR_MEMSIZE,
+
+	__IPSET_ATTR_CREATE_MAX,
+};
+#define IPSET_ATTR_CREATE_MAX	(__IPSET_ATTR_CREATE_MAX - 1)
+
+/* ADT specific attributes */
+enum {
+	IPSET_ATTR_ETHER = IPSET_ATTR_CADT_MAX + 1,
+	IPSET_ATTR_NAME,
+	IPSET_ATTR_NAMEREF,
+	IPSET_ATTR_IP2,
+	IPSET_ATTR_CIDR2,
+	IPSET_ATTR_IP2_TO,
+	IPSET_ATTR_IFACE,
+	__IPSET_ATTR_ADT_MAX,
+};
+#define IPSET_ATTR_ADT_MAX	(__IPSET_ATTR_ADT_MAX - 1)
+
+/* IP specific attributes */
+enum {
+	IPSET_ATTR_IPADDR_IPV4 = IPSET_ATTR_UNSPEC + 1,
+	IPSET_ATTR_IPADDR_IPV6,
+	__IPSET_ATTR_IPADDR_MAX,
+};
+#define IPSET_ATTR_IPADDR_MAX	(__IPSET_ATTR_IPADDR_MAX - 1)
+
+/* Error codes */
+enum ipset_errno {
+	IPSET_ERR_PRIVATE = 4096,
+	IPSET_ERR_PROTOCOL,
+	IPSET_ERR_FIND_TYPE,
+	IPSET_ERR_MAX_SETS,
+	IPSET_ERR_BUSY,
+	IPSET_ERR_EXIST_SETNAME2,
+	IPSET_ERR_TYPE_MISMATCH,
+	IPSET_ERR_EXIST,
+	IPSET_ERR_INVALID_CIDR,
+	IPSET_ERR_INVALID_NETMASK,
+	IPSET_ERR_INVALID_FAMILY,
+	IPSET_ERR_TIMEOUT,
+	IPSET_ERR_REFERENCED,
+	IPSET_ERR_IPADDR_IPV4,
+	IPSET_ERR_IPADDR_IPV6,
+
+	/* Type specific error codes */
+	IPSET_ERR_TYPE_SPECIFIC = 4352,
+};
+
+/* Flags at command level */
+enum ipset_cmd_flags {
+	IPSET_FLAG_BIT_EXIST	= 0,
+	IPSET_FLAG_EXIST	= (1 << IPSET_FLAG_BIT_EXIST),
+	IPSET_FLAG_BIT_LIST_SETNAME = 1,
+	IPSET_FLAG_LIST_SETNAME	= (1 << IPSET_FLAG_BIT_LIST_SETNAME),
+	IPSET_FLAG_BIT_LIST_HEADER = 2,
+	IPSET_FLAG_LIST_HEADER	= (1 << IPSET_FLAG_BIT_LIST_HEADER),
+	IPSET_FLAG_CMD_MAX = 15,	/* Lower half */
+};
+
+/* Flags at CADT attribute level */
+enum ipset_cadt_flags {
+	IPSET_FLAG_BIT_BEFORE	= 0,
+	IPSET_FLAG_BEFORE	= (1 << IPSET_FLAG_BIT_BEFORE),
+	IPSET_FLAG_BIT_PHYSDEV	= 1,
+	IPSET_FLAG_PHYSDEV	= (1 << IPSET_FLAG_BIT_PHYSDEV),
+	IPSET_FLAG_BIT_NOMATCH	= 2,
+	IPSET_FLAG_NOMATCH	= (1 << IPSET_FLAG_BIT_NOMATCH),
+	IPSET_FLAG_CADT_MAX	= 15,	/* Upper half */
+};
+
+/* Commands with settype-specific attributes */
+enum ipset_adt {
+	IPSET_ADD,
+	IPSET_DEL,
+	IPSET_TEST,
+	IPSET_ADT_MAX,
+	IPSET_CREATE = IPSET_ADT_MAX,
+	IPSET_CADT_MAX,
+};
+
+/* Sets are identified by an index in kernel space. Tweak with ip_set_id_t
+ * and IPSET_INVALID_ID if you want to increase the max number of sets.
+ */
+typedef __u16 ip_set_id_t;
+
+#define IPSET_INVALID_ID		65535
+
+enum ip_set_dim {
+	IPSET_DIM_ZERO = 0,
+	IPSET_DIM_ONE,
+	IPSET_DIM_TWO,
+	IPSET_DIM_THREE,
+	/* Max dimension in elements.
+	 * If changed, new revision of iptables match/target is required.
+	 */
+	IPSET_DIM_MAX = 6,
+	IPSET_BIT_RETURN_NOMATCH = 7,
+};
+
+/* Option flags for kernel operations */
+enum ip_set_kopt {
+	IPSET_INV_MATCH = (1 << IPSET_DIM_ZERO),
+	IPSET_DIM_ONE_SRC = (1 << IPSET_DIM_ONE),
+	IPSET_DIM_TWO_SRC = (1 << IPSET_DIM_TWO),
+	IPSET_DIM_THREE_SRC = (1 << IPSET_DIM_THREE),
+	IPSET_RETURN_NOMATCH = (1 << IPSET_BIT_RETURN_NOMATCH),
+};
+
+
+/* Interface to iptables/ip6tables */
+
+#define SO_IP_SET		83
+
+union ip_set_name_index {
+	char name[IPSET_MAXNAMELEN];
+	ip_set_id_t index;
+};
+
+#define IP_SET_OP_GET_BYNAME	0x00000006	/* Get set index by name */
+struct ip_set_req_get_set {
+	unsigned int op;
+	unsigned int version;
+	union ip_set_name_index set;
+};
+
+#define IP_SET_OP_GET_BYINDEX	0x00000007	/* Get set name by index */
+/* Uses ip_set_req_get_set */
+
+#define IP_SET_OP_VERSION	0x00000100	/* Ask kernel version */
+struct ip_set_req_version {
+	unsigned int op;
+	unsigned int version;
+};
+
+#endif /* _UAPI_IP_SET_H */
diff --git a/include/uapi/linux/netfilter/ipset/ip_set_bitmap.h b/include/uapi/linux/netfilter/ipset/ip_set_bitmap.h
new file mode 100644
index 0000000..6a2c038
--- /dev/null
+++ b/include/uapi/linux/netfilter/ipset/ip_set_bitmap.h
@@ -0,0 +1,13 @@
+#ifndef _UAPI__IP_SET_BITMAP_H
+#define _UAPI__IP_SET_BITMAP_H
+
+/* Bitmap type specific error codes */
+enum {
+	/* The element is out of the range of the set */
+	IPSET_ERR_BITMAP_RANGE = IPSET_ERR_TYPE_SPECIFIC,
+	/* The range exceeds the size limit of the set type */
+	IPSET_ERR_BITMAP_RANGE_SIZE,
+};
+
+
+#endif /* _UAPI__IP_SET_BITMAP_H */
diff --git a/include/uapi/linux/netfilter/ipset/ip_set_hash.h b/include/uapi/linux/netfilter/ipset/ip_set_hash.h
new file mode 100644
index 0000000..352eecc
--- /dev/null
+++ b/include/uapi/linux/netfilter/ipset/ip_set_hash.h
@@ -0,0 +1,21 @@
+#ifndef _UAPI__IP_SET_HASH_H
+#define _UAPI__IP_SET_HASH_H
+
+/* Hash type specific error codes */
+enum {
+	/* Hash is full */
+	IPSET_ERR_HASH_FULL = IPSET_ERR_TYPE_SPECIFIC,
+	/* Null-valued element */
+	IPSET_ERR_HASH_ELEM,
+	/* Invalid protocol */
+	IPSET_ERR_INVALID_PROTO,
+	/* Protocol missing but must be specified */
+	IPSET_ERR_MISSING_PROTO,
+	/* Range not supported */
+	IPSET_ERR_HASH_RANGE_UNSUPPORTED,
+	/* Invalid range */
+	IPSET_ERR_HASH_RANGE,
+};
+
+
+#endif /* _UAPI__IP_SET_HASH_H */
diff --git a/include/uapi/linux/netfilter/ipset/ip_set_list.h b/include/uapi/linux/netfilter/ipset/ip_set_list.h
new file mode 100644
index 0000000..a44efaa
--- /dev/null
+++ b/include/uapi/linux/netfilter/ipset/ip_set_list.h
@@ -0,0 +1,21 @@
+#ifndef _UAPI__IP_SET_LIST_H
+#define _UAPI__IP_SET_LIST_H
+
+/* List type specific error codes */
+enum {
+	/* Set name to be added/deleted/tested does not exist. */
+	IPSET_ERR_NAME = IPSET_ERR_TYPE_SPECIFIC,
+	/* list:set type is not permitted to add */
+	IPSET_ERR_LOOP,
+	/* Missing reference set */
+	IPSET_ERR_BEFORE,
+	/* Reference set does not exist */
+	IPSET_ERR_NAMEREF,
+	/* Set is full */
+	IPSET_ERR_LIST_FULL,
+	/* Reference set is not added to the set */
+	IPSET_ERR_REF_EXIST,
+};
+
+
+#endif /* _UAPI__IP_SET_LIST_H */
diff --git a/include/uapi/linux/netfilter/nf_conntrack_common.h b/include/uapi/linux/netfilter/nf_conntrack_common.h
new file mode 100644
index 0000000..1644cdd
--- /dev/null
+++ b/include/uapi/linux/netfilter/nf_conntrack_common.h
@@ -0,0 +1,117 @@
+#ifndef _UAPI_NF_CONNTRACK_COMMON_H
+#define _UAPI_NF_CONNTRACK_COMMON_H
+/* Connection state tracking for netfilter.  This is separated from,
+   but required by, the NAT layer; it can also be used by an iptables
+   extension. */
+enum ip_conntrack_info {
+	/* Part of an established connection (either direction). */
+	IP_CT_ESTABLISHED,
+
+	/* Like NEW, but related to an existing connection, or ICMP error
+	   (in either direction). */
+	IP_CT_RELATED,
+
+	/* Started a new connection to track (only
+           IP_CT_DIR_ORIGINAL); may be a retransmission. */
+	IP_CT_NEW,
+
+	/* >= this indicates reply direction */
+	IP_CT_IS_REPLY,
+
+	IP_CT_ESTABLISHED_REPLY = IP_CT_ESTABLISHED + IP_CT_IS_REPLY,
+	IP_CT_RELATED_REPLY = IP_CT_RELATED + IP_CT_IS_REPLY,
+	IP_CT_NEW_REPLY = IP_CT_NEW + IP_CT_IS_REPLY,	
+	/* Number of distinct IP_CT types (no NEW in reply dirn). */
+	IP_CT_NUMBER = IP_CT_IS_REPLY * 2 - 1
+};
+
+/* Bitset representing status of connection. */
+enum ip_conntrack_status {
+	/* It's an expected connection: bit 0 set.  This bit never changed */
+	IPS_EXPECTED_BIT = 0,
+	IPS_EXPECTED = (1 << IPS_EXPECTED_BIT),
+
+	/* We've seen packets both ways: bit 1 set.  Can be set, not unset. */
+	IPS_SEEN_REPLY_BIT = 1,
+	IPS_SEEN_REPLY = (1 << IPS_SEEN_REPLY_BIT),
+
+	/* Conntrack should never be early-expired. */
+	IPS_ASSURED_BIT = 2,
+	IPS_ASSURED = (1 << IPS_ASSURED_BIT),
+
+	/* Connection is confirmed: originating packet has left box */
+	IPS_CONFIRMED_BIT = 3,
+	IPS_CONFIRMED = (1 << IPS_CONFIRMED_BIT),
+
+	/* Connection needs src nat in orig dir.  This bit never changed. */
+	IPS_SRC_NAT_BIT = 4,
+	IPS_SRC_NAT = (1 << IPS_SRC_NAT_BIT),
+
+	/* Connection needs dst nat in orig dir.  This bit never changed. */
+	IPS_DST_NAT_BIT = 5,
+	IPS_DST_NAT = (1 << IPS_DST_NAT_BIT),
+
+	/* Both together. */
+	IPS_NAT_MASK = (IPS_DST_NAT | IPS_SRC_NAT),
+
+	/* Connection needs TCP sequence adjusted. */
+	IPS_SEQ_ADJUST_BIT = 6,
+	IPS_SEQ_ADJUST = (1 << IPS_SEQ_ADJUST_BIT),
+
+	/* NAT initialization bits. */
+	IPS_SRC_NAT_DONE_BIT = 7,
+	IPS_SRC_NAT_DONE = (1 << IPS_SRC_NAT_DONE_BIT),
+
+	IPS_DST_NAT_DONE_BIT = 8,
+	IPS_DST_NAT_DONE = (1 << IPS_DST_NAT_DONE_BIT),
+
+	/* Both together */
+	IPS_NAT_DONE_MASK = (IPS_DST_NAT_DONE | IPS_SRC_NAT_DONE),
+
+	/* Connection is dying (removed from lists), can not be unset. */
+	IPS_DYING_BIT = 9,
+	IPS_DYING = (1 << IPS_DYING_BIT),
+
+	/* Connection has fixed timeout. */
+	IPS_FIXED_TIMEOUT_BIT = 10,
+	IPS_FIXED_TIMEOUT = (1 << IPS_FIXED_TIMEOUT_BIT),
+
+	/* Conntrack is a template */
+	IPS_TEMPLATE_BIT = 11,
+	IPS_TEMPLATE = (1 << IPS_TEMPLATE_BIT),
+
+	/* Conntrack is a fake untracked entry */
+	IPS_UNTRACKED_BIT = 12,
+	IPS_UNTRACKED = (1 << IPS_UNTRACKED_BIT),
+
+	/* Conntrack got a helper explicitly attached via CT target. */
+	IPS_HELPER_BIT = 13,
+	IPS_HELPER = (1 << IPS_HELPER_BIT),
+};
+
+/* Connection tracking event types */
+enum ip_conntrack_events {
+	IPCT_NEW,		/* new conntrack */
+	IPCT_RELATED,		/* related conntrack */
+	IPCT_DESTROY,		/* destroyed conntrack */
+	IPCT_REPLY,		/* connection has seen two-way traffic */
+	IPCT_ASSURED,		/* connection status has changed to assured */
+	IPCT_PROTOINFO,		/* protocol information has changed */
+	IPCT_HELPER,		/* new helper has been set */
+	IPCT_MARK,		/* new mark has been set */
+	IPCT_NATSEQADJ,		/* NAT is doing sequence adjustment */
+	IPCT_SECMARK,		/* new security mark has been set */
+};
+
+enum ip_conntrack_expect_events {
+	IPEXP_NEW,		/* new expectation */
+	IPEXP_DESTROY,		/* destroyed expectation */
+};
+
+/* expectation flags */
+#define NF_CT_EXPECT_PERMANENT		0x1
+#define NF_CT_EXPECT_INACTIVE		0x2
+#define NF_CT_EXPECT_USERSPACE		0x4
+
+
+#endif /* _UAPI_NF_CONNTRACK_COMMON_H */
diff --git a/include/uapi/linux/netfilter/nf_conntrack_ftp.h b/include/uapi/linux/netfilter/nf_conntrack_ftp.h
new file mode 100644
index 0000000..1030315
--- /dev/null
+++ b/include/uapi/linux/netfilter/nf_conntrack_ftp.h
@@ -0,0 +1,18 @@
+#ifndef _UAPI_NF_CONNTRACK_FTP_H
+#define _UAPI_NF_CONNTRACK_FTP_H
+/* FTP tracking. */
+
+/* This enum is exposed to userspace */
+enum nf_ct_ftp_type {
+	/* PORT command from client */
+	NF_CT_FTP_PORT,
+	/* PASV response from server */
+	NF_CT_FTP_PASV,
+	/* EPRT command from client */
+	NF_CT_FTP_EPRT,
+	/* EPSV response from server */
+	NF_CT_FTP_EPSV,
+};
+
+
+#endif /* _UAPI_NF_CONNTRACK_FTP_H */
diff --git a/include/linux/netfilter/nf_conntrack_sctp.h b/include/uapi/linux/netfilter/nf_conntrack_sctp.h
similarity index 100%
rename from include/linux/netfilter/nf_conntrack_sctp.h
rename to include/uapi/linux/netfilter/nf_conntrack_sctp.h
diff --git a/include/uapi/linux/netfilter/nf_conntrack_tcp.h b/include/uapi/linux/netfilter/nf_conntrack_tcp.h
new file mode 100644
index 0000000..9993a42
--- /dev/null
+++ b/include/uapi/linux/netfilter/nf_conntrack_tcp.h
@@ -0,0 +1,51 @@
+#ifndef _UAPI_NF_CONNTRACK_TCP_H
+#define _UAPI_NF_CONNTRACK_TCP_H
+/* TCP tracking. */
+
+#include <linux/types.h>
+
+/* This is exposed to userspace (ctnetlink) */
+enum tcp_conntrack {
+	TCP_CONNTRACK_NONE,
+	TCP_CONNTRACK_SYN_SENT,
+	TCP_CONNTRACK_SYN_RECV,
+	TCP_CONNTRACK_ESTABLISHED,
+	TCP_CONNTRACK_FIN_WAIT,
+	TCP_CONNTRACK_CLOSE_WAIT,
+	TCP_CONNTRACK_LAST_ACK,
+	TCP_CONNTRACK_TIME_WAIT,
+	TCP_CONNTRACK_CLOSE,
+	TCP_CONNTRACK_LISTEN,	/* obsolete */
+#define TCP_CONNTRACK_SYN_SENT2	TCP_CONNTRACK_LISTEN
+	TCP_CONNTRACK_MAX,
+	TCP_CONNTRACK_IGNORE,
+	TCP_CONNTRACK_RETRANS,
+	TCP_CONNTRACK_UNACK,
+	TCP_CONNTRACK_TIMEOUT_MAX
+};
+
+/* Window scaling is advertised by the sender */
+#define IP_CT_TCP_FLAG_WINDOW_SCALE		0x01
+
+/* SACK is permitted by the sender */
+#define IP_CT_TCP_FLAG_SACK_PERM		0x02
+
+/* This sender sent FIN first */
+#define IP_CT_TCP_FLAG_CLOSE_INIT		0x04
+
+/* Be liberal in window checking */
+#define IP_CT_TCP_FLAG_BE_LIBERAL		0x08
+
+/* Has unacknowledged data */
+#define IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED	0x10
+
+/* The field td_maxack has been set */
+#define IP_CT_TCP_FLAG_MAXACK_SET		0x20
+
+struct nf_ct_tcp_flags {
+	__u8 flags;
+	__u8 mask;
+};
+
+
+#endif /* _UAPI_NF_CONNTRACK_TCP_H */
diff --git a/include/linux/netfilter/nf_conntrack_tuple_common.h b/include/uapi/linux/netfilter/nf_conntrack_tuple_common.h
similarity index 100%
rename from include/linux/netfilter/nf_conntrack_tuple_common.h
rename to include/uapi/linux/netfilter/nf_conntrack_tuple_common.h
diff --git a/include/linux/netfilter/nf_nat.h b/include/uapi/linux/netfilter/nf_nat.h
similarity index 100%
rename from include/linux/netfilter/nf_nat.h
rename to include/uapi/linux/netfilter/nf_nat.h
diff --git a/include/uapi/linux/netfilter/nfnetlink.h b/include/uapi/linux/netfilter/nfnetlink.h
new file mode 100644
index 0000000..4a4efaf
--- /dev/null
+++ b/include/uapi/linux/netfilter/nfnetlink.h
@@ -0,0 +1,56 @@
+#ifndef _UAPI_NFNETLINK_H
+#define _UAPI_NFNETLINK_H
+#include <linux/types.h>
+#include <linux/netfilter/nfnetlink_compat.h>
+
+enum nfnetlink_groups {
+	NFNLGRP_NONE,
+#define NFNLGRP_NONE			NFNLGRP_NONE
+	NFNLGRP_CONNTRACK_NEW,
+#define NFNLGRP_CONNTRACK_NEW		NFNLGRP_CONNTRACK_NEW
+	NFNLGRP_CONNTRACK_UPDATE,
+#define NFNLGRP_CONNTRACK_UPDATE	NFNLGRP_CONNTRACK_UPDATE
+	NFNLGRP_CONNTRACK_DESTROY,
+#define NFNLGRP_CONNTRACK_DESTROY	NFNLGRP_CONNTRACK_DESTROY
+	NFNLGRP_CONNTRACK_EXP_NEW,
+#define	NFNLGRP_CONNTRACK_EXP_NEW	NFNLGRP_CONNTRACK_EXP_NEW
+	NFNLGRP_CONNTRACK_EXP_UPDATE,
+#define NFNLGRP_CONNTRACK_EXP_UPDATE	NFNLGRP_CONNTRACK_EXP_UPDATE
+	NFNLGRP_CONNTRACK_EXP_DESTROY,
+#define NFNLGRP_CONNTRACK_EXP_DESTROY	NFNLGRP_CONNTRACK_EXP_DESTROY
+	__NFNLGRP_MAX,
+};
+#define NFNLGRP_MAX	(__NFNLGRP_MAX - 1)
+
+/* General form of address family dependent message.
+ */
+struct nfgenmsg {
+	__u8  nfgen_family;		/* AF_xxx */
+	__u8  version;		/* nfnetlink version */
+	__be16    res_id;		/* resource id */
+};
+
+#define NFNETLINK_V0	0
+
+/* netfilter netlink message types are split in two pieces:
+ * 8 bit subsystem, 8bit operation.
+ */
+
+#define NFNL_SUBSYS_ID(x)	((x & 0xff00) >> 8)
+#define NFNL_MSG_TYPE(x)	(x & 0x00ff)
+
+/* No enum here, otherwise __stringify() trick of MODULE_ALIAS_NFNL_SUBSYS()
+ * won't work anymore */
+#define NFNL_SUBSYS_NONE 		0
+#define NFNL_SUBSYS_CTNETLINK		1
+#define NFNL_SUBSYS_CTNETLINK_EXP	2
+#define NFNL_SUBSYS_QUEUE		3
+#define NFNL_SUBSYS_ULOG		4
+#define NFNL_SUBSYS_OSF			5
+#define NFNL_SUBSYS_IPSET		6
+#define NFNL_SUBSYS_ACCT		7
+#define NFNL_SUBSYS_CTNETLINK_TIMEOUT	8
+#define NFNL_SUBSYS_CTHELPER		9
+#define NFNL_SUBSYS_COUNT		10
+
+#endif /* _UAPI_NFNETLINK_H */
diff --git a/include/uapi/linux/netfilter/nfnetlink_acct.h b/include/uapi/linux/netfilter/nfnetlink_acct.h
new file mode 100644
index 0000000..c7b6269
--- /dev/null
+++ b/include/uapi/linux/netfilter/nfnetlink_acct.h
@@ -0,0 +1,27 @@
+#ifndef _UAPI_NFNL_ACCT_H_
+#define _UAPI_NFNL_ACCT_H_
+
+#ifndef NFACCT_NAME_MAX
+#define NFACCT_NAME_MAX		32
+#endif
+
+enum nfnl_acct_msg_types {
+	NFNL_MSG_ACCT_NEW,
+	NFNL_MSG_ACCT_GET,
+	NFNL_MSG_ACCT_GET_CTRZERO,
+	NFNL_MSG_ACCT_DEL,
+	NFNL_MSG_ACCT_MAX
+};
+
+enum nfnl_acct_type {
+	NFACCT_UNSPEC,
+	NFACCT_NAME,
+	NFACCT_PKTS,
+	NFACCT_BYTES,
+	NFACCT_USE,
+	__NFACCT_MAX
+};
+#define NFACCT_MAX (__NFACCT_MAX - 1)
+
+
+#endif /* _UAPI_NFNL_ACCT_H_ */
diff --git a/include/linux/netfilter/nfnetlink_compat.h b/include/uapi/linux/netfilter/nfnetlink_compat.h
similarity index 100%
rename from include/linux/netfilter/nfnetlink_compat.h
rename to include/uapi/linux/netfilter/nfnetlink_compat.h
diff --git a/include/linux/netfilter/nfnetlink_conntrack.h b/include/uapi/linux/netfilter/nfnetlink_conntrack.h
similarity index 100%
rename from include/linux/netfilter/nfnetlink_conntrack.h
rename to include/uapi/linux/netfilter/nfnetlink_conntrack.h
diff --git a/include/linux/netfilter/nfnetlink_cthelper.h b/include/uapi/linux/netfilter/nfnetlink_cthelper.h
similarity index 100%
rename from include/linux/netfilter/nfnetlink_cthelper.h
rename to include/uapi/linux/netfilter/nfnetlink_cthelper.h
diff --git a/include/linux/netfilter/nfnetlink_cttimeout.h b/include/uapi/linux/netfilter/nfnetlink_cttimeout.h
similarity index 100%
rename from include/linux/netfilter/nfnetlink_cttimeout.h
rename to include/uapi/linux/netfilter/nfnetlink_cttimeout.h
diff --git a/include/linux/netfilter/nfnetlink_log.h b/include/uapi/linux/netfilter/nfnetlink_log.h
similarity index 100%
rename from include/linux/netfilter/nfnetlink_log.h
rename to include/uapi/linux/netfilter/nfnetlink_log.h
diff --git a/include/linux/netfilter/nfnetlink_queue.h b/include/uapi/linux/netfilter/nfnetlink_queue.h
similarity index 100%
rename from include/linux/netfilter/nfnetlink_queue.h
rename to include/uapi/linux/netfilter/nfnetlink_queue.h
diff --git a/include/uapi/linux/netfilter/x_tables.h b/include/uapi/linux/netfilter/x_tables.h
new file mode 100644
index 0000000..c36969b
--- /dev/null
+++ b/include/uapi/linux/netfilter/x_tables.h
@@ -0,0 +1,187 @@
+#ifndef _UAPI_X_TABLES_H
+#define _UAPI_X_TABLES_H
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+#define XT_FUNCTION_MAXNAMELEN 30
+#define XT_EXTENSION_MAXNAMELEN 29
+#define XT_TABLE_MAXNAMELEN 32
+
+struct xt_entry_match {
+	union {
+		struct {
+			__u16 match_size;
+
+			/* Used by userspace */
+			char name[XT_EXTENSION_MAXNAMELEN];
+			__u8 revision;
+		} user;
+		struct {
+			__u16 match_size;
+
+			/* Used inside the kernel */
+			struct xt_match *match;
+		} kernel;
+
+		/* Total length */
+		__u16 match_size;
+	} u;
+
+	unsigned char data[0];
+};
+
+struct xt_entry_target {
+	union {
+		struct {
+			__u16 target_size;
+
+			/* Used by userspace */
+			char name[XT_EXTENSION_MAXNAMELEN];
+			__u8 revision;
+		} user;
+		struct {
+			__u16 target_size;
+
+			/* Used inside the kernel */
+			struct xt_target *target;
+		} kernel;
+
+		/* Total length */
+		__u16 target_size;
+	} u;
+
+	unsigned char data[0];
+};
+
+#define XT_TARGET_INIT(__name, __size)					       \
+{									       \
+	.target.u.user = {						       \
+		.target_size	= XT_ALIGN(__size),			       \
+		.name		= __name,				       \
+	},								       \
+}
+
+struct xt_standard_target {
+	struct xt_entry_target target;
+	int verdict;
+};
+
+struct xt_error_target {
+	struct xt_entry_target target;
+	char errorname[XT_FUNCTION_MAXNAMELEN];
+};
+
+/* The argument to IPT_SO_GET_REVISION_*.  Returns highest revision
+ * kernel supports, if >= revision. */
+struct xt_get_revision {
+	char name[XT_EXTENSION_MAXNAMELEN];
+	__u8 revision;
+};
+
+/* CONTINUE verdict for targets */
+#define XT_CONTINUE 0xFFFFFFFF
+
+/* For standard target */
+#define XT_RETURN (-NF_REPEAT - 1)
+
+/* this is a dummy structure to find out the alignment requirement for a struct
+ * containing all the fundamental data types that are used in ipt_entry,
+ * ip6t_entry and arpt_entry.  This sucks, and it is a hack.  It will be my
+ * personal pleasure to remove it -HW
+ */
+struct _xt_align {
+	__u8 u8;
+	__u16 u16;
+	__u32 u32;
+	__u64 u64;
+};
+
+#define XT_ALIGN(s) __ALIGN_KERNEL((s), __alignof__(struct _xt_align))
+
+/* Standard return verdict, or do jump. */
+#define XT_STANDARD_TARGET ""
+/* Error verdict. */
+#define XT_ERROR_TARGET "ERROR"
+
+#define SET_COUNTER(c,b,p) do { (c).bcnt = (b); (c).pcnt = (p); } while(0)
+#define ADD_COUNTER(c,b,p) do { (c).bcnt += (b); (c).pcnt += (p); } while(0)
+
+struct xt_counters {
+	__u64 pcnt, bcnt;			/* Packet and byte counters */
+};
+
+/* The argument to IPT_SO_ADD_COUNTERS. */
+struct xt_counters_info {
+	/* Which table. */
+	char name[XT_TABLE_MAXNAMELEN];
+
+	unsigned int num_counters;
+
+	/* The counters (actually `number' of these). */
+	struct xt_counters counters[0];
+};
+
+#define XT_INV_PROTO		0x40	/* Invert the sense of PROTO. */
+
+#ifndef __KERNEL__
+/* fn returns 0 to continue iteration */
+#define XT_MATCH_ITERATE(type, e, fn, args...)			\
+({								\
+	unsigned int __i;					\
+	int __ret = 0;						\
+	struct xt_entry_match *__m;				\
+								\
+	for (__i = sizeof(type);				\
+	     __i < (e)->target_offset;				\
+	     __i += __m->u.match_size) {			\
+		__m = (void *)e + __i;				\
+								\
+		__ret = fn(__m , ## args);			\
+		if (__ret != 0)					\
+			break;					\
+	}							\
+	__ret;							\
+})
+
+/* fn returns 0 to continue iteration */
+#define XT_ENTRY_ITERATE_CONTINUE(type, entries, size, n, fn, args...) \
+({								\
+	unsigned int __i, __n;					\
+	int __ret = 0;						\
+	type *__entry;						\
+								\
+	for (__i = 0, __n = 0; __i < (size);			\
+	     __i += __entry->next_offset, __n++) { 		\
+		__entry = (void *)(entries) + __i;		\
+		if (__n < n)					\
+			continue;				\
+								\
+		__ret = fn(__entry , ## args);			\
+		if (__ret != 0)					\
+			break;					\
+	}							\
+	__ret;							\
+})
+
+/* fn returns 0 to continue iteration */
+#define XT_ENTRY_ITERATE(type, entries, size, fn, args...) \
+	XT_ENTRY_ITERATE_CONTINUE(type, entries, size, 0, fn, args)
+
+#endif /* !__KERNEL__ */
+
+/* pos is normally a struct ipt_entry/ip6t_entry/etc. */
+#define xt_entry_foreach(pos, ehead, esize) \
+	for ((pos) = (typeof(pos))(ehead); \
+	     (pos) < (typeof(pos))((char *)(ehead) + (esize)); \
+	     (pos) = (typeof(pos))((char *)(pos) + (pos)->next_offset))
+
+/* can only be xt_entry_match, so no use of typeof here */
+#define xt_ematch_foreach(pos, entry) \
+	for ((pos) = (struct xt_entry_match *)entry->elems; \
+	     (pos) < (struct xt_entry_match *)((char *)(entry) + \
+	             (entry)->target_offset); \
+	     (pos) = (struct xt_entry_match *)((char *)(pos) + \
+	             (pos)->u.match_size))
+
+
+#endif /* _UAPI_X_TABLES_H */
diff --git a/include/linux/netfilter/xt_AUDIT.h b/include/uapi/linux/netfilter/xt_AUDIT.h
similarity index 100%
rename from include/linux/netfilter/xt_AUDIT.h
rename to include/uapi/linux/netfilter/xt_AUDIT.h
diff --git a/include/linux/netfilter/xt_CHECKSUM.h b/include/uapi/linux/netfilter/xt_CHECKSUM.h
similarity index 100%
rename from include/linux/netfilter/xt_CHECKSUM.h
rename to include/uapi/linux/netfilter/xt_CHECKSUM.h
diff --git a/include/linux/netfilter/xt_CLASSIFY.h b/include/uapi/linux/netfilter/xt_CLASSIFY.h
similarity index 100%
rename from include/linux/netfilter/xt_CLASSIFY.h
rename to include/uapi/linux/netfilter/xt_CLASSIFY.h
diff --git a/include/linux/netfilter/xt_CONNMARK.h b/include/uapi/linux/netfilter/xt_CONNMARK.h
similarity index 100%
rename from include/linux/netfilter/xt_CONNMARK.h
rename to include/uapi/linux/netfilter/xt_CONNMARK.h
diff --git a/include/linux/netfilter/xt_CONNSECMARK.h b/include/uapi/linux/netfilter/xt_CONNSECMARK.h
similarity index 100%
rename from include/linux/netfilter/xt_CONNSECMARK.h
rename to include/uapi/linux/netfilter/xt_CONNSECMARK.h
diff --git a/include/linux/netfilter/xt_CT.h b/include/uapi/linux/netfilter/xt_CT.h
similarity index 100%
rename from include/linux/netfilter/xt_CT.h
rename to include/uapi/linux/netfilter/xt_CT.h
diff --git a/include/linux/netfilter/xt_DSCP.h b/include/uapi/linux/netfilter/xt_DSCP.h
similarity index 100%
rename from include/linux/netfilter/xt_DSCP.h
rename to include/uapi/linux/netfilter/xt_DSCP.h
diff --git a/include/linux/netfilter/xt_IDLETIMER.h b/include/uapi/linux/netfilter/xt_IDLETIMER.h
similarity index 100%
rename from include/linux/netfilter/xt_IDLETIMER.h
rename to include/uapi/linux/netfilter/xt_IDLETIMER.h
diff --git a/include/linux/netfilter/xt_LED.h b/include/uapi/linux/netfilter/xt_LED.h
similarity index 100%
rename from include/linux/netfilter/xt_LED.h
rename to include/uapi/linux/netfilter/xt_LED.h
diff --git a/include/linux/netfilter/xt_LOG.h b/include/uapi/linux/netfilter/xt_LOG.h
similarity index 100%
rename from include/linux/netfilter/xt_LOG.h
rename to include/uapi/linux/netfilter/xt_LOG.h
diff --git a/include/linux/netfilter/xt_MARK.h b/include/uapi/linux/netfilter/xt_MARK.h
similarity index 100%
rename from include/linux/netfilter/xt_MARK.h
rename to include/uapi/linux/netfilter/xt_MARK.h
diff --git a/include/linux/netfilter/xt_NFLOG.h b/include/uapi/linux/netfilter/xt_NFLOG.h
similarity index 100%
rename from include/linux/netfilter/xt_NFLOG.h
rename to include/uapi/linux/netfilter/xt_NFLOG.h
diff --git a/include/linux/netfilter/xt_NFQUEUE.h b/include/uapi/linux/netfilter/xt_NFQUEUE.h
similarity index 100%
rename from include/linux/netfilter/xt_NFQUEUE.h
rename to include/uapi/linux/netfilter/xt_NFQUEUE.h
diff --git a/include/linux/netfilter/xt_RATEEST.h b/include/uapi/linux/netfilter/xt_RATEEST.h
similarity index 100%
rename from include/linux/netfilter/xt_RATEEST.h
rename to include/uapi/linux/netfilter/xt_RATEEST.h
diff --git a/include/linux/netfilter/xt_SECMARK.h b/include/uapi/linux/netfilter/xt_SECMARK.h
similarity index 100%
rename from include/linux/netfilter/xt_SECMARK.h
rename to include/uapi/linux/netfilter/xt_SECMARK.h
diff --git a/include/linux/netfilter/xt_TCPMSS.h b/include/uapi/linux/netfilter/xt_TCPMSS.h
similarity index 100%
rename from include/linux/netfilter/xt_TCPMSS.h
rename to include/uapi/linux/netfilter/xt_TCPMSS.h
diff --git a/include/linux/netfilter/xt_TCPOPTSTRIP.h b/include/uapi/linux/netfilter/xt_TCPOPTSTRIP.h
similarity index 100%
rename from include/linux/netfilter/xt_TCPOPTSTRIP.h
rename to include/uapi/linux/netfilter/xt_TCPOPTSTRIP.h
diff --git a/include/linux/netfilter/xt_TEE.h b/include/uapi/linux/netfilter/xt_TEE.h
similarity index 100%
rename from include/linux/netfilter/xt_TEE.h
rename to include/uapi/linux/netfilter/xt_TEE.h
diff --git a/include/linux/netfilter/xt_TPROXY.h b/include/uapi/linux/netfilter/xt_TPROXY.h
similarity index 100%
rename from include/linux/netfilter/xt_TPROXY.h
rename to include/uapi/linux/netfilter/xt_TPROXY.h
diff --git a/include/linux/netfilter/xt_addrtype.h b/include/uapi/linux/netfilter/xt_addrtype.h
similarity index 100%
rename from include/linux/netfilter/xt_addrtype.h
rename to include/uapi/linux/netfilter/xt_addrtype.h
diff --git a/include/linux/netfilter/xt_cluster.h b/include/uapi/linux/netfilter/xt_cluster.h
similarity index 100%
rename from include/linux/netfilter/xt_cluster.h
rename to include/uapi/linux/netfilter/xt_cluster.h
diff --git a/include/linux/netfilter/xt_comment.h b/include/uapi/linux/netfilter/xt_comment.h
similarity index 100%
rename from include/linux/netfilter/xt_comment.h
rename to include/uapi/linux/netfilter/xt_comment.h
diff --git a/include/linux/netfilter/xt_connbytes.h b/include/uapi/linux/netfilter/xt_connbytes.h
similarity index 100%
rename from include/linux/netfilter/xt_connbytes.h
rename to include/uapi/linux/netfilter/xt_connbytes.h
diff --git a/include/linux/netfilter/xt_connlimit.h b/include/uapi/linux/netfilter/xt_connlimit.h
similarity index 100%
rename from include/linux/netfilter/xt_connlimit.h
rename to include/uapi/linux/netfilter/xt_connlimit.h
diff --git a/include/linux/netfilter/xt_connmark.h b/include/uapi/linux/netfilter/xt_connmark.h
similarity index 100%
rename from include/linux/netfilter/xt_connmark.h
rename to include/uapi/linux/netfilter/xt_connmark.h
diff --git a/include/linux/netfilter/xt_conntrack.h b/include/uapi/linux/netfilter/xt_conntrack.h
similarity index 100%
rename from include/linux/netfilter/xt_conntrack.h
rename to include/uapi/linux/netfilter/xt_conntrack.h
diff --git a/include/linux/netfilter/xt_cpu.h b/include/uapi/linux/netfilter/xt_cpu.h
similarity index 100%
rename from include/linux/netfilter/xt_cpu.h
rename to include/uapi/linux/netfilter/xt_cpu.h
diff --git a/include/linux/netfilter/xt_dccp.h b/include/uapi/linux/netfilter/xt_dccp.h
similarity index 100%
rename from include/linux/netfilter/xt_dccp.h
rename to include/uapi/linux/netfilter/xt_dccp.h
diff --git a/include/linux/netfilter/xt_devgroup.h b/include/uapi/linux/netfilter/xt_devgroup.h
similarity index 100%
rename from include/linux/netfilter/xt_devgroup.h
rename to include/uapi/linux/netfilter/xt_devgroup.h
diff --git a/include/linux/netfilter/xt_dscp.h b/include/uapi/linux/netfilter/xt_dscp.h
similarity index 100%
rename from include/linux/netfilter/xt_dscp.h
rename to include/uapi/linux/netfilter/xt_dscp.h
diff --git a/include/linux/netfilter/xt_ecn.h b/include/uapi/linux/netfilter/xt_ecn.h
similarity index 100%
rename from include/linux/netfilter/xt_ecn.h
rename to include/uapi/linux/netfilter/xt_ecn.h
diff --git a/include/linux/netfilter/xt_esp.h b/include/uapi/linux/netfilter/xt_esp.h
similarity index 100%
rename from include/linux/netfilter/xt_esp.h
rename to include/uapi/linux/netfilter/xt_esp.h
diff --git a/include/uapi/linux/netfilter/xt_hashlimit.h b/include/uapi/linux/netfilter/xt_hashlimit.h
new file mode 100644
index 0000000..cbfc43d
--- /dev/null
+++ b/include/uapi/linux/netfilter/xt_hashlimit.h
@@ -0,0 +1,73 @@
+#ifndef _UAPI_XT_HASHLIMIT_H
+#define _UAPI_XT_HASHLIMIT_H
+
+#include <linux/types.h>
+
+/* timings are in milliseconds. */
+#define XT_HASHLIMIT_SCALE 10000
+/* 1/10,000 sec period => max of 10,000/sec.  Min rate is then 429490
+ * seconds, or one packet every 59 hours.
+ */
+
+/* packet length accounting is done in 16-byte steps */
+#define XT_HASHLIMIT_BYTE_SHIFT 4
+
+/* details of this structure hidden by the implementation */
+struct xt_hashlimit_htable;
+
+enum {
+	XT_HASHLIMIT_HASH_DIP = 1 << 0,
+	XT_HASHLIMIT_HASH_DPT = 1 << 1,
+	XT_HASHLIMIT_HASH_SIP = 1 << 2,
+	XT_HASHLIMIT_HASH_SPT = 1 << 3,
+	XT_HASHLIMIT_INVERT   = 1 << 4,
+	XT_HASHLIMIT_BYTES    = 1 << 5,
+};
+
+struct hashlimit_cfg {
+	__u32 mode;	  /* bitmask of XT_HASHLIMIT_HASH_* */
+	__u32 avg;    /* Average secs between packets * scale */
+	__u32 burst;  /* Period multiplier for upper limit. */
+
+	/* user specified */
+	__u32 size;		/* how many buckets */
+	__u32 max;		/* max number of entries */
+	__u32 gc_interval;	/* gc interval */
+	__u32 expire;	/* when do entries expire? */
+};
+
+struct xt_hashlimit_info {
+	char name [IFNAMSIZ];		/* name */
+	struct hashlimit_cfg cfg;
+
+	/* Used internally by the kernel */
+	struct xt_hashlimit_htable *hinfo;
+	union {
+		void *ptr;
+		struct xt_hashlimit_info *master;
+	} u;
+};
+
+struct hashlimit_cfg1 {
+	__u32 mode;	  /* bitmask of XT_HASHLIMIT_HASH_* */
+	__u32 avg;    /* Average secs between packets * scale */
+	__u32 burst;  /* Period multiplier for upper limit. */
+
+	/* user specified */
+	__u32 size;		/* how many buckets */
+	__u32 max;		/* max number of entries */
+	__u32 gc_interval;	/* gc interval */
+	__u32 expire;	/* when do entries expire? */
+
+	__u8 srcmask, dstmask;
+};
+
+struct xt_hashlimit_mtinfo1 {
+	char name[IFNAMSIZ];
+	struct hashlimit_cfg1 cfg;
+
+	/* Used internally by the kernel */
+	struct xt_hashlimit_htable *hinfo __attribute__((aligned(8)));
+};
+
+#endif /* _UAPI_XT_HASHLIMIT_H */
diff --git a/include/linux/netfilter/xt_helper.h b/include/uapi/linux/netfilter/xt_helper.h
similarity index 100%
rename from include/linux/netfilter/xt_helper.h
rename to include/uapi/linux/netfilter/xt_helper.h
diff --git a/include/linux/netfilter/xt_iprange.h b/include/uapi/linux/netfilter/xt_iprange.h
similarity index 100%
rename from include/linux/netfilter/xt_iprange.h
rename to include/uapi/linux/netfilter/xt_iprange.h
diff --git a/include/linux/netfilter/xt_ipvs.h b/include/uapi/linux/netfilter/xt_ipvs.h
similarity index 100%
rename from include/linux/netfilter/xt_ipvs.h
rename to include/uapi/linux/netfilter/xt_ipvs.h
diff --git a/include/linux/netfilter/xt_length.h b/include/uapi/linux/netfilter/xt_length.h
similarity index 100%
rename from include/linux/netfilter/xt_length.h
rename to include/uapi/linux/netfilter/xt_length.h
diff --git a/include/linux/netfilter/xt_limit.h b/include/uapi/linux/netfilter/xt_limit.h
similarity index 100%
rename from include/linux/netfilter/xt_limit.h
rename to include/uapi/linux/netfilter/xt_limit.h
diff --git a/include/linux/netfilter/xt_mac.h b/include/uapi/linux/netfilter/xt_mac.h
similarity index 100%
rename from include/linux/netfilter/xt_mac.h
rename to include/uapi/linux/netfilter/xt_mac.h
diff --git a/include/linux/netfilter/xt_mark.h b/include/uapi/linux/netfilter/xt_mark.h
similarity index 100%
rename from include/linux/netfilter/xt_mark.h
rename to include/uapi/linux/netfilter/xt_mark.h
diff --git a/include/linux/netfilter/xt_multiport.h b/include/uapi/linux/netfilter/xt_multiport.h
similarity index 100%
rename from include/linux/netfilter/xt_multiport.h
rename to include/uapi/linux/netfilter/xt_multiport.h
diff --git a/include/linux/netfilter/xt_nfacct.h b/include/uapi/linux/netfilter/xt_nfacct.h
similarity index 100%
rename from include/linux/netfilter/xt_nfacct.h
rename to include/uapi/linux/netfilter/xt_nfacct.h
diff --git a/include/linux/netfilter/xt_osf.h b/include/uapi/linux/netfilter/xt_osf.h
similarity index 100%
rename from include/linux/netfilter/xt_osf.h
rename to include/uapi/linux/netfilter/xt_osf.h
diff --git a/include/linux/netfilter/xt_owner.h b/include/uapi/linux/netfilter/xt_owner.h
similarity index 100%
rename from include/linux/netfilter/xt_owner.h
rename to include/uapi/linux/netfilter/xt_owner.h
diff --git a/include/uapi/linux/netfilter/xt_physdev.h b/include/uapi/linux/netfilter/xt_physdev.h
new file mode 100644
index 0000000..db7a298
--- /dev/null
+++ b/include/uapi/linux/netfilter/xt_physdev.h
@@ -0,0 +1,23 @@
+#ifndef _UAPI_XT_PHYSDEV_H
+#define _UAPI_XT_PHYSDEV_H
+
+#include <linux/types.h>
+
+
+#define XT_PHYSDEV_OP_IN		0x01
+#define XT_PHYSDEV_OP_OUT		0x02
+#define XT_PHYSDEV_OP_BRIDGED		0x04
+#define XT_PHYSDEV_OP_ISIN		0x08
+#define XT_PHYSDEV_OP_ISOUT		0x10
+#define XT_PHYSDEV_OP_MASK		(0x20 - 1)
+
+struct xt_physdev_info {
+	char physindev[IFNAMSIZ];
+	char in_mask[IFNAMSIZ];
+	char physoutdev[IFNAMSIZ];
+	char out_mask[IFNAMSIZ];
+	__u8 invert;
+	__u8 bitmask;
+};
+
+#endif /* _UAPI_XT_PHYSDEV_H */
diff --git a/include/linux/netfilter/xt_pkttype.h b/include/uapi/linux/netfilter/xt_pkttype.h
similarity index 100%
rename from include/linux/netfilter/xt_pkttype.h
rename to include/uapi/linux/netfilter/xt_pkttype.h
diff --git a/include/linux/netfilter/xt_policy.h b/include/uapi/linux/netfilter/xt_policy.h
similarity index 100%
rename from include/linux/netfilter/xt_policy.h
rename to include/uapi/linux/netfilter/xt_policy.h
diff --git a/include/linux/netfilter/xt_quota.h b/include/uapi/linux/netfilter/xt_quota.h
similarity index 100%
rename from include/linux/netfilter/xt_quota.h
rename to include/uapi/linux/netfilter/xt_quota.h
diff --git a/include/linux/netfilter/xt_rateest.h b/include/uapi/linux/netfilter/xt_rateest.h
similarity index 100%
rename from include/linux/netfilter/xt_rateest.h
rename to include/uapi/linux/netfilter/xt_rateest.h
diff --git a/include/linux/netfilter/xt_realm.h b/include/uapi/linux/netfilter/xt_realm.h
similarity index 100%
rename from include/linux/netfilter/xt_realm.h
rename to include/uapi/linux/netfilter/xt_realm.h
diff --git a/include/linux/netfilter/xt_recent.h b/include/uapi/linux/netfilter/xt_recent.h
similarity index 100%
rename from include/linux/netfilter/xt_recent.h
rename to include/uapi/linux/netfilter/xt_recent.h
diff --git a/include/linux/netfilter/xt_sctp.h b/include/uapi/linux/netfilter/xt_sctp.h
similarity index 100%
rename from include/linux/netfilter/xt_sctp.h
rename to include/uapi/linux/netfilter/xt_sctp.h
diff --git a/include/linux/netfilter/xt_set.h b/include/uapi/linux/netfilter/xt_set.h
similarity index 100%
rename from include/linux/netfilter/xt_set.h
rename to include/uapi/linux/netfilter/xt_set.h
diff --git a/include/linux/netfilter/xt_socket.h b/include/uapi/linux/netfilter/xt_socket.h
similarity index 100%
rename from include/linux/netfilter/xt_socket.h
rename to include/uapi/linux/netfilter/xt_socket.h
diff --git a/include/linux/netfilter/xt_state.h b/include/uapi/linux/netfilter/xt_state.h
similarity index 100%
rename from include/linux/netfilter/xt_state.h
rename to include/uapi/linux/netfilter/xt_state.h
diff --git a/include/linux/netfilter/xt_statistic.h b/include/uapi/linux/netfilter/xt_statistic.h
similarity index 100%
rename from include/linux/netfilter/xt_statistic.h
rename to include/uapi/linux/netfilter/xt_statistic.h
diff --git a/include/linux/netfilter/xt_string.h b/include/uapi/linux/netfilter/xt_string.h
similarity index 100%
rename from include/linux/netfilter/xt_string.h
rename to include/uapi/linux/netfilter/xt_string.h
diff --git a/include/linux/netfilter/xt_tcpmss.h b/include/uapi/linux/netfilter/xt_tcpmss.h
similarity index 100%
rename from include/linux/netfilter/xt_tcpmss.h
rename to include/uapi/linux/netfilter/xt_tcpmss.h
diff --git a/include/linux/netfilter/xt_tcpudp.h b/include/uapi/linux/netfilter/xt_tcpudp.h
similarity index 100%
rename from include/linux/netfilter/xt_tcpudp.h
rename to include/uapi/linux/netfilter/xt_tcpudp.h
diff --git a/include/linux/netfilter/xt_time.h b/include/uapi/linux/netfilter/xt_time.h
similarity index 100%
rename from include/linux/netfilter/xt_time.h
rename to include/uapi/linux/netfilter/xt_time.h
diff --git a/include/linux/netfilter/xt_u32.h b/include/uapi/linux/netfilter/xt_u32.h
similarity index 100%
rename from include/linux/netfilter/xt_u32.h
rename to include/uapi/linux/netfilter/xt_u32.h
diff --git a/include/uapi/linux/netfilter_arp/Kbuild b/include/uapi/linux/netfilter_arp/Kbuild
index aafaa5a..62d5637 100644
--- a/include/uapi/linux/netfilter_arp/Kbuild
+++ b/include/uapi/linux/netfilter_arp/Kbuild
@@ -1 +1,3 @@
 # UAPI Header export list
+header-y += arp_tables.h
+header-y += arpt_mangle.h
diff --git a/include/uapi/linux/netfilter_arp/arp_tables.h b/include/uapi/linux/netfilter_arp/arp_tables.h
new file mode 100644
index 0000000..a5a86a4
--- /dev/null
+++ b/include/uapi/linux/netfilter_arp/arp_tables.h
@@ -0,0 +1,206 @@
+/*
+ * 	Format of an ARP firewall descriptor
+ *
+ * 	src, tgt, src_mask, tgt_mask, arpop, arpop_mask are always stored in
+ *	network byte order.
+ * 	flags are stored in host byte order (of course).
+ */
+
+#ifndef _UAPI_ARPTABLES_H
+#define _UAPI_ARPTABLES_H
+
+#include <linux/types.h>
+#include <linux/compiler.h>
+#include <linux/netfilter_arp.h>
+
+#include <linux/netfilter/x_tables.h>
+
+#ifndef __KERNEL__
+#define ARPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
+#define ARPT_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN
+#define arpt_entry_target xt_entry_target
+#define arpt_standard_target xt_standard_target
+#define arpt_error_target xt_error_target
+#define ARPT_CONTINUE XT_CONTINUE
+#define ARPT_RETURN XT_RETURN
+#define arpt_counters_info xt_counters_info
+#define arpt_counters xt_counters
+#define ARPT_STANDARD_TARGET XT_STANDARD_TARGET
+#define ARPT_ERROR_TARGET XT_ERROR_TARGET
+#define ARPT_ENTRY_ITERATE(entries, size, fn, args...) \
+	XT_ENTRY_ITERATE(struct arpt_entry, entries, size, fn, ## args)
+#endif
+
+#define ARPT_DEV_ADDR_LEN_MAX 16
+
+struct arpt_devaddr_info {
+	char addr[ARPT_DEV_ADDR_LEN_MAX];
+	char mask[ARPT_DEV_ADDR_LEN_MAX];
+};
+
+/* Yes, Virginia, you have to zero the padding. */
+struct arpt_arp {
+	/* Source and target IP addr */
+	struct in_addr src, tgt;
+	/* Mask for src and target IP addr */
+	struct in_addr smsk, tmsk;
+
+	/* Device hw address length, src+target device addresses */
+	__u8 arhln, arhln_mask;
+	struct arpt_devaddr_info src_devaddr;
+	struct arpt_devaddr_info tgt_devaddr;
+
+	/* ARP operation code. */
+	__be16 arpop, arpop_mask;
+
+	/* ARP hardware address and protocol address format. */
+	__be16 arhrd, arhrd_mask;
+	__be16 arpro, arpro_mask;
+
+	/* The protocol address length is only accepted if it is 4
+	 * so there is no use in offering a way to do filtering on it.
+	 */
+
+	char iniface[IFNAMSIZ], outiface[IFNAMSIZ];
+	unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];
+
+	/* Flags word */
+	__u8 flags;
+	/* Inverse flags */
+	__u16 invflags;
+};
+
+/* Values for "flag" field in struct arpt_ip (general arp structure).
+ * No flags defined yet.
+ */
+#define ARPT_F_MASK		0x00	/* All possible flag bits mask. */
+
+/* Values for "inv" field in struct arpt_arp. */
+#define ARPT_INV_VIA_IN		0x0001	/* Invert the sense of IN IFACE. */
+#define ARPT_INV_VIA_OUT	0x0002	/* Invert the sense of OUT IFACE */
+#define ARPT_INV_SRCIP		0x0004	/* Invert the sense of SRC IP. */
+#define ARPT_INV_TGTIP		0x0008	/* Invert the sense of TGT IP. */
+#define ARPT_INV_SRCDEVADDR	0x0010	/* Invert the sense of SRC DEV ADDR. */
+#define ARPT_INV_TGTDEVADDR	0x0020	/* Invert the sense of TGT DEV ADDR. */
+#define ARPT_INV_ARPOP		0x0040	/* Invert the sense of ARP OP. */
+#define ARPT_INV_ARPHRD		0x0080	/* Invert the sense of ARP HRD. */
+#define ARPT_INV_ARPPRO		0x0100	/* Invert the sense of ARP PRO. */
+#define ARPT_INV_ARPHLN		0x0200	/* Invert the sense of ARP HLN. */
+#define ARPT_INV_MASK		0x03FF	/* All possible flag bits mask. */
+
+/* This structure defines each of the firewall rules.  Consists of 3
+   parts which are 1) general ARP header stuff 2) match specific
+   stuff 3) the target to perform if the rule matches */
+struct arpt_entry
+{
+	struct arpt_arp arp;
+
+	/* Size of arpt_entry + matches */
+	__u16 target_offset;
+	/* Size of arpt_entry + matches + target */
+	__u16 next_offset;
+
+	/* Back pointer */
+	unsigned int comefrom;
+
+	/* Packet and byte counters. */
+	struct xt_counters counters;
+
+	/* The matches (if any), then the target. */
+	unsigned char elems[0];
+};
+
+/*
+ * New IP firewall options for [gs]etsockopt at the RAW IP level.
+ * Unlike BSD Linux inherits IP options so you don't have to use a raw
+ * socket for this. Instead we check rights in the calls.
+ *
+ * ATTENTION: check linux/in.h before adding new number here.
+ */
+#define ARPT_BASE_CTL		96
+
+#define ARPT_SO_SET_REPLACE		(ARPT_BASE_CTL)
+#define ARPT_SO_SET_ADD_COUNTERS	(ARPT_BASE_CTL + 1)
+#define ARPT_SO_SET_MAX			ARPT_SO_SET_ADD_COUNTERS
+
+#define ARPT_SO_GET_INFO		(ARPT_BASE_CTL)
+#define ARPT_SO_GET_ENTRIES		(ARPT_BASE_CTL + 1)
+/* #define ARPT_SO_GET_REVISION_MATCH	(APRT_BASE_CTL + 2) */
+#define ARPT_SO_GET_REVISION_TARGET	(ARPT_BASE_CTL + 3)
+#define ARPT_SO_GET_MAX			(ARPT_SO_GET_REVISION_TARGET)
+
+/* The argument to ARPT_SO_GET_INFO */
+struct arpt_getinfo {
+	/* Which table: caller fills this in. */
+	char name[XT_TABLE_MAXNAMELEN];
+
+	/* Kernel fills these in. */
+	/* Which hook entry points are valid: bitmask */
+	unsigned int valid_hooks;
+
+	/* Hook entry points: one per netfilter hook. */
+	unsigned int hook_entry[NF_ARP_NUMHOOKS];
+
+	/* Underflow points. */
+	unsigned int underflow[NF_ARP_NUMHOOKS];
+
+	/* Number of entries */
+	unsigned int num_entries;
+
+	/* Size of entries. */
+	unsigned int size;
+};
+
+/* The argument to ARPT_SO_SET_REPLACE. */
+struct arpt_replace {
+	/* Which table. */
+	char name[XT_TABLE_MAXNAMELEN];
+
+	/* Which hook entry points are valid: bitmask.  You can't
+           change this. */
+	unsigned int valid_hooks;
+
+	/* Number of entries */
+	unsigned int num_entries;
+
+	/* Total size of new entries */
+	unsigned int size;
+
+	/* Hook entry points. */
+	unsigned int hook_entry[NF_ARP_NUMHOOKS];
+
+	/* Underflow points. */
+	unsigned int underflow[NF_ARP_NUMHOOKS];
+
+	/* Information about old entries: */
+	/* Number of counters (must be equal to current number of entries). */
+	unsigned int num_counters;
+	/* The old entries' counters. */
+	struct xt_counters __user *counters;
+
+	/* The entries (hang off end: not really an array). */
+	struct arpt_entry entries[0];
+};
+
+/* The argument to ARPT_SO_GET_ENTRIES. */
+struct arpt_get_entries {
+	/* Which table: user fills this in. */
+	char name[XT_TABLE_MAXNAMELEN];
+
+	/* User fills this in: total entry size. */
+	unsigned int size;
+
+	/* The entries. */
+	struct arpt_entry entrytable[0];
+};
+
+/* Helper functions */
+static __inline__ struct xt_entry_target *arpt_get_target(struct arpt_entry *e)
+{
+	return (void *)e + e->target_offset;
+}
+
+/*
+ *	Main firewall chains definitions and global var's definitions.
+ */
+#endif /* _UAPI_ARPTABLES_H */
diff --git a/include/linux/netfilter_arp/arpt_mangle.h b/include/uapi/linux/netfilter_arp/arpt_mangle.h
similarity index 100%
rename from include/linux/netfilter_arp/arpt_mangle.h
rename to include/uapi/linux/netfilter_arp/arpt_mangle.h
diff --git a/include/uapi/linux/netfilter_bridge/Kbuild b/include/uapi/linux/netfilter_bridge/Kbuild
index aafaa5a..348717c 100644
--- a/include/uapi/linux/netfilter_bridge/Kbuild
+++ b/include/uapi/linux/netfilter_bridge/Kbuild
@@ -1 +1,19 @@
 # UAPI Header export list
+header-y += ebt_802_3.h
+header-y += ebt_among.h
+header-y += ebt_arp.h
+header-y += ebt_arpreply.h
+header-y += ebt_ip.h
+header-y += ebt_ip6.h
+header-y += ebt_limit.h
+header-y += ebt_log.h
+header-y += ebt_mark_m.h
+header-y += ebt_mark_t.h
+header-y += ebt_nat.h
+header-y += ebt_nflog.h
+header-y += ebt_pkttype.h
+header-y += ebt_redirect.h
+header-y += ebt_stp.h
+header-y += ebt_ulog.h
+header-y += ebt_vlan.h
+header-y += ebtables.h
diff --git a/include/uapi/linux/netfilter_bridge/ebt_802_3.h b/include/uapi/linux/netfilter_bridge/ebt_802_3.h
new file mode 100644
index 0000000..5bf8491
--- /dev/null
+++ b/include/uapi/linux/netfilter_bridge/ebt_802_3.h
@@ -0,0 +1,62 @@
+#ifndef _UAPI__LINUX_BRIDGE_EBT_802_3_H
+#define _UAPI__LINUX_BRIDGE_EBT_802_3_H
+
+#include <linux/types.h>
+
+#define EBT_802_3_SAP 0x01
+#define EBT_802_3_TYPE 0x02
+
+#define EBT_802_3_MATCH "802_3"
+
+/*
+ * If frame has DSAP/SSAP value 0xaa you must check the SNAP type
+ * to discover what kind of packet we're carrying. 
+ */
+#define CHECK_TYPE 0xaa
+
+/*
+ * Control field may be one or two bytes.  If the first byte has
+ * the value 0x03 then the entire length is one byte, otherwise it is two.
+ * One byte controls are used in Unnumbered Information frames.
+ * Two byte controls are used in Numbered Information frames.
+ */
+#define IS_UI 0x03
+
+#define EBT_802_3_MASK (EBT_802_3_SAP | EBT_802_3_TYPE | EBT_802_3)
+
+/* ui has one byte ctrl, ni has two */
+struct hdr_ui {
+	__u8 dsap;
+	__u8 ssap;
+	__u8 ctrl;
+	__u8 orig[3];
+	__be16 type;
+};
+
+struct hdr_ni {
+	__u8 dsap;
+	__u8 ssap;
+	__be16 ctrl;
+	__u8  orig[3];
+	__be16 type;
+};
+
+struct ebt_802_3_hdr {
+	__u8  daddr[6];
+	__u8  saddr[6];
+	__be16 len;
+	union {
+		struct hdr_ui ui;
+		struct hdr_ni ni;
+	} llc;
+};
+
+
+struct ebt_802_3_info {
+	__u8  sap;
+	__be16 type;
+	__u8  bitmask;
+	__u8  invflags;
+};
+
+#endif /* _UAPI__LINUX_BRIDGE_EBT_802_3_H */
diff --git a/include/linux/netfilter_bridge/ebt_among.h b/include/uapi/linux/netfilter_bridge/ebt_among.h
similarity index 100%
rename from include/linux/netfilter_bridge/ebt_among.h
rename to include/uapi/linux/netfilter_bridge/ebt_among.h
diff --git a/include/linux/netfilter_bridge/ebt_arp.h b/include/uapi/linux/netfilter_bridge/ebt_arp.h
similarity index 100%
rename from include/linux/netfilter_bridge/ebt_arp.h
rename to include/uapi/linux/netfilter_bridge/ebt_arp.h
diff --git a/include/linux/netfilter_bridge/ebt_arpreply.h b/include/uapi/linux/netfilter_bridge/ebt_arpreply.h
similarity index 100%
rename from include/linux/netfilter_bridge/ebt_arpreply.h
rename to include/uapi/linux/netfilter_bridge/ebt_arpreply.h
diff --git a/include/linux/netfilter_bridge/ebt_ip.h b/include/uapi/linux/netfilter_bridge/ebt_ip.h
similarity index 100%
rename from include/linux/netfilter_bridge/ebt_ip.h
rename to include/uapi/linux/netfilter_bridge/ebt_ip.h
diff --git a/include/linux/netfilter_bridge/ebt_ip6.h b/include/uapi/linux/netfilter_bridge/ebt_ip6.h
similarity index 100%
rename from include/linux/netfilter_bridge/ebt_ip6.h
rename to include/uapi/linux/netfilter_bridge/ebt_ip6.h
diff --git a/include/linux/netfilter_bridge/ebt_limit.h b/include/uapi/linux/netfilter_bridge/ebt_limit.h
similarity index 100%
rename from include/linux/netfilter_bridge/ebt_limit.h
rename to include/uapi/linux/netfilter_bridge/ebt_limit.h
diff --git a/include/linux/netfilter_bridge/ebt_log.h b/include/uapi/linux/netfilter_bridge/ebt_log.h
similarity index 100%
rename from include/linux/netfilter_bridge/ebt_log.h
rename to include/uapi/linux/netfilter_bridge/ebt_log.h
diff --git a/include/linux/netfilter_bridge/ebt_mark_m.h b/include/uapi/linux/netfilter_bridge/ebt_mark_m.h
similarity index 100%
rename from include/linux/netfilter_bridge/ebt_mark_m.h
rename to include/uapi/linux/netfilter_bridge/ebt_mark_m.h
diff --git a/include/linux/netfilter_bridge/ebt_mark_t.h b/include/uapi/linux/netfilter_bridge/ebt_mark_t.h
similarity index 100%
rename from include/linux/netfilter_bridge/ebt_mark_t.h
rename to include/uapi/linux/netfilter_bridge/ebt_mark_t.h
diff --git a/include/linux/netfilter_bridge/ebt_nat.h b/include/uapi/linux/netfilter_bridge/ebt_nat.h
similarity index 100%
rename from include/linux/netfilter_bridge/ebt_nat.h
rename to include/uapi/linux/netfilter_bridge/ebt_nat.h
diff --git a/include/linux/netfilter_bridge/ebt_nflog.h b/include/uapi/linux/netfilter_bridge/ebt_nflog.h
similarity index 100%
rename from include/linux/netfilter_bridge/ebt_nflog.h
rename to include/uapi/linux/netfilter_bridge/ebt_nflog.h
diff --git a/include/linux/netfilter_bridge/ebt_pkttype.h b/include/uapi/linux/netfilter_bridge/ebt_pkttype.h
similarity index 100%
rename from include/linux/netfilter_bridge/ebt_pkttype.h
rename to include/uapi/linux/netfilter_bridge/ebt_pkttype.h
diff --git a/include/linux/netfilter_bridge/ebt_redirect.h b/include/uapi/linux/netfilter_bridge/ebt_redirect.h
similarity index 100%
rename from include/linux/netfilter_bridge/ebt_redirect.h
rename to include/uapi/linux/netfilter_bridge/ebt_redirect.h
diff --git a/include/linux/netfilter_bridge/ebt_stp.h b/include/uapi/linux/netfilter_bridge/ebt_stp.h
similarity index 100%
rename from include/linux/netfilter_bridge/ebt_stp.h
rename to include/uapi/linux/netfilter_bridge/ebt_stp.h
diff --git a/include/linux/netfilter_bridge/ebt_ulog.h b/include/uapi/linux/netfilter_bridge/ebt_ulog.h
similarity index 100%
rename from include/linux/netfilter_bridge/ebt_ulog.h
rename to include/uapi/linux/netfilter_bridge/ebt_ulog.h
diff --git a/include/linux/netfilter_bridge/ebt_vlan.h b/include/uapi/linux/netfilter_bridge/ebt_vlan.h
similarity index 100%
rename from include/linux/netfilter_bridge/ebt_vlan.h
rename to include/uapi/linux/netfilter_bridge/ebt_vlan.h
diff --git a/include/uapi/linux/netfilter_bridge/ebtables.h b/include/uapi/linux/netfilter_bridge/ebtables.h
new file mode 100644
index 0000000..ba99336
--- /dev/null
+++ b/include/uapi/linux/netfilter_bridge/ebtables.h
@@ -0,0 +1,268 @@
+/*
+ *  ebtables
+ *
+ *	Authors:
+ *	Bart De Schuymer		<bdschuym@pandora.be>
+ *
+ *  ebtables.c,v 2.0, April, 2002
+ *
+ *  This code is stongly inspired on the iptables code which is
+ *  Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling
+ */
+
+#ifndef _UAPI__LINUX_BRIDGE_EFF_H
+#define _UAPI__LINUX_BRIDGE_EFF_H
+#include <linux/if.h>
+#include <linux/netfilter_bridge.h>
+#include <linux/if_ether.h>
+
+#define EBT_TABLE_MAXNAMELEN 32
+#define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN
+#define EBT_FUNCTION_MAXNAMELEN EBT_TABLE_MAXNAMELEN
+
+/* verdicts >0 are "branches" */
+#define EBT_ACCEPT   -1
+#define EBT_DROP     -2
+#define EBT_CONTINUE -3
+#define EBT_RETURN   -4
+#define NUM_STANDARD_TARGETS   4
+/* ebtables target modules store the verdict inside an int. We can
+ * reclaim a part of this int for backwards compatible extensions.
+ * The 4 lsb are more than enough to store the verdict. */
+#define EBT_VERDICT_BITS 0x0000000F
+
+struct xt_match;
+struct xt_target;
+
+struct ebt_counter {
+	uint64_t pcnt;
+	uint64_t bcnt;
+};
+
+struct ebt_replace {
+	char name[EBT_TABLE_MAXNAMELEN];
+	unsigned int valid_hooks;
+	/* nr of rules in the table */
+	unsigned int nentries;
+	/* total size of the entries */
+	unsigned int entries_size;
+	/* start of the chains */
+	struct ebt_entries __user *hook_entry[NF_BR_NUMHOOKS];
+	/* nr of counters userspace expects back */
+	unsigned int num_counters;
+	/* where the kernel will put the old counters */
+	struct ebt_counter __user *counters;
+	char __user *entries;
+};
+
+struct ebt_replace_kernel {
+	char name[EBT_TABLE_MAXNAMELEN];
+	unsigned int valid_hooks;
+	/* nr of rules in the table */
+	unsigned int nentries;
+	/* total size of the entries */
+	unsigned int entries_size;
+	/* start of the chains */
+	struct ebt_entries *hook_entry[NF_BR_NUMHOOKS];
+	/* nr of counters userspace expects back */
+	unsigned int num_counters;
+	/* where the kernel will put the old counters */
+	struct ebt_counter *counters;
+	char *entries;
+};
+
+struct ebt_entries {
+	/* this field is always set to zero
+	 * See EBT_ENTRY_OR_ENTRIES.
+	 * Must be same size as ebt_entry.bitmask */
+	unsigned int distinguisher;
+	/* the chain name */
+	char name[EBT_CHAIN_MAXNAMELEN];
+	/* counter offset for this chain */
+	unsigned int counter_offset;
+	/* one standard (accept, drop, return) per hook */
+	int policy;
+	/* nr. of entries */
+	unsigned int nentries;
+	/* entry list */
+	char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
+};
+
+/* used for the bitmask of struct ebt_entry */
+
+/* This is a hack to make a difference between an ebt_entry struct and an
+ * ebt_entries struct when traversing the entries from start to end.
+ * Using this simplifies the code a lot, while still being able to use
+ * ebt_entries.
+ * Contrary, iptables doesn't use something like ebt_entries and therefore uses
+ * different techniques for naming the policy and such. So, iptables doesn't
+ * need a hack like this.
+ */
+#define EBT_ENTRY_OR_ENTRIES 0x01
+/* these are the normal masks */
+#define EBT_NOPROTO 0x02
+#define EBT_802_3 0x04
+#define EBT_SOURCEMAC 0x08
+#define EBT_DESTMAC 0x10
+#define EBT_F_MASK (EBT_NOPROTO | EBT_802_3 | EBT_SOURCEMAC | EBT_DESTMAC \
+   | EBT_ENTRY_OR_ENTRIES)
+
+#define EBT_IPROTO 0x01
+#define EBT_IIN 0x02
+#define EBT_IOUT 0x04
+#define EBT_ISOURCE 0x8
+#define EBT_IDEST 0x10
+#define EBT_ILOGICALIN 0x20
+#define EBT_ILOGICALOUT 0x40
+#define EBT_INV_MASK (EBT_IPROTO | EBT_IIN | EBT_IOUT | EBT_ILOGICALIN \
+   | EBT_ILOGICALOUT | EBT_ISOURCE | EBT_IDEST)
+
+struct ebt_entry_match {
+	union {
+		char name[EBT_FUNCTION_MAXNAMELEN];
+		struct xt_match *match;
+	} u;
+	/* size of data */
+	unsigned int match_size;
+	unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
+};
+
+struct ebt_entry_watcher {
+	union {
+		char name[EBT_FUNCTION_MAXNAMELEN];
+		struct xt_target *watcher;
+	} u;
+	/* size of data */
+	unsigned int watcher_size;
+	unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
+};
+
+struct ebt_entry_target {
+	union {
+		char name[EBT_FUNCTION_MAXNAMELEN];
+		struct xt_target *target;
+	} u;
+	/* size of data */
+	unsigned int target_size;
+	unsigned char data[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
+};
+
+#define EBT_STANDARD_TARGET "standard"
+struct ebt_standard_target {
+	struct ebt_entry_target target;
+	int verdict;
+};
+
+/* one entry */
+struct ebt_entry {
+	/* this needs to be the first field */
+	unsigned int bitmask;
+	unsigned int invflags;
+	__be16 ethproto;
+	/* the physical in-dev */
+	char in[IFNAMSIZ];
+	/* the logical in-dev */
+	char logical_in[IFNAMSIZ];
+	/* the physical out-dev */
+	char out[IFNAMSIZ];
+	/* the logical out-dev */
+	char logical_out[IFNAMSIZ];
+	unsigned char sourcemac[ETH_ALEN];
+	unsigned char sourcemsk[ETH_ALEN];
+	unsigned char destmac[ETH_ALEN];
+	unsigned char destmsk[ETH_ALEN];
+	/* sizeof ebt_entry + matches */
+	unsigned int watchers_offset;
+	/* sizeof ebt_entry + matches + watchers */
+	unsigned int target_offset;
+	/* sizeof ebt_entry + matches + watchers + target */
+	unsigned int next_offset;
+	unsigned char elems[0] __attribute__ ((aligned (__alignof__(struct ebt_replace))));
+};
+
+/* {g,s}etsockopt numbers */
+#define EBT_BASE_CTL            128
+
+#define EBT_SO_SET_ENTRIES      (EBT_BASE_CTL)
+#define EBT_SO_SET_COUNTERS     (EBT_SO_SET_ENTRIES+1)
+#define EBT_SO_SET_MAX          (EBT_SO_SET_COUNTERS+1)
+
+#define EBT_SO_GET_INFO         (EBT_BASE_CTL)
+#define EBT_SO_GET_ENTRIES      (EBT_SO_GET_INFO+1)
+#define EBT_SO_GET_INIT_INFO    (EBT_SO_GET_ENTRIES+1)
+#define EBT_SO_GET_INIT_ENTRIES (EBT_SO_GET_INIT_INFO+1)
+#define EBT_SO_GET_MAX          (EBT_SO_GET_INIT_ENTRIES+1)
+
+
+/* blatently stolen from ip_tables.h
+ * fn returns 0 to continue iteration */
+#define EBT_MATCH_ITERATE(e, fn, args...)                   \
+({                                                          \
+	unsigned int __i;                                   \
+	int __ret = 0;                                      \
+	struct ebt_entry_match *__match;                    \
+	                                                    \
+	for (__i = sizeof(struct ebt_entry);                \
+	     __i < (e)->watchers_offset;                    \
+	     __i += __match->match_size +                   \
+	     sizeof(struct ebt_entry_match)) {              \
+		__match = (void *)(e) + __i;                \
+		                                            \
+		__ret = fn(__match , ## args);              \
+		if (__ret != 0)                             \
+			break;                              \
+	}                                                   \
+	if (__ret == 0) {                                   \
+		if (__i != (e)->watchers_offset)            \
+			__ret = -EINVAL;                    \
+	}                                                   \
+	__ret;                                              \
+})
+
+#define EBT_WATCHER_ITERATE(e, fn, args...)                 \
+({                                                          \
+	unsigned int __i;                                   \
+	int __ret = 0;                                      \
+	struct ebt_entry_watcher *__watcher;                \
+	                                                    \
+	for (__i = e->watchers_offset;                      \
+	     __i < (e)->target_offset;                      \
+	     __i += __watcher->watcher_size +               \
+	     sizeof(struct ebt_entry_watcher)) {            \
+		__watcher = (void *)(e) + __i;              \
+		                                            \
+		__ret = fn(__watcher , ## args);            \
+		if (__ret != 0)                             \
+			break;                              \
+	}                                                   \
+	if (__ret == 0) {                                   \
+		if (__i != (e)->target_offset)              \
+			__ret = -EINVAL;                    \
+	}                                                   \
+	__ret;                                              \
+})
+
+#define EBT_ENTRY_ITERATE(entries, size, fn, args...)       \
+({                                                          \
+	unsigned int __i;                                   \
+	int __ret = 0;                                      \
+	struct ebt_entry *__entry;                          \
+	                                                    \
+	for (__i = 0; __i < (size);) {                      \
+		__entry = (void *)(entries) + __i;          \
+		__ret = fn(__entry , ## args);              \
+		if (__ret != 0)                             \
+			break;                              \
+		if (__entry->bitmask != 0)                  \
+			__i += __entry->next_offset;        \
+		else                                        \
+			__i += sizeof(struct ebt_entries);  \
+	}                                                   \
+	if (__ret == 0) {                                   \
+		if (__i != (size))                          \
+			__ret = -EINVAL;                    \
+	}                                                   \
+	__ret;                                              \
+})
+
+#endif /* _UAPI__LINUX_BRIDGE_EFF_H */
diff --git a/include/uapi/linux/netfilter_ipv4/Kbuild b/include/uapi/linux/netfilter_ipv4/Kbuild
index aafaa5a..fb00843 100644
--- a/include/uapi/linux/netfilter_ipv4/Kbuild
+++ b/include/uapi/linux/netfilter_ipv4/Kbuild
@@ -1 +1,11 @@
 # UAPI Header export list
+header-y += ip_tables.h
+header-y += ipt_CLUSTERIP.h
+header-y += ipt_ECN.h
+header-y += ipt_LOG.h
+header-y += ipt_REJECT.h
+header-y += ipt_TTL.h
+header-y += ipt_ULOG.h
+header-y += ipt_ah.h
+header-y += ipt_ecn.h
+header-y += ipt_ttl.h
diff --git a/include/uapi/linux/netfilter_ipv4/ip_tables.h b/include/uapi/linux/netfilter_ipv4/ip_tables.h
new file mode 100644
index 0000000..f1e6ef2
--- /dev/null
+++ b/include/uapi/linux/netfilter_ipv4/ip_tables.h
@@ -0,0 +1,229 @@
+/*
+ * 25-Jul-1998 Major changes to allow for ip chain table
+ *
+ * 3-Jan-2000 Named tables to allow packet selection for different uses.
+ */
+
+/*
+ * 	Format of an IP firewall descriptor
+ *
+ * 	src, dst, src_mask, dst_mask are always stored in network byte order.
+ * 	flags are stored in host byte order (of course).
+ * 	Port numbers are stored in HOST byte order.
+ */
+
+#ifndef _UAPI_IPTABLES_H
+#define _UAPI_IPTABLES_H
+
+#include <linux/types.h>
+#include <linux/compiler.h>
+#include <linux/netfilter_ipv4.h>
+
+#include <linux/netfilter/x_tables.h>
+
+#ifndef __KERNEL__
+#define IPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
+#define IPT_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN
+#define ipt_match xt_match
+#define ipt_target xt_target
+#define ipt_table xt_table
+#define ipt_get_revision xt_get_revision
+#define ipt_entry_match xt_entry_match
+#define ipt_entry_target xt_entry_target
+#define ipt_standard_target xt_standard_target
+#define ipt_error_target xt_error_target
+#define ipt_counters xt_counters
+#define IPT_CONTINUE XT_CONTINUE
+#define IPT_RETURN XT_RETURN
+
+/* This group is older than old (iptables < v1.4.0-rc1~89) */
+#include <linux/netfilter/xt_tcpudp.h>
+#define ipt_udp xt_udp
+#define ipt_tcp xt_tcp
+#define IPT_TCP_INV_SRCPT	XT_TCP_INV_SRCPT
+#define IPT_TCP_INV_DSTPT	XT_TCP_INV_DSTPT
+#define IPT_TCP_INV_FLAGS	XT_TCP_INV_FLAGS
+#define IPT_TCP_INV_OPTION	XT_TCP_INV_OPTION
+#define IPT_TCP_INV_MASK	XT_TCP_INV_MASK
+#define IPT_UDP_INV_SRCPT	XT_UDP_INV_SRCPT
+#define IPT_UDP_INV_DSTPT	XT_UDP_INV_DSTPT
+#define IPT_UDP_INV_MASK	XT_UDP_INV_MASK
+
+/* The argument to IPT_SO_ADD_COUNTERS. */
+#define ipt_counters_info xt_counters_info
+/* Standard return verdict, or do jump. */
+#define IPT_STANDARD_TARGET XT_STANDARD_TARGET
+/* Error verdict. */
+#define IPT_ERROR_TARGET XT_ERROR_TARGET
+
+/* fn returns 0 to continue iteration */
+#define IPT_MATCH_ITERATE(e, fn, args...) \
+	XT_MATCH_ITERATE(struct ipt_entry, e, fn, ## args)
+
+/* fn returns 0 to continue iteration */
+#define IPT_ENTRY_ITERATE(entries, size, fn, args...) \
+	XT_ENTRY_ITERATE(struct ipt_entry, entries, size, fn, ## args)
+#endif
+
+/* Yes, Virginia, you have to zero the padding. */
+struct ipt_ip {
+	/* Source and destination IP addr */
+	struct in_addr src, dst;
+	/* Mask for src and dest IP addr */
+	struct in_addr smsk, dmsk;
+	char iniface[IFNAMSIZ], outiface[IFNAMSIZ];
+	unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];
+
+	/* Protocol, 0 = ANY */
+	__u16 proto;
+
+	/* Flags word */
+	__u8 flags;
+	/* Inverse flags */
+	__u8 invflags;
+};
+
+/* Values for "flag" field in struct ipt_ip (general ip structure). */
+#define IPT_F_FRAG		0x01	/* Set if rule is a fragment rule */
+#define IPT_F_GOTO		0x02	/* Set if jump is a goto */
+#define IPT_F_MASK		0x03	/* All possible flag bits mask. */
+
+/* Values for "inv" field in struct ipt_ip. */
+#define IPT_INV_VIA_IN		0x01	/* Invert the sense of IN IFACE. */
+#define IPT_INV_VIA_OUT		0x02	/* Invert the sense of OUT IFACE */
+#define IPT_INV_TOS		0x04	/* Invert the sense of TOS. */
+#define IPT_INV_SRCIP		0x08	/* Invert the sense of SRC IP. */
+#define IPT_INV_DSTIP		0x10	/* Invert the sense of DST OP. */
+#define IPT_INV_FRAG		0x20	/* Invert the sense of FRAG. */
+#define IPT_INV_PROTO		XT_INV_PROTO
+#define IPT_INV_MASK		0x7F	/* All possible flag bits mask. */
+
+/* This structure defines each of the firewall rules.  Consists of 3
+   parts which are 1) general IP header stuff 2) match specific
+   stuff 3) the target to perform if the rule matches */
+struct ipt_entry {
+	struct ipt_ip ip;
+
+	/* Mark with fields that we care about. */
+	unsigned int nfcache;
+
+	/* Size of ipt_entry + matches */
+	__u16 target_offset;
+	/* Size of ipt_entry + matches + target */
+	__u16 next_offset;
+
+	/* Back pointer */
+	unsigned int comefrom;
+
+	/* Packet and byte counters. */
+	struct xt_counters counters;
+
+	/* The matches (if any), then the target. */
+	unsigned char elems[0];
+};
+
+/*
+ * New IP firewall options for [gs]etsockopt at the RAW IP level.
+ * Unlike BSD Linux inherits IP options so you don't have to use a raw
+ * socket for this. Instead we check rights in the calls.
+ *
+ * ATTENTION: check linux/in.h before adding new number here.
+ */
+#define IPT_BASE_CTL		64
+
+#define IPT_SO_SET_REPLACE	(IPT_BASE_CTL)
+#define IPT_SO_SET_ADD_COUNTERS	(IPT_BASE_CTL + 1)
+#define IPT_SO_SET_MAX		IPT_SO_SET_ADD_COUNTERS
+
+#define IPT_SO_GET_INFO			(IPT_BASE_CTL)
+#define IPT_SO_GET_ENTRIES		(IPT_BASE_CTL + 1)
+#define IPT_SO_GET_REVISION_MATCH	(IPT_BASE_CTL + 2)
+#define IPT_SO_GET_REVISION_TARGET	(IPT_BASE_CTL + 3)
+#define IPT_SO_GET_MAX			IPT_SO_GET_REVISION_TARGET
+
+/* ICMP matching stuff */
+struct ipt_icmp {
+	__u8 type;				/* type to match */
+	__u8 code[2];				/* range of code */
+	__u8 invflags;				/* Inverse flags */
+};
+
+/* Values for "inv" field for struct ipt_icmp. */
+#define IPT_ICMP_INV	0x01	/* Invert the sense of type/code test */
+
+/* The argument to IPT_SO_GET_INFO */
+struct ipt_getinfo {
+	/* Which table: caller fills this in. */
+	char name[XT_TABLE_MAXNAMELEN];
+
+	/* Kernel fills these in. */
+	/* Which hook entry points are valid: bitmask */
+	unsigned int valid_hooks;
+
+	/* Hook entry points: one per netfilter hook. */
+	unsigned int hook_entry[NF_INET_NUMHOOKS];
+
+	/* Underflow points. */
+	unsigned int underflow[NF_INET_NUMHOOKS];
+
+	/* Number of entries */
+	unsigned int num_entries;
+
+	/* Size of entries. */
+	unsigned int size;
+};
+
+/* The argument to IPT_SO_SET_REPLACE. */
+struct ipt_replace {
+	/* Which table. */
+	char name[XT_TABLE_MAXNAMELEN];
+
+	/* Which hook entry points are valid: bitmask.  You can't
+           change this. */
+	unsigned int valid_hooks;
+
+	/* Number of entries */
+	unsigned int num_entries;
+
+	/* Total size of new entries */
+	unsigned int size;
+
+	/* Hook entry points. */
+	unsigned int hook_entry[NF_INET_NUMHOOKS];
+
+	/* Underflow points. */
+	unsigned int underflow[NF_INET_NUMHOOKS];
+
+	/* Information about old entries: */
+	/* Number of counters (must be equal to current number of entries). */
+	unsigned int num_counters;
+	/* The old entries' counters. */
+	struct xt_counters __user *counters;
+
+	/* The entries (hang off end: not really an array). */
+	struct ipt_entry entries[0];
+};
+
+/* The argument to IPT_SO_GET_ENTRIES. */
+struct ipt_get_entries {
+	/* Which table: user fills this in. */
+	char name[XT_TABLE_MAXNAMELEN];
+
+	/* User fills this in: total entry size. */
+	unsigned int size;
+
+	/* The entries. */
+	struct ipt_entry entrytable[0];
+};
+
+/* Helper functions */
+static __inline__ struct xt_entry_target *
+ipt_get_target(struct ipt_entry *e)
+{
+	return (void *)e + e->target_offset;
+}
+
+/*
+ *	Main firewall chains definitions and global var's definitions.
+ */
+#endif /* _UAPI_IPTABLES_H */
diff --git a/include/linux/netfilter_ipv4/ipt_CLUSTERIP.h b/include/uapi/linux/netfilter_ipv4/ipt_CLUSTERIP.h
similarity index 100%
rename from include/linux/netfilter_ipv4/ipt_CLUSTERIP.h
rename to include/uapi/linux/netfilter_ipv4/ipt_CLUSTERIP.h
diff --git a/include/linux/netfilter_ipv4/ipt_ECN.h b/include/uapi/linux/netfilter_ipv4/ipt_ECN.h
similarity index 100%
rename from include/linux/netfilter_ipv4/ipt_ECN.h
rename to include/uapi/linux/netfilter_ipv4/ipt_ECN.h
diff --git a/include/linux/netfilter_ipv4/ipt_LOG.h b/include/uapi/linux/netfilter_ipv4/ipt_LOG.h
similarity index 100%
rename from include/linux/netfilter_ipv4/ipt_LOG.h
rename to include/uapi/linux/netfilter_ipv4/ipt_LOG.h
diff --git a/include/linux/netfilter_ipv4/ipt_REJECT.h b/include/uapi/linux/netfilter_ipv4/ipt_REJECT.h
similarity index 100%
rename from include/linux/netfilter_ipv4/ipt_REJECT.h
rename to include/uapi/linux/netfilter_ipv4/ipt_REJECT.h
diff --git a/include/linux/netfilter_ipv4/ipt_TTL.h b/include/uapi/linux/netfilter_ipv4/ipt_TTL.h
similarity index 100%
rename from include/linux/netfilter_ipv4/ipt_TTL.h
rename to include/uapi/linux/netfilter_ipv4/ipt_TTL.h
diff --git a/include/linux/netfilter_ipv4/ipt_ULOG.h b/include/uapi/linux/netfilter_ipv4/ipt_ULOG.h
similarity index 100%
rename from include/linux/netfilter_ipv4/ipt_ULOG.h
rename to include/uapi/linux/netfilter_ipv4/ipt_ULOG.h
diff --git a/include/linux/netfilter_ipv4/ipt_ah.h b/include/uapi/linux/netfilter_ipv4/ipt_ah.h
similarity index 100%
rename from include/linux/netfilter_ipv4/ipt_ah.h
rename to include/uapi/linux/netfilter_ipv4/ipt_ah.h
diff --git a/include/linux/netfilter_ipv4/ipt_ecn.h b/include/uapi/linux/netfilter_ipv4/ipt_ecn.h
similarity index 100%
rename from include/linux/netfilter_ipv4/ipt_ecn.h
rename to include/uapi/linux/netfilter_ipv4/ipt_ecn.h
diff --git a/include/linux/netfilter_ipv4/ipt_ttl.h b/include/uapi/linux/netfilter_ipv4/ipt_ttl.h
similarity index 100%
rename from include/linux/netfilter_ipv4/ipt_ttl.h
rename to include/uapi/linux/netfilter_ipv4/ipt_ttl.h
diff --git a/include/uapi/linux/netfilter_ipv6/Kbuild b/include/uapi/linux/netfilter_ipv6/Kbuild
index aafaa5a..75a668c 100644
--- a/include/uapi/linux/netfilter_ipv6/Kbuild
+++ b/include/uapi/linux/netfilter_ipv6/Kbuild
@@ -1 +1,13 @@
 # UAPI Header export list
+header-y += ip6_tables.h
+header-y += ip6t_HL.h
+header-y += ip6t_LOG.h
+header-y += ip6t_NPT.h
+header-y += ip6t_REJECT.h
+header-y += ip6t_ah.h
+header-y += ip6t_frag.h
+header-y += ip6t_hl.h
+header-y += ip6t_ipv6header.h
+header-y += ip6t_mh.h
+header-y += ip6t_opts.h
+header-y += ip6t_rt.h
diff --git a/include/uapi/linux/netfilter_ipv6/ip6_tables.h b/include/uapi/linux/netfilter_ipv6/ip6_tables.h
new file mode 100644
index 0000000..bf1ef65
--- /dev/null
+++ b/include/uapi/linux/netfilter_ipv6/ip6_tables.h
@@ -0,0 +1,267 @@
+/*
+ * 25-Jul-1998 Major changes to allow for ip chain table
+ *
+ * 3-Jan-2000 Named tables to allow packet selection for different uses.
+ */
+
+/*
+ * 	Format of an IP6 firewall descriptor
+ *
+ * 	src, dst, src_mask, dst_mask are always stored in network byte order.
+ * 	flags are stored in host byte order (of course).
+ * 	Port numbers are stored in HOST byte order.
+ */
+
+#ifndef _UAPI_IP6_TABLES_H
+#define _UAPI_IP6_TABLES_H
+
+#include <linux/types.h>
+#include <linux/compiler.h>
+#include <linux/netfilter_ipv6.h>
+
+#include <linux/netfilter/x_tables.h>
+
+#ifndef __KERNEL__
+#define IP6T_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN
+#define IP6T_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN
+#define ip6t_match xt_match
+#define ip6t_target xt_target
+#define ip6t_table xt_table
+#define ip6t_get_revision xt_get_revision
+#define ip6t_entry_match xt_entry_match
+#define ip6t_entry_target xt_entry_target
+#define ip6t_standard_target xt_standard_target
+#define ip6t_error_target xt_error_target
+#define ip6t_counters xt_counters
+#define IP6T_CONTINUE XT_CONTINUE
+#define IP6T_RETURN XT_RETURN
+
+/* Pre-iptables-1.4.0 */
+#include <linux/netfilter/xt_tcpudp.h>
+#define ip6t_tcp xt_tcp
+#define ip6t_udp xt_udp
+#define IP6T_TCP_INV_SRCPT	XT_TCP_INV_SRCPT
+#define IP6T_TCP_INV_DSTPT	XT_TCP_INV_DSTPT
+#define IP6T_TCP_INV_FLAGS	XT_TCP_INV_FLAGS
+#define IP6T_TCP_INV_OPTION	XT_TCP_INV_OPTION
+#define IP6T_TCP_INV_MASK	XT_TCP_INV_MASK
+#define IP6T_UDP_INV_SRCPT	XT_UDP_INV_SRCPT
+#define IP6T_UDP_INV_DSTPT	XT_UDP_INV_DSTPT
+#define IP6T_UDP_INV_MASK	XT_UDP_INV_MASK
+
+#define ip6t_counters_info xt_counters_info
+#define IP6T_STANDARD_TARGET XT_STANDARD_TARGET
+#define IP6T_ERROR_TARGET XT_ERROR_TARGET
+#define IP6T_MATCH_ITERATE(e, fn, args...) \
+	XT_MATCH_ITERATE(struct ip6t_entry, e, fn, ## args)
+#define IP6T_ENTRY_ITERATE(entries, size, fn, args...) \
+	XT_ENTRY_ITERATE(struct ip6t_entry, entries, size, fn, ## args)
+#endif
+
+/* Yes, Virginia, you have to zero the padding. */
+struct ip6t_ip6 {
+	/* Source and destination IP6 addr */
+	struct in6_addr src, dst;		
+	/* Mask for src and dest IP6 addr */
+	struct in6_addr smsk, dmsk;
+	char iniface[IFNAMSIZ], outiface[IFNAMSIZ];
+	unsigned char iniface_mask[IFNAMSIZ], outiface_mask[IFNAMSIZ];
+
+	/* Upper protocol number
+	 * - The allowed value is 0 (any) or protocol number of last parsable
+	 *   header, which is 50 (ESP), 59 (No Next Header), 135 (MH), or
+	 *   the non IPv6 extension headers.
+	 * - The protocol numbers of IPv6 extension headers except of ESP and
+	 *   MH do not match any packets.
+	 * - You also need to set IP6T_FLAGS_PROTO to "flags" to check protocol.
+	 */
+	__u16 proto;
+	/* TOS to match iff flags & IP6T_F_TOS */
+	__u8 tos;
+
+	/* Flags word */
+	__u8 flags;
+	/* Inverse flags */
+	__u8 invflags;
+};
+
+/* Values for "flag" field in struct ip6t_ip6 (general ip6 structure). */
+#define IP6T_F_PROTO		0x01	/* Set if rule cares about upper 
+					   protocols */
+#define IP6T_F_TOS		0x02	/* Match the TOS. */
+#define IP6T_F_GOTO		0x04	/* Set if jump is a goto */
+#define IP6T_F_MASK		0x07	/* All possible flag bits mask. */
+
+/* Values for "inv" field in struct ip6t_ip6. */
+#define IP6T_INV_VIA_IN		0x01	/* Invert the sense of IN IFACE. */
+#define IP6T_INV_VIA_OUT		0x02	/* Invert the sense of OUT IFACE */
+#define IP6T_INV_TOS		0x04	/* Invert the sense of TOS. */
+#define IP6T_INV_SRCIP		0x08	/* Invert the sense of SRC IP. */
+#define IP6T_INV_DSTIP		0x10	/* Invert the sense of DST OP. */
+#define IP6T_INV_FRAG		0x20	/* Invert the sense of FRAG. */
+#define IP6T_INV_PROTO		XT_INV_PROTO
+#define IP6T_INV_MASK		0x7F	/* All possible flag bits mask. */
+
+/* This structure defines each of the firewall rules.  Consists of 3
+   parts which are 1) general IP header stuff 2) match specific
+   stuff 3) the target to perform if the rule matches */
+struct ip6t_entry {
+	struct ip6t_ip6 ipv6;
+
+	/* Mark with fields that we care about. */
+	unsigned int nfcache;
+
+	/* Size of ipt_entry + matches */
+	__u16 target_offset;
+	/* Size of ipt_entry + matches + target */
+	__u16 next_offset;
+
+	/* Back pointer */
+	unsigned int comefrom;
+
+	/* Packet and byte counters. */
+	struct xt_counters counters;
+
+	/* The matches (if any), then the target. */
+	unsigned char elems[0];
+};
+
+/* Standard entry */
+struct ip6t_standard {
+	struct ip6t_entry entry;
+	struct xt_standard_target target;
+};
+
+struct ip6t_error {
+	struct ip6t_entry entry;
+	struct xt_error_target target;
+};
+
+#define IP6T_ENTRY_INIT(__size)						       \
+{									       \
+	.target_offset	= sizeof(struct ip6t_entry),			       \
+	.next_offset	= (__size),					       \
+}
+
+#define IP6T_STANDARD_INIT(__verdict)					       \
+{									       \
+	.entry		= IP6T_ENTRY_INIT(sizeof(struct ip6t_standard)),       \
+	.target		= XT_TARGET_INIT(XT_STANDARD_TARGET,		       \
+					 sizeof(struct xt_standard_target)),   \
+	.target.verdict	= -(__verdict) - 1,				       \
+}
+
+#define IP6T_ERROR_INIT							       \
+{									       \
+	.entry		= IP6T_ENTRY_INIT(sizeof(struct ip6t_error)),	       \
+	.target		= XT_TARGET_INIT(XT_ERROR_TARGET,		       \
+					 sizeof(struct xt_error_target)),      \
+	.target.errorname = "ERROR",					       \
+}
+
+/*
+ * New IP firewall options for [gs]etsockopt at the RAW IP level.
+ * Unlike BSD Linux inherits IP options so you don't have to use
+ * a raw socket for this. Instead we check rights in the calls.
+ *
+ * ATTENTION: check linux/in6.h before adding new number here.
+ */
+#define IP6T_BASE_CTL			64
+
+#define IP6T_SO_SET_REPLACE		(IP6T_BASE_CTL)
+#define IP6T_SO_SET_ADD_COUNTERS	(IP6T_BASE_CTL + 1)
+#define IP6T_SO_SET_MAX			IP6T_SO_SET_ADD_COUNTERS
+
+#define IP6T_SO_GET_INFO		(IP6T_BASE_CTL)
+#define IP6T_SO_GET_ENTRIES		(IP6T_BASE_CTL + 1)
+#define IP6T_SO_GET_REVISION_MATCH	(IP6T_BASE_CTL + 4)
+#define IP6T_SO_GET_REVISION_TARGET	(IP6T_BASE_CTL + 5)
+#define IP6T_SO_GET_MAX			IP6T_SO_GET_REVISION_TARGET
+
+/* ICMP matching stuff */
+struct ip6t_icmp {
+	__u8 type;				/* type to match */
+	__u8 code[2];				/* range of code */
+	__u8 invflags;				/* Inverse flags */
+};
+
+/* Values for "inv" field for struct ipt_icmp. */
+#define IP6T_ICMP_INV	0x01	/* Invert the sense of type/code test */
+
+/* The argument to IP6T_SO_GET_INFO */
+struct ip6t_getinfo {
+	/* Which table: caller fills this in. */
+	char name[XT_TABLE_MAXNAMELEN];
+
+	/* Kernel fills these in. */
+	/* Which hook entry points are valid: bitmask */
+	unsigned int valid_hooks;
+
+	/* Hook entry points: one per netfilter hook. */
+	unsigned int hook_entry[NF_INET_NUMHOOKS];
+
+	/* Underflow points. */
+	unsigned int underflow[NF_INET_NUMHOOKS];
+
+	/* Number of entries */
+	unsigned int num_entries;
+
+	/* Size of entries. */
+	unsigned int size;
+};
+
+/* The argument to IP6T_SO_SET_REPLACE. */
+struct ip6t_replace {
+	/* Which table. */
+	char name[XT_TABLE_MAXNAMELEN];
+
+	/* Which hook entry points are valid: bitmask.  You can't
+           change this. */
+	unsigned int valid_hooks;
+
+	/* Number of entries */
+	unsigned int num_entries;
+
+	/* Total size of new entries */
+	unsigned int size;
+
+	/* Hook entry points. */
+	unsigned int hook_entry[NF_INET_NUMHOOKS];
+
+	/* Underflow points. */
+	unsigned int underflow[NF_INET_NUMHOOKS];
+
+	/* Information about old entries: */
+	/* Number of counters (must be equal to current number of entries). */
+	unsigned int num_counters;
+	/* The old entries' counters. */
+	struct xt_counters __user *counters;
+
+	/* The entries (hang off end: not really an array). */
+	struct ip6t_entry entries[0];
+};
+
+/* The argument to IP6T_SO_GET_ENTRIES. */
+struct ip6t_get_entries {
+	/* Which table: user fills this in. */
+	char name[XT_TABLE_MAXNAMELEN];
+
+	/* User fills this in: total entry size. */
+	unsigned int size;
+
+	/* The entries. */
+	struct ip6t_entry entrytable[0];
+};
+
+/* Helper functions */
+static __inline__ struct xt_entry_target *
+ip6t_get_target(struct ip6t_entry *e)
+{
+	return (void *)e + e->target_offset;
+}
+
+/*
+ *	Main firewall chains definitions and global var's definitions.
+ */
+
+#endif /* _UAPI_IP6_TABLES_H */
diff --git a/include/linux/netfilter_ipv6/ip6t_HL.h b/include/uapi/linux/netfilter_ipv6/ip6t_HL.h
similarity index 100%
rename from include/linux/netfilter_ipv6/ip6t_HL.h
rename to include/uapi/linux/netfilter_ipv6/ip6t_HL.h
diff --git a/include/linux/netfilter_ipv6/ip6t_LOG.h b/include/uapi/linux/netfilter_ipv6/ip6t_LOG.h
similarity index 100%
rename from include/linux/netfilter_ipv6/ip6t_LOG.h
rename to include/uapi/linux/netfilter_ipv6/ip6t_LOG.h
diff --git a/include/linux/netfilter_ipv6/ip6t_NPT.h b/include/uapi/linux/netfilter_ipv6/ip6t_NPT.h
similarity index 100%
rename from include/linux/netfilter_ipv6/ip6t_NPT.h
rename to include/uapi/linux/netfilter_ipv6/ip6t_NPT.h
diff --git a/include/linux/netfilter_ipv6/ip6t_REJECT.h b/include/uapi/linux/netfilter_ipv6/ip6t_REJECT.h
similarity index 100%
rename from include/linux/netfilter_ipv6/ip6t_REJECT.h
rename to include/uapi/linux/netfilter_ipv6/ip6t_REJECT.h
diff --git a/include/linux/netfilter_ipv6/ip6t_ah.h b/include/uapi/linux/netfilter_ipv6/ip6t_ah.h
similarity index 100%
rename from include/linux/netfilter_ipv6/ip6t_ah.h
rename to include/uapi/linux/netfilter_ipv6/ip6t_ah.h
diff --git a/include/linux/netfilter_ipv6/ip6t_frag.h b/include/uapi/linux/netfilter_ipv6/ip6t_frag.h
similarity index 100%
rename from include/linux/netfilter_ipv6/ip6t_frag.h
rename to include/uapi/linux/netfilter_ipv6/ip6t_frag.h
diff --git a/include/linux/netfilter_ipv6/ip6t_hl.h b/include/uapi/linux/netfilter_ipv6/ip6t_hl.h
similarity index 100%
rename from include/linux/netfilter_ipv6/ip6t_hl.h
rename to include/uapi/linux/netfilter_ipv6/ip6t_hl.h
diff --git a/include/linux/netfilter_ipv6/ip6t_ipv6header.h b/include/uapi/linux/netfilter_ipv6/ip6t_ipv6header.h
similarity index 100%
rename from include/linux/netfilter_ipv6/ip6t_ipv6header.h
rename to include/uapi/linux/netfilter_ipv6/ip6t_ipv6header.h
diff --git a/include/linux/netfilter_ipv6/ip6t_mh.h b/include/uapi/linux/netfilter_ipv6/ip6t_mh.h
similarity index 100%
rename from include/linux/netfilter_ipv6/ip6t_mh.h
rename to include/uapi/linux/netfilter_ipv6/ip6t_mh.h
diff --git a/include/linux/netfilter_ipv6/ip6t_opts.h b/include/uapi/linux/netfilter_ipv6/ip6t_opts.h
similarity index 100%
rename from include/linux/netfilter_ipv6/ip6t_opts.h
rename to include/uapi/linux/netfilter_ipv6/ip6t_opts.h
diff --git a/include/linux/netfilter_ipv6/ip6t_rt.h b/include/uapi/linux/netfilter_ipv6/ip6t_rt.h
similarity index 100%
rename from include/linux/netfilter_ipv6/ip6t_rt.h
rename to include/uapi/linux/netfilter_ipv6/ip6t_rt.h
diff --git a/include/uapi/linux/tc_act/Kbuild b/include/uapi/linux/tc_act/Kbuild
index aafaa5a..0623ec4 100644
--- a/include/uapi/linux/tc_act/Kbuild
+++ b/include/uapi/linux/tc_act/Kbuild
@@ -1 +1,8 @@
 # UAPI Header export list
+header-y += tc_csum.h
+header-y += tc_gact.h
+header-y += tc_ipt.h
+header-y += tc_mirred.h
+header-y += tc_nat.h
+header-y += tc_pedit.h
+header-y += tc_skbedit.h
diff --git a/include/linux/tc_act/tc_csum.h b/include/uapi/linux/tc_act/tc_csum.h
similarity index 100%
rename from include/linux/tc_act/tc_csum.h
rename to include/uapi/linux/tc_act/tc_csum.h
diff --git a/include/linux/tc_act/tc_gact.h b/include/uapi/linux/tc_act/tc_gact.h
similarity index 100%
rename from include/linux/tc_act/tc_gact.h
rename to include/uapi/linux/tc_act/tc_gact.h
diff --git a/include/linux/tc_act/tc_ipt.h b/include/uapi/linux/tc_act/tc_ipt.h
similarity index 100%
rename from include/linux/tc_act/tc_ipt.h
rename to include/uapi/linux/tc_act/tc_ipt.h
diff --git a/include/linux/tc_act/tc_mirred.h b/include/uapi/linux/tc_act/tc_mirred.h
similarity index 100%
rename from include/linux/tc_act/tc_mirred.h
rename to include/uapi/linux/tc_act/tc_mirred.h
diff --git a/include/linux/tc_act/tc_nat.h b/include/uapi/linux/tc_act/tc_nat.h
similarity index 100%
rename from include/linux/tc_act/tc_nat.h
rename to include/uapi/linux/tc_act/tc_nat.h
diff --git a/include/linux/tc_act/tc_pedit.h b/include/uapi/linux/tc_act/tc_pedit.h
similarity index 100%
rename from include/linux/tc_act/tc_pedit.h
rename to include/uapi/linux/tc_act/tc_pedit.h
diff --git a/include/linux/tc_act/tc_skbedit.h b/include/uapi/linux/tc_act/tc_skbedit.h
similarity index 100%
rename from include/linux/tc_act/tc_skbedit.h
rename to include/uapi/linux/tc_act/tc_skbedit.h
diff --git a/include/uapi/linux/tc_ematch/Kbuild b/include/uapi/linux/tc_ematch/Kbuild
index aafaa5a..53fca39 100644
--- a/include/uapi/linux/tc_ematch/Kbuild
+++ b/include/uapi/linux/tc_ematch/Kbuild
@@ -1 +1,5 @@
 # UAPI Header export list
+header-y += tc_em_cmp.h
+header-y += tc_em_meta.h
+header-y += tc_em_nbyte.h
+header-y += tc_em_text.h
diff --git a/include/linux/tc_ematch/tc_em_cmp.h b/include/uapi/linux/tc_ematch/tc_em_cmp.h
similarity index 100%
rename from include/linux/tc_ematch/tc_em_cmp.h
rename to include/uapi/linux/tc_ematch/tc_em_cmp.h
diff --git a/include/linux/tc_ematch/tc_em_meta.h b/include/uapi/linux/tc_ematch/tc_em_meta.h
similarity index 100%
rename from include/linux/tc_ematch/tc_em_meta.h
rename to include/uapi/linux/tc_ematch/tc_em_meta.h
diff --git a/include/linux/tc_ematch/tc_em_nbyte.h b/include/uapi/linux/tc_ematch/tc_em_nbyte.h
similarity index 100%
rename from include/linux/tc_ematch/tc_em_nbyte.h
rename to include/uapi/linux/tc_ematch/tc_em_nbyte.h
diff --git a/include/linux/tc_ematch/tc_em_text.h b/include/uapi/linux/tc_ematch/tc_em_text.h
similarity index 100%
rename from include/linux/tc_ematch/tc_em_text.h
rename to include/uapi/linux/tc_ematch/tc_em_text.h
diff --git a/include/uapi/mtd/Kbuild b/include/uapi/mtd/Kbuild
index aafaa5a..5a691e1 100644
--- a/include/uapi/mtd/Kbuild
+++ b/include/uapi/mtd/Kbuild
@@ -1 +1,6 @@
 # UAPI Header export list
+header-y += inftl-user.h
+header-y += mtd-abi.h
+header-y += mtd-user.h
+header-y += nftl-user.h
+header-y += ubi-user.h
diff --git a/include/mtd/inftl-user.h b/include/uapi/mtd/inftl-user.h
similarity index 100%
rename from include/mtd/inftl-user.h
rename to include/uapi/mtd/inftl-user.h
diff --git a/include/mtd/mtd-abi.h b/include/uapi/mtd/mtd-abi.h
similarity index 100%
rename from include/mtd/mtd-abi.h
rename to include/uapi/mtd/mtd-abi.h
diff --git a/include/mtd/mtd-user.h b/include/uapi/mtd/mtd-user.h
similarity index 100%
rename from include/mtd/mtd-user.h
rename to include/uapi/mtd/mtd-user.h
diff --git a/include/mtd/nftl-user.h b/include/uapi/mtd/nftl-user.h
similarity index 100%
rename from include/mtd/nftl-user.h
rename to include/uapi/mtd/nftl-user.h
diff --git a/include/mtd/ubi-user.h b/include/uapi/mtd/ubi-user.h
similarity index 100%
rename from include/mtd/ubi-user.h
rename to include/uapi/mtd/ubi-user.h
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index a6267a2..3729173 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -48,10 +48,10 @@
 #define DISPC_IRQ_FRAMEDONEWB		(1 << 23)
 #define DISPC_IRQ_FRAMEDONETV		(1 << 24)
 #define DISPC_IRQ_WBBUFFEROVERFLOW	(1 << 25)
-#define DISPC_IRQ_FRAMEDONE3		(1 << 26)
-#define DISPC_IRQ_VSYNC3		(1 << 27)
-#define DISPC_IRQ_ACBIAS_COUNT_STAT3	(1 << 28)
-#define DISPC_IRQ_SYNC_LOST3		(1 << 29)
+#define DISPC_IRQ_SYNC_LOST3		(1 << 27)
+#define DISPC_IRQ_VSYNC3		(1 << 28)
+#define DISPC_IRQ_ACBIAS_COUNT_STAT3	(1 << 29)
+#define DISPC_IRQ_FRAMEDONE3		(1 << 30)
 
 struct omap_dss_device;
 struct omap_overlay_manager;
@@ -73,6 +73,7 @@
 	OMAP_DSS_VIDEO1	= 1,
 	OMAP_DSS_VIDEO2	= 2,
 	OMAP_DSS_VIDEO3	= 3,
+	OMAP_DSS_WB	= 4,
 };
 
 enum omap_channel {
@@ -186,6 +187,8 @@
 	OMAP_DSS_OVL_CAP_GLOBAL_ALPHA = 1 << 1,
 	OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA = 1 << 2,
 	OMAP_DSS_OVL_CAP_ZORDER = 1 << 3,
+	OMAP_DSS_OVL_CAP_POS = 1 << 4,
+	OMAP_DSS_OVL_CAP_REPLICATION = 1 << 5,
 };
 
 enum omap_overlay_manager_caps {
@@ -207,6 +210,16 @@
 	OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP = 1 << 0,
 };
 
+enum omap_dss_output_id {
+	OMAP_DSS_OUTPUT_DPI	= 1 << 0,
+	OMAP_DSS_OUTPUT_DBI	= 1 << 1,
+	OMAP_DSS_OUTPUT_SDI	= 1 << 2,
+	OMAP_DSS_OUTPUT_DSI1	= 1 << 3,
+	OMAP_DSS_OUTPUT_DSI2	= 1 << 4,
+	OMAP_DSS_OUTPUT_VENC	= 1 << 5,
+	OMAP_DSS_OUTPUT_HDMI	= 1 << 6,
+};
+
 /* RFBI */
 
 struct rfbi_timings {
@@ -243,7 +256,7 @@
 
 /* DSI */
 
-struct omap_dss_dsi_videomode_data {
+struct omap_dss_dsi_videomode_timings {
 	/* DSI video mode blanking data */
 	/* Unit: byte clock cycles */
 	u16 hsa;
@@ -424,6 +437,8 @@
 			struct omap_overlay_info *info);
 
 	int (*wait_for_go)(struct omap_overlay *ovl);
+
+	struct omap_dss_device *(*get_device)(struct omap_overlay *ovl);
 };
 
 struct omap_overlay_manager_info {
@@ -448,9 +463,10 @@
 	enum omap_overlay_manager_caps caps;
 	struct list_head overlays;
 	enum omap_display_type supported_displays;
+	enum omap_dss_output_id supported_outputs;
 
 	/* dynamic fields */
-	struct omap_dss_device *device;
+	struct omap_dss_output *output;
 
 	/*
 	 * The following functions do not block:
@@ -463,9 +479,9 @@
 	 * interrupt context
 	 */
 
-	int (*set_device)(struct omap_overlay_manager *mgr,
-		struct omap_dss_device *dssdev);
-	int (*unset_device)(struct omap_overlay_manager *mgr);
+	int (*set_output)(struct omap_overlay_manager *mgr,
+		struct omap_dss_output *output);
+	int (*unset_output)(struct omap_overlay_manager *mgr);
 
 	int (*set_manager_info)(struct omap_overlay_manager *mgr,
 			struct omap_overlay_manager_info *info);
@@ -475,6 +491,8 @@
 	int (*apply)(struct omap_overlay_manager *mgr);
 	int (*wait_for_go)(struct omap_overlay_manager *mgr);
 	int (*wait_for_vsync)(struct omap_overlay_manager *mgr);
+
+	struct omap_dss_device *(*get_device)(struct omap_overlay_manager *mgr);
 };
 
 /* 22 pins means 1 clk lane and 10 data lanes */
@@ -492,6 +510,37 @@
 	int pins[OMAP_DSS_MAX_DSI_PINS];
 };
 
+struct omap_dss_writeback_info {
+	u32 paddr;
+	u32 p_uv_addr;
+	u16 buf_width;
+	u16 width;
+	u16 height;
+	enum omap_color_mode color_mode;
+	u8 rotation;
+	enum omap_dss_rotation_type rotation_type;
+	bool mirror;
+	u8 pre_mult_alpha;
+};
+
+struct omap_dss_output {
+	struct list_head list;
+
+	/* display type supported by the output */
+	enum omap_display_type type;
+
+	/* output instance */
+	enum omap_dss_output_id id;
+
+	/* output's platform device pointer */
+	struct platform_device *pdev;
+
+	/* dynamic fields */
+	struct omap_overlay_manager *manager;
+
+	struct omap_dss_device *device;
+};
+
 struct omap_dss_device {
 	struct device dev;
 
@@ -564,7 +613,7 @@
 
 		enum omap_dss_dsi_pixel_format dsi_pix_fmt;
 		enum omap_dss_dsi_mode dsi_mode;
-		struct omap_dss_dsi_videomode_data dsi_vm_data;
+		struct omap_dss_dsi_videomode_timings dsi_vm_timings;
 	} panel;
 
 	struct {
@@ -590,7 +639,7 @@
 
 	enum omap_display_caps caps;
 
-	struct omap_overlay_manager *manager;
+	struct omap_dss_output *output;
 
 	enum omap_dss_display_state state;
 
@@ -605,6 +654,8 @@
 
 struct omap_dss_hdmi_data
 {
+	int ct_cp_hpd_gpio;
+	int ls_oe_gpio;
 	int hpd_gpio;
 };
 
@@ -699,6 +750,11 @@
 int omap_dss_get_num_overlays(void);
 struct omap_overlay *omap_dss_get_overlay(int num);
 
+struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id);
+int omapdss_output_set_device(struct omap_dss_output *out,
+		struct omap_dss_device *dssdev);
+int omapdss_output_unset_device(struct omap_dss_output *out);
+
 void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
 		u16 *xres, u16 *yres);
 int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev);
@@ -719,6 +775,15 @@
 void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
 		bool enable);
 int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable);
+void omapdss_dsi_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings);
+void omapdss_dsi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h);
+void omapdss_dsi_set_pixel_format(struct omap_dss_device *dssdev,
+		enum omap_dss_dsi_pixel_format fmt);
+void omapdss_dsi_set_operation_mode(struct omap_dss_device *dssdev,
+		enum omap_dss_dsi_mode mode);
+void omapdss_dsi_set_videomode_timings(struct omap_dss_device *dssdev,
+		struct omap_dss_dsi_videomode_timings *timings);
 
 int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
 		void (*callback)(int, void *), void *data);
@@ -727,6 +792,8 @@
 void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel);
 int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev,
 		const struct omap_dsi_pin_config *pin_cfg);
+int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev,
+		unsigned long ddr_clk, unsigned long lp_clk);
 
 int omapdss_dsi_display_enable(struct omap_dss_device *dssdev);
 void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
@@ -734,22 +801,29 @@
 
 int omapdss_dpi_display_enable(struct omap_dss_device *dssdev);
 void omapdss_dpi_display_disable(struct omap_dss_device *dssdev);
-void dpi_set_timings(struct omap_dss_device *dssdev,
-			struct omap_video_timings *timings);
+void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings);
 int dpi_check_timings(struct omap_dss_device *dssdev,
 			struct omap_video_timings *timings);
+void omapdss_dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines);
 
 int omapdss_sdi_display_enable(struct omap_dss_device *dssdev);
 void omapdss_sdi_display_disable(struct omap_dss_device *dssdev);
+void omapdss_sdi_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings);
+void omapdss_sdi_set_datapairs(struct omap_dss_device *dssdev, int datapairs);
 
 int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev);
 void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev);
-int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
-		u16 *x, u16 *y, u16 *w, u16 *h);
-int omap_rfbi_update(struct omap_dss_device *dssdev,
-		u16 x, u16 y, u16 w, u16 h,
-		void (*callback)(void *), void *data);
-int omap_rfbi_configure(struct omap_dss_device *dssdev, int pixel_size,
+int omap_rfbi_update(struct omap_dss_device *dssdev, void (*callback)(void *),
+		void *data);
+int omap_rfbi_configure(struct omap_dss_device *dssdev);
+void omapdss_rfbi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h);
+void omapdss_rfbi_set_pixel_size(struct omap_dss_device *dssdev,
+		int pixel_size);
+void omapdss_rfbi_set_data_lines(struct omap_dss_device *dssdev,
 		int data_lines);
+void omapdss_rfbi_set_interface_timings(struct omap_dss_device *dssdev,
+		struct rfbi_timings *timings);
 
 #endif
diff --git a/arch/arm/plat-samsung/include/plat/regs-fb.h b/include/video/samsung_fimd.h
similarity index 73%
rename from arch/arm/plat-samsung/include/plat/regs-fb.h
rename to include/video/samsung_fimd.h
index 9a78012..7ae6c07 100644
--- a/arch/arm/plat-samsung/include/plat/regs-fb.h
+++ b/include/video/samsung_fimd.h
@@ -1,13 +1,13 @@
-/* arch/arm/plat-samsung/include/plat/regs-fb.h
+/* include/video/samsung_fimd.h
  *
  * Copyright 2008 Openmoko, Inc.
  * Copyright 2008 Simtec Electronics
  *      http://armlinux.simtec.co.uk/
  *      Ben Dooks <ben@simtec.co.uk>
  *
- * S3C Platform - new-style framebuffer register definitions
+ * S3C Platform - new-style fimd and framebuffer register definitions
  *
- * This is the register set for the new style framebuffer interface
+ * This is the register set for the fimd and new style framebuffer interface
  * found from the S3C2443 onwards into the S3C2416, S3C2450 and the
  * S3C64XX series such as the S3C6400 and S3C6410.
  *
@@ -15,19 +15,11 @@
  * whichever architecture is selected, it only contains the core of the
  * register set. See <mach/regs-fb.h> to get the specifics.
  *
- * Note, we changed to using regs-fb.h as it avoids any clashes with
- * the original regs-lcd.h so out of the way of regs-lcd.h as well as
- * indicating the newer block is much more than just an LCD interface.
- *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
 */
 
-/* Please do not include this file directly, use <mach/regs-fb.h> to
- * ensure all the localised SoC support is included as necessary.
-*/
-
 /* VIDCON0 */
 
 #define VIDCON0					(0x00)
@@ -401,3 +393,141 @@
 #define BLENDCON_NEW_8BIT_ALPHA_VALUE		(1 << 0)
 #define BLENDCON_NEW_4BIT_ALPHA_VALUE		(0 << 0)
 
+#define S3C_FB_MAX_WIN (5)  /* number of hardware windows available. */
+#define VIDCON1_FSTATUS_EVEN	(1 << 15)
+
+/* Video timing controls */
+#define VIDTCON0				(0x10)
+#define VIDTCON1				(0x14)
+#define VIDTCON2				(0x18)
+
+/* Window position controls */
+
+#define WINCON(_win)				(0x20 + ((_win) * 4))
+
+/* OSD1 and OSD4 do not have register D */
+
+#define VIDOSD_BASE				(0x40)
+
+#define VIDINTCON0				(0x130)
+
+/* WINCONx */
+
+#define WINCONx_CSCWIDTH_MASK			(0x3 << 26)
+#define WINCONx_CSCWIDTH_SHIFT			(26)
+#define WINCONx_CSCWIDTH_WIDE			(0x0 << 26)
+#define WINCONx_CSCWIDTH_NARROW			(0x3 << 26)
+
+#define WINCONx_ENLOCAL				(1 << 22)
+#define WINCONx_BUFSTATUS			(1 << 21)
+#define WINCONx_BUFSEL				(1 << 20)
+#define WINCONx_BUFAUTOEN			(1 << 19)
+#define WINCONx_YCbCr				(1 << 13)
+
+#define WINCON1_LOCALSEL_CAMIF			(1 << 23)
+
+#define WINCON2_LOCALSEL_CAMIF			(1 << 23)
+#define WINCON2_BLD_PIX				(1 << 6)
+
+#define WINCON2_ALPHA_SEL			(1 << 1)
+#define WINCON2_BPPMODE_MASK			(0xf << 2)
+#define WINCON2_BPPMODE_SHIFT			(2)
+#define WINCON2_BPPMODE_1BPP			(0x0 << 2)
+#define WINCON2_BPPMODE_2BPP			(0x1 << 2)
+#define WINCON2_BPPMODE_4BPP			(0x2 << 2)
+#define WINCON2_BPPMODE_8BPP_1232		(0x4 << 2)
+#define WINCON2_BPPMODE_16BPP_565		(0x5 << 2)
+#define WINCON2_BPPMODE_16BPP_A1555		(0x6 << 2)
+#define WINCON2_BPPMODE_16BPP_I1555		(0x7 << 2)
+#define WINCON2_BPPMODE_18BPP_666		(0x8 << 2)
+#define WINCON2_BPPMODE_18BPP_A1665		(0x9 << 2)
+#define WINCON2_BPPMODE_19BPP_A1666		(0xa << 2)
+#define WINCON2_BPPMODE_24BPP_888		(0xb << 2)
+#define WINCON2_BPPMODE_24BPP_A1887		(0xc << 2)
+#define WINCON2_BPPMODE_25BPP_A1888		(0xd << 2)
+#define WINCON2_BPPMODE_28BPP_A4888		(0xd << 2)
+
+#define WINCON3_BLD_PIX				(1 << 6)
+
+#define WINCON3_ALPHA_SEL			(1 << 1)
+#define WINCON3_BPPMODE_MASK			(0xf << 2)
+#define WINCON3_BPPMODE_SHIFT			(2)
+#define WINCON3_BPPMODE_1BPP			(0x0 << 2)
+#define WINCON3_BPPMODE_2BPP			(0x1 << 2)
+#define WINCON3_BPPMODE_4BPP			(0x2 << 2)
+#define WINCON3_BPPMODE_16BPP_565		(0x5 << 2)
+#define WINCON3_BPPMODE_16BPP_A1555		(0x6 << 2)
+#define WINCON3_BPPMODE_16BPP_I1555		(0x7 << 2)
+#define WINCON3_BPPMODE_18BPP_666		(0x8 << 2)
+#define WINCON3_BPPMODE_18BPP_A1665		(0x9 << 2)
+#define WINCON3_BPPMODE_19BPP_A1666		(0xa << 2)
+#define WINCON3_BPPMODE_24BPP_888		(0xb << 2)
+#define WINCON3_BPPMODE_24BPP_A1887		(0xc << 2)
+#define WINCON3_BPPMODE_25BPP_A1888		(0xd << 2)
+#define WINCON3_BPPMODE_28BPP_A4888		(0xd << 2)
+
+#define VIDINTCON0_FIFIOSEL_WINDOW2		(0x10 << 5)
+#define VIDINTCON0_FIFIOSEL_WINDOW3		(0x20 << 5)
+#define VIDINTCON0_FIFIOSEL_WINDOW4		(0x40 << 5)
+
+#define DITHMODE				(0x170)
+#define WINxMAP(_win)				(0x180 + ((_win) * 4))
+
+
+#define DITHMODE_R_POS_MASK			(0x3 << 5)
+#define DITHMODE_R_POS_SHIFT			(5)
+#define DITHMODE_R_POS_8BIT			(0x0 << 5)
+#define DITHMODE_R_POS_6BIT			(0x1 << 5)
+#define DITHMODE_R_POS_5BIT			(0x2 << 5)
+
+#define DITHMODE_G_POS_MASK			(0x3 << 3)
+#define DITHMODE_G_POS_SHIFT			(3)
+#define DITHMODE_G_POS_8BIT			(0x0 << 3)
+#define DITHMODE_G_POS_6BIT			(0x1 << 3)
+#define DITHMODE_G_POS_5BIT			(0x2 << 3)
+
+#define DITHMODE_B_POS_MASK			(0x3 << 1)
+#define DITHMODE_B_POS_SHIFT			(1)
+#define DITHMODE_B_POS_8BIT			(0x0 << 1)
+#define DITHMODE_B_POS_6BIT			(0x1 << 1)
+#define DITHMODE_B_POS_5BIT			(0x2 << 1)
+
+#define DITHMODE_DITH_EN			(1 << 0)
+
+#define WPALCON					(0x1A0)
+
+/* Palette control */
+/* Note for S5PC100: you can still use those macros on WPALCON (aka WPALCON_L),
+ * but make sure that WPALCON_H W2PAL-W4PAL entries are zeroed out */
+#define WPALCON_W4PAL_16BPP_A555		(1 << 8)
+#define WPALCON_W3PAL_16BPP_A555		(1 << 7)
+#define WPALCON_W2PAL_16BPP_A555		(1 << 6)
+
+
+/* Notes on per-window bpp settings
+ *
+ * Value	Win0	 Win1	  Win2	   Win3	    Win 4
+ * 0000		1(P)	 1(P)	  1(P)	   1(P)	    1(P)
+ * 0001		2(P)	 2(P)     2(P)	   2(P)	    2(P)
+ * 0010		4(P)	 4(P)     4(P)	   4(P)     -none-
+ * 0011		8(P)	 8(P)     -none-   -none-   -none-
+ * 0100		-none-	 8(A232)  8(A232)  -none-   -none-
+ * 0101		16(565)	 16(565)  16(565)  16(565)   16(565)
+ * 0110		-none-	 16(A555) 16(A555) 16(A555)  16(A555)
+ * 0111		16(I555) 16(I565) 16(I555) 16(I555)  16(I555)
+ * 1000		18(666)	 18(666)  18(666)  18(666)   18(666)
+ * 1001		-none-	 18(A665) 18(A665) 18(A665)  16(A665)
+ * 1010		-none-	 19(A666) 19(A666) 19(A666)  19(A666)
+ * 1011		24(888)	 24(888)  24(888)  24(888)   24(888)
+ * 1100		-none-	 24(A887) 24(A887) 24(A887)  24(A887)
+ * 1101		-none-	 25(A888) 25(A888) 25(A888)  25(A888)
+ * 1110		-none-	 -none-	  -none-   -none-    -none-
+ * 1111		-none-	 -none-   -none-   -none-    -none-
+*/
+
+/* FIMD Version 8 register offset definitions */
+#define FIMD_V8_VIDTCON0	(0x20010)
+#define FIMD_V8_VIDTCON1	(0x20014)
+#define FIMD_V8_VIDTCON2	(0x20018)
+#define FIMD_V8_VIDTCON3	(0x2001C)
+#define FIMD_V8_VIDCON1		(0x20004)
diff --git a/init/Kconfig b/init/Kconfig
index ed6334d..4c93533 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1125,10 +1125,12 @@
           environments which can tolerate a "non-standard" kernel.
           Only use this if you really know what you are doing.
 
+config HAVE_UID16
+	bool
+
 config UID16
 	bool "Enable 16-bit UID system calls" if EXPERT
-	depends on ARM || BLACKFIN || CRIS || FRV || H8300 || X86_32 || M68K || (S390 && !64BIT) || SUPERH || SPARC32 || (SPARC64 && COMPAT) || UML || (X86_64 && IA32_EMULATION) \
-		|| AARCH32_EMULATION
+	depends on HAVE_UID16
 	default y
 	help
 	  This enables the legacy 16-bit UID syscall wrappers.
@@ -1150,6 +1152,11 @@
 
 	  If unsure say N here.
 
+config SYSCTL_EXCEPTION_TRACE
+	bool
+	help
+	  Enable support for /proc/sys/debug/exception-trace.
+
 config KALLSYMS
 	 bool "Load all symbols for debugging/ksymoops" if EXPERT
 	 default y
diff --git a/init/main.c b/init/main.c
index db34c0e..313360f 100644
--- a/init/main.c
+++ b/init/main.c
@@ -86,7 +86,6 @@
 extern void fork_init(unsigned long);
 extern void mca_init(void);
 extern void sbus_init(void);
-extern void prio_tree_init(void);
 extern void radix_tree_init(void);
 #ifndef CONFIG_DEBUG_RODATA
 static inline void mark_rodata_ro(void) { }
@@ -547,7 +546,6 @@
 	/* init some links before init_ISA_irqs() */
 	early_irq_init();
 	init_IRQ();
-	prio_tree_init();
 	init_timers();
 	hrtimers_init();
 	softirq_init();
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 6d255e5..6b97e24 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -142,7 +142,6 @@
 		leaf = kmalloc(sizeof(*leaf), GFP_ATOMIC);
 		if (!leaf)
 			return -ENOMEM;
-		rb_init_node(&leaf->rb_node);
 		INIT_LIST_HEAD(&leaf->msg_list);
 		info->qsize += sizeof(*leaf);
 	}
@@ -1013,7 +1012,6 @@
 
 	if (!info->node_cache && new_leaf) {
 		/* Save our speculative allocation into the cache */
-		rb_init_node(&new_leaf->rb_node);
 		INIT_LIST_HEAD(&new_leaf->msg_list);
 		info->node_cache = new_leaf;
 		info->qsize += sizeof(*new_leaf);
@@ -1121,7 +1119,6 @@
 
 	if (!info->node_cache && new_leaf) {
 		/* Save our speculative allocation into the cache */
-		rb_init_node(&new_leaf->rb_node);
 		INIT_LIST_HEAD(&new_leaf->msg_list);
 		info->node_cache = new_leaf;
 		info->qsize += sizeof(*new_leaf);
diff --git a/kernel/audit.c b/kernel/audit.c
index 4d0ceed..40414e9 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1440,6 +1440,8 @@
 
 	ab = audit_log_start(current->audit_context, GFP_KERNEL,
 			     AUDIT_ANOM_LINK);
+	if (!ab)
+		return;
 	audit_log_format(ab, "op=%s action=denied", operation);
 	audit_log_format(ab, " pid=%d comm=", current->pid);
 	audit_log_untrustedstring(ab, current->comm);
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 29e090c..f4a7756 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1151,7 +1151,6 @@
 	const struct cred *cred;
 	char name[sizeof(tsk->comm)];
 	struct mm_struct *mm = tsk->mm;
-	struct vm_area_struct *vma;
 	char *tty;
 
 	if (!ab)
@@ -1191,16 +1190,8 @@
 
 	if (mm) {
 		down_read(&mm->mmap_sem);
-		vma = mm->mmap;
-		while (vma) {
-			if ((vma->vm_flags & VM_EXECUTABLE) &&
-			    vma->vm_file) {
-				audit_log_d_path(ab, " exe=",
-						 &vma->vm_file->f_path);
-				break;
-			}
-			vma = vma->vm_next;
-		}
+		if (mm->exe_file)
+			audit_log_d_path(ab, " exe=", &mm->exe_file->f_path);
 		up_read(&mm->mmap_sem);
 	}
 	audit_log_task_context(ab);
diff --git a/kernel/cpu.c b/kernel/cpu.c
index f560598..42bd331 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -80,6 +80,10 @@
 	if (cpu_hotplug.active_writer == current)
 		return;
 	mutex_lock(&cpu_hotplug.lock);
+
+	if (WARN_ON(!cpu_hotplug.refcount))
+		cpu_hotplug.refcount++; /* try to fix things up */
+
 	if (!--cpu_hotplug.refcount && unlikely(cpu_hotplug.active_writer))
 		wake_up_process(cpu_hotplug.active_writer);
 	mutex_unlock(&cpu_hotplug.lock);
diff --git a/kernel/events/core.c b/kernel/events/core.c
index f16f3c5..cda3ebd 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -3671,7 +3671,7 @@
 		atomic_inc(&event->mmap_count);
 	mutex_unlock(&event->mmap_mutex);
 
-	vma->vm_flags |= VM_RESERVED;
+	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 	vma->vm_ops = &perf_mmap_vmops;
 
 	return ret;
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
index 912ef48..98256bc 100644
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -141,10 +141,14 @@
 	spinlock_t *ptl;
 	pte_t *ptep;
 	int err;
+	/* For mmu_notifiers */
+	const unsigned long mmun_start = addr;
+	const unsigned long mmun_end   = addr + PAGE_SIZE;
 
 	/* For try_to_free_swap() and munlock_vma_page() below */
 	lock_page(page);
 
+	mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
 	err = -EAGAIN;
 	ptep = page_check_address(page, mm, addr, &ptl, 0);
 	if (!ptep)
@@ -173,6 +177,7 @@
 
 	err = 0;
  unlock:
+	mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
 	unlock_page(page);
 	return err;
 }
@@ -735,7 +740,6 @@
 build_map_info(struct address_space *mapping, loff_t offset, bool is_register)
 {
 	unsigned long pgoff = offset >> PAGE_SHIFT;
-	struct prio_tree_iter iter;
 	struct vm_area_struct *vma;
 	struct map_info *curr = NULL;
 	struct map_info *prev = NULL;
@@ -744,7 +748,7 @@
 
  again:
 	mutex_lock(&mapping->i_mmap_mutex);
-	vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
+	vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) {
 		if (!valid_vma(vma, is_register))
 			continue;
 
diff --git a/kernel/fork.c b/kernel/fork.c
index a2b1efc..8b20ab7 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -423,7 +423,12 @@
 				mapping->i_mmap_writable++;
 			flush_dcache_mmap_lock(mapping);
 			/* insert tmp into the share list, just after mpnt */
-			vma_prio_tree_add(tmp, mpnt);
+			if (unlikely(tmp->vm_flags & VM_NONLINEAR))
+				vma_nonlinear_insert(tmp,
+						&mapping->i_mmap_nonlinear);
+			else
+				vma_interval_tree_insert_after(tmp, mpnt,
+							&mapping->i_mmap);
 			flush_dcache_mmap_unlock(mapping);
 			mutex_unlock(&mapping->i_mmap_mutex);
 		}
@@ -622,26 +627,6 @@
 }
 EXPORT_SYMBOL_GPL(mmput);
 
-/*
- * We added or removed a vma mapping the executable. The vmas are only mapped
- * during exec and are not mapped with the mmap system call.
- * Callers must hold down_write() on the mm's mmap_sem for these
- */
-void added_exe_file_vma(struct mm_struct *mm)
-{
-	mm->num_exe_file_vmas++;
-}
-
-void removed_exe_file_vma(struct mm_struct *mm)
-{
-	mm->num_exe_file_vmas--;
-	if ((mm->num_exe_file_vmas == 0) && mm->exe_file) {
-		fput(mm->exe_file);
-		mm->exe_file = NULL;
-	}
-
-}
-
 void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file)
 {
 	if (new_exe_file)
@@ -649,15 +634,13 @@
 	if (mm->exe_file)
 		fput(mm->exe_file);
 	mm->exe_file = new_exe_file;
-	mm->num_exe_file_vmas = 0;
 }
 
 struct file *get_mm_exe_file(struct mm_struct *mm)
 {
 	struct file *exe_file;
 
-	/* We need mmap_sem to protect against races with removal of
-	 * VM_EXECUTABLE vmas */
+	/* We need mmap_sem to protect against races with removal of exe_file */
 	down_read(&mm->mmap_sem);
 	exe_file = mm->exe_file;
 	if (exe_file)
@@ -1078,7 +1061,6 @@
 	init_rwsem(&sig->group_rwsem);
 #endif
 
-	sig->oom_adj = current->signal->oom_adj;
 	sig->oom_score_adj = current->signal->oom_score_adj;
 	sig->oom_score_adj_min = current->signal->oom_score_adj_min;
 
@@ -1602,7 +1584,7 @@
 	 * requested, no event is reported; otherwise, report if the event
 	 * for the type of forking is enabled.
 	 */
-	if (likely(user_mode(regs)) && !(clone_flags & CLONE_UNTRACED)) {
+	if (!(clone_flags & CLONE_UNTRACED) && likely(user_mode(regs))) {
 		if (clone_flags & CLONE_VFORK)
 			trace = PTRACE_EVENT_VFORK;
 		else if ((clone_flags & CSIGNAL) != SIGCHLD)
@@ -1652,6 +1634,17 @@
 	return nr;
 }
 
+#ifdef CONFIG_GENERIC_KERNEL_THREAD
+/*
+ * Create a kernel thread.
+ */
+pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
+{
+	return do_fork(flags|CLONE_VM|CLONE_UNTRACED, (unsigned long)fn, NULL,
+		(unsigned long)arg, NULL, NULL);
+}
+#endif
+
 #ifndef ARCH_MIN_MMSTRUCT_ALIGN
 #define ARCH_MIN_MMSTRUCT_ALIGN 0
 #endif
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 49a7772..4e69e24 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -148,7 +148,8 @@
  * @host_data: Controller private data pointer
  *
  * Allocates a legacy irq_domain if irq_base is positive or a linear
- * domain otherwise.
+ * domain otherwise. For the legacy domain, IRQ descriptors will also
+ * be allocated.
  *
  * This is intended to implement the expected behaviour for most
  * interrupt controllers which is that a linear mapping should
@@ -162,11 +163,33 @@
 					 const struct irq_domain_ops *ops,
 					 void *host_data)
 {
-	if (first_irq > 0)
-		return irq_domain_add_legacy(of_node, size, first_irq, 0,
+	if (first_irq > 0) {
+		int irq_base;
+
+		if (IS_ENABLED(CONFIG_SPARSE_IRQ)) {
+			/*
+			 * Set the descriptor allocator to search for a
+			 * 1-to-1 mapping, such as irq_alloc_desc_at().
+			 * Use of_node_to_nid() which is defined to
+			 * numa_node_id() on platforms that have no custom
+			 * implementation.
+			 */
+			irq_base = irq_alloc_descs(first_irq, first_irq, size,
+						   of_node_to_nid(of_node));
+			if (irq_base < 0) {
+				WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n",
+				     first_irq);
+				irq_base = first_irq;
+			}
+		} else
+			irq_base = first_irq;
+
+		return irq_domain_add_legacy(of_node, size, irq_base, 0,
 					     ops, host_data);
-	else
-		return irq_domain_add_linear(of_node, size, ops, host_data);
+	}
+
+	/* A linear domain is the default */
+	return irq_domain_add_linear(of_node, size, ops, host_data);
 }
 
 /**
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index c177472..bd7c394 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -505,7 +505,7 @@
 #ifdef CONFIG_SMP
 
 #ifndef tsk_is_polling
-#define tsk_is_polling(t) test_tsk_thread_flag(t, TIF_POLLING_NRFLAG)
+#define tsk_is_polling(t) 0
 #endif
 
 void resched_task(struct task_struct *p)
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index c2a2f80..26f65ea 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1549,8 +1549,7 @@
 };
 
 static struct ctl_table debug_table[] = {
-#if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) || \
-    defined(CONFIG_S390) || defined(CONFIG_TILE) || defined(CONFIG_ARM64)
+#ifdef CONFIG_SYSCTL_EXCEPTION_TRACE
 	{
 		.procname	= "exception-trace",
 		.data		= &show_unhandled_signals,
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 7fba3a9..28e9d6c9 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -450,12 +450,12 @@
 	  out which slabs are relevant to a particular load.
 	  Try running: slabinfo -DA
 
+config HAVE_DEBUG_KMEMLEAK
+	bool
+
 config DEBUG_KMEMLEAK
 	bool "Kernel memory leak detector"
-	depends on DEBUG_KERNEL && EXPERIMENTAL && \
-		(X86 || ARM || PPC || MIPS || S390 || SPARC64 || SUPERH || \
-		 MICROBLAZE || TILE || ARM64)
-
+	depends on DEBUG_KERNEL && EXPERIMENTAL && HAVE_DEBUG_KMEMLEAK
 	select DEBUG_FS
 	select STACKTRACE if STACKTRACE_SUPPORT
 	select KALLSYMS
@@ -751,12 +751,12 @@
 	  This options enables addition error checking for high memory systems.
 	  Disable for production systems.
 
+config HAVE_DEBUG_BUGVERBOSE
+	bool
+
 config DEBUG_BUGVERBOSE
 	bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EXPERT
-	depends on BUG
-	depends on ARM || AVR32 || M32R || M68K || SPARC32 || SPARC64 || \
-		   FRV || SUPERH || GENERIC_BUG || BLACKFIN || MN10300 || \
-		   TILE || ARM64
+	depends on BUG && (GENERIC_BUG || HAVE_DEBUG_BUGVERBOSE)
 	default y
 	help
 	  Say Y here to make BUG() panics output the file name and line number
@@ -798,6 +798,15 @@
 
 	  If unsure, say N.
 
+config DEBUG_VM_RB
+	bool "Debug VM red-black trees"
+	depends on DEBUG_VM
+	help
+	  Enable this to turn on more extended checks in the virtual-memory
+	  system that may impact performance.
+
+	  If unsure, say N.
+
 config DEBUG_VIRTUAL
 	bool "Debug VM translations"
 	depends on DEBUG_KERNEL && X86
@@ -1282,6 +1291,19 @@
 source mm/Kconfig.debug
 source kernel/trace/Kconfig
 
+config RBTREE_TEST
+	tristate "Red-Black tree test"
+	depends on m && DEBUG_KERNEL
+	help
+	  A benchmark measuring the performance of the rbtree library.
+	  Also includes rbtree invariant checks.
+
+config INTERVAL_TREE_TEST
+	tristate "Interval tree test"
+	depends on m && DEBUG_KERNEL
+	help
+	  A benchmark measuring the performance of the interval tree library
+
 config PROVIDE_OHCI1394_DMA_INIT
 	bool "Remote debugging over FireWire early on boot"
 	depends on PCI && X86
diff --git a/lib/Makefile b/lib/Makefile
index 42d283e..3128e35 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -9,7 +9,7 @@
 
 lib-y := ctype.o string.o vsprintf.o cmdline.o \
 	 rbtree.o radix-tree.o dump_stack.o timerqueue.o\
-	 idr.o int_sqrt.o extable.o prio_tree.o \
+	 idr.o int_sqrt.o extable.o \
 	 sha1.o md5.o irq_regs.o reciprocal_div.o argv_split.o \
 	 proportions.o flex_proportions.o prio_heap.o ratelimit.o show_mem.o \
 	 is_single_threaded.o plist.o decompress.o
@@ -140,6 +140,11 @@
 	$(eval CFLAGS_$(file) = -I$(src)/../scripts/dtc/libfdt))
 lib-$(CONFIG_LIBFDT) += $(libfdt_files)
 
+obj-$(CONFIG_RBTREE_TEST) += rbtree_test.o
+obj-$(CONFIG_INTERVAL_TREE_TEST) += interval_tree_test.o
+
+interval_tree_test-objs := interval_tree_test_main.o interval_tree.o
+
 hostprogs-y	:= gen_crc32table
 clean-files	:= crc32table.h
 
diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index 66ce414..b9087bf 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -120,11 +120,6 @@
 static const char *dir2name[4] = { "DMA_BIDIRECTIONAL", "DMA_TO_DEVICE",
 				   "DMA_FROM_DEVICE", "DMA_NONE" };
 
-/* little merge helper - remove it after the merge window */
-#ifndef BUS_NOTIFY_UNBOUND_DRIVER
-#define BUS_NOTIFY_UNBOUND_DRIVER 0x0005
-#endif
-
 /*
  * The access to some variables in this macro is racy. We can't use atomic_t
  * here because all these variables are exported to debugfs. Some of them even
diff --git a/lib/interval_tree.c b/lib/interval_tree.c
new file mode 100644
index 0000000..e6eb406
--- /dev/null
+++ b/lib/interval_tree.c
@@ -0,0 +1,10 @@
+#include <linux/init.h>
+#include <linux/interval_tree.h>
+#include <linux/interval_tree_generic.h>
+
+#define START(node) ((node)->start)
+#define LAST(node)  ((node)->last)
+
+INTERVAL_TREE_DEFINE(struct interval_tree_node, rb,
+		     unsigned long, __subtree_last,
+		     START, LAST,, interval_tree)
diff --git a/lib/interval_tree_test_main.c b/lib/interval_tree_test_main.c
new file mode 100644
index 0000000..b259039
--- /dev/null
+++ b/lib/interval_tree_test_main.c
@@ -0,0 +1,105 @@
+#include <linux/module.h>
+#include <linux/interval_tree.h>
+#include <linux/random.h>
+#include <asm/timex.h>
+
+#define NODES        100
+#define PERF_LOOPS   100000
+#define SEARCHES     100
+#define SEARCH_LOOPS 10000
+
+static struct rb_root root = RB_ROOT;
+static struct interval_tree_node nodes[NODES];
+static u32 queries[SEARCHES];
+
+static struct rnd_state rnd;
+
+static inline unsigned long
+search(unsigned long query, struct rb_root *root)
+{
+	struct interval_tree_node *node;
+	unsigned long results = 0;
+
+	for (node = interval_tree_iter_first(root, query, query); node;
+	     node = interval_tree_iter_next(node, query, query))
+		results++;
+	return results;
+}
+
+static void init(void)
+{
+	int i;
+	for (i = 0; i < NODES; i++) {
+		u32 a = prandom32(&rnd), b = prandom32(&rnd);
+		if (a <= b) {
+			nodes[i].start = a;
+			nodes[i].last = b;
+		} else {
+			nodes[i].start = b;
+			nodes[i].last = a;
+		}
+	}
+	for (i = 0; i < SEARCHES; i++)
+		queries[i] = prandom32(&rnd);
+}
+
+static int interval_tree_test_init(void)
+{
+	int i, j;
+	unsigned long results;
+	cycles_t time1, time2, time;
+
+	printk(KERN_ALERT "interval tree insert/remove");
+
+	prandom32_seed(&rnd, 3141592653589793238ULL);
+	init();
+
+	time1 = get_cycles();
+
+	for (i = 0; i < PERF_LOOPS; i++) {
+		for (j = 0; j < NODES; j++)
+			interval_tree_insert(nodes + j, &root);
+		for (j = 0; j < NODES; j++)
+			interval_tree_remove(nodes + j, &root);
+	}
+
+	time2 = get_cycles();
+	time = time2 - time1;
+
+	time = div_u64(time, PERF_LOOPS);
+	printk(" -> %llu cycles\n", (unsigned long long)time);
+
+	printk(KERN_ALERT "interval tree search");
+
+	for (j = 0; j < NODES; j++)
+		interval_tree_insert(nodes + j, &root);
+
+	time1 = get_cycles();
+
+	results = 0;
+	for (i = 0; i < SEARCH_LOOPS; i++)
+		for (j = 0; j < SEARCHES; j++)
+			results += search(queries[j], &root);
+
+	time2 = get_cycles();
+	time = time2 - time1;
+
+	time = div_u64(time, SEARCH_LOOPS);
+	results = div_u64(results, SEARCH_LOOPS);
+	printk(" -> %llu cycles (%lu results)\n",
+	       (unsigned long long)time, results);
+
+	return -EAGAIN; /* Fail will directly unload the module */
+}
+
+static void interval_tree_test_exit(void)
+{
+	printk(KERN_ALERT "test exit\n");
+}
+
+module_init(interval_tree_test_init)
+module_exit(interval_tree_test_exit)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Michel Lespinasse");
+MODULE_DESCRIPTION("Interval Tree test");
diff --git a/lib/kasprintf.c b/lib/kasprintf.c
index ae0de80..32f1215 100644
--- a/lib/kasprintf.c
+++ b/lib/kasprintf.c
@@ -21,7 +21,7 @@
 	len = vsnprintf(NULL, 0, fmt, aq);
 	va_end(aq);
 
-	p = kmalloc(len+1, gfp);
+	p = kmalloc_track_caller(len+1, gfp);
 	if (!p)
 		return NULL;
 
diff --git a/lib/prio_tree.c b/lib/prio_tree.c
deleted file mode 100644
index 8d443af..0000000
--- a/lib/prio_tree.c
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- * lib/prio_tree.c - priority search tree
- *
- * Copyright (C) 2004, Rajesh Venkatasubramanian <vrajesh@umich.edu>
- *
- * This file is released under the GPL v2.
- *
- * Based on the radix priority search tree proposed by Edward M. McCreight
- * SIAM Journal of Computing, vol. 14, no.2, pages 257-276, May 1985
- *
- * 02Feb2004	Initial version
- */
-
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/prio_tree.h>
-
-/*
- * A clever mix of heap and radix trees forms a radix priority search tree (PST)
- * which is useful for storing intervals, e.g, we can consider a vma as a closed
- * interval of file pages [offset_begin, offset_end], and store all vmas that
- * map a file in a PST. Then, using the PST, we can answer a stabbing query,
- * i.e., selecting a set of stored intervals (vmas) that overlap with (map) a
- * given input interval X (a set of consecutive file pages), in "O(log n + m)"
- * time where 'log n' is the height of the PST, and 'm' is the number of stored
- * intervals (vmas) that overlap (map) with the input interval X (the set of
- * consecutive file pages).
- *
- * In our implementation, we store closed intervals of the form [radix_index,
- * heap_index]. We assume that always radix_index <= heap_index. McCreight's PST
- * is designed for storing intervals with unique radix indices, i.e., each
- * interval have different radix_index. However, this limitation can be easily
- * overcome by using the size, i.e., heap_index - radix_index, as part of the
- * index, so we index the tree using [(radix_index,size), heap_index].
- *
- * When the above-mentioned indexing scheme is used, theoretically, in a 32 bit
- * machine, the maximum height of a PST can be 64. We can use a balanced version
- * of the priority search tree to optimize the tree height, but the balanced
- * tree proposed by McCreight is too complex and memory-hungry for our purpose.
- */
-
-/*
- * The following macros are used for implementing prio_tree for i_mmap
- */
-
-#define RADIX_INDEX(vma)  ((vma)->vm_pgoff)
-#define VMA_SIZE(vma)	  (((vma)->vm_end - (vma)->vm_start) >> PAGE_SHIFT)
-/* avoid overflow */
-#define HEAP_INDEX(vma)	  ((vma)->vm_pgoff + (VMA_SIZE(vma) - 1))
-
-
-static void get_index(const struct prio_tree_root *root,
-    const struct prio_tree_node *node,
-    unsigned long *radix, unsigned long *heap)
-{
-	if (root->raw) {
-		struct vm_area_struct *vma = prio_tree_entry(
-		    node, struct vm_area_struct, shared.prio_tree_node);
-
-		*radix = RADIX_INDEX(vma);
-		*heap = HEAP_INDEX(vma);
-	}
-	else {
-		*radix = node->start;
-		*heap = node->last;
-	}
-}
-
-static unsigned long index_bits_to_maxindex[BITS_PER_LONG];
-
-void __init prio_tree_init(void)
-{
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(index_bits_to_maxindex) - 1; i++)
-		index_bits_to_maxindex[i] = (1UL << (i + 1)) - 1;
-	index_bits_to_maxindex[ARRAY_SIZE(index_bits_to_maxindex) - 1] = ~0UL;
-}
-
-/*
- * Maximum heap_index that can be stored in a PST with index_bits bits
- */
-static inline unsigned long prio_tree_maxindex(unsigned int bits)
-{
-	return index_bits_to_maxindex[bits - 1];
-}
-
-static void prio_set_parent(struct prio_tree_node *parent,
-			    struct prio_tree_node *child, bool left)
-{
-	if (left)
-		parent->left = child;
-	else
-		parent->right = child;
-
-	child->parent = parent;
-}
-
-/*
- * Extend a priority search tree so that it can store a node with heap_index
- * max_heap_index. In the worst case, this algorithm takes O((log n)^2).
- * However, this function is used rarely and the common case performance is
- * not bad.
- */
-static struct prio_tree_node *prio_tree_expand(struct prio_tree_root *root,
-		struct prio_tree_node *node, unsigned long max_heap_index)
-{
-	struct prio_tree_node *prev;
-
-	if (max_heap_index > prio_tree_maxindex(root->index_bits))
-		root->index_bits++;
-
-	prev = node;
-	INIT_PRIO_TREE_NODE(node);
-
-	while (max_heap_index > prio_tree_maxindex(root->index_bits)) {
-		struct prio_tree_node *tmp = root->prio_tree_node;
-
-		root->index_bits++;
-
-		if (prio_tree_empty(root))
-			continue;
-
-		prio_tree_remove(root, root->prio_tree_node);
-		INIT_PRIO_TREE_NODE(tmp);
-
-		prio_set_parent(prev, tmp, true);
-		prev = tmp;
-	}
-
-	if (!prio_tree_empty(root))
-		prio_set_parent(prev, root->prio_tree_node, true);
-
-	root->prio_tree_node = node;
-	return node;
-}
-
-/*
- * Replace a prio_tree_node with a new node and return the old node
- */
-struct prio_tree_node *prio_tree_replace(struct prio_tree_root *root,
-		struct prio_tree_node *old, struct prio_tree_node *node)
-{
-	INIT_PRIO_TREE_NODE(node);
-
-	if (prio_tree_root(old)) {
-		BUG_ON(root->prio_tree_node != old);
-		/*
-		 * We can reduce root->index_bits here. However, it is complex
-		 * and does not help much to improve performance (IMO).
-		 */
-		root->prio_tree_node = node;
-	} else
-		prio_set_parent(old->parent, node, old->parent->left == old);
-
-	if (!prio_tree_left_empty(old))
-		prio_set_parent(node, old->left, true);
-
-	if (!prio_tree_right_empty(old))
-		prio_set_parent(node, old->right, false);
-
-	return old;
-}
-
-/*
- * Insert a prio_tree_node @node into a radix priority search tree @root. The
- * algorithm typically takes O(log n) time where 'log n' is the number of bits
- * required to represent the maximum heap_index. In the worst case, the algo
- * can take O((log n)^2) - check prio_tree_expand.
- *
- * If a prior node with same radix_index and heap_index is already found in
- * the tree, then returns the address of the prior node. Otherwise, inserts
- * @node into the tree and returns @node.
- */
-struct prio_tree_node *prio_tree_insert(struct prio_tree_root *root,
-		struct prio_tree_node *node)
-{
-	struct prio_tree_node *cur, *res = node;
-	unsigned long radix_index, heap_index;
-	unsigned long r_index, h_index, index, mask;
-	int size_flag = 0;
-
-	get_index(root, node, &radix_index, &heap_index);
-
-	if (prio_tree_empty(root) ||
-			heap_index > prio_tree_maxindex(root->index_bits))
-		return prio_tree_expand(root, node, heap_index);
-
-	cur = root->prio_tree_node;
-	mask = 1UL << (root->index_bits - 1);
-
-	while (mask) {
-		get_index(root, cur, &r_index, &h_index);
-
-		if (r_index == radix_index && h_index == heap_index)
-			return cur;
-
-                if (h_index < heap_index ||
-		    (h_index == heap_index && r_index > radix_index)) {
-			struct prio_tree_node *tmp = node;
-			node = prio_tree_replace(root, cur, node);
-			cur = tmp;
-			/* swap indices */
-			index = r_index;
-			r_index = radix_index;
-			radix_index = index;
-			index = h_index;
-			h_index = heap_index;
-			heap_index = index;
-		}
-
-		if (size_flag)
-			index = heap_index - radix_index;
-		else
-			index = radix_index;
-
-		if (index & mask) {
-			if (prio_tree_right_empty(cur)) {
-				INIT_PRIO_TREE_NODE(node);
-				prio_set_parent(cur, node, false);
-				return res;
-			} else
-				cur = cur->right;
-		} else {
-			if (prio_tree_left_empty(cur)) {
-				INIT_PRIO_TREE_NODE(node);
-				prio_set_parent(cur, node, true);
-				return res;
-			} else
-				cur = cur->left;
-		}
-
-		mask >>= 1;
-
-		if (!mask) {
-			mask = 1UL << (BITS_PER_LONG - 1);
-			size_flag = 1;
-		}
-	}
-	/* Should not reach here */
-	BUG();
-	return NULL;
-}
-
-/*
- * Remove a prio_tree_node @node from a radix priority search tree @root. The
- * algorithm takes O(log n) time where 'log n' is the number of bits required
- * to represent the maximum heap_index.
- */
-void prio_tree_remove(struct prio_tree_root *root, struct prio_tree_node *node)
-{
-	struct prio_tree_node *cur;
-	unsigned long r_index, h_index_right, h_index_left;
-
-	cur = node;
-
-	while (!prio_tree_left_empty(cur) || !prio_tree_right_empty(cur)) {
-		if (!prio_tree_left_empty(cur))
-			get_index(root, cur->left, &r_index, &h_index_left);
-		else {
-			cur = cur->right;
-			continue;
-		}
-
-		if (!prio_tree_right_empty(cur))
-			get_index(root, cur->right, &r_index, &h_index_right);
-		else {
-			cur = cur->left;
-			continue;
-		}
-
-		/* both h_index_left and h_index_right cannot be 0 */
-		if (h_index_left >= h_index_right)
-			cur = cur->left;
-		else
-			cur = cur->right;
-	}
-
-	if (prio_tree_root(cur)) {
-		BUG_ON(root->prio_tree_node != cur);
-		__INIT_PRIO_TREE_ROOT(root, root->raw);
-		return;
-	}
-
-	if (cur->parent->right == cur)
-		cur->parent->right = cur->parent;
-	else
-		cur->parent->left = cur->parent;
-
-	while (cur != node)
-		cur = prio_tree_replace(root, cur->parent, cur);
-}
-
-static void iter_walk_down(struct prio_tree_iter *iter)
-{
-	iter->mask >>= 1;
-	if (iter->mask) {
-		if (iter->size_level)
-			iter->size_level++;
-		return;
-	}
-
-	if (iter->size_level) {
-		BUG_ON(!prio_tree_left_empty(iter->cur));
-		BUG_ON(!prio_tree_right_empty(iter->cur));
-		iter->size_level++;
-		iter->mask = ULONG_MAX;
-	} else {
-		iter->size_level = 1;
-		iter->mask = 1UL << (BITS_PER_LONG - 1);
-	}
-}
-
-static void iter_walk_up(struct prio_tree_iter *iter)
-{
-	if (iter->mask == ULONG_MAX)
-		iter->mask = 1UL;
-	else if (iter->size_level == 1)
-		iter->mask = 1UL;
-	else
-		iter->mask <<= 1;
-	if (iter->size_level)
-		iter->size_level--;
-	if (!iter->size_level && (iter->value & iter->mask))
-		iter->value ^= iter->mask;
-}
-
-/*
- * Following functions help to enumerate all prio_tree_nodes in the tree that
- * overlap with the input interval X [radix_index, heap_index]. The enumeration
- * takes O(log n + m) time where 'log n' is the height of the tree (which is
- * proportional to # of bits required to represent the maximum heap_index) and
- * 'm' is the number of prio_tree_nodes that overlap the interval X.
- */
-
-static struct prio_tree_node *prio_tree_left(struct prio_tree_iter *iter,
-		unsigned long *r_index, unsigned long *h_index)
-{
-	if (prio_tree_left_empty(iter->cur))
-		return NULL;
-
-	get_index(iter->root, iter->cur->left, r_index, h_index);
-
-	if (iter->r_index <= *h_index) {
-		iter->cur = iter->cur->left;
-		iter_walk_down(iter);
-		return iter->cur;
-	}
-
-	return NULL;
-}
-
-static struct prio_tree_node *prio_tree_right(struct prio_tree_iter *iter,
-		unsigned long *r_index, unsigned long *h_index)
-{
-	unsigned long value;
-
-	if (prio_tree_right_empty(iter->cur))
-		return NULL;
-
-	if (iter->size_level)
-		value = iter->value;
-	else
-		value = iter->value | iter->mask;
-
-	if (iter->h_index < value)
-		return NULL;
-
-	get_index(iter->root, iter->cur->right, r_index, h_index);
-
-	if (iter->r_index <= *h_index) {
-		iter->cur = iter->cur->right;
-		iter_walk_down(iter);
-		return iter->cur;
-	}
-
-	return NULL;
-}
-
-static struct prio_tree_node *prio_tree_parent(struct prio_tree_iter *iter)
-{
-	iter->cur = iter->cur->parent;
-	iter_walk_up(iter);
-	return iter->cur;
-}
-
-static inline int overlap(struct prio_tree_iter *iter,
-		unsigned long r_index, unsigned long h_index)
-{
-	return iter->h_index >= r_index && iter->r_index <= h_index;
-}
-
-/*
- * prio_tree_first:
- *
- * Get the first prio_tree_node that overlaps with the interval [radix_index,
- * heap_index]. Note that always radix_index <= heap_index. We do a pre-order
- * traversal of the tree.
- */
-static struct prio_tree_node *prio_tree_first(struct prio_tree_iter *iter)
-{
-	struct prio_tree_root *root;
-	unsigned long r_index, h_index;
-
-	INIT_PRIO_TREE_ITER(iter);
-
-	root = iter->root;
-	if (prio_tree_empty(root))
-		return NULL;
-
-	get_index(root, root->prio_tree_node, &r_index, &h_index);
-
-	if (iter->r_index > h_index)
-		return NULL;
-
-	iter->mask = 1UL << (root->index_bits - 1);
-	iter->cur = root->prio_tree_node;
-
-	while (1) {
-		if (overlap(iter, r_index, h_index))
-			return iter->cur;
-
-		if (prio_tree_left(iter, &r_index, &h_index))
-			continue;
-
-		if (prio_tree_right(iter, &r_index, &h_index))
-			continue;
-
-		break;
-	}
-	return NULL;
-}
-
-/*
- * prio_tree_next:
- *
- * Get the next prio_tree_node that overlaps with the input interval in iter
- */
-struct prio_tree_node *prio_tree_next(struct prio_tree_iter *iter)
-{
-	unsigned long r_index, h_index;
-
-	if (iter->cur == NULL)
-		return prio_tree_first(iter);
-
-repeat:
-	while (prio_tree_left(iter, &r_index, &h_index))
-		if (overlap(iter, r_index, h_index))
-			return iter->cur;
-
-	while (!prio_tree_right(iter, &r_index, &h_index)) {
-	    	while (!prio_tree_root(iter->cur) &&
-				iter->cur->parent->right == iter->cur)
-			prio_tree_parent(iter);
-
-		if (prio_tree_root(iter->cur))
-			return NULL;
-
-		prio_tree_parent(iter);
-	}
-
-	if (overlap(iter, r_index, h_index))
-		return iter->cur;
-
-	goto repeat;
-}
diff --git a/lib/rbtree.c b/lib/rbtree.c
index d417556..4f56a11 100644
--- a/lib/rbtree.c
+++ b/lib/rbtree.c
@@ -2,7 +2,8 @@
   Red Black Trees
   (C) 1999  Andrea Arcangeli <andrea@suse.de>
   (C) 2002  David Woodhouse <dwmw2@infradead.org>
-  
+  (C) 2012  Michel Lespinasse <walken@google.com>
+
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
@@ -20,339 +21,382 @@
   linux/lib/rbtree.c
 */
 
-#include <linux/rbtree.h>
+#include <linux/rbtree_augmented.h>
 #include <linux/export.h>
 
-static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
+/*
+ * red-black trees properties:  http://en.wikipedia.org/wiki/Rbtree
+ *
+ *  1) A node is either red or black
+ *  2) The root is black
+ *  3) All leaves (NULL) are black
+ *  4) Both children of every red node are black
+ *  5) Every simple path from root to leaves contains the same number
+ *     of black nodes.
+ *
+ *  4 and 5 give the O(log n) guarantee, since 4 implies you cannot have two
+ *  consecutive red nodes in a path and every red node is therefore followed by
+ *  a black. So if B is the number of black nodes on every simple path (as per
+ *  5), then the longest possible path due to 4 is 2B.
+ *
+ *  We shall indicate color with case, where black nodes are uppercase and red
+ *  nodes will be lowercase. Unknown color nodes shall be drawn as red within
+ *  parentheses and have some accompanying text comment.
+ */
+
+static inline void rb_set_black(struct rb_node *rb)
 {
-	struct rb_node *right = node->rb_right;
-	struct rb_node *parent = rb_parent(node);
-
-	if ((node->rb_right = right->rb_left))
-		rb_set_parent(right->rb_left, node);
-	right->rb_left = node;
-
-	rb_set_parent(right, parent);
-
-	if (parent)
-	{
-		if (node == parent->rb_left)
-			parent->rb_left = right;
-		else
-			parent->rb_right = right;
-	}
-	else
-		root->rb_node = right;
-	rb_set_parent(node, right);
+	rb->__rb_parent_color |= RB_BLACK;
 }
 
-static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
+static inline struct rb_node *rb_red_parent(struct rb_node *red)
 {
-	struct rb_node *left = node->rb_left;
-	struct rb_node *parent = rb_parent(node);
-
-	if ((node->rb_left = left->rb_right))
-		rb_set_parent(left->rb_right, node);
-	left->rb_right = node;
-
-	rb_set_parent(left, parent);
-
-	if (parent)
-	{
-		if (node == parent->rb_right)
-			parent->rb_right = left;
-		else
-			parent->rb_left = left;
-	}
-	else
-		root->rb_node = left;
-	rb_set_parent(node, left);
+	return (struct rb_node *)red->__rb_parent_color;
 }
 
+/*
+ * Helper function for rotations:
+ * - old's parent and color get assigned to new
+ * - old gets assigned new as a parent and 'color' as a color.
+ */
+static inline void
+__rb_rotate_set_parents(struct rb_node *old, struct rb_node *new,
+			struct rb_root *root, int color)
+{
+	struct rb_node *parent = rb_parent(old);
+	new->__rb_parent_color = old->__rb_parent_color;
+	rb_set_parent_color(old, new, color);
+	__rb_change_child(old, new, parent, root);
+}
+
+static __always_inline void
+__rb_insert(struct rb_node *node, struct rb_root *root,
+	    void (*augment_rotate)(struct rb_node *old, struct rb_node *new))
+{
+	struct rb_node *parent = rb_red_parent(node), *gparent, *tmp;
+
+	while (true) {
+		/*
+		 * Loop invariant: node is red
+		 *
+		 * If there is a black parent, we are done.
+		 * Otherwise, take some corrective action as we don't
+		 * want a red root or two consecutive red nodes.
+		 */
+		if (!parent) {
+			rb_set_parent_color(node, NULL, RB_BLACK);
+			break;
+		} else if (rb_is_black(parent))
+			break;
+
+		gparent = rb_red_parent(parent);
+
+		tmp = gparent->rb_right;
+		if (parent != tmp) {	/* parent == gparent->rb_left */
+			if (tmp && rb_is_red(tmp)) {
+				/*
+				 * Case 1 - color flips
+				 *
+				 *       G            g
+				 *      / \          / \
+				 *     p   u  -->   P   U
+				 *    /            /
+				 *   n            N
+				 *
+				 * However, since g's parent might be red, and
+				 * 4) does not allow this, we need to recurse
+				 * at g.
+				 */
+				rb_set_parent_color(tmp, gparent, RB_BLACK);
+				rb_set_parent_color(parent, gparent, RB_BLACK);
+				node = gparent;
+				parent = rb_parent(node);
+				rb_set_parent_color(node, parent, RB_RED);
+				continue;
+			}
+
+			tmp = parent->rb_right;
+			if (node == tmp) {
+				/*
+				 * Case 2 - left rotate at parent
+				 *
+				 *      G             G
+				 *     / \           / \
+				 *    p   U  -->    n   U
+				 *     \           /
+				 *      n         p
+				 *
+				 * This still leaves us in violation of 4), the
+				 * continuation into Case 3 will fix that.
+				 */
+				parent->rb_right = tmp = node->rb_left;
+				node->rb_left = parent;
+				if (tmp)
+					rb_set_parent_color(tmp, parent,
+							    RB_BLACK);
+				rb_set_parent_color(parent, node, RB_RED);
+				augment_rotate(parent, node);
+				parent = node;
+				tmp = node->rb_right;
+			}
+
+			/*
+			 * Case 3 - right rotate at gparent
+			 *
+			 *        G           P
+			 *       / \         / \
+			 *      p   U  -->  n   g
+			 *     /                 \
+			 *    n                   U
+			 */
+			gparent->rb_left = tmp;  /* == parent->rb_right */
+			parent->rb_right = gparent;
+			if (tmp)
+				rb_set_parent_color(tmp, gparent, RB_BLACK);
+			__rb_rotate_set_parents(gparent, parent, root, RB_RED);
+			augment_rotate(gparent, parent);
+			break;
+		} else {
+			tmp = gparent->rb_left;
+			if (tmp && rb_is_red(tmp)) {
+				/* Case 1 - color flips */
+				rb_set_parent_color(tmp, gparent, RB_BLACK);
+				rb_set_parent_color(parent, gparent, RB_BLACK);
+				node = gparent;
+				parent = rb_parent(node);
+				rb_set_parent_color(node, parent, RB_RED);
+				continue;
+			}
+
+			tmp = parent->rb_left;
+			if (node == tmp) {
+				/* Case 2 - right rotate at parent */
+				parent->rb_left = tmp = node->rb_right;
+				node->rb_right = parent;
+				if (tmp)
+					rb_set_parent_color(tmp, parent,
+							    RB_BLACK);
+				rb_set_parent_color(parent, node, RB_RED);
+				augment_rotate(parent, node);
+				parent = node;
+				tmp = node->rb_left;
+			}
+
+			/* Case 3 - left rotate at gparent */
+			gparent->rb_right = tmp;  /* == parent->rb_left */
+			parent->rb_left = gparent;
+			if (tmp)
+				rb_set_parent_color(tmp, gparent, RB_BLACK);
+			__rb_rotate_set_parents(gparent, parent, root, RB_RED);
+			augment_rotate(gparent, parent);
+			break;
+		}
+	}
+}
+
+__always_inline void
+__rb_erase_color(struct rb_node *parent, struct rb_root *root,
+	void (*augment_rotate)(struct rb_node *old, struct rb_node *new))
+{
+	struct rb_node *node = NULL, *sibling, *tmp1, *tmp2;
+
+	while (true) {
+		/*
+		 * Loop invariants:
+		 * - node is black (or NULL on first iteration)
+		 * - node is not the root (parent is not NULL)
+		 * - All leaf paths going through parent and node have a
+		 *   black node count that is 1 lower than other leaf paths.
+		 */
+		sibling = parent->rb_right;
+		if (node != sibling) {	/* node == parent->rb_left */
+			if (rb_is_red(sibling)) {
+				/*
+				 * Case 1 - left rotate at parent
+				 *
+				 *     P               S
+				 *    / \             / \
+				 *   N   s    -->    p   Sr
+				 *      / \         / \
+				 *     Sl  Sr      N   Sl
+				 */
+				parent->rb_right = tmp1 = sibling->rb_left;
+				sibling->rb_left = parent;
+				rb_set_parent_color(tmp1, parent, RB_BLACK);
+				__rb_rotate_set_parents(parent, sibling, root,
+							RB_RED);
+				augment_rotate(parent, sibling);
+				sibling = tmp1;
+			}
+			tmp1 = sibling->rb_right;
+			if (!tmp1 || rb_is_black(tmp1)) {
+				tmp2 = sibling->rb_left;
+				if (!tmp2 || rb_is_black(tmp2)) {
+					/*
+					 * Case 2 - sibling color flip
+					 * (p could be either color here)
+					 *
+					 *    (p)           (p)
+					 *    / \           / \
+					 *   N   S    -->  N   s
+					 *      / \           / \
+					 *     Sl  Sr        Sl  Sr
+					 *
+					 * This leaves us violating 5) which
+					 * can be fixed by flipping p to black
+					 * if it was red, or by recursing at p.
+					 * p is red when coming from Case 1.
+					 */
+					rb_set_parent_color(sibling, parent,
+							    RB_RED);
+					if (rb_is_red(parent))
+						rb_set_black(parent);
+					else {
+						node = parent;
+						parent = rb_parent(node);
+						if (parent)
+							continue;
+					}
+					break;
+				}
+				/*
+				 * Case 3 - right rotate at sibling
+				 * (p could be either color here)
+				 *
+				 *   (p)           (p)
+				 *   / \           / \
+				 *  N   S    -->  N   Sl
+				 *     / \             \
+				 *    sl  Sr            s
+				 *                       \
+				 *                        Sr
+				 */
+				sibling->rb_left = tmp1 = tmp2->rb_right;
+				tmp2->rb_right = sibling;
+				parent->rb_right = tmp2;
+				if (tmp1)
+					rb_set_parent_color(tmp1, sibling,
+							    RB_BLACK);
+				augment_rotate(sibling, tmp2);
+				tmp1 = sibling;
+				sibling = tmp2;
+			}
+			/*
+			 * Case 4 - left rotate at parent + color flips
+			 * (p and sl could be either color here.
+			 *  After rotation, p becomes black, s acquires
+			 *  p's color, and sl keeps its color)
+			 *
+			 *      (p)             (s)
+			 *      / \             / \
+			 *     N   S     -->   P   Sr
+			 *        / \         / \
+			 *      (sl) sr      N  (sl)
+			 */
+			parent->rb_right = tmp2 = sibling->rb_left;
+			sibling->rb_left = parent;
+			rb_set_parent_color(tmp1, sibling, RB_BLACK);
+			if (tmp2)
+				rb_set_parent(tmp2, parent);
+			__rb_rotate_set_parents(parent, sibling, root,
+						RB_BLACK);
+			augment_rotate(parent, sibling);
+			break;
+		} else {
+			sibling = parent->rb_left;
+			if (rb_is_red(sibling)) {
+				/* Case 1 - right rotate at parent */
+				parent->rb_left = tmp1 = sibling->rb_right;
+				sibling->rb_right = parent;
+				rb_set_parent_color(tmp1, parent, RB_BLACK);
+				__rb_rotate_set_parents(parent, sibling, root,
+							RB_RED);
+				augment_rotate(parent, sibling);
+				sibling = tmp1;
+			}
+			tmp1 = sibling->rb_left;
+			if (!tmp1 || rb_is_black(tmp1)) {
+				tmp2 = sibling->rb_right;
+				if (!tmp2 || rb_is_black(tmp2)) {
+					/* Case 2 - sibling color flip */
+					rb_set_parent_color(sibling, parent,
+							    RB_RED);
+					if (rb_is_red(parent))
+						rb_set_black(parent);
+					else {
+						node = parent;
+						parent = rb_parent(node);
+						if (parent)
+							continue;
+					}
+					break;
+				}
+				/* Case 3 - right rotate at sibling */
+				sibling->rb_right = tmp1 = tmp2->rb_left;
+				tmp2->rb_left = sibling;
+				parent->rb_left = tmp2;
+				if (tmp1)
+					rb_set_parent_color(tmp1, sibling,
+							    RB_BLACK);
+				augment_rotate(sibling, tmp2);
+				tmp1 = sibling;
+				sibling = tmp2;
+			}
+			/* Case 4 - left rotate at parent + color flips */
+			parent->rb_left = tmp2 = sibling->rb_right;
+			sibling->rb_right = parent;
+			rb_set_parent_color(tmp1, sibling, RB_BLACK);
+			if (tmp2)
+				rb_set_parent(tmp2, parent);
+			__rb_rotate_set_parents(parent, sibling, root,
+						RB_BLACK);
+			augment_rotate(parent, sibling);
+			break;
+		}
+	}
+}
+EXPORT_SYMBOL(__rb_erase_color);
+
+/*
+ * Non-augmented rbtree manipulation functions.
+ *
+ * We use dummy augmented callbacks here, and have the compiler optimize them
+ * out of the rb_insert_color() and rb_erase() function definitions.
+ */
+
+static inline void dummy_propagate(struct rb_node *node, struct rb_node *stop) {}
+static inline void dummy_copy(struct rb_node *old, struct rb_node *new) {}
+static inline void dummy_rotate(struct rb_node *old, struct rb_node *new) {}
+
+static const struct rb_augment_callbacks dummy_callbacks = {
+	dummy_propagate, dummy_copy, dummy_rotate
+};
+
 void rb_insert_color(struct rb_node *node, struct rb_root *root)
 {
-	struct rb_node *parent, *gparent;
-
-	while ((parent = rb_parent(node)) && rb_is_red(parent))
-	{
-		gparent = rb_parent(parent);
-
-		if (parent == gparent->rb_left)
-		{
-			{
-				register struct rb_node *uncle = gparent->rb_right;
-				if (uncle && rb_is_red(uncle))
-				{
-					rb_set_black(uncle);
-					rb_set_black(parent);
-					rb_set_red(gparent);
-					node = gparent;
-					continue;
-				}
-			}
-
-			if (parent->rb_right == node)
-			{
-				register struct rb_node *tmp;
-				__rb_rotate_left(parent, root);
-				tmp = parent;
-				parent = node;
-				node = tmp;
-			}
-
-			rb_set_black(parent);
-			rb_set_red(gparent);
-			__rb_rotate_right(gparent, root);
-		} else {
-			{
-				register struct rb_node *uncle = gparent->rb_left;
-				if (uncle && rb_is_red(uncle))
-				{
-					rb_set_black(uncle);
-					rb_set_black(parent);
-					rb_set_red(gparent);
-					node = gparent;
-					continue;
-				}
-			}
-
-			if (parent->rb_left == node)
-			{
-				register struct rb_node *tmp;
-				__rb_rotate_right(parent, root);
-				tmp = parent;
-				parent = node;
-				node = tmp;
-			}
-
-			rb_set_black(parent);
-			rb_set_red(gparent);
-			__rb_rotate_left(gparent, root);
-		}
-	}
-
-	rb_set_black(root->rb_node);
+	__rb_insert(node, root, dummy_rotate);
 }
 EXPORT_SYMBOL(rb_insert_color);
 
-static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
-			     struct rb_root *root)
-{
-	struct rb_node *other;
-
-	while ((!node || rb_is_black(node)) && node != root->rb_node)
-	{
-		if (parent->rb_left == node)
-		{
-			other = parent->rb_right;
-			if (rb_is_red(other))
-			{
-				rb_set_black(other);
-				rb_set_red(parent);
-				__rb_rotate_left(parent, root);
-				other = parent->rb_right;
-			}
-			if ((!other->rb_left || rb_is_black(other->rb_left)) &&
-			    (!other->rb_right || rb_is_black(other->rb_right)))
-			{
-				rb_set_red(other);
-				node = parent;
-				parent = rb_parent(node);
-			}
-			else
-			{
-				if (!other->rb_right || rb_is_black(other->rb_right))
-				{
-					rb_set_black(other->rb_left);
-					rb_set_red(other);
-					__rb_rotate_right(other, root);
-					other = parent->rb_right;
-				}
-				rb_set_color(other, rb_color(parent));
-				rb_set_black(parent);
-				rb_set_black(other->rb_right);
-				__rb_rotate_left(parent, root);
-				node = root->rb_node;
-				break;
-			}
-		}
-		else
-		{
-			other = parent->rb_left;
-			if (rb_is_red(other))
-			{
-				rb_set_black(other);
-				rb_set_red(parent);
-				__rb_rotate_right(parent, root);
-				other = parent->rb_left;
-			}
-			if ((!other->rb_left || rb_is_black(other->rb_left)) &&
-			    (!other->rb_right || rb_is_black(other->rb_right)))
-			{
-				rb_set_red(other);
-				node = parent;
-				parent = rb_parent(node);
-			}
-			else
-			{
-				if (!other->rb_left || rb_is_black(other->rb_left))
-				{
-					rb_set_black(other->rb_right);
-					rb_set_red(other);
-					__rb_rotate_left(other, root);
-					other = parent->rb_left;
-				}
-				rb_set_color(other, rb_color(parent));
-				rb_set_black(parent);
-				rb_set_black(other->rb_left);
-				__rb_rotate_right(parent, root);
-				node = root->rb_node;
-				break;
-			}
-		}
-	}
-	if (node)
-		rb_set_black(node);
-}
-
 void rb_erase(struct rb_node *node, struct rb_root *root)
 {
-	struct rb_node *child, *parent;
-	int color;
-
-	if (!node->rb_left)
-		child = node->rb_right;
-	else if (!node->rb_right)
-		child = node->rb_left;
-	else
-	{
-		struct rb_node *old = node, *left;
-
-		node = node->rb_right;
-		while ((left = node->rb_left) != NULL)
-			node = left;
-
-		if (rb_parent(old)) {
-			if (rb_parent(old)->rb_left == old)
-				rb_parent(old)->rb_left = node;
-			else
-				rb_parent(old)->rb_right = node;
-		} else
-			root->rb_node = node;
-
-		child = node->rb_right;
-		parent = rb_parent(node);
-		color = rb_color(node);
-
-		if (parent == old) {
-			parent = node;
-		} else {
-			if (child)
-				rb_set_parent(child, parent);
-			parent->rb_left = child;
-
-			node->rb_right = old->rb_right;
-			rb_set_parent(old->rb_right, node);
-		}
-
-		node->rb_parent_color = old->rb_parent_color;
-		node->rb_left = old->rb_left;
-		rb_set_parent(old->rb_left, node);
-
-		goto color;
-	}
-
-	parent = rb_parent(node);
-	color = rb_color(node);
-
-	if (child)
-		rb_set_parent(child, parent);
-	if (parent)
-	{
-		if (parent->rb_left == node)
-			parent->rb_left = child;
-		else
-			parent->rb_right = child;
-	}
-	else
-		root->rb_node = child;
-
- color:
-	if (color == RB_BLACK)
-		__rb_erase_color(child, parent, root);
+	rb_erase_augmented(node, root, &dummy_callbacks);
 }
 EXPORT_SYMBOL(rb_erase);
 
-static void rb_augment_path(struct rb_node *node, rb_augment_f func, void *data)
-{
-	struct rb_node *parent;
-
-up:
-	func(node, data);
-	parent = rb_parent(node);
-	if (!parent)
-		return;
-
-	if (node == parent->rb_left && parent->rb_right)
-		func(parent->rb_right, data);
-	else if (parent->rb_left)
-		func(parent->rb_left, data);
-
-	node = parent;
-	goto up;
-}
-
 /*
- * after inserting @node into the tree, update the tree to account for
- * both the new entry and any damage done by rebalance
+ * Augmented rbtree manipulation functions.
+ *
+ * This instantiates the same __always_inline functions as in the non-augmented
+ * case, but this time with user-defined callbacks.
  */
-void rb_augment_insert(struct rb_node *node, rb_augment_f func, void *data)
+
+void __rb_insert_augmented(struct rb_node *node, struct rb_root *root,
+	void (*augment_rotate)(struct rb_node *old, struct rb_node *new))
 {
-	if (node->rb_left)
-		node = node->rb_left;
-	else if (node->rb_right)
-		node = node->rb_right;
-
-	rb_augment_path(node, func, data);
+	__rb_insert(node, root, augment_rotate);
 }
-EXPORT_SYMBOL(rb_augment_insert);
-
-/*
- * before removing the node, find the deepest node on the rebalance path
- * that will still be there after @node gets removed
- */
-struct rb_node *rb_augment_erase_begin(struct rb_node *node)
-{
-	struct rb_node *deepest;
-
-	if (!node->rb_right && !node->rb_left)
-		deepest = rb_parent(node);
-	else if (!node->rb_right)
-		deepest = node->rb_left;
-	else if (!node->rb_left)
-		deepest = node->rb_right;
-	else {
-		deepest = rb_next(node);
-		if (deepest->rb_right)
-			deepest = deepest->rb_right;
-		else if (rb_parent(deepest) != node)
-			deepest = rb_parent(deepest);
-	}
-
-	return deepest;
-}
-EXPORT_SYMBOL(rb_augment_erase_begin);
-
-/*
- * after removal, update the tree to account for the removed entry
- * and any rebalance damage.
- */
-void rb_augment_erase_end(struct rb_node *node, rb_augment_f func, void *data)
-{
-	if (node)
-		rb_augment_path(node, func, data);
-}
-EXPORT_SYMBOL(rb_augment_erase_end);
+EXPORT_SYMBOL(__rb_insert_augmented);
 
 /*
  * This function returns the first node (in sort order) of the tree.
@@ -387,11 +431,13 @@
 {
 	struct rb_node *parent;
 
-	if (rb_parent(node) == node)
+	if (RB_EMPTY_NODE(node))
 		return NULL;
 
-	/* If we have a right-hand child, go down and then left as far
-	   as we can. */
+	/*
+	 * If we have a right-hand child, go down and then left as far
+	 * as we can.
+	 */
 	if (node->rb_right) {
 		node = node->rb_right; 
 		while (node->rb_left)
@@ -399,12 +445,13 @@
 		return (struct rb_node *)node;
 	}
 
-	/* No right-hand children.  Everything down and left is
-	   smaller than us, so any 'next' node must be in the general
-	   direction of our parent. Go up the tree; any time the
-	   ancestor is a right-hand child of its parent, keep going
-	   up. First time it's a left-hand child of its parent, said
-	   parent is our 'next' node. */
+	/*
+	 * No right-hand children. Everything down and left is smaller than us,
+	 * so any 'next' node must be in the general direction of our parent.
+	 * Go up the tree; any time the ancestor is a right-hand child of its
+	 * parent, keep going up. First time it's a left-hand child of its
+	 * parent, said parent is our 'next' node.
+	 */
 	while ((parent = rb_parent(node)) && node == parent->rb_right)
 		node = parent;
 
@@ -416,11 +463,13 @@
 {
 	struct rb_node *parent;
 
-	if (rb_parent(node) == node)
+	if (RB_EMPTY_NODE(node))
 		return NULL;
 
-	/* If we have a left-hand child, go down and then right as far
-	   as we can. */
+	/*
+	 * If we have a left-hand child, go down and then right as far
+	 * as we can.
+	 */
 	if (node->rb_left) {
 		node = node->rb_left; 
 		while (node->rb_right)
@@ -428,8 +477,10 @@
 		return (struct rb_node *)node;
 	}
 
-	/* No left-hand children. Go up till we find an ancestor which
-	   is a right-hand child of its parent */
+	/*
+	 * No left-hand children. Go up till we find an ancestor which
+	 * is a right-hand child of its parent.
+	 */
 	while ((parent = rb_parent(node)) && node == parent->rb_left)
 		node = parent;
 
@@ -443,14 +494,7 @@
 	struct rb_node *parent = rb_parent(victim);
 
 	/* Set the surrounding nodes to point to the replacement */
-	if (parent) {
-		if (victim == parent->rb_left)
-			parent->rb_left = new;
-		else
-			parent->rb_right = new;
-	} else {
-		root->rb_node = new;
-	}
+	__rb_change_child(victim, new, parent, root);
 	if (victim->rb_left)
 		rb_set_parent(victim->rb_left, new);
 	if (victim->rb_right)
diff --git a/lib/rbtree_test.c b/lib/rbtree_test.c
new file mode 100644
index 0000000..268b239
--- /dev/null
+++ b/lib/rbtree_test.c
@@ -0,0 +1,234 @@
+#include <linux/module.h>
+#include <linux/rbtree_augmented.h>
+#include <linux/random.h>
+#include <asm/timex.h>
+
+#define NODES       100
+#define PERF_LOOPS  100000
+#define CHECK_LOOPS 100
+
+struct test_node {
+	struct rb_node rb;
+	u32 key;
+
+	/* following fields used for testing augmented rbtree functionality */
+	u32 val;
+	u32 augmented;
+};
+
+static struct rb_root root = RB_ROOT;
+static struct test_node nodes[NODES];
+
+static struct rnd_state rnd;
+
+static void insert(struct test_node *node, struct rb_root *root)
+{
+	struct rb_node **new = &root->rb_node, *parent = NULL;
+	u32 key = node->key;
+
+	while (*new) {
+		parent = *new;
+		if (key < rb_entry(parent, struct test_node, rb)->key)
+			new = &parent->rb_left;
+		else
+			new = &parent->rb_right;
+	}
+
+	rb_link_node(&node->rb, parent, new);
+	rb_insert_color(&node->rb, root);
+}
+
+static inline void erase(struct test_node *node, struct rb_root *root)
+{
+	rb_erase(&node->rb, root);
+}
+
+static inline u32 augment_recompute(struct test_node *node)
+{
+	u32 max = node->val, child_augmented;
+	if (node->rb.rb_left) {
+		child_augmented = rb_entry(node->rb.rb_left, struct test_node,
+					   rb)->augmented;
+		if (max < child_augmented)
+			max = child_augmented;
+	}
+	if (node->rb.rb_right) {
+		child_augmented = rb_entry(node->rb.rb_right, struct test_node,
+					   rb)->augmented;
+		if (max < child_augmented)
+			max = child_augmented;
+	}
+	return max;
+}
+
+RB_DECLARE_CALLBACKS(static, augment_callbacks, struct test_node, rb,
+		     u32, augmented, augment_recompute)
+
+static void insert_augmented(struct test_node *node, struct rb_root *root)
+{
+	struct rb_node **new = &root->rb_node, *rb_parent = NULL;
+	u32 key = node->key;
+	u32 val = node->val;
+	struct test_node *parent;
+
+	while (*new) {
+		rb_parent = *new;
+		parent = rb_entry(rb_parent, struct test_node, rb);
+		if (parent->augmented < val)
+			parent->augmented = val;
+		if (key < parent->key)
+			new = &parent->rb.rb_left;
+		else
+			new = &parent->rb.rb_right;
+	}
+
+	node->augmented = val;
+	rb_link_node(&node->rb, rb_parent, new);
+	rb_insert_augmented(&node->rb, root, &augment_callbacks);
+}
+
+static void erase_augmented(struct test_node *node, struct rb_root *root)
+{
+	rb_erase_augmented(&node->rb, root, &augment_callbacks);
+}
+
+static void init(void)
+{
+	int i;
+	for (i = 0; i < NODES; i++) {
+		nodes[i].key = prandom32(&rnd);
+		nodes[i].val = prandom32(&rnd);
+	}
+}
+
+static bool is_red(struct rb_node *rb)
+{
+	return !(rb->__rb_parent_color & 1);
+}
+
+static int black_path_count(struct rb_node *rb)
+{
+	int count;
+	for (count = 0; rb; rb = rb_parent(rb))
+		count += !is_red(rb);
+	return count;
+}
+
+static void check(int nr_nodes)
+{
+	struct rb_node *rb;
+	int count = 0;
+	int blacks;
+	u32 prev_key = 0;
+
+	for (rb = rb_first(&root); rb; rb = rb_next(rb)) {
+		struct test_node *node = rb_entry(rb, struct test_node, rb);
+		WARN_ON_ONCE(node->key < prev_key);
+		WARN_ON_ONCE(is_red(rb) &&
+			     (!rb_parent(rb) || is_red(rb_parent(rb))));
+		if (!count)
+			blacks = black_path_count(rb);
+		else
+			WARN_ON_ONCE((!rb->rb_left || !rb->rb_right) &&
+				     blacks != black_path_count(rb));
+		prev_key = node->key;
+		count++;
+	}
+	WARN_ON_ONCE(count != nr_nodes);
+}
+
+static void check_augmented(int nr_nodes)
+{
+	struct rb_node *rb;
+
+	check(nr_nodes);
+	for (rb = rb_first(&root); rb; rb = rb_next(rb)) {
+		struct test_node *node = rb_entry(rb, struct test_node, rb);
+		WARN_ON_ONCE(node->augmented != augment_recompute(node));
+	}
+}
+
+static int rbtree_test_init(void)
+{
+	int i, j;
+	cycles_t time1, time2, time;
+
+	printk(KERN_ALERT "rbtree testing");
+
+	prandom32_seed(&rnd, 3141592653589793238ULL);
+	init();
+
+	time1 = get_cycles();
+
+	for (i = 0; i < PERF_LOOPS; i++) {
+		for (j = 0; j < NODES; j++)
+			insert(nodes + j, &root);
+		for (j = 0; j < NODES; j++)
+			erase(nodes + j, &root);
+	}
+
+	time2 = get_cycles();
+	time = time2 - time1;
+
+	time = div_u64(time, PERF_LOOPS);
+	printk(" -> %llu cycles\n", (unsigned long long)time);
+
+	for (i = 0; i < CHECK_LOOPS; i++) {
+		init();
+		for (j = 0; j < NODES; j++) {
+			check(j);
+			insert(nodes + j, &root);
+		}
+		for (j = 0; j < NODES; j++) {
+			check(NODES - j);
+			erase(nodes + j, &root);
+		}
+		check(0);
+	}
+
+	printk(KERN_ALERT "augmented rbtree testing");
+
+	init();
+
+	time1 = get_cycles();
+
+	for (i = 0; i < PERF_LOOPS; i++) {
+		for (j = 0; j < NODES; j++)
+			insert_augmented(nodes + j, &root);
+		for (j = 0; j < NODES; j++)
+			erase_augmented(nodes + j, &root);
+	}
+
+	time2 = get_cycles();
+	time = time2 - time1;
+
+	time = div_u64(time, PERF_LOOPS);
+	printk(" -> %llu cycles\n", (unsigned long long)time);
+
+	for (i = 0; i < CHECK_LOOPS; i++) {
+		init();
+		for (j = 0; j < NODES; j++) {
+			check_augmented(j);
+			insert_augmented(nodes + j, &root);
+		}
+		for (j = 0; j < NODES; j++) {
+			check_augmented(NODES - j);
+			erase_augmented(nodes + j, &root);
+		}
+		check_augmented(0);
+	}
+
+	return -EAGAIN; /* Fail will directly unload the module */
+}
+
+static void rbtree_test_exit(void)
+{
+	printk(KERN_ALERT "test exit\n");
+}
+
+module_init(rbtree_test_init)
+module_exit(rbtree_test_exit)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Michel Lespinasse");
+MODULE_DESCRIPTION("Red Black Tree test");
diff --git a/lib/scatterlist.c b/lib/scatterlist.c
index e76d85c..3675452b 100644
--- a/lib/scatterlist.c
+++ b/lib/scatterlist.c
@@ -39,6 +39,25 @@
 EXPORT_SYMBOL(sg_next);
 
 /**
+ * sg_nents - return total count of entries in scatterlist
+ * @sg:		The scatterlist
+ *
+ * Description:
+ * Allows to know how many entries are in sg, taking into acount
+ * chaining as well
+ *
+ **/
+int sg_nents(struct scatterlist *sg)
+{
+	int nents;
+	for (nents = 0; sg; sg = sg_next(sg))
+		nents++;
+	return nents;
+}
+EXPORT_SYMBOL(sg_nents);
+
+
+/**
  * sg_last - return the last scatterlist entry in a list
  * @sgl:	First entry in the scatterlist
  * @nents:	Number of entries in the scatterlist
diff --git a/mm/Kconfig b/mm/Kconfig
index d5c8019..a3f8ddd 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -191,6 +191,7 @@
 # support for memory compaction
 config COMPACTION
 	bool "Allow for memory compaction"
+	def_bool y
 	select MIGRATION
 	depends on MMU
 	help
@@ -318,7 +319,7 @@
 
 config TRANSPARENT_HUGEPAGE
 	bool "Transparent Hugepage Support"
-	depends on X86 && MMU
+	depends on HAVE_ARCH_TRANSPARENT_HUGEPAGE
 	select COMPACTION
 	help
 	  Transparent Hugepages allows the kernel to use huge pages and
diff --git a/mm/Makefile b/mm/Makefile
index 92753e2..6b025f8 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -14,9 +14,9 @@
 obj-y			:= filemap.o mempool.o oom_kill.o fadvise.o \
 			   maccess.o page_alloc.o page-writeback.o \
 			   readahead.o swap.o truncate.o vmscan.o shmem.o \
-			   prio_tree.o util.o mmzone.o vmstat.o backing-dev.o \
+			   util.o mmzone.o vmstat.o backing-dev.o \
 			   mm_init.o mmu_context.o percpu.o slab_common.o \
-			   compaction.o $(mmu-y)
+			   compaction.o interval_tree.o $(mmu-y)
 
 obj-y += init-mm.o
 
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index b41823c..d3ca2b3 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -158,16 +158,16 @@
 				  const char *buf, size_t count)
 {
 	struct backing_dev_info *bdi = dev_get_drvdata(dev);
-	char *end;
 	unsigned long read_ahead_kb;
-	ssize_t ret = -EINVAL;
+	ssize_t ret;
 
-	read_ahead_kb = simple_strtoul(buf, &end, 10);
-	if (*buf && (end[0] == '\0' || (end[0] == '\n' && end[1] == '\0'))) {
-		bdi->ra_pages = read_ahead_kb >> (PAGE_SHIFT - 10);
-		ret = count;
-	}
-	return ret;
+	ret = kstrtoul(buf, 10, &read_ahead_kb);
+	if (ret < 0)
+		return ret;
+
+	bdi->ra_pages = read_ahead_kb >> (PAGE_SHIFT - 10);
+
+	return count;
 }
 
 #define K(pages) ((pages) << (PAGE_SHIFT - 10))
@@ -187,16 +187,17 @@
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct backing_dev_info *bdi = dev_get_drvdata(dev);
-	char *end;
 	unsigned int ratio;
-	ssize_t ret = -EINVAL;
+	ssize_t ret;
 
-	ratio = simple_strtoul(buf, &end, 10);
-	if (*buf && (end[0] == '\0' || (end[0] == '\n' && end[1] == '\0'))) {
-		ret = bdi_set_min_ratio(bdi, ratio);
-		if (!ret)
-			ret = count;
-	}
+	ret = kstrtouint(buf, 10, &ratio);
+	if (ret < 0)
+		return ret;
+
+	ret = bdi_set_min_ratio(bdi, ratio);
+	if (!ret)
+		ret = count;
+
 	return ret;
 }
 BDI_SHOW(min_ratio, bdi->min_ratio)
@@ -205,16 +206,17 @@
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct backing_dev_info *bdi = dev_get_drvdata(dev);
-	char *end;
 	unsigned int ratio;
-	ssize_t ret = -EINVAL;
+	ssize_t ret;
 
-	ratio = simple_strtoul(buf, &end, 10);
-	if (*buf && (end[0] == '\0' || (end[0] == '\n' && end[1] == '\0'))) {
-		ret = bdi_set_max_ratio(bdi, ratio);
-		if (!ret)
-			ret = count;
-	}
+	ret = kstrtouint(buf, 10, &ratio);
+	if (ret < 0)
+		return ret;
+
+	ret = bdi_set_max_ratio(bdi, ratio);
+	if (!ret)
+		ret = count;
+
 	return ret;
 }
 BDI_SHOW(max_ratio, bdi->max_ratio)
diff --git a/mm/bootmem.c b/mm/bootmem.c
index f468185..434be4a 100644
--- a/mm/bootmem.c
+++ b/mm/bootmem.c
@@ -198,6 +198,8 @@
 			int order = ilog2(BITS_PER_LONG);
 
 			__free_pages_bootmem(pfn_to_page(start), order);
+			fixup_zone_present_pages(page_to_nid(pfn_to_page(start)),
+					start, start + BITS_PER_LONG);
 			count += BITS_PER_LONG;
 			start += BITS_PER_LONG;
 		} else {
@@ -208,6 +210,9 @@
 				if (vec & 1) {
 					page = pfn_to_page(start + off);
 					__free_pages_bootmem(page, 0);
+					fixup_zone_present_pages(
+						page_to_nid(page),
+						start + off, start + off + 1);
 					count++;
 				}
 				vec >>= 1;
@@ -221,8 +226,11 @@
 	pages = bdata->node_low_pfn - bdata->node_min_pfn;
 	pages = bootmem_bootmap_pages(pages);
 	count += pages;
-	while (pages--)
+	while (pages--) {
+		fixup_zone_present_pages(page_to_nid(page),
+				page_to_pfn(page), page_to_pfn(page) + 1);
 		__free_pages_bootmem(page++, 0);
+	}
 
 	bdebug("nid=%td released=%lx\n", bdata - bootmem_node_data, count);
 
diff --git a/mm/compaction.c b/mm/compaction.c
index 7fcd3a5..2c4ce17 100644
--- a/mm/compaction.c
+++ b/mm/compaction.c
@@ -50,6 +50,111 @@
 	return is_migrate_cma(migratetype) || migratetype == MIGRATE_MOVABLE;
 }
 
+#ifdef CONFIG_COMPACTION
+/* Returns true if the pageblock should be scanned for pages to isolate. */
+static inline bool isolation_suitable(struct compact_control *cc,
+					struct page *page)
+{
+	if (cc->ignore_skip_hint)
+		return true;
+
+	return !get_pageblock_skip(page);
+}
+
+/*
+ * This function is called to clear all cached information on pageblocks that
+ * should be skipped for page isolation when the migrate and free page scanner
+ * meet.
+ */
+static void __reset_isolation_suitable(struct zone *zone)
+{
+	unsigned long start_pfn = zone->zone_start_pfn;
+	unsigned long end_pfn = zone->zone_start_pfn + zone->spanned_pages;
+	unsigned long pfn;
+
+	zone->compact_cached_migrate_pfn = start_pfn;
+	zone->compact_cached_free_pfn = end_pfn;
+	zone->compact_blockskip_flush = false;
+
+	/* Walk the zone and mark every pageblock as suitable for isolation */
+	for (pfn = start_pfn; pfn < end_pfn; pfn += pageblock_nr_pages) {
+		struct page *page;
+
+		cond_resched();
+
+		if (!pfn_valid(pfn))
+			continue;
+
+		page = pfn_to_page(pfn);
+		if (zone != page_zone(page))
+			continue;
+
+		clear_pageblock_skip(page);
+	}
+}
+
+void reset_isolation_suitable(pg_data_t *pgdat)
+{
+	int zoneid;
+
+	for (zoneid = 0; zoneid < MAX_NR_ZONES; zoneid++) {
+		struct zone *zone = &pgdat->node_zones[zoneid];
+		if (!populated_zone(zone))
+			continue;
+
+		/* Only flush if a full compaction finished recently */
+		if (zone->compact_blockskip_flush)
+			__reset_isolation_suitable(zone);
+	}
+}
+
+/*
+ * If no pages were isolated then mark this pageblock to be skipped in the
+ * future. The information is later cleared by __reset_isolation_suitable().
+ */
+static void update_pageblock_skip(struct compact_control *cc,
+			struct page *page, unsigned long nr_isolated,
+			bool migrate_scanner)
+{
+	struct zone *zone = cc->zone;
+	if (!page)
+		return;
+
+	if (!nr_isolated) {
+		unsigned long pfn = page_to_pfn(page);
+		set_pageblock_skip(page);
+
+		/* Update where compaction should restart */
+		if (migrate_scanner) {
+			if (!cc->finished_update_migrate &&
+			    pfn > zone->compact_cached_migrate_pfn)
+				zone->compact_cached_migrate_pfn = pfn;
+		} else {
+			if (!cc->finished_update_free &&
+			    pfn < zone->compact_cached_free_pfn)
+				zone->compact_cached_free_pfn = pfn;
+		}
+	}
+}
+#else
+static inline bool isolation_suitable(struct compact_control *cc,
+					struct page *page)
+{
+	return true;
+}
+
+static void update_pageblock_skip(struct compact_control *cc,
+			struct page *page, unsigned long nr_isolated,
+			bool migrate_scanner)
+{
+}
+#endif /* CONFIG_COMPACTION */
+
+static inline bool should_release_lock(spinlock_t *lock)
+{
+	return need_resched() || spin_is_contended(lock);
+}
+
 /*
  * Compaction requires the taking of some coarse locks that are potentially
  * very heavily contended. Check if the process needs to be scheduled or
@@ -62,7 +167,7 @@
 static bool compact_checklock_irqsave(spinlock_t *lock, unsigned long *flags,
 				      bool locked, struct compact_control *cc)
 {
-	if (need_resched() || spin_is_contended(lock)) {
+	if (should_release_lock(lock)) {
 		if (locked) {
 			spin_unlock_irqrestore(lock, *flags);
 			locked = false;
@@ -70,14 +175,11 @@
 
 		/* async aborts if taking too long or contended */
 		if (!cc->sync) {
-			if (cc->contended)
-				*cc->contended = true;
+			cc->contended = true;
 			return false;
 		}
 
 		cond_resched();
-		if (fatal_signal_pending(current))
-			return false;
 	}
 
 	if (!locked)
@@ -91,44 +193,139 @@
 	return compact_checklock_irqsave(lock, flags, false, cc);
 }
 
+/* Returns true if the page is within a block suitable for migration to */
+static bool suitable_migration_target(struct page *page)
+{
+	int migratetype = get_pageblock_migratetype(page);
+
+	/* Don't interfere with memory hot-remove or the min_free_kbytes blocks */
+	if (migratetype == MIGRATE_ISOLATE || migratetype == MIGRATE_RESERVE)
+		return false;
+
+	/* If the page is a large free page, then allow migration */
+	if (PageBuddy(page) && page_order(page) >= pageblock_order)
+		return true;
+
+	/* If the block is MIGRATE_MOVABLE or MIGRATE_CMA, allow migration */
+	if (migrate_async_suitable(migratetype))
+		return true;
+
+	/* Otherwise skip the block */
+	return false;
+}
+
+static void compact_capture_page(struct compact_control *cc)
+{
+	unsigned long flags;
+	int mtype, mtype_low, mtype_high;
+
+	if (!cc->page || *cc->page)
+		return;
+
+	/*
+	 * For MIGRATE_MOVABLE allocations we capture a suitable page ASAP
+	 * regardless of the migratetype of the freelist is is captured from.
+	 * This is fine because the order for a high-order MIGRATE_MOVABLE
+	 * allocation is typically at least a pageblock size and overall
+	 * fragmentation is not impaired. Other allocation types must
+	 * capture pages from their own migratelist because otherwise they
+	 * could pollute other pageblocks like MIGRATE_MOVABLE with
+	 * difficult to move pages and making fragmentation worse overall.
+	 */
+	if (cc->migratetype == MIGRATE_MOVABLE) {
+		mtype_low = 0;
+		mtype_high = MIGRATE_PCPTYPES;
+	} else {
+		mtype_low = cc->migratetype;
+		mtype_high = cc->migratetype + 1;
+	}
+
+	/* Speculatively examine the free lists without zone lock */
+	for (mtype = mtype_low; mtype < mtype_high; mtype++) {
+		int order;
+		for (order = cc->order; order < MAX_ORDER; order++) {
+			struct page *page;
+			struct free_area *area;
+			area = &(cc->zone->free_area[order]);
+			if (list_empty(&area->free_list[mtype]))
+				continue;
+
+			/* Take the lock and attempt capture of the page */
+			if (!compact_trylock_irqsave(&cc->zone->lock, &flags, cc))
+				return;
+			if (!list_empty(&area->free_list[mtype])) {
+				page = list_entry(area->free_list[mtype].next,
+							struct page, lru);
+				if (capture_free_page(page, cc->order, mtype)) {
+					spin_unlock_irqrestore(&cc->zone->lock,
+									flags);
+					*cc->page = page;
+					return;
+				}
+			}
+			spin_unlock_irqrestore(&cc->zone->lock, flags);
+		}
+	}
+}
+
 /*
  * Isolate free pages onto a private freelist. Caller must hold zone->lock.
  * If @strict is true, will abort returning 0 on any invalid PFNs or non-free
  * pages inside of the pageblock (even though it may still end up isolating
  * some pages).
  */
-static unsigned long isolate_freepages_block(unsigned long blockpfn,
+static unsigned long isolate_freepages_block(struct compact_control *cc,
+				unsigned long blockpfn,
 				unsigned long end_pfn,
 				struct list_head *freelist,
 				bool strict)
 {
 	int nr_scanned = 0, total_isolated = 0;
-	struct page *cursor;
+	struct page *cursor, *valid_page = NULL;
+	unsigned long nr_strict_required = end_pfn - blockpfn;
+	unsigned long flags;
+	bool locked = false;
 
 	cursor = pfn_to_page(blockpfn);
 
-	/* Isolate free pages. This assumes the block is valid */
+	/* Isolate free pages. */
 	for (; blockpfn < end_pfn; blockpfn++, cursor++) {
 		int isolated, i;
 		struct page *page = cursor;
 
-		if (!pfn_valid_within(blockpfn)) {
-			if (strict)
-				return 0;
-			continue;
-		}
 		nr_scanned++;
-
-		if (!PageBuddy(page)) {
-			if (strict)
-				return 0;
+		if (!pfn_valid_within(blockpfn))
 			continue;
-		}
+		if (!valid_page)
+			valid_page = page;
+		if (!PageBuddy(page))
+			continue;
+
+		/*
+		 * The zone lock must be held to isolate freepages.
+		 * Unfortunately this is a very coarse lock and can be
+		 * heavily contended if there are parallel allocations
+		 * or parallel compactions. For async compaction do not
+		 * spin on the lock and we acquire the lock as late as
+		 * possible.
+		 */
+		locked = compact_checklock_irqsave(&cc->zone->lock, &flags,
+								locked, cc);
+		if (!locked)
+			break;
+
+		/* Recheck this is a suitable migration target under lock */
+		if (!strict && !suitable_migration_target(page))
+			break;
+
+		/* Recheck this is a buddy page under lock */
+		if (!PageBuddy(page))
+			continue;
 
 		/* Found a free page, break it into order-0 pages */
 		isolated = split_free_page(page);
 		if (!isolated && strict)
-			return 0;
+			break;
 		total_isolated += isolated;
 		for (i = 0; i < isolated; i++) {
 			list_add(&page->lru, freelist);
@@ -143,6 +340,22 @@
 	}
 
 	trace_mm_compaction_isolate_freepages(nr_scanned, total_isolated);
+
+	/*
+	 * If strict isolation is requested by CMA then check that all the
+	 * pages requested were isolated. If there were any failures, 0 is
+	 * returned and CMA will fail.
+	 */
+	if (strict && nr_strict_required != total_isolated)
+		total_isolated = 0;
+
+	if (locked)
+		spin_unlock_irqrestore(&cc->zone->lock, flags);
+
+	/* Update the pageblock-skip if the whole pageblock was scanned */
+	if (blockpfn == end_pfn)
+		update_pageblock_skip(cc, valid_page, total_isolated, false);
+
 	return total_isolated;
 }
 
@@ -160,17 +373,14 @@
  * a free page).
  */
 unsigned long
-isolate_freepages_range(unsigned long start_pfn, unsigned long end_pfn)
+isolate_freepages_range(struct compact_control *cc,
+			unsigned long start_pfn, unsigned long end_pfn)
 {
-	unsigned long isolated, pfn, block_end_pfn, flags;
-	struct zone *zone = NULL;
+	unsigned long isolated, pfn, block_end_pfn;
 	LIST_HEAD(freelist);
 
-	if (pfn_valid(start_pfn))
-		zone = page_zone(pfn_to_page(start_pfn));
-
 	for (pfn = start_pfn; pfn < end_pfn; pfn += isolated) {
-		if (!pfn_valid(pfn) || zone != page_zone(pfn_to_page(pfn)))
+		if (!pfn_valid(pfn) || cc->zone != page_zone(pfn_to_page(pfn)))
 			break;
 
 		/*
@@ -180,10 +390,8 @@
 		block_end_pfn = ALIGN(pfn + 1, pageblock_nr_pages);
 		block_end_pfn = min(block_end_pfn, end_pfn);
 
-		spin_lock_irqsave(&zone->lock, flags);
-		isolated = isolate_freepages_block(pfn, block_end_pfn,
+		isolated = isolate_freepages_block(cc, pfn, block_end_pfn,
 						   &freelist, true);
-		spin_unlock_irqrestore(&zone->lock, flags);
 
 		/*
 		 * In strict mode, isolate_freepages_block() returns 0 if
@@ -253,6 +461,7 @@
  * @cc:		Compaction control structure.
  * @low_pfn:	The first PFN of the range.
  * @end_pfn:	The one-past-the-last PFN of the range.
+ * @unevictable: true if it allows to isolate unevictable pages
  *
  * Isolate all pages that can be migrated from the range specified by
  * [low_pfn, end_pfn).  Returns zero if there is a fatal signal
@@ -268,7 +477,7 @@
  */
 unsigned long
 isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
-			   unsigned long low_pfn, unsigned long end_pfn)
+		unsigned long low_pfn, unsigned long end_pfn, bool unevictable)
 {
 	unsigned long last_pageblock_nr = 0, pageblock_nr;
 	unsigned long nr_scanned = 0, nr_isolated = 0;
@@ -276,7 +485,8 @@
 	isolate_mode_t mode = 0;
 	struct lruvec *lruvec;
 	unsigned long flags;
-	bool locked;
+	bool locked = false;
+	struct page *page = NULL, *valid_page = NULL;
 
 	/*
 	 * Ensure that there are not too many pages isolated from the LRU
@@ -296,23 +506,15 @@
 
 	/* Time to isolate some pages for migration */
 	cond_resched();
-	spin_lock_irqsave(&zone->lru_lock, flags);
-	locked = true;
 	for (; low_pfn < end_pfn; low_pfn++) {
-		struct page *page;
-
 		/* give a chance to irqs before checking need_resched() */
-		if (!((low_pfn+1) % SWAP_CLUSTER_MAX)) {
-			spin_unlock_irqrestore(&zone->lru_lock, flags);
-			locked = false;
+		if (locked && !((low_pfn+1) % SWAP_CLUSTER_MAX)) {
+			if (should_release_lock(&zone->lru_lock)) {
+				spin_unlock_irqrestore(&zone->lru_lock, flags);
+				locked = false;
+			}
 		}
 
-		/* Check if it is ok to still hold the lock */
-		locked = compact_checklock_irqsave(&zone->lru_lock, &flags,
-								locked, cc);
-		if (!locked)
-			break;
-
 		/*
 		 * migrate_pfn does not necessarily start aligned to a
 		 * pageblock. Ensure that pfn_valid is called when moving
@@ -340,6 +542,14 @@
 		if (page_zone(page) != zone)
 			continue;
 
+		if (!valid_page)
+			valid_page = page;
+
+		/* If isolation recently failed, do not retry */
+		pageblock_nr = low_pfn >> pageblock_order;
+		if (!isolation_suitable(cc, page))
+			goto next_pageblock;
+
 		/* Skip if free */
 		if (PageBuddy(page))
 			continue;
@@ -349,24 +559,43 @@
 		 * migration is optimistic to see if the minimum amount of work
 		 * satisfies the allocation
 		 */
-		pageblock_nr = low_pfn >> pageblock_order;
 		if (!cc->sync && last_pageblock_nr != pageblock_nr &&
 		    !migrate_async_suitable(get_pageblock_migratetype(page))) {
-			low_pfn += pageblock_nr_pages;
-			low_pfn = ALIGN(low_pfn, pageblock_nr_pages) - 1;
-			last_pageblock_nr = pageblock_nr;
-			continue;
+			cc->finished_update_migrate = true;
+			goto next_pageblock;
 		}
 
+		/* Check may be lockless but that's ok as we recheck later */
 		if (!PageLRU(page))
 			continue;
 
 		/*
-		 * PageLRU is set, and lru_lock excludes isolation,
-		 * splitting and collapsing (collapsing has already
-		 * happened if PageLRU is set).
+		 * PageLRU is set. lru_lock normally excludes isolation
+		 * splitting and collapsing (collapsing has already happened
+		 * if PageLRU is set) but the lock is not necessarily taken
+		 * here and it is wasteful to take it just to check transhuge.
+		 * Check TransHuge without lock and skip the whole pageblock if
+		 * it's either a transhuge or hugetlbfs page, as calling
+		 * compound_order() without preventing THP from splitting the
+		 * page underneath us may return surprising results.
 		 */
 		if (PageTransHuge(page)) {
+			if (!locked)
+				goto next_pageblock;
+			low_pfn += (1 << compound_order(page)) - 1;
+			continue;
+		}
+
+		/* Check if it is ok to still hold the lock */
+		locked = compact_checklock_irqsave(&zone->lru_lock, &flags,
+								locked, cc);
+		if (!locked || fatal_signal_pending(current))
+			break;
+
+		/* Recheck PageLRU and PageTransHuge under lock */
+		if (!PageLRU(page))
+			continue;
+		if (PageTransHuge(page)) {
 			low_pfn += (1 << compound_order(page)) - 1;
 			continue;
 		}
@@ -374,6 +603,9 @@
 		if (!cc->sync)
 			mode |= ISOLATE_ASYNC_MIGRATE;
 
+		if (unevictable)
+			mode |= ISOLATE_UNEVICTABLE;
+
 		lruvec = mem_cgroup_page_lruvec(page, zone);
 
 		/* Try isolate the page */
@@ -383,6 +615,7 @@
 		VM_BUG_ON(PageTransCompound(page));
 
 		/* Successfully isolated */
+		cc->finished_update_migrate = true;
 		del_page_from_lru_list(page, lruvec, page_lru(page));
 		list_add(&page->lru, migratelist);
 		cc->nr_migratepages++;
@@ -393,6 +626,13 @@
 			++low_pfn;
 			break;
 		}
+
+		continue;
+
+next_pageblock:
+		low_pfn += pageblock_nr_pages;
+		low_pfn = ALIGN(low_pfn, pageblock_nr_pages) - 1;
+		last_pageblock_nr = pageblock_nr;
 	}
 
 	acct_isolated(zone, locked, cc);
@@ -400,6 +640,10 @@
 	if (locked)
 		spin_unlock_irqrestore(&zone->lru_lock, flags);
 
+	/* Update the pageblock-skip if the whole pageblock was scanned */
+	if (low_pfn == end_pfn)
+		update_pageblock_skip(cc, valid_page, nr_isolated, true);
+
 	trace_mm_compaction_isolate_migratepages(nr_scanned, nr_isolated);
 
 	return low_pfn;
@@ -407,43 +651,6 @@
 
 #endif /* CONFIG_COMPACTION || CONFIG_CMA */
 #ifdef CONFIG_COMPACTION
-
-/* Returns true if the page is within a block suitable for migration to */
-static bool suitable_migration_target(struct page *page)
-{
-
-	int migratetype = get_pageblock_migratetype(page);
-
-	/* Don't interfere with memory hot-remove or the min_free_kbytes blocks */
-	if (migratetype == MIGRATE_ISOLATE || migratetype == MIGRATE_RESERVE)
-		return false;
-
-	/* If the page is a large free page, then allow migration */
-	if (PageBuddy(page) && page_order(page) >= pageblock_order)
-		return true;
-
-	/* If the block is MIGRATE_MOVABLE or MIGRATE_CMA, allow migration */
-	if (migrate_async_suitable(migratetype))
-		return true;
-
-	/* Otherwise skip the block */
-	return false;
-}
-
-/*
- * Returns the start pfn of the last page block in a zone.  This is the starting
- * point for full compaction of a zone.  Compaction searches for free pages from
- * the end of each zone, while isolate_freepages_block scans forward inside each
- * page block.
- */
-static unsigned long start_free_pfn(struct zone *zone)
-{
-	unsigned long free_pfn;
-	free_pfn = zone->zone_start_pfn + zone->spanned_pages;
-	free_pfn &= ~(pageblock_nr_pages-1);
-	return free_pfn;
-}
-
 /*
  * Based on information in the current compact_control, find blocks
  * suitable for isolating free pages from and then isolate them.
@@ -453,7 +660,6 @@
 {
 	struct page *page;
 	unsigned long high_pfn, low_pfn, pfn, zone_end_pfn, end_pfn;
-	unsigned long flags;
 	int nr_freepages = cc->nr_freepages;
 	struct list_head *freelist = &cc->freepages;
 
@@ -501,30 +707,16 @@
 		if (!suitable_migration_target(page))
 			continue;
 
-		/*
-		 * Found a block suitable for isolating free pages from. Now
-		 * we disabled interrupts, double check things are ok and
-		 * isolate the pages. This is to minimise the time IRQs
-		 * are disabled
-		 */
-		isolated = 0;
+		/* If isolation recently failed, do not retry */
+		if (!isolation_suitable(cc, page))
+			continue;
 
-		/*
-		 * The zone lock must be held to isolate freepages. This
-		 * unfortunately this is a very coarse lock and can be
-		 * heavily contended if there are parallel allocations
-		 * or parallel compactions. For async compaction do not
-		 * spin on the lock
-		 */
-		if (!compact_trylock_irqsave(&zone->lock, &flags, cc))
-			break;
-		if (suitable_migration_target(page)) {
-			end_pfn = min(pfn + pageblock_nr_pages, zone_end_pfn);
-			isolated = isolate_freepages_block(pfn, end_pfn,
-							   freelist, false);
-			nr_freepages += isolated;
-		}
-		spin_unlock_irqrestore(&zone->lock, flags);
+		/* Found a block suitable for isolating free pages from */
+		isolated = 0;
+		end_pfn = min(pfn + pageblock_nr_pages, zone_end_pfn);
+		isolated = isolate_freepages_block(cc, pfn, end_pfn,
+						   freelist, false);
+		nr_freepages += isolated;
 
 		/*
 		 * Record the highest PFN we isolated pages from. When next
@@ -532,17 +724,8 @@
 		 * page migration may have returned some pages to the allocator
 		 */
 		if (isolated) {
+			cc->finished_update_free = true;
 			high_pfn = max(high_pfn, pfn);
-
-			/*
-			 * If the free scanner has wrapped, update
-			 * compact_cached_free_pfn to point to the highest
-			 * pageblock with free pages. This reduces excessive
-			 * scanning of full pageblocks near the end of the
-			 * zone
-			 */
-			if (cc->order > 0 && cc->wrapped)
-				zone->compact_cached_free_pfn = high_pfn;
 		}
 	}
 
@@ -551,11 +734,6 @@
 
 	cc->free_pfn = high_pfn;
 	cc->nr_freepages = nr_freepages;
-
-	/* If compact_cached_free_pfn is reset then set it now */
-	if (cc->order > 0 && !cc->wrapped &&
-			zone->compact_cached_free_pfn == start_free_pfn(zone))
-		zone->compact_cached_free_pfn = high_pfn;
 }
 
 /*
@@ -633,8 +811,8 @@
 	}
 
 	/* Perform the isolation */
-	low_pfn = isolate_migratepages_range(zone, cc, low_pfn, end_pfn);
-	if (!low_pfn)
+	low_pfn = isolate_migratepages_range(zone, cc, low_pfn, end_pfn, false);
+	if (!low_pfn || cc->contended)
 		return ISOLATE_ABORT;
 
 	cc->migrate_pfn = low_pfn;
@@ -645,34 +823,25 @@
 static int compact_finished(struct zone *zone,
 			    struct compact_control *cc)
 {
-	unsigned int order;
 	unsigned long watermark;
 
 	if (fatal_signal_pending(current))
 		return COMPACT_PARTIAL;
 
-	/*
-	 * A full (order == -1) compaction run starts at the beginning and
-	 * end of a zone; it completes when the migrate and free scanner meet.
-	 * A partial (order > 0) compaction can start with the free scanner
-	 * at a random point in the zone, and may have to restart.
-	 */
+	/* Compaction run completes if the migrate and free scanner meet */
 	if (cc->free_pfn <= cc->migrate_pfn) {
-		if (cc->order > 0 && !cc->wrapped) {
-			/* We started partway through; restart at the end. */
-			unsigned long free_pfn = start_free_pfn(zone);
-			zone->compact_cached_free_pfn = free_pfn;
-			cc->free_pfn = free_pfn;
-			cc->wrapped = 1;
-			return COMPACT_CONTINUE;
-		}
+		/*
+		 * Mark that the PG_migrate_skip information should be cleared
+		 * by kswapd when it goes to sleep. kswapd does not set the
+		 * flag itself as the decision to be clear should be directly
+		 * based on an allocation request.
+		 */
+		if (!current_is_kswapd())
+			zone->compact_blockskip_flush = true;
+
 		return COMPACT_COMPLETE;
 	}
 
-	/* We wrapped around and ended up where we started. */
-	if (cc->wrapped && cc->free_pfn <= cc->start_free_pfn)
-		return COMPACT_COMPLETE;
-
 	/*
 	 * order == -1 is expected when compacting via
 	 * /proc/sys/vm/compact_memory
@@ -688,14 +857,22 @@
 		return COMPACT_CONTINUE;
 
 	/* Direct compactor: Is a suitable page free? */
-	for (order = cc->order; order < MAX_ORDER; order++) {
-		/* Job done if page is free of the right migratetype */
-		if (!list_empty(&zone->free_area[order].free_list[cc->migratetype]))
+	if (cc->page) {
+		/* Was a suitable page captured? */
+		if (*cc->page)
 			return COMPACT_PARTIAL;
+	} else {
+		unsigned int order;
+		for (order = cc->order; order < MAX_ORDER; order++) {
+			struct free_area *area = &zone->free_area[cc->order];
+			/* Job done if page is free of the right migratetype */
+			if (!list_empty(&area->free_list[cc->migratetype]))
+				return COMPACT_PARTIAL;
 
-		/* Job done if allocation would set block type */
-		if (order >= pageblock_order && zone->free_area[order].nr_free)
-			return COMPACT_PARTIAL;
+			/* Job done if allocation would set block type */
+			if (cc->order >= pageblock_order && area->nr_free)
+				return COMPACT_PARTIAL;
+		}
 	}
 
 	return COMPACT_CONTINUE;
@@ -754,6 +931,8 @@
 static int compact_zone(struct zone *zone, struct compact_control *cc)
 {
 	int ret;
+	unsigned long start_pfn = zone->zone_start_pfn;
+	unsigned long end_pfn = zone->zone_start_pfn + zone->spanned_pages;
 
 	ret = compaction_suitable(zone, cc->order);
 	switch (ret) {
@@ -766,17 +945,29 @@
 		;
 	}
 
-	/* Setup to move all movable pages to the end of the zone */
-	cc->migrate_pfn = zone->zone_start_pfn;
-
-	if (cc->order > 0) {
-		/* Incremental compaction. Start where the last one stopped. */
-		cc->free_pfn = zone->compact_cached_free_pfn;
-		cc->start_free_pfn = cc->free_pfn;
-	} else {
-		/* Order == -1 starts at the end of the zone. */
-		cc->free_pfn = start_free_pfn(zone);
+	/*
+	 * Setup to move all movable pages to the end of the zone. Used cached
+	 * information on where the scanners should start but check that it
+	 * is initialised by ensuring the values are within zone boundaries.
+	 */
+	cc->migrate_pfn = zone->compact_cached_migrate_pfn;
+	cc->free_pfn = zone->compact_cached_free_pfn;
+	if (cc->free_pfn < start_pfn || cc->free_pfn > end_pfn) {
+		cc->free_pfn = end_pfn & ~(pageblock_nr_pages-1);
+		zone->compact_cached_free_pfn = cc->free_pfn;
 	}
+	if (cc->migrate_pfn < start_pfn || cc->migrate_pfn > end_pfn) {
+		cc->migrate_pfn = start_pfn;
+		zone->compact_cached_migrate_pfn = cc->migrate_pfn;
+	}
+
+	/*
+	 * Clear pageblock skip if there were failures recently and compaction
+	 * is about to be retried after being deferred. kswapd does not do
+	 * this reset as it'll reset the cached information when going to sleep.
+	 */
+	if (compaction_restarting(zone, cc->order) && !current_is_kswapd())
+		__reset_isolation_suitable(zone);
 
 	migrate_prep_local();
 
@@ -787,6 +978,8 @@
 		switch (isolate_migratepages(zone, cc)) {
 		case ISOLATE_ABORT:
 			ret = COMPACT_PARTIAL;
+			putback_lru_pages(&cc->migratepages);
+			cc->nr_migratepages = 0;
 			goto out;
 		case ISOLATE_NONE:
 			continue;
@@ -817,6 +1010,9 @@
 				goto out;
 			}
 		}
+
+		/* Capture a page now if it is a suitable size */
+		compact_capture_page(cc);
 	}
 
 out:
@@ -829,8 +1025,10 @@
 
 static unsigned long compact_zone_order(struct zone *zone,
 				 int order, gfp_t gfp_mask,
-				 bool sync, bool *contended)
+				 bool sync, bool *contended,
+				 struct page **page)
 {
+	unsigned long ret;
 	struct compact_control cc = {
 		.nr_freepages = 0,
 		.nr_migratepages = 0,
@@ -838,12 +1036,18 @@
 		.migratetype = allocflags_to_migratetype(gfp_mask),
 		.zone = zone,
 		.sync = sync,
-		.contended = contended,
+		.page = page,
 	};
 	INIT_LIST_HEAD(&cc.freepages);
 	INIT_LIST_HEAD(&cc.migratepages);
 
-	return compact_zone(zone, &cc);
+	ret = compact_zone(zone, &cc);
+
+	VM_BUG_ON(!list_empty(&cc.freepages));
+	VM_BUG_ON(!list_empty(&cc.migratepages));
+
+	*contended = cc.contended;
+	return ret;
 }
 
 int sysctl_extfrag_threshold = 500;
@@ -855,12 +1059,14 @@
  * @gfp_mask: The GFP mask of the current allocation
  * @nodemask: The allowed nodes to allocate from
  * @sync: Whether migration is synchronous or not
+ * @contended: Return value that is true if compaction was aborted due to lock contention
+ * @page: Optionally capture a free page of the requested order during compaction
  *
  * This is the main entry point for direct page compaction.
  */
 unsigned long try_to_compact_pages(struct zonelist *zonelist,
 			int order, gfp_t gfp_mask, nodemask_t *nodemask,
-			bool sync, bool *contended)
+			bool sync, bool *contended, struct page **page)
 {
 	enum zone_type high_zoneidx = gfp_zone(gfp_mask);
 	int may_enter_fs = gfp_mask & __GFP_FS;
@@ -868,28 +1074,30 @@
 	struct zoneref *z;
 	struct zone *zone;
 	int rc = COMPACT_SKIPPED;
+	int alloc_flags = 0;
 
-	/*
-	 * Check whether it is worth even starting compaction. The order check is
-	 * made because an assumption is made that the page allocator can satisfy
-	 * the "cheaper" orders without taking special steps
-	 */
+	/* Check if the GFP flags allow compaction */
 	if (!order || !may_enter_fs || !may_perform_io)
 		return rc;
 
 	count_vm_event(COMPACTSTALL);
 
+#ifdef CONFIG_CMA
+	if (allocflags_to_migratetype(gfp_mask) == MIGRATE_MOVABLE)
+		alloc_flags |= ALLOC_CMA;
+#endif
 	/* Compact each zone in the list */
 	for_each_zone_zonelist_nodemask(zone, z, zonelist, high_zoneidx,
 								nodemask) {
 		int status;
 
 		status = compact_zone_order(zone, order, gfp_mask, sync,
-						contended);
+						contended, page);
 		rc = max(status, rc);
 
 		/* If a normal allocation would succeed, stop compacting */
-		if (zone_watermark_ok(zone, order, low_wmark_pages(zone), 0, 0))
+		if (zone_watermark_ok(zone, order, low_wmark_pages(zone), 0,
+				      alloc_flags))
 			break;
 	}
 
@@ -940,6 +1148,7 @@
 	struct compact_control cc = {
 		.order = order,
 		.sync = false,
+		.page = NULL,
 	};
 
 	return __compact_pgdat(pgdat, &cc);
@@ -950,6 +1159,7 @@
 	struct compact_control cc = {
 		.order = -1,
 		.sync = true,
+		.page = NULL,
 	};
 
 	return __compact_pgdat(NODE_DATA(nid), &cc);
diff --git a/mm/filemap.c b/mm/filemap.c
index 3843445..83efee7 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1607,13 +1607,13 @@
 	 * Do we have something in the page cache already?
 	 */
 	page = find_get_page(mapping, offset);
-	if (likely(page)) {
+	if (likely(page) && !(vmf->flags & FAULT_FLAG_TRIED)) {
 		/*
 		 * We found the page, so try async readahead before
 		 * waiting for the lock.
 		 */
 		do_async_mmap_readahead(vma, ra, file, page, offset);
-	} else {
+	} else if (!page) {
 		/* No page in the page cache at all */
 		do_sync_mmap_readahead(vma, ra, file, offset);
 		count_vm_event(PGMAJFAULT);
@@ -1737,6 +1737,7 @@
 const struct vm_operations_struct generic_file_vm_ops = {
 	.fault		= filemap_fault,
 	.page_mkwrite	= filemap_page_mkwrite,
+	.remap_pages	= generic_file_remap_pages,
 };
 
 /* This is used for a general mmap of a disk file */
@@ -1749,7 +1750,6 @@
 		return -ENOEXEC;
 	file_accessed(file);
 	vma->vm_ops = &generic_file_vm_ops;
-	vma->vm_flags |= VM_CAN_NONLINEAR;
 	return 0;
 }
 
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c
index 13e013b..a912da6 100644
--- a/mm/filemap_xip.c
+++ b/mm/filemap_xip.c
@@ -167,7 +167,6 @@
 {
 	struct vm_area_struct *vma;
 	struct mm_struct *mm;
-	struct prio_tree_iter iter;
 	unsigned long address;
 	pte_t *pte;
 	pte_t pteval;
@@ -184,7 +183,7 @@
 
 retry:
 	mutex_lock(&mapping->i_mmap_mutex);
-	vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
+	vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) {
 		mm = vma->vm_mm;
 		address = vma->vm_start +
 			((pgoff - vma->vm_pgoff) << PAGE_SHIFT);
@@ -193,11 +192,13 @@
 		if (pte) {
 			/* Nuke the page table entry. */
 			flush_cache_page(vma, address, pte_pfn(*pte));
-			pteval = ptep_clear_flush_notify(vma, address, pte);
+			pteval = ptep_clear_flush(vma, address, pte);
 			page_remove_rmap(page);
 			dec_mm_counter(mm, MM_FILEPAGES);
 			BUG_ON(pte_dirty(pteval));
 			pte_unmap_unlock(pte, ptl);
+			/* must invalidate_page _before_ freeing the page */
+			mmu_notifier_invalidate_page(mm, address);
 			page_cache_release(page);
 		}
 	}
@@ -305,6 +306,7 @@
 static const struct vm_operations_struct xip_file_vm_ops = {
 	.fault	= xip_file_fault,
 	.page_mkwrite	= filemap_page_mkwrite,
+	.remap_pages = generic_file_remap_pages,
 };
 
 int xip_file_mmap(struct file * file, struct vm_area_struct * vma)
@@ -313,7 +315,7 @@
 
 	file_accessed(file);
 	vma->vm_ops = &xip_file_vm_ops;
-	vma->vm_flags |= VM_CAN_NONLINEAR | VM_MIXEDMAP;
+	vma->vm_flags |= VM_MIXEDMAP;
 	return 0;
 }
 EXPORT_SYMBOL_GPL(xip_file_mmap);
diff --git a/mm/fremap.c b/mm/fremap.c
index 048659c..3899a86 100644
--- a/mm/fremap.c
+++ b/mm/fremap.c
@@ -5,6 +5,7 @@
  *
  * started by Ingo Molnar, Copyright (C) 2002, 2003
  */
+#include <linux/export.h>
 #include <linux/backing-dev.h>
 #include <linux/mm.h>
 #include <linux/swap.h>
@@ -80,9 +81,10 @@
 	return err;
 }
 
-static int populate_range(struct mm_struct *mm, struct vm_area_struct *vma,
-			unsigned long addr, unsigned long size, pgoff_t pgoff)
+int generic_file_remap_pages(struct vm_area_struct *vma, unsigned long addr,
+			     unsigned long size, pgoff_t pgoff)
 {
+	struct mm_struct *mm = vma->vm_mm;
 	int err;
 
 	do {
@@ -95,9 +97,9 @@
 		pgoff++;
 	} while (size);
 
-        return 0;
-
+	return 0;
 }
+EXPORT_SYMBOL(generic_file_remap_pages);
 
 /**
  * sys_remap_file_pages - remap arbitrary pages of an existing VM_SHARED vma
@@ -167,7 +169,7 @@
 	if (vma->vm_private_data && !(vma->vm_flags & VM_NONLINEAR))
 		goto out;
 
-	if (!(vma->vm_flags & VM_CAN_NONLINEAR))
+	if (!vma->vm_ops->remap_pages)
 		goto out;
 
 	if (start < vma->vm_start || start + size > vma->vm_end)
@@ -212,7 +214,7 @@
 		mutex_lock(&mapping->i_mmap_mutex);
 		flush_dcache_mmap_lock(mapping);
 		vma->vm_flags |= VM_NONLINEAR;
-		vma_prio_tree_remove(vma, &mapping->i_mmap);
+		vma_interval_tree_remove(vma, &mapping->i_mmap);
 		vma_nonlinear_insert(vma, &mapping->i_mmap_nonlinear);
 		flush_dcache_mmap_unlock(mapping);
 		mutex_unlock(&mapping->i_mmap_mutex);
@@ -228,7 +230,7 @@
 	}
 
 	mmu_notifier_invalidate_range_start(mm, start, start + size);
-	err = populate_range(mm, vma, start, size, pgoff);
+	err = vma->vm_ops->remap_pages(vma, start, size, pgoff);
 	mmu_notifier_invalidate_range_end(mm, start, start + size);
 	if (!err && !(flags & MAP_NONBLOCK)) {
 		if (vma->vm_flags & VM_LOCKED) {
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 141dbb6..a863af2 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -102,10 +102,7 @@
 	unsigned long recommended_min;
 	extern int min_free_kbytes;
 
-	if (!test_bit(TRANSPARENT_HUGEPAGE_FLAG,
-		      &transparent_hugepage_flags) &&
-	    !test_bit(TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG,
-		      &transparent_hugepage_flags))
+	if (!khugepaged_enabled())
 		return 0;
 
 	for_each_populated_zone(zone)
@@ -139,12 +136,6 @@
 {
 	int err = 0;
 	if (khugepaged_enabled()) {
-		int wakeup;
-		if (unlikely(!mm_slot_cache || !mm_slots_hash)) {
-			err = -ENOMEM;
-			goto out;
-		}
-		mutex_lock(&khugepaged_mutex);
 		if (!khugepaged_thread)
 			khugepaged_thread = kthread_run(khugepaged, NULL,
 							"khugepaged");
@@ -154,16 +145,16 @@
 			err = PTR_ERR(khugepaged_thread);
 			khugepaged_thread = NULL;
 		}
-		wakeup = !list_empty(&khugepaged_scan.mm_head);
-		mutex_unlock(&khugepaged_mutex);
-		if (wakeup)
+
+		if (!list_empty(&khugepaged_scan.mm_head))
 			wake_up_interruptible(&khugepaged_wait);
 
 		set_recommended_min_free_kbytes();
-	} else
-		/* wakeup to exit */
-		wake_up_interruptible(&khugepaged_wait);
-out:
+	} else if (khugepaged_thread) {
+		kthread_stop(khugepaged_thread);
+		khugepaged_thread = NULL;
+	}
+
 	return err;
 }
 
@@ -224,18 +215,16 @@
 				TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG);
 
 	if (ret > 0) {
-		int err = start_khugepaged();
+		int err;
+
+		mutex_lock(&khugepaged_mutex);
+		err = start_khugepaged();
+		mutex_unlock(&khugepaged_mutex);
+
 		if (err)
 			ret = err;
 	}
 
-	if (ret > 0 &&
-	    (test_bit(TRANSPARENT_HUGEPAGE_FLAG,
-		      &transparent_hugepage_flags) ||
-	     test_bit(TRANSPARENT_HUGEPAGE_REQ_MADV_FLAG,
-		      &transparent_hugepage_flags)))
-		set_recommended_min_free_kbytes();
-
 	return ret;
 }
 static struct kobj_attribute enabled_attr =
@@ -570,8 +559,6 @@
 
 	start_khugepaged();
 
-	set_recommended_min_free_kbytes();
-
 	return 0;
 out:
 	hugepage_exit_sysfs(hugepage_kobj);
@@ -611,19 +598,6 @@
 }
 __setup("transparent_hugepage=", setup_transparent_hugepage);
 
-static void prepare_pmd_huge_pte(pgtable_t pgtable,
-				 struct mm_struct *mm)
-{
-	assert_spin_locked(&mm->page_table_lock);
-
-	/* FIFO */
-	if (!mm->pmd_huge_pte)
-		INIT_LIST_HEAD(&pgtable->lru);
-	else
-		list_add(&pgtable->lru, &mm->pmd_huge_pte->lru);
-	mm->pmd_huge_pte = pgtable;
-}
-
 static inline pmd_t maybe_pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma)
 {
 	if (likely(vma->vm_flags & VM_WRITE))
@@ -665,7 +639,7 @@
 		 */
 		page_add_new_anon_rmap(page, vma, haddr);
 		set_pmd_at(mm, haddr, pmd, entry);
-		prepare_pmd_huge_pte(pgtable, mm);
+		pgtable_trans_huge_deposit(mm, pgtable);
 		add_mm_counter(mm, MM_ANONPAGES, HPAGE_PMD_NR);
 		mm->nr_ptes++;
 		spin_unlock(&mm->page_table_lock);
@@ -791,7 +765,7 @@
 	pmdp_set_wrprotect(src_mm, addr, src_pmd);
 	pmd = pmd_mkold(pmd_wrprotect(pmd));
 	set_pmd_at(dst_mm, addr, dst_pmd, pmd);
-	prepare_pmd_huge_pte(pgtable, dst_mm);
+	pgtable_trans_huge_deposit(dst_mm, pgtable);
 	dst_mm->nr_ptes++;
 
 	ret = 0;
@@ -802,25 +776,6 @@
 	return ret;
 }
 
-/* no "address" argument so destroys page coloring of some arch */
-pgtable_t get_pmd_huge_pte(struct mm_struct *mm)
-{
-	pgtable_t pgtable;
-
-	assert_spin_locked(&mm->page_table_lock);
-
-	/* FIFO */
-	pgtable = mm->pmd_huge_pte;
-	if (list_empty(&pgtable->lru))
-		mm->pmd_huge_pte = NULL;
-	else {
-		mm->pmd_huge_pte = list_entry(pgtable->lru.next,
-					      struct page, lru);
-		list_del(&pgtable->lru);
-	}
-	return pgtable;
-}
-
 static int do_huge_pmd_wp_page_fallback(struct mm_struct *mm,
 					struct vm_area_struct *vma,
 					unsigned long address,
@@ -832,6 +787,8 @@
 	pmd_t _pmd;
 	int ret = 0, i;
 	struct page **pages;
+	unsigned long mmun_start;	/* For mmu_notifiers */
+	unsigned long mmun_end;		/* For mmu_notifiers */
 
 	pages = kmalloc(sizeof(struct page *) * HPAGE_PMD_NR,
 			GFP_KERNEL);
@@ -868,15 +825,19 @@
 		cond_resched();
 	}
 
+	mmun_start = haddr;
+	mmun_end   = haddr + HPAGE_PMD_SIZE;
+	mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
+
 	spin_lock(&mm->page_table_lock);
 	if (unlikely(!pmd_same(*pmd, orig_pmd)))
 		goto out_free_pages;
 	VM_BUG_ON(!PageHead(page));
 
-	pmdp_clear_flush_notify(vma, haddr, pmd);
+	pmdp_clear_flush(vma, haddr, pmd);
 	/* leave pmd empty until pte is filled */
 
-	pgtable = get_pmd_huge_pte(mm);
+	pgtable = pgtable_trans_huge_withdraw(mm);
 	pmd_populate(mm, &_pmd, pgtable);
 
 	for (i = 0; i < HPAGE_PMD_NR; i++, haddr += PAGE_SIZE) {
@@ -896,6 +857,8 @@
 	page_remove_rmap(page);
 	spin_unlock(&mm->page_table_lock);
 
+	mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
+
 	ret |= VM_FAULT_WRITE;
 	put_page(page);
 
@@ -904,6 +867,7 @@
 
 out_free_pages:
 	spin_unlock(&mm->page_table_lock);
+	mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
 	mem_cgroup_uncharge_start();
 	for (i = 0; i < HPAGE_PMD_NR; i++) {
 		mem_cgroup_uncharge_page(pages[i]);
@@ -920,6 +884,8 @@
 	int ret = 0;
 	struct page *page, *new_page;
 	unsigned long haddr;
+	unsigned long mmun_start;	/* For mmu_notifiers */
+	unsigned long mmun_end;		/* For mmu_notifiers */
 
 	VM_BUG_ON(!vma->anon_vma);
 	spin_lock(&mm->page_table_lock);
@@ -934,7 +900,7 @@
 		entry = pmd_mkyoung(orig_pmd);
 		entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma);
 		if (pmdp_set_access_flags(vma, haddr, pmd, entry,  1))
-			update_mmu_cache(vma, address, entry);
+			update_mmu_cache_pmd(vma, address, pmd);
 		ret |= VM_FAULT_WRITE;
 		goto out_unlock;
 	}
@@ -970,38 +936,47 @@
 	copy_user_huge_page(new_page, page, haddr, vma, HPAGE_PMD_NR);
 	__SetPageUptodate(new_page);
 
+	mmun_start = haddr;
+	mmun_end   = haddr + HPAGE_PMD_SIZE;
+	mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
+
 	spin_lock(&mm->page_table_lock);
 	put_page(page);
 	if (unlikely(!pmd_same(*pmd, orig_pmd))) {
 		spin_unlock(&mm->page_table_lock);
 		mem_cgroup_uncharge_page(new_page);
 		put_page(new_page);
-		goto out;
+		goto out_mn;
 	} else {
 		pmd_t entry;
 		VM_BUG_ON(!PageHead(page));
 		entry = mk_pmd(new_page, vma->vm_page_prot);
 		entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma);
 		entry = pmd_mkhuge(entry);
-		pmdp_clear_flush_notify(vma, haddr, pmd);
+		pmdp_clear_flush(vma, haddr, pmd);
 		page_add_new_anon_rmap(new_page, vma, haddr);
 		set_pmd_at(mm, haddr, pmd, entry);
-		update_mmu_cache(vma, address, entry);
+		update_mmu_cache_pmd(vma, address, pmd);
 		page_remove_rmap(page);
 		put_page(page);
 		ret |= VM_FAULT_WRITE;
 	}
+	spin_unlock(&mm->page_table_lock);
+out_mn:
+	mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
+out:
+	return ret;
 out_unlock:
 	spin_unlock(&mm->page_table_lock);
-out:
 	return ret;
 }
 
-struct page *follow_trans_huge_pmd(struct mm_struct *mm,
+struct page *follow_trans_huge_pmd(struct vm_area_struct *vma,
 				   unsigned long addr,
 				   pmd_t *pmd,
 				   unsigned int flags)
 {
+	struct mm_struct *mm = vma->vm_mm;
 	struct page *page = NULL;
 
 	assert_spin_locked(&mm->page_table_lock);
@@ -1024,6 +999,14 @@
 		_pmd = pmd_mkyoung(pmd_mkdirty(*pmd));
 		set_pmd_at(mm, addr & HPAGE_PMD_MASK, pmd, _pmd);
 	}
+	if ((flags & FOLL_MLOCK) && (vma->vm_flags & VM_LOCKED)) {
+		if (page->mapping && trylock_page(page)) {
+			lru_add_drain();
+			if (page->mapping)
+				mlock_vma_page(page);
+			unlock_page(page);
+		}
+	}
 	page += (addr & ~HPAGE_PMD_MASK) >> PAGE_SHIFT;
 	VM_BUG_ON(!PageCompound(page));
 	if (flags & FOLL_GET)
@@ -1041,9 +1024,10 @@
 	if (__pmd_trans_huge_lock(pmd, vma) == 1) {
 		struct page *page;
 		pgtable_t pgtable;
-		pgtable = get_pmd_huge_pte(tlb->mm);
-		page = pmd_page(*pmd);
-		pmd_clear(pmd);
+		pmd_t orig_pmd;
+		pgtable = pgtable_trans_huge_withdraw(tlb->mm);
+		orig_pmd = pmdp_get_and_clear(tlb->mm, addr, pmd);
+		page = pmd_page(orig_pmd);
 		tlb_remove_pmd_tlb_entry(tlb, pmd, addr);
 		page_remove_rmap(page);
 		VM_BUG_ON(page_mapcount(page) < 0);
@@ -1207,7 +1191,11 @@
 	struct mm_struct *mm = vma->vm_mm;
 	pmd_t *pmd;
 	int ret = 0;
+	/* For mmu_notifiers */
+	const unsigned long mmun_start = address;
+	const unsigned long mmun_end   = address + HPAGE_PMD_SIZE;
 
+	mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
 	spin_lock(&mm->page_table_lock);
 	pmd = page_check_address_pmd(page, mm, address,
 				     PAGE_CHECK_ADDRESS_PMD_NOTSPLITTING_FLAG);
@@ -1219,10 +1207,11 @@
 		 * and it won't wait on the anon_vma->root->mutex to
 		 * serialize against split_huge_page*.
 		 */
-		pmdp_splitting_flush_notify(vma, address, pmd);
+		pmdp_splitting_flush(vma, address, pmd);
 		ret = 1;
 	}
 	spin_unlock(&mm->page_table_lock);
+	mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
 
 	return ret;
 }
@@ -1358,11 +1347,11 @@
 	pmd = page_check_address_pmd(page, mm, address,
 				     PAGE_CHECK_ADDRESS_PMD_SPLITTING_FLAG);
 	if (pmd) {
-		pgtable = get_pmd_huge_pte(mm);
+		pgtable = pgtable_trans_huge_withdraw(mm);
 		pmd_populate(mm, &_pmd, pgtable);
 
-		for (i = 0, haddr = address; i < HPAGE_PMD_NR;
-		     i++, haddr += PAGE_SIZE) {
+		haddr = address;
+		for (i = 0; i < HPAGE_PMD_NR; i++, haddr += PAGE_SIZE) {
 			pte_t *pte, entry;
 			BUG_ON(PageCompound(page+i));
 			entry = mk_pte(page + i, vma->vm_page_prot);
@@ -1406,8 +1395,7 @@
 		 * SMP TLB and finally we write the non-huge version
 		 * of the pmd entry with pmd_populate.
 		 */
-		set_pmd_at(mm, address, pmd, pmd_mknotpresent(*pmd));
-		flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
+		pmdp_invalidate(vma, address, pmd);
 		pmd_populate(mm, pmd, pgtable);
 		ret = 1;
 	}
@@ -1421,18 +1409,17 @@
 			      struct anon_vma *anon_vma)
 {
 	int mapcount, mapcount2;
+	pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
 	struct anon_vma_chain *avc;
 
 	BUG_ON(!PageHead(page));
 	BUG_ON(PageTail(page));
 
 	mapcount = 0;
-	list_for_each_entry(avc, &anon_vma->head, same_anon_vma) {
+	anon_vma_interval_tree_foreach(avc, &anon_vma->rb_root, pgoff, pgoff) {
 		struct vm_area_struct *vma = avc->vma;
 		unsigned long addr = vma_address(page, vma);
 		BUG_ON(is_vma_temporary_stack(vma));
-		if (addr == -EFAULT)
-			continue;
 		mapcount += __split_huge_page_splitting(page, vma, addr);
 	}
 	/*
@@ -1453,12 +1440,10 @@
 	__split_huge_page_refcount(page);
 
 	mapcount2 = 0;
-	list_for_each_entry(avc, &anon_vma->head, same_anon_vma) {
+	anon_vma_interval_tree_foreach(avc, &anon_vma->rb_root, pgoff, pgoff) {
 		struct vm_area_struct *vma = avc->vma;
 		unsigned long addr = vma_address(page, vma);
 		BUG_ON(is_vma_temporary_stack(vma));
-		if (addr == -EFAULT)
-			continue;
 		mapcount2 += __split_huge_page_map(page, vma, addr);
 	}
 	if (mapcount != mapcount2)
@@ -1491,12 +1476,13 @@
 	return ret;
 }
 
-#define VM_NO_THP (VM_SPECIAL|VM_INSERTPAGE|VM_MIXEDMAP|VM_SAO| \
-		   VM_HUGETLB|VM_SHARED|VM_MAYSHARE)
+#define VM_NO_THP (VM_SPECIAL|VM_MIXEDMAP|VM_HUGETLB|VM_SHARED|VM_MAYSHARE)
 
 int hugepage_madvise(struct vm_area_struct *vma,
 		     unsigned long *vm_flags, int advice)
 {
+	struct mm_struct *mm = vma->vm_mm;
+
 	switch (advice) {
 	case MADV_HUGEPAGE:
 		/*
@@ -1504,6 +1490,8 @@
 		 */
 		if (*vm_flags & (VM_HUGEPAGE | VM_NO_THP))
 			return -EINVAL;
+		if (mm->def_flags & VM_NOHUGEPAGE)
+			return -EINVAL;
 		*vm_flags &= ~VM_NOHUGEPAGE;
 		*vm_flags |= VM_HUGEPAGE;
 		/*
@@ -1655,11 +1643,7 @@
 	if (vma->vm_ops)
 		/* khugepaged not yet working on file or special mappings */
 		return 0;
-	/*
-	 * If is_pfn_mapping() is true is_learn_pfn_mapping() must be
-	 * true too, verify it here.
-	 */
-	VM_BUG_ON(is_linear_pfn_mapping(vma) || vma->vm_flags & VM_NO_THP);
+	VM_BUG_ON(vma->vm_flags & VM_NO_THP);
 	hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK;
 	hend = vma->vm_end & HPAGE_PMD_MASK;
 	if (hstart < hend)
@@ -1833,28 +1817,35 @@
 	}
 }
 
-static void collapse_huge_page(struct mm_struct *mm,
-			       unsigned long address,
-			       struct page **hpage,
-			       struct vm_area_struct *vma,
-			       int node)
+static void khugepaged_alloc_sleep(void)
 {
-	pgd_t *pgd;
-	pud_t *pud;
-	pmd_t *pmd, _pmd;
-	pte_t *pte;
-	pgtable_t pgtable;
-	struct page *new_page;
-	spinlock_t *ptl;
-	int isolated;
-	unsigned long hstart, hend;
+	wait_event_freezable_timeout(khugepaged_wait, false,
+			msecs_to_jiffies(khugepaged_alloc_sleep_millisecs));
+}
 
-	VM_BUG_ON(address & ~HPAGE_PMD_MASK);
-#ifndef CONFIG_NUMA
-	up_read(&mm->mmap_sem);
-	VM_BUG_ON(!*hpage);
-	new_page = *hpage;
-#else
+#ifdef CONFIG_NUMA
+static bool khugepaged_prealloc_page(struct page **hpage, bool *wait)
+{
+	if (IS_ERR(*hpage)) {
+		if (!*wait)
+			return false;
+
+		*wait = false;
+		*hpage = NULL;
+		khugepaged_alloc_sleep();
+	} else if (*hpage) {
+		put_page(*hpage);
+		*hpage = NULL;
+	}
+
+	return true;
+}
+
+static struct page
+*khugepaged_alloc_page(struct page **hpage, struct mm_struct *mm,
+		       struct vm_area_struct *vma, unsigned long address,
+		       int node)
+{
 	VM_BUG_ON(*hpage);
 	/*
 	 * Allocate the page while the vma is still valid and under
@@ -1866,7 +1857,7 @@
 	 * mmap_sem in read mode is good idea also to allow greater
 	 * scalability.
 	 */
-	new_page = alloc_hugepage_vma(khugepaged_defrag(), vma, address,
+	*hpage  = alloc_hugepage_vma(khugepaged_defrag(), vma, address,
 				      node, __GFP_OTHER_NODE);
 
 	/*
@@ -1874,20 +1865,85 @@
 	 * preparation for taking it in write mode.
 	 */
 	up_read(&mm->mmap_sem);
-	if (unlikely(!new_page)) {
+	if (unlikely(!*hpage)) {
 		count_vm_event(THP_COLLAPSE_ALLOC_FAILED);
 		*hpage = ERR_PTR(-ENOMEM);
-		return;
+		return NULL;
 	}
-#endif
 
 	count_vm_event(THP_COLLAPSE_ALLOC);
-	if (unlikely(mem_cgroup_newpage_charge(new_page, mm, GFP_KERNEL))) {
-#ifdef CONFIG_NUMA
-		put_page(new_page);
+	return *hpage;
+}
+#else
+static struct page *khugepaged_alloc_hugepage(bool *wait)
+{
+	struct page *hpage;
+
+	do {
+		hpage = alloc_hugepage(khugepaged_defrag());
+		if (!hpage) {
+			count_vm_event(THP_COLLAPSE_ALLOC_FAILED);
+			if (!*wait)
+				return NULL;
+
+			*wait = false;
+			khugepaged_alloc_sleep();
+		} else
+			count_vm_event(THP_COLLAPSE_ALLOC);
+	} while (unlikely(!hpage) && likely(khugepaged_enabled()));
+
+	return hpage;
+}
+
+static bool khugepaged_prealloc_page(struct page **hpage, bool *wait)
+{
+	if (!*hpage)
+		*hpage = khugepaged_alloc_hugepage(wait);
+
+	if (unlikely(!*hpage))
+		return false;
+
+	return true;
+}
+
+static struct page
+*khugepaged_alloc_page(struct page **hpage, struct mm_struct *mm,
+		       struct vm_area_struct *vma, unsigned long address,
+		       int node)
+{
+	up_read(&mm->mmap_sem);
+	VM_BUG_ON(!*hpage);
+	return  *hpage;
+}
 #endif
+
+static void collapse_huge_page(struct mm_struct *mm,
+				   unsigned long address,
+				   struct page **hpage,
+				   struct vm_area_struct *vma,
+				   int node)
+{
+	pgd_t *pgd;
+	pud_t *pud;
+	pmd_t *pmd, _pmd;
+	pte_t *pte;
+	pgtable_t pgtable;
+	struct page *new_page;
+	spinlock_t *ptl;
+	int isolated;
+	unsigned long hstart, hend;
+	unsigned long mmun_start;	/* For mmu_notifiers */
+	unsigned long mmun_end;		/* For mmu_notifiers */
+
+	VM_BUG_ON(address & ~HPAGE_PMD_MASK);
+
+	/* release the mmap_sem read lock. */
+	new_page = khugepaged_alloc_page(hpage, mm, vma, address, node);
+	if (!new_page)
 		return;
-	}
+
+	if (unlikely(mem_cgroup_newpage_charge(new_page, mm, GFP_KERNEL)))
+		return;
 
 	/*
 	 * Prevent all access to pagetables with the exception of
@@ -1912,11 +1968,7 @@
 		goto out;
 	if (is_vma_temporary_stack(vma))
 		goto out;
-	/*
-	 * If is_pfn_mapping() is true is_learn_pfn_mapping() must be
-	 * true too, verify it here.
-	 */
-	VM_BUG_ON(is_linear_pfn_mapping(vma) || vma->vm_flags & VM_NO_THP);
+	VM_BUG_ON(vma->vm_flags & VM_NO_THP);
 
 	pgd = pgd_offset(mm, address);
 	if (!pgd_present(*pgd))
@@ -1936,6 +1988,9 @@
 	pte = pte_offset_map(pmd, address);
 	ptl = pte_lockptr(mm, pmd);
 
+	mmun_start = address;
+	mmun_end   = address + HPAGE_PMD_SIZE;
+	mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
 	spin_lock(&mm->page_table_lock); /* probably unnecessary */
 	/*
 	 * After this gup_fast can't run anymore. This also removes
@@ -1943,8 +1998,9 @@
 	 * huge and small TLB entries for the same virtual address
 	 * to avoid the risk of CPU bugs in that area.
 	 */
-	_pmd = pmdp_clear_flush_notify(vma, address, pmd);
+	_pmd = pmdp_clear_flush(vma, address, pmd);
 	spin_unlock(&mm->page_table_lock);
+	mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
 
 	spin_lock(ptl);
 	isolated = __collapse_huge_page_isolate(vma, address, pte);
@@ -1970,8 +2026,6 @@
 	pte_unmap(pte);
 	__SetPageUptodate(new_page);
 	pgtable = pmd_pgtable(_pmd);
-	VM_BUG_ON(page_count(pgtable) != 1);
-	VM_BUG_ON(page_mapcount(pgtable) != 0);
 
 	_pmd = mk_pmd(new_page, vma->vm_page_prot);
 	_pmd = maybe_pmd_mkwrite(pmd_mkdirty(_pmd), vma);
@@ -1988,13 +2042,12 @@
 	BUG_ON(!pmd_none(*pmd));
 	page_add_new_anon_rmap(new_page, vma, address);
 	set_pmd_at(mm, address, pmd, _pmd);
-	update_mmu_cache(vma, address, _pmd);
-	prepare_pmd_huge_pte(pgtable, mm);
+	update_mmu_cache_pmd(vma, address, pmd);
+	pgtable_trans_huge_deposit(mm, pgtable);
 	spin_unlock(&mm->page_table_lock);
 
-#ifndef CONFIG_NUMA
 	*hpage = NULL;
-#endif
+
 	khugepaged_pages_collapsed++;
 out_up_write:
 	up_write(&mm->mmap_sem);
@@ -2002,9 +2055,6 @@
 
 out:
 	mem_cgroup_uncharge_page(new_page);
-#ifdef CONFIG_NUMA
-	put_page(new_page);
-#endif
 	goto out_up_write;
 }
 
@@ -2154,12 +2204,7 @@
 			goto skip;
 		if (is_vma_temporary_stack(vma))
 			goto skip;
-		/*
-		 * If is_pfn_mapping() is true is_learn_pfn_mapping()
-		 * must be true too, verify it here.
-		 */
-		VM_BUG_ON(is_linear_pfn_mapping(vma) ||
-			  vma->vm_flags & VM_NO_THP);
+		VM_BUG_ON(vma->vm_flags & VM_NO_THP);
 
 		hstart = (vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK;
 		hend = vma->vm_end & HPAGE_PMD_MASK;
@@ -2234,32 +2279,23 @@
 static int khugepaged_wait_event(void)
 {
 	return !list_empty(&khugepaged_scan.mm_head) ||
-		!khugepaged_enabled();
+		kthread_should_stop();
 }
 
-static void khugepaged_do_scan(struct page **hpage)
+static void khugepaged_do_scan(void)
 {
+	struct page *hpage = NULL;
 	unsigned int progress = 0, pass_through_head = 0;
 	unsigned int pages = khugepaged_pages_to_scan;
+	bool wait = true;
 
 	barrier(); /* write khugepaged_pages_to_scan to local stack */
 
 	while (progress < pages) {
-		cond_resched();
-
-#ifndef CONFIG_NUMA
-		if (!*hpage) {
-			*hpage = alloc_hugepage(khugepaged_defrag());
-			if (unlikely(!*hpage)) {
-				count_vm_event(THP_COLLAPSE_ALLOC_FAILED);
-				break;
-			}
-			count_vm_event(THP_COLLAPSE_ALLOC);
-		}
-#else
-		if (IS_ERR(*hpage))
+		if (!khugepaged_prealloc_page(&hpage, &wait))
 			break;
-#endif
+
+		cond_resched();
 
 		if (unlikely(kthread_should_stop() || freezing(current)))
 			break;
@@ -2270,73 +2306,32 @@
 		if (khugepaged_has_work() &&
 		    pass_through_head < 2)
 			progress += khugepaged_scan_mm_slot(pages - progress,
-							    hpage);
+							    &hpage);
 		else
 			progress = pages;
 		spin_unlock(&khugepaged_mm_lock);
 	}
+
+	if (!IS_ERR_OR_NULL(hpage))
+		put_page(hpage);
 }
 
-static void khugepaged_alloc_sleep(void)
+static void khugepaged_wait_work(void)
 {
-	wait_event_freezable_timeout(khugepaged_wait, false,
-			msecs_to_jiffies(khugepaged_alloc_sleep_millisecs));
-}
+	try_to_freeze();
 
-#ifndef CONFIG_NUMA
-static struct page *khugepaged_alloc_hugepage(void)
-{
-	struct page *hpage;
+	if (khugepaged_has_work()) {
+		if (!khugepaged_scan_sleep_millisecs)
+			return;
 
-	do {
-		hpage = alloc_hugepage(khugepaged_defrag());
-		if (!hpage) {
-			count_vm_event(THP_COLLAPSE_ALLOC_FAILED);
-			khugepaged_alloc_sleep();
-		} else
-			count_vm_event(THP_COLLAPSE_ALLOC);
-	} while (unlikely(!hpage) &&
-		 likely(khugepaged_enabled()));
-	return hpage;
-}
-#endif
-
-static void khugepaged_loop(void)
-{
-	struct page *hpage;
-
-#ifdef CONFIG_NUMA
-	hpage = NULL;
-#endif
-	while (likely(khugepaged_enabled())) {
-#ifndef CONFIG_NUMA
-		hpage = khugepaged_alloc_hugepage();
-		if (unlikely(!hpage))
-			break;
-#else
-		if (IS_ERR(hpage)) {
-			khugepaged_alloc_sleep();
-			hpage = NULL;
-		}
-#endif
-
-		khugepaged_do_scan(&hpage);
-#ifndef CONFIG_NUMA
-		if (hpage)
-			put_page(hpage);
-#endif
-		try_to_freeze();
-		if (unlikely(kthread_should_stop()))
-			break;
-		if (khugepaged_has_work()) {
-			if (!khugepaged_scan_sleep_millisecs)
-				continue;
-			wait_event_freezable_timeout(khugepaged_wait, false,
-			    msecs_to_jiffies(khugepaged_scan_sleep_millisecs));
-		} else if (khugepaged_enabled())
-			wait_event_freezable(khugepaged_wait,
-					     khugepaged_wait_event());
+		wait_event_freezable_timeout(khugepaged_wait,
+					     kthread_should_stop(),
+			msecs_to_jiffies(khugepaged_scan_sleep_millisecs));
+		return;
 	}
+
+	if (khugepaged_enabled())
+		wait_event_freezable(khugepaged_wait, khugepaged_wait_event());
 }
 
 static int khugepaged(void *none)
@@ -2346,20 +2341,9 @@
 	set_freezable();
 	set_user_nice(current, 19);
 
-	/* serialize with start_khugepaged() */
-	mutex_lock(&khugepaged_mutex);
-
-	for (;;) {
-		mutex_unlock(&khugepaged_mutex);
-		VM_BUG_ON(khugepaged_thread != current);
-		khugepaged_loop();
-		VM_BUG_ON(khugepaged_thread != current);
-
-		mutex_lock(&khugepaged_mutex);
-		if (!khugepaged_enabled())
-			break;
-		if (unlikely(kthread_should_stop()))
-			break;
+	while (!kthread_should_stop()) {
+		khugepaged_do_scan();
+		khugepaged_wait_work();
 	}
 
 	spin_lock(&khugepaged_mm_lock);
@@ -2368,10 +2352,6 @@
 	if (mm_slot)
 		collect_mm_slot(mm_slot);
 	spin_unlock(&khugepaged_mm_lock);
-
-	khugepaged_thread = NULL;
-	mutex_unlock(&khugepaged_mutex);
-
 	return 0;
 }
 
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index bc72712..59a0059 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -30,7 +30,6 @@
 #include <linux/hugetlb.h>
 #include <linux/hugetlb_cgroup.h>
 #include <linux/node.h>
-#include <linux/hugetlb_cgroup.h>
 #include "internal.h"
 
 const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL;
@@ -637,6 +636,7 @@
 		h->surplus_huge_pages--;
 		h->surplus_huge_pages_node[nid]--;
 	} else {
+		arch_clear_hugepage_flags(page);
 		enqueue_huge_page(h, page);
 	}
 	spin_unlock(&hugetlb_lock);
@@ -671,6 +671,11 @@
 	}
 }
 
+/*
+ * PageHuge() only returns true for hugetlbfs pages, but not for normal or
+ * transparent huge pages.  See the PageTransHuge() documentation for more
+ * details.
+ */
 int PageHuge(struct page *page)
 {
 	compound_page_dtor *dtor;
@@ -2355,13 +2360,15 @@
 	struct page *page;
 	struct hstate *h = hstate_vma(vma);
 	unsigned long sz = huge_page_size(h);
+	const unsigned long mmun_start = start;	/* For mmu_notifiers */
+	const unsigned long mmun_end   = end;	/* For mmu_notifiers */
 
 	WARN_ON(!is_vm_hugetlb_page(vma));
 	BUG_ON(start & ~huge_page_mask(h));
 	BUG_ON(end & ~huge_page_mask(h));
 
 	tlb_start_vma(tlb, vma);
-	mmu_notifier_invalidate_range_start(mm, start, end);
+	mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
 again:
 	spin_lock(&mm->page_table_lock);
 	for (address = start; address < end; address += sz) {
@@ -2425,7 +2432,7 @@
 		if (address < end && !ref_page)
 			goto again;
 	}
-	mmu_notifier_invalidate_range_end(mm, start, end);
+	mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
 	tlb_end_vma(tlb, vma);
 }
 
@@ -2473,7 +2480,6 @@
 	struct hstate *h = hstate_vma(vma);
 	struct vm_area_struct *iter_vma;
 	struct address_space *mapping;
-	struct prio_tree_iter iter;
 	pgoff_t pgoff;
 
 	/*
@@ -2481,7 +2487,8 @@
 	 * from page cache lookup which is in HPAGE_SIZE units.
 	 */
 	address = address & huge_page_mask(h);
-	pgoff = vma_hugecache_offset(h, vma, address);
+	pgoff = ((address - vma->vm_start) >> PAGE_SHIFT) +
+			vma->vm_pgoff;
 	mapping = vma->vm_file->f_dentry->d_inode->i_mapping;
 
 	/*
@@ -2490,7 +2497,7 @@
 	 * __unmap_hugepage_range() is called as the lock is already held
 	 */
 	mutex_lock(&mapping->i_mmap_mutex);
-	vma_prio_tree_foreach(iter_vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
+	vma_interval_tree_foreach(iter_vma, &mapping->i_mmap, pgoff, pgoff) {
 		/* Do not unmap the current VMA */
 		if (iter_vma == vma)
 			continue;
@@ -2525,6 +2532,8 @@
 	struct page *old_page, *new_page;
 	int avoidcopy;
 	int outside_reserve = 0;
+	unsigned long mmun_start;	/* For mmu_notifiers */
+	unsigned long mmun_end;		/* For mmu_notifiers */
 
 	old_page = pte_page(pte);
 
@@ -2611,6 +2620,9 @@
 			    pages_per_huge_page(h));
 	__SetPageUptodate(new_page);
 
+	mmun_start = address & huge_page_mask(h);
+	mmun_end = mmun_start + huge_page_size(h);
+	mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
 	/*
 	 * Retake the page_table_lock to check for racing updates
 	 * before the page tables are altered
@@ -2619,9 +2631,6 @@
 	ptep = huge_pte_offset(mm, address & huge_page_mask(h));
 	if (likely(pte_same(huge_ptep_get(ptep), pte))) {
 		/* Break COW */
-		mmu_notifier_invalidate_range_start(mm,
-			address & huge_page_mask(h),
-			(address & huge_page_mask(h)) + huge_page_size(h));
 		huge_ptep_clear_flush(vma, address, ptep);
 		set_huge_pte_at(mm, address, ptep,
 				make_huge_pte(vma, new_page, 1));
@@ -2629,10 +2638,11 @@
 		hugepage_add_new_anon_rmap(new_page, vma, address);
 		/* Make the old page be freed below */
 		new_page = old_page;
-		mmu_notifier_invalidate_range_end(mm,
-			address & huge_page_mask(h),
-			(address & huge_page_mask(h)) + huge_page_size(h));
 	}
+	spin_unlock(&mm->page_table_lock);
+	mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
+	/* Caller expects lock to be held */
+	spin_lock(&mm->page_table_lock);
 	page_cache_release(new_page);
 	page_cache_release(old_page);
 	return 0;
diff --git a/mm/internal.h b/mm/internal.h
index b8c91b3..a4fa284 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -118,26 +118,27 @@
 	unsigned long nr_freepages;	/* Number of isolated free pages */
 	unsigned long nr_migratepages;	/* Number of pages to migrate */
 	unsigned long free_pfn;		/* isolate_freepages search base */
-	unsigned long start_free_pfn;	/* where we started the search */
 	unsigned long migrate_pfn;	/* isolate_migratepages search base */
 	bool sync;			/* Synchronous migration */
-	bool wrapped;			/* Order > 0 compactions are
-					   incremental, once free_pfn
-					   and migrate_pfn meet, we restart
-					   from the top of the zone;
-					   remember we wrapped around. */
+	bool ignore_skip_hint;		/* Scan blocks even if marked skip */
+	bool finished_update_free;	/* True when the zone cached pfns are
+					 * no longer being updated
+					 */
+	bool finished_update_migrate;
 
 	int order;			/* order a direct compactor needs */
 	int migratetype;		/* MOVABLE, RECLAIMABLE etc */
 	struct zone *zone;
-	bool *contended;		/* True if a lock was contended */
+	bool contended;			/* True if a lock was contended */
+	struct page **page;		/* Page captured of requested size */
 };
 
 unsigned long
-isolate_freepages_range(unsigned long start_pfn, unsigned long end_pfn);
+isolate_freepages_range(struct compact_control *cc,
+			unsigned long start_pfn, unsigned long end_pfn);
 unsigned long
 isolate_migratepages_range(struct zone *zone, struct compact_control *cc,
-			   unsigned long low_pfn, unsigned long end_pfn);
+	unsigned long low_pfn, unsigned long end_pfn, bool unevictable);
 
 #endif
 
@@ -167,9 +168,8 @@
 }
 
 /*
- * Called only in fault path via page_evictable() for a new page
- * to determine if it's being mapped into a LOCKED vma.
- * If so, mark page as mlocked.
+ * Called only in fault path, to determine if a new page is being
+ * mapped into a LOCKED vma.  If it is, mark page as mlocked.
  */
 static inline int mlocked_vma_newpage(struct vm_area_struct *vma,
 				    struct page *page)
@@ -180,7 +180,8 @@
 		return 0;
 
 	if (!TestSetPageMlocked(page)) {
-		inc_zone_page_state(page, NR_MLOCK);
+		mod_zone_page_state(page_zone(page), NR_MLOCK,
+				    hpage_nr_pages(page));
 		count_vm_event(UNEVICTABLE_PGMLOCKED);
 	}
 	return 1;
@@ -201,12 +202,7 @@
  * If called for a page that is still mapped by mlocked vmas, all we do
  * is revert to lazy LRU behaviour -- semantics are not broken.
  */
-extern void __clear_page_mlock(struct page *page);
-static inline void clear_page_mlock(struct page *page)
-{
-	if (unlikely(TestClearPageMlocked(page)))
-		__clear_page_mlock(page);
-}
+extern void clear_page_mlock(struct page *page);
 
 /*
  * mlock_migrate_page - called only from migrate_page_copy() to
@@ -340,7 +336,6 @@
 #define ZONE_RECLAIM_FULL	-1
 #define ZONE_RECLAIM_SOME	0
 #define ZONE_RECLAIM_SUCCESS	1
-#endif
 
 extern int hwpoison_filter(struct page *p);
 
@@ -356,3 +351,20 @@
         unsigned long, unsigned long);
 
 extern void set_pageblock_order(void);
+unsigned long reclaim_clean_pages_from_list(struct zone *zone,
+					    struct list_head *page_list);
+/* The ALLOC_WMARK bits are used as an index to zone->watermark */
+#define ALLOC_WMARK_MIN		WMARK_MIN
+#define ALLOC_WMARK_LOW		WMARK_LOW
+#define ALLOC_WMARK_HIGH	WMARK_HIGH
+#define ALLOC_NO_WATERMARKS	0x04 /* don't check watermarks at all */
+
+/* Mask to get the watermark bits */
+#define ALLOC_WMARK_MASK	(ALLOC_NO_WATERMARKS-1)
+
+#define ALLOC_HARDER		0x10 /* try to alloc harder */
+#define ALLOC_HIGH		0x20 /* __GFP_HIGH set */
+#define ALLOC_CPUSET		0x40 /* check for correct cpuset */
+#define ALLOC_CMA		0x80 /* allow allocations from CMA areas */
+
+#endif	/* __MM_INTERNAL_H */
diff --git a/mm/interval_tree.c b/mm/interval_tree.c
new file mode 100644
index 0000000..4a5822a
--- /dev/null
+++ b/mm/interval_tree.c
@@ -0,0 +1,112 @@
+/*
+ * mm/interval_tree.c - interval tree for mapping->i_mmap
+ *
+ * Copyright (C) 2012, Michel Lespinasse <walken@google.com>
+ *
+ * This file is released under the GPL v2.
+ */
+
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/rmap.h>
+#include <linux/interval_tree_generic.h>
+
+static inline unsigned long vma_start_pgoff(struct vm_area_struct *v)
+{
+	return v->vm_pgoff;
+}
+
+static inline unsigned long vma_last_pgoff(struct vm_area_struct *v)
+{
+	return v->vm_pgoff + ((v->vm_end - v->vm_start) >> PAGE_SHIFT) - 1;
+}
+
+INTERVAL_TREE_DEFINE(struct vm_area_struct, shared.linear.rb,
+		     unsigned long, shared.linear.rb_subtree_last,
+		     vma_start_pgoff, vma_last_pgoff,, vma_interval_tree)
+
+/* Insert node immediately after prev in the interval tree */
+void vma_interval_tree_insert_after(struct vm_area_struct *node,
+				    struct vm_area_struct *prev,
+				    struct rb_root *root)
+{
+	struct rb_node **link;
+	struct vm_area_struct *parent;
+	unsigned long last = vma_last_pgoff(node);
+
+	VM_BUG_ON(vma_start_pgoff(node) != vma_start_pgoff(prev));
+
+	if (!prev->shared.linear.rb.rb_right) {
+		parent = prev;
+		link = &prev->shared.linear.rb.rb_right;
+	} else {
+		parent = rb_entry(prev->shared.linear.rb.rb_right,
+				  struct vm_area_struct, shared.linear.rb);
+		if (parent->shared.linear.rb_subtree_last < last)
+			parent->shared.linear.rb_subtree_last = last;
+		while (parent->shared.linear.rb.rb_left) {
+			parent = rb_entry(parent->shared.linear.rb.rb_left,
+				struct vm_area_struct, shared.linear.rb);
+			if (parent->shared.linear.rb_subtree_last < last)
+				parent->shared.linear.rb_subtree_last = last;
+		}
+		link = &parent->shared.linear.rb.rb_left;
+	}
+
+	node->shared.linear.rb_subtree_last = last;
+	rb_link_node(&node->shared.linear.rb, &parent->shared.linear.rb, link);
+	rb_insert_augmented(&node->shared.linear.rb, root,
+			    &vma_interval_tree_augment);
+}
+
+static inline unsigned long avc_start_pgoff(struct anon_vma_chain *avc)
+{
+	return vma_start_pgoff(avc->vma);
+}
+
+static inline unsigned long avc_last_pgoff(struct anon_vma_chain *avc)
+{
+	return vma_last_pgoff(avc->vma);
+}
+
+INTERVAL_TREE_DEFINE(struct anon_vma_chain, rb, unsigned long, rb_subtree_last,
+		     avc_start_pgoff, avc_last_pgoff,
+		     static inline, __anon_vma_interval_tree)
+
+void anon_vma_interval_tree_insert(struct anon_vma_chain *node,
+				   struct rb_root *root)
+{
+#ifdef CONFIG_DEBUG_VM_RB
+	node->cached_vma_start = avc_start_pgoff(node);
+	node->cached_vma_last = avc_last_pgoff(node);
+#endif
+	__anon_vma_interval_tree_insert(node, root);
+}
+
+void anon_vma_interval_tree_remove(struct anon_vma_chain *node,
+				   struct rb_root *root)
+{
+	__anon_vma_interval_tree_remove(node, root);
+}
+
+struct anon_vma_chain *
+anon_vma_interval_tree_iter_first(struct rb_root *root,
+				  unsigned long first, unsigned long last)
+{
+	return __anon_vma_interval_tree_iter_first(root, first, last);
+}
+
+struct anon_vma_chain *
+anon_vma_interval_tree_iter_next(struct anon_vma_chain *node,
+				 unsigned long first, unsigned long last)
+{
+	return __anon_vma_interval_tree_iter_next(node, first, last);
+}
+
+#ifdef CONFIG_DEBUG_VM_RB
+void anon_vma_interval_tree_verify(struct anon_vma_chain *node)
+{
+	WARN_ON_ONCE(node->cached_vma_start != avc_start_pgoff(node));
+	WARN_ON_ONCE(node->cached_vma_last != avc_last_pgoff(node));
+}
+#endif
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 0de83b4..a217cc5 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -29,7 +29,7 @@
  * - kmemleak_lock (rwlock): protects the object_list modifications and
  *   accesses to the object_tree_root. The object_list is the main list
  *   holding the metadata (struct kmemleak_object) for the allocated memory
- *   blocks. The object_tree_root is a priority search tree used to look-up
+ *   blocks. The object_tree_root is a red black tree used to look-up
  *   metadata based on a pointer to the corresponding memory block.  The
  *   kmemleak_object structures are added to the object_list and
  *   object_tree_root in the create_object() function called from the
@@ -71,7 +71,7 @@
 #include <linux/delay.h>
 #include <linux/export.h>
 #include <linux/kthread.h>
-#include <linux/prio_tree.h>
+#include <linux/rbtree.h>
 #include <linux/fs.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
@@ -132,7 +132,7 @@
  * Structure holding the metadata for each allocated memory block.
  * Modifications to such objects should be made while holding the
  * object->lock. Insertions or deletions from object_list, gray_list or
- * tree_node are already protected by the corresponding locks or mutex (see
+ * rb_node are already protected by the corresponding locks or mutex (see
  * the notes on locking above). These objects are reference-counted
  * (use_count) and freed using the RCU mechanism.
  */
@@ -141,7 +141,7 @@
 	unsigned long flags;		/* object status flags */
 	struct list_head object_list;
 	struct list_head gray_list;
-	struct prio_tree_node tree_node;
+	struct rb_node rb_node;
 	struct rcu_head rcu;		/* object_list lockless traversal */
 	/* object usage count; object freed when use_count == 0 */
 	atomic_t use_count;
@@ -182,9 +182,9 @@
 static LIST_HEAD(object_list);
 /* the list of gray-colored objects (see color_gray comment below) */
 static LIST_HEAD(gray_list);
-/* prio search tree for object boundaries */
-static struct prio_tree_root object_tree_root;
-/* rw_lock protecting the access to object_list and prio_tree_root */
+/* search tree for object boundaries */
+static struct rb_root object_tree_root = RB_ROOT;
+/* rw_lock protecting the access to object_list and object_tree_root */
 static DEFINE_RWLOCK(kmemleak_lock);
 
 /* allocation caches for kmemleak internal data */
@@ -380,7 +380,7 @@
 	trace.entries = object->trace;
 
 	pr_notice("Object 0x%08lx (size %zu):\n",
-		  object->tree_node.start, object->size);
+		  object->pointer, object->size);
 	pr_notice("  comm \"%s\", pid %d, jiffies %lu\n",
 		  object->comm, object->pid, object->jiffies);
 	pr_notice("  min_count = %d\n", object->min_count);
@@ -392,32 +392,32 @@
 }
 
 /*
- * Look-up a memory block metadata (kmemleak_object) in the priority search
+ * Look-up a memory block metadata (kmemleak_object) in the object search
  * tree based on a pointer value. If alias is 0, only values pointing to the
  * beginning of the memory block are allowed. The kmemleak_lock must be held
  * when calling this function.
  */
 static struct kmemleak_object *lookup_object(unsigned long ptr, int alias)
 {
-	struct prio_tree_node *node;
-	struct prio_tree_iter iter;
-	struct kmemleak_object *object;
+	struct rb_node *rb = object_tree_root.rb_node;
 
-	prio_tree_iter_init(&iter, &object_tree_root, ptr, ptr);
-	node = prio_tree_next(&iter);
-	if (node) {
-		object = prio_tree_entry(node, struct kmemleak_object,
-					 tree_node);
-		if (!alias && object->pointer != ptr) {
+	while (rb) {
+		struct kmemleak_object *object =
+			rb_entry(rb, struct kmemleak_object, rb_node);
+		if (ptr < object->pointer)
+			rb = object->rb_node.rb_left;
+		else if (object->pointer + object->size <= ptr)
+			rb = object->rb_node.rb_right;
+		else if (object->pointer == ptr || alias)
+			return object;
+		else {
 			kmemleak_warn("Found object by alias at 0x%08lx\n",
 				      ptr);
 			dump_object_info(object);
-			object = NULL;
+			break;
 		}
-	} else
-		object = NULL;
-
-	return object;
+	}
+	return NULL;
 }
 
 /*
@@ -471,7 +471,7 @@
 }
 
 /*
- * Look up an object in the prio search tree and increase its use_count.
+ * Look up an object in the object search tree and increase its use_count.
  */
 static struct kmemleak_object *find_and_get_object(unsigned long ptr, int alias)
 {
@@ -516,8 +516,8 @@
 					     int min_count, gfp_t gfp)
 {
 	unsigned long flags;
-	struct kmemleak_object *object;
-	struct prio_tree_node *node;
+	struct kmemleak_object *object, *parent;
+	struct rb_node **link, *rb_parent;
 
 	object = kmem_cache_alloc(object_cache, gfp_kmemleak_mask(gfp));
 	if (!object) {
@@ -560,31 +560,34 @@
 	/* kernel backtrace */
 	object->trace_len = __save_stack_trace(object->trace);
 
-	INIT_PRIO_TREE_NODE(&object->tree_node);
-	object->tree_node.start = ptr;
-	object->tree_node.last = ptr + size - 1;
-
 	write_lock_irqsave(&kmemleak_lock, flags);
 
 	min_addr = min(min_addr, ptr);
 	max_addr = max(max_addr, ptr + size);
-	node = prio_tree_insert(&object_tree_root, &object->tree_node);
-	/*
-	 * The code calling the kernel does not yet have the pointer to the
-	 * memory block to be able to free it.  However, we still hold the
-	 * kmemleak_lock here in case parts of the kernel started freeing
-	 * random memory blocks.
-	 */
-	if (node != &object->tree_node) {
-		kmemleak_stop("Cannot insert 0x%lx into the object search tree "
-			      "(already existing)\n", ptr);
-		object = lookup_object(ptr, 1);
-		spin_lock(&object->lock);
-		dump_object_info(object);
-		spin_unlock(&object->lock);
-
-		goto out;
+	link = &object_tree_root.rb_node;
+	rb_parent = NULL;
+	while (*link) {
+		rb_parent = *link;
+		parent = rb_entry(rb_parent, struct kmemleak_object, rb_node);
+		if (ptr + size <= parent->pointer)
+			link = &parent->rb_node.rb_left;
+		else if (parent->pointer + parent->size <= ptr)
+			link = &parent->rb_node.rb_right;
+		else {
+			kmemleak_stop("Cannot insert 0x%lx into the object "
+				      "search tree (overlaps existing)\n",
+				      ptr);
+			kmem_cache_free(object_cache, object);
+			object = parent;
+			spin_lock(&object->lock);
+			dump_object_info(object);
+			spin_unlock(&object->lock);
+			goto out;
+		}
 	}
+	rb_link_node(&object->rb_node, rb_parent, link);
+	rb_insert_color(&object->rb_node, &object_tree_root);
+
 	list_add_tail_rcu(&object->object_list, &object_list);
 out:
 	write_unlock_irqrestore(&kmemleak_lock, flags);
@@ -600,7 +603,7 @@
 	unsigned long flags;
 
 	write_lock_irqsave(&kmemleak_lock, flags);
-	prio_tree_remove(&object_tree_root, &object->tree_node);
+	rb_erase(&object->rb_node, &object_tree_root);
 	list_del_rcu(&object->object_list);
 	write_unlock_irqrestore(&kmemleak_lock, flags);
 
@@ -1766,7 +1769,6 @@
 
 	object_cache = KMEM_CACHE(kmemleak_object, SLAB_NOLEAKTRACE);
 	scan_area_cache = KMEM_CACHE(kmemleak_scan_area, SLAB_NOLEAKTRACE);
-	INIT_PRIO_TREE_ROOT(&object_tree_root);
 
 	if (crt_early_log >= ARRAY_SIZE(early_log))
 		pr_warning("Early log buffer exceeded (%d), please increase "
diff --git a/mm/ksm.c b/mm/ksm.c
index 47c8853..ae539f0 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -709,15 +709,22 @@
 	spinlock_t *ptl;
 	int swapped;
 	int err = -EFAULT;
+	unsigned long mmun_start;	/* For mmu_notifiers */
+	unsigned long mmun_end;		/* For mmu_notifiers */
 
 	addr = page_address_in_vma(page, vma);
 	if (addr == -EFAULT)
 		goto out;
 
 	BUG_ON(PageTransCompound(page));
+
+	mmun_start = addr;
+	mmun_end   = addr + PAGE_SIZE;
+	mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
+
 	ptep = page_check_address(page, mm, addr, &ptl, 0);
 	if (!ptep)
-		goto out;
+		goto out_mn;
 
 	if (pte_write(*ptep) || pte_dirty(*ptep)) {
 		pte_t entry;
@@ -752,6 +759,8 @@
 
 out_unlock:
 	pte_unmap_unlock(ptep, ptl);
+out_mn:
+	mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
 out:
 	return err;
 }
@@ -776,6 +785,8 @@
 	spinlock_t *ptl;
 	unsigned long addr;
 	int err = -EFAULT;
+	unsigned long mmun_start;	/* For mmu_notifiers */
+	unsigned long mmun_end;		/* For mmu_notifiers */
 
 	addr = page_address_in_vma(page, vma);
 	if (addr == -EFAULT)
@@ -794,10 +805,14 @@
 	if (!pmd_present(*pmd))
 		goto out;
 
+	mmun_start = addr;
+	mmun_end   = addr + PAGE_SIZE;
+	mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
+
 	ptep = pte_offset_map_lock(mm, pmd, addr, &ptl);
 	if (!pte_same(*ptep, orig_pte)) {
 		pte_unmap_unlock(ptep, ptl);
-		goto out;
+		goto out_mn;
 	}
 
 	get_page(kpage);
@@ -814,6 +829,8 @@
 
 	pte_unmap_unlock(ptep, ptl);
 	err = 0;
+out_mn:
+	mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
 out:
 	return err;
 }
@@ -1469,10 +1486,14 @@
 		 */
 		if (*vm_flags & (VM_MERGEABLE | VM_SHARED  | VM_MAYSHARE   |
 				 VM_PFNMAP    | VM_IO      | VM_DONTEXPAND |
-				 VM_RESERVED  | VM_HUGETLB | VM_INSERTPAGE |
-				 VM_NONLINEAR | VM_MIXEDMAP | VM_SAO))
+				 VM_HUGETLB | VM_NONLINEAR | VM_MIXEDMAP))
 			return 0;		/* just ignore the advice */
 
+#ifdef VM_SAO
+		if (*vm_flags & VM_SAO)
+			return 0;
+#endif
+
 		if (!test_bit(MMF_VM_MERGEABLE, &mm->flags)) {
 			err = __ksm_enter(mm);
 			if (err)
@@ -1582,7 +1603,7 @@
 		SetPageSwapBacked(new_page);
 		__set_page_locked(new_page);
 
-		if (page_evictable(new_page, vma))
+		if (!mlocked_vma_newpage(vma, new_page))
 			lru_cache_add_lru(new_page, LRU_ACTIVE_ANON);
 		else
 			add_page_to_unevictable_list(new_page);
@@ -1614,7 +1635,8 @@
 		struct vm_area_struct *vma;
 
 		anon_vma_lock(anon_vma);
-		list_for_each_entry(vmac, &anon_vma->head, same_anon_vma) {
+		anon_vma_interval_tree_foreach(vmac, &anon_vma->rb_root,
+					       0, ULONG_MAX) {
 			vma = vmac->vma;
 			if (rmap_item->address < vma->vm_start ||
 			    rmap_item->address >= vma->vm_end)
@@ -1667,7 +1689,8 @@
 		struct vm_area_struct *vma;
 
 		anon_vma_lock(anon_vma);
-		list_for_each_entry(vmac, &anon_vma->head, same_anon_vma) {
+		anon_vma_interval_tree_foreach(vmac, &anon_vma->rb_root,
+					       0, ULONG_MAX) {
 			vma = vmac->vma;
 			if (rmap_item->address < vma->vm_start ||
 			    rmap_item->address >= vma->vm_end)
@@ -1719,7 +1742,8 @@
 		struct vm_area_struct *vma;
 
 		anon_vma_lock(anon_vma);
-		list_for_each_entry(vmac, &anon_vma->head, same_anon_vma) {
+		anon_vma_interval_tree_foreach(vmac, &anon_vma->rb_root,
+					       0, ULONG_MAX) {
 			vma = vmac->vma;
 			if (rmap_item->address < vma->vm_start ||
 			    rmap_item->address >= vma->vm_end)
diff --git a/mm/madvise.c b/mm/madvise.c
index 14d260f..03dfa5c 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -69,10 +69,14 @@
 		new_flags &= ~VM_DONTCOPY;
 		break;
 	case MADV_DONTDUMP:
-		new_flags |= VM_NODUMP;
+		new_flags |= VM_DONTDUMP;
 		break;
 	case MADV_DODUMP:
-		new_flags &= ~VM_NODUMP;
+		if (new_flags & VM_SPECIAL) {
+			error = -EINVAL;
+			goto out;
+		}
+		new_flags &= ~VM_DONTDUMP;
 		break;
 	case MADV_MERGEABLE:
 	case MADV_UNMERGEABLE:
diff --git a/mm/memblock.c b/mm/memblock.c
index 82aa349..931eef1 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -41,7 +41,8 @@
 static int memblock_reserved_in_slab __initdata_memblock = 0;
 
 /* inline so we don't get a warning when pr_debug is compiled out */
-static inline const char *memblock_type_name(struct memblock_type *type)
+static __init_memblock const char *
+memblock_type_name(struct memblock_type *type)
 {
 	if (type == &memblock.memory)
 		return "memory";
@@ -756,7 +757,7 @@
 		return ret;
 
 	for (i = start_rgn; i < end_rgn; i++)
-		type->regions[i].nid = nid;
+		memblock_set_region_node(&type->regions[i], nid);
 
 	memblock_merge_regions(type);
 	return 0;
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index a72f2ff..7acf43b 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -51,6 +51,7 @@
 #include <linux/oom.h>
 #include "internal.h"
 #include <net/sock.h>
+#include <net/ip.h>
 #include <net/tcp_memcontrol.h>
 
 #include <asm/uaccess.h>
@@ -326,7 +327,7 @@
 	struct mem_cgroup_stat_cpu nocpu_base;
 	spinlock_t pcp_counter_lock;
 
-#ifdef CONFIG_INET
+#if defined(CONFIG_MEMCG_KMEM) && defined(CONFIG_INET)
 	struct tcp_memcontrol tcp_mem;
 #endif
 };
@@ -411,12 +412,14 @@
 	return container_of(s, struct mem_cgroup, css);
 }
 
-/* Writing them here to avoid exposing memcg's inner layout */
-#ifdef CONFIG_MEMCG_KMEM
-#include <net/sock.h>
-#include <net/ip.h>
+static inline bool mem_cgroup_is_root(struct mem_cgroup *memcg)
+{
+	return (memcg == root_mem_cgroup);
+}
 
-static bool mem_cgroup_is_root(struct mem_cgroup *memcg);
+/* Writing them here to avoid exposing memcg's inner layout */
+#if defined(CONFIG_INET) && defined(CONFIG_MEMCG_KMEM)
+
 void sock_update_memcg(struct sock *sk)
 {
 	if (mem_cgroup_sockets_enabled) {
@@ -461,7 +464,6 @@
 	}
 }
 
-#ifdef CONFIG_INET
 struct cg_proto *tcp_proto_cgroup(struct mem_cgroup *memcg)
 {
 	if (!memcg || mem_cgroup_is_root(memcg))
@@ -470,10 +472,7 @@
 	return &memcg->tcp_mem.cg_proto;
 }
 EXPORT_SYMBOL(tcp_proto_cgroup);
-#endif /* CONFIG_INET */
-#endif /* CONFIG_MEMCG_KMEM */
 
-#if defined(CONFIG_INET) && defined(CONFIG_MEMCG_KMEM)
 static void disarm_sock_keys(struct mem_cgroup *memcg)
 {
 	if (!memcg_proto_activated(&memcg->tcp_mem.cg_proto))
@@ -1016,11 +1015,6 @@
 	     iter != NULL;				\
 	     iter = mem_cgroup_iter(NULL, iter, NULL))
 
-static inline bool mem_cgroup_is_root(struct mem_cgroup *memcg)
-{
-	return (memcg == root_mem_cgroup);
-}
-
 void mem_cgroup_count_vm_event(struct mm_struct *mm, enum vm_event_item idx)
 {
 	struct mem_cgroup *memcg;
diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index a6e2141..6c5899b 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -400,18 +400,21 @@
 	struct vm_area_struct *vma;
 	struct task_struct *tsk;
 	struct anon_vma *av;
+	pgoff_t pgoff;
 
 	av = page_lock_anon_vma(page);
 	if (av == NULL)	/* Not actually mapped anymore */
 		return;
 
+	pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
 	read_lock(&tasklist_lock);
 	for_each_process (tsk) {
 		struct anon_vma_chain *vmac;
 
 		if (!task_early_kill(tsk))
 			continue;
-		list_for_each_entry(vmac, &av->head, same_anon_vma) {
+		anon_vma_interval_tree_foreach(vmac, &av->rb_root,
+					       pgoff, pgoff) {
 			vma = vmac->vma;
 			if (!page_mapped_in_vma(page, vma))
 				continue;
@@ -431,7 +434,6 @@
 {
 	struct vm_area_struct *vma;
 	struct task_struct *tsk;
-	struct prio_tree_iter iter;
 	struct address_space *mapping = page->mapping;
 
 	mutex_lock(&mapping->i_mmap_mutex);
@@ -442,7 +444,7 @@
 		if (!task_early_kill(tsk))
 			continue;
 
-		vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff,
+		vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff,
 				      pgoff) {
 			/*
 			 * Send early kill signal to tasks where a vma covers
diff --git a/mm/memory.c b/mm/memory.c
index 5736170..fb135ba 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -712,7 +712,7 @@
 	add_taint(TAINT_BAD_PAGE);
 }
 
-static inline int is_cow_mapping(vm_flags_t flags)
+static inline bool is_cow_mapping(vm_flags_t flags)
 {
 	return (flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE;
 }
@@ -1039,6 +1039,9 @@
 	unsigned long next;
 	unsigned long addr = vma->vm_start;
 	unsigned long end = vma->vm_end;
+	unsigned long mmun_start;	/* For mmu_notifiers */
+	unsigned long mmun_end;		/* For mmu_notifiers */
+	bool is_cow;
 	int ret;
 
 	/*
@@ -1047,7 +1050,8 @@
 	 * readonly mappings. The tradeoff is that copy_page_range is more
 	 * efficient than faulting.
 	 */
-	if (!(vma->vm_flags & (VM_HUGETLB|VM_NONLINEAR|VM_PFNMAP|VM_INSERTPAGE))) {
+	if (!(vma->vm_flags & (VM_HUGETLB | VM_NONLINEAR |
+			       VM_PFNMAP | VM_MIXEDMAP))) {
 		if (!vma->anon_vma)
 			return 0;
 	}
@@ -1055,12 +1059,12 @@
 	if (is_vm_hugetlb_page(vma))
 		return copy_hugetlb_page_range(dst_mm, src_mm, vma);
 
-	if (unlikely(is_pfn_mapping(vma))) {
+	if (unlikely(vma->vm_flags & VM_PFNMAP)) {
 		/*
 		 * We do not free on error cases below as remove_vma
 		 * gets called on error from higher level routine
 		 */
-		ret = track_pfn_vma_copy(vma);
+		ret = track_pfn_copy(vma);
 		if (ret)
 			return ret;
 	}
@@ -1071,8 +1075,12 @@
 	 * parent mm. And a permission downgrade will only happen if
 	 * is_cow_mapping() returns true.
 	 */
-	if (is_cow_mapping(vma->vm_flags))
-		mmu_notifier_invalidate_range_start(src_mm, addr, end);
+	is_cow = is_cow_mapping(vma->vm_flags);
+	mmun_start = addr;
+	mmun_end   = end;
+	if (is_cow)
+		mmu_notifier_invalidate_range_start(src_mm, mmun_start,
+						    mmun_end);
 
 	ret = 0;
 	dst_pgd = pgd_offset(dst_mm, addr);
@@ -1088,9 +1096,8 @@
 		}
 	} while (dst_pgd++, src_pgd++, addr = next, addr != end);
 
-	if (is_cow_mapping(vma->vm_flags))
-		mmu_notifier_invalidate_range_end(src_mm,
-						  vma->vm_start, end);
+	if (is_cow)
+		mmu_notifier_invalidate_range_end(src_mm, mmun_start, mmun_end);
 	return ret;
 }
 
@@ -1327,8 +1334,8 @@
 	if (vma->vm_file)
 		uprobe_munmap(vma, start, end);
 
-	if (unlikely(is_pfn_mapping(vma)))
-		untrack_pfn_vma(vma, 0, 0);
+	if (unlikely(vma->vm_flags & VM_PFNMAP))
+		untrack_pfn(vma, 0, 0);
 
 	if (start != end) {
 		if (unlikely(is_vm_hugetlb_page(vma))) {
@@ -1521,7 +1528,7 @@
 				spin_unlock(&mm->page_table_lock);
 				wait_split_huge_page(vma->anon_vma, pmd);
 			} else {
-				page = follow_trans_huge_pmd(mm, address,
+				page = follow_trans_huge_pmd(vma, address,
 							     pmd, flags);
 				spin_unlock(&mm->page_table_lock);
 				goto out;
@@ -1576,12 +1583,12 @@
 		if (page->mapping && trylock_page(page)) {
 			lru_add_drain();  /* push cached pages to LRU */
 			/*
-			 * Because we lock page here and migration is
-			 * blocked by the pte's page reference, we need
-			 * only check for file-cache page truncation.
+			 * Because we lock page here, and migration is
+			 * blocked by the pte's page reference, and we
+			 * know the page is still mapped, we don't even
+			 * need to check for file-cache page truncation.
 			 */
-			if (page->mapping)
-				mlock_vma_page(page);
+			mlock_vma_page(page);
 			unlock_page(page);
 		}
 	}
@@ -2085,6 +2092,11 @@
  * ask for a shared writable mapping!
  *
  * The page does not need to be reserved.
+ *
+ * Usually this function is called from f_op->mmap() handler
+ * under mm->mmap_sem write-lock, so it can change vma->vm_flags.
+ * Caller must set VM_MIXEDMAP on vma if it wants to call this
+ * function from other places, for example from page-fault handler.
  */
 int vm_insert_page(struct vm_area_struct *vma, unsigned long addr,
 			struct page *page)
@@ -2093,7 +2105,11 @@
 		return -EFAULT;
 	if (!page_count(page))
 		return -EINVAL;
-	vma->vm_flags |= VM_INSERTPAGE;
+	if (!(vma->vm_flags & VM_MIXEDMAP)) {
+		BUG_ON(down_read_trylock(&vma->vm_mm->mmap_sem));
+		BUG_ON(vma->vm_flags & VM_PFNMAP);
+		vma->vm_flags |= VM_MIXEDMAP;
+	}
 	return insert_page(vma, addr, page, vma->vm_page_prot);
 }
 EXPORT_SYMBOL(vm_insert_page);
@@ -2132,7 +2148,7 @@
  * @addr: target user address of this page
  * @pfn: source kernel pfn
  *
- * Similar to vm_inert_page, this allows drivers to insert individual pages
+ * Similar to vm_insert_page, this allows drivers to insert individual pages
  * they've allocated into a user vma. Same comments apply.
  *
  * This function should only be called from a vm_ops->fault handler, and
@@ -2162,14 +2178,11 @@
 
 	if (addr < vma->vm_start || addr >= vma->vm_end)
 		return -EFAULT;
-	if (track_pfn_vma_new(vma, &pgprot, pfn, PAGE_SIZE))
+	if (track_pfn_insert(vma, &pgprot, pfn))
 		return -EINVAL;
 
 	ret = insert_pfn(vma, addr, pfn, pgprot);
 
-	if (ret)
-		untrack_pfn_vma(vma, pfn, PAGE_SIZE);
-
 	return ret;
 }
 EXPORT_SYMBOL(vm_insert_pfn);
@@ -2290,38 +2303,31 @@
 	 * rest of the world about it:
 	 *   VM_IO tells people not to look at these pages
 	 *	(accesses can have side effects).
-	 *   VM_RESERVED is specified all over the place, because
-	 *	in 2.4 it kept swapout's vma scan off this vma; but
-	 *	in 2.6 the LRU scan won't even find its pages, so this
-	 *	flag means no more than count its pages in reserved_vm,
-	 * 	and omit it from core dump, even when VM_IO turned off.
 	 *   VM_PFNMAP tells the core MM that the base pages are just
 	 *	raw PFN mappings, and do not have a "struct page" associated
 	 *	with them.
+	 *   VM_DONTEXPAND
+	 *      Disable vma merging and expanding with mremap().
+	 *   VM_DONTDUMP
+	 *      Omit vma from core dump, even when VM_IO turned off.
 	 *
 	 * There's a horrible special case to handle copy-on-write
 	 * behaviour that some programs depend on. We mark the "original"
 	 * un-COW'ed pages by matching them up with "vma->vm_pgoff".
+	 * See vm_normal_page() for details.
 	 */
-	if (addr == vma->vm_start && end == vma->vm_end) {
+	if (is_cow_mapping(vma->vm_flags)) {
+		if (addr != vma->vm_start || end != vma->vm_end)
+			return -EINVAL;
 		vma->vm_pgoff = pfn;
-		vma->vm_flags |= VM_PFN_AT_MMAP;
-	} else if (is_cow_mapping(vma->vm_flags))
-		return -EINVAL;
-
-	vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
-
-	err = track_pfn_vma_new(vma, &prot, pfn, PAGE_ALIGN(size));
-	if (err) {
-		/*
-		 * To indicate that track_pfn related cleanup is not
-		 * needed from higher level routine calling unmap_vmas
-		 */
-		vma->vm_flags &= ~(VM_IO | VM_RESERVED | VM_PFNMAP);
-		vma->vm_flags &= ~VM_PFN_AT_MMAP;
-		return -EINVAL;
 	}
 
+	err = track_pfn_remap(vma, &prot, pfn, addr, PAGE_ALIGN(size));
+	if (err)
+		return -EINVAL;
+
+	vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
+
 	BUG_ON(addr >= end);
 	pfn -= addr >> PAGE_SHIFT;
 	pgd = pgd_offset(mm, addr);
@@ -2335,7 +2341,7 @@
 	} while (pgd++, addr = next, addr != end);
 
 	if (err)
-		untrack_pfn_vma(vma, pfn, PAGE_ALIGN(size));
+		untrack_pfn(vma, pfn, PAGE_ALIGN(size));
 
 	return err;
 }
@@ -2516,11 +2522,14 @@
 		spinlock_t *ptl, pte_t orig_pte)
 	__releases(ptl)
 {
-	struct page *old_page, *new_page;
+	struct page *old_page, *new_page = NULL;
 	pte_t entry;
 	int ret = 0;
 	int page_mkwrite = 0;
 	struct page *dirty_page = NULL;
+	unsigned long mmun_start;	/* For mmu_notifiers */
+	unsigned long mmun_end;		/* For mmu_notifiers */
+	bool mmun_called = false;	/* For mmu_notifiers */
 
 	old_page = vm_normal_page(vma, address, orig_pte);
 	if (!old_page) {
@@ -2698,6 +2707,11 @@
 	if (mem_cgroup_newpage_charge(new_page, mm, GFP_KERNEL))
 		goto oom_free_new;
 
+	mmun_start  = address & PAGE_MASK;
+	mmun_end    = (address & PAGE_MASK) + PAGE_SIZE;
+	mmun_called = true;
+	mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
+
 	/*
 	 * Re-check the pte - we dropped the lock
 	 */
@@ -2764,6 +2778,8 @@
 		page_cache_release(new_page);
 unlock:
 	pte_unmap_unlock(page_table, ptl);
+	if (mmun_called)
+		mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
 	if (old_page) {
 		/*
 		 * Don't let another task, with possibly unlocked vma,
@@ -2801,14 +2817,13 @@
 	zap_page_range_single(vma, start_addr, end_addr - start_addr, details);
 }
 
-static inline void unmap_mapping_range_tree(struct prio_tree_root *root,
+static inline void unmap_mapping_range_tree(struct rb_root *root,
 					    struct zap_details *details)
 {
 	struct vm_area_struct *vma;
-	struct prio_tree_iter iter;
 	pgoff_t vba, vea, zba, zea;
 
-	vma_prio_tree_foreach(vma, &iter, root,
+	vma_interval_tree_foreach(vma, root,
 			details->first_index, details->last_index) {
 
 		vba = vma->vm_pgoff;
@@ -2839,7 +2854,7 @@
 	 * across *all* the pages in each nonlinear VMA, not just the pages
 	 * whose virtual address lies outside the file truncation point.
 	 */
-	list_for_each_entry(vma, head, shared.vm_set.list) {
+	list_for_each_entry(vma, head, shared.nonlinear) {
 		details->nonlinear_vma = vma;
 		unmap_mapping_range_vma(vma, vma->vm_start, vma->vm_end, details);
 	}
@@ -2883,7 +2898,7 @@
 
 
 	mutex_lock(&mapping->i_mmap_mutex);
-	if (unlikely(!prio_tree_empty(&mapping->i_mmap)))
+	if (unlikely(!RB_EMPTY_ROOT(&mapping->i_mmap)))
 		unmap_mapping_range_tree(&mapping->i_mmap, &details);
 	if (unlikely(!list_empty(&mapping->i_mmap_nonlinear)))
 		unmap_mapping_range_list(&mapping->i_mmap_nonlinear, &details);
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 6a5b90d..56b758a 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -106,6 +106,7 @@
 void __ref put_page_bootmem(struct page *page)
 {
 	unsigned long type;
+	struct zone *zone;
 
 	type = (unsigned long) page->lru.next;
 	BUG_ON(type < MEMORY_HOTPLUG_MIN_BOOTMEM_TYPE ||
@@ -116,6 +117,12 @@
 		set_page_private(page, 0);
 		INIT_LIST_HEAD(&page->lru);
 		__free_pages_bootmem(page, 0);
+
+		zone = page_zone(page);
+		zone_span_writelock(zone);
+		zone->present_pages++;
+		zone_span_writeunlock(zone);
+		totalram_pages++;
 	}
 
 }
@@ -362,11 +369,11 @@
 	BUG_ON(phys_start_pfn & ~PAGE_SECTION_MASK);
 	BUG_ON(nr_pages % PAGES_PER_SECTION);
 
+	release_mem_region(phys_start_pfn << PAGE_SHIFT, nr_pages * PAGE_SIZE);
+
 	sections_to_remove = nr_pages / PAGES_PER_SECTION;
 	for (i = 0; i < sections_to_remove; i++) {
 		unsigned long pfn = phys_start_pfn + i*PAGES_PER_SECTION;
-		release_mem_region(pfn << PAGE_SHIFT,
-				   PAGES_PER_SECTION << PAGE_SHIFT);
 		ret = __remove_section(zone, __pfn_to_section(pfn));
 		if (ret)
 			break;
@@ -756,13 +763,6 @@
 	return 0;
 }
 
-static struct page *
-hotremove_migrate_alloc(struct page *page, unsigned long private, int **x)
-{
-	/* This should be improooooved!! */
-	return alloc_page(GFP_HIGHUSER_MOVABLE);
-}
-
 #define NR_OFFLINE_AT_ONCE_PAGES	(256)
 static int
 do_migrate_range(unsigned long start_pfn, unsigned long end_pfn)
@@ -813,8 +813,12 @@
 			putback_lru_pages(&source);
 			goto out;
 		}
-		/* this function returns # of failed pages */
-		ret = migrate_pages(&source, hotremove_migrate_alloc, 0,
+
+		/*
+		 * alloc_migrate_target should be improooooved!!
+		 * migrate_pages returns # of failed pages.
+		 */
+		ret = migrate_pages(&source, alloc_migrate_target, 0,
 							true, MIGRATE_SYNC);
 		if (ret)
 			putback_lru_pages(&source);
@@ -870,7 +874,7 @@
 	return offlined;
 }
 
-static int __ref offline_pages(unsigned long start_pfn,
+static int __ref __offline_pages(unsigned long start_pfn,
 		  unsigned long end_pfn, unsigned long timeout)
 {
 	unsigned long pfn, nr_pages, expire;
@@ -970,8 +974,13 @@
 
 	init_per_zone_wmark_min();
 
-	if (!populated_zone(zone))
+	if (!populated_zone(zone)) {
 		zone_pcp_reset(zone);
+		mutex_lock(&zonelists_mutex);
+		build_all_zonelists(NULL, NULL);
+		mutex_unlock(&zonelists_mutex);
+	} else
+		zone_pcp_update(zone);
 
 	if (!node_present_pages(node)) {
 		node_clear_state(node, N_HIGH_MEMORY);
@@ -998,15 +1007,55 @@
 	return ret;
 }
 
+int offline_pages(unsigned long start_pfn, unsigned long nr_pages)
+{
+	return __offline_pages(start_pfn, start_pfn + nr_pages, 120 * HZ);
+}
+
 int remove_memory(u64 start, u64 size)
 {
+	struct memory_block *mem = NULL;
+	struct mem_section *section;
 	unsigned long start_pfn, end_pfn;
+	unsigned long pfn, section_nr;
+	int ret;
 
 	start_pfn = PFN_DOWN(start);
 	end_pfn = start_pfn + PFN_DOWN(size);
-	return offline_pages(start_pfn, end_pfn, 120 * HZ);
+
+	for (pfn = start_pfn; pfn < end_pfn; pfn += PAGES_PER_SECTION) {
+		section_nr = pfn_to_section_nr(pfn);
+		if (!present_section_nr(section_nr))
+			continue;
+
+		section = __nr_to_section(section_nr);
+		/* same memblock? */
+		if (mem)
+			if ((section_nr >= mem->start_section_nr) &&
+			    (section_nr <= mem->end_section_nr))
+				continue;
+
+		mem = find_memory_block_hinted(section, mem);
+		if (!mem)
+			continue;
+
+		ret = offline_memory_block(mem);
+		if (ret) {
+			kobject_put(&mem->dev.kobj);
+			return ret;
+		}
+	}
+
+	if (mem)
+		kobject_put(&mem->dev.kobj);
+
+	return 0;
 }
 #else
+int offline_pages(unsigned long start_pfn, unsigned long nr_pages)
+{
+	return -EINVAL;
+}
 int remove_memory(u64 start, u64 size)
 {
 	return -EINVAL;
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 4ada3be..0b78fb9 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -607,6 +607,42 @@
 	return first;
 }
 
+/*
+ * Apply policy to a single VMA
+ * This must be called with the mmap_sem held for writing.
+ */
+static int vma_replace_policy(struct vm_area_struct *vma,
+						struct mempolicy *pol)
+{
+	int err;
+	struct mempolicy *old;
+	struct mempolicy *new;
+
+	pr_debug("vma %lx-%lx/%lx vm_ops %p vm_file %p set_policy %p\n",
+		 vma->vm_start, vma->vm_end, vma->vm_pgoff,
+		 vma->vm_ops, vma->vm_file,
+		 vma->vm_ops ? vma->vm_ops->set_policy : NULL);
+
+	new = mpol_dup(pol);
+	if (IS_ERR(new))
+		return PTR_ERR(new);
+
+	if (vma->vm_ops && vma->vm_ops->set_policy) {
+		err = vma->vm_ops->set_policy(vma, new);
+		if (err)
+			goto err_out;
+	}
+
+	old = vma->vm_policy;
+	vma->vm_policy = new; /* protected by mmap_sem */
+	mpol_put(old);
+
+	return 0;
+ err_out:
+	mpol_put(new);
+	return err;
+}
+
 /* Step 2: apply policy to a range and do splits. */
 static int mbind_range(struct mm_struct *mm, unsigned long start,
 		       unsigned long end, struct mempolicy *new_pol)
@@ -655,23 +691,9 @@
 			if (err)
 				goto out;
 		}
-
-		/*
-		 * Apply policy to a single VMA. The reference counting of
-		 * policy for vma_policy linkages has already been handled by
-		 * vma_merge and split_vma as necessary. If this is a shared
-		 * policy then ->set_policy will increment the reference count
-		 * for an sp node.
-		 */
-		pr_debug("vma %lx-%lx/%lx vm_ops %p vm_file %p set_policy %p\n",
-			vma->vm_start, vma->vm_end, vma->vm_pgoff,
-			vma->vm_ops, vma->vm_file,
-			vma->vm_ops ? vma->vm_ops->set_policy : NULL);
-		if (vma->vm_ops && vma->vm_ops->set_policy) {
-			err = vma->vm_ops->set_policy(vma, new_pol);
-			if (err)
-				goto out;
-		}
+		err = vma_replace_policy(vma, new_pol);
+		if (err)
+			goto out;
 	}
 
  out:
@@ -924,15 +946,18 @@
 	nodemask_t nmask;
 	LIST_HEAD(pagelist);
 	int err = 0;
-	struct vm_area_struct *vma;
 
 	nodes_clear(nmask);
 	node_set(source, nmask);
 
-	vma = check_range(mm, mm->mmap->vm_start, mm->task_size, &nmask,
+	/*
+	 * This does not "check" the range but isolates all pages that
+	 * need migration.  Between passing in the full user address
+	 * space range and MPOL_MF_DISCONTIG_OK, this call can not fail.
+	 */
+	VM_BUG_ON(!(flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)));
+	check_range(mm, mm->mmap->vm_start, mm->task_size, &nmask,
 			flags | MPOL_MF_DISCONTIG_OK, &pagelist);
-	if (IS_ERR(vma))
-		return PTR_ERR(vma);
 
 	if (!list_empty(&pagelist)) {
 		err = migrate_pages(&pagelist, new_node_page, dest,
@@ -1530,8 +1555,18 @@
 									addr);
 			if (vpol)
 				pol = vpol;
-		} else if (vma->vm_policy)
+		} else if (vma->vm_policy) {
 			pol = vma->vm_policy;
+
+			/*
+			 * shmem_alloc_page() passes MPOL_F_SHARED policy with
+			 * a pseudo vma whose vma->vm_ops=NULL. Take a reference
+			 * count on these policies which will be dropped by
+			 * mpol_cond_put() later
+			 */
+			if (mpol_needs_cond_ref(pol))
+				mpol_get(pol);
+		}
 	}
 	if (!pol)
 		pol = &default_policy;
@@ -2061,7 +2096,7 @@
  */
 
 /* lookup first element intersecting start-end */
-/* Caller holds sp->lock */
+/* Caller holds sp->mutex */
 static struct sp_node *
 sp_lookup(struct shared_policy *sp, unsigned long start, unsigned long end)
 {
@@ -2125,36 +2160,50 @@
 
 	if (!sp->root.rb_node)
 		return NULL;
-	spin_lock(&sp->lock);
+	mutex_lock(&sp->mutex);
 	sn = sp_lookup(sp, idx, idx+1);
 	if (sn) {
 		mpol_get(sn->policy);
 		pol = sn->policy;
 	}
-	spin_unlock(&sp->lock);
+	mutex_unlock(&sp->mutex);
 	return pol;
 }
 
+static void sp_free(struct sp_node *n)
+{
+	mpol_put(n->policy);
+	kmem_cache_free(sn_cache, n);
+}
+
 static void sp_delete(struct shared_policy *sp, struct sp_node *n)
 {
 	pr_debug("deleting %lx-l%lx\n", n->start, n->end);
 	rb_erase(&n->nd, &sp->root);
-	mpol_put(n->policy);
-	kmem_cache_free(sn_cache, n);
+	sp_free(n);
 }
 
 static struct sp_node *sp_alloc(unsigned long start, unsigned long end,
 				struct mempolicy *pol)
 {
-	struct sp_node *n = kmem_cache_alloc(sn_cache, GFP_KERNEL);
+	struct sp_node *n;
+	struct mempolicy *newpol;
 
+	n = kmem_cache_alloc(sn_cache, GFP_KERNEL);
 	if (!n)
 		return NULL;
+
+	newpol = mpol_dup(pol);
+	if (IS_ERR(newpol)) {
+		kmem_cache_free(sn_cache, n);
+		return NULL;
+	}
+	newpol->flags |= MPOL_F_SHARED;
+
 	n->start = start;
 	n->end = end;
-	mpol_get(pol);
-	pol->flags |= MPOL_F_SHARED;	/* for unref */
-	n->policy = pol;
+	n->policy = newpol;
+
 	return n;
 }
 
@@ -2162,10 +2211,10 @@
 static int shared_policy_replace(struct shared_policy *sp, unsigned long start,
 				 unsigned long end, struct sp_node *new)
 {
-	struct sp_node *n, *new2 = NULL;
+	struct sp_node *n;
+	int ret = 0;
 
-restart:
-	spin_lock(&sp->lock);
+	mutex_lock(&sp->mutex);
 	n = sp_lookup(sp, start, end);
 	/* Take care of old policies in the same range. */
 	while (n && n->start < end) {
@@ -2178,16 +2227,14 @@
 		} else {
 			/* Old policy spanning whole new range. */
 			if (n->end > end) {
+				struct sp_node *new2;
+				new2 = sp_alloc(end, n->end, n->policy);
 				if (!new2) {
-					spin_unlock(&sp->lock);
-					new2 = sp_alloc(end, n->end, n->policy);
-					if (!new2)
-						return -ENOMEM;
-					goto restart;
+					ret = -ENOMEM;
+					goto out;
 				}
 				n->end = start;
 				sp_insert(sp, new2);
-				new2 = NULL;
 				break;
 			} else
 				n->end = start;
@@ -2198,12 +2245,9 @@
 	}
 	if (new)
 		sp_insert(sp, new);
-	spin_unlock(&sp->lock);
-	if (new2) {
-		mpol_put(new2->policy);
-		kmem_cache_free(sn_cache, new2);
-	}
-	return 0;
+out:
+	mutex_unlock(&sp->mutex);
+	return ret;
 }
 
 /**
@@ -2221,7 +2265,7 @@
 	int ret;
 
 	sp->root = RB_ROOT;		/* empty tree == default mempolicy */
-	spin_lock_init(&sp->lock);
+	mutex_init(&sp->mutex);
 
 	if (mpol) {
 		struct vm_area_struct pvma;
@@ -2275,7 +2319,7 @@
 	}
 	err = shared_policy_replace(info, vma->vm_pgoff, vma->vm_pgoff+sz, new);
 	if (err && new)
-		kmem_cache_free(sn_cache, new);
+		sp_free(new);
 	return err;
 }
 
@@ -2287,16 +2331,14 @@
 
 	if (!p->root.rb_node)
 		return;
-	spin_lock(&p->lock);
+	mutex_lock(&p->mutex);
 	next = rb_first(&p->root);
 	while (next) {
 		n = rb_entry(next, struct sp_node, nd);
 		next = rb_next(&n->nd);
-		rb_erase(&n->nd, &p->root);
-		mpol_put(n->policy);
-		kmem_cache_free(sn_cache, n);
+		sp_delete(p, n);
 	}
-	spin_unlock(&p->lock);
+	mutex_unlock(&p->mutex);
 }
 
 /* assumes fs == KERNEL_DS */
diff --git a/mm/mlock.c b/mm/mlock.c
index ef726e8..f0b9ce5 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -51,15 +51,13 @@
 /*
  *  LRU accounting for clear_page_mlock()
  */
-void __clear_page_mlock(struct page *page)
+void clear_page_mlock(struct page *page)
 {
-	VM_BUG_ON(!PageLocked(page));
-
-	if (!page->mapping) {	/* truncated ? */
+	if (!TestClearPageMlocked(page))
 		return;
-	}
 
-	dec_zone_page_state(page, NR_MLOCK);
+	mod_zone_page_state(page_zone(page), NR_MLOCK,
+			    -hpage_nr_pages(page));
 	count_vm_event(UNEVICTABLE_PGCLEARED);
 	if (!isolate_lru_page(page)) {
 		putback_lru_page(page);
@@ -81,7 +79,8 @@
 	BUG_ON(!PageLocked(page));
 
 	if (!TestSetPageMlocked(page)) {
-		inc_zone_page_state(page, NR_MLOCK);
+		mod_zone_page_state(page_zone(page), NR_MLOCK,
+				    hpage_nr_pages(page));
 		count_vm_event(UNEVICTABLE_PGMLOCKED);
 		if (!isolate_lru_page(page))
 			putback_lru_page(page);
@@ -108,7 +107,8 @@
 	BUG_ON(!PageLocked(page));
 
 	if (TestClearPageMlocked(page)) {
-		dec_zone_page_state(page, NR_MLOCK);
+		mod_zone_page_state(page_zone(page), NR_MLOCK,
+				    -hpage_nr_pages(page));
 		if (!isolate_lru_page(page)) {
 			int ret = SWAP_AGAIN;
 
@@ -227,7 +227,7 @@
 	if (vma->vm_flags & (VM_IO | VM_PFNMAP))
 		goto no_mlock;
 
-	if (!((vma->vm_flags & (VM_DONTEXPAND | VM_RESERVED)) ||
+	if (!((vma->vm_flags & VM_DONTEXPAND) ||
 			is_vm_hugetlb_page(vma) ||
 			vma == get_gate_vma(current->mm))) {
 
@@ -290,14 +290,7 @@
 		page = follow_page(vma, addr, FOLL_GET | FOLL_DUMP);
 		if (page && !IS_ERR(page)) {
 			lock_page(page);
-			/*
-			 * Like in __mlock_vma_pages_range(),
-			 * because we lock page here and migration is
-			 * blocked by the elevated reference, we need
-			 * only check for file-cache page truncation.
-			 */
-			if (page->mapping)
-				munlock_vma_page(page);
+			munlock_vma_page(page);
 			unlock_page(page);
 			put_page(page);
 		}
diff --git a/mm/mmap.c b/mm/mmap.c
index 872441e..2d94235 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -51,12 +51,6 @@
 		struct vm_area_struct *vma, struct vm_area_struct *prev,
 		unsigned long start, unsigned long end);
 
-/*
- * WARNING: the debugging will use recursive algorithms so never enable this
- * unless you know what you are doing.
- */
-#undef DEBUG_MM_RB
-
 /* description of effects of mapping type and prot in current implementation.
  * this is due to the limited x86 page protection hardware.  The expected
  * behavior is in parens:
@@ -199,14 +193,14 @@
 
 	flush_dcache_mmap_lock(mapping);
 	if (unlikely(vma->vm_flags & VM_NONLINEAR))
-		list_del_init(&vma->shared.vm_set.list);
+		list_del_init(&vma->shared.nonlinear);
 	else
-		vma_prio_tree_remove(vma, &mapping->i_mmap);
+		vma_interval_tree_remove(vma, &mapping->i_mmap);
 	flush_dcache_mmap_unlock(mapping);
 }
 
 /*
- * Unlink a file-based vm structure from its prio_tree, to hide
+ * Unlink a file-based vm structure from its interval tree, to hide
  * vma from rmap and vmtruncate before freeing its page tables.
  */
 void unlink_file_vma(struct vm_area_struct *vma)
@@ -231,11 +225,8 @@
 	might_sleep();
 	if (vma->vm_ops && vma->vm_ops->close)
 		vma->vm_ops->close(vma);
-	if (vma->vm_file) {
+	if (vma->vm_file)
 		fput(vma->vm_file);
-		if (vma->vm_flags & VM_EXECUTABLE)
-			removed_exe_file_vma(vma->vm_mm);
-	}
 	mpol_put(vma_policy(vma));
 	kmem_cache_free(vm_area_cachep, vma);
 	return next;
@@ -306,7 +297,7 @@
 	return retval;
 }
 
-#ifdef DEBUG_MM_RB
+#ifdef CONFIG_DEBUG_VM_RB
 static int browse_rb(struct rb_root *root)
 {
 	int i = 0, j;
@@ -340,9 +331,12 @@
 {
 	int bug = 0;
 	int i = 0;
-	struct vm_area_struct *tmp = mm->mmap;
-	while (tmp) {
-		tmp = tmp->vm_next;
+	struct vm_area_struct *vma = mm->mmap;
+	while (vma) {
+		struct anon_vma_chain *avc;
+		list_for_each_entry(avc, &vma->anon_vma_chain, same_vma)
+			anon_vma_interval_tree_verify(avc);
+		vma = vma->vm_next;
 		i++;
 	}
 	if (i != mm->map_count)
@@ -356,17 +350,46 @@
 #define validate_mm(mm) do { } while (0)
 #endif
 
-static struct vm_area_struct *
-find_vma_prepare(struct mm_struct *mm, unsigned long addr,
-		struct vm_area_struct **pprev, struct rb_node ***rb_link,
-		struct rb_node ** rb_parent)
+/*
+ * vma has some anon_vma assigned, and is already inserted on that
+ * anon_vma's interval trees.
+ *
+ * Before updating the vma's vm_start / vm_end / vm_pgoff fields, the
+ * vma must be removed from the anon_vma's interval trees using
+ * anon_vma_interval_tree_pre_update_vma().
+ *
+ * After the update, the vma will be reinserted using
+ * anon_vma_interval_tree_post_update_vma().
+ *
+ * The entire update must be protected by exclusive mmap_sem and by
+ * the root anon_vma's mutex.
+ */
+static inline void
+anon_vma_interval_tree_pre_update_vma(struct vm_area_struct *vma)
 {
-	struct vm_area_struct * vma;
-	struct rb_node ** __rb_link, * __rb_parent, * rb_prev;
+	struct anon_vma_chain *avc;
+
+	list_for_each_entry(avc, &vma->anon_vma_chain, same_vma)
+		anon_vma_interval_tree_remove(avc, &avc->anon_vma->rb_root);
+}
+
+static inline void
+anon_vma_interval_tree_post_update_vma(struct vm_area_struct *vma)
+{
+	struct anon_vma_chain *avc;
+
+	list_for_each_entry(avc, &vma->anon_vma_chain, same_vma)
+		anon_vma_interval_tree_insert(avc, &avc->anon_vma->rb_root);
+}
+
+static int find_vma_links(struct mm_struct *mm, unsigned long addr,
+		unsigned long end, struct vm_area_struct **pprev,
+		struct rb_node ***rb_link, struct rb_node **rb_parent)
+{
+	struct rb_node **__rb_link, *__rb_parent, *rb_prev;
 
 	__rb_link = &mm->mm_rb.rb_node;
 	rb_prev = __rb_parent = NULL;
-	vma = NULL;
 
 	while (*__rb_link) {
 		struct vm_area_struct *vma_tmp;
@@ -375,9 +398,9 @@
 		vma_tmp = rb_entry(__rb_parent, struct vm_area_struct, vm_rb);
 
 		if (vma_tmp->vm_end > addr) {
-			vma = vma_tmp;
-			if (vma_tmp->vm_start <= addr)
-				break;
+			/* Fail if an existing vma overlaps the area */
+			if (vma_tmp->vm_start < end)
+				return -ENOMEM;
 			__rb_link = &__rb_parent->rb_left;
 		} else {
 			rb_prev = __rb_parent;
@@ -390,7 +413,7 @@
 		*pprev = rb_entry(rb_prev, struct vm_area_struct, vm_rb);
 	*rb_link = __rb_link;
 	*rb_parent = __rb_parent;
-	return vma;
+	return 0;
 }
 
 void __vma_link_rb(struct mm_struct *mm, struct vm_area_struct *vma,
@@ -417,7 +440,7 @@
 		if (unlikely(vma->vm_flags & VM_NONLINEAR))
 			vma_nonlinear_insert(vma, &mapping->i_mmap_nonlinear);
 		else
-			vma_prio_tree_insert(vma, &mapping->i_mmap);
+			vma_interval_tree_insert(vma, &mapping->i_mmap);
 		flush_dcache_mmap_unlock(mapping);
 	}
 }
@@ -455,15 +478,16 @@
 
 /*
  * Helper for vma_adjust() in the split_vma insert case: insert a vma into the
- * mm's list and rbtree.  It has already been inserted into the prio_tree.
+ * mm's list and rbtree.  It has already been inserted into the interval tree.
  */
 static void __insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vma)
 {
-	struct vm_area_struct *__vma, *prev;
+	struct vm_area_struct *prev;
 	struct rb_node **rb_link, *rb_parent;
 
-	__vma = find_vma_prepare(mm, vma->vm_start,&prev, &rb_link, &rb_parent);
-	BUG_ON(__vma && __vma->vm_start < vma->vm_end);
+	if (find_vma_links(mm, vma->vm_start, vma->vm_end,
+			   &prev, &rb_link, &rb_parent))
+		BUG();
 	__vma_link(mm, vma, prev, rb_link, rb_parent);
 	mm->map_count++;
 }
@@ -496,7 +520,7 @@
 	struct vm_area_struct *next = vma->vm_next;
 	struct vm_area_struct *importer = NULL;
 	struct address_space *mapping = NULL;
-	struct prio_tree_root *root = NULL;
+	struct rb_root *root = NULL;
 	struct anon_vma *anon_vma = NULL;
 	struct file *file = vma->vm_file;
 	long adjust_next = 0;
@@ -559,7 +583,7 @@
 		mutex_lock(&mapping->i_mmap_mutex);
 		if (insert) {
 			/*
-			 * Put into prio_tree now, so instantiated pages
+			 * Put into interval tree now, so instantiated pages
 			 * are visible to arm/parisc __flush_dcache_page
 			 * throughout; but we cannot insert into address
 			 * space until vma start or end is updated.
@@ -570,22 +594,23 @@
 
 	vma_adjust_trans_huge(vma, start, end, adjust_next);
 
-	/*
-	 * When changing only vma->vm_end, we don't really need anon_vma
-	 * lock. This is a fairly rare case by itself, but the anon_vma
-	 * lock may be shared between many sibling processes.  Skipping
-	 * the lock for brk adjustments makes a difference sometimes.
-	 */
-	if (vma->anon_vma && (importer || start != vma->vm_start)) {
-		anon_vma = vma->anon_vma;
+	anon_vma = vma->anon_vma;
+	if (!anon_vma && adjust_next)
+		anon_vma = next->anon_vma;
+	if (anon_vma) {
+		VM_BUG_ON(adjust_next && next->anon_vma &&
+			  anon_vma != next->anon_vma);
 		anon_vma_lock(anon_vma);
+		anon_vma_interval_tree_pre_update_vma(vma);
+		if (adjust_next)
+			anon_vma_interval_tree_pre_update_vma(next);
 	}
 
 	if (root) {
 		flush_dcache_mmap_lock(mapping);
-		vma_prio_tree_remove(vma, root);
+		vma_interval_tree_remove(vma, root);
 		if (adjust_next)
-			vma_prio_tree_remove(next, root);
+			vma_interval_tree_remove(next, root);
 	}
 
 	vma->vm_start = start;
@@ -598,8 +623,8 @@
 
 	if (root) {
 		if (adjust_next)
-			vma_prio_tree_insert(next, root);
-		vma_prio_tree_insert(vma, root);
+			vma_interval_tree_insert(next, root);
+		vma_interval_tree_insert(vma, root);
 		flush_dcache_mmap_unlock(mapping);
 	}
 
@@ -620,8 +645,12 @@
 		__insert_vm_struct(mm, insert);
 	}
 
-	if (anon_vma)
+	if (anon_vma) {
+		anon_vma_interval_tree_post_update_vma(vma);
+		if (adjust_next)
+			anon_vma_interval_tree_post_update_vma(next);
 		anon_vma_unlock(anon_vma);
+	}
 	if (mapping)
 		mutex_unlock(&mapping->i_mmap_mutex);
 
@@ -636,8 +665,6 @@
 		if (file) {
 			uprobe_munmap(next, next->vm_start, next->vm_end);
 			fput(file);
-			if (next->vm_flags & VM_EXECUTABLE)
-				removed_exe_file_vma(mm);
 		}
 		if (next->anon_vma)
 			anon_vma_merge(vma, next);
@@ -669,8 +696,7 @@
 static inline int is_mergeable_vma(struct vm_area_struct *vma,
 			struct file *file, unsigned long vm_flags)
 {
-	/* VM_CAN_NONLINEAR may get set later by f_op->mmap() */
-	if ((vma->vm_flags ^ vm_flags) & ~VM_CAN_NONLINEAR)
+	if (vma->vm_flags ^ vm_flags)
 		return 0;
 	if (vma->vm_file != file)
 		return 0;
@@ -951,8 +977,6 @@
 			mm->exec_vm += pages;
 	} else if (flags & stack_flags)
 		mm->stack_vm += pages;
-	if (flags & (VM_RESERVED|VM_IO))
-		mm->reserved_vm += pages;
 }
 #endif /* CONFIG_PROC_FS */
 
@@ -1190,7 +1214,7 @@
 		return 0;
 
 	/* Specialty mapping? */
-	if (vm_flags & (VM_PFNMAP|VM_INSERTPAGE))
+	if (vm_flags & VM_PFNMAP)
 		return 0;
 
 	/* Can the mapping track the dirty pages? */
@@ -1229,8 +1253,7 @@
 	/* Clear old maps */
 	error = -ENOMEM;
 munmap_back:
-	vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
-	if (vma && vma->vm_start < addr + len) {
+	if (find_vma_links(mm, addr, addr + len, &prev, &rb_link, &rb_parent)) {
 		if (do_munmap(mm, addr, len))
 			return -ENOMEM;
 		goto munmap_back;
@@ -1305,8 +1328,6 @@
 		error = file->f_op->mmap(file, vma);
 		if (error)
 			goto unmap_and_free_vma;
-		if (vm_flags & VM_EXECUTABLE)
-			added_exe_file_vma(mm);
 
 		/* Can addr have changed??
 		 *
@@ -1757,13 +1778,16 @@
 		if (vma->vm_pgoff + (size >> PAGE_SHIFT) >= vma->vm_pgoff) {
 			error = acct_stack_growth(vma, size, grow);
 			if (!error) {
+				anon_vma_interval_tree_pre_update_vma(vma);
 				vma->vm_end = address;
+				anon_vma_interval_tree_post_update_vma(vma);
 				perf_event_mmap(vma);
 			}
 		}
 	}
 	vma_unlock_anon_vma(vma);
 	khugepaged_enter_vma_merge(vma);
+	validate_mm(vma->vm_mm);
 	return error;
 }
 #endif /* CONFIG_STACK_GROWSUP || CONFIG_IA64 */
@@ -1807,14 +1831,17 @@
 		if (grow <= vma->vm_pgoff) {
 			error = acct_stack_growth(vma, size, grow);
 			if (!error) {
+				anon_vma_interval_tree_pre_update_vma(vma);
 				vma->vm_start = address;
 				vma->vm_pgoff -= grow;
+				anon_vma_interval_tree_post_update_vma(vma);
 				perf_event_mmap(vma);
 			}
 		}
 	}
 	vma_unlock_anon_vma(vma);
 	khugepaged_enter_vma_merge(vma);
+	validate_mm(vma->vm_mm);
 	return error;
 }
 
@@ -1988,11 +2015,8 @@
 	if (anon_vma_clone(new, vma))
 		goto out_free_mpol;
 
-	if (new->vm_file) {
+	if (new->vm_file)
 		get_file(new->vm_file);
-		if (vma->vm_flags & VM_EXECUTABLE)
-			added_exe_file_vma(mm);
-	}
 
 	if (new->vm_ops && new->vm_ops->open)
 		new->vm_ops->open(new);
@@ -2010,11 +2034,8 @@
 	/* Clean everything up if vma_adjust failed. */
 	if (new->vm_ops && new->vm_ops->close)
 		new->vm_ops->close(new);
-	if (new->vm_file) {
-		if (vma->vm_flags & VM_EXECUTABLE)
-			removed_exe_file_vma(mm);
+	if (new->vm_file)
 		fput(new->vm_file);
-	}
 	unlink_anon_vmas(new);
  out_free_mpol:
 	mpol_put(pol);
@@ -2199,8 +2220,7 @@
 	 * Clear old maps.  this also does some error checking for us
 	 */
  munmap_back:
-	vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
-	if (vma && vma->vm_start < addr + len) {
+	if (find_vma_links(mm, addr, addr + len, &prev, &rb_link, &rb_parent)) {
 		if (do_munmap(mm, addr, len))
 			return -ENOMEM;
 		goto munmap_back;
@@ -2314,10 +2334,10 @@
  * and into the inode's i_mmap tree.  If vm_file is non-NULL
  * then i_mmap_mutex is taken here.
  */
-int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma)
+int insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vma)
 {
-	struct vm_area_struct * __vma, * prev;
-	struct rb_node ** rb_link, * rb_parent;
+	struct vm_area_struct *prev;
+	struct rb_node **rb_link, *rb_parent;
 
 	/*
 	 * The vm_pgoff of a purely anonymous vma should be irrelevant
@@ -2335,8 +2355,8 @@
 		BUG_ON(vma->anon_vma);
 		vma->vm_pgoff = vma->vm_start >> PAGE_SHIFT;
 	}
-	__vma = find_vma_prepare(mm,vma->vm_start,&prev,&rb_link,&rb_parent);
-	if (__vma && __vma->vm_start < vma->vm_end)
+	if (find_vma_links(mm, vma->vm_start, vma->vm_end,
+			   &prev, &rb_link, &rb_parent))
 		return -ENOMEM;
 	if ((vma->vm_flags & VM_ACCOUNT) &&
 	     security_vm_enough_memory_mm(mm, vma_pages(vma)))
@@ -2351,7 +2371,8 @@
  * prior to moving page table entries, to effect an mremap move.
  */
 struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
-	unsigned long addr, unsigned long len, pgoff_t pgoff)
+	unsigned long addr, unsigned long len, pgoff_t pgoff,
+	bool *need_rmap_locks)
 {
 	struct vm_area_struct *vma = *vmap;
 	unsigned long vma_start = vma->vm_start;
@@ -2370,7 +2391,8 @@
 		faulted_in_anon_vma = false;
 	}
 
-	find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
+	if (find_vma_links(mm, addr, addr + len, &prev, &rb_link, &rb_parent))
+		return NULL;	/* should never get here */
 	new_vma = vma_merge(mm, prev, addr, addr + len, vma->vm_flags,
 			vma->anon_vma, vma->vm_file, pgoff, vma_policy(vma));
 	if (new_vma) {
@@ -2392,32 +2414,29 @@
 			 * linear if there are no pages mapped yet.
 			 */
 			VM_BUG_ON(faulted_in_anon_vma);
-			*vmap = new_vma;
-		} else
-			anon_vma_moveto_tail(new_vma);
+			*vmap = vma = new_vma;
+		}
+		*need_rmap_locks = (new_vma->vm_pgoff <= vma->vm_pgoff);
 	} else {
 		new_vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
 		if (new_vma) {
 			*new_vma = *vma;
-			pol = mpol_dup(vma_policy(vma));
-			if (IS_ERR(pol))
-				goto out_free_vma;
-			INIT_LIST_HEAD(&new_vma->anon_vma_chain);
-			if (anon_vma_clone(new_vma, vma))
-				goto out_free_mempol;
-			vma_set_policy(new_vma, pol);
 			new_vma->vm_start = addr;
 			new_vma->vm_end = addr + len;
 			new_vma->vm_pgoff = pgoff;
-			if (new_vma->vm_file) {
+			pol = mpol_dup(vma_policy(vma));
+			if (IS_ERR(pol))
+				goto out_free_vma;
+			vma_set_policy(new_vma, pol);
+			INIT_LIST_HEAD(&new_vma->anon_vma_chain);
+			if (anon_vma_clone(new_vma, vma))
+				goto out_free_mempol;
+			if (new_vma->vm_file)
 				get_file(new_vma->vm_file);
-
-				if (vma->vm_flags & VM_EXECUTABLE)
-					added_exe_file_vma(mm);
-			}
 			if (new_vma->vm_ops && new_vma->vm_ops->open)
 				new_vma->vm_ops->open(new_vma);
 			vma_link(mm, new_vma, prev, rb_link, rb_parent);
+			*need_rmap_locks = false;
 		}
 	}
 	return new_vma;
@@ -2535,7 +2554,7 @@
 
 static void vm_lock_anon_vma(struct mm_struct *mm, struct anon_vma *anon_vma)
 {
-	if (!test_bit(0, (unsigned long *) &anon_vma->root->head.next)) {
+	if (!test_bit(0, (unsigned long *) &anon_vma->root->rb_root.rb_node)) {
 		/*
 		 * The LSB of head.next can't change from under us
 		 * because we hold the mm_all_locks_mutex.
@@ -2551,7 +2570,7 @@
 		 * anon_vma->root->mutex.
 		 */
 		if (__test_and_set_bit(0, (unsigned long *)
-				       &anon_vma->root->head.next))
+				       &anon_vma->root->rb_root.rb_node))
 			BUG();
 	}
 }
@@ -2592,7 +2611,7 @@
  * A single task can't take more than one mm_take_all_locks() in a row
  * or it would deadlock.
  *
- * The LSB in anon_vma->head.next and the AS_MM_ALL_LOCKS bitflag in
+ * The LSB in anon_vma->rb_root.rb_node and the AS_MM_ALL_LOCKS bitflag in
  * mapping->flags avoid to take the same lock twice, if more than one
  * vma in this mm is backed by the same anon_vma or address_space.
  *
@@ -2639,13 +2658,13 @@
 
 static void vm_unlock_anon_vma(struct anon_vma *anon_vma)
 {
-	if (test_bit(0, (unsigned long *) &anon_vma->root->head.next)) {
+	if (test_bit(0, (unsigned long *) &anon_vma->root->rb_root.rb_node)) {
 		/*
 		 * The LSB of head.next can't change to 0 from under
 		 * us because we hold the mm_all_locks_mutex.
 		 *
 		 * We must however clear the bitflag before unlocking
-		 * the vma so the users using the anon_vma->head will
+		 * the vma so the users using the anon_vma->rb_root will
 		 * never see our bitflag.
 		 *
 		 * No need of atomic instructions here, head.next
@@ -2653,7 +2672,7 @@
 		 * anon_vma->root->mutex.
 		 */
 		if (!__test_and_clear_bit(0, (unsigned long *)
-					  &anon_vma->root->head.next))
+					  &anon_vma->root->rb_root.rb_node))
 			BUG();
 		anon_vma_unlock(anon_vma);
 	}
diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c
index 862b608..479a1e7 100644
--- a/mm/mmu_notifier.c
+++ b/mm/mmu_notifier.c
@@ -14,10 +14,14 @@
 #include <linux/export.h>
 #include <linux/mm.h>
 #include <linux/err.h>
+#include <linux/srcu.h>
 #include <linux/rcupdate.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 
+/* global SRCU for all MMs */
+static struct srcu_struct srcu;
+
 /*
  * This function can't run concurrently against mmu_notifier_register
  * because mm->mm_users > 0 during mmu_notifier_register and exit_mmap
@@ -25,8 +29,8 @@
  * in parallel despite there being no task using this mm any more,
  * through the vmas outside of the exit_mmap context, such as with
  * vmtruncate. This serializes against mmu_notifier_unregister with
- * the mmu_notifier_mm->lock in addition to RCU and it serializes
- * against the other mmu notifiers with RCU. struct mmu_notifier_mm
+ * the mmu_notifier_mm->lock in addition to SRCU and it serializes
+ * against the other mmu notifiers with SRCU. struct mmu_notifier_mm
  * can't go away from under us as exit_mmap holds an mm_count pin
  * itself.
  */
@@ -34,12 +38,13 @@
 {
 	struct mmu_notifier *mn;
 	struct hlist_node *n;
+	int id;
 
 	/*
-	 * RCU here will block mmu_notifier_unregister until
+	 * SRCU here will block mmu_notifier_unregister until
 	 * ->release returns.
 	 */
-	rcu_read_lock();
+	id = srcu_read_lock(&srcu);
 	hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist)
 		/*
 		 * if ->release runs before mmu_notifier_unregister it
@@ -50,7 +55,7 @@
 		 */
 		if (mn->ops->release)
 			mn->ops->release(mn, mm);
-	rcu_read_unlock();
+	srcu_read_unlock(&srcu, id);
 
 	spin_lock(&mm->mmu_notifier_mm->lock);
 	while (unlikely(!hlist_empty(&mm->mmu_notifier_mm->list))) {
@@ -68,7 +73,7 @@
 	spin_unlock(&mm->mmu_notifier_mm->lock);
 
 	/*
-	 * synchronize_rcu here prevents mmu_notifier_release to
+	 * synchronize_srcu here prevents mmu_notifier_release to
 	 * return to exit_mmap (which would proceed freeing all pages
 	 * in the mm) until the ->release method returns, if it was
 	 * invoked by mmu_notifier_unregister.
@@ -76,7 +81,7 @@
 	 * The mmu_notifier_mm can't go away from under us because one
 	 * mm_count is hold by exit_mmap.
 	 */
-	synchronize_rcu();
+	synchronize_srcu(&srcu);
 }
 
 /*
@@ -89,14 +94,14 @@
 {
 	struct mmu_notifier *mn;
 	struct hlist_node *n;
-	int young = 0;
+	int young = 0, id;
 
-	rcu_read_lock();
+	id = srcu_read_lock(&srcu);
 	hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist) {
 		if (mn->ops->clear_flush_young)
 			young |= mn->ops->clear_flush_young(mn, mm, address);
 	}
-	rcu_read_unlock();
+	srcu_read_unlock(&srcu, id);
 
 	return young;
 }
@@ -106,9 +111,9 @@
 {
 	struct mmu_notifier *mn;
 	struct hlist_node *n;
-	int young = 0;
+	int young = 0, id;
 
-	rcu_read_lock();
+	id = srcu_read_lock(&srcu);
 	hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist) {
 		if (mn->ops->test_young) {
 			young = mn->ops->test_young(mn, mm, address);
@@ -116,7 +121,7 @@
 				break;
 		}
 	}
-	rcu_read_unlock();
+	srcu_read_unlock(&srcu, id);
 
 	return young;
 }
@@ -126,19 +131,14 @@
 {
 	struct mmu_notifier *mn;
 	struct hlist_node *n;
+	int id;
 
-	rcu_read_lock();
+	id = srcu_read_lock(&srcu);
 	hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist) {
 		if (mn->ops->change_pte)
 			mn->ops->change_pte(mn, mm, address, pte);
-		/*
-		 * Some drivers don't have change_pte,
-		 * so we must call invalidate_page in that case.
-		 */
-		else if (mn->ops->invalidate_page)
-			mn->ops->invalidate_page(mn, mm, address);
 	}
-	rcu_read_unlock();
+	srcu_read_unlock(&srcu, id);
 }
 
 void __mmu_notifier_invalidate_page(struct mm_struct *mm,
@@ -146,13 +146,14 @@
 {
 	struct mmu_notifier *mn;
 	struct hlist_node *n;
+	int id;
 
-	rcu_read_lock();
+	id = srcu_read_lock(&srcu);
 	hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist) {
 		if (mn->ops->invalidate_page)
 			mn->ops->invalidate_page(mn, mm, address);
 	}
-	rcu_read_unlock();
+	srcu_read_unlock(&srcu, id);
 }
 
 void __mmu_notifier_invalidate_range_start(struct mm_struct *mm,
@@ -160,13 +161,14 @@
 {
 	struct mmu_notifier *mn;
 	struct hlist_node *n;
+	int id;
 
-	rcu_read_lock();
+	id = srcu_read_lock(&srcu);
 	hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist) {
 		if (mn->ops->invalidate_range_start)
 			mn->ops->invalidate_range_start(mn, mm, start, end);
 	}
-	rcu_read_unlock();
+	srcu_read_unlock(&srcu, id);
 }
 
 void __mmu_notifier_invalidate_range_end(struct mm_struct *mm,
@@ -174,13 +176,14 @@
 {
 	struct mmu_notifier *mn;
 	struct hlist_node *n;
+	int id;
 
-	rcu_read_lock();
+	id = srcu_read_lock(&srcu);
 	hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist) {
 		if (mn->ops->invalidate_range_end)
 			mn->ops->invalidate_range_end(mn, mm, start, end);
 	}
-	rcu_read_unlock();
+	srcu_read_unlock(&srcu, id);
 }
 
 static int do_mmu_notifier_register(struct mmu_notifier *mn,
@@ -192,22 +195,29 @@
 
 	BUG_ON(atomic_read(&mm->mm_users) <= 0);
 
-	ret = -ENOMEM;
-	mmu_notifier_mm = kmalloc(sizeof(struct mmu_notifier_mm), GFP_KERNEL);
-	if (unlikely(!mmu_notifier_mm))
-		goto out;
+	/*
+	* Verify that mmu_notifier_init() already run and the global srcu is
+	* initialized.
+	*/
+	BUG_ON(!srcu.per_cpu_ref);
 
 	if (take_mmap_sem)
 		down_write(&mm->mmap_sem);
 	ret = mm_take_all_locks(mm);
 	if (unlikely(ret))
-		goto out_cleanup;
+		goto out;
 
 	if (!mm_has_notifiers(mm)) {
+		mmu_notifier_mm = kmalloc(sizeof(struct mmu_notifier_mm),
+					GFP_KERNEL);
+		if (unlikely(!mmu_notifier_mm)) {
+			ret = -ENOMEM;
+			goto out_of_mem;
+		}
 		INIT_HLIST_HEAD(&mmu_notifier_mm->list);
 		spin_lock_init(&mmu_notifier_mm->lock);
+
 		mm->mmu_notifier_mm = mmu_notifier_mm;
-		mmu_notifier_mm = NULL;
 	}
 	atomic_inc(&mm->mm_count);
 
@@ -223,13 +233,12 @@
 	hlist_add_head(&mn->hlist, &mm->mmu_notifier_mm->list);
 	spin_unlock(&mm->mmu_notifier_mm->lock);
 
+out_of_mem:
 	mm_drop_all_locks(mm);
-out_cleanup:
+out:
 	if (take_mmap_sem)
 		up_write(&mm->mmap_sem);
-	/* kfree() does nothing if mmu_notifier_mm is NULL */
-	kfree(mmu_notifier_mm);
-out:
+
 	BUG_ON(atomic_read(&mm->mm_users) <= 0);
 	return ret;
 }
@@ -274,8 +283,8 @@
 /*
  * This releases the mm_count pin automatically and frees the mm
  * structure if it was the last user of it. It serializes against
- * running mmu notifiers with RCU and against mmu_notifier_unregister
- * with the unregister lock + RCU. All sptes must be dropped before
+ * running mmu notifiers with SRCU and against mmu_notifier_unregister
+ * with the unregister lock + SRCU. All sptes must be dropped before
  * calling mmu_notifier_unregister. ->release or any other notifier
  * method may be invoked concurrently with mmu_notifier_unregister,
  * and only after mmu_notifier_unregister returned we're guaranteed
@@ -287,11 +296,12 @@
 
 	if (!hlist_unhashed(&mn->hlist)) {
 		/*
-		 * RCU here will force exit_mmap to wait ->release to finish
+		 * SRCU here will force exit_mmap to wait ->release to finish
 		 * before freeing the pages.
 		 */
-		rcu_read_lock();
+		int id;
 
+		id = srcu_read_lock(&srcu);
 		/*
 		 * exit_mmap will block in mmu_notifier_release to
 		 * guarantee ->release is called before freeing the
@@ -299,7 +309,7 @@
 		 */
 		if (mn->ops->release)
 			mn->ops->release(mn, mm);
-		rcu_read_unlock();
+		srcu_read_unlock(&srcu, id);
 
 		spin_lock(&mm->mmu_notifier_mm->lock);
 		hlist_del_rcu(&mn->hlist);
@@ -310,10 +320,17 @@
 	 * Wait any running method to finish, of course including
 	 * ->release if it was run by mmu_notifier_relase instead of us.
 	 */
-	synchronize_rcu();
+	synchronize_srcu(&srcu);
 
 	BUG_ON(atomic_read(&mm->mm_count) <= 0);
 
 	mmdrop(mm);
 }
 EXPORT_SYMBOL_GPL(mmu_notifier_unregister);
+
+static int __init mmu_notifier_init(void)
+{
+	return init_srcu_struct(&srcu);
+}
+
+module_init(mmu_notifier_init);
diff --git a/mm/mremap.c b/mm/mremap.c
index cc06d0e..1b61c2d 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -71,22 +71,41 @@
 static void move_ptes(struct vm_area_struct *vma, pmd_t *old_pmd,
 		unsigned long old_addr, unsigned long old_end,
 		struct vm_area_struct *new_vma, pmd_t *new_pmd,
-		unsigned long new_addr)
+		unsigned long new_addr, bool need_rmap_locks)
 {
 	struct address_space *mapping = NULL;
+	struct anon_vma *anon_vma = NULL;
 	struct mm_struct *mm = vma->vm_mm;
 	pte_t *old_pte, *new_pte, pte;
 	spinlock_t *old_ptl, *new_ptl;
 
-	if (vma->vm_file) {
-		/*
-		 * Subtle point from Rajesh Venkatasubramanian: before
-		 * moving file-based ptes, we must lock truncate_pagecache
-		 * out, since it might clean the dst vma before the src vma,
-		 * and we propagate stale pages into the dst afterward.
-		 */
-		mapping = vma->vm_file->f_mapping;
-		mutex_lock(&mapping->i_mmap_mutex);
+	/*
+	 * When need_rmap_locks is true, we take the i_mmap_mutex and anon_vma
+	 * locks to ensure that rmap will always observe either the old or the
+	 * new ptes. This is the easiest way to avoid races with
+	 * truncate_pagecache(), page migration, etc...
+	 *
+	 * When need_rmap_locks is false, we use other ways to avoid
+	 * such races:
+	 *
+	 * - During exec() shift_arg_pages(), we use a specially tagged vma
+	 *   which rmap call sites look for using is_vma_temporary_stack().
+	 *
+	 * - During mremap(), new_vma is often known to be placed after vma
+	 *   in rmap traversal order. This ensures rmap will always observe
+	 *   either the old pte, or the new pte, or both (the page table locks
+	 *   serialize access to individual ptes, but only rmap traversal
+	 *   order guarantees that we won't miss both the old and new ptes).
+	 */
+	if (need_rmap_locks) {
+		if (vma->vm_file) {
+			mapping = vma->vm_file->f_mapping;
+			mutex_lock(&mapping->i_mmap_mutex);
+		}
+		if (vma->anon_vma) {
+			anon_vma = vma->anon_vma;
+			anon_vma_lock(anon_vma);
+		}
 	}
 
 	/*
@@ -114,6 +133,8 @@
 		spin_unlock(new_ptl);
 	pte_unmap(new_pte - 1);
 	pte_unmap_unlock(old_pte - 1, old_ptl);
+	if (anon_vma)
+		anon_vma_unlock(anon_vma);
 	if (mapping)
 		mutex_unlock(&mapping->i_mmap_mutex);
 }
@@ -122,16 +143,21 @@
 
 unsigned long move_page_tables(struct vm_area_struct *vma,
 		unsigned long old_addr, struct vm_area_struct *new_vma,
-		unsigned long new_addr, unsigned long len)
+		unsigned long new_addr, unsigned long len,
+		bool need_rmap_locks)
 {
 	unsigned long extent, next, old_end;
 	pmd_t *old_pmd, *new_pmd;
 	bool need_flush = false;
+	unsigned long mmun_start;	/* For mmu_notifiers */
+	unsigned long mmun_end;		/* For mmu_notifiers */
 
 	old_end = old_addr + len;
 	flush_cache_range(vma, old_addr, old_end);
 
-	mmu_notifier_invalidate_range_start(vma->vm_mm, old_addr, old_end);
+	mmun_start = old_addr;
+	mmun_end   = old_end;
+	mmu_notifier_invalidate_range_start(vma->vm_mm, mmun_start, mmun_end);
 
 	for (; old_addr < old_end; old_addr += extent, new_addr += extent) {
 		cond_resched();
@@ -169,13 +195,13 @@
 		if (extent > LATENCY_LIMIT)
 			extent = LATENCY_LIMIT;
 		move_ptes(vma, old_pmd, old_addr, old_addr + extent,
-				new_vma, new_pmd, new_addr);
+			  new_vma, new_pmd, new_addr, need_rmap_locks);
 		need_flush = true;
 	}
 	if (likely(need_flush))
 		flush_tlb_range(vma, old_end-len, old_addr);
 
-	mmu_notifier_invalidate_range_end(vma->vm_mm, old_end-len, old_end);
+	mmu_notifier_invalidate_range_end(vma->vm_mm, mmun_start, mmun_end);
 
 	return len + old_addr - old_end;	/* how much done */
 }
@@ -193,6 +219,7 @@
 	unsigned long hiwater_vm;
 	int split = 0;
 	int err;
+	bool need_rmap_locks;
 
 	/*
 	 * We'd prefer to avoid failure later on in do_munmap:
@@ -214,27 +241,21 @@
 		return err;
 
 	new_pgoff = vma->vm_pgoff + ((old_addr - vma->vm_start) >> PAGE_SHIFT);
-	new_vma = copy_vma(&vma, new_addr, new_len, new_pgoff);
+	new_vma = copy_vma(&vma, new_addr, new_len, new_pgoff,
+			   &need_rmap_locks);
 	if (!new_vma)
 		return -ENOMEM;
 
-	moved_len = move_page_tables(vma, old_addr, new_vma, new_addr, old_len);
+	moved_len = move_page_tables(vma, old_addr, new_vma, new_addr, old_len,
+				     need_rmap_locks);
 	if (moved_len < old_len) {
 		/*
-		 * Before moving the page tables from the new vma to
-		 * the old vma, we need to be sure the old vma is
-		 * queued after new vma in the same_anon_vma list to
-		 * prevent SMP races with rmap_walk (that could lead
-		 * rmap_walk to miss some page table).
-		 */
-		anon_vma_moveto_tail(vma);
-
-		/*
 		 * On error, move entries back from new area to old,
 		 * which will succeed since page tables still there,
 		 * and then proceed to unmap new area instead of old.
 		 */
-		move_page_tables(new_vma, new_addr, vma, old_addr, moved_len);
+		move_page_tables(new_vma, new_addr, vma, old_addr, moved_len,
+				 true);
 		vma = new_vma;
 		old_len = new_len;
 		old_addr = new_addr;
diff --git a/mm/nobootmem.c b/mm/nobootmem.c
index 4055730..714d5d6 100644
--- a/mm/nobootmem.c
+++ b/mm/nobootmem.c
@@ -116,6 +116,8 @@
 		return 0;
 
 	__free_pages_memory(start_pfn, end_pfn);
+	fixup_zone_present_pages(pfn_to_nid(start >> PAGE_SHIFT),
+			start_pfn, end_pfn);
 
 	return end_pfn - start_pfn;
 }
@@ -126,6 +128,7 @@
 	phys_addr_t start, end, size;
 	u64 i;
 
+	reset_zone_present_pages();
 	for_each_free_mem_range(i, MAX_NUMNODES, &start, &end, NULL)
 		count += __free_memory_core(start, end);
 
@@ -162,8 +165,6 @@
 	 * We need to use MAX_NUMNODES instead of NODE_DATA(0)->node_id
 	 *  because in some case like Node0 doesn't have RAM installed
 	 *  low ram will be on Node1
-	 * Use MAX_NUMNODES will make sure all ranges in early_node_map[]
-	 *  will be used instead of only Node0 related
 	 */
 	return free_low_memory_core_early(MAX_NUMNODES);
 }
diff --git a/mm/nommu.c b/mm/nommu.c
index dee2ff8..45131b4 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -698,7 +698,7 @@
 
 		mutex_lock(&mapping->i_mmap_mutex);
 		flush_dcache_mmap_lock(mapping);
-		vma_prio_tree_insert(vma, &mapping->i_mmap);
+		vma_interval_tree_insert(vma, &mapping->i_mmap);
 		flush_dcache_mmap_unlock(mapping);
 		mutex_unlock(&mapping->i_mmap_mutex);
 	}
@@ -764,7 +764,7 @@
 
 		mutex_lock(&mapping->i_mmap_mutex);
 		flush_dcache_mmap_lock(mapping);
-		vma_prio_tree_remove(vma, &mapping->i_mmap);
+		vma_interval_tree_remove(vma, &mapping->i_mmap);
 		flush_dcache_mmap_unlock(mapping);
 		mutex_unlock(&mapping->i_mmap_mutex);
 	}
@@ -789,11 +789,8 @@
 	kenter("%p", vma);
 	if (vma->vm_ops && vma->vm_ops->close)
 		vma->vm_ops->close(vma);
-	if (vma->vm_file) {
+	if (vma->vm_file)
 		fput(vma->vm_file);
-		if (vma->vm_flags & VM_EXECUTABLE)
-			removed_exe_file_vma(mm);
-	}
 	put_nommu_region(vma->vm_region);
 	kmem_cache_free(vm_area_cachep, vma);
 }
@@ -1284,10 +1281,6 @@
 	if (file) {
 		region->vm_file = get_file(file);
 		vma->vm_file = get_file(file);
-		if (vm_flags & VM_EXECUTABLE) {
-			added_exe_file_vma(current->mm);
-			vma->vm_mm = current->mm;
-		}
 	}
 
 	down_write(&nommu_region_sem);
@@ -1440,8 +1433,6 @@
 	kmem_cache_free(vm_region_jar, region);
 	if (vma->vm_file)
 		fput(vma->vm_file);
-	if (vma->vm_flags & VM_EXECUTABLE)
-		removed_exe_file_vma(vma->vm_mm);
 	kmem_cache_free(vm_area_cachep, vma);
 	kleave(" = %d", ret);
 	return ret;
@@ -1820,7 +1811,7 @@
 	if (addr != (pfn << PAGE_SHIFT))
 		return -EINVAL;
 
-	vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
+	vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
 	return 0;
 }
 EXPORT_SYMBOL(remap_pfn_range);
@@ -1961,6 +1952,14 @@
 }
 EXPORT_SYMBOL(filemap_fault);
 
+int generic_file_remap_pages(struct vm_area_struct *vma, unsigned long addr,
+			     unsigned long size, pgoff_t pgoff)
+{
+	BUG();
+	return 0;
+}
+EXPORT_SYMBOL(generic_file_remap_pages);
+
 static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
 		unsigned long addr, void *buf, int len, int write)
 {
@@ -2045,7 +2044,6 @@
 				size_t newsize)
 {
 	struct vm_area_struct *vma;
-	struct prio_tree_iter iter;
 	struct vm_region *region;
 	pgoff_t low, high;
 	size_t r_size, r_top;
@@ -2057,8 +2055,7 @@
 	mutex_lock(&inode->i_mapping->i_mmap_mutex);
 
 	/* search for VMAs that fall within the dead zone */
-	vma_prio_tree_foreach(vma, &iter, &inode->i_mapping->i_mmap,
-			      low, high) {
+	vma_interval_tree_foreach(vma, &inode->i_mapping->i_mmap, low, high) {
 		/* found one - only interested if it's shared out of the page
 		 * cache */
 		if (vma->vm_flags & VM_SHARED) {
@@ -2074,8 +2071,8 @@
 	 * we don't check for any regions that start beyond the EOF as there
 	 * shouldn't be any
 	 */
-	vma_prio_tree_foreach(vma, &iter, &inode->i_mapping->i_mmap,
-			      0, ULONG_MAX) {
+	vma_interval_tree_foreach(vma, &inode->i_mapping->i_mmap,
+				  0, ULONG_MAX) {
 		if (!(vma->vm_flags & VM_SHARED))
 			continue;
 
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 1986008..79e0f3e 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -428,8 +428,8 @@
 {
 	task_lock(current);
 	pr_warning("%s invoked oom-killer: gfp_mask=0x%x, order=%d, "
-		"oom_adj=%d, oom_score_adj=%d\n",
-		current->comm, gfp_mask, order, current->signal->oom_adj,
+		"oom_score_adj=%d\n",
+		current->comm, gfp_mask, order,
 		current->signal->oom_score_adj);
 	cpuset_print_task_mems_allowed(current);
 	task_unlock(current);
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 5ad5ce2..830893b 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -1602,10 +1602,18 @@
 }
 
 static int __cpuinit
-ratelimit_handler(struct notifier_block *self, unsigned long u, void *v)
+ratelimit_handler(struct notifier_block *self, unsigned long action,
+		  void *hcpu)
 {
-	writeback_set_ratelimit();
-	return NOTIFY_DONE;
+
+	switch (action & ~CPU_TASKS_FROZEN) {
+	case CPU_ONLINE:
+	case CPU_DEAD:
+		writeback_set_ratelimit();
+		return NOTIFY_OK;
+	default:
+		return NOTIFY_DONE;
+	}
 }
 
 static struct notifier_block __cpuinitdata ratelimit_nb = {
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index c13ea75..bb90971 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -558,7 +558,8 @@
 		if (page_is_guard(buddy)) {
 			clear_page_guard_flag(buddy);
 			set_page_private(page, 0);
-			__mod_zone_page_state(zone, NR_FREE_PAGES, 1 << order);
+			__mod_zone_freepage_state(zone, 1 << order,
+						  migratetype);
 		} else {
 			list_del(&buddy->lru);
 			zone->free_area[order].nr_free--;
@@ -597,17 +598,6 @@
 	zone->free_area[order].nr_free++;
 }
 
-/*
- * free_page_mlock() -- clean up attempts to free and mlocked() page.
- * Page should not be on lru, so no need to fix that up.
- * free_pages_check() will verify...
- */
-static inline void free_page_mlock(struct page *page)
-{
-	__dec_zone_page_state(page, NR_MLOCK);
-	__count_vm_event(UNEVICTABLE_MLOCKFREED);
-}
-
 static inline int free_pages_check(struct page *page)
 {
 	if (unlikely(page_mapcount(page) |
@@ -668,12 +658,17 @@
 			batch_free = to_free;
 
 		do {
+			int mt;	/* migratetype of the to-be-freed page */
+
 			page = list_entry(list->prev, struct page, lru);
 			/* must delete as __free_one_page list manipulates */
 			list_del(&page->lru);
+			mt = get_freepage_migratetype(page);
 			/* MIGRATE_MOVABLE list may include MIGRATE_RESERVEs */
-			__free_one_page(page, zone, 0, page_private(page));
-			trace_mm_page_pcpu_drain(page, 0, page_private(page));
+			__free_one_page(page, zone, 0, mt);
+			trace_mm_page_pcpu_drain(page, 0, mt);
+			if (is_migrate_cma(mt))
+				__mod_zone_page_state(zone, NR_FREE_CMA_PAGES, 1);
 		} while (--to_free && --batch_free && !list_empty(list));
 	}
 	__mod_zone_page_state(zone, NR_FREE_PAGES, count);
@@ -688,7 +683,8 @@
 	zone->pages_scanned = 0;
 
 	__free_one_page(page, zone, order, migratetype);
-	__mod_zone_page_state(zone, NR_FREE_PAGES, 1 << order);
+	if (unlikely(migratetype != MIGRATE_ISOLATE))
+		__mod_zone_freepage_state(zone, 1 << order, migratetype);
 	spin_unlock(&zone->lock);
 }
 
@@ -721,17 +717,16 @@
 static void __free_pages_ok(struct page *page, unsigned int order)
 {
 	unsigned long flags;
-	int wasMlocked = __TestClearPageMlocked(page);
+	int migratetype;
 
 	if (!free_pages_prepare(page, order))
 		return;
 
 	local_irq_save(flags);
-	if (unlikely(wasMlocked))
-		free_page_mlock(page);
 	__count_vm_events(PGFREE, 1 << order);
-	free_one_page(page_zone(page), page, order,
-					get_pageblock_migratetype(page));
+	migratetype = get_pageblock_migratetype(page);
+	set_freepage_migratetype(page, migratetype);
+	free_one_page(page_zone(page), page, order, migratetype);
 	local_irq_restore(flags);
 }
 
@@ -811,7 +806,8 @@
 			set_page_guard_flag(&page[size]);
 			set_page_private(&page[size], high);
 			/* Guard pages are not available for any usage */
-			__mod_zone_page_state(zone, NR_FREE_PAGES, -(1 << high));
+			__mod_zone_freepage_state(zone, -(1 << high),
+						  migratetype);
 			continue;
 		}
 #endif
@@ -915,7 +911,7 @@
  * Note that start_page and end_pages are not aligned on a pageblock
  * boundary. If alignment is required, use move_freepages_block()
  */
-static int move_freepages(struct zone *zone,
+int move_freepages(struct zone *zone,
 			  struct page *start_page, struct page *end_page,
 			  int migratetype)
 {
@@ -951,6 +947,7 @@
 		order = page_order(page);
 		list_move(&page->lru,
 			  &zone->free_area[order].free_list[migratetype]);
+		set_freepage_migratetype(page, migratetype);
 		page += 1 << order;
 		pages_moved += 1 << order;
 	}
@@ -1135,8 +1132,11 @@
 			if (!is_migrate_cma(mt) && mt != MIGRATE_ISOLATE)
 				mt = migratetype;
 		}
-		set_page_private(page, mt);
+		set_freepage_migratetype(page, mt);
 		list = &page->lru;
+		if (is_migrate_cma(mt))
+			__mod_zone_page_state(zone, NR_FREE_CMA_PAGES,
+					      -(1 << order));
 	}
 	__mod_zone_page_state(zone, NR_FREE_PAGES, -(i << order));
 	spin_unlock(&zone->lock);
@@ -1296,16 +1296,13 @@
 	struct per_cpu_pages *pcp;
 	unsigned long flags;
 	int migratetype;
-	int wasMlocked = __TestClearPageMlocked(page);
 
 	if (!free_pages_prepare(page, 0))
 		return;
 
 	migratetype = get_pageblock_migratetype(page);
-	set_page_private(page, migratetype);
+	set_freepage_migratetype(page, migratetype);
 	local_irq_save(flags);
-	if (unlikely(wasMlocked))
-		free_page_mlock(page);
 	__count_vm_event(PGFREE);
 
 	/*
@@ -1380,20 +1377,16 @@
 }
 
 /*
- * Similar to split_page except the page is already free. As this is only
- * being used for migration, the migratetype of the block also changes.
- * As this is called with interrupts disabled, the caller is responsible
- * for calling arch_alloc_page() and kernel_map_page() after interrupts
- * are enabled.
- *
- * Note: this is probably too low level an operation for use in drivers.
- * Please consult with lkml before using this in your driver.
+ * Similar to the split_page family of functions except that the page
+ * required at the given order and being isolated now to prevent races
+ * with parallel allocators
  */
-int split_free_page(struct page *page)
+int capture_free_page(struct page *page, int alloc_order, int migratetype)
 {
 	unsigned int order;
 	unsigned long watermark;
 	struct zone *zone;
+	int mt;
 
 	BUG_ON(!PageBuddy(page));
 
@@ -1409,12 +1402,16 @@
 	list_del(&page->lru);
 	zone->free_area[order].nr_free--;
 	rmv_page_order(page);
-	__mod_zone_page_state(zone, NR_FREE_PAGES, -(1UL << order));
 
-	/* Split into individual pages */
-	set_page_refcounted(page);
-	split_page(page, order);
+	mt = get_pageblock_migratetype(page);
+	if (unlikely(mt != MIGRATE_ISOLATE))
+		__mod_zone_freepage_state(zone, -(1UL << order), mt);
 
+	if (alloc_order != order)
+		expand(zone, page, alloc_order, order,
+			&zone->free_area[order], migratetype);
+
+	/* Set the pageblock if the captured page is at least a pageblock */
 	if (order >= pageblock_order - 1) {
 		struct page *endpage = page + (1 << order) - 1;
 		for (; page < endpage; page += pageblock_nr_pages) {
@@ -1425,7 +1422,35 @@
 		}
 	}
 
-	return 1 << order;
+	return 1UL << order;
+}
+
+/*
+ * Similar to split_page except the page is already free. As this is only
+ * being used for migration, the migratetype of the block also changes.
+ * As this is called with interrupts disabled, the caller is responsible
+ * for calling arch_alloc_page() and kernel_map_page() after interrupts
+ * are enabled.
+ *
+ * Note: this is probably too low level an operation for use in drivers.
+ * Please consult with lkml before using this in your driver.
+ */
+int split_free_page(struct page *page)
+{
+	unsigned int order;
+	int nr_pages;
+
+	BUG_ON(!PageBuddy(page));
+	order = page_order(page);
+
+	nr_pages = capture_free_page(page, order, 0);
+	if (!nr_pages)
+		return 0;
+
+	/* Split into individual pages */
+	set_page_refcounted(page);
+	split_page(page, order);
+	return nr_pages;
 }
 
 /*
@@ -1484,7 +1509,8 @@
 		spin_unlock(&zone->lock);
 		if (!page)
 			goto failed;
-		__mod_zone_page_state(zone, NR_FREE_PAGES, -(1 << order));
+		__mod_zone_freepage_state(zone, -(1 << order),
+					  get_pageblock_migratetype(page));
 	}
 
 	__count_zone_vm_events(PGALLOC, zone, 1 << order);
@@ -1501,19 +1527,6 @@
 	return NULL;
 }
 
-/* The ALLOC_WMARK bits are used as an index to zone->watermark */
-#define ALLOC_WMARK_MIN		WMARK_MIN
-#define ALLOC_WMARK_LOW		WMARK_LOW
-#define ALLOC_WMARK_HIGH	WMARK_HIGH
-#define ALLOC_NO_WATERMARKS	0x04 /* don't check watermarks at all */
-
-/* Mask to get the watermark bits */
-#define ALLOC_WMARK_MASK	(ALLOC_NO_WATERMARKS-1)
-
-#define ALLOC_HARDER		0x10 /* try to alloc harder */
-#define ALLOC_HIGH		0x20 /* __GFP_HIGH set */
-#define ALLOC_CPUSET		0x40 /* check for correct cpuset */
-
 #ifdef CONFIG_FAIL_PAGE_ALLOC
 
 static struct {
@@ -1608,7 +1621,11 @@
 		min -= min / 2;
 	if (alloc_flags & ALLOC_HARDER)
 		min -= min / 4;
-
+#ifdef CONFIG_CMA
+	/* If allocation can't use CMA areas don't use free CMA pages */
+	if (!(alloc_flags & ALLOC_CMA))
+		free_pages -= zone_page_state(z, NR_FREE_CMA_PAGES);
+#endif
 	if (free_pages <= min + lowmem_reserve)
 		return false;
 	for (o = 0; o < order; o++) {
@@ -1782,6 +1799,22 @@
 	bitmap_zero(zlc->fullzones, MAX_ZONES_PER_ZONELIST);
 }
 
+static bool zone_allows_reclaim(struct zone *local_zone, struct zone *zone)
+{
+	return node_isset(local_zone->node, zone->zone_pgdat->reclaim_nodes);
+}
+
+static void __paginginit init_zone_allows_reclaim(int nid)
+{
+	int i;
+
+	for_each_online_node(i)
+		if (node_distance(nid, i) <= RECLAIM_DISTANCE) {
+			node_set(i, NODE_DATA(nid)->reclaim_nodes);
+			zone_reclaim_mode = 1;
+		}
+}
+
 #else	/* CONFIG_NUMA */
 
 static nodemask_t *zlc_setup(struct zonelist *zonelist, int alloc_flags)
@@ -1802,6 +1835,15 @@
 static void zlc_clear_zones_full(struct zonelist *zonelist)
 {
 }
+
+static bool zone_allows_reclaim(struct zone *local_zone, struct zone *zone)
+{
+	return true;
+}
+
+static inline void init_zone_allows_reclaim(int nid)
+{
+}
 #endif	/* CONFIG_NUMA */
 
 /*
@@ -1886,7 +1928,8 @@
 				did_zlc_setup = 1;
 			}
 
-			if (zone_reclaim_mode == 0)
+			if (zone_reclaim_mode == 0 ||
+			    !zone_allows_reclaim(preferred_zone, zone))
 				goto this_zone_full;
 
 			/*
@@ -2105,7 +2148,7 @@
 	bool *contended_compaction, bool *deferred_compaction,
 	unsigned long *did_some_progress)
 {
-	struct page *page;
+	struct page *page = NULL;
 
 	if (!order)
 		return NULL;
@@ -2118,10 +2161,16 @@
 	current->flags |= PF_MEMALLOC;
 	*did_some_progress = try_to_compact_pages(zonelist, order, gfp_mask,
 						nodemask, sync_migration,
-						contended_compaction);
+						contended_compaction, &page);
 	current->flags &= ~PF_MEMALLOC;
-	if (*did_some_progress != COMPACT_SKIPPED) {
 
+	/* If compaction captured a page, prep and use it */
+	if (page) {
+		prep_new_page(page, order, gfp_mask);
+		goto got_page;
+	}
+
+	if (*did_some_progress != COMPACT_SKIPPED) {
 		/* Page migration frees to the PCP lists but we want merging */
 		drain_pages(get_cpu());
 		put_cpu();
@@ -2131,6 +2180,8 @@
 				alloc_flags & ~ALLOC_NO_WATERMARKS,
 				preferred_zone, migratetype);
 		if (page) {
+got_page:
+			preferred_zone->compact_blockskip_flush = false;
 			preferred_zone->compact_considered = 0;
 			preferred_zone->compact_defer_shift = 0;
 			if (order >= preferred_zone->compact_order_failed)
@@ -2315,7 +2366,10 @@
 				 unlikely(test_thread_flag(TIF_MEMDIE))))
 			alloc_flags |= ALLOC_NO_WATERMARKS;
 	}
-
+#ifdef CONFIG_CMA
+	if (allocflags_to_migratetype(gfp_mask) == MIGRATE_MOVABLE)
+		alloc_flags |= ALLOC_CMA;
+#endif
 	return alloc_flags;
 }
 
@@ -2362,9 +2416,8 @@
 		goto nopage;
 
 restart:
-	if (!(gfp_mask & __GFP_NO_KSWAPD))
-		wake_all_kswapd(order, zonelist, high_zoneidx,
-						zone_idx(preferred_zone));
+	wake_all_kswapd(order, zonelist, high_zoneidx,
+					zone_idx(preferred_zone));
 
 	/*
 	 * OK, we're below the kswapd watermark and have kicked background
@@ -2441,7 +2494,7 @@
 	 * system then fail the allocation instead of entering direct reclaim.
 	 */
 	if ((deferred_compaction || contended_compaction) &&
-						(gfp_mask & __GFP_NO_KSWAPD))
+	    (gfp_mask & (__GFP_MOVABLE|__GFP_REPEAT)) == __GFP_MOVABLE)
 		goto nopage;
 
 	/* Try direct reclaim and then allocating */
@@ -2541,6 +2594,7 @@
 	struct page *page = NULL;
 	int migratetype = allocflags_to_migratetype(gfp_mask);
 	unsigned int cpuset_mems_cookie;
+	int alloc_flags = ALLOC_WMARK_LOW|ALLOC_CPUSET;
 
 	gfp_mask &= gfp_allowed_mask;
 
@@ -2569,9 +2623,13 @@
 	if (!preferred_zone)
 		goto out;
 
+#ifdef CONFIG_CMA
+	if (allocflags_to_migratetype(gfp_mask) == MIGRATE_MOVABLE)
+		alloc_flags |= ALLOC_CMA;
+#endif
 	/* First allocation attempt */
 	page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, nodemask, order,
-			zonelist, high_zoneidx, ALLOC_WMARK_LOW|ALLOC_CPUSET,
+			zonelist, high_zoneidx, alloc_flags,
 			preferred_zone, migratetype);
 	if (unlikely(!page))
 		page = __alloc_pages_slowpath(gfp_mask, order,
@@ -2852,7 +2910,8 @@
 		" unevictable:%lu"
 		" dirty:%lu writeback:%lu unstable:%lu\n"
 		" free:%lu slab_reclaimable:%lu slab_unreclaimable:%lu\n"
-		" mapped:%lu shmem:%lu pagetables:%lu bounce:%lu\n",
+		" mapped:%lu shmem:%lu pagetables:%lu bounce:%lu\n"
+		" free_cma:%lu\n",
 		global_page_state(NR_ACTIVE_ANON),
 		global_page_state(NR_INACTIVE_ANON),
 		global_page_state(NR_ISOLATED_ANON),
@@ -2869,7 +2928,8 @@
 		global_page_state(NR_FILE_MAPPED),
 		global_page_state(NR_SHMEM),
 		global_page_state(NR_PAGETABLE),
-		global_page_state(NR_BOUNCE));
+		global_page_state(NR_BOUNCE),
+		global_page_state(NR_FREE_CMA_PAGES));
 
 	for_each_populated_zone(zone) {
 		int i;
@@ -2901,6 +2961,7 @@
 			" pagetables:%lukB"
 			" unstable:%lukB"
 			" bounce:%lukB"
+			" free_cma:%lukB"
 			" writeback_tmp:%lukB"
 			" pages_scanned:%lu"
 			" all_unreclaimable? %s"
@@ -2930,6 +2991,7 @@
 			K(zone_page_state(zone, NR_PAGETABLE)),
 			K(zone_page_state(zone, NR_UNSTABLE_NFS)),
 			K(zone_page_state(zone, NR_BOUNCE)),
+			K(zone_page_state(zone, NR_FREE_CMA_PAGES)),
 			K(zone_page_state(zone, NR_WRITEBACK_TEMP)),
 			zone->pages_scanned,
 			(zone->all_unreclaimable ? "yes" : "no")
@@ -3328,21 +3390,13 @@
 	j = 0;
 
 	while ((node = find_next_best_node(local_node, &used_mask)) >= 0) {
-		int distance = node_distance(local_node, node);
-
-		/*
-		 * If another node is sufficiently far away then it is better
-		 * to reclaim pages in a zone before going off node.
-		 */
-		if (distance > RECLAIM_DISTANCE)
-			zone_reclaim_mode = 1;
-
 		/*
 		 * We don't want to pressure a particular node.
 		 * So adding penalty to the first node in same
 		 * distance group to make it round-robin.
 		 */
-		if (distance != node_distance(local_node, prev_node))
+		if (node_distance(local_node, node) !=
+		    node_distance(local_node, prev_node))
 			node_load[node] = load;
 
 		prev_node = node;
@@ -4438,11 +4492,6 @@
 
 		zone->spanned_pages = size;
 		zone->present_pages = realsize;
-#if defined CONFIG_COMPACTION || defined CONFIG_CMA
-		zone->compact_cached_free_pfn = zone->zone_start_pfn +
-						zone->spanned_pages;
-		zone->compact_cached_free_pfn &= ~(pageblock_nr_pages-1);
-#endif
 #ifdef CONFIG_NUMA
 		zone->node = nid;
 		zone->min_unmapped_pages = (realsize*sysctl_min_unmapped_ratio)
@@ -4521,6 +4570,7 @@
 
 	pgdat->node_id = nid;
 	pgdat->node_start_pfn = node_start_pfn;
+	init_zone_allows_reclaim(nid);
 	calculate_node_totalpages(pgdat, zones_size, zholes_size);
 
 	alloc_node_mem_map(pgdat);
@@ -4879,7 +4929,7 @@
 			       zone_movable_pfn[i] << PAGE_SHIFT);
 	}
 
-	/* Print out the early_node_map[] */
+	/* Print out the early node map */
 	printk("Early memory node ranges\n");
 	for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, &nid)
 		printk("  node %3d: [mem %#010lx-%#010lx]\n", nid,
@@ -5619,47 +5669,28 @@
 				pageblock_nr_pages));
 }
 
-static struct page *
-__alloc_contig_migrate_alloc(struct page *page, unsigned long private,
-			     int **resultp)
-{
-	gfp_t gfp_mask = GFP_USER | __GFP_MOVABLE;
-
-	if (PageHighMem(page))
-		gfp_mask |= __GFP_HIGHMEM;
-
-	return alloc_page(gfp_mask);
-}
-
 /* [start, end) must belong to a single zone. */
-static int __alloc_contig_migrate_range(unsigned long start, unsigned long end)
+static int __alloc_contig_migrate_range(struct compact_control *cc,
+					unsigned long start, unsigned long end)
 {
 	/* This function is based on compact_zone() from compaction.c. */
-
+	unsigned long nr_reclaimed;
 	unsigned long pfn = start;
 	unsigned int tries = 0;
 	int ret = 0;
 
-	struct compact_control cc = {
-		.nr_migratepages = 0,
-		.order = -1,
-		.zone = page_zone(pfn_to_page(start)),
-		.sync = true,
-	};
-	INIT_LIST_HEAD(&cc.migratepages);
-
 	migrate_prep_local();
 
-	while (pfn < end || !list_empty(&cc.migratepages)) {
+	while (pfn < end || !list_empty(&cc->migratepages)) {
 		if (fatal_signal_pending(current)) {
 			ret = -EINTR;
 			break;
 		}
 
-		if (list_empty(&cc.migratepages)) {
-			cc.nr_migratepages = 0;
-			pfn = isolate_migratepages_range(cc.zone, &cc,
-							 pfn, end);
+		if (list_empty(&cc->migratepages)) {
+			cc->nr_migratepages = 0;
+			pfn = isolate_migratepages_range(cc->zone, cc,
+							 pfn, end, true);
 			if (!pfn) {
 				ret = -EINTR;
 				break;
@@ -5670,12 +5701,16 @@
 			break;
 		}
 
-		ret = migrate_pages(&cc.migratepages,
-				    __alloc_contig_migrate_alloc,
+		nr_reclaimed = reclaim_clean_pages_from_list(cc->zone,
+							&cc->migratepages);
+		cc->nr_migratepages -= nr_reclaimed;
+
+		ret = migrate_pages(&cc->migratepages,
+				    alloc_migrate_target,
 				    0, false, MIGRATE_SYNC);
 	}
 
-	putback_lru_pages(&cc.migratepages);
+	putback_lru_pages(&cc->migratepages);
 	return ret > 0 ? 0 : ret;
 }
 
@@ -5754,6 +5789,15 @@
 	unsigned long outer_start, outer_end;
 	int ret = 0, order;
 
+	struct compact_control cc = {
+		.nr_migratepages = 0,
+		.order = -1,
+		.zone = page_zone(pfn_to_page(start)),
+		.sync = true,
+		.ignore_skip_hint = true,
+	};
+	INIT_LIST_HEAD(&cc.migratepages);
+
 	/*
 	 * What we do here is we mark all pageblocks in range as
 	 * MIGRATE_ISOLATE.  Because pageblock and max order pages may
@@ -5783,7 +5827,7 @@
 	if (ret)
 		goto done;
 
-	ret = __alloc_contig_migrate_range(start, end);
+	ret = __alloc_contig_migrate_range(&cc, start, end);
 	if (ret)
 		goto done;
 
@@ -5832,7 +5876,7 @@
 	__reclaim_pages(zone, GFP_HIGHUSER_MOVABLE, end-start);
 
 	/* Grab isolated pages from freelists. */
-	outer_end = isolate_freepages_range(outer_start, end);
+	outer_end = isolate_freepages_range(&cc, outer_start, end);
 	if (!outer_end) {
 		ret = -EBUSY;
 		goto done;
@@ -5874,6 +5918,7 @@
 		local_irq_save(flags);
 		if (pcp->count > 0)
 			free_pcppages_bulk(zone, pcp->count, pcp);
+		drain_zonestat(zone, pset);
 		setup_pageset(pset, batch);
 		local_irq_restore(flags);
 	}
@@ -5890,10 +5935,16 @@
 void zone_pcp_reset(struct zone *zone)
 {
 	unsigned long flags;
+	int cpu;
+	struct per_cpu_pageset *pset;
 
 	/* avoid races with drain_pages()  */
 	local_irq_save(flags);
 	if (zone->pageset != &boot_pageset) {
+		for_each_online_cpu(cpu) {
+			pset = per_cpu_ptr(zone->pageset, cpu);
+			drain_zonestat(zone, pset);
+		}
 		free_percpu(zone->pageset);
 		zone->pageset = &boot_pageset;
 	}
@@ -6047,3 +6098,37 @@
 	dump_page_flags(page->flags);
 	mem_cgroup_print_bad_page(page);
 }
+
+/* reset zone->present_pages */
+void reset_zone_present_pages(void)
+{
+	struct zone *z;
+	int i, nid;
+
+	for_each_node_state(nid, N_HIGH_MEMORY) {
+		for (i = 0; i < MAX_NR_ZONES; i++) {
+			z = NODE_DATA(nid)->node_zones + i;
+			z->present_pages = 0;
+		}
+	}
+}
+
+/* calculate zone's present pages in buddy system */
+void fixup_zone_present_pages(int nid, unsigned long start_pfn,
+				unsigned long end_pfn)
+{
+	struct zone *z;
+	unsigned long zone_start_pfn, zone_end_pfn;
+	int i;
+
+	for (i = 0; i < MAX_NR_ZONES; i++) {
+		z = NODE_DATA(nid)->node_zones + i;
+		zone_start_pfn = z->zone_start_pfn;
+		zone_end_pfn = zone_start_pfn + z->spanned_pages;
+
+		/* if the two regions intersect */
+		if (!(zone_start_pfn >= end_pfn	|| zone_end_pfn <= start_pfn))
+			z->present_pages += min(end_pfn, zone_end_pfn) -
+					    max(start_pfn, zone_start_pfn);
+	}
+}
diff --git a/mm/page_isolation.c b/mm/page_isolation.c
index 247d1f1..f2f5b48 100644
--- a/mm/page_isolation.c
+++ b/mm/page_isolation.c
@@ -76,8 +76,13 @@
 
 out:
 	if (!ret) {
+		unsigned long nr_pages;
+		int migratetype = get_pageblock_migratetype(page);
+
 		set_pageblock_isolate(page);
-		move_freepages_block(zone, page, MIGRATE_ISOLATE);
+		nr_pages = move_freepages_block(zone, page, MIGRATE_ISOLATE);
+
+		__mod_zone_freepage_state(zone, -nr_pages, migratetype);
 	}
 
 	spin_unlock_irqrestore(&zone->lock, flags);
@@ -89,12 +94,14 @@
 void unset_migratetype_isolate(struct page *page, unsigned migratetype)
 {
 	struct zone *zone;
-	unsigned long flags;
+	unsigned long flags, nr_pages;
+
 	zone = page_zone(page);
 	spin_lock_irqsave(&zone->lock, flags);
 	if (get_pageblock_migratetype(page) != MIGRATE_ISOLATE)
 		goto out;
-	move_freepages_block(zone, page, migratetype);
+	nr_pages = move_freepages_block(zone, page, migratetype);
+	__mod_zone_freepage_state(zone, nr_pages, migratetype);
 	restore_pageblock_isolate(page, migratetype);
 out:
 	spin_unlock_irqrestore(&zone->lock, flags);
@@ -193,10 +200,25 @@
 			continue;
 		}
 		page = pfn_to_page(pfn);
-		if (PageBuddy(page))
+		if (PageBuddy(page)) {
+			/*
+			 * If race between isolatation and allocation happens,
+			 * some free pages could be in MIGRATE_MOVABLE list
+			 * although pageblock's migratation type of the page
+			 * is MIGRATE_ISOLATE. Catch it and move the page into
+			 * MIGRATE_ISOLATE list.
+			 */
+			if (get_freepage_migratetype(page) != MIGRATE_ISOLATE) {
+				struct page *end_page;
+
+				end_page = page + (1 << page_order(page)) - 1;
+				move_freepages(page_zone(page), page, end_page,
+						MIGRATE_ISOLATE);
+			}
 			pfn += 1 << page_order(page);
+		}
 		else if (page_count(page) == 0 &&
-				page_private(page) == MIGRATE_ISOLATE)
+			get_freepage_migratetype(page) == MIGRATE_ISOLATE)
 			pfn += 1;
 		else
 			break;
@@ -233,3 +255,14 @@
 	spin_unlock_irqrestore(&zone->lock, flags);
 	return ret ? 0 : -EBUSY;
 }
+
+struct page *alloc_migrate_target(struct page *page, unsigned long private,
+				  int **resultp)
+{
+	gfp_t gfp_mask = GFP_USER | __GFP_MOVABLE;
+
+	if (PageHighMem(page))
+		gfp_mask |= __GFP_HIGHMEM;
+
+	return alloc_page(gfp_mask);
+}
diff --git a/mm/pgtable-generic.c b/mm/pgtable-generic.c
index 74c0dda..e642627 100644
--- a/mm/pgtable-generic.c
+++ b/mm/pgtable-generic.c
@@ -120,3 +120,53 @@
 }
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 #endif
+
+#ifndef __HAVE_ARCH_PGTABLE_DEPOSIT
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable)
+{
+	assert_spin_locked(&mm->page_table_lock);
+
+	/* FIFO */
+	if (!mm->pmd_huge_pte)
+		INIT_LIST_HEAD(&pgtable->lru);
+	else
+		list_add(&pgtable->lru, &mm->pmd_huge_pte->lru);
+	mm->pmd_huge_pte = pgtable;
+}
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+#endif
+
+#ifndef __HAVE_ARCH_PGTABLE_WITHDRAW
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+/* no "address" argument so destroys page coloring of some arch */
+pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm)
+{
+	pgtable_t pgtable;
+
+	assert_spin_locked(&mm->page_table_lock);
+
+	/* FIFO */
+	pgtable = mm->pmd_huge_pte;
+	if (list_empty(&pgtable->lru))
+		mm->pmd_huge_pte = NULL;
+	else {
+		mm->pmd_huge_pte = list_entry(pgtable->lru.next,
+					      struct page, lru);
+		list_del(&pgtable->lru);
+	}
+	return pgtable;
+}
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+#endif
+
+#ifndef __HAVE_ARCH_PMDP_INVALIDATE
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
+		     pmd_t *pmdp)
+{
+	set_pmd_at(vma->vm_mm, address, pmdp, pmd_mknotpresent(*pmdp));
+	flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
+}
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+#endif
diff --git a/mm/prio_tree.c b/mm/prio_tree.c
deleted file mode 100644
index 799dcfd..0000000
--- a/mm/prio_tree.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * mm/prio_tree.c - priority search tree for mapping->i_mmap
- *
- * Copyright (C) 2004, Rajesh Venkatasubramanian <vrajesh@umich.edu>
- *
- * This file is released under the GPL v2.
- *
- * Based on the radix priority search tree proposed by Edward M. McCreight
- * SIAM Journal of Computing, vol. 14, no.2, pages 257-276, May 1985
- *
- * 02Feb2004	Initial version
- */
-
-#include <linux/mm.h>
-#include <linux/prio_tree.h>
-#include <linux/prefetch.h>
-
-/*
- * See lib/prio_tree.c for details on the general radix priority search tree
- * code.
- */
-
-/*
- * The following #defines are mirrored from lib/prio_tree.c. They're only used
- * for debugging, and should be removed (along with the debugging code using
- * them) when switching also VMAs to the regular prio_tree code.
- */
-
-#define RADIX_INDEX(vma)  ((vma)->vm_pgoff)
-#define VMA_SIZE(vma)	  (((vma)->vm_end - (vma)->vm_start) >> PAGE_SHIFT)
-/* avoid overflow */
-#define HEAP_INDEX(vma)   ((vma)->vm_pgoff + (VMA_SIZE(vma) - 1))
-
-/*
- * Radix priority search tree for address_space->i_mmap
- *
- * For each vma that map a unique set of file pages i.e., unique [radix_index,
- * heap_index] value, we have a corresponding priority search tree node. If
- * multiple vmas have identical [radix_index, heap_index] value, then one of
- * them is used as a tree node and others are stored in a vm_set list. The tree
- * node points to the first vma (head) of the list using vm_set.head.
- *
- * prio_tree_root
- *      |
- *      A       vm_set.head
- *     / \      /
- *    L   R -> H-I-J-K-M-N-O-P-Q-S
- *    ^   ^    <-- vm_set.list -->
- *  tree nodes
- *
- * We need some way to identify whether a vma is a tree node, head of a vm_set
- * list, or just a member of a vm_set list. We cannot use vm_flags to store
- * such information. The reason is, in the above figure, it is possible that
- * vm_flags' of R and H are covered by the different mmap_sems. When R is
- * removed under R->mmap_sem, H replaces R as a tree node. Since we do not hold
- * H->mmap_sem, we cannot use H->vm_flags for marking that H is a tree node now.
- * That's why some trick involving shared.vm_set.parent is used for identifying
- * tree nodes and list head nodes.
- *
- * vma radix priority search tree node rules:
- *
- * vma->shared.vm_set.parent != NULL    ==> a tree node
- *      vma->shared.vm_set.head != NULL ==> list of others mapping same range
- *      vma->shared.vm_set.head == NULL ==> no others map the same range
- *
- * vma->shared.vm_set.parent == NULL
- * 	vma->shared.vm_set.head != NULL ==> list head of vmas mapping same range
- * 	vma->shared.vm_set.head == NULL ==> a list node
- */
-
-/*
- * Add a new vma known to map the same set of pages as the old vma:
- * useful for fork's dup_mmap as well as vma_prio_tree_insert below.
- * Note that it just happens to work correctly on i_mmap_nonlinear too.
- */
-void vma_prio_tree_add(struct vm_area_struct *vma, struct vm_area_struct *old)
-{
-	/* Leave these BUG_ONs till prio_tree patch stabilizes */
-	BUG_ON(RADIX_INDEX(vma) != RADIX_INDEX(old));
-	BUG_ON(HEAP_INDEX(vma) != HEAP_INDEX(old));
-
-	vma->shared.vm_set.head = NULL;
-	vma->shared.vm_set.parent = NULL;
-
-	if (!old->shared.vm_set.parent)
-		list_add(&vma->shared.vm_set.list,
-				&old->shared.vm_set.list);
-	else if (old->shared.vm_set.head)
-		list_add_tail(&vma->shared.vm_set.list,
-				&old->shared.vm_set.head->shared.vm_set.list);
-	else {
-		INIT_LIST_HEAD(&vma->shared.vm_set.list);
-		vma->shared.vm_set.head = old;
-		old->shared.vm_set.head = vma;
-	}
-}
-
-void vma_prio_tree_insert(struct vm_area_struct *vma,
-			  struct prio_tree_root *root)
-{
-	struct prio_tree_node *ptr;
-	struct vm_area_struct *old;
-
-	vma->shared.vm_set.head = NULL;
-
-	ptr = raw_prio_tree_insert(root, &vma->shared.prio_tree_node);
-	if (ptr != (struct prio_tree_node *) &vma->shared.prio_tree_node) {
-		old = prio_tree_entry(ptr, struct vm_area_struct,
-					shared.prio_tree_node);
-		vma_prio_tree_add(vma, old);
-	}
-}
-
-void vma_prio_tree_remove(struct vm_area_struct *vma,
-			  struct prio_tree_root *root)
-{
-	struct vm_area_struct *node, *head, *new_head;
-
-	if (!vma->shared.vm_set.head) {
-		if (!vma->shared.vm_set.parent)
-			list_del_init(&vma->shared.vm_set.list);
-		else
-			raw_prio_tree_remove(root, &vma->shared.prio_tree_node);
-	} else {
-		/* Leave this BUG_ON till prio_tree patch stabilizes */
-		BUG_ON(vma->shared.vm_set.head->shared.vm_set.head != vma);
-		if (vma->shared.vm_set.parent) {
-			head = vma->shared.vm_set.head;
-			if (!list_empty(&head->shared.vm_set.list)) {
-				new_head = list_entry(
-					head->shared.vm_set.list.next,
-					struct vm_area_struct,
-					shared.vm_set.list);
-				list_del_init(&head->shared.vm_set.list);
-			} else
-				new_head = NULL;
-
-			raw_prio_tree_replace(root, &vma->shared.prio_tree_node,
-					&head->shared.prio_tree_node);
-			head->shared.vm_set.head = new_head;
-			if (new_head)
-				new_head->shared.vm_set.head = head;
-
-		} else {
-			node = vma->shared.vm_set.head;
-			if (!list_empty(&vma->shared.vm_set.list)) {
-				new_head = list_entry(
-					vma->shared.vm_set.list.next,
-					struct vm_area_struct,
-					shared.vm_set.list);
-				list_del_init(&vma->shared.vm_set.list);
-				node->shared.vm_set.head = new_head;
-				new_head->shared.vm_set.head = node;
-			} else
-				node->shared.vm_set.head = NULL;
-		}
-	}
-}
-
-/*
- * Helper function to enumerate vmas that map a given file page or a set of
- * contiguous file pages. The function returns vmas that at least map a single
- * page in the given range of contiguous file pages.
- */
-struct vm_area_struct *vma_prio_tree_next(struct vm_area_struct *vma,
-					struct prio_tree_iter *iter)
-{
-	struct prio_tree_node *ptr;
-	struct vm_area_struct *next;
-
-	if (!vma) {
-		/*
-		 * First call is with NULL vma
-		 */
-		ptr = prio_tree_next(iter);
-		if (ptr) {
-			next = prio_tree_entry(ptr, struct vm_area_struct,
-						shared.prio_tree_node);
-			prefetch(next->shared.vm_set.head);
-			return next;
-		} else
-			return NULL;
-	}
-
-	if (vma->shared.vm_set.parent) {
-		if (vma->shared.vm_set.head) {
-			next = vma->shared.vm_set.head;
-			prefetch(next->shared.vm_set.list.next);
-			return next;
-		}
-	} else {
-		next = list_entry(vma->shared.vm_set.list.next,
-				struct vm_area_struct, shared.vm_set.list);
-		if (!next->shared.vm_set.head) {
-			prefetch(next->shared.vm_set.list.next);
-			return next;
-		}
-	}
-
-	ptr = prio_tree_next(iter);
-	if (ptr) {
-		next = prio_tree_entry(ptr, struct vm_area_struct,
-					shared.prio_tree_node);
-		prefetch(next->shared.vm_set.head);
-		return next;
-	} else
-		return NULL;
-}
diff --git a/mm/rmap.c b/mm/rmap.c
index 0f3b7cd..7df7984 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -127,12 +127,7 @@
 	avc->vma = vma;
 	avc->anon_vma = anon_vma;
 	list_add(&avc->same_vma, &vma->anon_vma_chain);
-
-	/*
-	 * It's critical to add new vmas to the tail of the anon_vma,
-	 * see comment in huge_memory.c:__split_huge_page().
-	 */
-	list_add_tail(&avc->same_anon_vma, &anon_vma->head);
+	anon_vma_interval_tree_insert(avc, &anon_vma->rb_root);
 }
 
 /**
@@ -269,51 +264,6 @@
 }
 
 /*
- * Some rmap walk that needs to find all ptes/hugepmds without false
- * negatives (like migrate and split_huge_page) running concurrent
- * with operations that copy or move pagetables (like mremap() and
- * fork()) to be safe. They depend on the anon_vma "same_anon_vma"
- * list to be in a certain order: the dst_vma must be placed after the
- * src_vma in the list. This is always guaranteed by fork() but
- * mremap() needs to call this function to enforce it in case the
- * dst_vma isn't newly allocated and chained with the anon_vma_clone()
- * function but just an extension of a pre-existing vma through
- * vma_merge.
- *
- * NOTE: the same_anon_vma list can still be changed by other
- * processes while mremap runs because mremap doesn't hold the
- * anon_vma mutex to prevent modifications to the list while it
- * runs. All we need to enforce is that the relative order of this
- * process vmas isn't changing (we don't care about other vmas
- * order). Each vma corresponds to an anon_vma_chain structure so
- * there's no risk that other processes calling anon_vma_moveto_tail()
- * and changing the same_anon_vma list under mremap() will screw with
- * the relative order of this process vmas in the list, because we
- * they can't alter the order of any vma that belongs to this
- * process. And there can't be another anon_vma_moveto_tail() running
- * concurrently with mremap() coming from this process because we hold
- * the mmap_sem for the whole mremap(). fork() ordering dependency
- * also shouldn't be affected because fork() only cares that the
- * parent vmas are placed in the list before the child vmas and
- * anon_vma_moveto_tail() won't reorder vmas from either the fork()
- * parent or child.
- */
-void anon_vma_moveto_tail(struct vm_area_struct *dst)
-{
-	struct anon_vma_chain *pavc;
-	struct anon_vma *root = NULL;
-
-	list_for_each_entry_reverse(pavc, &dst->anon_vma_chain, same_vma) {
-		struct anon_vma *anon_vma = pavc->anon_vma;
-		VM_BUG_ON(pavc->vma != dst);
-		root = lock_anon_vma_root(root, anon_vma);
-		list_del(&pavc->same_anon_vma);
-		list_add_tail(&pavc->same_anon_vma, &anon_vma->head);
-	}
-	unlock_anon_vma_root(root);
-}
-
-/*
  * Attach vma to its own anon_vma, as well as to the anon_vmas that
  * the corresponding VMA in the parent process is attached to.
  * Returns 0 on success, non-zero on failure.
@@ -381,13 +331,13 @@
 		struct anon_vma *anon_vma = avc->anon_vma;
 
 		root = lock_anon_vma_root(root, anon_vma);
-		list_del(&avc->same_anon_vma);
+		anon_vma_interval_tree_remove(avc, &anon_vma->rb_root);
 
 		/*
 		 * Leave empty anon_vmas on the list - we'll need
 		 * to free them outside the lock.
 		 */
-		if (list_empty(&anon_vma->head))
+		if (RB_EMPTY_ROOT(&anon_vma->rb_root))
 			continue;
 
 		list_del(&avc->same_vma);
@@ -416,7 +366,7 @@
 
 	mutex_init(&anon_vma->mutex);
 	atomic_set(&anon_vma->refcount, 0);
-	INIT_LIST_HEAD(&anon_vma->head);
+	anon_vma->rb_root = RB_ROOT;
 }
 
 void __init anon_vma_init(void)
@@ -560,22 +510,26 @@
 
 /*
  * At what user virtual address is page expected in @vma?
- * Returns virtual address or -EFAULT if page's index/offset is not
- * within the range mapped the @vma.
  */
-inline unsigned long
-vma_address(struct page *page, struct vm_area_struct *vma)
+static inline unsigned long
+__vma_address(struct page *page, struct vm_area_struct *vma)
 {
 	pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
-	unsigned long address;
 
 	if (unlikely(is_vm_hugetlb_page(vma)))
 		pgoff = page->index << huge_page_order(page_hstate(page));
-	address = vma->vm_start + ((pgoff - vma->vm_pgoff) << PAGE_SHIFT);
-	if (unlikely(address < vma->vm_start || address >= vma->vm_end)) {
-		/* page should be within @vma mapping range */
-		return -EFAULT;
-	}
+
+	return vma->vm_start + ((pgoff - vma->vm_pgoff) << PAGE_SHIFT);
+}
+
+inline unsigned long
+vma_address(struct page *page, struct vm_area_struct *vma)
+{
+	unsigned long address = __vma_address(page, vma);
+
+	/* page should be within @vma mapping range */
+	VM_BUG_ON(address < vma->vm_start || address >= vma->vm_end);
+
 	return address;
 }
 
@@ -585,6 +539,7 @@
  */
 unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma)
 {
+	unsigned long address;
 	if (PageAnon(page)) {
 		struct anon_vma *page__anon_vma = page_anon_vma(page);
 		/*
@@ -600,7 +555,10 @@
 			return -EFAULT;
 	} else
 		return -EFAULT;
-	return vma_address(page, vma);
+	address = __vma_address(page, vma);
+	if (unlikely(address < vma->vm_start || address >= vma->vm_end))
+		return -EFAULT;
+	return address;
 }
 
 /*
@@ -674,8 +632,8 @@
 	pte_t *pte;
 	spinlock_t *ptl;
 
-	address = vma_address(page, vma);
-	if (address == -EFAULT)		/* out of vma range */
+	address = __vma_address(page, vma);
+	if (unlikely(address < vma->vm_start || address >= vma->vm_end))
 		return 0;
 	pte = page_check_address(page, vma->vm_mm, address, &ptl, 1);
 	if (!pte)			/* the page is not in this mm */
@@ -769,6 +727,7 @@
 {
 	unsigned int mapcount;
 	struct anon_vma *anon_vma;
+	pgoff_t pgoff;
 	struct anon_vma_chain *avc;
 	int referenced = 0;
 
@@ -777,11 +736,10 @@
 		return referenced;
 
 	mapcount = page_mapcount(page);
-	list_for_each_entry(avc, &anon_vma->head, same_anon_vma) {
+	pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
+	anon_vma_interval_tree_foreach(avc, &anon_vma->rb_root, pgoff, pgoff) {
 		struct vm_area_struct *vma = avc->vma;
 		unsigned long address = vma_address(page, vma);
-		if (address == -EFAULT)
-			continue;
 		/*
 		 * If we are reclaiming on behalf of a cgroup, skip
 		 * counting on behalf of references from different
@@ -820,7 +778,6 @@
 	struct address_space *mapping = page->mapping;
 	pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
 	struct vm_area_struct *vma;
-	struct prio_tree_iter iter;
 	int referenced = 0;
 
 	/*
@@ -846,10 +803,8 @@
 	 */
 	mapcount = page_mapcount(page);
 
-	vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
+	vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) {
 		unsigned long address = vma_address(page, vma);
-		if (address == -EFAULT)
-			continue;
 		/*
 		 * If we are reclaiming on behalf of a cgroup, skip
 		 * counting on behalf of references from different
@@ -929,7 +884,7 @@
 		pte_t entry;
 
 		flush_cache_page(vma, address, pte_pfn(*pte));
-		entry = ptep_clear_flush_notify(vma, address, pte);
+		entry = ptep_clear_flush(vma, address, pte);
 		entry = pte_wrprotect(entry);
 		entry = pte_mkclean(entry);
 		set_pte_at(mm, address, pte, entry);
@@ -937,6 +892,9 @@
 	}
 
 	pte_unmap_unlock(pte, ptl);
+
+	if (ret)
+		mmu_notifier_invalidate_page(mm, address);
 out:
 	return ret;
 }
@@ -945,17 +903,14 @@
 {
 	pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
 	struct vm_area_struct *vma;
-	struct prio_tree_iter iter;
 	int ret = 0;
 
 	BUG_ON(PageAnon(page));
 
 	mutex_lock(&mapping->i_mmap_mutex);
-	vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
+	vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) {
 		if (vma->vm_flags & VM_SHARED) {
 			unsigned long address = vma_address(page, vma);
-			if (address == -EFAULT)
-				continue;
 			ret += page_mkclean_one(page, vma, address);
 		}
 	}
@@ -1128,7 +1083,7 @@
 	else
 		__inc_zone_page_state(page, NR_ANON_TRANSPARENT_HUGEPAGES);
 	__page_set_anon_rmap(page, vma, address, 1);
-	if (page_evictable(page, vma))
+	if (!mlocked_vma_newpage(vma, page))
 		lru_cache_add_lru(page, LRU_ACTIVE_ANON);
 	else
 		add_page_to_unevictable_list(page);
@@ -1203,7 +1158,10 @@
 	} else {
 		__dec_zone_page_state(page, NR_FILE_MAPPED);
 		mem_cgroup_dec_page_stat(page, MEMCG_NR_FILE_MAPPED);
+		mem_cgroup_end_update_page_stat(page, &locked, &flags);
 	}
+	if (unlikely(PageMlocked(page)))
+		clear_page_mlock(page);
 	/*
 	 * It would be tidy to reset the PageAnon mapping here,
 	 * but that might overwrite a racing page_add_anon_rmap
@@ -1213,6 +1171,7 @@
 	 * Leaving it set also helps swapoff to reinstate ptes
 	 * faster for those pages still in swapcache.
 	 */
+	return;
 out:
 	if (!anon)
 		mem_cgroup_end_update_page_stat(page, &locked, &flags);
@@ -1256,7 +1215,7 @@
 
 	/* Nuke the page table entry. */
 	flush_cache_page(vma, address, page_to_pfn(page));
-	pteval = ptep_clear_flush_notify(vma, address, pte);
+	pteval = ptep_clear_flush(vma, address, pte);
 
 	/* Move the dirty bit to the physical page now the pte is gone. */
 	if (pte_dirty(pteval))
@@ -1318,6 +1277,8 @@
 
 out_unmap:
 	pte_unmap_unlock(pte, ptl);
+	if (ret != SWAP_FAIL)
+		mmu_notifier_invalidate_page(mm, address);
 out:
 	return ret;
 
@@ -1382,6 +1343,8 @@
 	spinlock_t *ptl;
 	struct page *page;
 	unsigned long address;
+	unsigned long mmun_start;	/* For mmu_notifiers */
+	unsigned long mmun_end;		/* For mmu_notifiers */
 	unsigned long end;
 	int ret = SWAP_AGAIN;
 	int locked_vma = 0;
@@ -1405,6 +1368,10 @@
 	if (!pmd_present(*pmd))
 		return ret;
 
+	mmun_start = address;
+	mmun_end   = end;
+	mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
+
 	/*
 	 * If we can acquire the mmap_sem for read, and vma is VM_LOCKED,
 	 * keep the sem while scanning the cluster for mlocking pages.
@@ -1438,7 +1405,7 @@
 
 		/* Nuke the page table entry. */
 		flush_cache_page(vma, address, pte_pfn(*pte));
-		pteval = ptep_clear_flush_notify(vma, address, pte);
+		pteval = ptep_clear_flush(vma, address, pte);
 
 		/* If nonlinear, store the file page offset in the pte. */
 		if (page->index != linear_page_index(vma, address))
@@ -1454,6 +1421,7 @@
 		(*mapcount)--;
 	}
 	pte_unmap_unlock(pte - 1, ptl);
+	mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
 	if (locked_vma)
 		up_read(&vma->vm_mm->mmap_sem);
 	return ret;
@@ -1492,6 +1460,7 @@
 static int try_to_unmap_anon(struct page *page, enum ttu_flags flags)
 {
 	struct anon_vma *anon_vma;
+	pgoff_t pgoff;
 	struct anon_vma_chain *avc;
 	int ret = SWAP_AGAIN;
 
@@ -1499,7 +1468,8 @@
 	if (!anon_vma)
 		return ret;
 
-	list_for_each_entry(avc, &anon_vma->head, same_anon_vma) {
+	pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
+	anon_vma_interval_tree_foreach(avc, &anon_vma->rb_root, pgoff, pgoff) {
 		struct vm_area_struct *vma = avc->vma;
 		unsigned long address;
 
@@ -1516,8 +1486,6 @@
 			continue;
 
 		address = vma_address(page, vma);
-		if (address == -EFAULT)
-			continue;
 		ret = try_to_unmap_one(page, vma, address, flags);
 		if (ret != SWAP_AGAIN || !page_mapped(page))
 			break;
@@ -1547,7 +1515,6 @@
 	struct address_space *mapping = page->mapping;
 	pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
 	struct vm_area_struct *vma;
-	struct prio_tree_iter iter;
 	int ret = SWAP_AGAIN;
 	unsigned long cursor;
 	unsigned long max_nl_cursor = 0;
@@ -1555,10 +1522,8 @@
 	unsigned int mapcount;
 
 	mutex_lock(&mapping->i_mmap_mutex);
-	vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
+	vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) {
 		unsigned long address = vma_address(page, vma);
-		if (address == -EFAULT)
-			continue;
 		ret = try_to_unmap_one(page, vma, address, flags);
 		if (ret != SWAP_AGAIN || !page_mapped(page))
 			goto out;
@@ -1576,7 +1541,7 @@
 		goto out;
 
 	list_for_each_entry(vma, &mapping->i_mmap_nonlinear,
-						shared.vm_set.list) {
+							shared.nonlinear) {
 		cursor = (unsigned long) vma->vm_private_data;
 		if (cursor > max_nl_cursor)
 			max_nl_cursor = cursor;
@@ -1608,7 +1573,7 @@
 
 	do {
 		list_for_each_entry(vma, &mapping->i_mmap_nonlinear,
-						shared.vm_set.list) {
+							shared.nonlinear) {
 			cursor = (unsigned long) vma->vm_private_data;
 			while ( cursor < max_nl_cursor &&
 				cursor < vma->vm_end - vma->vm_start) {
@@ -1631,7 +1596,7 @@
 	 * in locked vmas).  Reset cursor on all unreserved nonlinear
 	 * vmas, now forgetting on which ones it had fallen behind.
 	 */
-	list_for_each_entry(vma, &mapping->i_mmap_nonlinear, shared.vm_set.list)
+	list_for_each_entry(vma, &mapping->i_mmap_nonlinear, shared.nonlinear)
 		vma->vm_private_data = NULL;
 out:
 	mutex_unlock(&mapping->i_mmap_mutex);
@@ -1716,6 +1681,7 @@
 		struct vm_area_struct *, unsigned long, void *), void *arg)
 {
 	struct anon_vma *anon_vma;
+	pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
 	struct anon_vma_chain *avc;
 	int ret = SWAP_AGAIN;
 
@@ -1729,11 +1695,9 @@
 	if (!anon_vma)
 		return ret;
 	anon_vma_lock(anon_vma);
-	list_for_each_entry(avc, &anon_vma->head, same_anon_vma) {
+	anon_vma_interval_tree_foreach(avc, &anon_vma->rb_root, pgoff, pgoff) {
 		struct vm_area_struct *vma = avc->vma;
 		unsigned long address = vma_address(page, vma);
-		if (address == -EFAULT)
-			continue;
 		ret = rmap_one(page, vma, address, arg);
 		if (ret != SWAP_AGAIN)
 			break;
@@ -1748,16 +1712,13 @@
 	struct address_space *mapping = page->mapping;
 	pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
 	struct vm_area_struct *vma;
-	struct prio_tree_iter iter;
 	int ret = SWAP_AGAIN;
 
 	if (!mapping)
 		return ret;
 	mutex_lock(&mapping->i_mmap_mutex);
-	vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
+	vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) {
 		unsigned long address = vma_address(page, vma);
-		if (address == -EFAULT)
-			continue;
 		ret = rmap_one(page, vma, address, arg);
 		if (ret != SWAP_AGAIN)
 			break;
diff --git a/mm/shmem.c b/mm/shmem.c
index d375211..67afba5 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1339,7 +1339,6 @@
 {
 	file_accessed(file);
 	vma->vm_ops = &shmem_vm_ops;
-	vma->vm_flags |= VM_CAN_NONLINEAR;
 	return 0;
 }
 
@@ -2221,12 +2220,14 @@
 {
 	struct inode *inode;
 	struct dentry *dentry = NULL;
-	u64 inum = fid->raw[2];
-	inum = (inum << 32) | fid->raw[1];
+	u64 inum;
 
 	if (fh_len < 3)
 		return NULL;
 
+	inum = fid->raw[2];
+	inum = (inum << 32) | fid->raw[1];
+
 	inode = ilookup5(sb, (unsigned long)(inum + fid->raw[0]),
 			shmem_match, fid->raw);
 	if (inode) {
@@ -2643,6 +2644,7 @@
 	.set_policy     = shmem_set_policy,
 	.get_policy     = shmem_get_policy,
 #endif
+	.remap_pages	= generic_file_remap_pages,
 };
 
 static struct dentry *shmem_mount(struct file_system_type *fs_type,
@@ -2836,7 +2838,6 @@
 		fput(vma->vm_file);
 	vma->vm_file = file;
 	vma->vm_ops = &shmem_vm_ops;
-	vma->vm_flags |= VM_CAN_NONLINEAR;
 	return 0;
 }
 
diff --git a/mm/swap.c b/mm/swap.c
index 7782588..6310dc2 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -446,13 +446,22 @@
 }
 EXPORT_SYMBOL(mark_page_accessed);
 
+/*
+ * Order of operations is important: flush the pagevec when it's already
+ * full, not when adding the last page, to make sure that last page is
+ * not added to the LRU directly when passed to this function. Because
+ * mark_page_accessed() (called after this when writing) only activates
+ * pages that are on the LRU, linear writes in subpage chunks would see
+ * every PAGEVEC_SIZE page activated, which is unexpected.
+ */
 void __lru_cache_add(struct page *page, enum lru_list lru)
 {
 	struct pagevec *pvec = &get_cpu_var(lru_add_pvecs)[lru];
 
 	page_cache_get(page);
-	if (!pagevec_add(pvec, page))
+	if (!pagevec_space(pvec))
 		__pagevec_lru_add(pvec, lru);
+	pagevec_add(pvec, page);
 	put_cpu_var(lru_add_pvecs);
 }
 EXPORT_SYMBOL(__lru_cache_add);
@@ -742,7 +751,7 @@
 
 	SetPageLRU(page_tail);
 
-	if (page_evictable(page_tail, NULL)) {
+	if (page_evictable(page_tail)) {
 		if (PageActive(page)) {
 			SetPageActive(page_tail);
 			active = 1;
diff --git a/mm/truncate.c b/mm/truncate.c
index 75801ac..d51ce92 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -107,7 +107,6 @@
 
 	cancel_dirty_page(page, PAGE_CACHE_SIZE);
 
-	clear_page_mlock(page);
 	ClearPageMappedToDisk(page);
 	delete_from_page_cache(page);
 	return 0;
@@ -132,7 +131,6 @@
 	if (page_has_private(page) && !try_to_release_page(page, 0))
 		return 0;
 
-	clear_page_mlock(page);
 	ret = remove_mapping(mapping, page);
 
 	return ret;
@@ -398,7 +396,6 @@
 	if (PageDirty(page))
 		goto failed;
 
-	clear_page_mlock(page);
 	BUG_ON(page_has_private(page));
 	__delete_from_page_cache(page);
 	spin_unlock_irq(&mapping->tree_lock);
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 2bb90b1..78e0830 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -2163,8 +2163,7 @@
 		usize -= PAGE_SIZE;
 	} while (usize > 0);
 
-	/* Prevent "things" like memory migration? VM_flags need a cleanup... */
-	vma->vm_flags |= VM_RESERVED;
+	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 
 	return 0;
 }
@@ -2572,7 +2571,7 @@
 {
 	struct vm_struct *v = p;
 
-	seq_printf(m, "0x%p-0x%p %7ld",
+	seq_printf(m, "0x%pK-0x%pK %7ld",
 		v->addr, v->addr + v->size, v->size);
 
 	if (v->caller)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 99b434b..2624edc 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -553,7 +553,7 @@
 redo:
 	ClearPageUnevictable(page);
 
-	if (page_evictable(page, NULL)) {
+	if (page_evictable(page)) {
 		/*
 		 * For evictable pages, we can use the cache.
 		 * In event of a race, worst case is we end up with an
@@ -587,7 +587,7 @@
 	 * page is on unevictable list, it never be freed. To avoid that,
 	 * check after we added it to the list, again.
 	 */
-	if (lru == LRU_UNEVICTABLE && page_evictable(page, NULL)) {
+	if (lru == LRU_UNEVICTABLE && page_evictable(page)) {
 		if (!isolate_lru_page(page)) {
 			put_page(page);
 			goto redo;
@@ -674,8 +674,10 @@
 static unsigned long shrink_page_list(struct list_head *page_list,
 				      struct zone *zone,
 				      struct scan_control *sc,
+				      enum ttu_flags ttu_flags,
 				      unsigned long *ret_nr_dirty,
-				      unsigned long *ret_nr_writeback)
+				      unsigned long *ret_nr_writeback,
+				      bool force_reclaim)
 {
 	LIST_HEAD(ret_pages);
 	LIST_HEAD(free_pages);
@@ -689,10 +691,10 @@
 
 	mem_cgroup_uncharge_start();
 	while (!list_empty(page_list)) {
-		enum page_references references;
 		struct address_space *mapping;
 		struct page *page;
 		int may_enter_fs;
+		enum page_references references = PAGEREF_RECLAIM_CLEAN;
 
 		cond_resched();
 
@@ -707,7 +709,7 @@
 
 		sc->nr_scanned++;
 
-		if (unlikely(!page_evictable(page, NULL)))
+		if (unlikely(!page_evictable(page)))
 			goto cull_mlocked;
 
 		if (!sc->may_unmap && page_mapped(page))
@@ -758,7 +760,9 @@
 			wait_on_page_writeback(page);
 		}
 
-		references = page_check_references(page, sc);
+		if (!force_reclaim)
+			references = page_check_references(page, sc);
+
 		switch (references) {
 		case PAGEREF_ACTIVATE:
 			goto activate_locked;
@@ -788,7 +792,7 @@
 		 * processes. Try to unmap it here.
 		 */
 		if (page_mapped(page) && mapping) {
-			switch (try_to_unmap(page, TTU_UNMAP)) {
+			switch (try_to_unmap(page, ttu_flags)) {
 			case SWAP_FAIL:
 				goto activate_locked;
 			case SWAP_AGAIN:
@@ -960,6 +964,33 @@
 	return nr_reclaimed;
 }
 
+unsigned long reclaim_clean_pages_from_list(struct zone *zone,
+					    struct list_head *page_list)
+{
+	struct scan_control sc = {
+		.gfp_mask = GFP_KERNEL,
+		.priority = DEF_PRIORITY,
+		.may_unmap = 1,
+	};
+	unsigned long ret, dummy1, dummy2;
+	struct page *page, *next;
+	LIST_HEAD(clean_pages);
+
+	list_for_each_entry_safe(page, next, page_list, lru) {
+		if (page_is_file_cache(page) && !PageDirty(page)) {
+			ClearPageActive(page);
+			list_move(&page->lru, &clean_pages);
+		}
+	}
+
+	ret = shrink_page_list(&clean_pages, zone, &sc,
+				TTU_UNMAP|TTU_IGNORE_ACCESS,
+				&dummy1, &dummy2, true);
+	list_splice(&clean_pages, page_list);
+	__mod_zone_page_state(zone, NR_ISOLATED_FILE, -ret);
+	return ret;
+}
+
 /*
  * Attempt to remove the specified page from its LRU.  Only take this page
  * if it is of the appropriate PageActive status.  Pages which are being
@@ -978,8 +1009,8 @@
 	if (!PageLRU(page))
 		return ret;
 
-	/* Do not give back unevictable pages for compaction */
-	if (PageUnevictable(page))
+	/* Compaction should not handle unevictable pages but CMA can do so */
+	if (PageUnevictable(page) && !(mode & ISOLATE_UNEVICTABLE))
 		return ret;
 
 	ret = -EBUSY;
@@ -1186,7 +1217,7 @@
 
 		VM_BUG_ON(PageLRU(page));
 		list_del(&page->lru);
-		if (unlikely(!page_evictable(page, NULL))) {
+		if (unlikely(!page_evictable(page))) {
 			spin_unlock_irq(&zone->lru_lock);
 			putback_lru_page(page);
 			spin_lock_irq(&zone->lru_lock);
@@ -1278,8 +1309,8 @@
 	if (nr_taken == 0)
 		return 0;
 
-	nr_reclaimed = shrink_page_list(&page_list, zone, sc,
-						&nr_dirty, &nr_writeback);
+	nr_reclaimed = shrink_page_list(&page_list, zone, sc, TTU_UNMAP,
+					&nr_dirty, &nr_writeback, false);
 
 	spin_lock_irq(&zone->lru_lock);
 
@@ -1439,7 +1470,7 @@
 		page = lru_to_page(&l_hold);
 		list_del(&page->lru);
 
-		if (unlikely(!page_evictable(page, NULL))) {
+		if (unlikely(!page_evictable(page))) {
 			putback_lru_page(page);
 			continue;
 		}
@@ -1729,6 +1760,28 @@
 	return false;
 }
 
+#ifdef CONFIG_COMPACTION
+/*
+ * If compaction is deferred for sc->order then scale the number of pages
+ * reclaimed based on the number of consecutive allocation failures
+ */
+static unsigned long scale_for_compaction(unsigned long pages_for_compaction,
+			struct lruvec *lruvec, struct scan_control *sc)
+{
+	struct zone *zone = lruvec_zone(lruvec);
+
+	if (zone->compact_order_failed <= sc->order)
+		pages_for_compaction <<= zone->compact_defer_shift;
+	return pages_for_compaction;
+}
+#else
+static unsigned long scale_for_compaction(unsigned long pages_for_compaction,
+			struct lruvec *lruvec, struct scan_control *sc)
+{
+	return pages_for_compaction;
+}
+#endif
+
 /*
  * Reclaim/compaction is used for high-order allocation requests. It reclaims
  * order-0 pages before compacting the zone. should_continue_reclaim() returns
@@ -1776,6 +1829,9 @@
 	 * inactive lists are large enough, continue reclaiming
 	 */
 	pages_for_compaction = (2UL << sc->order);
+
+	pages_for_compaction = scale_for_compaction(pages_for_compaction,
+						    lruvec, sc);
 	inactive_lru_pages = get_lru_size(lruvec, LRU_INACTIVE_FILE);
 	if (nr_swap_pages > 0)
 		inactive_lru_pages += get_lru_size(lruvec, LRU_INACTIVE_ANON);
@@ -2839,6 +2895,14 @@
 		 */
 		set_pgdat_percpu_threshold(pgdat, calculate_normal_threshold);
 
+		/*
+		 * Compaction records what page blocks it recently failed to
+		 * isolate pages from and skips them in the future scanning.
+		 * When kswapd is going to sleep, it is reasonable to assume
+		 * that pages and compaction may succeed so reset the cache.
+		 */
+		reset_isolation_suitable(pgdat);
+
 		if (!kthread_should_stop())
 			schedule();
 
@@ -3101,9 +3165,9 @@
 	if (IS_ERR(pgdat->kswapd)) {
 		/* failure at boot is fatal */
 		BUG_ON(system_state == SYSTEM_BOOTING);
-		printk("Failed to start kswapd on node %d\n",nid);
 		pgdat->kswapd = NULL;
-		ret = -1;
+		pr_err("Failed to start kswapd on node %d\n", nid);
+		ret = PTR_ERR(pgdat->kswapd);
 	}
 	return ret;
 }
@@ -3350,27 +3414,18 @@
 /*
  * page_evictable - test whether a page is evictable
  * @page: the page to test
- * @vma: the VMA in which the page is or will be mapped, may be NULL
  *
  * Test whether page is evictable--i.e., should be placed on active/inactive
- * lists vs unevictable list.  The vma argument is !NULL when called from the
- * fault path to determine how to instantate a new page.
+ * lists vs unevictable list.
  *
  * Reasons page might not be evictable:
  * (1) page's mapping marked unevictable
  * (2) page is part of an mlocked VMA
  *
  */
-int page_evictable(struct page *page, struct vm_area_struct *vma)
+int page_evictable(struct page *page)
 {
-
-	if (mapping_unevictable(page_mapping(page)))
-		return 0;
-
-	if (PageMlocked(page) || (vma && mlocked_vma_newpage(vma, page)))
-		return 0;
-
-	return 1;
+	return !mapping_unevictable(page_mapping(page)) && !PageMlocked(page);
 }
 
 #ifdef CONFIG_SHMEM
@@ -3408,7 +3463,7 @@
 		if (!PageLRU(page) || !PageUnevictable(page))
 			continue;
 
-		if (page_evictable(page, NULL)) {
+		if (page_evictable(page)) {
 			enum lru_list lru = page_lru_base_type(page);
 
 			VM_BUG_ON(PageActive(page));
diff --git a/mm/vmstat.c b/mm/vmstat.c
index b3e3b9d..c737057 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -495,6 +495,18 @@
 			atomic_long_add(global_diff[i], &vm_stat[i]);
 }
 
+void drain_zonestat(struct zone *zone, struct per_cpu_pageset *pset)
+{
+	int i;
+
+	for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
+		if (pset->vm_stat_diff[i]) {
+			int v = pset->vm_stat_diff[i];
+			pset->vm_stat_diff[i] = 0;
+			atomic_long_add(v, &zone->vm_stat[i]);
+			atomic_long_add(v, &vm_stat[i]);
+		}
+}
 #endif
 
 #ifdef CONFIG_NUMA
@@ -722,6 +734,7 @@
 	"numa_other",
 #endif
 	"nr_anon_transparent_hugepages",
+	"nr_free_cma",
 	"nr_dirty_threshold",
 	"nr_dirty_background_threshold",
 
@@ -781,7 +794,6 @@
 	"unevictable_pgs_munlocked",
 	"unevictable_pgs_cleared",
 	"unevictable_pgs_stranded",
-	"unevictable_pgs_mlockfreed",
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 	"thp_fault_alloc",
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index add69d0..fbbf1fa 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -5,7 +5,7 @@
 #include <linux/export.h>
 #include "vlan.h"
 
-bool vlan_do_receive(struct sk_buff **skbp, bool last_handler)
+bool vlan_do_receive(struct sk_buff **skbp)
 {
 	struct sk_buff *skb = *skbp;
 	u16 vlan_id = skb->vlan_tci & VLAN_VID_MASK;
@@ -13,14 +13,8 @@
 	struct vlan_pcpu_stats *rx_stats;
 
 	vlan_dev = vlan_find_dev(skb->dev, vlan_id);
-	if (!vlan_dev) {
-		/* Only the last call to vlan_do_receive() should change
-		 * pkt_type to PACKET_OTHERHOST
-		 */
-		if (vlan_id && last_handler)
-			skb->pkt_type = PACKET_OTHERHOST;
+	if (!vlan_dev)
 		return false;
-	}
 
 	skb = *skbp = skb_share_check(skb, GFP_ATOMIC);
 	if (unlikely(!skb))
diff --git a/net/9p/client.c b/net/9p/client.c
index 8260f13..34d4176 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -76,6 +76,20 @@
 }
 EXPORT_SYMBOL(p9_is_proto_dotu);
 
+/*
+ * Some error codes are taken directly from the server replies,
+ * make sure they are valid.
+ */
+static int safe_errno(int err)
+{
+	if ((err > 0) || (err < -MAX_ERRNO)) {
+		p9_debug(P9_DEBUG_ERROR, "Invalid error code %d\n", err);
+		return -EPROTO;
+	}
+	return err;
+}
+
+
 /* Interpret mount option for protocol version */
 static int get_protocol_version(char *s)
 {
@@ -782,7 +796,7 @@
 		return req;
 reterr:
 	p9_free_req(c, req);
-	return ERR_PTR(err);
+	return ERR_PTR(safe_errno(err));
 }
 
 /**
@@ -865,7 +879,7 @@
 		return req;
 reterr:
 	p9_free_req(c, req);
-	return ERR_PTR(err);
+	return ERR_PTR(safe_errno(err));
 }
 
 static struct p9_fid *p9_fid_create(struct p9_client *clnt)
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index 15656b8..02efb25 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -316,8 +316,7 @@
 						m->rsize - m->rpos);
 	p9_debug(P9_DEBUG_TRANS, "mux %p got %d bytes\n", m, err);
 	if (err == -EAGAIN) {
-		clear_bit(Rworksched, &m->wsched);
-		return;
+		goto end_clear;
 	}
 
 	if (err <= 0)
@@ -379,19 +378,20 @@
 		m->req = NULL;
 	}
 
+end_clear:
+	clear_bit(Rworksched, &m->wsched);
+
 	if (!list_empty(&m->req_list)) {
 		if (test_and_clear_bit(Rpending, &m->wsched))
 			n = POLLIN;
 		else
 			n = p9_fd_poll(m->client, NULL);
 
-		if (n & POLLIN) {
+		if ((n & POLLIN) && !test_and_set_bit(Rworksched, &m->wsched)) {
 			p9_debug(P9_DEBUG_TRANS, "sched read work %p\n", m);
 			schedule_work(&m->rq);
-		} else
-			clear_bit(Rworksched, &m->wsched);
-	} else
-		clear_bit(Rworksched, &m->wsched);
+		}
+	}
 
 	return;
 error:
@@ -453,12 +453,13 @@
 	}
 
 	if (!m->wsize) {
+		spin_lock(&m->client->lock);
 		if (list_empty(&m->unsent_req_list)) {
 			clear_bit(Wworksched, &m->wsched);
+			spin_unlock(&m->client->lock);
 			return;
 		}
 
-		spin_lock(&m->client->lock);
 		req = list_entry(m->unsent_req_list.next, struct p9_req_t,
 			       req_list);
 		req->status = REQ_STATUS_SENT;
@@ -476,10 +477,9 @@
 	clear_bit(Wpending, &m->wsched);
 	err = p9_fd_write(m->client, m->wbuf + m->wpos, m->wsize - m->wpos);
 	p9_debug(P9_DEBUG_TRANS, "mux %p sent %d bytes\n", m, err);
-	if (err == -EAGAIN) {
-		clear_bit(Wworksched, &m->wsched);
-		return;
-	}
+	if (err == -EAGAIN)
+		goto end_clear;
+
 
 	if (err < 0)
 		goto error;
@@ -492,19 +492,21 @@
 	if (m->wpos == m->wsize)
 		m->wpos = m->wsize = 0;
 
-	if (m->wsize == 0 && !list_empty(&m->unsent_req_list)) {
+end_clear:
+	clear_bit(Wworksched, &m->wsched);
+
+	if (m->wsize || !list_empty(&m->unsent_req_list)) {
 		if (test_and_clear_bit(Wpending, &m->wsched))
 			n = POLLOUT;
 		else
 			n = p9_fd_poll(m->client, NULL);
 
-		if (n & POLLOUT) {
+		if ((n & POLLOUT) &&
+		   !test_and_set_bit(Wworksched, &m->wsched)) {
 			p9_debug(P9_DEBUG_TRANS, "sched write work %p\n", m);
 			schedule_work(&m->wq);
-		} else
-			clear_bit(Wworksched, &m->wsched);
-	} else
-		clear_bit(Wworksched, &m->wsched);
+		}
+	}
 
 	return;
 
diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c
index 900ea0f..812eb3b 100644
--- a/net/ceph/mon_client.c
+++ b/net/ceph/mon_client.c
@@ -637,7 +637,7 @@
 /*
  * Do a synchronous pool op.
  */
-int ceph_monc_do_poolop(struct ceph_mon_client *monc, u32 op,
+static int do_poolop(struct ceph_mon_client *monc, u32 op,
 			u32 pool, u64 snapid,
 			char *buf, int len)
 {
@@ -687,7 +687,7 @@
 int ceph_monc_create_snapid(struct ceph_mon_client *monc,
 			    u32 pool, u64 *snapid)
 {
-	return ceph_monc_do_poolop(monc,  POOL_OP_CREATE_UNMANAGED_SNAP,
+	return do_poolop(monc,  POOL_OP_CREATE_UNMANAGED_SNAP,
 				   pool, 0, (char *)snapid, sizeof(*snapid));
 
 }
@@ -696,7 +696,7 @@
 int ceph_monc_delete_snapid(struct ceph_mon_client *monc,
 			    u32 pool, u64 snapid)
 {
-	return ceph_monc_do_poolop(monc,  POOL_OP_CREATE_UNMANAGED_SNAP,
+	return do_poolop(monc,  POOL_OP_CREATE_UNMANAGED_SNAP,
 				   pool, snapid, 0, 0);
 
 }
@@ -769,7 +769,6 @@
 		monc->monmap->mon_inst[i].name.num = cpu_to_le64(i);
 	}
 	monc->monmap->num_mon = num_mon;
-	monc->have_fsid = false;
 	return 0;
 }
 
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index 42119c0..c1d756c 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -52,7 +52,7 @@
 		op == CEPH_OSD_OP_WRITE);
 }
 
-void ceph_calc_raw_layout(struct ceph_osd_client *osdc,
+int ceph_calc_raw_layout(struct ceph_osd_client *osdc,
 			struct ceph_file_layout *layout,
 			u64 snapid,
 			u64 off, u64 *plen, u64 *bno,
@@ -62,12 +62,15 @@
 	struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base;
 	u64 orig_len = *plen;
 	u64 objoff, objlen;    /* extent in object */
+	int r;
 
 	reqhead->snapid = cpu_to_le64(snapid);
 
 	/* object extent? */
-	ceph_calc_file_object_mapping(layout, off, plen, bno,
-				      &objoff, &objlen);
+	r = ceph_calc_file_object_mapping(layout, off, plen, bno,
+					  &objoff, &objlen);
+	if (r < 0)
+		return r;
 	if (*plen < orig_len)
 		dout(" skipping last %llu, final file extent %llu~%llu\n",
 		     orig_len - *plen, off, *plen);
@@ -83,7 +86,7 @@
 
 	dout("calc_layout bno=%llx %llu~%llu (%d pages)\n",
 	     *bno, objoff, objlen, req->r_num_pages);
-
+	return 0;
 }
 EXPORT_SYMBOL(ceph_calc_raw_layout);
 
@@ -112,20 +115,25 @@
  *
  * fill osd op in request message.
  */
-static void calc_layout(struct ceph_osd_client *osdc,
-			struct ceph_vino vino,
-			struct ceph_file_layout *layout,
-			u64 off, u64 *plen,
-			struct ceph_osd_request *req,
-			struct ceph_osd_req_op *op)
+static int calc_layout(struct ceph_osd_client *osdc,
+		       struct ceph_vino vino,
+		       struct ceph_file_layout *layout,
+		       u64 off, u64 *plen,
+		       struct ceph_osd_request *req,
+		       struct ceph_osd_req_op *op)
 {
 	u64 bno;
+	int r;
 
-	ceph_calc_raw_layout(osdc, layout, vino.snap, off,
-			     plen, &bno, req, op);
+	r = ceph_calc_raw_layout(osdc, layout, vino.snap, off,
+				 plen, &bno, req, op);
+	if (r < 0)
+		return r;
 
 	snprintf(req->r_oid, sizeof(req->r_oid), "%llx.%08llx", vino.ino, bno);
 	req->r_oid_len = strlen(req->r_oid);
+
+	return r;
 }
 
 /*
@@ -213,7 +221,6 @@
 	kref_init(&req->r_kref);
 	init_completion(&req->r_completion);
 	init_completion(&req->r_safe_completion);
-	rb_init_node(&req->r_node);
 	INIT_LIST_HEAD(&req->r_unsafe_item);
 	INIT_LIST_HEAD(&req->r_linger_item);
 	INIT_LIST_HEAD(&req->r_linger_osd);
@@ -456,6 +463,7 @@
 {
 	struct ceph_osd_req_op ops[3];
 	struct ceph_osd_request *req;
+	int r;
 
 	ops[0].op = opcode;
 	ops[0].extent.truncate_seq = truncate_seq;
@@ -474,10 +482,12 @@
 					 use_mempool,
 					 GFP_NOFS, NULL, NULL);
 	if (!req)
-		return NULL;
+		return ERR_PTR(-ENOMEM);
 
 	/* calculate max write size */
-	calc_layout(osdc, vino, layout, off, plen, req, ops);
+	r = calc_layout(osdc, vino, layout, off, plen, req, ops);
+	if (r < 0)
+		return ERR_PTR(r);
 	req->r_file_layout = *layout;  /* keep a copy */
 
 	/* in case it differs from natural (file) alignment that
@@ -1920,8 +1930,8 @@
 				    CEPH_OSD_OP_READ, CEPH_OSD_FLAG_READ,
 				    NULL, 0, truncate_seq, truncate_size, NULL,
 				    false, 1, page_align);
-	if (!req)
-		return -ENOMEM;
+	if (IS_ERR(req))
+		return PTR_ERR(req);
 
 	/* it may be a short read due to an object boundary */
 	req->r_pages = pages;
@@ -1963,8 +1973,8 @@
 				    snapc, do_sync,
 				    truncate_seq, truncate_size, mtime,
 				    nofail, 1, page_align);
-	if (!req)
-		return -ENOMEM;
+	if (IS_ERR(req))
+		return PTR_ERR(req);
 
 	/* it may be a short write due to an object boundary */
 	req->r_pages = pages;
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c
index 3124b71..5433fb0 100644
--- a/net/ceph/osdmap.c
+++ b/net/ceph/osdmap.c
@@ -984,7 +984,7 @@
  * for now, we write only a single su, until we can
  * pass a stride back to the caller.
  */
-void ceph_calc_file_object_mapping(struct ceph_file_layout *layout,
+int ceph_calc_file_object_mapping(struct ceph_file_layout *layout,
 				   u64 off, u64 *plen,
 				   u64 *ono,
 				   u64 *oxoff, u64 *oxlen)
@@ -998,11 +998,17 @@
 
 	dout("mapping %llu~%llu  osize %u fl_su %u\n", off, *plen,
 	     osize, su);
+	if (su == 0 || sc == 0)
+		goto invalid;
 	su_per_object = osize / su;
+	if (su_per_object == 0)
+		goto invalid;
 	dout("osize %u / su %u = su_per_object %u\n", osize, su,
 	     su_per_object);
 
-	BUG_ON((su & ~PAGE_MASK) != 0);
+	if ((su & ~PAGE_MASK) != 0)
+		goto invalid;
+
 	/* bl = *off / su; */
 	t = off;
 	do_div(t, su);
@@ -1030,6 +1036,14 @@
 	*plen = *oxlen;
 
 	dout(" obj extent %llu~%llu\n", *oxoff, *oxlen);
+	return 0;
+
+invalid:
+	dout(" invalid layout\n");
+	*ono = 0;
+	*oxoff = 0;
+	*oxlen = 0;
+	return -EINVAL;
 }
 EXPORT_SYMBOL(ceph_calc_file_object_mapping);
 
diff --git a/net/ceph/pagelist.c b/net/ceph/pagelist.c
index 665cd23..92866be 100644
--- a/net/ceph/pagelist.c
+++ b/net/ceph/pagelist.c
@@ -1,4 +1,3 @@
-
 #include <linux/module.h>
 #include <linux/gfp.h>
 #include <linux/pagemap.h>
@@ -134,8 +133,8 @@
 	ceph_pagelist_unmap_tail(pl);
 	while (pl->head.prev != c->page_lru) {
 		page = list_entry(pl->head.prev, struct page, lru);
-		list_del(&page->lru);                /* remove from pagelist */
-		list_add_tail(&page->lru, &pl->free_list); /* add to reserve */
+		/* move from pagelist to reserve */
+		list_move_tail(&page->lru, &pl->free_list);
 		++pl->num_pages_free;
 	}
 	pl->room = c->room;
diff --git a/net/core/dev.c b/net/core/dev.c
index 1e0a184..09cb3f6 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3300,18 +3300,18 @@
 				&& !skb_pfmemalloc_protocol(skb))
 		goto drop;
 
-	rx_handler = rcu_dereference(skb->dev->rx_handler);
 	if (vlan_tx_tag_present(skb)) {
 		if (pt_prev) {
 			ret = deliver_skb(skb, pt_prev, orig_dev);
 			pt_prev = NULL;
 		}
-		if (vlan_do_receive(&skb, !rx_handler))
+		if (vlan_do_receive(&skb))
 			goto another_round;
 		else if (unlikely(!skb))
 			goto unlock;
 	}
 
+	rx_handler = rcu_dereference(skb->dev->rx_handler);
 	if (rx_handler) {
 		if (pt_prev) {
 			ret = deliver_skb(skb, pt_prev, orig_dev);
@@ -3331,6 +3331,9 @@
 		}
 	}
 
+	if (vlan_tx_nonzero_tag_present(skb))
+		skb->pkt_type = PACKET_OTHERHOST;
+
 	/* deliver only exact match when indicated */
 	null_or_dev = deliver_exact ? skb->dev : NULL;
 
@@ -3471,17 +3474,31 @@
 	return netif_receive_skb(skb);
 }
 
-inline void napi_gro_flush(struct napi_struct *napi)
+/* napi->gro_list contains packets ordered by age.
+ * youngest packets at the head of it.
+ * Complete skbs in reverse order to reduce latencies.
+ */
+void napi_gro_flush(struct napi_struct *napi, bool flush_old)
 {
-	struct sk_buff *skb, *next;
+	struct sk_buff *skb, *prev = NULL;
 
-	for (skb = napi->gro_list; skb; skb = next) {
-		next = skb->next;
-		skb->next = NULL;
-		napi_gro_complete(skb);
+	/* scan list and build reverse chain */
+	for (skb = napi->gro_list; skb != NULL; skb = skb->next) {
+		skb->prev = prev;
+		prev = skb;
 	}
 
-	napi->gro_count = 0;
+	for (skb = prev; skb; skb = prev) {
+		skb->next = NULL;
+
+		if (flush_old && NAPI_GRO_CB(skb)->age == jiffies)
+			return;
+
+		prev = skb->prev;
+		napi_gro_complete(skb);
+		napi->gro_count--;
+	}
+
 	napi->gro_list = NULL;
 }
 EXPORT_SYMBOL(napi_gro_flush);
@@ -3542,6 +3559,7 @@
 
 	napi->gro_count++;
 	NAPI_GRO_CB(skb)->count = 1;
+	NAPI_GRO_CB(skb)->age = jiffies;
 	skb_shinfo(skb)->gso_size = skb_gro_len(skb);
 	skb->next = napi->gro_list;
 	napi->gro_list = skb;
@@ -3631,20 +3649,22 @@
 }
 EXPORT_SYMBOL(napi_skb_finish);
 
-void skb_gro_reset_offset(struct sk_buff *skb)
+static void skb_gro_reset_offset(struct sk_buff *skb)
 {
+	const struct skb_shared_info *pinfo = skb_shinfo(skb);
+	const skb_frag_t *frag0 = &pinfo->frags[0];
+
 	NAPI_GRO_CB(skb)->data_offset = 0;
 	NAPI_GRO_CB(skb)->frag0 = NULL;
 	NAPI_GRO_CB(skb)->frag0_len = 0;
 
 	if (skb->mac_header == skb->tail &&
-	    !PageHighMem(skb_frag_page(&skb_shinfo(skb)->frags[0]))) {
-		NAPI_GRO_CB(skb)->frag0 =
-			skb_frag_address(&skb_shinfo(skb)->frags[0]);
-		NAPI_GRO_CB(skb)->frag0_len = skb_frag_size(&skb_shinfo(skb)->frags[0]);
+	    pinfo->nr_frags &&
+	    !PageHighMem(skb_frag_page(frag0))) {
+		NAPI_GRO_CB(skb)->frag0 = skb_frag_address(frag0);
+		NAPI_GRO_CB(skb)->frag0_len = skb_frag_size(frag0);
 	}
 }
-EXPORT_SYMBOL(skb_gro_reset_offset);
 
 gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
 {
@@ -3876,7 +3896,7 @@
 	if (unlikely(test_bit(NAPI_STATE_NPSVC, &n->state)))
 		return;
 
-	napi_gro_flush(n);
+	napi_gro_flush(n, false);
 	local_irq_save(flags);
 	__napi_complete(n);
 	local_irq_restore(flags);
@@ -3981,8 +4001,17 @@
 				local_irq_enable();
 				napi_complete(n);
 				local_irq_disable();
-			} else
+			} else {
+				if (n->gro_list) {
+					/* flush too old packets
+					 * If HZ < 1000, flush all packets.
+					 */
+					local_irq_enable();
+					napi_gro_flush(n, HZ >= 1000);
+					local_irq_disable();
+				}
 				list_move_tail(&n->poll_list, &sd->poll_list);
+			}
 		}
 
 		netpoll_poll_unlock(have);
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index baca771..2257148 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1301,8 +1301,6 @@
 	if (!dst)
 		goto discard;
 
-	__skb_pull(skb, skb_network_offset(skb));
-
 	if (!neigh_event_send(neigh, skb)) {
 		int err;
 		struct net_device *dev = neigh->dev;
@@ -1312,6 +1310,7 @@
 			neigh_hh_init(neigh, dst);
 
 		do {
+			__skb_pull(skb, skb_network_offset(skb));
 			seq = read_seqbegin(&neigh->ha_lock);
 			err = dev_hard_header(skb, dev, ntohs(skb->protocol),
 					      neigh->ha, NULL, skb->len);
@@ -1342,9 +1341,8 @@
 	unsigned int seq;
 	int err;
 
-	__skb_pull(skb, skb_network_offset(skb));
-
 	do {
+		__skb_pull(skb, skb_network_offset(skb));
 		seq = read_seqbegin(&neigh->ha_lock);
 		err = dev_hard_header(skb, dev, ntohs(skb->protocol),
 				      neigh->ha, NULL, skb->len);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index cdc2859..6e04b1f 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -655,53 +655,6 @@
 }
 EXPORT_SYMBOL(consume_skb);
 
-/**
- * 	skb_recycle - clean up an skb for reuse
- * 	@skb: buffer
- *
- * 	Recycles the skb to be reused as a receive buffer. This
- * 	function does any necessary reference count dropping, and
- * 	cleans up the skbuff as if it just came from __alloc_skb().
- */
-void skb_recycle(struct sk_buff *skb)
-{
-	struct skb_shared_info *shinfo;
-
-	skb_release_head_state(skb);
-
-	shinfo = skb_shinfo(skb);
-	memset(shinfo, 0, offsetof(struct skb_shared_info, dataref));
-	atomic_set(&shinfo->dataref, 1);
-
-	memset(skb, 0, offsetof(struct sk_buff, tail));
-	skb->data = skb->head + NET_SKB_PAD;
-	skb_reset_tail_pointer(skb);
-}
-EXPORT_SYMBOL(skb_recycle);
-
-/**
- *	skb_recycle_check - check if skb can be reused for receive
- *	@skb: buffer
- *	@skb_size: minimum receive buffer size
- *
- *	Checks that the skb passed in is not shared or cloned, and
- *	that it is linear and its head portion at least as large as
- *	skb_size so that it can be recycled as a receive buffer.
- *	If these conditions are met, this function does any necessary
- *	reference count dropping and cleans up the skbuff as if it
- *	just came from __alloc_skb().
- */
-bool skb_recycle_check(struct sk_buff *skb, int skb_size)
-{
-	if (!skb_is_recycleable(skb, skb_size))
-		return false;
-
-	skb_recycle(skb);
-
-	return true;
-}
-EXPORT_SYMBOL(skb_recycle_check);
-
 static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
 {
 	new->tstamp		= old->tstamp;
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 68c93d1..825c608 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -322,7 +322,8 @@
 {
 	int r = secpath_exists(skb) ? 0 : IN_DEV_RPFILTER(idev);
 
-	if (!r && !fib_num_tclassid_users(dev_net(dev))) {
+	if (!r && !fib_num_tclassid_users(dev_net(dev)) &&
+	    (dev->ifindex != oif || !IN_DEV_TX_REDIRECTS(idev))) {
 		*itag = 0;
 		return 0;
 	}
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 2677530..71b125c 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -840,6 +840,8 @@
 	change_nexthops(fi) {
 		nexthop_nh->nh_parent = fi;
 		nexthop_nh->nh_pcpu_rth_output = alloc_percpu(struct rtable __rcu *);
+		if (!nexthop_nh->nh_pcpu_rth_output)
+			goto failure;
 	} endfor_nexthops(fi)
 
 	if (cfg->fc_mx) {
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index f0c5b9c..d34ce29 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -406,7 +406,7 @@
 	rt = ip_route_output_flow(net, fl4, sk);
 	if (IS_ERR(rt))
 		goto no_route;
-	if (opt && opt->opt.is_strictroute && rt->rt_gateway)
+	if (opt && opt->opt.is_strictroute && rt->rt_uses_gateway)
 		goto route_err;
 	return &rt->dst;
 
@@ -442,7 +442,7 @@
 	rt = ip_route_output_flow(net, fl4, sk);
 	if (IS_ERR(rt))
 		goto no_route;
-	if (opt && opt->opt.is_strictroute && rt->rt_gateway)
+	if (opt && opt->opt.is_strictroute && rt->rt_uses_gateway)
 		goto route_err;
 	rcu_read_unlock();
 	return &rt->dst;
diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c
index ab09b12..694de3b 100644
--- a/net/ipv4/ip_forward.c
+++ b/net/ipv4/ip_forward.c
@@ -85,7 +85,7 @@
 
 	rt = skb_rtable(skb);
 
-	if (opt->is_strictroute && opt->nexthop != rt->rt_gateway)
+	if (opt->is_strictroute && rt->rt_uses_gateway)
 		goto sr_failed;
 
 	if (unlikely(skb->len > dst_mtu(&rt->dst) && !skb_is_gso(skb) &&
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 24a29a3..6537a40 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -193,7 +193,7 @@
 	}
 
 	rcu_read_lock_bh();
-	nexthop = rt->rt_gateway ? rt->rt_gateway : ip_hdr(skb)->daddr;
+	nexthop = (__force u32) rt_nexthop(rt, ip_hdr(skb)->daddr);
 	neigh = __ipv4_neigh_lookup_noref(dev, nexthop);
 	if (unlikely(!neigh))
 		neigh = __neigh_create(&arp_tbl, &nexthop, dev, false);
@@ -371,7 +371,7 @@
 	skb_dst_set_noref(skb, &rt->dst);
 
 packet_routed:
-	if (inet_opt && inet_opt->opt.is_strictroute && rt->rt_gateway)
+	if (inet_opt && inet_opt->opt.is_strictroute && rt->rt_uses_gateway)
 		goto no_route;
 
 	/* OK, we know where to send it, allocate and build IP header. */
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index ff62206..1a0da8d 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -802,7 +802,8 @@
 	net = dev_net(rt->dst.dev);
 	peer = inet_getpeer_v4(net->ipv4.peers, ip_hdr(skb)->saddr, 1);
 	if (!peer) {
-		icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, rt->rt_gateway);
+		icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST,
+			  rt_nexthop(rt, ip_hdr(skb)->daddr));
 		return;
 	}
 
@@ -827,7 +828,9 @@
 	    time_after(jiffies,
 		       (peer->rate_last +
 			(ip_rt_redirect_load << peer->rate_tokens)))) {
-		icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, rt->rt_gateway);
+		__be32 gw = rt_nexthop(rt, ip_hdr(skb)->daddr);
+
+		icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, gw);
 		peer->rate_last = jiffies;
 		++peer->rate_tokens;
 #ifdef CONFIG_IP_ROUTE_VERBOSE
@@ -835,7 +838,7 @@
 		    peer->rate_tokens == ip_rt_redirect_number)
 			net_warn_ratelimited("host %pI4/if%d ignores redirects for %pI4 to %pI4\n",
 					     &ip_hdr(skb)->saddr, inet_iif(skb),
-					     &ip_hdr(skb)->daddr, &rt->rt_gateway);
+					     &ip_hdr(skb)->daddr, &gw);
 #endif
 	}
 out_put_peer:
@@ -904,22 +907,32 @@
 	return 0;
 }
 
-static u32 __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu)
+static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu)
 {
+	struct dst_entry *dst = &rt->dst;
 	struct fib_result res;
 
+	if (dst->dev->mtu < mtu)
+		return;
+
 	if (mtu < ip_rt_min_pmtu)
 		mtu = ip_rt_min_pmtu;
 
+	if (!rt->rt_pmtu) {
+		dst->obsolete = DST_OBSOLETE_KILL;
+	} else {
+		rt->rt_pmtu = mtu;
+		dst->expires = max(1UL, jiffies + ip_rt_mtu_expires);
+	}
+
 	rcu_read_lock();
-	if (fib_lookup(dev_net(rt->dst.dev), fl4, &res) == 0) {
+	if (fib_lookup(dev_net(dst->dev), fl4, &res) == 0) {
 		struct fib_nh *nh = &FIB_RES_NH(res);
 
 		update_or_create_fnhe(nh, fl4->daddr, 0, mtu,
 				      jiffies + ip_rt_mtu_expires);
 	}
 	rcu_read_unlock();
-	return mtu;
 }
 
 static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
@@ -929,14 +942,7 @@
 	struct flowi4 fl4;
 
 	ip_rt_build_flow_key(&fl4, sk, skb);
-	mtu = __ip_rt_update_pmtu(rt, &fl4, mtu);
-
-	if (!rt->rt_pmtu) {
-		dst->obsolete = DST_OBSOLETE_KILL;
-	} else {
-		rt->rt_pmtu = mtu;
-		rt->dst.expires = max(1UL, jiffies + ip_rt_mtu_expires);
-	}
+	__ip_rt_update_pmtu(rt, &fl4, mtu);
 }
 
 void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu,
@@ -1120,7 +1126,7 @@
 	mtu = dst->dev->mtu;
 
 	if (unlikely(dst_metric_locked(dst, RTAX_MTU))) {
-		if (rt->rt_gateway && mtu > 576)
+		if (rt->rt_uses_gateway && mtu > 576)
 			mtu = 576;
 	}
 
@@ -1171,7 +1177,9 @@
 		if (fnhe->fnhe_gw) {
 			rt->rt_flags |= RTCF_REDIRECTED;
 			rt->rt_gateway = fnhe->fnhe_gw;
-		}
+			rt->rt_uses_gateway = 1;
+		} else if (!rt->rt_gateway)
+			rt->rt_gateway = daddr;
 
 		orig = rcu_dereference(fnhe->fnhe_rth);
 		rcu_assign_pointer(fnhe->fnhe_rth, rt);
@@ -1180,13 +1188,6 @@
 
 		fnhe->fnhe_stamp = jiffies;
 		ret = true;
-	} else {
-		/* Routes we intend to cache in nexthop exception have
-		 * the DST_NOCACHE bit clear.  However, if we are
-		 * unsuccessful at storing this route into the cache
-		 * we really need to set it.
-		 */
-		rt->dst.flags |= DST_NOCACHE;
 	}
 	spin_unlock_bh(&fnhe_lock);
 
@@ -1201,8 +1202,6 @@
 	if (rt_is_input_route(rt)) {
 		p = (struct rtable **)&nh->nh_rth_input;
 	} else {
-		if (!nh->nh_pcpu_rth_output)
-			goto nocache;
 		p = (struct rtable **)__this_cpu_ptr(nh->nh_pcpu_rth_output);
 	}
 	orig = *p;
@@ -1211,16 +1210,8 @@
 	if (prev == orig) {
 		if (orig)
 			rt_free(orig);
-	} else {
-		/* Routes we intend to cache in the FIB nexthop have
-		 * the DST_NOCACHE bit clear.  However, if we are
-		 * unsuccessful at storing this route into the cache
-		 * we really need to set it.
-		 */
-nocache:
-		rt->dst.flags |= DST_NOCACHE;
+	} else
 		ret = false;
-	}
 
 	return ret;
 }
@@ -1281,8 +1272,10 @@
 	if (fi) {
 		struct fib_nh *nh = &FIB_RES_NH(*res);
 
-		if (nh->nh_gw && nh->nh_scope == RT_SCOPE_LINK)
+		if (nh->nh_gw && nh->nh_scope == RT_SCOPE_LINK) {
 			rt->rt_gateway = nh->nh_gw;
+			rt->rt_uses_gateway = 1;
+		}
 		dst_init_metrics(&rt->dst, fi->fib_metrics, true);
 #ifdef CONFIG_IP_ROUTE_CLASSID
 		rt->dst.tclassid = nh->nh_tclassid;
@@ -1291,8 +1284,18 @@
 			cached = rt_bind_exception(rt, fnhe, daddr);
 		else if (!(rt->dst.flags & DST_NOCACHE))
 			cached = rt_cache_route(nh, rt);
-	}
-	if (unlikely(!cached))
+		if (unlikely(!cached)) {
+			/* Routes we intend to cache in nexthop exception or
+			 * FIB nexthop have the DST_NOCACHE bit clear.
+			 * However, if we are unsuccessful at storing this
+			 * route into the cache we really need to set it.
+			 */
+			rt->dst.flags |= DST_NOCACHE;
+			if (!rt->rt_gateway)
+				rt->rt_gateway = daddr;
+			rt_add_uncached_list(rt);
+		}
+	} else
 		rt_add_uncached_list(rt);
 
 #ifdef CONFIG_IP_ROUTE_CLASSID
@@ -1360,6 +1363,7 @@
 	rth->rt_iif	= 0;
 	rth->rt_pmtu	= 0;
 	rth->rt_gateway	= 0;
+	rth->rt_uses_gateway = 0;
 	INIT_LIST_HEAD(&rth->rt_uncached);
 	if (our) {
 		rth->dst.input= ip_local_deliver;
@@ -1429,7 +1433,6 @@
 		return -EINVAL;
 	}
 
-
 	err = fib_validate_source(skb, saddr, daddr, tos, FIB_RES_OIF(*res),
 				  in_dev->dev, in_dev, &itag);
 	if (err < 0) {
@@ -1439,10 +1442,13 @@
 		goto cleanup;
 	}
 
-	if (out_dev == in_dev && err &&
+	do_cache = res->fi && !itag;
+	if (out_dev == in_dev && err && IN_DEV_TX_REDIRECTS(out_dev) &&
 	    (IN_DEV_SHARED_MEDIA(out_dev) ||
-	     inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res))))
+	     inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res)))) {
 		flags |= RTCF_DOREDIRECT;
+		do_cache = false;
+	}
 
 	if (skb->protocol != htons(ETH_P_IP)) {
 		/* Not IP (i.e. ARP). Do not create route, if it is
@@ -1459,15 +1465,11 @@
 		}
 	}
 
-	do_cache = false;
-	if (res->fi) {
-		if (!itag) {
-			rth = rcu_dereference(FIB_RES_NH(*res).nh_rth_input);
-			if (rt_cache_valid(rth)) {
-				skb_dst_set_noref(skb, &rth->dst);
-				goto out;
-			}
-			do_cache = true;
+	if (do_cache) {
+		rth = rcu_dereference(FIB_RES_NH(*res).nh_rth_input);
+		if (rt_cache_valid(rth)) {
+			skb_dst_set_noref(skb, &rth->dst);
+			goto out;
 		}
 	}
 
@@ -1486,6 +1488,7 @@
 	rth->rt_iif 	= 0;
 	rth->rt_pmtu	= 0;
 	rth->rt_gateway	= 0;
+	rth->rt_uses_gateway = 0;
 	INIT_LIST_HEAD(&rth->rt_uncached);
 
 	rth->dst.input = ip_forward;
@@ -1656,6 +1659,7 @@
 	rth->rt_iif	= 0;
 	rth->rt_pmtu	= 0;
 	rth->rt_gateway	= 0;
+	rth->rt_uses_gateway = 0;
 	INIT_LIST_HEAD(&rth->rt_uncached);
 	if (res.type == RTN_UNREACHABLE) {
 		rth->dst.input= ip_error;
@@ -1758,6 +1762,7 @@
 	struct in_device *in_dev;
 	u16 type = res->type;
 	struct rtable *rth;
+	bool do_cache;
 
 	in_dev = __in_dev_get_rcu(dev_out);
 	if (!in_dev)
@@ -1794,24 +1799,36 @@
 	}
 
 	fnhe = NULL;
+	do_cache = fi != NULL;
 	if (fi) {
 		struct rtable __rcu **prth;
+		struct fib_nh *nh = &FIB_RES_NH(*res);
 
-		fnhe = find_exception(&FIB_RES_NH(*res), fl4->daddr);
+		fnhe = find_exception(nh, fl4->daddr);
 		if (fnhe)
 			prth = &fnhe->fnhe_rth;
-		else
-			prth = __this_cpu_ptr(FIB_RES_NH(*res).nh_pcpu_rth_output);
+		else {
+			if (unlikely(fl4->flowi4_flags &
+				     FLOWI_FLAG_KNOWN_NH &&
+				     !(nh->nh_gw &&
+				       nh->nh_scope == RT_SCOPE_LINK))) {
+				do_cache = false;
+				goto add;
+			}
+			prth = __this_cpu_ptr(nh->nh_pcpu_rth_output);
+		}
 		rth = rcu_dereference(*prth);
 		if (rt_cache_valid(rth)) {
 			dst_hold(&rth->dst);
 			return rth;
 		}
 	}
+
+add:
 	rth = rt_dst_alloc(dev_out,
 			   IN_DEV_CONF_GET(in_dev, NOPOLICY),
 			   IN_DEV_CONF_GET(in_dev, NOXFRM),
-			   fi);
+			   do_cache);
 	if (!rth)
 		return ERR_PTR(-ENOBUFS);
 
@@ -1824,6 +1841,7 @@
 	rth->rt_iif	= orig_oif ? : 0;
 	rth->rt_pmtu	= 0;
 	rth->rt_gateway = 0;
+	rth->rt_uses_gateway = 0;
 	INIT_LIST_HEAD(&rth->rt_uncached);
 
 	RT_CACHE_STAT_INC(out_slow_tot);
@@ -2102,6 +2120,7 @@
 		rt->rt_flags = ort->rt_flags;
 		rt->rt_type = ort->rt_type;
 		rt->rt_gateway = ort->rt_gateway;
+		rt->rt_uses_gateway = ort->rt_uses_gateway;
 
 		INIT_LIST_HEAD(&rt->rt_uncached);
 
@@ -2180,12 +2199,22 @@
 		if (nla_put_be32(skb, RTA_PREFSRC, fl4->saddr))
 			goto nla_put_failure;
 	}
-	if (rt->rt_gateway &&
+	if (rt->rt_uses_gateway &&
 	    nla_put_be32(skb, RTA_GATEWAY, rt->rt_gateway))
 		goto nla_put_failure;
 
+	expires = rt->dst.expires;
+	if (expires) {
+		unsigned long now = jiffies;
+
+		if (time_before(now, expires))
+			expires -= now;
+		else
+			expires = 0;
+	}
+
 	memcpy(metrics, dst_metrics_ptr(&rt->dst), sizeof(metrics));
-	if (rt->rt_pmtu)
+	if (rt->rt_pmtu && expires)
 		metrics[RTAX_MTU - 1] = rt->rt_pmtu;
 	if (rtnetlink_put_metrics(skb, metrics) < 0)
 		goto nla_put_failure;
@@ -2195,13 +2224,6 @@
 		goto nla_put_failure;
 
 	error = rt->dst.error;
-	expires = rt->dst.expires;
-	if (expires) {
-		if (time_before(jiffies, expires))
-			expires -= jiffies;
-		else
-			expires = 0;
-	}
 
 	if (rt_is_input_route(rt)) {
 		if (nla_put_u32(skb, RTA_IIF, rt->rt_iif))
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 681ea2f..05c5ab8 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -91,6 +91,7 @@
 					      RTCF_LOCAL);
 	xdst->u.rt.rt_type = rt->rt_type;
 	xdst->u.rt.rt_gateway = rt->rt_gateway;
+	xdst->u.rt.rt_uses_gateway = rt->rt_uses_gateway;
 	xdst->u.rt.rt_pmtu = rt->rt_pmtu;
 	INIT_LIST_HEAD(&xdst->u.rt.rt_uncached);
 
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index e22e6d8..a974247 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -822,13 +822,6 @@
 	return segs;
 }
 
-struct ipv6_gro_cb {
-	struct napi_gro_cb napi;
-	int proto;
-};
-
-#define IPV6_GRO_CB(skb) ((struct ipv6_gro_cb *)(skb)->cb)
-
 static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,
 					 struct sk_buff *skb)
 {
@@ -874,28 +867,31 @@
 		iph = ipv6_hdr(skb);
 	}
 
-	IPV6_GRO_CB(skb)->proto = proto;
+	NAPI_GRO_CB(skb)->proto = proto;
 
 	flush--;
 	nlen = skb_network_header_len(skb);
 
 	for (p = *head; p; p = p->next) {
-		struct ipv6hdr *iph2;
+		const struct ipv6hdr *iph2;
+		__be32 first_word; /* <Version:4><Traffic_Class:8><Flow_Label:20> */
 
 		if (!NAPI_GRO_CB(p)->same_flow)
 			continue;
 
 		iph2 = ipv6_hdr(p);
+		first_word = *(__be32 *)iph ^ *(__be32 *)iph2 ;
 
-		/* All fields must match except length. */
+		/* All fields must match except length and Traffic Class. */
 		if (nlen != skb_network_header_len(p) ||
-		    memcmp(iph, iph2, offsetof(struct ipv6hdr, payload_len)) ||
+		    (first_word & htonl(0xF00FFFFF)) ||
 		    memcmp(&iph->nexthdr, &iph2->nexthdr,
 			   nlen - offsetof(struct ipv6hdr, nexthdr))) {
 			NAPI_GRO_CB(p)->same_flow = 0;
 			continue;
 		}
-
+		/* flush if Traffic Class fields are different */
+		NAPI_GRO_CB(p)->flush |= !!(first_word & htonl(0x0FF00000));
 		NAPI_GRO_CB(p)->flush |= flush;
 	}
 
@@ -927,7 +923,7 @@
 				 sizeof(*iph));
 
 	rcu_read_lock();
-	ops = rcu_dereference(inet6_protos[IPV6_GRO_CB(skb)->proto]);
+	ops = rcu_dereference(inet6_protos[NAPI_GRO_CB(skb)->proto]);
 	if (WARN_ON(!ops || !ops->gro_complete))
 		goto out_unlock;
 
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index 56f6d5d..cc4c809 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -50,6 +50,7 @@
 				      * local
 				      */
 	IP_VS_RT_MODE_CONNECT	= 8, /* Always bind route to saddr */
+	IP_VS_RT_MODE_KNOWN_NH	= 16,/* Route via remote addr */
 };
 
 /*
@@ -113,6 +114,8 @@
 	fl4.daddr = daddr;
 	fl4.saddr = (rt_mode & IP_VS_RT_MODE_CONNECT) ? *saddr : 0;
 	fl4.flowi4_tos = rtos;
+	fl4.flowi4_flags = (rt_mode & IP_VS_RT_MODE_KNOWN_NH) ?
+			   FLOWI_FLAG_KNOWN_NH : 0;
 
 retry:
 	rt = ip_route_output_key(net, &fl4);
@@ -1061,7 +1064,8 @@
 	if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip,
 				      RT_TOS(iph->tos),
 				      IP_VS_RT_MODE_LOCAL |
-					IP_VS_RT_MODE_NON_LOCAL, NULL)))
+				      IP_VS_RT_MODE_NON_LOCAL |
+				      IP_VS_RT_MODE_KNOWN_NH, NULL)))
 		goto tx_error_icmp;
 	if (rt->rt_flags & RTCF_LOCAL) {
 		ip_rt_put(rt);
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 0f2e3ad..01e944a 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -169,6 +169,8 @@
 	if (nlk->cb) {
 		if (nlk->cb->done)
 			nlk->cb->done(nlk->cb);
+
+		module_put(nlk->cb->module);
 		netlink_destroy_callback(nlk->cb);
 	}
 
@@ -1758,6 +1760,7 @@
 	nlk->cb = NULL;
 	mutex_unlock(nlk->cb_mutex);
 
+	module_put(cb->module);
 	netlink_consume_callback(cb);
 	return 0;
 
@@ -1767,9 +1770,9 @@
 	return err;
 }
 
-int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
-		       const struct nlmsghdr *nlh,
-		       struct netlink_dump_control *control)
+int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
+			 const struct nlmsghdr *nlh,
+			 struct netlink_dump_control *control)
 {
 	struct netlink_callback *cb;
 	struct sock *sk;
@@ -1784,6 +1787,7 @@
 	cb->done = control->done;
 	cb->nlh = nlh;
 	cb->data = control->data;
+	cb->module = control->module;
 	cb->min_dump_alloc = control->min_dump_alloc;
 	atomic_inc(&skb->users);
 	cb->skb = skb;
@@ -1794,19 +1798,28 @@
 		return -ECONNREFUSED;
 	}
 	nlk = nlk_sk(sk);
-	/* A dump is in progress... */
+
 	mutex_lock(nlk->cb_mutex);
+	/* A dump is in progress... */
 	if (nlk->cb) {
 		mutex_unlock(nlk->cb_mutex);
 		netlink_destroy_callback(cb);
-		sock_put(sk);
-		return -EBUSY;
+		ret = -EBUSY;
+		goto out;
 	}
+	/* add reference of module which cb->dump belongs to */
+	if (!try_module_get(cb->module)) {
+		mutex_unlock(nlk->cb_mutex);
+		netlink_destroy_callback(cb);
+		ret = -EPROTONOSUPPORT;
+		goto out;
+	}
+
 	nlk->cb = cb;
 	mutex_unlock(nlk->cb_mutex);
 
 	ret = netlink_dump(sk);
-
+out:
 	sock_put(sk);
 
 	if (ret)
@@ -1817,7 +1830,7 @@
 	 */
 	return -EINTR;
 }
-EXPORT_SYMBOL(netlink_dump_start);
+EXPORT_SYMBOL(__netlink_dump_start);
 
 void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err)
 {
diff --git a/net/rds/send.c b/net/rds/send.c
index 96531d4..88eace5 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -1122,7 +1122,7 @@
 	rds_stats_inc(s_send_pong);
 
 	if (!test_bit(RDS_LL_SEND_FULL, &conn->c_flags))
-		rds_send_xmit(conn);
+		queue_delayed_work(rds_wq, &conn->c_send_w, 0);
 
 	rds_message_put(rm);
 	return 0;
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index 34c5220..909dc0c 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -239,7 +239,7 @@
 	}
 	return q;
 err:
-	dprintk("RPC:       gss_fill_context returning %ld\n", -PTR_ERR(p));
+	dprintk("RPC:       %s returning %ld\n", __func__, -PTR_ERR(p));
 	return p;
 }
 
@@ -301,10 +301,10 @@
 		if (pos->uid != uid)
 			continue;
 		atomic_inc(&pos->count);
-		dprintk("RPC:       gss_find_upcall found msg %p\n", pos);
+		dprintk("RPC:       %s found msg %p\n", __func__, pos);
 		return pos;
 	}
-	dprintk("RPC:       gss_find_upcall found nothing\n");
+	dprintk("RPC:       %s found nothing\n", __func__);
 	return NULL;
 }
 
@@ -507,8 +507,8 @@
 	struct rpc_pipe *pipe;
 	int err = 0;
 
-	dprintk("RPC: %5u gss_refresh_upcall for uid %u\n", task->tk_pid,
-								cred->cr_uid);
+	dprintk("RPC: %5u %s for uid %u\n",
+		task->tk_pid, __func__, cred->cr_uid);
 	gss_msg = gss_setup_upcall(task->tk_client, gss_auth, cred);
 	if (PTR_ERR(gss_msg) == -EAGAIN) {
 		/* XXX: warning on the first, under the assumption we
@@ -539,8 +539,8 @@
 	spin_unlock(&pipe->lock);
 	gss_release_msg(gss_msg);
 out:
-	dprintk("RPC: %5u gss_refresh_upcall for uid %u result %d\n",
-			task->tk_pid, cred->cr_uid, err);
+	dprintk("RPC: %5u %s for uid %u result %d\n",
+		task->tk_pid, __func__, cred->cr_uid, err);
 	return err;
 }
 
@@ -553,7 +553,7 @@
 	DEFINE_WAIT(wait);
 	int err = 0;
 
-	dprintk("RPC:       gss_upcall for uid %u\n", cred->cr_uid);
+	dprintk("RPC:       %s for uid %u\n", __func__, cred->cr_uid);
 retry:
 	gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred);
 	if (PTR_ERR(gss_msg) == -EAGAIN) {
@@ -594,8 +594,8 @@
 	finish_wait(&gss_msg->waitqueue, &wait);
 	gss_release_msg(gss_msg);
 out:
-	dprintk("RPC:       gss_create_upcall for uid %u result %d\n",
-			cred->cr_uid, err);
+	dprintk("RPC:       %s for uid %u result %d\n",
+		__func__, cred->cr_uid, err);
 	return err;
 }
 
@@ -681,7 +681,7 @@
 err:
 	kfree(buf);
 out:
-	dprintk("RPC:       gss_pipe_downcall returning %Zd\n", err);
+	dprintk("RPC:       %s returning %Zd\n", __func__, err);
 	return err;
 }
 
@@ -747,8 +747,8 @@
 	struct gss_upcall_msg *gss_msg = container_of(msg, struct gss_upcall_msg, msg);
 
 	if (msg->errno < 0) {
-		dprintk("RPC:       gss_pipe_destroy_msg releasing msg %p\n",
-				gss_msg);
+		dprintk("RPC:       %s releasing msg %p\n",
+			__func__, gss_msg);
 		atomic_inc(&gss_msg->count);
 		gss_unhash_msg(gss_msg);
 		if (msg->errno == -ETIMEDOUT)
@@ -976,7 +976,7 @@
 static void
 gss_do_free_ctx(struct gss_cl_ctx *ctx)
 {
-	dprintk("RPC:       gss_free_ctx\n");
+	dprintk("RPC:       %s\n", __func__);
 
 	gss_delete_sec_context(&ctx->gc_gss_ctx);
 	kfree(ctx->gc_wire_ctx.data);
@@ -999,7 +999,7 @@
 static void
 gss_free_cred(struct gss_cred *gss_cred)
 {
-	dprintk("RPC:       gss_free_cred %p\n", gss_cred);
+	dprintk("RPC:       %s cred=%p\n", __func__, gss_cred);
 	kfree(gss_cred);
 }
 
@@ -1049,8 +1049,8 @@
 	struct gss_cred	*cred = NULL;
 	int err = -ENOMEM;
 
-	dprintk("RPC:       gss_create_cred for uid %d, flavor %d\n",
-		acred->uid, auth->au_flavor);
+	dprintk("RPC:       %s for uid %d, flavor %d\n",
+		__func__, acred->uid, auth->au_flavor);
 
 	if (!(cred = kzalloc(sizeof(*cred), GFP_NOFS)))
 		goto out_err;
@@ -1069,7 +1069,7 @@
 	return &cred->gc_base;
 
 out_err:
-	dprintk("RPC:       gss_create_cred failed with error %d\n", err);
+	dprintk("RPC:       %s failed with error %d\n", __func__, err);
 	return ERR_PTR(err);
 }
 
@@ -1127,7 +1127,7 @@
 	struct kvec	iov;
 	struct xdr_buf	verf_buf;
 
-	dprintk("RPC: %5u gss_marshal\n", task->tk_pid);
+	dprintk("RPC: %5u %s\n", task->tk_pid, __func__);
 
 	*p++ = htonl(RPC_AUTH_GSS);
 	cred_len = p++;
@@ -1253,7 +1253,7 @@
 	u32		flav,len;
 	u32		maj_stat;
 
-	dprintk("RPC: %5u gss_validate\n", task->tk_pid);
+	dprintk("RPC: %5u %s\n", task->tk_pid, __func__);
 
 	flav = ntohl(*p++);
 	if ((len = ntohl(*p++)) > RPC_MAX_AUTH_SIZE)
@@ -1271,20 +1271,20 @@
 	if (maj_stat == GSS_S_CONTEXT_EXPIRED)
 		clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
 	if (maj_stat) {
-		dprintk("RPC: %5u gss_validate: gss_verify_mic returned "
-				"error 0x%08x\n", task->tk_pid, maj_stat);
+		dprintk("RPC: %5u %s: gss_verify_mic returned error 0x%08x\n",
+			task->tk_pid, __func__, maj_stat);
 		goto out_bad;
 	}
 	/* We leave it to unwrap to calculate au_rslack. For now we just
 	 * calculate the length of the verifier: */
 	cred->cr_auth->au_verfsize = XDR_QUADLEN(len) + 2;
 	gss_put_ctx(ctx);
-	dprintk("RPC: %5u gss_validate: gss_verify_mic succeeded.\n",
-			task->tk_pid);
+	dprintk("RPC: %5u %s: gss_verify_mic succeeded.\n",
+			task->tk_pid, __func__);
 	return p + XDR_QUADLEN(len);
 out_bad:
 	gss_put_ctx(ctx);
-	dprintk("RPC: %5u gss_validate failed.\n", task->tk_pid);
+	dprintk("RPC: %5u %s failed.\n", task->tk_pid, __func__);
 	return NULL;
 }
 
@@ -1466,7 +1466,7 @@
 	struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
 	int             status = -EIO;
 
-	dprintk("RPC: %5u gss_wrap_req\n", task->tk_pid);
+	dprintk("RPC: %5u %s\n", task->tk_pid, __func__);
 	if (ctx->gc_proc != RPC_GSS_PROC_DATA) {
 		/* The spec seems a little ambiguous here, but I think that not
 		 * wrapping context destruction requests makes the most sense.
@@ -1489,7 +1489,7 @@
 	}
 out:
 	gss_put_ctx(ctx);
-	dprintk("RPC: %5u gss_wrap_req returning %d\n", task->tk_pid, status);
+	dprintk("RPC: %5u %s returning %d\n", task->tk_pid, __func__, status);
 	return status;
 }
 
@@ -1604,8 +1604,8 @@
 	status = gss_unwrap_req_decode(decode, rqstp, p, obj);
 out:
 	gss_put_ctx(ctx);
-	dprintk("RPC: %5u gss_unwrap_resp returning %d\n", task->tk_pid,
-			status);
+	dprintk("RPC: %5u %s returning %d\n",
+		task->tk_pid, __func__, status);
 	return status;
 }
 
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index fa48c60..cdc7564b 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -490,61 +490,86 @@
  * same transport while varying parameters such as the authentication
  * flavour.
  */
-struct rpc_clnt *
-rpc_clone_client(struct rpc_clnt *clnt)
+static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args,
+					   struct rpc_clnt *clnt)
 {
-	struct rpc_clnt *new;
 	struct rpc_xprt *xprt;
-	int err = -ENOMEM;
+	struct rpc_clnt *new;
+	int err;
 
-	new = kmemdup(clnt, sizeof(*new), GFP_KERNEL);
-	if (!new)
-		goto out_no_clnt;
-	new->cl_parent = clnt;
-	/* Turn off autobind on clones */
-	new->cl_autobind = 0;
-	INIT_LIST_HEAD(&new->cl_tasks);
-	spin_lock_init(&new->cl_lock);
-	rpc_init_rtt(&new->cl_rtt_default, clnt->cl_timeout->to_initval);
-	new->cl_metrics = rpc_alloc_iostats(clnt);
-	if (new->cl_metrics == NULL)
-		goto out_no_stats;
-	if (clnt->cl_principal) {
-		new->cl_principal = kstrdup(clnt->cl_principal, GFP_KERNEL);
-		if (new->cl_principal == NULL)
-			goto out_no_principal;
-	}
+	err = -ENOMEM;
 	rcu_read_lock();
 	xprt = xprt_get(rcu_dereference(clnt->cl_xprt));
 	rcu_read_unlock();
 	if (xprt == NULL)
-		goto out_no_transport;
-	rcu_assign_pointer(new->cl_xprt, xprt);
-	atomic_set(&new->cl_count, 1);
-	err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name);
-	if (err != 0)
-		goto out_no_path;
-	rpc_clnt_set_nodename(new, utsname()->nodename);
-	if (new->cl_auth)
-		atomic_inc(&new->cl_auth->au_count);
+		goto out_err;
+	args->servername = xprt->servername;
+
+	new = rpc_new_client(args, xprt);
+	if (IS_ERR(new)) {
+		err = PTR_ERR(new);
+		goto out_put;
+	}
+
 	atomic_inc(&clnt->cl_count);
-	rpc_register_client(new);
-	rpciod_up();
+	new->cl_parent = clnt;
+
+	/* Turn off autobind on clones */
+	new->cl_autobind = 0;
+	new->cl_softrtry = clnt->cl_softrtry;
+	new->cl_discrtry = clnt->cl_discrtry;
+	new->cl_chatty = clnt->cl_chatty;
 	return new;
-out_no_path:
+
+out_put:
 	xprt_put(xprt);
-out_no_transport:
-	kfree(new->cl_principal);
-out_no_principal:
-	rpc_free_iostats(new->cl_metrics);
-out_no_stats:
-	kfree(new);
-out_no_clnt:
+out_err:
 	dprintk("RPC:       %s: returned error %d\n", __func__, err);
 	return ERR_PTR(err);
 }
+
+/**
+ * rpc_clone_client - Clone an RPC client structure
+ *
+ * @clnt: RPC client whose parameters are copied
+ *
+ * Returns a fresh RPC client or an ERR_PTR.
+ */
+struct rpc_clnt *rpc_clone_client(struct rpc_clnt *clnt)
+{
+	struct rpc_create_args args = {
+		.program	= clnt->cl_program,
+		.prognumber	= clnt->cl_prog,
+		.version	= clnt->cl_vers,
+		.authflavor	= clnt->cl_auth->au_flavor,
+		.client_name	= clnt->cl_principal,
+	};
+	return __rpc_clone_client(&args, clnt);
+}
 EXPORT_SYMBOL_GPL(rpc_clone_client);
 
+/**
+ * rpc_clone_client_set_auth - Clone an RPC client structure and set its auth
+ *
+ * @clnt: RPC client whose parameters are copied
+ * @auth: security flavor for new client
+ *
+ * Returns a fresh RPC client or an ERR_PTR.
+ */
+struct rpc_clnt *
+rpc_clone_client_set_auth(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
+{
+	struct rpc_create_args args = {
+		.program	= clnt->cl_program,
+		.prognumber	= clnt->cl_prog,
+		.version	= clnt->cl_vers,
+		.authflavor	= flavor,
+		.client_name	= clnt->cl_principal,
+	};
+	return __rpc_clone_client(&args, clnt);
+}
+EXPORT_SYMBOL_GPL(rpc_clone_client_set_auth);
+
 /*
  * Kill all tasks for the given client.
  * XXX: kill their descendants as well?
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 21fde99..80f5dd2 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -1119,8 +1119,8 @@
 		return -ENOMEM;
 	if (rpc_populate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF, NULL))
 		return -ENOMEM;
-	dprintk("RPC:	sending pipefs MOUNT notification for net %p%s\n", net,
-								NET_NAME(net));
+	dprintk("RPC:       sending pipefs MOUNT notification for net %p%s\n",
+		net, NET_NAME(net));
 	sn->pipefs_sb = sb;
 	err = blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
 					   RPC_PIPEFS_MOUNT,
@@ -1155,8 +1155,8 @@
 	sn->pipefs_sb = NULL;
 	mutex_unlock(&sn->pipefs_sb_lock);
 	put_net(net);
-	dprintk("RPC:	sending pipefs UMOUNT notification for net %p%s\n", net,
-								NET_NAME(net));
+	dprintk("RPC:       sending pipefs UMOUNT notification for net %p%s\n",
+		net, NET_NAME(net));
 	blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
 					   RPC_PIPEFS_UMOUNT,
 					   sb);
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 128494ec..6357fcb 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -1022,7 +1022,7 @@
 	 * Create the rpciod thread and wait for it to start.
 	 */
 	dprintk("RPC:       creating workqueue rpciod\n");
-	wq = alloc_workqueue("rpciod", WQ_MEM_RECLAIM, 0);
+	wq = alloc_workqueue("rpciod", WQ_MEM_RECLAIM, 1);
 	rpciod_workqueue = wq;
 	return rpciod_workqueue != NULL;
 }
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 0afba1b..08f50af 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -730,19 +730,24 @@
 
 	if (xdr->nwords == 0)
 		return 0;
+	/* Realign pages to current pointer position */
+	iov  = buf->head;
+	if (iov->iov_len > cur) {
+		xdr_shrink_bufhead(buf, iov->iov_len - cur);
+		xdr->nwords = XDR_QUADLEN(buf->len - cur);
+	}
+
 	if (nwords > xdr->nwords) {
 		nwords = xdr->nwords;
 		len = nwords << 2;
 	}
-	/* Realign pages to current pointer position */
-	iov  = buf->head;
-	if (iov->iov_len > cur)
-		xdr_shrink_bufhead(buf, iov->iov_len - cur);
-
-	/* Truncate page data and move it into the tail */
-	if (buf->page_len > len)
+	if (buf->page_len <= len)
+		len = buf->page_len;
+	else if (nwords < xdr->nwords) {
+		/* Truncate page data and move it into the tail */
 		xdr_shrink_pagelen(buf, buf->page_len - len);
-	xdr->nwords = XDR_QUADLEN(buf->len - cur);
+		xdr->nwords = XDR_QUADLEN(buf->len - cur);
+	}
 	return len;
 }
 
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 5d7f61d..bd462a5 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -231,7 +231,7 @@
 static void xprt_clear_locked(struct rpc_xprt *xprt)
 {
 	xprt->snd_task = NULL;
-	if (!test_bit(XPRT_CLOSE_WAIT, &xprt->state) || xprt->shutdown) {
+	if (!test_bit(XPRT_CLOSE_WAIT, &xprt->state)) {
 		smp_mb__before_clear_bit();
 		clear_bit(XPRT_LOCKED, &xprt->state);
 		smp_mb__after_clear_bit();
@@ -504,9 +504,6 @@
  */
 void xprt_write_space(struct rpc_xprt *xprt)
 {
-	if (unlikely(xprt->shutdown))
-		return;
-
 	spin_lock_bh(&xprt->transport_lock);
 	if (xprt->snd_task) {
 		dprintk("RPC:       write space: waking waiting task on "
@@ -679,7 +676,7 @@
 	struct rpc_xprt *xprt = (struct rpc_xprt *)data;
 
 	spin_lock(&xprt->transport_lock);
-	if (!list_empty(&xprt->recv) || xprt->shutdown)
+	if (!list_empty(&xprt->recv))
 		goto out_abort;
 	if (test_and_set_bit(XPRT_LOCKED, &xprt->state))
 		goto out_abort;
@@ -1262,7 +1259,6 @@
 static void xprt_destroy(struct rpc_xprt *xprt)
 {
 	dprintk("RPC:       destroying transport %p\n", xprt);
-	xprt->shutdown = 1;
 	del_timer_sync(&xprt->timer);
 
 	rpc_destroy_wait_queue(&xprt->binding);
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
index 5d9202d..c9aa7a3 100644
--- a/net/sunrpc/xprtrdma/transport.c
+++ b/net/sunrpc/xprtrdma/transport.c
@@ -199,21 +199,15 @@
 	struct rpc_xprt *xprt = &r_xprt->xprt;
 	int rc = 0;
 
-	if (!xprt->shutdown) {
-		current->flags |= PF_FSTRANS;
-		xprt_clear_connected(xprt);
+	current->flags |= PF_FSTRANS;
+	xprt_clear_connected(xprt);
 
-		dprintk("RPC:       %s: %sconnect\n", __func__,
-				r_xprt->rx_ep.rep_connected != 0 ? "re" : "");
-		rc = rpcrdma_ep_connect(&r_xprt->rx_ep, &r_xprt->rx_ia);
-		if (rc)
-			goto out;
-	}
-	goto out_clear;
+	dprintk("RPC:       %s: %sconnect\n", __func__,
+			r_xprt->rx_ep.rep_connected != 0 ? "re" : "");
+	rc = rpcrdma_ep_connect(&r_xprt->rx_ep, &r_xprt->rx_ia);
+	if (rc)
+		xprt_wake_pending_tasks(xprt, rc);
 
-out:
-	xprt_wake_pending_tasks(xprt, rc);
-out_clear:
 	dprintk("RPC:       %s: exit\n", __func__);
 	xprt_clear_connecting(xprt);
 	current->flags &= ~PF_FSTRANS;
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index a35b8e5..aaaadfb 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -917,9 +917,6 @@
 	if (skb == NULL)
 		goto out;
 
-	if (xprt->shutdown)
-		goto dropit;
-
 	repsize = skb->len - sizeof(rpc_fraghdr);
 	if (repsize < 4) {
 		dprintk("RPC:       impossible RPC reply size %d\n", repsize);
@@ -981,9 +978,6 @@
 	if ((skb = skb_recv_datagram(sk, 0, 1, &err)) == NULL)
 		goto out;
 
-	if (xprt->shutdown)
-		goto dropit;
-
 	repsize = skb->len - sizeof(struct udphdr);
 	if (repsize < 4) {
 		dprintk("RPC:       impossible RPC reply size %d!\n", repsize);
@@ -1025,6 +1019,16 @@
 	read_unlock_bh(&sk->sk_callback_lock);
 }
 
+/*
+ * Helper function to force a TCP close if the server is sending
+ * junk and/or it has put us in CLOSE_WAIT
+ */
+static void xs_tcp_force_close(struct rpc_xprt *xprt)
+{
+	set_bit(XPRT_CONNECTION_CLOSE, &xprt->state);
+	xprt_force_disconnect(xprt);
+}
+
 static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, struct xdr_skb_reader *desc)
 {
 	struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
@@ -1051,7 +1055,7 @@
 	/* Sanity check of the record length */
 	if (unlikely(transport->tcp_reclen < 8)) {
 		dprintk("RPC:       invalid TCP record fragment length\n");
-		xprt_force_disconnect(xprt);
+		xs_tcp_force_close(xprt);
 		return;
 	}
 	dprintk("RPC:       reading TCP record fragment of length %d\n",
@@ -1132,7 +1136,7 @@
 		break;
 	default:
 		dprintk("RPC:       invalid request message type\n");
-		xprt_force_disconnect(&transport->xprt);
+		xs_tcp_force_close(&transport->xprt);
 	}
 	xs_tcp_check_fraghdr(transport);
 }
@@ -1402,9 +1406,6 @@
 	read_lock_bh(&sk->sk_callback_lock);
 	if (!(xprt = xprt_from_sock(sk)))
 		goto out;
-	if (xprt->shutdown)
-		goto out;
-
 	/* Any data means we had a useful conversation, so
 	 * the we don't need to delay the next reconnect
 	 */
@@ -1455,6 +1456,8 @@
 static void xs_sock_mark_closed(struct rpc_xprt *xprt)
 {
 	smp_mb__before_clear_bit();
+	clear_bit(XPRT_CONNECTION_ABORT, &xprt->state);
+	clear_bit(XPRT_CONNECTION_CLOSE, &xprt->state);
 	clear_bit(XPRT_CLOSE_WAIT, &xprt->state);
 	clear_bit(XPRT_CLOSING, &xprt->state);
 	smp_mb__after_clear_bit();
@@ -1512,8 +1515,8 @@
 		break;
 	case TCP_CLOSE_WAIT:
 		/* The server initiated a shutdown of the socket */
-		xprt_force_disconnect(xprt);
 		xprt->connect_cookie++;
+		xs_tcp_force_close(xprt);
 	case TCP_CLOSING:
 		/*
 		 * If the server closed down the connection, make sure that
@@ -1889,9 +1892,6 @@
 	struct socket *sock;
 	int status = -EIO;
 
-	if (xprt->shutdown)
-		goto out;
-
 	current->flags |= PF_FSTRANS;
 
 	clear_bit(XPRT_CONNECTION_ABORT, &xprt->state);
@@ -2008,9 +2008,6 @@
 	struct socket *sock = transport->sock;
 	int status = -EIO;
 
-	if (xprt->shutdown)
-		goto out;
-
 	current->flags |= PF_FSTRANS;
 
 	/* Start by resetting any existing state */
@@ -2156,9 +2153,6 @@
 	struct rpc_xprt *xprt = &transport->xprt;
 	int status = -EIO;
 
-	if (xprt->shutdown)
-		goto out;
-
 	current->flags |= PF_FSTRANS;
 
 	if (!sock) {
@@ -2199,8 +2193,7 @@
 		/* We're probably in TIME_WAIT. Get rid of existing socket,
 		 * and retry
 		 */
-		set_bit(XPRT_CONNECTION_CLOSE, &xprt->state);
-		xprt_force_disconnect(xprt);
+		xs_tcp_force_close(xprt);
 		break;
 	case -ECONNREFUSED:
 	case -ECONNRESET:
@@ -2528,6 +2521,7 @@
 static struct rpc_xprt_ops bc_tcp_ops = {
 	.reserve_xprt		= xprt_reserve_xprt,
 	.release_xprt		= xprt_release_xprt,
+	.alloc_slot		= xprt_alloc_slot,
 	.rpcbind		= xs_local_rpcbind,
 	.buf_alloc		= bc_malloc,
 	.buf_free		= bc_free,
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index afa4459..978416d 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -98,24 +98,24 @@
 # Usage: cflags-y += $(call as-option,-Wa$(comma)-isa=foo,)
 
 as-option = $(call try-run,\
-	$(CC) $(KBUILD_CFLAGS) $(1) -c -xassembler /dev/null -o "$$TMP",$(1),$(2))
+	$(CC) $(KBUILD_CFLAGS) $(1) -c -x assembler /dev/null -o "$$TMP",$(1),$(2))
 
 # as-instr
 # Usage: cflags-y += $(call as-instr,instr,option1,option2)
 
 as-instr = $(call try-run,\
-	printf "%b\n" "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -xassembler -o "$$TMP" -,$(2),$(3))
+	printf "%b\n" "$(1)" | $(CC) $(KBUILD_AFLAGS) -c -x assembler -o "$$TMP" -,$(2),$(3))
 
 # cc-option
 # Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586)
 
 cc-option = $(call try-run,\
-	$(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -xc /dev/null -o "$$TMP",$(1),$(2))
+	$(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",$(1),$(2))
 
 # cc-option-yn
 # Usage: flag := $(call cc-option-yn,-march=winchip-c6)
 cc-option-yn = $(call try-run,\
-	$(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -xc /dev/null -o "$$TMP",y,n)
+	$(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n)
 
 # cc-option-align
 # Prefix align with either -falign or -malign
@@ -125,7 +125,7 @@
 # cc-disable-warning
 # Usage: cflags-y += $(call cc-disable-warning,unused-but-set-variable)
 cc-disable-warning = $(call try-run,\
-	$(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -W$(strip $(1)) -c -xc /dev/null -o "$$TMP",-Wno-$(strip $(1)))
+	$(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1)))
 
 # cc-version
 # Usage gcc-ver := $(call cc-version)
@@ -143,7 +143,7 @@
 # cc-ldoption
 # Usage: ldflags += $(call cc-ldoption, -Wl$(comma)--hash-style=both)
 cc-ldoption = $(call try-run,\
-	$(CC) $(1) -nostdlib -xc /dev/null -o "$$TMP",$(1),$(2))
+	$(CC) $(1) -nostdlib -x c /dev/null -o "$$TMP",$(1),$(2))
 
 # ld-option
 # Usage: LDFLAGS += $(call ld-option, -X)
diff --git a/scripts/Makefile.fwinst b/scripts/Makefile.fwinst
index 4d908d1..c3f69ae2 100644
--- a/scripts/Makefile.fwinst
+++ b/scripts/Makefile.fwinst
@@ -27,7 +27,7 @@
 installed-mod-fw := $(addprefix $(INSTALL_FW_PATH)/,$(mod-fw))
 
 installed-fw := $(addprefix $(INSTALL_FW_PATH)/,$(fw-shipped-all))
-installed-fw-dirs := $(sort $(dir $(installed-fw))) $(INSTALL_FW_PATH)/./
+installed-fw-dirs := $(sort $(dir $(installed-fw))) $(INSTALL_FW_PATH)/.
 
 # Workaround for make < 3.81, where .SECONDEXPANSION doesn't work.
 PHONY += $(INSTALL_FW_PATH)/$$(%) install-all-dirs
@@ -42,7 +42,7 @@
 $(installed-fw-dirs):
 	$(call cmd,mkdir)
 
-$(installed-fw): $(INSTALL_FW_PATH)/%: $(obj)/% | $(INSTALL_FW_PATH)/$$(dir %)
+$(installed-fw): $(INSTALL_FW_PATH)/%: $(obj)/% | $$(dir $(INSTALL_FW_PATH)/%)
 	$(call cmd,install)
 
 PHONY +=  __fw_install __fw_modinst FORCE
diff --git a/scripts/Makefile.modinst b/scripts/Makefile.modinst
index efa5d94..3d13d3a 100644
--- a/scripts/Makefile.modinst
+++ b/scripts/Makefile.modinst
@@ -9,7 +9,7 @@
 
 #
 
-__modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
+__modules := $(sort $(shell grep -h '\.ko$$' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
 modules := $(patsubst %.o,%.ko,$(wildcard $(__modules:.ko=.o)))
 
 PHONY += $(modules)
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
index 08dce14..a1cb022 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -60,7 +60,7 @@
 modulesymfile := $(firstword $(KBUILD_EXTMOD))/Module.symvers
 
 # Step 1), find all modules listed in $(MODVERDIR)/
-__modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
+__modules := $(sort $(shell grep -h '\.ko$$' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
 modules   := $(patsubst %.o,%.ko, $(wildcard $(__modules:.ko=.o)))
 
 # Stop after building .o files if NOFINAL is set. Makes compile tests quicker
diff --git a/scripts/coccicheck b/scripts/coccicheck
index 823e972..1a49d1c 100755
--- a/scripts/coccicheck
+++ b/scripts/coccicheck
@@ -95,6 +95,9 @@
 	$SPATCH -D report  $FLAGS -sp_file $COCCI $OPT $OPTIONS -no_show_diff || \
 	$SPATCH -D context $FLAGS -sp_file $COCCI $OPT $OPTIONS               || \
 	$SPATCH -D org     $FLAGS -sp_file $COCCI $OPT $OPTIONS -no_show_diff || exit 1
+    elif [ "$MODE" = "rep+ctxt" ] ; then
+	$SPATCH -D report  $FLAGS -sp_file $COCCI $OPT $OPTIONS -no_show_diff && \
+	$SPATCH -D context $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1
     else
 	$SPATCH -D $MODE   $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1
     fi
diff --git a/scripts/coccinelle/api/ptr_ret.cocci b/scripts/coccinelle/api/ptr_ret.cocci
index cbfd08c..15f076f 100644
--- a/scripts/coccinelle/api/ptr_ret.cocci
+++ b/scripts/coccinelle/api/ptr_ret.cocci
@@ -30,6 +30,13 @@
 - if (IS_ERR(ptr)) return PTR_ERR(ptr); return 0;
 + return PTR_RET(ptr);
 
+@depends on patch@
+expression ptr;
+@@
+
+- (IS_ERR(ptr) ? PTR_ERR(ptr) : 0)
++ PTR_RET(ptr)
+
 @r1 depends on !patch@
 expression ptr;
 position p1;
@@ -44,6 +51,13 @@
 
 * if@p2 (IS_ERR(ptr)) return PTR_ERR(ptr); return 0;
 
+@r3 depends on !patch@
+expression ptr;
+position p3;
+@@
+
+* IS_ERR@p3(ptr) ? PTR_ERR(ptr) : 0
+
 @script:python depends on org@
 p << r1.p1;
 @@
@@ -57,6 +71,12 @@
 
 coccilib.org.print_todo(p[0], "WARNING: PTR_RET can be used")
 
+@script:python depends on org@
+p << r3.p3;
+@@
+
+coccilib.org.print_todo(p[0], "WARNING: PTR_RET can be used")
+
 @script:python depends on report@
 p << r1.p1;
 @@
@@ -68,3 +88,9 @@
 @@
 
 coccilib.report.print_report(p[0], "WARNING: PTR_RET can be used")
+
+@script:python depends on report@
+p << r3.p3;
+@@
+
+coccilib.report.print_report(p[0], "WARNING: PTR_RET can be used")
diff --git a/scripts/coccinelle/tests/odd_ptr_err.cocci b/scripts/coccinelle/tests/odd_ptr_err.cocci
new file mode 100644
index 0000000..e8dd8a6
--- /dev/null
+++ b/scripts/coccinelle/tests/odd_ptr_err.cocci
@@ -0,0 +1,65 @@
+/// PTR_ERR should access the value just tested by IS_ERR
+//# There can be false positives in the patch case, where it is the call
+//# IS_ERR that is wrong.
+///
+// Confidence: High
+// Copyright: (C) 2012 Julia Lawall, INRIA.  GPLv2.
+// Copyright: (C) 2012 Gilles Muller, INRIA.  GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments:
+// Options: -no_includes -include_headers
+
+virtual patch
+virtual context
+virtual org
+virtual report
+
+@depends on patch@
+expression e,e1;
+@@
+
+(
+if (IS_ERR(e)) { ... PTR_ERR(e) ... }
+|
+if (IS_ERR(e=e1)) { ... PTR_ERR(e) ... }
+|
+if (IS_ERR(e))
+ { ...
+  PTR_ERR(
+-   e1
++   e
+  )
+   ... }
+)
+
+@r depends on !patch@
+expression e,e1;
+position p1,p2;
+@@
+
+(
+if (IS_ERR(e)) { ... PTR_ERR(e) ... }
+|
+if (IS_ERR(e=e1)) { ... PTR_ERR(e) ... }
+|
+*if (IS_ERR@p1(e))
+ { ...
+*  PTR_ERR@p2(e1)
+   ... }
+)
+
+@script:python depends on org@
+p1 << r.p1;
+p2 << r.p2;
+@@
+
+cocci.print_main("inconsistent IS_ERR and PTR_ERR",p1)
+cocci.print_secs("PTR_ERR",p2)
+
+@script:python depends on report@
+p1 << r.p1;
+p2 << r.p2;
+@@
+
+msg = "inconsistent IS_ERR and PTR_ERR, PTR_ERR on line %s" % (p2[0].line)
+coccilib.report.print_report(p1[0],msg)
diff --git a/scripts/gcc-version.sh b/scripts/gcc-version.sh
index debecb5..7f2126d 100644
--- a/scripts/gcc-version.sh
+++ b/scripts/gcc-version.sh
@@ -22,10 +22,10 @@
 	exit 1
 fi
 
-MAJOR=$(echo __GNUC__ | $compiler -E -xc - | tail -n 1)
-MINOR=$(echo __GNUC_MINOR__ | $compiler -E -xc - | tail -n 1)
+MAJOR=$(echo __GNUC__ | $compiler -E -x c - | tail -n 1)
+MINOR=$(echo __GNUC_MINOR__ | $compiler -E -x c - | tail -n 1)
 if [ "x$with_patchlevel" != "x" ] ; then
-	PATCHLEVEL=$(echo __GNUC_PATCHLEVEL__ | $compiler -E -xc - | tail -n 1)
+	PATCHLEVEL=$(echo __GNUC_PATCHLEVEL__ | $compiler -E -x c - | tail -n 1)
 	printf "%02d%02d%02d\\n" $MAJOR $MINOR $PATCHLEVEL
 else
 	printf "%02d%02d\\n" $MAJOR $MINOR
diff --git a/scripts/gcc-x86_32-has-stack-protector.sh b/scripts/gcc-x86_32-has-stack-protector.sh
index 29493dc..12dbd0b 100644
--- a/scripts/gcc-x86_32-has-stack-protector.sh
+++ b/scripts/gcc-x86_32-has-stack-protector.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-echo "int foo(void) { char X[200]; return 3; }" | $* -S -xc -c -O0 -fstack-protector - -o - 2> /dev/null | grep -q "%gs"
+echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -O0 -fstack-protector - -o - 2> /dev/null | grep -q "%gs"
 if [ "$?" -eq "0" ] ; then
 	echo y
 else
diff --git a/scripts/gcc-x86_64-has-stack-protector.sh b/scripts/gcc-x86_64-has-stack-protector.sh
index afaec61..973e8c1 100644
--- a/scripts/gcc-x86_64-has-stack-protector.sh
+++ b/scripts/gcc-x86_64-has-stack-protector.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-echo "int foo(void) { char X[200]; return 3; }" | $* -S -xc -c -O0 -mcmodel=kernel -fstack-protector - -o - 2> /dev/null | grep -q "%gs"
+echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -O0 -mcmodel=kernel -fstack-protector - -o - 2> /dev/null | grep -q "%gs"
 if [ "$?" -eq "0" ] ; then
 	echo y
 else
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 77d5399..3091794 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -76,11 +76,17 @@
 allnoconfig allyesconfig allmodconfig alldefconfig randconfig: $(obj)/conf
 	$< --$@ $(Kconfig)
 
-PHONY += listnewconfig oldnoconfig savedefconfig defconfig
+PHONY += listnewconfig olddefconfig oldnoconfig savedefconfig defconfig
 
-listnewconfig oldnoconfig: $(obj)/conf
+listnewconfig olddefconfig: $(obj)/conf
 	$< --$@ $(Kconfig)
 
+# oldnoconfig is an alias of olddefconfig, because people already are dependent
+# on its behavior(sets new symbols to their default value but not 'n') with the
+# counter-intuitive name.
+oldnoconfig: $(obj)/conf
+	$< --olddefconfig $(Kconfig)
+
 savedefconfig: $(obj)/conf
 	$< --$@=defconfig $(Kconfig)
 
@@ -114,7 +120,7 @@
 	@echo  '  alldefconfig    - New config with all symbols set to default'
 	@echo  '  randconfig	  - New config with random answer to all options'
 	@echo  '  listnewconfig   - List new options'
-	@echo  '  oldnoconfig     - Same as silentoldconfig but sets new symbols to their default value'
+	@echo  '  olddefconfig	  - Same as silentoldconfig but sets new symbols to their default value'
 
 # lxdialog stuff
 check-lxdialog  := $(srctree)/$(src)/lxdialog/check-lxdialog.sh
diff --git a/scripts/kconfig/check.sh b/scripts/kconfig/check.sh
index fa59cbf..854d9c7 100755
--- a/scripts/kconfig/check.sh
+++ b/scripts/kconfig/check.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 # Needed for systems without gettext
-$* -xc -o /dev/null - > /dev/null 2>&1 << EOF
+$* -x c -o /dev/null - > /dev/null 2>&1 << EOF
 #include <libintl.h>
 int main()
 {
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 0dc4a2c..4da3b4a 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -32,7 +32,7 @@
 	defconfig,
 	savedefconfig,
 	listnewconfig,
-	oldnoconfig,
+	olddefconfig,
 } input_mode = oldaskconfig;
 
 static int indent = 1;
@@ -365,7 +365,7 @@
 		case P_MENU:
 			if ((input_mode == silentoldconfig ||
 			     input_mode == listnewconfig ||
-			     input_mode == oldnoconfig) &&
+			     input_mode == olddefconfig) &&
 			    rootEntry != menu) {
 				check_conf(menu);
 				return;
@@ -429,7 +429,7 @@
 				if (sym->name && !sym_is_choice_value(sym)) {
 					printf("%s%s\n", CONFIG_, sym->name);
 				}
-			} else if (input_mode != oldnoconfig) {
+			} else if (input_mode != olddefconfig) {
 				if (!conf_cnt++)
 					printf(_("*\n* Restart config...\n*\n"));
 				rootEntry = menu_get_parent_menu(menu);
@@ -454,7 +454,13 @@
 	{"alldefconfig",    no_argument,       NULL, alldefconfig},
 	{"randconfig",      no_argument,       NULL, randconfig},
 	{"listnewconfig",   no_argument,       NULL, listnewconfig},
-	{"oldnoconfig",     no_argument,       NULL, oldnoconfig},
+	{"olddefconfig",    no_argument,       NULL, olddefconfig},
+	/*
+	 * oldnoconfig is an alias of olddefconfig, because people already
+	 * are dependent on its behavior(sets new symbols to their default
+	 * value but not 'n') with the counter-intuitive name.
+	 */
+	{"oldnoconfig",     no_argument,       NULL, olddefconfig},
 	{NULL, 0, NULL, 0}
 };
 
@@ -467,7 +473,8 @@
 	printf("  --oldaskconfig          Start a new configuration using a line-oriented program\n");
 	printf("  --oldconfig             Update a configuration using a provided .config as base\n");
 	printf("  --silentoldconfig       Same as oldconfig, but quietly, additionally update deps\n");
-	printf("  --oldnoconfig           Same as silentoldconfig but set new symbols to no\n");
+	printf("  --olddefconfig          Same as silentoldconfig but sets new symbols to their default value\n");
+	printf("  --oldnoconfig           An alias of olddefconfig\n");
 	printf("  --defconfig <file>      New config with default defined in <file>\n");
 	printf("  --savedefconfig <file>  Save the minimal current configuration to <file>\n");
 	printf("  --allnoconfig           New config where all options are answered with no\n");
@@ -520,7 +527,7 @@
 		case allmodconfig:
 		case alldefconfig:
 		case listnewconfig:
-		case oldnoconfig:
+		case olddefconfig:
 			break;
 		case '?':
 			conf_usage(progname);
@@ -565,7 +572,7 @@
 	case oldaskconfig:
 	case oldconfig:
 	case listnewconfig:
-	case oldnoconfig:
+	case olddefconfig:
 		conf_read(NULL);
 		break;
 	case allnoconfig:
@@ -645,7 +652,7 @@
 		/* fall through */
 	case oldconfig:
 	case listnewconfig:
-	case oldnoconfig:
+	case olddefconfig:
 	case silentoldconfig:
 		/* Update until a loop caused no more changes */
 		do {
@@ -653,7 +660,7 @@
 			check_conf(&rootmenu);
 		} while (conf_cnt &&
 			 (input_mode != listnewconfig &&
-			  input_mode != oldnoconfig));
+			  input_mode != olddefconfig));
 		break;
 	}
 
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index d4ecce8..bd2e098 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -12,6 +12,7 @@
 
 #include <assert.h>
 #include <stdio.h>
+#include <sys/queue.h>
 #ifndef __cplusplus
 #include <stdbool.h>
 #endif
@@ -173,6 +174,16 @@
 #define MENU_CHANGED		0x0001
 #define MENU_ROOT		0x0002
 
+struct jump_key {
+	CIRCLEQ_ENTRY(jump_key) entries;
+	size_t offset;
+	struct menu *target;
+	int index;
+};
+CIRCLEQ_HEAD(jk_head, jump_key);
+
+#define JUMP_NB			9
+
 extern struct file *file_list;
 extern struct file *current_file;
 struct file *lookup_file(const char *name);
diff --git a/scripts/kconfig/lkc_proto.h b/scripts/kconfig/lkc_proto.h
index 47fe9c3..1d1c085 100644
--- a/scripts/kconfig/lkc_proto.h
+++ b/scripts/kconfig/lkc_proto.h
@@ -21,8 +21,10 @@
 P(menu_get_parent_menu,struct menu *,(struct menu *menu));
 P(menu_has_help,bool,(struct menu *menu));
 P(menu_get_help,const char *,(struct menu *menu));
-P(get_symbol_str, void, (struct gstr *r, struct symbol *sym));
-P(get_relations_str, struct gstr, (struct symbol **sym_arr));
+P(get_symbol_str, void, (struct gstr *r, struct symbol *sym, struct jk_head
+			 *head));
+P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct jk_head
+				   *head));
 P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help));
 
 /* symbol.c */
diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh
index e3b12c0..c8e8a71 100644
--- a/scripts/kconfig/lxdialog/check-lxdialog.sh
+++ b/scripts/kconfig/lxdialog/check-lxdialog.sh
@@ -38,7 +38,7 @@
 
 # Check if we can link to ncurses
 check() {
-        $cc -xc - -o $tmp 2>/dev/null <<'EOF'
+        $cc -x c - -o $tmp 2>/dev/null <<'EOF'
 #include CURSES_LOC
 main() {}
 EOF
diff --git a/scripts/kconfig/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h
index b5211fc..ee17a52 100644
--- a/scripts/kconfig/lxdialog/dialog.h
+++ b/scripts/kconfig/lxdialog/dialog.h
@@ -144,6 +144,7 @@
  */
 extern struct dialog_info dlg;
 extern char dialog_input_result[];
+extern int saved_x, saved_y;		/* Needed in signal handler in mconf.c */
 
 /*
  * Function prototypes
@@ -209,7 +210,13 @@
 int dialog_yesno(const char *title, const char *prompt, int height, int width);
 int dialog_msgbox(const char *title, const char *prompt, int height,
 		  int width, int pause);
-int dialog_textbox(const char *title, const char *file, int height, int width);
+
+
+typedef void (*update_text_fn)(char *buf, size_t start, size_t end, void
+			       *_data);
+int dialog_textbox(const char *title, char *tbuf, int initial_height,
+		   int initial_width, int *keys, int *_vscroll, int *_hscroll,
+		   update_text_fn update_text, void *data);
 int dialog_menu(const char *title, const char *prompt,
 		const void *selected, int *s_scroll);
 int dialog_checklist(const char *title, const char *prompt, int height,
diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c
index 4e5de60..a48bb93e 100644
--- a/scripts/kconfig/lxdialog/textbox.c
+++ b/scripts/kconfig/lxdialog/textbox.c
@@ -22,23 +22,25 @@
 #include "dialog.h"
 
 static void back_lines(int n);
-static void print_page(WINDOW * win, int height, int width);
-static void print_line(WINDOW * win, int row, int width);
+static void print_page(WINDOW *win, int height, int width, update_text_fn
+		       update_text, void *data);
+static void print_line(WINDOW *win, int row, int width);
 static char *get_line(void);
 static void print_position(WINDOW * win);
 
 static int hscroll;
 static int begin_reached, end_reached, page_length;
-static const char *buf;
-static const char *page;
+static char *buf;
+static char *page;
 
 /*
  * refresh window content
  */
 static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw,
-							  int cur_y, int cur_x)
+			     int cur_y, int cur_x, update_text_fn update_text,
+			     void *data)
 {
-	print_page(box, boxh, boxw);
+	print_page(box, boxh, boxw, update_text, data);
 	print_position(dialog);
 	wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
 	wrefresh(dialog);
@@ -47,14 +49,18 @@
 
 /*
  * Display text from a file in a dialog box.
+ *
+ * keys is a null-terminated array
+ * update_text() may not add or remove any '\n' or '\0' in tbuf
  */
-int dialog_textbox(const char *title, const char *tbuf,
-		   int initial_height, int initial_width)
+int dialog_textbox(const char *title, char *tbuf, int initial_height,
+		   int initial_width, int *keys, int *_vscroll, int *_hscroll,
+		   update_text_fn update_text, void *data)
 {
 	int i, x, y, cur_x, cur_y, key = 0;
 	int height, width, boxh, boxw;
-	int passed_end;
 	WINDOW *dialog, *box;
+	bool done = false;
 
 	begin_reached = 1;
 	end_reached = 0;
@@ -63,6 +69,15 @@
 	buf = tbuf;
 	page = buf;	/* page is pointer to start of page to be displayed */
 
+	if (_vscroll && *_vscroll) {
+		begin_reached = 0;
+
+		for (i = 0; i < *_vscroll; i++)
+			get_line();
+	}
+	if (_hscroll)
+		hscroll = *_hscroll;
+
 do_resize:
 	getmaxyx(stdscr, height, width);
 	if (height < 8 || width < 8)
@@ -120,9 +135,10 @@
 
 	/* Print first page of text */
 	attr_clear(box, boxh, boxw, dlg.dialog.atr);
-	refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
+	refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x, update_text,
+			 data);
 
-	while ((key != KEY_ESC) && (key != '\n')) {
+	while (!done) {
 		key = wgetch(dialog);
 		switch (key) {
 		case 'E':	/* Exit */
@@ -130,16 +146,17 @@
 		case 'X':
 		case 'x':
 		case 'q':
-			delwin(box);
-			delwin(dialog);
-			return 0;
+		case '\n':
+			done = true;
+			break;
 		case 'g':	/* First page */
 		case KEY_HOME:
 			if (!begin_reached) {
 				begin_reached = 1;
 				page = buf;
 				refresh_text_box(dialog, box, boxh, boxw,
-						 cur_y, cur_x);
+						 cur_y, cur_x, update_text,
+						 data);
 			}
 			break;
 		case 'G':	/* Last page */
@@ -149,45 +166,18 @@
 			/* point to last char in buf */
 			page = buf + strlen(buf);
 			back_lines(boxh);
-			refresh_text_box(dialog, box, boxh, boxw,
-					 cur_y, cur_x);
+			refresh_text_box(dialog, box, boxh, boxw, cur_y,
+					 cur_x, update_text, data);
 			break;
 		case 'K':	/* Previous line */
 		case 'k':
 		case KEY_UP:
-			if (!begin_reached) {
-				back_lines(page_length + 1);
+			if (begin_reached)
+				break;
 
-				/* We don't call print_page() here but use
-				 * scrolling to ensure faster screen update.
-				 * However, 'end_reached' and 'page_length'
-				 * should still be updated, and 'page' should
-				 * point to start of next page. This is done
-				 * by calling get_line() in the following
-				 * 'for' loop. */
-				scrollok(box, TRUE);
-				wscrl(box, -1);	/* Scroll box region down one line */
-				scrollok(box, FALSE);
-				page_length = 0;
-				passed_end = 0;
-				for (i = 0; i < boxh; i++) {
-					if (!i) {
-						/* print first line of page */
-						print_line(box, 0, boxw);
-						wnoutrefresh(box);
-					} else
-						/* Called to update 'end_reached' and 'page' */
-						get_line();
-					if (!passed_end)
-						page_length++;
-					if (end_reached && !passed_end)
-						passed_end = 1;
-				}
-
-				print_position(dialog);
-				wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
-				wrefresh(dialog);
-			}
+			back_lines(page_length + 1);
+			refresh_text_box(dialog, box, boxh, boxw, cur_y,
+					 cur_x, update_text, data);
 			break;
 		case 'B':	/* Previous page */
 		case 'b':
@@ -196,23 +186,18 @@
 			if (begin_reached)
 				break;
 			back_lines(page_length + boxh);
-			refresh_text_box(dialog, box, boxh, boxw,
-					 cur_y, cur_x);
+			refresh_text_box(dialog, box, boxh, boxw, cur_y,
+					 cur_x, update_text, data);
 			break;
 		case 'J':	/* Next line */
 		case 'j':
 		case KEY_DOWN:
-			if (!end_reached) {
-				begin_reached = 0;
-				scrollok(box, TRUE);
-				scroll(box);	/* Scroll box region up one line */
-				scrollok(box, FALSE);
-				print_line(box, boxh - 1, boxw);
-				wnoutrefresh(box);
-				print_position(dialog);
-				wmove(dialog, cur_y, cur_x);	/* Restore cursor position */
-				wrefresh(dialog);
-			}
+			if (end_reached)
+				break;
+
+			back_lines(page_length - 1);
+			refresh_text_box(dialog, box, boxh, boxw, cur_y,
+					 cur_x, update_text, data);
 			break;
 		case KEY_NPAGE:	/* Next page */
 		case ' ':
@@ -221,8 +206,8 @@
 				break;
 
 			begin_reached = 0;
-			refresh_text_box(dialog, box, boxh, boxw,
-					 cur_y, cur_x);
+			refresh_text_box(dialog, box, boxh, boxw, cur_y,
+					 cur_x, update_text, data);
 			break;
 		case '0':	/* Beginning of line */
 		case 'H':	/* Scroll left */
@@ -237,8 +222,8 @@
 				hscroll--;
 			/* Reprint current page to scroll horizontally */
 			back_lines(page_length);
-			refresh_text_box(dialog, box, boxh, boxw,
-					 cur_y, cur_x);
+			refresh_text_box(dialog, box, boxh, boxw, cur_y,
+					 cur_x, update_text, data);
 			break;
 		case 'L':	/* Scroll right */
 		case 'l':
@@ -248,11 +233,12 @@
 			hscroll++;
 			/* Reprint current page to scroll horizontally */
 			back_lines(page_length);
-			refresh_text_box(dialog, box, boxh, boxw,
-					 cur_y, cur_x);
+			refresh_text_box(dialog, box, boxh, boxw, cur_y,
+					 cur_x, update_text, data);
 			break;
 		case KEY_ESC:
-			key = on_key_esc(dialog);
+			if (on_key_esc(dialog) == KEY_ESC)
+				done = true;
 			break;
 		case KEY_RESIZE:
 			back_lines(height);
@@ -260,11 +246,31 @@
 			delwin(dialog);
 			on_key_resize();
 			goto do_resize;
+		default:
+			for (i = 0; keys[i]; i++) {
+				if (key == keys[i]) {
+					done = true;
+					break;
+				}
+			}
 		}
 	}
 	delwin(box);
 	delwin(dialog);
-	return key;		/* ESC pressed */
+	if (_vscroll) {
+		const char *s;
+
+		s = buf;
+		*_vscroll = 0;
+		back_lines(page_length);
+		while (s < page && (s = strchr(s, '\n'))) {
+			(*_vscroll)++;
+			s++;
+		}
+	}
+	if (_hscroll)
+		*_hscroll = hscroll;
+	return key;
 }
 
 /*
@@ -301,12 +307,23 @@
 }
 
 /*
- * Print a new page of text. Called by dialog_textbox().
+ * Print a new page of text.
  */
-static void print_page(WINDOW * win, int height, int width)
+static void print_page(WINDOW *win, int height, int width, update_text_fn
+		       update_text, void *data)
 {
 	int i, passed_end = 0;
 
+	if (update_text) {
+		char *end;
+
+		for (i = 0; i < height; i++)
+			get_line();
+		end = page;
+		back_lines(height);
+		update_text(buf, page - buf, end - buf, data);
+	}
+
 	page_length = 0;
 	for (i = 0; i < height; i++) {
 		print_line(win, i, width);
@@ -319,7 +336,7 @@
 }
 
 /*
- * Print a new line of text. Called by dialog_textbox() and print_page().
+ * Print a new line of text.
  */
 static void print_line(WINDOW * win, int row, int width)
 {
@@ -357,10 +374,8 @@
 	end_reached = 0;
 	while (*page != '\n') {
 		if (*page == '\0') {
-			if (!end_reached) {
-				end_reached = 1;
-				break;
-			}
+			end_reached = 1;
+			break;
 		} else if (i < MAX_LEN)
 			line[i++] = *(page++);
 		else {
@@ -373,7 +388,7 @@
 	if (i <= MAX_LEN)
 		line[i] = '\0';
 	if (!end_reached)
-		page++;		/* move pass '\n' */
+		page++;		/* move past '\n' */
 
 	return line;
 }
diff --git a/scripts/kconfig/lxdialog/util.c b/scripts/kconfig/lxdialog/util.c
index f2375ad..109d531 100644
--- a/scripts/kconfig/lxdialog/util.c
+++ b/scripts/kconfig/lxdialog/util.c
@@ -23,6 +23,9 @@
 
 #include "dialog.h"
 
+/* Needed in signal handler in mconf.c */
+int saved_x, saved_y;
+
 struct dialog_info dlg;
 
 static void set_mono_theme(void)
@@ -273,6 +276,10 @@
 	int height, width;
 
 	initscr();		/* Init curses */
+
+	/* Get current cursor position for signal handler in mconf.c */
+	getyx(stdscr, saved_y, saved_x);
+
 	getmaxyx(stdscr, height, width);
 	if (height < 19 || width < 80) {
 		endwin();
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index f584a28..48f6744 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -236,16 +236,19 @@
 	"Result:\n"
 	"-----------------------------------------------------------------\n"
 	"Symbol: FOO [=m]\n"
+	"Type  : tristate\n"
 	"Prompt: Foo bus is used to drive the bar HW\n"
-	"Defined at drivers/pci/Kconfig:47\n"
-	"Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
-	"Location:\n"
-	"  -> Bus options (PCI, PCMCIA, EISA, ISA)\n"
-	"    -> PCI support (PCI [=y])\n"
-	"      -> PCI access mode (<choice> [=y])\n"
-	"Selects: LIBCRC32\n"
-	"Selected by: BAR\n"
+	"  Defined at drivers/pci/Kconfig:47\n"
+	"  Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
+	"  Location:\n"
+	"    -> Bus options (PCI, PCMCIA, EISA, ISA)\n"
+	"      -> PCI support (PCI [=y])\n"
+	"(1)     -> PCI access mode (<choice> [=y])\n"
+	"  Selects: LIBCRC32\n"
+	"  Selected by: BAR\n"
 	"-----------------------------------------------------------------\n"
+	"o The line 'Type:' shows the type of the configuration option for\n"
+	"  this symbol (boolean, tristate, string, ...)\n"
 	"o The line 'Prompt:' shows the text used in the menu structure for\n"
 	"  this symbol\n"
 	"o The 'Defined at' line tell at what file / line number the symbol\n"
@@ -254,8 +257,12 @@
 	"  this symbol to be visible in the menu (selectable)\n"
 	"o The 'Location:' lines tell where in the menu structure this symbol\n"
 	"  is located\n"
-	"    A location followed by a [=y] indicate that this is a selectable\n"
-	"    menu item - and current value is displayed inside brackets.\n"
+	"    A location followed by a [=y] indicates that this is a\n"
+	"    selectable menu item - and the current value is displayed inside\n"
+	"    brackets.\n"
+	"    Press the key in the (#) prefix to jump directly to that\n"
+	"    location. You will be returned to the current search results\n"
+	"    after exiting this new menu.\n"
 	"o The 'Selects:' line tell what symbol will be automatically\n"
 	"  selected if this symbol is selected (y or m)\n"
 	"o The 'Selected by' line tell what symbol has selected this symbol\n"
@@ -273,13 +280,15 @@
 static int child_count;
 static int single_menu_mode;
 static int show_all_options;
-static int saved_x, saved_y;
 
-static void conf(struct menu *menu);
+static void conf(struct menu *menu, struct menu *active_menu);
 static void conf_choice(struct menu *menu);
 static void conf_string(struct menu *menu);
 static void conf_load(void);
 static void conf_save(void);
+static int show_textbox_ext(const char *title, char *text, int r, int c,
+			    int *keys, int *vscroll, int *hscroll,
+			    update_text_fn update_text, void *data);
 static void show_textbox(const char *title, const char *text, int r, int c);
 static void show_helptext(const char *title, const char *text);
 static void show_help(struct menu *menu);
@@ -302,12 +311,47 @@
 }
 
 
+struct search_data {
+	struct jk_head *head;
+	struct menu **targets;
+	int *keys;
+};
+
+static void update_text(char *buf, size_t start, size_t end, void *_data)
+{
+	struct search_data *data = _data;
+	struct jump_key *pos;
+	int k = 0;
+
+	CIRCLEQ_FOREACH(pos, data->head, entries) {
+		if (pos->offset >= start && pos->offset < end) {
+			char header[4];
+
+			if (k < JUMP_NB) {
+				int key = '0' + (pos->index % JUMP_NB) + 1;
+
+				sprintf(header, "(%c)", key);
+				data->keys[k] = key;
+				data->targets[k] = pos->target;
+				k++;
+			} else {
+				sprintf(header, "   ");
+			}
+
+			memcpy(buf + pos->offset, header, sizeof(header) - 1);
+		}
+	}
+	data->keys[k] = 0;
+}
+
 static void search_conf(void)
 {
 	struct symbol **sym_arr;
 	struct gstr res;
 	char *dialog_input;
-	int dres;
+	int dres, vscroll = 0, hscroll = 0;
+	bool again;
+
 again:
 	dialog_clear();
 	dres = dialog_inputbox(_("Search Configuration Parameter"),
@@ -330,10 +374,30 @@
 		dialog_input += strlen(CONFIG_);
 
 	sym_arr = sym_re_search(dialog_input);
-	res = get_relations_str(sym_arr);
+	do {
+		struct jk_head head = CIRCLEQ_HEAD_INITIALIZER(head);
+		struct menu *targets[JUMP_NB];
+		int keys[JUMP_NB + 1], i;
+		struct search_data data = {
+			.head = &head,
+			.targets = targets,
+			.keys = keys,
+		};
+
+		res = get_relations_str(sym_arr, &head);
+		dres = show_textbox_ext(_("Search Results"), (char *)
+					str_get(&res), 0, 0, keys, &vscroll,
+					&hscroll, &update_text, (void *)
+					&data);
+		again = false;
+		for (i = 0; i < JUMP_NB && keys[i]; i++)
+			if (dres == keys[i]) {
+				conf(targets[i]->parent, targets[i]);
+				again = true;
+			}
+		str_free(&res);
+	} while (again);
 	free(sym_arr);
-	show_textbox(_("Search Results"), str_get(&res), 0, 0);
-	str_free(&res);
 }
 
 static void build_conf(struct menu *menu)
@@ -514,12 +578,11 @@
 	indent -= doint;
 }
 
-static void conf(struct menu *menu)
+static void conf(struct menu *menu, struct menu *active_menu)
 {
 	struct menu *submenu;
 	const char *prompt = menu_get_prompt(menu);
 	struct symbol *sym;
-	struct menu *active_menu = NULL;
 	int res;
 	int s_scroll = 0;
 
@@ -562,13 +625,13 @@
 				if (single_menu_mode)
 					submenu->data = (void *) (long) !submenu->data;
 				else
-					conf(submenu);
+					conf(submenu, NULL);
 				break;
 			case 't':
 				if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
 					conf_choice(submenu);
 				else if (submenu->prompt->type == P_MENU)
-					conf(submenu);
+					conf(submenu, NULL);
 				break;
 			case 's':
 				conf_string(submenu);
@@ -607,7 +670,7 @@
 			if (item_is_tag('t'))
 				sym_toggle_tristate_value(sym);
 			else if (item_is_tag('m'))
-				conf(submenu);
+				conf(submenu, NULL);
 			break;
 		case 7:
 			search_conf();
@@ -619,10 +682,19 @@
 	}
 }
 
-static void show_textbox(const char *title, const char *text, int r, int c)
+static int show_textbox_ext(const char *title, char *text, int r, int c, int
+			    *keys, int *vscroll, int *hscroll, update_text_fn
+			    update_text, void *data)
 {
 	dialog_clear();
-	dialog_textbox(title, text, r, c);
+	return dialog_textbox(title, text, r, c, keys, vscroll, hscroll,
+			      update_text, data);
+}
+
+static void show_textbox(const char *title, const char *text, int r, int c)
+{
+	show_textbox_ext(title, (char *) text, r, c, (int []) {0}, NULL, NULL,
+			 NULL, NULL);
 }
 
 static void show_helptext(const char *title, const char *text)
@@ -862,9 +934,6 @@
 			single_menu_mode = 1;
 	}
 
-	initscr();
-
-	getyx(stdscr, saved_y, saved_x);
 	if (init_dialog(NULL)) {
 		fprintf(stderr, N_("Your display is too small to run Menuconfig!\n"));
 		fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n"));
@@ -873,7 +942,7 @@
 
 	set_config_filename(conf_get_configname());
 	do {
-		conf(&rootmenu);
+		conf(&rootmenu, NULL);
 		res = handle_exit();
 	} while (res == KEY_ESC);
 
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 8c2a97e..a3cade6 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -507,10 +507,12 @@
 		return "";
 }
 
-static void get_prompt_str(struct gstr *r, struct property *prop)
+static void get_prompt_str(struct gstr *r, struct property *prop,
+			   struct jk_head *head)
 {
 	int i, j;
-	struct menu *submenu[8], *menu;
+	struct menu *submenu[8], *menu, *location = NULL;
+	struct jump_key *jump;
 
 	str_printf(r, _("Prompt: %s\n"), _(prop->text));
 	str_printf(r, _("  Defined at %s:%d\n"), prop->menu->file->name,
@@ -521,13 +523,43 @@
 		str_append(r, "\n");
 	}
 	menu = prop->menu->parent;
-	for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent)
+	for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent) {
+		bool accessible = menu_is_visible(menu);
+
 		submenu[i++] = menu;
+		if (location == NULL && accessible)
+			location = menu;
+	}
+	if (head && location) {
+		jump = malloc(sizeof(struct jump_key));
+
+		if (menu_is_visible(prop->menu)) {
+			/*
+			 * There is not enough room to put the hint at the
+			 * beginning of the "Prompt" line. Put the hint on the
+			 * last "Location" line even when it would belong on
+			 * the former.
+			 */
+			jump->target = prop->menu;
+		} else
+			jump->target = location;
+
+		if (CIRCLEQ_EMPTY(head))
+			jump->index = 0;
+		else
+			jump->index = CIRCLEQ_LAST(head)->index + 1;
+
+		CIRCLEQ_INSERT_TAIL(head, jump, entries);
+	}
+
 	if (i > 0) {
 		str_printf(r, _("  Location:\n"));
 		for (j = 4; --i >= 0; j += 2) {
 			menu = submenu[i];
-			str_printf(r, "%*c-> %s", j, ' ', _(menu_get_prompt(menu)));
+			if (head && location && menu == location)
+				jump->offset = r->len - 1;
+			str_printf(r, "%*c-> %s", j, ' ',
+				   _(menu_get_prompt(menu)));
 			if (menu->sym) {
 				str_printf(r, " (%s [=%s])", menu->sym->name ?
 					menu->sym->name : _("<choice>"),
@@ -538,7 +570,10 @@
 	}
 }
 
-void get_symbol_str(struct gstr *r, struct symbol *sym)
+/*
+ * head is optional and may be NULL
+ */
+void get_symbol_str(struct gstr *r, struct symbol *sym, struct jk_head *head)
 {
 	bool hit;
 	struct property *prop;
@@ -557,7 +592,7 @@
 		}
 	}
 	for_all_prompts(sym, prop)
-		get_prompt_str(r, prop);
+		get_prompt_str(r, prop, head);
 	hit = false;
 	for_all_properties(sym, prop, P_SELECT) {
 		if (!hit) {
@@ -577,14 +612,14 @@
 	str_append(r, "\n\n");
 }
 
-struct gstr get_relations_str(struct symbol **sym_arr)
+struct gstr get_relations_str(struct symbol **sym_arr, struct jk_head *head)
 {
 	struct symbol *sym;
 	struct gstr res = str_new();
 	int i;
 
 	for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
-		get_symbol_str(&res, sym);
+		get_symbol_str(&res, sym, head);
 	if (!i)
 		str_append(&res, _("No matches found.\n"));
 	return res;
@@ -603,5 +638,5 @@
 	}
 	str_printf(help, "%s\n", _(help_text));
 	if (sym)
-		get_symbol_str(help, sym);
+		get_symbol_str(help, sym, NULL);
 }
diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c
index 1704a85..87d4b15 100644
--- a/scripts/kconfig/nconf.c
+++ b/scripts/kconfig/nconf.c
@@ -721,7 +721,7 @@
 		dialog_input += strlen(CONFIG_);
 
 	sym_arr = sym_re_search(dialog_input);
-	res = get_relations_str(sym_arr);
+	res = get_relations_str(sym_arr, NULL);
 	free(sym_arr);
 	show_scroll_win(main_window,
 			_("Search Results"), str_get(&res));
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 01e8a8e..46e7aff 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -6,6 +6,7 @@
 ## Copyright (C) 2000, 1  Tim Waugh <twaugh@redhat.com>          ##
 ## Copyright (C) 2001  Simon Huggins                             ##
 ## Copyright (C) 2005-2012  Randy Dunlap                         ##
+## Copyright (C) 2012  Dan Luedtke                               ##
 ## 								 ##
 ## #define enhancements by Armin Kuster <akuster@mvista.com>	 ##
 ## Copyright (c) 2000 MontaVista Software, Inc.			 ##
@@ -35,6 +36,8 @@
 #              Small fixes (like spaces vs. \s in regex)
 # -- Tim Jansen <tim@tjansen.de>
 
+# 25/07/2012 - Added support for HTML5
+# -- Dan Luedtke <mail@danrl.de>
 
 #
 # This will read a 'c' file and scan for embedded comments in the
@@ -44,12 +47,16 @@
 # Note: This only supports 'c'.
 
 # usage:
-# kernel-doc [ -docbook | -html | -text | -man | -list ] [ -no-doc-sections ]
-#           [ -function funcname [ -function funcname ...] ] c file(s)s > outputfile
+# kernel-doc [ -docbook | -html | -html5 | -text | -man | -list ]
+#            [ -no-doc-sections ]
+#            [ -function funcname [ -function funcname ...] ]
+#            c file(s)s > outputfile
 # or
-#           [ -nofunction funcname [ -function funcname ...] ] c file(s)s > outputfile
+#            [ -nofunction funcname [ -function funcname ...] ]
+#            c file(s)s > outputfile
 #
-#  Set output format using one of -docbook -html -text or -man.  Default is man.
+#  Set output format using one of -docbook -html -html5 -text or -man.
+#  Default is man.
 #  The -list format is for internal use by docproc.
 #
 #  -no-doc-sections
@@ -182,6 +189,14 @@
 my $local_gt = "\\\\\\\\gt:";
 my $blankline_html = $local_lt . "p" . $local_gt;	# was "<p>"
 
+# html version 5
+my %highlights_html5 = ( $type_constant, "<span class=\"const\">\$1</span>",
+			$type_func, "<span class=\"func\">\$1</span>",
+			$type_struct_xml, "<span class=\"struct\">\$1</span>",
+			$type_env, "<span class=\"env\">\$1</span>",
+			$type_param, "<span class=\"param\">\$1</span>" );
+my $blankline_html5 = $local_lt . "br /" . $local_gt;
+
 # XML, docbook format
 my %highlights_xml = ( "([^=])\\\"([^\\\"<]+)\\\"", "\$1<quote>\$2</quote>",
 			$type_constant, "<constant>\$1</constant>",
@@ -311,6 +326,10 @@
 	$output_mode = "html";
 	%highlights = %highlights_html;
 	$blankline = $blankline_html;
+    } elsif ($cmd eq "-html5") {
+	$output_mode = "html5";
+	%highlights = %highlights_html5;
+	$blankline = $blankline_html5;
     } elsif ($cmd eq "-man") {
 	$output_mode = "man";
 	%highlights = %highlights_man;
@@ -353,10 +372,11 @@
 # continue execution near EOF;
 
 sub usage {
-    print "Usage: $0 [ -v ] [ -docbook | -html | -text | -man | -list ]\n";
+    print "Usage: $0 [ -docbook | -html | -html5 | -text | -man | -list ]\n";
     print "         [ -no-doc-sections ]\n";
     print "         [ -function funcname [ -function funcname ...] ]\n";
     print "         [ -nofunction funcname [ -nofunction funcname ...] ]\n";
+    print "         [ -v ]\n";
     print "         c source file(s) > outputfile\n";
     print "         -v : verbose output, more warnings & other info listed\n";
     exit 1;
@@ -450,7 +470,8 @@
 #	confess "output_highlight got called with no args?\n";
 #   }
 
-    if ($output_mode eq "html" || $output_mode eq "xml") {
+    if ($output_mode eq "html" || $output_mode eq "html5" ||
+	$output_mode eq "xml") {
 	$contents = local_unescape($contents);
 	# convert data read & converted thru xml_escape() into &xyz; format:
 	$contents =~ s/\\\\\\/\&/g;
@@ -460,6 +481,11 @@
     die $@ if $@;
 #   print STDERR "contents af:$contents\n";
 
+#   strip whitespaces when generating html5
+    if ($output_mode eq "html5") {
+	$contents =~ s/^\s+//;
+	$contents =~ s/\s+$//;
+    }
     foreach $line (split "\n", $contents) {
 	if (! $output_preformatted) {
 	    $line =~ s/^\s*//;
@@ -480,7 +506,7 @@
     }
 }
 
-#output sections in html
+# output sections in html
 sub output_section_html(%) {
     my %args = %{$_[0]};
     my $section;
@@ -640,6 +666,239 @@
     print "<hr>\n";
 }
 
+# output sections in html5
+sub output_section_html5(%) {
+    my %args = %{$_[0]};
+    my $section;
+
+    foreach $section (@{$args{'sectionlist'}}) {
+	print "<section>\n";
+	print "<h1>$section</h1>\n";
+	print "<p>\n";
+	output_highlight($args{'sections'}{$section});
+	print "</p>\n";
+	print "</section>\n";
+    }
+}
+
+# output enum in html5
+sub output_enum_html5(%) {
+    my %args = %{$_[0]};
+    my ($parameter);
+    my $count;
+    my $html5id;
+
+    $html5id = $args{'enum'};
+    $html5id =~ s/[^a-zA-Z0-9\-]+/_/g;
+    print "<article class=\"enum\" id=\"enum:". $html5id . "\">";
+    print "<h1>enum " . $args{'enum'} . "</h1>\n";
+    print "<ol class=\"code\">\n";
+    print "<li>";
+    print "<span class=\"keyword\">enum</span> ";
+    print "<span class=\"identifier\">" . $args{'enum'} . "</span> {";
+    print "</li>\n";
+    $count = 0;
+    foreach $parameter (@{$args{'parameterlist'}}) {
+	print "<li class=\"indent\">";
+	print "<span class=\"param\">" . $parameter . "</span>";
+	if ($count != $#{$args{'parameterlist'}}) {
+	    $count++;
+	    print ",";
+	}
+	print "</li>\n";
+    }
+    print "<li>};</li>\n";
+    print "</ol>\n";
+
+    print "<section>\n";
+    print "<h1>Constants</h1>\n";
+    print "<dl>\n";
+    foreach $parameter (@{$args{'parameterlist'}}) {
+	print "<dt>" . $parameter . "</dt>\n";
+	print "<dd>";
+	output_highlight($args{'parameterdescs'}{$parameter});
+	print "</dd>\n";
+    }
+    print "</dl>\n";
+    print "</section>\n";
+    output_section_html5(@_);
+    print "</article>\n";
+}
+
+# output typedef in html5
+sub output_typedef_html5(%) {
+    my %args = %{$_[0]};
+    my ($parameter);
+    my $count;
+    my $html5id;
+
+    $html5id = $args{'typedef'};
+    $html5id =~ s/[^a-zA-Z0-9\-]+/_/g;
+    print "<article class=\"typedef\" id=\"typedef:" . $html5id . "\">\n";
+    print "<h1>typedef " . $args{'typedef'} . "</h1>\n";
+
+    print "<ol class=\"code\">\n";
+    print "<li>";
+    print "<span class=\"keyword\">typedef</span> ";
+    print "<span class=\"identifier\">" . $args{'typedef'} . "</span>";
+    print "</li>\n";
+    print "</ol>\n";
+    output_section_html5(@_);
+    print "</article>\n";
+}
+
+# output struct in html5
+sub output_struct_html5(%) {
+    my %args = %{$_[0]};
+    my ($parameter);
+    my $html5id;
+
+    $html5id = $args{'struct'};
+    $html5id =~ s/[^a-zA-Z0-9\-]+/_/g;
+    print "<article class=\"struct\" id=\"struct:" . $html5id . "\">\n";
+    print "<hgroup>\n";
+    print "<h1>" . $args{'type'} . " " . $args{'struct'} . "</h1>";
+    print "<h2>". $args{'purpose'} . "</h2>\n";
+    print "</hgroup>\n";
+    print "<ol class=\"code\">\n";
+    print "<li>";
+    print "<span class=\"type\">" . $args{'type'} . "</span> ";
+    print "<span class=\"identifier\">" . $args{'struct'} . "</span> {";
+    print "</li>\n";
+    foreach $parameter (@{$args{'parameterlist'}}) {
+	print "<li class=\"indent\">";
+	if ($parameter =~ /^#/) {
+		print "<span class=\"param\">" . $parameter ."</span>\n";
+		print "</li>\n";
+		next;
+	}
+	my $parameter_name = $parameter;
+	$parameter_name =~ s/\[.*//;
+
+	($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+	$type = $args{'parametertypes'}{$parameter};
+	if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
+	    # pointer-to-function
+	    print "<span class=\"type\">$1</span> ";
+	    print "<span class=\"param\">$parameter</span>";
+	    print "<span class=\"type\">)</span> ";
+	    print "(<span class=\"args\">$2</span>);";
+	} elsif ($type =~ m/^(.*?)\s*(:.*)/) {
+	    # bitfield
+	    print "<span class=\"type\">$1</span> ";
+	    print "<span class=\"param\">$parameter</span>";
+	    print "<span class=\"bits\">$2</span>;";
+	} else {
+	    print "<span class=\"type\">$type</span> ";
+	    print "<span class=\"param\">$parameter</span>;";
+	}
+	print "</li>\n";
+    }
+    print "<li>};</li>\n";
+    print "</ol>\n";
+
+    print "<section>\n";
+    print "<h1>Members</h1>\n";
+    print "<dl>\n";
+    foreach $parameter (@{$args{'parameterlist'}}) {
+	($parameter =~ /^#/) && next;
+
+	my $parameter_name = $parameter;
+	$parameter_name =~ s/\[.*//;
+
+	($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+	print "<dt>" . $parameter . "</dt>\n";
+	print "<dd>";
+	output_highlight($args{'parameterdescs'}{$parameter_name});
+	print "</dd>\n";
+    }
+    print "</dl>\n";
+    print "</section>\n";
+    output_section_html5(@_);
+    print "</article>\n";
+}
+
+# output function in html5
+sub output_function_html5(%) {
+    my %args = %{$_[0]};
+    my ($parameter, $section);
+    my $count;
+    my $html5id;
+
+    $html5id = $args{'function'};
+    $html5id =~ s/[^a-zA-Z0-9\-]+/_/g;
+    print "<article class=\"function\" id=\"func:". $html5id . "\">\n";
+    print "<hgroup>\n";
+    print "<h1>" . $args{'function'} . "</h1>";
+    print "<h2>" . $args{'purpose'} . "</h2>\n";
+    print "</hgroup>\n";
+    print "<ol class=\"code\">\n";
+    print "<li>";
+    print "<span class=\"type\">" . $args{'functiontype'} . "</span> ";
+    print "<span class=\"identifier\">" . $args{'function'} . "</span> (";
+    print "</li>";
+    $count = 0;
+    foreach $parameter (@{$args{'parameterlist'}}) {
+	print "<li class=\"indent\">";
+	$type = $args{'parametertypes'}{$parameter};
+	if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
+	    # pointer-to-function
+	    print "<span class=\"type\">$1</span> ";
+	    print "<span class=\"param\">$parameter</span>";
+	    print "<span class=\"type\">)</span> ";
+	    print "(<span class=\"args\">$2</span>)";
+	} else {
+	    print "<span class=\"type\">$type</span> ";
+	    print "<span class=\"param\">$parameter</span>";
+	}
+	if ($count != $#{$args{'parameterlist'}}) {
+	    $count++;
+	    print ",";
+	}
+	print "</li>\n";
+    }
+    print "<li>)</li>\n";
+    print "</ol>\n";
+
+    print "<section>\n";
+    print "<h1>Arguments</h1>\n";
+    print "<p>\n";
+    print "<dl>\n";
+    foreach $parameter (@{$args{'parameterlist'}}) {
+	my $parameter_name = $parameter;
+	$parameter_name =~ s/\[.*//;
+
+	($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next;
+	print "<dt>" . $parameter . "</dt>\n";
+	print "<dd>";
+	output_highlight($args{'parameterdescs'}{$parameter_name});
+	print "</dd>\n";
+    }
+    print "</dl>\n";
+    print "</section>\n";
+    output_section_html5(@_);
+    print "</article>\n";
+}
+
+# output DOC: block header in html5
+sub output_blockhead_html5(%) {
+    my %args = %{$_[0]};
+    my ($parameter, $section);
+    my $count;
+    my $html5id;
+
+    foreach $section (@{$args{'sectionlist'}}) {
+	$html5id = $section;
+	$html5id =~ s/[^a-zA-Z0-9\-]+/_/g;
+	print "<article class=\"doc\" id=\"doc:". $html5id . "\">\n";
+	print "<h1>$section</h1>\n";
+	print "<p>\n";
+	output_highlight($args{'sections'}{$section});
+	print "</p>\n";
+    }
+    print "</article>\n";
+}
+
 sub output_section_xml(%) {
     my %args = %{$_[0]};
     my $section;
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 68e9f5ed..0d93856 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -821,12 +821,15 @@
 	".debug*",
 	".zdebug*",		/* Compressed debug sections. */
 	".GCC-command-line",	/* mn10300 */
+	".GCC.command.line",	/* record-gcc-switches, non mn10300 */
 	".mdebug*",        /* alpha, score, mips etc. */
 	".pdr",            /* alpha, score, mips etc. */
 	".stab*",
 	".note*",
 	".got*",
 	".toc*",
+	".xt.prop",				 /* xtensa */
+	".xt.lit",         /* xtensa */
 	NULL
 };
 
diff --git a/scripts/package/buildtar b/scripts/package/buildtar
index 8a7b155..62d8234 100644
--- a/scripts/package/buildtar
+++ b/scripts/package/buildtar
@@ -28,15 +28,15 @@
 		file_ext=""
 		;;
 	targz-pkg)
-		compress="gzip -c9"
+		compress="gzip"
 		file_ext=".gz"
 		;;
 	tarbz2-pkg)
-		compress="bzip2 -c9"
+		compress="bzip2"
 		file_ext=".bz2"
 		;;
 	tarxz-pkg)
-		compress="xz -c9"
+		compress="xz"
 		file_ext=".xz"
 		;;
 	*)
@@ -109,7 +109,7 @@
 	if tar --owner=root --group=root --help >/dev/null 2>&1; then
 		opts="--owner=root --group=root"
 	fi
-	tar cf - . $opts | ${compress} > "${tarball}${file_ext}"
+	tar cf - boot/* lib/* $opts | ${compress} > "${tarball}${file_ext}"
 )
 
 echo "Tarball successfully created in ${tarball}${file_ext}"
diff --git a/scripts/tags.sh b/scripts/tags.sh
index cff8faa..79fdafb 100755
--- a/scripts/tags.sh
+++ b/scripts/tags.sh
@@ -154,7 +154,9 @@
 	--regex-c++='/__CLEARPAGEFLAG_NOOP\(([^,)]*).*/__ClearPage\1/'	\
 	--regex-c++='/TESTCLEARFLAG_FALSE\(([^,)]*).*/TestClearPage\1/' \
 	--regex-c++='/__TESTCLEARFLAG_FALSE\(([^,)]*).*/__TestClearPage\1/' \
-	--regex-c++='/_PE\(([^,)]*).*/PEVENT_ERRNO__\1/'
+	--regex-c++='/_PE\(([^,)]*).*/PEVENT_ERRNO__\1/'		\
+	--regex-c='/PCI_OP_READ\(([a-z]*[a-z]).*[1-4]\)/pci_bus_read_config_\1/' \
+	--regex-c='/PCI_OP_WRITE\(([a-z]*[a-z]).*[1-4]\)/pci_bus_write_config_\1/'
 
 	all_kconfigs | xargs $1 -a                              \
 	--langdef=kconfig --language-force=kconfig              \
@@ -197,7 +199,9 @@
 	--regex='/__CLEARPAGEFLAG_NOOP\(([^,)]*).*/__ClearPage\1/' \
 	--regex='/TESTCLEARFLAG_FALSE\(([^,)]*).*/TestClearPage\1/' \
 	--regex='/__TESTCLEARFLAG_FALSE\(([^,)]*).*/__TestClearPage\1/' \
-	--regex='/_PE\(([^,)]*).*/PEVENT_ERRNO__\1/'
+	--regex='/_PE\(([^,)]*).*/PEVENT_ERRNO__\1/'		\
+	--regex='/PCI_OP_READ\(([a-z]*[a-z]).*[1-4]\)/pci_bus_read_config_\1/' \
+	--regex='/PCI_OP_WRITE\(([a-z]*[a-z]).*[1-4]\)/pci_bus_write_config_\1/'
 
 	all_kconfigs | xargs $1 -a                              \
 	--regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/'
diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
index 806bd19..7b3021c 100644
--- a/security/apparmor/Makefile
+++ b/security/apparmor/Makefile
@@ -60,6 +60,6 @@
 $(obj)/capability_names.h : $(srctree)/include/linux/capability.h \
 			    $(src)/Makefile
 	$(call cmd,make-caps)
-$(obj)/rlim_names.h : $(srctree)/include/asm-generic/resource.h \
+$(obj)/rlim_names.h : $(srctree)/include/uapi/asm-generic/resource.h \
 		      $(src)/Makefile
 	$(call cmd,make-rlim)
diff --git a/security/capability.c b/security/capability.c
index a40aac6..b14a30c 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -74,8 +74,8 @@
 	return 0;
 }
 
-static int cap_sb_mount(char *dev_name, struct path *path, char *type,
-			unsigned long flags, void *data)
+static int cap_sb_mount(const char *dev_name, struct path *path,
+			const char *type, unsigned long flags, void *data)
 {
 	return 0;
 }
diff --git a/security/security.c b/security/security.c
index 3724029..8dcd4ae 100644
--- a/security/security.c
+++ b/security/security.c
@@ -276,8 +276,8 @@
 	return security_ops->sb_statfs(dentry);
 }
 
-int security_sb_mount(char *dev_name, struct path *path,
-                       char *type, unsigned long flags, void *data)
+int security_sb_mount(const char *dev_name, struct path *path,
+                       const char *type, unsigned long flags, void *data)
 {
 	return security_ops->sb_mount(dev_name, path, type, flags, data);
 }
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 651d845..24ab414 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2452,9 +2452,9 @@
 	return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
 }
 
-static int selinux_mount(char *dev_name,
+static int selinux_mount(const char *dev_name,
 			 struct path *path,
-			 char *type,
+			 const char *type,
 			 unsigned long flags,
 			 void *data)
 {
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 55af8c5..3a6e873 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -485,7 +485,7 @@
 			return -EACCES;
 	}
 
-	vma->vm_flags |= VM_RESERVED;
+	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 	vma->vm_ops = &sel_mmap_policy_ops;
 
 	return 0;
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 2874c73..38be92c 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -408,8 +408,8 @@
  * Returns 0 if current can write the floor of the filesystem
  * being mounted on, an error code otherwise.
  */
-static int smack_sb_mount(char *dev_name, struct path *path,
-			  char *type, unsigned long flags, void *data)
+static int smack_sb_mount(const char *dev_name, struct path *path,
+			  const char *type, unsigned long flags, void *data)
 {
 	struct superblock_smack *sbp = path->dentry->d_sb->s_security;
 	struct smk_audit_info ad;
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index af010b6..d4f166b 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -970,7 +970,7 @@
 			     const u8 index);
 int tomoyo_mkdev_perm(const u8 operation, struct path *path,
 		      const unsigned int mode, unsigned int dev);
-int tomoyo_mount_permission(char *dev_name, struct path *path,
+int tomoyo_mount_permission(const char *dev_name, struct path *path,
 			    const char *type, unsigned long flags,
 			    void *data_page);
 int tomoyo_open_control(const u8 type, struct file *file);
diff --git a/security/tomoyo/mount.c b/security/tomoyo/mount.c
index fe00cdf..390c646 100644
--- a/security/tomoyo/mount.c
+++ b/security/tomoyo/mount.c
@@ -71,7 +71,8 @@
  *
  * Caller holds tomoyo_read_lock().
  */
-static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name,
+static int tomoyo_mount_acl(struct tomoyo_request_info *r,
+			    const char *dev_name,
 			    struct path *dir, const char *type,
 			    unsigned long flags)
 {
@@ -183,7 +184,7 @@
  *
  * Returns 0 on success, negative value otherwise.
  */
-int tomoyo_mount_permission(char *dev_name, struct path *path,
+int tomoyo_mount_permission(const char *dev_name, struct path *path,
 			    const char *type, unsigned long flags,
 			    void *data_page)
 {
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c
index d88eb3a..a2ee362 100644
--- a/security/tomoyo/tomoyo.c
+++ b/security/tomoyo/tomoyo.c
@@ -408,8 +408,8 @@
  *
  * Returns 0 on success, negative value otherwise.
  */
-static int tomoyo_sb_mount(char *dev_name, struct path *path,
-			   char *type, unsigned long flags, void *data)
+static int tomoyo_sb_mount(const char *dev_name, struct path *path,
+			   const char *type, unsigned long flags, void *data)
 {
 	return tomoyo_mount_permission(dev_name, path, type, flags, data);
 }
diff --git a/security/tomoyo/util.c b/security/tomoyo/util.c
index 867558c..2952ba5 100644
--- a/security/tomoyo/util.c
+++ b/security/tomoyo/util.c
@@ -949,18 +949,13 @@
 const char *tomoyo_get_exe(void)
 {
 	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma;
 	const char *cp = NULL;
 
 	if (!mm)
 		return NULL;
 	down_read(&mm->mmap_sem);
-	for (vma = mm->mmap; vma; vma = vma->vm_next) {
-		if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) {
-			cp = tomoyo_realpath_from_path(&vma->vm_file->f_path);
-			break;
-		}
-	}
+	if (mm->exe_file)
+		cp = tomoyo_realpath_from_path(&mm->exe_file->f_path);
 	up_read(&mm->mmap_sem);
 	return cp;
 }
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
index eb60cb8..c40ae57 100644
--- a/sound/core/compress_offload.c
+++ b/sound/core/compress_offload.c
@@ -425,6 +425,26 @@
 	return 0;
 }
 
+static int snd_compress_check_input(struct snd_compr_params *params)
+{
+	/* first let's check the buffer parameter's */
+	if (params->buffer.fragment_size == 0 ||
+			params->buffer.fragments > SIZE_MAX / params->buffer.fragment_size)
+		return -EINVAL;
+
+	/* now codec parameters */
+	if (params->codec.id == 0 || params->codec.id > SND_AUDIOCODEC_MAX)
+		return -EINVAL;
+
+	if (params->codec.ch_in == 0 || params->codec.ch_out == 0)
+		return -EINVAL;
+
+	if (!(params->codec.sample_rate & SNDRV_PCM_RATE_8000_192000))
+		return -EINVAL;
+
+	return 0;
+}
+
 static int
 snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg)
 {
@@ -443,11 +463,17 @@
 			retval = -EFAULT;
 			goto out;
 		}
+
+		retval = snd_compress_check_input(params);
+		if (retval)
+			goto out;
+
 		retval = snd_compr_allocate_buffer(stream, params);
 		if (retval) {
 			retval = -ENOMEM;
 			goto out;
 		}
+
 		retval = stream->ops->set_params(stream, params);
 		if (retval)
 			goto out;
diff --git a/sound/core/control.c b/sound/core/control.c
index 2487a6b..7e86a5b 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -246,6 +246,7 @@
 	kctl.count = ncontrol->count ? ncontrol->count : 1;
 	access = ncontrol->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
 		 (ncontrol->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|
+				      SNDRV_CTL_ELEM_ACCESS_VOLATILE|
 				      SNDRV_CTL_ELEM_ACCESS_INACTIVE|
 				      SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE|
 				      SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND|
diff --git a/sound/core/info.c b/sound/core/info.c
index c1e611c..6b368d2 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -28,7 +28,7 @@
 #include <sound/core.h>
 #include <sound/minors.h>
 #include <sound/info.h>
-#include <sound/version.h>
+#include <linux/utsname.h>
 #include <linux/proc_fs.h>
 #include <linux/mutex.h>
 #include <stdarg.h>
@@ -986,9 +986,8 @@
 static void snd_info_version_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
 {
 	snd_iprintf(buffer,
-		    "Advanced Linux Sound Architecture Driver Version "
-		    CONFIG_SND_VERSION CONFIG_SND_DATE ".\n"
-		   );
+		    "Advanced Linux Sound Architecture Driver Version k%s.\n",
+		    init_utsname()->release);
 }
 
 static int __init snd_info_version_init(void)
diff --git a/sound/core/info_oss.c b/sound/core/info_oss.c
index cf42ab5..83c29db 100644
--- a/sound/core/info_oss.c
+++ b/sound/core/info_oss.c
@@ -26,7 +26,6 @@
 #include <sound/core.h>
 #include <sound/minors.h>
 #include <sound/info.h>
-#include <sound/version.h>
 #include <linux/utsname.h>
 #include <linux/mutex.h>
 
@@ -94,7 +93,7 @@
 static void snd_sndstat_proc_read(struct snd_info_entry *entry,
 				  struct snd_info_buffer *buffer)
 {
-	snd_iprintf(buffer, "Sound Driver:3.8.1a-980706 (ALSA v" CONFIG_SND_VERSION " emulation code)\n");
+	snd_iprintf(buffer, "Sound Driver:3.8.1a-980706 (ALSA emulation code)\n");
 	snd_iprintf(buffer, "Kernel: %s %s %s %s %s\n",
 		    init_utsname()->sysname,
 		    init_utsname()->nodename,
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 18297f7..29f6ded 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -1046,6 +1046,7 @@
 			
 		if (kctl->info(kctl, uinfo)) {
 			up_read(&mixer->card->controls_rwsem);
+			kfree(uinfo);
 			return 0;
 		}
 		strcpy(str, ptr->name);
@@ -1061,6 +1062,7 @@
 				uinfo->value.enumerated.item = slot.capture_item;
 				if (kctl->info(kctl, uinfo)) {
 					up_read(&mixer->card->controls_rwsem);
+					kfree(uinfo);
 					return 0;
 				}
 				if (!strcmp(uinfo->value.enumerated.name, str)) {
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 1a3070b..f299194 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -1105,6 +1105,10 @@
 			break;
 		}
 		snd_unregister_device(devtype, pcm->card, pcm->device);
+		if (pcm->streams[cidx].chmap_kctl) {
+			snd_ctl_remove(pcm->card, pcm->streams[cidx].chmap_kctl);
+			pcm->streams[cidx].chmap_kctl = NULL;
+		}
 	}
  unlock:
 	mutex_unlock(&register_mutex);
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 7ae6719..f42c10a 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -26,6 +26,7 @@
 #include <linux/export.h>
 #include <sound/core.h>
 #include <sound/control.h>
+#include <sound/tlv.h>
 #include <sound/info.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -2302,3 +2303,216 @@
 }
 
 EXPORT_SYMBOL(snd_pcm_lib_readv);
+
+/*
+ * standard channel mapping helpers
+ */
+
+/* default channel maps for multi-channel playbacks, up to 8 channels */
+const struct snd_pcm_chmap_elem snd_pcm_std_chmaps[] = {
+	{ .channels = 1,
+	  .map = { SNDRV_CHMAP_MONO } },
+	{ .channels = 2,
+	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
+	{ .channels = 4,
+	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
+		   SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
+	{ .channels = 6,
+	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
+		   SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
+		   SNDRV_CHMAP_FC, SNDRV_CHMAP_LFE } },
+	{ .channels = 8,
+	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
+		   SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
+		   SNDRV_CHMAP_FC, SNDRV_CHMAP_LFE,
+		   SNDRV_CHMAP_SL, SNDRV_CHMAP_SR } },
+	{ }
+};
+EXPORT_SYMBOL_GPL(snd_pcm_std_chmaps);
+
+/* alternative channel maps with CLFE <-> surround swapped for 6/8 channels */
+const struct snd_pcm_chmap_elem snd_pcm_alt_chmaps[] = {
+	{ .channels = 1,
+	  .map = { SNDRV_CHMAP_MONO } },
+	{ .channels = 2,
+	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
+	{ .channels = 4,
+	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
+		   SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
+	{ .channels = 6,
+	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
+		   SNDRV_CHMAP_FC, SNDRV_CHMAP_LFE,
+		   SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
+	{ .channels = 8,
+	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
+		   SNDRV_CHMAP_FC, SNDRV_CHMAP_LFE,
+		   SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
+		   SNDRV_CHMAP_SL, SNDRV_CHMAP_SR } },
+	{ }
+};
+EXPORT_SYMBOL_GPL(snd_pcm_alt_chmaps);
+
+static bool valid_chmap_channels(const struct snd_pcm_chmap *info, int ch)
+{
+	if (ch > info->max_channels)
+		return false;
+	return !info->channel_mask || (info->channel_mask & (1U << ch));
+}
+
+static int pcm_chmap_ctl_info(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_info *uinfo)
+{
+	struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 0;
+	uinfo->count = info->max_channels;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = SNDRV_CHMAP_LAST;
+	return 0;
+}
+
+/* get callback for channel map ctl element
+ * stores the channel position firstly matching with the current channels
+ */
+static int pcm_chmap_ctl_get(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
+	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
+	struct snd_pcm_substream *substream;
+	const struct snd_pcm_chmap_elem *map;
+
+	if (snd_BUG_ON(!info->chmap))
+		return -EINVAL;
+	substream = snd_pcm_chmap_substream(info, idx);
+	if (!substream)
+		return -ENODEV;
+	memset(ucontrol->value.integer.value, 0,
+	       sizeof(ucontrol->value.integer.value));
+	if (!substream->runtime)
+		return 0; /* no channels set */
+	for (map = info->chmap; map->channels; map++) {
+		int i;
+		if (map->channels == substream->runtime->channels &&
+		    valid_chmap_channels(info, map->channels)) {
+			for (i = 0; i < map->channels; i++)
+				ucontrol->value.integer.value[i] = map->map[i];
+			return 0;
+		}
+	}
+	return -EINVAL;
+}
+
+/* tlv callback for channel map ctl element
+ * expands the pre-defined channel maps in a form of TLV
+ */
+static int pcm_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag,
+			     unsigned int size, unsigned int __user *tlv)
+{
+	struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
+	const struct snd_pcm_chmap_elem *map;
+	unsigned int __user *dst;
+	int c, count = 0;
+
+	if (snd_BUG_ON(!info->chmap))
+		return -EINVAL;
+	if (size < 8)
+		return -ENOMEM;
+	if (put_user(SNDRV_CTL_TLVT_CONTAINER, tlv))
+		return -EFAULT;
+	size -= 8;
+	dst = tlv + 2;
+	for (map = info->chmap; map->channels; map++) {
+		int chs_bytes = map->channels * 4;
+		if (!valid_chmap_channels(info, map->channels))
+			continue;
+		if (size < 8)
+			return -ENOMEM;
+		if (put_user(SNDRV_CTL_TLVT_CHMAP_FIXED, dst) ||
+		    put_user(chs_bytes, dst + 1))
+			return -EFAULT;
+		dst += 2;
+		size -= 8;
+		count += 8;
+		if (size < chs_bytes)
+			return -ENOMEM;
+		size -= chs_bytes;
+		count += chs_bytes;
+		for (c = 0; c < map->channels; c++) {
+			if (put_user(map->map[c], dst))
+				return -EFAULT;
+			dst++;
+		}
+	}
+	if (put_user(count, tlv + 1))
+		return -EFAULT;
+	return 0;
+}
+
+static void pcm_chmap_ctl_private_free(struct snd_kcontrol *kcontrol)
+{
+	struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
+	info->pcm->streams[info->stream].chmap_kctl = NULL;
+	kfree(info);
+}
+
+/**
+ * snd_pcm_add_chmap_ctls - create channel-mapping control elements
+ * @pcm: the assigned PCM instance
+ * @stream: stream direction
+ * @chmap: channel map elements (for query)
+ * @max_channels: the max number of channels for the stream
+ * @private_value: the value passed to each kcontrol's private_value field
+ * @info_ret: store struct snd_pcm_chmap instance if non-NULL
+ *
+ * Create channel-mapping control elements assigned to the given PCM stream(s).
+ * Returns zero if succeed, or a negative error value.
+ */
+int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
+			   const struct snd_pcm_chmap_elem *chmap,
+			   int max_channels,
+			   unsigned long private_value,
+			   struct snd_pcm_chmap **info_ret)
+{
+	struct snd_pcm_chmap *info;
+	struct snd_kcontrol_new knew = {
+		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
+		.access = SNDRV_CTL_ELEM_ACCESS_READ |
+			SNDRV_CTL_ELEM_ACCESS_TLV_READ |
+			SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,
+		.info = pcm_chmap_ctl_info,
+		.get = pcm_chmap_ctl_get,
+		.tlv.c = pcm_chmap_ctl_tlv,
+	};
+	int err;
+
+	info = kzalloc(sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+	info->pcm = pcm;
+	info->stream = stream;
+	info->chmap = chmap;
+	info->max_channels = max_channels;
+	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+		knew.name = "Playback Channel Map";
+	else
+		knew.name = "Capture Channel Map";
+	knew.device = pcm->device;
+	knew.count = pcm->streams[stream].substream_count;
+	knew.private_value = private_value;
+	info->kctl = snd_ctl_new1(&knew, info);
+	if (!info->kctl) {
+		kfree(info);
+		return -ENOMEM;
+	}
+	info->kctl->private_free = pcm_chmap_ctl_private_free;
+	err = snd_ctl_add(pcm->card, info->kctl);
+	if (err < 0)
+		return err;
+	pcm->streams[stream].chmap_kctl = info->kctl;
+	if (info_ret)
+		*info_ret = info;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(snd_pcm_add_chmap_ctls);
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
index 9571313..69e01c4 100644
--- a/sound/core/pcm_memory.c
+++ b/sound/core/pcm_memory.c
@@ -327,32 +327,6 @@
 }
 
 EXPORT_SYMBOL(snd_pcm_sgbuf_ops_page);
-
-/*
- * compute the max chunk size with continuous pages on sg-buffer
- */
-unsigned int snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream,
-					  unsigned int ofs, unsigned int size)
-{
-	struct snd_sg_buf *sg = snd_pcm_substream_sgbuf(substream);
-	unsigned int start, end, pg;
-
-	start = ofs >> PAGE_SHIFT;
-	end = (ofs + size - 1) >> PAGE_SHIFT;
-	/* check page continuity */
-	pg = sg->table[start].addr >> PAGE_SHIFT;
-	for (;;) {
-		start++;
-		if (start > end)
-			break;
-		pg++;
-		if ((sg->table[start].addr >> PAGE_SHIFT) != pg)
-			return (start << PAGE_SHIFT) - ofs;
-	}
-	/* ok, all on continuous pages */
-	return size;
-}
-EXPORT_SYMBOL(snd_pcm_sgbuf_get_chunk_size);
 #endif /* CONFIG_SND_DMA_SGBUF */
 
 /**
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 20554ef..5e12e5b 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -3039,7 +3039,7 @@
 		return -EINVAL;
 	area->vm_ops = &snd_pcm_vm_ops_status;
 	area->vm_private_data = substream;
-	area->vm_flags |= VM_RESERVED;
+	area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 	return 0;
 }
 
@@ -3076,7 +3076,7 @@
 		return -EINVAL;
 	area->vm_ops = &snd_pcm_vm_ops_control;
 	area->vm_private_data = substream;
-	area->vm_flags |= VM_RESERVED;
+	area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 	return 0;
 }
 #else /* ! coherent mmap */
@@ -3170,7 +3170,7 @@
 int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream,
 			     struct vm_area_struct *area)
 {
-	area->vm_flags |= VM_RESERVED;
+	area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 #ifdef ARCH_HAS_DMA_MMAP_COHERENT
 	if (!substream->ops->page &&
 	    substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV)
diff --git a/sound/core/seq/seq_device.c b/sound/core/seq/seq_device.c
index 5cf8d65..60e8fc1 100644
--- a/sound/core/seq/seq_device.c
+++ b/sound/core/seq/seq_device.c
@@ -569,5 +569,7 @@
 EXPORT_SYMBOL(snd_seq_device_new);
 EXPORT_SYMBOL(snd_seq_device_register_driver);
 EXPORT_SYMBOL(snd_seq_device_unregister_driver);
+#ifdef CONFIG_MODULES
 EXPORT_SYMBOL(snd_seq_autoload_lock);
 EXPORT_SYMBOL(snd_seq_autoload_unlock);
+#endif
diff --git a/sound/core/sgbuf.c b/sound/core/sgbuf.c
index d0f0035..0a41850 100644
--- a/sound/core/sgbuf.c
+++ b/sound/core/sgbuf.c
@@ -22,6 +22,7 @@
 #include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
+#include <linux/export.h>
 #include <sound/memalloc.h>
 
 
@@ -136,3 +137,29 @@
 	snd_free_sgbuf_pages(dmab); /* free the table */
 	return NULL;
 }
+
+/*
+ * compute the max chunk size with continuous pages on sg-buffer
+ */
+unsigned int snd_sgbuf_get_chunk_size(struct snd_dma_buffer *dmab,
+				      unsigned int ofs, unsigned int size)
+{
+	struct snd_sg_buf *sg = dmab->private_data;
+	unsigned int start, end, pg;
+
+	start = ofs >> PAGE_SHIFT;
+	end = (ofs + size - 1) >> PAGE_SHIFT;
+	/* check page continuity */
+	pg = sg->table[start].addr >> PAGE_SHIFT;
+	for (;;) {
+		start++;
+		if (start > end)
+			break;
+		pg++;
+		if ((sg->table[start].addr >> PAGE_SHIFT) != pg)
+			return (start << PAGE_SHIFT) - ofs;
+	}
+	/* ok, all on continuous pages */
+	return size;
+}
+EXPORT_SYMBOL(snd_sgbuf_get_chunk_size);
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 28f3559..6439760 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -27,7 +27,6 @@
 #include <sound/core.h>
 #include <sound/minors.h>
 #include <sound/info.h>
-#include <sound/version.h>
 #include <sound/control.h>
 #include <sound/initval.h>
 #include <linux/kmod.h>
@@ -468,7 +467,7 @@
 	}
 	snd_info_minor_register();
 #ifndef MODULE
-	printk(KERN_INFO "Advanced Linux Sound Architecture Driver Version " CONFIG_SND_VERSION CONFIG_SND_DATE ".\n");
+	printk(KERN_INFO "Advanced Linux Sound Architecture Driver Initialized.\n");
 #endif
 	return 0;
 }
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c
index 5a34355..0fe6d64 100644
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -120,6 +120,7 @@
 	unsigned int last_drift;
 	unsigned long last_jiffies;
 	struct timer_list timer;
+	spinlock_t timer_lock;
 };
 
 static struct platform_device *devices[SNDRV_CARDS];
@@ -170,6 +171,7 @@
 	unsigned long tick;
 	unsigned int rate_shift = get_rate_shift(dpcm);
 
+	spin_lock(&dpcm->timer_lock);
 	if (rate_shift != dpcm->pcm_rate_shift) {
 		dpcm->pcm_rate_shift = rate_shift;
 		dpcm->period_size_frac = frac_pos(dpcm, dpcm->pcm_period_size);
@@ -182,12 +184,15 @@
 	tick = (tick + dpcm->pcm_bps - 1) / dpcm->pcm_bps;
 	dpcm->timer.expires = jiffies + tick;
 	add_timer(&dpcm->timer);
+	spin_unlock(&dpcm->timer_lock);
 }
 
 static inline void loopback_timer_stop(struct loopback_pcm *dpcm)
 {
+	spin_lock(&dpcm->timer_lock);
 	del_timer(&dpcm->timer);
 	dpcm->timer.expires = 0;
+	spin_unlock(&dpcm->timer_lock);
 }
 
 #define CABLE_VALID_PLAYBACK	(1 << SNDRV_PCM_STREAM_PLAYBACK)
@@ -667,6 +672,7 @@
 	dpcm->substream = substream;
 	setup_timer(&dpcm->timer, loopback_timer_function,
 		    (unsigned long)dpcm);
+	spin_lock_init(&dpcm->timer_lock);
 
 	cable = loopback->cables[substream->number][dev];
 	if (!cable) {
diff --git a/sound/drivers/opl3/opl3_midi.c b/sound/drivers/opl3/opl3_midi.c
index 2bfe4bc..0c796bc 100644
--- a/sound/drivers/opl3/opl3_midi.c
+++ b/sound/drivers/opl3/opl3_midi.c
@@ -163,7 +163,7 @@
 	struct best *bp;
 
 	for (i = 0; i < END; i++) {
-		best[i].time = (unsigned int)(-1); /* XXX MAX_?INT really */;
+		best[i].time = (unsigned int)(-1); /* XXX MAX_?INT really */
 		best[i].voice = -1;
 	}
 
diff --git a/sound/drivers/opl4/opl4_synth.c b/sound/drivers/opl4/opl4_synth.c
index 49b9e24..4b91adc 100644
--- a/sound/drivers/opl4/opl4_synth.c
+++ b/sound/drivers/opl4/opl4_synth.c
@@ -504,8 +504,7 @@
 	spin_lock_irqsave(&opl4->reg_lock, flags);
 	for (i = 0; i < voices; i++) {
 		voice[i] = snd_opl4_get_voice(opl4);
-		list_del(&voice[i]->list);
-		list_add_tail(&voice[i]->list, &opl4->on_voices);
+		list_move_tail(&voice[i]->list, &opl4->on_voices);
 		voice[i]->chan = chan;
 		voice[i]->note = note;
 		voice[i]->velocity = vel & 0x7f;
@@ -555,8 +554,7 @@
 
 static void snd_opl4_voice_off(struct snd_opl4 *opl4, struct opl4_voice *voice)
 {
-	list_del(&voice->list);
-	list_add_tail(&voice->list, &opl4->off_voices);
+	list_move_tail(&voice->list, &opl4->off_voices);
 
 	voice->reg_misc &= ~OPL4_KEY_ON_BIT;
 	snd_opl4_write(opl4, OPL4_REG_MISC + voice->number, voice->reg_misc);
@@ -571,8 +569,7 @@
 
 static void snd_opl4_terminate_voice(struct snd_opl4 *opl4, struct opl4_voice *voice)
 {
-	list_del(&voice->list);
-	list_add_tail(&voice->list, &opl4->off_voices);
+	list_move_tail(&voice->list, &opl4->off_voices);
 
 	voice->reg_misc = (voice->reg_misc & ~OPL4_KEY_ON_BIT) | OPL4_DAMP_BIT;
 	snd_opl4_write(opl4, OPL4_REG_MISC + voice->number, voice->reg_misc);
diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c
index 5e897b2..deed5ef 100644
--- a/sound/drivers/vx/vx_pcm.c
+++ b/sound/drivers/vx/vx_pcm.c
@@ -184,7 +184,7 @@
 	default : 
 		snd_BUG();
 		return -EINVAL;
-        };
+	}
 
 	return vx_set_stream_format(chip, pipe, header);
 }
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index 52064cf..a38d964 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -117,6 +117,18 @@
 	  To compile this driver as a module, choose M here: the module
 	  will be called snd-azt2320.
 
+config SND_CMI8328
+	tristate "C-Media CMI8328"
+	select SND_WSS_LIB
+	select SND_OPL3_LIB
+	select SND_MPU401_UART
+	help
+	  Say Y here to include support for soundcards based on the
+	  C-Media CMI8328 chip.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd-cmi8328.
+
 config SND_CMI8330
 	tristate "C-Media CMI8330"
 	select SND_WSS_LIB
diff --git a/sound/isa/Makefile b/sound/isa/Makefile
index 8d781e4..9a15f14 100644
--- a/sound/isa/Makefile
+++ b/sound/isa/Makefile
@@ -6,6 +6,7 @@
 snd-adlib-objs := adlib.o
 snd-als100-objs := als100.o
 snd-azt2320-objs := azt2320.o
+snd-cmi8328-objs := cmi8328.o
 snd-cmi8330-objs := cmi8330.o
 snd-es18xx-objs := es18xx.o
 snd-opl3sa2-objs := opl3sa2.o
@@ -16,6 +17,7 @@
 obj-$(CONFIG_SND_ADLIB) += snd-adlib.o
 obj-$(CONFIG_SND_ALS100) += snd-als100.o
 obj-$(CONFIG_SND_AZT2320) += snd-azt2320.o
+obj-$(CONFIG_SND_CMI8328) += snd-cmi8328.o
 obj-$(CONFIG_SND_CMI8330) += snd-cmi8330.o
 obj-$(CONFIG_SND_ES18XX) += snd-es18xx.o
 obj-$(CONFIG_SND_OPL3SA2) += snd-opl3sa2.o
diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c
index 94b83b6..2c2f829 100644
--- a/sound/isa/ad1816a/ad1816a.c
+++ b/sound/isa/ad1816a/ad1816a.c
@@ -63,11 +63,6 @@
 module_param_array(clockfreq, int, NULL, 0444);
 MODULE_PARM_DESC(clockfreq, "Clock frequency for ad1816a driver (default = 0).");
 
-struct snd_card_ad1816a {
-	struct pnp_dev *dev;
-	struct pnp_dev *devmpu;
-};
-
 static struct pnp_card_device_id snd_ad1816a_pnpids[] = {
 	/* Analog Devices AD1815 */
 	{ .id = "ADS7150", .devs = { { .id = "ADS7150" }, { .id = "ADS7151" } } },
@@ -99,25 +94,16 @@
 #define	DRIVER_NAME	"snd-card-ad1816a"
 
 
-static int __devinit snd_card_ad1816a_pnp(int dev, struct snd_card_ad1816a *acard,
-					  struct pnp_card_link *card,
+static int __devinit snd_card_ad1816a_pnp(int dev, struct pnp_card_link *card,
 					  const struct pnp_card_device_id *id)
 {
 	struct pnp_dev *pdev;
 	int err;
 
-	acard->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
-	if (acard->dev == NULL)
+	pdev = pnp_request_card_device(card, id->devs[0].id, NULL);
+	if (pdev == NULL)
 		return -EBUSY;
 
-	acard->devmpu = pnp_request_card_device(card, id->devs[1].id, NULL);
-	if (acard->devmpu == NULL) {
-		mpu_port[dev] = -1;
-		snd_printk(KERN_WARNING PFX "MPU401 device busy, skipping.\n");
-	}
-
-	pdev = acard->dev;
-
 	err = pnp_activate_dev(pdev);
 	if (err < 0) {
 		printk(KERN_ERR PFX "AUDIO PnP configure failure\n");
@@ -130,16 +116,17 @@
 	dma2[dev] = pnp_dma(pdev, 1);
 	irq[dev] = pnp_irq(pdev, 0);
 
-	if (acard->devmpu == NULL)
+	pdev = pnp_request_card_device(card, id->devs[1].id, NULL);
+	if (pdev == NULL) {
+		mpu_port[dev] = -1;
+		snd_printk(KERN_WARNING PFX "MPU401 device busy, skipping.\n");
 		return 0;
-
-	pdev = acard->devmpu;
+	}
 
 	err = pnp_activate_dev(pdev);
 	if (err < 0) {
 		printk(KERN_ERR PFX "MPU401 PnP configure failure\n");
 		mpu_port[dev] = -1;
-		acard->devmpu = NULL;
 	} else {
 		mpu_port[dev] = pnp_port_start(pdev, 0);
 		mpu_irq[dev] = pnp_irq(pdev, 0);
@@ -153,18 +140,17 @@
 {
 	int error;
 	struct snd_card *card;
-	struct snd_card_ad1816a *acard;
 	struct snd_ad1816a *chip;
 	struct snd_opl3 *opl3;
 	struct snd_timer *timer;
 
 	error = snd_card_create(index[dev], id[dev], THIS_MODULE,
-				sizeof(struct snd_card_ad1816a), &card);
+				sizeof(struct snd_ad1816a), &card);
 	if (error < 0)
 		return error;
-	acard = card->private_data;
+	chip = card->private_data;
 
-	if ((error = snd_card_ad1816a_pnp(dev, acard, pcard, pid))) {
+	if ((error = snd_card_ad1816a_pnp(dev, pcard, pid))) {
 		snd_card_free(card);
 		return error;
 	}
@@ -174,7 +160,7 @@
 					irq[dev],
 					dma1[dev],
 					dma2[dev],
-					&chip)) < 0) {
+					chip)) < 0) {
 		snd_card_free(card);
 		return error;
 	}
@@ -258,13 +244,37 @@
 	pnp_set_card_drvdata(pcard, NULL);
 }
 
+#ifdef CONFIG_PM
+static int snd_ad1816a_pnp_suspend(struct pnp_card_link *pcard,
+				   pm_message_t state)
+{
+	struct snd_card *card = pnp_get_card_drvdata(pcard);
+
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+	snd_ad1816a_suspend(card->private_data);
+	return 0;
+}
+
+static int snd_ad1816a_pnp_resume(struct pnp_card_link *pcard)
+{
+	struct snd_card *card = pnp_get_card_drvdata(pcard);
+
+	snd_ad1816a_resume(card->private_data);
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+	return 0;
+}
+#endif
+
 static struct pnp_card_driver ad1816a_pnpc_driver = {
 	.flags		= PNP_DRIVER_RES_DISABLE,
 	.name		= "ad1816a",
 	.id_table	= snd_ad1816a_pnpids,
 	.probe		= snd_ad1816a_pnp_detect,
 	.remove		= __devexit_p(snd_ad1816a_pnp_remove),
-	/* FIXME: suspend/resume */
+#ifdef CONFIG_PM
+	.suspend	= snd_ad1816a_pnp_suspend,
+	.resume		= snd_ad1816a_pnp_resume,
+#endif
 };
 
 static int __init alsa_card_ad1816a_init(void)
diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c
index 177eed3..db64df6 100644
--- a/sound/isa/ad1816a/ad1816a_lib.c
+++ b/sound/isa/ad1816a/ad1816a_lib.c
@@ -491,7 +491,7 @@
 }
 
 
-static void __devinit snd_ad1816a_init(struct snd_ad1816a *chip)
+static void snd_ad1816a_init(struct snd_ad1816a *chip)
 {
 	unsigned long flags;
 
@@ -511,6 +511,32 @@
 	spin_unlock_irqrestore(&chip->lock, flags);
 }
 
+#ifdef CONFIG_PM
+void snd_ad1816a_suspend(struct snd_ad1816a *chip)
+{
+	int reg;
+	unsigned long flags;
+
+	snd_pcm_suspend_all(chip->pcm);
+	spin_lock_irqsave(&chip->lock, flags);
+	for (reg = 0; reg < 48; reg++)
+		chip->image[reg] = snd_ad1816a_read(chip, reg);
+	spin_unlock_irqrestore(&chip->lock, flags);
+}
+
+void snd_ad1816a_resume(struct snd_ad1816a *chip)
+{
+	int reg;
+	unsigned long flags;
+
+	snd_ad1816a_init(chip);
+	spin_lock_irqsave(&chip->lock, flags);
+	for (reg = 0; reg < 48; reg++)
+		snd_ad1816a_write(chip, reg, chip->image[reg]);
+	spin_unlock_irqrestore(&chip->lock, flags);
+}
+#endif
+
 static int __devinit snd_ad1816a_probe(struct snd_ad1816a *chip)
 {
 	unsigned long flags;
@@ -548,7 +574,6 @@
 		snd_dma_disable(chip->dma2);
 		free_dma(chip->dma2);
 	}
-	kfree(chip);
 	return 0;
 }
 
@@ -573,19 +598,13 @@
 
 int __devinit snd_ad1816a_create(struct snd_card *card,
 				 unsigned long port, int irq, int dma1, int dma2,
-				 struct snd_ad1816a **rchip)
+				 struct snd_ad1816a *chip)
 {
         static struct snd_device_ops ops = {
 		.dev_free =	snd_ad1816a_dev_free,
 	};
 	int error;
-	struct snd_ad1816a *chip;
 
-	*rchip = NULL;
-
-	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
-	if (chip == NULL)
-		return -ENOMEM;
 	chip->irq = -1;
 	chip->dma1 = -1;
 	chip->dma2 = -1;
@@ -631,7 +650,6 @@
 		return error;
 	}
 
-	*rchip = chip;
 	return 0;
 }
 
diff --git a/sound/isa/cmi8328.c b/sound/isa/cmi8328.c
new file mode 100644
index 0000000..bde6013
--- /dev/null
+++ b/sound/isa/cmi8328.c
@@ -0,0 +1,483 @@
+/*
+ * Driver for C-Media CMI8328-based soundcards, such as AudioExcel AV500
+ * Copyright (c) 2012 Ondrej Zary
+ *
+ * AudioExcel AV500 card consists of:
+ *  - CMI8328 - main chip (SB Pro emulation, gameport, OPL3, MPU401, CD-ROM)
+ *  - CS4231A - WSS codec
+ *  - Dream SAM9233+GMS950400+RAM+ROM: Wavetable MIDI, connected to MPU401
+ */
+
+#include <linux/init.h>
+#include <linux/isa.h>
+#include <linux/module.h>
+#include <linux/gameport.h>
+#include <asm/dma.h>
+#include <sound/core.h>
+#include <sound/wss.h>
+#include <sound/opl3.h>
+#include <sound/mpu401.h>
+#define SNDRV_LEGACY_FIND_FREE_IOPORT
+#define SNDRV_LEGACY_FIND_FREE_IRQ
+#define SNDRV_LEGACY_FIND_FREE_DMA
+#include <sound/initval.h>
+
+MODULE_AUTHOR("Ondrej Zary <linux@rainbow-software.org>");
+MODULE_DESCRIPTION("C-Media CMI8328");
+MODULE_LICENSE("GPL");
+
+#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE)
+#define SUPPORT_JOYSTICK 1
+#endif
+
+/* I/O port is configured by jumpers on the card to one of these */
+static int cmi8328_ports[] = { 0x530, 0xe80, 0xf40, 0x604 };
+#define CMI8328_MAX	ARRAY_SIZE(cmi8328_ports)
+
+static int index[CMI8328_MAX] =     {[0 ... (CMI8328_MAX-1)] = -1};
+static char *id[CMI8328_MAX] =      {[0 ... (CMI8328_MAX-1)] = NULL};
+static long port[CMI8328_MAX] =     {[0 ... (CMI8328_MAX-1)] = SNDRV_AUTO_PORT};
+static int irq[CMI8328_MAX] =       {[0 ... (CMI8328_MAX-1)] = SNDRV_AUTO_IRQ};
+static int dma1[CMI8328_MAX] =      {[0 ... (CMI8328_MAX-1)] = SNDRV_AUTO_DMA};
+static int dma2[CMI8328_MAX] =      {[0 ... (CMI8328_MAX-1)] = SNDRV_AUTO_DMA};
+static long mpuport[CMI8328_MAX] =  {[0 ... (CMI8328_MAX-1)] = SNDRV_AUTO_PORT};
+static int mpuirq[CMI8328_MAX] =    {[0 ... (CMI8328_MAX-1)] = SNDRV_AUTO_IRQ};
+#ifdef SUPPORT_JOYSTICK
+static bool gameport[CMI8328_MAX] = {[0 ... (CMI8328_MAX-1)] = true};
+#endif
+
+module_param_array(index, int, NULL, 0444);
+MODULE_PARM_DESC(index, "Index value for CMI8328 soundcard.");
+module_param_array(id, charp, NULL, 0444);
+MODULE_PARM_DESC(id, "ID string for CMI8328 soundcard.");
+
+module_param_array(port, long, NULL, 0444);
+MODULE_PARM_DESC(port, "Port # for CMI8328 driver.");
+module_param_array(irq, int, NULL, 0444);
+MODULE_PARM_DESC(irq, "IRQ # for CMI8328 driver.");
+module_param_array(dma1, int, NULL, 0444);
+MODULE_PARM_DESC(dma1, "DMA1 for CMI8328 driver.");
+module_param_array(dma2, int, NULL, 0444);
+MODULE_PARM_DESC(dma2, "DMA2 for CMI8328 driver.");
+
+module_param_array(mpuport, long, NULL, 0444);
+MODULE_PARM_DESC(mpuport, "MPU-401 port # for CMI8328 driver.");
+module_param_array(mpuirq, int, NULL, 0444);
+MODULE_PARM_DESC(mpuirq, "IRQ # for CMI8328 MPU-401 port.");
+#ifdef SUPPORT_JOYSTICK
+module_param_array(gameport, bool, NULL, 0444);
+MODULE_PARM_DESC(gameport, "Enable gameport.");
+#endif
+
+struct snd_cmi8328 {
+	u16 port;
+	u8 cfg[3];
+	u8 wss_cfg;
+	struct snd_card *card;
+	struct snd_wss *wss;
+#ifdef SUPPORT_JOYSTICK
+	struct gameport *gameport;
+#endif
+};
+
+/* CMI8328 configuration registers */
+#define CFG1 0x61
+#define CFG1_SB_DISABLE	(1 << 0)
+#define CFG1_GAMEPORT	(1 << 1)
+/*
+ * bit 0:    SB: 0=enabled, 1=disabled
+ * bit 1:    gameport: 0=disabled, 1=enabled
+ * bits 2-4: SB IRQ: 001=3, 010=5, 011=7, 100=9, 101=10, 110=11
+ * bits 5-6: SB DMA: 00=disabled (when SB disabled), 01=DMA0, 10=DMA1, 11=DMA3
+ * bit 7:    SB port: 0=0x220, 1=0x240
+ */
+#define CFG2 0x62
+#define CFG2_MPU_ENABLE (1 << 2)
+/*
+ * bits 0-1: CD-ROM mode: 00=disabled, 01=Panasonic, 10=Sony/Mitsumi/Wearnes,
+			  11=IDE
+ * bit 2:    MPU401: 0=disabled, 1=enabled
+ * bits 3-4: MPU401 IRQ: 00=3, 01=5, 10=7, 11=9,
+ * bits 5-7: MPU401 port: 000=0x300, 001=0x310, 010=0x320, 011=0x330, 100=0x332,
+			  101=0x334, 110=0x336
+ */
+#define CFG3 0x63
+/*
+ * bits 0-2: CD-ROM IRQ: 000=disabled, 001=3, 010=5, 011=7, 100=9, 101=10,
+			 110=11
+ * bits 3-4: CD-ROM DMA: 00=disabled, 01=DMA0, 10=DMA1, 11=DMA3
+ * bits 5-7: CD-ROM port: 000=0x300, 001=0x310, 010=0x320, 011=0x330, 100=0x340,
+			  101=0x350, 110=0x360, 111=0x370
+ */
+
+static u8 snd_cmi8328_cfg_read(u16 port, u8 reg)
+{
+	outb(0x43, port + 3);
+	outb(0x21, port + 3);
+	outb(reg, port + 3);
+	return inb(port);
+}
+
+static void snd_cmi8328_cfg_write(u16 port, u8 reg, u8 val)
+{
+	outb(0x43, port + 3);
+	outb(0x21, port + 3);
+	outb(reg, port + 3);
+	outb(val, port + 3);	/* yes, value goes to the same port as index */
+}
+
+static void snd_cmi8328_cfg_save(u16 port, u8 cfg[])
+{
+	cfg[0] = snd_cmi8328_cfg_read(port, CFG1);
+	cfg[1] = snd_cmi8328_cfg_read(port, CFG2);
+	cfg[2] = snd_cmi8328_cfg_read(port, CFG3);
+}
+
+static void snd_cmi8328_cfg_restore(u16 port, u8 cfg[])
+{
+	snd_cmi8328_cfg_write(port, CFG1, cfg[0]);
+	snd_cmi8328_cfg_write(port, CFG2, cfg[1]);
+	snd_cmi8328_cfg_write(port, CFG3, cfg[2]);
+}
+
+static int __devinit snd_cmi8328_mixer(struct snd_wss *chip)
+{
+	struct snd_card *card;
+	struct snd_ctl_elem_id id1, id2;
+	int err;
+
+	card = chip->card;
+
+	memset(&id1, 0, sizeof(id1));
+	memset(&id2, 0, sizeof(id2));
+	id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+	/* rename AUX0 switch to CD */
+	strcpy(id1.name, "Aux Playback Switch");
+	strcpy(id2.name, "CD Playback Switch");
+	err = snd_ctl_rename_id(card, &id1, &id2);
+	if (err < 0) {
+		snd_printk(KERN_ERR "error renaming control\n");
+		return err;
+	}
+	/* rename AUX0 volume to CD */
+	strcpy(id1.name, "Aux Playback Volume");
+	strcpy(id2.name, "CD Playback Volume");
+	err = snd_ctl_rename_id(card, &id1, &id2);
+	if (err < 0) {
+		snd_printk(KERN_ERR "error renaming control\n");
+		return err;
+	}
+	/* rename AUX1 switch to Synth */
+	strcpy(id1.name, "Aux Playback Switch");
+	id1.index = 1;
+	strcpy(id2.name, "Synth Playback Switch");
+	err = snd_ctl_rename_id(card, &id1, &id2);
+	if (err < 0) {
+		snd_printk(KERN_ERR "error renaming control\n");
+		return err;
+	}
+	/* rename AUX1 volume to Synth */
+	strcpy(id1.name, "Aux Playback Volume");
+	id1.index = 1;
+	strcpy(id2.name, "Synth Playback Volume");
+	err = snd_ctl_rename_id(card, &id1, &id2);
+	if (err < 0) {
+		snd_printk(KERN_ERR "error renaming control\n");
+		return err;
+	}
+
+	return 0;
+}
+
+/* find index of an item in "-1"-ended array */
+int array_find(int array[], int item)
+{
+	int i;
+
+	for (i = 0; array[i] != -1; i++)
+		if (array[i] == item)
+			return i;
+
+	return -1;
+}
+/* the same for long */
+int array_find_l(long array[], long item)
+{
+	int i;
+
+	for (i = 0; array[i] != -1; i++)
+		if (array[i] == item)
+			return i;
+
+	return -1;
+}
+
+static int __devinit snd_cmi8328_probe(struct device *pdev, unsigned int ndev)
+{
+	struct snd_card *card;
+	struct snd_opl3 *opl3;
+	struct snd_cmi8328 *cmi;
+#ifdef SUPPORT_JOYSTICK
+	struct resource *res;
+#endif
+	int err, pos;
+	static long mpu_ports[] = { 0x330, 0x300, 0x310, 0x320, 0x332, 0x334,
+				   0x336, -1 };
+	static u8 mpu_port_bits[] = { 3, 0, 1, 2, 4, 5, 6 };
+	static int mpu_irqs[] = { 9, 7, 5, 3, -1 };
+	static u8 mpu_irq_bits[] = { 3, 2, 1, 0 };
+	static int irqs[] = { 9, 10, 11, 7, -1 };
+	static u8 irq_bits[] = { 2, 3, 4, 1 };
+	static int dma1s[] = { 3, 1, 0, -1 };
+	static u8 dma_bits[] = { 3, 2, 1 };
+	static int dma2s[][2] = { {1, -1}, {0, -1}, {-1, -1}, {0, -1} };
+	u16 port = cmi8328_ports[ndev];
+	u8 val;
+
+	/* 0xff is invalid configuration (but settable - hope it isn't set) */
+	if (snd_cmi8328_cfg_read(port, CFG1) == 0xff)
+		return -ENODEV;
+	/* the SB disable bit must NEVER EVER be cleared or the WSS dies */
+	snd_cmi8328_cfg_write(port, CFG1, CFG1_SB_DISABLE);
+	if (snd_cmi8328_cfg_read(port, CFG1) != CFG1_SB_DISABLE)
+		return -ENODEV;
+	/* disable everything first */
+	snd_cmi8328_cfg_write(port, CFG2, 0);	/* disable CDROM and MPU401 */
+	snd_cmi8328_cfg_write(port, CFG3, 0);	/* disable CDROM IRQ and DMA */
+
+	if (irq[ndev] == SNDRV_AUTO_IRQ) {
+		irq[ndev] = snd_legacy_find_free_irq(irqs);
+		if (irq[ndev] < 0) {
+			snd_printk(KERN_ERR "unable to find a free IRQ\n");
+			return -EBUSY;
+		}
+	}
+	if (dma1[ndev] == SNDRV_AUTO_DMA) {
+		dma1[ndev] = snd_legacy_find_free_dma(dma1s);
+		if (dma1[ndev] < 0) {
+			snd_printk(KERN_ERR "unable to find a free DMA1\n");
+			return -EBUSY;
+		}
+	}
+	if (dma2[ndev] == SNDRV_AUTO_DMA) {
+		dma2[ndev] = snd_legacy_find_free_dma(dma2s[dma1[ndev] % 4]);
+		if (dma2[ndev] < 0) {
+			snd_printk(KERN_WARNING "unable to find a free DMA2, full-duplex will not work\n");
+			dma2[ndev] = -1;
+		}
+	}
+	/* configure WSS IRQ... */
+	pos = array_find(irqs, irq[ndev]);
+	if (pos < 0) {
+		snd_printk(KERN_ERR "invalid IRQ %d\n", irq[ndev]);
+		return -EINVAL;
+	}
+	val = irq_bits[pos] << 3;
+	/* ...and DMA... */
+	pos = array_find(dma1s, dma1[ndev]);
+	if (pos < 0) {
+		snd_printk(KERN_ERR "invalid DMA1 %d\n", dma1[ndev]);
+		return -EINVAL;
+	}
+	val |= dma_bits[pos];
+	/* ...and DMA2 */
+	if (dma2[ndev] >= 0 && dma1[ndev] != dma2[ndev]) {
+		pos = array_find(dma2s[dma1[ndev]], dma2[ndev]);
+		if (pos < 0) {
+			snd_printk(KERN_ERR "invalid DMA2 %d\n", dma2[ndev]);
+			return -EINVAL;
+		}
+		val |= 0x04; /* enable separate capture DMA */
+	}
+	outb(val, port);
+
+	err = snd_card_create(index[ndev], id[ndev], THIS_MODULE,
+				sizeof(struct snd_cmi8328), &card);
+	if (err < 0)
+		return err;
+	cmi = card->private_data;
+	cmi->card = card;
+	cmi->port = port;
+	cmi->wss_cfg = val;
+	snd_card_set_dev(card, pdev);
+
+	err = snd_wss_create(card, port + 4, -1, irq[ndev], dma1[ndev],
+			dma2[ndev], WSS_HW_DETECT, 0, &cmi->wss);
+	if (err < 0)
+		goto error;
+
+	err = snd_wss_pcm(cmi->wss, 0, NULL);
+	if (err < 0)
+		goto error;
+
+	err = snd_wss_mixer(cmi->wss);
+	if (err < 0)
+		goto error;
+	err = snd_cmi8328_mixer(cmi->wss);
+	if (err < 0)
+		goto error;
+
+	if (snd_wss_timer(cmi->wss, 0, NULL) < 0)
+		snd_printk(KERN_WARNING "error initializing WSS timer\n");
+
+	if (mpuport[ndev] == SNDRV_AUTO_PORT) {
+		mpuport[ndev] = snd_legacy_find_free_ioport(mpu_ports, 2);
+		if (mpuport[ndev] < 0)
+			snd_printk(KERN_ERR "unable to find a free MPU401 port\n");
+	}
+	if (mpuirq[ndev] == SNDRV_AUTO_IRQ) {
+		mpuirq[ndev] = snd_legacy_find_free_irq(mpu_irqs);
+		if (mpuirq[ndev] < 0)
+			snd_printk(KERN_ERR "unable to find a free MPU401 IRQ\n");
+	}
+	/* enable and configure MPU401 */
+	if (mpuport[ndev] > 0 && mpuirq[ndev] > 0) {
+		val = CFG2_MPU_ENABLE;
+		pos = array_find_l(mpu_ports, mpuport[ndev]);
+		if (pos < 0)
+			snd_printk(KERN_WARNING "invalid MPU401 port 0x%lx\n",
+								mpuport[ndev]);
+		else {
+			val |= mpu_port_bits[pos] << 5;
+			pos = array_find(mpu_irqs, mpuirq[ndev]);
+			if (pos < 0)
+				snd_printk(KERN_WARNING "invalid MPU401 IRQ %d\n",
+								mpuirq[ndev]);
+			else {
+				val |= mpu_irq_bits[pos] << 3;
+				snd_cmi8328_cfg_write(port, CFG2, val);
+				if (snd_mpu401_uart_new(card, 0,
+						MPU401_HW_MPU401, mpuport[ndev],
+						0, mpuirq[ndev], NULL) < 0)
+					snd_printk(KERN_ERR "error initializing MPU401\n");
+			}
+		}
+	}
+	/* OPL3 is hardwired to 0x388 and cannot be disabled */
+	if (snd_opl3_create(card, 0x388, 0x38a, OPL3_HW_AUTO, 0, &opl3) < 0)
+		snd_printk(KERN_ERR "error initializing OPL3\n");
+	else
+		if (snd_opl3_hwdep_new(opl3, 0, 1, NULL) < 0)
+			snd_printk(KERN_WARNING "error initializing OPL3 hwdep\n");
+
+	strcpy(card->driver, "CMI8328");
+	strcpy(card->shortname, "C-Media CMI8328");
+	sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d,%d",
+		card->shortname, cmi->wss->port, irq[ndev], dma1[ndev],
+		(dma2[ndev] >= 0) ? dma2[ndev] : dma1[ndev]);
+
+	dev_set_drvdata(pdev, card);
+	err = snd_card_register(card);
+	if (err < 0)
+		goto error;
+#ifdef SUPPORT_JOYSTICK
+	if (!gameport[ndev])
+		return 0;
+	/* gameport is hardwired to 0x200 */
+	res = request_region(0x200, 8, "CMI8328 gameport");
+	if (!res)
+		snd_printk(KERN_WARNING "unable to allocate gameport I/O port\n");
+	else {
+		struct gameport *gp = cmi->gameport = gameport_allocate_port();
+		if (!cmi->gameport)
+			release_and_free_resource(res);
+		else {
+			gameport_set_name(gp, "CMI8328 Gameport");
+			gameport_set_phys(gp, "%s/gameport0", dev_name(pdev));
+			gameport_set_dev_parent(gp, pdev);
+			gp->io = 0x200;
+			gameport_set_port_data(gp, res);
+			/* Enable gameport */
+			snd_cmi8328_cfg_write(port, CFG1,
+					CFG1_SB_DISABLE | CFG1_GAMEPORT);
+			gameport_register_port(gp);
+		}
+	}
+#endif
+	return 0;
+error:
+	snd_card_free(card);
+
+	return err;
+}
+
+static int __devexit snd_cmi8328_remove(struct device *pdev, unsigned int dev)
+{
+	struct snd_card *card = dev_get_drvdata(pdev);
+	struct snd_cmi8328 *cmi = card->private_data;
+
+#ifdef SUPPORT_JOYSTICK
+	if (cmi->gameport) {
+		struct resource *res = gameport_get_port_data(cmi->gameport);
+		gameport_unregister_port(cmi->gameport);
+		release_and_free_resource(res);
+	}
+#endif
+	/* disable everything */
+	snd_cmi8328_cfg_write(cmi->port, CFG1, CFG1_SB_DISABLE);
+	snd_cmi8328_cfg_write(cmi->port, CFG2, 0);
+	snd_cmi8328_cfg_write(cmi->port, CFG3, 0);
+	snd_card_free(card);
+	dev_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int snd_cmi8328_suspend(struct device *pdev, unsigned int n,
+				pm_message_t state)
+{
+	struct snd_card *card = dev_get_drvdata(pdev);
+	struct snd_cmi8328 *cmi;
+
+	if (!card)	/* ignore absent devices */
+		return 0;
+	cmi = card->private_data;
+	snd_cmi8328_cfg_save(cmi->port, cmi->cfg);
+	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+	snd_pcm_suspend_all(cmi->wss->pcm);
+	cmi->wss->suspend(cmi->wss);
+
+	return 0;
+}
+
+static int snd_cmi8328_resume(struct device *pdev, unsigned int n)
+{
+	struct snd_card *card = dev_get_drvdata(pdev);
+	struct snd_cmi8328 *cmi;
+
+	if (!card)	/* ignore absent devices */
+		return 0;
+	cmi = card->private_data;
+	snd_cmi8328_cfg_restore(cmi->port, cmi->cfg);
+	outb(cmi->wss_cfg, cmi->port);
+	cmi->wss->resume(cmi->wss);
+	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+
+	return 0;
+}
+#endif
+
+static struct isa_driver snd_cmi8328_driver = {
+	.probe		= snd_cmi8328_probe,
+	.remove		= __devexit_p(snd_cmi8328_remove),
+#ifdef CONFIG_PM
+	.suspend	= snd_cmi8328_suspend,
+	.resume		= snd_cmi8328_resume,
+#endif
+	.driver		= {
+		.name	= "cmi8328"
+	},
+};
+
+static int __init alsa_card_cmi8328_init(void)
+{
+	return isa_register_driver(&snd_cmi8328_driver, CMI8328_MAX);
+}
+
+static void __exit alsa_card_cmi8328_exit(void)
+{
+	isa_unregister_driver(&snd_cmi8328_driver);
+}
+
+module_init(alsa_card_cmi8328_init)
+module_exit(alsa_card_cmi8328_exit)
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index a76bc8d..3fc8b66 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -443,9 +443,8 @@
 		for (i = 0; i < 8; ++i)
 			iwave[i] = snd_gf1_peek(gus, bank_pos + i);
 #ifdef CONFIG_SND_DEBUG_ROM
-		printk(KERN_DEBUG "ROM at 0x%06x = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", bank_pos,
-		       iwave[0], iwave[1], iwave[2], iwave[3],
-		       iwave[4], iwave[5], iwave[6], iwave[7]);
+		printk(KERN_DEBUG "ROM at 0x%06x = %*phC\n", bank_pos,
+				  8, iwave);
 #endif
 		if (strncmp(iwave, "INTRWAVE", 8))
 			continue;	/* first check */
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index c24594c..3d1afb6 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -37,6 +37,7 @@
 #include <sound/opl4.h>
 #include <sound/control.h>
 #include <sound/info.h>
+#define SNDRV_LEGACY_FIND_FREE_IOPORT
 #define SNDRV_LEGACY_FIND_FREE_IRQ
 #define SNDRV_LEGACY_FIND_FREE_DMA
 #include <sound/initval.h>
@@ -770,20 +771,6 @@
 	return 0;
 }
 
-static long snd_legacy_find_free_ioport(long *port_table, long size)
-{
-	while (*port_table != -1) {
-		struct resource *res;
-		if ((res = request_region(*port_table, size, 
-					  "ALSA test")) != NULL) {
-			release_and_free_resource(res);
-			return *port_table;
-		}
-		port_table++;
-	}
-	return -1;
-}
-
 static int __devinit snd_miro_init(struct snd_miro *chip,
 				   unsigned short hardware)
 {
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index f8fbe22..2899c9f 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -39,6 +39,7 @@
 #ifndef OPTi93X
 #include <sound/opl4.h>
 #endif
+#define SNDRV_LEGACY_FIND_FREE_IOPORT
 #define SNDRV_LEGACY_FIND_FREE_IRQ
 #define SNDRV_LEGACY_FIND_FREE_DMA
 #include <sound/initval.h>
@@ -185,19 +186,6 @@
 	"82C930",	"82C931",	"82C933"
 };
 
-
-static long __devinit snd_legacy_find_free_ioport(long *port_table, long size)
-{
-	while (*port_table != -1) {
-		if (request_region(*port_table, size, "ALSA test")) {
-			release_region(*port_table, size);
-			return *port_table;
-		}
-		port_table++;
-	}
-	return -1;
-}
-
 static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip,
 				      unsigned short hardware)
 {
diff --git a/sound/isa/sb/emu8000.c b/sound/isa/sb/emu8000.c
index 7188787..2aae6a0 100644
--- a/sound/isa/sb/emu8000.c
+++ b/sound/isa/sb/emu8000.c
@@ -417,9 +417,6 @@
 		EMU8000_SMLD_READ(emu); /* discard stale data  */
 		if (EMU8000_SMLD_READ(emu) != UNIQUE_ID2)
 			break; /* no memory at this address */
-
-		detected_size = size;
-
 		snd_emu8000_read_wait(emu);
 
 		/*
@@ -432,6 +429,18 @@
 		if (EMU8000_SMLD_READ(emu) != UNIQUE_ID1)
 			break; /* we must have wrapped around */
 		snd_emu8000_read_wait(emu);
+
+		/* Otherwise, it's valid memory. */
+		detected_size = size + 512 * 1024;
+	}
+
+	/* Distinguish 512 KiB from 0. */
+	if (detected_size == 0) {
+		snd_emu8000_read_wait(emu);
+		EMU8000_SMALR_WRITE(emu, EMU8000_DRAM_OFFSET);
+		EMU8000_SMLD_READ(emu); /* discard stale data  */
+		if (EMU8000_SMLD_READ(emu) == UNIQUE_ID1)
+			detected_size = 512 * 1024;
 	}
 
 	/* wait until FULL bit in SMAxW register is false */
diff --git a/sound/isa/sb/emu8000_callback.c b/sound/isa/sb/emu8000_callback.c
index 344b435..72a9ac5 100644
--- a/sound/isa/sb/emu8000_callback.c
+++ b/sound/isa/sb/emu8000_callback.c
@@ -175,7 +175,7 @@
 	hw = emu->hw;
 
 	for (i = 0; i < END; i++) {
-		best[i].time = (unsigned int)(-1); /* XXX MAX_?INT really */;
+		best[i].time = (unsigned int)(-1); /* XXX MAX_?INT really */
 		best[i].voice = -1;
 	}
 
diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c
index 405f8b6..b1bf8d4 100644
--- a/sound/isa/wavefront/wavefront_synth.c
+++ b/sound/isa/wavefront/wavefront_synth.c
@@ -538,7 +538,7 @@
 	                            /* Note: we leave the upper bits in place */ 
 
 		dst++;
- 	};
+	}
 	return dst;
 };
 
diff --git a/sound/last.c b/sound/last.c
index 7ffc182..43f2228 100644
--- a/sound/last.c
+++ b/sound/last.c
@@ -19,7 +19,6 @@
  *
  */
 
-#define SNDRV_MAIN_OBJECT_FILE
 #include <linux/init.h>
 #include <sound/core.h>
 
diff --git a/sound/oss/audio.c b/sound/oss/audio.c
index 4b958b1..09c932f 100644
--- a/sound/oss/audio.c
+++ b/sound/oss/audio.c
@@ -354,7 +354,7 @@
 
 			if(copy_to_user(&(buf)[p], fixit, l))
 				return -EFAULT;
-		};
+		}
 
 		DMAbuf_rmchars(dev, buf_no, l);
 
diff --git a/sound/oss/opl3.c b/sound/oss/opl3.c
index 407cd67..c5c2440 100644
--- a/sound/oss/opl3.c
+++ b/sound/oss/opl3.c
@@ -1190,7 +1190,7 @@
 
 		for (i = 0; i < 18; i++)
 			pv_map[i].ioaddr = devc->left_io;
-	};
+	}
 	conf_printf2(devc->fm_info.name, ioaddr, 0, -1, -1);
 
 	for (i = 0; i < SBFM_MAXINSTR; i++)
diff --git a/sound/oss/pss.c b/sound/oss/pss.c
index 0f32a56..145e36b 100644
--- a/sound/oss/pss.c
+++ b/sound/oss/pss.c
@@ -359,7 +359,7 @@
 		{
 			/*_____ Send the next byte */
 			outw (*block++, REG (PSS_DATA));
-		};
+		}
 		count++;
 	}
 
diff --git a/sound/oss/sb_ess.c b/sound/oss/sb_ess.c
index 5c773df..c0be085 100644
--- a/sound/oss/sb_ess.c
+++ b/sound/oss/sb_ess.c
@@ -1104,15 +1104,15 @@
 		default:
 			printk (KERN_ERR "Invalid esstype=%d specified\n", devc->sbmo.esstype);
 			return 0;
-		};
+		}
 		if (submodel != -1) {
 			devc->submodel = submodel;
 			sprintf (modelname, "ES%d", devc->sbmo.esstype);
 			chip = modelname;
-		};
+		}
 		if (chip == NULL && (ess_minor & 0x0f) < 8) {
 			chip = "ES688";
-		};
+		}
 #ifdef FKS_TEST
 FKS_test (devc);
 #endif
@@ -1122,7 +1122,7 @@
 		 */
 		if (chip == NULL && devc->sbmo.esstype == ESSTYPE_LIKE20) {
 			chip = "ES1688";
-		};
+		}
 
 		if (chip == NULL) {
 			int type;
@@ -1150,8 +1150,8 @@
 				if ((type & 0x00ff) != ((type >> 8) & 0x00ff)) {
 					printk ("ess_init: Unrecognized %04x\n", type);
 				}
-			};
-		};
+			}
+		}
 #if 0
 		/*
 		 * this one failed:
@@ -1182,10 +1182,10 @@
 				chip = "ES1788";
 				devc->submodel = SUBMDL_ES1788;
 			}
-		};
+		}
 		if (chip == NULL) {
 			chip = "ES1688";
-		};
+		}
 
 	    printk ( KERN_INFO "ESS chip %s %s%s\n"
                , chip
@@ -1293,7 +1293,7 @@
 			default:
 				printk(KERN_ERR "ESS1887: Invalid DMA16 %d\n", dma);
 				return 0;
-			};
+			}
 			ess_chgmixer (devc, 0x78, 0x20, dma16_bits);
 			ess_chgmixer (devc, 0x7d, 0x07, dma_bits);
 		}
@@ -1584,7 +1584,7 @@
 		udelay(20);
 		outb(((unsigned char) (value & 0xff)), MIXER_DATA);
 		udelay(20);
-	};
+	}
 	spin_unlock_irqrestore(&devc->lock, flags);
 }
 
@@ -1761,7 +1761,7 @@
 			ess_chgmixer(devc, 0x7a, 0x18, 0x08);
 			ess_chgmixer(devc, 0x1c, 0x07, 0x07);
 			break;
-		};
+		}
 		/*
 		 * Call set_recmask for proper initialization
 		 */
diff --git a/sound/oss/sb_mixer.c b/sound/oss/sb_mixer.c
index f8f3b7a..acf7586 100644
--- a/sound/oss/sb_mixer.c
+++ b/sound/oss/sb_mixer.c
@@ -410,7 +410,7 @@
 		case MDL_SMW:
 			if (devc->model == MDL_ESS && ess_set_recmask (devc, &devmask)) {
 				break;
-			};
+			}
 			if (devmask != SOUND_MASK_MIC &&
 				devmask != SOUND_MASK_LINE &&
 				devmask != SOUND_MASK_CD)
@@ -666,7 +666,7 @@
 
 	if (devc->model != MDL_ESS || !ess_mixer_reset (devc)) {
 		set_recmask(devc, SOUND_MASK_MIC);
-	};
+	}
 }
 
 int sb_mixer_init(sb_devc * devc, struct module *owner)
diff --git a/sound/oss/sys_timer.c b/sound/oss/sys_timer.c
index 8db6aef..9f03983 100644
--- a/sound/oss/sys_timer.c
+++ b/sound/oss/sys_timer.c
@@ -57,7 +57,7 @@
 		  {
 			  def_tmr.expires = (1) + jiffies;
 			  add_timer(&def_tmr);
-		  };
+		  }
 
 		  if (tmr_running)
 		    {
@@ -103,7 +103,7 @@
 	{
 		def_tmr.expires = (1) + jiffies;
 		add_timer(&def_tmr);
-	};
+	}
 
 	return 0;
 }
diff --git a/sound/oss/uart6850.c b/sound/oss/uart6850.c
index f3f914a..1079133 100644
--- a/sound/oss/uart6850.c
+++ b/sound/oss/uart6850.c
@@ -146,7 +146,7 @@
 	{
 /*		  printk("Midi6850: Midi busy\n");*/
 		  return -EBUSY;
-	};
+	}
 
 	uart6850_cmd(UART_RESET);
 	uart6850_input_loop();
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index a872d0a..66a3bc9 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -2595,6 +2595,21 @@
 			     shared ? 0 : 0x100);
 }
 
+static int alc650_swap_surround_put(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
+	struct snd_pcm_chmap *map = ac97->chmaps[SNDRV_PCM_STREAM_PLAYBACK];
+
+	if (map) {
+		if (ucontrol->value.integer.value[0])
+			map->chmap = snd_pcm_std_chmaps;
+		else
+			map->chmap = snd_pcm_alt_chmaps;
+	}
+	return snd_ac97_put_volsw(kcontrol, ucontrol);
+}
+
 static const struct snd_kcontrol_new snd_ac97_controls_alc650[] = {
 	AC97_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0),
 	AC97_SINGLE("Surround Down Mix", AC97_ALC650_MULTICH, 1, 1, 0),
@@ -2608,7 +2623,14 @@
 	/* 9: Line-In/Surround share */
 	/* 10: Mic/CLFE share */
 	/* 11-13: in IEC958 controls */
-	AC97_SINGLE("Swap Surround Slot", AC97_ALC650_MULTICH, 14, 1, 0),
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Swap Surround Slot",
+		.info = snd_ac97_info_volsw,
+		.get = snd_ac97_get_volsw,
+		.put = alc650_swap_surround_put,
+		.private_value =  AC97_SINGLE_VALUE(AC97_ALC650_MULTICH, 14, 1, 0),
+	},
 #if 0 /* always set in patch_alc650 */
 	AC97_SINGLE("IEC958 Input Clock Enable", AC97_ALC650_CLOCK, 0, 1, 0),
 	AC97_SINGLE("IEC958 Input Pin Enable", AC97_ALC650_CLOCK, 1, 1, 0),
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index ee895f3..c7e3c53 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -270,7 +270,7 @@
 	spinlock_t	reg_lock;
 	spinlock_t	voice_alloc;
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	struct snd_ali_image *image;
 #endif
 };
@@ -1883,7 +1883,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int ali_suspend(struct device *dev)
 {
 	struct pci_dev *pci = to_pci_dev(dev);
@@ -1989,7 +1989,7 @@
 #define ALI_PM_OPS	&ali_pm
 #else
 #define ALI_PM_OPS	NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 static int snd_ali_free(struct snd_ali * codec)
 {
@@ -2000,7 +2000,7 @@
 	if (codec->port)
 		pci_release_regions(codec->pci);
 	pci_disable_device(codec->pci);
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	kfree(codec->image);
 #endif
 	pci_dev_put(codec->pci_m1533);
@@ -2232,7 +2232,7 @@
 		return err;
 	}
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	codec->image = kmalloc(sizeof(*codec->image), GFP_KERNEL);
 	if (!codec->image)
 		snd_printk(KERN_WARNING "can't allocate apm buffer\n");
diff --git a/sound/pci/als300.c b/sound/pci/als300.c
index 68c4469..00f157a 100644
--- a/sound/pci/als300.c
+++ b/sound/pci/als300.c
@@ -765,7 +765,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int snd_als300_suspend(struct device *dev)
 {
 	struct pci_dev *pci = to_pci_dev(dev);
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 0eeca49..feb2a14 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -987,7 +987,7 @@
 	pci_set_drvdata(pci, NULL);
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int snd_als4000_suspend(struct device *dev)
 {
 	struct pci_dev *pci = to_pci_dev(dev);
@@ -1040,7 +1040,7 @@
 #define SND_ALS4000_PM_OPS	&snd_als4000_pm
 #else
 #define SND_ALS4000_PM_OPS	NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 static struct pci_driver als4000_driver = {
 	.name = KBUILD_MODNAME,
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c
index e8de831..eedc017 100644
--- a/sound/pci/asihpi/asihpi.c
+++ b/sound/pci/asihpi/asihpi.c
@@ -2658,7 +2658,7 @@
 					hpi_ctl.dst_node_type,
 					hpi_ctl.dst_node_index);
 			continue;
-		};
+		}
 		if (err < 0)
 			return err;
 	}
@@ -2968,7 +2968,7 @@
 	.id_table = asihpi_pci_tbl,
 	.probe = snd_asihpi_probe,
 	.remove = __devexit_p(snd_asihpi_remove),
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 /*	.suspend = snd_asihpi_suspend,
 	.resume = snd_asihpi_resume, */
 #endif
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 31020d2..368df8b 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -535,7 +535,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int snd_atiixp_aclink_down(struct atiixp *chip)
 {
 	// if (atiixp_read(chip, MODEM_MIRROR) & 0x1) /* modem running, too? */
@@ -1250,6 +1250,7 @@
 static int __devinit snd_atiixp_pcm_new(struct atiixp *chip)
 {
 	struct snd_pcm *pcm;
+	struct snd_pcm_chmap *chmap;
 	struct snd_ac97_bus *pbus = chip->ac97_bus;
 	int err, i, num_pcms;
 
@@ -1293,6 +1294,14 @@
 					      snd_dma_pci_data(chip->pci),
 					      64*1024, 128*1024);
 
+	err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+				     snd_pcm_alt_chmaps, chip->max_channels, 0,
+				     &chmap);
+	if (err < 0)
+		return err;
+	chmap->channel_mask = SND_PCM_CHMAP_MASK_2468;
+	chip->ac97[0]->chmaps[SNDRV_PCM_STREAM_PLAYBACK] = chmap;
+
 	/* no SPDIF support on codec? */
 	if (chip->pcms[ATI_PCM_SPDIF] && ! chip->pcms[ATI_PCM_SPDIF]->rates)
 		return 0;
@@ -1458,7 +1467,7 @@
 }
 
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 /*
  * power management
  */
@@ -1533,7 +1542,7 @@
 #define SND_ATIIXP_PM_OPS	&snd_atiixp_pm
 #else
 #define SND_ATIIXP_PM_OPS	NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 
 #ifdef CONFIG_PROC_FS
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index 79e204e..6fc03d9 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -511,7 +511,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int snd_atiixp_aclink_down(struct atiixp_modem *chip)
 {
 	// if (atiixp_read(chip, MODEM_MIRROR) & 0x1) /* modem running, too? */
@@ -1113,7 +1113,7 @@
 }
 
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 /*
  * power management
  */
@@ -1169,7 +1169,7 @@
 #define SND_ATIIXP_PM_OPS	&snd_atiixp_pm
 #else
 #define SND_ATIIXP_PM_OPS	NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 #ifdef CONFIG_PROC_FS
 /*
diff --git a/sound/pci/au88x0/au88x0_game.c b/sound/pci/au88x0/au88x0_game.c
index c07c792..30a4567 100644
--- a/sound/pci/au88x0/au88x0_game.c
+++ b/sound/pci/au88x0/au88x0_game.c
@@ -100,7 +100,7 @@
 	if (!gp) {
 		printk(KERN_ERR "vortex: cannot allocate memory for gameport\n");
 		return -ENOMEM;
-	};
+	}
 
 	gameport_set_name(gp, "AU88x0 Gameport");
 	gameport_set_phys(gp, "pci%s/gameport0", pci_name(vortex->pci_dev));
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c
index e59f120..b240502 100644
--- a/sound/pci/au88x0/au88x0_pcm.c
+++ b/sound/pci/au88x0/au88x0_pcm.c
@@ -585,7 +585,7 @@
 				case 4:
 					mixin = p->mixin[i];
 					break;
-				};
+				}
 				vol = p->vol[i];
 				vortex_mix_setinputvolumebyte(vortex,
 					vortex->mixplayb[i], mixin, vol);
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 4dddd87..c03b66b 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -365,7 +365,7 @@
 	 * CONFIG_PM register storage below, but that's slightly difficult. */
 	u16 shadow_reg_ctrl_6AH;
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	/* register value containers for power management
 	 * Note: not always full I/O range preserved (similar to Win driver!) */
 	u32 saved_regs_ctrl[AZF_ALIGN(AZF_IO_SIZE_CTRL_PM) / 4];
@@ -2729,7 +2729,7 @@
 	snd_azf3328_dbgcallleave();
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static inline void
 snd_azf3328_suspend_regs(unsigned long io_addr, unsigned count, u32 *saved_regs)
 {
@@ -2866,7 +2866,7 @@
 #define SND_AZF3328_PM_OPS	&snd_azf3328_pm
 #else
 #define SND_AZF3328_PM_OPS	NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 static struct pci_driver azf3328_driver = {
 	.name = KBUILD_MODNAME,
diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h
index e8e8ccc..04402c1 100644
--- a/sound/pci/ca0106/ca0106.h
+++ b/sound/pci/ca0106/ca0106.h
@@ -710,7 +710,7 @@
 
 	u16 spi_dac_reg[16];
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 #define NUM_SAVED_VOLUMES	9
 	unsigned int saved_vol[NUM_SAVED_VOLUMES];
 #endif
@@ -733,7 +733,7 @@
 int snd_ca0106_spi_write(struct snd_ca0106 * emu,
 				   unsigned int data);
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 void snd_ca0106_mixer_suspend(struct snd_ca0106 *chip);
 void snd_ca0106_mixer_resume(struct snd_ca0106 *chip);
 #else
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 83277b7..65c5591 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -1334,10 +1334,29 @@
 	return IRQ_HANDLED;
 }
 
+static const struct snd_pcm_chmap_elem surround_map[] = {
+	{ .channels = 2,
+	  .map = { SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
+	{ }
+};
+
+static const struct snd_pcm_chmap_elem clfe_map[] = {
+	{ .channels = 2,
+	  .map = { SNDRV_CHMAP_FC, SNDRV_CHMAP_LFE } },
+	{ }
+};
+
+static const struct snd_pcm_chmap_elem side_map[] = {
+	{ .channels = 2,
+	  .map = { SNDRV_CHMAP_SL, SNDRV_CHMAP_SR } },
+	{ }
+};
+
 static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device)
 {
 	struct snd_pcm *pcm;
 	struct snd_pcm_substream *substream;
+	const struct snd_pcm_chmap_elem *map = NULL;
 	int err;
   
 	err = snd_pcm_new(emu->card, "ca0106", device, 1, 1, &pcm);
@@ -1350,18 +1369,22 @@
 	case 0:
 	  snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ca0106_playback_front_ops);
 	  snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ca0106_capture_0_ops);
+	  map = snd_pcm_std_chmaps;
           break;
 	case 1:
 	  snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ca0106_playback_rear_ops);
 	  snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ca0106_capture_1_ops);
+	  map = surround_map;
           break;
 	case 2:
 	  snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ca0106_playback_center_lfe_ops);
 	  snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ca0106_capture_2_ops);
+	  map = clfe_map;
           break;
 	case 3:
 	  snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_ca0106_playback_unknown_ops);
 	  snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_ca0106_capture_3_ops);
+	  map = side_map;
           break;
         }
 
@@ -1388,6 +1411,11 @@
 			return err;
 	}
   
+	err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, map, 2,
+				     1 << 2, NULL);
+	if (err < 0)
+		return err;
+
 	emu->pcm[device] = pcm;
   
 	return 0;
@@ -1871,7 +1899,7 @@
 	pci_set_drvdata(pci, NULL);
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int snd_ca0106_suspend(struct device *dev)
 {
 	struct pci_dev *pci = to_pci_dev(dev);
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
index 84f3f92..68eacf7 100644
--- a/sound/pci/ca0106/ca0106_mixer.c
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -907,7 +907,7 @@
         return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 struct ca0106_vol_tbl {
 	unsigned int channel_id;
 	unsigned int reg;
@@ -953,4 +953,4 @@
 	if (chip->details->i2c_adc)
 		ca0106_set_capture_mic_line_in(chip);
 }
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index b7d6f2b..22122ff 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -504,7 +504,7 @@
 
 	spinlock_t reg_lock;
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	unsigned int saved_regs[0x20];
 	unsigned char saved_mixers[0x20];
 #endif
@@ -1962,6 +1962,12 @@
 	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
 					      snd_dma_pci_data(cm->pci), 64*1024, 128*1024);
 
+	err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+				     snd_pcm_alt_chmaps, cm->max_channels, 0,
+				     NULL);
+	if (err < 0)
+		return err;
+
 	return 0;
 }
 
@@ -3315,7 +3321,7 @@
 }
 
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 /*
  * power management
  */
@@ -3403,7 +3409,7 @@
 #define SND_CMIPCI_PM_OPS	&snd_cmipci_pm
 #else
 #define SND_CMIPCI_PM_OPS	NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 static struct pci_driver cmipci_driver = {
 	.name = KBUILD_MODNAME,
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index 45a8317..8e86ec0 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -486,7 +486,7 @@
 
 	struct gameport *gameport;
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	u32 suspend_regs[SUSPEND_REGISTERS];
 #endif
 
@@ -1977,7 +1977,7 @@
 /*
  * Power Management
  */
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 
 static int saved_regs[SUSPEND_REGISTERS] = {
 	BA0_JSCTL,
@@ -2089,7 +2089,7 @@
 #define CS4281_PM_OPS	&cs4281_pm
 #else
 #define CS4281_PM_OPS	NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 static struct pci_driver cs4281_driver = {
 	.name = KBUILD_MODNAME,
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c
index 1e007c7..575bed0 100644
--- a/sound/pci/cs46xx/cs46xx.c
+++ b/sound/pci/cs46xx/cs46xx.c
@@ -166,7 +166,7 @@
 	.id_table = snd_cs46xx_ids,
 	.probe = snd_card_cs46xx_probe,
 	.remove = __devexit_p(snd_card_cs46xx_remove),
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	.driver = {
 		.pm = &snd_cs46xx_pm,
 	},
diff --git a/sound/pci/cs46xx/cs46xx.h b/sound/pci/cs46xx/cs46xx.h
index 29d8a8d..fc339ef 100644
--- a/sound/pci/cs46xx/cs46xx.h
+++ b/sound/pci/cs46xx/cs46xx.h
@@ -1721,7 +1721,7 @@
 	unsigned int play_ctl;
 #endif
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	u32 *saved_regs;
 #endif
 };
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index a71d1c1..a2bb8c9 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -2797,7 +2797,7 @@
 	}
 #endif
 	
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	kfree(chip->saved_regs);
 #endif
 
@@ -3590,7 +3590,7 @@
 /*
  * APM support
  */
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static unsigned int saved_regs[] = {
 	BA0_ACOSV,
 	/*BA0_ASER_FADDR,*/
@@ -3711,7 +3711,7 @@
 }
 
 SIMPLE_DEV_PM_OPS(snd_cs46xx_pm, snd_cs46xx_suspend, snd_cs46xx_resume);
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 
 /*
@@ -3868,7 +3868,7 @@
 	
 	snd_cs46xx_proc_init(card, chip);
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	chip->saved_regs = kmalloc(sizeof(*chip->saved_regs) *
 				   ARRAY_SIZE(saved_regs), GFP_KERNEL);
 	if (!chip->saved_regs) {
diff --git a/sound/pci/cs46xx/cs46xx_lib.h b/sound/pci/cs46xx/cs46xx_lib.h
index b518949..86f1462 100644
--- a/sound/pci/cs46xx/cs46xx_lib.h
+++ b/sound/pci/cs46xx/cs46xx_lib.h
@@ -90,7 +90,7 @@
 struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip);
 void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip);
 int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * module);
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 int cs46xx_dsp_resume(struct snd_cs46xx * chip);
 #endif
 struct dsp_symbol_entry *cs46xx_dsp_lookup_symbol (struct snd_cs46xx * chip, char * symbol_name,
diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c
index 56fec0b..1686b4f 100644
--- a/sound/pci/cs46xx/dsp_spos.c
+++ b/sound/pci/cs46xx/dsp_spos.c
@@ -287,7 +287,7 @@
 		if (ins->scbs[i].deleted) continue;
 
 		cs46xx_dsp_proc_free_scb_desc ( (ins->scbs + i) );
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 		kfree(ins->scbs[i].data);
 #endif
 	}
@@ -1019,7 +1019,7 @@
 {
 	struct dsp_scb_descriptor * desc;
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	/* copy the data for resume */
 	scb_data = kmemdup(scb_data, SCB_BYTES, GFP_KERNEL);
 	if (!scb_data)
@@ -1032,7 +1032,7 @@
 		_dsp_create_scb(chip,scb_data,dest);
 	} else {
 		snd_printk(KERN_ERR "dsp_spos: failed to map SCB\n");
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 		kfree(scb_data);
 #endif
 	}
@@ -1937,7 +1937,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 int cs46xx_dsp_resume(struct snd_cs46xx * chip)
 {
 	struct dsp_spos_instance * ins = chip->dsp_spos_instance;
diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c
index c2c695b..409e876 100644
--- a/sound/pci/cs46xx/dsp_spos_scb_lib.c
+++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c
@@ -203,7 +203,7 @@
 	remove_symbol (chip,scb->scb_symbol);
 
 	ins->scbs[scb->index].deleted = 1;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	kfree(ins->scbs[scb->index].data);
 	ins->scbs[scb->index].data = NULL;
 #endif
diff --git a/sound/pci/cs5530.c b/sound/pci/cs5530.c
index f1e4229..d1cca28 100644
--- a/sound/pci/cs5530.c
+++ b/sound/pci/cs5530.c
@@ -142,8 +142,7 @@
 
 	mem = pci_ioremap_bar(pci, 0);
 	if (mem == NULL) {
-		kfree(chip);
-		pci_disable_device(pci);
+		snd_cs5530_free(chip);
 		return -EBUSY;
 	}
 
diff --git a/sound/pci/cs5535audio/Makefile b/sound/pci/cs5535audio/Makefile
index ccc6422..a8f75f8 100644
--- a/sound/pci/cs5535audio/Makefile
+++ b/sound/pci/cs5535audio/Makefile
@@ -3,7 +3,7 @@
 #
 
 snd-cs5535audio-y := cs5535audio.o cs5535audio_pcm.o
-snd-cs5535audio-$(CONFIG_PM) += cs5535audio_pm.o
+snd-cs5535audio-$(CONFIG_PM_SLEEP) += cs5535audio_pm.o
 snd-cs5535audio-$(CONFIG_OLPC) += cs5535audio_olpc.o
 
 # Toplevel Module Dependency
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
index 51f64ba..4915efa 100644
--- a/sound/pci/cs5535audio/cs5535audio.c
+++ b/sound/pci/cs5535audio/cs5535audio.c
@@ -399,7 +399,7 @@
 	.id_table = snd_cs5535audio_ids,
 	.probe = snd_cs5535audio_probe,
 	.remove = __devexit_p(snd_cs5535audio_remove),
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	.driver = {
 		.pm = &snd_cs5535audio_pm,
 	},
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c
index 2f6e9c7..a2f997a 100644
--- a/sound/pci/ctxfi/ctatc.c
+++ b/sound/pci/ctxfi/ctatc.c
@@ -1536,7 +1536,7 @@
 	}
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int atc_suspend(struct ct_atc *atc)
 {
 	int i;
@@ -1647,7 +1647,7 @@
 	.output_switch_put = atc_output_switch_put,
 	.mic_source_switch_get = atc_mic_source_switch_get,
 	.mic_source_switch_put = atc_mic_source_switch_put,
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	.suspend = atc_suspend,
 	.resume = atc_resume,
 #endif
diff --git a/sound/pci/ctxfi/ctatc.h b/sound/pci/ctxfi/ctatc.h
index 653e813..69b51f9 100644
--- a/sound/pci/ctxfi/ctatc.h
+++ b/sound/pci/ctxfi/ctatc.h
@@ -143,7 +143,7 @@
 
 	struct ct_timer *timer;
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	int (*suspend)(struct ct_atc *atc);
 	int (*resume)(struct ct_atc *atc);
 #define NUM_PCMS (NUM_CTALSADEVS - 1)
diff --git a/sound/pci/ctxfi/cthardware.h b/sound/pci/ctxfi/cthardware.h
index c56fe53..5977e9a 100644
--- a/sound/pci/ctxfi/cthardware.h
+++ b/sound/pci/ctxfi/cthardware.h
@@ -72,7 +72,7 @@
 	int (*card_init)(struct hw *hw, struct card_conf *info);
 	int (*card_stop)(struct hw *hw);
 	int (*pll_init)(struct hw *hw, unsigned int rsr);
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	int (*suspend)(struct hw *hw);
 	int (*resume)(struct hw *hw, struct card_conf *info);
 #endif
diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c
index dc1969b..4507f70 100644
--- a/sound/pci/ctxfi/cthw20k1.c
+++ b/sound/pci/ctxfi/cthw20k1.c
@@ -2085,7 +2085,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int hw_suspend(struct hw *hw)
 {
 	struct pci_dev *pci = hw->pci;
@@ -2180,7 +2180,7 @@
 	.is_adc_source_selected = hw_is_adc_input_selected,
 	.select_adc_source = hw_adc_input_select,
 	.capabilities = hw_capabilities,
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	.suspend = hw_suspend,
 	.resume = hw_resume,
 #endif
diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c
index 9d1231d..b9c9349 100644
--- a/sound/pci/ctxfi/cthw20k2.c
+++ b/sound/pci/ctxfi/cthw20k2.c
@@ -2201,7 +2201,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int hw_suspend(struct hw *hw)
 {
 	struct pci_dev *pci = hw->pci;
@@ -2250,7 +2250,7 @@
 	.output_switch_put = hw_output_switch_put,
 	.mic_source_switch_get = hw_mic_source_switch_get,
 	.mic_source_switch_put = hw_mic_source_switch_put,
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	.suspend = hw_suspend,
 	.resume = hw_resume,
 #endif
diff --git a/sound/pci/ctxfi/ctmixer.c b/sound/pci/ctxfi/ctmixer.c
index 0cc13ee..48fe0e3 100644
--- a/sound/pci/ctxfi/ctmixer.c
+++ b/sound/pci/ctxfi/ctmixer.c
@@ -1118,7 +1118,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int mixer_resume(struct ct_mixer *mixer)
 {
 	int i, state;
@@ -1188,7 +1188,7 @@
 	mixer->get_output_ports = mixer_get_output_ports;
 	mixer->set_input_left = mixer_set_input_left;
 	mixer->set_input_right = mixer_set_input_right;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	mixer->resume = mixer_resume;
 #endif
 
diff --git a/sound/pci/ctxfi/ctmixer.h b/sound/pci/ctxfi/ctmixer.h
index b009e98..be881c6 100644
--- a/sound/pci/ctxfi/ctmixer.h
+++ b/sound/pci/ctxfi/ctmixer.h
@@ -56,7 +56,7 @@
 			      enum MIXER_PORT_T type, struct rsc *rsc);
 	int (*set_input_right)(struct ct_mixer *mixer,
 			       enum MIXER_PORT_T type, struct rsc *rsc);
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	int (*resume)(struct ct_mixer *mixer);
 #endif
 };
diff --git a/sound/pci/ctxfi/ctpcm.c b/sound/pci/ctxfi/ctpcm.c
index 2c86226..e8a4feb 100644
--- a/sound/pci/ctxfi/ctpcm.c
+++ b/sound/pci/ctxfi/ctpcm.c
@@ -395,12 +395,38 @@
 	.page		= snd_pcm_sgbuf_ops_page,
 };
 
+static const struct snd_pcm_chmap_elem surround_map[] = {
+	{ .channels = 1,
+	  .map = { SNDRV_CHMAP_MONO } },
+	{ .channels = 2,
+	  .map = { SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
+	{ }
+};
+
+static const struct snd_pcm_chmap_elem clfe_map[] = {
+	{ .channels = 1,
+	  .map = { SNDRV_CHMAP_MONO } },
+	{ .channels = 2,
+	  .map = { SNDRV_CHMAP_FC, SNDRV_CHMAP_LFE } },
+	{ }
+};
+
+static const struct snd_pcm_chmap_elem side_map[] = {
+	{ .channels = 1,
+	  .map = { SNDRV_CHMAP_MONO } },
+	{ .channels = 2,
+	  .map = { SNDRV_CHMAP_SL, SNDRV_CHMAP_SR } },
+	{ }
+};
+
 /* Create ALSA pcm device */
 int ct_alsa_pcm_create(struct ct_atc *atc,
 		       enum CTALSADEVS device,
 		       const char *device_name)
 {
 	struct snd_pcm *pcm;
+	const struct snd_pcm_chmap_elem *map;
+	int chs;
 	int err;
 	int playback_count, capture_count;
 
@@ -427,7 +453,31 @@
 	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
 			snd_dma_pci_data(atc->pci), 128*1024, 128*1024);
 
-#ifdef CONFIG_PM
+	chs = 2;
+	switch (device) {
+	case FRONT:
+		chs = 8;
+		map = snd_pcm_std_chmaps;
+		break;
+	case SURROUND:
+		map = surround_map;
+		break;
+	case CLFE:
+		map = clfe_map;
+		break;
+	case SIDE:
+		map = side_map;
+		break;
+	default:
+		map = snd_pcm_std_chmaps;
+		break;
+	}
+	err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, map, chs,
+				     0, NULL);
+	if (err < 0)
+		return err;
+
+#ifdef CONFIG_PM_SLEEP
 	atc->pcms[device] = pcm;
 #endif
 
diff --git a/sound/pci/ctxfi/xfi.c b/sound/pci/ctxfi/xfi.c
index e002183..07c07d7 100644
--- a/sound/pci/ctxfi/xfi.c
+++ b/sound/pci/ctxfi/xfi.c
@@ -125,7 +125,7 @@
 	pci_set_drvdata(pci, NULL);
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int ct_card_suspend(struct device *dev)
 {
 	struct snd_card *card = dev_get_drvdata(dev);
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index 0ff754f..abb0b86 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -46,7 +46,7 @@
 	int err;
 	char name[30];
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	if (chip->fw_cache[fw_index]) {
 		DE_ACT(("firmware requested: %s is cached\n", card_fw[fw_index].data));
 		*fw_entry = chip->fw_cache[fw_index];
@@ -59,7 +59,7 @@
 	err = request_firmware(fw_entry, name, pci_device(chip));
 	if (err < 0)
 		snd_printk(KERN_ERR "get_firmware(): Firmware not available (%d)\n", err);
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	else
 		chip->fw_cache[fw_index] = *fw_entry;
 #endif
@@ -70,7 +70,7 @@
 
 static void free_firmware(const struct firmware *fw_entry)
 {
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	DE_ACT(("firmware not released (kept in cache)\n"));
 #else
 	release_firmware(fw_entry);
@@ -82,7 +82,7 @@
 
 static void free_firmware_cache(struct echoaudio *chip)
 {
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	int i;
 
 	for (i = 0; i < 8 ; i++)
@@ -2203,7 +2203,7 @@
 
 
 
-#if defined(CONFIG_PM)
+#if defined(CONFIG_PM_SLEEP)
 
 static int snd_echo_suspend(struct device *dev)
 {
@@ -2313,7 +2313,7 @@
 #define SND_ECHO_PM_OPS	&snd_echo_pm
 #else
 #define SND_ECHO_PM_OPS	NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 
 static void __devexit snd_echo_remove(struct pci_dev *pci)
diff --git a/sound/pci/echoaudio/echoaudio.h b/sound/pci/echoaudio/echoaudio.h
index 1df974d..e158369 100644
--- a/sound/pci/echoaudio/echoaudio.h
+++ b/sound/pci/echoaudio/echoaudio.h
@@ -449,7 +449,7 @@
 	volatile u32 __iomem *dsp_registers;	/* DSP's register base */
 	u32 active_mask;			/* Chs. active mask or
 						 * punks out */
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	const struct firmware *fw_cache[8];	/* Cached firmwares */
 #endif
 
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index ddac4e6..b7c1875 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -206,7 +206,7 @@
 }
 
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int snd_emu10k1_suspend(struct device *dev)
 {
 	struct pci_dev *pci = to_pci_dev(dev);
@@ -268,7 +268,7 @@
 #define SND_EMU10K1_PM_OPS	&snd_emu10k1_pm
 #else
 #define SND_EMU10K1_PM_OPS	NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 static struct pci_driver emu10k1_driver = {
 	.name = KBUILD_MODNAME,
diff --git a/sound/pci/emu10k1/emu10k1_callback.c b/sound/pci/emu10k1/emu10k1_callback.c
index a0afa50..cae3659 100644
--- a/sound/pci/emu10k1/emu10k1_callback.c
+++ b/sound/pci/emu10k1/emu10k1_callback.c
@@ -228,7 +228,7 @@
 	int  i;
 
 	for (i = 0; i < V_END; i++) {
-		best[i].time = (unsigned int)-1; /* XXX MAX_?INT really */;
+		best[i].time = (unsigned int)-1; /* XXX MAX_?INT really */
 		best[i].voice = -1;
 	}
 
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 7549240..bed4485 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -1241,7 +1241,7 @@
  *  Create the EMU10K1 instance
  */
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int alloc_pm_buffer(struct snd_emu10k1 *emu);
 static void free_pm_buffer(struct snd_emu10k1 *emu);
 #endif
@@ -1275,7 +1275,7 @@
 		snd_dma_free_pages(&emu->ptb_pages);
 	vfree(emu->page_ptr_table);
 	vfree(emu->page_addr_table);
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	free_pm_buffer(emu);
 #endif
 	if (emu->port)
@@ -1971,7 +1971,7 @@
 	err = snd_emu10k1_init(emu, enable_ir, 0);
 	if (err < 0)
 		goto error;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	err = alloc_pm_buffer(emu);
 	if (err < 0)
 		goto error;
@@ -2000,7 +2000,7 @@
 	return err;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static unsigned char saved_regs[] = {
 	CPF, PTRX, CVCF, VTFT, Z1, Z2, PSST, DSL, CCCA, CCR, CLP,
 	FXRT, MAPA, MAPB, ENVVOL, ATKHLDV, DCYSUSV, LFOVAL1, ENVVAL,
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index 5c8978b..556fd6f 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -830,9 +830,22 @@
 	return IRQ_HANDLED;
 }
 
+static const struct snd_pcm_chmap_elem surround_map[] = {
+	{ .channels = 2,
+	  .map = { SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
+	{ }
+};
+
+static const struct snd_pcm_chmap_elem clfe_map[] = {
+	{ .channels = 2,
+	  .map = { SNDRV_CHMAP_FC, SNDRV_CHMAP_LFE } },
+	{ }
+};
+
 static int __devinit snd_emu10k1x_pcm(struct emu10k1x *emu, int device, struct snd_pcm **rpcm)
 {
 	struct snd_pcm *pcm;
+	const struct snd_pcm_chmap_elem *map = NULL;
 	int err;
 	int capture = 0;
   
@@ -861,12 +874,15 @@
 	switch(device) {
 	case 0:
 		strcpy(pcm->name, "EMU10K1X Front");
+		map = snd_pcm_std_chmaps;
 		break;
 	case 1:
 		strcpy(pcm->name, "EMU10K1X Rear");
+		map = surround_map;
 		break;
 	case 2:
 		strcpy(pcm->name, "EMU10K1X Center/LFE");
+		map = clfe_map;
 		break;
 	}
 	emu->pcm = pcm;
@@ -875,6 +891,11 @@
 					      snd_dma_pci_data(emu->pci), 
 					      32*1024, 32*1024);
   
+	err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, map, 2,
+				     1 << 2, NULL);
+	if (err < 0)
+		return err;
+
 	if (rpcm)
 		*rpcm = pcm;
   
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
index dae4050..5241995 100644
--- a/sound/pci/emu10k1/emufx.c
+++ b/sound/pci/emu10k1/emufx.c
@@ -2646,7 +2646,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 int __devinit snd_emu10k1_efx_alloc_pm_buffer(struct snd_emu10k1 *emu)
 {
 	int len;
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index e22b8e2..0e6664f 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -1310,7 +1310,7 @@
 			runtime->hw.channels_min =
 				runtime->hw.channels_max = 16;
 			break;
-		};
+		}
 #endif
 #if 0
 		/* For 96kHz */
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index 0a43662..ae709c1 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -263,8 +263,8 @@
 	spin_lock_irqsave(&emu->memblk_lock, flags);
 	if (blk->mapped_page >= 0) {
 		/* update order link */
-		list_del(&blk->mapped_order_link);
-		list_add_tail(&blk->mapped_order_link, &emu->mapped_order_link_head);
+		list_move_tail(&blk->mapped_order_link,
+			       &emu->mapped_order_link_head);
 		spin_unlock_irqrestore(&emu->memblk_lock, flags);
 		return 0;
 	}
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c
index a81dc44..88cec6b 100644
--- a/sound/pci/emu10k1/p16v.c
+++ b/sound/pci/emu10k1/p16v.c
@@ -893,7 +893,7 @@
         return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 
 #define NUM_CHS	1	/* up to 4, but only first channel is used */
 
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index f7e6f73..5674cc3 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -55,8 +55,10 @@
 
 #ifdef CHIP1370
 #define DRIVER_NAME "ENS1370"
+#define CHIP_NAME "ES1370" /* it can be ENS but just to keep compatibility... */
 #else
 #define DRIVER_NAME "ENS1371"
+#define CHIP_NAME "ES1371"
 #endif
 
 
@@ -1258,6 +1260,14 @@
 	.pointer =	snd_ensoniq_capture_pointer,
 };
 
+static const struct snd_pcm_chmap_elem surround_map[] = {
+	{ .channels = 1,
+	  .map = { SNDRV_CHMAP_MONO } },
+	{ .channels = 2,
+	  .map = { SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
+	{ }
+};
+
 static int __devinit snd_ensoniq_pcm(struct ensoniq * ensoniq, int device,
 				     struct snd_pcm ** rpcm)
 {
@@ -1266,11 +1276,7 @@
 
 	if (rpcm)
 		*rpcm = NULL;
-#ifdef CHIP1370
-	err = snd_pcm_new(ensoniq->card, "ES1370/1", device, 1, 1, &pcm);
-#else
-	err = snd_pcm_new(ensoniq->card, "ES1371/1", device, 1, 1, &pcm);
-#endif
+	err = snd_pcm_new(ensoniq->card, CHIP_NAME "/1", device, 1, 1, &pcm);
 	if (err < 0)
 		return err;
 
@@ -1283,16 +1289,22 @@
 
 	pcm->private_data = ensoniq;
 	pcm->info_flags = 0;
-#ifdef CHIP1370
-	strcpy(pcm->name, "ES1370 DAC2/ADC");
-#else
-	strcpy(pcm->name, "ES1371 DAC2/ADC");
-#endif
+	strcpy(pcm->name, CHIP_NAME " DAC2/ADC");
 	ensoniq->pcm1 = pcm;
 
 	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
 					      snd_dma_pci_data(ensoniq->pci), 64*1024, 128*1024);
 
+#ifdef CHIP1370
+	err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+				     surround_map, 2, 0, NULL);
+#else
+	err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+				     snd_pcm_std_chmaps, 2, 0, NULL);
+#endif
+	if (err < 0)
+		return err;
+
 	if (rpcm)
 		*rpcm = pcm;
 	return 0;
@@ -1306,11 +1318,7 @@
 
 	if (rpcm)
 		*rpcm = NULL;
-#ifdef CHIP1370
-	err = snd_pcm_new(ensoniq->card, "ES1370/2", device, 1, 0, &pcm);
-#else
-	err = snd_pcm_new(ensoniq->card, "ES1371/2", device, 1, 0, &pcm);
-#endif
+	err = snd_pcm_new(ensoniq->card, CHIP_NAME "/2", device, 1, 0, &pcm);
 	if (err < 0)
 		return err;
 
@@ -1321,16 +1329,22 @@
 #endif
 	pcm->private_data = ensoniq;
 	pcm->info_flags = 0;
-#ifdef CHIP1370
-	strcpy(pcm->name, "ES1370 DAC1");
-#else
-	strcpy(pcm->name, "ES1371 DAC1");
-#endif
+	strcpy(pcm->name, CHIP_NAME " DAC1");
 	ensoniq->pcm2 = pcm;
 
 	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
 					      snd_dma_pci_data(ensoniq->pci), 64*1024, 128*1024);
 
+#ifdef CHIP1370
+	err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+				     snd_pcm_std_chmaps, 2, 0, NULL);
+#else
+	err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+				     surround_map, 2, 0, NULL);
+#endif
+	if (err < 0)
+		return err;
+
 	if (rpcm)
 		*rpcm = pcm;
 	return 0;
@@ -1885,11 +1899,7 @@
 {
 	struct ensoniq *ensoniq = entry->private_data;
 
-#ifdef CHIP1370
-	snd_iprintf(buffer, "Ensoniq AudioPCI ES1370\n\n");
-#else
-	snd_iprintf(buffer, "Ensoniq AudioPCI ES1371\n\n");
-#endif
+	snd_iprintf(buffer, "Ensoniq AudioPCI " CHIP_NAME "\n\n");
 	snd_iprintf(buffer, "Joystick enable  : %s\n",
 		    ensoniq->ctrl & ES_JYSTK_EN ? "on" : "off");
 #ifdef CHIP1370
@@ -2032,7 +2042,7 @@
 	synchronize_irq(ensoniq->irq);
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int snd_ensoniq_suspend(struct device *dev)
 {
 	struct pci_dev *pci = to_pci_dev(dev);
@@ -2094,7 +2104,7 @@
 #define SND_ENSONIQ_PM_OPS	&snd_ensoniq_pm
 #else
 #define SND_ENSONIQ_PM_OPS	NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 static int __devinit snd_ensoniq_create(struct snd_card *card,
 				     struct pci_dev *pci,
@@ -2361,11 +2371,7 @@
 		*rrawmidi = NULL;
 	if ((err = snd_rawmidi_new(ensoniq->card, "ES1370/1", device, 1, 1, &rmidi)) < 0)
 		return err;
-#ifdef CHIP1370
-	strcpy(rmidi->name, "ES1370");
-#else
-	strcpy(rmidi->name, "ES1371");
-#endif
+	strcpy(rmidi->name, CHIP_NAME);
 	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_ensoniq_midi_output);
 	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_ensoniq_midi_input);
 	rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT | SNDRV_RAWMIDI_INFO_INPUT |
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index dbb8180..394c5d4 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -236,7 +236,7 @@
 #ifdef SUPPORT_JOYSTICK
 	struct gameport *gameport;
 #endif
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	unsigned char saved_regs[SAVED_REG_SIZE];
 #endif
 };
@@ -1456,7 +1456,7 @@
 	outb(0, SLDM_REG(chip, DMACLEAR));
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 /*
  * PM support
  */
@@ -1536,7 +1536,7 @@
 #define ES1938_PM_OPS	&es1938_pm
 #else
 #define ES1938_PM_OPS	NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 #ifdef SUPPORT_JOYSTICK
 static int __devinit snd_es1938_create_gameport(struct es1938 *chip)
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index fb4c90b9..5d0e568 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -491,7 +491,7 @@
 	/* linked list */
 	struct list_head list;
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	u16 wc_map[4];
 #endif
 };
@@ -544,7 +544,7 @@
 	struct list_head substream_list;
 	spinlock_t substream_lock;
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	u16 apu_map[NR_APUS][NR_APU_REGS];
 #endif
 
@@ -706,7 +706,7 @@
 {
 	if (snd_BUG_ON(channel >= NR_APUS))
 		return;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	chip->apu_map[channel][reg] = data;
 #endif
 	reg |= (channel << 4);
@@ -993,7 +993,7 @@
 	/* set the wavecache control reg */
 	wave_set_register(chip, es->apu[channel] << 3, tmpval);
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	es->wc_map[channel] = tmpval;
 #endif
 }
@@ -2377,7 +2377,7 @@
 	outw(w, chip->io_port + ESM_PORT_HOST_IRQ);
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 /*
  * PM support
  */
@@ -2461,7 +2461,7 @@
 #define ES1968_PM_OPS	&es1968_pm
 #else
 #define ES1968_PM_OPS	NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 #ifdef SUPPORT_JOYSTICK
 #define JOYSTICK_ADDR	0x200
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index 522c870..cc2e91d 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -205,7 +205,7 @@
 	struct snd_tea575x tea;
 #endif
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	u16 saved_regs[0x20];
 #endif
 };
@@ -711,6 +711,13 @@
 					      snd_dma_pci_data(chip->pci),
 					      chip->multichannel ? 128*1024 : 64*1024, 128*1024);
 
+	err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+				     snd_pcm_alt_chmaps,
+				     chip->multichannel ? 6 : 2, 0,
+				     NULL);
+	if (err < 0)
+		return err;
+
 	if (rpcm)
 		*rpcm = pcm;
 	return 0;
@@ -1361,7 +1368,7 @@
 	pci_set_drvdata(pci, NULL);
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static unsigned char saved_regs[] = {
 	FM801_PCM_VOL, FM801_I2S_VOL, FM801_FM_VOL, FM801_REC_SRC,
 	FM801_PLY_CTRL, FM801_PLY_COUNT, FM801_PLY_BUF1, FM801_PLY_BUF2,
@@ -1421,7 +1428,7 @@
 #define SND_FM801_PM_OPS	&snd_fm801_pm
 #else
 #define SND_FM801_PM_OPS	NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 static struct pci_driver fm801_driver = {
 	.name = KBUILD_MODNAME,
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 194d625..7105c3d 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -228,17 +228,9 @@
 	  Say Y here to enable the generic HD-audio codec parser
 	  in snd-hda-intel driver.
 
-config SND_HDA_POWER_SAVE
-	bool "Aggressive power-saving on HD-audio"
-	depends on PM
-	help
-	  Say Y here to enable more aggressive power-saving mode on
-	  HD-audio driver.  The power-saving timeout can be configured
-	  via power_save option or over sysfs on-the-fly.
-
 config SND_HDA_POWER_SAVE_DEFAULT
 	int "Default time-out for HD-audio power-save mode"
-	depends on SND_HDA_POWER_SAVE
+	depends on PM
 	default 0
 	help
 	  The default time-out value in seconds for HD-audio automatic
diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c
index 4f7d2df..4ec6dc8 100644
--- a/sound/pci/hda/hda_auto_parser.c
+++ b/sound/pci/hda/hda_auto_parser.c
@@ -141,7 +141,6 @@
 	memset(sequences_hp, 0, sizeof(sequences_hp));
 	assoc_line_out = 0;
 
-	codec->ignore_misc_bit = true;
 	end_nid = codec->start_nid + codec->num_nodes;
 	for (nid = codec->start_nid; nid < end_nid; nid++) {
 		unsigned int wid_caps = get_wcaps(codec, nid);
@@ -157,9 +156,6 @@
 			continue;
 
 		def_conf = snd_hda_codec_get_pincfg(codec, nid);
-		if (!(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
-		      AC_DEFCFG_MISC_NO_PRESENCE))
-			codec->ignore_misc_bit = false;
 		conn = get_defcfg_connect(def_conf);
 		if (conn == AC_JACK_PORT_NONE)
 			continue;
@@ -502,6 +498,38 @@
 	return channel_sfx[i];
 }
 
+static const char *check_output_pfx(struct hda_codec *codec, hda_nid_t nid)
+{
+	unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
+	int attr = snd_hda_get_input_pin_attr(def_conf);
+
+	/* check the location */
+	switch (attr) {
+	case INPUT_PIN_ATTR_DOCK:
+		return "Dock ";
+	case INPUT_PIN_ATTR_FRONT:
+		return "Front ";
+	}
+	return "";
+}
+
+static int get_hp_label_index(struct hda_codec *codec, hda_nid_t nid,
+			      const hda_nid_t *pins, int num_pins)
+{
+	int i, j, idx = 0;
+
+	const char *pfx = check_output_pfx(codec, nid);
+
+	i = find_idx_in_nid_list(nid, pins, num_pins);
+	if (i < 0)
+		return -1;
+	for (j = 0; j < i; j++)
+		if (pfx == check_output_pfx(codec, pins[j]))
+			idx++;
+
+	return idx;
+}
+
 static int fill_audio_out_name(struct hda_codec *codec, hda_nid_t nid,
 			       const struct auto_pin_cfg *cfg,
 			       const char *name, char *label, int maxlen,
@@ -509,20 +537,13 @@
 {
 	unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
 	int attr = snd_hda_get_input_pin_attr(def_conf);
-	const char *pfx = "", *sfx = "";
+	const char *pfx, *sfx = "";
 
 	/* handle as a speaker if it's a fixed line-out */
 	if (!strcmp(name, "Line Out") && attr == INPUT_PIN_ATTR_INT)
 		name = "Speaker";
-	/* check the location */
-	switch (attr) {
-	case INPUT_PIN_ATTR_DOCK:
-		pfx = "Dock ";
-		break;
-	case INPUT_PIN_ATTR_FRONT:
-		pfx = "Front ";
-		break;
-	}
+	pfx = check_output_pfx(codec, nid);
+
 	if (cfg) {
 		/* try to give a unique suffix if needed */
 		sfx = check_output_sfx(nid, cfg->line_out_pins, cfg->line_outs,
@@ -532,8 +553,8 @@
 					       indexp);
 		if (!sfx) {
 			/* don't add channel suffix for Headphone controls */
-			int idx = find_idx_in_nid_list(nid, cfg->hp_pins,
-						       cfg->hp_outs);
+			int idx = get_hp_label_index(codec, nid, cfg->hp_pins,
+						     cfg->hp_outs);
 			if (idx >= 0)
 				*indexp = idx;
 			sfx = "";
@@ -739,7 +760,8 @@
 		for (q = quirk; q->subvendor; q++) {
 			unsigned int vendorid =
 				q->subdevice | (q->subvendor << 16);
-			if (vendorid == codec->subsystem_id) {
+			unsigned int mask = 0xffff0000 | q->subdevice_mask;
+			if ((codec->subsystem_id & mask) == (vendorid & mask)) {
 				id = q->value;
 #ifdef CONFIG_SND_DEBUG_VERBOSE
 				name = q->name;
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 1c65cc5..70d4848 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -94,13 +94,19 @@
 }
 EXPORT_SYMBOL_HDA(snd_hda_delete_codec_preset);
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 static void hda_power_work(struct work_struct *work);
 static void hda_keep_power_on(struct hda_codec *codec);
 #define hda_codec_is_power_on(codec)	((codec)->power_on)
+static inline void hda_call_pm_notify(struct hda_bus *bus, bool power_up)
+{
+	if (bus->ops.pm_notify)
+		bus->ops.pm_notify(bus, power_up);
+}
 #else
 static inline void hda_keep_power_on(struct hda_codec *codec) {}
 #define hda_codec_is_power_on(codec)	1
+#define hda_call_pm_notify(bus, state) {}
 #endif
 
 /**
@@ -808,7 +814,7 @@
 {
 	struct hda_codec_preset_list *tbl;
 	const struct hda_codec_preset *preset;
-	int mod_requested = 0;
+	unsigned int mod_requested = 0;
 
 	if (is_generic_config(codec))
 		return NULL; /* use the generic parser */
@@ -1186,7 +1192,7 @@
 		return;
 	snd_hda_jack_tbl_clear(codec);
 	restore_init_pincfgs(codec);
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 	cancel_delayed_work(&codec->power_work);
 	flush_workqueue(codec->bus->workq);
 #endif
@@ -1199,6 +1205,10 @@
 	codec->bus->caddr_tbl[codec->addr] = NULL;
 	if (codec->patch_ops.free)
 		codec->patch_ops.free(codec);
+#ifdef CONFIG_PM
+	if (!codec->pm_down_notified) /* cancel leftover refcounts */
+		hda_call_pm_notify(codec->bus, false);
+#endif
 	module_put(codec->owner);
 	free_hda_cache(&codec->amp_cache);
 	free_hda_cache(&codec->cmd_cache);
@@ -1212,7 +1222,7 @@
 static bool snd_hda_codec_get_supported_ps(struct hda_codec *codec,
 				hda_nid_t fg, unsigned int power_state);
 
-static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
+static unsigned int hda_set_power_state(struct hda_codec *codec,
 				unsigned int power_state);
 
 /**
@@ -1229,6 +1239,7 @@
 {
 	struct hda_codec *codec;
 	char component[31];
+	hda_nid_t fg;
 	int err;
 
 	if (snd_BUG_ON(!bus))
@@ -1263,7 +1274,7 @@
 	snd_array_init(&codec->conn_lists, sizeof(hda_nid_t), 64);
 	snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16);
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 	spin_lock_init(&codec->power_lock);
 	INIT_DELAYED_WORK(&codec->power_work, hda_power_work);
 	/* snd_hda_codec_new() marks the codec as power-up, and leave it as is.
@@ -1271,6 +1282,7 @@
 	 * phase.
 	 */
 	hda_keep_power_on(codec);
+	hda_call_pm_notify(bus, true);
 #endif
 
 	if (codec->bus->modelname) {
@@ -1304,7 +1316,8 @@
 		goto error;
 	}
 
-	err = read_widget_caps(codec, codec->afg ? codec->afg : codec->mfg);
+	fg = codec->afg ? codec->afg : codec->mfg;
+	err = read_widget_caps(codec, fg);
 	if (err < 0) {
 		snd_printk(KERN_ERR "hda_codec: cannot malloc\n");
 		goto error;
@@ -1314,20 +1327,22 @@
 		goto error;
 
 	if (!codec->subsystem_id) {
-		hda_nid_t nid = codec->afg ? codec->afg : codec->mfg;
 		codec->subsystem_id =
-			snd_hda_codec_read(codec, nid, 0,
+			snd_hda_codec_read(codec, fg, 0,
 					   AC_VERB_GET_SUBSYSTEM_ID, 0);
 	}
 
-	codec->epss = snd_hda_codec_get_supported_ps(codec,
-					codec->afg ? codec->afg : codec->mfg,
+#ifdef CONFIG_PM
+	codec->d3_stop_clk = snd_hda_codec_get_supported_ps(codec, fg,
+					AC_PWRST_CLKSTOP);
+	if (!codec->d3_stop_clk)
+		bus->power_keep_link_on = 1;
+#endif
+	codec->epss = snd_hda_codec_get_supported_ps(codec, fg,
 					AC_PWRST_EPSS);
 
 	/* power-up all before initialization */
-	hda_set_power_state(codec,
-			    codec->afg ? codec->afg : codec->mfg,
-			    AC_PWRST_D0);
+	hda_set_power_state(codec, AC_PWRST_D0);
 
 	snd_hda_codec_proc_new(codec);
 
@@ -2335,7 +2350,7 @@
 
 	/* OK, let it free */
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 	cancel_delayed_work_sync(&codec->power_work);
 	codec->power_on = 0;
 	codec->power_transition = 0;
@@ -3500,20 +3515,6 @@
 		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE,
 				    power_state);
 	}
-
-	if (power_state == AC_PWRST_D0) {
-		unsigned long end_time;
-		int state;
-		/* wait until the codec reachs to D0 */
-		end_time = jiffies + msecs_to_jiffies(500);
-		do {
-			state = snd_hda_codec_read(codec, fg, 0,
-						   AC_VERB_GET_POWER_STATE, 0);
-			if (state == power_state)
-				break;
-			msleep(1);
-		} while (time_after_eq(end_time, jiffies));
-	}
 }
 EXPORT_SYMBOL_HDA(snd_hda_codec_set_power_to_all);
 
@@ -3534,19 +3535,41 @@
 }
 
 /*
- * set power state of the codec
+ * wait until the state is reached, returns the current state
  */
-static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
-				unsigned int power_state)
+static unsigned int hda_sync_power_state(struct hda_codec *codec,
+					 hda_nid_t fg,
+					 unsigned int power_state)
 {
+	unsigned long end_time = jiffies + msecs_to_jiffies(500);
+	unsigned int state, actual_state;
+
+	for (;;) {
+		state = snd_hda_codec_read(codec, fg, 0,
+					   AC_VERB_GET_POWER_STATE, 0);
+		if (state & AC_PWRST_ERROR)
+			break;
+		actual_state = (state >> 4) & 0x0f;
+		if (actual_state == power_state)
+			break;
+		if (time_after_eq(jiffies, end_time))
+			break;
+		/* wait until the codec reachs to the target state */
+		msleep(1);
+	}
+	return state;
+}
+
+/*
+ * set power state of the codec, and return the power state
+ */
+static unsigned int hda_set_power_state(struct hda_codec *codec,
+					unsigned int power_state)
+{
+	hda_nid_t fg = codec->afg ? codec->afg : codec->mfg;
 	int count;
 	unsigned int state;
 
-	if (codec->patch_ops.set_power_state) {
-		codec->patch_ops.set_power_state(codec, fg, power_state);
-		return;
-	}
-
 	/* this delay seems necessary to avoid click noise at power-down */
 	if (power_state == AC_PWRST_D3) {
 		/* transition time less than 10ms for power down */
@@ -3555,14 +3578,22 @@
 
 	/* repeat power states setting at most 10 times*/
 	for (count = 0; count < 10; count++) {
-		snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
-				    power_state);
-		snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
-		state = snd_hda_codec_read(codec, fg, 0,
-					   AC_VERB_GET_POWER_STATE, 0);
+		if (codec->patch_ops.set_power_state)
+			codec->patch_ops.set_power_state(codec, fg,
+							 power_state);
+		else {
+			snd_hda_codec_read(codec, fg, 0,
+					   AC_VERB_SET_POWER_STATE,
+					   power_state);
+			snd_hda_codec_set_power_to_all(codec, fg, power_state,
+						       true);
+		}
+		state = hda_sync_power_state(codec, fg, power_state);
 		if (!(state & AC_PWRST_ERROR))
 			break;
 	}
+
+	return state;
 }
 
 #ifdef CONFIG_SND_HDA_HWDEP
@@ -3579,17 +3610,19 @@
 #ifdef CONFIG_PM
 /*
  * call suspend and power-down; used both from PM and power-save
+ * this function returns the power state in the end
  */
-static void hda_call_codec_suspend(struct hda_codec *codec)
+static unsigned int hda_call_codec_suspend(struct hda_codec *codec, bool in_wq)
 {
+	unsigned int state;
+
 	if (codec->patch_ops.suspend)
 		codec->patch_ops.suspend(codec);
 	hda_cleanup_all_streams(codec);
-	hda_set_power_state(codec,
-			    codec->afg ? codec->afg : codec->mfg,
-			    AC_PWRST_D3);
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-	cancel_delayed_work(&codec->power_work);
+	state = hda_set_power_state(codec, AC_PWRST_D3);
+	/* Cancel delayed work if we aren't currently running from it. */
+	if (!in_wq)
+		cancel_delayed_work_sync(&codec->power_work);
 	spin_lock(&codec->power_lock);
 	snd_hda_update_power_acct(codec);
 	trace_hda_power_down(codec);
@@ -3597,7 +3630,7 @@
 	codec->power_transition = 0;
 	codec->power_jiffies = jiffies;
 	spin_unlock(&codec->power_lock);
-#endif
+	return state;
 }
 
 /*
@@ -3609,9 +3642,7 @@
 	 * in the resume / power-save sequence
 	 */
 	hda_keep_power_on(codec);
-	hda_set_power_state(codec,
-			    codec->afg ? codec->afg : codec->mfg,
-			    AC_PWRST_D0);
+	hda_set_power_state(codec, AC_PWRST_D0);
 	restore_pincfgs(codec); /* restore all current pin configs */
 	restore_shutup_pins(codec);
 	hda_exec_init_verbs(codec);
@@ -3624,6 +3655,7 @@
 		snd_hda_codec_resume_amp(codec);
 		snd_hda_codec_resume_cache(codec);
 	}
+	snd_hda_jack_report_sync(codec);
 	snd_hda_power_down(codec); /* flag down before returning */
 }
 #endif /* CONFIG_PM */
@@ -3658,6 +3690,36 @@
 }
 EXPORT_SYMBOL_HDA(snd_hda_build_controls);
 
+/*
+ * add standard channel maps if not specified
+ */
+static int add_std_chmaps(struct hda_codec *codec)
+{
+	int i, str, err;
+
+	for (i = 0; i < codec->num_pcms; i++) {
+		for (str = 0; str < 2; str++) {
+			struct snd_pcm *pcm = codec->pcm_info[i].pcm;
+			struct hda_pcm_stream *hinfo =
+				&codec->pcm_info[i].stream[str];
+			struct snd_pcm_chmap *chmap;
+
+			if (codec->pcm_info[i].own_chmap)
+				continue;
+			if (!pcm || !hinfo->substreams)
+				continue;
+			err = snd_pcm_add_chmap_ctls(pcm, str,
+						     snd_pcm_std_chmaps,
+						     hinfo->channels_max,
+						     0, &chmap);
+			if (err < 0)
+				return err;
+			chmap->channel_mask = SND_PCM_CHMAP_MASK_2468;
+		}
+	}
+	return 0;
+}
+
 int snd_hda_codec_build_controls(struct hda_codec *codec)
 {
 	int err = 0;
@@ -3669,6 +3731,13 @@
 		err = codec->patch_ops.build_controls(codec);
 	if (err < 0)
 		return err;
+
+	/* we create chmaps here instead of build_pcms */
+	err = add_std_chmaps(codec);
+	if (err < 0)
+		return err;
+
+	snd_hda_jack_report_sync(codec); /* call at the last init point */
 	return 0;
 }
 
@@ -4211,7 +4280,7 @@
  *
  * This function returns 0 if successful, or a negative error code.
  */
-int __devinit snd_hda_build_pcms(struct hda_bus *bus)
+int snd_hda_build_pcms(struct hda_bus *bus)
 {
 	struct hda_codec *codec;
 
@@ -4391,12 +4460,13 @@
 }
 EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls);
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 static void hda_power_work(struct work_struct *work)
 {
 	struct hda_codec *codec =
 		container_of(work, struct hda_codec, power_work.work);
 	struct hda_bus *bus = codec->bus;
+	unsigned int state;
 
 	spin_lock(&codec->power_lock);
 	if (codec->power_transition > 0) { /* during power-up sequence? */
@@ -4410,9 +4480,12 @@
 	}
 	spin_unlock(&codec->power_lock);
 
-	hda_call_codec_suspend(codec);
-	if (bus->ops.pm_notify)
-		bus->ops.pm_notify(bus);
+	state = hda_call_codec_suspend(codec, true);
+	codec->pm_down_notified = 0;
+	if (!bus->power_keep_link_on && (state & AC_PWRST_CLK_STOP_OK)) {
+		codec->pm_down_notified = 1;
+		hda_call_pm_notify(bus, false);
+	}
 }
 
 static void hda_keep_power_on(struct hda_codec *codec)
@@ -4438,19 +4511,16 @@
 /* Transition to powered up, if wait_power_down then wait for a pending
  * transition to D3 to complete. A pending D3 transition is indicated
  * with power_transition == -1. */
+/* call this with codec->power_lock held! */
 static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down)
 {
 	struct hda_bus *bus = codec->bus;
 
-	spin_lock(&codec->power_lock);
-	codec->power_count++;
 	/* Return if power_on or transitioning to power_on, unless currently
 	 * powering down. */
 	if ((codec->power_on || codec->power_transition > 0) &&
-	    !(wait_power_down && codec->power_transition < 0)) {
-		spin_unlock(&codec->power_lock);
+	    !(wait_power_down && codec->power_transition < 0))
 		return;
-	}
 	spin_unlock(&codec->power_lock);
 
 	cancel_delayed_work_sync(&codec->power_work);
@@ -4462,9 +4532,9 @@
 	if (codec->power_on) {
 		if (codec->power_transition < 0)
 			codec->power_transition = 0;
-		spin_unlock(&codec->power_lock);
 		return;
 	}
+
 	trace_hda_power_up(codec);
 	snd_hda_update_power_acct(codec);
 	codec->power_on = 1;
@@ -4472,71 +4542,54 @@
 	codec->power_transition = 1; /* avoid reentrance */
 	spin_unlock(&codec->power_lock);
 
-	if (bus->ops.pm_notify)
-		bus->ops.pm_notify(bus);
+	if (codec->pm_down_notified) {
+		codec->pm_down_notified = 0;
+		hda_call_pm_notify(bus, true);
+	}
+
 	hda_call_codec_resume(codec);
 
 	spin_lock(&codec->power_lock);
 	codec->power_transition = 0;
-	spin_unlock(&codec->power_lock);
 }
 
-/**
- * snd_hda_power_up - Power-up the codec
- * @codec: HD-audio codec
- *
- * Increment the power-up counter and power up the hardware really when
- * not turned on yet.
- */
-void snd_hda_power_up(struct hda_codec *codec)
-{
-	__snd_hda_power_up(codec, false);
-}
-EXPORT_SYMBOL_HDA(snd_hda_power_up);
-
-/**
- * snd_hda_power_up_d3wait - Power-up the codec after waiting for any pending
- *   D3 transition to complete.  This differs from snd_hda_power_up() when
- *   power_transition == -1.  snd_hda_power_up sees this case as a nop,
- *   snd_hda_power_up_d3wait waits for the D3 transition to complete then powers
- *   back up.
- * @codec: HD-audio codec
- *
- * Cancel any power down operation hapenning on the work queue, then power up.
- */
-void snd_hda_power_up_d3wait(struct hda_codec *codec)
-{
-	/* This will cancel and wait for pending power_work to complete. */
-	__snd_hda_power_up(codec, true);
-}
-EXPORT_SYMBOL_HDA(snd_hda_power_up_d3wait);
-
 #define power_save(codec)	\
 	((codec)->bus->power_save ? *(codec)->bus->power_save : 0)
 
-/**
- * snd_hda_power_down - Power-down the codec
- * @codec: HD-audio codec
- *
- * Decrement the power-up counter and schedules the power-off work if
- * the counter rearches to zero.
- */
-void snd_hda_power_down(struct hda_codec *codec)
+/* Transition to powered down */
+static void __snd_hda_power_down(struct hda_codec *codec)
 {
-	spin_lock(&codec->power_lock);
-	--codec->power_count;
-	if (!codec->power_on || codec->power_count || codec->power_transition) {
-		spin_unlock(&codec->power_lock);
+	if (!codec->power_on || codec->power_count || codec->power_transition)
 		return;
-	}
+
 	if (power_save(codec)) {
 		codec->power_transition = -1; /* avoid reentrance */
 		queue_delayed_work(codec->bus->workq, &codec->power_work,
 				msecs_to_jiffies(power_save(codec) * 1000));
 	}
+}
+
+/**
+ * snd_hda_power_save - Power-up/down/sync the codec
+ * @codec: HD-audio codec
+ * @delta: the counter delta to change
+ *
+ * Change the power-up counter via @delta, and power up or down the hardware
+ * appropriately.  For the power-down, queue to the delayed action.
+ * Passing zero to @delta means to synchronize the power state.
+ */
+void snd_hda_power_save(struct hda_codec *codec, int delta, bool d3wait)
+{
+	spin_lock(&codec->power_lock);
+	codec->power_count += delta;
+	trace_hda_power_count(codec);
+	if (delta > 0)
+		__snd_hda_power_up(codec, d3wait);
+	else
+		__snd_hda_power_down(codec);
 	spin_unlock(&codec->power_lock);
 }
-EXPORT_SYMBOL_HDA(snd_hda_power_down);
+EXPORT_SYMBOL_HDA(snd_hda_power_save);
 
 /**
  * snd_hda_check_amp_list_power - Check the amp list and update the power
@@ -5076,7 +5129,7 @@
 
 	list_for_each_entry(codec, &bus->codec_list, list) {
 		if (hda_codec_is_power_on(codec))
-			hda_call_codec_suspend(codec);
+			hda_call_codec_suspend(codec, false);
 	}
 	return 0;
 }
@@ -5087,9 +5140,6 @@
  * @bus: the HDA bus
  *
  * Returns 0 if successful.
- *
- * This function is defined only when POWER_SAVE isn't set.
- * In the power-save mode, the codec is resumed dynamically.
  */
 int snd_hda_resume(struct hda_bus *bus)
 {
@@ -5118,6 +5168,8 @@
  */
 void *snd_array_new(struct snd_array *array)
 {
+	if (snd_BUG_ON(!array->elem_size))
+		return NULL;
 	if (array->used >= array->alloced) {
 		int num = array->alloced + array->alloc_align;
 		int size = (num + 1) * array->elem_size;
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index e5a7e19..507fe8a 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -386,6 +386,10 @@
 /* DIGITAL2 bits */
 #define AC_DIG2_CC			(0x7f<<0)
 
+/* DIGITAL3 bits */
+#define AC_DIG3_ICT			(0xf<<0)
+#define AC_DIG3_KAE			(1<<7)
+
 /* Pin widget control - 8bit */
 #define AC_PINCTL_EPT			(0x3<<0)
 #define AC_PINCTL_EPT_NATIVE		0
@@ -610,9 +614,9 @@
 			  struct hda_pcm *pcm);
 	/* reset bus for retry verb */
 	void (*bus_reset)(struct hda_bus *bus);
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 	/* notify power-up/down from codec to controller */
-	void (*pm_notify)(struct hda_bus *bus);
+	void (*pm_notify)(struct hda_bus *bus, bool power_up);
 #endif
 };
 
@@ -708,8 +712,6 @@
 #ifdef CONFIG_PM
 	int (*suspend)(struct hda_codec *codec);
 	int (*resume)(struct hda_codec *codec);
-#endif
-#ifdef CONFIG_SND_HDA_POWER_SAVE
 	int (*check_power_status)(struct hda_codec *codec, hda_nid_t nid);
 #endif
 	void (*reboot_notify)(struct hda_codec *codec);
@@ -774,6 +776,7 @@
 	unsigned int pcm_type;	/* HDA_PCM_TYPE_XXX */
 	int device;		/* device number to assign */
 	struct snd_pcm *pcm;	/* assigned PCM instance */
+	bool own_chmap;		/* codec driver provides own channel maps */
 };
 
 /* codec information */
@@ -859,12 +862,13 @@
 	unsigned int no_sticky_stream:1; /* no sticky-PCM stream assignment */
 	unsigned int pins_shutup:1;	/* pins are shut up */
 	unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */
-	unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */
 	unsigned int no_jack_detect:1;	/* Machine has no jack-detection */
 	unsigned int pcm_format_first:1; /* PCM format must be set first */
 	unsigned int epss:1;		/* supporting EPSS? */
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 	unsigned int power_on :1;	/* current (global) power-state */
+	unsigned int d3_stop_clk:1;	/* support D3 operation without BCLK */
+	unsigned int pm_down_notified:1; /* PM notified to controller */
 	int power_transition;	/* power-state in transition */
 	int power_count;	/* current (global) power refcount */
 	struct delayed_work power_work; /* delayed task for powerdown */
@@ -1042,7 +1046,7 @@
 static inline
 int hda_call_check_power_status(struct hda_codec *codec, hda_nid_t nid)
 {
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 	if (codec->patch_ops.check_power_status)
 		return codec->patch_ops.check_power_status(codec, nid);
 #endif
@@ -1059,22 +1063,70 @@
 /*
  * power saving
  */
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-void snd_hda_power_up(struct hda_codec *codec);
-void snd_hda_power_up_d3wait(struct hda_codec *codec);
-void snd_hda_power_down(struct hda_codec *codec);
+#ifdef CONFIG_PM
+void snd_hda_power_save(struct hda_codec *codec, int delta, bool d3wait);
 void snd_hda_update_power_acct(struct hda_codec *codec);
 #else
-static inline void snd_hda_power_up(struct hda_codec *codec) {}
-static inline void snd_hda_power_up_d3wait(struct hda_codec *codec) {}
-static inline void snd_hda_power_down(struct hda_codec *codec) {}
+static inline void snd_hda_power_save(struct hda_codec *codec, int delta,
+				      bool d3wait) {}
 #endif
 
+/**
+ * snd_hda_power_up - Power-up the codec
+ * @codec: HD-audio codec
+ *
+ * Increment the power-up counter and power up the hardware really when
+ * not turned on yet.
+ */
+static inline void snd_hda_power_up(struct hda_codec *codec)
+{
+	snd_hda_power_save(codec, 1, false);
+}
+
+/**
+ * snd_hda_power_up_d3wait - Power-up the codec after waiting for any pending
+ *   D3 transition to complete.  This differs from snd_hda_power_up() when
+ *   power_transition == -1.  snd_hda_power_up sees this case as a nop,
+ *   snd_hda_power_up_d3wait waits for the D3 transition to complete then powers
+ *   back up.
+ * @codec: HD-audio codec
+ *
+ * Cancel any power down operation hapenning on the work queue, then power up.
+ */
+static inline void snd_hda_power_up_d3wait(struct hda_codec *codec)
+{
+	snd_hda_power_save(codec, 1, true);
+}
+
+/**
+ * snd_hda_power_down - Power-down the codec
+ * @codec: HD-audio codec
+ *
+ * Decrement the power-up counter and schedules the power-off work if
+ * the counter rearches to zero.
+ */
+static inline void snd_hda_power_down(struct hda_codec *codec)
+{
+	snd_hda_power_save(codec, -1, false);
+}
+
+/**
+ * snd_hda_power_sync - Synchronize the power-save status
+ * @codec: HD-audio codec
+ *
+ * Synchronize the actual power state with the power account;
+ * called when power_save parameter is changed
+ */
+static inline void snd_hda_power_sync(struct hda_codec *codec)
+{
+	snd_hda_power_save(codec, 0, false);
+}
+
 #ifdef CONFIG_SND_HDA_PATCH_LOADER
 /*
  * patch firmware
  */
-int snd_hda_load_patch(struct hda_bus *bus, const char *patch);
+int snd_hda_load_patch(struct hda_bus *bus, size_t size, const void *buf);
 #endif
 
 /*
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 431bf86..b81d3d0 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -70,7 +70,7 @@
 
 	struct list_head nid_list;	/* list of widgets */
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 #define MAX_LOOPBACK_AMPS	7
 	struct hda_loopback_check loopback;
 	int num_loopbacks;
@@ -654,7 +654,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 static void add_input_loopback(struct hda_codec *codec, hda_nid_t nid,
 			       int dir, int idx)
 {
@@ -1028,7 +1028,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 static int generic_check_power_status(struct hda_codec *codec, hda_nid_t nid)
 {
 	struct hda_gspec *spec = codec->spec;
@@ -1043,7 +1043,7 @@
 	.build_controls = build_generic_controls,
 	.build_pcms = build_generic_pcms,
 	.free = snd_hda_generic_free,
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 	.check_power_status = generic_check_power_status,
 #endif
 };
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
index 6b2efb8..1af86d4 100644
--- a/sound/pci/hda/hda_hwdep.c
+++ b/sound/pci/hda/hda_hwdep.c
@@ -25,7 +25,6 @@
 #include <linux/mutex.h>
 #include <linux/ctype.h>
 #include <linux/string.h>
-#include <linux/firmware.h>
 #include <linux/export.h>
 #include <sound/core.h>
 #include "hda_codec.h"
@@ -156,7 +155,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 static ssize_t power_on_acct_show(struct device *dev,
 				  struct device_attribute *attr,
 				  char *buf)
@@ -192,7 +191,7 @@
 					  hwdep->device, &power_attrs[i]);
 	return 0;
 }
-#endif /* CONFIG_SND_HDA_POWER_SAVE */
+#endif /* CONFIG_PM */
 
 #ifdef CONFIG_SND_HDA_RECONFIG
 
@@ -747,18 +746,21 @@
  *
  * the spaces at the beginning and the end of the line are stripped
  */
-static int get_line_from_fw(char *buf, int size, struct firmware *fw)
+static int get_line_from_fw(char *buf, int size, size_t *fw_size_p,
+			    const void **fw_data_p)
 {
 	int len;
-	const char *p = fw->data;
-	while (isspace(*p) && fw->size) {
+	size_t fw_size = *fw_size_p;
+	const char *p = *fw_data_p;
+
+	while (isspace(*p) && fw_size) {
 		p++;
-		fw->size--;
+		fw_size--;
 	}
-	if (!fw->size)
+	if (!fw_size)
 		return 0;
 
-	for (len = 0; len < fw->size; len++) {
+	for (len = 0; len < fw_size; len++) {
 		if (!*p)
 			break;
 		if (*p == '\n') {
@@ -770,8 +772,8 @@
 			*buf++ = *p++;
 	}
 	*buf = 0;
-	fw->size -= len;
-	fw->data = p;
+	*fw_size_p = fw_size - len;
+	*fw_data_p = p;
 	remove_trail_spaces(buf);
 	return 1;
 }
@@ -779,29 +781,15 @@
 /*
  * load a "patch" firmware file and parse it
  */
-int snd_hda_load_patch(struct hda_bus *bus, const char *patch)
+int snd_hda_load_patch(struct hda_bus *bus, size_t fw_size, const void *fw_buf)
 {
-	int err;
-	const struct firmware *fw;
-	struct firmware tmp;
 	char buf[128];
 	struct hda_codec *codec;
 	int line_mode;
-	struct device *dev = bus->card->dev;
 
-	if (snd_BUG_ON(!dev))
-		return -ENODEV;
-	err = request_firmware(&fw, patch, dev);
-	if (err < 0) {
-		printk(KERN_ERR "hda-codec: Cannot load the patch '%s'\n",
-		       patch);
-		return err;
-	}
-
-	tmp = *fw;
 	line_mode = LINE_MODE_NONE;
 	codec = NULL;
-	while (get_line_from_fw(buf, sizeof(buf) - 1, &tmp)) {
+	while (get_line_from_fw(buf, sizeof(buf) - 1, &fw_size, &fw_buf)) {
 		if (!*buf || *buf == '#' || *buf == '\n')
 			continue;
 		if (*buf == '[')
@@ -810,7 +798,6 @@
 			 (codec || !patch_items[line_mode].need_codec))
 			patch_items[line_mode].parser(buf, bus, &codec);
 	}
-	release_firmware(fw);
 	return 0;
 }
 EXPORT_SYMBOL_HDA(snd_hda_load_patch);
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index c4763c5..6833835 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -46,6 +46,7 @@
 #include <linux/mutex.h>
 #include <linux/reboot.h>
 #include <linux/io.h>
+#include <linux/pm_runtime.h>
 #ifdef CONFIG_X86
 /* for snoop control */
 #include <asm/pgtable.h>
@@ -55,6 +56,7 @@
 #include <sound/initval.h>
 #include <linux/vgaarb.h>
 #include <linux/vga_switcheroo.h>
+#include <linux/firmware.h>
 #include "hda_codec.h"
 
 
@@ -62,7 +64,7 @@
 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
 static char *model[SNDRV_CARDS];
-static int position_fix[SNDRV_CARDS];
+static int position_fix[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
 static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
 static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
 static int probe_only[SNDRV_CARDS];
@@ -86,7 +88,7 @@
 MODULE_PARM_DESC(model, "Use the given board model.");
 module_param_array(position_fix, int, NULL, 0444);
 MODULE_PARM_DESC(position_fix, "DMA pointer read method."
-		 "(0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO).");
+		 "(-1 = system default, 0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO).");
 module_param_array(bdl_pos_adj, int, NULL, 0644);
 MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");
 module_param_array(probe_mask, int, NULL, 0444);
@@ -108,9 +110,16 @@
 			    "(0=off, 1=on) (default=1).");
 #endif
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
+static int param_set_xint(const char *val, const struct kernel_param *kp);
+static struct kernel_param_ops param_ops_xint = {
+	.set = param_set_xint,
+	.get = param_get_int,
+};
+#define param_check_xint param_check_int
+
 static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT;
-module_param(power_save, int, 0644);
+module_param(power_save, xint, 0644);
 MODULE_PARM_DESC(power_save, "Automatic power-saving timeout "
 		 "(in second, 0 = disable).");
 
@@ -121,7 +130,7 @@
 static bool power_save_controller = 1;
 module_param(power_save_controller, bool, 0644);
 MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode.");
-#endif
+#endif /* CONFIG_PM */
 
 static int align_buffer_size = -1;
 module_param(align_buffer_size, bint, 0644);
@@ -406,6 +415,7 @@
 	 */
 	unsigned int insufficient :1;
 	unsigned int wc_marked:1;
+	unsigned int no_period_wakeup:1;
 };
 
 /* CORB/RIRB */
@@ -471,6 +481,10 @@
 	struct snd_dma_buffer rb;
 	struct snd_dma_buffer posbuf;
 
+#ifdef CONFIG_SND_HDA_PATCH_LOADER
+	const struct firmware *fw;
+#endif
+
 	/* flags */
 	int position_fix[2]; /* for both playback/capture streams */
 	int poll_count;
@@ -498,6 +512,9 @@
 
 	/* reboot notifier (for mysterious hangup problem at power-down) */
 	struct notifier_block reboot_notifier;
+
+	/* card list (for power_save trigger) */
+	struct list_head list;
 };
 
 /* driver types */
@@ -537,7 +554,7 @@
 #define AZX_DCAPS_BUFSIZE	(1 << 21)	/* no buffer size alignment */
 #define AZX_DCAPS_ALIGN_BUFSIZE	(1 << 22)	/* buffer size alignment */
 #define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23)	/* BDLE in 4k boundary */
-#define AZX_DCAPS_POSFIX_COMBO  (1 << 24)	/* Use COMBO as default */
+#define AZX_DCAPS_COUNT_LPIB_DELAY  (1 << 25)	/* Take LPIB as delay */
 
 /* quirks for ATI SB / AMD Hudson */
 #define AZX_DCAPS_PRESET_ATI_SB \
@@ -560,13 +577,17 @@
  * VGA-switcher support
  */
 #ifdef SUPPORT_VGA_SWITCHEROO
+#define use_vga_switcheroo(chip)	((chip)->use_vga_switcheroo)
+#else
+#define use_vga_switcheroo(chip)	0
+#endif
+
+#if defined(SUPPORT_VGA_SWITCHEROO) || defined(CONFIG_SND_HDA_PATCH_LOADER)
 #define DELAYED_INIT_MARK
 #define DELAYED_INITDATA_MARK
-#define use_vga_switcheroo(chip)	((chip)->use_vga_switcheroo)
 #else
 #define DELAYED_INIT_MARK	__devinit
 #define DELAYED_INITDATA_MARK	__devinitdata
-#define use_vga_switcheroo(chip)	0
 #endif
 
 static char *driver_short_names[] DELAYED_INITDATA_MARK = {
@@ -1012,8 +1033,8 @@
 		return azx_rirb_get_response(bus, addr);
 }
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-static void azx_power_notify(struct hda_bus *bus);
+#ifdef CONFIG_PM
+static void azx_power_notify(struct hda_bus *bus, bool power_up);
 #endif
 
 /* reset codec link */
@@ -1269,6 +1290,11 @@
 	u8 sd_status;
 	int i, ok;
 
+#ifdef CONFIG_PM_RUNTIME
+	if (chip->pci->dev.power.runtime_status != RPM_ACTIVE)
+		return IRQ_NONE;
+#endif
+
 	spin_lock(&chip->reg_lock);
 
 	if (chip->disabled) {
@@ -1394,7 +1420,7 @@
 	ofs = 0;
 	azx_dev->frags = 0;
 	pos_adj = bdl_pos_adj[chip->dev_index];
-	if (pos_adj > 0) {
+	if (!azx_dev->no_period_wakeup && pos_adj > 0) {
 		struct snd_pcm_runtime *runtime = substream->runtime;
 		int pos_align = pos_adj;
 		pos_adj = (pos_adj * runtime->rate + 47999) / 48000;
@@ -1410,8 +1436,7 @@
 			pos_adj = 0;
 		} else {
 			ofs = setup_bdle(chip, substream, azx_dev,
-					 &bdl, ofs, pos_adj,
-					 !substream->runtime->no_period_wakeup);
+					 &bdl, ofs, pos_adj, true);
 			if (ofs < 0)
 				goto error;
 		}
@@ -1424,7 +1449,7 @@
 		else
 			ofs = setup_bdle(chip, substream, azx_dev, &bdl, ofs,
 					 period_bytes,
-					 !substream->runtime->no_period_wakeup);
+					 !azx_dev->no_period_wakeup);
 		if (ofs < 0)
 			goto error;
 	}
@@ -1580,7 +1605,7 @@
 	bus_temp.ops.get_response = azx_get_response;
 	bus_temp.ops.attach_pcm = azx_attach_pcm_stream;
 	bus_temp.ops.bus_reset = azx_bus_reset;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 	bus_temp.power_save = &power_save;
 	bus_temp.ops.pm_notify = azx_power_notify;
 #endif
@@ -1897,10 +1922,12 @@
 
 	if (bufsize != azx_dev->bufsize ||
 	    period_bytes != azx_dev->period_bytes ||
-	    format_val != azx_dev->format_val) {
+	    format_val != azx_dev->format_val ||
+	    runtime->no_period_wakeup != azx_dev->no_period_wakeup) {
 		azx_dev->bufsize = bufsize;
 		azx_dev->period_bytes = period_bytes;
 		azx_dev->format_val = format_val;
+		azx_dev->no_period_wakeup = runtime->no_period_wakeup;
 		err = azx_setup_periods(chip, substream, azx_dev);
 		if (err < 0)
 			return err;
@@ -1959,14 +1986,14 @@
 	}
 
 	spin_lock(&chip->reg_lock);
-	if (nsync > 1) {
-		/* first, set SYNC bits of corresponding streams */
-		if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC)
-			azx_writel(chip, OLD_SSYNC,
-				   azx_readl(chip, OLD_SSYNC) | sbits);
-		else
-			azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) | sbits);
-	}
+
+	/* first, set SYNC bits of corresponding streams */
+	if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC)
+		azx_writel(chip, OLD_SSYNC,
+			azx_readl(chip, OLD_SSYNC) | sbits);
+	else
+		azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) | sbits);
+
 	snd_pcm_group_for_each_entry(s, substream) {
 		if (s->pcm->card != substream->pcm->card)
 			continue;
@@ -1984,8 +2011,6 @@
 	}
 	spin_unlock(&chip->reg_lock);
 	if (start) {
-		if (nsync == 1)
-			return 0;
 		/* wait until all FIFOs get ready */
 		for (timeout = 5000; timeout; timeout--) {
 			nwait = 0;
@@ -2018,16 +2043,14 @@
 			cpu_relax();
 		}
 	}
-	if (nsync > 1) {
-		spin_lock(&chip->reg_lock);
-		/* reset SYNC bits */
-		if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC)
-			azx_writel(chip, OLD_SSYNC,
-				   azx_readl(chip, OLD_SSYNC) & ~sbits);
-		else
-			azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) & ~sbits);
-		spin_unlock(&chip->reg_lock);
-	}
+	spin_lock(&chip->reg_lock);
+	/* reset SYNC bits */
+	if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC)
+		azx_writel(chip, OLD_SSYNC,
+			azx_readl(chip, OLD_SSYNC) & ~sbits);
+	else
+		azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) & ~sbits);
+	spin_unlock(&chip->reg_lock);
 	return 0;
 }
 
@@ -2120,6 +2143,27 @@
 
 	if (pos >= azx_dev->bufsize)
 		pos = 0;
+
+	/* calculate runtime delay from LPIB */
+	if (azx_dev->substream->runtime &&
+	    chip->position_fix[stream] == POS_FIX_POSBUF &&
+	    (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) {
+		unsigned int lpib_pos = azx_sd_readl(azx_dev, SD_LPIB);
+		int delay;
+		if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+			delay = pos - lpib_pos;
+		else
+			delay = lpib_pos - pos;
+		if (delay < 0)
+			delay += azx_dev->bufsize;
+		if (delay >= azx_dev->period_bytes) {
+			snd_printdd("delay %d > period_bytes %d\n",
+				delay, azx_dev->period_bytes);
+			delay = 0; /* something is wrong */
+		}
+		azx_dev->substream->runtime->delay =
+			bytes_to_frames(azx_dev->substream->runtime, delay);
+	}
 	return pos;
 }
 
@@ -2379,33 +2423,65 @@
 	chip->initialized = 0;
 }
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 /* power-up/down the controller */
-static void azx_power_notify(struct hda_bus *bus)
+static void azx_power_notify(struct hda_bus *bus, bool power_up)
 {
 	struct azx *chip = bus->private_data;
-	struct hda_codec *c;
-	int power_on = 0;
 
-	list_for_each_entry(c, &bus->codec_list, list) {
-		if (c->power_on) {
-			power_on = 1;
-			break;
-		}
-	}
-	if (power_on)
-		azx_init_chip(chip, 1);
-	else if (chip->running && power_save_controller &&
-		 !bus->power_keep_link_on)
-		azx_stop_chip(chip);
+	if (power_up)
+		pm_runtime_get_sync(&chip->pci->dev);
+	else
+		pm_runtime_put_sync(&chip->pci->dev);
 }
-#endif /* CONFIG_SND_HDA_POWER_SAVE */
 
-#ifdef CONFIG_PM
+static DEFINE_MUTEX(card_list_lock);
+static LIST_HEAD(card_list);
+
+static void azx_add_card_list(struct azx *chip)
+{
+	mutex_lock(&card_list_lock);
+	list_add(&chip->list, &card_list);
+	mutex_unlock(&card_list_lock);
+}
+
+static void azx_del_card_list(struct azx *chip)
+{
+	mutex_lock(&card_list_lock);
+	list_del_init(&chip->list);
+	mutex_unlock(&card_list_lock);
+}
+
+/* trigger power-save check at writing parameter */
+static int param_set_xint(const char *val, const struct kernel_param *kp)
+{
+	struct azx *chip;
+	struct hda_codec *c;
+	int prev = power_save;
+	int ret = param_set_int(val, kp);
+
+	if (ret || prev == power_save)
+		return ret;
+
+	mutex_lock(&card_list_lock);
+	list_for_each_entry(chip, &card_list, list) {
+		if (!chip->bus || chip->disabled)
+			continue;
+		list_for_each_entry(c, &chip->bus->codec_list, list)
+			snd_hda_power_sync(c);
+	}
+	mutex_unlock(&card_list_lock);
+	return 0;
+}
+#else
+#define azx_add_card_list(chip) /* NOP */
+#define azx_del_card_list(chip) /* NOP */
+#endif /* CONFIG_PM */
+
+#if defined(CONFIG_PM_SLEEP) || defined(SUPPORT_VGA_SWITCHEROO)
 /*
  * power management
  */
-
 static int azx_suspend(struct device *dev)
 {
 	struct pci_dev *pci = to_pci_dev(dev);
@@ -2460,11 +2536,41 @@
 	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
 	return 0;
 }
-static SIMPLE_DEV_PM_OPS(azx_pm, azx_suspend, azx_resume);
+#endif /* CONFIG_PM_SLEEP || SUPPORT_VGA_SWITCHEROO */
+
+#ifdef CONFIG_PM_RUNTIME
+static int azx_runtime_suspend(struct device *dev)
+{
+	struct snd_card *card = dev_get_drvdata(dev);
+	struct azx *chip = card->private_data;
+
+	if (!power_save_controller)
+		return -EAGAIN;
+
+	azx_stop_chip(chip);
+	azx_clear_irq_pending(chip);
+	return 0;
+}
+
+static int azx_runtime_resume(struct device *dev)
+{
+	struct snd_card *card = dev_get_drvdata(dev);
+	struct azx *chip = card->private_data;
+
+	azx_init_pci(chip);
+	azx_init_chip(chip, 1);
+	return 0;
+}
+#endif /* CONFIG_PM_RUNTIME */
+
+#ifdef CONFIG_PM
+static const struct dev_pm_ops azx_pm = {
+	SET_SYSTEM_SLEEP_PM_OPS(azx_suspend, azx_resume)
+	SET_RUNTIME_PM_OPS(azx_runtime_suspend, azx_runtime_resume, NULL)
+};
+
 #define AZX_PM_OPS	&azx_pm
 #else
-#define azx_suspend(dev)
-#define azx_resume(dev)
 #define AZX_PM_OPS	NULL
 #endif /* CONFIG_PM */
 
@@ -2599,6 +2705,8 @@
 {
 	int i;
 
+	azx_del_card_list(chip);
+
 	azx_notifier_unregister(chip);
 
 	if (use_vga_switcheroo(chip)) {
@@ -2640,6 +2748,10 @@
 		pci_release_regions(chip->pci);
 	pci_disable_device(chip->pci);
 	kfree(chip->azx_dev);
+#ifdef CONFIG_SND_HDA_PATCH_LOADER
+	if (chip->fw)
+		release_firmware(chip->fw);
+#endif
 	kfree(chip);
 
 	return 0;
@@ -2719,6 +2831,7 @@
 	const struct snd_pci_quirk *q;
 
 	switch (fix) {
+	case POS_FIX_AUTO:
 	case POS_FIX_LPIB:
 	case POS_FIX_POSBUF:
 	case POS_FIX_VIACOMBO:
@@ -2744,10 +2857,6 @@
 		snd_printd(SFX "Using LPIB position fix\n");
 		return POS_FIX_LPIB;
 	}
-	if (chip->driver_caps & AZX_DCAPS_POSFIX_COMBO) {
-		snd_printd(SFX "Using COMBO position fix\n");
-		return POS_FIX_COMBO;
-	}
 	return POS_FIX_AUTO;
 }
 
@@ -2904,6 +3013,7 @@
 	chip->dev_index = dev;
 	INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work);
 	INIT_LIST_HEAD(&chip->pcm_list);
+	INIT_LIST_HEAD(&chip->list);
 	init_vga_switcheroo(chip);
 
 	chip->position_fix[0] = chip->position_fix[1] =
@@ -3138,7 +3248,7 @@
 
 static void power_down_all_codecs(struct azx *chip)
 {
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 	/* The codecs were powered up in snd_hda_codec_new().
 	 * Now all initialization done, so turn them down if possible
 	 */
@@ -3149,12 +3259,40 @@
 #endif
 }
 
+#ifdef CONFIG_SND_HDA_PATCH_LOADER
+/* callback from request_firmware_nowait() */
+static void azx_firmware_cb(const struct firmware *fw, void *context)
+{
+	struct snd_card *card = context;
+	struct azx *chip = card->private_data;
+	struct pci_dev *pci = chip->pci;
+
+	if (!fw) {
+		snd_printk(KERN_ERR SFX "Cannot load firmware, aborting\n");
+		goto error;
+	}
+
+	chip->fw = fw;
+	if (!chip->disabled) {
+		/* continue probing */
+		if (azx_probe_continue(chip))
+			goto error;
+	}
+	return; /* OK */
+
+ error:
+	snd_card_free(card);
+	pci_set_drvdata(pci, NULL);
+}
+#endif
+
 static int __devinit azx_probe(struct pci_dev *pci,
 			       const struct pci_device_id *pci_id)
 {
 	static int dev;
 	struct snd_card *card;
 	struct azx *chip;
+	bool probe_now;
 	int err;
 
 	if (dev >= SNDRV_CARDS)
@@ -3170,15 +3308,28 @@
 		return err;
 	}
 
-	/* set this here since it's referred in snd_hda_load_patch() */
 	snd_card_set_dev(card, &pci->dev);
 
 	err = azx_create(card, pci, dev, pci_id->driver_data, &chip);
 	if (err < 0)
 		goto out_free;
 	card->private_data = chip;
+	probe_now = !chip->disabled;
 
-	if (!chip->disabled) {
+#ifdef CONFIG_SND_HDA_PATCH_LOADER
+	if (patch[dev] && *patch[dev]) {
+		snd_printk(KERN_ERR SFX "Applying patch firmware '%s'\n",
+			   patch[dev]);
+		err = request_firmware_nowait(THIS_MODULE, true, patch[dev],
+					      &pci->dev, GFP_KERNEL, card,
+					      azx_firmware_cb);
+		if (err < 0)
+			goto out_free;
+		probe_now = false; /* continued in azx_firmware_cb() */
+	}
+#endif /* CONFIG_SND_HDA_PATCH_LOADER */
+
+	if (probe_now) {
 		err = azx_probe_continue(chip);
 		if (err < 0)
 			goto out_free;
@@ -3186,6 +3337,9 @@
 
 	pci_set_drvdata(pci, card);
 
+	if (pci_dev_run_wake(pci))
+		pm_runtime_put_noidle(&pci->dev);
+
 	dev++;
 	return 0;
 
@@ -3208,12 +3362,13 @@
 	if (err < 0)
 		goto out_free;
 #ifdef CONFIG_SND_HDA_PATCH_LOADER
-	if (patch[dev] && *patch[dev]) {
-		snd_printk(KERN_ERR SFX "Applying patch firmware '%s'\n",
-			   patch[dev]);
-		err = snd_hda_load_patch(chip->bus, patch[dev]);
+	if (chip->fw) {
+		err = snd_hda_load_patch(chip->bus, chip->fw->size,
+					 chip->fw->data);
 		if (err < 0)
 			goto out_free;
+		release_firmware(chip->fw); /* no longer needed */
+		chip->fw = NULL;
 	}
 #endif
 	if ((probe_only[dev] & 1) == 0) {
@@ -3239,6 +3394,7 @@
 	chip->running = 1;
 	power_down_all_codecs(chip);
 	azx_notifier_register(chip);
+	azx_add_card_list(chip);
 
 	return 0;
 
@@ -3250,6 +3406,10 @@
 static void __devexit azx_remove(struct pci_dev *pci)
 {
 	struct snd_card *card = pci_get_drvdata(pci);
+
+	if (pci_dev_run_wake(pci))
+		pm_runtime_get_noresume(&pci->dev);
+
 	if (card)
 		snd_card_free(card);
 	pci_set_drvdata(pci, NULL);
@@ -3260,7 +3420,7 @@
 	/* CPT */
 	{ PCI_DEVICE(0x8086, 0x1c20),
 	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
-	  AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
+	  AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
 	/* PBG */
 	{ PCI_DEVICE(0x8086, 0x1d20),
 	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
@@ -3268,23 +3428,30 @@
 	/* Panther Point */
 	{ PCI_DEVICE(0x8086, 0x1e20),
 	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
-	  AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
+	  AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
 	/* Lynx Point */
 	{ PCI_DEVICE(0x8086, 0x8c20),
 	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
-	  AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
+	  AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
 	/* Lynx Point-LP */
 	{ PCI_DEVICE(0x8086, 0x9c20),
 	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
-	  AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
+	  AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
 	/* Lynx Point-LP */
 	{ PCI_DEVICE(0x8086, 0x9c21),
 	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
-	  AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
+	  AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
 	/* Haswell */
 	{ PCI_DEVICE(0x8086, 0x0c0c),
 	  .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
-	  AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
+	  AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
+	{ PCI_DEVICE(0x8086, 0x0d0c),
+	  .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
+	  AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
+	/* 5 Series/3400 */
+	{ PCI_DEVICE(0x8086, 0x3b56),
+	  .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
+	  AZX_DCAPS_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY },
 	/* SCH */
 	{ PCI_DEVICE(0x8086, 0x811b),
 	  .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
index aaccc02..5c690cb 100644
--- a/sound/pci/hda/hda_jack.c
+++ b/sound/pci/hda/hda_jack.c
@@ -26,9 +26,8 @@
 		return false;
 	if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT))
 		return false;
-	if (!codec->ignore_misc_bit &&
-	    (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
-	     AC_DEFCFG_MISC_NO_PRESENCE))
+	if (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
+	     AC_DEFCFG_MISC_NO_PRESENCE)
 		return false;
 	if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP))
 		return false;
@@ -193,8 +192,9 @@
 /**
  * snd_hda_jack_detect_enable - enable the jack-detection
  */
-int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
-			       unsigned char action)
+int snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid,
+					unsigned char action,
+					hda_jack_callback cb)
 {
 	struct hda_jack_tbl *jack = snd_hda_jack_tbl_new(codec, nid);
 	if (!jack)
@@ -204,10 +204,19 @@
 	jack->jack_detect = 1;
 	if (action)
 		jack->action = action;
+	if (cb)
+		jack->callback = cb;
 	return snd_hda_codec_write_cache(codec, nid, 0,
 					 AC_VERB_SET_UNSOLICITED_ENABLE,
 					 AC_USRSP_EN | jack->tag);
 }
+EXPORT_SYMBOL_HDA(snd_hda_jack_detect_enable_callback);
+
+int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
+			       unsigned char action)
+{
+	return snd_hda_jack_detect_enable_callback(codec, nid, action, NULL);
+}
 EXPORT_SYMBOL_HDA(snd_hda_jack_detect_enable);
 
 /**
@@ -412,3 +421,21 @@
 	return 0;
 }
 EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctls);
+
+void snd_hda_jack_unsol_event(struct hda_codec *codec, unsigned int res)
+{
+	struct hda_jack_tbl *event;
+	int tag = (res >> AC_UNSOL_RES_TAG_SHIFT) & 0x7f;
+
+	event = snd_hda_jack_tbl_get_from_tag(codec, tag);
+	if (!event)
+		return;
+	event->jack_dirty = 1;
+
+	if (event->callback)
+		event->callback(codec, event);
+
+	snd_hda_jack_report_sync(codec);
+}
+EXPORT_SYMBOL_HDA(snd_hda_jack_unsol_event);
+
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h
index a9803da..af8dd47 100644
--- a/sound/pci/hda/hda_jack.h
+++ b/sound/pci/hda/hda_jack.h
@@ -13,12 +13,16 @@
 #define __SOUND_HDA_JACK_H
 
 struct auto_pin_cfg;
+struct hda_jack_tbl;
+
+typedef void (*hda_jack_callback) (struct hda_codec *, struct hda_jack_tbl *);
 
 struct hda_jack_tbl {
 	hda_nid_t nid;
 	unsigned char action;		/* event action (0 = none) */
 	unsigned char tag;		/* unsol event tag */
 	unsigned int private_data;	/* arbitrary data */
+	hda_jack_callback callback;
 	/* jack-detection stuff */
 	unsigned int pin_sense;		/* cached pin-sense value */
 	unsigned int jack_detect:1;	/* capable of jack-detection? */
@@ -61,6 +65,10 @@
 
 int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid,
 			       unsigned char action);
+int snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid,
+					unsigned char action,
+					hda_jack_callback cb);
+
 
 u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid);
 int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
@@ -74,5 +82,6 @@
 
 void snd_hda_jack_report_sync(struct hda_codec *codec);
 
+void snd_hda_jack_unsol_event(struct hda_codec *codec, unsigned int res);
 
 #endif /* __SOUND_HDA_JACK_H */
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 1b4c129..09dbdc3 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -529,7 +529,7 @@
 static inline int snd_hda_create_hwdep(struct hda_codec *codec) { return 0; }
 #endif
 
-#if defined(CONFIG_SND_HDA_POWER_SAVE) && defined(CONFIG_SND_HDA_HWDEP)
+#if defined(CONFIG_PM) && defined(CONFIG_SND_HDA_HWDEP)
 int snd_hda_hwdep_add_power_sysfs(struct hda_codec *codec);
 #else
 static inline int snd_hda_hwdep_add_power_sysfs(struct hda_codec *codec)
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index 6894ec6..045e5d3 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -402,6 +402,9 @@
 {
 	unsigned int digi1 = snd_hda_codec_read(codec, nid, 0,
 						AC_VERB_GET_DIGI_CONVERT_1, 0);
+	unsigned char digi2 = digi1 >> 8;
+	unsigned char digi3 = digi1 >> 16;
+
 	snd_iprintf(buffer, "  Digital:");
 	if (digi1 & AC_DIG1_ENABLE)
 		snd_iprintf(buffer, " Enabled");
@@ -419,9 +422,13 @@
 		snd_iprintf(buffer, " Pro");
 	if (digi1 & AC_DIG1_LEVEL)
 		snd_iprintf(buffer, " GenLevel");
+	if (digi3 & AC_DIG3_KAE)
+		snd_iprintf(buffer, " KAE");
 	snd_iprintf(buffer, "\n");
 	snd_iprintf(buffer, "  Digital category: 0x%x\n",
-		    (digi1 >> 8) & AC_DIG2_CC);
+		    digi2 & AC_DIG2_CC);
+	snd_iprintf(buffer, "  IEC Coding Type: 0x%x\n",
+			digi3 & AC_DIG3_ICT);
 }
 
 static const char *get_pwr_state(u32 state)
diff --git a/sound/pci/hda/hda_trace.h b/sound/pci/hda/hda_trace.h
index 9884871..3a1c631 100644
--- a/sound/pci/hda/hda_trace.h
+++ b/sound/pci/hda/hda_trace.h
@@ -58,6 +58,7 @@
 	TP_printk("[%d]", __entry->card)
 );
 
+#ifdef CONFIG_PM
 DECLARE_EVENT_CLASS(hda_power,
 
 	TP_PROTO(struct hda_codec *codec),
@@ -87,6 +88,31 @@
 	TP_ARGS(codec)
 );
 
+TRACE_EVENT(hda_power_count,
+	TP_PROTO(struct hda_codec *codec),
+	TP_ARGS(codec),
+	TP_STRUCT__entry(
+		__field( unsigned int, card )
+		__field( unsigned int, addr )
+		__field( int, power_count )
+		__field( int, power_on )
+		__field( int, power_transition )
+	),
+
+	TP_fast_assign(
+		__entry->card = (codec)->bus->card->number;
+		__entry->addr = (codec)->addr;
+		__entry->power_count = (codec)->power_count;
+		__entry->power_on = (codec)->power_on;
+		__entry->power_transition = (codec)->power_transition;
+	),
+
+	TP_printk("[%d:%d] power_count=%d, power_on=%d, power_transition=%d",
+		  __entry->card, __entry->addr, __entry->power_count,
+		  __entry->power_on, __entry->power_transition)
+);
+#endif /* CONFIG_PM */
+
 TRACE_EVENT(hda_unsol_event,
 
 	TP_PROTO(struct hda_bus *bus, u32 res, u32 res_ex),
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 0208fa1..cdd43ea 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -85,7 +85,7 @@
 	unsigned int analog_beep: 1;	/* analog beep input present */
 	unsigned int avoid_init_slave_vol:1;
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 	struct hda_loopback_check loopback;
 #endif
 	/* for virtual master */
@@ -269,7 +269,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 static int ad198x_check_power_status(struct hda_codec *codec, hda_nid_t nid)
 {
 	struct ad198x_spec *spec = codec->spec;
@@ -654,10 +654,8 @@
 	.build_pcms = ad198x_build_pcms,
 	.init = ad198x_init,
 	.free = ad198x_free,
-#ifdef CONFIG_SND_HDA_POWER_SAVE
-	.check_power_status = ad198x_check_power_status,
-#endif
 #ifdef CONFIG_PM
+	.check_power_status = ad198x_check_power_status,
 	.suspend = ad198x_suspend,
 #endif
 	.reboot_notify = ad198x_shutup,
@@ -1231,7 +1229,7 @@
 	{}
 };
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 static const struct hda_amp_list ad1986a_loopbacks[] = {
 	{ 0x13, HDA_OUTPUT, 0 }, /* Mic */
 	{ 0x14, HDA_OUTPUT, 0 }, /* Phone */
@@ -1278,7 +1276,7 @@
 	spec->mixers[0] = ad1986a_mixers;
 	spec->num_init_verbs = 1;
 	spec->init_verbs[0] = ad1986a_init_verbs;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 	spec->loopback.amplist = ad1986a_loopbacks;
 #endif
 	spec->vmaster_nid = 0x1b;
@@ -1537,7 +1535,7 @@
 	{ } /* end */
 };
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 static const struct hda_amp_list ad1983_loopbacks[] = {
 	{ 0x12, HDA_OUTPUT, 0 }, /* Mic */
 	{ 0x13, HDA_OUTPUT, 0 }, /* Line */
@@ -1576,7 +1574,7 @@
 	spec->num_init_verbs = 1;
 	spec->init_verbs[0] = ad1983_init_verbs;
 	spec->spdif_route = 0;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 	spec->loopback.amplist = ad1983_loopbacks;
 #endif
 	spec->vmaster_nid = 0x05;
@@ -1704,7 +1702,7 @@
 	{ } /* end */
 };
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 static const struct hda_amp_list ad1981_loopbacks[] = {
 	{ 0x12, HDA_OUTPUT, 0 }, /* Front Mic */
 	{ 0x13, HDA_OUTPUT, 0 }, /* Line */
@@ -1812,7 +1810,7 @@
 	.num_items = 3,
 	.items = {
 		{ "Mic", 0x0 },
-		{ "Docking-Station", 0x1 },
+		{ "Dock Mic", 0x1 },
 		{ "Mix", 0x2 },
 	},
 };
@@ -1836,8 +1834,8 @@
 	 */
 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
 	HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
-	HDA_CODEC_VOLUME("Docking-Station Playback Volume", 0x13, 0x0, HDA_OUTPUT),
-	HDA_CODEC_MUTE("Docking-Station Playback Switch", 0x13, 0x0, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
+	HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
 	HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
 	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
 	/* FIXME: does this laptop have analog CD connection? */
@@ -1982,7 +1980,7 @@
 	spec->num_init_verbs = 1;
 	spec->init_verbs[0] = ad1981_init_verbs;
 	spec->spdif_route = 0;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 	spec->loopback.amplist = ad1981_loopbacks;
 #endif
 	spec->vmaster_nid = 0x05;
@@ -2807,7 +2805,7 @@
 		snd_hda_sequence_write(codec, ad1988_laptop_hp_off);
 } 
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 static const struct hda_amp_list ad1988_loopbacks[] = {
 	{ 0x20, HDA_INPUT, 0 }, /* Front Mic */
 	{ 0x20, HDA_INPUT, 1 }, /* Line */
@@ -3399,7 +3397,7 @@
 		codec->patch_ops.unsol_event = ad1988_laptop_unsol_event;
 		break;
 	}
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 	spec->loopback.amplist = ad1988_loopbacks;
 #endif
 	spec->vmaster_nid = 0x04;
@@ -3555,7 +3553,7 @@
 	{ } /* end */
 };
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 static const struct hda_amp_list ad1884_loopbacks[] = {
 	{ 0x20, HDA_INPUT, 0 }, /* Front Mic */
 	{ 0x20, HDA_INPUT, 1 }, /* Mic */
@@ -3567,7 +3565,7 @@
 
 static const char * const ad1884_slave_vols[] = {
 	"PCM", "Mic", "Mono", "Front Mic", "Mic", "CD",
-	"Internal Mic", "Docking Mic", /* "Beep", */ "IEC958",
+	"Internal Mic", "Dock Mic", /* "Beep", */ "IEC958",
 	NULL
 };
 
@@ -3602,7 +3600,7 @@
 	spec->num_init_verbs = 1;
 	spec->init_verbs[0] = ad1884_init_verbs;
 	spec->spdif_route = 0;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 	spec->loopback.amplist = ad1884_loopbacks;
 #endif
 	spec->vmaster_nid = 0x04;
@@ -3628,7 +3626,7 @@
 		{ "Mic", 0x0 },
 		{ "Internal Mic", 0x1 },
 		{ "Mix", 0x3 },
-		{ "Docking-Station", 0x4 },
+		{ "Dock Mic", 0x4 },
 	},
 };
 
@@ -3657,8 +3655,8 @@
 	HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
 	HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
 	HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
-	HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
-	HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
+	HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
+	HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
 	HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
 	HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
 	HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
@@ -3994,7 +3992,7 @@
 	{ } /* end */
 };
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 static const struct hda_amp_list ad1884a_loopbacks[] = {
 	{ 0x20, HDA_INPUT, 0 }, /* Front Mic */
 	{ 0x20, HDA_INPUT, 1 }, /* Mic */
@@ -4602,7 +4600,7 @@
 	spec->num_init_verbs = 1;
 	spec->init_verbs[0] = ad1884a_init_verbs;
 	spec->spdif_route = 0;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 	spec->loopback.amplist = ad1884a_loopbacks;
 #endif
 	codec->patch_ops = ad198x_patch_ops;
@@ -4814,6 +4812,32 @@
 	{ } /* end */
 };
 
+/* simple auto-mute control for AD1882 3-stack board */
+#define AD1882_HP_EVENT	0x01
+
+static void ad1882_3stack_automute(struct hda_codec *codec)
+{
+	bool mute = snd_hda_jack_detect(codec, 0x11);
+	snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
+			    mute ? 0 : PIN_OUT);
+}
+
+static int ad1882_3stack_automute_init(struct hda_codec *codec)
+{
+	ad198x_init(codec);
+	ad1882_3stack_automute(codec);
+	return 0;
+}
+
+static void ad1882_3stack_unsol_event(struct hda_codec *codec, unsigned int res)
+{
+	switch (res >> 26) {
+	case AD1882_HP_EVENT:
+		ad1882_3stack_automute(codec);
+		break;
+	}
+}
+
 static const struct snd_kcontrol_new ad1882_6stack_mixers[] = {
 	HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT),
 	HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT),
@@ -4928,7 +4952,12 @@
 	{ } /* end */
 };
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+static const struct hda_verb ad1882_3stack_automute_verbs[] = {
+	{0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1882_HP_EVENT},
+	{ } /* end */
+};
+
+#ifdef CONFIG_PM
 static const struct hda_amp_list ad1882_loopbacks[] = {
 	{ 0x20, HDA_INPUT, 0 }, /* Front Mic */
 	{ 0x20, HDA_INPUT, 1 }, /* Mic */
@@ -4942,12 +4971,14 @@
 enum {
 	AD1882_3STACK,
 	AD1882_6STACK,
+	AD1882_3STACK_AUTOMUTE,
 	AD1882_MODELS
 };
 
 static const char * const ad1882_models[AD1986A_MODELS] = {
 	[AD1882_3STACK]		= "3stack",
 	[AD1882_6STACK]		= "6stack",
+	[AD1882_3STACK_AUTOMUTE] = "3stack-automute",
 };
 
 
@@ -4989,7 +5020,7 @@
 	spec->num_init_verbs = 1;
 	spec->init_verbs[0] = ad1882_init_verbs;
 	spec->spdif_route = 0;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 	spec->loopback.amplist = ad1882_loopbacks;
 #endif
 	spec->vmaster_nid = 0x04;
@@ -5002,6 +5033,7 @@
 	switch (board_config) {
 	default:
 	case AD1882_3STACK:
+	case AD1882_3STACK_AUTOMUTE:
 		spec->num_mixers = 3;
 		spec->mixers[2] = ad1882_3stack_mixers;
 		spec->channel_mode = ad1882_modes;
@@ -5009,6 +5041,12 @@
 		spec->need_dac_fix = 1;
 		spec->multiout.max_channels = 2;
 		spec->multiout.num_dacs = 1;
+		if (board_config != AD1882_3STACK) {
+			spec->init_verbs[spec->num_init_verbs++] =
+				ad1882_3stack_automute_verbs;
+			codec->patch_ops.unsol_event = ad1882_3stack_unsol_event;
+			codec->patch_ops.init = ad1882_3stack_automute_init;
+		}
 		break;
 	case AD1882_6STACK:
 		spec->num_mixers = 3;
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 0c4c1a6..61a7113 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -34,7 +34,8 @@
  */
 
 struct cs_spec {
-	int board_config;
+	struct hda_gen_spec gen;
+
 	struct auto_pin_cfg autocfg;
 	struct hda_multi_out multiout;
 	struct snd_kcontrol *vmaster_sw;
@@ -80,16 +81,20 @@
 	CS420X_MBP53,
 	CS420X_MBP55,
 	CS420X_IMAC27,
-	CS420X_IMAC27_122,
-	CS420X_APPLE,
+	CS420X_GPIO_13,
+	CS420X_GPIO_23,
+	CS420X_MBP101,
+	CS420X_MBP101_COEF,
 	CS420X_AUTO,
-	CS420X_MODELS
+	/* aliases */
+	CS420X_IMAC27_122 = CS420X_GPIO_23,
+	CS420X_APPLE = CS420X_GPIO_13,
 };
 
 /* CS421x boards */
 enum {
 	CS421X_CDB4210,
-	CS421X_MODELS
+	CS421X_SENSE_B,
 };
 
 /* Vendor-specific processing widget */
@@ -892,7 +897,7 @@
  * HP/SPK/SPDIF
  */
 
-static void cs_automute(struct hda_codec *codec)
+static void cs_automute(struct hda_codec *codec, struct hda_jack_tbl *tbl)
 {
 	struct cs_spec *spec = codec->spec;
 	struct auto_pin_cfg *cfg = &spec->autocfg;
@@ -968,7 +973,7 @@
  * Switch max 3 inputs of a single ADC (nid 3)
 */
 
-static void cs_automic(struct hda_codec *codec)
+static void cs_automic(struct hda_codec *codec, struct hda_jack_tbl *tbl)
 {
 	struct cs_spec *spec = codec->spec;
 	struct auto_pin_cfg *cfg = &spec->autocfg;
@@ -1030,7 +1035,7 @@
 		if (!cfg->speaker_outs)
 			continue;
 		if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
-			snd_hda_jack_detect_enable(codec, nid, HP_EVENT);
+			snd_hda_jack_detect_enable_callback(codec, nid, HP_EVENT, cs_automute);
 			spec->hp_detect = 1;
 		}
 	}
@@ -1041,7 +1046,7 @@
 
 	/* SPDIF is enabled on presence detect for CS421x */
 	if (spec->hp_detect || spec->spdif_detect)
-		cs_automute(codec);
+		cs_automute(codec, NULL);
 }
 
 static void init_input(struct hda_codec *codec)
@@ -1065,13 +1070,13 @@
 				    AC_VERB_SET_AMP_GAIN_MUTE,
 				    AMP_IN_MUTE(spec->adc_idx[i]));
 		if (spec->mic_detect && spec->automic_idx == i)
-			snd_hda_jack_detect_enable(codec, pin, MIC_EVENT);
+			snd_hda_jack_detect_enable_callback(codec, pin, MIC_EVENT, cs_automic);
 	}
 	/* CS420x has multiple ADC, CS421x has single ADC */
 	if (spec->vendor_nid == CS420X_VENDOR_NID) {
 		change_cur_input(codec, spec->cur_input, 1);
 		if (spec->mic_detect)
-			cs_automic(codec);
+			cs_automic(codec, NULL);
 
 		coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */
 		if (is_active_pin(codec, CS_DMIC2_PIN_NID))
@@ -1084,7 +1089,7 @@
 		cs_vendor_coef_set(codec, IDX_ADC_CFG, coef);
 	} else {
 		if (spec->mic_detect)
-			cs_automic(codec);
+			cs_automic(codec, NULL);
 		else  {
 			spec->cur_adc = spec->adc_nid[spec->cur_input];
 			cs_update_input_select(codec);
@@ -1157,6 +1162,14 @@
 	{} /* terminator */
 };
 
+static const struct hda_verb mbp101_init_verbs[] = {
+	{0x11, AC_VERB_SET_COEF_INDEX, 0x0002},
+	{0x11, AC_VERB_SET_PROC_COEF, 0x100a},
+	{0x11, AC_VERB_SET_COEF_INDEX, 0x0004},
+	{0x11, AC_VERB_SET_PROC_COEF, 0x000f},
+	{}
+};
+
 /* SPDIF setup */
 static void init_digital(struct hda_codec *codec)
 {
@@ -1193,7 +1206,6 @@
 	init_output(codec);
 	init_input(codec);
 	init_digital(codec);
-	snd_hda_jack_report_sync(codec);
 
 	return 0;
 }
@@ -1231,28 +1243,16 @@
 	struct cs_spec *spec = codec->spec;
 	kfree(spec->capture_bind[0]);
 	kfree(spec->capture_bind[1]);
+	snd_hda_gen_free(&spec->gen);
 	kfree(codec->spec);
 }
 
-static void cs_unsol_event(struct hda_codec *codec, unsigned int res)
-{
-	switch (snd_hda_jack_get_action(codec, res >> 26)) {
-	case HP_EVENT:
-		cs_automute(codec);
-		break;
-	case MIC_EVENT:
-		cs_automic(codec);
-		break;
-	}
-	snd_hda_jack_report_sync(codec);
-}
-
 static const struct hda_codec_ops cs_patch_ops = {
 	.build_controls = cs_build_controls,
 	.build_pcms = cs_build_pcms,
 	.init = cs_init,
 	.free = cs_free,
-	.unsol_event = cs_unsol_event,
+	.unsol_event = snd_hda_jack_unsol_event,
 };
 
 static int cs_parse_auto_config(struct hda_codec *codec)
@@ -1279,38 +1279,32 @@
 	return 0;
 }
 
-static const char * const cs420x_models[CS420X_MODELS] = {
-	[CS420X_MBP53] = "mbp53",
-	[CS420X_MBP55] = "mbp55",
-	[CS420X_IMAC27] = "imac27",
-	[CS420X_IMAC27_122] = "imac27_122",
-	[CS420X_APPLE] = "apple",
-	[CS420X_AUTO] = "auto",
+static const struct hda_model_fixup cs420x_models[] = {
+	{ .id = CS420X_MBP53, .name = "mbp53" },
+	{ .id = CS420X_MBP55, .name = "mbp55" },
+	{ .id = CS420X_IMAC27, .name = "imac27" },
+	{ .id = CS420X_IMAC27_122, .name = "imac27_122" },
+	{ .id = CS420X_APPLE, .name = "apple" },
+	{ .id = CS420X_MBP101, .name = "mbp101" },
+	{}
 };
 
-
-static const struct snd_pci_quirk cs420x_cfg_tbl[] = {
+static const struct snd_pci_quirk cs420x_fixup_tbl[] = {
 	SND_PCI_QUIRK(0x10de, 0x0ac0, "MacBookPro 5,3", CS420X_MBP53),
 	SND_PCI_QUIRK(0x10de, 0x0d94, "MacBookAir 3,1(2)", CS420X_MBP55),
 	SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55),
 	SND_PCI_QUIRK(0x10de, 0xcb89, "MacBookPro 7,1", CS420X_MBP55),
 	/* this conflicts with too many other models */
 	/*SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27),*/
-	{} /* terminator */
-};
 
-static const struct snd_pci_quirk cs420x_codec_cfg_tbl[] = {
+	/* codec SSID */
 	SND_PCI_QUIRK(0x106b, 0x2000, "iMac 12,2", CS420X_IMAC27_122),
+	SND_PCI_QUIRK(0x106b, 0x2800, "MacBookPro 10,1", CS420X_MBP101),
 	SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE),
 	{} /* terminator */
 };
 
-struct cs_pincfg {
-	hda_nid_t nid;
-	u32 val;
-};
-
-static const struct cs_pincfg mbp53_pincfgs[] = {
+static const struct hda_pintbl mbp53_pincfgs[] = {
 	{ 0x09, 0x012b4050 },
 	{ 0x0a, 0x90100141 },
 	{ 0x0b, 0x90100140 },
@@ -1324,7 +1318,7 @@
 	{} /* terminator */
 };
 
-static const struct cs_pincfg mbp55_pincfgs[] = {
+static const struct hda_pintbl mbp55_pincfgs[] = {
 	{ 0x09, 0x012b4030 },
 	{ 0x0a, 0x90100121 },
 	{ 0x0b, 0x90100120 },
@@ -1338,7 +1332,7 @@
 	{} /* terminator */
 };
 
-static const struct cs_pincfg imac27_pincfgs[] = {
+static const struct hda_pintbl imac27_pincfgs[] = {
 	{ 0x09, 0x012b4050 },
 	{ 0x0a, 0x90100140 },
 	{ 0x0b, 0x90100142 },
@@ -1352,22 +1346,78 @@
 	{} /* terminator */
 };
 
-static const struct cs_pincfg *cs_pincfgs[CS420X_MODELS] = {
-	[CS420X_MBP53] = mbp53_pincfgs,
-	[CS420X_MBP55] = mbp55_pincfgs,
-	[CS420X_IMAC27] = imac27_pincfgs,
+static const struct hda_pintbl mbp101_pincfgs[] = {
+	{ 0x0d, 0x40ab90f0 },
+	{ 0x0e, 0x90a600f0 },
+	{ 0x12, 0x50a600f0 },
+	{} /* terminator */
 };
 
-static void fix_pincfg(struct hda_codec *codec, int model,
-		       const struct cs_pincfg **pin_configs)
+static void cs420x_fixup_gpio_13(struct hda_codec *codec,
+				 const struct hda_fixup *fix, int action)
 {
-	const struct cs_pincfg *cfg = pin_configs[model];
-	if (!cfg)
-		return;
-	for (; cfg->nid; cfg++)
-		snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
+	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
+		struct cs_spec *spec = codec->spec;
+		spec->gpio_eapd_hp = 2; /* GPIO1 = headphones */
+		spec->gpio_eapd_speaker = 8; /* GPIO3 = speakers */
+		spec->gpio_mask = spec->gpio_dir =
+			spec->gpio_eapd_hp | spec->gpio_eapd_speaker;
+	}
 }
 
+static void cs420x_fixup_gpio_23(struct hda_codec *codec,
+				 const struct hda_fixup *fix, int action)
+{
+	if (action == HDA_FIXUP_ACT_PRE_PROBE) {
+		struct cs_spec *spec = codec->spec;
+		spec->gpio_eapd_hp = 4; /* GPIO2 = headphones */
+		spec->gpio_eapd_speaker = 8; /* GPIO3 = speakers */
+		spec->gpio_mask = spec->gpio_dir =
+			spec->gpio_eapd_hp | spec->gpio_eapd_speaker;
+	}
+}
+
+static const struct hda_fixup cs420x_fixups[] = {
+	[CS420X_MBP53] = {
+		.type = HDA_FIXUP_PINS,
+		.v.pins = mbp53_pincfgs,
+		.chained = true,
+		.chain_id = CS420X_APPLE,
+	},
+	[CS420X_MBP55] = {
+		.type = HDA_FIXUP_PINS,
+		.v.pins = mbp55_pincfgs,
+		.chained = true,
+		.chain_id = CS420X_GPIO_13,
+	},
+	[CS420X_IMAC27] = {
+		.type = HDA_FIXUP_PINS,
+		.v.pins = imac27_pincfgs,
+		.chained = true,
+		.chain_id = CS420X_GPIO_13,
+	},
+	[CS420X_GPIO_13] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = cs420x_fixup_gpio_13,
+	},
+	[CS420X_GPIO_23] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = cs420x_fixup_gpio_23,
+	},
+	[CS420X_MBP101] = {
+		.type = HDA_FIXUP_PINS,
+		.v.pins = mbp101_pincfgs,
+		.chained = true,
+		.chain_id = CS420X_MBP101_COEF,
+	},
+	[CS420X_MBP101_COEF] = {
+		.type = HDA_FIXUP_VERBS,
+		.v.verbs = mbp101_init_verbs,
+		.chained = true,
+		.chain_id = CS420X_GPIO_13,
+	},
+};
+
 static int patch_cs420x(struct hda_codec *codec)
 {
 	struct cs_spec *spec;
@@ -1377,36 +1427,13 @@
 	if (!spec)
 		return -ENOMEM;
 	codec->spec = spec;
+	snd_hda_gen_init(&spec->gen);
 
 	spec->vendor_nid = CS420X_VENDOR_NID;
 
-	spec->board_config =
-		snd_hda_check_board_config(codec, CS420X_MODELS,
-					   cs420x_models, cs420x_cfg_tbl);
-	if (spec->board_config < 0)
-		spec->board_config =
-			snd_hda_check_board_codec_sid_config(codec,
-				CS420X_MODELS, NULL, cs420x_codec_cfg_tbl);
-	if (spec->board_config >= 0)
-		fix_pincfg(codec, spec->board_config, cs_pincfgs);
-
-	switch (spec->board_config) {
-	case CS420X_IMAC27:
-	case CS420X_MBP53:
-	case CS420X_MBP55:
-	case CS420X_APPLE:
-		spec->gpio_eapd_hp = 2; /* GPIO1 = headphones */
-		spec->gpio_eapd_speaker = 8; /* GPIO3 = speakers */
-		spec->gpio_mask = spec->gpio_dir =
-			spec->gpio_eapd_hp | spec->gpio_eapd_speaker;
-		break;
-	case CS420X_IMAC27_122:
-		spec->gpio_eapd_hp = 4; /* GPIO2 = headphones */
-		spec->gpio_eapd_speaker = 8; /* GPIO3 = speakers */
-		spec->gpio_mask = spec->gpio_dir =
-			spec->gpio_eapd_hp | spec->gpio_eapd_speaker;
-		break;
-	}
+	snd_hda_pick_fixup(codec, cs420x_models, cs420x_fixup_tbl,
+			   cs420x_fixups);
+	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
 
 	err = cs_parse_auto_config(codec);
 	if (err < 0)
@@ -1414,10 +1441,12 @@
 
 	codec->patch_ops = cs_patch_ops;
 
+	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
+
 	return 0;
 
  error:
-	kfree(codec->spec);
+	cs_free(codec);
 	codec->spec = NULL;
 	return err;
 }
@@ -1431,11 +1460,12 @@
 */
 
 /* CS4210 board names */
-static const char *cs421x_models[CS421X_MODELS] = {
-	[CS421X_CDB4210] = "cdb4210",
+static const struct hda_model_fixup cs421x_models[] = {
+	{ .id = CS421X_CDB4210, .name = "cdb4210" },
+	{}
 };
 
-static const struct snd_pci_quirk cs421x_cfg_tbl[] = {
+static const struct snd_pci_quirk cs421x_fixup_tbl[] = {
 	/* Test Intel board + CDB2410  */
 	SND_PCI_QUIRK(0x8086, 0x5001, "DP45SG/CDB4210", CS421X_CDB4210),
 	{} /* terminator */
@@ -1443,7 +1473,7 @@
 
 /* CS4210 board pinconfigs */
 /* Default CS4210 (CDB4210)*/
-static const struct cs_pincfg cdb4210_pincfgs[] = {
+static const struct hda_pintbl cdb4210_pincfgs[] = {
 	{ 0x05, 0x0321401f },
 	{ 0x06, 0x90170010 },
 	{ 0x07, 0x03813031 },
@@ -1453,8 +1483,26 @@
 	{} /* terminator */
 };
 
-static const struct cs_pincfg *cs421x_pincfgs[CS421X_MODELS] = {
-	[CS421X_CDB4210] = cdb4210_pincfgs,
+/* Setup GPIO/SENSE for each board (if used) */
+static void cs421x_fixup_sense_b(struct hda_codec *codec,
+				 const struct hda_fixup *fix, int action)
+{
+	struct cs_spec *spec = codec->spec;
+	if (action == HDA_FIXUP_ACT_PRE_PROBE)
+		spec->sense_b = 1;
+}
+
+static const struct hda_fixup cs421x_fixups[] = {
+	[CS421X_CDB4210] = {
+		.type = HDA_FIXUP_PINS,
+		.v.pins = cdb4210_pincfgs,
+		.chained = true,
+		.chain_id = CS421X_SENSE_B,
+	},
+	[CS421X_SENSE_B] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = cs421x_fixup_sense_b,
+	}
 };
 
 static const struct hda_verb cs421x_coef_init_verbs[] = {
@@ -1615,7 +1663,7 @@
 		if (!cfg->speaker_outs)
 			continue;
 		if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
-			snd_hda_jack_detect_enable(codec, nid, SPDIF_EVENT);
+			snd_hda_jack_detect_enable_callback(codec, nid, SPDIF_EVENT, cs_automute);
 			spec->spdif_detect = 1;
 		}
 	}
@@ -1643,7 +1691,6 @@
 	init_output(codec);
 	init_input(codec);
 	init_cs421x_digital(codec);
-	snd_hda_jack_report_sync(codec);
 
 	return 0;
 }
@@ -1831,21 +1878,6 @@
 	return 0;
 }
 
-static void cs421x_unsol_event(struct hda_codec *codec, unsigned int res)
-{
-	switch (snd_hda_jack_get_action(codec, res >> 26)) {
-	case HP_EVENT:
-	case SPDIF_EVENT:
-		cs_automute(codec);
-		break;
-
-	case MIC_EVENT:
-		cs_automic(codec);
-		break;
-	}
-	snd_hda_jack_report_sync(codec);
-}
-
 static int parse_cs421x_input(struct hda_codec *codec)
 {
 	struct cs_spec *spec = codec->spec;
@@ -1919,7 +1951,7 @@
 	.build_pcms = cs_build_pcms,
 	.init = cs421x_init,
 	.free = cs_free,
-	.unsol_event = cs421x_unsol_event,
+	.unsol_event = snd_hda_jack_unsol_event,
 #ifdef CONFIG_PM
 	.suspend = cs421x_suspend,
 #endif
@@ -1934,29 +1966,13 @@
 	if (!spec)
 		return -ENOMEM;
 	codec->spec = spec;
+	snd_hda_gen_init(&spec->gen);
 
 	spec->vendor_nid = CS4210_VENDOR_NID;
 
-	spec->board_config =
-		snd_hda_check_board_config(codec, CS421X_MODELS,
-					   cs421x_models, cs421x_cfg_tbl);
-	if (spec->board_config >= 0)
-		fix_pincfg(codec, spec->board_config, cs421x_pincfgs);
-	/*
-	    Setup GPIO/SENSE for each board (if used)
-	*/
-	switch (spec->board_config) {
-	case CS421X_CDB4210:
-		snd_printd("CS4210 board: %s\n",
-			cs421x_models[spec->board_config]);
-/*		spec->gpio_mask = 3;
-		spec->gpio_dir = 3;
-		spec->gpio_data = 3;
-*/
-		spec->sense_b = 1;
-
-		break;
-	}
+	snd_hda_pick_fixup(codec, cs421x_models, cs421x_fixup_tbl,
+			   cs421x_fixups);
+	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
 
 	/*
 	    Update the GPIO/DMIC/SENSE_B pinmux before the configuration
@@ -1971,10 +1987,12 @@
 
 	codec->patch_ops = cs421x_patch_ops;
 
+	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
+
 	return 0;
 
  error:
-	kfree(codec->spec);
+	cs_free(codec);
 	codec->spec = NULL;
 	return err;
 }
@@ -1988,6 +2006,7 @@
 	if (!spec)
 		return -ENOMEM;
 	codec->spec = spec;
+	snd_hda_gen_init(&spec->gen);
 
 	spec->vendor_nid = CS4213_VENDOR_NID;
 
@@ -1999,7 +2018,7 @@
 	return 0;
 
  error:
-	kfree(codec->spec);
+	cs_free(codec);
 	codec->spec = NULL;
 	return err;
 }
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 5e22a8f..03b1dc3 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -553,7 +553,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 static int conexant_suspend(struct hda_codec *codec)
 {
 	snd_hda_shutup_pins(codec);
@@ -567,7 +567,7 @@
 	.init = conexant_init,
 	.free = conexant_free,
 	.set_power_state = conexant_set_power,
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 	.suspend = conexant_suspend,
 #endif
 	.reboot_notify = snd_hda_shutup_pins,
@@ -1710,8 +1710,8 @@
 	HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
 	HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT),
 	HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT),
-	HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT),
-	HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT),
+	HDA_CODEC_VOLUME("Dock Mic Volume", 0x15, 0x00, HDA_INPUT),
+	HDA_CODEC_MUTE("Dock Mic Switch", 0x15, 0x00, HDA_INPUT),
 	{}
 };
 
@@ -3402,7 +3402,7 @@
 	do_automute(codec, cfg->line_outs, cfg->line_out_pins, on);
 }
 
-static void cx_auto_hp_automute(struct hda_codec *codec)
+static void cx_auto_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
 {
 	struct conexant_spec *spec = codec->spec;
 	struct auto_pin_cfg *cfg = &spec->autocfg;
@@ -3413,7 +3413,7 @@
 	cx_auto_update_speakers(codec);
 }
 
-static void cx_auto_line_automute(struct hda_codec *codec)
+static void cx_auto_line_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
 {
 	struct conexant_spec *spec = codec->spec;
 	struct auto_pin_cfg *cfg = &spec->autocfg;
@@ -3540,8 +3540,9 @@
 				     hda_nid_t pin, hda_nid_t *srcp,
 				     bool do_select, int depth)
 {
+	struct conexant_spec *spec = codec->spec;
 	hda_nid_t conn[HDA_MAX_NUM_INPUTS];
-	int i, nums;
+	int startidx, i, nums;
 
 	switch (get_wcaps_type(get_wcaps(codec, mux))) {
 	case AC_WID_AUD_IN:
@@ -3565,14 +3566,25 @@
 	depth++;
 	if (depth == 2)
 		return -1;
+
+	/* Try to rotate around connections to avoid one boost controlling
+	   another input path as well */
+	startidx = 0;
+	for (i = 0; i < spec->private_imux.num_items; i++)
+		if (spec->imux_info[i].pin == pin) {
+			startidx = i;
+			break;
+		}
+
 	for (i = 0; i < nums; i++) {
-		int ret  = __select_input_connection(codec, conn[i], pin, srcp,
+		int j = (i + startidx) % nums;
+		int ret  = __select_input_connection(codec, conn[j], pin, srcp,
 						     do_select, depth);
 		if (ret >= 0) {
 			if (do_select)
 				snd_hda_codec_write(codec, mux, 0,
-						    AC_VERB_SET_CONNECT_SEL, i);
-			return i;
+						    AC_VERB_SET_CONNECT_SEL, j);
+			return j;
 		}
 	}
 	return -1;
@@ -3652,7 +3664,7 @@
 }
 
 /* automatic switch internal and external mic */
-static void cx_auto_automic(struct hda_codec *codec)
+static void cx_auto_automic(struct hda_codec *codec, struct hda_jack_tbl *jack)
 {
 	struct conexant_spec *spec = codec->spec;
 
@@ -3663,22 +3675,6 @@
 			select_automic(codec, spec->auto_mic_int, false);
 }
 
-static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res)
-{
-	switch (snd_hda_jack_get_action(codec, res >> 26)) {
-	case CONEXANT_HP_EVENT:
-		cx_auto_hp_automute(codec);
-		break;
-	case CONEXANT_LINE_EVENT:
-		cx_auto_line_automute(codec);
-		break;
-	case CONEXANT_MIC_EVENT:
-		cx_auto_automic(codec);
-		break;
-	}
-	snd_hda_jack_report_sync(codec);
-}
-
 /* check whether the pin config is suitable for auto-mic switching;
  * auto-mic is enabled only when one int-mic and one ext- and/or
  * one dock-mic exist
@@ -3888,11 +3884,12 @@
 }
 
 static void enable_unsol_pins(struct hda_codec *codec, int num_pins,
-			      hda_nid_t *pins, unsigned int action)
+			      hda_nid_t *pins, unsigned int action,
+			      hda_jack_callback cb)
 {
 	int i;
 	for (i = 0; i < num_pins; i++)
-		snd_hda_jack_detect_enable(codec, pins[i], action);
+		snd_hda_jack_detect_enable_callback(codec, pins[i], action, cb);
 }
 
 static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
@@ -3980,13 +3977,14 @@
 	}
 	if (spec->auto_mute) {
 		enable_unsol_pins(codec, cfg->hp_outs, cfg->hp_pins,
-				  CONEXANT_HP_EVENT);
+				  CONEXANT_HP_EVENT, cx_auto_hp_automute);
 		spec->hp_present = detect_jacks(codec, cfg->hp_outs,
 						cfg->hp_pins);
 		if (spec->detect_line) {
 			enable_unsol_pins(codec, cfg->line_outs,
 					  cfg->line_out_pins,
-					  CONEXANT_LINE_EVENT);
+					  CONEXANT_LINE_EVENT,
+					  cx_auto_line_automute);
 			spec->line_present =
 				detect_jacks(codec, cfg->line_outs,
 					     cfg->line_out_pins);
@@ -4027,16 +4025,16 @@
 
 	if (spec->auto_mic) {
 		if (spec->auto_mic_ext >= 0) {
-			snd_hda_jack_detect_enable(codec,
+			snd_hda_jack_detect_enable_callback(codec,
 				cfg->inputs[spec->auto_mic_ext].pin,
-				CONEXANT_MIC_EVENT);
+				CONEXANT_MIC_EVENT, cx_auto_automic);
 		}
 		if (spec->auto_mic_dock >= 0) {
-			snd_hda_jack_detect_enable(codec,
+			snd_hda_jack_detect_enable_callback(codec,
 				cfg->inputs[spec->auto_mic_dock].pin,
-				CONEXANT_MIC_EVENT);
+				CONEXANT_MIC_EVENT, cx_auto_automic);
 		}
-		cx_auto_automic(codec);
+		cx_auto_automic(codec, NULL);
 	} else {
 		select_input_connection(codec, spec->imux_info[0].adc,
 					spec->imux_info[0].pin);
@@ -4061,7 +4059,6 @@
 	cx_auto_init_output(codec);
 	cx_auto_init_input(codec);
 	cx_auto_init_digital(codec);
-	snd_hda_jack_report_sync(codec);
 	snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
 	return 0;
 }
@@ -4262,7 +4259,7 @@
 
 	if (get_wcaps(codec, mux) & AC_WCAP_OUT_AMP) {
 		spec->imux_info[idx].boost = mux;
-		return cx_auto_add_volume(codec, label, " Boost", 0,
+		return cx_auto_add_volume(codec, label, " Boost", cidx,
 					  mux, HDA_OUTPUT);
 	}
 	return 0;
@@ -4395,8 +4392,8 @@
 	.build_pcms = conexant_build_pcms,
 	.init = cx_auto_init,
 	.free = conexant_free,
-	.unsol_event = cx_auto_unsol_event,
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+	.unsol_event = snd_hda_jack_unsol_event,
+#ifdef CONFIG_PM
 	.suspend = conexant_suspend,
 #endif
 	.reboot_notify = snd_hda_shutup_pins,
@@ -4462,6 +4459,7 @@
 	SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410),
 	SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410),
 	SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC),
+	SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC),
 	SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC),
 	{}
 };
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 8f23374..71555cc 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -34,6 +34,8 @@
 #include <linux/module.h>
 #include <sound/core.h>
 #include <sound/jack.h>
+#include <sound/asoundef.h>
+#include <sound/tlv.h>
 #include "hda_codec.h"
 #include "hda_local.h"
 #include "hda_jack.h"
@@ -71,6 +73,9 @@
 	struct hdmi_eld sink_eld;
 	struct delayed_work work;
 	int repoll_count;
+	bool non_pcm;
+	bool chmap_set;		/* channel-map override by ALSA API? */
+	unsigned char chmap[8]; /* ALSA API channel-map */
 };
 
 struct hdmi_spec {
@@ -80,6 +85,7 @@
 	int num_pins;
 	struct hdmi_spec_per_pin pins[MAX_HDMI_PINS];
 	struct hda_pcm pcm_rec[MAX_HDMI_PINS];
+	unsigned int channels_max; /* max over all cvts */
 
 	/*
 	 * Non-generic ATI/NVIDIA specific
@@ -469,6 +475,17 @@
 	}
 }
 
+static int get_channel_allocation_order(int ca)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
+		if (channel_allocations[i].ca_index == ca)
+			break;
+	}
+	return i;
+}
+
 /*
  * The transformation takes two steps:
  *
@@ -535,24 +552,36 @@
 }
 
 
-static void hdmi_setup_channel_mapping(struct hda_codec *codec,
+static void hdmi_std_setup_channel_mapping(struct hda_codec *codec,
 				       hda_nid_t pin_nid,
+				       bool non_pcm,
 				       int ca)
 {
 	int i;
 	int err;
+	int order;
+	int non_pcm_mapping[8];
+
+	order = get_channel_allocation_order(ca);
 
 	if (hdmi_channel_mapping[ca][1] == 0) {
-		for (i = 0; i < channel_allocations[ca].channels; i++)
+		for (i = 0; i < channel_allocations[order].channels; i++)
 			hdmi_channel_mapping[ca][i] = i | (i << 4);
 		for (; i < 8; i++)
 			hdmi_channel_mapping[ca][i] = 0xf | (i << 4);
 	}
 
+	if (non_pcm) {
+		for (i = 0; i < channel_allocations[order].channels; i++)
+			non_pcm_mapping[i] = i | (i << 4);
+		for (; i < 8; i++)
+			non_pcm_mapping[i] = 0xf | (i << 4);
+	}
+
 	for (i = 0; i < 8; i++) {
 		err = snd_hda_codec_write(codec, pin_nid, 0,
 					  AC_VERB_SET_HDMI_CHAN_SLOT,
-					  hdmi_channel_mapping[ca][i]);
+					  non_pcm ? non_pcm_mapping[i] : hdmi_channel_mapping[ca][i]);
 		if (err) {
 			snd_printdd(KERN_NOTICE
 				    "HDMI: channel mapping failed\n");
@@ -563,6 +592,136 @@
 	hdmi_debug_channel_mapping(codec, pin_nid);
 }
 
+struct channel_map_table {
+	unsigned char map;		/* ALSA API channel map position */
+	unsigned char cea_slot;		/* CEA slot value */
+	int spk_mask;			/* speaker position bit mask */
+};
+
+static struct channel_map_table map_tables[] = {
+	{ SNDRV_CHMAP_FL,	0x00,	FL },
+	{ SNDRV_CHMAP_FR,	0x01,	FR },
+	{ SNDRV_CHMAP_RL,	0x04,	RL },
+	{ SNDRV_CHMAP_RR,	0x05,	RR },
+	{ SNDRV_CHMAP_LFE,	0x02,	LFE },
+	{ SNDRV_CHMAP_FC,	0x03,	FC },
+	{ SNDRV_CHMAP_RLC,	0x06,	RLC },
+	{ SNDRV_CHMAP_RRC,	0x07,	RRC },
+	{} /* terminator */
+};
+
+/* from ALSA API channel position to speaker bit mask */
+static int to_spk_mask(unsigned char c)
+{
+	struct channel_map_table *t = map_tables;
+	for (; t->map; t++) {
+		if (t->map == c)
+			return t->spk_mask;
+	}
+	return 0;
+}
+
+/* from ALSA API channel position to CEA slot */
+static int to_cea_slot(unsigned char c)
+{
+	struct channel_map_table *t = map_tables;
+	for (; t->map; t++) {
+		if (t->map == c)
+			return t->cea_slot;
+	}
+	return 0x0f;
+}
+
+/* from CEA slot to ALSA API channel position */
+static int from_cea_slot(unsigned char c)
+{
+	struct channel_map_table *t = map_tables;
+	for (; t->map; t++) {
+		if (t->cea_slot == c)
+			return t->map;
+	}
+	return 0;
+}
+
+/* from speaker bit mask to ALSA API channel position */
+static int spk_to_chmap(int spk)
+{
+	struct channel_map_table *t = map_tables;
+	for (; t->map; t++) {
+		if (t->spk_mask == spk)
+			return t->map;
+	}
+	return 0;
+}
+
+/* get the CA index corresponding to the given ALSA API channel map */
+static int hdmi_manual_channel_allocation(int chs, unsigned char *map)
+{
+	int i, spks = 0, spk_mask = 0;
+
+	for (i = 0; i < chs; i++) {
+		int mask = to_spk_mask(map[i]);
+		if (mask) {
+			spk_mask |= mask;
+			spks++;
+		}
+	}
+
+	for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
+		if ((chs == channel_allocations[i].channels ||
+		     spks == channel_allocations[i].channels) &&
+		    (spk_mask & channel_allocations[i].spk_mask) ==
+				channel_allocations[i].spk_mask)
+			return channel_allocations[i].ca_index;
+	}
+	return -1;
+}
+
+/* set up the channel slots for the given ALSA API channel map */
+static int hdmi_manual_setup_channel_mapping(struct hda_codec *codec,
+					     hda_nid_t pin_nid,
+					     int chs, unsigned char *map)
+{
+	int i;
+	for (i = 0; i < 8; i++) {
+		int val, err;
+		if (i < chs)
+			val = to_cea_slot(map[i]);
+		else
+			val = 0xf;
+		val |= (i << 4);
+		err = snd_hda_codec_write(codec, pin_nid, 0,
+					  AC_VERB_SET_HDMI_CHAN_SLOT, val);
+		if (err)
+			return -EINVAL;
+	}
+	return 0;
+}
+
+/* store ALSA API channel map from the current default map */
+static void hdmi_setup_fake_chmap(unsigned char *map, int ca)
+{
+	int i;
+	for (i = 0; i < 8; i++) {
+		if (i < channel_allocations[ca].channels)
+			map[i] = from_cea_slot((hdmi_channel_mapping[ca][i] >> 4) & 0x0f);
+		else
+			map[i] = 0;
+	}
+}
+
+static void hdmi_setup_channel_mapping(struct hda_codec *codec,
+				       hda_nid_t pin_nid, bool non_pcm, int ca,
+				       int channels, unsigned char *map)
+{
+	if (!non_pcm && map) {
+		hdmi_manual_setup_channel_mapping(codec, pin_nid,
+						  channels, map);
+	} else {
+		hdmi_std_setup_channel_mapping(codec, pin_nid, non_pcm, ca);
+		hdmi_setup_fake_chmap(map, ca);
+	}
+}
 
 /*
  * Audio InfoFrame routines
@@ -686,7 +845,8 @@
 }
 
 static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx,
-					struct snd_pcm_substream *substream)
+				       bool non_pcm,
+				       struct snd_pcm_substream *substream)
 {
 	struct hdmi_spec *spec = codec->spec;
 	struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
@@ -700,7 +860,12 @@
 	if (!eld->monitor_present)
 		return;
 
-	ca = hdmi_channel_allocation(eld, channels);
+	if (!non_pcm && per_pin->chmap_set)
+		ca = hdmi_manual_channel_allocation(channels, per_pin->chmap);
+	else
+		ca = hdmi_channel_allocation(eld, channels);
+	if (ca < 0)
+		ca = 0;
 
 	memset(&ai, 0, sizeof(ai));
 	if (eld->conn_type == 0) { /* HDMI */
@@ -737,12 +902,21 @@
 			    "pin=%d channels=%d\n",
 			    pin_nid,
 			    channels);
-		hdmi_setup_channel_mapping(codec, pin_nid, ca);
+		hdmi_setup_channel_mapping(codec, pin_nid, non_pcm, ca,
+					   channels, per_pin->chmap);
 		hdmi_stop_infoframe_trans(codec, pin_nid);
 		hdmi_fill_audio_infoframe(codec, pin_nid,
 					    ai.bytes, sizeof(ai));
 		hdmi_start_infoframe_trans(codec, pin_nid);
+	} else {
+		/* For non-pcm audio switch, setup new channel mapping
+		 * accordingly */
+		if (per_pin->non_pcm != non_pcm)
+			hdmi_setup_channel_mapping(codec, pin_nid, non_pcm, ca,
+						   channels, per_pin->chmap);
 	}
+
+	per_pin->non_pcm = non_pcm;
 }
 
 
@@ -1035,6 +1209,7 @@
 	per_pin = &spec->pins[pin_idx];
 
 	per_pin->pin_nid = pin_nid;
+	per_pin->non_pcm = false;
 
 	err = hdmi_read_pin_conn(codec, pin_idx);
 	if (err < 0)
@@ -1064,8 +1239,11 @@
 
 	per_cvt->cvt_nid = cvt_nid;
 	per_cvt->channels_min = 2;
-	if (chans <= 16)
+	if (chans <= 16) {
 		per_cvt->channels_max = chans;
+		if (chans > spec->channels_max)
+			spec->channels_max = chans;
+	}
 
 	err = snd_hda_query_supported_pcm(codec, cvt_nid,
 					  &per_cvt->rates,
@@ -1115,7 +1293,7 @@
 	 * can be lost and presence sense verb will become inaccurate if the
 	 * HDA link is powered off at hot plug or hw initialization time.
 	 */
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 	if (!(snd_hda_param_read(codec, codec->afg, AC_PAR_POWER_STATE) &
 	      AC_PWRST_EPSS))
 		codec->bus->power_keep_link_on = 1;
@@ -1133,6 +1311,19 @@
 	return &names[idx][0];
 }
 
+static bool check_non_pcm_per_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
+{
+	struct hda_spdif_out *spdif;
+	bool non_pcm;
+
+	mutex_lock(&codec->spdif_mutex);
+	spdif = snd_hda_spdif_out_of_nid(codec, cvt_nid);
+	non_pcm = !!(spdif->status & IEC958_AES0_NONAUDIO);
+	mutex_unlock(&codec->spdif_mutex);
+	return non_pcm;
+}
+
+
 /*
  * HDMI callbacks
  */
@@ -1148,10 +1339,13 @@
 	int pin_idx = hinfo_to_pin_index(spec, hinfo);
 	hda_nid_t pin_nid = spec->pins[pin_idx].pin_nid;
 	int pinctl;
+	bool non_pcm;
+
+	non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
 
 	hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels);
 
-	hdmi_setup_audio_infoframe(codec, pin_idx, substream);
+	hdmi_setup_audio_infoframe(codec, pin_idx, non_pcm, substream);
 
 	pinctl = snd_hda_codec_read(codec, pin_nid, 0,
 				    AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
@@ -1200,7 +1394,10 @@
 				    AC_VERB_SET_PIN_WIDGET_CONTROL,
 				    pinctl & ~PIN_OUT);
 		snd_hda_spdif_ctls_unassign(codec, pin_idx);
+		per_pin->chmap_set = false;
+		memset(per_pin->chmap, 0, sizeof(per_pin->chmap));
 	}
+
 	return 0;
 }
 
@@ -1211,6 +1408,135 @@
 	.cleanup = generic_hdmi_playback_pcm_cleanup,
 };
 
+/*
+ * ALSA API channel-map control callbacks
+ */
+static int hdmi_chmap_ctl_info(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_info *uinfo)
+{
+	struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
+	struct hda_codec *codec = info->private_data;
+	struct hdmi_spec *spec = codec->spec;
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = spec->channels_max;
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = SNDRV_CHMAP_LAST;
+	return 0;
+}
+
+static int hdmi_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag,
+			      unsigned int size, unsigned int __user *tlv)
+{
+	struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
+	struct hda_codec *codec = info->private_data;
+	struct hdmi_spec *spec = codec->spec;
+	const unsigned int valid_mask =
+		FL | FR | RL | RR | LFE | FC | RLC | RRC;
+	unsigned int __user *dst;
+	int chs, count = 0;
+
+	if (size < 8)
+		return -ENOMEM;
+	if (put_user(SNDRV_CTL_TLVT_CONTAINER, tlv))
+		return -EFAULT;
+	size -= 8;
+	dst = tlv + 2;
+	for (chs = 2; chs <= spec->channels_max; chs++) {
+		int i, c;
+		struct cea_channel_speaker_allocation *cap;
+		cap = channel_allocations;
+		for (i = 0; i < ARRAY_SIZE(channel_allocations); i++, cap++) {
+			int chs_bytes = chs * 4;
+			if (cap->channels != chs)
+				continue;
+			if (cap->spk_mask & ~valid_mask)
+				continue;
+			if (size < 8)
+				return -ENOMEM;
+			if (put_user(SNDRV_CTL_TLVT_CHMAP_VAR, dst) ||
+			    put_user(chs_bytes, dst + 1))
+				return -EFAULT;
+			dst += 2;
+			size -= 8;
+			count += 8;
+			if (size < chs_bytes)
+				return -ENOMEM;
+			size -= chs_bytes;
+			count += chs_bytes;
+			for (c = 7; c >= 0; c--) {
+				int spk = cap->speakers[c];
+				if (!spk)
+					continue;
+				if (put_user(spk_to_chmap(spk), dst))
+					return -EFAULT;
+				dst++;
+			}
+		}
+	}
+	if (put_user(count, tlv + 1))
+		return -EFAULT;
+	return 0;
+}
+
+static int hdmi_chmap_ctl_get(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
+	struct hda_codec *codec = info->private_data;
+	struct hdmi_spec *spec = codec->spec;
+	int pin_idx = kcontrol->private_value;
+	struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(per_pin->chmap); i++)
+		ucontrol->value.integer.value[i] = per_pin->chmap[i];
+	return 0;
+}
+
+static int hdmi_chmap_ctl_put(struct snd_kcontrol *kcontrol,
+			      struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
+	struct hda_codec *codec = info->private_data;
+	struct hdmi_spec *spec = codec->spec;
+	int pin_idx = kcontrol->private_value;
+	struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
+	unsigned int ctl_idx;
+	struct snd_pcm_substream *substream;
+	unsigned char chmap[8];
+	int i, ca, prepared = 0;
+
+	ctl_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
+	substream = snd_pcm_chmap_substream(info, ctl_idx);
+	if (!substream || !substream->runtime)
+		return -EBADFD;
+	switch (substream->runtime->status->state) {
+	case SNDRV_PCM_STATE_OPEN:
+	case SNDRV_PCM_STATE_SETUP:
+		break;
+	case SNDRV_PCM_STATE_PREPARED:
+		prepared = 1;
+		break;
+	default:
+		return -EBUSY;
+	}
+	memset(chmap, 0, sizeof(chmap));
+	for (i = 0; i < ARRAY_SIZE(chmap); i++)
+		chmap[i] = ucontrol->value.integer.value[i];
+	if (!memcmp(chmap, per_pin->chmap, sizeof(chmap)))
+		return 0;
+	ca = hdmi_manual_channel_allocation(ARRAY_SIZE(chmap), chmap);
+	if (ca < 0)
+		return -EINVAL;
+	per_pin->chmap_set = true;
+	memcpy(per_pin->chmap, chmap, sizeof(chmap));
+	if (prepared)
+		hdmi_setup_audio_infoframe(codec, pin_idx, per_pin->non_pcm,
+					   substream);
+
+	return 0;
+}
+
 static int generic_hdmi_build_pcms(struct hda_codec *codec)
 {
 	struct hdmi_spec *spec = codec->spec;
@@ -1223,6 +1549,7 @@
 		info = &spec->pcm_rec[pin_idx];
 		info->name = get_hdmi_pcm_name(pin_idx);
 		info->pcm_type = HDA_PCM_TYPE_HDMI;
+		info->own_chmap = true;
 
 		pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
 		pstr->substreams = 1;
@@ -1280,6 +1607,27 @@
 		hdmi_present_sense(per_pin, 0);
 	}
 
+	/* add channel maps */
+	for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
+		struct snd_pcm_chmap *chmap;
+		struct snd_kcontrol *kctl;
+		int i;
+		err = snd_pcm_add_chmap_ctls(codec->pcm_info[pin_idx].pcm,
+					     SNDRV_PCM_STREAM_PLAYBACK,
+					     NULL, 0, pin_idx, &chmap);
+		if (err < 0)
+			return err;
+		/* override handlers */
+		chmap->private_data = codec;
+		kctl = chmap->kctl;
+		for (i = 0; i < kctl->count; i++)
+			kctl->vd[i].access |= SNDRV_CTL_ELEM_ACCESS_WRITE;
+		kctl->info = hdmi_chmap_ctl_info;
+		kctl->get = hdmi_chmap_ctl_get;
+		kctl->put = hdmi_chmap_ctl_put;
+		kctl->tlv.c = hdmi_chmap_ctl_tlv;
+	}
+
 	return 0;
 }
 
@@ -1311,7 +1659,6 @@
 		hdmi_init_pin(codec, pin_nid);
 		snd_hda_jack_detect_enable(codec, pin_nid, pin_nid);
 	}
-	snd_hda_jack_report_sync(codec);
 	return 0;
 }
 
@@ -1428,7 +1775,6 @@
 		snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_AMP_GAIN_MUTE,
 				    AMP_OUT_UNMUTE);
 	snd_hda_jack_detect_enable(codec, pin, pin);
-	snd_hda_jack_report_sync(codec);
 	return 0;
 }
 
@@ -1809,6 +2155,43 @@
 	return 0;
 }
 
+static int nvhdmi_7x_8ch_build_pcms(struct hda_codec *codec)
+{
+	struct hdmi_spec *spec = codec->spec;
+	int err = simple_playback_build_pcms(codec);
+	spec->pcm_rec[0].own_chmap = true;
+	return err;
+}
+
+static int nvhdmi_7x_8ch_build_controls(struct hda_codec *codec)
+{
+	struct hdmi_spec *spec = codec->spec;
+	struct snd_pcm_chmap *chmap;
+	int err;
+
+	err = simple_playback_build_controls(codec);
+	if (err < 0)
+		return err;
+
+	/* add channel maps */
+	err = snd_pcm_add_chmap_ctls(spec->pcm_rec[0].pcm,
+				     SNDRV_PCM_STREAM_PLAYBACK,
+				     snd_pcm_alt_chmaps, 8, 0, &chmap);
+	if (err < 0)
+		return err;
+	switch (codec->preset->id) {
+	case 0x10de0002:
+	case 0x10de0003:
+	case 0x10de0005:
+	case 0x10de0006:
+		chmap->channel_mask = (1U << 2) | (1U << 8);
+		break;
+	case 0x10de0007:
+		chmap->channel_mask = (1U << 2) | (1U << 6) | (1U << 8);
+	}
+	return 0;
+}
+
 static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
 {
 	struct hdmi_spec *spec;
@@ -1819,6 +2202,8 @@
 	spec->multiout.max_channels = 8;
 	spec->pcm_playback = nvhdmi_pcm_playback_8ch_7x;
 	codec->patch_ops.init = nvhdmi_7x_init_8ch;
+	codec->patch_ops.build_pcms = nvhdmi_7x_8ch_build_pcms;
+	codec->patch_ops.build_controls = nvhdmi_7x_8ch_build_controls;
 
 	/* Initialize the audio infoframe channel mask and checksum to something
 	 * valid */
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 4f81dd4..8253b4e 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -174,7 +174,7 @@
 
 	/* hooks */
 	void (*init_hook)(struct hda_codec *codec);
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 	void (*power_hook)(struct hda_codec *codec);
 #endif
 	void (*shutup)(struct hda_codec *codec);
@@ -215,7 +215,7 @@
 	/* for virtual master */
 	hda_nid_t vmaster_nid;
 	struct hda_vmaster_mute_hook vmaster_mute;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 	struct hda_loopback_check loopback;
 	int num_loopbacks;
 	struct hda_amp_list loopback_list[8];
@@ -594,7 +594,7 @@
 }
 
 /* standard HP-automute helper */
-static void alc_hp_automute(struct hda_codec *codec)
+static void alc_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
 {
 	struct alc_spec *spec = codec->spec;
 
@@ -607,10 +607,12 @@
 }
 
 /* standard line-out-automute helper */
-static void alc_line_automute(struct hda_codec *codec)
+static void alc_line_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
 {
 	struct alc_spec *spec = codec->spec;
 
+	if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
+		return;
 	/* check LO jack only when it's different from HP */
 	if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0])
 		return;
@@ -627,7 +629,7 @@
 	snd_hda_get_conn_index(codec, mux, nid, 0)
 
 /* standard mic auto-switch helper */
-static void alc_mic_automute(struct hda_codec *codec)
+static void alc_mic_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
 {
 	struct alc_spec *spec = codec->spec;
 	hda_nid_t *pins = spec->imux_pins;
@@ -648,25 +650,8 @@
 		alc_mux_select(codec, 0, spec->int_mic_idx, false);
 }
 
-/* handle the specified unsol action (ALC_XXX_EVENT) */
-static void alc_exec_unsol_event(struct hda_codec *codec, int action)
-{
-	switch (action) {
-	case ALC_HP_EVENT:
-		alc_hp_automute(codec);
-		break;
-	case ALC_FRONT_EVENT:
-		alc_line_automute(codec);
-		break;
-	case ALC_MIC_EVENT:
-		alc_mic_automute(codec);
-		break;
-	}
-	snd_hda_jack_report_sync(codec);
-}
-
 /* update the master volume per volume-knob's unsol event */
-static void alc_update_knob_master(struct hda_codec *codec, hda_nid_t nid)
+static void alc_update_knob_master(struct hda_codec *codec, struct hda_jack_tbl *jack)
 {
 	unsigned int val;
 	struct snd_kcontrol *kctl;
@@ -678,7 +663,7 @@
 	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
 	if (!uctl)
 		return;
-	val = snd_hda_codec_read(codec, nid, 0,
+	val = snd_hda_codec_read(codec, jack->nid, 0,
 				 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
 	val &= HDA_AMP_VOLMASK;
 	uctl->value.integer.value[0] = val;
@@ -687,37 +672,19 @@
 	kfree(uctl);
 }
 
-/* unsolicited event for HP jack sensing */
-static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
+static void alc880_unsol_event(struct hda_codec *codec, unsigned int res)
 {
-	int action;
-
-	if (codec->vendor_id == 0x10ec0880)
-		res >>= 28;
-	else
-		res >>= 26;
-	action = snd_hda_jack_get_action(codec, res);
-	if (action == ALC_DCVOL_EVENT) {
-		/* Execute the dc-vol event here as it requires the NID
-		 * but we don't pass NID to alc_exec_unsol_event().
-		 * Once when we convert all static quirks to the auto-parser,
-		 * this can be integerated into there.
-		 */
-		struct hda_jack_tbl *jack;
-		jack = snd_hda_jack_tbl_get_from_tag(codec, res);
-		if (jack)
-			alc_update_knob_master(codec, jack->nid);
-		return;
-	}
-	alc_exec_unsol_event(codec, action);
+	/* For some reason, the res given from ALC880 is broken.
+	   Here we adjust it properly. */
+	snd_hda_jack_unsol_event(codec, res >> 2);
 }
 
 /* call init functions of standard auto-mute helpers */
 static void alc_inithook(struct hda_codec *codec)
 {
-	alc_hp_automute(codec);
-	alc_line_automute(codec);
-	alc_mic_automute(codec);
+	alc_hp_automute(codec, NULL);
+	alc_line_automute(codec, NULL);
+	alc_mic_automute(codec, NULL);
 }
 
 /* additional initialization for ALC888 variants */
@@ -999,7 +966,8 @@
 			continue;
 		snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
 			    nid);
-		snd_hda_jack_detect_enable(codec, nid, ALC_HP_EVENT);
+		snd_hda_jack_detect_enable_callback(codec, nid, ALC_HP_EVENT,
+						    alc_hp_automute);
 		spec->detect_hp = 1;
 	}
 
@@ -1011,10 +979,10 @@
 					continue;
 				snd_printdd("realtek: Enable Line-Out "
 					    "auto-muting on NID 0x%x\n", nid);
-				snd_hda_jack_detect_enable(codec, nid,
-							   ALC_FRONT_EVENT);
+				snd_hda_jack_detect_enable_callback(codec, nid, ALC_FRONT_EVENT,
+								    alc_line_automute);
 				spec->detect_lo = 1;
-		}
+			}
 		spec->automute_lo_possible = spec->detect_hp;
 	}
 
@@ -1110,10 +1078,12 @@
 		return false; /* no corresponding imux */
 	}
 
-	snd_hda_jack_detect_enable(codec, spec->ext_mic_pin, ALC_MIC_EVENT);
+	snd_hda_jack_detect_enable_callback(codec, spec->ext_mic_pin,
+					    ALC_MIC_EVENT, alc_mic_automute);
 	if (spec->dock_mic_pin)
-		snd_hda_jack_detect_enable(codec, spec->dock_mic_pin,
-					   ALC_MIC_EVENT);
+		snd_hda_jack_detect_enable_callback(codec, spec->dock_mic_pin,
+						    ALC_MIC_EVENT,
+						    alc_mic_automute);
 
 	spec->auto_mic_valid_imux = 1;
 	spec->auto_mic = 1;
@@ -2053,13 +2023,11 @@
 
 	alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
 
-	snd_hda_jack_report_sync(codec);
-
 	hda_call_check_power_status(codec, 0x01);
 	return 0;
 }
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
 {
 	struct alc_spec *spec = codec->spec;
@@ -2289,6 +2257,8 @@
 			p = &alc_pcm_analog_playback;
 		info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
 		info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
+		info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
+			spec->multiout.max_channels;
 	}
 	if (spec->adc_nids) {
 		p = spec->stream_analog_capture;
@@ -2437,7 +2407,7 @@
 	snd_hda_detach_beep_device(codec);
 }
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 static void alc_power_eapd(struct hda_codec *codec)
 {
 	alc_auto_setup_eapd(codec, false);
@@ -2473,17 +2443,18 @@
 	.build_pcms = alc_build_pcms,
 	.init = alc_init,
 	.free = alc_free,
-	.unsol_event = alc_unsol_event,
+	.unsol_event = snd_hda_jack_unsol_event,
 #ifdef CONFIG_PM
 	.resume = alc_resume,
 #endif
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 	.suspend = alc_suspend,
 	.check_power_status = alc_check_power_status,
 #endif
 	.reboot_notify = alc_shutup,
 };
 
+
 /* replace the codec chip_name with the given string */
 static int alc_codec_rename(struct hda_codec *codec, const char *name)
 {
@@ -2633,7 +2604,7 @@
 	return channel_name[ch];
 }
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 /* add the powersave loopback-list entry */
 static void add_loopback_list(struct alc_spec *spec, hda_nid_t mix, int idx)
 {
@@ -4276,6 +4247,7 @@
 	((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
 
 static const struct snd_pci_quirk beep_white_list[] = {
+	SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1),
 	SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
 	SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
 	SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
@@ -4447,7 +4419,7 @@
 				  const struct alc_fixup *fix, int action)
 {
 	if (action == ALC_FIXUP_ACT_PROBE)
-		snd_hda_jack_detect_enable(codec, 0x21, ALC_DCVOL_EVENT);
+		snd_hda_jack_detect_enable_callback(codec, 0x21, ALC_DCVOL_EVENT, alc_update_knob_master);
 }
 
 static const struct alc_fixup alc880_fixups[] = {
@@ -4812,6 +4784,8 @@
 	}
 
 	codec->patch_ops = alc_patch_ops;
+	codec->patch_ops.unsol_event = alc880_unsol_event;
+
 
 	alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
 
@@ -4866,7 +4840,8 @@
 		spec->detect_hp = 1;
 		spec->automute_speaker = 1;
 		spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
-		snd_hda_jack_detect_enable(codec, 0x0f, ALC_HP_EVENT);
+		snd_hda_jack_detect_enable_callback(codec, 0x0f, ALC_HP_EVENT,
+						    alc_hp_automute);
 		snd_hda_gen_add_verbs(&spec->gen, alc_gpio1_init_verbs);
 	}
 }
@@ -6189,6 +6164,7 @@
 	SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
 	SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED),
 	SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC),
+	SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_DMIC),
 	SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
 	SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
 	SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
@@ -6334,6 +6310,12 @@
 
 	spec = codec->spec;
 
+	alc_pick_fixup(codec, alc269_fixup_models,
+		       alc269_fixup_tbl, alc269_fixups);
+	alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
+
+	alc_auto_parse_customize_define(codec);
+
 	if (codec->vendor_id == 0x10ec0269) {
 		spec->codec_variant = ALC269_TYPE_ALC269VA;
 		switch (alc_get_coef0(codec) & 0x00f0) {
@@ -6361,12 +6343,6 @@
 		alc269_fill_coef(codec);
 	}
 
-	alc_pick_fixup(codec, alc269_fixup_models,
-		       alc269_fixup_tbl, alc269_fixups);
-	alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
-
-	alc_auto_parse_customize_define(codec);
-
 	/* automatic parse from the BIOS config */
 	err = alc269_parse_auto_config(codec);
 	if (err < 0)
@@ -6503,7 +6479,7 @@
 	}
 
 	codec->patch_ops = alc_patch_ops;
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 	spec->power_hook = alc_power_eapd;
 #endif
 
@@ -7068,6 +7044,8 @@
 	{ .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
 	{ .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 },
 	{ .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 },
+	{ .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 },
+	{ .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 },
 	{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
 	  .patch = patch_alc861 },
 	{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 3d4722f..770013f 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -103,6 +103,8 @@
 	STAC_HP_ZEPHYR,
 	STAC_92HD83XXX_HP_LED,
 	STAC_92HD83XXX_HP_INV_LED,
+	STAC_92HD83XXX_HP_MIC_LED,
+	STAC_92HD83XXX_HEADSET_JACK,
 	STAC_92HD83XXX_MODELS
 };
 
@@ -203,6 +205,7 @@
 	unsigned int check_volume_offset:1;
 	unsigned int auto_mic:1;
 	unsigned int linear_tone_beep:1;
+	unsigned int headset_jack:1; /* 4-pin headset jack (hp + mono mic) */
 
 	/* gpio lines */
 	unsigned int eapd_mask;
@@ -215,6 +218,9 @@
 	unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */
 	unsigned int vref_led;
 
+	unsigned int mic_mute_led_gpio; /* capture mute LED GPIO */
+	bool mic_mute_led_on; /* current mic mute state */
+
 	/* stream */
 	unsigned int stream_delay;
 
@@ -1679,6 +1685,8 @@
 	[STAC_HP_ZEPHYR] = "hp-zephyr",
 	[STAC_92HD83XXX_HP_LED] = "hp-led",
 	[STAC_92HD83XXX_HP_INV_LED] = "hp-inv-led",
+	[STAC_92HD83XXX_HP_MIC_LED] = "hp-mic-led",
+	[STAC_92HD83XXX_HEADSET_JACK] = "headset-jack",
 };
 
 static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
@@ -1689,6 +1697,24 @@
 		      "DFI LanParty", STAC_92HD83XXX_REF),
 	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba,
 		      "unknown Dell", STAC_DELL_S14),
+	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0532,
+		      "Dell Latitude E6230", STAC_92HD83XXX_HEADSET_JACK),
+	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0533,
+		      "Dell Latitude E6330", STAC_92HD83XXX_HEADSET_JACK),
+	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0534,
+		      "Dell Latitude E6430", STAC_92HD83XXX_HEADSET_JACK),
+	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0535,
+		      "Dell Latitude E6530", STAC_92HD83XXX_HEADSET_JACK),
+	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x053c,
+		      "Dell Latitude E5430", STAC_92HD83XXX_HEADSET_JACK),
+	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x053d,
+		      "Dell Latitude E5530", STAC_92HD83XXX_HEADSET_JACK),
+	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0549,
+		      "Dell Latitude E5430", STAC_92HD83XXX_HEADSET_JACK),
+	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x057d,
+		      "Dell Latitude E6430s", STAC_92HD83XXX_HEADSET_JACK),
+	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0584,
+		      "Dell Latitude E6430U", STAC_92HD83XXX_HEADSET_JACK),
 	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028,
 		      "Dell Vostro 3500", STAC_DELL_VOSTRO_3500),
 	SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656,
@@ -1703,6 +1729,8 @@
 			  "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
 	SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165B,
 			  "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
+	SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x18df,
+			  "HP Folio", STAC_92HD83XXX_HP_MIC_LED),
 	SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3388,
 			  "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
 	SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3389,
@@ -2791,18 +2819,27 @@
 	return knew;
 }
 
+static struct snd_kcontrol_new *
+add_control_temp(struct sigmatel_spec *spec,
+		 const struct snd_kcontrol_new *ktemp,
+		 int idx, const char *name,
+		 unsigned long val)
+{
+	struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name,
+							 HDA_SUBDEV_AMP_FLAG);
+	if (!knew)
+		return NULL;
+	knew->index = idx;
+	knew->private_value = val;
+	return knew;
+}
+
 static int stac92xx_add_control_temp(struct sigmatel_spec *spec,
 				     const struct snd_kcontrol_new *ktemp,
 				     int idx, const char *name,
 				     unsigned long val)
 {
-	struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name,
-							 HDA_SUBDEV_AMP_FLAG);
-	if (!knew)
-		return -ENOMEM;
-	knew->index = idx;
-	knew->private_value = val;
-	return 0;
+	return add_control_temp(spec, ktemp, idx, name, val) ? 0 : -ENOMEM;
 }
 
 static inline int stac92xx_add_control_idx(struct sigmatel_spec *spec,
@@ -2839,6 +2876,9 @@
 	char name[22];
 
 	if (snd_hda_get_input_pin_attr(def_conf) != INPUT_PIN_ATTR_INT) {
+		if (spec->headset_jack && snd_hda_get_input_pin_attr(def_conf)
+			!= INPUT_PIN_ATTR_DOCK)
+			return 0;
 		if (snd_hda_get_default_vref(codec, nid) == AC_PINCTL_VREF_GRD
 			&& nid == spec->line_switch)
 			control = STAC_CTL_WIDGET_IO_SWITCH;
@@ -3226,9 +3266,12 @@
 				idx = i;
 				break;
 			case AUTO_PIN_SPEAKER_OUT:
-				name = "Speaker";
-				idx = i;
-				break;
+				if (num_outs <= 1) {
+					name = "Speaker";
+					idx = i;
+					break;
+				}
+				/* Fall through in case of multi speaker outs */
 			default:
 				name = chname[i];
 				idx = 0;
@@ -3242,18 +3285,56 @@
 	return 0;
 }
 
+static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
+			  unsigned int dir_mask, unsigned int data);
+
+/* hook for controlling mic-mute LED GPIO */
+static int stac92xx_capture_sw_put_led(struct snd_kcontrol *kcontrol,
+				       struct snd_ctl_elem_value *ucontrol)
+{
+	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+	struct sigmatel_spec *spec = codec->spec;
+	int err;
+	bool mute;
+
+	err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
+	if (err <= 0)
+		return err;
+	mute = !(ucontrol->value.integer.value[0] &&
+		 ucontrol->value.integer.value[1]);
+	if (spec->mic_mute_led_on != mute) {
+		spec->mic_mute_led_on = mute;
+		if (mute)
+			spec->gpio_data |= spec->mic_mute_led_gpio;
+		else
+			spec->gpio_data &= ~spec->mic_mute_led_gpio;
+		stac_gpio_set(codec, spec->gpio_mask,
+			      spec->gpio_dir, spec->gpio_data);
+	}
+	return err;
+}
+
 static int stac92xx_add_capvol_ctls(struct hda_codec *codec, unsigned long vol,
 				    unsigned long sw, int idx)
 {
+	struct sigmatel_spec *spec = codec->spec;
+	struct snd_kcontrol_new *knew;
 	int err;
+
 	err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_VOL, idx,
 				       "Capture Volume", vol);
 	if (err < 0)
 		return err;
-	err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_MUTE, idx,
-				       "Capture Switch", sw);
-	if (err < 0)
-		return err;
+
+	knew = add_control_temp(spec,
+				&stac92xx_control_templates[STAC_CTL_WIDGET_MUTE],
+				idx, "Capture Switch", sw);
+	if (!knew)
+		return -ENOMEM;
+	/* add a LED hook for some HP laptops */
+	if (spec->mic_mute_led_gpio)
+		knew->put = stac92xx_capture_sw_put_led;
+
 	return 0;
 }
 
@@ -4155,6 +4236,9 @@
 	return 0;
 }
 
+static void handle_unsol_event(struct hda_codec *codec,
+			       struct hda_jack_tbl *event);
+
 /* check if given nid is a valid pin and no other events are assigned
  * to it.  If OK, assign the event, set the unsol flag, and returns 1.
  * Otherwise, returns zero.
@@ -4172,6 +4256,7 @@
 	if (event->action && event->action != type)
 		return 0;
 	event->action = type;
+	event->callback = handle_unsol_event;
 	snd_hda_jack_detect_enable(codec, nid, 0);
 	return 1;
 }
@@ -4418,8 +4503,6 @@
 		stac_toggle_power_map(codec, nid, 0);
 	}
 
-	snd_hda_jack_report_sync(codec);
-
 	/* sync mute LED */
 	if (spec->gpio_led) {
 		if (spec->vmaster_mute.hook)
@@ -4812,20 +4895,6 @@
 	handle_unsol_event(codec, event);
 }
 
-static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
-{
-	struct hda_jack_tbl *event;
-	int tag;
-
-	tag = (res >> 26) & 0x7f;
-	event = snd_hda_jack_tbl_get_from_tag(codec, tag);
-	if (!event)
-		return;
-	event->jack_dirty = 1;
-	handle_unsol_event(codec, event);
-	snd_hda_jack_report_sync(codec);
-}
-
 static int hp_blike_system(u32 subsystem_id);
 
 static void set_hp_led_gpio(struct hda_codec *codec)
@@ -5076,7 +5145,7 @@
 	.build_pcms = stac92xx_build_pcms,
 	.init = stac92xx_init,
 	.free = stac92xx_free,
-	.unsol_event = stac92xx_unsol_event,
+	.unsol_event = snd_hda_jack_unsol_event,
 #ifdef CONFIG_PM
 	.suspend = stac92xx_suspend,
 	.resume = stac92xx_resume,
@@ -5578,6 +5647,12 @@
 	case STAC_92HD83XXX_HP_INV_LED:
 		default_polarity = 1;
 		break;
+	case STAC_92HD83XXX_HP_MIC_LED:
+		spec->mic_mute_led_gpio = 0x08; /* GPIO3 */
+		break;
+	case STAC_92HD83XXX_HEADSET_JACK:
+		spec->headset_jack = 1;
+		break;
 	}
 
 	if (find_mute_led_cfg(codec, default_polarity))
@@ -5596,6 +5671,13 @@
 		}
 	}
 
+	if (spec->mic_mute_led_gpio) {
+		spec->gpio_mask |= spec->mic_mute_led_gpio;
+		spec->gpio_dir |= spec->mic_mute_led_gpio;
+		spec->mic_mute_led_on = true;
+		spec->gpio_data |= spec->mic_mute_led_gpio;
+	}
+
 	err = stac92xx_parse_auto_config(codec);
 	if (!err) {
 		if (spec->board_config < 0) {
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 4307717..72a2f60 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -118,6 +118,8 @@
 };
 
 struct via_spec {
+	struct hda_gen_spec gen;
+
 	/* codec parameterization */
 	const struct snd_kcontrol_new *mixers[6];
 	unsigned int num_mixers;
@@ -246,6 +248,7 @@
 	/* VT1708BCE & VT1708S are almost same */
 	if (spec->codec_type == VT1708BCE)
 		spec->codec_type = VT1708S;
+	snd_hda_gen_init(&spec->gen);
 	return spec;
 }
 
@@ -299,7 +302,6 @@
 
 #define VIA_JACK_EVENT		0x20
 #define VIA_HP_EVENT		0x01
-#define VIA_GPIO_EVENT		0x02
 #define VIA_LINE_EVENT		0x03
 
 enum {
@@ -1628,6 +1630,7 @@
 	vt1708_stop_hp_work(spec);
 	kfree(spec->bind_cap_vol);
 	kfree(spec->bind_cap_sw);
+	snd_hda_gen_free(&spec->gen);
 	kfree(spec);
 }
 
@@ -1672,7 +1675,8 @@
 	struct via_spec *spec = codec->spec;
 
 	if (!spec->hp_independent_mode && spec->autocfg.hp_pins[0] &&
-	    (spec->codec_type != VT1708 || spec->vt1708_jack_detect))
+	    (spec->codec_type != VT1708 || spec->vt1708_jack_detect) &&
+	    is_jack_detectable(codec, spec->autocfg.hp_pins[0]))
 		present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
 
 	if (spec->smart51_enabled)
@@ -1684,69 +1688,6 @@
 	via_line_automute(codec, present);
 }
 
-static void via_gpio_control(struct hda_codec *codec)
-{
-	unsigned int gpio_data;
-	unsigned int vol_counter;
-	unsigned int vol;
-	unsigned int master_vol;
-
-	struct via_spec *spec = codec->spec;
-
-	gpio_data = snd_hda_codec_read(codec, codec->afg, 0,
-				       AC_VERB_GET_GPIO_DATA, 0) & 0x03;
-
-	vol_counter = (snd_hda_codec_read(codec, codec->afg, 0,
-					  0xF84, 0) & 0x3F0000) >> 16;
-
-	vol = vol_counter & 0x1F;
-	master_vol = snd_hda_codec_read(codec, 0x1A, 0,
-					AC_VERB_GET_AMP_GAIN_MUTE,
-					AC_AMP_GET_INPUT);
-
-	if (gpio_data == 0x02) {
-		/* unmute line out */
-		snd_hda_set_pin_ctl(codec, spec->autocfg.line_out_pins[0],
-				    PIN_OUT);
-		if (vol_counter & 0x20) {
-			/* decrease volume */
-			if (vol > master_vol)
-				vol = master_vol;
-			snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT,
-						 0, HDA_AMP_VOLMASK,
-						 master_vol-vol);
-		} else {
-			/* increase volume */
-			snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT, 0,
-					 HDA_AMP_VOLMASK,
-					 ((master_vol+vol) > 0x2A) ? 0x2A :
-					  (master_vol+vol));
-		}
-	} else if (!(gpio_data & 0x02)) {
-		/* mute line out */
-		snd_hda_set_pin_ctl(codec, spec->autocfg.line_out_pins[0], 0);
-	}
-}
-
-/* unsolicited event for jack sensing */
-static void via_unsol_event(struct hda_codec *codec,
-				  unsigned int res)
-{
-	res >>= 26;
-	res = snd_hda_jack_get_action(codec, res);
-
-	if (res & VIA_JACK_EVENT)
-		set_widgets_power_state(codec);
-
-	res &= ~VIA_JACK_EVENT;
-
-	if (res == VIA_HP_EVENT || res == VIA_LINE_EVENT)
-		via_hp_automute(codec);
-	else if (res == VIA_GPIO_EVENT)
-		via_gpio_control(codec);
-	snd_hda_jack_report_sync(codec);
-}
-
 #ifdef CONFIG_PM
 static int via_suspend(struct hda_codec *codec)
 {
@@ -1764,7 +1705,7 @@
 }
 #endif
 
-#ifdef CONFIG_SND_HDA_POWER_SAVE
+#ifdef CONFIG_PM
 static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
 {
 	struct via_spec *spec = codec->spec;
@@ -1782,11 +1723,9 @@
 	.build_pcms = via_build_pcms,
 	.init = via_init,
 	.free = via_free,
-	.unsol_event = via_unsol_event,
+	.unsol_event = snd_hda_jack_unsol_event,
 #ifdef CONFIG_PM
 	.suspend = via_suspend,
-#endif
-#ifdef CONFIG_SND_HDA_POWER_SAVE
 	.check_power_status = via_check_power_status,
 #endif
 };
@@ -2762,6 +2701,17 @@
 	snd_hda_set_pin_ctl(codec, spec->autocfg.dig_in_pin, PIN_IN);
 }
 
+static void via_jack_output_event(struct hda_codec *codec, struct hda_jack_tbl *tbl)
+{
+	set_widgets_power_state(codec);
+	via_hp_automute(codec);
+}
+
+static void via_jack_powerstate_event(struct hda_codec *codec, struct hda_jack_tbl *tbl)
+{
+	set_widgets_power_state(codec);
+}
+
 /* initialize the unsolicited events */
 static void via_auto_init_unsol_event(struct hda_codec *codec)
 {
@@ -2769,26 +2719,31 @@
 	struct auto_pin_cfg *cfg = &spec->autocfg;
 	unsigned int ev;
 	int i;
+	hda_jack_callback cb;
 
 	if (cfg->hp_pins[0] && is_jack_detectable(codec, cfg->hp_pins[0]))
-		snd_hda_jack_detect_enable(codec, cfg->hp_pins[0],
-					   VIA_HP_EVENT | VIA_JACK_EVENT);
+		snd_hda_jack_detect_enable_callback(codec, cfg->hp_pins[0],
+						    VIA_HP_EVENT | VIA_JACK_EVENT,
+						    via_jack_output_event);
 
 	if (cfg->speaker_pins[0])
 		ev = VIA_LINE_EVENT;
 	else
 		ev = 0;
+	cb = ev ? via_jack_output_event : via_jack_powerstate_event;
+
 	for (i = 0; i < cfg->line_outs; i++) {
 		if (cfg->line_out_pins[i] &&
 		    is_jack_detectable(codec, cfg->line_out_pins[i]))
-			snd_hda_jack_detect_enable(codec, cfg->line_out_pins[i],
-						   ev | VIA_JACK_EVENT);
+			snd_hda_jack_detect_enable_callback(codec, cfg->line_out_pins[i],
+							    ev | VIA_JACK_EVENT, cb);
 	}
 
 	for (i = 0; i < cfg->num_inputs; i++) {
 		if (is_jack_detectable(codec, cfg->inputs[i].pin))
-			snd_hda_jack_detect_enable(codec, cfg->inputs[i].pin,
-						   VIA_JACK_EVENT);
+			snd_hda_jack_detect_enable_callback(codec, cfg->inputs[i].pin,
+							    VIA_JACK_EVENT,
+							    via_jack_powerstate_event);
 	}
 }
 
@@ -2815,7 +2770,6 @@
 
 	via_hp_automute(codec);
 	vt1708_update_hp_work(spec);
-	snd_hda_jack_report_sync(codec);
 
 	return 0;
 }
@@ -3669,6 +3623,32 @@
 		update_power_state(codec, 0x21, AC_PWRST_D3);
 }
 
+/*
+ * pin fix-up
+ */
+enum {
+	VIA_FIXUP_INTMIC_BOOST,
+};
+
+static void via_fixup_intmic_boost(struct hda_codec *codec,
+				  const struct hda_fixup *fix, int action)
+{
+	if (action == HDA_FIXUP_ACT_PRE_PROBE)
+		override_mic_boost(codec, 0x30, 0, 2, 40);
+}
+
+static const struct hda_fixup via_fixups[] = {
+	[VIA_FIXUP_INTMIC_BOOST] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = via_fixup_intmic_boost,
+	},
+};
+
+static const struct snd_pci_quirk vt2002p_fixups[] = {
+	SND_PCI_QUIRK(0x1043, 0x8532, "Asus X202E", VIA_FIXUP_INTMIC_BOOST),
+	{}
+};
+
 /* patch for vt2002P */
 static int patch_vt2002P(struct hda_codec *codec)
 {
@@ -3685,6 +3665,9 @@
 	override_mic_boost(codec, 0x29, 0, 3, 40);
 	add_secret_dac_path(codec);
 
+	snd_hda_pick_fixup(codec, NULL, vt2002p_fixups, via_fixups);
+	snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
+
 	/* automatic parse from the BIOS config */
 	err = via_parse_auto_config(codec);
 	if (err < 0) {
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 3e4f8c1..20bcdde 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -2103,7 +2103,7 @@
 /*
  * suspend/resume
  */
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int aureon_resume(struct snd_ice1712 *ice)
 {
 	struct aureon_spec *spec = ice->spec;
@@ -2160,7 +2160,7 @@
 		wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
 	}
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	ice->pm_resume = aureon_resume;
 	ice->pm_suspend_enabled = 1;
 #endif
diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h
index 0da778a..d0e7d87 100644
--- a/sound/pci/ice1712/ice1712.h
+++ b/sound/pci/ice1712/ice1712.h
@@ -384,7 +384,7 @@
 	char **ext_clock_names;
 	int ext_clock_count;
 	void (*pro_open)(struct snd_ice1712 *, struct snd_pcm_substream *);
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	int (*pm_suspend)(struct snd_ice1712 *);
 	int (*pm_resume)(struct snd_ice1712 *);
 	unsigned int pm_suspend_enabled:1;
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index bed9f34..3050a52 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -2792,7 +2792,7 @@
 	pci_set_drvdata(pci, NULL);
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int snd_vt1724_suspend(struct device *dev)
 {
 	struct pci_dev *pci = to_pci_dev(dev);
@@ -2878,7 +2878,7 @@
 #define SND_VT1724_PM_OPS	&snd_vt1724_pm
 #else
 #define SND_VT1724_PM_OPS	NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 static struct pci_driver vt1724_driver = {
 	.name = KBUILD_MODNAME,
diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c
index 98bc3b7..14fd536 100644
--- a/sound/pci/ice1712/juli.c
+++ b/sound/pci/ice1712/juli.c
@@ -486,7 +486,7 @@
  * suspend/resume
  * */
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int juli_resume(struct snd_ice1712 *ice)
 {
 	struct snd_akm4xxx *ak = ice->akm;
@@ -652,7 +652,7 @@
 
 	ice->spdif.ops.open = juli_spdif_in_open;
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	ice->pm_resume = juli_resume;
 	ice->pm_suspend = juli_suspend;
 	ice->pm_suspend_enabled = 1;
diff --git a/sound/pci/ice1712/prodigy_hifi.c b/sound/pci/ice1712/prodigy_hifi.c
index 075d5aa..7bf093c 100644
--- a/sound/pci/ice1712/prodigy_hifi.c
+++ b/sound/pci/ice1712/prodigy_hifi.c
@@ -1100,7 +1100,7 @@
 		ak4396_write(ice, ak4396_inits[i], ak4396_inits[i+1]);
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int prodigy_hd2_resume(struct snd_ice1712 *ice)
 {
 	/* initialize ak4396 codec and restore previous mixer volumes */
@@ -1141,7 +1141,7 @@
 		return -ENOMEM;
 	ice->spec = spec;
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	ice->pm_resume = &prodigy_hd2_resume;
 	ice->pm_suspend_enabled = 1;
 #endif
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index cd553f5..ea4b706 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -1541,6 +1541,26 @@
 					      snd_dma_pci_data(chip->pci),
 					      rec->prealloc_size, rec->prealloc_max_size);
 
+	if (rec->ac97_idx == ICHD_PCMOUT && rec->playback_ops) {
+		struct snd_pcm_chmap *chmap;
+		int chs = 2;
+		if (rec->ac97_idx == ICHD_PCMOUT) {
+			if (chip->multi8)
+				chs = 8;
+			else if (chip->multi6)
+				chs = 6;
+			else if (chip->multi4)
+				chs = 4;
+		}
+		err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+					     snd_pcm_alt_chmaps, chs, 0,
+					     &chmap);
+		if (err < 0)
+			return err;
+		chmap->channel_mask = SND_PCM_CHMAP_MASK_2468;
+		chip->ac97[0]->chmaps[SNDRV_PCM_STREAM_PLAYBACK] = chmap;
+	}
+
 	return 0;
 }
 
@@ -2206,7 +2226,7 @@
 		case DEVICE_INTEL_ICH4:
 			chip->spdif_idx = ICHD_SPBAR;
 			break;
-		};
+		}
 	}
 
 	chip->in_ac97_init = 1;
@@ -2620,7 +2640,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 /*
  * power management
  */
@@ -2741,7 +2761,7 @@
 #define INTEL8X0_PM_OPS	&intel8x0_pm
 #else
 #define INTEL8X0_PM_OPS	NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 #define INTEL8X0_TESTBUF_SIZE	32768	/* enough large for one shot */
 
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index da44bb3..4d55173 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -1008,7 +1008,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 /*
  * power management
  */
@@ -1067,7 +1067,7 @@
 #define INTEL8X0M_PM_OPS	&intel8x0m_pm
 #else
 #define INTEL8X0M_PM_OPS	NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 #ifdef CONFIG_PROC_FS
 static void snd_intel8x0m_proc_read(struct snd_info_entry * entry,
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index e69ce5f..8a67ce95 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -196,8 +196,8 @@
 #define K1212_ADAT_BUF_SIZE	(K1212_ADAT_CHANNELS * 2 * kPlayBufferFrames * kNumBuffers)
 #define K1212_MAX_BUF_SIZE	(K1212_ANALOG_BUF_SIZE + K1212_ADAT_BUF_SIZE)
 
-#define k1212MinADCSens     0x7f
-#define k1212MaxADCSens     0x00
+#define k1212MinADCSens     0x00
+#define k1212MaxADCSens     0x7f
 #define k1212MaxVolume      0x7fff
 #define k1212MaxWaveVolume  0xffff
 #define k1212MinVolume      0x0000
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index c85d1ff..eb3cd3a 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -789,7 +789,7 @@
 
 	unsigned int in_suspend;
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	u16 *suspend_mem;
 #endif
 
@@ -2368,7 +2368,7 @@
 		outw(0, chip->iobase + HOST_INT_CTRL); /* disable ints */
 	}
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	vfree(chip->suspend_mem);
 #endif
 
@@ -2390,7 +2390,7 @@
 /*
  * APM support
  */
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int m3_suspend(struct device *dev)
 {
 	struct pci_dev *pci = to_pci_dev(dev);
@@ -2485,7 +2485,7 @@
 #define M3_PM_OPS	&m3_pm
 #else
 #define M3_PM_OPS	NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 #ifdef CONFIG_SND_MAESTRO3_INPUT
 static int __devinit snd_m3_input_register(struct snd_m3 *chip)
@@ -2656,7 +2656,7 @@
 	}
 	chip->irq = pci->irq;
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	chip->suspend_mem = vmalloc(sizeof(u16) * (REV_B_CODE_MEMORY_LENGTH + REV_B_DATA_MEMORY_LENGTH));
 	if (chip->suspend_mem == NULL)
 		snd_printk(KERN_WARNING "can't allocate apm buffer\n");
diff --git a/sound/pci/mixart/mixart_hwdep.c b/sound/pci/mixart/mixart_hwdep.c
index bfbdc91..e0f4d875 100644
--- a/sound/pci/mixart/mixart_hwdep.c
+++ b/sound/pci/mixart/mixart_hwdep.c
@@ -538,7 +538,7 @@
 
 		if ((err = snd_card_register(chip->card)) < 0)
 			return err;
-	};
+	}
 
 	snd_printdd("miXart firmware downloaded and successfully set up\n");
 
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index 465cff2..e80e9a1 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -1377,7 +1377,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 /*
  * APM event handler, so the card is properly reinitialized after a power
  * event.
@@ -1441,7 +1441,7 @@
 #define NM256_PM_OPS	&nm256_pm
 #else
 #define NM256_PM_OPS	NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 static int snd_nm256_free(struct nm256 *chip)
 {
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index 37520a2b4..2becae1 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -872,7 +872,7 @@
 	.id_table = oxygen_ids,
 	.probe = generic_oxygen_probe,
 	.remove = __devexit_p(oxygen_pci_remove),
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	.driver = {
 		.pm = &oxygen_pci_pm,
 	},
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h
index 7112a89..09a24b2 100644
--- a/sound/pci/oxygen/oxygen.h
+++ b/sound/pci/oxygen/oxygen.h
@@ -161,7 +161,7 @@
 				     )
 		    );
 void oxygen_pci_remove(struct pci_dev *pci);
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 extern const struct dev_pm_ops oxygen_pci_pm;
 #endif
 void oxygen_pci_shutdown(struct pci_dev *pci);
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index e9fa2d0..9562dc6 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -726,7 +726,7 @@
 }
 EXPORT_SYMBOL(oxygen_pci_remove);
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int oxygen_pci_suspend(struct device *dev)
 {
 	struct pci_dev *pci = to_pci_dev(dev);
@@ -824,7 +824,7 @@
 
 SIMPLE_DEV_PM_OPS(oxygen_pci_pm, oxygen_pci_suspend, oxygen_pci_resume);
 EXPORT_SYMBOL(oxygen_pci_pm);
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 void oxygen_pci_shutdown(struct pci_dev *pci)
 {
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index d3b606b..3d71423 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -93,7 +93,7 @@
 	.id_table = xonar_ids,
 	.probe = xonar_probe,
 	.remove = __devexit_p(oxygen_pci_remove),
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	.driver = {
 		.pm = &oxygen_pci_pm,
 	},
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index e3ac1f7..be4f145 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -91,6 +91,14 @@
 	PCI_ID_PCX924E,
 	PCI_ID_PCX924HRMIC,
 	PCI_ID_PCX924E_MIC,
+	PCI_ID_VX442HR,
+	PCI_ID_PCX442HR,
+	PCI_ID_VX442E,
+	PCI_ID_PCX442E,
+	PCI_ID_VX822HR,
+	PCI_ID_PCX822HR,
+	PCI_ID_VX822E,
+	PCI_ID_PCX822E,
 	PCI_ID_LAST
 };
 
@@ -121,6 +129,14 @@
 	{ 0x10b5, 0x9056, 0x1369, 0xbb21, 0, 0, PCI_ID_PCX924E, },
 	{ 0x10b5, 0x9056, 0x1369, 0xbf01, 0, 0, PCI_ID_PCX924HRMIC, },
 	{ 0x10b5, 0x9056, 0x1369, 0xbf21, 0, 0, PCI_ID_PCX924E_MIC, },
+	{ 0x10b5, 0x9656, 0x1369, 0xd001, 0, 0, PCI_ID_VX442HR, },
+	{ 0x10b5, 0x9656, 0x1369, 0xd101, 0, 0, PCI_ID_PCX442HR, },
+	{ 0x10b5, 0x9056, 0x1369, 0xd021, 0, 0, PCI_ID_VX442E, },
+	{ 0x10b5, 0x9056, 0x1369, 0xd121, 0, 0, PCI_ID_PCX442E, },
+	{ 0x10b5, 0x9656, 0x1369, 0xd201, 0, 0, PCI_ID_VX822HR, },
+	{ 0x10b5, 0x9656, 0x1369, 0xd301, 0, 0, PCI_ID_PCX822HR, },
+	{ 0x10b5, 0x9056, 0x1369, 0xd221, 0, 0, PCI_ID_VX822E, },
+	{ 0x10b5, 0x9056, 0x1369, 0xd321, 0, 0, PCI_ID_PCX822E, },
 	{ 0, }
 };
 
@@ -160,6 +176,14 @@
 [PCI_ID_PCX924E] =      { "PCX924e",      1, 1, 5, 44 },
 [PCI_ID_PCX924HRMIC] =  { "PCX924HR-Mic", 1, 1, 5, 44 },
 [PCI_ID_PCX924E_MIC] =  { "PCX924e-Mic",  1, 1, 5, 44 },
+[PCI_ID_VX442HR] =      { "VX442HR",      2, 2, 0, 41 },
+[PCI_ID_PCX442HR] =     { "PCX442HR",     2, 2, 0, 41 },
+[PCI_ID_VX442E] =       { "VX442e",       2, 2, 1, 41 },
+[PCI_ID_PCX442E] =      { "PCX442e",      2, 2, 1, 41 },
+[PCI_ID_VX822HR] =      { "VX822HR",      4, 1, 2, 42 },
+[PCI_ID_PCX822HR] =     { "PCX822HR",     4, 1, 2, 42 },
+[PCI_ID_VX822E] =       { "VX822e",       4, 1, 3, 42 },
+[PCI_ID_PCX822E] =      { "PCX822e",      4, 1, 3, 42 },
 };
 
 /* boards without hw AES1 and SRC onboard are all using fw_file_set==4 */
diff --git a/sound/pci/pcxhr/pcxhr_hwdep.c b/sound/pci/pcxhr/pcxhr_hwdep.c
index ec1587c..bf207e3 100644
--- a/sound/pci/pcxhr/pcxhr_hwdep.c
+++ b/sound/pci/pcxhr/pcxhr_hwdep.c
@@ -66,10 +66,10 @@
 	err = pcxhr_send_msg(mgr, &rmh);
 	if (err)
 		return err;
-	/* test 8 or 12 phys out */
-	if ((rmh.stat[0] & MASK_FIRST_FIELD) != mgr->playback_chips * 2)
+	/* test 4, 8 or 12 phys out */
+	if ((rmh.stat[0] & MASK_FIRST_FIELD) < mgr->playback_chips * 2)
 		return -EINVAL;
-	/* test 8 or 2 phys in */
+	/* test 4, 8 or 2 phys in */
 	if (((rmh.stat[0] >> (2 * FIELD_SIZE)) & MASK_FIRST_FIELD) <
 	    mgr->capture_chips * 2)
 		return -EINVAL;
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index 760ee46..7d29154 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -464,7 +464,7 @@
 
 	unsigned long received_irqs;
 	unsigned long handled_irqs;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	int in_suspend;
 #endif
 };
@@ -1150,7 +1150,7 @@
 	}
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int riptide_suspend(struct device *dev)
 {
 	struct pci_dev *pci = to_pci_dev(dev);
@@ -1193,7 +1193,7 @@
 #define RIPTIDE_PM_OPS	&riptide_pm
 #else
 #define RIPTIDE_PM_OPS	NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 static int try_to_load_firmware(struct cmdif *cif, struct snd_riptide *chip)
 {
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c
index 805ab6e..51e4340 100644
--- a/sound/pci/sis7019.c
+++ b/sound/pci/sis7019.c
@@ -103,7 +103,7 @@
  * we're not doing power management, we still need to allocate a page
  * for the silence buffer.
  */
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 #define SIS_SUSPEND_PAGES	4
 #else
 #define SIS_SUSPEND_PAGES	1
@@ -1208,7 +1208,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int sis_suspend(struct device *dev)
 {
 	struct pci_dev *pci = to_pci_dev(dev);
@@ -1305,7 +1305,7 @@
 #define SIS_PM_OPS	&sis_pm
 #else
 #define SIS_PM_OPS	NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 static int sis_alloc_suspend(struct sis7019 *sis)
 {
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
index d36e6ca..8a6f1f7 100644
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -177,7 +177,7 @@
 	.id_table = snd_trident_ids,
 	.probe = snd_trident_probe,
 	.remove = __devexit_p(snd_trident_remove),
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	.driver = {
 		.pm = &snd_trident_pm,
 	},
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index 94011dc..06b10d1 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -3919,7 +3919,7 @@
 	}
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int snd_trident_suspend(struct device *dev)
 {
 	struct pci_dev *pci = to_pci_dev(dev);
@@ -3983,4 +3983,4 @@
 }
 
 SIMPLE_DEV_PM_OPS(snd_trident_pm, snd_trident_suspend, snd_trident_resume);
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 0eb7245..f0b4efd 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -362,7 +362,7 @@
 
 	unsigned char old_legacy;
 	unsigned char old_legacy_cfg;
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	unsigned char legacy_saved;
 	unsigned char legacy_cfg_saved;
 	unsigned char spdif_ctrl_saved;
@@ -1440,6 +1440,7 @@
 static int __devinit snd_via8233_pcm_new(struct via82xx *chip)
 {
 	struct snd_pcm *pcm;
+	struct snd_pcm_chmap *chmap;
 	int i, err;
 
 	chip->playback_devno = 0;	/* x 4 */
@@ -1467,6 +1468,12 @@
 					      snd_dma_pci_data(chip->pci),
 					      64*1024, VIA_MAX_BUFSIZE);
 
+	err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+				     snd_pcm_std_chmaps, 2, 0,
+				     &chmap);
+	if (err < 0)
+		return err;
+
 	/* PCM #1:  multi-channel playback and 2nd capture */
 	err = snd_pcm_new(chip->card, chip->card->shortname, 1, 1, 1, &pcm);
 	if (err < 0)
@@ -1484,6 +1491,14 @@
 	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
 					      snd_dma_pci_data(chip->pci),
 					      64*1024, VIA_MAX_BUFSIZE);
+
+	err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+				     snd_pcm_alt_chmaps, 6, 0,
+				     &chmap);
+	if (err < 0)
+		return err;
+	chip->ac97->chmaps[SNDRV_PCM_STREAM_PLAYBACK] = chmap;
+
 	return 0;
 }
 
@@ -1493,6 +1508,7 @@
 static int __devinit snd_via8233a_pcm_new(struct via82xx *chip)
 {
 	struct snd_pcm *pcm;
+	struct snd_pcm_chmap *chmap;
 	int err;
 
 	chip->multi_devno = 0;
@@ -1519,6 +1535,13 @@
 					      snd_dma_pci_data(chip->pci),
 					      64*1024, VIA_MAX_BUFSIZE);
 
+	err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+				     snd_pcm_alt_chmaps, 6, 0,
+				     &chmap);
+	if (err < 0)
+		return err;
+	chip->ac97->chmaps[SNDRV_PCM_STREAM_PLAYBACK] = chmap;
+
 	/* SPDIF supported? */
 	if (! ac97_can_spdif(chip->ac97))
 		return 0;
@@ -2038,7 +2061,7 @@
 		if (mpu_port >= 0x200) {	/* force MIDI */
 			mpu_port &= 0xfffc;
 			pci_write_config_dword(chip->pci, 0x18, mpu_port | 0x01);
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 			chip->mpu_port_saved = mpu_port;
 #endif
 		} else {
@@ -2090,7 +2113,7 @@
 
 	snd_via686_create_gameport(chip, &legacy);
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	chip->legacy_saved = legacy;
 	chip->legacy_cfg_saved = legacy_cfg;
 #endif
@@ -2238,7 +2261,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 /*
  * power management
  */
@@ -2313,7 +2336,7 @@
 #define SND_VIA82XX_PM_OPS	&snd_via82xx_pm
 #else
 #define SND_VIA82XX_PM_OPS	NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 static int snd_via82xx_free(struct via82xx *chip)
 {
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index e886bc1..8e0efc4 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -1019,7 +1019,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 /*
  * power management
  */
@@ -1076,7 +1076,7 @@
 #define SND_VIA82XX_PM_OPS	&snd_via82xx_pm
 #else
 #define SND_VIA82XX_PM_OPS	NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 static int snd_via82xx_free(struct via82xx_modem *chip)
 {
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c
index b89e7a8..fdfbaf857 100644
--- a/sound/pci/vx222/vx222.c
+++ b/sound/pci/vx222/vx222.c
@@ -257,7 +257,7 @@
 	pci_set_drvdata(pci, NULL);
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int snd_vx222_suspend(struct device *dev)
 {
 	struct pci_dev *pci = to_pci_dev(dev);
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index 4810356..e01fe34 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -355,7 +355,7 @@
 	.id_table = snd_ymfpci_ids,
 	.probe = snd_card_ymfpci_probe,
 	.remove = __devexit_p(snd_card_ymfpci_remove),
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	.driver = {
 		.pm = &snd_ymfpci_pm,
 	},
diff --git a/sound/pci/ymfpci/ymfpci.h b/sound/pci/ymfpci/ymfpci.h
index bddc405..4631a23 100644
--- a/sound/pci/ymfpci/ymfpci.h
+++ b/sound/pci/ymfpci/ymfpci.h
@@ -363,7 +363,7 @@
 	const struct firmware *dsp_microcode;
 	const struct firmware *controller_microcode;
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	u32 *saved_regs;
 	u32 saved_ydsxgr_mode;
 	u16 saved_dsxg_legacy;
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 62b2363..3a6f03f 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -1166,6 +1166,11 @@
 	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
 					      snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
 
+	err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+				     snd_pcm_std_chmaps, 2, 0, NULL);
+	if (err < 0)
+		return err;
+
 	if (rpcm)
 		*rpcm = pcm;
 	return 0;
@@ -1257,6 +1262,14 @@
 	.pointer =		snd_ymfpci_playback_pointer,
 };
 
+static const struct snd_pcm_chmap_elem surround_map[] = {
+	{ .channels = 1,
+	  .map = { SNDRV_CHMAP_MONO } },
+	{ .channels = 2,
+	  .map = { SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
+	{ }
+};
+
 int __devinit snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device, struct snd_pcm ** rpcm)
 {
 	struct snd_pcm *pcm;
@@ -1278,6 +1291,11 @@
 	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
 					      snd_dma_pci_data(chip->pci), 64*1024, 256*1024);
 
+	err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
+				     surround_map, 2, 0, NULL);
+	if (err < 0)
+		return err;
+
 	if (rpcm)
 		*rpcm = pcm;
 	return 0;
@@ -2242,7 +2260,7 @@
 	pci_set_power_state(chip->pci, 3);
 #endif
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	vfree(chip->saved_regs);
 #endif
 	if (chip->irq >= 0)
@@ -2272,7 +2290,7 @@
 	return snd_ymfpci_free(chip);
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int saved_regs_index[] = {
 	/* spdif */
 	YDSXGR_SPDIFOUTCTRL,
@@ -2374,7 +2392,7 @@
 }
 
 SIMPLE_DEV_PM_OPS(snd_ymfpci_pm, snd_ymfpci_suspend, snd_ymfpci_resume);
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 int __devinit snd_ymfpci_create(struct snd_card *card,
 				struct pci_dev * pci,
@@ -2452,7 +2470,7 @@
 		return err;
 	}
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 	chip->saved_regs = vmalloc(YDSXGR_NUM_SAVED_REGS * sizeof(u32));
 	if (chip->saved_regs == NULL) {
 		snd_ymfpci_free(chip);
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index c5de0a8..5da8ca7 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -9,6 +9,7 @@
 	select SND_JACK if INPUT=y || INPUT=SND
 	select REGMAP_I2C if I2C
 	select REGMAP_SPI if SPI_MASTER
+	select SND_COMPRESS_OFFLOAD
 	---help---
 
 	  If you want ASoC support, you should say Y here and also to the
@@ -32,9 +33,9 @@
 source "sound/soc/atmel/Kconfig"
 source "sound/soc/au1x/Kconfig"
 source "sound/soc/blackfin/Kconfig"
+source "sound/soc/cirrus/Kconfig"
 source "sound/soc/davinci/Kconfig"
 source "sound/soc/dwc/Kconfig"
-source "sound/soc/ep93xx/Kconfig"
 source "sound/soc/fsl/Kconfig"
 source "sound/soc/jz4740/Kconfig"
 source "sound/soc/nuc900/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 00a555a..bcbf1d0 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -1,5 +1,5 @@
 snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o
-snd-soc-core-objs += soc-pcm.o soc-io.o
+snd-soc-core-objs += soc-pcm.o soc-compress.o soc-io.o
 
 snd-soc-dmaengine-pcm-objs := soc-dmaengine-pcm.o
 obj-$(CONFIG_SND_SOC_DMAENGINE_PCM) += snd-soc-dmaengine-pcm.o
@@ -10,9 +10,9 @@
 obj-$(CONFIG_SND_SOC)	+= atmel/
 obj-$(CONFIG_SND_SOC)	+= au1x/
 obj-$(CONFIG_SND_SOC)	+= blackfin/
+obj-$(CONFIG_SND_SOC)	+= cirrus/
 obj-$(CONFIG_SND_SOC)	+= davinci/
 obj-$(CONFIG_SND_SOC)	+= dwc/
-obj-$(CONFIG_SND_SOC)	+= ep93xx/
 obj-$(CONFIG_SND_SOC)	+= fsl/
 obj-$(CONFIG_SND_SOC)	+= jz4740/
 obj-$(CONFIG_SND_SOC)	+= mid-x86/
diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c
index d542d406..16b9c9e 100644
--- a/sound/soc/blackfin/bf5xx-ad1836.c
+++ b/sound/soc/blackfin/bf5xx-ad1836.c
@@ -59,62 +59,63 @@
 #define BF5XX_AD1836_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \
 				SND_SOC_DAIFMT_CBM_CFM)
 
-static struct snd_soc_dai_link bf5xx_ad1836_dai[] = {
-	{
-		.name = "ad1836",
-		.stream_name = "AD1836",
-		.cpu_dai_name = "bfin-tdm.0",
-		.codec_dai_name = "ad1836-hifi",
-		.platform_name = "bfin-tdm-pcm-audio",
-		.codec_name = "spi0.4",
-		.ops = &bf5xx_ad1836_ops,
-		.dai_fmt = BF5XX_AD1836_DAIFMT,
-	},
-	{
-		.name = "ad1836",
-		.stream_name = "AD1836",
-		.cpu_dai_name = "bfin-tdm.1",
-		.codec_dai_name = "ad1836-hifi",
-		.platform_name = "bfin-tdm-pcm-audio",
-		.codec_name = "spi0.4",
-		.ops = &bf5xx_ad1836_ops,
-		.dai_fmt = BF5XX_AD1836_DAIFMT,
-	},
+static struct snd_soc_dai_link bf5xx_ad1836_dai = {
+	.name = "ad1836",
+	.stream_name = "AD1836",
+	.codec_dai_name = "ad1836-hifi",
+	.platform_name = "bfin-tdm-pcm-audio",
+	.ops = &bf5xx_ad1836_ops,
+	.dai_fmt = BF5XX_AD1836_DAIFMT,
 };
 
 static struct snd_soc_card bf5xx_ad1836 = {
 	.name = "bfin-ad1836",
 	.owner = THIS_MODULE,
-	.dai_link = &bf5xx_ad1836_dai[CONFIG_SND_BF5XX_SPORT_NUM],
+	.dai_link = &bf5xx_ad1836_dai,
 	.num_links = 1,
 };
 
-static struct platform_device *bfxx_ad1836_snd_device;
-
-static int __init bf5xx_ad1836_init(void)
+static __devinit int bf5xx_ad1836_driver_probe(struct platform_device *pdev)
 {
+	struct snd_soc_card *card = &bf5xx_ad1836;
+	const char **link_name;
 	int ret;
 
-	bfxx_ad1836_snd_device = platform_device_alloc("soc-audio", -1);
-	if (!bfxx_ad1836_snd_device)
-		return -ENOMEM;
+	link_name = pdev->dev.platform_data;
+	if (!link_name) {
+		dev_err(&pdev->dev, "No platform data supplied\n");
+		return -EINVAL;
+	}
+	bf5xx_ad1836_dai.cpu_dai_name = link_name[0];
+	bf5xx_ad1836_dai.codec_name = link_name[1];
 
-	platform_set_drvdata(bfxx_ad1836_snd_device, &bf5xx_ad1836);
-	ret = platform_device_add(bfxx_ad1836_snd_device);
+	card->dev = &pdev->dev;
+	platform_set_drvdata(pdev, card);
 
+	ret = snd_soc_register_card(card);
 	if (ret)
-		platform_device_put(bfxx_ad1836_snd_device);
-
+		dev_err(&pdev->dev, "Failed to register card\n");
 	return ret;
 }
 
-static void __exit bf5xx_ad1836_exit(void)
+static int __devexit bf5xx_ad1836_driver_remove(struct platform_device *pdev)
 {
-	platform_device_unregister(bfxx_ad1836_snd_device);
+	struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+	snd_soc_unregister_card(card);
+	return 0;
 }
 
-module_init(bf5xx_ad1836_init);
-module_exit(bf5xx_ad1836_exit);
+static struct platform_driver bf5xx_ad1836_driver = {
+	.driver = {
+		.name = "bfin-snd-ad1836",
+		.owner = THIS_MODULE,
+		.pm = &snd_soc_pm_ops,
+	},
+	.probe = bf5xx_ad1836_driver_probe,
+	.remove = __devexit_p(bf5xx_ad1836_driver_remove),
+};
+module_platform_driver(bf5xx_ad1836_driver);
 
 /* Module information */
 MODULE_AUTHOR("Barry Song");
diff --git a/sound/soc/ep93xx/Kconfig b/sound/soc/cirrus/Kconfig
similarity index 100%
rename from sound/soc/ep93xx/Kconfig
rename to sound/soc/cirrus/Kconfig
diff --git a/sound/soc/ep93xx/Makefile b/sound/soc/cirrus/Makefile
similarity index 100%
rename from sound/soc/ep93xx/Makefile
rename to sound/soc/cirrus/Makefile
diff --git a/sound/soc/ep93xx/edb93xx.c b/sound/soc/cirrus/edb93xx.c
similarity index 100%
rename from sound/soc/ep93xx/edb93xx.c
rename to sound/soc/cirrus/edb93xx.c
diff --git a/sound/soc/ep93xx/ep93xx-ac97.c b/sound/soc/cirrus/ep93xx-ac97.c
similarity index 100%
rename from sound/soc/ep93xx/ep93xx-ac97.c
rename to sound/soc/cirrus/ep93xx-ac97.c
diff --git a/sound/soc/ep93xx/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c
similarity index 100%
rename from sound/soc/ep93xx/ep93xx-i2s.c
rename to sound/soc/cirrus/ep93xx-i2s.c
diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/cirrus/ep93xx-pcm.c
similarity index 100%
rename from sound/soc/ep93xx/ep93xx-pcm.c
rename to sound/soc/cirrus/ep93xx-pcm.c
diff --git a/sound/soc/ep93xx/ep93xx-pcm.h b/sound/soc/cirrus/ep93xx-pcm.h
similarity index 100%
rename from sound/soc/ep93xx/ep93xx-pcm.h
rename to sound/soc/cirrus/ep93xx-pcm.h
diff --git a/sound/soc/ep93xx/simone.c b/sound/soc/cirrus/simone.c
similarity index 100%
rename from sound/soc/ep93xx/simone.c
rename to sound/soc/cirrus/simone.c
diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/cirrus/snappercl15.c
similarity index 100%
rename from sound/soc/ep93xx/snappercl15.c
rename to sound/soc/cirrus/snappercl15.c
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 9f8e859..b92759a 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -37,6 +37,7 @@
 	select SND_SOC_CX20442
 	select SND_SOC_DA7210 if I2C
 	select SND_SOC_DA732X if I2C
+	select SND_SOC_DA9055 if I2C
 	select SND_SOC_DFBMCS320
 	select SND_SOC_ISABELLE if I2C
 	select SND_SOC_JZ4740_CODEC
@@ -70,6 +71,7 @@
 	select SND_SOC_UDA134X
 	select SND_SOC_UDA1380 if I2C
 	select SND_SOC_WL1273 if MFD_WL1273_CORE
+	select SND_SOC_WM0010 if SPI_MASTER
 	select SND_SOC_WM1250_EV1 if I2C
 	select SND_SOC_WM2000 if I2C
 	select SND_SOC_WM2200 if I2C
@@ -238,6 +240,9 @@
 config SND_SOC_DA732X
         tristate
 
+config SND_SOC_DA9055
+	tristate
+
 config SND_SOC_DFBMCS320
 	tristate
 
@@ -326,6 +331,9 @@
 config SND_SOC_WL1273
 	tristate
 
+config SND_SOC_WM0010
+	tristate
+
 config SND_SOC_WM1250_EV1
 	tristate
 
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 34148bb..9bd4d95 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -24,6 +24,7 @@
 snd-soc-cx20442-objs := cx20442.o
 snd-soc-da7210-objs := da7210.o
 snd-soc-da732x-objs := da732x.o
+snd-soc-da9055-objs := da9055.o
 snd-soc-dfbmcs320-objs := dfbmcs320.o
 snd-soc-dmic-objs := dmic.o
 snd-soc-isabelle-objs := isabelle.o
@@ -61,6 +62,7 @@
 snd-soc-uda134x-objs := uda134x.o
 snd-soc-uda1380-objs := uda1380.o
 snd-soc-wl1273-objs := wl1273.o
+snd-soc-wm0010-objs := wm0010.o
 snd-soc-wm1250-ev1-objs := wm1250-ev1.o
 snd-soc-wm2000-objs := wm2000.o
 snd-soc-wm2200-objs := wm2200.o
@@ -143,6 +145,7 @@
 obj-$(CONFIG_SND_SOC_CX20442)	+= snd-soc-cx20442.o
 obj-$(CONFIG_SND_SOC_DA7210)	+= snd-soc-da7210.o
 obj-$(CONFIG_SND_SOC_DA732X)	+= snd-soc-da732x.o
+obj-$(CONFIG_SND_SOC_DA9055)	+= snd-soc-da9055.o
 obj-$(CONFIG_SND_SOC_DFBMCS320)	+= snd-soc-dfbmcs320.o
 obj-$(CONFIG_SND_SOC_DMIC)	+= snd-soc-dmic.o
 obj-$(CONFIG_SND_SOC_ISABELLE)	+= snd-soc-isabelle.o
@@ -177,6 +180,7 @@
 obj-$(CONFIG_SND_SOC_UDA134X)	+= snd-soc-uda134x.o
 obj-$(CONFIG_SND_SOC_UDA1380)	+= snd-soc-uda1380.o
 obj-$(CONFIG_SND_SOC_WL1273)	+= snd-soc-wl1273.o
+obj-$(CONFIG_SND_SOC_WM0010)	+= snd-soc-wm0010.o
 obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o
 obj-$(CONFIG_SND_SOC_WM2000)	+= snd-soc-wm2000.o
 obj-$(CONFIG_SND_SOC_WM2200)	+= snd-soc-wm2200.o
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c
index 07abd09..af54749 100644
--- a/sound/soc/codecs/ab8500-codec.c
+++ b/sound/soc/codecs/ab8500-codec.c
@@ -391,10 +391,10 @@
 	SND_SOC_DAPM_CLOCK_SUPPLY("audioclk"),
 
 	/* Regulators */
-	SND_SOC_DAPM_REGULATOR_SUPPLY("V-AUD", 0),
-	SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC1", 0),
-	SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC2", 0),
-	SND_SOC_DAPM_REGULATOR_SUPPLY("V-DMIC", 0),
+	SND_SOC_DAPM_REGULATOR_SUPPLY("V-AUD", 0, 0),
+	SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC1", 0, 0),
+	SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC2", 0, 0),
+	SND_SOC_DAPM_REGULATOR_SUPPLY("V-DMIC", 0, 0),
 
 	/* Power */
 	SND_SOC_DAPM_SUPPLY("Audio Power",
@@ -2462,10 +2462,7 @@
 	dev_dbg(dev, "%s: Enter.\n", __func__);
 
 	/* Setup AB8500 according to board-settings */
-	pdata = (struct ab8500_platform_data *)dev_get_platdata(dev->parent);
-
-	/* Inform SoC Core that we have our own I/O arrangements. */
-	codec->control_data = (void *)true;
+	pdata = dev_get_platdata(dev->parent);
 
 	if (np) {
 		if (!pdata)
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index c67b50d..dce6ebe 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -19,6 +19,8 @@
 #include <sound/soc.h>
 #include <sound/tlv.h>
 #include <linux/spi/spi.h>
+#include <linux/regmap.h>
+
 #include "ad1836.h"
 
 enum ad1836_type {
@@ -30,6 +32,7 @@
 /* codec private data */
 struct ad1836_priv {
 	enum ad1836_type type;
+	struct regmap *regmap;
 };
 
 /*
@@ -161,8 +164,8 @@
 		struct snd_pcm_hw_params *params,
 		struct snd_soc_dai *dai)
 {
+	struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(dai->codec);
 	int word_len = 0;
-	struct snd_soc_codec *codec = dai->codec;
 
 	/* bit size */
 	switch (params_format(params)) {
@@ -178,10 +181,12 @@
 		break;
 	}
 
-	snd_soc_update_bits(codec, AD1836_DAC_CTRL1, AD1836_DAC_WORD_LEN_MASK,
+	regmap_update_bits(ad1836->regmap, AD1836_DAC_CTRL1,
+		AD1836_DAC_WORD_LEN_MASK,
 		word_len << AD1836_DAC_WORD_LEN_OFFSET);
 
-	snd_soc_update_bits(codec, AD1836_ADC_CTRL2, AD1836_ADC_WORD_LEN_MASK,
+	regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2,
+		AD1836_ADC_WORD_LEN_MASK,
 		word_len << AD1836_ADC_WORD_OFFSET);
 
 	return 0;
@@ -223,15 +228,17 @@
 #ifdef CONFIG_PM
 static int ad1836_suspend(struct snd_soc_codec *codec)
 {
+	struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
 	/* reset clock control mode */
-	return snd_soc_update_bits(codec, AD1836_ADC_CTRL2,
+	return regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2,
 		AD1836_ADC_SERFMT_MASK, 0);
 }
 
 static int ad1836_resume(struct snd_soc_codec *codec)
 {
+	struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
 	/* restore clock control mode */
-	return snd_soc_update_bits(codec, AD1836_ADC_CTRL2,
+	return regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2,
 		AD1836_ADC_SERFMT_MASK, AD1836_ADC_AUX);
 }
 #else
@@ -250,37 +257,30 @@
 	num_dacs = ad183x_dais[ad1836->type].playback.channels_max / 2;
 	num_adcs = ad183x_dais[ad1836->type].capture.channels_max / 2;
 
-	ret = snd_soc_codec_set_cache_io(codec, 4, 12, SND_SOC_SPI);
-	if (ret < 0) {
-		dev_err(codec->dev, "failed to set cache I/O: %d\n",
-				ret);
-		return ret;
-	}
-
 	/* default setting for ad1836 */
 	/* de-emphasis: 48kHz, power-on dac */
-	snd_soc_write(codec, AD1836_DAC_CTRL1, 0x300);
+	regmap_write(ad1836->regmap, AD1836_DAC_CTRL1, 0x300);
 	/* unmute dac channels */
-	snd_soc_write(codec, AD1836_DAC_CTRL2, 0x0);
+	regmap_write(ad1836->regmap, AD1836_DAC_CTRL2, 0x0);
 	/* high-pass filter enable, power-on adc */
-	snd_soc_write(codec, AD1836_ADC_CTRL1, 0x100);
+	regmap_write(ad1836->regmap, AD1836_ADC_CTRL1, 0x100);
 	/* unmute adc channles, adc aux mode */
-	snd_soc_write(codec, AD1836_ADC_CTRL2, 0x180);
+	regmap_write(ad1836->regmap, AD1836_ADC_CTRL2, 0x180);
 	/* volume */
 	for (i = 1; i <= num_dacs; ++i) {
-		snd_soc_write(codec, AD1836_DAC_L_VOL(i), 0x3FF);
-		snd_soc_write(codec, AD1836_DAC_R_VOL(i), 0x3FF);
+		regmap_write(ad1836->regmap, AD1836_DAC_L_VOL(i), 0x3FF);
+		regmap_write(ad1836->regmap, AD1836_DAC_R_VOL(i), 0x3FF);
 	}
 
 	if (ad1836->type == AD1836) {
 		/* left/right diff:PGA/MUX */
-		snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A);
+		regmap_write(ad1836->regmap, AD1836_ADC_CTRL3, 0x3A);
 		ret = snd_soc_add_codec_controls(codec, ad1836_controls,
 				ARRAY_SIZE(ad1836_controls));
 		if (ret)
 			return ret;
 	} else {
-		snd_soc_write(codec, AD1836_ADC_CTRL3, 0x00);
+		regmap_write(ad1836->regmap, AD1836_ADC_CTRL3, 0x00);
 	}
 
 	ret = snd_soc_add_codec_controls(codec, ad183x_dac_controls, num_dacs * 2);
@@ -313,8 +313,9 @@
 /* power down chip */
 static int ad1836_remove(struct snd_soc_codec *codec)
 {
+	struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
 	/* reset clock control mode */
-	return snd_soc_update_bits(codec, AD1836_ADC_CTRL2,
+	return regmap_update_bits(ad1836->regmap, AD1836_ADC_CTRL2,
 		AD1836_ADC_SERFMT_MASK, 0);
 }
 
@@ -323,8 +324,6 @@
 	.remove = ad1836_remove,
 	.suspend = ad1836_suspend,
 	.resume = ad1836_resume,
-	.reg_cache_size = AD1836_NUM_REGS,
-	.reg_word_size = sizeof(u16),
 
 	.controls = ad183x_controls,
 	.num_controls = ARRAY_SIZE(ad183x_controls),
@@ -334,6 +333,33 @@
 	.num_dapm_routes = ARRAY_SIZE(ad183x_dapm_routes),
 };
 
+static const struct reg_default ad1836_reg_defaults[] = {
+	{ AD1836_DAC_CTRL1, 0x0000 },
+	{ AD1836_DAC_CTRL2, 0x0000 },
+	{ AD1836_DAC_L_VOL(0), 0x0000 },
+	{ AD1836_DAC_R_VOL(0), 0x0000 },
+	{ AD1836_DAC_L_VOL(1), 0x0000 },
+	{ AD1836_DAC_R_VOL(1), 0x0000 },
+	{ AD1836_DAC_L_VOL(2), 0x0000 },
+	{ AD1836_DAC_R_VOL(2), 0x0000 },
+	{ AD1836_DAC_L_VOL(3), 0x0000 },
+	{ AD1836_DAC_R_VOL(3), 0x0000 },
+	{ AD1836_ADC_CTRL1, 0x0000 },
+	{ AD1836_ADC_CTRL2, 0x0000 },
+	{ AD1836_ADC_CTRL3, 0x0000 },
+};
+
+static const struct regmap_config ad1836_regmap_config = {
+	.val_bits = 12,
+	.reg_bits = 4,
+	.read_flag_mask = 0x08,
+
+	.max_register = AD1836_ADC_CTRL3,
+	.reg_defaults = ad1836_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(ad1836_reg_defaults),
+	.cache_type = REGCACHE_RBTREE,
+};
+
 static int __devinit ad1836_spi_probe(struct spi_device *spi)
 {
 	struct ad1836_priv *ad1836;
@@ -344,6 +370,10 @@
 	if (ad1836 == NULL)
 		return -ENOMEM;
 
+	ad1836->regmap = devm_regmap_init_spi(spi, &ad1836_regmap_config);
+	if (IS_ERR(ad1836->regmap))
+		return PTR_ERR(ad1836->regmap);
+
 	ad1836->type = spi_get_device_id(spi)->driver_data;
 
 	spi_set_drvdata(spi, ad1836);
@@ -379,17 +409,7 @@
 	.id_table	= ad1836_ids,
 };
 
-static int __init ad1836_init(void)
-{
-	return spi_register_driver(&ad1836_spi_driver);
-}
-module_init(ad1836_init);
-
-static void __exit ad1836_exit(void)
-{
-	spi_unregister_driver(&ad1836_spi_driver);
-}
-module_exit(ad1836_exit);
+module_spi_driver(ad1836_spi_driver);
 
 MODULE_DESCRIPTION("ASoC ad1836 driver");
 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index 13e62be..2f75266 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -381,40 +381,25 @@
 static int __devinit ad193x_spi_probe(struct spi_device *spi)
 {
 	struct ad193x_priv *ad193x;
-	int ret;
 
 	ad193x = devm_kzalloc(&spi->dev, sizeof(struct ad193x_priv),
 			      GFP_KERNEL);
 	if (ad193x == NULL)
 		return -ENOMEM;
 
-	ad193x->regmap = regmap_init_spi(spi, &ad193x_spi_regmap_config);
-	if (IS_ERR(ad193x->regmap)) {
-		ret = PTR_ERR(ad193x->regmap);
-		goto err_out;
-	}
+	ad193x->regmap = devm_regmap_init_spi(spi, &ad193x_spi_regmap_config);
+	if (IS_ERR(ad193x->regmap))
+		return PTR_ERR(ad193x->regmap);
 
 	spi_set_drvdata(spi, ad193x);
 
-	ret = snd_soc_register_codec(&spi->dev,
-			&soc_codec_dev_ad193x, &ad193x_dai, 1);
-	if (ret < 0)
-		goto err_regmap_exit;
-
-	return 0;
-
-err_regmap_exit:
-	regmap_exit(ad193x->regmap);
-err_out:
-	return ret;
+	return snd_soc_register_codec(&spi->dev, &soc_codec_dev_ad193x,
+			&ad193x_dai, 1);
 }
 
 static int __devexit ad193x_spi_remove(struct spi_device *spi)
 {
-	struct ad193x_priv *ad193x = spi_get_drvdata(spi);
-
 	snd_soc_unregister_codec(&spi->dev);
-	regmap_exit(ad193x->regmap);
 	return 0;
 }
 
@@ -449,40 +434,25 @@
 		const struct i2c_device_id *id)
 {
 	struct ad193x_priv *ad193x;
-	int ret;
 
 	ad193x = devm_kzalloc(&client->dev, sizeof(struct ad193x_priv),
 			      GFP_KERNEL);
 	if (ad193x == NULL)
 		return -ENOMEM;
 
-	ad193x->regmap = regmap_init_i2c(client, &ad193x_i2c_regmap_config);
-	if (IS_ERR(ad193x->regmap)) {
-		ret = PTR_ERR(ad193x->regmap);
-		goto err_out;
-	}
+	ad193x->regmap = devm_regmap_init_i2c(client, &ad193x_i2c_regmap_config);
+	if (IS_ERR(ad193x->regmap))
+		return PTR_ERR(ad193x->regmap);
 
 	i2c_set_clientdata(client, ad193x);
 
-	ret =  snd_soc_register_codec(&client->dev,
-			&soc_codec_dev_ad193x, &ad193x_dai, 1);
-	if (ret < 0)
-		goto err_regmap_exit;
-
-	return 0;
-
-err_regmap_exit:
-	regmap_exit(ad193x->regmap);
-err_out:
-	return ret;
+	return snd_soc_register_codec(&client->dev, &soc_codec_dev_ad193x,
+			&ad193x_dai, 1);
 }
 
 static int __devexit ad193x_i2c_remove(struct i2c_client *client)
 {
-	struct ad193x_priv *ad193x = i2c_get_clientdata(client);
-
 	snd_soc_unregister_codec(&client->dev);
-	regmap_exit(ad193x->regmap);
 	return 0;
 }
 
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 11b1b71..8c39ddd 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -186,7 +186,6 @@
 
 	printk(KERN_INFO "AD1980 SoC Audio Codec\n");
 
-	codec->control_data = codec;	/* we don't use regmap! */
 	ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
 	if (ret < 0) {
 		printk(KERN_ERR "ad1980: failed to register AC97 codec\n");
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c
index 44f5906..704544b 100644
--- a/sound/soc/codecs/adau1373.c
+++ b/sound/soc/codecs/adau1373.c
@@ -1392,17 +1392,7 @@
 	.id_table = adau1373_i2c_id,
 };
 
-static int __init adau1373_init(void)
-{
-	return i2c_add_driver(&adau1373_i2c_driver);
-}
-module_init(adau1373_init);
-
-static void __exit adau1373_exit(void)
-{
-	i2c_del_driver(&adau1373_i2c_driver);
-}
-module_exit(adau1373_exit);
+module_i2c_driver(adau1373_i2c_driver);
 
 MODULE_DESCRIPTION("ASoC ADAU1373 driver");
 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c
index 3d50fc8..51f2f3c 100644
--- a/sound/soc/codecs/adau1701.c
+++ b/sound/soc/codecs/adau1701.c
@@ -527,17 +527,7 @@
 	.id_table	= adau1701_i2c_id,
 };
 
-static int __init adau1701_init(void)
-{
-	return i2c_add_driver(&adau1701_i2c_driver);
-}
-module_init(adau1701_init);
-
-static void __exit adau1701_exit(void)
-{
-	i2c_del_driver(&adau1701_i2c_driver);
-}
-module_exit(adau1701_exit);
+module_i2c_driver(adau1701_i2c_driver);
 
 MODULE_DESCRIPTION("ASoC ADAU1701 SigmaDSP driver");
 MODULE_AUTHOR("Cliff Cai <cliff.cai@analog.com>");
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index 5fb7c2a..2b45797 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -696,17 +696,7 @@
 	.id_table = ak4671_i2c_id,
 };
 
-static int __init ak4671_modinit(void)
-{
-	return i2c_add_driver(&ak4671_i2c_driver);
-}
-module_init(ak4671_modinit);
-
-static void __exit ak4671_exit(void)
-{
-	i2c_del_driver(&ak4671_i2c_driver);
-}
-module_exit(ak4671_exit);
+module_i2c_driver(ak4671_i2c_driver);
 
 MODULE_DESCRIPTION("ASoC AK4671 codec driver");
 MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index 1cf7a32..c03b65a 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -119,6 +119,24 @@
 	"DSP1.4",
 	"DSP1.5",
 	"DSP1.6",
+	"DSP2.1",
+	"DSP2.2",
+	"DSP2.3",
+	"DSP2.4",
+	"DSP2.5",
+	"DSP2.6",
+	"DSP3.1",
+	"DSP3.2",
+	"DSP3.3",
+	"DSP3.4",
+	"DSP3.5",
+	"DSP3.6",
+	"DSP4.1",
+	"DSP4.2",
+	"DSP4.3",
+	"DSP4.4",
+	"DSP4.5",
+	"DSP4.6",
 	"ASRC1L",
 	"ASRC1R",
 	"ASRC2L",
@@ -180,6 +198,24 @@
 	0x6b,
 	0x6c,
 	0x6d,
+	0x70,  /* DSP2.1 */
+	0x71,
+	0x72,
+	0x73,
+	0x74,
+	0x75,
+	0x78,  /* DSP3.1 */
+	0x79,
+	0x7a,
+	0x7b,
+	0x7c,
+	0x7d,
+	0x80,  /* DSP4.1 */
+	0x81,
+	0x82,
+	0x83,
+	0x84,
+	0x85,
 	0x90,  /* ASRC1L */
 	0x91,
 	0x92,
@@ -229,6 +265,75 @@
 }
 EXPORT_SYMBOL_GPL(arizona_out_ev);
 
+static unsigned int arizona_sysclk_48k_rates[] = {
+	6144000,
+	12288000,
+	22579200,
+	49152000,
+	73728000,
+	98304000,
+	147456000,
+};
+
+static unsigned int arizona_sysclk_44k1_rates[] = {
+	5644800,
+	11289600,
+	24576000,
+	45158400,
+	67737600,
+	90316800,
+	135475200,
+};
+
+static int arizona_set_opclk(struct snd_soc_codec *codec, unsigned int clk,
+			     unsigned int freq)
+{
+	struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
+	unsigned int reg;
+	unsigned int *rates;
+	int ref, div, refclk;
+
+	switch (clk) {
+	case ARIZONA_CLK_OPCLK:
+		reg = ARIZONA_OUTPUT_SYSTEM_CLOCK;
+		refclk = priv->sysclk;
+		break;
+	case ARIZONA_CLK_ASYNC_OPCLK:
+		reg = ARIZONA_OUTPUT_ASYNC_CLOCK;
+		refclk = priv->asyncclk;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (refclk % 8000)
+		rates = arizona_sysclk_44k1_rates;
+	else
+		rates = arizona_sysclk_48k_rates;
+
+	for (ref = 0; ref < ARRAY_SIZE(arizona_sysclk_48k_rates) &&
+		     rates[ref] <= refclk; ref++) {
+		div = 1;
+		while (rates[ref] / div >= freq && div < 32) {
+			if (rates[ref] / div == freq) {
+				dev_dbg(codec->dev, "Configured %dHz OPCLK\n",
+					freq);
+				snd_soc_update_bits(codec, reg,
+						    ARIZONA_OPCLK_DIV_MASK |
+						    ARIZONA_OPCLK_SEL_MASK,
+						    (div <<
+						     ARIZONA_OPCLK_DIV_SHIFT) |
+						    ref);
+				return 0;
+			}
+			div++;
+		}
+	}
+
+	dev_err(codec->dev, "Unable to generate %dHz OPCLK\n", freq);
+	return -EINVAL;
+}
+
 int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
 		       int source, unsigned int freq, int dir)
 {
@@ -252,6 +357,9 @@
 		reg = ARIZONA_ASYNC_CLOCK_1;
 		clk = &priv->asyncclk;
 		break;
+	case ARIZONA_CLK_OPCLK:
+	case ARIZONA_CLK_ASYNC_OPCLK:
+		return arizona_set_opclk(codec, clk_id, freq);
 	default:
 		return -EINVAL;
 	}
@@ -666,7 +774,7 @@
 {
 	struct arizona_fll *fll = data;
 
-	arizona_fll_dbg(fll, "Locked\n");
+	arizona_fll_dbg(fll, "Lock status changed\n");
 
 	complete(&fll->lock);
 
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
index 59caca8..36ec649 100644
--- a/sound/soc/codecs/arizona.h
+++ b/sound/soc/codecs/arizona.h
@@ -17,8 +17,10 @@
 
 #include <sound/soc.h>
 
-#define ARIZONA_CLK_SYSCLK   1
-#define ARIZONA_CLK_ASYNCCLK 2
+#define ARIZONA_CLK_SYSCLK         1
+#define ARIZONA_CLK_ASYNCCLK       2
+#define ARIZONA_CLK_OPCLK          3
+#define ARIZONA_CLK_ASYNC_OPCLK    4
 
 #define ARIZONA_CLK_SRC_MCLK1    0x0
 #define ARIZONA_CLK_SRC_MCLK2    0x1
@@ -59,7 +61,7 @@
 	struct arizona_dai_priv dai[ARIZONA_MAX_DAI];
 };
 
-#define ARIZONA_NUM_MIXER_INPUTS 57
+#define ARIZONA_NUM_MIXER_INPUTS 75
 
 extern const unsigned int arizona_mixer_tlv[];
 extern const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS];
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 047917f..8e47798 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -29,6 +29,8 @@
 #include <linux/i2c.h>
 #include <linux/delay.h>
 #include <linux/regulator/consumer.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
 
 /*
  * The codec isn't really big-endian or little-endian, since the I2S
@@ -110,14 +112,15 @@
  * This array contains the power-on default values of the registers, with the
  * exception of the "CHIPID" register (01h).  The lower four bits of that
  * register contain the hardware revision, so it is treated as volatile.
- *
- * Also note that on the CS4270, the first readable register is 1, but ASoC
- * assumes the first register is 0.  Therfore, the array must have an entry for
- * register 0, but we use cs4270_reg_is_readable() to tell ASoC that it can't
- * be read.
  */
-static const u8 cs4270_default_reg_cache[CS4270_LASTREG + 1] = {
-	0x00, 0x00, 0x00, 0x30, 0x00, 0x60, 0x20, 0x00, 0x00
+static const struct reg_default cs4270_reg_defaults[] = {
+	{ 2, 0x00 },
+	{ 3, 0x30 },
+	{ 4, 0x00 },
+	{ 5, 0x60 },
+	{ 6, 0x20 },
+	{ 7, 0x00 },
+	{ 8, 0x00 },
 };
 
 static const char *supply_names[] = {
@@ -126,7 +129,7 @@
 
 /* Private data for the CS4270 */
 struct cs4270_private {
-	enum snd_soc_control_type control_type;
+	struct regmap *regmap;
 	unsigned int mclk; /* Input frequency of the MCLK pin */
 	unsigned int mode; /* The mode (I2S or left-justified) */
 	unsigned int slave_mode;
@@ -191,12 +194,12 @@
 /* The number of MCLK/LRCK ratios supported by the CS4270 */
 #define NUM_MCLK_RATIOS		ARRAY_SIZE(cs4270_mode_ratios)
 
-static int cs4270_reg_is_readable(struct snd_soc_codec *codec, unsigned int reg)
+static bool cs4270_reg_is_readable(struct device *dev, unsigned int reg)
 {
 	return (reg >= CS4270_FIRSTREG) && (reg <= CS4270_LASTREG);
 }
 
-static int cs4270_reg_is_volatile(struct snd_soc_codec *codec, unsigned int reg)
+static bool cs4270_reg_is_volatile(struct device *dev, unsigned int reg)
 {
 	/* Unreadable registers are considered volatile */
 	if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG))
@@ -456,7 +459,7 @@
 	.name = "cs4270-hifi",
 	.playback = {
 		.stream_name = "Playback",
-		.channels_min = 1,
+		.channels_min = 2,
 		.channels_max = 2,
 		.rates = SNDRV_PCM_RATE_CONTINUOUS,
 		.rate_min = 4000,
@@ -465,7 +468,7 @@
 	},
 	.capture = {
 		.stream_name = "Capture",
-		.channels_min = 1,
+		.channels_min = 2,
 		.channels_max = 2,
 		.rates = SNDRV_PCM_RATE_CONTINUOUS,
 		.rate_min = 4000,
@@ -485,12 +488,12 @@
 static int cs4270_probe(struct snd_soc_codec *codec)
 {
 	struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
-	int i, ret;
+	int ret;
 
 	/* Tell ASoC what kind of I/O to use to read the registers.  ASoC will
 	 * then do the I2C transactions itself.
 	 */
-	ret = snd_soc_codec_set_cache_io(codec, 8, 8, cs4270->control_type);
+	ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
 	if (ret < 0) {
 		dev_err(codec->dev, "failed to set cache I/O (ret=%i)\n", ret);
 		return ret;
@@ -519,33 +522,8 @@
 		return ret;
 	}
 
-	/* Add the non-DAPM controls */
-	ret = snd_soc_add_codec_controls(codec, cs4270_snd_controls,
-				ARRAY_SIZE(cs4270_snd_controls));
-	if (ret < 0) {
-		dev_err(codec->dev, "failed to add controls\n");
-		return ret;
-	}
-
-	/* get the power supply regulators */
-	for (i = 0; i < ARRAY_SIZE(supply_names); i++)
-		cs4270->supplies[i].supply = supply_names[i];
-
-	ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(cs4270->supplies),
-				 cs4270->supplies);
-	if (ret < 0)
-		return ret;
-
 	ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
 				    cs4270->supplies);
-	if (ret < 0)
-		goto error_free_regulators;
-
-	return 0;
-
-error_free_regulators:
-	regulator_bulk_free(ARRAY_SIZE(cs4270->supplies),
-			    cs4270->supplies);
 
 	return ret;
 }
@@ -561,7 +539,6 @@
 	struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
 
 	regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
-	regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
 
 	return 0;
 };
@@ -611,7 +588,7 @@
 	ndelay(500);
 
 	/* first restore the entire register cache ... */
-	snd_soc_cache_sync(codec);
+	regcache_sync(cs4270->regmap);
 
 	/* ... then disable the power-down bits */
 	reg = snd_soc_read(codec, CS4270_PWRCTL);
@@ -632,11 +609,30 @@
 	.remove =		cs4270_remove,
 	.suspend =		cs4270_soc_suspend,
 	.resume =		cs4270_soc_resume,
-	.volatile_register =	cs4270_reg_is_volatile,
-	.readable_register =	cs4270_reg_is_readable,
-	.reg_cache_size =	CS4270_LASTREG + 1,
-	.reg_word_size =	sizeof(u8),
-	.reg_cache_default =	cs4270_default_reg_cache,
+
+	.controls =		cs4270_snd_controls,
+	.num_controls =		ARRAY_SIZE(cs4270_snd_controls),
+};
+
+/*
+ * cs4270_of_match - the device tree bindings
+ */
+static const struct of_device_id cs4270_of_match[] = {
+	{ .compatible = "cirrus,cs4270", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, cs4270_of_match);
+
+static const struct regmap_config cs4270_regmap = {
+	.reg_bits =		8,
+	.val_bits =		8,
+	.max_register =		CS4270_LASTREG,
+	.reg_defaults =		cs4270_reg_defaults,
+	.num_reg_defaults =	ARRAY_SIZE(cs4270_reg_defaults),
+	.cache_type =		REGCACHE_RBTREE,
+
+	.readable_reg =		cs4270_reg_is_readable,
+	.volatile_reg =		cs4270_reg_is_volatile,
 };
 
 /**
@@ -650,27 +646,10 @@
 static int cs4270_i2c_probe(struct i2c_client *i2c_client,
 	const struct i2c_device_id *id)
 {
+	struct device_node *np = i2c_client->dev.of_node;
 	struct cs4270_private *cs4270;
-	int ret;
-
-	/* Verify that we have a CS4270 */
-
-	ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
-	if (ret < 0) {
-		dev_err(&i2c_client->dev, "failed to read i2c at addr %X\n",
-		       i2c_client->addr);
-		return ret;
-	}
-	/* The top four bits of the chip ID should be 1100. */
-	if ((ret & 0xF0) != 0xC0) {
-		dev_err(&i2c_client->dev, "device at addr %X is not a CS4270\n",
-		       i2c_client->addr);
-		return -ENODEV;
-	}
-
-	dev_info(&i2c_client->dev, "found device at i2c address %X\n",
-		i2c_client->addr);
-	dev_info(&i2c_client->dev, "hardware revision %X\n", ret & 0xF);
+	unsigned int val;
+	int ret, i;
 
 	cs4270 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs4270_private),
 			      GFP_KERNEL);
@@ -679,8 +658,54 @@
 		return -ENOMEM;
 	}
 
+	/* get the power supply regulators */
+	for (i = 0; i < ARRAY_SIZE(supply_names); i++)
+		cs4270->supplies[i].supply = supply_names[i];
+
+	ret = devm_regulator_bulk_get(&i2c_client->dev,
+				      ARRAY_SIZE(cs4270->supplies),
+				      cs4270->supplies);
+	if (ret < 0)
+		return ret;
+
+	/* See if we have a way to bring the codec out of reset */
+	if (np) {
+		enum of_gpio_flags flags;
+		int gpio = of_get_named_gpio_flags(np, "reset-gpio", 0, &flags);
+
+		if (gpio_is_valid(gpio)) {
+			ret = devm_gpio_request_one(&i2c_client->dev, gpio,
+				     flags & OF_GPIO_ACTIVE_LOW ?
+					GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH,
+				     "cs4270 reset");
+			if (ret < 0)
+				return ret;
+		}
+	}
+
+	cs4270->regmap = devm_regmap_init_i2c(i2c_client, &cs4270_regmap);
+	if (IS_ERR(cs4270->regmap))
+		return PTR_ERR(cs4270->regmap);
+
+	/* Verify that we have a CS4270 */
+	ret = regmap_read(cs4270->regmap, CS4270_CHIPID, &val);
+	if (ret < 0) {
+		dev_err(&i2c_client->dev, "failed to read i2c at addr %X\n",
+		       i2c_client->addr);
+		return ret;
+	}
+	/* The top four bits of the chip ID should be 1100. */
+	if ((val & 0xF0) != 0xC0) {
+		dev_err(&i2c_client->dev, "device at addr %X is not a CS4270\n",
+		       i2c_client->addr);
+		return -ENODEV;
+	}
+
+	dev_info(&i2c_client->dev, "found device at i2c address %X\n",
+		i2c_client->addr);
+	dev_info(&i2c_client->dev, "hardware revision %X\n", val & 0xF);
+
 	i2c_set_clientdata(i2c_client, cs4270);
-	cs4270->control_type = SND_SOC_I2C;
 
 	ret = snd_soc_register_codec(&i2c_client->dev,
 			&soc_codec_device_cs4270, &cs4270_dai, 1);
@@ -718,23 +743,14 @@
 	.driver = {
 		.name = "cs4270",
 		.owner = THIS_MODULE,
+		.of_match_table = cs4270_of_match,
 	},
 	.id_table = cs4270_id,
 	.probe = cs4270_i2c_probe,
 	.remove = cs4270_i2c_remove,
 };
 
-static int __init cs4270_init(void)
-{
-	return i2c_add_driver(&cs4270_i2c_driver);
-}
-module_init(cs4270_init);
-
-static void __exit cs4270_exit(void)
-{
-	i2c_del_driver(&cs4270_i2c_driver);
-}
-module_exit(cs4270_exit);
+module_i2c_driver(cs4270_i2c_driver);
 
 MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
 MODULE_DESCRIPTION("Cirrus Logic CS4270 ALSA SoC Codec Driver");
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c
index 9eb01d7..f994af3 100644
--- a/sound/soc/codecs/cs4271.c
+++ b/sound/soc/codecs/cs4271.c
@@ -22,12 +22,14 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-#include <sound/tlv.h>
 #include <linux/gpio.h>
 #include <linux/i2c.h>
 #include <linux/spi/spi.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
 #include <sound/cs4271.h>
 
 #define CS4271_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
@@ -458,6 +460,14 @@
 #define cs4271_soc_resume	NULL
 #endif /* CONFIG_PM */
 
+#ifdef CONFIG_OF
+static const struct of_device_id cs4271_dt_ids[] = {
+	{ .compatible = "cirrus,cs4271", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, cs4271_dt_ids);
+#endif
+
 static int cs4271_probe(struct snd_soc_codec *codec)
 {
 	struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec);
@@ -465,6 +475,12 @@
 	int ret;
 	int gpio_nreset = -EINVAL;
 
+#ifdef CONFIG_OF
+	if (of_match_device(cs4271_dt_ids, codec->dev))
+		gpio_nreset = of_get_named_gpio(codec->dev->of_node,
+						"reset-gpio", 0);
+#endif
+
 	if (cs4271plat && gpio_is_valid(cs4271plat->gpio_nreset))
 		gpio_nreset = cs4271plat->gpio_nreset;
 
@@ -569,6 +585,7 @@
 	.driver = {
 		.name	= "cs4271",
 		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(cs4271_dt_ids),
 	},
 	.probe		= cs4271_spi_probe,
 	.remove		= __devexit_p(cs4271_spi_remove),
@@ -608,6 +625,7 @@
 	.driver = {
 		.name	= "cs4271",
 		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(cs4271_dt_ids),
 	},
 	.id_table	= cs4271_i2c_id,
 	.probe		= cs4271_i2c_probe,
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
index 091d019..1e0fa3b 100644
--- a/sound/soc/codecs/cs42l51.c
+++ b/sound/soc/codecs/cs42l51.c
@@ -614,24 +614,7 @@
 	.remove = cs42l51_i2c_remove,
 };
 
-static int __init cs42l51_init(void)
-{
-	int ret;
-
-	ret = i2c_add_driver(&cs42l51_i2c_driver);
-	if (ret != 0) {
-		printk(KERN_ERR "%s: can't add i2c driver\n", __func__);
-		return ret;
-	}
-	return 0;
-}
-module_init(cs42l51_init);
-
-static void __exit cs42l51_exit(void)
-{
-	i2c_del_driver(&cs42l51_i2c_driver);
-}
-module_exit(cs42l51_exit);
+module_i2c_driver(cs42l51_i2c_driver);
 
 MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
 MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver");
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c
index 628daf6..6159929 100644
--- a/sound/soc/codecs/cs42l52.c
+++ b/sound/soc/codecs/cs42l52.c
@@ -24,7 +24,6 @@
 #include <linux/slab.h>
 #include <linux/workqueue.h>
 #include <linux/platform_device.h>
-#include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c
new file mode 100644
index 0000000..185d8dd
--- /dev/null
+++ b/sound/soc/codecs/da9055.c
@@ -0,0 +1,1510 @@
+/*
+ * DA9055 ALSA Soc codec driver
+ *
+ * Copyright (c) 2012 Dialog Semiconductor
+ *
+ * Tested on (Samsung SMDK6410 board + DA9055 EVB) using I2S and I2C
+ * Written by David Chen <david.chen@diasemi.com> and
+ * Ashish Chavan <ashish.chavan@kpitcummins.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+#include <sound/da9055.h>
+
+/* DA9055 register space */
+
+/* Status Registers */
+#define DA9055_STATUS1			0x02
+#define DA9055_PLL_STATUS		0x03
+#define DA9055_AUX_L_GAIN_STATUS	0x04
+#define DA9055_AUX_R_GAIN_STATUS	0x05
+#define DA9055_MIC_L_GAIN_STATUS	0x06
+#define DA9055_MIC_R_GAIN_STATUS	0x07
+#define DA9055_MIXIN_L_GAIN_STATUS	0x08
+#define DA9055_MIXIN_R_GAIN_STATUS	0x09
+#define DA9055_ADC_L_GAIN_STATUS	0x0A
+#define DA9055_ADC_R_GAIN_STATUS	0x0B
+#define DA9055_DAC_L_GAIN_STATUS	0x0C
+#define DA9055_DAC_R_GAIN_STATUS	0x0D
+#define DA9055_HP_L_GAIN_STATUS		0x0E
+#define DA9055_HP_R_GAIN_STATUS		0x0F
+#define DA9055_LINE_GAIN_STATUS		0x10
+
+/* System Initialisation Registers */
+#define DA9055_CIF_CTRL			0x20
+#define DA9055_DIG_ROUTING_AIF		0X21
+#define DA9055_SR			0x22
+#define DA9055_REFERENCES		0x23
+#define DA9055_PLL_FRAC_TOP		0x24
+#define DA9055_PLL_FRAC_BOT		0x25
+#define DA9055_PLL_INTEGER		0x26
+#define DA9055_PLL_CTRL			0x27
+#define DA9055_AIF_CLK_MODE		0x28
+#define DA9055_AIF_CTRL			0x29
+#define DA9055_DIG_ROUTING_DAC		0x2A
+#define DA9055_ALC_CTRL1		0x2B
+
+/* Input - Gain, Select and Filter Registers */
+#define DA9055_AUX_L_GAIN		0x30
+#define DA9055_AUX_R_GAIN		0x31
+#define DA9055_MIXIN_L_SELECT		0x32
+#define DA9055_MIXIN_R_SELECT		0x33
+#define DA9055_MIXIN_L_GAIN		0x34
+#define DA9055_MIXIN_R_GAIN		0x35
+#define DA9055_ADC_L_GAIN		0x36
+#define DA9055_ADC_R_GAIN		0x37
+#define DA9055_ADC_FILTERS1		0x38
+#define DA9055_MIC_L_GAIN		0x39
+#define DA9055_MIC_R_GAIN		0x3A
+
+/* Output - Gain, Select and Filter Registers */
+#define DA9055_DAC_FILTERS5		0x40
+#define DA9055_DAC_FILTERS2		0x41
+#define DA9055_DAC_FILTERS3		0x42
+#define DA9055_DAC_FILTERS4		0x43
+#define DA9055_DAC_FILTERS1		0x44
+#define DA9055_DAC_L_GAIN		0x45
+#define DA9055_DAC_R_GAIN		0x46
+#define DA9055_CP_CTRL			0x47
+#define DA9055_HP_L_GAIN		0x48
+#define DA9055_HP_R_GAIN		0x49
+#define DA9055_LINE_GAIN		0x4A
+#define DA9055_MIXOUT_L_SELECT		0x4B
+#define DA9055_MIXOUT_R_SELECT		0x4C
+
+/* System Controller Registers */
+#define DA9055_SYSTEM_MODES_INPUT	0x50
+#define DA9055_SYSTEM_MODES_OUTPUT	0x51
+
+/* Control Registers */
+#define DA9055_AUX_L_CTRL		0x60
+#define DA9055_AUX_R_CTRL		0x61
+#define DA9055_MIC_BIAS_CTRL		0x62
+#define DA9055_MIC_L_CTRL		0x63
+#define DA9055_MIC_R_CTRL		0x64
+#define DA9055_MIXIN_L_CTRL		0x65
+#define DA9055_MIXIN_R_CTRL		0x66
+#define DA9055_ADC_L_CTRL		0x67
+#define DA9055_ADC_R_CTRL		0x68
+#define DA9055_DAC_L_CTRL		0x69
+#define DA9055_DAC_R_CTRL		0x6A
+#define DA9055_HP_L_CTRL		0x6B
+#define DA9055_HP_R_CTRL		0x6C
+#define DA9055_LINE_CTRL		0x6D
+#define DA9055_MIXOUT_L_CTRL		0x6E
+#define DA9055_MIXOUT_R_CTRL		0x6F
+
+/* Configuration Registers */
+#define DA9055_LDO_CTRL			0x90
+#define DA9055_IO_CTRL			0x91
+#define DA9055_GAIN_RAMP_CTRL		0x92
+#define DA9055_MIC_CONFIG		0x93
+#define DA9055_PC_COUNT			0x94
+#define DA9055_CP_VOL_THRESHOLD1	0x95
+#define DA9055_CP_DELAY			0x96
+#define DA9055_CP_DETECTOR		0x97
+#define DA9055_AIF_OFFSET		0x98
+#define DA9055_DIG_CTRL			0x99
+#define DA9055_ALC_CTRL2		0x9A
+#define DA9055_ALC_CTRL3		0x9B
+#define DA9055_ALC_NOISE		0x9C
+#define DA9055_ALC_TARGET_MIN		0x9D
+#define DA9055_ALC_TARGET_MAX		0x9E
+#define DA9055_ALC_GAIN_LIMITS		0x9F
+#define DA9055_ALC_ANA_GAIN_LIMITS	0xA0
+#define DA9055_ALC_ANTICLIP_CTRL	0xA1
+#define DA9055_ALC_ANTICLIP_LEVEL	0xA2
+#define DA9055_ALC_OFFSET_OP2M_L	0xA6
+#define DA9055_ALC_OFFSET_OP2U_L	0xA7
+#define DA9055_ALC_OFFSET_OP2M_R	0xAB
+#define DA9055_ALC_OFFSET_OP2U_R	0xAC
+#define DA9055_ALC_CIC_OP_LVL_CTRL	0xAD
+#define DA9055_ALC_CIC_OP_LVL_DATA	0xAE
+#define DA9055_DAC_NG_SETUP_TIME	0xAF
+#define DA9055_DAC_NG_OFF_THRESHOLD	0xB0
+#define DA9055_DAC_NG_ON_THRESHOLD	0xB1
+#define DA9055_DAC_NG_CTRL		0xB2
+
+/* SR bit fields */
+#define DA9055_SR_8000			(0x1 << 0)
+#define DA9055_SR_11025			(0x2 << 0)
+#define DA9055_SR_12000			(0x3 << 0)
+#define DA9055_SR_16000			(0x5 << 0)
+#define DA9055_SR_22050			(0x6 << 0)
+#define DA9055_SR_24000			(0x7 << 0)
+#define DA9055_SR_32000			(0x9 << 0)
+#define DA9055_SR_44100			(0xA << 0)
+#define DA9055_SR_48000			(0xB << 0)
+#define DA9055_SR_88200			(0xE << 0)
+#define DA9055_SR_96000			(0xF << 0)
+
+/* REFERENCES bit fields */
+#define DA9055_BIAS_EN			(1 << 3)
+#define DA9055_VMID_EN			(1 << 7)
+
+/* PLL_CTRL bit fields */
+#define DA9055_PLL_INDIV_10_20_MHZ	(1 << 2)
+#define DA9055_PLL_SRM_EN		(1 << 6)
+#define DA9055_PLL_EN			(1 << 7)
+
+/* AIF_CLK_MODE bit fields */
+#define DA9055_AIF_BCLKS_PER_WCLK_32	(0 << 0)
+#define DA9055_AIF_BCLKS_PER_WCLK_64	(1 << 0)
+#define DA9055_AIF_BCLKS_PER_WCLK_128	(2 << 0)
+#define DA9055_AIF_BCLKS_PER_WCLK_256	(3 << 0)
+#define DA9055_AIF_CLK_EN_SLAVE_MODE	(0 << 7)
+#define DA9055_AIF_CLK_EN_MASTER_MODE	(1 << 7)
+
+/* AIF_CTRL bit fields */
+#define DA9055_AIF_FORMAT_I2S_MODE	(0 << 0)
+#define DA9055_AIF_FORMAT_LEFT_J	(1 << 0)
+#define DA9055_AIF_FORMAT_RIGHT_J	(2 << 0)
+#define DA9055_AIF_WORD_S16_LE		(0 << 2)
+#define DA9055_AIF_WORD_S20_3LE		(1 << 2)
+#define DA9055_AIF_WORD_S24_LE		(2 << 2)
+#define DA9055_AIF_WORD_S32_LE		(3 << 2)
+
+/* MIXIN_L_CTRL bit fields */
+#define DA9055_MIXIN_L_MIX_EN		(1 << 3)
+
+/* MIXIN_R_CTRL bit fields */
+#define DA9055_MIXIN_R_MIX_EN		(1 << 3)
+
+/* ADC_L_CTRL bit fields */
+#define DA9055_ADC_L_EN			(1 << 7)
+
+/* ADC_R_CTRL bit fields */
+#define DA9055_ADC_R_EN			(1 << 7)
+
+/* DAC_L_CTRL bit fields */
+#define DA9055_DAC_L_MUTE_EN		(1 << 6)
+
+/* DAC_R_CTRL bit fields */
+#define DA9055_DAC_R_MUTE_EN		(1 << 6)
+
+/* HP_L_CTRL bit fields */
+#define DA9055_HP_L_AMP_OE		(1 << 3)
+
+/* HP_R_CTRL bit fields */
+#define DA9055_HP_R_AMP_OE		(1 << 3)
+
+/* LINE_CTRL bit fields */
+#define DA9055_LINE_AMP_OE		(1 << 3)
+
+/* MIXOUT_L_CTRL bit fields */
+#define DA9055_MIXOUT_L_MIX_EN		(1 << 3)
+
+/* MIXOUT_R_CTRL bit fields */
+#define DA9055_MIXOUT_R_MIX_EN		(1 << 3)
+
+/* MIC bias select bit fields */
+#define DA9055_MICBIAS2_EN		(1 << 6)
+
+/* ALC_CIC_OP_LEVEL_CTRL bit fields */
+#define DA9055_ALC_DATA_MIDDLE		(2 << 0)
+#define DA9055_ALC_DATA_TOP		(3 << 0)
+#define DA9055_ALC_CIC_OP_CHANNEL_LEFT	(0 << 7)
+#define DA9055_ALC_CIC_OP_CHANNEL_RIGHT	(1 << 7)
+
+#define DA9055_AIF_BCLK_MASK		(3 << 0)
+#define DA9055_AIF_CLK_MODE_MASK	(1 << 7)
+#define DA9055_AIF_FORMAT_MASK		(3 << 0)
+#define DA9055_AIF_WORD_LENGTH_MASK	(3 << 2)
+#define DA9055_GAIN_RAMPING_EN		(1 << 5)
+#define DA9055_MICBIAS_LEVEL_MASK	(3 << 4)
+
+#define DA9055_ALC_OFFSET_15_8		0x00FF00
+#define DA9055_ALC_OFFSET_17_16		0x030000
+#define DA9055_ALC_AVG_ITERATIONS	5
+
+struct pll_div {
+	int fref;
+	int fout;
+	u8 frac_top;
+	u8 frac_bot;
+	u8 integer;
+	u8 mode;	/* 0 = slave, 1 = master */
+};
+
+/* PLL divisor table */
+static const struct pll_div da9055_pll_div[] = {
+	/* for MASTER mode, fs = 44.1Khz and its harmonics */
+	{11289600, 2822400, 0x00, 0x00, 0x20, 1},	/* MCLK=11.2896Mhz */
+	{12000000, 2822400, 0x03, 0x61, 0x1E, 1},	/* MCLK=12Mhz */
+	{12288000, 2822400, 0x0C, 0xCC, 0x1D, 1},	/* MCLK=12.288Mhz */
+	{13000000, 2822400, 0x19, 0x45, 0x1B, 1},	/* MCLK=13Mhz */
+	{13500000, 2822400, 0x18, 0x56, 0x1A, 1},	/* MCLK=13.5Mhz */
+	{14400000, 2822400, 0x02, 0xD0, 0x19, 1},	/* MCLK=14.4Mhz */
+	{19200000, 2822400, 0x1A, 0x1C, 0x12, 1},	/* MCLK=19.2Mhz */
+	{19680000, 2822400, 0x0B, 0x6D, 0x12, 1},	/* MCLK=19.68Mhz */
+	{19800000, 2822400, 0x07, 0xDD, 0x12, 1},	/* MCLK=19.8Mhz */
+	/* for MASTER mode, fs = 48Khz and its harmonics */
+	{11289600, 3072000, 0x1A, 0x8E, 0x22, 1},	/* MCLK=11.2896Mhz */
+	{12000000, 3072000, 0x18, 0x93, 0x20, 1},	/* MCLK=12Mhz */
+	{12288000, 3072000, 0x00, 0x00, 0x20, 1},	/* MCLK=12.288Mhz */
+	{13000000, 3072000, 0x07, 0xEA, 0x1E, 1},	/* MCLK=13Mhz */
+	{13500000, 3072000, 0x04, 0x11, 0x1D, 1},	/* MCLK=13.5Mhz */
+	{14400000, 3072000, 0x09, 0xD0, 0x1B, 1},	/* MCLK=14.4Mhz */
+	{19200000, 3072000, 0x0F, 0x5C, 0x14, 1},	/* MCLK=19.2Mhz */
+	{19680000, 3072000, 0x1F, 0x60, 0x13, 1},	/* MCLK=19.68Mhz */
+	{19800000, 3072000, 0x1B, 0x80, 0x13, 1},	/* MCLK=19.8Mhz */
+	/* for SLAVE mode with SRM */
+	{11289600, 2822400, 0x0D, 0x47, 0x21, 0},	/* MCLK=11.2896Mhz */
+	{12000000, 2822400, 0x0D, 0xFA, 0x1F, 0},	/* MCLK=12Mhz */
+	{12288000, 2822400, 0x16, 0x66, 0x1E, 0},	/* MCLK=12.288Mhz */
+	{13000000, 2822400, 0x00, 0x98, 0x1D, 0},	/* MCLK=13Mhz */
+	{13500000, 2822400, 0x1E, 0x33, 0x1B, 0},	/* MCLK=13.5Mhz */
+	{14400000, 2822400, 0x06, 0x50, 0x1A, 0},	/* MCLK=14.4Mhz */
+	{19200000, 2822400, 0x14, 0xBC, 0x13, 0},	/* MCLK=19.2Mhz */
+	{19680000, 2822400, 0x05, 0x66, 0x13, 0},	/* MCLK=19.68Mhz */
+	{19800000, 2822400, 0x01, 0xAE, 0x13, 0},	/* MCLK=19.8Mhz  */
+};
+
+enum clk_src {
+	DA9055_CLKSRC_MCLK
+};
+
+/* Gain and Volume */
+
+static const unsigned int aux_vol_tlv[] = {
+	TLV_DB_RANGE_HEAD(2),
+	0x0, 0x10, TLV_DB_SCALE_ITEM(-5400, 0, 0),
+	/* -54dB to 15dB */
+	0x11, 0x3f, TLV_DB_SCALE_ITEM(-5400, 150, 0)
+};
+
+static const unsigned int digital_gain_tlv[] = {
+	TLV_DB_RANGE_HEAD(2),
+	0x0, 0x07, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
+	/* -78dB to 12dB */
+	0x08, 0x7f, TLV_DB_SCALE_ITEM(-7800, 75, 0)
+};
+
+static const unsigned int alc_analog_gain_tlv[] = {
+	TLV_DB_RANGE_HEAD(2),
+	0x0, 0x0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
+	/* 0dB to 36dB */
+	0x01, 0x07, TLV_DB_SCALE_ITEM(0, 600, 0)
+};
+
+static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, -600, 600, 0);
+static const DECLARE_TLV_DB_SCALE(mixin_gain_tlv, -450, 150, 0);
+static const DECLARE_TLV_DB_SCALE(eq_gain_tlv, -1050, 150, 0);
+static const DECLARE_TLV_DB_SCALE(hp_vol_tlv, -5700, 100, 0);
+static const DECLARE_TLV_DB_SCALE(lineout_vol_tlv, -4800, 100, 0);
+static const DECLARE_TLV_DB_SCALE(alc_threshold_tlv, -9450, 150, 0);
+static const DECLARE_TLV_DB_SCALE(alc_gain_tlv, 0, 600, 0);
+
+/* ADC and DAC high pass filter cutoff value */
+static const char * const da9055_hpf_cutoff_txt[] = {
+	"Fs/24000", "Fs/12000", "Fs/6000", "Fs/3000"
+};
+
+static const struct soc_enum da9055_dac_hpf_cutoff =
+	SOC_ENUM_SINGLE(DA9055_DAC_FILTERS1, 4, 4, da9055_hpf_cutoff_txt);
+
+static const struct soc_enum da9055_adc_hpf_cutoff =
+	SOC_ENUM_SINGLE(DA9055_ADC_FILTERS1, 4, 4, da9055_hpf_cutoff_txt);
+
+/* ADC and DAC voice mode (8kHz) high pass cutoff value */
+static const char * const da9055_vf_cutoff_txt[] = {
+	"2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"
+};
+
+static const struct soc_enum da9055_dac_vf_cutoff =
+	SOC_ENUM_SINGLE(DA9055_DAC_FILTERS1, 0, 8, da9055_vf_cutoff_txt);
+
+static const struct soc_enum da9055_adc_vf_cutoff =
+	SOC_ENUM_SINGLE(DA9055_ADC_FILTERS1, 0, 8, da9055_vf_cutoff_txt);
+
+/* Gain ramping rate value */
+static const char * const da9055_gain_ramping_txt[] = {
+	"nominal rate", "nominal rate * 4", "nominal rate * 8",
+	"nominal rate / 8"
+};
+
+static const struct soc_enum da9055_gain_ramping_rate =
+	SOC_ENUM_SINGLE(DA9055_GAIN_RAMP_CTRL, 0, 4, da9055_gain_ramping_txt);
+
+/* DAC noise gate setup time value */
+static const char * const da9055_dac_ng_setup_time_txt[] = {
+	"256 samples", "512 samples", "1024 samples", "2048 samples"
+};
+
+static const struct soc_enum da9055_dac_ng_setup_time =
+	SOC_ENUM_SINGLE(DA9055_DAC_NG_SETUP_TIME, 0, 4,
+			da9055_dac_ng_setup_time_txt);
+
+/* DAC noise gate rampup rate value */
+static const char * const da9055_dac_ng_rampup_txt[] = {
+	"0.02 ms/dB", "0.16 ms/dB"
+};
+
+static const struct soc_enum da9055_dac_ng_rampup_rate =
+	SOC_ENUM_SINGLE(DA9055_DAC_NG_SETUP_TIME, 2, 2,
+			da9055_dac_ng_rampup_txt);
+
+/* DAC noise gate rampdown rate value */
+static const char * const da9055_dac_ng_rampdown_txt[] = {
+	"0.64 ms/dB", "20.48 ms/dB"
+};
+
+static const struct soc_enum da9055_dac_ng_rampdown_rate =
+	SOC_ENUM_SINGLE(DA9055_DAC_NG_SETUP_TIME, 3, 2,
+			da9055_dac_ng_rampdown_txt);
+
+/* DAC soft mute rate value */
+static const char * const da9055_dac_soft_mute_rate_txt[] = {
+	"1", "2", "4", "8", "16", "32", "64"
+};
+
+static const struct soc_enum da9055_dac_soft_mute_rate =
+	SOC_ENUM_SINGLE(DA9055_DAC_FILTERS5, 4, 7,
+			da9055_dac_soft_mute_rate_txt);
+
+/* DAC routing select */
+static const char * const da9055_dac_src_txt[] = {
+	"ADC output left", "ADC output right", "AIF input left",
+	"AIF input right"
+};
+
+static const struct soc_enum da9055_dac_l_src =
+	SOC_ENUM_SINGLE(DA9055_DIG_ROUTING_DAC, 0, 4, da9055_dac_src_txt);
+
+static const struct soc_enum da9055_dac_r_src =
+	SOC_ENUM_SINGLE(DA9055_DIG_ROUTING_DAC, 4, 4, da9055_dac_src_txt);
+
+/* MIC PGA Left source select */
+static const char * const da9055_mic_l_src_txt[] = {
+	"MIC1_P_N", "MIC1_P", "MIC1_N", "MIC2_L"
+};
+
+static const struct soc_enum da9055_mic_l_src =
+	SOC_ENUM_SINGLE(DA9055_MIXIN_L_SELECT, 4, 4, da9055_mic_l_src_txt);
+
+/* MIC PGA Right source select */
+static const char * const da9055_mic_r_src_txt[] = {
+	"MIC2_R_L", "MIC2_R", "MIC2_L"
+};
+
+static const struct soc_enum da9055_mic_r_src =
+	SOC_ENUM_SINGLE(DA9055_MIXIN_R_SELECT, 4, 3, da9055_mic_r_src_txt);
+
+/* ALC Input Signal Tracking rate select */
+static const char * const da9055_signal_tracking_rate_txt[] = {
+	"1/4", "1/16", "1/256", "1/65536"
+};
+
+static const struct soc_enum da9055_integ_attack_rate =
+	SOC_ENUM_SINGLE(DA9055_ALC_CTRL3, 4, 4,
+			da9055_signal_tracking_rate_txt);
+
+static const struct soc_enum da9055_integ_release_rate =
+	SOC_ENUM_SINGLE(DA9055_ALC_CTRL3, 6, 4,
+			da9055_signal_tracking_rate_txt);
+
+/* ALC Attack Rate select */
+static const char * const da9055_attack_rate_txt[] = {
+	"44/fs", "88/fs", "176/fs", "352/fs", "704/fs", "1408/fs", "2816/fs",
+	"5632/fs", "11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs"
+};
+
+static const struct soc_enum da9055_attack_rate =
+	SOC_ENUM_SINGLE(DA9055_ALC_CTRL2, 0, 13, da9055_attack_rate_txt);
+
+/* ALC Release Rate select */
+static const char * const da9055_release_rate_txt[] = {
+	"176/fs", "352/fs", "704/fs", "1408/fs", "2816/fs", "5632/fs",
+	"11264/fs", "22528/fs", "45056/fs", "90112/fs", "180224/fs"
+};
+
+static const struct soc_enum da9055_release_rate =
+	SOC_ENUM_SINGLE(DA9055_ALC_CTRL2, 4, 11, da9055_release_rate_txt);
+
+/* ALC Hold Time select */
+static const char * const da9055_hold_time_txt[] = {
+	"62/fs", "124/fs", "248/fs", "496/fs", "992/fs", "1984/fs", "3968/fs",
+	"7936/fs", "15872/fs", "31744/fs", "63488/fs", "126976/fs",
+	"253952/fs", "507904/fs", "1015808/fs", "2031616/fs"
+};
+
+static const struct soc_enum da9055_hold_time =
+	SOC_ENUM_SINGLE(DA9055_ALC_CTRL3, 0, 16, da9055_hold_time_txt);
+
+static int da9055_get_alc_data(struct snd_soc_codec *codec, u8 reg_val)
+{
+	int mid_data, top_data;
+	int sum = 0;
+	u8 iteration;
+
+	for (iteration = 0; iteration < DA9055_ALC_AVG_ITERATIONS;
+	     iteration++) {
+		/* Select the left or right channel and capture data */
+		snd_soc_write(codec, DA9055_ALC_CIC_OP_LVL_CTRL, reg_val);
+
+		/* Select middle 8 bits for read back from data register */
+		snd_soc_write(codec, DA9055_ALC_CIC_OP_LVL_CTRL,
+			      reg_val | DA9055_ALC_DATA_MIDDLE);
+		mid_data = snd_soc_read(codec, DA9055_ALC_CIC_OP_LVL_DATA);
+
+		/* Select top 8 bits for read back from data register */
+		snd_soc_write(codec, DA9055_ALC_CIC_OP_LVL_CTRL,
+			      reg_val | DA9055_ALC_DATA_TOP);
+		top_data = snd_soc_read(codec, DA9055_ALC_CIC_OP_LVL_DATA);
+
+		sum += ((mid_data << 8) | (top_data << 16));
+	}
+
+	return sum / DA9055_ALC_AVG_ITERATIONS;
+}
+
+static int da9055_put_alc_sw(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+	u8 reg_val, adc_left, adc_right;
+	int avg_left_data, avg_right_data, offset_l, offset_r;
+
+	if (ucontrol->value.integer.value[0]) {
+		/*
+		 * While enabling ALC (or ALC sync mode), calibration of the DC
+		 * offsets must be done first
+		 */
+
+		/* Save current values from ADC control registers */
+		adc_left = snd_soc_read(codec, DA9055_ADC_L_CTRL);
+		adc_right = snd_soc_read(codec, DA9055_ADC_R_CTRL);
+
+		/* Enable ADC Left and Right */
+		snd_soc_update_bits(codec, DA9055_ADC_L_CTRL,
+				    DA9055_ADC_L_EN, DA9055_ADC_L_EN);
+		snd_soc_update_bits(codec, DA9055_ADC_R_CTRL,
+				    DA9055_ADC_R_EN, DA9055_ADC_R_EN);
+
+		/* Calculate average for Left and Right data */
+		/* Left Data */
+		avg_left_data = da9055_get_alc_data(codec,
+				DA9055_ALC_CIC_OP_CHANNEL_LEFT);
+		/* Right Data */
+		avg_right_data = da9055_get_alc_data(codec,
+				 DA9055_ALC_CIC_OP_CHANNEL_RIGHT);
+
+		/* Calculate DC offset */
+		offset_l = -avg_left_data;
+		offset_r = -avg_right_data;
+
+		reg_val = (offset_l & DA9055_ALC_OFFSET_15_8) >> 8;
+		snd_soc_write(codec, DA9055_ALC_OFFSET_OP2M_L, reg_val);
+		reg_val = (offset_l & DA9055_ALC_OFFSET_17_16) >> 16;
+		snd_soc_write(codec, DA9055_ALC_OFFSET_OP2U_L, reg_val);
+
+		reg_val = (offset_r & DA9055_ALC_OFFSET_15_8) >> 8;
+		snd_soc_write(codec, DA9055_ALC_OFFSET_OP2M_R, reg_val);
+		reg_val = (offset_r & DA9055_ALC_OFFSET_17_16) >> 16;
+		snd_soc_write(codec, DA9055_ALC_OFFSET_OP2U_R, reg_val);
+
+		/* Restore original values of ADC control registers */
+		snd_soc_write(codec, DA9055_ADC_L_CTRL, adc_left);
+		snd_soc_write(codec, DA9055_ADC_R_CTRL, adc_right);
+	}
+
+	return snd_soc_put_volsw(kcontrol, ucontrol);
+}
+
+static const struct snd_kcontrol_new da9055_snd_controls[] = {
+
+	/* Volume controls */
+	SOC_DOUBLE_R_TLV("Mic Volume",
+			 DA9055_MIC_L_GAIN, DA9055_MIC_R_GAIN,
+			 0, 0x7, 0, mic_vol_tlv),
+	SOC_DOUBLE_R_TLV("Aux Volume",
+			 DA9055_AUX_L_GAIN, DA9055_AUX_R_GAIN,
+			 0, 0x3f, 0, aux_vol_tlv),
+	SOC_DOUBLE_R_TLV("Mixin PGA Volume",
+			 DA9055_MIXIN_L_GAIN, DA9055_MIXIN_R_GAIN,
+			 0, 0xf, 0, mixin_gain_tlv),
+	SOC_DOUBLE_R_TLV("ADC Volume",
+			 DA9055_ADC_L_GAIN, DA9055_ADC_R_GAIN,
+			 0, 0x7f, 0, digital_gain_tlv),
+
+	SOC_DOUBLE_R_TLV("DAC Volume",
+			 DA9055_DAC_L_GAIN, DA9055_DAC_R_GAIN,
+			 0, 0x7f, 0, digital_gain_tlv),
+	SOC_DOUBLE_R_TLV("Headphone Volume",
+			 DA9055_HP_L_GAIN, DA9055_HP_R_GAIN,
+			 0, 0x3f, 0, hp_vol_tlv),
+	SOC_SINGLE_TLV("Lineout Volume", DA9055_LINE_GAIN, 0, 0x3f, 0,
+		       lineout_vol_tlv),
+
+	/* DAC Equalizer controls */
+	SOC_SINGLE("DAC EQ Switch", DA9055_DAC_FILTERS4, 7, 1, 0),
+	SOC_SINGLE_TLV("DAC EQ1 Volume", DA9055_DAC_FILTERS2, 0, 0xf, 0,
+		       eq_gain_tlv),
+	SOC_SINGLE_TLV("DAC EQ2 Volume", DA9055_DAC_FILTERS2, 4, 0xf, 0,
+		       eq_gain_tlv),
+	SOC_SINGLE_TLV("DAC EQ3 Volume", DA9055_DAC_FILTERS3, 0, 0xf, 0,
+		       eq_gain_tlv),
+	SOC_SINGLE_TLV("DAC EQ4 Volume", DA9055_DAC_FILTERS3, 4, 0xf, 0,
+		       eq_gain_tlv),
+	SOC_SINGLE_TLV("DAC EQ5 Volume", DA9055_DAC_FILTERS4, 0, 0xf, 0,
+		       eq_gain_tlv),
+
+	/* High Pass Filter and Voice Mode controls */
+	SOC_SINGLE("ADC HPF Switch", DA9055_ADC_FILTERS1, 7, 1, 0),
+	SOC_ENUM("ADC HPF Cutoff", da9055_adc_hpf_cutoff),
+	SOC_SINGLE("ADC Voice Mode Switch", DA9055_ADC_FILTERS1, 3, 1, 0),
+	SOC_ENUM("ADC Voice Cutoff", da9055_adc_vf_cutoff),
+
+	SOC_SINGLE("DAC HPF Switch", DA9055_DAC_FILTERS1, 7, 1, 0),
+	SOC_ENUM("DAC HPF Cutoff", da9055_dac_hpf_cutoff),
+	SOC_SINGLE("DAC Voice Mode Switch", DA9055_DAC_FILTERS1, 3, 1, 0),
+	SOC_ENUM("DAC Voice Cutoff", da9055_dac_vf_cutoff),
+
+	/* Mute controls */
+	SOC_DOUBLE_R("Mic Switch", DA9055_MIC_L_CTRL,
+		     DA9055_MIC_R_CTRL, 6, 1, 0),
+	SOC_DOUBLE_R("Aux Switch", DA9055_AUX_L_CTRL,
+		     DA9055_AUX_R_CTRL, 6, 1, 0),
+	SOC_DOUBLE_R("Mixin PGA Switch", DA9055_MIXIN_L_CTRL,
+		     DA9055_MIXIN_R_CTRL, 6, 1, 0),
+	SOC_DOUBLE_R("ADC Switch", DA9055_ADC_L_CTRL,
+		     DA9055_ADC_R_CTRL, 6, 1, 0),
+	SOC_DOUBLE_R("Headphone Switch", DA9055_HP_L_CTRL,
+		     DA9055_HP_R_CTRL, 6, 1, 0),
+	SOC_SINGLE("Lineout Switch", DA9055_LINE_CTRL, 6, 1, 0),
+	SOC_SINGLE("DAC Soft Mute Switch", DA9055_DAC_FILTERS5, 7, 1, 0),
+	SOC_ENUM("DAC Soft Mute Rate", da9055_dac_soft_mute_rate),
+
+	/* Zero Cross controls */
+	SOC_DOUBLE_R("Aux ZC Switch", DA9055_AUX_L_CTRL,
+		     DA9055_AUX_R_CTRL, 4, 1, 0),
+	SOC_DOUBLE_R("Mixin PGA ZC Switch", DA9055_MIXIN_L_CTRL,
+		     DA9055_MIXIN_R_CTRL, 4, 1, 0),
+	SOC_DOUBLE_R("Headphone ZC Switch", DA9055_HP_L_CTRL,
+		     DA9055_HP_R_CTRL, 4, 1, 0),
+	SOC_SINGLE("Lineout ZC Switch", DA9055_LINE_CTRL, 4, 1, 0),
+
+	/* Gain Ramping controls */
+	SOC_DOUBLE_R("Aux Gain Ramping Switch", DA9055_AUX_L_CTRL,
+		     DA9055_AUX_R_CTRL, 5, 1, 0),
+	SOC_DOUBLE_R("Mixin Gain Ramping Switch", DA9055_MIXIN_L_CTRL,
+		     DA9055_MIXIN_R_CTRL, 5, 1, 0),
+	SOC_DOUBLE_R("ADC Gain Ramping Switch", DA9055_ADC_L_CTRL,
+		     DA9055_ADC_R_CTRL, 5, 1, 0),
+	SOC_DOUBLE_R("DAC Gain Ramping Switch", DA9055_DAC_L_CTRL,
+		     DA9055_DAC_R_CTRL, 5, 1, 0),
+	SOC_DOUBLE_R("Headphone Gain Ramping Switch", DA9055_HP_L_CTRL,
+		     DA9055_HP_R_CTRL, 5, 1, 0),
+	SOC_SINGLE("Lineout Gain Ramping Switch", DA9055_LINE_CTRL, 5, 1, 0),
+	SOC_ENUM("Gain Ramping Rate", da9055_gain_ramping_rate),
+
+	/* DAC Noise Gate controls */
+	SOC_SINGLE("DAC NG Switch", DA9055_DAC_NG_CTRL, 7, 1, 0),
+	SOC_SINGLE("DAC NG ON Threshold", DA9055_DAC_NG_ON_THRESHOLD,
+		   0, 0x7, 0),
+	SOC_SINGLE("DAC NG OFF Threshold", DA9055_DAC_NG_OFF_THRESHOLD,
+		   0, 0x7, 0),
+	SOC_ENUM("DAC NG Setup Time", da9055_dac_ng_setup_time),
+	SOC_ENUM("DAC NG Rampup Rate", da9055_dac_ng_rampup_rate),
+	SOC_ENUM("DAC NG Rampdown Rate", da9055_dac_ng_rampdown_rate),
+
+	/* DAC Invertion control */
+	SOC_SINGLE("DAC Left Invert", DA9055_DIG_CTRL, 3, 1, 0),
+	SOC_SINGLE("DAC Right Invert", DA9055_DIG_CTRL, 7, 1, 0),
+
+	/* DMIC controls */
+	SOC_DOUBLE_R("DMIC Switch", DA9055_MIXIN_L_SELECT,
+		     DA9055_MIXIN_R_SELECT, 7, 1, 0),
+
+	/* ALC Controls */
+	SOC_DOUBLE_EXT("ALC Switch", DA9055_ALC_CTRL1, 3, 7, 1, 0,
+		       snd_soc_get_volsw, da9055_put_alc_sw),
+	SOC_SINGLE_EXT("ALC Sync Mode Switch", DA9055_ALC_CTRL1, 1, 1, 0,
+		       snd_soc_get_volsw, da9055_put_alc_sw),
+	SOC_SINGLE("ALC Offset Switch", DA9055_ALC_CTRL1, 0, 1, 0),
+	SOC_SINGLE("ALC Anticlip Mode Switch", DA9055_ALC_ANTICLIP_CTRL,
+		   7, 1, 0),
+	SOC_SINGLE("ALC Anticlip Level", DA9055_ALC_ANTICLIP_LEVEL,
+		   0, 0x7f, 0),
+	SOC_SINGLE_TLV("ALC Min Threshold Volume", DA9055_ALC_TARGET_MIN,
+		       0, 0x3f, 1, alc_threshold_tlv),
+	SOC_SINGLE_TLV("ALC Max Threshold Volume", DA9055_ALC_TARGET_MAX,
+		       0, 0x3f, 1, alc_threshold_tlv),
+	SOC_SINGLE_TLV("ALC Noise Threshold Volume", DA9055_ALC_NOISE,
+		       0, 0x3f, 1, alc_threshold_tlv),
+	SOC_SINGLE_TLV("ALC Max Gain Volume", DA9055_ALC_GAIN_LIMITS,
+		       4, 0xf, 0, alc_gain_tlv),
+	SOC_SINGLE_TLV("ALC Max Attenuation Volume", DA9055_ALC_GAIN_LIMITS,
+		       0, 0xf, 0, alc_gain_tlv),
+	SOC_SINGLE_TLV("ALC Min Analog Gain Volume",
+		       DA9055_ALC_ANA_GAIN_LIMITS,
+		       0, 0x7, 0, alc_analog_gain_tlv),
+	SOC_SINGLE_TLV("ALC Max Analog Gain Volume",
+		       DA9055_ALC_ANA_GAIN_LIMITS,
+		       4, 0x7, 0, alc_analog_gain_tlv),
+	SOC_ENUM("ALC Attack Rate", da9055_attack_rate),
+	SOC_ENUM("ALC Release Rate", da9055_release_rate),
+	SOC_ENUM("ALC Hold Time", da9055_hold_time),
+	/*
+	 * Rate at which input signal envelope is tracked as the signal gets
+	 * larger
+	 */
+	SOC_ENUM("ALC Integ Attack Rate", da9055_integ_attack_rate),
+	/*
+	 * Rate at which input signal envelope is tracked as the signal gets
+	 * smaller
+	 */
+	SOC_ENUM("ALC Integ Release Rate", da9055_integ_release_rate),
+};
+
+/* DAPM Controls */
+
+/* Mic PGA Left Source */
+static const struct snd_kcontrol_new da9055_mic_l_mux_controls =
+SOC_DAPM_ENUM("Route", da9055_mic_l_src);
+
+/* Mic PGA Right Source */
+static const struct snd_kcontrol_new da9055_mic_r_mux_controls =
+SOC_DAPM_ENUM("Route", da9055_mic_r_src);
+
+/* In Mixer Left */
+static const struct snd_kcontrol_new da9055_dapm_mixinl_controls[] = {
+	SOC_DAPM_SINGLE("Aux Left Switch", DA9055_MIXIN_L_SELECT, 0, 1, 0),
+	SOC_DAPM_SINGLE("Mic Left Switch", DA9055_MIXIN_L_SELECT, 1, 1, 0),
+	SOC_DAPM_SINGLE("Mic Right Switch", DA9055_MIXIN_L_SELECT, 2, 1, 0),
+};
+
+/* In Mixer Right */
+static const struct snd_kcontrol_new da9055_dapm_mixinr_controls[] = {
+	SOC_DAPM_SINGLE("Aux Right Switch", DA9055_MIXIN_R_SELECT, 0, 1, 0),
+	SOC_DAPM_SINGLE("Mic Right Switch", DA9055_MIXIN_R_SELECT, 1, 1, 0),
+	SOC_DAPM_SINGLE("Mic Left Switch", DA9055_MIXIN_R_SELECT, 2, 1, 0),
+	SOC_DAPM_SINGLE("Mixin Left Switch", DA9055_MIXIN_R_SELECT, 3, 1, 0),
+};
+
+/* DAC Left Source */
+static const struct snd_kcontrol_new da9055_dac_l_mux_controls =
+SOC_DAPM_ENUM("Route", da9055_dac_l_src);
+
+/* DAC Right Source */
+static const struct snd_kcontrol_new da9055_dac_r_mux_controls =
+SOC_DAPM_ENUM("Route", da9055_dac_r_src);
+
+/* Out Mixer Left */
+static const struct snd_kcontrol_new da9055_dapm_mixoutl_controls[] = {
+	SOC_DAPM_SINGLE("Aux Left Switch", DA9055_MIXOUT_L_SELECT, 0, 1, 0),
+	SOC_DAPM_SINGLE("Mixin Left Switch", DA9055_MIXOUT_L_SELECT, 1, 1, 0),
+	SOC_DAPM_SINGLE("Mixin Right Switch", DA9055_MIXOUT_L_SELECT, 2, 1, 0),
+	SOC_DAPM_SINGLE("DAC Left Switch", DA9055_MIXOUT_L_SELECT, 3, 1, 0),
+	SOC_DAPM_SINGLE("Aux Left Invert Switch", DA9055_MIXOUT_L_SELECT,
+			4, 1, 0),
+	SOC_DAPM_SINGLE("Mixin Left Invert Switch", DA9055_MIXOUT_L_SELECT,
+			5, 1, 0),
+	SOC_DAPM_SINGLE("Mixin Right Invert Switch", DA9055_MIXOUT_L_SELECT,
+			6, 1, 0),
+};
+
+/* Out Mixer Right */
+static const struct snd_kcontrol_new da9055_dapm_mixoutr_controls[] = {
+	SOC_DAPM_SINGLE("Aux Right Switch", DA9055_MIXOUT_R_SELECT, 0, 1, 0),
+	SOC_DAPM_SINGLE("Mixin Right Switch", DA9055_MIXOUT_R_SELECT, 1, 1, 0),
+	SOC_DAPM_SINGLE("Mixin Left Switch", DA9055_MIXOUT_R_SELECT, 2, 1, 0),
+	SOC_DAPM_SINGLE("DAC Right Switch", DA9055_MIXOUT_R_SELECT, 3, 1, 0),
+	SOC_DAPM_SINGLE("Aux Right Invert Switch", DA9055_MIXOUT_R_SELECT,
+			4, 1, 0),
+	SOC_DAPM_SINGLE("Mixin Right Invert Switch", DA9055_MIXOUT_R_SELECT,
+			5, 1, 0),
+	SOC_DAPM_SINGLE("Mixin Left Invert Switch", DA9055_MIXOUT_R_SELECT,
+			6, 1, 0),
+};
+
+/* DAPM widgets */
+static const struct snd_soc_dapm_widget da9055_dapm_widgets[] = {
+	/* Input Side */
+
+	/* Input Lines */
+	SND_SOC_DAPM_INPUT("MIC1"),
+	SND_SOC_DAPM_INPUT("MIC2"),
+	SND_SOC_DAPM_INPUT("AUXL"),
+	SND_SOC_DAPM_INPUT("AUXR"),
+
+	/* MUXs for Mic PGA source selection */
+	SND_SOC_DAPM_MUX("Mic Left Source", SND_SOC_NOPM, 0, 0,
+			 &da9055_mic_l_mux_controls),
+	SND_SOC_DAPM_MUX("Mic Right Source", SND_SOC_NOPM, 0, 0,
+			 &da9055_mic_r_mux_controls),
+
+	/* Input PGAs */
+	SND_SOC_DAPM_PGA("Mic Left", DA9055_MIC_L_CTRL, 7, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("Mic Right", DA9055_MIC_R_CTRL, 7, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("Aux Left", DA9055_AUX_L_CTRL, 7, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("Aux Right", DA9055_AUX_R_CTRL, 7, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("MIXIN Left", DA9055_MIXIN_L_CTRL, 7, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("MIXIN Right", DA9055_MIXIN_R_CTRL, 7, 0, NULL, 0),
+
+	SND_SOC_DAPM_SUPPLY("Mic Bias", DA9055_MIC_BIAS_CTRL, 7, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("AIF", DA9055_AIF_CTRL, 7, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("Charge Pump", DA9055_CP_CTRL, 7, 0, NULL, 0),
+
+	/* Input Mixers */
+	SND_SOC_DAPM_MIXER("In Mixer Left", SND_SOC_NOPM, 0, 0,
+			   &da9055_dapm_mixinl_controls[0],
+			   ARRAY_SIZE(da9055_dapm_mixinl_controls)),
+	SND_SOC_DAPM_MIXER("In Mixer Right", SND_SOC_NOPM, 0, 0,
+			   &da9055_dapm_mixinr_controls[0],
+			   ARRAY_SIZE(da9055_dapm_mixinr_controls)),
+
+	/* ADCs */
+	SND_SOC_DAPM_ADC("ADC Left", "Capture", DA9055_ADC_L_CTRL, 7, 0),
+	SND_SOC_DAPM_ADC("ADC Right", "Capture", DA9055_ADC_R_CTRL, 7, 0),
+
+	/* Output Side */
+
+	/* MUXs for DAC source selection */
+	SND_SOC_DAPM_MUX("DAC Left Source", SND_SOC_NOPM, 0, 0,
+			 &da9055_dac_l_mux_controls),
+	SND_SOC_DAPM_MUX("DAC Right Source", SND_SOC_NOPM, 0, 0,
+			 &da9055_dac_r_mux_controls),
+
+	/* AIF input */
+	SND_SOC_DAPM_AIF_IN("AIFIN Left", "Playback", 0, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_AIF_IN("AIFIN Right", "Playback", 0, SND_SOC_NOPM, 0, 0),
+
+	/* DACs */
+	SND_SOC_DAPM_DAC("DAC Left", "Playback", DA9055_DAC_L_CTRL, 7, 0),
+	SND_SOC_DAPM_DAC("DAC Right", "Playback", DA9055_DAC_R_CTRL, 7, 0),
+
+	/* Output Mixers */
+	SND_SOC_DAPM_MIXER("Out Mixer Left", SND_SOC_NOPM, 0, 0,
+			   &da9055_dapm_mixoutl_controls[0],
+			   ARRAY_SIZE(da9055_dapm_mixoutl_controls)),
+	SND_SOC_DAPM_MIXER("Out Mixer Right", SND_SOC_NOPM, 0, 0,
+			   &da9055_dapm_mixoutr_controls[0],
+			   ARRAY_SIZE(da9055_dapm_mixoutr_controls)),
+
+	/* Output PGAs */
+	SND_SOC_DAPM_PGA("MIXOUT Left", DA9055_MIXOUT_L_CTRL, 7, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("MIXOUT Right", DA9055_MIXOUT_R_CTRL, 7, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("Lineout", DA9055_LINE_CTRL, 7, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("Headphone Left", DA9055_HP_L_CTRL, 7, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("Headphone Right", DA9055_HP_R_CTRL, 7, 0, NULL, 0),
+
+	/* Output Lines */
+	SND_SOC_DAPM_OUTPUT("HPL"),
+	SND_SOC_DAPM_OUTPUT("HPR"),
+	SND_SOC_DAPM_OUTPUT("LINE"),
+};
+
+/* DAPM audio route definition */
+static const struct snd_soc_dapm_route da9055_audio_map[] = {
+	/* Dest       Connecting Widget    source */
+
+	/* Input path */
+	{"Mic Left Source", "MIC1_P_N", "MIC1"},
+	{"Mic Left Source", "MIC1_P", "MIC1"},
+	{"Mic Left Source", "MIC1_N", "MIC1"},
+	{"Mic Left Source", "MIC2_L", "MIC2"},
+
+	{"Mic Right Source", "MIC2_R_L", "MIC2"},
+	{"Mic Right Source", "MIC2_R", "MIC2"},
+	{"Mic Right Source", "MIC2_L", "MIC2"},
+
+	{"Mic Left", NULL, "Mic Left Source"},
+	{"Mic Right", NULL, "Mic Right Source"},
+
+	{"Aux Left", NULL, "AUXL"},
+	{"Aux Right", NULL, "AUXR"},
+
+	{"In Mixer Left", "Mic Left Switch", "Mic Left"},
+	{"In Mixer Left", "Mic Right Switch", "Mic Right"},
+	{"In Mixer Left", "Aux Left Switch", "Aux Left"},
+
+	{"In Mixer Right", "Mic Right Switch", "Mic Right"},
+	{"In Mixer Right", "Mic Left Switch", "Mic Left"},
+	{"In Mixer Right", "Aux Right Switch", "Aux Right"},
+	{"In Mixer Right", "Mixin Left Switch", "MIXIN Left"},
+
+	{"MIXIN Left", NULL, "In Mixer Left"},
+	{"ADC Left", NULL, "MIXIN Left"},
+
+	{"MIXIN Right", NULL, "In Mixer Right"},
+	{"ADC Right", NULL, "MIXIN Right"},
+
+	{"ADC Left", NULL, "AIF"},
+	{"ADC Right", NULL, "AIF"},
+
+	/* Output path */
+	{"AIFIN Left", NULL, "AIF"},
+	{"AIFIN Right", NULL, "AIF"},
+
+	{"DAC Left Source", "ADC output left", "ADC Left"},
+	{"DAC Left Source", "ADC output right", "ADC Right"},
+	{"DAC Left Source", "AIF input left", "AIFIN Left"},
+	{"DAC Left Source", "AIF input right", "AIFIN Right"},
+
+	{"DAC Right Source", "ADC output left", "ADC Left"},
+	{"DAC Right Source", "ADC output right", "ADC Right"},
+	{"DAC Right Source", "AIF input left", "AIFIN Left"},
+	{"DAC Right Source", "AIF input right", "AIFIN Right"},
+
+	{"DAC Left", NULL, "DAC Left Source"},
+	{"DAC Right", NULL, "DAC Right Source"},
+
+	{"Out Mixer Left", "Aux Left Switch", "Aux Left"},
+	{"Out Mixer Left", "Mixin Left Switch", "MIXIN Left"},
+	{"Out Mixer Left", "Mixin Right Switch", "MIXIN Right"},
+	{"Out Mixer Left", "Aux Left Invert Switch", "Aux Left"},
+	{"Out Mixer Left", "Mixin Left Invert Switch", "MIXIN Left"},
+	{"Out Mixer Left", "Mixin Right Invert Switch", "MIXIN Right"},
+	{"Out Mixer Left", "DAC Left Switch", "DAC Left"},
+
+	{"Out Mixer Right", "Aux Right Switch", "Aux Right"},
+	{"Out Mixer Right", "Mixin Right Switch", "MIXIN Right"},
+	{"Out Mixer Right", "Mixin Left Switch", "MIXIN Left"},
+	{"Out Mixer Right", "Aux Right Invert Switch", "Aux Right"},
+	{"Out Mixer Right", "Mixin Right Invert Switch", "MIXIN Right"},
+	{"Out Mixer Right", "Mixin Left Invert Switch", "MIXIN Left"},
+	{"Out Mixer Right", "DAC Right Switch", "DAC Right"},
+
+	{"MIXOUT Left", NULL, "Out Mixer Left"},
+	{"Headphone Left", NULL, "MIXOUT Left"},
+	{"Headphone Left", NULL, "Charge Pump"},
+	{"HPL", NULL, "Headphone Left"},
+
+	{"MIXOUT Right", NULL, "Out Mixer Right"},
+	{"Headphone Right", NULL, "MIXOUT Right"},
+	{"Headphone Right", NULL, "Charge Pump"},
+	{"HPR", NULL, "Headphone Right"},
+
+	{"MIXOUT Right", NULL, "Out Mixer Right"},
+	{"Lineout", NULL, "MIXOUT Right"},
+	{"LINE", NULL, "Lineout"},
+};
+
+/* Codec private data */
+struct da9055_priv {
+	struct regmap *regmap;
+	unsigned int mclk_rate;
+	int master;
+	struct da9055_platform_data *pdata;
+};
+
+static struct reg_default da9055_reg_defaults[] = {
+	{ 0x21, 0x10 },
+	{ 0x22, 0x0A },
+	{ 0x23, 0x00 },
+	{ 0x24, 0x00 },
+	{ 0x25, 0x00 },
+	{ 0x26, 0x00 },
+	{ 0x27, 0x0C },
+	{ 0x28, 0x01 },
+	{ 0x29, 0x08 },
+	{ 0x2A, 0x32 },
+	{ 0x2B, 0x00 },
+	{ 0x30, 0x35 },
+	{ 0x31, 0x35 },
+	{ 0x32, 0x00 },
+	{ 0x33, 0x00 },
+	{ 0x34, 0x03 },
+	{ 0x35, 0x03 },
+	{ 0x36, 0x6F },
+	{ 0x37, 0x6F },
+	{ 0x38, 0x80 },
+	{ 0x39, 0x01 },
+	{ 0x3A, 0x01 },
+	{ 0x40, 0x00 },
+	{ 0x41, 0x88 },
+	{ 0x42, 0x88 },
+	{ 0x43, 0x08 },
+	{ 0x44, 0x80 },
+	{ 0x45, 0x6F },
+	{ 0x46, 0x6F },
+	{ 0x47, 0x61 },
+	{ 0x48, 0x35 },
+	{ 0x49, 0x35 },
+	{ 0x4A, 0x35 },
+	{ 0x4B, 0x00 },
+	{ 0x4C, 0x00 },
+	{ 0x60, 0x44 },
+	{ 0x61, 0x44 },
+	{ 0x62, 0x00 },
+	{ 0x63, 0x40 },
+	{ 0x64, 0x40 },
+	{ 0x65, 0x40 },
+	{ 0x66, 0x40 },
+	{ 0x67, 0x40 },
+	{ 0x68, 0x40 },
+	{ 0x69, 0x48 },
+	{ 0x6A, 0x40 },
+	{ 0x6B, 0x41 },
+	{ 0x6C, 0x40 },
+	{ 0x6D, 0x40 },
+	{ 0x6E, 0x10 },
+	{ 0x6F, 0x10 },
+	{ 0x90, 0x80 },
+	{ 0x92, 0x02 },
+	{ 0x93, 0x00 },
+	{ 0x99, 0x00 },
+	{ 0x9A, 0x00 },
+	{ 0x9B, 0x00 },
+	{ 0x9C, 0x3F },
+	{ 0x9D, 0x00 },
+	{ 0x9E, 0x3F },
+	{ 0x9F, 0xFF },
+	{ 0xA0, 0x71 },
+	{ 0xA1, 0x00 },
+	{ 0xA2, 0x00 },
+	{ 0xA6, 0x00 },
+	{ 0xA7, 0x00 },
+	{ 0xAB, 0x00 },
+	{ 0xAC, 0x00 },
+	{ 0xAD, 0x00 },
+	{ 0xAF, 0x08 },
+	{ 0xB0, 0x00 },
+	{ 0xB1, 0x00 },
+	{ 0xB2, 0x00 },
+};
+
+static bool da9055_volatile_register(struct device *dev,
+				     unsigned int reg)
+{
+	switch (reg) {
+	case DA9055_STATUS1:
+	case DA9055_PLL_STATUS:
+	case DA9055_AUX_L_GAIN_STATUS:
+	case DA9055_AUX_R_GAIN_STATUS:
+	case DA9055_MIC_L_GAIN_STATUS:
+	case DA9055_MIC_R_GAIN_STATUS:
+	case DA9055_MIXIN_L_GAIN_STATUS:
+	case DA9055_MIXIN_R_GAIN_STATUS:
+	case DA9055_ADC_L_GAIN_STATUS:
+	case DA9055_ADC_R_GAIN_STATUS:
+	case DA9055_DAC_L_GAIN_STATUS:
+	case DA9055_DAC_R_GAIN_STATUS:
+	case DA9055_HP_L_GAIN_STATUS:
+	case DA9055_HP_R_GAIN_STATUS:
+	case DA9055_LINE_GAIN_STATUS:
+	case DA9055_ALC_CIC_OP_LVL_DATA:
+		return 1;
+	default:
+		return 0;
+	}
+}
+
+/* Set DAI word length */
+static int da9055_hw_params(struct snd_pcm_substream *substream,
+			    struct snd_pcm_hw_params *params,
+			    struct snd_soc_dai *dai)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec);
+	u8 aif_ctrl, fs;
+	u32 sysclk;
+
+	switch (params_format(params)) {
+	case SNDRV_PCM_FORMAT_S16_LE:
+		aif_ctrl = DA9055_AIF_WORD_S16_LE;
+		break;
+	case SNDRV_PCM_FORMAT_S20_3LE:
+		aif_ctrl = DA9055_AIF_WORD_S20_3LE;
+		break;
+	case SNDRV_PCM_FORMAT_S24_LE:
+		aif_ctrl = DA9055_AIF_WORD_S24_LE;
+		break;
+	case SNDRV_PCM_FORMAT_S32_LE:
+		aif_ctrl = DA9055_AIF_WORD_S32_LE;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* Set AIF format */
+	snd_soc_update_bits(codec, DA9055_AIF_CTRL, DA9055_AIF_WORD_LENGTH_MASK,
+			    aif_ctrl);
+
+	switch (params_rate(params)) {
+	case 8000:
+		fs		= DA9055_SR_8000;
+		sysclk		= 3072000;
+		break;
+	case 11025:
+		fs		= DA9055_SR_11025;
+		sysclk		= 2822400;
+		break;
+	case 12000:
+		fs		= DA9055_SR_12000;
+		sysclk		= 3072000;
+		break;
+	case 16000:
+		fs		= DA9055_SR_16000;
+		sysclk		= 3072000;
+		break;
+	case 22050:
+		fs		= DA9055_SR_22050;
+		sysclk		= 2822400;
+		break;
+	case 32000:
+		fs		= DA9055_SR_32000;
+		sysclk		= 3072000;
+		break;
+	case 44100:
+		fs		= DA9055_SR_44100;
+		sysclk		= 2822400;
+		break;
+	case 48000:
+		fs		= DA9055_SR_48000;
+		sysclk		= 3072000;
+		break;
+	case 88200:
+		fs		= DA9055_SR_88200;
+		sysclk		= 2822400;
+		break;
+	case 96000:
+		fs		= DA9055_SR_96000;
+		sysclk		= 3072000;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (da9055->mclk_rate) {
+		/* PLL Mode, Write actual FS */
+		snd_soc_write(codec, DA9055_SR, fs);
+	} else {
+		/*
+		 * Non-PLL Mode
+		 * When PLL is bypassed, chip assumes constant MCLK of
+		 * 12.288MHz and uses sample rate value to divide this MCLK
+		 * to derive its sys clk. As sys clk has to be 256 * Fs, we
+		 * need to write constant sample rate i.e. 48KHz.
+		 */
+		snd_soc_write(codec, DA9055_SR, DA9055_SR_48000);
+	}
+
+	if (da9055->mclk_rate && (da9055->mclk_rate != sysclk)) {
+		/* PLL Mode */
+		if (!da9055->master) {
+			/* PLL slave mode, enable PLL and also SRM */
+			snd_soc_update_bits(codec, DA9055_PLL_CTRL,
+					    DA9055_PLL_EN | DA9055_PLL_SRM_EN,
+					    DA9055_PLL_EN | DA9055_PLL_SRM_EN);
+		} else {
+			/* PLL master mode, only enable PLL */
+			snd_soc_update_bits(codec, DA9055_PLL_CTRL,
+					    DA9055_PLL_EN, DA9055_PLL_EN);
+		}
+	} else {
+		/* Non PLL Mode, disable PLL */
+		snd_soc_update_bits(codec, DA9055_PLL_CTRL, DA9055_PLL_EN, 0);
+	}
+
+	return 0;
+}
+
+/* Set DAI mode and Format */
+static int da9055_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
+{
+	struct snd_soc_codec *codec = codec_dai->codec;
+	struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec);
+	u8 aif_clk_mode, aif_ctrl, mode;
+
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBM_CFM:
+		/* DA9055 in I2S Master Mode */
+		mode = 1;
+		aif_clk_mode = DA9055_AIF_CLK_EN_MASTER_MODE;
+		break;
+	case SND_SOC_DAIFMT_CBS_CFS:
+		/* DA9055 in I2S Slave Mode */
+		mode = 0;
+		aif_clk_mode = DA9055_AIF_CLK_EN_SLAVE_MODE;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* Don't allow change of mode if PLL is enabled */
+	if ((snd_soc_read(codec, DA9055_PLL_CTRL) & DA9055_PLL_EN) &&
+	    (da9055->master != mode))
+		return -EINVAL;
+
+	da9055->master = mode;
+
+	/* Only I2S is supported */
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		aif_ctrl = DA9055_AIF_FORMAT_I2S_MODE;
+		break;
+	case SND_SOC_DAIFMT_LEFT_J:
+		aif_ctrl = DA9055_AIF_FORMAT_LEFT_J;
+		break;
+	case SND_SOC_DAIFMT_RIGHT_J:
+		aif_ctrl = DA9055_AIF_FORMAT_RIGHT_J;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* By default only 32 BCLK per WCLK is supported */
+	aif_clk_mode |= DA9055_AIF_BCLKS_PER_WCLK_32;
+
+	snd_soc_update_bits(codec, DA9055_AIF_CLK_MODE,
+			    (DA9055_AIF_CLK_MODE_MASK | DA9055_AIF_BCLK_MASK),
+			    aif_clk_mode);
+	snd_soc_update_bits(codec, DA9055_AIF_CTRL, DA9055_AIF_FORMAT_MASK,
+			    aif_ctrl);
+	return 0;
+}
+
+static int da9055_mute(struct snd_soc_dai *dai, int mute)
+{
+	struct snd_soc_codec *codec = dai->codec;
+
+	if (mute) {
+		snd_soc_update_bits(codec, DA9055_DAC_L_CTRL,
+				    DA9055_DAC_L_MUTE_EN, DA9055_DAC_L_MUTE_EN);
+		snd_soc_update_bits(codec, DA9055_DAC_R_CTRL,
+				    DA9055_DAC_R_MUTE_EN, DA9055_DAC_R_MUTE_EN);
+	} else {
+		snd_soc_update_bits(codec, DA9055_DAC_L_CTRL,
+				    DA9055_DAC_L_MUTE_EN, 0);
+		snd_soc_update_bits(codec, DA9055_DAC_R_CTRL,
+				    DA9055_DAC_R_MUTE_EN, 0);
+	}
+
+	return 0;
+}
+
+#define DA9055_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
+			SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+static int da9055_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+				 int clk_id, unsigned int freq, int dir)
+{
+	struct snd_soc_codec *codec = codec_dai->codec;
+	struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec);
+
+	switch (clk_id) {
+	case DA9055_CLKSRC_MCLK:
+		switch (freq) {
+		case 11289600:
+		case 12000000:
+		case 12288000:
+		case 13000000:
+		case 13500000:
+		case 14400000:
+		case 19200000:
+		case 19680000:
+		case 19800000:
+			da9055->mclk_rate = freq;
+			return 0;
+		default:
+			dev_err(codec_dai->dev, "Unsupported MCLK value %d\n",
+				freq);
+			return -EINVAL;
+		}
+		break;
+	default:
+		dev_err(codec_dai->dev, "Unknown clock source %d\n", clk_id);
+		return -EINVAL;
+	}
+}
+
+/*
+ * da9055_set_dai_pll	: Configure the codec PLL
+ * @param codec_dai	: Pointer to codec DAI
+ * @param pll_id	: da9055 has only one pll, so pll_id is always zero
+ * @param fref		: Input MCLK frequency
+ * @param fout		: FsDM value
+ * @return int		: Zero for success, negative error code for error
+ *
+ * Note: Supported PLL input frequencies are 11.2896MHz, 12MHz, 12.288MHz,
+ *	 13MHz, 13.5MHz, 14.4MHz, 19.2MHz, 19.6MHz and 19.8MHz
+ */
+static int da9055_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
+			      int source, unsigned int fref, unsigned int fout)
+{
+	struct snd_soc_codec *codec = codec_dai->codec;
+	struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec);
+
+	u8 pll_frac_top, pll_frac_bot, pll_integer, cnt;
+
+	/* Disable PLL before setting the divisors */
+	snd_soc_update_bits(codec, DA9055_PLL_CTRL, DA9055_PLL_EN, 0);
+
+	/* In slave mode, there is only one set of divisors */
+	if (!da9055->master && (fout != 2822400))
+		goto pll_err;
+
+	/* Search pll div array for correct divisors */
+	for (cnt = 0; cnt < ARRAY_SIZE(da9055_pll_div); cnt++) {
+		/* Check fref, mode  and fout */
+		if ((fref == da9055_pll_div[cnt].fref) &&
+		    (da9055->master ==  da9055_pll_div[cnt].mode) &&
+		    (fout == da9055_pll_div[cnt].fout)) {
+			/* All match, pick up divisors */
+			pll_frac_top = da9055_pll_div[cnt].frac_top;
+			pll_frac_bot = da9055_pll_div[cnt].frac_bot;
+			pll_integer = da9055_pll_div[cnt].integer;
+			break;
+		}
+	}
+	if (cnt >= ARRAY_SIZE(da9055_pll_div))
+		goto pll_err;
+
+	/* Write PLL dividers */
+	snd_soc_write(codec, DA9055_PLL_FRAC_TOP, pll_frac_top);
+	snd_soc_write(codec, DA9055_PLL_FRAC_BOT, pll_frac_bot);
+	snd_soc_write(codec, DA9055_PLL_INTEGER, pll_integer);
+
+	return 0;
+pll_err:
+	dev_err(codec_dai->dev, "Error in setting up PLL\n");
+	return -EINVAL;
+}
+
+/* DAI operations */
+static const struct snd_soc_dai_ops da9055_dai_ops = {
+	.hw_params	= da9055_hw_params,
+	.set_fmt	= da9055_set_dai_fmt,
+	.set_sysclk	= da9055_set_dai_sysclk,
+	.set_pll	= da9055_set_dai_pll,
+	.digital_mute	= da9055_mute,
+};
+
+static struct snd_soc_dai_driver da9055_dai = {
+	.name = "da9055-hifi",
+	/* Playback Capabilities */
+	.playback = {
+		.stream_name = "Playback",
+		.channels_min = 1,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_8000_96000,
+		.formats = DA9055_FORMATS,
+	},
+	/* Capture Capabilities */
+	.capture = {
+		.stream_name = "Capture",
+		.channels_min = 1,
+		.channels_max = 2,
+		.rates = SNDRV_PCM_RATE_8000_96000,
+		.formats = DA9055_FORMATS,
+	},
+	.ops = &da9055_dai_ops,
+	.symmetric_rates = 1,
+};
+
+static int da9055_set_bias_level(struct snd_soc_codec *codec,
+				 enum snd_soc_bias_level level)
+{
+	switch (level) {
+	case SND_SOC_BIAS_ON:
+	case SND_SOC_BIAS_PREPARE:
+		break;
+	case SND_SOC_BIAS_STANDBY:
+		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+			/* Enable VMID reference & master bias */
+			snd_soc_update_bits(codec, DA9055_REFERENCES,
+					    DA9055_VMID_EN | DA9055_BIAS_EN,
+					    DA9055_VMID_EN | DA9055_BIAS_EN);
+		}
+		break;
+	case SND_SOC_BIAS_OFF:
+		/* Disable VMID reference & master bias */
+		snd_soc_update_bits(codec, DA9055_REFERENCES,
+				    DA9055_VMID_EN | DA9055_BIAS_EN, 0);
+		break;
+	}
+	codec->dapm.bias_level = level;
+	return 0;
+}
+
+static int da9055_probe(struct snd_soc_codec *codec)
+{
+	int ret;
+	struct da9055_priv *da9055 = snd_soc_codec_get_drvdata(codec);
+
+	codec->control_data = da9055->regmap;
+	ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
+	if (ret < 0) {
+		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+		return ret;
+	}
+
+	/* Enable all Gain Ramps */
+	snd_soc_update_bits(codec, DA9055_AUX_L_CTRL,
+			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
+	snd_soc_update_bits(codec, DA9055_AUX_R_CTRL,
+			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
+	snd_soc_update_bits(codec, DA9055_MIXIN_L_CTRL,
+			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
+	snd_soc_update_bits(codec, DA9055_MIXIN_R_CTRL,
+			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
+	snd_soc_update_bits(codec, DA9055_ADC_L_CTRL,
+			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
+	snd_soc_update_bits(codec, DA9055_ADC_R_CTRL,
+			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
+	snd_soc_update_bits(codec, DA9055_DAC_L_CTRL,
+			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
+	snd_soc_update_bits(codec, DA9055_DAC_R_CTRL,
+			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
+	snd_soc_update_bits(codec, DA9055_HP_L_CTRL,
+			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
+	snd_soc_update_bits(codec, DA9055_HP_R_CTRL,
+			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
+	snd_soc_update_bits(codec, DA9055_LINE_CTRL,
+			    DA9055_GAIN_RAMPING_EN, DA9055_GAIN_RAMPING_EN);
+
+	/*
+	 * There are two separate control bits for input and output mixers as
+	 * well as headphone and line outs.
+	 * One to enable corresponding amplifier and other to enable its
+	 * output. As amplifier bits are related to power control, they are
+	 * being managed by DAPM while other (non power related) bits are
+	 * enabled here
+	 */
+	snd_soc_update_bits(codec, DA9055_MIXIN_L_CTRL,
+			    DA9055_MIXIN_L_MIX_EN, DA9055_MIXIN_L_MIX_EN);
+	snd_soc_update_bits(codec, DA9055_MIXIN_R_CTRL,
+			    DA9055_MIXIN_R_MIX_EN, DA9055_MIXIN_R_MIX_EN);
+
+	snd_soc_update_bits(codec, DA9055_MIXOUT_L_CTRL,
+			    DA9055_MIXOUT_L_MIX_EN, DA9055_MIXOUT_L_MIX_EN);
+	snd_soc_update_bits(codec, DA9055_MIXOUT_R_CTRL,
+			    DA9055_MIXOUT_R_MIX_EN, DA9055_MIXOUT_R_MIX_EN);
+
+	snd_soc_update_bits(codec, DA9055_HP_L_CTRL,
+			    DA9055_HP_L_AMP_OE, DA9055_HP_L_AMP_OE);
+	snd_soc_update_bits(codec, DA9055_HP_R_CTRL,
+			    DA9055_HP_R_AMP_OE, DA9055_HP_R_AMP_OE);
+
+	snd_soc_update_bits(codec, DA9055_LINE_CTRL,
+			    DA9055_LINE_AMP_OE, DA9055_LINE_AMP_OE);
+
+	/* Set this as per your system configuration */
+	snd_soc_write(codec, DA9055_PLL_CTRL, DA9055_PLL_INDIV_10_20_MHZ);
+
+	/* Set platform data values */
+	if (da9055->pdata) {
+		/* set mic bias source */
+		if (da9055->pdata->micbias_source) {
+			snd_soc_update_bits(codec, DA9055_MIXIN_R_SELECT,
+					    DA9055_MICBIAS2_EN,
+					    DA9055_MICBIAS2_EN);
+		} else {
+			snd_soc_update_bits(codec, DA9055_MIXIN_R_SELECT,
+					    DA9055_MICBIAS2_EN, 0);
+		}
+		/* set mic bias voltage */
+		switch (da9055->pdata->micbias) {
+		case DA9055_MICBIAS_2_2V:
+		case DA9055_MICBIAS_2_1V:
+		case DA9055_MICBIAS_1_8V:
+		case DA9055_MICBIAS_1_6V:
+			snd_soc_update_bits(codec, DA9055_MIC_CONFIG,
+					    DA9055_MICBIAS_LEVEL_MASK,
+					    (da9055->pdata->micbias) << 4);
+			break;
+		}
+	}
+	return 0;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_da9055 = {
+	.probe			= da9055_probe,
+	.set_bias_level		= da9055_set_bias_level,
+
+	.controls		= da9055_snd_controls,
+	.num_controls		= ARRAY_SIZE(da9055_snd_controls),
+
+	.dapm_widgets		= da9055_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(da9055_dapm_widgets),
+	.dapm_routes		= da9055_audio_map,
+	.num_dapm_routes	= ARRAY_SIZE(da9055_audio_map),
+};
+
+static const struct regmap_config da9055_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+
+	.reg_defaults = da9055_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(da9055_reg_defaults),
+	.volatile_reg = da9055_volatile_register,
+	.cache_type = REGCACHE_RBTREE,
+};
+
+static int __devinit da9055_i2c_probe(struct i2c_client *i2c,
+				      const struct i2c_device_id *id)
+{
+	struct da9055_priv *da9055;
+	struct da9055_platform_data *pdata = dev_get_platdata(&i2c->dev);
+	int ret;
+
+	da9055 = devm_kzalloc(&i2c->dev, sizeof(struct da9055_priv),
+			      GFP_KERNEL);
+	if (!da9055)
+		return -ENOMEM;
+
+	if (pdata)
+		da9055->pdata = pdata;
+
+	i2c_set_clientdata(i2c, da9055);
+
+	da9055->regmap = devm_regmap_init_i2c(i2c, &da9055_regmap_config);
+	if (IS_ERR(da9055->regmap)) {
+		ret = PTR_ERR(da9055->regmap);
+		dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
+		return ret;
+	}
+
+	ret = snd_soc_register_codec(&i2c->dev,
+			&soc_codec_dev_da9055, &da9055_dai, 1);
+	if (ret < 0) {
+		dev_err(&i2c->dev, "Failed to register da9055 codec: %d\n",
+			ret);
+	}
+	return ret;
+}
+
+static int __devexit da9055_remove(struct i2c_client *client)
+{
+	snd_soc_unregister_codec(&client->dev);
+	return 0;
+}
+
+static const struct i2c_device_id da9055_i2c_id[] = {
+	{ "da9055", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, da9055_i2c_id);
+
+/* I2C codec control layer */
+static struct i2c_driver da9055_i2c_driver = {
+	.driver = {
+		.name = "da9055",
+		.owner = THIS_MODULE,
+	},
+	.probe		= da9055_i2c_probe,
+	.remove		= __devexit_p(da9055_remove),
+	.id_table	= da9055_i2c_id,
+};
+
+module_i2c_driver(da9055_i2c_driver);
+
+MODULE_DESCRIPTION("ASoC DA9055 Codec driver");
+MODULE_AUTHOR("David Chen, Ashish Chavan");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c
index 5d8f39e..1bf5560 100644
--- a/sound/soc/codecs/isabelle.c
+++ b/sound/soc/codecs/isabelle.c
@@ -13,7 +13,6 @@
  */
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/delay.h>
diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c
index ba4fafb..81a328c 100644
--- a/sound/soc/codecs/lm4857.c
+++ b/sound/soc/codecs/lm4857.c
@@ -250,17 +250,7 @@
 	.id_table = lm4857_i2c_id,
 };
 
-static int __init lm4857_init(void)
-{
-	return i2c_add_driver(&lm4857_i2c_driver);
-}
-module_init(lm4857_init);
-
-static void __exit lm4857_exit(void)
-{
-	i2c_del_driver(&lm4857_i2c_driver);
-}
-module_exit(lm4857_exit);
+module_i2c_driver(lm4857_i2c_driver);
 
 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
 MODULE_DESCRIPTION("LM4857 amplifier driver");
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index af7324b..3264a51 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -2107,23 +2107,7 @@
        .id_table = max98088_i2c_id,
 };
 
-static int __init max98088_init(void)
-{
-       int ret;
-
-       ret = i2c_add_driver(&max98088_i2c_driver);
-       if (ret)
-               pr_err("Failed to register max98088 I2C driver: %d\n", ret);
-
-       return ret;
-}
-module_init(max98088_init);
-
-static void __exit max98088_exit(void)
-{
-       i2c_del_driver(&max98088_i2c_driver);
-}
-module_exit(max98088_exit);
+module_i2c_driver(max98088_i2c_driver);
 
 MODULE_DESCRIPTION("ALSA SoC MAX98088 driver");
 MODULE_AUTHOR("Peter Hsiang, Jesse Marroquin");
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
index 7cd508e..38d43c5 100644
--- a/sound/soc/codecs/max98095.c
+++ b/sound/soc/codecs/max98095.c
@@ -2533,23 +2533,7 @@
 	.id_table = max98095_i2c_id,
 };
 
-static int __init max98095_init(void)
-{
-	int ret;
-
-	ret = i2c_add_driver(&max98095_i2c_driver);
-	if (ret)
-		pr_err("Failed to register max98095 I2C driver: %d\n", ret);
-
-	return ret;
-}
-module_init(max98095_init);
-
-static void __exit max98095_exit(void)
-{
-	i2c_del_driver(&max98095_i2c_driver);
-}
-module_exit(max98095_exit);
+module_i2c_driver(max98095_i2c_driver);
 
 MODULE_DESCRIPTION("ALSA SoC MAX98095 driver");
 MODULE_AUTHOR("Peter Hsiang");
diff --git a/sound/soc/codecs/max9850.c b/sound/soc/codecs/max9850.c
index a191309..efe535c 100644
--- a/sound/soc/codecs/max9850.c
+++ b/sound/soc/codecs/max9850.c
@@ -369,17 +369,7 @@
 	.id_table = max9850_i2c_id,
 };
 
-static int __init max9850_init(void)
-{
-	return i2c_add_driver(&max9850_i2c_driver);
-}
-module_init(max9850_init);
-
-static void __exit max9850_exit(void)
-{
-	i2c_del_driver(&max9850_i2c_driver);
-}
-module_exit(max9850_exit);
+module_i2c_driver(max9850_i2c_driver);
 
 MODULE_AUTHOR("Christian Glindkamp <christian.glindkamp@taskit.de>");
 MODULE_DESCRIPTION("ASoC MAX9850 codec driver");
diff --git a/sound/soc/codecs/max9877.c b/sound/soc/codecs/max9877.c
index 3a2ba3d..d15e594 100644
--- a/sound/soc/codecs/max9877.c
+++ b/sound/soc/codecs/max9877.c
@@ -291,17 +291,7 @@
 	.id_table = max9877_i2c_id,
 };
 
-static int __init max9877_init(void)
-{
-	return i2c_add_driver(&max9877_i2c_driver);
-}
-module_init(max9877_init);
-
-static void __exit max9877_exit(void)
-{
-	i2c_del_driver(&max9877_i2c_driver);
-}
-module_exit(max9877_exit);
+module_i2c_driver(max9877_i2c_driver);
 
 MODULE_DESCRIPTION("ASoC MAX9877 amp driver");
 MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c
index 115a403..bc95599 100644
--- a/sound/soc/codecs/mc13783.c
+++ b/sound/soc/codecs/mc13783.c
@@ -426,16 +426,16 @@
 }
 
 static const struct snd_kcontrol_new mc1l_amp_ctl =
-	SOC_DAPM_SINGLE("Switch", 38, 7, 1, 0);
+	SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_TX, 7, 1, 0);
 
 static const struct snd_kcontrol_new mc1r_amp_ctl =
-	SOC_DAPM_SINGLE("Switch", 38, 5, 1, 0);
+	SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_TX, 5, 1, 0);
 
 static const struct snd_kcontrol_new mc2_amp_ctl =
-	SOC_DAPM_SINGLE("Switch", 38, 9, 1, 0);
+	SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_TX, 9, 1, 0);
 
 static const struct snd_kcontrol_new atx_amp_ctl =
-	SOC_DAPM_SINGLE("Switch", 38, 11, 1, 0);
+	SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_TX, 11, 1, 0);
 
 
 /* Virtual mux. The chip does the input selection automatically
@@ -461,22 +461,22 @@
 	SOC_DAPM_ENUM_VIRT("Route", adcr_enum);
 
 static const struct snd_kcontrol_new samp_ctl =
-	SOC_DAPM_SINGLE("Switch", 36, 3, 1, 0);
+	SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 3, 1, 0);
 
 static const struct snd_kcontrol_new lamp_ctl =
-	SOC_DAPM_SINGLE("Switch", 36, 5, 1, 0);
+	SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 5, 1, 0);
 
 static const struct snd_kcontrol_new hlamp_ctl =
-	SOC_DAPM_SINGLE("Switch", 36, 10, 1, 0);
+	SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 10, 1, 0);
 
 static const struct snd_kcontrol_new hramp_ctl =
-	SOC_DAPM_SINGLE("Switch", 36, 9, 1, 0);
+	SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 9, 1, 0);
 
 static const struct snd_kcontrol_new llamp_ctl =
-	SOC_DAPM_SINGLE("Switch", 36, 16, 1, 0);
+	SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 16, 1, 0);
 
 static const struct snd_kcontrol_new lramp_ctl =
-	SOC_DAPM_SINGLE("Switch", 36, 15, 1, 0);
+	SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 15, 1, 0);
 
 static const struct snd_soc_dapm_widget mc13783_dapm_widgets[] = {
 /* Input */
@@ -487,13 +487,13 @@
 	SND_SOC_DAPM_INPUT("RXINL"),
 	SND_SOC_DAPM_INPUT("TXIN"),
 
-	SND_SOC_DAPM_SUPPLY("MC1 Bias", 38, 0, 0, NULL, 0),
-	SND_SOC_DAPM_SUPPLY("MC2 Bias", 38, 1, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("MC1 Bias", MC13783_AUDIO_TX, 0, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("MC2 Bias", MC13783_AUDIO_TX, 1, 0, NULL, 0),
 
-	SND_SOC_DAPM_SWITCH("MC1L Amp", 38, 7, 0, &mc1l_amp_ctl),
-	SND_SOC_DAPM_SWITCH("MC1R Amp", 38, 5, 0, &mc1r_amp_ctl),
-	SND_SOC_DAPM_SWITCH("MC2 Amp", 38, 9, 0, &mc2_amp_ctl),
-	SND_SOC_DAPM_SWITCH("TXIN Amp", 38, 11, 0, &atx_amp_ctl),
+	SND_SOC_DAPM_SWITCH("MC1L Amp", MC13783_AUDIO_TX, 7, 0, &mc1l_amp_ctl),
+	SND_SOC_DAPM_SWITCH("MC1R Amp", MC13783_AUDIO_TX, 5, 0, &mc1r_amp_ctl),
+	SND_SOC_DAPM_SWITCH("MC2 Amp", MC13783_AUDIO_TX, 9, 0, &mc2_amp_ctl),
+	SND_SOC_DAPM_SWITCH("TXIN Amp", MC13783_AUDIO_TX, 11, 0, &atx_amp_ctl),
 
 	SND_SOC_DAPM_VIRT_MUX("PGA Left Input Mux", SND_SOC_NOPM, 0, 0,
 			      &left_input_mux),
@@ -503,12 +503,12 @@
 	SND_SOC_DAPM_PGA("PGA Left Input", SND_SOC_NOPM, 0, 0, NULL, 0),
 	SND_SOC_DAPM_PGA("PGA Right Input", SND_SOC_NOPM, 0, 0, NULL, 0),
 
-	SND_SOC_DAPM_ADC("ADC", "Capture", 40, 11, 0),
-	SND_SOC_DAPM_SUPPLY("ADC_Reset", 40, 15, 0, NULL, 0),
+	SND_SOC_DAPM_ADC("ADC", "Capture", MC13783_AUDIO_CODEC, 11, 0),
+	SND_SOC_DAPM_SUPPLY("ADC_Reset", MC13783_AUDIO_CODEC, 15, 0, NULL, 0),
 
 /* Output */
-	SND_SOC_DAPM_SUPPLY("DAC_E", 41, 11, 0, NULL, 0),
-	SND_SOC_DAPM_SUPPLY("DAC_Reset", 41, 15, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("DAC_E", MC13783_AUDIO_DAC, 11, 0, NULL, 0),
+	SND_SOC_DAPM_SUPPLY("DAC_Reset", MC13783_AUDIO_DAC, 15, 0, NULL, 0),
 	SND_SOC_DAPM_OUTPUT("RXOUTL"),
 	SND_SOC_DAPM_OUTPUT("RXOUTR"),
 	SND_SOC_DAPM_OUTPUT("HSL"),
@@ -516,14 +516,18 @@
 	SND_SOC_DAPM_OUTPUT("LSP"),
 	SND_SOC_DAPM_OUTPUT("SP"),
 
-	SND_SOC_DAPM_SWITCH("Speaker Amp", 36, 3, 0, &samp_ctl),
+	SND_SOC_DAPM_SWITCH("Speaker Amp", MC13783_AUDIO_RX0, 3, 0, &samp_ctl),
 	SND_SOC_DAPM_SWITCH("Loudspeaker Amp", SND_SOC_NOPM, 0, 0, &lamp_ctl),
-	SND_SOC_DAPM_SWITCH("Headset Amp Left", 36, 10, 0, &hlamp_ctl),
-	SND_SOC_DAPM_SWITCH("Headset Amp Right", 36, 9, 0, &hramp_ctl),
-	SND_SOC_DAPM_SWITCH("Line out Amp Left", 36, 16, 0, &llamp_ctl),
-	SND_SOC_DAPM_SWITCH("Line out Amp Right", 36, 15, 0, &lramp_ctl),
-	SND_SOC_DAPM_DAC("DAC", "Playback", 36, 22, 0),
-	SND_SOC_DAPM_PGA("DAC PGA", 37, 5, 0, NULL, 0),
+	SND_SOC_DAPM_SWITCH("Headset Amp Left", MC13783_AUDIO_RX0, 10, 0,
+			&hlamp_ctl),
+	SND_SOC_DAPM_SWITCH("Headset Amp Right", MC13783_AUDIO_RX0, 9, 0,
+			&hramp_ctl),
+	SND_SOC_DAPM_SWITCH("Line out Amp Left", MC13783_AUDIO_RX0, 16, 0,
+			&llamp_ctl),
+	SND_SOC_DAPM_SWITCH("Line out Amp Right", MC13783_AUDIO_RX0, 15, 0,
+			&lramp_ctl),
+	SND_SOC_DAPM_DAC("DAC", "Playback", MC13783_AUDIO_RX0, 22, 0),
+	SND_SOC_DAPM_PGA("DAC PGA", MC13783_AUDIO_RX1, 5, 0, NULL, 0),
 };
 
 static struct snd_soc_dapm_route mc13783_routes[] = {
@@ -581,8 +585,6 @@
 {
 	struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec);
 
-	codec->control_data = priv->mc13xxx;
-
 	mc13xxx_lock(priv->mc13xxx);
 
 	/* these are the reset values */
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c
index 8d717f4..0935bfe 100644
--- a/sound/soc/codecs/sta32x.c
+++ b/sound/soc/codecs/sta32x.c
@@ -24,6 +24,7 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
+#include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
@@ -55,12 +56,50 @@
 	 SNDRV_PCM_FMTBIT_S32_LE  | SNDRV_PCM_FMTBIT_S32_BE)
 
 /* Power-up register defaults */
-static const u8 sta32x_regs[STA32X_REGISTER_COUNT] = {
-	0x63, 0x80, 0xc2, 0x40, 0xc2, 0x5c, 0x10, 0xff, 0x60, 0x60,
-	0x60, 0x80, 0x00, 0x00, 0x00, 0x40, 0x80, 0x77, 0x6a, 0x69,
-	0x6a, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
-	0xc0, 0xf3, 0x33, 0x00, 0x0c,
+static const struct reg_default sta32x_regs[] = {
+	{  0x0, 0x63 },
+	{  0x1, 0x80 },
+	{  0x2, 0xc2 },
+	{  0x3, 0x40 },
+	{  0x4, 0xc2 },
+	{  0x5, 0x5c },
+	{  0x6, 0x10 },
+	{  0x7, 0xff },
+	{  0x8, 0x60 },
+	{  0x9, 0x60 },
+	{  0xa, 0x60 },
+	{  0xb, 0x80 },
+	{  0xc, 0x00 },
+	{  0xd, 0x00 },
+	{  0xe, 0x00 },
+	{  0xf, 0x40 },
+	{ 0x10, 0x80 },
+	{ 0x11, 0x77 },
+	{ 0x12, 0x6a },
+	{ 0x13, 0x69 },
+	{ 0x14, 0x6a },
+	{ 0x15, 0x69 },
+	{ 0x16, 0x00 },
+	{ 0x17, 0x00 },
+	{ 0x18, 0x00 },
+	{ 0x19, 0x00 },
+	{ 0x1a, 0x00 },
+	{ 0x1b, 0x00 },
+	{ 0x1c, 0x00 },
+	{ 0x1d, 0x00 },
+	{ 0x1e, 0x00 },
+	{ 0x1f, 0x00 },
+	{ 0x20, 0x00 },
+	{ 0x21, 0x00 },
+	{ 0x22, 0x00 },
+	{ 0x23, 0x00 },
+	{ 0x24, 0x00 },
+	{ 0x25, 0x00 },
+	{ 0x26, 0x00 },
+	{ 0x27, 0x2d },
+	{ 0x28, 0xc0 },
+	{ 0x2b, 0x00 },
+	{ 0x2c, 0x0c },
 };
 
 /* regulator power supply names */
@@ -72,6 +111,7 @@
 
 /* codec private data */
 struct sta32x_priv {
+	struct regmap *regmap;
 	struct regulator_bulk_data supplies[ARRAY_SIZE(sta32x_supply_names)];
 	struct snd_soc_codec *codec;
 	struct sta32x_platform_data *pdata;
@@ -291,17 +331,15 @@
 
 static int sta32x_cache_sync(struct snd_soc_codec *codec)
 {
+	struct sta32x_priv *sta32x = codec->control_data;
 	unsigned int mute;
 	int rc;
 
-	if (!codec->cache_sync)
-		return 0;
-
 	/* mute during register sync */
 	mute = snd_soc_read(codec, STA32X_MMUTE);
 	snd_soc_write(codec, STA32X_MMUTE, mute | STA32X_MMUTE_MMUTE);
 	sta32x_sync_coef_shadow(codec);
-	rc = snd_soc_cache_sync(codec);
+	rc = regcache_sync(sta32x->regmap);
 	snd_soc_write(codec, STA32X_MMUTE, mute);
 	return rc;
 }
@@ -316,11 +354,11 @@
 
 	/* check if sta32x has reset itself */
 	confa_cached = snd_soc_read(codec, STA32X_CONFA);
-	codec->cache_bypass = 1;
+	regcache_cache_bypass(sta32x->regmap, true);
 	confa = snd_soc_read(codec, STA32X_CONFA);
-	codec->cache_bypass = 0;
+	regcache_cache_bypass(sta32x->regmap, false);
 	if (confa != confa_cached) {
-		codec->cache_sync = 1;
+		regcache_mark_dirty(sta32x->regmap);
 		sta32x_cache_sync(codec);
 	}
 
@@ -825,31 +863,21 @@
 	sta32x->codec = codec;
 	sta32x->pdata = dev_get_platdata(codec->dev);
 
-	/* regulators */
-	for (i = 0; i < ARRAY_SIZE(sta32x->supplies); i++)
-		sta32x->supplies[i].supply = sta32x_supply_names[i];
-
-	ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(sta32x->supplies),
-				 sta32x->supplies);
-	if (ret != 0) {
-		dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
-		goto err;
-	}
-
 	ret = regulator_bulk_enable(ARRAY_SIZE(sta32x->supplies),
 				    sta32x->supplies);
 	if (ret != 0) {
 		dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
-		goto err_get;
+		return ret;
 	}
 
 	/* Tell ASoC what kind of I/O to use to read the registers.  ASoC will
 	 * then do the I2C transactions itself.
 	 */
-	ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C);
+	codec->control_data = sta32x->regmap;
+	ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
 	if (ret < 0) {
 		dev_err(codec->dev, "failed to set cache I/O (ret=%i)\n", ret);
-		return ret;
+		goto err;
 	}
 
 	/* Chip documentation explicitly requires that the reset values
@@ -858,13 +886,15 @@
 	 * so the write to the these registers are suppressed by the cache
 	 * restore code when it skips writes of default registers.
 	 */
-	snd_soc_cache_write(codec, STA32X_CONFC, 0xc2);
-	snd_soc_cache_write(codec, STA32X_CONFE, 0xc2);
-	snd_soc_cache_write(codec, STA32X_CONFF, 0x5c);
-	snd_soc_cache_write(codec, STA32X_MMUTE, 0x10);
-	snd_soc_cache_write(codec, STA32X_AUTO1, 0x60);
-	snd_soc_cache_write(codec, STA32X_AUTO3, 0x00);
-	snd_soc_cache_write(codec, STA32X_C3CFG, 0x40);
+	regcache_cache_only(sta32x->regmap, true);
+	snd_soc_write(codec, STA32X_CONFC, 0xc2);
+	snd_soc_write(codec, STA32X_CONFE, 0xc2);
+	snd_soc_write(codec, STA32X_CONFF, 0x5c);
+	snd_soc_write(codec, STA32X_MMUTE, 0x10);
+	snd_soc_write(codec, STA32X_AUTO1, 0x60);
+	snd_soc_write(codec, STA32X_AUTO3, 0x00);
+	snd_soc_write(codec, STA32X_C3CFG, 0x40);
+	regcache_cache_only(sta32x->regmap, false);
 
 	/* set thermal warning adjustment and recovery */
 	if (!(sta32x->pdata->thermal_conf & STA32X_THERMAL_ADJUSTMENT_ENABLE))
@@ -915,9 +945,8 @@
 
 	return 0;
 
-err_get:
-	regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
 err:
+	regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
 	return ret;
 }
 
@@ -928,13 +957,11 @@
 	sta32x_watchdog_stop(sta32x);
 	sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF);
 	regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
-	regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies);
 
 	return 0;
 }
 
-static int sta32x_reg_is_volatile(struct snd_soc_codec *codec,
-				  unsigned int reg)
+static bool sta32x_reg_is_volatile(struct device *dev, unsigned int reg)
 {
 	switch (reg) {
 	case STA32X_CONFA ... STA32X_L2ATRT:
@@ -949,10 +976,6 @@
 	.remove =		sta32x_remove,
 	.suspend =		sta32x_suspend,
 	.resume =		sta32x_resume,
-	.reg_cache_size =	STA32X_REGISTER_COUNT,
-	.reg_word_size =	sizeof(u8),
-	.reg_cache_default =	sta32x_regs,
-	.volatile_register =	sta32x_reg_is_volatile,
 	.set_bias_level =	sta32x_set_bias_level,
 	.controls =		sta32x_snd_controls,
 	.num_controls =		ARRAY_SIZE(sta32x_snd_controls),
@@ -962,17 +985,45 @@
 	.num_dapm_routes =	ARRAY_SIZE(sta32x_dapm_routes),
 };
 
+static const struct regmap_config sta32x_regmap = {
+	.reg_bits =		8,
+	.val_bits =		8,
+	.max_register =		STA32X_FDRC2,
+	.reg_defaults =		sta32x_regs,
+	.num_reg_defaults =	ARRAY_SIZE(sta32x_regs),
+	.cache_type =		REGCACHE_RBTREE,
+	.volatile_reg =		sta32x_reg_is_volatile,
+};
+
 static __devinit int sta32x_i2c_probe(struct i2c_client *i2c,
 				      const struct i2c_device_id *id)
 {
 	struct sta32x_priv *sta32x;
-	int ret;
+	int ret, i;
 
 	sta32x = devm_kzalloc(&i2c->dev, sizeof(struct sta32x_priv),
 			      GFP_KERNEL);
 	if (!sta32x)
 		return -ENOMEM;
 
+	/* regulators */
+	for (i = 0; i < ARRAY_SIZE(sta32x->supplies); i++)
+		sta32x->supplies[i].supply = sta32x_supply_names[i];
+
+	ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(sta32x->supplies),
+				      sta32x->supplies);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
+		return ret;
+	}
+
+	sta32x->regmap = devm_regmap_init_i2c(i2c, &sta32x_regmap);
+	if (IS_ERR(sta32x->regmap)) {
+		ret = PTR_ERR(sta32x->regmap);
+		dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret);
+		return ret;
+	}
+
 	i2c_set_clientdata(i2c, sta32x);
 
 	ret = snd_soc_register_codec(&i2c->dev, &sta32x_codec, &sta32x_dai, 1);
@@ -1006,17 +1057,7 @@
 	.id_table = sta32x_i2c_id,
 };
 
-static int __init sta32x_init(void)
-{
-	return i2c_add_driver(&sta32x_i2c_driver);
-}
-module_init(sta32x_init);
-
-static void __exit sta32x_exit(void)
-{
-	i2c_del_driver(&sta32x_i2c_driver);
-}
-module_exit(sta32x_exit);
+module_i2c_driver(sta32x_i2c_driver);
 
 MODULE_DESCRIPTION("ASoC STA32X driver");
 MODULE_AUTHOR("Johannes Stezenbach <js@sig21.net>");
diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c
index 0c225cd..9e31448 100644
--- a/sound/soc/codecs/sta529.c
+++ b/sound/soc/codecs/sta529.c
@@ -358,7 +358,7 @@
 	return 0;
 }
 
-struct snd_soc_codec_driver sta529_codec_driver = {
+static const struct snd_soc_codec_driver sta529_codec_driver = {
 	.probe = sta529_probe,
 	.remove = sta529_remove,
 	.set_bias_level = sta529_set_bias_level,
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index 33c0f3d..982e437 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -340,7 +340,6 @@
 
 	printk(KERN_INFO "STAC9766 SoC Audio Codec %s\n", STAC9766_VERSION);
 
-	codec->control_data = codec;	/* we don't use regmap! */
 	ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
 	if (ret < 0)
 		goto codec_err;
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index 85944e9..b1f6982 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -444,14 +444,4 @@
 	.remove = aic26_spi_remove,
 };
 
-static int __init aic26_init(void)
-{
-	return spi_register_driver(&aic26_spi);
-}
-module_init(aic26_init);
-
-static void __exit aic26_exit(void)
-{
-	spi_unregister_driver(&aic26_spi);
-}
-module_exit(aic26_exit);
+module_spi_driver(aic26_spi);
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
index b0a73d3..f230292 100644
--- a/sound/soc/codecs/tlv320aic32x4.c
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -746,24 +746,7 @@
 	.id_table = aic32x4_i2c_id,
 };
 
-static int __init aic32x4_modinit(void)
-{
-	int ret = 0;
-
-	ret = i2c_add_driver(&aic32x4_i2c_driver);
-	if (ret != 0) {
-		printk(KERN_ERR "Failed to register aic32x4 I2C driver: %d\n",
-		       ret);
-	}
-	return ret;
-}
-module_init(aic32x4_modinit);
-
-static void __exit aic32x4_exit(void)
-{
-	i2c_del_driver(&aic32x4_i2c_driver);
-}
-module_exit(aic32x4_exit);
+module_i2c_driver(aic32x4_i2c_driver);
 
 MODULE_DESCRIPTION("ASoC tlv320aic32x4 codec driver");
 MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>");
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index dc78f5a..5708a97 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -40,6 +40,7 @@
 #include <linux/i2c.h>
 #include <linux/gpio.h>
 #include <linux/regulator/consumer.h>
+#include <linux/of_gpio.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -1457,6 +1458,8 @@
 {
 	struct aic3x_pdata *pdata = i2c->dev.platform_data;
 	struct aic3x_priv *aic3x;
+	struct aic3x_setup_data *ai3x_setup;
+	struct device_node *np = i2c->dev.of_node;
 	int ret;
 
 	aic3x = devm_kzalloc(&i2c->dev, sizeof(struct aic3x_priv), GFP_KERNEL);
@@ -1471,6 +1474,25 @@
 	if (pdata) {
 		aic3x->gpio_reset = pdata->gpio_reset;
 		aic3x->setup = pdata->setup;
+	} else if (np) {
+		ai3x_setup = devm_kzalloc(&i2c->dev, sizeof(*ai3x_setup),
+								GFP_KERNEL);
+		if (ai3x_setup == NULL) {
+			dev_err(&i2c->dev, "failed to create private data\n");
+			return -ENOMEM;
+		}
+
+		ret = of_get_named_gpio(np, "gpio-reset", 0);
+		if (ret >= 0)
+			aic3x->gpio_reset = ret;
+		else
+			aic3x->gpio_reset = -1;
+
+		if (of_property_read_u32_array(np, "ai3x-gpio-func",
+					ai3x_setup->gpio_func, 2) >= 0) {
+			aic3x->setup = ai3x_setup;
+		}
+
 	} else {
 		aic3x->gpio_reset = -1;
 	}
@@ -1488,34 +1510,27 @@
 	return 0;
 }
 
+#if defined(CONFIG_OF)
+static const struct of_device_id tlv320aic3x_of_match[] = {
+	{ .compatible = "ti,tlv320aic3x", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, tlv320aic3x_of_match);
+#endif
+
 /* machine i2c codec control layer */
 static struct i2c_driver aic3x_i2c_driver = {
 	.driver = {
 		.name = "tlv320aic3x-codec",
 		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(tlv320aic3x_of_match),
 	},
 	.probe	= aic3x_i2c_probe,
 	.remove = aic3x_i2c_remove,
 	.id_table = aic3x_i2c_id,
 };
 
-static int __init aic3x_modinit(void)
-{
-	int ret = 0;
-	ret = i2c_add_driver(&aic3x_i2c_driver);
-	if (ret != 0) {
-		printk(KERN_ERR "Failed to register TLV320AIC3x I2C driver: %d\n",
-		       ret);
-	}
-	return ret;
-}
-module_init(aic3x_modinit);
-
-static void __exit aic3x_exit(void)
-{
-	i2c_del_driver(&aic3x_i2c_driver);
-}
-module_exit(aic3x_exit);
+module_i2c_driver(aic3x_i2c_driver);
 
 MODULE_DESCRIPTION("ASoC TLV320AIC3X codec driver");
 MODULE_AUTHOR("Vladimir Barinov");
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 0dd4107..d2e16c5 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -1621,24 +1621,7 @@
 	.id_table	= tlv320dac33_i2c_id,
 };
 
-static int __init dac33_module_init(void)
-{
-	int r;
-	r = i2c_add_driver(&tlv320dac33_i2c_driver);
-	if (r < 0) {
-		printk(KERN_ERR "DAC33: driver registration failed\n");
-		return r;
-	}
-	return 0;
-}
-module_init(dac33_module_init);
-
-static void __exit dac33_module_exit(void)
-{
-	i2c_del_driver(&tlv320dac33_i2c_driver);
-}
-module_exit(dac33_module_exit);
-
+module_i2c_driver(tlv320dac33_i2c_driver);
 
 MODULE_DESCRIPTION("ASoC TLV320DAC33 codec driver");
 MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 6fe4aa3..565ff39 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -487,19 +487,8 @@
 	.id_table = tpa6130a2_id,
 };
 
-static int __init tpa6130a2_init(void)
-{
-	return i2c_add_driver(&tpa6130a2_i2c_driver);
-}
-
-static void __exit tpa6130a2_exit(void)
-{
-	i2c_del_driver(&tpa6130a2_i2c_driver);
-}
+module_i2c_driver(tpa6130a2_i2c_driver);
 
 MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
 MODULE_DESCRIPTION("TPA6130A2 Headphone amplifier driver");
 MODULE_LICENSE("GPL");
-
-module_init(tpa6130a2_init);
-module_exit(tpa6130a2_exit);
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 391fcfc..e7f6089 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -26,8 +26,11 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
 #include <linux/i2c/twl.h>
 #include <linux/slab.h>
+#include <linux/gpio.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -152,8 +155,7 @@
 	u8 predrivel_enabled, predriver_enabled;
 	u8 carkitl_enabled, carkitr_enabled;
 
-	/* Delay needed after enabling the digimic interface */
-	unsigned int digimic_delay;
+	struct twl4030_codec_data *pdata;
 };
 
 /*
@@ -295,13 +297,73 @@
 
 }
 
-static void twl4030_init_chip(struct snd_soc_codec *codec)
+static void twl4030_setup_pdata_of(struct twl4030_codec_data *pdata,
+				   struct device_node *node)
+{
+	int value;
+
+	of_property_read_u32(node, "ti,digimic_delay",
+			     &pdata->digimic_delay);
+	of_property_read_u32(node, "ti,ramp_delay_value",
+			     &pdata->ramp_delay_value);
+	of_property_read_u32(node, "ti,offset_cncl_path",
+			     &pdata->offset_cncl_path);
+	if (!of_property_read_u32(node, "ti,hs_extmute", &value))
+		pdata->hs_extmute = value;
+
+	pdata->hs_extmute_gpio = of_get_named_gpio(node,
+						   "ti,hs_extmute_gpio", 0);
+	if (gpio_is_valid(pdata->hs_extmute_gpio))
+		pdata->hs_extmute = 1;
+}
+
+static struct twl4030_codec_data *twl4030_get_pdata(struct snd_soc_codec *codec)
 {
 	struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev);
+	struct device_node *twl4030_codec_node = NULL;
+
+	twl4030_codec_node = of_find_node_by_name(codec->dev->parent->of_node,
+						  "codec");
+
+	if (!pdata && twl4030_codec_node) {
+		pdata = devm_kzalloc(codec->dev,
+				     sizeof(struct twl4030_codec_data),
+				     GFP_KERNEL);
+		if (!pdata) {
+			dev_err(codec->dev, "Can not allocate memory\n");
+			return NULL;
+		}
+		twl4030_setup_pdata_of(pdata, twl4030_codec_node);
+	}
+
+	return pdata;
+}
+
+static void twl4030_init_chip(struct snd_soc_codec *codec)
+{
+	struct twl4030_codec_data *pdata;
 	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
 	u8 reg, byte;
 	int i = 0;
 
+	pdata = twl4030_get_pdata(codec);
+
+	if (pdata && pdata->hs_extmute &&
+	    gpio_is_valid(pdata->hs_extmute_gpio)) {
+		int ret;
+
+		if (!pdata->hs_extmute_gpio)
+			dev_warn(codec->dev,
+				 "Extmute GPIO is 0 is this correct?\n");
+
+		ret = gpio_request_one(pdata->hs_extmute_gpio,
+				       GPIOF_OUT_INIT_LOW, "hs_extmute");
+		if (ret) {
+			dev_err(codec->dev, "Failed to get hs_extmute GPIO\n");
+			pdata->hs_extmute_gpio = -1;
+		}
+	}
+
 	/* Check defaults, if instructed before anything else */
 	if (pdata && pdata->check_defaults)
 		twl4030_check_defaults(codec);
@@ -331,7 +393,7 @@
 	if (!pdata)
 		return;
 
-	twl4030->digimic_delay = pdata->digimic_delay;
+	twl4030->pdata = pdata;
 
 	reg = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
 	reg &= ~TWL4030_RAMP_DELAY;
@@ -732,9 +794,9 @@
 
 static void headset_ramp(struct snd_soc_codec *codec, int ramp)
 {
-	struct twl4030_codec_data *pdata = codec->dev->platform_data;
 	unsigned char hs_gain, hs_pop;
 	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+	struct twl4030_codec_data *pdata = twl4030->pdata;
 	/* Base values for ramp delay calculation: 2^19 - 2^26 */
 	unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304,
 				    8388608, 16777216, 33554432, 67108864};
@@ -748,8 +810,8 @@
 	/* Enable external mute control, this dramatically reduces
 	 * the pop-noise */
 	if (pdata && pdata->hs_extmute) {
-		if (pdata->set_hs_extmute) {
-			pdata->set_hs_extmute(1);
+		if (gpio_is_valid(pdata->hs_extmute_gpio)) {
+			gpio_set_value(pdata->hs_extmute_gpio, 1);
 		} else {
 			hs_pop |= TWL4030_EXTMUTE;
 			twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
@@ -786,8 +848,8 @@
 
 	/* Disable external mute */
 	if (pdata && pdata->hs_extmute) {
-		if (pdata->set_hs_extmute) {
-			pdata->set_hs_extmute(0);
+		if (gpio_is_valid(pdata->hs_extmute_gpio)) {
+			gpio_set_value(pdata->hs_extmute_gpio, 0);
 		} else {
 			hs_pop &= ~TWL4030_EXTMUTE;
 			twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
@@ -847,9 +909,10 @@
 		struct snd_kcontrol *kcontrol, int event)
 {
 	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
+	struct twl4030_codec_data *pdata = twl4030->pdata;
 
-	if (twl4030->digimic_delay)
-		twl4030_wait_ms(twl4030->digimic_delay);
+	if (pdata && pdata->digimic_delay)
+		twl4030_wait_ms(pdata->digimic_delay);
 	return 0;
 }
 
@@ -999,7 +1062,7 @@
 	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
 	unsigned short val;
-	unsigned short mask, bitmask;
+	unsigned short mask;
 
 	if (twl4030->configured) {
 		dev_err(codec->dev,
@@ -1007,18 +1070,16 @@
 		return -EBUSY;
 	}
 
-	for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
-		;
 	if (ucontrol->value.enumerated.item[0] > e->max - 1)
 		return -EINVAL;
 
 	val = ucontrol->value.enumerated.item[0] << e->shift_l;
-	mask = (bitmask - 1) << e->shift_l;
+	mask = e->mask << e->shift_l;
 	if (e->shift_l != e->shift_r) {
 		if (ucontrol->value.enumerated.item[1] > e->max - 1)
 			return -EINVAL;
 		val |= ucontrol->value.enumerated.item[1] << e->shift_r;
-		mask |= (bitmask - 1) << e->shift_r;
+		mask |= e->mask << e->shift_r;
 	}
 
 	return snd_soc_update_bits(codec, e->reg, mask, val);
@@ -1239,16 +1300,11 @@
 	SND_SOC_DAPM_OUTPUT("Virtual Voice OUT"),
 
 	/* DACs */
-	SND_SOC_DAPM_DAC("DAC Right1", "Right Front HiFi Playback",
-			SND_SOC_NOPM, 0, 0),
-	SND_SOC_DAPM_DAC("DAC Left1", "Left Front HiFi Playback",
-			SND_SOC_NOPM, 0, 0),
-	SND_SOC_DAPM_DAC("DAC Right2", "Right Rear HiFi Playback",
-			SND_SOC_NOPM, 0, 0),
-	SND_SOC_DAPM_DAC("DAC Left2", "Left Rear HiFi Playback",
-			SND_SOC_NOPM, 0, 0),
-	SND_SOC_DAPM_DAC("DAC Voice", "Voice Playback",
-			SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_DAC("DAC Right1", NULL, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_DAC("DAC Left1", NULL, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_DAC("DAC Right2", NULL, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_DAC("DAC Left2", NULL, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_DAC("DAC Voice", NULL, SND_SOC_NOPM, 0, 0),
 
 	/* Analog bypasses */
 	SND_SOC_DAPM_SWITCH("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0,
@@ -1377,14 +1433,10 @@
 
 	/* Introducing four virtual ADC, since TWL4030 have four channel for
 	   capture */
-	SND_SOC_DAPM_ADC("ADC Virtual Left1", "Left Front Capture",
-		SND_SOC_NOPM, 0, 0),
-	SND_SOC_DAPM_ADC("ADC Virtual Right1", "Right Front Capture",
-		SND_SOC_NOPM, 0, 0),
-	SND_SOC_DAPM_ADC("ADC Virtual Left2", "Left Rear Capture",
-		SND_SOC_NOPM, 0, 0),
-	SND_SOC_DAPM_ADC("ADC Virtual Right2", "Right Rear Capture",
-		SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_ADC("ADC Virtual Left1", NULL, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_ADC("ADC Virtual Right1", NULL, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_ADC("ADC Virtual Left2", NULL, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_ADC("ADC Virtual Right2", NULL, SND_SOC_NOPM, 0, 0),
 
 	/* Analog/Digital mic path selection.
 	   TX1 Left/Right: either analog Left/Right or Digimic0
@@ -1428,6 +1480,23 @@
 };
 
 static const struct snd_soc_dapm_route intercon[] = {
+	/* Stream -> DAC mapping */
+	{"DAC Right1", NULL, "HiFi Playback"},
+	{"DAC Left1", NULL, "HiFi Playback"},
+	{"DAC Right2", NULL, "HiFi Playback"},
+	{"DAC Left2", NULL, "HiFi Playback"},
+	{"DAC Voice", NULL, "Voice Playback"},
+
+	/* ADC -> Stream mapping */
+	{"HiFi Capture", NULL, "ADC Virtual Left1"},
+	{"HiFi Capture", NULL, "ADC Virtual Right1"},
+	{"HiFi Capture", NULL, "ADC Virtual Left2"},
+	{"HiFi Capture", NULL, "ADC Virtual Right2"},
+	{"Voice Capture", NULL, "ADC Virtual Left1"},
+	{"Voice Capture", NULL, "ADC Virtual Right1"},
+	{"Voice Capture", NULL, "ADC Virtual Left2"},
+	{"Voice Capture", NULL, "ADC Virtual Right2"},
+
 	{"Digital L1 Playback Mixer", NULL, "DAC Left1"},
 	{"Digital R1 Playback Mixer", NULL, "DAC Right1"},
 	{"Digital L2 Playback Mixer", NULL, "DAC Left2"},
@@ -2172,7 +2241,7 @@
 		.formats = TWL4030_FORMATS,
 		.sig_bits = 24,},
 	.capture = {
-		.stream_name = "Capture",
+		.stream_name = "HiFi Capture",
 		.channels_min = 2,
 		.channels_max = 4,
 		.rates = TWL4030_RATES,
@@ -2189,7 +2258,7 @@
 		.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
 		.formats = SNDRV_PCM_FMTBIT_S16_LE,},
 	.capture = {
-		.stream_name = "Capture",
+		.stream_name = "Voice Capture",
 		.channels_min = 1,
 		.channels_max = 2,
 		.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
@@ -2214,7 +2283,8 @@
 {
 	struct twl4030_priv *twl4030;
 
-	twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL);
+	twl4030 = devm_kzalloc(codec->dev, sizeof(struct twl4030_priv),
+			       GFP_KERNEL);
 	if (twl4030 == NULL) {
 		dev_err(codec->dev, "Can not allocate memory\n");
 		return -ENOMEM;
@@ -2231,11 +2301,15 @@
 static int twl4030_soc_remove(struct snd_soc_codec *codec)
 {
 	struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
+	struct twl4030_codec_data *pdata = twl4030->pdata;
 
 	/* Reset registers to their chip default before leaving */
 	twl4030_reset_registers(codec);
 	twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
-	kfree(twl4030);
+
+	if (pdata && pdata->hs_extmute && gpio_is_valid(pdata->hs_extmute_gpio))
+		gpio_free(pdata->hs_extmute_gpio);
+
 	return 0;
 }
 
@@ -2262,13 +2336,6 @@
 
 static int __devinit twl4030_codec_probe(struct platform_device *pdev)
 {
-	struct twl4030_codec_data *pdata = pdev->dev.platform_data;
-
-	if (!pdata) {
-		dev_err(&pdev->dev, "platform_data is missing\n");
-		return -EINVAL;
-	}
-
 	return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_twl4030,
 			twl4030_dai, ARRAY_SIZE(twl4030_dai));
 }
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index c084c54..e8f97af 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -727,10 +727,8 @@
 			TWL6040_REG_MICRCTL, 1, 0, NULL, 0),
 
 	/* ADCs */
-	SND_SOC_DAPM_ADC("ADC Left", "Left Front Capture",
-			TWL6040_REG_MICLCTL, 2, 0),
-	SND_SOC_DAPM_ADC("ADC Right", "Right Front Capture",
-			TWL6040_REG_MICRCTL, 2, 0),
+	SND_SOC_DAPM_ADC("ADC Left", NULL, TWL6040_REG_MICLCTL, 2, 0),
+	SND_SOC_DAPM_ADC("ADC Right", NULL, TWL6040_REG_MICRCTL, 2, 0),
 
 	/* Microphone bias */
 	SND_SOC_DAPM_SUPPLY("Headset Mic Bias",
@@ -743,15 +741,12 @@
 			    TWL6040_REG_DMICBCTL, 4, 0, NULL, 0),
 
 	/* DACs */
-	SND_SOC_DAPM_DAC("HSDAC Left", "Headset Playback", SND_SOC_NOPM, 0, 0),
-	SND_SOC_DAPM_DAC("HSDAC Right", "Headset Playback", SND_SOC_NOPM, 0, 0),
-	SND_SOC_DAPM_DAC("HFDAC Left", "Handsfree Playback",
-			 TWL6040_REG_HFLCTL, 0, 0),
-	SND_SOC_DAPM_DAC("HFDAC Right", "Handsfree Playback",
-			 TWL6040_REG_HFRCTL, 0, 0),
+	SND_SOC_DAPM_DAC("HSDAC Left", NULL, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_DAC("HSDAC Right", NULL, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_DAC("HFDAC Left", NULL, TWL6040_REG_HFLCTL, 0, 0),
+	SND_SOC_DAPM_DAC("HFDAC Right", NULL, TWL6040_REG_HFRCTL, 0, 0),
 	/* Virtual DAC for vibra path (DL4 channel) */
-	SND_SOC_DAPM_DAC("VIBRA DAC", "Vibra Playback",
-			SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_DAC("VIBRA DAC", NULL, SND_SOC_NOPM, 0, 0),
 
 	SND_SOC_DAPM_MUX("Handsfree Left Playback",
 			SND_SOC_NOPM, 0, 0, &hfl_mux_controls),
@@ -810,6 +805,26 @@
 };
 
 static const struct snd_soc_dapm_route intercon[] = {
+	/* Stream -> DAC mapping */
+	{"HSDAC Left", NULL, "Legacy Playback"},
+	{"HSDAC Left", NULL, "Headset Playback"},
+	{"HSDAC Right", NULL, "Legacy Playback"},
+	{"HSDAC Right", NULL, "Headset Playback"},
+
+	{"HFDAC Left", NULL, "Legacy Playback"},
+	{"HFDAC Left", NULL, "Handsfree Playback"},
+	{"HFDAC Right", NULL, "Legacy Playback"},
+	{"HFDAC Right", NULL, "Handsfree Playback"},
+
+	{"VIBRA DAC", NULL, "Legacy Playback"},
+	{"VIBRA DAC", NULL, "Vibra Playback"},
+
+	/* ADC -> Stream mapping */
+	{"ADC Left", NULL, "Legacy Capture"},
+	{"ADC Left", NULL, "Capture"},
+	{"ADC Right", NULL, "Legacy Capture"},
+	{"ADC Right", NULL, "Capture"},
+
 	/* Capture path */
 	{"Analog Left Capture Route", "Headset Mic", "HSMIC"},
 	{"Analog Left Capture Route", "Main Mic", "MAINMIC"},
@@ -1028,14 +1043,14 @@
 {
 	.name = "twl6040-legacy",
 	.playback = {
-		.stream_name = "Playback",
+		.stream_name = "Legacy Playback",
 		.channels_min = 1,
 		.channels_max = 5,
 		.rates = TWL6040_RATES,
 		.formats = TWL6040_FORMATS,
 	},
 	.capture = {
-		.stream_name = "Capture",
+		.stream_name = "Legacy Capture",
 		.channels_min = 1,
 		.channels_max = 2,
 		.rates = TWL6040_RATES,
diff --git a/sound/soc/codecs/wm0010.c b/sound/soc/codecs/wm0010.c
new file mode 100644
index 0000000..99afc00
--- /dev/null
+++ b/sound/soc/codecs/wm0010.c
@@ -0,0 +1,940 @@
+/*
+ * wm0010.c  --  WM0010 DSP Driver
+ *
+ * Copyright 2012 Wolfson Microelectronics PLC.
+ *
+ * Authors: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *          Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
+ *          Scott Ling <sl@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/irqreturn.h>
+#include <linux/init.h>
+#include <linux/spi/spi.h>
+#include <linux/firmware.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+
+#include <sound/soc.h>
+#include <sound/wm0010.h>
+
+#define DEVICE_ID_WM0010	10
+
+enum dfw_cmd {
+	DFW_CMD_FUSE = 0x01,
+	DFW_CMD_CODE_HDR,
+	DFW_CMD_CODE_DATA,
+	DFW_CMD_PLL,
+	DFW_CMD_INFO = 0xff
+};
+
+struct dfw_binrec {
+	u8 command;
+	u32 length:24;
+	u32 address;
+	uint8_t data[0];
+} __packed;
+
+struct dfw_pllrec {
+	u8 command;
+	u32 length:24;
+	u32 address;
+	u32 clkctrl1;
+	u32 clkctrl2;
+	u32 clkctrl3;
+	u32 ldetctrl;
+	u32 uart_div;
+	u32 spi_div;
+} __packed;
+
+static struct pll_clock_map {
+	int max_sysclk;
+	int max_pll_spi_speed;
+	u32 pll_clkctrl1;
+} pll_clock_map[] = {			   /* Dividers */
+	{ 22000000, 26000000, 0x00201f11 }, /* 2,32,2  */
+	{ 18000000, 26000000, 0x00203f21 }, /* 2,64,4  */
+	{ 14000000, 26000000, 0x00202620 }, /* 1,39,4  */
+	{ 10000000, 22000000, 0x00203120 }, /* 1,50,4  */
+	{  6500000, 22000000, 0x00204520 }, /* 1,70,4  */
+	{  5500000, 22000000, 0x00103f10 }, /* 1,64,2  */
+};
+
+enum wm0010_state {
+	WM0010_POWER_OFF,
+	WM0010_OUT_OF_RESET,
+	WM0010_BOOTROM,
+	WM0010_STAGE2,
+	WM0010_FIRMWARE,
+};
+
+struct wm0010_priv {
+	struct snd_soc_codec *codec;
+
+	struct mutex lock;
+	struct device *dev;
+
+	struct wm0010_pdata pdata;
+
+	int gpio_reset;
+	int gpio_reset_value;
+
+	struct regulator_bulk_data core_supplies[2];
+	struct regulator *dbvdd;
+
+	int sysclk;
+
+	enum wm0010_state state;
+	bool boot_failed;
+	int boot_done;
+	bool ready;
+	bool pll_running;
+	int max_spi_freq;
+	int board_max_spi_speed;
+	u32 pll_clkctrl1;
+
+	spinlock_t irq_lock;
+	int irq;
+
+	struct completion boot_completion;
+};
+
+struct wm0010_spi_msg {
+	struct spi_message m;
+	struct spi_transfer t;
+	u8 *tx_buf;
+	u8 *rx_buf;
+	size_t len;
+};
+
+static const struct snd_soc_dapm_widget wm0010_dapm_widgets[] = {
+SND_SOC_DAPM_SUPPLY("CLKIN",  SND_SOC_NOPM, 0, 0, NULL, 0),
+};
+
+static const struct snd_soc_dapm_route wm0010_dapm_routes[] = {
+	{ "SDI2 Capture", NULL, "SDI1 Playback" },
+	{ "SDI1 Capture", NULL, "SDI2 Playback" },
+
+	{ "SDI1 Capture", NULL, "CLKIN" },
+	{ "SDI2 Capture", NULL, "CLKIN" },
+	{ "SDI1 Playback", NULL, "CLKIN" },
+	{ "SDI2 Playback", NULL, "CLKIN" },
+};
+
+static const char *wm0010_state_to_str(enum wm0010_state state)
+{
+	const char *state_to_str[] = {
+		"Power off",
+		"Out of reset",
+		"Boot ROM",
+		"Stage2",
+		"Firmware"
+	};
+
+	if (state < 0 || state >= ARRAY_SIZE(state_to_str))
+		return "null";
+	return state_to_str[state];
+}
+
+/* Called with wm0010->lock held */
+static void wm0010_halt(struct snd_soc_codec *codec)
+{
+	struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+	unsigned long flags;
+	enum wm0010_state state;
+
+	/* Fetch the wm0010 state */
+	spin_lock_irqsave(&wm0010->irq_lock, flags);
+	state = wm0010->state;
+	spin_unlock_irqrestore(&wm0010->irq_lock, flags);
+
+	switch (state) {
+	case WM0010_POWER_OFF:
+		/* If there's nothing to do, bail out */
+		return;
+	case WM0010_OUT_OF_RESET:
+	case WM0010_BOOTROM:
+	case WM0010_STAGE2:
+	case WM0010_FIRMWARE:
+		/* Remember to put chip back into reset */
+		gpio_set_value_cansleep(wm0010->gpio_reset,
+					wm0010->gpio_reset_value);
+		/* Disable the regulators */
+		regulator_disable(wm0010->dbvdd);
+		regulator_bulk_disable(ARRAY_SIZE(wm0010->core_supplies),
+				       wm0010->core_supplies);
+		break;
+	}
+
+	spin_lock_irqsave(&wm0010->irq_lock, flags);
+	wm0010->state = WM0010_POWER_OFF;
+	spin_unlock_irqrestore(&wm0010->irq_lock, flags);
+}
+
+struct wm0010_boot_xfer {
+	struct list_head list;
+	struct snd_soc_codec *codec;
+	struct completion *done;
+	struct spi_message m;
+	struct spi_transfer t;
+};
+
+/* Called with wm0010->lock held */
+static void wm0010_mark_boot_failure(struct wm0010_priv *wm0010)
+{
+	enum wm0010_state state;
+	unsigned long flags;
+
+	spin_lock_irqsave(&wm0010->irq_lock, flags);
+	state = wm0010->state;
+	spin_unlock_irqrestore(&wm0010->irq_lock, flags);
+
+	dev_err(wm0010->dev, "Failed to transition from `%s' state to `%s' state\n",
+		wm0010_state_to_str(state), wm0010_state_to_str(state + 1));
+
+	wm0010->boot_failed = true;
+}
+
+static void wm0010_boot_xfer_complete(void *data)
+{
+	struct wm0010_boot_xfer *xfer = data;
+	struct snd_soc_codec *codec = xfer->codec;
+	struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+	u32 *out32 = xfer->t.rx_buf;
+	int i;
+
+	if (xfer->m.status != 0) {
+		dev_err(codec->dev, "SPI transfer failed: %d\n",
+			xfer->m.status);
+		wm0010_mark_boot_failure(wm0010);
+		if (xfer->done)
+			complete(xfer->done);
+		return;
+	}
+
+	for (i = 0; i < xfer->t.len / 4; i++) {
+		dev_dbg(codec->dev, "%d: %04x\n", i, out32[i]);
+
+		switch (be32_to_cpu(out32[i])) {
+		case 0xe0e0e0e0:
+			dev_err(codec->dev,
+				"%d: ROM error reported in stage 2\n", i);
+			wm0010_mark_boot_failure(wm0010);
+			break;
+
+		case 0x55555555:
+			if (wm0010->boot_done == 0)
+				break;
+			dev_err(codec->dev,
+				"%d: ROM bootloader running in stage 2\n", i);
+			wm0010_mark_boot_failure(wm0010);
+			break;
+
+		case 0x0fed0000:
+			dev_dbg(codec->dev, "Stage2 loader running\n");
+			break;
+
+		case 0x0fed0007:
+			dev_dbg(codec->dev, "CODE_HDR packet received\n");
+			break;
+
+		case 0x0fed0008:
+			dev_dbg(codec->dev, "CODE_DATA packet received\n");
+			break;
+
+		case 0x0fed0009:
+			dev_dbg(codec->dev, "Download complete\n");
+			break;
+
+		case 0x0fed000c:
+			dev_dbg(codec->dev, "Application start\n");
+			break;
+
+		case 0x0fed000e:
+			dev_dbg(codec->dev, "PLL packet received\n");
+			wm0010->pll_running = true;
+			break;
+
+		case 0x0fed0025:
+			dev_err(codec->dev, "Device reports image too long\n");
+			wm0010_mark_boot_failure(wm0010);
+			break;
+
+		case 0x0fed002c:
+			dev_err(codec->dev, "Device reports bad SPI packet\n");
+			wm0010_mark_boot_failure(wm0010);
+			break;
+
+		case 0x0fed0031:
+			dev_err(codec->dev, "Device reports SPI read overflow\n");
+			wm0010_mark_boot_failure(wm0010);
+			break;
+
+		case 0x0fed0032:
+			dev_err(codec->dev, "Device reports SPI underclock\n");
+			wm0010_mark_boot_failure(wm0010);
+			break;
+
+		case 0x0fed0033:
+			dev_err(codec->dev, "Device reports bad header packet\n");
+			wm0010_mark_boot_failure(wm0010);
+			break;
+
+		case 0x0fed0034:
+			dev_err(codec->dev, "Device reports invalid packet type\n");
+			wm0010_mark_boot_failure(wm0010);
+			break;
+
+		case 0x0fed0035:
+			dev_err(codec->dev, "Device reports data before header error\n");
+			wm0010_mark_boot_failure(wm0010);
+			break;
+
+		case 0x0fed0038:
+			dev_err(codec->dev, "Device reports invalid PLL packet\n");
+			break;
+
+		case 0x0fed003a:
+			dev_err(codec->dev, "Device reports packet alignment error\n");
+			wm0010_mark_boot_failure(wm0010);
+			break;
+
+		default:
+			dev_err(codec->dev, "Unrecognised return 0x%x\n",
+			    be32_to_cpu(out32[i]));
+			wm0010_mark_boot_failure(wm0010);
+			break;
+		}
+
+		if (wm0010->boot_failed)
+			break;
+	}
+
+	wm0010->boot_done++;
+	if (xfer->done)
+		complete(xfer->done);
+}
+
+static void byte_swap_64(u64 *data_in, u64 *data_out, u32 len)
+{
+	int i;
+
+	for (i = 0; i < len / 8; i++)
+		data_out[i] = cpu_to_be64(le64_to_cpu(data_in[i]));
+}
+
+static int wm0010_boot(struct snd_soc_codec *codec)
+{
+	struct spi_device *spi = to_spi_device(codec->dev);
+	struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+	unsigned long flags;
+	struct list_head xfer_list;
+	struct wm0010_boot_xfer *xfer;
+	int ret;
+	struct completion done;
+	const struct firmware *fw;
+	const struct dfw_binrec *rec;
+	struct spi_message m;
+	struct spi_transfer t;
+	struct dfw_pllrec pll_rec;
+	u32 *img, *p;
+	u64 *img_swap;
+	u8 *out;
+	u32 len, offset;
+	int i;
+
+	spin_lock_irqsave(&wm0010->irq_lock, flags);
+	if (wm0010->state != WM0010_POWER_OFF)
+		dev_warn(wm0010->dev, "DSP already powered up!\n");
+	spin_unlock_irqrestore(&wm0010->irq_lock, flags);
+
+	if (wm0010->sysclk > 26000000) {
+		dev_err(codec->dev, "Max DSP clock frequency is 26MHz\n");
+		ret = -ECANCELED;
+		goto err;
+	}
+
+	INIT_LIST_HEAD(&xfer_list);
+
+	mutex_lock(&wm0010->lock);
+	wm0010->pll_running = false;
+
+	dev_dbg(codec->dev, "max_spi_freq: %d\n", wm0010->max_spi_freq);
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(wm0010->core_supplies),
+				    wm0010->core_supplies);
+	if (ret != 0) {
+		dev_err(&spi->dev, "Failed to enable core supplies: %d\n",
+			ret);
+		mutex_unlock(&wm0010->lock);
+		goto err;
+	}
+
+	ret = regulator_enable(wm0010->dbvdd);
+	if (ret != 0) {
+		dev_err(&spi->dev, "Failed to enable DBVDD: %d\n", ret);
+		goto err_core;
+	}
+
+	/* Release reset */
+	gpio_set_value_cansleep(wm0010->gpio_reset, !wm0010->gpio_reset_value);
+	spin_lock_irqsave(&wm0010->irq_lock, flags);
+	wm0010->state = WM0010_OUT_OF_RESET;
+	spin_unlock_irqrestore(&wm0010->irq_lock, flags);
+
+	/* First the bootloader */
+	ret = request_firmware(&fw, "wm0010_stage2.bin", codec->dev);
+	if (ret != 0) {
+		dev_err(codec->dev, "Failed to request stage2 loader: %d\n",
+			ret);
+		goto abort;
+	}
+
+	if (!wait_for_completion_timeout(&wm0010->boot_completion,
+					 msecs_to_jiffies(10)))
+		dev_err(codec->dev, "Failed to get interrupt from DSP\n");
+
+	spin_lock_irqsave(&wm0010->irq_lock, flags);
+	wm0010->state = WM0010_BOOTROM;
+	spin_unlock_irqrestore(&wm0010->irq_lock, flags);
+
+	dev_dbg(codec->dev, "Downloading %zu byte stage 2 loader\n", fw->size);
+
+	/* Copy to local buffer first as vmalloc causes problems for dma */
+	img = kzalloc(fw->size, GFP_KERNEL);
+	if (!img) {
+		dev_err(codec->dev, "Failed to allocate image buffer\n");
+		goto abort;
+	}
+
+	out = kzalloc(fw->size, GFP_KERNEL);
+	if (!out) {
+		dev_err(codec->dev, "Failed to allocate output buffer\n");
+		goto abort;
+	}
+
+	memcpy(img, &fw->data[0], fw->size);
+
+	spi_message_init(&m);
+	memset(&t, 0, sizeof(t));
+	t.rx_buf = out;
+	t.tx_buf = img;
+	t.len = fw->size;
+	t.bits_per_word = 8;
+	t.speed_hz = wm0010->sysclk / 10;
+	spi_message_add_tail(&t, &m);
+
+	dev_dbg(codec->dev, "Starting initial download at %dHz\n",
+		t.speed_hz);
+
+	ret = spi_sync(spi, &m);
+	if (ret != 0) {
+		dev_err(codec->dev, "Initial download failed: %d\n", ret);
+		goto abort;
+	}
+
+	/* Look for errors from the boot ROM */
+	for (i = 0; i < fw->size; i++) {
+		if (out[i] != 0x55) {
+			ret = -EBUSY;
+			dev_err(codec->dev, "Boot ROM error: %x in %d\n",
+				out[i], i);
+			wm0010_mark_boot_failure(wm0010);
+			goto abort;
+		}
+	}
+
+	release_firmware(fw);
+	kfree(img);
+	kfree(out);
+
+	if (!wait_for_completion_timeout(&wm0010->boot_completion,
+					 msecs_to_jiffies(10)))
+		dev_err(codec->dev, "Failed to get interrupt from DSP loader.\n");
+
+	spin_lock_irqsave(&wm0010->irq_lock, flags);
+	wm0010->state = WM0010_STAGE2;
+	spin_unlock_irqrestore(&wm0010->irq_lock, flags);
+
+	/* Only initialise PLL if max_spi_freq initialised */
+	if (wm0010->max_spi_freq) {
+
+		/* Initialise a PLL record */
+		memset(&pll_rec, 0, sizeof(pll_rec));
+		pll_rec.command = DFW_CMD_PLL;
+		pll_rec.length = (sizeof(pll_rec) - 8);
+
+		/* On wm0010 only the CLKCTRL1 value is used */
+		pll_rec.clkctrl1 = wm0010->pll_clkctrl1;
+
+		len = pll_rec.length + 8;
+		out = kzalloc(len, GFP_KERNEL);
+		if (!out) {
+			dev_err(codec->dev,
+				"Failed to allocate RX buffer\n");
+			goto abort;
+		}
+
+		img_swap = kzalloc(len, GFP_KERNEL);
+		if (!img_swap) {
+			dev_err(codec->dev,
+				"Failed to allocate image buffer\n");
+			goto abort;
+		}
+
+		/* We need to re-order for 0010 */
+		byte_swap_64((u64 *)&pll_rec, img_swap, len);
+
+		spi_message_init(&m);
+		memset(&t, 0, sizeof(t));
+		t.rx_buf = out;
+		t.tx_buf = img_swap;
+		t.len = len;
+		t.bits_per_word = 8;
+		t.speed_hz = wm0010->sysclk / 6;
+		spi_message_add_tail(&t, &m);
+
+		ret = spi_sync(spi, &m);
+		if (ret != 0) {
+			dev_err(codec->dev, "First PLL write failed: %d\n", ret);
+			goto abort;
+		}
+
+		/* Use a second send of the message to get the return status */
+		ret = spi_sync(spi, &m);
+		if (ret != 0) {
+			dev_err(codec->dev, "Second PLL write failed: %d\n", ret);
+			goto abort;
+		}
+
+		p = (u32 *)out;
+
+		/* Look for PLL active code from the DSP */
+		for (i = 0; i < len / 4; i++) {
+			if (*p == 0x0e00ed0f) {
+				dev_dbg(codec->dev, "PLL packet received\n");
+				wm0010->pll_running = true;
+				break;
+			}
+			p++;
+		}
+
+		kfree(img_swap);
+		kfree(out);
+	} else
+		dev_dbg(codec->dev, "Not enabling DSP PLL.");
+
+	ret = request_firmware(&fw, "wm0010.dfw", codec->dev);
+	if (ret != 0) {
+		dev_err(codec->dev, "Failed to request application: %d\n",
+			ret);
+		goto abort;
+	}
+
+	rec = (const struct dfw_binrec *)fw->data;
+	offset = 0;
+	wm0010->boot_done = 0;
+	wm0010->boot_failed = false;
+	BUG_ON(!list_empty(&xfer_list));
+	init_completion(&done);
+
+	/* First record should be INFO */
+	if (rec->command != DFW_CMD_INFO) {
+		dev_err(codec->dev, "First record not INFO\r\n");
+		goto abort;
+	}
+
+	/* Check it's a 0010 file */
+	if (rec->data[0] != DEVICE_ID_WM0010) {
+		dev_err(codec->dev, "Not a WM0010 firmware file.\r\n");
+		goto abort;
+	}
+
+	/* Skip the info record as we don't need to send it */
+	offset += ((rec->length) + 8);
+	rec = (void *)&rec->data[rec->length];
+
+	while (offset < fw->size) {
+		dev_dbg(codec->dev,
+			"Packet: command %d, data length = 0x%x\r\n",
+			rec->command, rec->length);
+		len = rec->length + 8;
+
+		out = kzalloc(len, GFP_KERNEL);
+		if (!out) {
+			dev_err(codec->dev,
+				"Failed to allocate RX buffer\n");
+			goto abort;
+		}
+
+		img_swap = kzalloc(len, GFP_KERNEL);
+		if (!img_swap) {
+			dev_err(codec->dev,
+				"Failed to allocate image buffer\n");
+			goto abort;
+		}
+
+		/* We need to re-order for 0010 */
+		byte_swap_64((u64 *)&rec->command, img_swap, len);
+
+		xfer = kzalloc(sizeof(*xfer), GFP_KERNEL);
+		if (!xfer) {
+			dev_err(codec->dev, "Failed to allocate xfer\n");
+			goto abort;
+		}
+
+		xfer->codec = codec;
+		list_add_tail(&xfer->list, &xfer_list);
+
+		spi_message_init(&xfer->m);
+		xfer->m.complete = wm0010_boot_xfer_complete;
+		xfer->m.context = xfer;
+		xfer->t.tx_buf = img_swap;
+		xfer->t.rx_buf = out;
+		xfer->t.len = len;
+		xfer->t.bits_per_word = 8;
+
+		if (!wm0010->pll_running) {
+			xfer->t.speed_hz = wm0010->sysclk / 6;
+		} else {
+			xfer->t.speed_hz = wm0010->max_spi_freq;
+
+			if (wm0010->board_max_spi_speed &&
+			   (wm0010->board_max_spi_speed < wm0010->max_spi_freq))
+					xfer->t.speed_hz = wm0010->board_max_spi_speed;
+		}
+
+		/* Store max usable spi frequency for later use */
+		wm0010->max_spi_freq = xfer->t.speed_hz;
+
+		spi_message_add_tail(&xfer->t, &xfer->m);
+
+		offset += ((rec->length) + 8);
+		rec = (void *)&rec->data[rec->length];
+
+		if (offset >= fw->size) {
+			dev_dbg(codec->dev, "All transfers scheduled\n");
+			xfer->done = &done;
+		}
+
+		ret = spi_async(spi, &xfer->m);
+		if (ret != 0) {
+			dev_err(codec->dev, "Write failed: %d\n", ret);
+			goto abort;
+		}
+
+		if (wm0010->boot_failed)
+			goto abort;
+	}
+
+	wait_for_completion(&done);
+
+	spin_lock_irqsave(&wm0010->irq_lock, flags);
+	wm0010->state = WM0010_FIRMWARE;
+	spin_unlock_irqrestore(&wm0010->irq_lock, flags);
+
+	mutex_unlock(&wm0010->lock);
+
+	release_firmware(fw);
+
+	while (!list_empty(&xfer_list)) {
+		xfer = list_first_entry(&xfer_list, struct wm0010_boot_xfer,
+					list);
+		kfree(xfer->t.rx_buf);
+		kfree(xfer->t.tx_buf);
+		list_del(&xfer->list);
+		kfree(xfer);
+	}
+
+	return 0;
+
+abort:
+	/* Put the chip back into reset */
+	wm0010_halt(codec);
+	mutex_unlock(&wm0010->lock);
+	return ret;
+
+err_core:
+	mutex_unlock(&wm0010->lock);
+	regulator_bulk_disable(ARRAY_SIZE(wm0010->core_supplies),
+			       wm0010->core_supplies);
+err:
+	return ret;
+}
+
+static int wm0010_set_bias_level(struct snd_soc_codec *codec,
+				 enum snd_soc_bias_level level)
+{
+	struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+
+	switch (level) {
+	case SND_SOC_BIAS_ON:
+		if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE)
+			wm0010_boot(codec);
+		break;
+	case SND_SOC_BIAS_PREPARE:
+		break;
+	case SND_SOC_BIAS_STANDBY:
+		if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE) {
+			mutex_lock(&wm0010->lock);
+			wm0010_halt(codec);
+			mutex_unlock(&wm0010->lock);
+		}
+		break;
+	case SND_SOC_BIAS_OFF:
+		break;
+	}
+
+	codec->dapm.bias_level = level;
+
+	return 0;
+}
+
+static int wm0010_set_sysclk(struct snd_soc_codec *codec, int source,
+			     int clk_id, unsigned int freq, int dir)
+{
+	struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+	unsigned int i;
+
+	wm0010->sysclk = freq;
+
+	if (freq < pll_clock_map[ARRAY_SIZE(pll_clock_map)-1].max_sysclk) {
+		wm0010->max_spi_freq = 0;
+	} else {
+		for (i = 0; i < ARRAY_SIZE(pll_clock_map); i++)
+			if (freq >= pll_clock_map[i].max_sysclk)
+				break;
+
+		wm0010->max_spi_freq = pll_clock_map[i].max_pll_spi_speed;
+		wm0010->pll_clkctrl1 = pll_clock_map[i].pll_clkctrl1;
+	}
+
+	return 0;
+}
+
+static int wm0010_probe(struct snd_soc_codec *codec);
+
+static struct snd_soc_codec_driver soc_codec_dev_wm0010 = {
+	.probe = wm0010_probe,
+	.set_bias_level = wm0010_set_bias_level,
+	.set_sysclk = wm0010_set_sysclk,
+	.idle_bias_off = true,
+
+	.dapm_widgets = wm0010_dapm_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(wm0010_dapm_widgets),
+	.dapm_routes = wm0010_dapm_routes,
+	.num_dapm_routes = ARRAY_SIZE(wm0010_dapm_routes),
+};
+
+#define WM0010_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
+#define WM0010_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
+			SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE |\
+			SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_driver wm0010_dai[] = {
+	{
+		.name = "wm0010-sdi1",
+		.playback = {
+			.stream_name = "SDI1 Playback",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = WM0010_RATES,
+			.formats = WM0010_FORMATS,
+		},
+		.capture = {
+			 .stream_name = "SDI1 Capture",
+			 .channels_min = 1,
+			 .channels_max = 2,
+			 .rates = WM0010_RATES,
+			 .formats = WM0010_FORMATS,
+		 },
+	},
+	{
+		.name = "wm0010-sdi2",
+		.playback = {
+			.stream_name = "SDI2 Playback",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = WM0010_RATES,
+			.formats = WM0010_FORMATS,
+		},
+		.capture = {
+			 .stream_name = "SDI2 Capture",
+			 .channels_min = 1,
+			 .channels_max = 2,
+			 .rates = WM0010_RATES,
+			 .formats = WM0010_FORMATS,
+		 },
+	},
+};
+
+static irqreturn_t wm0010_irq(int irq, void *data)
+{
+	struct wm0010_priv *wm0010 = data;
+
+	switch (wm0010->state) {
+	case WM0010_POWER_OFF:
+	case WM0010_OUT_OF_RESET:
+	case WM0010_BOOTROM:
+	case WM0010_STAGE2:
+		spin_lock(&wm0010->irq_lock);
+		complete(&wm0010->boot_completion);
+		spin_unlock(&wm0010->irq_lock);
+		return IRQ_HANDLED;
+	default:
+		return IRQ_NONE;
+	}
+
+	return IRQ_NONE;
+}
+
+static int wm0010_probe(struct snd_soc_codec *codec)
+{
+	struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
+
+	wm0010->codec = codec;
+
+	return 0;
+}
+
+static int __devinit wm0010_spi_probe(struct spi_device *spi)
+{
+	unsigned long gpio_flags;
+	int ret;
+	int trigger;
+	int irq;
+	struct wm0010_priv *wm0010;
+
+	wm0010 = devm_kzalloc(&spi->dev, sizeof(*wm0010),
+			      GFP_KERNEL);
+	if (!wm0010)
+		return -ENOMEM;
+
+	mutex_init(&wm0010->lock);
+	spin_lock_init(&wm0010->irq_lock);
+
+	spi_set_drvdata(spi, wm0010);
+	wm0010->dev = &spi->dev;
+
+	if (dev_get_platdata(&spi->dev))
+		memcpy(&wm0010->pdata, dev_get_platdata(&spi->dev),
+		       sizeof(wm0010->pdata));
+
+	init_completion(&wm0010->boot_completion);
+
+	wm0010->core_supplies[0].supply = "AVDD";
+	wm0010->core_supplies[1].supply = "DCVDD";
+	ret = devm_regulator_bulk_get(wm0010->dev, ARRAY_SIZE(wm0010->core_supplies),
+				      wm0010->core_supplies);
+	if (ret != 0) {
+		dev_err(wm0010->dev, "Failed to obtain core supplies: %d\n",
+			ret);
+		return ret;
+	}
+
+	wm0010->dbvdd = devm_regulator_get(wm0010->dev, "DBVDD");
+	if (IS_ERR(wm0010->dbvdd)) {
+		ret = PTR_ERR(wm0010->dbvdd);
+		dev_err(wm0010->dev, "Failed to obtain DBVDD: %d\n", ret);
+		return ret;
+	}
+
+	if (wm0010->pdata.gpio_reset) {
+		wm0010->gpio_reset = wm0010->pdata.gpio_reset;
+
+		if (wm0010->pdata.reset_active_high)
+			wm0010->gpio_reset_value = 1;
+		else
+			wm0010->gpio_reset_value = 0;
+
+		if (wm0010->gpio_reset_value)
+			gpio_flags = GPIOF_OUT_INIT_HIGH;
+		else
+			gpio_flags = GPIOF_OUT_INIT_LOW;
+
+		ret = devm_gpio_request_one(wm0010->dev, wm0010->gpio_reset,
+					    gpio_flags, "wm0010 reset");
+		if (ret < 0) {
+			dev_err(wm0010->dev,
+				"Failed to request GPIO for DSP reset: %d\n",
+				ret);
+			return ret;
+		}
+	} else {
+		dev_err(wm0010->dev, "No reset GPIO configured\n");
+		return -EINVAL;
+	}
+
+	wm0010->state = WM0010_POWER_OFF;
+
+	irq = spi->irq;
+	if (wm0010->pdata.irq_flags)
+		trigger = wm0010->pdata.irq_flags;
+	else
+		trigger = IRQF_TRIGGER_FALLING;
+	trigger |= IRQF_ONESHOT;
+
+	ret = request_threaded_irq(irq, NULL, wm0010_irq, trigger | IRQF_ONESHOT,
+				   "wm0010", wm0010);
+	if (ret) {
+		dev_err(wm0010->dev, "Failed to request IRQ %d: %d\n",
+			irq, ret);
+		return ret;
+	}
+	wm0010->irq = irq;
+
+	if (spi->max_speed_hz)
+		wm0010->board_max_spi_speed = spi->max_speed_hz;
+	else
+		wm0010->board_max_spi_speed = 0;
+
+	ret = snd_soc_register_codec(&spi->dev,
+				     &soc_codec_dev_wm0010, wm0010_dai,
+				     ARRAY_SIZE(wm0010_dai));
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int __devexit wm0010_spi_remove(struct spi_device *spi)
+{
+	struct wm0010_priv *wm0010 = spi_get_drvdata(spi);
+
+	snd_soc_unregister_codec(&spi->dev);
+
+	gpio_set_value_cansleep(wm0010->gpio_reset,
+				wm0010->gpio_reset_value);
+
+	if (wm0010->irq)
+		free_irq(wm0010->irq, wm0010);
+
+	return 0;
+}
+
+static struct spi_driver wm0010_spi_driver = {
+	.driver = {
+		.name	= "wm0010",
+		.bus 	= &spi_bus_type,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= wm0010_spi_probe,
+	.remove		= __devexit_p(wm0010_spi_remove),
+};
+
+module_spi_driver(wm0010_spi_driver);
+
+MODULE_DESCRIPTION("ASoC WM0010 driver");
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index a3acb7a..683dc43 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -31,6 +31,7 @@
 #include <linux/i2c.h>
 #include <linux/regmap.h>
 #include <linux/debugfs.h>
+#include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -43,6 +44,14 @@
 
 #include "wm2000.h"
 
+#define WM2000_NUM_SUPPLIES 3
+
+static const char *wm2000_supplies[WM2000_NUM_SUPPLIES] = {
+	"SPKVDD",
+	"DBVDD",
+	"DCVDD",
+};
+
 enum wm2000_anc_mode {
 	ANC_ACTIVE = 0,
 	ANC_BYPASS = 1,
@@ -54,6 +63,8 @@
 	struct i2c_client *i2c;
 	struct regmap *regmap;
 
+	struct regulator_bulk_data supplies[WM2000_NUM_SUPPLIES];
+
 	enum wm2000_anc_mode anc_mode;
 
 	unsigned int anc_active:1;
@@ -126,6 +137,12 @@
 
 	dev_dbg(&i2c->dev, "Beginning power up\n");
 
+	ret = regulator_bulk_enable(WM2000_NUM_SUPPLIES, wm2000->supplies);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
+		return ret;
+	}
+
 	if (!wm2000->mclk_div) {
 		dev_dbg(&i2c->dev, "Disabling MCLK divider\n");
 		wm2000_write(i2c, WM2000_REG_SYS_CTL2,
@@ -143,12 +160,14 @@
 	if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT,
 			     WM2000_ANC_ENG_IDLE)) {
 		dev_err(&i2c->dev, "ANC engine failed to reset\n");
+		regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);
 		return -ETIMEDOUT;
 	}
 
 	if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
 			     WM2000_STATUS_BOOT_COMPLETE)) {
 		dev_err(&i2c->dev, "ANC engine failed to initialise\n");
+		regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);
 		return -ETIMEDOUT;
 	}
 
@@ -163,11 +182,13 @@
 			      wm2000->anc_download_size);
 	if (ret < 0) {
 		dev_err(&i2c->dev, "i2c_transfer() failed: %d\n", ret);
+		regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);
 		return ret;
 	}
 	if (ret != wm2000->anc_download_size) {
 		dev_err(&i2c->dev, "i2c_transfer() failed, %d != %d\n",
 			ret, wm2000->anc_download_size);
+		regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);
 		return -EIO;
 	}
 
@@ -201,6 +222,7 @@
 	if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
 			     WM2000_STATUS_MOUSE_ACTIVE)) {
 		dev_err(&i2c->dev, "Timed out waiting for device\n");
+		regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);
 		return -ETIMEDOUT;
 	}
 
@@ -238,6 +260,8 @@
 		return -ETIMEDOUT;
 	}
 
+	regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);
+
 	dev_dbg(&i2c->dev, "powered off\n");
 	wm2000->anc_mode = ANC_OFF;
 
@@ -747,7 +771,7 @@
 	struct wm2000_platform_data *pdata;
 	const char *filename;
 	const struct firmware *fw = NULL;
-	int ret;
+	int ret, i;
 	int reg;
 	u16 id;
 
@@ -760,7 +784,7 @@
 
 	dev_set_drvdata(&i2c->dev, wm2000);
 
-	wm2000->regmap = regmap_init_i2c(i2c, &wm2000_regmap);
+	wm2000->regmap = devm_regmap_init_i2c(i2c, &wm2000_regmap);
 	if (IS_ERR(wm2000->regmap)) {
 		ret = PTR_ERR(wm2000->regmap);
 		dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
@@ -768,6 +792,22 @@
 		goto out;
 	}
 
+	for (i = 0; i < WM2000_NUM_SUPPLIES; i++)
+		wm2000->supplies[i].supply = wm2000_supplies[i];
+
+	ret = devm_regulator_bulk_get(&i2c->dev, WM2000_NUM_SUPPLIES,
+				      wm2000->supplies);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "Failed to get supplies: %d\n", ret);
+		return ret;
+	}
+
+	ret = regulator_bulk_enable(WM2000_NUM_SUPPLIES, wm2000->supplies);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
+		return ret;
+	}
+
 	/* Verify that this is a WM2000 */
 	reg = wm2000_read(i2c, WM2000_REG_ID1);
 	id = reg << 8;
@@ -777,7 +817,7 @@
 	if (id != 0x2000) {
 		dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id);
 		ret = -ENODEV;
-		goto out_regmap_exit;
+		goto err_supplies;
 	}
 
 	reg = wm2000_read(i2c, WM2000_REG_REVISON);
@@ -796,7 +836,7 @@
 	ret = request_firmware(&fw, filename, &i2c->dev);
 	if (ret != 0) {
 		dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret);
-		goto out_regmap_exit;
+		goto err_supplies;
 	}
 
 	/* Pre-cook the concatenation of the register address onto the image */
@@ -807,7 +847,7 @@
 	if (wm2000->anc_download == NULL) {
 		dev_err(&i2c->dev, "Out of memory\n");
 		ret = -ENOMEM;
-		goto out_regmap_exit;
+		goto err_supplies;
 	}
 
 	wm2000->anc_download[0] = 0x80;
@@ -822,11 +862,10 @@
 	wm2000_reset(wm2000);
 
 	ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, NULL, 0);
-	if (!ret)
-		goto out;
 
-out_regmap_exit:
-	regmap_exit(wm2000->regmap);
+err_supplies:
+	regulator_bulk_disable(WM2000_NUM_SUPPLIES, wm2000->supplies);
+
 out:
 	release_firmware(fw);
 	return ret;
@@ -834,10 +873,7 @@
 
 static __devexit int wm2000_i2c_remove(struct i2c_client *i2c)
 {
-	struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
-
 	snd_soc_unregister_codec(&i2c->dev);
-	regmap_exit(wm2000->regmap);
 
 	return 0;
 }
@@ -858,17 +894,7 @@
 	.id_table = wm2000_i2c_id,
 };
 
-static int __init wm2000_init(void)
-{
-	return i2c_add_driver(&wm2000_i2c_driver);
-}
-module_init(wm2000_init);
-
-static void __exit wm2000_exit(void)
-{
-	i2c_del_driver(&wm2000_i2c_driver);
-}
-module_exit(wm2000_exit);
+module_i2c_driver(wm2000_i2c_driver);
 
 MODULE_DESCRIPTION("ASoC WM2000 driver");
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>");
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c
index 32682c1..efa93dbb 100644
--- a/sound/soc/codecs/wm2200.c
+++ b/sound/soc/codecs/wm2200.c
@@ -1117,8 +1117,8 @@
 		    0, NULL, 0),
 SND_SOC_DAPM_SUPPLY("MICBIAS2", WM2200_MIC_BIAS_CTRL_2, WM2200_MICB2_ENA_SHIFT,
 		    0, NULL, 0),
-SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
-SND_SOC_DAPM_REGULATOR_SUPPLY("AVDD", 20),
+SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("AVDD", 20, 0),
 
 SND_SOC_DAPM_INPUT("IN1L"),
 SND_SOC_DAPM_INPUT("IN1R"),
@@ -2270,17 +2270,7 @@
 	.id_table = wm2200_i2c_id,
 };
 
-static int __init wm2200_modinit(void)
-{
-	return i2c_add_driver(&wm2200_i2c_driver);
-}
-module_init(wm2200_modinit);
-
-static void __exit wm2200_exit(void)
-{
-	i2c_del_driver(&wm2200_i2c_driver);
-}
-module_exit(wm2200_exit);
+module_i2c_driver(wm2200_i2c_driver);
 
 MODULE_DESCRIPTION("ASoC WM2200 driver");
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index aa62c0e..7f56758 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -848,9 +848,9 @@
 SND_SOC_DAPM_SUPPLY("ASYNCCLK", WM5100_CLOCKING_6, WM5100_ASYNC_CLK_ENA_SHIFT,
 		    0, NULL, 0),
 
-SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
-SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0),
-SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0, 0),
 
 SND_SOC_DAPM_SUPPLY("CP1", WM5100_HP_CHARGE_PUMP_1, WM5100_CP1_ENA_SHIFT, 0,
 		    NULL, 0),
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index e33d327..1722b58 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -274,18 +274,43 @@
 ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
 ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE);
 
+
+static const char *wm5102_aec_loopback_texts[] = {
+	"HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "EPOUT",
+	"SPKOUTL", "SPKOUTR", "SPKDAT1L", "SPKDAT1R",
+};
+
+static const unsigned int wm5102_aec_loopback_values[] = {
+	0, 1, 2, 3, 4, 6, 7, 8, 9,
+};
+
+static const struct soc_enum wm5102_aec_loopback =
+	SOC_VALUE_ENUM_SINGLE(ARIZONA_DAC_AEC_CONTROL_1,
+			      ARIZONA_AEC_LOOPBACK_SRC_SHIFT,
+			      ARIZONA_AEC_LOOPBACK_SRC_MASK,
+			      ARRAY_SIZE(wm5102_aec_loopback_texts),
+			      wm5102_aec_loopback_texts,
+			      wm5102_aec_loopback_values);
+
+static const struct snd_kcontrol_new wm5102_aec_loopback_mux =
+	SOC_DAPM_VALUE_ENUM("AEC Loopback", wm5102_aec_loopback);
+
 static const struct snd_soc_dapm_widget wm5102_dapm_widgets[] = {
 SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT,
 		    0, NULL, 0),
 SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1,
 		    ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK,
+		    ARIZONA_OPCLK_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("ASYNCOPCLK", ARIZONA_OUTPUT_ASYNC_CLOCK,
+		    ARIZONA_OPCLK_ASYNC_ENA_SHIFT, 0, NULL, 0),
 
-SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0),
-SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0),
-SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
-SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0),
-SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDL", 0),
-SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0, SND_SOC_DAPM_REGULATOR_BYPASS),
+SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDL", 0, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0, 0),
 
 SND_SOC_DAPM_SIGGEN("TONE"),
 SND_SOC_DAPM_SIGGEN("NOISE"),
@@ -421,6 +446,9 @@
 SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,
 		    ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0),
 
+SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
+		       ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5102_aec_loopback_mux),
+
 SND_SOC_DAPM_PGA_E("OUT1L", ARIZONA_OUTPUT_ENABLES_1,
 		   ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
 		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
@@ -516,6 +544,7 @@
 	{ name, "Noise Generator", "Noise Generator" }, \
 	{ name, "Tone Generator 1", "Tone Generator 1" }, \
 	{ name, "Tone Generator 2", "Tone Generator 2" }, \
+	{ name, "AEC", "AEC Loopback" }, \
 	{ name, "IN1L", "IN1L PGA" }, \
 	{ name, "IN1R", "IN1R PGA" }, \
 	{ name, "IN2L", "IN2L PGA" }, \
@@ -681,21 +710,30 @@
 	ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"),
 	ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"),
 
+	{ "AEC Loopback", "HPOUT1L", "OUT1L" },
+	{ "AEC Loopback", "HPOUT1R", "OUT1R" },
 	{ "HPOUT1L", NULL, "OUT1L" },
 	{ "HPOUT1R", NULL, "OUT1R" },
 
+	{ "AEC Loopback", "HPOUT2L", "OUT2L" },
+	{ "AEC Loopback", "HPOUT2R", "OUT2R" },
 	{ "HPOUT2L", NULL, "OUT2L" },
 	{ "HPOUT2R", NULL, "OUT2R" },
 
+	{ "AEC Loopback", "EPOUT", "OUT3L" },
 	{ "EPOUTN", NULL, "OUT3L" },
 	{ "EPOUTP", NULL, "OUT3L" },
 
+	{ "AEC Loopback", "SPKOUTL", "OUT4L" },
 	{ "SPKOUTLN", NULL, "OUT4L" },
 	{ "SPKOUTLP", NULL, "OUT4L" },
 
+	{ "AEC Loopback", "SPKOUTR", "OUT4R" },
 	{ "SPKOUTRN", NULL, "OUT4R" },
 	{ "SPKOUTRP", NULL, "OUT4R" },
 
+	{ "AEC Loopback", "SPKDAT1L", "OUT5L" },
+	{ "AEC Loopback", "SPKDAT1R", "OUT5R" },
 	{ "SPKDAT1L", NULL, "OUT5L" },
 	{ "SPKDAT1R", NULL, "OUT5R" },
 };
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index 01ebbcc..9211e41 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -153,6 +153,15 @@
 SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode),
 SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode),
 
+ARIZONA_MIXER_CONTROLS("DSP1L", ARIZONA_DSP1LMIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("DSP1R", ARIZONA_DSP1RMIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("DSP2L", ARIZONA_DSP2LMIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("DSP2R", ARIZONA_DSP2RMIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("DSP3L", ARIZONA_DSP3LMIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("DSP3R", ARIZONA_DSP3RMIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("DSP4L", ARIZONA_DSP4LMIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("DSP5R", ARIZONA_DSP4RMIX_INPUT_1_SOURCE),
+
 ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE),
 
@@ -163,7 +172,8 @@
 ARIZONA_MIXER_CONTROLS("HPOUT1R", ARIZONA_OUT1RMIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("HPOUT2L", ARIZONA_OUT2LMIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("HPOUT2R", ARIZONA_OUT2RMIX_INPUT_1_SOURCE),
-ARIZONA_MIXER_CONTROLS("EPOUT", ARIZONA_OUT3LMIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("HPOUT3L", ARIZONA_OUT3LMIX_INPUT_1_SOURCE),
+ARIZONA_MIXER_CONTROLS("HPOUT3R", ARIZONA_OUT3RMIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("SPKOUTL", ARIZONA_OUT4LMIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("SPKOUTR", ARIZONA_OUT4RMIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE),
@@ -175,7 +185,7 @@
 	   ARIZONA_OUT1_OSR_SHIFT, 1, 0),
 SOC_SINGLE("OUT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_2L,
 	   ARIZONA_OUT2_OSR_SHIFT, 1, 0),
-SOC_SINGLE("EPOUT High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_3L,
+SOC_SINGLE("OUT3 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_3L,
 	   ARIZONA_OUT3_OSR_SHIFT, 1, 0),
 SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L,
 	   ARIZONA_OUT4_OSR_SHIFT, 1, 0),
@@ -188,8 +198,8 @@
 	     ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1),
 SOC_DOUBLE_R("OUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L,
 	     ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_MUTE_SHIFT, 1, 1),
-SOC_SINGLE("EPOUT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_3L,
-	   ARIZONA_OUT3L_MUTE_SHIFT, 1, 1),
+SOC_DOUBLE_R("OUT3 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_3L,
+	     ARIZONA_DAC_DIGITAL_VOLUME_3R, ARIZONA_OUT3L_MUTE_SHIFT, 1, 1),
 SOC_DOUBLE_R("Speaker Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_4L,
 	     ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_MUTE_SHIFT, 1, 1),
 SOC_DOUBLE_R("SPKDAT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_5L,
@@ -203,8 +213,9 @@
 SOC_DOUBLE_R_TLV("OUT2 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_2L,
 		 ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_VOL_SHIFT,
 		 0xbf, 0, digital_tlv),
-SOC_SINGLE_TLV("EPOUT Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_3L,
-	       ARIZONA_OUT3L_VOL_SHIFT, 0xbf, 0, digital_tlv),
+SOC_DOUBLE_R_TLV("OUT3 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_3L,
+		 ARIZONA_DAC_DIGITAL_VOLUME_3R, ARIZONA_OUT3L_VOL_SHIFT,
+		 0xbf, 0, digital_tlv),
 SOC_DOUBLE_R_TLV("Speaker Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_4L,
 		 ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_VOL_SHIFT,
 		 0xbf, 0, digital_tlv),
@@ -223,8 +234,9 @@
 		       ARIZONA_OUTPUT_PATH_CONFIG_2R,
 		       ARIZONA_OUT2L_PGA_VOL_SHIFT,
 		       0x34, 0x40, 0, ana_tlv),
-SOC_SINGLE_RANGE_TLV("EPOUT Volume", ARIZONA_OUTPUT_PATH_CONFIG_3L,
-		     ARIZONA_OUT3L_PGA_VOL_SHIFT, 0x34, 0x40, 0, ana_tlv),
+SOC_DOUBLE_R_RANGE_TLV("OUT3 Volume", ARIZONA_OUTPUT_PATH_CONFIG_3L,
+		       ARIZONA_OUTPUT_PATH_CONFIG_3R,
+		       ARIZONA_OUT3L_PGA_VOL_SHIFT, 0x34, 0x40, 0, ana_tlv),
 
 SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT,
 	   ARIZONA_SPK1R_MUTE_SHIFT, 1, 1),
@@ -272,7 +284,8 @@
 ARIZONA_MIXER_ENUMS(OUT1R, ARIZONA_OUT1RMIX_INPUT_1_SOURCE);
 ARIZONA_MIXER_ENUMS(OUT2L, ARIZONA_OUT2LMIX_INPUT_1_SOURCE);
 ARIZONA_MIXER_ENUMS(OUT2R, ARIZONA_OUT2RMIX_INPUT_1_SOURCE);
-ARIZONA_MIXER_ENUMS(OUT3, ARIZONA_OUT3LMIX_INPUT_1_SOURCE);
+ARIZONA_MIXER_ENUMS(OUT3L, ARIZONA_OUT3LMIX_INPUT_1_SOURCE);
+ARIZONA_MIXER_ENUMS(OUT3R, ARIZONA_OUT3RMIX_INPUT_1_SOURCE);
 ARIZONA_MIXER_ENUMS(SPKOUTL, ARIZONA_OUT4LMIX_INPUT_1_SOURCE);
 ARIZONA_MIXER_ENUMS(SPKOUTR, ARIZONA_OUT4RMIX_INPUT_1_SOURCE);
 ARIZONA_MIXER_ENUMS(SPKDAT1L, ARIZONA_OUT5LMIX_INPUT_1_SOURCE);
@@ -300,18 +313,42 @@
 ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
 ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE);
 
+static const char *wm5110_aec_loopback_texts[] = {
+	"HPOUT1L", "HPOUT1R", "HPOUT2L", "HPOUT2R", "HPOUT3L", "HPOUT3R",
+	"SPKOUTL", "SPKOUTR", "SPKDAT1L", "SPKDAT1R", "SPKDAT2L", "SPKDAT2R",
+};
+
+static const unsigned int wm5110_aec_loopback_values[] = {
+	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
+};
+
+static const struct soc_enum wm5110_aec_loopback =
+	SOC_VALUE_ENUM_SINGLE(ARIZONA_DAC_AEC_CONTROL_1,
+			      ARIZONA_AEC_LOOPBACK_SRC_SHIFT,
+			      ARIZONA_AEC_LOOPBACK_SRC_MASK,
+			      ARRAY_SIZE(wm5110_aec_loopback_texts),
+			      wm5110_aec_loopback_texts,
+			      wm5110_aec_loopback_values);
+
+static const struct snd_kcontrol_new wm5110_aec_loopback_mux =
+	SOC_DAPM_VALUE_ENUM("AEC Loopback", wm5110_aec_loopback);
+
 static const struct snd_soc_dapm_widget wm5110_dapm_widgets[] = {
 SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT,
 		    0, NULL, 0),
 SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1,
 		    ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK,
+		    ARIZONA_OPCLK_ENA_SHIFT, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("ASYNCOPCLK", ARIZONA_OUTPUT_ASYNC_CLOCK,
+		    ARIZONA_OPCLK_ASYNC_ENA_SHIFT, 0, NULL, 0),
 
-SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0),
-SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0),
-SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
-SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0),
-SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDL", 0),
-SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0, SND_SOC_DAPM_REGULATOR_BYPASS),
+SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDL", 0, 0),
+SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0, 0),
 
 SND_SOC_DAPM_SIGGEN("TONE"),
 SND_SOC_DAPM_SIGGEN("NOISE"),
@@ -405,6 +442,9 @@
 SND_SOC_DAPM_PGA("ASRC2R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2R_ENA_SHIFT, 0,
 		 NULL, 0),
 
+SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1,
+		       ARIZONA_AEC_LOOPBACK_ENA, 0, &wm5110_aec_loopback_mux),
+
 SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0,
 		     ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0),
 SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0,
@@ -474,6 +514,9 @@
 SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1,
 		   ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
 		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_PGA_E("OUT3R", ARIZONA_OUTPUT_ENABLES_1,
+		   ARIZONA_OUT3R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
+		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
 SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1,
 		   ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
 		   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
@@ -518,7 +561,8 @@
 ARIZONA_MIXER_WIDGETS(OUT1R, "HPOUT1R"),
 ARIZONA_MIXER_WIDGETS(OUT2L, "HPOUT2L"),
 ARIZONA_MIXER_WIDGETS(OUT2R, "HPOUT2R"),
-ARIZONA_MIXER_WIDGETS(OUT3, "EPOUT"),
+ARIZONA_MIXER_WIDGETS(OUT3L, "HPOUT3L"),
+ARIZONA_MIXER_WIDGETS(OUT3R, "HPOUT3R"),
 ARIZONA_MIXER_WIDGETS(SPKOUTL, "SPKOUTL"),
 ARIZONA_MIXER_WIDGETS(SPKOUTR, "SPKOUTR"),
 ARIZONA_MIXER_WIDGETS(SPKDAT1L, "SPKDAT1L"),
@@ -550,8 +594,8 @@
 SND_SOC_DAPM_OUTPUT("HPOUT1R"),
 SND_SOC_DAPM_OUTPUT("HPOUT2L"),
 SND_SOC_DAPM_OUTPUT("HPOUT2R"),
-SND_SOC_DAPM_OUTPUT("EPOUTN"),
-SND_SOC_DAPM_OUTPUT("EPOUTP"),
+SND_SOC_DAPM_OUTPUT("HPOUT3L"),
+SND_SOC_DAPM_OUTPUT("HPOUT3R"),
 SND_SOC_DAPM_OUTPUT("SPKOUTLN"),
 SND_SOC_DAPM_OUTPUT("SPKOUTLP"),
 SND_SOC_DAPM_OUTPUT("SPKOUTRN"),
@@ -566,6 +610,7 @@
 	{ name, "Noise Generator", "Noise Generator" }, \
 	{ name, "Tone Generator 1", "Tone Generator 1" }, \
 	{ name, "Tone Generator 2", "Tone Generator 2" }, \
+	{ name, "AEC", "AEC Loopback" }, \
 	{ name, "IN1L", "IN1L PGA" }, \
 	{ name, "IN1R", "IN1R PGA" }, \
 	{ name, "IN2L", "IN2L PGA" }, \
@@ -616,6 +661,7 @@
 	{ "OUT2L", NULL, "CPVDD" },
 	{ "OUT2R", NULL, "CPVDD" },
 	{ "OUT3L", NULL, "CPVDD" },
+	{ "OUT3R", NULL, "CPVDD" },
 
 	{ "OUT4L", NULL, "SPKVDDL" },
 	{ "OUT4R", NULL, "SPKVDDR" },
@@ -697,7 +743,8 @@
 	ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"),
 	ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"),
 	ARIZONA_MIXER_ROUTES("OUT2R", "HPOUT2R"),
-	ARIZONA_MIXER_ROUTES("OUT3L", "EPOUT"),
+	ARIZONA_MIXER_ROUTES("OUT3L", "HPOUT3L"),
+	ARIZONA_MIXER_ROUTES("OUT3R", "HPOUT3R"),
 
 	ARIZONA_MIXER_ROUTES("OUT4L", "SPKOUTL"),
 	ARIZONA_MIXER_ROUTES("OUT4R", "SPKOUTR"),
@@ -750,8 +797,8 @@
 	{ "HPOUT2L", NULL, "OUT2L" },
 	{ "HPOUT2R", NULL, "OUT2R" },
 
-	{ "EPOUTN", NULL, "OUT3L" },
-	{ "EPOUTP", NULL, "OUT3L" },
+	{ "HPOUT3L", NULL, "OUT3L" },
+	{ "HPOUT3R", NULL, "OUT3L" },
 
 	{ "SPKOUTLN", NULL, "OUT4L" },
 	{ "SPKOUTLP", NULL, "OUT4L" },
@@ -869,6 +916,8 @@
 	ARIZONA_ADC_DIGITAL_VOLUME_2R,
 	ARIZONA_ADC_DIGITAL_VOLUME_3L,
 	ARIZONA_ADC_DIGITAL_VOLUME_3R,
+	ARIZONA_ADC_DIGITAL_VOLUME_4L,
+	ARIZONA_ADC_DIGITAL_VOLUME_4R,
 
 	ARIZONA_DAC_DIGITAL_VOLUME_1L,
 	ARIZONA_DAC_DIGITAL_VOLUME_1R,
@@ -880,6 +929,8 @@
 	ARIZONA_DAC_DIGITAL_VOLUME_4R,
 	ARIZONA_DAC_DIGITAL_VOLUME_5L,
 	ARIZONA_DAC_DIGITAL_VOLUME_5R,
+	ARIZONA_DAC_DIGITAL_VOLUME_6L,
+	ARIZONA_DAC_DIGITAL_VOLUME_6R,
 };
 
 static struct snd_soc_codec_driver soc_codec_dev_wm5110 = {
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 56a0495..c12a54e 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -20,6 +20,7 @@
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
 #include <linux/of_device.h>
+#include <linux/regmap.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -33,24 +34,75 @@
  * We can't read the WM8510 register space when we are
  * using 2 wire for device control, so we cache them instead.
  */
-static const u16 wm8510_reg[WM8510_CACHEREGNUM] = {
-	0x0000, 0x0000, 0x0000, 0x0000,
-	0x0050, 0x0000, 0x0140, 0x0000,
-	0x0000, 0x0000, 0x0000, 0x00ff,
-	0x0000, 0x0000, 0x0100, 0x00ff,
-	0x0000, 0x0000, 0x012c, 0x002c,
-	0x002c, 0x002c, 0x002c, 0x0000,
-	0x0032, 0x0000, 0x0000, 0x0000,
-	0x0000, 0x0000, 0x0000, 0x0000,
-	0x0038, 0x000b, 0x0032, 0x0000,
-	0x0008, 0x000c, 0x0093, 0x00e9,
-	0x0000, 0x0000, 0x0000, 0x0000,
-	0x0003, 0x0010, 0x0000, 0x0000,
-	0x0000, 0x0002, 0x0001, 0x0000,
-	0x0000, 0x0000, 0x0039, 0x0000,
-	0x0001,
+static const struct reg_default wm8510_reg_defaults[] = {
+	{  1, 0x0000 },
+	{  2, 0x0000 },
+	{  3, 0x0000 },
+	{  4, 0x0050 },
+	{  5, 0x0000 },
+	{  6, 0x0140 },
+	{  7, 0x0000 },
+	{  8, 0x0000 },
+	{  9, 0x0000 },
+	{ 10, 0x0000 },
+	{ 11, 0x00ff },
+	{ 12, 0x0000 },
+	{ 13, 0x0000 },
+	{ 14, 0x0100 },
+	{ 15, 0x00ff },
+	{ 16, 0x0000 },
+	{ 17, 0x0000 },
+	{ 18, 0x012c },
+	{ 19, 0x002c },
+	{ 20, 0x002c },
+	{ 21, 0x002c },
+	{ 22, 0x002c },
+	{ 23, 0x0000 },
+	{ 24, 0x0032 },
+	{ 25, 0x0000 },
+	{ 26, 0x0000 },
+	{ 27, 0x0000 },
+	{ 28, 0x0000 },
+	{ 29, 0x0000 },
+	{ 30, 0x0000 },
+	{ 31, 0x0000 },
+	{ 32, 0x0038 },
+	{ 33, 0x000b },
+	{ 34, 0x0032 },
+	{ 35, 0x0000 },
+	{ 36, 0x0008 },
+	{ 37, 0x000c },
+	{ 38, 0x0093 },
+	{ 39, 0x00e9 },
+	{ 40, 0x0000 },
+	{ 41, 0x0000 },
+	{ 42, 0x0000 },
+	{ 43, 0x0000 },
+	{ 44, 0x0003 },
+	{ 45, 0x0010 },
+	{ 46, 0x0000 },
+	{ 47, 0x0000 },
+	{ 48, 0x0000 },
+	{ 49, 0x0002 },
+	{ 50, 0x0001 },
+	{ 51, 0x0000 },
+	{ 52, 0x0000 },
+	{ 53, 0x0000 },
+	{ 54, 0x0039 },
+	{ 55, 0x0000 },
+	{ 56, 0x0001 },
 };
 
+static bool wm8510_volatile(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case WM8510_RESET:
+		return true;
+	default:
+		return false;
+	}
+}
+
 #define WM8510_POWER1_BIASEN  0x08
 #define WM8510_POWER1_BUFIOEN 0x10
 
@@ -58,7 +110,7 @@
 
 /* codec private data */
 struct wm8510_priv {
-	enum snd_soc_control_type control_type;
+	struct regmap *regmap;
 };
 
 static const char *wm8510_companding[] = { "Off", "NC", "u-law", "A-law" };
@@ -454,6 +506,7 @@
 static int wm8510_set_bias_level(struct snd_soc_codec *codec,
 	enum snd_soc_bias_level level)
 {
+	struct wm8510_priv *wm8510 = snd_soc_codec_get_drvdata(codec);
 	u16 power1 = snd_soc_read(codec, WM8510_POWER1) & ~0x3;
 
 	switch (level) {
@@ -467,7 +520,7 @@
 		power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN;
 
 		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
-			snd_soc_cache_sync(codec);
+			regcache_sync(wm8510->regmap);
 
 			/* Initial cap charge at VMID 5k */
 			snd_soc_write(codec, WM8510_POWER1, power1 | 0x3);
@@ -536,10 +589,9 @@
 
 static int wm8510_probe(struct snd_soc_codec *codec)
 {
-	struct wm8510_priv *wm8510 = snd_soc_codec_get_drvdata(codec);
 	int ret;
 
-	ret = snd_soc_codec_set_cache_io(codec, 7, 9,  wm8510->control_type);
+	ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
 	if (ret < 0) {
 		printk(KERN_ERR "wm8510: failed to set cache I/O: %d\n", ret);
 		return ret;
@@ -569,9 +621,6 @@
 	.suspend =	wm8510_suspend,
 	.resume =	wm8510_resume,
 	.set_bias_level = wm8510_set_bias_level,
-	.reg_cache_size = ARRAY_SIZE(wm8510_reg),
-	.reg_word_size = sizeof(u16),
-	.reg_cache_default =wm8510_reg,
 
 	.controls = wm8510_snd_controls,
 	.num_controls = ARRAY_SIZE(wm8510_snd_controls),
@@ -586,23 +635,38 @@
 	{ },
 };
 
+static const struct regmap_config wm8510_regmap = {
+	.reg_bits = 7,
+	.val_bits = 9,
+	.max_register = WM8510_MONOMIX,
+
+	.reg_defaults = wm8510_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(wm8510_reg_defaults),
+	.cache_type = REGCACHE_RBTREE,
+
+	.volatile_reg = wm8510_volatile,
+};
+
 #if defined(CONFIG_SPI_MASTER)
 static int __devinit wm8510_spi_probe(struct spi_device *spi)
 {
 	struct wm8510_priv *wm8510;
 	int ret;
 
-	wm8510 = kzalloc(sizeof(struct wm8510_priv), GFP_KERNEL);
+	wm8510 = devm_kzalloc(&spi->dev, sizeof(struct wm8510_priv),
+			      GFP_KERNEL);
 	if (wm8510 == NULL)
 		return -ENOMEM;
 
-	wm8510->control_type = SND_SOC_SPI;
+	wm8510->regmap = devm_regmap_init_spi(spi, &wm8510_regmap);
+	if (IS_ERR(wm8510->regmap))
+		return PTR_ERR(wm8510->regmap);
+
 	spi_set_drvdata(spi, wm8510);
 
 	ret = snd_soc_register_codec(&spi->dev,
 			&soc_codec_dev_wm8510, &wm8510_dai, 1);
-	if (ret < 0)
-		kfree(wm8510);
+
 	return ret;
 }
 
@@ -630,17 +694,20 @@
 	struct wm8510_priv *wm8510;
 	int ret;
 
-	wm8510 = kzalloc(sizeof(struct wm8510_priv), GFP_KERNEL);
+	wm8510 = devm_kzalloc(&i2c->dev, sizeof(struct wm8510_priv),
+			      GFP_KERNEL);
 	if (wm8510 == NULL)
 		return -ENOMEM;
 
+	wm8510->regmap = devm_regmap_init_i2c(i2c, &wm8510_regmap);
+	if (IS_ERR(wm8510->regmap))
+		return PTR_ERR(wm8510->regmap);
+
 	i2c_set_clientdata(i2c, wm8510);
-	wm8510->control_type = SND_SOC_I2C;
 
 	ret =  snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_wm8510, &wm8510_dai, 1);
-	if (ret < 0)
-		kfree(wm8510);
+
 	return ret;
 }
 
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 1c3ffb2..8d5c276 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -17,6 +17,7 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
+#include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <linux/of_device.h>
@@ -39,41 +40,34 @@
 
 /* codec private data */
 struct wm8523_priv {
-	enum snd_soc_control_type control_type;
+	struct regmap *regmap;
 	struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES];
 	unsigned int sysclk;
 	unsigned int rate_constraint_list[WM8523_NUM_RATES];
 	struct snd_pcm_hw_constraint_list rate_constraint;
 };
 
-static const u16 wm8523_reg[WM8523_REGISTER_COUNT] = {
-	0x8523,     /* R0 - DEVICE_ID */
-	0x0001,     /* R1 - REVISION */
-	0x0000,     /* R2 - PSCTRL1 */
-	0x1812,     /* R3 - AIF_CTRL1 */
-	0x0000,     /* R4 - AIF_CTRL2 */
-	0x0001,     /* R5 - DAC_CTRL3 */
-	0x0190,     /* R6 - DAC_GAINL */
-	0x0190,     /* R7 - DAC_GAINR */
-	0x0000,     /* R8 - ZERO_DETECT */
+static const struct reg_default wm8523_reg_defaults[] = {
+	{ 2, 0x0000 },     /* R2 - PSCTRL1 */
+	{ 3, 0x1812 },     /* R3 - AIF_CTRL1 */
+	{ 4, 0x0000 },     /* R4 - AIF_CTRL2 */
+	{ 5, 0x0001 },     /* R5 - DAC_CTRL3 */
+	{ 6, 0x0190 },     /* R6 - DAC_GAINL */
+	{ 7, 0x0190 },     /* R7 - DAC_GAINR */
+	{ 8, 0x0000 },     /* R8 - ZERO_DETECT */
 };
 
-static int wm8523_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
+static bool wm8523_volatile_register(struct device *dev, unsigned int reg)
 {
 	switch (reg) {
 	case WM8523_DEVICE_ID:
 	case WM8523_REVISION:
-		return 1;
+		return true;
 	default:
-		return 0;
+		return false;
 	}
 }
 
-static int wm8523_reset(struct snd_soc_codec *codec)
-{
-	return snd_soc_write(codec, WM8523_DEVICE_ID, 0);
-}
-
 static const DECLARE_TLV_DB_SCALE(dac_tlv, -10000, 25, 0);
 
 static const char *wm8523_zd_count_text[] = {
@@ -301,8 +295,7 @@
 				 enum snd_soc_bias_level level)
 {
 	struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
-	u16 *reg_cache = codec->reg_cache;
-	int ret, i;
+	int ret;
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
@@ -325,16 +318,13 @@
 				return ret;
 			}
 
+			/* Sync back default/cached values */
+			regcache_sync(wm8523->regmap);
+
 			/* Initial power up */
 			snd_soc_update_bits(codec, WM8523_PSCTRL1,
 					    WM8523_SYS_ENA_MASK, 1);
 
-			/* Sync back default/cached values */
-			for (i = WM8523_AIF_CTRL1;
-			     i < WM8523_MAX_REGISTER; i++)
-				snd_soc_write(codec, i, reg_cache[i]);
-
-
 			msleep(100);
 		}
 
@@ -402,60 +392,18 @@
 static int wm8523_probe(struct snd_soc_codec *codec)
 {
 	struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
-	int ret, i;
+	int ret;
 
 	wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0];
 	wm8523->rate_constraint.count =
 		ARRAY_SIZE(wm8523->rate_constraint_list);
 
-	ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8523->control_type);
+	ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
 	if (ret != 0) {
 		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
 		return ret;
 	}
 
-	for (i = 0; i < ARRAY_SIZE(wm8523->supplies); i++)
-		wm8523->supplies[i].supply = wm8523_supply_names[i];
-
-	ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8523->supplies),
-				 wm8523->supplies);
-	if (ret != 0) {
-		dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
-		return ret;
-	}
-
-	ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
-				    wm8523->supplies);
-	if (ret != 0) {
-		dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
-		goto err_get;
-	}
-
-	ret = snd_soc_read(codec, WM8523_DEVICE_ID);
-	if (ret < 0) {
-		dev_err(codec->dev, "Failed to read ID register\n");
-		goto err_enable;
-	}
-	if (ret != wm8523_reg[WM8523_DEVICE_ID]) {
-		dev_err(codec->dev, "Device is not a WM8523, ID is %x\n", ret);
-		ret = -EINVAL;
-		goto err_enable;
-	}
-
-	ret = snd_soc_read(codec, WM8523_REVISION);
-	if (ret < 0) {
-		dev_err(codec->dev, "Failed to read revision register\n");
-		goto err_enable;
-	}
-	dev_info(codec->dev, "revision %c\n",
-		 (ret & WM8523_CHIP_REV_MASK) + 'A');
-
-	ret = wm8523_reset(codec);
-	if (ret < 0) {
-		dev_err(codec->dev, "Failed to issue reset\n");
-		goto err_enable;
-	}
-
 	/* Change some default settings - latch VU and enable ZC */
 	snd_soc_update_bits(codec, WM8523_DAC_GAINR,
 			    WM8523_DACR_VU, WM8523_DACR_VU);
@@ -463,25 +411,12 @@
 
 	wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
-	/* Bias level configuration will have done an extra enable */
-	regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
-
 	return 0;
-
-err_enable:
-	regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
-err_get:
-	regulator_bulk_free(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
-
-	return ret;
 }
 
 static int wm8523_remove(struct snd_soc_codec *codec)
 {
-	struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
-
 	wm8523_set_bias_level(codec, SND_SOC_BIAS_OFF);
-	regulator_bulk_free(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
 	return 0;
 }
 
@@ -491,10 +426,6 @@
 	.suspend =	wm8523_suspend,
 	.resume =	wm8523_resume,
 	.set_bias_level = wm8523_set_bias_level,
-	.reg_cache_size = WM8523_REGISTER_COUNT,
-	.reg_word_size = sizeof(u16),
-	.reg_cache_default = wm8523_reg,
-	.volatile_register = wm8523_volatile_register,
 
 	.controls = wm8523_controls,
 	.num_controls = ARRAY_SIZE(wm8523_controls),
@@ -509,32 +440,97 @@
 	{ },
 };
 
+static const struct regmap_config wm8523_regmap = {
+	.reg_bits = 8,
+	.val_bits = 16,
+	.max_register = WM8523_ZERO_DETECT,
+
+	.reg_defaults = wm8523_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(wm8523_reg_defaults),
+	.cache_type = REGCACHE_RBTREE,
+
+	.volatile_reg = wm8523_volatile_register,
+};
+
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 static __devinit int wm8523_i2c_probe(struct i2c_client *i2c,
 				      const struct i2c_device_id *id)
 {
 	struct wm8523_priv *wm8523;
-	int ret;
+	unsigned int val;
+	int ret, i;
 
-	wm8523 = kzalloc(sizeof(struct wm8523_priv), GFP_KERNEL);
+	wm8523 = devm_kzalloc(&i2c->dev, sizeof(struct wm8523_priv),
+			      GFP_KERNEL);
 	if (wm8523 == NULL)
 		return -ENOMEM;
 
+	wm8523->regmap = devm_regmap_init_i2c(i2c, &wm8523_regmap);
+	if (IS_ERR(wm8523->regmap)) {
+		ret = PTR_ERR(wm8523->regmap);
+		dev_err(&i2c->dev, "Failed to create regmap: %d\n", ret);
+		return ret;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(wm8523->supplies); i++)
+		wm8523->supplies[i].supply = wm8523_supply_names[i];
+
+	ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8523->supplies),
+				      wm8523->supplies);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
+		return ret;
+	}
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
+				    wm8523->supplies);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
+		return ret;
+	}
+
+	ret = regmap_read(wm8523->regmap, WM8523_DEVICE_ID, &val);
+	if (ret < 0) {
+		dev_err(&i2c->dev, "Failed to read ID register\n");
+		goto err_enable;
+	}
+	if (val != 0x8523) {
+		dev_err(&i2c->dev, "Device is not a WM8523, ID is %x\n", ret);
+		ret = -EINVAL;
+		goto err_enable;
+	}
+
+	ret = regmap_read(wm8523->regmap, WM8523_REVISION, &val);
+	if (ret < 0) {
+		dev_err(&i2c->dev, "Failed to read revision register\n");
+		goto err_enable;
+	}
+	dev_info(&i2c->dev, "revision %c\n",
+		 (val & WM8523_CHIP_REV_MASK) + 'A');
+
+	ret = regmap_write(wm8523->regmap, WM8523_DEVICE_ID, 0x8523);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "Failed to reset device: %d\n", ret);
+		goto err_enable;
+	}
+
+	regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
+
 	i2c_set_clientdata(i2c, wm8523);
-	wm8523->control_type = SND_SOC_I2C;
 
 	ret =  snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_wm8523, &wm8523_dai, 1);
-	if (ret < 0)
-		kfree(wm8523);
+
 	return ret;
 
+err_enable:
+	regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
+	return ret;
 }
 
 static __devexit int wm8523_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
-	kfree(i2c_get_clientdata(client));
 	return 0;
 }
 
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 7c68226..5e9c40f 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -1,7 +1,7 @@
 /*
  * wm8580.c  --  WM8580 ALSA Soc Audio driver
  *
- * Copyright 2008-11 Wolfson Microelectronics PLC.
+ * Copyright 2008-12 Wolfson Microelectronics PLC.
  *
  *  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
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
+#include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <linux/of_device.h>
@@ -157,23 +158,72 @@
  * We can't read the WM8580 register space when we
  * are using 2 wire for device control, so we cache them instead.
  */
-static const u16 wm8580_reg[] = {
-	0x0121, 0x017e, 0x007d, 0x0014, /*R3*/
-	0x0121, 0x017e, 0x007d, 0x0194, /*R7*/
-	0x0010, 0x0002, 0x0002, 0x00c2, /*R11*/
-	0x0182, 0x0082, 0x000a, 0x0024, /*R15*/
-	0x0009, 0x0000, 0x00ff, 0x0000, /*R19*/
-	0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R23*/
-	0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R27*/
-	0x01f0, 0x0040, 0x0000, 0x0000, /*R31(0x1F)*/
-	0x0000, 0x0000, 0x0031, 0x000b, /*R35*/
-	0x0039, 0x0000, 0x0010, 0x0032, /*R39*/
-	0x0054, 0x0076, 0x0098, 0x0000, /*R43(0x2B)*/
-	0x0000, 0x0000, 0x0000, 0x0000, /*R47*/
-	0x0000, 0x0000, 0x005e, 0x003e, /*R51(0x33)*/
-	0x0000, 0x0000 /*R53*/
+static const struct reg_default wm8580_reg_defaults[] = {
+	{  0, 0x0121 },
+	{  1, 0x017e },
+	{  2, 0x007d },
+	{  3, 0x0014 },
+	{  4, 0x0121 },
+	{  5, 0x017e },
+	{  6, 0x007d },
+	{  7, 0x0194 },
+	{  8, 0x0010 },
+	{  9, 0x0002 },
+	{ 10, 0x0002 },
+	{ 11, 0x00c2 },
+	{ 12, 0x0182 },
+	{ 13, 0x0082 },
+	{ 14, 0x000a },
+	{ 15, 0x0024 },
+	{ 16, 0x0009 },
+	{ 17, 0x0000 },
+	{ 18, 0x00ff },
+	{ 19, 0x0000 },
+	{ 20, 0x00ff },
+	{ 21, 0x00ff },
+	{ 22, 0x00ff },
+	{ 23, 0x00ff },
+	{ 24, 0x00ff },
+	{ 25, 0x00ff },
+	{ 26, 0x00ff },
+	{ 27, 0x00ff },
+	{ 28, 0x01f0 },
+	{ 29, 0x0040 },
+	{ 30, 0x0000 },
+	{ 31, 0x0000 },
+	{ 32, 0x0000 },
+	{ 33, 0x0000 },
+	{ 34, 0x0031 },
+	{ 35, 0x000b },
+	{ 36, 0x0039 },
+	{ 37, 0x0000 },
+	{ 38, 0x0010 },
+	{ 39, 0x0032 },
+	{ 40, 0x0054 },
+	{ 41, 0x0076 },
+	{ 42, 0x0098 },
+	{ 43, 0x0000 },
+	{ 44, 0x0000 },
+	{ 45, 0x0000 },
+	{ 46, 0x0000 },
+	{ 47, 0x0000 },
+	{ 48, 0x0000 },
+	{ 49, 0x0000 },
+	{ 50, 0x005e },
+	{ 51, 0x003e },
+	{ 52, 0x0000 },
 };
 
+static bool wm8580_volatile(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case WM8580_RESET:
+		return true;
+	default:
+		return false;
+	}
+}
+
 struct pll_state {
 	unsigned int in;
 	unsigned int out;
@@ -188,7 +238,7 @@
 
 /* codec private data */
 struct wm8580_priv {
-	enum snd_soc_control_type control_type;
+	struct regmap *regmap;
 	struct regulator_bulk_data supplies[WM8580_NUM_SUPPLIES];
 	struct pll_state a;
 	struct pll_state b;
@@ -203,14 +253,16 @@
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-	u16 *reg_cache = codec->reg_cache;
+	struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
 	unsigned int reg = mc->reg;
 	unsigned int reg2 = mc->rreg;
 	int ret;
 
-	/* Clear the register cache so we write without VU set */
-	reg_cache[reg] = 0;
-	reg_cache[reg2] = 0;
+	/* Clear the register cache VU so we write without VU set */
+	regcache_cache_only(wm8580->regmap, true);
+	regmap_update_bits(wm8580->regmap, reg, 0x100, 0x000);
+	regmap_update_bits(wm8580->regmap, reg2, 0x100, 0x000);
+	regcache_cache_only(wm8580->regmap, false);
 
 	ret = snd_soc_put_volsw(kcontrol, ucontrol);
 	if (ret < 0)
@@ -815,24 +867,14 @@
 static int wm8580_probe(struct snd_soc_codec *codec)
 {
 	struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
-	int ret = 0,i;
+	int ret = 0;
 
-	ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8580->control_type);
+	ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
 	if (ret < 0) {
 		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
 		return ret;
 	}
 
-	for (i = 0; i < ARRAY_SIZE(wm8580->supplies); i++)
-		wm8580->supplies[i].supply = wm8580_supply_names[i];
-
-	ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8580->supplies),
-				 wm8580->supplies);
-	if (ret != 0) {
-		dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
-		return ret;
-	}
-
 	ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies),
 				    wm8580->supplies);
 	if (ret != 0) {
@@ -854,7 +896,6 @@
 err_regulator_enable:
 	regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
 err_regulator_get:
-	regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
 	return ret;
 }
 
@@ -866,7 +907,6 @@
 	wm8580_set_bias_level(codec, SND_SOC_BIAS_OFF);
 
 	regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
-	regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
 
 	return 0;
 }
@@ -875,9 +915,6 @@
 	.probe =	wm8580_probe,
 	.remove =	wm8580_remove,
 	.set_bias_level = wm8580_set_bias_level,
-	.reg_cache_size = ARRAY_SIZE(wm8580_reg),
-	.reg_word_size = sizeof(u16),
-	.reg_cache_default = wm8580_reg,
 
 	.controls = wm8580_snd_controls,
 	.num_controls = ARRAY_SIZE(wm8580_snd_controls),
@@ -892,31 +929,55 @@
 	{ },
 };
 
+static const struct regmap_config wm8580_regmap = {
+	.reg_bits = 7,
+	.val_bits = 9,
+	.max_register = WM8580_MAX_REGISTER,
+
+	.reg_defaults = wm8580_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(wm8580_reg_defaults),
+	.cache_type = REGCACHE_RBTREE,
+
+	.volatile_reg = wm8580_volatile,
+};
+
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 static int wm8580_i2c_probe(struct i2c_client *i2c,
 			    const struct i2c_device_id *id)
 {
 	struct wm8580_priv *wm8580;
-	int ret;
+	int ret, i;
 
-	wm8580 = kzalloc(sizeof(struct wm8580_priv), GFP_KERNEL);
+	wm8580 = devm_kzalloc(&i2c->dev, sizeof(struct wm8580_priv),
+			      GFP_KERNEL);
 	if (wm8580 == NULL)
 		return -ENOMEM;
 
+	wm8580->regmap = devm_regmap_init_i2c(i2c, &wm8580_regmap);
+	if (IS_ERR(wm8580->regmap))
+		return PTR_ERR(wm8580->regmap);
+
+	for (i = 0; i < ARRAY_SIZE(wm8580->supplies); i++)
+		wm8580->supplies[i].supply = wm8580_supply_names[i];
+
+	ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8580->supplies),
+				      wm8580->supplies);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
+		return ret;
+	}
+
 	i2c_set_clientdata(i2c, wm8580);
-	wm8580->control_type = SND_SOC_I2C;
 
 	ret =  snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_wm8580, wm8580_dai, ARRAY_SIZE(wm8580_dai));
-	if (ret < 0)
-		kfree(wm8580);
+
 	return ret;
 }
 
 static int wm8580_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
-	kfree(i2c_get_clientdata(client));
 	return 0;
 }
 
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index 0b76d1d..8b8bb70 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -18,6 +18,7 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
+#include <linux/regmap.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
 #include <linux/of_device.h>
@@ -32,7 +33,7 @@
 
 /* codec private data */
 struct wm8711_priv {
-	enum snd_soc_control_type bus_type;
+	struct regmap *regmap;
 	unsigned int sysclk;
 };
 
@@ -42,11 +43,21 @@
  * using 2 wire for device control, so we cache them instead.
  * There is no point in caching the reset register
  */
-static const u16 wm8711_reg[WM8711_CACHEREGNUM] = {
-	0x0079, 0x0079, 0x000a, 0x0008,
-	0x009f, 0x000a, 0x0000, 0x0000
+static const struct reg_default wm8711_reg_defaults[] = {
+	{ 0, 0x0079 }, { 1, 0x0079 }, { 2, 0x000a }, { 3, 0x0008 },
+	{ 4, 0x009f }, { 5, 0x000a }, { 6, 0x0000 }, { 7, 0x0000 },
 };
 
+static bool wm8711_volatile(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case WM8711_RESET:
+		return true;
+	default:
+		return false;
+	}
+}
+
 #define wm8711_reset(c)	snd_soc_write(c, WM8711_RESET, 0)
 
 static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
@@ -289,6 +300,7 @@
 static int wm8711_set_bias_level(struct snd_soc_codec *codec,
 	enum snd_soc_bias_level level)
 {
+	struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec);
 	u16 reg = snd_soc_read(codec, WM8711_PWR) & 0xff7f;
 
 	switch (level) {
@@ -299,7 +311,7 @@
 		break;
 	case SND_SOC_BIAS_STANDBY:
 		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
-			snd_soc_cache_sync(codec);
+			regcache_sync(wm8711->regmap);
 
 		snd_soc_write(codec, WM8711_PWR, reg | 0x0040);
 		break;
@@ -353,10 +365,9 @@
 
 static int wm8711_probe(struct snd_soc_codec *codec)
 {
-	struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec);
 	int ret;
 
-	ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8711->bus_type);
+	ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
 	if (ret < 0) {
 		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
 		return ret;
@@ -391,9 +402,6 @@
 	.suspend =	wm8711_suspend,
 	.resume =	wm8711_resume,
 	.set_bias_level = wm8711_set_bias_level,
-	.reg_cache_size = ARRAY_SIZE(wm8711_reg),
-	.reg_word_size = sizeof(u16),
-	.reg_cache_default = wm8711_reg,
 	.controls = wm8711_snd_controls,
 	.num_controls = ARRAY_SIZE(wm8711_snd_controls),
 	.dapm_widgets = wm8711_dapm_widgets,
@@ -408,30 +416,45 @@
 };
 MODULE_DEVICE_TABLE(of, wm8711_of_match);
 
+static const struct regmap_config wm8711_regmap = {
+	.reg_bits = 7,
+	.val_bits = 9,
+	.max_register = WM8711_RESET,
+
+	.reg_defaults = wm8711_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(wm8711_reg_defaults),
+	.cache_type = REGCACHE_RBTREE,
+
+	.volatile_reg = wm8711_volatile,
+};
+
 #if defined(CONFIG_SPI_MASTER)
 static int __devinit wm8711_spi_probe(struct spi_device *spi)
 {
 	struct wm8711_priv *wm8711;
 	int ret;
 
-	wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL);
+	wm8711 = devm_kzalloc(&spi->dev, sizeof(struct wm8711_priv),
+			      GFP_KERNEL);
 	if (wm8711 == NULL)
 		return -ENOMEM;
 
+	wm8711->regmap = devm_regmap_init_spi(spi, &wm8711_regmap);
+	if (IS_ERR(wm8711->regmap))
+		return PTR_ERR(wm8711->regmap);
+
 	spi_set_drvdata(spi, wm8711);
-	wm8711->bus_type = SND_SOC_SPI;
 
 	ret = snd_soc_register_codec(&spi->dev,
 			&soc_codec_dev_wm8711, &wm8711_dai, 1);
-	if (ret < 0)
-		kfree(wm8711);
+
 	return ret;
 }
 
 static int __devexit wm8711_spi_remove(struct spi_device *spi)
 {
 	snd_soc_unregister_codec(&spi->dev);
-	kfree(spi_get_drvdata(spi));
+
 	return 0;
 }
 
@@ -453,24 +476,26 @@
 	struct wm8711_priv *wm8711;
 	int ret;
 
-	wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL);
+	wm8711 = devm_kzalloc(&client->dev, sizeof(struct wm8711_priv),
+			      GFP_KERNEL);
 	if (wm8711 == NULL)
 		return -ENOMEM;
 
+	wm8711->regmap = devm_regmap_init_i2c(client, &wm8711_regmap);
+	if (IS_ERR(wm8711->regmap))
+		return PTR_ERR(wm8711->regmap);
+
 	i2c_set_clientdata(client, wm8711);
-	wm8711->bus_type = SND_SOC_I2C;
 
 	ret =  snd_soc_register_codec(&client->dev,
 			&soc_codec_dev_wm8711, &wm8711_dai, 1);
-	if (ret < 0)
-		kfree(wm8711);
+
 	return ret;
 }
 
 static __devexit int wm8711_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
-	kfree(i2c_get_clientdata(client));
 	return 0;
 }
 
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index 1467f97..00a12a0 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -17,6 +17,7 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
+#include <linux/regmap.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
 #include <linux/of_device.h>
@@ -35,16 +36,16 @@
  * the volume update bits, mute the output and enable infinite zero
  * detect.
  */
-static const u16 wm8728_reg_defaults[] = {
-	0x1ff,
-	0x1ff,
-	0x001,
-	0x100,
+static const struct reg_default wm8728_reg_defaults[] = {
+	{ 0, 0x1ff },
+	{ 1, 0x1ff },
+	{ 2, 0x001 },
+	{ 3, 0x100 },
 };
 
 /* codec private data */
 struct wm8728_priv {
-	enum snd_soc_control_type control_type;
+	struct regmap *regmap;
 };
 
 static const DECLARE_TLV_DB_SCALE(wm8728_tlv, -12750, 50, 1);
@@ -162,8 +163,8 @@
 static int wm8728_set_bias_level(struct snd_soc_codec *codec,
 				 enum snd_soc_bias_level level)
 {
+	struct wm8728_priv *wm8728 = snd_soc_codec_get_drvdata(codec);
 	u16 reg;
-	int i;
 
 	switch (level) {
 	case SND_SOC_BIAS_ON:
@@ -175,9 +176,7 @@
 			snd_soc_write(codec, WM8728_DACCTL, reg & ~0x4);
 
 			/* ..then sync in the register cache. */
-			for (i = 0; i < ARRAY_SIZE(wm8728_reg_defaults); i++)
-				snd_soc_write(codec, i,
-					     snd_soc_read(codec, i));
+			regcache_sync(wm8728->regmap);
 		}
 		break;
 
@@ -229,10 +228,9 @@
 
 static int wm8728_probe(struct snd_soc_codec *codec)
 {
-	struct wm8728_priv *wm8728 = snd_soc_codec_get_drvdata(codec);
 	int ret;
 
-	ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8728->control_type);
+	ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
 	if (ret < 0) {
 		printk(KERN_ERR "wm8728: failed to configure cache I/O: %d\n",
 		       ret);
@@ -257,9 +255,6 @@
 	.suspend =	wm8728_suspend,
 	.resume =	wm8728_resume,
 	.set_bias_level = wm8728_set_bias_level,
-	.reg_cache_size = ARRAY_SIZE(wm8728_reg_defaults),
-	.reg_word_size = sizeof(u16),
-	.reg_cache_default = wm8728_reg_defaults,
 	.controls = wm8728_snd_controls,
 	.num_controls = ARRAY_SIZE(wm8728_snd_controls),
 	.dapm_widgets = wm8728_dapm_widgets,
@@ -274,30 +269,43 @@
 };
 MODULE_DEVICE_TABLE(of, wm8728_of_match);
 
+static const struct regmap_config wm8728_regmap = {
+	.reg_bits = 7,
+	.val_bits = 9,
+	.max_register = WM8728_IFCTL,
+
+	.reg_defaults = wm8728_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(wm8728_reg_defaults),
+	.cache_type = REGCACHE_RBTREE,
+};
+
 #if defined(CONFIG_SPI_MASTER)
 static int __devinit wm8728_spi_probe(struct spi_device *spi)
 {
 	struct wm8728_priv *wm8728;
 	int ret;
 
-	wm8728 = kzalloc(sizeof(struct wm8728_priv), GFP_KERNEL);
+	wm8728 = devm_kzalloc(&spi->dev, sizeof(struct wm8728_priv),
+			      GFP_KERNEL);
 	if (wm8728 == NULL)
 		return -ENOMEM;
 
-	wm8728->control_type = SND_SOC_SPI;
+	wm8728->regmap = devm_regmap_init_spi(spi, &wm8728_regmap);
+	if (IS_ERR(wm8728->regmap))
+		return PTR_ERR(wm8728->regmap);
+
 	spi_set_drvdata(spi, wm8728);
 
 	ret = snd_soc_register_codec(&spi->dev,
 			&soc_codec_dev_wm8728, &wm8728_dai, 1);
-	if (ret < 0)
-		kfree(wm8728);
+
 	return ret;
 }
 
 static int __devexit wm8728_spi_remove(struct spi_device *spi)
 {
 	snd_soc_unregister_codec(&spi->dev);
-	kfree(spi_get_drvdata(spi));
+
 	return 0;
 }
 
@@ -319,24 +327,26 @@
 	struct wm8728_priv *wm8728;
 	int ret;
 
-	wm8728 = kzalloc(sizeof(struct wm8728_priv), GFP_KERNEL);
+	wm8728 = devm_kzalloc(&i2c->dev, sizeof(struct wm8728_priv),
+			      GFP_KERNEL);
 	if (wm8728 == NULL)
 		return -ENOMEM;
 
+	wm8728->regmap = devm_regmap_init_i2c(i2c, &wm8728_regmap);
+	if (IS_ERR(wm8728->regmap))
+		return PTR_ERR(wm8728->regmap);
+
 	i2c_set_clientdata(i2c, wm8728);
-	wm8728->control_type = SND_SOC_I2C;
 
 	ret =  snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_wm8728, &wm8728_dai, 1);
-	if (ret < 0)
-		kfree(wm8728);
+
 	return ret;
 }
 
 static __devexit int wm8728_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
-	kfree(i2c_get_clientdata(client));
 	return 0;
 }
 
diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c
index d052012..5c9634f 100644
--- a/sound/soc/codecs/wm8737.c
+++ b/sound/soc/codecs/wm8737.c
@@ -16,6 +16,7 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
+#include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
@@ -40,29 +41,39 @@
 
 /* codec private data */
 struct wm8737_priv {
-	enum snd_soc_control_type control_type;
+	struct regmap *regmap;
 	struct regulator_bulk_data supplies[WM8737_NUM_SUPPLIES];
 	unsigned int mclk;
 };
 
-static const u16 wm8737_reg[WM8737_REGISTER_COUNT] = {
-	0x00C3,     /* R0  - Left PGA volume */
-	0x00C3,     /* R1  - Right PGA volume */
-	0x0007,     /* R2  - AUDIO path L */
-	0x0007,     /* R3  - AUDIO path R */
-	0x0000,     /* R4  - 3D Enhance */
-	0x0000,     /* R5  - ADC Control */
-	0x0000,     /* R6  - Power Management */
-	0x000A,     /* R7  - Audio Format */
-	0x0000,     /* R8  - Clocking */
-	0x000F,     /* R9  - MIC Preamp Control */
-	0x0003,     /* R10 - Misc Bias Control */
-	0x0000,     /* R11 - Noise Gate */
-	0x007C,     /* R12 - ALC1 */
-	0x0000,     /* R13 - ALC2 */
-	0x0032,     /* R14 - ALC3 */
+static const struct reg_default wm8737_reg_defaults[] = {
+	{  0, 0x00C3 },     /* R0  - Left PGA volume */
+	{  1, 0x00C3 },     /* R1  - Right PGA volume */
+	{  2, 0x0007 },     /* R2  - AUDIO path L */
+	{  3, 0x0007 },     /* R3  - AUDIO path R */
+	{  4, 0x0000 },     /* R4  - 3D Enhance */
+	{  5, 0x0000 },     /* R5  - ADC Control */
+	{  6, 0x0000 },     /* R6  - Power Management */
+	{  7, 0x000A },     /* R7  - Audio Format */
+	{  8, 0x0000 },     /* R8  - Clocking */
+	{  9, 0x000F },     /* R9  - MIC Preamp Control */
+	{ 10, 0x0003 },     /* R10 - Misc Bias Control */
+	{ 11, 0x0000 },     /* R11 - Noise Gate */
+	{ 12, 0x007C },     /* R12 - ALC1 */
+	{ 13, 0x0000 },     /* R13 - ALC2 */
+	{ 14, 0x0032 },     /* R14 - ALC3 */
 };
 
+static bool wm8737_volatile(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case WM8737_RESET:
+		return true;
+	default:
+		return false;
+	}
+}
+
 static int wm8737_reset(struct snd_soc_codec *codec)
 {
 	return snd_soc_write(codec, WM8737_RESET, 0);
@@ -479,7 +490,7 @@
 				return ret;
 			}
 
-			snd_soc_cache_sync(codec);
+			regcache_sync(wm8737->regmap);
 
 			/* Fast VMID ramp at 2*2.5k */
 			snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
@@ -557,24 +568,14 @@
 static int wm8737_probe(struct snd_soc_codec *codec)
 {
 	struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
-	int ret, i;
+	int ret;
 
-	ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8737->control_type);
+	ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
 	if (ret != 0) {
 		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
 		return ret;
 	}
 
-	for (i = 0; i < ARRAY_SIZE(wm8737->supplies); i++)
-		wm8737->supplies[i].supply = wm8737_supply_names[i];
-
-	ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8737->supplies),
-				 wm8737->supplies);
-	if (ret != 0) {
-		dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
-		return ret;
-	}
-
 	ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies),
 				    wm8737->supplies);
 	if (ret != 0) {
@@ -607,17 +608,12 @@
 err_enable:
 	regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
 err_get:
-	regulator_bulk_free(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
-
 	return ret;
 }
 
 static int wm8737_remove(struct snd_soc_codec *codec)
 {
-	struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
-
 	wm8737_set_bias_level(codec, SND_SOC_BIAS_OFF);
-	regulator_bulk_free(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
 	return 0;
 }
 
@@ -627,10 +623,6 @@
 	.suspend	= wm8737_suspend,
 	.resume		= wm8737_resume,
 	.set_bias_level = wm8737_set_bias_level,
-
-	.reg_cache_size = WM8737_REGISTER_COUNT - 1, /* Skip reset */
-	.reg_word_size	= sizeof(u16),
-	.reg_cache_default = wm8737_reg,
 };
 
 static const struct of_device_id wm8737_of_match[] = {
@@ -640,24 +632,49 @@
 
 MODULE_DEVICE_TABLE(of, wm8737_of_match);
 
+static const struct regmap_config wm8737_regmap = {
+	.reg_bits = 7,
+	.val_bits = 9,
+	.max_register = WM8737_MAX_REGISTER,
+
+	.reg_defaults = wm8737_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(wm8737_reg_defaults),
+	.cache_type = REGCACHE_RBTREE,
+
+	.volatile_reg = wm8737_volatile,
+};
+
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 static __devinit int wm8737_i2c_probe(struct i2c_client *i2c,
 				      const struct i2c_device_id *id)
 {
 	struct wm8737_priv *wm8737;
-	int ret;
+	int ret, i;
 
-	wm8737 = kzalloc(sizeof(struct wm8737_priv), GFP_KERNEL);
+	wm8737 = devm_kzalloc(&i2c->dev, sizeof(struct wm8737_priv),
+			      GFP_KERNEL);
 	if (wm8737 == NULL)
 		return -ENOMEM;
 
+	for (i = 0; i < ARRAY_SIZE(wm8737->supplies); i++)
+		wm8737->supplies[i].supply = wm8737_supply_names[i];
+
+	ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8737->supplies),
+				      wm8737->supplies);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
+		return ret;
+	}
+
+	wm8737->regmap = devm_regmap_init_i2c(i2c, &wm8737_regmap);
+	if (IS_ERR(wm8737->regmap))
+		return PTR_ERR(wm8737->regmap);
+
 	i2c_set_clientdata(i2c, wm8737);
-	wm8737->control_type = SND_SOC_I2C;
 
 	ret =  snd_soc_register_codec(&i2c->dev,
 				      &soc_codec_dev_wm8737, &wm8737_dai, 1);
-	if (ret < 0)
-		kfree(wm8737);
+
 	return ret;
 
 }
@@ -665,7 +682,7 @@
 static __devexit int wm8737_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
-	kfree(i2c_get_clientdata(client));
+
 	return 0;
 }
 
@@ -691,26 +708,39 @@
 static int __devinit wm8737_spi_probe(struct spi_device *spi)
 {
 	struct wm8737_priv *wm8737;
-	int ret;
+	int ret, i;
 
-	wm8737 = kzalloc(sizeof(struct wm8737_priv), GFP_KERNEL);
+	wm8737 = devm_kzalloc(&spi->dev, sizeof(struct wm8737_priv),
+			      GFP_KERNEL);
 	if (wm8737 == NULL)
 		return -ENOMEM;
 
-	wm8737->control_type = SND_SOC_SPI;
+	for (i = 0; i < ARRAY_SIZE(wm8737->supplies); i++)
+		wm8737->supplies[i].supply = wm8737_supply_names[i];
+
+	ret = devm_regulator_bulk_get(&spi->dev, ARRAY_SIZE(wm8737->supplies),
+				      wm8737->supplies);
+	if (ret != 0) {
+		dev_err(&spi->dev, "Failed to request supplies: %d\n", ret);
+		return ret;
+	}
+
+	wm8737->regmap = devm_regmap_init_spi(spi, &wm8737_regmap);
+	if (IS_ERR(wm8737->regmap))
+		return PTR_ERR(wm8737->regmap);
+
 	spi_set_drvdata(spi, wm8737);
 
 	ret = snd_soc_register_codec(&spi->dev,
 				     &soc_codec_dev_wm8737, &wm8737_dai, 1);
-	if (ret < 0)
-		kfree(wm8737);
+
 	return ret;
 }
 
 static int __devexit wm8737_spi_remove(struct spi_device *spi)
 {
 	snd_soc_unregister_codec(&spi->dev);
-	kfree(spi_get_drvdata(spi));
+
 	return 0;
 }
 
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index 35f3d23..4281a08 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -18,6 +18,7 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/spi/spi.h>
+#include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <linux/of_device.h>
@@ -40,26 +41,43 @@
 
 /* codec private data */
 struct wm8741_priv {
-	enum snd_soc_control_type control_type;
+	struct regmap *regmap;
 	struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES];
 	unsigned int sysclk;
 	struct snd_pcm_hw_constraint_list *sysclk_constraints;
 };
 
-static const u16 wm8741_reg_defaults[WM8741_REGISTER_COUNT] = {
-	0x0000,     /* R0  - DACLLSB Attenuation */
-	0x0000,     /* R1  - DACLMSB Attenuation */
-	0x0000,     /* R2  - DACRLSB Attenuation */
-	0x0000,     /* R3  - DACRMSB Attenuation */
-	0x0000,     /* R4  - Volume Control */
-	0x000A,     /* R5  - Format Control */
-	0x0000,     /* R6  - Filter Control */
-	0x0000,     /* R7  - Mode Control 1 */
-	0x0002,     /* R8  - Mode Control 2 */
-	0x0000,	    /* R9  - Reset */
-	0x0002,     /* R32 - ADDITONAL_CONTROL_1 */
+static const struct reg_default wm8741_reg_defaults[] = {
+	{  0, 0x0000 },     /* R0  - DACLLSB Attenuation */
+	{  1, 0x0000 },     /* R1  - DACLMSB Attenuation */
+	{  2, 0x0000 },     /* R2  - DACRLSB Attenuation */
+	{  3, 0x0000 },     /* R3  - DACRMSB Attenuation */
+	{  4, 0x0000 },     /* R4  - Volume Control */
+	{  5, 0x000A },     /* R5  - Format Control */
+	{  6, 0x0000 },     /* R6  - Filter Control */
+	{  7, 0x0000 },     /* R7  - Mode Control 1 */
+	{  8, 0x0002 },     /* R8  - Mode Control 2 */
+	{ 32, 0x0002 },     /* R32 - ADDITONAL_CONTROL_1 */
 };
 
+static bool wm8741_readable(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case WM8741_DACLLSB_ATTENUATION:
+	case WM8741_DACLMSB_ATTENUATION:
+	case WM8741_DACRLSB_ATTENUATION:
+	case WM8741_DACRMSB_ATTENUATION:
+	case WM8741_VOLUME_CONTROL:
+	case WM8741_FORMAT_CONTROL:
+	case WM8741_FILTER_CONTROL:
+	case WM8741_MODE_CONTROL_1:
+	case WM8741_MODE_CONTROL_2:
+	case WM8741_ADDITIONAL_CONTROL_1:
+		return true;
+	default:
+		return false;
+	}
+}
 
 static int wm8741_reset(struct snd_soc_codec *codec)
 {
@@ -403,17 +421,6 @@
 {
 	struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
 	int ret = 0;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++)
-		wm8741->supplies[i].supply = wm8741_supply_names[i];
-
-	ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8741->supplies),
-				 wm8741->supplies);
-	if (ret != 0) {
-		dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
-		goto err;
-	}
 
 	ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies),
 				    wm8741->supplies);
@@ -422,7 +429,7 @@
 		goto err_get;
 	}
 
-	ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type);
+	ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
 	if (ret != 0) {
 		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
 		goto err_enable;
@@ -450,8 +457,6 @@
 err_enable:
 	regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
 err_get:
-	regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
-err:
 	return ret;
 }
 
@@ -460,7 +465,6 @@
 	struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec);
 
 	regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
-	regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
 
 	return 0;
 }
@@ -469,9 +473,6 @@
 	.probe =	wm8741_probe,
 	.remove =	wm8741_remove,
 	.resume =	wm8741_resume,
-	.reg_cache_size = ARRAY_SIZE(wm8741_reg_defaults),
-	.reg_word_size = sizeof(u16),
-	.reg_cache_default = wm8741_reg_defaults,
 
 	.controls = wm8741_snd_controls,
 	.num_controls = ARRAY_SIZE(wm8741_snd_controls),
@@ -487,20 +488,48 @@
 };
 MODULE_DEVICE_TABLE(of, wm8741_of_match);
 
+static const struct regmap_config wm8741_regmap = {
+	.reg_bits = 7,
+	.val_bits = 9,
+	.max_register = WM8741_MAX_REGISTER,
+
+	.reg_defaults = wm8741_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(wm8741_reg_defaults),
+	.cache_type = REGCACHE_RBTREE,
+
+	.readable_reg = wm8741_readable,
+};
+
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 static int wm8741_i2c_probe(struct i2c_client *i2c,
 			    const struct i2c_device_id *id)
 {
 	struct wm8741_priv *wm8741;
-	int ret;
+	int ret, i;
 
 	wm8741 = devm_kzalloc(&i2c->dev, sizeof(struct wm8741_priv),
 			      GFP_KERNEL);
 	if (wm8741 == NULL)
 		return -ENOMEM;
 
+	for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++)
+		wm8741->supplies[i].supply = wm8741_supply_names[i];
+
+	ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8741->supplies),
+				      wm8741->supplies);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
+		return ret;
+	}
+
+	wm8741->regmap = regmap_init_i2c(i2c, &wm8741_regmap);
+	if (IS_ERR(wm8741->regmap)) {
+		ret = PTR_ERR(wm8741->regmap);
+		dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret);
+		return ret;
+	}
+
 	i2c_set_clientdata(i2c, wm8741);
-	wm8741->control_type = SND_SOC_I2C;
 
 	ret = snd_soc_register_codec(&i2c->dev,
 				     &soc_codec_dev_wm8741, &wm8741_dai, 1);
@@ -536,14 +565,30 @@
 static int __devinit wm8741_spi_probe(struct spi_device *spi)
 {
 	struct wm8741_priv *wm8741;
-	int ret;
+	int ret, i;
 
 	wm8741 = devm_kzalloc(&spi->dev, sizeof(struct wm8741_priv),
 			     GFP_KERNEL);
 	if (wm8741 == NULL)
 		return -ENOMEM;
 
-	wm8741->control_type = SND_SOC_SPI;
+	for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++)
+		wm8741->supplies[i].supply = wm8741_supply_names[i];
+
+	ret = devm_regulator_bulk_get(&spi->dev, ARRAY_SIZE(wm8741->supplies),
+				      wm8741->supplies);
+	if (ret != 0) {
+		dev_err(&spi->dev, "Failed to request supplies: %d\n", ret);
+		return ret;
+	}
+
+	wm8741->regmap = regmap_init_spi(spi, &wm8741_regmap);
+	if (IS_ERR(wm8741->regmap)) {
+		ret = PTR_ERR(wm8741->regmap);
+		dev_err(&spi->dev, "Failed to init regmap: %d\n", ret);
+		return ret;
+	}
+
 	spi_set_drvdata(spi, wm8741);
 
 	ret = snd_soc_register_codec(&spi->dev,
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c
index a5127b4..c7c0034 100644
--- a/sound/soc/codecs/wm8770.c
+++ b/sound/soc/codecs/wm8770.c
@@ -724,24 +724,7 @@
 	.remove = __devexit_p(wm8770_spi_remove)
 };
 
-static int __init wm8770_modinit(void)
-{
-	int ret = 0;
-
-	ret = spi_register_driver(&wm8770_spi_driver);
-	if (ret) {
-		printk(KERN_ERR "Failed to register wm8770 SPI driver: %d\n",
-		       ret);
-	}
-	return ret;
-}
-module_init(wm8770_modinit);
-
-static void __exit wm8770_exit(void)
-{
-	spi_unregister_driver(&wm8770_spi_driver);
-}
-module_exit(wm8770_exit);
+module_spi_driver(wm8770_spi_driver);
 
 MODULE_DESCRIPTION("ASoC WM8770 driver");
 MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index 879c356..c32249d 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -19,6 +19,7 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/of_device.h>
+#include <linux/regmap.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
 #include <sound/core.h>
@@ -37,18 +38,46 @@
 
 /* codec private data */
 struct wm8776_priv {
-	enum snd_soc_control_type control_type;
+	struct regmap *regmap;
 	int sysclk[2];
 };
 
-static const u16 wm8776_reg[WM8776_CACHEREGNUM] = {
-	0x79, 0x79, 0x79, 0xff, 0xff,  /* 4 */
-	0xff, 0x00, 0x90, 0x00, 0x00,  /* 9 */
-	0x22, 0x22, 0x22, 0x08, 0xcf,  /* 14 */
-	0xcf, 0x7b, 0x00, 0x32, 0x00,  /* 19 */
-	0xa6, 0x01, 0x01
+static const struct reg_default wm8776_reg_defaults[] = {
+	{  0, 0x79 },
+	{  1, 0x79 },
+	{  2, 0x79 },
+	{  3, 0xff },
+	{  4, 0xff },
+	{  5, 0xff },
+	{  6, 0x00 },
+	{  7, 0x90 },
+	{  8, 0x00 },
+	{  9, 0x00 },
+	{ 10, 0x22 },
+	{ 11, 0x22 },
+	{ 12, 0x22 },
+	{ 13, 0x08 },
+	{ 14, 0xcf },
+	{ 15, 0xcf },
+	{ 16, 0x7b },
+	{ 17, 0x00 },
+	{ 18, 0x32 },
+	{ 19, 0x00 },
+	{ 20, 0xa6 },
+	{ 21, 0x01 },
+	{ 22, 0x01 },
 };
 
+static bool wm8776_volatile(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case WM8776_RESET:
+		return true;
+	default:
+		return false;
+	}
+}
+
 static int wm8776_reset(struct snd_soc_codec *codec)
 {
 	return snd_soc_write(codec, WM8776_RESET, 0);
@@ -306,6 +335,8 @@
 static int wm8776_set_bias_level(struct snd_soc_codec *codec,
 				 enum snd_soc_bias_level level)
 {
+	struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
+
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 		break;
@@ -313,7 +344,7 @@
 		break;
 	case SND_SOC_BIAS_STANDBY:
 		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
-			snd_soc_cache_sync(codec);
+			regcache_sync(wm8776->regmap);
 
 			/* Disable the global powerdown; DAPM does the rest */
 			snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 0);
@@ -396,10 +427,9 @@
 
 static int wm8776_probe(struct snd_soc_codec *codec)
 {
-	struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
 	int ret = 0;
 
-	ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8776->control_type);
+	ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
 	if (ret < 0) {
 		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
 		return ret;
@@ -434,9 +464,6 @@
 	.suspend = 	wm8776_suspend,
 	.resume =	wm8776_resume,
 	.set_bias_level = wm8776_set_bias_level,
-	.reg_cache_size = ARRAY_SIZE(wm8776_reg),
-	.reg_word_size = sizeof(u16),
-	.reg_cache_default = wm8776_reg,
 
 	.controls = wm8776_snd_controls,
 	.num_controls = ARRAY_SIZE(wm8776_snd_controls),
@@ -452,6 +479,18 @@
 };
 MODULE_DEVICE_TABLE(of, wm8776_of_match);
 
+static const struct regmap_config wm8776_regmap = {
+	.reg_bits = 7,
+	.val_bits = 9,
+	.max_register = WM8776_RESET,
+
+	.reg_defaults = wm8776_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(wm8776_reg_defaults),
+	.cache_type = REGCACHE_RBTREE,
+
+	.volatile_reg = wm8776_volatile,
+};
+
 #if defined(CONFIG_SPI_MASTER)
 static int __devinit wm8776_spi_probe(struct spi_device *spi)
 {
@@ -463,7 +502,10 @@
 	if (wm8776 == NULL)
 		return -ENOMEM;
 
-	wm8776->control_type = SND_SOC_SPI;
+	wm8776->regmap = devm_regmap_init_spi(spi, &wm8776_regmap);
+	if (IS_ERR(wm8776->regmap))
+		return PTR_ERR(wm8776->regmap);
+
 	spi_set_drvdata(spi, wm8776);
 
 	ret = snd_soc_register_codec(&spi->dev,
@@ -501,8 +543,11 @@
 	if (wm8776 == NULL)
 		return -ENOMEM;
 
+	wm8776->regmap = devm_regmap_init_i2c(i2c, &wm8776_regmap);
+	if (IS_ERR(wm8776->regmap))
+		return PTR_ERR(wm8776->regmap);
+
 	i2c_set_clientdata(i2c, wm8776);
-	wm8776->control_type = SND_SOC_I2C;
 
 	ret =  snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_wm8776, wm8776_dai, ARRAY_SIZE(wm8776_dai));
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index 077c962..e781f86 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -23,6 +23,7 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
+#include <linux/regmap.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
 #include <sound/core.h>
@@ -137,7 +138,7 @@
 #define WM8900_LRC_MASK 0x03ff
 
 struct wm8900_priv {
-	enum snd_soc_control_type control_type;
+	struct regmap *regmap;
 
 	u32 fll_in; /* FLL input frequency */
 	u32 fll_out; /* FLL output frequency */
@@ -147,54 +148,77 @@
  * wm8900 register cache.  We can't read the entire register space and we
  * have slow control buses so we cache the registers.
  */
-static const u16 wm8900_reg_defaults[WM8900_MAXREG] = {
-	0x8900, 0x0000,
-	0xc000, 0x0000,
-	0x4050, 0x4000,
-	0x0008, 0x0000,
-	0x0040, 0x0040,
-	0x1004, 0x00c0,
-	0x00c0, 0x0000,
-	0x0100, 0x00c0,
-	0x00c0, 0x0000,
-	0xb001, 0x0000,
-	0x0000, 0x0044,
-	0x004c, 0x004c,
-	0x0044, 0x0044,
-	0x0000, 0x0044,
-	0x0000, 0x0000,
-	0x0002, 0x0000,
-	0x0000, 0x0000,
-	0x0000, 0x0000,
-	0x0008, 0x0000,
-	0x0000, 0x0008,
-	0x0097, 0x0100,
-	0x0000, 0x0000,
-	0x0050, 0x0050,
-	0x0055, 0x0055,
-	0x0055, 0x0000,
-	0x0000, 0x0079,
-	0x0079, 0x0079,
-	0x0079, 0x0000,
-	/* Remaining registers all zero */
+static const struct reg_default wm8900_reg_defaults[] = {
+	{  1, 0x0000 },
+	{  2, 0xc000 },
+	{  3, 0x0000 },
+	{  4, 0x4050 },
+	{  5, 0x4000 },
+	{  6, 0x0008 },
+	{  7, 0x0000 },
+	{  8, 0x0040 },
+	{  9, 0x0040 },
+	{ 10, 0x1004 },
+	{ 11, 0x00c0 },
+	{ 12, 0x00c0 },
+	{ 13, 0x0000 },
+	{ 14, 0x0100 },
+	{ 15, 0x00c0 },
+	{ 16, 0x00c0 },
+	{ 17, 0x0000 },
+	{ 18, 0xb001 },
+	{ 19, 0x0000 },
+	{ 20, 0x0000 },
+	{ 21, 0x0044 },
+	{ 22, 0x004c },
+	{ 23, 0x004c },
+	{ 24, 0x0044 },
+	{ 25, 0x0044 },
+	{ 26, 0x0000 },
+	{ 27, 0x0044 },
+	{ 28, 0x0000 },
+	{ 29, 0x0000 },
+	{ 30, 0x0002 },
+	{ 31, 0x0000 },
+	{ 32, 0x0000 },
+	{ 33, 0x0000 },
+	{ 34, 0x0000 },
+	{ 35, 0x0000 },
+	{ 36, 0x0008 },
+	{ 37, 0x0000 },
+	{ 38, 0x0000 },
+	{ 39, 0x0008 },
+	{ 40, 0x0097 },
+	{ 41, 0x0100 },
+	{ 42, 0x0000 },
+	{ 43, 0x0000 },
+	{ 44, 0x0050 },
+	{ 45, 0x0050 },
+	{ 46, 0x0055 },
+	{ 47, 0x0055 },
+	{ 48, 0x0055 },
+	{ 49, 0x0000 },
+	{ 50, 0x0000 },
+	{ 51, 0x0079 },
+	{ 52, 0x0079 },
+	{ 53, 0x0079 },
+	{ 54, 0x0079 },
+	{ 55, 0x0000 },
 };
 
-static int wm8900_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
+static bool wm8900_volatile_register(struct device *dev, unsigned int reg)
 {
 	switch (reg) {
 	case WM8900_REG_ID:
-		return 1;
+		return true;
 	default:
-		return 0;
+		return false;
 	}
 }
 
 static void wm8900_reset(struct snd_soc_codec *codec)
 {
 	snd_soc_write(codec, WM8900_REG_RESET, 0);
-
-	memcpy(codec->reg_cache, wm8900_reg_defaults,
-	       sizeof(wm8900_reg_defaults));
 }
 
 static int wm8900_hp_event(struct snd_soc_dapm_widget *w,
@@ -469,10 +493,10 @@
 SOC_DAPM_SINGLE("RINPUT3 Switch", WM8900_REG_INCTL, 0, 1, 0),
 };
 
-static const char *wm9700_lp_mux[] = { "Disabled", "Enabled" };
+static const char *wm8900_lp_mux[] = { "Disabled", "Enabled" };
 
 static const struct soc_enum wm8900_lineout2_lp_mux =
-SOC_ENUM_SINGLE(WM8900_REG_LOUTMIXCTL1, 1, 2, wm9700_lp_mux);
+SOC_ENUM_SINGLE(WM8900_REG_LOUTMIXCTL1, 1, 2, wm8900_lp_mux);
 
 static const struct snd_kcontrol_new wm8900_lineout2_lp =
 SOC_DAPM_ENUM("Route", wm8900_lineout2_lp_mux);
@@ -1119,13 +1143,16 @@
 static int wm8900_resume(struct snd_soc_codec *codec)
 {
 	struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
-	u16 *cache;
-	int i, ret;
-
-	cache = kmemdup(codec->reg_cache, sizeof(wm8900_reg_defaults),
-			GFP_KERNEL);
+	int ret;
 
 	wm8900_reset(codec);
+
+	ret = regcache_sync(wm8900->regmap);
+	if (ret != 0) {
+		dev_err(codec->dev, "Failed to restore cache: %d\n", ret);
+		return ret;
+	}
+
 	wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
 	/* Restart the FLL? */
@@ -1139,27 +1166,18 @@
 		ret = wm8900_set_fll(codec, 0, fll_in, fll_out);
 		if (ret != 0) {
 			dev_err(codec->dev, "Failed to restart FLL\n");
-			kfree(cache);
 			return ret;
 		}
 	}
 
-	if (cache) {
-		for (i = 0; i < WM8900_MAXREG; i++)
-			snd_soc_write(codec, i, cache[i]);
-		kfree(cache);
-	} else
-		dev_err(codec->dev, "Unable to allocate register cache\n");
-
 	return 0;
 }
 
 static int wm8900_probe(struct snd_soc_codec *codec)
 {
-	struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec);
 	int ret = 0, reg;
 
-	ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8900->control_type);
+	ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
 	if (ret != 0) {
 		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
 		return ret;
@@ -1207,10 +1225,6 @@
 	.suspend =	wm8900_suspend,
 	.resume =	wm8900_resume,
 	.set_bias_level = wm8900_set_bias_level,
-	.volatile_register = wm8900_volatile_register,
-	.reg_cache_size = ARRAY_SIZE(wm8900_reg_defaults),
-	.reg_word_size = sizeof(u16),
-	.reg_cache_default = wm8900_reg_defaults,
 
 	.controls = wm8900_snd_controls,
 	.num_controls = ARRAY_SIZE(wm8900_snd_controls),
@@ -1220,30 +1234,44 @@
 	.num_dapm_routes = ARRAY_SIZE(wm8900_dapm_routes),
 };
 
+static const struct regmap_config wm8900_regmap = {
+	.reg_bits = 8,
+	.val_bits = 16,
+	.max_register = WM8900_MAXREG,
+
+	.reg_defaults = wm8900_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(wm8900_reg_defaults),
+	.cache_type = REGCACHE_RBTREE,
+
+	.volatile_reg = wm8900_volatile_register,
+};
+
 #if defined(CONFIG_SPI_MASTER)
 static int __devinit wm8900_spi_probe(struct spi_device *spi)
 {
 	struct wm8900_priv *wm8900;
 	int ret;
 
-	wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
+	wm8900 = devm_kzalloc(&spi->dev, sizeof(struct wm8900_priv),
+			      GFP_KERNEL);
 	if (wm8900 == NULL)
 		return -ENOMEM;
 
-	wm8900->control_type = SND_SOC_SPI;
+	wm8900->regmap = devm_regmap_init_spi(spi, &wm8900_regmap);
+	if (IS_ERR(wm8900->regmap))
+		return PTR_ERR(wm8900->regmap);
+
 	spi_set_drvdata(spi, wm8900);
 
 	ret = snd_soc_register_codec(&spi->dev,
 			&soc_codec_dev_wm8900, &wm8900_dai, 1);
-	if (ret < 0)
-		kfree(wm8900);
+
 	return ret;
 }
 
 static int __devexit wm8900_spi_remove(struct spi_device *spi)
 {
 	snd_soc_unregister_codec(&spi->dev);
-	kfree(spi_get_drvdata(spi));
 	return 0;
 }
 
@@ -1264,24 +1292,26 @@
 	struct wm8900_priv *wm8900;
 	int ret;
 
-	wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
+	wm8900 = devm_kzalloc(&i2c->dev, sizeof(struct wm8900_priv),
+			      GFP_KERNEL);
 	if (wm8900 == NULL)
 		return -ENOMEM;
 
+	wm8900->regmap = devm_regmap_init_i2c(i2c, &wm8900_regmap);
+	if (IS_ERR(wm8900->regmap))
+		return PTR_ERR(wm8900->regmap);
+
 	i2c_set_clientdata(i2c, wm8900);
-	wm8900->control_type = SND_SOC_I2C;
 
 	ret =  snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_wm8900, &wm8900_dai, 1);
-	if (ret < 0)
-		kfree(wm8900);
+
 	return ret;
 }
 
 static __devexit int wm8900_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
-	kfree(i2c_get_clientdata(client));
 	return 0;
 }
 
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 73f1c8d..839414f 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -2241,23 +2241,7 @@
 	.id_table = wm8903_i2c_id,
 };
 
-static int __init wm8903_modinit(void)
-{
-	int ret = 0;
-	ret = i2c_add_driver(&wm8903_i2c_driver);
-	if (ret != 0) {
-		printk(KERN_ERR "Failed to register wm8903 I2C driver: %d\n",
-		       ret);
-	}
-	return ret;
-}
-module_init(wm8903_modinit);
-
-static void __exit wm8903_exit(void)
-{
-	i2c_del_driver(&wm8903_i2c_driver);
-}
-module_exit(wm8903_exit);
+module_i2c_driver(wm8903_i2c_driver);
 
 MODULE_DESCRIPTION("ASoC WM8903 driver");
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.cm>");
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index dc4262e..7c8df52 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -1185,8 +1185,6 @@
 		snd_soc_dapm_new_controls(dapm, wm8904_dapm_widgets,
 					  ARRAY_SIZE(wm8904_dapm_widgets));
 
-		snd_soc_dapm_add_routes(dapm, core_intercon,
-					ARRAY_SIZE(core_intercon));
 		snd_soc_dapm_add_routes(dapm, adc_intercon,
 					ARRAY_SIZE(adc_intercon));
 		snd_soc_dapm_add_routes(dapm, dac_intercon,
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index 481a3d9..b20aa4e 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -785,23 +785,7 @@
 	.id_table = wm8940_i2c_id,
 };
 
-static int __init wm8940_modinit(void)
-{
-	int ret = 0;
-	ret = i2c_add_driver(&wm8940_i2c_driver);
-	if (ret != 0) {
-		printk(KERN_ERR "Failed to register wm8940 I2C driver: %d\n",
-		       ret);
-	}
-	return ret;
-}
-module_init(wm8940_modinit);
-
-static void __exit wm8940_exit(void)
-{
-	i2c_del_driver(&wm8940_i2c_driver);
-}
-module_exit(wm8940_exit);
+module_i2c_driver(wm8940_i2c_driver);
 
 MODULE_DESCRIPTION("ASoC WM8940 driver");
 MODULE_AUTHOR("Jonathan Cameron");
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index 61fe974..2f1c075 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -1071,23 +1071,7 @@
 	.id_table = wm8955_i2c_id,
 };
 
-static int __init wm8955_modinit(void)
-{
-	int ret = 0;
-	ret = i2c_add_driver(&wm8955_i2c_driver);
-	if (ret != 0) {
-		printk(KERN_ERR "Failed to register WM8955 I2C driver: %d\n",
-		       ret);
-	}
-	return ret;
-}
-module_init(wm8955_modinit);
-
-static void __exit wm8955_exit(void)
-{
-	i2c_del_driver(&wm8955_i2c_driver);
-}
-module_exit(wm8955_exit);
+module_i2c_driver(wm8955_i2c_driver);
 
 MODULE_DESCRIPTION("ASoC WM8955 driver");
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c
index 1332692..00121ba 100644
--- a/sound/soc/codecs/wm8958-dsp2.c
+++ b/sound/soc/codecs/wm8958-dsp2.c
@@ -946,7 +946,7 @@
 		wm8994->mbc_texts = kmalloc(sizeof(char *)
 					    * pdata->num_mbc_cfgs, GFP_KERNEL);
 		if (!wm8994->mbc_texts) {
-			dev_err(wm8994->codec->dev,
+			dev_err(wm8994->hubs.codec->dev,
 				"Failed to allocate %d MBC config texts\n",
 				pdata->num_mbc_cfgs);
 			return;
@@ -958,9 +958,10 @@
 		wm8994->mbc_enum.max = pdata->num_mbc_cfgs;
 		wm8994->mbc_enum.texts = wm8994->mbc_texts;
 
-		ret = snd_soc_add_codec_controls(wm8994->codec, control, 1);
+		ret = snd_soc_add_codec_controls(wm8994->hubs.codec,
+						 control, 1);
 		if (ret != 0)
-			dev_err(wm8994->codec->dev,
+			dev_err(wm8994->hubs.codec->dev,
 				"Failed to add MBC mode controls: %d\n", ret);
 	}
 
@@ -974,7 +975,7 @@
 		wm8994->vss_texts = kmalloc(sizeof(char *)
 					    * pdata->num_vss_cfgs, GFP_KERNEL);
 		if (!wm8994->vss_texts) {
-			dev_err(wm8994->codec->dev,
+			dev_err(wm8994->hubs.codec->dev,
 				"Failed to allocate %d VSS config texts\n",
 				pdata->num_vss_cfgs);
 			return;
@@ -986,9 +987,10 @@
 		wm8994->vss_enum.max = pdata->num_vss_cfgs;
 		wm8994->vss_enum.texts = wm8994->vss_texts;
 
-		ret = snd_soc_add_codec_controls(wm8994->codec, control, 1);
+		ret = snd_soc_add_codec_controls(wm8994->hubs.codec,
+						 control, 1);
 		if (ret != 0)
-			dev_err(wm8994->codec->dev,
+			dev_err(wm8994->hubs.codec->dev,
 				"Failed to add VSS mode controls: %d\n", ret);
 	}
 
@@ -1003,7 +1005,7 @@
 		wm8994->vss_hpf_texts = kmalloc(sizeof(char *)
 						* pdata->num_vss_hpf_cfgs, GFP_KERNEL);
 		if (!wm8994->vss_hpf_texts) {
-			dev_err(wm8994->codec->dev,
+			dev_err(wm8994->hubs.codec->dev,
 				"Failed to allocate %d VSS HPF config texts\n",
 				pdata->num_vss_hpf_cfgs);
 			return;
@@ -1015,9 +1017,10 @@
 		wm8994->vss_hpf_enum.max = pdata->num_vss_hpf_cfgs;
 		wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts;
 
-		ret = snd_soc_add_codec_controls(wm8994->codec, control, 1);
+		ret = snd_soc_add_codec_controls(wm8994->hubs.codec,
+						 control, 1);
 		if (ret != 0)
-			dev_err(wm8994->codec->dev,
+			dev_err(wm8994->hubs.codec->dev,
 				"Failed to add VSS HPFmode controls: %d\n",
 				ret);
 	}
@@ -1033,7 +1036,7 @@
 		wm8994->enh_eq_texts = kmalloc(sizeof(char *)
 						* pdata->num_enh_eq_cfgs, GFP_KERNEL);
 		if (!wm8994->enh_eq_texts) {
-			dev_err(wm8994->codec->dev,
+			dev_err(wm8994->hubs.codec->dev,
 				"Failed to allocate %d enhanced EQ config texts\n",
 				pdata->num_enh_eq_cfgs);
 			return;
@@ -1045,9 +1048,10 @@
 		wm8994->enh_eq_enum.max = pdata->num_enh_eq_cfgs;
 		wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts;
 
-		ret = snd_soc_add_codec_controls(wm8994->codec, control, 1);
+		ret = snd_soc_add_codec_controls(wm8994->hubs.codec,
+						 control, 1);
 		if (ret != 0)
-			dev_err(wm8994->codec->dev,
+			dev_err(wm8994->hubs.codec->dev,
 				"Failed to add enhanced EQ controls: %d\n",
 				ret);
 	}
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 96518ac..f0f6f660 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -52,25 +52,72 @@
  * We can't read the WM8960 register space when we are
  * using 2 wire for device control, so we cache them instead.
  */
-static const u16 wm8960_reg[WM8960_CACHEREGNUM] = {
-	0x0097, 0x0097, 0x0000, 0x0000,
-	0x0000, 0x0008, 0x0000, 0x000a,
-	0x01c0, 0x0000, 0x00ff, 0x00ff,
-	0x0000, 0x0000, 0x0000, 0x0000,
-	0x0000, 0x007b, 0x0100, 0x0032,
-	0x0000, 0x00c3, 0x00c3, 0x01c0,
-	0x0000, 0x0000, 0x0000, 0x0000,
-	0x0000, 0x0000, 0x0000, 0x0000,
-	0x0100, 0x0100, 0x0050, 0x0050,
-	0x0050, 0x0050, 0x0000, 0x0000,
-	0x0000, 0x0000, 0x0040, 0x0000,
-	0x0000, 0x0050, 0x0050, 0x0000,
-	0x0002, 0x0037, 0x004d, 0x0080,
-	0x0008, 0x0031, 0x0026, 0x00e9,
+static const struct reg_default wm8960_reg_defaults[] = {
+	{  0x0, 0x0097 },
+	{  0x1, 0x0097 },
+	{  0x2, 0x0000 },
+	{  0x3, 0x0000 },
+	{  0x4, 0x0000 },
+	{  0x5, 0x0008 },
+	{  0x6, 0x0000 },
+	{  0x7, 0x000a },
+	{  0x8, 0x01c0 },
+	{  0x9, 0x0000 },
+	{  0xa, 0x00ff },
+	{  0xb, 0x00ff },
+
+	{ 0x10, 0x0000 },
+	{ 0x11, 0x007b },
+	{ 0x12, 0x0100 },
+	{ 0x13, 0x0032 },
+	{ 0x14, 0x0000 },
+	{ 0x15, 0x00c3 },
+	{ 0x16, 0x00c3 },
+	{ 0x17, 0x01c0 },
+	{ 0x18, 0x0000 },
+	{ 0x19, 0x0000 },
+	{ 0x1a, 0x0000 },
+	{ 0x1b, 0x0000 },
+	{ 0x1c, 0x0000 },
+	{ 0x1d, 0x0000 },
+
+	{ 0x20, 0x0100 },
+	{ 0x21, 0x0100 },
+	{ 0x22, 0x0050 },
+
+	{ 0x25, 0x0050 },
+	{ 0x26, 0x0000 },
+	{ 0x27, 0x0000 },
+	{ 0x28, 0x0000 },
+	{ 0x29, 0x0000 },
+	{ 0x2a, 0x0040 },
+	{ 0x2b, 0x0000 },
+	{ 0x2c, 0x0000 },
+	{ 0x2d, 0x0050 },
+	{ 0x2e, 0x0050 },
+	{ 0x2f, 0x0000 },
+	{ 0x30, 0x0002 },
+	{ 0x31, 0x0037 },
+
+	{ 0x33, 0x0080 },
+	{ 0x34, 0x0008 },
+	{ 0x35, 0x0031 },
+	{ 0x36, 0x0026 },
+	{ 0x37, 0x00e9 },
 };
 
+static bool wm8960_volatile(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case WM8960_RESET:
+		return true;
+	default:
+		return false;
+	}
+}
+
 struct wm8960_priv {
-	enum snd_soc_control_type control_type;
+	struct regmap *regmap;
 	int (*set_bias_level)(struct snd_soc_codec *,
 			      enum snd_soc_bias_level level);
 	struct snd_soc_dapm_widget *lout1;
@@ -510,18 +557,25 @@
 	struct snd_soc_codec *codec = dai->codec;
 	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
 	u16 iface = snd_soc_read(codec, WM8960_IFACE1) & 0xfff3;
+	snd_pcm_format_t format = params_format(params);
 	int i;
 
 	/* bit size */
-	switch (params_format(params)) {
+	switch (format) {
 	case SNDRV_PCM_FORMAT_S16_LE:
+	case SNDRV_PCM_FORMAT_S16_BE:
 		break;
 	case SNDRV_PCM_FORMAT_S20_3LE:
+	case SNDRV_PCM_FORMAT_S20_3BE:
 		iface |= 0x0004;
 		break;
 	case SNDRV_PCM_FORMAT_S24_LE:
+	case SNDRV_PCM_FORMAT_S24_BE:
 		iface |= 0x0008;
 		break;
+	default:
+		dev_err(codec->dev, "unsupported format %i\n", format);
+		return -EINVAL;
 	}
 
 	/* Update filters for the new rate */
@@ -555,6 +609,8 @@
 static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
 				      enum snd_soc_bias_level level)
 {
+	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
+
 	switch (level) {
 	case SND_SOC_BIAS_ON:
 		break;
@@ -566,7 +622,7 @@
 
 	case SND_SOC_BIAS_STANDBY:
 		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
-			snd_soc_cache_sync(codec);
+			regcache_sync(wm8960->regmap);
 
 			/* Enable anti-pop features */
 			snd_soc_write(codec, WM8960_APOP1,
@@ -667,7 +723,7 @@
 			break;
 
 		case SND_SOC_BIAS_OFF:
-			snd_soc_cache_sync(codec);
+			regcache_sync(wm8960->regmap);
 			break;
 		default:
 			break;
@@ -906,16 +962,11 @@
 	if (!pdata) {
 		dev_warn(codec->dev, "No platform data supplied\n");
 	} else {
-		if (pdata->dres > WM8960_DRES_MAX) {
-			dev_err(codec->dev, "Invalid DRES: %d\n", pdata->dres);
-			pdata->dres = 0;
-		}
-
 		if (pdata->capless)
 			wm8960->set_bias_level = wm8960_set_bias_level_capless;
 	}
 
-	ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8960->control_type);
+	ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
 	if (ret < 0) {
 		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
 		return ret;
@@ -963,14 +1014,24 @@
 	.suspend =	wm8960_suspend,
 	.resume =	wm8960_resume,
 	.set_bias_level = wm8960_set_bias_level,
-	.reg_cache_size = ARRAY_SIZE(wm8960_reg),
-	.reg_word_size = sizeof(u16),
-	.reg_cache_default = wm8960_reg,
+};
+
+static const struct regmap_config wm8960_regmap = {
+	.reg_bits = 7,
+	.val_bits = 9,
+	.max_register = WM8960_PLL4,
+
+	.reg_defaults = wm8960_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(wm8960_reg_defaults),
+	.cache_type = REGCACHE_RBTREE,
+
+	.volatile_reg = wm8960_volatile,
 };
 
 static __devinit int wm8960_i2c_probe(struct i2c_client *i2c,
 				      const struct i2c_device_id *id)
 {
+	struct wm8960_data *pdata = dev_get_platdata(&i2c->dev);
 	struct wm8960_priv *wm8960;
 	int ret;
 
@@ -979,8 +1040,21 @@
 	if (wm8960 == NULL)
 		return -ENOMEM;
 
+	wm8960->regmap = regmap_init_i2c(i2c, &wm8960_regmap);
+	if (IS_ERR(wm8960->regmap))
+		return PTR_ERR(wm8960->regmap);
+
+	if (pdata && pdata->shared_lrclk) {
+		ret = regmap_update_bits(wm8960->regmap, WM8960_ADDCTL2,
+					 0x4, 0x4);
+		if (ret != 0) {
+			dev_err(&i2c->dev, "Failed to enable LRCM: %d\n",
+				ret);
+			return ret;
+		}
+	}
+
 	i2c_set_clientdata(i2c, wm8960);
-	wm8960->control_type = SND_SOC_I2C;
 
 	ret = snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_wm8960, &wm8960_dai, 1);
@@ -1010,23 +1084,7 @@
 	.id_table = wm8960_i2c_id,
 };
 
-static int __init wm8960_modinit(void)
-{
-	int ret = 0;
-	ret = i2c_add_driver(&wm8960_i2c_driver);
-	if (ret != 0) {
-		printk(KERN_ERR "Failed to register WM8960 I2C driver: %d\n",
-		       ret);
-	}
-	return ret;
-}
-module_init(wm8960_modinit);
-
-static void __exit wm8960_exit(void)
-{
-	i2c_del_driver(&wm8960_i2c_driver);
-}
-module_exit(wm8960_exit);
+module_i2c_driver(wm8960_i2c_driver);
 
 MODULE_DESCRIPTION("ASoC WM8960 driver");
 MODULE_AUTHOR("Liam Girdwood");
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 01edbcc..f387670 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -19,6 +19,7 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
+#include <linux/regmap.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -31,283 +32,159 @@
 
 #define WM8961_MAX_REGISTER                     0xFC
 
-static u16 wm8961_reg_defaults[] = {
-	0x009F,     /* R0   - Left Input volume */
-	0x009F,     /* R1   - Right Input volume */
-	0x0000,     /* R2   - LOUT1 volume */
-	0x0000,     /* R3   - ROUT1 volume */
-	0x0020,     /* R4   - Clocking1 */
-	0x0008,     /* R5   - ADC & DAC Control 1 */
-	0x0000,     /* R6   - ADC & DAC Control 2 */
-	0x000A,     /* R7   - Audio Interface 0 */
-	0x01F4,     /* R8   - Clocking2 */
-	0x0000,     /* R9   - Audio Interface 1 */
-	0x00FF,     /* R10  - Left DAC volume */
-	0x00FF,     /* R11  - Right DAC volume */
-	0x0000,     /* R12 */
-	0x0000,     /* R13 */
-	0x0040,     /* R14  - Audio Interface 2 */
-	0x0000,     /* R15  - Software Reset */
-	0x0000,     /* R16 */
-	0x007B,     /* R17  - ALC1 */
-	0x0000,     /* R18  - ALC2 */
-	0x0032,     /* R19  - ALC3 */
-	0x0000,     /* R20  - Noise Gate */
-	0x00C0,     /* R21  - Left ADC volume */
-	0x00C0,     /* R22  - Right ADC volume */
-	0x0120,     /* R23  - Additional control(1) */
-	0x0000,     /* R24  - Additional control(2) */
-	0x0000,     /* R25  - Pwr Mgmt (1) */
-	0x0000,     /* R26  - Pwr Mgmt (2) */
-	0x0000,     /* R27  - Additional Control (3) */
-	0x0000,     /* R28  - Anti-pop */
-	0x0000,     /* R29 */
-	0x005F,     /* R30  - Clocking 3 */
-	0x0000,     /* R31 */
-	0x0000,     /* R32  - ADCL signal path */
-	0x0000,     /* R33  - ADCR signal path */
-	0x0000,     /* R34 */
-	0x0000,     /* R35 */
-	0x0000,     /* R36 */
-	0x0000,     /* R37 */
-	0x0000,     /* R38 */
-	0x0000,     /* R39 */
-	0x0000,     /* R40  - LOUT2 volume */
-	0x0000,     /* R41  - ROUT2 volume */
-	0x0000,     /* R42 */
-	0x0000,     /* R43 */
-	0x0000,     /* R44 */
-	0x0000,     /* R45 */
-	0x0000,     /* R46 */
-	0x0000,     /* R47  - Pwr Mgmt (3) */
-	0x0023,     /* R48  - Additional Control (4) */
-	0x0000,     /* R49  - Class D Control 1 */
-	0x0000,     /* R50 */
-	0x0003,     /* R51  - Class D Control 2 */
-	0x0000,     /* R52 */
-	0x0000,     /* R53 */
-	0x0000,     /* R54 */
-	0x0000,     /* R55 */
-	0x0106,     /* R56  - Clocking 4 */
-	0x0000,     /* R57  - DSP Sidetone 0 */
-	0x0000,     /* R58  - DSP Sidetone 1 */
-	0x0000,     /* R59 */
-	0x0000,     /* R60  - DC Servo 0 */
-	0x0000,     /* R61  - DC Servo 1 */
-	0x0000,     /* R62 */
-	0x015E,     /* R63  - DC Servo 3 */
-	0x0010,     /* R64 */
-	0x0010,     /* R65  - DC Servo 5 */
-	0x0000,     /* R66 */
-	0x0001,     /* R67 */
-	0x0003,     /* R68  - Analogue PGA Bias */
-	0x0000,     /* R69  - Analogue HP 0 */
-	0x0060,     /* R70 */
-	0x01FB,     /* R71  - Analogue HP 2 */
-	0x0000,     /* R72  - Charge Pump 1 */
-	0x0065,     /* R73 */
-	0x005F,     /* R74 */
-	0x0059,     /* R75 */
-	0x006B,     /* R76 */
-	0x0038,     /* R77 */
-	0x000C,     /* R78 */
-	0x000A,     /* R79 */
-	0x006B,     /* R80 */
-	0x0000,     /* R81 */
-	0x0000,     /* R82  - Charge Pump B */
-	0x0087,     /* R83 */
-	0x0000,     /* R84 */
-	0x005C,     /* R85 */
-	0x0000,     /* R86 */
-	0x0000,     /* R87  - Write Sequencer 1 */
-	0x0000,     /* R88  - Write Sequencer 2 */
-	0x0000,     /* R89  - Write Sequencer 3 */
-	0x0000,     /* R90  - Write Sequencer 4 */
-	0x0000,     /* R91  - Write Sequencer 5 */
-	0x0000,     /* R92  - Write Sequencer 6 */
-	0x0000,     /* R93  - Write Sequencer 7 */
-	0x0000,     /* R94 */
-	0x0000,     /* R95 */
-	0x0000,     /* R96 */
-	0x0000,     /* R97 */
-	0x0000,     /* R98 */
-	0x0000,     /* R99 */
-	0x0000,     /* R100 */
-	0x0000,     /* R101 */
-	0x0000,     /* R102 */
-	0x0000,     /* R103 */
-	0x0000,     /* R104 */
-	0x0000,     /* R105 */
-	0x0000,     /* R106 */
-	0x0000,     /* R107 */
-	0x0000,     /* R108 */
-	0x0000,     /* R109 */
-	0x0000,     /* R110 */
-	0x0000,     /* R111 */
-	0x0000,     /* R112 */
-	0x0000,     /* R113 */
-	0x0000,     /* R114 */
-	0x0000,     /* R115 */
-	0x0000,     /* R116 */
-	0x0000,     /* R117 */
-	0x0000,     /* R118 */
-	0x0000,     /* R119 */
-	0x0000,     /* R120 */
-	0x0000,     /* R121 */
-	0x0000,     /* R122 */
-	0x0000,     /* R123 */
-	0x0000,     /* R124 */
-	0x0000,     /* R125 */
-	0x0000,     /* R126 */
-	0x0000,     /* R127 */
-	0x0000,     /* R128 */
-	0x0000,     /* R129 */
-	0x0000,     /* R130 */
-	0x0000,     /* R131 */
-	0x0000,     /* R132 */
-	0x0000,     /* R133 */
-	0x0000,     /* R134 */
-	0x0000,     /* R135 */
-	0x0000,     /* R136 */
-	0x0000,     /* R137 */
-	0x0000,     /* R138 */
-	0x0000,     /* R139 */
-	0x0000,     /* R140 */
-	0x0000,     /* R141 */
-	0x0000,     /* R142 */
-	0x0000,     /* R143 */
-	0x0000,     /* R144 */
-	0x0000,     /* R145 */
-	0x0000,     /* R146 */
-	0x0000,     /* R147 */
-	0x0000,     /* R148 */
-	0x0000,     /* R149 */
-	0x0000,     /* R150 */
-	0x0000,     /* R151 */
-	0x0000,     /* R152 */
-	0x0000,     /* R153 */
-	0x0000,     /* R154 */
-	0x0000,     /* R155 */
-	0x0000,     /* R156 */
-	0x0000,     /* R157 */
-	0x0000,     /* R158 */
-	0x0000,     /* R159 */
-	0x0000,     /* R160 */
-	0x0000,     /* R161 */
-	0x0000,     /* R162 */
-	0x0000,     /* R163 */
-	0x0000,     /* R164 */
-	0x0000,     /* R165 */
-	0x0000,     /* R166 */
-	0x0000,     /* R167 */
-	0x0000,     /* R168 */
-	0x0000,     /* R169 */
-	0x0000,     /* R170 */
-	0x0000,     /* R171 */
-	0x0000,     /* R172 */
-	0x0000,     /* R173 */
-	0x0000,     /* R174 */
-	0x0000,     /* R175 */
-	0x0000,     /* R176 */
-	0x0000,     /* R177 */
-	0x0000,     /* R178 */
-	0x0000,     /* R179 */
-	0x0000,     /* R180 */
-	0x0000,     /* R181 */
-	0x0000,     /* R182 */
-	0x0000,     /* R183 */
-	0x0000,     /* R184 */
-	0x0000,     /* R185 */
-	0x0000,     /* R186 */
-	0x0000,     /* R187 */
-	0x0000,     /* R188 */
-	0x0000,     /* R189 */
-	0x0000,     /* R190 */
-	0x0000,     /* R191 */
-	0x0000,     /* R192 */
-	0x0000,     /* R193 */
-	0x0000,     /* R194 */
-	0x0000,     /* R195 */
-	0x0030,     /* R196 */
-	0x0006,     /* R197 */
-	0x0000,     /* R198 */
-	0x0060,     /* R199 */
-	0x0000,     /* R200 */
-	0x003F,     /* R201 */
-	0x0000,     /* R202 */
-	0x0000,     /* R203 */
-	0x0000,     /* R204 */
-	0x0001,     /* R205 */
-	0x0000,     /* R206 */
-	0x0181,     /* R207 */
-	0x0005,     /* R208 */
-	0x0008,     /* R209 */
-	0x0008,     /* R210 */
-	0x0000,     /* R211 */
-	0x013B,     /* R212 */
-	0x0000,     /* R213 */
-	0x0000,     /* R214 */
-	0x0000,     /* R215 */
-	0x0000,     /* R216 */
-	0x0070,     /* R217 */
-	0x0000,     /* R218 */
-	0x0000,     /* R219 */
-	0x0000,     /* R220 */
-	0x0000,     /* R221 */
-	0x0000,     /* R222 */
-	0x0003,     /* R223 */
-	0x0000,     /* R224 */
-	0x0000,     /* R225 */
-	0x0001,     /* R226 */
-	0x0008,     /* R227 */
-	0x0000,     /* R228 */
-	0x0000,     /* R229 */
-	0x0000,     /* R230 */
-	0x0000,     /* R231 */
-	0x0004,     /* R232 */
-	0x0000,     /* R233 */
-	0x0000,     /* R234 */
-	0x0000,     /* R235 */
-	0x0000,     /* R236 */
-	0x0000,     /* R237 */
-	0x0080,     /* R238 */
-	0x0000,     /* R239 */
-	0x0000,     /* R240 */
-	0x0000,     /* R241 */
-	0x0000,     /* R242 */
-	0x0000,     /* R243 */
-	0x0000,     /* R244 */
-	0x0052,     /* R245 */
-	0x0110,     /* R246 */
-	0x0040,     /* R247 */
-	0x0000,     /* R248 */
-	0x0030,     /* R249 */
-	0x0000,     /* R250 */
-	0x0000,     /* R251 */
-	0x0001,     /* R252 - General test 1 */
+static const struct reg_default wm8961_reg_defaults[] = {
+	{  0, 0x009F },     /* R0   - Left Input volume */
+	{  1, 0x009F },     /* R1   - Right Input volume */
+	{  2, 0x0000 },     /* R2   - LOUT1 volume */
+	{  3, 0x0000 },     /* R3   - ROUT1 volume */
+	{  4, 0x0020 },     /* R4   - Clocking1 */
+	{  5, 0x0008 },     /* R5   - ADC & DAC Control 1 */
+	{  6, 0x0000 },     /* R6   - ADC & DAC Control 2 */
+	{  7, 0x000A },     /* R7   - Audio Interface 0 */
+	{  8, 0x01F4 },     /* R8   - Clocking2 */
+	{  9, 0x0000 },     /* R9   - Audio Interface 1 */
+	{ 10, 0x00FF },     /* R10  - Left DAC volume */
+	{ 11, 0x00FF },     /* R11  - Right DAC volume */
+
+	{ 14, 0x0040 },     /* R14  - Audio Interface 2 */
+
+	{ 17, 0x007B },     /* R17  - ALC1 */
+	{ 18, 0x0000 },     /* R18  - ALC2 */
+	{ 19, 0x0032 },     /* R19  - ALC3 */
+	{ 20, 0x0000 },     /* R20  - Noise Gate */
+	{ 21, 0x00C0 },     /* R21  - Left ADC volume */
+	{ 22, 0x00C0 },     /* R22  - Right ADC volume */
+	{ 23, 0x0120 },     /* R23  - Additional control(1) */
+	{ 24, 0x0000 },     /* R24  - Additional control(2) */
+	{ 25, 0x0000 },     /* R25  - Pwr Mgmt (1) */
+	{ 26, 0x0000 },     /* R26  - Pwr Mgmt (2) */
+	{ 27, 0x0000 },     /* R27  - Additional Control (3) */
+	{ 28, 0x0000 },     /* R28  - Anti-pop */
+
+	{ 30, 0x005F },     /* R30  - Clocking 3 */
+
+	{ 32, 0x0000 },     /* R32  - ADCL signal path */
+	{ 33, 0x0000 },     /* R33  - ADCR signal path */
+
+	{ 40, 0x0000 },     /* R40  - LOUT2 volume */
+	{ 41, 0x0000 },     /* R41  - ROUT2 volume */
+
+	{ 47, 0x0000 },     /* R47  - Pwr Mgmt (3) */
+	{ 48, 0x0023 },     /* R48  - Additional Control (4) */
+	{ 49, 0x0000 },     /* R49  - Class D Control 1 */
+
+	{ 51, 0x0003 },     /* R51  - Class D Control 2 */
+
+	{ 56, 0x0106 },     /* R56  - Clocking 4 */
+	{ 57, 0x0000 },     /* R57  - DSP Sidetone 0 */
+	{ 58, 0x0000 },     /* R58  - DSP Sidetone 1 */
+
+	{ 60, 0x0000 },     /* R60  - DC Servo 0 */
+	{ 61, 0x0000 },     /* R61  - DC Servo 1 */
+
+	{ 63, 0x015E },     /* R63  - DC Servo 3 */
+
+	{ 65, 0x0010 },     /* R65  - DC Servo 5 */
+
+	{ 68, 0x0003 },     /* R68  - Analogue PGA Bias */
+	{ 69, 0x0000 },     /* R69  - Analogue HP 0 */
+
+	{ 71, 0x01FB },     /* R71  - Analogue HP 2 */
+	{ 72, 0x0000 },     /* R72  - Charge Pump 1 */
+
+	{ 82, 0x0000 },     /* R82  - Charge Pump B */
+
+	{ 87, 0x0000 },     /* R87  - Write Sequencer 1 */
+	{ 88, 0x0000 },     /* R88  - Write Sequencer 2 */
+	{ 89, 0x0000 },     /* R89  - Write Sequencer 3 */
+	{ 90, 0x0000 },     /* R90  - Write Sequencer 4 */
+	{ 91, 0x0000 },     /* R91  - Write Sequencer 5 */
+	{ 92, 0x0000 },     /* R92  - Write Sequencer 6 */
+	{ 93, 0x0000 },     /* R93  - Write Sequencer 7 */
+
+	{ 252, 0x0001 },     /* R252 - General test 1 */
 };
 
 struct wm8961_priv {
-	enum snd_soc_control_type control_type;
+	struct regmap *regmap;
 	int sysclk;
 };
 
-static int wm8961_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
+static bool wm8961_volatile(struct device *dev, unsigned int reg)
 {
 	switch (reg) {
 	case WM8961_SOFTWARE_RESET:
 	case WM8961_WRITE_SEQUENCER_7:
 	case WM8961_DC_SERVO_1:
-		return 1;
+		return true;
 
 	default:
-		return 0;
+		return false;
 	}
 }
 
-static int wm8961_reset(struct snd_soc_codec *codec)
+static bool wm8961_readable(struct device *dev, unsigned int reg)
 {
-	return snd_soc_write(codec, WM8961_SOFTWARE_RESET, 0);
+	switch (reg) {
+	case WM8961_LEFT_INPUT_VOLUME:
+	case WM8961_RIGHT_INPUT_VOLUME:
+	case WM8961_LOUT1_VOLUME:
+	case WM8961_ROUT1_VOLUME:
+	case WM8961_CLOCKING1:
+	case WM8961_ADC_DAC_CONTROL_1:
+	case WM8961_ADC_DAC_CONTROL_2:
+	case WM8961_AUDIO_INTERFACE_0:
+	case WM8961_CLOCKING2:
+	case WM8961_AUDIO_INTERFACE_1:
+	case WM8961_LEFT_DAC_VOLUME:
+	case WM8961_RIGHT_DAC_VOLUME:
+	case WM8961_AUDIO_INTERFACE_2:
+	case WM8961_SOFTWARE_RESET:
+	case WM8961_ALC1:
+	case WM8961_ALC2:
+	case WM8961_ALC3:
+	case WM8961_NOISE_GATE:
+	case WM8961_LEFT_ADC_VOLUME:
+	case WM8961_RIGHT_ADC_VOLUME:
+	case WM8961_ADDITIONAL_CONTROL_1:
+	case WM8961_ADDITIONAL_CONTROL_2:
+	case WM8961_PWR_MGMT_1:
+	case WM8961_PWR_MGMT_2:
+	case WM8961_ADDITIONAL_CONTROL_3:
+	case WM8961_ANTI_POP:
+	case WM8961_CLOCKING_3:
+	case WM8961_ADCL_SIGNAL_PATH:
+	case WM8961_ADCR_SIGNAL_PATH:
+	case WM8961_LOUT2_VOLUME:
+	case WM8961_ROUT2_VOLUME:
+	case WM8961_PWR_MGMT_3:
+	case WM8961_ADDITIONAL_CONTROL_4:
+	case WM8961_CLASS_D_CONTROL_1:
+	case WM8961_CLASS_D_CONTROL_2:
+	case WM8961_CLOCKING_4:
+	case WM8961_DSP_SIDETONE_0:
+	case WM8961_DSP_SIDETONE_1:
+	case WM8961_DC_SERVO_0:
+	case WM8961_DC_SERVO_1:
+	case WM8961_DC_SERVO_3:
+	case WM8961_DC_SERVO_5:
+	case WM8961_ANALOGUE_PGA_BIAS:
+	case WM8961_ANALOGUE_HP_0:
+	case WM8961_ANALOGUE_HP_2:
+	case WM8961_CHARGE_PUMP_1:
+	case WM8961_CHARGE_PUMP_B:
+	case WM8961_WRITE_SEQUENCER_1:
+	case WM8961_WRITE_SEQUENCER_2:
+	case WM8961_WRITE_SEQUENCER_3:
+	case WM8961_WRITE_SEQUENCER_4:
+	case WM8961_WRITE_SEQUENCER_5:
+	case WM8961_WRITE_SEQUENCER_6:
+	case WM8961_WRITE_SEQUENCER_7:
+	case WM8961_GENERAL_TEST_1:
+		return true;
+	default:
+		return false;
+	}
 }
 
 /*
@@ -962,33 +839,12 @@
 	int ret = 0;
 	u16 reg;
 
-	ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
+	ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
 	if (ret != 0) {
 		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
 		return ret;
 	}
 
-	reg = snd_soc_read(codec, WM8961_SOFTWARE_RESET);
-	if (reg != 0x1801) {
-		dev_err(codec->dev, "Device is not a WM8961: ID=0x%x\n", reg);
-		return -EINVAL;
-	}
-
-	/* This isn't volatile - readback doesn't correspond to write */
-	codec->cache_bypass = 1;
-	reg = snd_soc_read(codec, WM8961_RIGHT_INPUT_VOLUME);
-	codec->cache_bypass = 0;
-	dev_info(codec->dev, "WM8961 family %d revision %c\n",
-		 (reg & WM8961_DEVICE_ID_MASK) >> WM8961_DEVICE_ID_SHIFT,
-		 ((reg & WM8961_CHIP_REV_MASK) >> WM8961_CHIP_REV_SHIFT)
-		 + 'A');
-
-	ret = wm8961_reset(codec);
-	if (ret < 0) {
-		dev_err(codec->dev, "Failed to issue reset\n");
-		return ret;
-	}
-
 	/* Enable class W */
 	reg = snd_soc_read(codec, WM8961_CHARGE_PUMP_B);
 	reg |= WM8961_CP_DYN_PWR_MASK;
@@ -1066,16 +922,26 @@
 	.suspend =	wm8961_suspend,
 	.resume =	wm8961_resume,
 	.set_bias_level = wm8961_set_bias_level,
-	.reg_cache_size = ARRAY_SIZE(wm8961_reg_defaults),
-	.reg_word_size = sizeof(u16),
-	.reg_cache_default = wm8961_reg_defaults,
-	.volatile_register = wm8961_volatile_register,
+};
+
+static const struct regmap_config wm8961_regmap = {
+	.reg_bits = 8,
+	.val_bits = 16,
+	.max_register = WM8961_MAX_REGISTER,
+
+	.reg_defaults = wm8961_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(wm8961_reg_defaults),
+	.cache_type = REGCACHE_RBTREE,
+
+	.volatile_reg = wm8961_volatile,
+	.readable_reg = wm8961_readable,
 };
 
 static __devinit int wm8961_i2c_probe(struct i2c_client *i2c,
 				      const struct i2c_device_id *id)
 {
 	struct wm8961_priv *wm8961;
+	unsigned int val;
 	int ret;
 
 	wm8961 = devm_kzalloc(&i2c->dev, sizeof(struct wm8961_priv),
@@ -1083,6 +949,42 @@
 	if (wm8961 == NULL)
 		return -ENOMEM;
 
+	wm8961->regmap = devm_regmap_init_i2c(i2c, &wm8961_regmap);
+	if (IS_ERR(wm8961->regmap))
+		return PTR_ERR(wm8961->regmap);
+
+	ret = regmap_read(wm8961->regmap, WM8961_SOFTWARE_RESET, &val);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret);
+		return ret;
+	}
+
+	if (val != 0x1801) {
+		dev_err(&i2c->dev, "Device is not a WM8961: ID=0x%x\n", val);
+		return -EINVAL;
+	}
+
+	/* This isn't volatile - readback doesn't correspond to write */
+	regcache_cache_bypass(wm8961->regmap, true);
+	ret = regmap_read(wm8961->regmap, WM8961_RIGHT_INPUT_VOLUME, &val);
+	regcache_cache_bypass(wm8961->regmap, false);
+
+	if (ret != 0) {
+		dev_err(&i2c->dev, "Failed to read chip revision: %d\n", ret);
+		return ret;
+	}
+
+	dev_info(&i2c->dev, "WM8961 family %d revision %c\n",
+		 (val & WM8961_DEVICE_ID_MASK) >> WM8961_DEVICE_ID_SHIFT,
+		 ((val & WM8961_CHIP_REV_MASK) >> WM8961_CHIP_REV_SHIFT)
+		 + 'A');
+
+	ret = regmap_write(wm8961->regmap, WM8961_SOFTWARE_RESET, 0x1801);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret);
+		return ret;
+	}
+
 	i2c_set_clientdata(i2c, wm8961);
 
 	ret = snd_soc_register_codec(&i2c->dev,
@@ -1114,23 +1016,7 @@
 	.id_table = wm8961_i2c_id,
 };
 
-static int __init wm8961_modinit(void)
-{
-	int ret = 0;
-	ret = i2c_add_driver(&wm8961_i2c_driver);
-	if (ret != 0) {
-		printk(KERN_ERR "Failed to register wm8961 I2C driver: %d\n",
-		       ret);
-	}
-	return ret;
-}
-module_init(wm8961_modinit);
-
-static void __exit wm8961_exit(void)
-{
-	i2c_del_driver(&wm8961_i2c_driver);
-}
-module_exit(wm8961_exit);
+module_i2c_driver(wm8961_i2c_driver);
 
 MODULE_DESCRIPTION("ASoC WM8961 driver");
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index eef783f..5ce6477 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -721,23 +721,7 @@
 	.id_table = wm8971_i2c_id,
 };
 
-static int __init wm8971_modinit(void)
-{
-	int ret = 0;
-	ret = i2c_add_driver(&wm8971_i2c_driver);
-	if (ret != 0) {
-		printk(KERN_ERR "Failed to register WM8971 I2C driver: %d\n",
-		       ret);
-	}
-	return ret;
-}
-module_init(wm8971_modinit);
-
-static void __exit wm8971_exit(void)
-{
-	i2c_del_driver(&wm8971_i2c_driver);
-}
-module_exit(wm8971_exit);
+module_i2c_driver(wm8971_i2c_driver);
 
 MODULE_DESCRIPTION("ASoC WM8971 driver");
 MODULE_AUTHOR("Lab126");
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index d93c03f..9a39511 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -659,23 +659,7 @@
 	.id_table = wm8974_i2c_id,
 };
 
-static int __init wm8974_modinit(void)
-{
-	int ret = 0;
-	ret = i2c_add_driver(&wm8974_i2c_driver);
-	if (ret != 0) {
-		printk(KERN_ERR "Failed to register wm8974 I2C driver: %d\n",
-		       ret);
-	}
-	return ret;
-}
-module_init(wm8974_modinit);
-
-static void __exit wm8974_exit(void)
-{
-	i2c_del_driver(&wm8974_i2c_driver);
-}
-module_exit(wm8974_exit);
+module_i2c_driver(wm8974_i2c_driver);
 
 MODULE_DESCRIPTION("ASoC WM8974 driver");
 MODULE_AUTHOR("Liam Girdwood");
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index a5be3ad..5421fd9 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -1105,23 +1105,7 @@
 	.id_table = wm8978_i2c_id,
 };
 
-static int __init wm8978_modinit(void)
-{
-	int ret = 0;
-	ret = i2c_add_driver(&wm8978_i2c_driver);
-	if (ret != 0) {
-		printk(KERN_ERR "Failed to register WM8978 I2C driver: %d\n",
-		       ret);
-	}
-	return ret;
-}
-module_init(wm8978_modinit);
-
-static void __exit wm8978_exit(void)
-{
-	i2c_del_driver(&wm8978_i2c_driver);
-}
-module_exit(wm8978_exit);
+module_i2c_driver(wm8978_i2c_driver);
 
 MODULE_DESCRIPTION("ASoC WM8978 codec driver");
 MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c
index 367388f..d8879f2 100644
--- a/sound/soc/codecs/wm8983.c
+++ b/sound/soc/codecs/wm8983.c
@@ -16,6 +16,7 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/i2c.h>
+#include <linux/regmap.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
 #include <sound/core.h>
@@ -27,61 +28,60 @@
 
 #include "wm8983.h"
 
-static const u16 wm8983_reg_defs[WM8983_MAX_REGISTER + 1] = {
-	[0x00] = 0x0000,     /* R0  - Software Reset */
-	[0x01] = 0x0000,     /* R1  - Power management 1 */
-	[0x02] = 0x0000,     /* R2  - Power management 2 */
-	[0x03] = 0x0000,     /* R3  - Power management 3 */
-	[0x04] = 0x0050,     /* R4  - Audio Interface */
-	[0x05] = 0x0000,     /* R5  - Companding control */
-	[0x06] = 0x0140,     /* R6  - Clock Gen control */
-	[0x07] = 0x0000,     /* R7  - Additional control */
-	[0x08] = 0x0000,     /* R8  - GPIO Control */
-	[0x09] = 0x0000,     /* R9  - Jack Detect Control 1 */
-	[0x0A] = 0x0000,     /* R10 - DAC Control */
-	[0x0B] = 0x00FF,     /* R11 - Left DAC digital Vol */
-	[0x0C] = 0x00FF,     /* R12 - Right DAC digital vol */
-	[0x0D] = 0x0000,     /* R13 - Jack Detect Control 2 */
-	[0x0E] = 0x0100,     /* R14 - ADC Control */
-	[0x0F] = 0x00FF,     /* R15 - Left ADC Digital Vol */
-	[0x10] = 0x00FF,     /* R16 - Right ADC Digital Vol */
-	[0x12] = 0x012C,     /* R18 - EQ1 - low shelf */
-	[0x13] = 0x002C,     /* R19 - EQ2 - peak 1 */
-	[0x14] = 0x002C,     /* R20 - EQ3 - peak 2 */
-	[0x15] = 0x002C,     /* R21 - EQ4 - peak 3 */
-	[0x16] = 0x002C,     /* R22 - EQ5 - high shelf */
-	[0x18] = 0x0032,     /* R24 - DAC Limiter 1 */
-	[0x19] = 0x0000,     /* R25 - DAC Limiter 2 */
-	[0x1B] = 0x0000,     /* R27 - Notch Filter 1 */
-	[0x1C] = 0x0000,     /* R28 - Notch Filter 2 */
-	[0x1D] = 0x0000,     /* R29 - Notch Filter 3 */
-	[0x1E] = 0x0000,     /* R30 - Notch Filter 4 */
-	[0x20] = 0x0038,     /* R32 - ALC control 1 */
-	[0x21] = 0x000B,     /* R33 - ALC control 2 */
-	[0x22] = 0x0032,     /* R34 - ALC control 3 */
-	[0x23] = 0x0000,     /* R35 - Noise Gate */
-	[0x24] = 0x0008,     /* R36 - PLL N */
-	[0x25] = 0x000C,     /* R37 - PLL K 1 */
-	[0x26] = 0x0093,     /* R38 - PLL K 2 */
-	[0x27] = 0x00E9,     /* R39 - PLL K 3 */
-	[0x29] = 0x0000,     /* R41 - 3D control */
-	[0x2A] = 0x0000,     /* R42 - OUT4 to ADC */
-	[0x2B] = 0x0000,     /* R43 - Beep control */
-	[0x2C] = 0x0033,     /* R44 - Input ctrl */
-	[0x2D] = 0x0010,     /* R45 - Left INP PGA gain ctrl */
-	[0x2E] = 0x0010,     /* R46 - Right INP PGA gain ctrl */
-	[0x2F] = 0x0100,     /* R47 - Left ADC BOOST ctrl */
-	[0x30] = 0x0100,     /* R48 - Right ADC BOOST ctrl */
-	[0x31] = 0x0002,     /* R49 - Output ctrl */
-	[0x32] = 0x0001,     /* R50 - Left mixer ctrl */
-	[0x33] = 0x0001,     /* R51 - Right mixer ctrl */
-	[0x34] = 0x0039,     /* R52 - LOUT1 (HP) volume ctrl */
-	[0x35] = 0x0039,     /* R53 - ROUT1 (HP) volume ctrl */
-	[0x36] = 0x0039,     /* R54 - LOUT2 (SPK) volume ctrl */
-	[0x37] = 0x0039,     /* R55 - ROUT2 (SPK) volume ctrl */
-	[0x38] = 0x0001,     /* R56 - OUT3 mixer ctrl */
-	[0x39] = 0x0001,     /* R57 - OUT4 (MONO) mix ctrl */
-	[0x3D] = 0x0000      /* R61 - BIAS CTRL */
+static const struct reg_default wm8983_defaults[] = {
+	{ 0x01, 0x0000 },     /* R1  - Power management 1 */
+	{ 0x02, 0x0000 },     /* R2  - Power management 2 */
+	{ 0x03, 0x0000 },     /* R3  - Power management 3 */
+	{ 0x04, 0x0050 },     /* R4  - Audio Interface */
+	{ 0x05, 0x0000 },     /* R5  - Companding control */
+	{ 0x06, 0x0140 },     /* R6  - Clock Gen control */
+	{ 0x07, 0x0000 },     /* R7  - Additional control */
+	{ 0x08, 0x0000 },     /* R8  - GPIO Control */
+	{ 0x09, 0x0000 },     /* R9  - Jack Detect Control 1 */
+	{ 0x0A, 0x0000 },     /* R10 - DAC Control */
+	{ 0x0B, 0x00FF },     /* R11 - Left DAC digital Vol */
+	{ 0x0C, 0x00FF },     /* R12 - Right DAC digital vol */
+	{ 0x0D, 0x0000 },     /* R13 - Jack Detect Control 2 */
+	{ 0x0E, 0x0100 },     /* R14 - ADC Control */
+	{ 0x0F, 0x00FF },     /* R15 - Left ADC Digital Vol */
+	{ 0x10, 0x00FF },     /* R16 - Right ADC Digital Vol */
+	{ 0x12, 0x012C },     /* R18 - EQ1 - low shelf */
+	{ 0x13, 0x002C },     /* R19 - EQ2 - peak 1 */
+	{ 0x14, 0x002C },     /* R20 - EQ3 - peak 2 */
+	{ 0x15, 0x002C },     /* R21 - EQ4 - peak 3 */
+	{ 0x16, 0x002C },     /* R22 - EQ5 - high shelf */
+	{ 0x18, 0x0032 },     /* R24 - DAC Limiter 1 */
+	{ 0x19, 0x0000 },     /* R25 - DAC Limiter 2 */
+	{ 0x1B, 0x0000 },     /* R27 - Notch Filter 1 */
+	{ 0x1C, 0x0000 },     /* R28 - Notch Filter 2 */
+	{ 0x1D, 0x0000 },     /* R29 - Notch Filter 3 */
+	{ 0x1E, 0x0000 },     /* R30 - Notch Filter 4 */
+	{ 0x20, 0x0038 },     /* R32 - ALC control 1 */
+	{ 0x21, 0x000B },     /* R33 - ALC control 2 */
+	{ 0x22, 0x0032 },     /* R34 - ALC control 3 */
+	{ 0x23, 0x0000 },     /* R35 - Noise Gate */
+	{ 0x24, 0x0008 },     /* R36 - PLL N */
+	{ 0x25, 0x000C },     /* R37 - PLL K 1 */
+	{ 0x26, 0x0093 },     /* R38 - PLL K 2 */
+	{ 0x27, 0x00E9 },     /* R39 - PLL K 3 */
+	{ 0x29, 0x0000 },     /* R41 - 3D control */
+	{ 0x2A, 0x0000 },     /* R42 - OUT4 to ADC */
+	{ 0x2B, 0x0000 },     /* R43 - Beep control */
+	{ 0x2C, 0x0033 },     /* R44 - Input ctrl */
+	{ 0x2D, 0x0010 },     /* R45 - Left INP PGA gain ctrl */
+	{ 0x2E, 0x0010 },     /* R46 - Right INP PGA gain ctrl */
+	{ 0x2F, 0x0100 },     /* R47 - Left ADC BOOST ctrl */
+	{ 0x30, 0x0100 },     /* R48 - Right ADC BOOST ctrl */
+	{ 0x31, 0x0002 },     /* R49 - Output ctrl */
+	{ 0x32, 0x0001 },     /* R50 - Left mixer ctrl */
+	{ 0x33, 0x0001 },     /* R51 - Right mixer ctrl */
+	{ 0x34, 0x0039 },     /* R52 - LOUT1 (HP) volume ctrl */
+	{ 0x35, 0x0039 },     /* R53 - ROUT1 (HP) volume ctrl */
+	{ 0x36, 0x0039 },     /* R54 - LOUT2 (SPK) volume ctrl */
+	{ 0x37, 0x0039 },     /* R55 - ROUT2 (SPK) volume ctrl */
+	{ 0x38, 0x0001 },     /* R56 - OUT3 mixer ctrl */
+	{ 0x39, 0x0001 },     /* R57 - OUT4 (MONO) mix ctrl */
+	{ 0x3D, 0x0000 },      /* R61 - BIAS CTRL */
 };
 
 static const struct wm8983_reg_access {
@@ -159,7 +159,7 @@
 };
 
 struct wm8983_priv {
-	enum snd_soc_control_type control_type;
+	struct regmap *regmap;
 	u32 sysclk;
 	u32 bclk;
 };
@@ -610,7 +610,7 @@
 	return 0;
 }
 
-static int wm8983_readable(struct snd_soc_codec *codec, unsigned int reg)
+static bool wm8983_readable(struct device *dev, unsigned int reg)
 {
 	if (reg > WM8983_MAX_REGISTER)
 		return 0;
@@ -905,6 +905,7 @@
 static int wm8983_set_bias_level(struct snd_soc_codec *codec,
 				 enum snd_soc_bias_level level)
 {
+	struct wm8983_priv *wm8983 = snd_soc_codec_get_drvdata(codec);
 	int ret;
 
 	switch (level) {
@@ -917,7 +918,7 @@
 		break;
 	case SND_SOC_BIAS_STANDBY:
 		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
-			ret = snd_soc_cache_sync(codec);
+			ret = regcache_sync(wm8983->regmap);
 			if (ret < 0) {
 				dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
 				return ret;
@@ -994,10 +995,9 @@
 static int wm8983_probe(struct snd_soc_codec *codec)
 {
 	int ret;
-	struct wm8983_priv *wm8983 = snd_soc_codec_get_drvdata(codec);
 	int i;
 
-	ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8983->control_type);
+	ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
 	if (ret < 0) {
 		dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
 		return ret;
@@ -1067,16 +1067,23 @@
 	.suspend = wm8983_suspend,
 	.resume = wm8983_resume,
 	.set_bias_level = wm8983_set_bias_level,
-	.reg_cache_size = ARRAY_SIZE(wm8983_reg_defs),
-	.reg_word_size = sizeof(u16),
-	.reg_cache_default = wm8983_reg_defs,
 	.controls = wm8983_snd_controls,
 	.num_controls = ARRAY_SIZE(wm8983_snd_controls),
 	.dapm_widgets = wm8983_dapm_widgets,
 	.num_dapm_widgets = ARRAY_SIZE(wm8983_dapm_widgets),
 	.dapm_routes = wm8983_audio_map,
 	.num_dapm_routes = ARRAY_SIZE(wm8983_audio_map),
-	.readable_register = wm8983_readable
+};
+
+static const struct regmap_config wm8983_regmap = {
+	.reg_bits = 7,
+	.val_bits = 9,
+
+	.reg_defaults = wm8983_defaults,
+	.num_reg_defaults = ARRAY_SIZE(wm8983_defaults),
+	.cache_type = REGCACHE_RBTREE,
+
+	.readable_reg = wm8983_readable,
 };
 
 #if defined(CONFIG_SPI_MASTER)
@@ -1085,24 +1092,27 @@
 	struct wm8983_priv *wm8983;
 	int ret;
 
-	wm8983 = kzalloc(sizeof *wm8983, GFP_KERNEL);
+	wm8983 = devm_kzalloc(&spi->dev, sizeof *wm8983, GFP_KERNEL);
 	if (!wm8983)
 		return -ENOMEM;
 
-	wm8983->control_type = SND_SOC_SPI;
+	wm8983->regmap = devm_regmap_init_spi(spi, &wm8983_regmap);
+	if (IS_ERR(wm8983->regmap)) {
+		ret = PTR_ERR(wm8983->regmap);
+		dev_err(&spi->dev, "Failed to init regmap: %d\n", ret);
+		return ret;
+	}
+
 	spi_set_drvdata(spi, wm8983);
 
 	ret = snd_soc_register_codec(&spi->dev,
 				     &soc_codec_dev_wm8983, &wm8983_dai, 1);
-	if (ret < 0)
-		kfree(wm8983);
 	return ret;
 }
 
 static int __devexit wm8983_spi_remove(struct spi_device *spi)
 {
 	snd_soc_unregister_codec(&spi->dev);
-	kfree(spi_get_drvdata(spi));
 	return 0;
 }
 
@@ -1123,24 +1133,28 @@
 	struct wm8983_priv *wm8983;
 	int ret;
 
-	wm8983 = kzalloc(sizeof *wm8983, GFP_KERNEL);
+	wm8983 = devm_kzalloc(&i2c->dev, sizeof *wm8983, GFP_KERNEL);
 	if (!wm8983)
 		return -ENOMEM;
 
-	wm8983->control_type = SND_SOC_I2C;
+	wm8983->regmap = devm_regmap_init_i2c(i2c, &wm8983_regmap);
+	if (IS_ERR(wm8983->regmap)) {
+		ret = PTR_ERR(wm8983->regmap);
+		dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret);
+		return ret;
+	}
+
 	i2c_set_clientdata(i2c, wm8983);
 
 	ret = snd_soc_register_codec(&i2c->dev,
 				     &soc_codec_dev_wm8983, &wm8983_dai, 1);
-	if (ret < 0)
-		kfree(wm8983);
+
 	return ret;
 }
 
 static __devexit int wm8983_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
-	kfree(i2c_get_clientdata(client));
 	return 0;
 }
 
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index db63c97..c28c83e 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -1388,7 +1388,8 @@
 	struct wm8990_priv *wm8990;
 	int ret;
 
-	wm8990 = kzalloc(sizeof(struct wm8990_priv), GFP_KERNEL);
+	wm8990 = devm_kzalloc(&i2c->dev, sizeof(struct wm8990_priv),
+			      GFP_KERNEL);
 	if (wm8990 == NULL)
 		return -ENOMEM;
 
@@ -1396,15 +1397,14 @@
 
 	ret = snd_soc_register_codec(&i2c->dev,
 			&soc_codec_dev_wm8990, &wm8990_dai, 1);
-	if (ret < 0)
-		kfree(wm8990);
+
 	return ret;
 }
 
 static __devexit int wm8990_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
-	kfree(i2c_get_clientdata(client));
+
 	return 0;
 }
 
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c
index 9ac31ba..fe439f02 100644
--- a/sound/soc/codecs/wm8991.c
+++ b/sound/soc/codecs/wm8991.c
@@ -1363,7 +1363,7 @@
 	struct wm8991_priv *wm8991;
 	int ret;
 
-	wm8991 = kzalloc(sizeof *wm8991, GFP_KERNEL);
+	wm8991 = devm_kzalloc(&i2c->dev, sizeof(*wm8991), GFP_KERNEL);
 	if (!wm8991)
 		return -ENOMEM;
 
@@ -1372,15 +1372,14 @@
 
 	ret = snd_soc_register_codec(&i2c->dev,
 				     &soc_codec_dev_wm8991, &wm8991_dai, 1);
-	if (ret < 0)
-		kfree(wm8991);
+
 	return ret;
 }
 
 static __devexit int wm8991_i2c_remove(struct i2c_client *client)
 {
 	snd_soc_unregister_codec(&client->dev);
-	kfree(i2c_get_clientdata(client));
+
 	return 0;
 }
 
@@ -1400,23 +1399,7 @@
 	.id_table = wm8991_i2c_id,
 };
 
-static int __init wm8991_modinit(void)
-{
-	int ret;
-	ret = i2c_add_driver(&wm8991_i2c_driver);
-	if (ret != 0) {
-		printk(KERN_ERR "Failed to register WM8991 I2C driver: %d\n",
-		       ret);
-	}
-	return 0;
-}
-module_init(wm8991_modinit);
-
-static void __exit wm8991_exit(void)
-{
-	i2c_del_driver(&wm8991_i2c_driver);
-}
-module_exit(wm8991_exit);
+module_i2c_driver(wm8991_i2c_driver);
 
 MODULE_DESCRIPTION("ASoC WM8991 driver");
 MODULE_AUTHOR("Graeme Gregory");
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 9fd80d6..94737a3 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -1520,6 +1520,8 @@
 				      wm8993->pdata.lineout2fb,
 				      wm8993->pdata.jd_scthr,
 				      wm8993->pdata.jd_thr,
+				      wm8993->pdata.micbias1_delay,
+				      wm8993->pdata.micbias2_delay,
 				      wm8993->pdata.micbias1_lvl,
 				      wm8993->pdata.micbias2_lvl);
 
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 6c9eeca..2b2dadc 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -671,6 +671,18 @@
 	       eq_tlv),
 };
 
+static const struct snd_kcontrol_new wm8994_drc_controls[] = {
+SND_SOC_BYTES_MASK("AIF1.1 DRC", WM8994_AIF1_DRC1_1, 5,
+		   WM8994_AIF1DAC1_DRC_ENA | WM8994_AIF1ADC1L_DRC_ENA |
+		   WM8994_AIF1ADC1R_DRC_ENA),
+SND_SOC_BYTES_MASK("AIF1.2 DRC", WM8994_AIF1_DRC2_1, 5,
+		   WM8994_AIF1DAC2_DRC_ENA | WM8994_AIF1ADC2L_DRC_ENA |
+		   WM8994_AIF1ADC2R_DRC_ENA),
+SND_SOC_BYTES_MASK("AIF2 DRC", WM8994_AIF2_DRC_1, 5,
+		   WM8994_AIF2DAC_DRC_ENA | WM8994_AIF2ADCL_DRC_ENA |
+		   WM8994_AIF2ADCR_DRC_ENA),
+};
+
 static const char *wm8958_ng_text[] = {
 	"30ms", "125ms", "250ms", "500ms",
 };
@@ -789,11 +801,27 @@
 			 struct snd_kcontrol *kcontrol, int event)
 {
 	struct snd_soc_codec *codec = w->codec;
+	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
 		return configure_clock(codec);
 
+	case SND_SOC_DAPM_POST_PMU:
+		/*
+		 * JACKDET won't run until we start the clock and it
+		 * only reports deltas, make sure we notify the state
+		 * up the stack on startup.  Use a *very* generous
+		 * timeout for paranoia, there's no urgency and we
+		 * don't want false reports.
+		 */
+		if (wm8994->jackdet && !wm8994->clk_has_run) {
+			schedule_delayed_work(&wm8994->jackdet_bootstrap,
+					      msecs_to_jiffies(1000));
+			wm8994->clk_has_run = true;
+		}
+		break;
+
 	case SND_SOC_DAPM_POST_PMD:
 		configure_clock(codec);
 		break;
@@ -1632,7 +1660,8 @@
 		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 
 SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,
-		    SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+		    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+		    SND_SOC_DAPM_PRE_PMD),
 
 SND_SOC_DAPM_SUPPLY("DSP1CLK", SND_SOC_NOPM, 3, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY("DSP2CLK", SND_SOC_NOPM, 2, 0, NULL, 0),
@@ -2102,6 +2131,10 @@
 	case WM8994_FLL_SRC_LRCLK:
 	case WM8994_FLL_SRC_BCLK:
 		break;
+	case WM8994_FLL_SRC_INTERNAL:
+		freq_in = 12000000;
+		freq_out = 12000000;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -2161,12 +2194,14 @@
 
 	snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_4 + reg_offset,
 			    WM8994_FLL1_N_MASK,
-				    fll.n << WM8994_FLL1_N_SHIFT);
+			    fll.n << WM8994_FLL1_N_SHIFT);
 
 	snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset,
-			    WM8958_FLL1_BYP |
+			    WM8994_FLL1_FRC_NCO | WM8958_FLL1_BYP |
 			    WM8994_FLL1_REFCLK_DIV_MASK |
 			    WM8994_FLL1_REFCLK_SRC_MASK,
+			    ((src == WM8994_FLL_SRC_INTERNAL)
+			     << WM8994_FLL1_FRC_NCO_SHIFT) |
 			    (fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT) |
 			    (src - 1));
 
@@ -2192,13 +2227,16 @@
 			}
 		}
 
+		reg = WM8994_FLL1_ENA;
+
 		if (fll.k)
-			reg = WM8994_FLL1_ENA | WM8994_FLL1_FRAC;
-		else
-			reg = WM8994_FLL1_ENA;
+			reg |= WM8994_FLL1_FRAC;
+		if (src == WM8994_FLL_SRC_INTERNAL)
+			reg |= WM8994_FLL1_OSC_ENA;
+
 		snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
-				    WM8994_FLL1_ENA | WM8994_FLL1_FRAC,
-				    reg);
+				    WM8994_FLL1_ENA | WM8994_FLL1_OSC_ENA |
+				    WM8994_FLL1_FRAC, reg);
 
 		if (wm8994->fll_locked_irq) {
 			timeout = wait_for_completion_timeout(&wm8994->fll_locked[id],
@@ -3027,7 +3065,7 @@
 
 static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
 {
-	struct snd_soc_codec *codec = wm8994->codec;
+	struct snd_soc_codec *codec = wm8994->hubs.codec;
 	struct wm8994_pdata *pdata = wm8994->pdata;
 	struct snd_kcontrol_new controls[] = {
 		SOC_ENUM_EXT("AIF1.1 EQ Mode",
@@ -3085,16 +3123,16 @@
 	wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts;
 	wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts;
 
-	ret = snd_soc_add_codec_controls(wm8994->codec, controls,
+	ret = snd_soc_add_codec_controls(wm8994->hubs.codec, controls,
 				   ARRAY_SIZE(controls));
 	if (ret != 0)
-		dev_err(wm8994->codec->dev,
+		dev_err(wm8994->hubs.codec->dev,
 			"Failed to add ReTune Mobile controls: %d\n", ret);
 }
 
 static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
 {
-	struct snd_soc_codec *codec = wm8994->codec;
+	struct snd_soc_codec *codec = wm8994->hubs.codec;
 	struct wm8994_pdata *pdata = wm8994->pdata;
 	int ret, i;
 
@@ -3107,6 +3145,8 @@
 				      pdata->lineout2fb,
 				      pdata->jd_scthr,
 				      pdata->jd_thr,
+				      pdata->micb1_delay,
+				      pdata->micb2_delay,
 				      pdata->micbias1_lvl,
 				      pdata->micbias2_lvl);
 
@@ -3123,10 +3163,10 @@
 		};
 
 		/* We need an array of texts for the enum API */
-		wm8994->drc_texts = devm_kzalloc(wm8994->codec->dev,
+		wm8994->drc_texts = devm_kzalloc(wm8994->hubs.codec->dev,
 			    sizeof(char *) * pdata->num_drc_cfgs, GFP_KERNEL);
 		if (!wm8994->drc_texts) {
-			dev_err(wm8994->codec->dev,
+			dev_err(wm8994->hubs.codec->dev,
 				"Failed to allocate %d DRC config texts\n",
 				pdata->num_drc_cfgs);
 			return;
@@ -3138,23 +3178,28 @@
 		wm8994->drc_enum.max = pdata->num_drc_cfgs;
 		wm8994->drc_enum.texts = wm8994->drc_texts;
 
-		ret = snd_soc_add_codec_controls(wm8994->codec, controls,
+		ret = snd_soc_add_codec_controls(wm8994->hubs.codec, controls,
 					   ARRAY_SIZE(controls));
-		if (ret != 0)
-			dev_err(wm8994->codec->dev,
-				"Failed to add DRC mode controls: %d\n", ret);
-
 		for (i = 0; i < WM8994_NUM_DRC; i++)
 			wm8994_set_drc(codec, i);
+	} else {
+		ret = snd_soc_add_codec_controls(wm8994->hubs.codec,
+						 wm8994_drc_controls,
+						 ARRAY_SIZE(wm8994_drc_controls));
 	}
 
+	if (ret != 0)
+		dev_err(wm8994->hubs.codec->dev,
+			"Failed to add DRC mode controls: %d\n", ret);
+
+
 	dev_dbg(codec->dev, "%d ReTune Mobile configurations\n",
 		pdata->num_retune_mobile_cfgs);
 
 	if (pdata->num_retune_mobile_cfgs)
 		wm8994_handle_retune_mobile_pdata(wm8994);
 	else
-		snd_soc_add_codec_controls(wm8994->codec, wm8994_eq_controls,
+		snd_soc_add_codec_controls(wm8994->hubs.codec, wm8994_eq_controls,
 				     ARRAY_SIZE(wm8994_eq_controls));
 
 	for (i = 0; i < ARRAY_SIZE(pdata->micbias); i++) {
@@ -3236,6 +3281,12 @@
 
 	snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg);
 
+	/* enable MICDET and MICSHRT deboune */
+	snd_soc_update_bits(codec, WM8994_IRQ_DEBOUNCE,
+			    WM8994_MIC1_DET_DB_MASK | WM8994_MIC1_SHRT_DB_MASK |
+			    WM8994_MIC2_DET_DB_MASK | WM8994_MIC2_SHRT_DB_MASK,
+			    WM8994_MIC1_DET_DB | WM8994_MIC1_SHRT_DB);
+
 	snd_soc_dapm_sync(&codec->dapm);
 
 	return 0;
@@ -3309,7 +3360,7 @@
 static irqreturn_t wm8994_mic_irq(int irq, void *data)
 {
 	struct wm8994_priv *priv = data;
-	struct snd_soc_codec *codec = priv->codec;
+	struct snd_soc_codec *codec = priv->hubs.codec;
 
 #ifndef CONFIG_SND_SOC_WM8994_MODULE
 	trace_snd_soc_jack_irq(dev_name(codec->dev));
@@ -3345,7 +3396,7 @@
 
 			snd_soc_jack_report(wm8994->micdet[0].jack, 0,
 					    wm8994->btn_mask |
-					     SND_JACK_HEADSET);
+					    SND_JACK_HEADSET);
 		}
 		return;
 	}
@@ -3422,7 +3473,7 @@
 static irqreturn_t wm1811_jackdet_irq(int irq, void *data)
 {
 	struct wm8994_priv *wm8994 = data;
-	struct snd_soc_codec *codec = wm8994->codec;
+	struct snd_soc_codec *codec = wm8994->hubs.codec;
 	int reg;
 	bool present;
 
@@ -3499,10 +3550,22 @@
 				    SND_JACK_MECHANICAL | SND_JACK_HEADSET |
 				    wm8994->btn_mask);
 
+	/* Since we only report deltas force an update, ensures we
+	 * avoid bootstrapping issues with the core. */
+	snd_soc_jack_report(wm8994->micdet[0].jack, 0, 0);
+
 	pm_runtime_put(codec->dev);
 	return IRQ_HANDLED;
 }
 
+static void wm1811_jackdet_bootstrap(struct work_struct *work)
+{
+	struct wm8994_priv *wm8994 = container_of(work,
+						struct wm8994_priv,
+						jackdet_bootstrap.work);
+	wm1811_jackdet_irq(0, wm8994);
+}
+
 /**
  * wm8958_mic_detect - Enable microphone detection via the WM8958 IRQ
  *
@@ -3573,6 +3636,10 @@
 		 * otherwise jump straight to microphone detection.
 		 */
 		if (wm8994->jackdet) {
+			/* Disable debounce for the initial detect */
+			snd_soc_update_bits(codec, WM1811_JACKDET_CTRL,
+					    WM1811_JACKDET_DB, 0);
+
 			snd_soc_update_bits(codec, WM8958_MICBIAS2,
 					    WM8958_MICB2_DISCH,
 					    WM8958_MICB2_DISCH);
@@ -3600,7 +3667,7 @@
 static irqreturn_t wm8958_mic_irq(int irq, void *data)
 {
 	struct wm8994_priv *wm8994 = data;
-	struct snd_soc_codec *codec = wm8994->codec;
+	struct snd_soc_codec *codec = wm8994->hubs.codec;
 	int reg, count;
 
 	/*
@@ -3690,15 +3757,15 @@
 	unsigned int reg;
 	int ret, i;
 
-	wm8994->codec = codec;
+	wm8994->hubs.codec = codec;
 	codec->control_data = control->regmap;
 
 	snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
 
-	wm8994->codec = codec;
-
 	mutex_init(&wm8994->accdet_lock);
 	INIT_DELAYED_WORK(&wm8994->mic_work, wm8994_mic_work);
+	INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap,
+			  wm1811_jackdet_bootstrap);
 
 	for (i = 0; i < ARRAY_SIZE(wm8994->fll_locked); i++)
 		init_completion(&wm8994->fll_locked[i]);
@@ -3756,14 +3823,17 @@
 		wm8994->hubs.no_cache_dac_hp_direct = true;
 		wm8994->fll_byp = true;
 
-		switch (wm8994->revision) {
+		switch (control->cust_id) {
 		case 0:
-		case 1:
 		case 2:
-		case 3:
 			wm8994->hubs.dcs_codes_l = -9;
 			wm8994->hubs.dcs_codes_r = -7;
 			break;
+		case 1:
+		case 3:
+			wm8994->hubs.dcs_codes_l = -8;
+			wm8994->hubs.dcs_codes_r = -7;
+			break;
 		default:
 			break;
 		}
@@ -3852,7 +3922,7 @@
 
 	switch (control->type) {
 	case WM1811:
-		if (wm8994->revision > 1) {
+		if (control->cust_id > 1 || wm8994->revision > 1) {
 			ret = wm8994_request_irq(wm8994->wm8994,
 						 WM8994_IRQ_GPIO(6),
 						 wm1811_jackdet_irq, "JACKDET",
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index d77e06f..f142ec1 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -28,10 +28,11 @@
 #define WM8994_FLL1 1
 #define WM8994_FLL2 2
 
-#define WM8994_FLL_SRC_MCLK1  1
-#define WM8994_FLL_SRC_MCLK2  2
-#define WM8994_FLL_SRC_LRCLK  3
-#define WM8994_FLL_SRC_BCLK   4
+#define WM8994_FLL_SRC_MCLK1    1
+#define WM8994_FLL_SRC_MCLK2    2
+#define WM8994_FLL_SRC_LRCLK    3
+#define WM8994_FLL_SRC_BCLK     4
+#define WM8994_FLL_SRC_INTERNAL 5
 
 enum wm8994_vmid_mode {
 	WM8994_VMID_NORMAL,
@@ -72,7 +73,6 @@
 struct wm8994_priv {
 	struct wm_hubs_data hubs;
 	struct wm8994 *wm8994;
-	struct snd_soc_codec *codec;
 	int sysclk[2];
 	int sysclk_rate[2];
 	int mclk[2];
@@ -81,6 +81,7 @@
 	struct completion fll_locked[2];
 	bool fll_locked_irq;
 	bool fll_byp;
+	bool clk_has_run;
 
 	int vmid_refcount;
 	int active_refcount;
@@ -134,6 +135,7 @@
 	int btn_mask;
 	bool jackdet;
 	int jackdet_mode;
+	struct delayed_work jackdet_bootstrap;
 
 	wm8958_micdet_cb jack_cb;
 	void *jack_cb_data;
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
index 00f183d..6dcb02c 100644
--- a/sound/soc/codecs/wm8996.c
+++ b/sound/soc/codecs/wm8996.c
@@ -931,7 +931,7 @@
 SND_SOC_DAPM_INPUT("DMIC1DAT"),
 SND_SOC_DAPM_INPUT("DMIC2DAT"),
 
-SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
+SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0),
 SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8996_AIF_CLOCKING_1, 0, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0),
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index 2c2346f..c7ddc56 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -695,17 +695,7 @@
 	.id_table = wm9090_id,
 };
 
-static int __init wm9090_init(void)
-{
-	return i2c_add_driver(&wm9090_i2c_driver);
-}
-module_init(wm9090_init);
-
-static void __exit wm9090_exit(void)
-{
-	i2c_del_driver(&wm9090_i2c_driver);
-}
-module_exit(wm9090_exit);
+module_i2c_driver(wm9090_i2c_driver);
 
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
 MODULE_DESCRIPTION("WM9090 ASoC driver");
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index c6d2076..4dd73ea 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -132,8 +132,9 @@
 SOC_SINGLE("Phone Volume", AC97_PHONE, 0, 15, 1),
 SOC_DOUBLE("Line Capture Volume", AC97_LINE, 8, 0, 31, 1),
 
-SOC_SINGLE("Capture 20dB Boost Switch", AC97_REC_SEL, 14, 1, 0),
-SOC_SINGLE("Capture to Phone 20dB Boost Switch", AC97_REC_SEL, 11, 1, 1),
+SOC_SINGLE_TLV("Capture Boost Switch", AC97_REC_SEL, 14, 1, 0, boost_tlv),
+SOC_SINGLE_TLV("Capture to Phone Boost Switch", AC97_REC_SEL, 11, 1, 1,
+	       boost_tlv),
 
 SOC_SINGLE("3D Upper Cut-off Switch", AC97_3D_CONTROL, 5, 1, 1),
 SOC_SINGLE("3D Lower Cut-off Switch", AC97_3D_CONTROL, 4, 1, 1),
@@ -146,7 +147,7 @@
 SOC_SINGLE("Bass Volume", AC97_MASTER_TONE, 8, 15, 1),
 SOC_SINGLE("Treble Volume", AC97_MASTER_TONE, 0, 15, 1),
 
-SOC_SINGLE("Capture ADC Switch", AC97_REC_GAIN, 15, 1, 1),
+SOC_SINGLE("Capture Switch", AC97_REC_GAIN, 15, 1, 1),
 SOC_ENUM("Capture Volume Steps", wm9712_enum[6]),
 SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 0),
 SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0),
@@ -634,7 +635,6 @@
 {
 	int ret = 0;
 
-	codec->control_data = codec;	/* we don't use regmap! */
 	ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
 	if (ret < 0) {
 		printk(KERN_ERR "wm9712: failed to register AC97 codec\n");
@@ -699,8 +699,8 @@
 
 static struct platform_driver wm9712_codec_driver = {
 	.driver = {
-			.name = "wm9712-codec",
-			.owner = THIS_MODULE,
+		.name = "wm9712-codec",
+		.owner = THIS_MODULE,
 	},
 
 	.probe = wm9712_probe,
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index d0b8a32..3eb19fb 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -1196,7 +1196,6 @@
 	if (wm9713 == NULL)
 		return -ENOMEM;
 	snd_soc_codec_set_drvdata(codec, wm9713);
-	codec->control_data = wm9713;	/* we don't use regmap! */
 
 	ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
 	if (ret < 0)
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 61baa48..867ae97 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -199,15 +199,56 @@
 	list_add_tail(&cache->list, &hubs->dcs_cache);
 }
 
+static void wm_hubs_read_dc_servo(struct snd_soc_codec *codec,
+				  u16 *reg_l, u16 *reg_r)
+{
+	struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
+	u16 dcs_reg, reg;
+
+	switch (hubs->dcs_readback_mode) {
+	case 2:
+		dcs_reg = WM8994_DC_SERVO_4E;
+		break;
+	case 1:
+		dcs_reg = WM8994_DC_SERVO_READBACK;
+		break;
+	default:
+		dcs_reg = WM8993_DC_SERVO_3;
+		break;
+	}
+
+	/* Different chips in the family support different readback
+	 * methods.
+	 */
+	switch (hubs->dcs_readback_mode) {
+	case 0:
+		*reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1)
+			& WM8993_DCS_INTEG_CHAN_0_MASK;
+		*reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
+			& WM8993_DCS_INTEG_CHAN_1_MASK;
+		break;
+	case 2:
+	case 1:
+		reg = snd_soc_read(codec, dcs_reg);
+		*reg_r = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
+			>> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
+		*reg_l = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
+		break;
+	default:
+		WARN(1, "Unknown DCS readback method\n");
+		return;
+	}
+}
+
 /*
  * Startup calibration of the DC servo
  */
-static void calibrate_dc_servo(struct snd_soc_codec *codec)
+static void enable_dc_servo(struct snd_soc_codec *codec)
 {
 	struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
 	struct wm_hubs_dcs_cache *cache;
 	s8 offset;
-	u16 reg, reg_l, reg_r, dcs_cfg, dcs_reg;
+	u16 reg_l, reg_r, dcs_cfg, dcs_reg;
 
 	switch (hubs->dcs_readback_mode) {
 	case 2:
@@ -245,27 +286,7 @@
 				  WM8993_DCS_TRIG_STARTUP_1);
 	}
 
-	/* Different chips in the family support different readback
-	 * methods.
-	 */
-	switch (hubs->dcs_readback_mode) {
-	case 0:
-		reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1)
-			& WM8993_DCS_INTEG_CHAN_0_MASK;
-		reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
-			& WM8993_DCS_INTEG_CHAN_1_MASK;
-		break;
-	case 2:
-	case 1:
-		reg = snd_soc_read(codec, dcs_reg);
-		reg_r = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
-			>> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
-		reg_l = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
-		break;
-	default:
-		WARN(1, "Unknown DCS readback method\n");
-		return;
-	}
+	wm_hubs_read_dc_servo(codec, &reg_l, &reg_r);
 
 	dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r);
 
@@ -276,12 +297,16 @@
 			hubs->dcs_codes_l, hubs->dcs_codes_r);
 
 		/* HPOUT1R */
-		offset = reg_r;
+		offset = (s8)reg_r;
+		dev_dbg(codec->dev, "DCS right %d->%d\n", offset,
+			offset + hubs->dcs_codes_r);
 		offset += hubs->dcs_codes_r;
 		dcs_cfg = (u8)offset << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
 
 		/* HPOUT1L */
-		offset = reg_l;
+		offset = (s8)reg_l;
+		dev_dbg(codec->dev, "DCS left %d->%d\n", offset,
+			offset + hubs->dcs_codes_l);
 		offset += hubs->dcs_codes_l;
 		dcs_cfg |= (u8)offset;
 
@@ -535,7 +560,7 @@
 		snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
 				    WM8993_DCS_TIMER_PERIOD_01_MASK, 0);
 
-		calibrate_dc_servo(codec);
+		enable_dc_servo(codec);
 
 		reg |= WM8993_HPOUT1R_OUTP | WM8993_HPOUT1R_RMV_SHORT |
 			WM8993_HPOUT1L_OUTP | WM8993_HPOUT1L_RMV_SHORT;
@@ -619,6 +644,28 @@
 	return 0;
 }
 
+static int micbias_event(struct snd_soc_dapm_widget *w,
+			 struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_codec *codec = w->codec;
+	struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
+
+	switch (w->shift) {
+	case WM8993_MICB1_ENA_SHIFT:
+		if (hubs->micb1_delay)
+			msleep(hubs->micb1_delay);
+		break;
+	case WM8993_MICB2_ENA_SHIFT:
+		if (hubs->micb2_delay)
+			msleep(hubs->micb2_delay);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 void wm_hubs_update_class_w(struct snd_soc_codec *codec)
 {
 	struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
@@ -634,6 +681,11 @@
 
 	snd_soc_update_bits(codec, WM8993_CLASS_W_0,
 			    WM8993_CP_DYN_V | WM8993_CP_DYN_FREQ, enable);
+
+	snd_soc_write(codec, WM8993_LEFT_OUTPUT_VOLUME,
+		      snd_soc_read(codec, WM8993_LEFT_OUTPUT_VOLUME));
+	snd_soc_write(codec, WM8993_RIGHT_OUTPUT_VOLUME,
+		      snd_soc_read(codec, WM8993_RIGHT_OUTPUT_VOLUME));
 }
 EXPORT_SYMBOL_GPL(wm_hubs_update_class_w);
 
@@ -809,8 +861,10 @@
 SND_SOC_DAPM_INPUT("IN2RN"),
 SND_SOC_DAPM_INPUT("IN2RP:VXRP"),
 
-SND_SOC_DAPM_SUPPLY("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0, NULL, 0),
-SND_SOC_DAPM_SUPPLY("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0, NULL, 0),
+SND_SOC_DAPM_SUPPLY("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0,
+		    micbias_event, SND_SOC_DAPM_POST_PMU),
+SND_SOC_DAPM_SUPPLY("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0,
+		    micbias_event, SND_SOC_DAPM_POST_PMU),
 
 SND_SOC_DAPM_MIXER("IN1L PGA", WM8993_POWER_MANAGEMENT_2, 6, 0,
 		   in1l_pga, ARRAY_SIZE(in1l_pga)),
@@ -1112,6 +1166,8 @@
 	struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
 	struct snd_soc_dapm_context *dapm = &codec->dapm;
 
+	hubs->codec = codec;
+
 	INIT_LIST_HEAD(&hubs->dcs_cache);
 	init_completion(&hubs->dcs_done);
 
@@ -1143,13 +1199,16 @@
 int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
 				  int lineout1_diff, int lineout2_diff,
 				  int lineout1fb, int lineout2fb,
-				  int jd_scthr, int jd_thr, int micbias1_lvl,
-				  int micbias2_lvl)
+				  int jd_scthr, int jd_thr,
+				  int micbias1_delay, int micbias2_delay,
+				  int micbias1_lvl, int micbias2_lvl)
 {
 	struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
 
 	hubs->lineout1_se = !lineout1_diff;
 	hubs->lineout2_se = !lineout2_diff;
+	hubs->micb1_delay = micbias1_delay;
+	hubs->micb2_delay = micbias2_delay;
 
 	if (!lineout1_diff)
 		snd_soc_update_bits(codec, WM8993_LINE_MIXER1,
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index da2dc89..24c763d 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -36,6 +36,9 @@
 	struct list_head dcs_cache;
 	bool (*check_class_w_digital)(struct snd_soc_codec *);
 
+	int micb1_delay;
+	int micb2_delay;
+
 	bool lineout1_se;
 	bool lineout1n_ena;
 	bool lineout1p_ena;
@@ -46,6 +49,8 @@
 
 	bool dcs_done_irq;
 	struct completion dcs_done;
+
+	struct snd_soc_codec *codec;
 };
 
 extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *);
@@ -54,6 +59,7 @@
 					 int lineout1_diff, int lineout2_diff,
 					 int lineout1fb, int lineout2fb,
 					 int jd_scthr, int jd_thr,
+					 int micbias1_dly, int micbias2_dly,
 					 int micbias1_lvl, int micbias2_lvl);
 
 extern irqreturn_t wm_hubs_dcs_done(int irq, void *data);
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index 10a2d8c..6fac5af 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -22,10 +22,6 @@
 #include <asm/dma.h>
 #include <asm/mach-types.h>
 
-#include <mach/asp.h>
-#include <mach/edma.h>
-#include <mach/mux.h>
-
 #include "davinci-pcm.h"
 #include "davinci-i2s.h"
 #include "davinci-mcasp.h"
@@ -160,7 +156,7 @@
 	.cpu_dai_name = "davinci-mcbsp",
 	.codec_dai_name = "tlv320aic3x-hifi",
 	.codec_name = "tlv320aic3x-codec.1-001b",
-	.platform_name = "davinci-pcm-audio",
+	.platform_name = "davinci-mcbsp",
 	.init = evm_aic3x_init,
 	.ops = &evm_ops,
 };
@@ -171,7 +167,7 @@
 	.cpu_dai_name = "davinci-mcbsp.1",
 	.codec_dai_name = "tlv320aic3x-hifi",
 	.codec_name = "tlv320aic3x-codec.1-001b",
-	.platform_name = "davinci-pcm-audio",
+	.platform_name = "davinci-mcbsp.1",
 	.init = evm_aic3x_init,
 	.ops = &evm_ops,
 };
@@ -185,14 +181,15 @@
 	.init = evm_aic3x_init,
 	.codec_name = "tlv320aic3x-codec.1-0018",
 	.ops = &evm_ops,
+	.platform_name = "davinci-mcbsp",
 #elif defined(CONFIG_SND_DM365_VOICE_CODEC)
 	.name = "Voice Codec - CQ93VC",
 	.stream_name = "CQ93",
 	.cpu_dai_name = "davinci-vcif",
 	.codec_dai_name = "cq93vc-hifi",
 	.codec_name = "cq93vc-codec",
+	.platform_name = "davinci-vcif",
 #endif
-	.platform_name = "davinci-pcm-audio",
 };
 
 static struct snd_soc_dai_link dm6467_evm_dai[] = {
@@ -201,7 +198,7 @@
 		.stream_name = "AIC3X",
 		.cpu_dai_name= "davinci-mcasp.0",
 		.codec_dai_name = "tlv320aic3x-hifi",
-		.platform_name ="davinci-pcm-audio",
+		.platform_name = "davinci-mcasp.0",
 		.codec_name = "tlv320aic3x-codec.0-001a",
 		.init = evm_aic3x_init,
 		.ops = &evm_ops,
@@ -212,7 +209,7 @@
 		.cpu_dai_name= "davinci-mcasp.1",
 		.codec_dai_name = "dit-hifi",
 		.codec_name = "spdif_dit",
-		.platform_name = "davinci-pcm-audio",
+		.platform_name = "davinci-mcasp.1",
 		.ops = &evm_spdif_ops,
 	},
 };
@@ -223,7 +220,7 @@
 	.cpu_dai_name = "davinci-mcasp.1",
 	.codec_dai_name = "tlv320aic3x-hifi",
 	.codec_name = "tlv320aic3x-codec.1-0018",
-	.platform_name = "davinci-pcm-audio",
+	.platform_name = "davinci-mcasp.1",
 	.init = evm_aic3x_init,
 	.ops = &evm_ops,
 };
@@ -234,7 +231,7 @@
 	.cpu_dai_name= "davinci-mcasp.0",
 	.codec_dai_name = "tlv320aic3x-hifi",
 	.codec_name = "tlv320aic3x-codec.1-0018",
-	.platform_name = "davinci-pcm-audio",
+	.platform_name = "davinci-mcasp.0",
 	.init = evm_aic3x_init,
 	.ops = &evm_ops,
 };
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index 0a74b95..8218312 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -16,6 +16,7 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/clk.h>
+#include <linux/platform_data/davinci_asp.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -23,8 +24,6 @@
 #include <sound/initval.h>
 #include <sound/soc.h>
 
-#include <mach/asp.h>
-
 #include "davinci-pcm.h"
 #include "davinci-i2s.h"
 
@@ -732,8 +731,16 @@
 	if (ret != 0)
 		goto err_release_clk;
 
+	ret = davinci_soc_platform_register(&pdev->dev);
+	if (ret) {
+		dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
+		goto err_unregister_dai;
+	}
+
 	return 0;
 
+err_unregister_dai:
+	snd_soc_unregister_dai(&pdev->dev);
 err_release_clk:
 	clk_disable(dev->clk);
 	clk_put(dev->clk);
@@ -745,6 +752,8 @@
 	struct davinci_mcbsp_dev *dev = dev_get_drvdata(&pdev->dev);
 
 	snd_soc_unregister_dai(&pdev->dev);
+	davinci_soc_platform_unregister(&pdev->dev);
+
 	clk_disable(dev->clk);
 	clk_put(dev->clk);
 	dev->clk = NULL;
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index ce5e5cd..714e51e 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -21,7 +21,10 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/io.h>
-#include <linux/clk.h>
+#include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/of_device.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -108,6 +111,10 @@
 #define DAVINCI_MCASP_WFIFOSTS		(0x1014)
 #define DAVINCI_MCASP_RFIFOCTL		(0x1018)
 #define DAVINCI_MCASP_RFIFOSTS		(0x101C)
+#define MCASP_VER3_WFIFOCTL		(0x1000)
+#define MCASP_VER3_WFIFOSTS		(0x1004)
+#define MCASP_VER3_RFIFOCTL		(0x1008)
+#define MCASP_VER3_RFIFOSTS		(0x100C)
 
 /*
  * DAVINCI_MCASP_PWREMUMGT_REG - Power Down and Emulation Management
@@ -381,18 +388,36 @@
 {
 	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		if (dev->txnumevt) {	/* enable FIFO */
-			mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
+			switch (dev->version) {
+			case MCASP_VERSION_3:
+				mcasp_clr_bits(dev->base + MCASP_VER3_WFIFOCTL,
 								FIFO_ENABLE);
-			mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
+				mcasp_set_bits(dev->base + MCASP_VER3_WFIFOCTL,
 								FIFO_ENABLE);
+				break;
+			default:
+				mcasp_clr_bits(dev->base +
+					DAVINCI_MCASP_WFIFOCTL,	FIFO_ENABLE);
+				mcasp_set_bits(dev->base +
+					DAVINCI_MCASP_WFIFOCTL,	FIFO_ENABLE);
+			}
 		}
 		mcasp_start_tx(dev);
 	} else {
 		if (dev->rxnumevt) {	/* enable FIFO */
-			mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
+			switch (dev->version) {
+			case MCASP_VERSION_3:
+				mcasp_clr_bits(dev->base + MCASP_VER3_RFIFOCTL,
 								FIFO_ENABLE);
-			mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
+				mcasp_set_bits(dev->base + MCASP_VER3_RFIFOCTL,
 								FIFO_ENABLE);
+				break;
+			default:
+				mcasp_clr_bits(dev->base +
+					DAVINCI_MCASP_RFIFOCTL,	FIFO_ENABLE);
+				mcasp_set_bits(dev->base +
+					DAVINCI_MCASP_RFIFOCTL,	FIFO_ENABLE);
+			}
 		}
 		mcasp_start_rx(dev);
 	}
@@ -413,14 +438,31 @@
 static void davinci_mcasp_stop(struct davinci_audio_dev *dev, int stream)
 {
 	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		if (dev->txnumevt)	/* disable FIFO */
-			mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
+		if (dev->txnumevt) {	/* disable FIFO */
+			switch (dev->version) {
+			case MCASP_VERSION_3:
+				mcasp_clr_bits(dev->base + MCASP_VER3_WFIFOCTL,
 								FIFO_ENABLE);
+				break;
+			default:
+				mcasp_clr_bits(dev->base +
+					DAVINCI_MCASP_WFIFOCTL,	FIFO_ENABLE);
+			}
+		}
 		mcasp_stop_tx(dev);
 	} else {
-		if (dev->rxnumevt)	/* disable FIFO */
-			mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
+		if (dev->rxnumevt) {	/* disable FIFO */
+			switch (dev->version) {
+			case MCASP_VERSION_3:
+				mcasp_clr_bits(dev->base + MCASP_VER3_RFIFOCTL,
 								FIFO_ENABLE);
+			break;
+
+			default:
+				mcasp_clr_bits(dev->base +
+					DAVINCI_MCASP_RFIFOCTL,	FIFO_ENABLE);
+			}
+		}
 		mcasp_stop_rx(dev);
 	}
 }
@@ -619,20 +661,37 @@
 		if (dev->txnumevt * tx_ser > 64)
 			dev->txnumevt = 1;
 
-		mcasp_mod_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, tx_ser,
+		switch (dev->version) {
+		case MCASP_VERSION_3:
+			mcasp_mod_bits(dev->base + MCASP_VER3_WFIFOCTL, tx_ser,
 								NUMDMA_MASK);
-		mcasp_mod_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
+			mcasp_mod_bits(dev->base + MCASP_VER3_WFIFOCTL,
 				((dev->txnumevt * tx_ser) << 8), NUMEVT_MASK);
+			break;
+		default:
+			mcasp_mod_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
+							tx_ser,	NUMDMA_MASK);
+			mcasp_mod_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
+				((dev->txnumevt * tx_ser) << 8), NUMEVT_MASK);
+		}
 	}
 
 	if (dev->rxnumevt && stream == SNDRV_PCM_STREAM_CAPTURE) {
 		if (dev->rxnumevt * rx_ser > 64)
 			dev->rxnumevt = 1;
-
-		mcasp_mod_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, rx_ser,
+		switch (dev->version) {
+		case MCASP_VERSION_3:
+			mcasp_mod_bits(dev->base + MCASP_VER3_RFIFOCTL, rx_ser,
 								NUMDMA_MASK);
-		mcasp_mod_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
+			mcasp_mod_bits(dev->base + MCASP_VER3_RFIFOCTL,
 				((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK);
+			break;
+		default:
+			mcasp_mod_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
+							rx_ser,	NUMDMA_MASK);
+			mcasp_mod_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
+				((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK);
+		}
 	}
 }
 
@@ -782,20 +841,17 @@
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		if (!dev->clk_active) {
-			clk_enable(dev->clk);
-			dev->clk_active = 1;
-		}
+		ret = pm_runtime_get_sync(dev->dev);
+		if (IS_ERR_VALUE(ret))
+			dev_err(dev->dev, "pm_runtime_get_sync() failed\n");
 		davinci_mcasp_start(dev, substream->stream);
 		break;
 
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 		davinci_mcasp_stop(dev, substream->stream);
-		if (dev->clk_active) {
-			clk_disable(dev->clk);
-			dev->clk_active = 0;
-		}
-
+		ret = pm_runtime_put_sync(dev->dev);
+		if (IS_ERR_VALUE(ret))
+			dev_err(dev->dev, "pm_runtime_put_sync() failed\n");
 		break;
 
 	case SNDRV_PCM_TRIGGER_STOP:
@@ -865,6 +921,118 @@
 
 };
 
+static const struct of_device_id mcasp_dt_ids[] = {
+	{
+		.compatible = "ti,dm646x-mcasp-audio",
+		.data = (void *)MCASP_VERSION_1,
+	},
+	{
+		.compatible = "ti,da830-mcasp-audio",
+		.data = (void *)MCASP_VERSION_2,
+	},
+	{
+		.compatible = "ti,omap2-mcasp-audio",
+		.data = (void *)MCASP_VERSION_3,
+	},
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mcasp_dt_ids);
+
+static struct snd_platform_data *davinci_mcasp_set_pdata_from_of(
+						struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct snd_platform_data *pdata = NULL;
+	const struct of_device_id *match =
+			of_match_device(of_match_ptr(mcasp_dt_ids), &pdev->dev);
+
+	const u32 *of_serial_dir32;
+	u8 *of_serial_dir;
+	u32 val;
+	int i, ret = 0;
+
+	if (pdev->dev.platform_data) {
+		pdata = pdev->dev.platform_data;
+		return pdata;
+	} else if (match) {
+		pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+		if (!pdata) {
+			ret = -ENOMEM;
+			goto nodata;
+		}
+	} else {
+		/* control shouldn't reach here. something is wrong */
+		ret = -EINVAL;
+		goto nodata;
+	}
+
+	if (match->data)
+		pdata->version = (u8)((int)match->data);
+
+	ret = of_property_read_u32(np, "op-mode", &val);
+	if (ret >= 0)
+		pdata->op_mode = val;
+
+	ret = of_property_read_u32(np, "tdm-slots", &val);
+	if (ret >= 0)
+		pdata->tdm_slots = val;
+
+	ret = of_property_read_u32(np, "num-serializer", &val);
+	if (ret >= 0)
+		pdata->num_serializer = val;
+
+	of_serial_dir32 = of_get_property(np, "serial-dir", &val);
+	val /= sizeof(u32);
+	if (val != pdata->num_serializer) {
+		dev_err(&pdev->dev,
+				"num-serializer(%d) != serial-dir size(%d)\n",
+				pdata->num_serializer, val);
+		ret = -EINVAL;
+		goto nodata;
+	}
+
+	if (of_serial_dir32) {
+		of_serial_dir = devm_kzalloc(&pdev->dev,
+						(sizeof(*of_serial_dir) * val),
+						GFP_KERNEL);
+		if (!of_serial_dir) {
+			ret = -ENOMEM;
+			goto nodata;
+		}
+
+		for (i = 0; i < pdata->num_serializer; i++)
+			of_serial_dir[i] = be32_to_cpup(&of_serial_dir32[i]);
+
+		pdata->serial_dir = of_serial_dir;
+	}
+
+	ret = of_property_read_u32(np, "tx-num-evt", &val);
+	if (ret >= 0)
+		pdata->txnumevt = val;
+
+	ret = of_property_read_u32(np, "rx-num-evt", &val);
+	if (ret >= 0)
+		pdata->rxnumevt = val;
+
+	ret = of_property_read_u32(np, "sram-size-playback", &val);
+	if (ret >= 0)
+		pdata->sram_size_playback = val;
+
+	ret = of_property_read_u32(np, "sram-size-capture", &val);
+	if (ret >= 0)
+		pdata->sram_size_capture = val;
+
+	return  pdata;
+
+nodata:
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Error populating platform data, err %d\n",
+			ret);
+		pdata = NULL;
+	}
+	return  pdata;
+}
+
 static int davinci_mcasp_probe(struct platform_device *pdev)
 {
 	struct davinci_pcm_dma_params *dma_data;
@@ -873,11 +1041,22 @@
 	struct davinci_audio_dev *dev;
 	int ret;
 
+	if (!pdev->dev.platform_data && !pdev->dev.of_node) {
+		dev_err(&pdev->dev, "No platform data supplied\n");
+		return -EINVAL;
+	}
+
 	dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_audio_dev),
 			   GFP_KERNEL);
 	if (!dev)
 		return	-ENOMEM;
 
+	pdata = davinci_mcasp_set_pdata_from_of(pdev);
+	if (!pdata) {
+		dev_err(&pdev->dev, "no platform data\n");
+		return -EINVAL;
+	}
+
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!mem) {
 		dev_err(&pdev->dev, "no mem resource?\n");
@@ -891,13 +1070,13 @@
 		return -EBUSY;
 	}
 
-	pdata = pdev->dev.platform_data;
-	dev->clk = clk_get(&pdev->dev, NULL);
-	if (IS_ERR(dev->clk))
-		return -ENODEV;
+	pm_runtime_enable(&pdev->dev);
 
-	clk_enable(dev->clk);
-	dev->clk_active = 1;
+	ret = pm_runtime_get_sync(&pdev->dev);
+	if (IS_ERR_VALUE(ret)) {
+		dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n");
+		return ret;
+	}
 
 	dev->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
 	if (!dev->base) {
@@ -914,6 +1093,7 @@
 	dev->version = pdata->version;
 	dev->txnumevt = pdata->txnumevt;
 	dev->rxnumevt = pdata->rxnumevt;
+	dev->dev = &pdev->dev;
 
 	dma_data = &dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
 	dma_data->asp_chan_q = pdata->asp_chan_q;
@@ -952,22 +1132,31 @@
 
 	if (ret != 0)
 		goto err_release_clk;
+
+	ret = davinci_soc_platform_register(&pdev->dev);
+	if (ret) {
+		dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
+		goto err_unregister_dai;
+	}
+
 	return 0;
 
+err_unregister_dai:
+	snd_soc_unregister_dai(&pdev->dev);
 err_release_clk:
-	clk_disable(dev->clk);
-	clk_put(dev->clk);
+	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
 	return ret;
 }
 
 static int davinci_mcasp_remove(struct platform_device *pdev)
 {
-	struct davinci_audio_dev *dev = dev_get_drvdata(&pdev->dev);
 
 	snd_soc_unregister_dai(&pdev->dev);
-	clk_disable(dev->clk);
-	clk_put(dev->clk);
-	dev->clk = NULL;
+	davinci_soc_platform_unregister(&pdev->dev);
+
+	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
 
 	return 0;
 }
@@ -978,6 +1167,7 @@
 	.driver		= {
 		.name	= "davinci-mcasp",
 		.owner	= THIS_MODULE,
+		.of_match_table = of_match_ptr(mcasp_dt_ids),
 	},
 };
 
diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h
index 4681acc..0de9ed6 100644
--- a/sound/soc/davinci/davinci-mcasp.h
+++ b/sound/soc/davinci/davinci-mcasp.h
@@ -19,7 +19,8 @@
 #define DAVINCI_MCASP_H
 
 #include <linux/io.h>
-#include <mach/asp.h>
+#include <linux/platform_data/davinci_asp.h>
+
 #include "davinci-pcm.h"
 
 #define DAVINCI_MCASP_RATES	SNDRV_PCM_RATE_8000_96000
@@ -40,9 +41,8 @@
 	struct davinci_pcm_dma_params dma_params[2];
 	void __iomem *base;
 	int sample_rate;
-	struct clk *clk;
+	struct device *dev;
 	unsigned int codec_fmt;
-	u8 clk_active;
 
 	/* McASP specific data */
 	int	tdm_slots;
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index 97d77b2..93ea3bf 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -23,7 +23,6 @@
 #include <sound/soc.h>
 
 #include <asm/dma.h>
-#include <mach/edma.h>
 #include <mach/sram.h>
 
 #include "davinci-pcm.h"
@@ -864,28 +863,17 @@
 	.pcm_free = 	davinci_pcm_free,
 };
 
-static int __devinit davinci_soc_platform_probe(struct platform_device *pdev)
+int davinci_soc_platform_register(struct device *dev)
 {
-	return snd_soc_register_platform(&pdev->dev, &davinci_soc_platform);
+	return snd_soc_register_platform(dev, &davinci_soc_platform);
 }
+EXPORT_SYMBOL_GPL(davinci_soc_platform_register);
 
-static int __devexit davinci_soc_platform_remove(struct platform_device *pdev)
+void davinci_soc_platform_unregister(struct device *dev)
 {
-	snd_soc_unregister_platform(&pdev->dev);
-	return 0;
+	snd_soc_unregister_platform(dev);
 }
-
-static struct platform_driver davinci_pcm_driver = {
-	.driver = {
-			.name = "davinci-pcm-audio",
-			.owner = THIS_MODULE,
-	},
-
-	.probe = davinci_soc_platform_probe,
-	.remove = __devexit_p(davinci_soc_platform_remove),
-};
-
-module_platform_driver(davinci_pcm_driver);
+EXPORT_SYMBOL_GPL(davinci_soc_platform_unregister);
 
 MODULE_AUTHOR("Vladimir Barinov");
 MODULE_DESCRIPTION("TI DAVINCI PCM DMA module");
diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h
index c0d6c9b..fc4d01c 100644
--- a/sound/soc/davinci/davinci-pcm.h
+++ b/sound/soc/davinci/davinci-pcm.h
@@ -12,9 +12,8 @@
 #ifndef _DAVINCI_PCM_H
 #define _DAVINCI_PCM_H
 
+#include <linux/platform_data/davinci_asp.h>
 #include <mach/edma.h>
-#include <mach/asp.h>
-
 
 struct davinci_pcm_dma_params {
 	int channel;			/* sync dma channel ID */
@@ -28,4 +27,7 @@
 	unsigned int fifo_level;
 };
 
+int davinci_soc_platform_register(struct device *dev);
+void davinci_soc_platform_unregister(struct device *dev);
+
 #endif
diff --git a/sound/soc/davinci/davinci-sffsdr.c b/sound/soc/davinci/davinci-sffsdr.c
index f71175b..5be65aa 100644
--- a/sound/soc/davinci/davinci-sffsdr.c
+++ b/sound/soc/davinci/davinci-sffsdr.c
@@ -86,7 +86,7 @@
 	.cpu_dai_name = "davinci-mcbsp",
 	.codec_dai_name = "pcm3008-hifi",
 	.codec_name = "pcm3008-codec",
-	.platform_name = "davinci-pcm-audio",
+	.platform_name = "davinci-mcbsp",
 	.ops = &sffsdr_ops,
 };
 
diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c
index da030ff..07bde2e 100644
--- a/sound/soc/davinci/davinci-vcif.c
+++ b/sound/soc/davinci/davinci-vcif.c
@@ -240,12 +240,20 @@
 		return ret;
 	}
 
+	ret = davinci_soc_platform_register(&pdev->dev);
+	if (ret) {
+		dev_err(&pdev->dev, "register PCM failed: %d\n", ret);
+		snd_soc_unregister_dai(&pdev->dev);
+		return ret;
+	}
+
 	return 0;
 }
 
 static int davinci_vcif_remove(struct platform_device *pdev)
 {
 	snd_soc_unregister_dai(&pdev->dev);
+	davinci_soc_platform_unregister(&pdev->dev);
 
 	return 0;
 }
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index d701330..4563b28 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -6,7 +6,7 @@
 
 menuconfig SND_POWERPC_SOC
 	tristate "SoC Audio for Freescale PowerPC CPUs"
-	depends on FSL_SOC
+	depends on FSL_SOC || PPC_MPC52xx
 	help
 	  Say Y or M if you want to add support for codecs attached to
 	  the PowerPC CPUs.
diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c
index efb9ede..267d5b4 100644
--- a/sound/soc/fsl/eukrea-tlv320.c
+++ b/sound/soc/fsl/eukrea-tlv320.c
@@ -93,9 +93,7 @@
 	.num_links	= 1,
 };
 
-static struct platform_device *eukrea_tlv320_snd_device;
-
-static int __init eukrea_tlv320_init(void)
+static int __devinit eukrea_tlv320_probe(struct platform_device *pdev)
 {
 	int ret;
 	int int_port = 0, ext_port;
@@ -136,29 +134,32 @@
 		return 0;
 	}
 
-	eukrea_tlv320_snd_device = platform_device_alloc("soc-audio", -1);
-	if (!eukrea_tlv320_snd_device)
-		return -ENOMEM;
-
-	platform_set_drvdata(eukrea_tlv320_snd_device, &eukrea_tlv320);
-	ret = platform_device_add(eukrea_tlv320_snd_device);
-
-	if (ret) {
-		printk(KERN_ERR "ASoC: Platform device allocation failed\n");
-		platform_device_put(eukrea_tlv320_snd_device);
-	}
+	eukrea_tlv320.dev = &pdev->dev;
+	ret = snd_soc_register_card(&eukrea_tlv320);
+	if (ret)
+		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
 
 	return ret;
 }
 
-static void __exit eukrea_tlv320_exit(void)
+static int __devexit eukrea_tlv320_remove(struct platform_device *pdev)
 {
-	platform_device_unregister(eukrea_tlv320_snd_device);
+	snd_soc_unregister_card(&eukrea_tlv320);
+
+	return 0;
 }
 
-module_init(eukrea_tlv320_init);
-module_exit(eukrea_tlv320_exit);
+static struct platform_driver eukrea_tlv320_driver = {
+	.driver = {
+		.name = "eukrea_tlv320",
+		.owner = THIS_MODULE,
+	},
+	.probe = eukrea_tlv320_probe,
+	.remove = __devexit_p(eukrea_tlv320_remove),};
+
+module_platform_driver(eukrea_tlv320_driver);
 
 MODULE_AUTHOR("Eric Bénard <eric@eukrea.com>");
 MODULE_DESCRIPTION("CPUIMX ALSA SoC driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:eukrea_tlv320");
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index 96bb92d..6feb265 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -823,12 +823,6 @@
 		if (dma_private->irq)
 			free_irq(dma_private->irq, dma_private);
 
-		if (dma_private->ld_buf_phys) {
-			dma_unmap_single(dev, dma_private->ld_buf_phys,
-					 sizeof(dma_private->link),
-					 DMA_TO_DEVICE);
-		}
-
 		/* Deallocate the fsl_dma_private structure */
 		dma_free_coherent(dev, sizeof(struct fsl_dma_private),
 				  dma_private, dma_private->ld_buf_phys);
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
index e7c800e..524ce62 100644
--- a/sound/soc/fsl/imx-audmux.c
+++ b/sound/soc/fsl/imx-audmux.c
@@ -74,9 +74,6 @@
 	if (!buf)
 		return -ENOMEM;
 
-	if (!audmux_base)
-		return -ENOSYS;
-
 	if (audmux_clk)
 		clk_prepare_enable(audmux_clk);
 
diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c
index 89a7755..d85929b 100644
--- a/sound/soc/fsl/imx-pcm-dma.c
+++ b/sound/soc/fsl/imx-pcm-dma.c
@@ -109,6 +109,9 @@
 	dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
 
 	dma_data = kzalloc(sizeof(*dma_data), GFP_KERNEL);
+	if (!dma_data)
+		return -ENOMEM;
+
 	dma_data->peripheral_type = dma_params->shared_peripheral ?
 					IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI;
 	dma_data->priority = DMA_PRIO_HIGH;
@@ -117,7 +120,7 @@
 	ret = snd_dmaengine_pcm_open(substream, filter, dma_data);
 	if (ret) {
 		kfree(dma_data);
-		return 0;
+		return ret;
 	}
 
 	snd_dmaengine_pcm_set_data(substream, dma_data);
diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c
index e6a17ba..006f7d4 100644
--- a/sound/soc/fsl/imx-ssi.c
+++ b/sound/soc/fsl/imx-ssi.c
@@ -380,14 +380,13 @@
 static struct snd_soc_dai_driver imx_ssi_dai = {
 	.probe = imx_ssi_dai_probe,
 	.playback = {
-		/* The SSI does not support monaural audio. */
-		.channels_min = 2,
+		.channels_min = 1,
 		.channels_max = 2,
 		.rates = SNDRV_PCM_RATE_8000_96000,
 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
 	},
 	.capture = {
-		.channels_min = 2,
+		.channels_min = 1,
 		.channels_max = 2,
 		.rates = SNDRV_PCM_RATE_8000_96000,
 		.formats = SNDRV_PCM_FMTBIT_S16_LE,
@@ -524,7 +523,7 @@
 	int ret = 0;
 	struct snd_soc_dai_driver *dai;
 
-	ssi = kzalloc(sizeof(*ssi), GFP_KERNEL);
+	ssi = devm_kzalloc(&pdev->dev, sizeof(*ssi), GFP_KERNEL);
 	if (!ssi)
 		return -ENOMEM;
 	dev_set_drvdata(&pdev->dev, ssi);
@@ -537,7 +536,7 @@
 
 	ssi->irq = platform_get_irq(pdev, 0);
 
-	ssi->clk = clk_get(&pdev->dev, NULL);
+	ssi->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(ssi->clk)) {
 		ret = PTR_ERR(ssi->clk);
 		dev_err(&pdev->dev, "Cannot get the clock: %d\n",
@@ -552,23 +551,18 @@
 		goto failed_get_resource;
 	}
 
-	if (!request_mem_region(res->start, resource_size(res), DRV_NAME)) {
-		dev_err(&pdev->dev, "request_mem_region failed\n");
-		ret = -EBUSY;
-		goto failed_get_resource;
-	}
-
-	ssi->base = ioremap(res->start, resource_size(res));
+	ssi->base = devm_request_and_ioremap(&pdev->dev, res);
 	if (!ssi->base) {
 		dev_err(&pdev->dev, "ioremap failed\n");
 		ret = -ENODEV;
-		goto failed_ioremap;
+		goto failed_register;
 	}
 
 	if (ssi->flags & IMX_SSI_USE_AC97) {
 		if (ac97_ssi) {
+			dev_err(&pdev->dev, "AC'97 SSI already registered\n");
 			ret = -EBUSY;
-			goto failed_ac97;
+			goto failed_register;
 		}
 		ac97_ssi = ssi;
 		setup_channel_to_ac97(ssi);
@@ -637,15 +631,10 @@
 failed_pdev_fiq_alloc:
 	snd_soc_unregister_dai(&pdev->dev);
 failed_register:
-failed_ac97:
-	iounmap(ssi->base);
-failed_ioremap:
 	release_mem_region(res->start, resource_size(res));
 failed_get_resource:
 	clk_disable_unprepare(ssi->clk);
-	clk_put(ssi->clk);
 failed_clk:
-	kfree(ssi);
 
 	return ret;
 }
@@ -663,11 +652,8 @@
 	if (ssi->flags & IMX_SSI_USE_AC97)
 		ac97_ssi = NULL;
 
-	iounmap(ssi->base);
 	release_mem_region(res->start, resource_size(res));
 	clk_disable_unprepare(ssi->clk);
-	clk_put(ssi->clk);
-	kfree(ssi);
 
 	return 0;
 }
diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c
index 9a3f7c5a..9997c03 100644
--- a/sound/soc/fsl/mpc5200_dma.c
+++ b/sound/soc/fsl/mpc5200_dma.c
@@ -370,7 +370,7 @@
 	.pcm_free	= &psc_dma_free,
 };
 
-static int mpc5200_hpcd_probe(struct platform_device *op)
+int mpc5200_audio_dma_create(struct platform_device *op)
 {
 	phys_addr_t fifo;
 	struct psc_dma *psc_dma;
@@ -487,8 +487,9 @@
 	iounmap(regs);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(mpc5200_audio_dma_create);
 
-static int mpc5200_hpcd_remove(struct platform_device *op)
+int mpc5200_audio_dma_destroy(struct platform_device *op)
 {
 	struct psc_dma *psc_dma = dev_get_drvdata(&op->dev);
 
@@ -510,24 +511,7 @@
 
 	return 0;
 }
-
-static struct of_device_id mpc5200_hpcd_match[] = {
-	{ .compatible = "fsl,mpc5200-pcm", },
-	{}
-};
-MODULE_DEVICE_TABLE(of, mpc5200_hpcd_match);
-
-static struct platform_driver mpc5200_hpcd_of_driver = {
-	.probe		= mpc5200_hpcd_probe,
-	.remove		= mpc5200_hpcd_remove,
-	.driver = {
-		.owner		= THIS_MODULE,
-		.name		= "mpc5200-pcm-audio",
-		.of_match_table    = mpc5200_hpcd_match,
-	}
-};
-
-module_platform_driver(mpc5200_hpcd_of_driver);
+EXPORT_SYMBOL_GPL(mpc5200_audio_dma_destroy);
 
 MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
 MODULE_DESCRIPTION("Freescale MPC5200 PSC in DMA mode ASoC Driver");
diff --git a/sound/soc/fsl/mpc5200_dma.h b/sound/soc/fsl/mpc5200_dma.h
index a3c0cd5..dff253f 100644
--- a/sound/soc/fsl/mpc5200_dma.h
+++ b/sound/soc/fsl/mpc5200_dma.h
@@ -81,4 +81,7 @@
 	return &psc_dma->playback;
 }
 
+int mpc5200_audio_dma_create(struct platform_device *op);
+int mpc5200_audio_dma_destroy(struct platform_device *op);
+
 #endif /* __SOUND_SOC_FSL_MPC5200_DMA_H__ */
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c
index ffa00a2..a313c0a 100644
--- a/sound/soc/fsl/mpc5200_psc_ac97.c
+++ b/sound/soc/fsl/mpc5200_psc_ac97.c
@@ -237,15 +237,18 @@
 
 static struct snd_soc_dai_driver psc_ac97_dai[] = {
 {
+	.name = "mpc5200-psc-ac97.0",
 	.ac97_control = 1,
 	.probe	= psc_ac97_probe,
 	.playback = {
+		.stream_name	= "AC97 Playback",
 		.channels_min   = 1,
 		.channels_max   = 6,
 		.rates          = SNDRV_PCM_RATE_8000_48000,
 		.formats = SNDRV_PCM_FMTBIT_S32_BE,
 	},
 	.capture = {
+		.stream_name	= "AC97 Capture",
 		.channels_min   = 1,
 		.channels_max   = 2,
 		.rates          = SNDRV_PCM_RATE_8000_48000,
@@ -254,8 +257,10 @@
 	.ops = &psc_ac97_analog_ops,
 },
 {
+	.name = "mpc5200-psc-ac97.1",
 	.ac97_control = 1,
 	.playback = {
+		.stream_name	= "AC97 SPDIF",
 		.channels_min   = 1,
 		.channels_max   = 2,
 		.rates          = SNDRV_PCM_RATE_32000 | \
@@ -278,6 +283,10 @@
 	struct snd_ac97 ac97;
 	struct mpc52xx_psc __iomem *regs;
 
+	rc = mpc5200_audio_dma_create(op);
+	if (rc != 0)
+		return rc;
+
 	rc = snd_soc_register_dais(&op->dev, psc_ac97_dai, ARRAY_SIZE(psc_ac97_dai));
 	if (rc != 0) {
 		dev_err(&op->dev, "Failed to register DAI\n");
@@ -303,6 +312,7 @@
 
 static int __devexit psc_ac97_of_remove(struct platform_device *op)
 {
+	mpc5200_audio_dma_destroy(op);
 	snd_soc_unregister_dais(&op->dev, ARRAY_SIZE(psc_ac97_dai));
 	return 0;
 }
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
index 7b53032..ba1f0a6 100644
--- a/sound/soc/fsl/mpc5200_psc_i2s.c
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -130,13 +130,16 @@
 };
 
 static struct snd_soc_dai_driver psc_i2s_dai[] = {{
+	.name = "mpc5200-psc-i2s.0",
 	.playback = {
+		.stream_name = "I2S Playback",
 		.channels_min = 2,
 		.channels_max = 2,
 		.rates = PSC_I2S_RATES,
 		.formats = PSC_I2S_FORMATS,
 	},
 	.capture = {
+		.stream_name = "I2S Capture",
 		.channels_min = 2,
 		.channels_max = 2,
 		.rates = PSC_I2S_RATES,
@@ -156,6 +159,10 @@
 	struct psc_dma *psc_dma;
 	struct mpc52xx_psc __iomem *regs;
 
+	rc = mpc5200_audio_dma_create(op);
+	if (rc != 0)
+		return rc;
+
 	rc = snd_soc_register_dais(&op->dev, psc_i2s_dai, ARRAY_SIZE(psc_i2s_dai));
 	if (rc != 0) {
 		pr_err("Failed to register DAI\n");
@@ -200,6 +207,7 @@
 
 static int __devexit psc_i2s_of_remove(struct platform_device *op)
 {
+	mpc5200_audio_dma_destroy(op);
 	snd_soc_unregister_dais(&op->dev, ARRAY_SIZE(psc_i2s_dai));
 	return 0;
 }
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index 60bcba1..9ff9318 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -192,7 +192,6 @@
 		container_of(dev, struct platform_device, dev);
 	struct device_node *np = ssi_pdev->dev.of_node;
 	struct device_node *codec_np = NULL;
-	struct platform_device *sound_device = NULL;
 	struct mpc8610_hpcd_data *machine_data;
 	int ret = -ENODEV;
 	const char *sprop;
@@ -341,34 +340,22 @@
 	machine_data->card.probe = mpc8610_hpcd_machine_probe;
 	machine_data->card.remove = mpc8610_hpcd_machine_remove;
 	machine_data->card.name = pdev->name; /* The platform driver name */
+	machine_data->card.owner = THIS_MODULE;
+	machine_data->card.dev = &pdev->dev;
 	machine_data->card.num_links = 2;
 	machine_data->card.dai_link = machine_data->dai;
 
-	/* Allocate a new audio platform device structure */
-	sound_device = platform_device_alloc("soc-audio", -1);
-	if (!sound_device) {
-		dev_err(&pdev->dev, "platform device alloc failed\n");
-		ret = -ENOMEM;
+	/* Register with ASoC */
+	ret = snd_soc_register_card(&machine_data->card);
+	if (ret) {
+		dev_err(&pdev->dev, "could not register card\n");
 		goto error;
 	}
 
-	/* Associate the card data with the sound device */
-	platform_set_drvdata(sound_device, &machine_data->card);
-
-	/* Register with ASoC */
-	ret = platform_device_add(sound_device);
-	if (ret) {
-		dev_err(&pdev->dev, "platform device add failed\n");
-		goto error_sound;
-	}
-	dev_set_drvdata(&pdev->dev, sound_device);
-
 	of_node_put(codec_np);
 
 	return 0;
 
-error_sound:
-	platform_device_put(sound_device);
 error:
 	kfree(machine_data);
 error_alloc:
@@ -383,17 +370,12 @@
  */
 static int __devexit mpc8610_hpcd_remove(struct platform_device *pdev)
 {
-	struct platform_device *sound_device = dev_get_drvdata(&pdev->dev);
-	struct snd_soc_card *card = platform_get_drvdata(sound_device);
+	struct snd_soc_card *card = platform_get_drvdata(pdev);
 	struct mpc8610_hpcd_data *machine_data =
 		container_of(card, struct mpc8610_hpcd_data, card);
 
-	platform_device_unregister(sound_device);
-
+	snd_soc_unregister_card(card);
 	kfree(machine_data);
-	sound_device->dev.platform_data = NULL;
-
-	dev_set_drvdata(&pdev->dev, NULL);
 
 	return 0;
 }
diff --git a/sound/soc/fsl/mx27vis-aic32x4.c b/sound/soc/fsl/mx27vis-aic32x4.c
index f6d04ad..2b76877 100644
--- a/sound/soc/fsl/mx27vis-aic32x4.c
+++ b/sound/soc/fsl/mx27vis-aic32x4.c
@@ -26,13 +26,13 @@
 #include <linux/device.h>
 #include <linux/i2c.h>
 #include <linux/gpio.h>
+#include <linux/platform_data/asoc-mx27vis.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
 #include <sound/soc-dapm.h>
 #include <sound/tlv.h>
 #include <asm/mach-types.h>
-#include <mach/iomux-mx27.h>
 
 #include "../codecs/tlv320aic32x4.h"
 #include "imx-ssi.h"
@@ -41,20 +41,12 @@
 #define MX27VIS_AMP_GAIN	0
 #define MX27VIS_AMP_MUTE	1
 
-#define MX27VIS_PIN_G0		(GPIO_PORTF + 9)
-#define MX27VIS_PIN_G1		(GPIO_PORTF + 8)
-#define MX27VIS_PIN_SDL		(GPIO_PORTE + 5)
-#define MX27VIS_PIN_SDR		(GPIO_PORTF + 7)
-
 static int mx27vis_amp_gain;
 static int mx27vis_amp_mute;
-
-static const int mx27vis_amp_pins[] = {
-	MX27VIS_PIN_G0 | GPIO_GPIO | GPIO_OUT,
-	MX27VIS_PIN_G1 | GPIO_GPIO | GPIO_OUT,
-	MX27VIS_PIN_SDL | GPIO_GPIO | GPIO_OUT,
-	MX27VIS_PIN_SDR | GPIO_GPIO | GPIO_OUT,
-};
+static int mx27vis_amp_gain0_gpio;
+static int mx27vis_amp_gain1_gpio;
+static int mx27vis_amp_mutel_gpio;
+static int mx27vis_amp_muter_gpio;
 
 static int mx27vis_aic32x4_hw_params(struct snd_pcm_substream *substream,
 			    struct snd_pcm_hw_params *params)
@@ -109,13 +101,13 @@
 
 	switch (reg) {
 	case MX27VIS_AMP_GAIN:
-		gpio_set_value(MX27VIS_PIN_G0, value & 1);
-		gpio_set_value(MX27VIS_PIN_G1, value >> 1);
+		gpio_set_value(mx27vis_amp_gain0_gpio, value & 1);
+		gpio_set_value(mx27vis_amp_gain1_gpio, value >> 1);
 		mx27vis_amp_gain = value;
 		break;
 	case MX27VIS_AMP_MUTE:
-		gpio_set_value(MX27VIS_PIN_SDL, value & 1);
-		gpio_set_value(MX27VIS_PIN_SDR, value >> 1);
+		gpio_set_value(mx27vis_amp_mutel_gpio, value & 1);
+		gpio_set_value(mx27vis_amp_muter_gpio, value >> 1);
 		mx27vis_amp_mute = value;
 		break;
 	}
@@ -190,8 +182,19 @@
 
 static int __devinit mx27vis_aic32x4_probe(struct platform_device *pdev)
 {
+	struct snd_mx27vis_platform_data *pdata = pdev->dev.platform_data;
 	int ret;
 
+	if (!pdata) {
+		dev_err(&pdev->dev, "No platform data supplied\n");
+		return -EINVAL;
+	}
+
+	mx27vis_amp_gain0_gpio = pdata->amp_gain0_gpio;
+	mx27vis_amp_gain1_gpio = pdata->amp_gain1_gpio;
+	mx27vis_amp_mutel_gpio = pdata->amp_mutel_gpio;
+	mx27vis_amp_muter_gpio = pdata->amp_muter_gpio;
+
 	mx27vis_aic32x4.dev = &pdev->dev;
 	ret = snd_soc_register_card(&mx27vis_aic32x4);
 	if (ret) {
@@ -213,11 +216,6 @@
 			IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0)
 	);
 
-	ret = mxc_gpio_setup_multiple_pins(mx27vis_amp_pins,
-			ARRAY_SIZE(mx27vis_amp_pins), "MX27VIS_AMP");
-	if (ret)
-		printk(KERN_ERR "ASoC: unable to setup gpios\n");
-
 	return ret;
 }
 
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c
index 50adf40..144d496 100644
--- a/sound/soc/fsl/p1022_ds.c
+++ b/sound/soc/fsl/p1022_ds.c
@@ -202,7 +202,6 @@
 		container_of(dev, struct platform_device, dev);
 	struct device_node *np = ssi_pdev->dev.of_node;
 	struct device_node *codec_np = NULL;
-	struct platform_device *sound_device = NULL;
 	struct machine_data *mdata;
 	int ret = -ENODEV;
 	const char *sprop;
@@ -349,36 +348,23 @@
 	mdata->card.probe = p1022_ds_machine_probe;
 	mdata->card.remove = p1022_ds_machine_remove;
 	mdata->card.name = pdev->name; /* The platform driver name */
+	mdata->card.owner = THIS_MODULE;
+	mdata->card.dev = &pdev->dev;
 	mdata->card.num_links = 2;
 	mdata->card.dai_link = mdata->dai;
 
-	/* Allocate a new audio platform device structure */
-	sound_device = platform_device_alloc("soc-audio", -1);
-	if (!sound_device) {
-		dev_err(&pdev->dev, "platform device alloc failed\n");
-		ret = -ENOMEM;
-		goto error;
-	}
-
-	/* Associate the card data with the sound device */
-	platform_set_drvdata(sound_device, &mdata->card);
-
 	/* Register with ASoC */
-	ret = platform_device_add(sound_device);
+	ret = snd_soc_register_card(&mdata->card);
 	if (ret) {
-		dev_err(&pdev->dev, "platform device add failed\n");
+		dev_err(&pdev->dev, "could not register card\n");
 		goto error;
 	}
-	dev_set_drvdata(&pdev->dev, sound_device);
 
 	of_node_put(codec_np);
 
 	return 0;
 
 error:
-	if (sound_device)
-		platform_device_put(sound_device);
-
 	kfree(mdata);
 error_put:
 	of_node_put(codec_np);
@@ -392,17 +378,12 @@
  */
 static int __devexit p1022_ds_remove(struct platform_device *pdev)
 {
-	struct platform_device *sound_device = dev_get_drvdata(&pdev->dev);
-	struct snd_soc_card *card = platform_get_drvdata(sound_device);
+	struct snd_soc_card *card = platform_get_drvdata(pdev);
 	struct machine_data *mdata =
 		container_of(card, struct machine_data, card);
 
-	platform_device_unregister(sound_device);
-
+	snd_soc_unregister_card(card);
 	kfree(mdata);
-	sound_device->dev.platform_data = NULL;
-
-	dev_set_drvdata(&pdev->dev, NULL);
 
 	return 0;
 }
diff --git a/sound/soc/fsl/pcm030-audio-fabric.c b/sound/soc/fsl/pcm030-audio-fabric.c
index b3af55d..4b63ec8 100644
--- a/sound/soc/fsl/pcm030-audio-fabric.c
+++ b/sound/soc/fsl/pcm030-audio-fabric.c
@@ -12,32 +12,27 @@
 
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/interrupt.h>
 #include <linux/device.h>
-#include <linux/delay.h>
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
-#include <linux/dma-mapping.h>
 
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
 #include <sound/soc.h>
 
 #include "mpc5200_dma.h"
-#include "mpc5200_psc_ac97.h"
-#include "../codecs/wm9712.h"
 
 #define DRV_NAME "pcm030-audio-fabric"
 
+struct pcm030_audio_data {
+	struct snd_soc_card *card;
+	struct platform_device *codec_device;
+};
+
 static struct snd_soc_dai_link pcm030_fabric_dai[] = {
 {
 	.name = "AC97",
 	.stream_name = "AC97 Analog",
 	.codec_dai_name = "wm9712-hifi",
 	.cpu_dai_name = "mpc5200-psc-ac97.0",
-	.platform_name = "mpc5200-pcm-audio",
 	.codec_name = "wm9712-codec",
 },
 {
@@ -45,44 +40,95 @@
 	.stream_name = "AC97 IEC958",
 	.codec_dai_name = "wm9712-aux",
 	.cpu_dai_name = "mpc5200-psc-ac97.1",
-	.platform_name = "mpc5200-pcm-audio",
 	.codec_name = "wm9712-codec",
 },
 };
 
-static struct snd_soc_card card = {
+static struct snd_soc_card pcm030_card = {
 	.name = "pcm030",
 	.owner = THIS_MODULE,
 	.dai_link = pcm030_fabric_dai,
 	.num_links = ARRAY_SIZE(pcm030_fabric_dai),
 };
 
-static __init int pcm030_fabric_init(void)
+static int __init pcm030_fabric_probe(struct platform_device *op)
 {
-	struct platform_device *pdev;
-	int rc;
+	struct device_node *np = op->dev.of_node;
+	struct device_node *platform_np;
+	struct snd_soc_card *card = &pcm030_card;
+	struct pcm030_audio_data *pdata;
+	int ret;
+	int i;
 
 	if (!of_machine_is_compatible("phytec,pcm030"))
 		return -ENODEV;
 
-	pdev = platform_device_alloc("soc-audio", 1);
-	if (!pdev) {
-		pr_err("pcm030_fabric_init: platform_device_alloc() failed\n");
+	pdata = devm_kzalloc(&op->dev, sizeof(struct pcm030_audio_data),
+			     GFP_KERNEL);
+	if (!pdata)
+		return -ENOMEM;
+
+	card->dev = &op->dev;
+	platform_set_drvdata(op, pdata);
+
+	pdata->card = card;
+
+	platform_np = of_parse_phandle(np, "asoc-platform", 0);
+	if (!platform_np) {
+		dev_err(&op->dev, "ac97 not registered\n");
 		return -ENODEV;
 	}
 
-	platform_set_drvdata(pdev, &card);
+	for (i = 0; i < card->num_links; i++)
+		card->dai_link[i].platform_of_node = platform_np;
 
-	rc = platform_device_add(pdev);
-	if (rc) {
-		pr_err("pcm030_fabric_init: platform_device_add() failed\n");
-		platform_device_put(pdev);
-		return -ENODEV;
-	}
-	return 0;
+	ret = request_module("snd-soc-wm9712");
+	if (ret)
+		dev_err(&op->dev, "request_module returned: %d\n", ret);
+
+	pdata->codec_device = platform_device_alloc("wm9712-codec", -1);
+	if (!pdata->codec_device)
+		dev_err(&op->dev, "platform_device_alloc() failed\n");
+
+	ret = platform_device_add(pdata->codec_device);
+	if (ret)
+		dev_err(&op->dev, "platform_device_add() failed: %d\n", ret);
+
+	ret = snd_soc_register_card(card);
+	if (ret)
+		dev_err(&op->dev, "snd_soc_register_card() failed: %d\n", ret);
+
+	return ret;
 }
 
-module_init(pcm030_fabric_init);
+static int __devexit pcm030_fabric_remove(struct platform_device *op)
+{
+	struct pcm030_audio_data *pdata = platform_get_drvdata(op);
+	int ret;
+
+	ret = snd_soc_unregister_card(pdata->card);
+	platform_device_unregister(pdata->codec_device);
+
+	return ret;
+}
+
+static struct of_device_id pcm030_audio_match[] = {
+	{ .compatible = "phytec,pcm030-audio-fabric", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, pcm030_audio_match);
+
+static struct platform_driver pcm030_fabric_driver = {
+	.probe		= pcm030_fabric_probe,
+	.remove		= __devexit_p(pcm030_fabric_remove),
+	.driver		= {
+		.name	= DRV_NAME,
+		.owner	= THIS_MODULE,
+		.of_match_table    = pcm030_audio_match,
+	},
+};
+
+module_platform_driver(pcm030_fabric_driver);
 
 
 MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c
index 2937e54..2cc7782 100644
--- a/sound/soc/mid-x86/mfld_machine.c
+++ b/sound/soc/mid-x86/mfld_machine.c
@@ -318,6 +318,15 @@
 		.platform_name = "sst-platform",
 		.init = NULL,
 	},
+	{
+		.name = "Medfield Compress",
+		.stream_name = "Speaker",
+		.cpu_dai_name = "Compress-cpu-dai",
+		.codec_dai_name = "SN95031 Speaker",
+		.codec_name = "sn95031",
+		.platform_name = "sst-platform",
+		.init = NULL,
+	},
 };
 
 /* SoC card */
diff --git a/sound/soc/mid-x86/sst_dsp.h b/sound/soc/mid-x86/sst_dsp.h
new file mode 100644
index 0000000..0fce1de
--- /dev/null
+++ b/sound/soc/mid-x86/sst_dsp.h
@@ -0,0 +1,134 @@
+#ifndef __SST_DSP_H__
+#define __SST_DSP_H__
+/*
+ *  sst_dsp.h - Intel SST Driver for audio engine
+ *
+ *  Copyright (C) 2008-12 Intel Corporation
+ *  Authors:	Vinod Koul <vinod.koul@linux.intel.com>
+ *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+enum sst_codec_types {
+	/*  AUDIO/MUSIC	CODEC Type Definitions */
+	SST_CODEC_TYPE_UNKNOWN = 0,
+	SST_CODEC_TYPE_PCM,	/* Pass through Audio codec */
+	SST_CODEC_TYPE_MP3,
+	SST_CODEC_TYPE_MP24,
+	SST_CODEC_TYPE_AAC,
+	SST_CODEC_TYPE_AACP,
+	SST_CODEC_TYPE_eAACP,
+};
+
+enum stream_type {
+	SST_STREAM_TYPE_NONE = 0,
+	SST_STREAM_TYPE_MUSIC = 1,
+};
+
+struct snd_pcm_params {
+	u16 codec;	/* codec type */
+	u8 num_chan;	/* 1=Mono, 2=Stereo */
+	u8 pcm_wd_sz;	/* 16/24 - bit*/
+	u32 reserved;	/* Bitrate in bits per second */
+	u32 sfreq;	/* Sampling rate in Hz */
+	u8 use_offload_path;
+	u8 reserved2;
+	u16 reserved3;
+	u8 channel_map[8];
+} __packed;
+
+/* MP3 Music Parameters Message */
+struct snd_mp3_params {
+	u16 codec;
+	u8  num_chan;	/* 1=Mono, 2=Stereo	*/
+	u8  pcm_wd_sz; /* 16/24 - bit*/
+	u8  crc_check; /* crc_check - disable (0) or enable (1) */
+	u8  reserved1; /* unused*/
+	u16 reserved2;	/* Unused */
+} __packed;
+
+#define AAC_BIT_STREAM_ADTS		0
+#define AAC_BIT_STREAM_ADIF		1
+#define AAC_BIT_STREAM_RAW		2
+
+/* AAC Music Parameters Message */
+struct snd_aac_params {
+	u16 codec;
+	u8 num_chan; /* 1=Mono, 2=Stereo*/
+	u8 pcm_wd_sz; /* 16/24 - bit*/
+	u8 bdownsample; /*SBR downsampling 0 - disable 1 -enabled AAC+ only */
+	u8 bs_format; /* input bit stream format adts=0, adif=1, raw=2 */
+	u16  reser2;
+	u32 externalsr; /*sampling rate of basic AAC raw bit stream*/
+	u8 sbr_signalling;/*disable/enable/set automode the SBR tool.AAC+*/
+	u8 reser1;
+	u16  reser3;
+} __packed;
+
+/* WMA Music Parameters Message */
+struct snd_wma_params {
+	u16 codec;
+	u8  num_chan;	/* 1=Mono, 2=Stereo */
+	u8  pcm_wd_sz;	/* 16/24 - bit*/
+	u32 brate;	/* Use the hard coded value. */
+	u32 sfreq;	/* Sampling freq eg. 8000, 441000, 48000 */
+	u32 channel_mask;  /* Channel Mask */
+	u16 format_tag;	/* Format Tag */
+	u16 block_align;	/* packet size */
+	u16 wma_encode_opt;/* Encoder option */
+	u8 op_align;	/* op align 0- 16 bit, 1- MSB, 2 LSB */
+	u8 reserved;	/* reserved */
+} __packed;
+
+/* Codec params struture */
+union  snd_sst_codec_params {
+	struct snd_pcm_params pcm_params;
+	struct snd_mp3_params mp3_params;
+	struct snd_aac_params aac_params;
+	struct snd_wma_params wma_params;
+} __packed;
+
+/* Address and size info of a frame buffer */
+struct sst_address_info {
+	u32 addr; /* Address at IA */
+	u32 size; /* Size of the buffer */
+};
+
+struct snd_sst_alloc_params_ext {
+	struct sst_address_info  ring_buf_info[8];
+	u8 sg_count;
+	u8 reserved;
+	u16 reserved2;
+	u32 frag_size;	/*Number of samples after which period elapsed
+				  message is sent valid only if path  = 0*/
+} __packed;
+
+struct snd_sst_stream_params {
+	union snd_sst_codec_params uc;
+} __packed;
+
+struct snd_sst_params {
+	u32 stream_id;
+	u8 codec;
+	u8 ops;
+	u8 stream_type;
+	u8 device_type;
+	struct snd_sst_stream_params sparams;
+	struct snd_sst_alloc_params_ext aparams;
+};
+
+#endif /* __SST_DSP_H__ */
diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c
index d34563b..a263cbe 100644
--- a/sound/soc/mid-x86/sst_platform.c
+++ b/sound/soc/mid-x86/sst_platform.c
@@ -1,7 +1,7 @@
 /*
  *  sst_platform.c - Intel MID Platform driver
  *
- *  Copyright (C) 2010 Intel Corp
+ *  Copyright (C) 2010-2012 Intel Corp
  *  Author: Vinod Koul <vinod.koul@intel.com>
  *  Author: Harsha Priya <priya.harsha@intel.com>
  *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -32,6 +32,7 @@
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
+#include <sound/compress_driver.h>
 #include "sst_platform.h"
 
 static struct sst_device *sst;
@@ -152,6 +153,16 @@
 		.formats = SNDRV_PCM_FMTBIT_S24_LE,
 	},
 },
+{
+	.name = "Compress-cpu-dai",
+	.compress_dai = 1,
+	.playback = {
+		.channels_min = SST_STEREO,
+		.channels_max = SST_STEREO,
+		.rates = SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000,
+		.formats = SNDRV_PCM_FMTBIT_S16_LE,
+	},
+},
 };
 
 /* helper functions */
@@ -463,8 +474,199 @@
 	}
 	return retval;
 }
+
+/* compress stream operations */
+static void sst_compr_fragment_elapsed(void *arg)
+{
+	struct snd_compr_stream *cstream = (struct snd_compr_stream *)arg;
+
+	pr_debug("fragment elapsed by driver\n");
+	if (cstream)
+		snd_compr_fragment_elapsed(cstream);
+}
+
+static int sst_platform_compr_open(struct snd_compr_stream *cstream)
+{
+
+	int ret_val = 0;
+	struct snd_compr_runtime *runtime = cstream->runtime;
+	struct sst_runtime_stream *stream;
+
+	stream = kzalloc(sizeof(*stream), GFP_KERNEL);
+	if (!stream)
+		return -ENOMEM;
+
+	spin_lock_init(&stream->status_lock);
+
+	/* get the sst ops */
+	if (!sst || !try_module_get(sst->dev->driver->owner)) {
+		pr_err("no device available to run\n");
+		ret_val = -ENODEV;
+		goto out_ops;
+	}
+	stream->compr_ops = sst->compr_ops;
+
+	stream->id = 0;
+	sst_set_stream_status(stream, SST_PLATFORM_INIT);
+	runtime->private_data = stream;
+	return 0;
+out_ops:
+	kfree(stream);
+	return ret_val;
+}
+
+static int sst_platform_compr_free(struct snd_compr_stream *cstream)
+{
+	struct sst_runtime_stream *stream;
+	int ret_val = 0, str_id;
+
+	stream = cstream->runtime->private_data;
+	/*need to check*/
+	str_id = stream->id;
+	if (str_id)
+		ret_val = stream->compr_ops->close(str_id);
+	module_put(sst->dev->driver->owner);
+	kfree(stream);
+	pr_debug("%s: %d\n", __func__, ret_val);
+	return 0;
+}
+
+static int sst_platform_compr_set_params(struct snd_compr_stream *cstream,
+					struct snd_compr_params *params)
+{
+	struct sst_runtime_stream *stream;
+	int retval;
+	struct snd_sst_params str_params;
+	struct sst_compress_cb cb;
+
+	stream = cstream->runtime->private_data;
+	/* construct fw structure for this*/
+	memset(&str_params, 0, sizeof(str_params));
+
+	str_params.ops = STREAM_OPS_PLAYBACK;
+	str_params.stream_type = SST_STREAM_TYPE_MUSIC;
+	str_params.device_type = SND_SST_DEVICE_COMPRESS;
+
+	switch (params->codec.id) {
+	case SND_AUDIOCODEC_MP3: {
+		str_params.codec = SST_CODEC_TYPE_MP3;
+		str_params.sparams.uc.mp3_params.codec = SST_CODEC_TYPE_MP3;
+		str_params.sparams.uc.mp3_params.num_chan = params->codec.ch_in;
+		str_params.sparams.uc.mp3_params.pcm_wd_sz = 16;
+		break;
+	}
+
+	case SND_AUDIOCODEC_AAC: {
+		str_params.codec = SST_CODEC_TYPE_AAC;
+		str_params.sparams.uc.aac_params.codec = SST_CODEC_TYPE_AAC;
+		str_params.sparams.uc.aac_params.num_chan = params->codec.ch_in;
+		str_params.sparams.uc.aac_params.pcm_wd_sz = 16;
+		if (params->codec.format == SND_AUDIOSTREAMFORMAT_MP4ADTS)
+			str_params.sparams.uc.aac_params.bs_format =
+							AAC_BIT_STREAM_ADTS;
+		else if (params->codec.format == SND_AUDIOSTREAMFORMAT_RAW)
+			str_params.sparams.uc.aac_params.bs_format =
+							AAC_BIT_STREAM_RAW;
+		else {
+			pr_err("Undefined format%d\n", params->codec.format);
+			return -EINVAL;
+		}
+		str_params.sparams.uc.aac_params.externalsr =
+						params->codec.sample_rate;
+		break;
+	}
+
+	default:
+		pr_err("codec not supported, id =%d\n", params->codec.id);
+		return -EINVAL;
+	}
+
+	str_params.aparams.ring_buf_info[0].addr  =
+					virt_to_phys(cstream->runtime->buffer);
+	str_params.aparams.ring_buf_info[0].size =
+					cstream->runtime->buffer_size;
+	str_params.aparams.sg_count = 1;
+	str_params.aparams.frag_size = cstream->runtime->fragment_size;
+
+	cb.param = cstream;
+	cb.compr_cb = sst_compr_fragment_elapsed;
+
+	retval = stream->compr_ops->open(&str_params, &cb);
+	if (retval < 0) {
+		pr_err("stream allocation failed %d\n", retval);
+		return retval;
+	}
+
+	stream->id = retval;
+	return 0;
+}
+
+static int sst_platform_compr_trigger(struct snd_compr_stream *cstream, int cmd)
+{
+	struct sst_runtime_stream *stream =
+		cstream->runtime->private_data;
+
+	return stream->compr_ops->control(cmd, stream->id);
+}
+
+static int sst_platform_compr_pointer(struct snd_compr_stream *cstream,
+					struct snd_compr_tstamp *tstamp)
+{
+	struct sst_runtime_stream *stream;
+
+	stream  = cstream->runtime->private_data;
+	stream->compr_ops->tstamp(stream->id, tstamp);
+	tstamp->byte_offset = tstamp->copied_total %
+				 (u32)cstream->runtime->buffer_size;
+	pr_debug("calc bytes offset/copied bytes as %d\n", tstamp->byte_offset);
+	return 0;
+}
+
+static int sst_platform_compr_ack(struct snd_compr_stream *cstream,
+					size_t bytes)
+{
+	struct sst_runtime_stream *stream;
+
+	stream  = cstream->runtime->private_data;
+	stream->compr_ops->ack(stream->id, (unsigned long)bytes);
+	stream->bytes_written += bytes;
+
+	return 0;
+}
+
+static int sst_platform_compr_get_caps(struct snd_compr_stream *cstream,
+					struct snd_compr_caps *caps)
+{
+	struct sst_runtime_stream *stream =
+		cstream->runtime->private_data;
+
+	return stream->compr_ops->get_caps(caps);
+}
+
+static int sst_platform_compr_get_codec_caps(struct snd_compr_stream *cstream,
+					struct snd_compr_codec_caps *codec)
+{
+	struct sst_runtime_stream *stream =
+		cstream->runtime->private_data;
+
+	return stream->compr_ops->get_codec_caps(codec);
+}
+
+static struct snd_compr_ops sst_platform_compr_ops = {
+
+	.open = sst_platform_compr_open,
+	.free = sst_platform_compr_free,
+	.set_params = sst_platform_compr_set_params,
+	.trigger = sst_platform_compr_trigger,
+	.pointer = sst_platform_compr_pointer,
+	.ack = sst_platform_compr_ack,
+	.get_caps = sst_platform_compr_get_caps,
+	.get_codec_caps = sst_platform_compr_get_codec_caps,
+};
+
 static struct snd_soc_platform_driver sst_soc_platform_drv = {
 	.ops		= &sst_platform_ops,
+	.compr_ops	= &sst_platform_compr_ops,
 	.pcm_new	= sst_pcm_new,
 	.pcm_free	= sst_pcm_free,
 };
diff --git a/sound/soc/mid-x86/sst_platform.h b/sound/soc/mid-x86/sst_platform.h
index f04f4f7..d61c5d5 100644
--- a/sound/soc/mid-x86/sst_platform.h
+++ b/sound/soc/mid-x86/sst_platform.h
@@ -27,6 +27,8 @@
 #ifndef __SST_PLATFORMDRV_H__
 #define __SST_PLATFORMDRV_H__
 
+#include "sst_dsp.h"
+
 #define SST_MONO		1
 #define SST_STEREO		2
 #define SST_MAX_CAP		5
@@ -42,7 +44,6 @@
 #define SST_MIN_PERIODS		2
 #define SST_MAX_PERIODS		(1024*2)
 #define SST_FIFO_SIZE		0
-#define SST_CODEC_TYPE_PCM	1
 
 struct pcm_stream_info {
 	int str_id;
@@ -83,6 +84,7 @@
 	SND_SST_DEVICE_VIBRA,
 	SND_SST_DEVICE_HAPTIC,
 	SND_SST_DEVICE_CAPTURE,
+	SND_SST_DEVICE_COMPRESS,
 };
 
 /* PCM Parameters */
@@ -107,6 +109,24 @@
 	struct sst_pcm_params sparams;
 };
 
+struct sst_compress_cb {
+	void *param;
+	void (*compr_cb)(void *param);
+};
+
+struct compress_sst_ops {
+	const char *name;
+	int (*open) (struct snd_sst_params *str_params,
+			struct sst_compress_cb *cb);
+	int (*control) (unsigned int cmd, unsigned int str_id);
+	int (*tstamp) (unsigned int str_id, struct snd_compr_tstamp *tstamp);
+	int (*ack) (unsigned int str_id, unsigned long bytes);
+	int (*close) (unsigned int str_id);
+	int (*get_caps) (struct snd_compr_caps *caps);
+	int (*get_codec_caps) (struct snd_compr_codec_caps *codec);
+
+};
+
 struct sst_ops {
 	int (*open) (struct sst_stream_params *str_param);
 	int (*device_control) (int cmd, void *arg);
@@ -115,8 +135,11 @@
 
 struct sst_runtime_stream {
 	int     stream_status;
+	unsigned int id;
+	size_t bytes_written;
 	struct pcm_stream_info stream_info;
 	struct sst_ops *ops;
+	struct compress_sst_ops *compr_ops;
 	spinlock_t	status_lock;
 };
 
@@ -124,6 +147,7 @@
 	char *name;
 	struct device *dev;
 	struct sst_ops *ops;
+	struct compress_sst_ops *compr_ops;
 };
 
 int sst_register_dsp(struct sst_device *sst);
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
index b303071..aa037b2 100644
--- a/sound/soc/mxs/mxs-saif.c
+++ b/sound/soc/mxs/mxs-saif.c
@@ -704,7 +704,7 @@
 		return ret;
 	}
 
-	saif->clk = clk_get(&pdev->dev, NULL);
+	saif->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(saif->clk)) {
 		ret = PTR_ERR(saif->clk);
 		dev_err(&pdev->dev, "Cannot get the clock: %d\n",
@@ -717,8 +717,7 @@
 	saif->base = devm_request_and_ioremap(&pdev->dev, iores);
 	if (!saif->base) {
 		dev_err(&pdev->dev, "ioremap failed\n");
-		ret = -ENODEV;
-		goto failed_get_resource;
+		return -ENODEV;
 	}
 
 	dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
@@ -731,7 +730,7 @@
 					   &saif->dma_param.chan_num);
 		if (ret) {
 			dev_err(&pdev->dev, "failed to get dma channel\n");
-			goto failed_get_resource;
+			return ret;
 		}
 	} else {
 		saif->dma_param.chan_num = dmares->start;
@@ -742,7 +741,7 @@
 		ret = saif->irq;
 		dev_err(&pdev->dev, "failed to get irq resource: %d\n",
 			ret);
-		goto failed_get_resource;
+		return ret;
 	}
 
 	saif->dev = &pdev->dev;
@@ -750,7 +749,7 @@
 			       "mxs-saif", saif);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to request irq\n");
-		goto failed_get_resource;
+		return ret;
 	}
 
 	saif->dma_param.chan_irq = platform_get_irq(pdev, 1);
@@ -758,7 +757,7 @@
 		ret = saif->dma_param.chan_irq;
 		dev_err(&pdev->dev, "failed to get dma irq resource: %d\n",
 			ret);
-		goto failed_get_resource;
+		return ret;
 	}
 
 	platform_set_drvdata(pdev, saif);
@@ -766,7 +765,7 @@
 	ret = snd_soc_register_dai(&pdev->dev, &mxs_saif_dai);
 	if (ret) {
 		dev_err(&pdev->dev, "register DAI failed\n");
-		goto failed_get_resource;
+		return ret;
 	}
 
 	ret = mxs_pcm_platform_register(&pdev->dev);
@@ -779,19 +778,14 @@
 
 failed_pdev_alloc:
 	snd_soc_unregister_dai(&pdev->dev);
-failed_get_resource:
-	clk_put(saif->clk);
 
 	return ret;
 }
 
 static int __devexit mxs_saif_remove(struct platform_device *pdev)
 {
-	struct mxs_saif *saif = platform_get_drvdata(pdev);
-
 	mxs_pcm_platform_unregister(&pdev->dev);
 	snd_soc_unregister_dai(&pdev->dev);
-	clk_put(saif->clk);
 
 	return 0;
 }
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index 57a2fa7..7048137 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -1,6 +1,7 @@
 config SND_OMAP_SOC
 	tristate "SoC Audio for the Texas Instruments OMAP chips"
-	depends on ARCH_OMAP
+	depends on ARCH_OMAP && DMA_OMAP
+	select SND_SOC_DMAENGINE_PCM
 
 config SND_OMAP_SOC_DMIC
 	tristate
@@ -60,23 +61,6 @@
 	help
 	  Say Y if you want to add support for SoC audio on osk5912.
 
-config SND_OMAP_SOC_OVERO
-	tristate "SoC Audio support for Gumstix Overo and CompuLab CM-T35"
-	depends on TWL4030_CORE && SND_OMAP_SOC && (MACH_OVERO || MACH_CM_T35)
-	select SND_OMAP_SOC_MCBSP
-	select SND_SOC_TWL4030
-	help
-	  Say Y if you want to add support for SoC audio on the
-	  Gumstix Overo or CompuLab CM-T35
-
-config SND_OMAP_SOC_OMAP3EVM
-	tristate "SoC Audio support for OMAP3EVM board"
-	depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3EVM
-	select SND_OMAP_SOC_MCBSP
-	select SND_SOC_TWL4030
-	help
-	  Say Y if you want to add support for SoC audio on the omap3evm board.
-
 config SND_OMAP_SOC_AM3517EVM
 	tristate "SoC Audio support for OMAP3517 / AM3517 EVM"
 	depends on SND_OMAP_SOC && MACH_OMAP3517EVM && I2C
@@ -95,6 +79,19 @@
 	  Say Y if you want to add support for SoC audio on Texas Instruments
 	  SDP3430.
 
+config SND_OMAP_SOC_OMAP_TWL4030
+	tristate "SoC Audio support for TI SoC based boards with twl4030 codec"
+	depends on TWL4030_CORE && SND_OMAP_SOC
+	select SND_OMAP_SOC_MCBSP
+	select SND_SOC_TWL4030
+	help
+	  Say Y if you want to add support for SoC audio on TI SoC based boards
+	  using twl4030 as c codec. This driver currently supports:
+	  - Beagleboard or Devkit8000
+	  - Gumstix Overo or CompuLab CM-T35/CM-T3730
+	  - IGEP v2
+	  - OMAP3EVM
+
 config SND_OMAP_SOC_OMAP_ABE_TWL6040
 	tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec"
 	depends on TWL6040_CORE && SND_OMAP_SOC && ARCH_OMAP4
@@ -127,16 +124,6 @@
 	help
 	  Say Y if you want to add support for SoC audio on the OMAP3 Pandora.
 
-config SND_OMAP_SOC_OMAP3_BEAGLE
-	tristate "SoC Audio support for OMAP3 Beagle and Devkit8000"
-	depends on TWL4030_CORE && SND_OMAP_SOC
-	depends on (MACH_OMAP3_BEAGLE || MACH_DEVKIT8000)
-	select SND_OMAP_SOC_MCBSP
-	select SND_SOC_TWL4030
-	help
-	  Say Y if you want to add support for SoC audio on the Beagleboard or
-	  the clone Devkit8000.
-
 config SND_OMAP_SOC_ZOOM2
 	tristate "SoC Audio support for Zoom2"
 	depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_ZOOM2
@@ -144,11 +131,3 @@
 	select SND_SOC_TWL4030
 	help
 	  Say Y if you want to add support for Soc audio on Zoom2 board.
-
-config SND_OMAP_SOC_IGEP0020
-	tristate "SoC Audio support for IGEP v2"
-	depends on TWL4030_CORE && SND_OMAP_SOC && MACH_IGEP0020
-	select SND_OMAP_SOC_MCBSP
-	select SND_SOC_TWL4030
-	help
-	  Say Y if you want to add support for Soc audio on IGEP v2 board.
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index 0e14dd3..19637e5 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -16,29 +16,23 @@
 snd-soc-rx51-objs := rx51.o
 snd-soc-ams-delta-objs := ams-delta.o
 snd-soc-osk5912-objs := osk5912.o
-snd-soc-overo-objs := overo.o
-snd-soc-omap3evm-objs := omap3evm.o
 snd-soc-am3517evm-objs := am3517evm.o
 snd-soc-sdp3430-objs := sdp3430.o
 snd-soc-omap-abe-twl6040-objs := omap-abe-twl6040.o
+snd-soc-omap-twl4030-objs := omap-twl4030.o
 snd-soc-omap3pandora-objs := omap3pandora.o
-snd-soc-omap3beagle-objs := omap3beagle.o
 snd-soc-zoom2-objs := zoom2.o
-snd-soc-igep0020-objs := igep0020.o
 snd-soc-omap-hdmi-card-objs := omap-hdmi-card.o
 
 obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
 obj-$(CONFIG_SND_OMAP_SOC_RX51) += snd-soc-rx51.o
 obj-$(CONFIG_SND_OMAP_SOC_AMS_DELTA) += snd-soc-ams-delta.o
 obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
-obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o
 obj-$(CONFIG_SND_OMAP_SOC_OMAP2EVM) += snd-soc-omap2evm.o
-obj-$(CONFIG_SND_OMAP_SOC_OMAP3EVM) += snd-soc-omap3evm.o
 obj-$(CONFIG_SND_OMAP_SOC_AM3517EVM) += snd-soc-am3517evm.o
 obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o
 obj-$(CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040) += snd-soc-omap-abe-twl6040.o
+obj-$(CONFIG_SND_OMAP_SOC_OMAP_TWL4030) += snd-soc-omap-twl4030.o
 obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o
-obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o
 obj-$(CONFIG_SND_OMAP_SOC_ZOOM2) += snd-soc-zoom2.o
-obj-$(CONFIG_SND_OMAP_SOC_IGEP0020) += snd-soc-igep0020.o
 obj-$(CONFIG_SND_OMAP_SOC_OMAP_HDMI) += snd-soc-omap-hdmi-card.o
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c
index a52e87d..fad3506 100644
--- a/sound/soc/omap/am3517evm.c
+++ b/sound/soc/omap/am3517evm.c
@@ -41,32 +41,15 @@
 {
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_dai *codec_dai = rtd->codec_dai;
-	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	int ret;
 
 	/* Set the codec system clock for DAC and ADC */
 	ret = snd_soc_dai_set_sysclk(codec_dai, 0,
 			CODEC_CLOCK, SND_SOC_CLOCK_IN);
-	if (ret < 0) {
+	if (ret < 0)
 		printk(KERN_ERR "can't set codec system clock\n");
-		return ret;
-	}
 
-	ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_CLKR_SRC_CLKX, 0,
-				SND_SOC_CLOCK_IN);
-	if (ret < 0) {
-		printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_CLKR_SRC_CLKX\n");
-		return ret;
-	}
-
-	ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_FSR_SRC_FSX, 0,
-				SND_SOC_CLOCK_IN);
-	if (ret < 0) {
-		printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_FSR_SRC_FSX\n");
-		return ret;
-	}
-
-	return 0;
+	return ret;
 }
 
 static struct snd_soc_ops am3517evm_ops = {
diff --git a/sound/soc/omap/igep0020.c b/sound/soc/omap/igep0020.c
deleted file mode 100644
index 5ed8716..0000000
--- a/sound/soc/omap/igep0020.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * igep0020.c  --  SoC audio for IGEP v2
- *
- * Based on sound/soc/omap/overo.c by Steve Sakoman
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <mach/gpio.h>
-#include <linux/platform_data/asoc-ti-mcbsp.h>
-
-#include "omap-mcbsp.h"
-#include "omap-pcm.h"
-
-static int igep2_hw_params(struct snd_pcm_substream *substream,
-	struct snd_pcm_hw_params *params)
-{
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *codec_dai = rtd->codec_dai;
-	int ret;
-
-	/* Set the codec system clock for DAC and ADC */
-	ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
-					    SND_SOC_CLOCK_IN);
-	if (ret < 0) {
-		printk(KERN_ERR "can't set codec system clock\n");
-		return ret;
-	}
-
-	return 0;
-}
-
-static struct snd_soc_ops igep2_ops = {
-	.hw_params = igep2_hw_params,
-};
-
-/* Digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link igep2_dai = {
-	.name = "TWL4030",
-	.stream_name = "TWL4030",
-	.cpu_dai_name = "omap-mcbsp.2",
-	.codec_dai_name = "twl4030-hifi",
-	.platform_name = "omap-pcm-audio",
-	.codec_name = "twl4030-codec",
-	.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
-		   SND_SOC_DAIFMT_CBM_CFM,
-	.ops = &igep2_ops,
-};
-
-/* Audio machine driver */
-static struct snd_soc_card snd_soc_card_igep2 = {
-	.name = "igep2",
-	.owner = THIS_MODULE,
-	.dai_link = &igep2_dai,
-	.num_links = 1,
-};
-
-static struct platform_device *igep2_snd_device;
-
-static int __init igep2_soc_init(void)
-{
-	int ret;
-
-	if (!machine_is_igep0020())
-		return -ENODEV;
-	printk(KERN_INFO "IGEP v2 SoC init\n");
-
-	igep2_snd_device = platform_device_alloc("soc-audio", -1);
-	if (!igep2_snd_device) {
-		printk(KERN_ERR "Platform device allocation failed\n");
-		return -ENOMEM;
-	}
-
-	platform_set_drvdata(igep2_snd_device, &snd_soc_card_igep2);
-
-	ret = platform_device_add(igep2_snd_device);
-	if (ret)
-		goto err1;
-
-	return 0;
-
-err1:
-	printk(KERN_ERR "Unable to add platform device\n");
-	platform_device_put(igep2_snd_device);
-
-	return ret;
-}
-module_init(igep2_soc_init);
-
-static void __exit igep2_soc_exit(void)
-{
-	platform_device_unregister(igep2_snd_device);
-}
-module_exit(igep2_soc_exit);
-
-MODULE_AUTHOR("Enric Balletbo i Serra <eballetbo@iseebcn.com>");
-MODULE_DESCRIPTION("ALSA SoC IGEP v2");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c
index a681a9a..afb8d4f1 100644
--- a/sound/soc/omap/mcbsp.c
+++ b/sound/soc/omap/mcbsp.c
@@ -24,6 +24,7 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/slab.h>
+#include <linux/pm_runtime.h>
 
 #include <linux/platform_data/asoc-ti-mcbsp.h>
 
@@ -728,50 +729,39 @@
 
 int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id)
 {
+	struct clk *fck_src;
 	const char *src;
+	int r;
 
 	if (fck_src_id == MCBSP_CLKS_PAD_SRC)
-		src = "clks_ext";
+		src = "pad_fck";
 	else if (fck_src_id == MCBSP_CLKS_PRCM_SRC)
-		src = "clks_fclk";
+		src = "prcm_fck";
 	else
 		return -EINVAL;
 
-	if (mcbsp->pdata->set_clk_src)
-		return mcbsp->pdata->set_clk_src(mcbsp->dev, mcbsp->fclk, src);
-	else
-		return -EINVAL;
-}
-
-int omap_mcbsp_6pin_src_mux(struct omap_mcbsp *mcbsp, u8 mux)
-{
-	const char *signal, *src;
-
-	if (!mcbsp->pdata->mux_signal)
-		return -EINVAL;
-
-	switch (mux) {
-	case CLKR_SRC_CLKR:
-		signal = "clkr";
-		src = "clkr";
-		break;
-	case CLKR_SRC_CLKX:
-		signal = "clkr";
-		src = "clkx";
-		break;
-	case FSR_SRC_FSR:
-		signal = "fsr";
-		src = "fsr";
-		break;
-	case FSR_SRC_FSX:
-		signal = "fsr";
-		src = "fsx";
-		break;
-	default:
+	fck_src = clk_get(mcbsp->dev, src);
+	if (IS_ERR(fck_src)) {
+		dev_err(mcbsp->dev, "CLKS: could not clk_get() %s\n", src);
 		return -EINVAL;
 	}
 
-	return mcbsp->pdata->mux_signal(mcbsp->dev, signal, src);
+	pm_runtime_put_sync(mcbsp->dev);
+
+	r = clk_set_parent(mcbsp->fclk, fck_src);
+	if (r) {
+		dev_err(mcbsp->dev, "CLKS: could not clk_set_parent() to %s\n",
+			src);
+		clk_put(fck_src);
+		return r;
+	}
+
+	pm_runtime_get_sync(mcbsp->dev);
+
+	clk_put(fck_src);
+
+	return 0;
+
 }
 
 #define max_thres(m)			(mcbsp->pdata->buffer_size)
diff --git a/sound/soc/omap/mcbsp.h b/sound/soc/omap/mcbsp.h
index 262a615..49a6725 100644
--- a/sound/soc/omap/mcbsp.h
+++ b/sound/soc/omap/mcbsp.h
@@ -334,9 +334,6 @@
 /* McBSP functional clock source changing function */
 int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id);
 
-/* McBSP signal muxing API */
-int omap_mcbsp_6pin_src_mux(struct omap_mcbsp *mcbsp, u8 mux);
-
 /* Sidetone specific API */
 int omap_st_set_chgain(struct omap_mcbsp *mcbsp, int channel, s16 chgain);
 int omap_st_get_chgain(struct omap_mcbsp *mcbsp, int channel, s16 *chgain);
diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c
index 45909ca..4a73ef3 100644
--- a/sound/soc/omap/omap-abe-twl6040.c
+++ b/sound/soc/omap/omap-abe-twl6040.c
@@ -25,6 +25,7 @@
 #include <linux/mfd/twl6040.h>
 #include <linux/platform_data/omap-abe-twl6040.h>
 #include <linux/module.h>
+#include <linux/of.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -39,6 +40,8 @@
 struct abe_twl6040 {
 	int	jack_detection;	/* board can detect jack events */
 	int	mclk_freq;	/* MCLK frequency speed for twl6040 */
+
+	struct platform_device *dmic_codec_dev;
 };
 
 static int omap_abe_hw_params(struct snd_pcm_substream *substream,
@@ -181,17 +184,6 @@
 	int hs_trim;
 	int ret = 0;
 
-	/* Disable not connected paths if not used */
-	twl6040_disconnect_pin(dapm, pdata->has_hs, "Headset Stereophone");
-	twl6040_disconnect_pin(dapm, pdata->has_hf, "Ext Spk");
-	twl6040_disconnect_pin(dapm, pdata->has_ep, "Earphone Spk");
-	twl6040_disconnect_pin(dapm, pdata->has_aux, "Line Out");
-	twl6040_disconnect_pin(dapm, pdata->has_vibra, "Vinrator");
-	twl6040_disconnect_pin(dapm, pdata->has_hsmic, "Headset Mic");
-	twl6040_disconnect_pin(dapm, pdata->has_mainmic, "Main Handset Mic");
-	twl6040_disconnect_pin(dapm, pdata->has_submic, "Sub Handset Mic");
-	twl6040_disconnect_pin(dapm, pdata->has_afm, "Line In");
-
 	/*
 	 * Configure McPDM offset cancellation based on the HSOTRIM value from
 	 * twl6040.
@@ -212,6 +204,24 @@
 		twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET);
 	}
 
+	/*
+	 * NULL pdata means we booted with DT. In this case the routing is
+	 * provided and the card is fully routed, no need to mark pins.
+	 */
+	if (!pdata)
+		return ret;
+
+	/* Disable not connected paths if not used */
+	twl6040_disconnect_pin(dapm, pdata->has_hs, "Headset Stereophone");
+	twl6040_disconnect_pin(dapm, pdata->has_hf, "Ext Spk");
+	twl6040_disconnect_pin(dapm, pdata->has_ep, "Earphone Spk");
+	twl6040_disconnect_pin(dapm, pdata->has_aux, "Line Out");
+	twl6040_disconnect_pin(dapm, pdata->has_vibra, "Vinrator");
+	twl6040_disconnect_pin(dapm, pdata->has_hsmic, "Headset Mic");
+	twl6040_disconnect_pin(dapm, pdata->has_mainmic, "Main Handset Mic");
+	twl6040_disconnect_pin(dapm, pdata->has_submic, "Sub Handset Mic");
+	twl6040_disconnect_pin(dapm, pdata->has_afm, "Line In");
+
 	return ret;
 }
 
@@ -266,52 +276,116 @@
 static __devinit int omap_abe_probe(struct platform_device *pdev)
 {
 	struct omap_abe_twl6040_data *pdata = dev_get_platdata(&pdev->dev);
+	struct device_node *node = pdev->dev.of_node;
 	struct snd_soc_card *card = &omap_abe_card;
 	struct abe_twl6040 *priv;
 	int num_links = 0;
-	int ret;
+	int ret = 0;
 
 	card->dev = &pdev->dev;
 
-	if (!pdata) {
-		dev_err(&pdev->dev, "Missing pdata\n");
-		return -ENODEV;
-	}
-
 	priv = devm_kzalloc(&pdev->dev, sizeof(struct abe_twl6040), GFP_KERNEL);
 	if (priv == NULL)
 		return -ENOMEM;
 
-	if (pdata->card_name) {
-		card->name = pdata->card_name;
+	priv->dmic_codec_dev = ERR_PTR(-EINVAL);
+
+	if (node) {
+		struct device_node *dai_node;
+
+		if (snd_soc_of_parse_card_name(card, "ti,model")) {
+			dev_err(&pdev->dev, "Card name is not provided\n");
+			return -ENODEV;
+		}
+
+		ret = snd_soc_of_parse_audio_routing(card,
+						"ti,audio-routing");
+		if (ret) {
+			dev_err(&pdev->dev,
+				"Error while parsing DAPM routing\n");
+			return ret;
+		}
+
+		dai_node = of_parse_phandle(node, "ti,mcpdm", 0);
+		if (!dai_node) {
+			dev_err(&pdev->dev, "McPDM node is not provided\n");
+			return -EINVAL;
+		}
+		abe_twl6040_dai_links[0].cpu_dai_name  = NULL;
+		abe_twl6040_dai_links[0].cpu_of_node = dai_node;
+
+		dai_node = of_parse_phandle(node, "ti,dmic", 0);
+		if (dai_node) {
+			num_links = 2;
+			abe_twl6040_dai_links[1].cpu_dai_name  = NULL;
+			abe_twl6040_dai_links[1].cpu_of_node = dai_node;
+
+			priv->dmic_codec_dev = platform_device_register_simple(
+						"dmic-codec", -1, NULL, 0);
+			if (IS_ERR(priv->dmic_codec_dev)) {
+				dev_err(&pdev->dev,
+					"Can't instantiate dmic-codec\n");
+				return PTR_ERR(priv->dmic_codec_dev);
+			}
+		} else {
+			num_links = 1;
+		}
+
+		of_property_read_u32(node, "ti,jack-detection",
+				     &priv->jack_detection);
+		of_property_read_u32(node, "ti,mclk-freq",
+				     &priv->mclk_freq);
+		if (!priv->mclk_freq) {
+			dev_err(&pdev->dev, "MCLK frequency not provided\n");
+			ret = -EINVAL;
+			goto err_unregister;
+		}
+
+		omap_abe_card.fully_routed = 1;
+	} else if (pdata) {
+		if (pdata->card_name) {
+			card->name = pdata->card_name;
+		} else {
+			dev_err(&pdev->dev, "Card name is not provided\n");
+			return -ENODEV;
+		}
+
+		if (pdata->has_dmic)
+			num_links = 2;
+		else
+			num_links = 1;
+
+		priv->jack_detection = pdata->jack_detection;
+		priv->mclk_freq = pdata->mclk_freq;
 	} else {
-		dev_err(&pdev->dev, "Card name is not provided\n");
+		dev_err(&pdev->dev, "Missing pdata\n");
 		return -ENODEV;
 	}
 
-	priv->jack_detection = pdata->jack_detection;
-	priv->mclk_freq = pdata->mclk_freq;
-
 
 	if (!priv->mclk_freq) {
 		dev_err(&pdev->dev, "MCLK frequency missing\n");
-		return -ENODEV;
+		ret = -ENODEV;
+		goto err_unregister;
 	}
 
-	if (pdata->has_dmic)
-		num_links = 2;
-	else
-		num_links = 1;
-
 	card->dai_link = abe_twl6040_dai_links;
 	card->num_links = num_links;
 
 	snd_soc_card_set_drvdata(card, priv);
 
 	ret = snd_soc_register_card(card);
-	if (ret)
+	if (ret) {
 		dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
 			ret);
+		goto err_unregister;
+	}
+
+	return 0;
+
+err_unregister:
+	if (!IS_ERR(priv->dmic_codec_dev))
+		platform_device_unregister(priv->dmic_codec_dev);
 
 	return ret;
 }
@@ -319,17 +393,28 @@
 static int __devexit omap_abe_remove(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
+	struct abe_twl6040 *priv = snd_soc_card_get_drvdata(card);
 
 	snd_soc_unregister_card(card);
 
+	if (!IS_ERR(priv->dmic_codec_dev))
+		platform_device_unregister(priv->dmic_codec_dev);
+
 	return 0;
 }
 
+static const struct of_device_id omap_abe_of_match[] = {
+	{.compatible = "ti,abe-twl6040", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, omap_abe_of_match);
+
 static struct platform_driver omap_abe_driver = {
 	.driver = {
 		.name = "omap-abe-twl6040",
 		.owner = THIS_MODULE,
 		.pm = &snd_soc_pm_ops,
+		.of_match_table = omap_abe_of_match,
 	},
 	.probe = omap_abe_probe,
 	.remove = __devexit_p(omap_abe_remove),
diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c
index 75f5dca..68f2cd1 100644
--- a/sound/soc/omap/omap-dmic.c
+++ b/sound/soc/omap/omap-dmic.c
@@ -33,7 +33,6 @@
 #include <linux/slab.h>
 #include <linux/pm_runtime.h>
 #include <linux/of_device.h>
-#include <plat/dma.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -63,8 +62,6 @@
  */
 static struct omap_pcm_dma_data omap_dmic_dai_dma_params = {
 	.name		= "DMIC capture",
-	.data_type	= OMAP_DMA_DATA_TYPE_S32,
-	.sync_mode	= OMAP_DMA_SYNC_PACKET,
 };
 
 static inline void omap_dmic_write(struct omap_dmic *dmic, u16 reg, u32 val)
@@ -121,6 +118,7 @@
 
 	mutex_unlock(&dmic->mutex);
 
+	snd_soc_dai_set_dma_data(dai, substream, &omap_dmic_dai_dma_params);
 	return ret;
 }
 
@@ -205,6 +203,7 @@
 				    struct snd_soc_dai *dai)
 {
 	struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
+	struct omap_pcm_dma_data *dma_data;
 	int channels;
 
 	dmic->clk_div = omap_dmic_select_divider(dmic, params_rate(params));
@@ -230,8 +229,8 @@
 	}
 
 	/* packet size is threshold * channels */
-	omap_dmic_dai_dma_params.packet_size = dmic->threshold * channels;
-	snd_soc_dai_set_dma_data(dai, substream, &omap_dmic_dai_dma_params);
+	dma_data = snd_soc_dai_get_dma_data(dai, substream);
+	dma_data->packet_size = dmic->threshold * channels;
 
 	return 0;
 }
diff --git a/sound/soc/omap/omap-hdmi.c b/sound/soc/omap/omap-hdmi.c
index a08245d..f59c69f 100644
--- a/sound/soc/omap/omap-hdmi.c
+++ b/sound/soc/omap/omap-hdmi.c
@@ -34,7 +34,6 @@
 #include <sound/asoundef.h>
 #include <video/omapdss.h>
 
-#include <plat/dma.h>
 #include "omap-pcm.h"
 #include "omap-hdmi.h"
 
@@ -68,6 +67,9 @@
 		dev_err(dai->dev, "audio not supported\n");
 		return -ENODEV;
 	}
+
+	snd_soc_dai_set_dma_data(dai, substream, &priv->dma_params);
+
 	return 0;
 }
 
@@ -86,24 +88,24 @@
 	struct hdmi_priv *priv = snd_soc_dai_get_drvdata(dai);
 	struct snd_aes_iec958 *iec = &priv->iec;
 	struct snd_cea_861_aud_if *cea = &priv->cea;
+	struct omap_pcm_dma_data *dma_data;
 	int err = 0;
 
+	dma_data = snd_soc_dai_get_dma_data(dai, substream);
+
 	switch (params_format(params)) {
 	case SNDRV_PCM_FORMAT_S16_LE:
-		priv->dma_params.packet_size = 16;
+		dma_data->packet_size = 16;
 		break;
 	case SNDRV_PCM_FORMAT_S24_LE:
-		priv->dma_params.packet_size = 32;
+		dma_data->packet_size = 32;
 		break;
 	default:
 		dev_err(dai->dev, "format not supported!\n");
 		return -EINVAL;
 	}
 
-	priv->dma_params.data_type = OMAP_DMA_DATA_TYPE_S32;
-
-	snd_soc_dai_set_dma_data(dai, substream,
-				 &priv->dma_params);
+	dma_data->data_type = 32;
 
 	/*
 	 * fill the IEC-60958 channel status word
@@ -290,7 +292,6 @@
 
 	hdmi_data->dma_params.dma_req =  hdmi_rsrc->start;
 	hdmi_data->dma_params.name = "HDMI playback";
-	hdmi_data->dma_params.sync_mode = OMAP_DMA_SYNC_PACKET;
 
 	/*
 	 * TODO: We assume that there is only one DSS HDMI device. Future
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 1b186277..a6ee157 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -26,6 +26,8 @@
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -33,7 +35,6 @@
 #include <sound/soc.h>
 
 #include <plat/cpu.h>
-#include <plat/dma.h>
 #include <linux/platform_data/asoc-ti-mcbsp.h>
 #include "mcbsp.h"
 #include "omap-mcbsp.h"
@@ -80,9 +81,6 @@
 	 */
 	if (dma_data->packet_size)
 		words = dma_data->packet_size;
-	else if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD)
-		words = snd_pcm_lib_period_bytes(substream) /
-						(mcbsp->wlen / 8);
 	else
 		words = 1;
 
@@ -154,6 +152,9 @@
 					   SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2);
 	}
 
+	snd_soc_dai_set_dma_data(cpu_dai, substream,
+				 &mcbsp->dma_data[substream->stream]);
+
 	return err;
 }
 
@@ -227,20 +228,18 @@
 	struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
 	struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs;
 	struct omap_pcm_dma_data *dma_data;
-	int wlen, channels, wpf, sync_mode = OMAP_DMA_SYNC_ELEMENT;
+	int wlen, channels, wpf;
 	int pkt_size = 0;
 	unsigned int format, div, framesize, master;
 
-	dma_data = &mcbsp->dma_data[substream->stream];
+	dma_data = snd_soc_dai_get_dma_data(cpu_dai, substream);
 	channels = params_channels(params);
 
 	switch (params_format(params)) {
 	case SNDRV_PCM_FORMAT_S16_LE:
-		dma_data->data_type = OMAP_DMA_DATA_TYPE_S16;
 		wlen = 16;
 		break;
 	case SNDRV_PCM_FORMAT_S32_LE:
-		dma_data->data_type = OMAP_DMA_DATA_TYPE_S32;
 		wlen = 32;
 		break;
 	default:
@@ -250,6 +249,7 @@
 		dma_data->set_threshold = omap_mcbsp_set_threshold;
 		if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) {
 			int period_words, max_thrsh;
+			int divider = 0;
 
 			period_words = params_period_bytes(params) / (wlen / 8);
 			if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
@@ -257,46 +257,30 @@
 			else
 				max_thrsh = mcbsp->max_rx_thres;
 			/*
-			 * If the period contains less or equal number of words,
-			 * we are using the original threshold mode setup:
-			 * McBSP threshold = sDMA frame size = period_size
-			 * Otherwise we switch to sDMA packet mode:
-			 * McBSP threshold = sDMA packet size
-			 * sDMA frame size = period size
+			 * Use sDMA packet mode if McBSP is in threshold mode:
+			 * If period words less than the FIFO size the packet
+			 * size is set to the number of period words, otherwise
+			 * Look for the biggest threshold value which divides
+			 * the period size evenly.
 			 */
-			if (period_words > max_thrsh) {
-				int divider = 0;
+			divider = period_words / max_thrsh;
+			if (period_words % max_thrsh)
+				divider++;
+			while (period_words % divider &&
+				divider < period_words)
+				divider++;
+			if (divider == period_words)
+				return -EINVAL;
 
-				/*
-				 * Look for the biggest threshold value, which
-				 * divides the period size evenly.
-				 */
-				divider = period_words / max_thrsh;
-				if (period_words % max_thrsh)
-					divider++;
-				while (period_words % divider &&
-					divider < period_words)
-					divider++;
-				if (divider == period_words)
-					return -EINVAL;
-
-				pkt_size = period_words / divider;
-				sync_mode = OMAP_DMA_SYNC_PACKET;
-			} else {
-				sync_mode = OMAP_DMA_SYNC_FRAME;
-			}
+			pkt_size = period_words / divider;
 		} else if (channels > 1) {
 			/* Use packet mode for non mono streams */
 			pkt_size = channels;
-			sync_mode = OMAP_DMA_SYNC_PACKET;
 		}
 	}
 
-	dma_data->sync_mode = sync_mode;
 	dma_data->packet_size = pkt_size;
 
-	snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
-
 	if (mcbsp->configured) {
 		/* McBSP already configured by another stream */
 		return 0;
@@ -399,12 +383,14 @@
 	/* Generic McBSP register settings */
 	regs->spcr2	|= XINTM(3) | FREE;
 	regs->spcr1	|= RINTM(3);
-	/* RFIG and XFIG are not defined in 34xx */
-	if (!cpu_is_omap34xx() && !cpu_is_omap44xx()) {
+	/* RFIG and XFIG are not defined in 2430 and on OMAP3+ */
+	if (!mcbsp->pdata->has_ccr) {
 		regs->rcr2	|= RFIG;
 		regs->xcr2	|= XFIG;
 	}
-	if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
+
+	/* Configure XCCR/RCCR only for revisions which have ccr registers */
+	if (mcbsp->pdata->has_ccr) {
 		regs->xccr = DXENDLY(1) | XDMAEN | XDISABLE;
 		regs->rccr = RFULL_CYCLE | RDMAEN | RDISABLE;
 	}
@@ -517,21 +503,9 @@
 			return -EBUSY;
 	}
 
-	if (clk_id == OMAP_MCBSP_SYSCLK_CLK ||
-	    clk_id == OMAP_MCBSP_SYSCLK_CLKS_FCLK ||
-	    clk_id == OMAP_MCBSP_SYSCLK_CLKS_EXT ||
-	    clk_id == OMAP_MCBSP_SYSCLK_CLKX_EXT ||
-	    clk_id == OMAP_MCBSP_SYSCLK_CLKR_EXT) {
-		mcbsp->in_freq = freq;
-		regs->srgr2	&= ~CLKSM;
-		regs->pcr0	&= ~SCLKME;
-	} else if (cpu_class_is_omap1()) {
-		/*
-		 * McBSP CLKR/FSR signal muxing functions are only available on
-		 * OMAP2 or newer versions
-		 */
-		return -EINVAL;
-	}
+	mcbsp->in_freq = freq;
+	regs->srgr2 &= ~CLKSM;
+	regs->pcr0 &= ~SCLKME;
 
 	switch (clk_id) {
 	case OMAP_MCBSP_SYSCLK_CLK:
@@ -559,20 +533,6 @@
 	case OMAP_MCBSP_SYSCLK_CLKR_EXT:
 		regs->pcr0	|= SCLKME;
 		break;
-
-
-	case OMAP_MCBSP_CLKR_SRC_CLKR:
-		err = omap_mcbsp_6pin_src_mux(mcbsp, CLKR_SRC_CLKR);
-		break;
-	case OMAP_MCBSP_CLKR_SRC_CLKX:
-		err = omap_mcbsp_6pin_src_mux(mcbsp, CLKR_SRC_CLKX);
-		break;
-	case OMAP_MCBSP_FSR_SRC_FSR:
-		err = omap_mcbsp_6pin_src_mux(mcbsp, FSR_SRC_FSR);
-		break;
-	case OMAP_MCBSP_FSR_SRC_FSX:
-		err = omap_mcbsp_6pin_src_mux(mcbsp, FSR_SRC_FSX);
-		break;
 	default:
 		err = -ENODEV;
 	}
@@ -642,9 +602,9 @@
 	return 0;
 }
 
-#define OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(channel)			\
+#define OMAP_MCBSP_ST_CHANNEL_VOLUME(channel)				\
 static int								\
-omap_mcbsp_set_st_ch##channel##_volume(struct snd_kcontrol *kc,	\
+omap_mcbsp_set_st_ch##channel##_volume(struct snd_kcontrol *kc,		\
 					struct snd_ctl_elem_value *uc)	\
 {									\
 	struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kc);		\
@@ -660,11 +620,10 @@
 									\
 	/* OMAP McBSP implementation uses index values 0..4 */		\
 	return omap_st_set_chgain(mcbsp, channel, val);			\
-}
-
-#define OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(channel)			\
+}									\
+									\
 static int								\
-omap_mcbsp_get_st_ch##channel##_volume(struct snd_kcontrol *kc,	\
+omap_mcbsp_get_st_ch##channel##_volume(struct snd_kcontrol *kc,		\
 					struct snd_ctl_elem_value *uc)	\
 {									\
 	struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kc);		\
@@ -678,10 +637,8 @@
 	return 0;							\
 }
 
-OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(0)
-OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(1)
-OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(0)
-OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(1)
+OMAP_MCBSP_ST_CHANNEL_VOLUME(0)
+OMAP_MCBSP_ST_CHANNEL_VOLUME(1)
 
 static int omap_mcbsp_st_put_mode(struct snd_kcontrol *kcontrol,
 				struct snd_ctl_elem_value *ucontrol)
@@ -711,41 +668,34 @@
 	return 0;
 }
 
-static const struct snd_kcontrol_new omap_mcbsp2_st_controls[] = {
-	SOC_SINGLE_EXT("McBSP2 Sidetone Switch", 1, 0, 1, 0,
-			omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode),
-	OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP2 Sidetone Channel 0 Volume",
-				      -32768, 32767,
-				      omap_mcbsp_get_st_ch0_volume,
-				      omap_mcbsp_set_st_ch0_volume),
-	OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP2 Sidetone Channel 1 Volume",
-				      -32768, 32767,
-				      omap_mcbsp_get_st_ch1_volume,
-				      omap_mcbsp_set_st_ch1_volume),
-};
+#define OMAP_MCBSP_ST_CONTROLS(port)					  \
+static const struct snd_kcontrol_new omap_mcbsp##port##_st_controls[] = { \
+SOC_SINGLE_EXT("McBSP" #port " Sidetone Switch", 1, 0, 1, 0,		  \
+	       omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode),		  \
+OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP" #port " Sidetone Channel 0 Volume", \
+			      -32768, 32767,				  \
+			      omap_mcbsp_get_st_ch0_volume,		  \
+			      omap_mcbsp_set_st_ch0_volume),		  \
+OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP" #port " Sidetone Channel 1 Volume", \
+			      -32768, 32767,				  \
+			      omap_mcbsp_get_st_ch1_volume,		  \
+			      omap_mcbsp_set_st_ch1_volume),		  \
+}
 
-static const struct snd_kcontrol_new omap_mcbsp3_st_controls[] = {
-	SOC_SINGLE_EXT("McBSP3 Sidetone Switch", 2, 0, 1, 0,
-			omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode),
-	OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP3 Sidetone Channel 0 Volume",
-				      -32768, 32767,
-				      omap_mcbsp_get_st_ch0_volume,
-				      omap_mcbsp_set_st_ch0_volume),
-	OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP3 Sidetone Channel 1 Volume",
-				      -32768, 32767,
-				      omap_mcbsp_get_st_ch1_volume,
-				      omap_mcbsp_set_st_ch1_volume),
-};
+OMAP_MCBSP_ST_CONTROLS(2);
+OMAP_MCBSP_ST_CONTROLS(3);
 
 int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd)
 {
 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
 
-	if (!mcbsp->st_data)
-		return -ENODEV;
+	if (!mcbsp->st_data) {
+		dev_warn(mcbsp->dev, "No sidetone data for port\n");
+		return 0;
+	}
 
-	switch (cpu_dai->id) {
+	switch (mcbsp->id) {
 	case 2: /* McBSP 2 */
 		return snd_soc_add_dai_controls(cpu_dai,
 					omap_mcbsp2_st_controls,
@@ -762,13 +712,74 @@
 }
 EXPORT_SYMBOL_GPL(omap_mcbsp_st_add_controls);
 
+static struct omap_mcbsp_platform_data omap2420_pdata = {
+	.reg_step = 4,
+	.reg_size = 2,
+};
+
+static struct omap_mcbsp_platform_data omap2430_pdata = {
+	.reg_step = 4,
+	.reg_size = 4,
+	.has_ccr = true,
+};
+
+static struct omap_mcbsp_platform_data omap3_pdata = {
+	.reg_step = 4,
+	.reg_size = 4,
+	.has_ccr = true,
+	.has_wakeup = true,
+};
+
+static struct omap_mcbsp_platform_data omap4_pdata = {
+	.reg_step = 4,
+	.reg_size = 4,
+	.has_ccr = true,
+	.has_wakeup = true,
+};
+
+static const struct of_device_id omap_mcbsp_of_match[] = {
+	{
+		.compatible = "ti,omap2420-mcbsp",
+		.data = &omap2420_pdata,
+	},
+	{
+		.compatible = "ti,omap2430-mcbsp",
+		.data = &omap2430_pdata,
+	},
+	{
+		.compatible = "ti,omap3-mcbsp",
+		.data = &omap3_pdata,
+	},
+	{
+		.compatible = "ti,omap4-mcbsp",
+		.data = &omap4_pdata,
+	},
+	{ },
+};
+MODULE_DEVICE_TABLE(of, omap_mcbsp_of_match);
+
 static __devinit int asoc_mcbsp_probe(struct platform_device *pdev)
 {
 	struct omap_mcbsp_platform_data *pdata = dev_get_platdata(&pdev->dev);
 	struct omap_mcbsp *mcbsp;
+	const struct of_device_id *match;
 	int ret;
 
-	if (!pdata) {
+	match = of_match_device(omap_mcbsp_of_match, &pdev->dev);
+	if (match) {
+		struct device_node *node = pdev->dev.of_node;
+		int buffer_size;
+
+		pdata = devm_kzalloc(&pdev->dev,
+				     sizeof(struct omap_mcbsp_platform_data),
+				     GFP_KERNEL);
+		if (!pdata)
+			return -ENOMEM;
+
+		memcpy(pdata, match->data, sizeof(*pdata));
+		if (!of_property_read_u32(node, "ti,buffer-size", &buffer_size))
+			pdata->buffer_size = buffer_size;
+	} else if (!pdata) {
 		dev_err(&pdev->dev, "missing platform data.\n");
 		return -EINVAL;
 	}
@@ -810,6 +821,7 @@
 	.driver = {
 			.name = "omap-mcbsp",
 			.owner = THIS_MODULE,
+			.of_match_table = omap_mcbsp_of_match,
 	},
 
 	.probe = asoc_mcbsp_probe,
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h
index f877b16..ba8386a 100644
--- a/sound/soc/omap/omap-mcbsp.h
+++ b/sound/soc/omap/omap-mcbsp.h
@@ -32,10 +32,6 @@
 	OMAP_MCBSP_SYSCLK_CLK,		/* Internal ICLK */
 	OMAP_MCBSP_SYSCLK_CLKX_EXT,	/* External CLKX pin */
 	OMAP_MCBSP_SYSCLK_CLKR_EXT,	/* External CLKR pin */
-	OMAP_MCBSP_CLKR_SRC_CLKR,	/* CLKR from CLKR pin */
-	OMAP_MCBSP_CLKR_SRC_CLKX,	/* CLKR from CLKX pin */
-	OMAP_MCBSP_FSR_SRC_FSR,		/* FSR from FSR pin */
-	OMAP_MCBSP_FSR_SRC_FSX,		/* FSR from FSX pin */
 };
 
 /* McBSP dividers */
@@ -43,22 +39,6 @@
 	OMAP_MCBSP_CLKGDV,		/* Sample rate generator divider */
 };
 
-#if defined(CONFIG_SOC_OMAP2420)
-#define NUM_LINKS	2
-#endif
-#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
-#undef  NUM_LINKS
-#define NUM_LINKS	3
-#endif
-#if defined(CONFIG_ARCH_OMAP4)
-#undef  NUM_LINKS
-#define NUM_LINKS	4
-#endif
-#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_SOC_OMAP2430)
-#undef  NUM_LINKS
-#define NUM_LINKS	5
-#endif
-
 int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd);
 
 #endif
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index ea053c3..c02b001 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -40,7 +40,6 @@
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 
-#include <plat/dma.h>
 #include <plat/omap_hwmod.h>
 #include "omap-mcpdm.h"
 #include "omap-pcm.h"
@@ -73,17 +72,9 @@
 static struct omap_pcm_dma_data omap_mcpdm_dai_dma_params[] = {
 	{
 		.name = "Audio playback",
-		.dma_req = OMAP44XX_DMA_MCPDM_DL,
-		.data_type = OMAP_DMA_DATA_TYPE_S32,
-		.sync_mode = OMAP_DMA_SYNC_PACKET,
-		.port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_REG_DN_DATA,
 	},
 	{
 		.name = "Audio capture",
-		.dma_req = OMAP44XX_DMA_MCPDM_UP,
-		.data_type = OMAP_DMA_DATA_TYPE_S32,
-		.sync_mode = OMAP_DMA_SYNC_PACKET,
-		.port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_REG_UP_DATA,
 	},
 };
 
@@ -278,9 +269,11 @@
 		}
 		omap_mcpdm_open_streams(mcpdm);
 	}
-
 	mutex_unlock(&mcpdm->mutex);
 
+	snd_soc_dai_set_dma_data(dai, substream,
+				 &omap_mcpdm_dai_dma_params[substream->stream]);
+
 	return 0;
 }
 
@@ -335,7 +328,7 @@
 		return -EINVAL;
 	}
 
-	dma_data = &omap_mcpdm_dai_dma_params[stream];
+	dma_data = snd_soc_dai_get_dma_data(dai, substream);
 
 	/* Configure McPDM channels, and DMA packet size */
 	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -347,8 +340,6 @@
 		dma_data->packet_size = mcpdm->up_threshold * channels;
 	}
 
-	snd_soc_dai_set_dma_data(dai, substream, dma_data);
-
 	return 0;
 }
 
@@ -447,9 +438,8 @@
 {
 	struct omap_mcpdm *mcpdm;
 	struct resource *res;
-	int ret = 0;
 
-	mcpdm = kzalloc(sizeof(struct omap_mcpdm), GFP_KERNEL);
+	mcpdm = devm_kzalloc(&pdev->dev, sizeof(struct omap_mcpdm), GFP_KERNEL);
 	if (!mcpdm)
 		return -ENOMEM;
 
@@ -457,56 +447,54 @@
 
 	mutex_init(&mcpdm->mutex);
 
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dma");
+	if (res == NULL)
+		return -ENOMEM;
+
+	omap_mcpdm_dai_dma_params[0].port_addr = res->start + MCPDM_REG_DN_DATA;
+	omap_mcpdm_dai_dma_params[1].port_addr = res->start + MCPDM_REG_UP_DATA;
+
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (res == NULL) {
-		dev_err(&pdev->dev, "no resource\n");
-		goto err_res;
-	}
+	if (res == NULL)
+		return -ENOMEM;
 
-	if (!request_mem_region(res->start, resource_size(res), "McPDM")) {
-		ret = -EBUSY;
-		goto err_res;
-	}
+	res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "dn_link");
+	if (!res)
+		return -ENODEV;
 
-	mcpdm->io_base = ioremap(res->start, resource_size(res));
-	if (!mcpdm->io_base) {
-		ret = -ENOMEM;
-		goto err_iomap;
-	}
+	omap_mcpdm_dai_dma_params[0].dma_req = res->start;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "up_link");
+	if (!res)
+		return -ENODEV;
+
+	omap_mcpdm_dai_dma_params[1].dma_req = res->start;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu");
+	if (res == NULL)
+		return -ENOMEM;
+
+	if (!devm_request_mem_region(&pdev->dev, res->start,
+				     resource_size(res), "McPDM"))
+		return -EBUSY;
+
+	mcpdm->io_base = devm_ioremap(&pdev->dev, res->start,
+				      resource_size(res));
+	if (!mcpdm->io_base)
+		return -ENOMEM;
 
 	mcpdm->irq = platform_get_irq(pdev, 0);
-	if (mcpdm->irq < 0) {
-		ret = mcpdm->irq;
-		goto err_irq;
-	}
+	if (mcpdm->irq < 0)
+		return mcpdm->irq;
 
 	mcpdm->dev = &pdev->dev;
 
-	ret = snd_soc_register_dai(&pdev->dev, &omap_mcpdm_dai);
-	if (!ret)
-		return 0;
-
-err_irq:
-	iounmap(mcpdm->io_base);
-err_iomap:
-	release_mem_region(res->start, resource_size(res));
-err_res:
-	kfree(mcpdm);
-	return ret;
+	return snd_soc_register_dai(&pdev->dev, &omap_mcpdm_dai);
 }
 
 static int __devexit asoc_mcpdm_remove(struct platform_device *pdev)
 {
-	struct omap_mcpdm *mcpdm = platform_get_drvdata(pdev);
-	struct resource *res;
-
 	snd_soc_unregister_dai(&pdev->dev);
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	iounmap(mcpdm->io_base);
-	release_mem_region(res->start, resource_size(res));
-
-	kfree(mcpdm);
 	return 0;
 }
 
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index b309941..340874e 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -25,13 +25,14 @@
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/omap-dma.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
+#include <sound/dmaengine_pcm.h>
 #include <sound/soc.h>
 
 #include <plat/cpu.h>
-#include <plat/dma.h>
 #include "omap-pcm.h"
 
 static const struct snd_pcm_hardware omap_pcm_hardware = {
@@ -50,61 +51,34 @@
 	.buffer_bytes_max	= 128 * 1024,
 };
 
-struct omap_runtime_data {
-	spinlock_t			lock;
-	struct omap_pcm_dma_data	*dma_data;
-	int				dma_ch;
-	int				period_index;
-};
-
-static void omap_pcm_dma_irq(int ch, u16 stat, void *data)
+static int omap_pcm_get_dma_buswidth(int num_bits)
 {
-	struct snd_pcm_substream *substream = data;
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct omap_runtime_data *prtd = runtime->private_data;
-	unsigned long flags;
+	int buswidth;
 
-	if ((cpu_is_omap1510())) {
-		/*
-		 * OMAP1510 doesn't fully support DMA progress counter
-		 * and there is no software emulation implemented yet,
-		 * so have to maintain our own progress counters
-		 * that can be used by omap_pcm_pointer() instead.
-		 */
-		spin_lock_irqsave(&prtd->lock, flags);
-		if ((stat == OMAP_DMA_LAST_IRQ) &&
-				(prtd->period_index == runtime->periods - 1)) {
-			/* we are in sync, do nothing */
-			spin_unlock_irqrestore(&prtd->lock, flags);
-			return;
-		}
-		if (prtd->period_index >= 0) {
-			if (stat & OMAP_DMA_BLOCK_IRQ) {
-				/* end of buffer reached, loop back */
-				prtd->period_index = 0;
-			} else if (stat & OMAP_DMA_LAST_IRQ) {
-				/* update the counter for the last period */
-				prtd->period_index = runtime->periods - 1;
-			} else if (++prtd->period_index >= runtime->periods) {
-				/* end of buffer missed? loop back */
-				prtd->period_index = 0;
-			}
-		}
-		spin_unlock_irqrestore(&prtd->lock, flags);
+	switch (num_bits) {
+	case 16:
+		buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
+		break;
+	case 32:
+		buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
+		break;
+	default:
+		buswidth = -EINVAL;
+		break;
 	}
-
-	snd_pcm_period_elapsed(substream);
+	return buswidth;
 }
 
+
 /* this may get called several times by oss emulation */
 static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
 			      struct snd_pcm_hw_params *params)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct omap_runtime_data *prtd = runtime->private_data;
 	struct omap_pcm_dma_data *dma_data;
-
+	struct dma_slave_config config;
+	struct dma_chan *chan;
 	int err = 0;
 
 	dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
@@ -117,162 +91,78 @@
 	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
 	runtime->dma_bytes = params_buffer_bytes(params);
 
-	if (prtd->dma_data)
-		return 0;
-	prtd->dma_data = dma_data;
-	err = omap_request_dma(dma_data->dma_req, dma_data->name,
-			       omap_pcm_dma_irq, substream, &prtd->dma_ch);
-	if (!err) {
-		/*
-		 * Link channel with itself so DMA doesn't need any
-		 * reprogramming while looping the buffer
-		 */
-		omap_dma_link_lch(prtd->dma_ch, prtd->dma_ch);
+	chan = snd_dmaengine_pcm_get_chan(substream);
+	if (!chan)
+		return -EINVAL;
+
+	/* fills in addr_width and direction */
+	err = snd_hwparams_to_dma_slave_config(substream, params, &config);
+	if (err)
+		return err;
+
+	/* Override the *_dma addr_width if requested by the DAI driver */
+	if (dma_data->data_type) {
+		int buswidth = omap_pcm_get_dma_buswidth(dma_data->data_type);
+
+		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+			config.dst_addr_width = buswidth;
+		else
+			config.src_addr_width = buswidth;
 	}
 
-	return err;
+	config.src_addr = dma_data->port_addr;
+	config.dst_addr = dma_data->port_addr;
+	config.src_maxburst = dma_data->packet_size;
+	config.dst_maxburst = dma_data->packet_size;
+
+	return dmaengine_slave_config(chan, &config);
 }
 
 static int omap_pcm_hw_free(struct snd_pcm_substream *substream)
 {
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct omap_runtime_data *prtd = runtime->private_data;
-
-	if (prtd->dma_data == NULL)
-		return 0;
-
-	omap_dma_unlink_lch(prtd->dma_ch, prtd->dma_ch);
-	omap_free_dma(prtd->dma_ch);
-	prtd->dma_data = NULL;
-
 	snd_pcm_set_runtime_buffer(substream, NULL);
-
-	return 0;
-}
-
-static int omap_pcm_prepare(struct snd_pcm_substream *substream)
-{
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct omap_runtime_data *prtd = runtime->private_data;
-	struct omap_pcm_dma_data *dma_data = prtd->dma_data;
-	struct omap_dma_channel_params dma_params;
-	int bytes;
-
-	/* return if this is a bufferless transfer e.g.
-	 * codec <--> BT codec or GSM modem -- lg FIXME */
-	if (!prtd->dma_data)
-		return 0;
-
-	memset(&dma_params, 0, sizeof(dma_params));
-	dma_params.data_type			= dma_data->data_type;
-	dma_params.trigger			= dma_data->dma_req;
-	dma_params.sync_mode			= dma_data->sync_mode;
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		dma_params.src_amode		= OMAP_DMA_AMODE_POST_INC;
-		dma_params.dst_amode		= OMAP_DMA_AMODE_CONSTANT;
-		dma_params.src_or_dst_synch	= OMAP_DMA_DST_SYNC;
-		dma_params.src_start		= runtime->dma_addr;
-		dma_params.dst_start		= dma_data->port_addr;
-		dma_params.dst_port		= OMAP_DMA_PORT_MPUI;
-		dma_params.dst_fi		= dma_data->packet_size;
-	} else {
-		dma_params.src_amode		= OMAP_DMA_AMODE_CONSTANT;
-		dma_params.dst_amode		= OMAP_DMA_AMODE_POST_INC;
-		dma_params.src_or_dst_synch	= OMAP_DMA_SRC_SYNC;
-		dma_params.src_start		= dma_data->port_addr;
-		dma_params.dst_start		= runtime->dma_addr;
-		dma_params.src_port		= OMAP_DMA_PORT_MPUI;
-		dma_params.src_fi		= dma_data->packet_size;
-	}
-	/*
-	 * Set DMA transfer frame size equal to ALSA period size and frame
-	 * count as no. of ALSA periods. Then with DMA frame interrupt enabled,
-	 * we can transfer the whole ALSA buffer with single DMA transfer but
-	 * still can get an interrupt at each period bounary
-	 */
-	bytes = snd_pcm_lib_period_bytes(substream);
-	dma_params.elem_count	= bytes >> dma_data->data_type;
-	dma_params.frame_count	= runtime->periods;
-	omap_set_dma_params(prtd->dma_ch, &dma_params);
-
-	if ((cpu_is_omap1510()))
-		omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ |
-			      OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ);
-	else if (!substream->runtime->no_period_wakeup)
-		omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ);
-	else {
-		/*
-		 * No period wakeup:
-		 * we need to disable BLOCK_IRQ, which is enabled by the omap
-		 * dma core at request dma time.
-		 */
-		omap_disable_dma_irq(prtd->dma_ch, OMAP_DMA_BLOCK_IRQ);
-	}
-
-	if (!(cpu_class_is_omap1())) {
-		omap_set_dma_src_burst_mode(prtd->dma_ch,
-						OMAP_DMA_DATA_BURST_16);
-		omap_set_dma_dest_burst_mode(prtd->dma_ch,
-						OMAP_DMA_DATA_BURST_16);
-	}
-
 	return 0;
 }
 
 static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct omap_runtime_data *prtd = runtime->private_data;
-	struct omap_pcm_dma_data *dma_data = prtd->dma_data;
-	unsigned long flags;
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct omap_pcm_dma_data *dma_data;
 	int ret = 0;
 
-	spin_lock_irqsave(&prtd->lock, flags);
+	dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		prtd->period_index = 0;
 		/* Configure McBSP internal buffer usage */
 		if (dma_data->set_threshold)
 			dma_data->set_threshold(substream);
-
-		omap_start_dma(prtd->dma_ch);
 		break;
 
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		prtd->period_index = -1;
-		omap_stop_dma(prtd->dma_ch);
 		break;
 	default:
 		ret = -EINVAL;
 	}
-	spin_unlock_irqrestore(&prtd->lock, flags);
+
+	if (ret == 0)
+		ret = snd_dmaengine_pcm_trigger(substream, cmd);
 
 	return ret;
 }
 
 static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream)
 {
-	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct omap_runtime_data *prtd = runtime->private_data;
-	dma_addr_t ptr;
 	snd_pcm_uframes_t offset;
 
-	if (cpu_is_omap1510()) {
-		offset = prtd->period_index * runtime->period_size;
-	} else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
-		ptr = omap_get_dma_dst_pos(prtd->dma_ch);
-		offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
-	} else {
-		ptr = omap_get_dma_src_pos(prtd->dma_ch);
-		offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
-	}
-
-	if (offset >= runtime->buffer_size)
-		offset = 0;
+	if (cpu_is_omap1510())
+		offset = snd_dmaengine_pcm_pointer_no_residue(substream);
+	else
+		offset = snd_dmaengine_pcm_pointer(substream);
 
 	return offset;
 }
@@ -280,7 +170,8 @@
 static int omap_pcm_open(struct snd_pcm_substream *substream)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
-	struct omap_runtime_data *prtd;
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct omap_pcm_dma_data *dma_data;
 	int ret;
 
 	snd_soc_set_runtime_hwparams(substream, &omap_pcm_hardware);
@@ -289,25 +180,17 @@
 	ret = snd_pcm_hw_constraint_integer(runtime,
 					    SNDRV_PCM_HW_PARAM_PERIODS);
 	if (ret < 0)
-		goto out;
+		return ret;
 
-	prtd = kzalloc(sizeof(*prtd), GFP_KERNEL);
-	if (prtd == NULL) {
-		ret = -ENOMEM;
-		goto out;
-	}
-	spin_lock_init(&prtd->lock);
-	runtime->private_data = prtd;
-
-out:
+	dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
+	ret = snd_dmaengine_pcm_open(substream, omap_dma_filter_fn,
+				     &dma_data->dma_req);
 	return ret;
 }
 
 static int omap_pcm_close(struct snd_pcm_substream *substream)
 {
-	struct snd_pcm_runtime *runtime = substream->runtime;
-
-	kfree(runtime->private_data);
+	snd_dmaengine_pcm_close(substream);
 	return 0;
 }
 
@@ -328,7 +211,6 @@
 	.ioctl		= snd_pcm_lib_ioctl,
 	.hw_params	= omap_pcm_hw_params,
 	.hw_free	= omap_pcm_hw_free,
-	.prepare	= omap_pcm_prepare,
 	.trigger	= omap_pcm_trigger,
 	.pointer	= omap_pcm_pointer,
 	.mmap		= omap_pcm_mmap,
diff --git a/sound/soc/omap/omap-pcm.h b/sound/soc/omap/omap-pcm.h
index b92248c..cabe74c 100644
--- a/sound/soc/omap/omap-pcm.h
+++ b/sound/soc/omap/omap-pcm.h
@@ -32,8 +32,8 @@
 	int		dma_req;	/* DMA request line */
 	unsigned long	port_addr;	/* transmit/receive register */
 	void (*set_threshold)(struct snd_pcm_substream *substream);
-	int		data_type;	/* data type 8,16,32 */
-	int		sync_mode;	/* DMA sync mode */
+	int		data_type;	/* 8, 16, 32 (bits) or 0 to let omap-pcm
+					 * to decide the sDMA data type */
 	int		packet_size;	/* packet size only in PACKET mode */
 };
 
diff --git a/sound/soc/omap/omap-twl4030.c b/sound/soc/omap/omap-twl4030.c
new file mode 100644
index 0000000..3b97b879
--- /dev/null
+++ b/sound/soc/omap/omap-twl4030.c
@@ -0,0 +1,188 @@
+/*
+ * omap-twl4030.c  --  SoC audio for TI SoC based boards with twl4030 codec
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com
+ * All rights reserved.
+ *
+ * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
+ *
+ * This driver replaces the following machine drivers:
+ * omap3beagle (Author: Steve Sakoman <steve@sakoman.com>)
+ * omap3evm (Author: Anuj Aggarwal <anuj.aggarwal@ti.com>)
+ * overo (Author: Steve Sakoman <steve@sakoman.com>)
+ * igep0020 (Author: Enric Balletbo i Serra <eballetbo@iseebcn.com>)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/platform_data/omap-twl4030.h>
+#include <linux/module.h>
+#include <linux/of.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+
+#include "omap-mcbsp.h"
+#include "omap-pcm.h"
+
+static int omap_twl4030_hw_params(struct snd_pcm_substream *substream,
+	struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_card *card = codec->card;
+	unsigned int fmt;
+	int ret;
+
+	switch (params_channels(params)) {
+	case 2: /* Stereo I2S mode */
+		fmt =	SND_SOC_DAIFMT_I2S |
+			SND_SOC_DAIFMT_NB_NF |
+			SND_SOC_DAIFMT_CBM_CFM;
+		break;
+	case 4: /* Four channel TDM mode */
+		fmt =	SND_SOC_DAIFMT_DSP_A |
+			SND_SOC_DAIFMT_IB_NF |
+			SND_SOC_DAIFMT_CBM_CFM;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* Set codec DAI configuration */
+	ret = snd_soc_dai_set_fmt(codec_dai, fmt);
+	if (ret < 0) {
+		dev_err(card->dev, "can't set codec DAI configuration\n");
+		return ret;
+	}
+
+	/* Set cpu DAI configuration */
+	ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
+	if (ret < 0) {
+		dev_err(card->dev, "can't set cpu DAI configuration\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static struct snd_soc_ops omap_twl4030_ops = {
+	.hw_params = omap_twl4030_hw_params,
+};
+
+/* Digital audio interface glue - connects codec <--> CPU */
+static struct snd_soc_dai_link omap_twl4030_dai_links[] = {
+	{
+		.name = "TWL4030",
+		.stream_name = "TWL4030",
+		.cpu_dai_name = "omap-mcbsp.2",
+		.codec_dai_name = "twl4030-hifi",
+		.platform_name = "omap-pcm-audio",
+		.codec_name = "twl4030-codec",
+		.ops = &omap_twl4030_ops,
+	},
+};
+
+/* Audio machine driver */
+static struct snd_soc_card omap_twl4030_card = {
+	.owner = THIS_MODULE,
+	.dai_link = omap_twl4030_dai_links,
+	.num_links = ARRAY_SIZE(omap_twl4030_dai_links),
+};
+
+static __devinit int omap_twl4030_probe(struct platform_device *pdev)
+{
+	struct omap_tw4030_pdata *pdata = dev_get_platdata(&pdev->dev);
+	struct device_node *node = pdev->dev.of_node;
+	struct snd_soc_card *card = &omap_twl4030_card;
+	int ret = 0;
+
+	card->dev = &pdev->dev;
+
+	if (node) {
+		struct device_node *dai_node;
+
+		if (snd_soc_of_parse_card_name(card, "ti,model")) {
+			dev_err(&pdev->dev, "Card name is not provided\n");
+			return -ENODEV;
+		}
+
+		dai_node = of_parse_phandle(node, "ti,mcbsp", 0);
+		if (!dai_node) {
+			dev_err(&pdev->dev, "McBSP node is not provided\n");
+			return -EINVAL;
+		}
+		omap_twl4030_dai_links[0].cpu_dai_name  = NULL;
+		omap_twl4030_dai_links[0].cpu_of_node = dai_node;
+
+	} else if (pdata) {
+		if (pdata->card_name) {
+			card->name = pdata->card_name;
+		} else {
+			dev_err(&pdev->dev, "Card name is not provided\n");
+			return -ENODEV;
+		}
+	} else {
+		dev_err(&pdev->dev, "Missing pdata\n");
+		return -ENODEV;
+	}
+
+	ret = snd_soc_register_card(card);
+	if (ret) {
+		dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
+			ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int __devexit omap_twl4030_remove(struct platform_device *pdev)
+{
+	struct snd_soc_card *card = platform_get_drvdata(pdev);
+
+	snd_soc_unregister_card(card);
+
+	return 0;
+}
+
+static const struct of_device_id omap_twl4030_of_match[] = {
+	{.compatible = "ti,omap-twl4030", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, omap_twl4030_of_match);
+
+static struct platform_driver omap_twl4030_driver = {
+	.driver = {
+		.name = "omap-twl4030",
+		.owner = THIS_MODULE,
+		.pm = &snd_soc_pm_ops,
+		.of_match_table = omap_twl4030_of_match,
+	},
+	.probe = omap_twl4030_probe,
+	.remove = __devexit_p(omap_twl4030_remove),
+};
+
+module_platform_driver(omap_twl4030_driver);
+
+MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
+MODULE_DESCRIPTION("ALSA SoC for TI SoC based boards with twl4030 codec");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:omap-twl4030");
diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c
deleted file mode 100644
index e263188..0000000
--- a/sound/soc/omap/omap3beagle.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * omap3beagle.c  --  SoC audio for OMAP3 Beagle
- *
- * Author: Steve Sakoman <steve@sakoman.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <mach/gpio.h>
-#include <linux/platform_data/asoc-ti-mcbsp.h>
-
-#include "omap-mcbsp.h"
-#include "omap-pcm.h"
-
-static int omap3beagle_hw_params(struct snd_pcm_substream *substream,
-	struct snd_pcm_hw_params *params)
-{
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *codec_dai = rtd->codec_dai;
-	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-	unsigned int fmt;
-	int ret;
-
-	switch (params_channels(params)) {
-	case 2: /* Stereo I2S mode */
-		fmt =	SND_SOC_DAIFMT_I2S |
-			SND_SOC_DAIFMT_NB_NF |
-			SND_SOC_DAIFMT_CBM_CFM;
-		break;
-	case 4: /* Four channel TDM mode */
-		fmt =	SND_SOC_DAIFMT_DSP_A |
-			SND_SOC_DAIFMT_IB_NF |
-			SND_SOC_DAIFMT_CBM_CFM;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	/* Set codec DAI configuration */
-	ret = snd_soc_dai_set_fmt(codec_dai, fmt);
-	if (ret < 0) {
-		printk(KERN_ERR "can't set codec DAI configuration\n");
-		return ret;
-	}
-
-	/* Set cpu DAI configuration */
-	ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
-	if (ret < 0) {
-		printk(KERN_ERR "can't set cpu DAI configuration\n");
-		return ret;
-	}
-
-	/* Set the codec system clock for DAC and ADC */
-	ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
-				     SND_SOC_CLOCK_IN);
-	if (ret < 0) {
-		printk(KERN_ERR "can't set codec system clock\n");
-		return ret;
-	}
-
-	return 0;
-}
-
-static struct snd_soc_ops omap3beagle_ops = {
-	.hw_params = omap3beagle_hw_params,
-};
-
-/* Digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link omap3beagle_dai = {
-	.name = "TWL4030",
-	.stream_name = "TWL4030",
-	.cpu_dai_name = "omap-mcbsp.2",
-	.platform_name = "omap-pcm-audio",
-	.codec_dai_name = "twl4030-hifi",
-	.codec_name = "twl4030-codec",
-	.ops = &omap3beagle_ops,
-};
-
-/* Audio machine driver */
-static struct snd_soc_card snd_soc_omap3beagle = {
-	.name = "omap3beagle",
-	.owner = THIS_MODULE,
-	.dai_link = &omap3beagle_dai,
-	.num_links = 1,
-};
-
-static struct platform_device *omap3beagle_snd_device;
-
-static int __init omap3beagle_soc_init(void)
-{
-	int ret;
-
-	if (!(machine_is_omap3_beagle() || machine_is_devkit8000()))
-		return -ENODEV;
-	pr_info("OMAP3 Beagle/Devkit8000 SoC init\n");
-
-	omap3beagle_snd_device = platform_device_alloc("soc-audio", -1);
-	if (!omap3beagle_snd_device) {
-		printk(KERN_ERR "Platform device allocation failed\n");
-		return -ENOMEM;
-	}
-
-	platform_set_drvdata(omap3beagle_snd_device, &snd_soc_omap3beagle);
-
-	ret = platform_device_add(omap3beagle_snd_device);
-	if (ret)
-		goto err1;
-
-	return 0;
-
-err1:
-	printk(KERN_ERR "Unable to add platform device\n");
-	platform_device_put(omap3beagle_snd_device);
-
-	return ret;
-}
-
-static void __exit omap3beagle_soc_exit(void)
-{
-	platform_device_unregister(omap3beagle_snd_device);
-}
-
-module_init(omap3beagle_soc_init);
-module_exit(omap3beagle_soc_exit);
-
-MODULE_AUTHOR("Steve Sakoman <steve@sakoman.com>");
-MODULE_DESCRIPTION("ALSA SoC OMAP3 Beagle");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c
deleted file mode 100644
index d632bfb..0000000
--- a/sound/soc/omap/omap3evm.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * omap3evm.c  -- ALSA SoC support for OMAP3 EVM
- *
- * Author: Anuj Aggarwal <anuj.aggarwal@ti.com>
- *
- * Based on sound/soc/omap/beagle.c by Steve Sakoman
- *
- * Copyright (C) 2008 Texas Instruments, Incorporated
- *
- * 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 version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
- * whether express or implied; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- */
-
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <mach/gpio.h>
-#include <linux/platform_data/asoc-ti-mcbsp.h>
-
-#include "omap-mcbsp.h"
-#include "omap-pcm.h"
-
-static int omap3evm_hw_params(struct snd_pcm_substream *substream,
-	struct snd_pcm_hw_params *params)
-{
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *codec_dai = rtd->codec_dai;
-	int ret;
-
-	/* Set the codec system clock for DAC and ADC */
-	ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
-				     SND_SOC_CLOCK_IN);
-	if (ret < 0) {
-		printk(KERN_ERR "Can't set codec system clock\n");
-		return ret;
-	}
-
-	return 0;
-}
-
-static struct snd_soc_ops omap3evm_ops = {
-	.hw_params = omap3evm_hw_params,
-};
-
-/* Digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link omap3evm_dai = {
-	.name 		= "TWL4030",
-	.stream_name 	= "TWL4030",
-	.cpu_dai_name = "omap-mcbsp.2",
-	.codec_dai_name = "twl4030-hifi",
-	.platform_name = "omap-pcm-audio",
-	.codec_name = "twl4030-codec",
-	.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
-		   SND_SOC_DAIFMT_CBM_CFM,
-	.ops 		= &omap3evm_ops,
-};
-
-/* Audio machine driver */
-static struct snd_soc_card snd_soc_omap3evm = {
-	.name = "omap3evm",
-	.owner = THIS_MODULE,
-	.dai_link = &omap3evm_dai,
-	.num_links = 1,
-};
-
-static struct platform_device *omap3evm_snd_device;
-
-static int __init omap3evm_soc_init(void)
-{
-	int ret;
-
-	if (!machine_is_omap3evm())
-		return -ENODEV;
-	pr_info("OMAP3 EVM SoC init\n");
-
-	omap3evm_snd_device = platform_device_alloc("soc-audio", -1);
-	if (!omap3evm_snd_device) {
-		printk(KERN_ERR "Platform device allocation failed\n");
-		return -ENOMEM;
-	}
-
-	platform_set_drvdata(omap3evm_snd_device, &snd_soc_omap3evm);
-	ret = platform_device_add(omap3evm_snd_device);
-	if (ret)
-		goto err1;
-
-	return 0;
-
-err1:
-	printk(KERN_ERR "Unable to add platform device\n");
-	platform_device_put(omap3evm_snd_device);
-
-	return ret;
-}
-
-static void __exit omap3evm_soc_exit(void)
-{
-	platform_device_unregister(omap3evm_snd_device);
-}
-
-module_init(omap3evm_soc_init);
-module_exit(omap3evm_soc_exit);
-
-MODULE_AUTHOR("Anuj Aggarwal <anuj.aggarwal@ti.com>");
-MODULE_DESCRIPTION("ALSA SoC OMAP3 EVM");
-MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/omap/overo.c b/sound/soc/omap/overo.c
deleted file mode 100644
index 502bce2..0000000
--- a/sound/soc/omap/overo.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * overo.c  --  SoC audio for Gumstix Overo
- *
- * Author: Steve Sakoman <steve@sakoman.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/soc.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <mach/gpio.h>
-#include <linux/platform_data/asoc-ti-mcbsp.h>
-
-#include "omap-mcbsp.h"
-#include "omap-pcm.h"
-
-static int overo_hw_params(struct snd_pcm_substream *substream,
-	struct snd_pcm_hw_params *params)
-{
-	struct snd_soc_pcm_runtime *rtd = substream->private_data;
-	struct snd_soc_dai *codec_dai = rtd->codec_dai;
-	int ret;
-
-	/* Set the codec system clock for DAC and ADC */
-	ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
-					    SND_SOC_CLOCK_IN);
-	if (ret < 0) {
-		printk(KERN_ERR "can't set codec system clock\n");
-		return ret;
-	}
-
-	return 0;
-}
-
-static struct snd_soc_ops overo_ops = {
-	.hw_params = overo_hw_params,
-};
-
-/* Digital audio interface glue - connects codec <--> CPU */
-static struct snd_soc_dai_link overo_dai = {
-	.name = "TWL4030",
-	.stream_name = "TWL4030",
-	.cpu_dai_name = "omap-mcbsp.2",
-	.codec_dai_name = "twl4030-hifi",
-	.platform_name = "omap-pcm-audio",
-	.codec_name = "twl4030-codec",
-	.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
-		   SND_SOC_DAIFMT_CBM_CFM,
-	.ops = &overo_ops,
-};
-
-/* Audio machine driver */
-static struct snd_soc_card snd_soc_card_overo = {
-	.name = "overo",
-	.owner = THIS_MODULE,
-	.dai_link = &overo_dai,
-	.num_links = 1,
-};
-
-static struct platform_device *overo_snd_device;
-
-static int __init overo_soc_init(void)
-{
-	int ret;
-
-	if (!(machine_is_overo() || machine_is_cm_t35())) {
-		pr_debug("Incomatible machine!\n");
-		return -ENODEV;
-	}
-	printk(KERN_INFO "overo SoC init\n");
-
-	overo_snd_device = platform_device_alloc("soc-audio", -1);
-	if (!overo_snd_device) {
-		printk(KERN_ERR "Platform device allocation failed\n");
-		return -ENOMEM;
-	}
-
-	platform_set_drvdata(overo_snd_device, &snd_soc_card_overo);
-
-	ret = platform_device_add(overo_snd_device);
-	if (ret)
-		goto err1;
-
-	return 0;
-
-err1:
-	printk(KERN_ERR "Unable to add platform device\n");
-	platform_device_put(overo_snd_device);
-
-	return ret;
-}
-module_init(overo_soc_init);
-
-static void __exit overo_soc_exit(void)
-{
-	platform_device_unregister(overo_snd_device);
-}
-module_exit(overo_soc_exit);
-
-MODULE_AUTHOR("Steve Sakoman <steve@sakoman.com>");
-MODULE_DESCRIPTION("ALSA SoC overo");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c
index 23de2b2..677b567 100644
--- a/sound/soc/omap/zoom2.c
+++ b/sound/soc/omap/zoom2.c
@@ -191,9 +191,6 @@
 	BUG_ON(gpio_request(ZOOM2_HEADSET_MUX_GPIO, "hs_mux") < 0);
 	gpio_direction_output(ZOOM2_HEADSET_MUX_GPIO, 0);
 
-	BUG_ON(gpio_request(ZOOM2_HEADSET_EXTMUTE_GPIO, "ext_mute") < 0);
-	gpio_direction_output(ZOOM2_HEADSET_EXTMUTE_GPIO, 0);
-
 	return 0;
 
 err1:
@@ -207,7 +204,6 @@
 static void __exit zoom2_soc_exit(void)
 {
 	gpio_free(ZOOM2_HEADSET_MUX_GPIO);
-	gpio_free(ZOOM2_HEADSET_EXTMUTE_GPIO);
 
 	platform_device_unregister(zoom2_snd_device);
 }
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index fe3995c..e7b8317 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -1,6 +1,6 @@
 config SND_SOC_SAMSUNG
 	tristate "ASoC support for Samsung"
-	depends on ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5P64X0 || ARCH_EXYNOS4
+	depends on PLAT_SAMSUNG
 	select S3C64XX_DMA if ARCH_S3C64XX
 	select S3C2410_DMA if ARCH_S3C24XX
 	help
@@ -191,6 +191,7 @@
 	select SND_SAMSUNG_I2S
 	select SND_SOC_WM8996
 	select SND_SOC_WM9081
+	select SND_SOC_WM0010
 	select SND_SOC_WM1250_EV1
 
 config SND_SOC_TOBERMORY
@@ -199,6 +200,14 @@
 	select SND_SAMSUNG_I2S
 	select SND_SOC_WM8962
 
+config SND_SOC_BELLS
+	tristate "Audio support for Wolfson Bells"
+	depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410
+	select SND_SAMSUNG_I2S
+	select SND_SOC_WM5102
+	select SND_SOC_WM5110
+	select SND_SOC_WM9081
+
 config SND_SOC_LOWLAND
 	tristate "Audio support for Wolfson Lowland"
 	depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410
diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile
index 9d03beb..709f605 100644
--- a/sound/soc/samsung/Makefile
+++ b/sound/soc/samsung/Makefile
@@ -42,6 +42,7 @@
 snd-soc-tobermory-objs := tobermory.o
 snd-soc-lowland-objs := lowland.o
 snd-soc-littlemill-objs := littlemill.o
+snd-soc-bells-objs := bells.o
 
 obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o
 obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
@@ -65,3 +66,4 @@
 obj-$(CONFIG_SND_SOC_TOBERMORY) += snd-soc-tobermory.o
 obj-$(CONFIG_SND_SOC_LOWLAND) += snd-soc-lowland.o
 obj-$(CONFIG_SND_SOC_LITTLEMILL) += snd-soc-littlemill.o
+obj-$(CONFIG_SND_SOC_BELLS) += snd-soc-bells.o
diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c
new file mode 100644
index 0000000..5dc10df
--- /dev/null
+++ b/sound/soc/samsung/bells.c
@@ -0,0 +1,346 @@
+/*
+ * Bells audio support
+ *
+ * Copyright 2012 Wolfson Microelectronics
+ *
+ * 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 <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/jack.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+
+#include "../codecs/wm5102.h"
+#include "../codecs/wm9081.h"
+
+/*
+ * 44.1kHz based clocks for the SYSCLK domain, use a very high clock
+ * to allow all the DSP functionality to be enabled if desired.
+ */
+#define SYSCLK_RATE (44100 * 1024)
+
+/* 48kHz based clocks for the ASYNC domain */
+#define ASYNCCLK_RATE (48000 * 512)
+
+/* BCLK2 is fixed at this currently */
+#define BCLK2_RATE (64 * 8000)
+
+/*
+ * Expect a 24.576MHz crystal if one is fitted (the driver will function
+ * if this is not fitted).
+ */
+#define MCLK_RATE 24576000
+
+#define WM9081_AUDIO_RATE 44100
+#define WM9081_MCLK_RATE  (WM9081_AUDIO_RATE * 256)
+
+static int bells_set_bias_level(struct snd_soc_card *card,
+				struct snd_soc_dapm_context *dapm,
+				enum snd_soc_bias_level level)
+{
+	struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
+	struct snd_soc_codec *codec = codec_dai->codec;
+	int ret;
+
+	if (dapm->dev != codec_dai->dev)
+		return 0;
+
+	switch (level) {
+	case SND_SOC_BIAS_PREPARE:
+		if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {
+			ret = snd_soc_codec_set_pll(codec, WM5102_FLL1,
+						    ARIZONA_FLL_SRC_MCLK1,
+						    MCLK_RATE,
+						    SYSCLK_RATE);
+			if (ret < 0)
+				pr_err("Failed to start FLL: %d\n", ret);
+
+			ret = snd_soc_codec_set_pll(codec, WM5102_FLL2,
+						    ARIZONA_FLL_SRC_AIF2BCLK,
+						    BCLK2_RATE,
+						    ASYNCCLK_RATE);
+			if (ret < 0)
+				pr_err("Failed to start FLL: %d\n", ret);
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int bells_set_bias_level_post(struct snd_soc_card *card,
+				     struct snd_soc_dapm_context *dapm,
+				     enum snd_soc_bias_level level)
+{
+	struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
+	struct snd_soc_codec *codec = codec_dai->codec;
+	int ret;
+
+	if (dapm->dev != codec_dai->dev)
+		return 0;
+
+	switch (level) {
+	case SND_SOC_BIAS_STANDBY:
+		ret = snd_soc_codec_set_pll(codec, WM5102_FLL1, 0, 0, 0);
+		if (ret < 0) {
+			pr_err("Failed to stop FLL: %d\n", ret);
+			return ret;
+		}
+
+		ret = snd_soc_codec_set_pll(codec, WM5102_FLL2, 0, 0, 0);
+		if (ret < 0) {
+			pr_err("Failed to stop FLL: %d\n", ret);
+			return ret;
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	dapm->bias_level = level;
+
+	return 0;
+}
+
+static int bells_late_probe(struct snd_soc_card *card)
+{
+	struct snd_soc_codec *codec = card->rtd[0].codec;
+	struct snd_soc_dai *aif1_dai = card->rtd[0].codec_dai;
+	struct snd_soc_dai *aif2_dai = card->rtd[1].cpu_dai;
+	struct snd_soc_dai *aif3_dai = card->rtd[2].cpu_dai;
+	struct snd_soc_dai *wm9081_dai = card->rtd[2].codec_dai;
+	int ret;
+
+	ret = snd_soc_dai_set_sysclk(aif1_dai, ARIZONA_CLK_SYSCLK, 0, 0);
+	if (ret != 0) {
+		dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret);
+		return ret;
+	}
+
+	ret = snd_soc_dai_set_sysclk(aif2_dai, ARIZONA_CLK_ASYNCCLK, 0, 0);
+	if (ret != 0) {
+		dev_err(aif2_dai->dev, "Failed to set AIF2 clock: %d\n", ret);
+		return ret;
+	}
+
+	ret = snd_soc_dai_set_sysclk(aif3_dai, ARIZONA_CLK_SYSCLK, 0, 0);
+	if (ret != 0) {
+		dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret);
+		return ret;
+	}
+
+	ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK,
+				       ARIZONA_CLK_SRC_FLL1, SYSCLK_RATE,
+				       SND_SOC_CLOCK_IN);
+	if (ret != 0) {
+		dev_err(codec->dev, "Failed to set SYSCLK: %d\n", ret);
+		return ret;
+	}
+
+	ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_OPCLK, 0,
+				       WM9081_MCLK_RATE, SND_SOC_CLOCK_OUT);
+	if (ret != 0) {
+		dev_err(codec->dev, "Failed to set OPCLK: %d\n", ret);
+		return ret;
+	}
+
+	ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_ASYNCCLK,
+				       ARIZONA_CLK_SRC_FLL2, ASYNCCLK_RATE,
+				       SND_SOC_CLOCK_IN);
+	if (ret != 0) {
+		dev_err(codec->dev, "Failed to set SYSCLK: %d\n", ret);
+		return ret;
+	}
+
+	ret = snd_soc_codec_set_sysclk(wm9081_dai->codec, WM9081_SYSCLK_MCLK,
+				       0, WM9081_MCLK_RATE, 0);
+	if (ret != 0) {
+		dev_err(wm9081_dai->dev, "Failed to set MCLK: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_pcm_stream baseband_params = {
+	.formats = SNDRV_PCM_FMTBIT_S32_LE,
+	.rate_min = 8000,
+	.rate_max = 8000,
+	.channels_min = 2,
+	.channels_max = 2,
+};
+
+static const struct snd_soc_pcm_stream sub_params = {
+	.formats = SNDRV_PCM_FMTBIT_S32_LE,
+	.rate_min = WM9081_AUDIO_RATE,
+	.rate_max = WM9081_AUDIO_RATE,
+	.channels_min = 2,
+	.channels_max = 2,
+};
+
+static struct snd_soc_dai_link bells_dai_wm5102[] = {
+	{
+		.name = "CPU",
+		.stream_name = "CPU",
+		.cpu_dai_name = "samsung-i2s.0",
+		.codec_dai_name = "wm5102-aif1",
+		.platform_name = "samsung-audio",
+		.codec_name = "wm5102-codec",
+		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+				| SND_SOC_DAIFMT_CBM_CFM,
+	},
+	{
+		.name = "Baseband",
+		.stream_name = "Baseband",
+		.cpu_dai_name = "wm5102-aif2",
+		.codec_dai_name = "wm1250-ev1",
+		.codec_name = "wm1250-ev1.1-0027",
+		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+				| SND_SOC_DAIFMT_CBM_CFM,
+		.ignore_suspend = 1,
+		.params = &baseband_params,
+	},
+	{
+		.name = "Sub",
+		.stream_name = "Sub",
+		.cpu_dai_name = "wm5102-aif3",
+		.codec_dai_name = "wm9081-hifi",
+		.codec_name = "wm9081.1-006c",
+		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+				| SND_SOC_DAIFMT_CBS_CFS,
+		.ignore_suspend = 1,
+		.params = &sub_params,
+	},
+};
+
+static struct snd_soc_dai_link bells_dai_wm5110[] = {
+	{
+		.name = "CPU",
+		.stream_name = "CPU",
+		.cpu_dai_name = "samsung-i2s.0",
+		.codec_dai_name = "wm5110-aif1",
+		.platform_name = "samsung-audio",
+		.codec_name = "wm5110-codec",
+		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+				| SND_SOC_DAIFMT_CBM_CFM,
+	},
+	{
+		.name = "Baseband",
+		.stream_name = "Baseband",
+		.cpu_dai_name = "wm5110-aif2",
+		.codec_dai_name = "wm1250-ev1",
+		.codec_name = "wm1250-ev1.1-0027",
+		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+				| SND_SOC_DAIFMT_CBM_CFM,
+		.ignore_suspend = 1,
+		.params = &baseband_params,
+	},
+	{
+		.name = "Sub",
+		.stream_name = "Sub",
+		.cpu_dai_name = "wm5102-aif3",
+		.codec_dai_name = "wm9081-hifi",
+		.codec_name = "wm9081.1-006c",
+		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+				| SND_SOC_DAIFMT_CBS_CFS,
+		.ignore_suspend = 1,
+		.params = &sub_params,
+	},
+};
+
+static struct snd_soc_codec_conf bells_codec_conf[] = {
+	{
+		.dev_name = "wm9081.1-006c",
+		.name_prefix = "Sub",
+	},
+};
+
+static struct snd_soc_dapm_route bells_routes[] = {
+	{ "Sub CLK_SYS", NULL, "OPCLK" },
+};
+
+static struct snd_soc_card bells_cards[] = {
+	{
+		.name = "Bells WM5102",
+		.owner = THIS_MODULE,
+		.dai_link = bells_dai_wm5102,
+		.num_links = ARRAY_SIZE(bells_dai_wm5102),
+		.codec_conf = bells_codec_conf,
+		.num_configs = ARRAY_SIZE(bells_codec_conf),
+
+		.late_probe = bells_late_probe,
+
+		.dapm_routes = bells_routes,
+		.num_dapm_routes = ARRAY_SIZE(bells_routes),
+
+		.set_bias_level = bells_set_bias_level,
+		.set_bias_level_post = bells_set_bias_level_post,
+	},
+	{
+		.name = "Bells WM5110",
+		.owner = THIS_MODULE,
+		.dai_link = bells_dai_wm5110,
+		.num_links = ARRAY_SIZE(bells_dai_wm5110),
+		.codec_conf = bells_codec_conf,
+		.num_configs = ARRAY_SIZE(bells_codec_conf),
+
+		.late_probe = bells_late_probe,
+
+		.dapm_routes = bells_routes,
+		.num_dapm_routes = ARRAY_SIZE(bells_routes),
+
+		.set_bias_level = bells_set_bias_level,
+		.set_bias_level_post = bells_set_bias_level_post,
+	},
+};
+
+
+static __devinit int bells_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	bells_cards[pdev->id].dev = &pdev->dev;
+
+	ret = snd_soc_register_card(&bells_cards[pdev->id]);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"snd_soc_register_card(%s) failed: %d\n",
+			bells_cards[pdev->id].name, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int __devexit bells_remove(struct platform_device *pdev)
+{
+	snd_soc_unregister_card(&bells_cards[pdev->id]);
+
+	return 0;
+}
+
+static struct platform_driver bells_driver = {
+	.driver = {
+		.name = "bells",
+		.owner = THIS_MODULE,
+		.pm = &snd_soc_pm_ops,
+	},
+	.probe = bells_probe,
+	.remove = __devexit_p(bells_remove),
+};
+
+module_platform_driver(bells_driver);
+
+MODULE_DESCRIPTION("Bells audio support");
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:bells");
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c
index a4a9fc7..c7e1c28 100644
--- a/sound/soc/samsung/speyside.c
+++ b/sound/soc/samsung/speyside.c
@@ -25,7 +25,7 @@
 				   struct snd_soc_dapm_context *dapm,
 				   enum snd_soc_bias_level level)
 {
-	struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
+	struct snd_soc_dai *codec_dai = card->rtd[1].codec_dai;
 	int ret;
 
 	if (dapm->dev != codec_dai->dev)
@@ -57,7 +57,7 @@
 					struct snd_soc_dapm_context *dapm,
 					enum snd_soc_bias_level level)
 {
-	struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
+	struct snd_soc_dai *codec_dai = card->rtd[1].codec_dai;
 	int ret;
 
 	if (dapm->dev != codec_dai->dev)
@@ -126,6 +126,18 @@
 	snd_soc_dapm_sync(&codec->dapm);
 }
 
+static int speyside_wm0010_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_soc_dai *dai = rtd->codec_dai;
+	int ret;
+
+	ret = snd_soc_dai_set_sysclk(dai, 0, MCLK_AUDIO_RATE, 0);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
 static int speyside_wm8996_init(struct snd_soc_pcm_runtime *rtd)
 {
 	struct snd_soc_dai *dai = rtd->codec_dai;
@@ -172,17 +184,37 @@
 	return 0;
 }
 
+static const struct snd_soc_pcm_stream dsp_codec_params = {
+	.formats = SNDRV_PCM_FMTBIT_S32_LE,
+	.rate_min = 48000,
+	.rate_max = 48000,
+	.channels_min = 2,
+	.channels_max = 2,
+};
+
 static struct snd_soc_dai_link speyside_dai[] = {
 	{
-		.name = "CPU",
-		.stream_name = "CPU",
+		.name = "CPU-DSP",
+		.stream_name = "CPU-DSP",
 		.cpu_dai_name = "samsung-i2s.0",
-		.codec_dai_name = "wm8996-aif1",
+		.codec_dai_name = "wm0010-sdi1",
 		.platform_name = "samsung-audio",
+		.codec_name = "spi0.0",
+		.init = speyside_wm0010_init,
+		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
+				| SND_SOC_DAIFMT_CBM_CFM,
+	},
+	{
+		.name = "DSP-CODEC",
+		.stream_name = "DSP-CODEC",
+		.cpu_dai_name = "wm0010-sdi2",
+		.codec_dai_name = "wm8996-aif1",
 		.codec_name = "wm8996.1-001a",
 		.init = speyside_wm8996_init,
 		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
 				| SND_SOC_DAIFMT_CBM_CFM,
+		.params = &dsp_codec_params,
+		.ignore_suspend = 1,
 	},
 	{
 		.name = "Baseband",
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 0540408..5328ae5 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -1655,22 +1655,20 @@
 	irq = platform_get_irq(pdev, 0);
 	if (!res || (int)irq <= 0) {
 		dev_err(&pdev->dev, "Not enough FSI platform resources.\n");
-		ret = -ENODEV;
-		goto exit;
+		return -ENODEV;
 	}
 
-	master = kzalloc(sizeof(*master), GFP_KERNEL);
+	master = devm_kzalloc(&pdev->dev, sizeof(*master), GFP_KERNEL);
 	if (!master) {
 		dev_err(&pdev->dev, "Could not allocate master\n");
-		ret = -ENOMEM;
-		goto exit;
+		return -ENOMEM;
 	}
 
-	master->base = ioremap_nocache(res->start, resource_size(res));
+	master->base = devm_ioremap_nocache(&pdev->dev,
+					    res->start, resource_size(res));
 	if (!master->base) {
-		ret = -ENXIO;
 		dev_err(&pdev->dev, "Unable to ioremap FSI registers.\n");
-		goto exit_kfree;
+		return -ENXIO;
 	}
 
 	/* master setting */
@@ -1686,7 +1684,7 @@
 	ret = fsi_stream_probe(&master->fsia, &pdev->dev);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "FSIA stream probe failed\n");
-		goto exit_iounmap;
+		return ret;
 	}
 
 	/* FSI B setting */
@@ -1730,16 +1728,11 @@
 exit_free_irq:
 	free_irq(irq, master);
 exit_fsib:
+	pm_runtime_disable(&pdev->dev);
 	fsi_stream_remove(&master->fsib);
 exit_fsia:
 	fsi_stream_remove(&master->fsia);
-exit_iounmap:
-	iounmap(master->base);
-	pm_runtime_disable(&pdev->dev);
-exit_kfree:
-	kfree(master);
-	master = NULL;
-exit:
+
 	return ret;
 }
 
@@ -1758,9 +1751,6 @@
 	fsi_stream_remove(&master->fsia);
 	fsi_stream_remove(&master->fsib);
 
-	iounmap(master->base);
-	kfree(master);
-
 	return 0;
 }
 
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
new file mode 100644
index 0000000..967d0e1
--- /dev/null
+++ b/sound/soc/soc-compress.c
@@ -0,0 +1,294 @@
+/*
+ * soc-compress.c  --  ALSA SoC Compress
+ *
+ * Copyright (C) 2012 Intel Corp.
+ *
+ * Authors: Namarta Kohli <namartax.kohli@intel.com>
+ *          Ramesh Babu K V <ramesh.babu@linux.intel.com>
+ *          Vinod Koul <vinod.koul@linux.intel.com>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <sound/core.h>
+#include <sound/compress_params.h>
+#include <sound/compress_driver.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+
+static int soc_compr_open(struct snd_compr_stream *cstream)
+{
+	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+	struct snd_soc_platform *platform = rtd->platform;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	int ret = 0;
+
+	if (platform->driver->compr_ops && platform->driver->compr_ops->open) {
+		ret = platform->driver->compr_ops->open(cstream);
+		if (ret < 0) {
+			pr_err("compress asoc: can't open platform %s\n", platform->name);
+			goto out;
+		}
+	}
+
+	if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->startup) {
+		ret = rtd->dai_link->compr_ops->startup(cstream);
+		if (ret < 0) {
+			pr_err("compress asoc: %s startup failed\n", rtd->dai_link->name);
+			goto machine_err;
+		}
+	}
+
+	if (cstream->direction == SND_COMPRESS_PLAYBACK) {
+		cpu_dai->playback_active++;
+		codec_dai->playback_active++;
+	} else {
+		cpu_dai->capture_active++;
+		codec_dai->capture_active++;
+	}
+
+	cpu_dai->active++;
+	codec_dai->active++;
+	rtd->codec->active++;
+
+	return 0;
+
+machine_err:
+	if (platform->driver->compr_ops && platform->driver->compr_ops->free)
+		platform->driver->compr_ops->free(cstream);
+out:
+	return ret;
+}
+
+static int soc_compr_free(struct snd_compr_stream *cstream)
+{
+	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+	struct snd_soc_platform *platform = rtd->platform;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	struct snd_soc_codec *codec = rtd->codec;
+
+	if (cstream->direction == SND_COMPRESS_PLAYBACK) {
+		cpu_dai->playback_active--;
+		codec_dai->playback_active--;
+	} else {
+		cpu_dai->capture_active--;
+		codec_dai->capture_active--;
+	}
+
+	snd_soc_dai_digital_mute(codec_dai, 1);
+
+	cpu_dai->active--;
+	codec_dai->active--;
+	codec->active--;
+
+	if (!cpu_dai->active)
+		cpu_dai->rate = 0;
+
+	if (!codec_dai->active)
+		codec_dai->rate = 0;
+
+
+	if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->shutdown)
+		rtd->dai_link->compr_ops->shutdown(cstream);
+
+	if (platform->driver->compr_ops && platform->driver->compr_ops->free)
+		platform->driver->compr_ops->free(cstream);
+	cpu_dai->runtime = NULL;
+
+	if (cstream->direction == SND_COMPRESS_PLAYBACK) {
+		if (!rtd->pmdown_time || codec->ignore_pmdown_time ||
+		    rtd->dai_link->ignore_pmdown_time) {
+			snd_soc_dapm_stream_event(rtd,
+					SNDRV_PCM_STREAM_PLAYBACK,
+					SND_SOC_DAPM_STREAM_STOP);
+		} else
+			codec_dai->pop_wait = 1;
+			schedule_delayed_work(&rtd->delayed_work,
+				msecs_to_jiffies(rtd->pmdown_time));
+	} else {
+		/* capture streams can be powered down now */
+		snd_soc_dapm_stream_event(rtd,
+			SNDRV_PCM_STREAM_CAPTURE,
+			SND_SOC_DAPM_STREAM_STOP);
+	}
+
+	return 0;
+}
+
+static int soc_compr_trigger(struct snd_compr_stream *cstream, int cmd)
+{
+
+	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+	struct snd_soc_platform *platform = rtd->platform;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	int ret = 0;
+
+	if (platform->driver->compr_ops && platform->driver->compr_ops->trigger) {
+		ret = platform->driver->compr_ops->trigger(cstream, cmd);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (cmd == SNDRV_PCM_TRIGGER_START)
+		snd_soc_dai_digital_mute(codec_dai, 0);
+	else if (cmd == SNDRV_PCM_TRIGGER_STOP)
+		snd_soc_dai_digital_mute(codec_dai, 1);
+
+	return ret;
+}
+
+static int soc_compr_set_params(struct snd_compr_stream *cstream,
+					struct snd_compr_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+	struct snd_soc_platform *platform = rtd->platform;
+	int ret = 0;
+
+	/* first we call set_params for the platform driver
+	 * this should configure the soc side
+	 * if the machine has compressed ops then we call that as well
+	 * expectation is that platform and machine will configure everything
+	 * for this compress path, like configuring pcm port for codec
+	 */
+	if (platform->driver->compr_ops && platform->driver->compr_ops->set_params) {
+		ret = platform->driver->compr_ops->set_params(cstream, params);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (rtd->dai_link->compr_ops && rtd->dai_link->compr_ops->set_params) {
+		ret = rtd->dai_link->compr_ops->set_params(cstream);
+		if (ret < 0)
+			return ret;
+	}
+
+	snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK,
+				SND_SOC_DAPM_STREAM_START);
+
+	return ret;
+}
+
+static int soc_compr_get_params(struct snd_compr_stream *cstream,
+					struct snd_codec *params)
+{
+	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+	struct snd_soc_platform *platform = rtd->platform;
+	int ret = 0;
+
+	if (platform->driver->compr_ops && platform->driver->compr_ops->get_params)
+		ret = platform->driver->compr_ops->get_params(cstream, params);
+
+	return ret;
+}
+
+static int soc_compr_get_caps(struct snd_compr_stream *cstream,
+				struct snd_compr_caps *caps)
+{
+	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+	struct snd_soc_platform *platform = rtd->platform;
+	int ret = 0;
+
+	if (platform->driver->compr_ops && platform->driver->compr_ops->get_caps)
+		ret = platform->driver->compr_ops->get_caps(cstream, caps);
+
+	return ret;
+}
+
+static int soc_compr_get_codec_caps(struct snd_compr_stream *cstream,
+				struct snd_compr_codec_caps *codec)
+{
+	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+	struct snd_soc_platform *platform = rtd->platform;
+	int ret = 0;
+
+	if (platform->driver->compr_ops && platform->driver->compr_ops->get_codec_caps)
+		ret = platform->driver->compr_ops->get_codec_caps(cstream, codec);
+
+	return ret;
+}
+
+static int soc_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
+{
+	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+	struct snd_soc_platform *platform = rtd->platform;
+	int ret = 0;
+
+	if (platform->driver->compr_ops && platform->driver->compr_ops->ack)
+		ret = platform->driver->compr_ops->ack(cstream, bytes);
+
+	return ret;
+}
+
+static int soc_compr_pointer(struct snd_compr_stream *cstream,
+			struct snd_compr_tstamp *tstamp)
+{
+	struct snd_soc_pcm_runtime *rtd = cstream->private_data;
+	struct snd_soc_platform *platform = rtd->platform;
+
+	if (platform->driver->compr_ops && platform->driver->compr_ops->pointer)
+		 platform->driver->compr_ops->pointer(cstream, tstamp);
+
+	return 0;
+}
+
+/* ASoC Compress operations */
+static struct snd_compr_ops soc_compr_ops = {
+	.open		= soc_compr_open,
+	.free		= soc_compr_free,
+	.set_params	= soc_compr_set_params,
+	.get_params	= soc_compr_get_params,
+	.trigger	= soc_compr_trigger,
+	.pointer	= soc_compr_pointer,
+	.ack		= soc_compr_ack,
+	.get_caps	= soc_compr_get_caps,
+	.get_codec_caps = soc_compr_get_codec_caps
+};
+
+/* create a new compress */
+int soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
+{
+	struct snd_soc_codec *codec = rtd->codec;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+	struct snd_compr *compr;
+	char new_name[64];
+	int ret = 0, direction = 0;
+
+	/* check client and interface hw capabilities */
+	snprintf(new_name, sizeof(new_name), "%s %s-%d",
+			rtd->dai_link->stream_name, codec_dai->name, num);
+	direction = SND_COMPRESS_PLAYBACK;
+	compr = kzalloc(sizeof(*compr), GFP_KERNEL);
+	if (compr == NULL) {
+		snd_printk(KERN_ERR "Cannot allocate compr\n");
+		return -ENOMEM;
+	}
+
+	compr->ops = &soc_compr_ops;
+	mutex_init(&compr->lock);
+	ret = snd_compress_new(rtd->card->snd_card, num, direction, compr);
+	if (ret < 0) {
+		pr_err("compress asoc: can't create compress for codec %s\n",
+			codec->name);
+		kfree(compr);
+		return ret;
+	}
+
+	rtd->compr = compr;
+	compr->private_data = rtd;
+
+	printk(KERN_INFO "compress asoc: %s <-> %s mapping ok\n", codec_dai->name,
+		cpu_dai->name);
+	return ret;
+}
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index cf3d0b0..d119862 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -609,6 +609,10 @@
 					  SND_SOC_DAPM_STREAM_SUSPEND);
 	}
 
+	/* Recheck all analogue paths too */
+	dapm_mark_io_dirty(&card->dapm);
+	snd_soc_dapm_sync(&card->dapm);
+
 	/* suspend all CODECs */
 	list_for_each_entry(codec, &card->codec_dev_list, card_list) {
 		/* If there are paths active then the CODEC will be held with
@@ -631,6 +635,8 @@
 				codec->driver->suspend(codec);
 				codec->suspended = 1;
 				codec->cache_sync = 1;
+				if (codec->using_regmap)
+					regcache_mark_dirty(codec->control_data);
 				break;
 			default:
 				dev_dbg(codec->dev, "CODEC is on over suspend\n");
@@ -756,6 +762,10 @@
 
 	/* userspace can access us now we are back as we were before */
 	snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D0);
+
+	/* Recheck all analogue paths too */
+	dapm_mark_io_dirty(&card->dapm);
+	snd_soc_dapm_sync(&card->dapm);
 }
 
 /* powers up audio subsystem after a suspend */
@@ -1388,37 +1398,48 @@
 	if (ret < 0)
 		pr_warn("asoc: failed to add pmdown_time sysfs:%d\n", ret);
 
-	if (!dai_link->params) {
-		/* create the pcm */
-		ret = soc_new_pcm(rtd, num);
+	if (cpu_dai->driver->compress_dai) {
+		/*create compress_device"*/
+		ret = soc_new_compress(rtd, num);
 		if (ret < 0) {
-			pr_err("asoc: can't create pcm %s :%d\n",
-			       dai_link->stream_name, ret);
+			pr_err("asoc: can't create compress %s\n",
+					 dai_link->stream_name);
 			return ret;
 		}
 	} else {
-		/* link the DAI widgets */
-		play_w = codec_dai->playback_widget;
-		capture_w = cpu_dai->capture_widget;
-		if (play_w && capture_w) {
-			ret = snd_soc_dapm_new_pcm(card, dai_link->params,
-						   capture_w, play_w);
-			if (ret != 0) {
-				dev_err(card->dev, "Can't link %s to %s: %d\n",
-					play_w->name, capture_w->name, ret);
+
+		if (!dai_link->params) {
+			/* create the pcm */
+			ret = soc_new_pcm(rtd, num);
+			if (ret < 0) {
+				pr_err("asoc: can't create pcm %s :%d\n",
+				       dai_link->stream_name, ret);
 				return ret;
 			}
-		}
-
-		play_w = cpu_dai->playback_widget;
-		capture_w = codec_dai->capture_widget;
-		if (play_w && capture_w) {
-			ret = snd_soc_dapm_new_pcm(card, dai_link->params,
+		} else {
+			/* link the DAI widgets */
+			play_w = codec_dai->playback_widget;
+			capture_w = cpu_dai->capture_widget;
+			if (play_w && capture_w) {
+				ret = snd_soc_dapm_new_pcm(card, dai_link->params,
 						   capture_w, play_w);
-			if (ret != 0) {
-				dev_err(card->dev, "Can't link %s to %s: %d\n",
-					play_w->name, capture_w->name, ret);
-				return ret;
+				if (ret != 0) {
+					dev_err(card->dev, "Can't link %s to %s: %d\n",
+						play_w->name, capture_w->name, ret);
+					return ret;
+				}
+			}
+
+			play_w = cpu_dai->playback_widget;
+			capture_w = codec_dai->capture_widget;
+			if (play_w && capture_w) {
+				ret = snd_soc_dapm_new_pcm(card, dai_link->params,
+						   capture_w, play_w);
+				if (ret != 0) {
+					dev_err(card->dev, "Can't link %s to %s: %d\n",
+						play_w->name, capture_w->name, ret);
+					return ret;
+				}
 			}
 		}
 	}
@@ -1816,7 +1837,6 @@
 static int soc_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = platform_get_drvdata(pdev);
-	int ret = 0;
 
 	/*
 	 * no card, so machine driver should be registering card
@@ -1832,13 +1852,7 @@
 	/* Bodge while we unpick instantiation */
 	card->dev = &pdev->dev;
 
-	ret = snd_soc_register_card(card);
-	if (ret != 0) {
-		dev_err(&pdev->dev, "Failed to register card\n");
-		return ret;
-	}
-
-	return 0;
+	return snd_soc_register_card(card);
 }
 
 static int soc_cleanup_card_resources(struct snd_soc_card *card)
@@ -2399,16 +2413,14 @@
 {
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
-	unsigned int val, bitmask;
+	unsigned int val;
 
-	for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
-		;
 	val = snd_soc_read(codec, e->reg);
 	ucontrol->value.enumerated.item[0]
-		= (val >> e->shift_l) & (bitmask - 1);
+		= (val >> e->shift_l) & e->mask;
 	if (e->shift_l != e->shift_r)
 		ucontrol->value.enumerated.item[1] =
-			(val >> e->shift_r) & (bitmask - 1);
+			(val >> e->shift_r) & e->mask;
 
 	return 0;
 }
@@ -2429,19 +2441,17 @@
 	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
 	unsigned int val;
-	unsigned int mask, bitmask;
+	unsigned int mask;
 
-	for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
-		;
 	if (ucontrol->value.enumerated.item[0] > e->max - 1)
 		return -EINVAL;
 	val = ucontrol->value.enumerated.item[0] << e->shift_l;
-	mask = (bitmask - 1) << e->shift_l;
+	mask = e->mask << e->shift_l;
 	if (e->shift_l != e->shift_r) {
 		if (ucontrol->value.enumerated.item[1] > e->max - 1)
 			return -EINVAL;
 		val |= ucontrol->value.enumerated.item[1] << e->shift_r;
-		mask |= (bitmask - 1) << e->shift_r;
+		mask |= e->mask << e->shift_r;
 	}
 
 	return snd_soc_update_bits_locked(codec, e->reg, mask, val);
@@ -3717,6 +3727,9 @@
 		}
 	}
 
+	if (!dai->codec)
+		dai->dapm.idle_bias_off = 1;
+
 	list_add(&dai->list, &dai_list);
 
 	mutex_unlock(&client_mutex);
@@ -3805,6 +3818,9 @@
 			}
 		}
 
+		if (!dai->codec)
+			dai->dapm.idle_bias_off = 1;
+
 		list_add(&dai->list, &dai_list);
 
 		mutex_unlock(&client_mutex);
@@ -4034,8 +4050,6 @@
 	return 0;
 
 fail:
-	kfree(codec->reg_def_copy);
-	codec->reg_def_copy = NULL;
 	kfree(codec->name);
 	kfree(codec);
 	return ret;
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index f90139b..d0a4be3 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -141,6 +141,28 @@
 }
 EXPORT_SYMBOL_GPL(dapm_mark_dirty);
 
+void dapm_mark_io_dirty(struct snd_soc_dapm_context *dapm)
+{
+	struct snd_soc_card *card = dapm->card;
+	struct snd_soc_dapm_widget *w;
+
+	mutex_lock(&card->dapm_mutex);
+
+	list_for_each_entry(w, &card->widgets, list) {
+		switch (w->id) {
+		case snd_soc_dapm_input:
+		case snd_soc_dapm_output:
+			dapm_mark_dirty(w, "Rechecking inputs and outputs");
+			break;
+		default:
+			break;
+		}
+	}
+
+	mutex_unlock(&card->dapm_mutex);
+}
+EXPORT_SYMBOL_GPL(dapm_mark_io_dirty);
+
 /* create a new dapm widget */
 static inline struct snd_soc_dapm_widget *dapm_cnew_widget(
 	const struct snd_soc_dapm_widget *_widget)
@@ -336,12 +358,10 @@
 	case snd_soc_dapm_mux: {
 		struct soc_enum *e = (struct soc_enum *)
 			w->kcontrol_news[i].private_value;
-		int val, item, bitmask;
+		int val, item;
 
-		for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
-			;
 		val = soc_widget_read(w, e->reg);
-		item = (val >> e->shift_l) & (bitmask - 1);
+		item = (val >> e->shift_l) & e->mask;
 
 		p->connect = 0;
 		for (i = 0; i < e->max; i++) {
@@ -997,10 +1017,29 @@
 int dapm_regulator_event(struct snd_soc_dapm_widget *w,
 		   struct snd_kcontrol *kcontrol, int event)
 {
-	if (SND_SOC_DAPM_EVENT_ON(event))
+	int ret;
+
+	if (SND_SOC_DAPM_EVENT_ON(event)) {
+		if (w->invert & SND_SOC_DAPM_REGULATOR_BYPASS) {
+			ret = regulator_allow_bypass(w->regulator, true);
+			if (ret != 0)
+				dev_warn(w->dapm->dev,
+					 "Failed to bypass %s: %d\n",
+					 w->name, ret);
+		}
+
 		return regulator_enable(w->regulator);
-	else
+	} else {
+		if (w->invert & SND_SOC_DAPM_REGULATOR_BYPASS) {
+			ret = regulator_allow_bypass(w->regulator, false);
+			if (ret != 0)
+				dev_warn(w->dapm->dev,
+					 "Failed to unbypass %s: %d\n",
+					 w->name, ret);
+		}
+
 		return regulator_disable_deferred(w->regulator, w->shift);
+	}
 }
 EXPORT_SYMBOL_GPL(dapm_regulator_event);
 
@@ -2658,15 +2697,13 @@
 	struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
 	struct snd_soc_dapm_widget *widget = wlist->widgets[0];
 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
-	unsigned int val, bitmask;
+	unsigned int val;
 
-	for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
-		;
 	val = snd_soc_read(widget->codec, e->reg);
-	ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & (bitmask - 1);
+	ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & e->mask;
 	if (e->shift_l != e->shift_r)
 		ucontrol->value.enumerated.item[1] =
-			(val >> e->shift_r) & (bitmask - 1);
+			(val >> e->shift_r) & e->mask;
 
 	return 0;
 }
@@ -2690,22 +2727,20 @@
 	struct snd_soc_card *card = codec->card;
 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
 	unsigned int val, mux, change;
-	unsigned int mask, bitmask;
+	unsigned int mask;
 	struct snd_soc_dapm_update update;
 	int wi;
 
-	for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
-		;
 	if (ucontrol->value.enumerated.item[0] > e->max - 1)
 		return -EINVAL;
 	mux = ucontrol->value.enumerated.item[0];
 	val = mux << e->shift_l;
-	mask = (bitmask - 1) << e->shift_l;
+	mask = e->mask << e->shift_l;
 	if (e->shift_l != e->shift_r) {
 		if (ucontrol->value.enumerated.item[1] > e->max - 1)
 			return -EINVAL;
 		val |= ucontrol->value.enumerated.item[1] << e->shift_r;
-		mask |= (bitmask - 1) << e->shift_r;
+		mask |= e->mask << e->shift_r;
 	}
 
 	mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c
index 5df529e..bbc1257 100644
--- a/sound/soc/soc-dmaengine-pcm.c
+++ b/sound/soc/soc-dmaengine-pcm.c
@@ -140,14 +140,18 @@
 	struct dma_chan *chan = prtd->dma_chan;
 	struct dma_async_tx_descriptor *desc;
 	enum dma_transfer_direction direction;
+	unsigned long flags = DMA_CTRL_ACK;
 
 	direction = snd_pcm_substream_to_dma_direction(substream);
 
+	if (!substream->runtime->no_period_wakeup)
+		flags |= DMA_PREP_INTERRUPT;
+
 	prtd->pos = 0;
 	desc = dmaengine_prep_dma_cyclic(chan,
 		substream->runtime->dma_addr,
 		snd_pcm_lib_buffer_bytes(substream),
-		snd_pcm_lib_period_bytes(substream), direction);
+		snd_pcm_lib_period_bytes(substream), direction, flags);
 
 	if (!desc)
 		return -ENOMEM;
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index 0c17293..fa0fd8d 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -83,11 +83,6 @@
 	jack->status &= ~mask;
 	jack->status |= status & mask;
 
-	/* The DAPM sync is expensive enough to be worth skipping.
-	 * However, empty mask means pin synchronization is desired. */
-	if (mask && (jack->status == oldstatus))
-		goto out;
-
 	trace_snd_soc_jack_notify(jack, status);
 
 	list_for_each_entry(pin, &jack->pins, list) {
@@ -109,7 +104,6 @@
 
 	snd_jack_report(jack->jack, jack->status);
 
-out:
 	mutex_unlock(&jack->mutex);
 }
 EXPORT_SYMBOL_GPL(snd_soc_jack_report);
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
index d4f14e4..cee13b7 100644
--- a/sound/soc/tegra/tegra_wm8903.c
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -34,13 +34,12 @@
 #include <linux/gpio.h>
 #include <linux/of_gpio.h>
 
-#include <mach/tegra_wm8903_pdata.h>
-
 #include <sound/core.h>
 #include <sound/jack.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
+#include <sound/tegra_wm8903.h>
 
 #include "../codecs/wm8903.h"
 
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index 45e43b4..be94bf9 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -760,6 +760,9 @@
 	drvdata = devm_kzalloc(&pdev->dev,
 				sizeof(struct ux500_msp_i2s_drvdata),
 				GFP_KERNEL);
+	if (!drvdata)
+		return -ENOMEM;
+
 	drvdata->fmt = 0;
 	drvdata->slots = 1;
 	drvdata->tx_mask = 0x01;
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c
index e5c79ca..b7c996e 100644
--- a/sound/soc/ux500/ux500_msp_i2s.c
+++ b/sound/soc/ux500/ux500_msp_i2s.c
@@ -689,6 +689,8 @@
 
 	*msp_p = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp), GFP_KERNEL);
 	msp = *msp_p;
+	if (!msp)
+		return -ENOMEM;
 
 	if (np) {
 		if (!platform_data) {
diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c
index b63b3a8..5701787 100644
--- a/sound/sparc/amd7930.c
+++ b/sound/sparc/amd7930.c
@@ -813,7 +813,7 @@
 	default:
 		swval = &amd->pgain;
 		break;
-	};
+	}
 
 	ucontrol->value.integer.value[0] = *swval;
 
@@ -838,7 +838,7 @@
 	default:
 		swval = &amd->pgain;
 		break;
-	};
+	}
 
 	spin_lock_irqsave(&amd->lock, flags);
 
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index a6b0deb..ae35f53 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -592,7 +592,7 @@
 		break;
 	default:
 		printk(KERN_ERR "DBRI reverse_bytes: unsupported length\n");
-	};
+	}
 
 	return b;
 }
diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c
index 56ad923..a1d9b07 100644
--- a/sound/usb/6fire/firmware.c
+++ b/sound/usb/6fire/firmware.c
@@ -346,11 +346,10 @@
 		if (!memcmp(version, known_fw_versions + i, 4))
 			return 0;
 
-	snd_printk(KERN_ERR PREFIX "invalid fimware version in device: "
-			"%02x %02x %02x %02x. "
+	snd_printk(KERN_ERR PREFIX "invalid fimware version in device: %*ph. "
 			"please reconnect to power. if this failure "
 			"still happens, check your firmware installation.",
-			version[0], version[1], version[2], version[3]);
+			4, version);
 	return -EINVAL;
 }
 
diff --git a/sound/usb/card.c b/sound/usb/card.c
index 4a469f0..561bb74 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -646,6 +646,8 @@
 			list_for_each(p, &chip->pcm_list) {
 				as = list_entry(p, struct snd_usb_stream, list);
 				snd_pcm_suspend_all(as->pcm);
+				as->substream[0].need_setup_ep =
+					as->substream[1].need_setup_ep = true;
 			}
  		}
 	} else {
diff --git a/sound/usb/card.h b/sound/usb/card.h
index 2b9ffff..afa4f9e 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -92,6 +92,8 @@
 	unsigned char silence_value;
 	unsigned int stride;
 	int iface, alt_idx;
+	int skip_packets;		/* quirks for devices to ignore the first n packets
+					   in a stream */
 
 	spinlock_t lock;
 	struct list_head list;
@@ -105,6 +107,8 @@
 	int interface;	/* current interface */
 	int endpoint;	/* assigned endpoint */
 	struct audioformat *cur_audiofmt;	/* current audioformat pointer (for hw_params callback) */
+	snd_pcm_format_t pcm_format;	/* current audio format (for hw_params callback) */
+	unsigned int channels;		/* current number of channels (for hw_params callback) */
 	unsigned int cur_rate;		/* current rate (for hw_params callback) */
 	unsigned int period_bytes;	/* current period bytes (for hw_params callback) */
 	unsigned int altset_idx;     /* USB data format: index of alternate setting */
@@ -115,14 +119,13 @@
 
 	unsigned int hwptr_done;	/* processed byte position in the buffer */
 	unsigned int transfer_done;		/* processed frames since last period update */
-	unsigned long active_mask;	/* bitmask of active urbs */
-	unsigned long unlink_mask;	/* bitmask of unlinked urbs */
 
 	/* data and sync endpoints for this stream */
 	unsigned int ep_num;		/* the endpoint number */
 	struct snd_usb_endpoint *data_endpoint;
 	struct snd_usb_endpoint *sync_endpoint;
 	unsigned long flags;
+	bool need_setup_ep;		/* (re)configure EP at prepare? */
 
 	u64 formats;			/* format bitmasks (all or'ed) */
 	unsigned int num_formats;		/* number of supported audio formats (list) */
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 060dccb..7f78c6d 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -31,6 +31,7 @@
 #include "card.h"
 #include "endpoint.h"
 #include "pcm.h"
+#include "quirks.h"
 
 #define EP_FLAG_ACTIVATED	0
 #define EP_FLAG_RUNNING		1
@@ -170,6 +171,11 @@
 {
 	struct urb *urb = urb_ctx->urb;
 
+	if (unlikely(ep->skip_packets > 0)) {
+		ep->skip_packets--;
+		return;
+	}
+
 	if (ep->sync_slave)
 		snd_usb_handle_sync_urb(ep->sync_slave, ep, urb);
 
@@ -567,20 +573,19 @@
  * configure a data endpoint
  */
 static int data_ep_set_params(struct snd_usb_endpoint *ep,
-			      struct snd_pcm_hw_params *hw_params,
+			      snd_pcm_format_t pcm_format,
+			      unsigned int channels,
+			      unsigned int period_bytes,
 			      struct audioformat *fmt,
 			      struct snd_usb_endpoint *sync_ep)
 {
 	unsigned int maxsize, i, urb_packs, total_packs, packs_per_ms;
-	int period_bytes = params_period_bytes(hw_params);
-	int format = params_format(hw_params);
 	int is_playback = usb_pipeout(ep->pipe);
-	int frame_bits = snd_pcm_format_physical_width(params_format(hw_params)) *
-							params_channels(hw_params);
+	int frame_bits = snd_pcm_format_physical_width(pcm_format) * channels;
 
 	ep->datainterval = fmt->datainterval;
 	ep->stride = frame_bits >> 3;
-	ep->silence_value = format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0;
+	ep->silence_value = pcm_format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0;
 
 	/* calculate max. frequency */
 	if (ep->maxpacksize) {
@@ -693,7 +698,6 @@
  * configure a sync endpoint
  */
 static int sync_ep_set_params(struct snd_usb_endpoint *ep,
-			      struct snd_pcm_hw_params *hw_params,
 			      struct audioformat *fmt)
 {
 	int i;
@@ -736,7 +740,10 @@
  * snd_usb_endpoint_set_params: configure an snd_usb_endpoint
  *
  * @ep: the snd_usb_endpoint to configure
- * @hw_params: the hardware parameters
+ * @pcm_format: the audio fomat.
+ * @channels: the number of audio channels.
+ * @period_bytes: the number of bytes in one alsa period.
+ * @rate: the frame rate.
  * @fmt: the USB audio format information
  * @sync_ep: the sync endpoint to use, if any
  *
@@ -745,7 +752,10 @@
  * An endpoint that is already running can not be reconfigured.
  */
 int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
-				struct snd_pcm_hw_params *hw_params,
+				snd_pcm_format_t pcm_format,
+				unsigned int channels,
+				unsigned int period_bytes,
+				unsigned int rate,
 				struct audioformat *fmt,
 				struct snd_usb_endpoint *sync_ep)
 {
@@ -765,9 +775,9 @@
 	ep->fill_max = !!(fmt->attributes & UAC_EP_CS_ATTR_FILL_MAX);
 
 	if (snd_usb_get_speed(ep->chip->dev) == USB_SPEED_FULL)
-		ep->freqn = get_usb_full_speed_rate(params_rate(hw_params));
+		ep->freqn = get_usb_full_speed_rate(rate);
 	else
-		ep->freqn = get_usb_high_speed_rate(params_rate(hw_params));
+		ep->freqn = get_usb_high_speed_rate(rate);
 
 	/* calculate the frequency in 16.16 format */
 	ep->freqm = ep->freqn;
@@ -777,10 +787,11 @@
 
 	switch (ep->type) {
 	case  SND_USB_ENDPOINT_TYPE_DATA:
-		err = data_ep_set_params(ep, hw_params, fmt, sync_ep);
+		err = data_ep_set_params(ep, pcm_format, channels,
+					 period_bytes, fmt, sync_ep);
 		break;
 	case  SND_USB_ENDPOINT_TYPE_SYNC:
-		err = sync_ep_set_params(ep, hw_params, fmt);
+		err = sync_ep_set_params(ep, fmt);
 		break;
 	default:
 		err = -EINVAL;
@@ -828,6 +839,8 @@
 	ep->unlink_mask = 0;
 	ep->phase = 0;
 
+	snd_usb_endpoint_start_quirk(ep);
+
 	/*
 	 * If this endpoint has a data endpoint as implicit feedback source,
 	 * don't start the urbs here. Instead, mark them all as available,
diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h
index cbbbdf2..6376ccf 100644
--- a/sound/usb/endpoint.h
+++ b/sound/usb/endpoint.h
@@ -9,7 +9,10 @@
 					      int ep_num, int direction, int type);
 
 int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
-				struct snd_pcm_hw_params *hw_params,
+				snd_pcm_format_t pcm_format,
+				unsigned int channels,
+				unsigned int period_bytes,
+				unsigned int rate,
 				struct audioformat *fmt,
 				struct snd_usb_endpoint *sync_ep);
 
diff --git a/sound/usb/helper.c b/sound/usb/helper.c
index 9eed8f4..c1db28f 100644
--- a/sound/usb/helper.c
+++ b/sound/usb/helper.c
@@ -21,6 +21,7 @@
 
 #include "usbaudio.h"
 #include "helper.h"
+#include "quirks.h"
 
 /*
  * combine bytes and get an integer value
@@ -97,6 +98,10 @@
 		memcpy(data, buf, size);
 		kfree(buf);
 	}
+
+	snd_usb_ctl_msg_quirk(dev, pipe, request, requesttype,
+			      value, index, data, size);
+
 	return err;
 }
 
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 4f40ba8..fe56c9d 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -1267,6 +1267,13 @@
 		/* disable non-functional volume control */
 		master_bits &= ~UAC_CONTROL_BIT(UAC_FU_VOLUME);
 		break;
+	case USB_ID(0x1130, 0xf211):
+		snd_printk(KERN_INFO
+			   "usbmixer: volume control quirk for Tenx TP6911 Audio Headset\n");
+		/* disable non-functional volume control */
+		channels = 0;
+		break;
+
 	}
 	if (channels > 0)
 		first_ch_bits = snd_usb_combine_bytes(bmaControls + csize, csize);
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index f782ce1..55e19e1 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -82,8 +82,7 @@
 /*
  * find a matching audio format
  */
-static struct audioformat *find_format(struct snd_usb_substream *subs, unsigned int format,
-				       unsigned int rate, unsigned int channels)
+static struct audioformat *find_format(struct snd_usb_substream *subs)
 {
 	struct list_head *p;
 	struct audioformat *found = NULL;
@@ -92,16 +91,17 @@
 	list_for_each(p, &subs->fmt_list) {
 		struct audioformat *fp;
 		fp = list_entry(p, struct audioformat, list);
-		if (!(fp->formats & (1uLL << format)))
+		if (!(fp->formats & (1uLL << subs->pcm_format)))
 			continue;
-		if (fp->channels != channels)
+		if (fp->channels != subs->channels)
 			continue;
-		if (rate < fp->rate_min || rate > fp->rate_max)
+		if (subs->cur_rate < fp->rate_min ||
+		    subs->cur_rate > fp->rate_max)
 			continue;
 		if (! (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)) {
 			unsigned int i;
 			for (i = 0; i < fp->nr_rates; i++)
-				if (fp->rate_table[i] == rate)
+				if (fp->rate_table[i] == subs->cur_rate)
 					break;
 			if (i >= fp->nr_rates)
 				continue;
@@ -436,6 +436,42 @@
 }
 
 /*
+ * configure endpoint params
+ *
+ * called  during initial setup and upon resume
+ */
+static int configure_endpoint(struct snd_usb_substream *subs)
+{
+	int ret;
+
+	mutex_lock(&subs->stream->chip->shutdown_mutex);
+	/* format changed */
+	stop_endpoints(subs, 0, 0, 0);
+	ret = snd_usb_endpoint_set_params(subs->data_endpoint,
+					  subs->pcm_format,
+					  subs->channels,
+					  subs->period_bytes,
+					  subs->cur_rate,
+					  subs->cur_audiofmt,
+					  subs->sync_endpoint);
+	if (ret < 0)
+		goto unlock;
+
+	if (subs->sync_endpoint)
+		ret = snd_usb_endpoint_set_params(subs->data_endpoint,
+						  subs->pcm_format,
+						  subs->channels,
+						  subs->period_bytes,
+						  subs->cur_rate,
+						  subs->cur_audiofmt,
+						  NULL);
+
+unlock:
+	mutex_unlock(&subs->stream->chip->shutdown_mutex);
+	return ret;
+}
+
+/*
  * hw_params callback
  *
  * allocate a buffer and set the given audio format.
@@ -450,63 +486,33 @@
 {
 	struct snd_usb_substream *subs = substream->runtime->private_data;
 	struct audioformat *fmt;
-	unsigned int channels, rate, format;
-	int ret, changed;
+	int ret;
 
 	ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
 					       params_buffer_bytes(hw_params));
 	if (ret < 0)
 		return ret;
 
-	format = params_format(hw_params);
-	rate = params_rate(hw_params);
-	channels = params_channels(hw_params);
-	fmt = find_format(subs, format, rate, channels);
+	subs->pcm_format = params_format(hw_params);
+	subs->period_bytes = params_period_bytes(hw_params);
+	subs->channels = params_channels(hw_params);
+	subs->cur_rate = params_rate(hw_params);
+
+	fmt = find_format(subs);
 	if (!fmt) {
 		snd_printd(KERN_DEBUG "cannot set format: format = %#x, rate = %d, channels = %d\n",
-			   format, rate, channels);
+			   subs->pcm_format, subs->cur_rate, subs->channels);
 		return -EINVAL;
 	}
 
-	changed = subs->cur_audiofmt != fmt ||
-		subs->period_bytes != params_period_bytes(hw_params) ||
-		subs->cur_rate != rate;
 	if ((ret = set_format(subs, fmt)) < 0)
 		return ret;
 
-	if (subs->cur_rate != rate) {
-		struct usb_host_interface *alts;
-		struct usb_interface *iface;
-		iface = usb_ifnum_to_if(subs->dev, fmt->iface);
-		alts = &iface->altsetting[fmt->altset_idx];
-		ret = snd_usb_init_sample_rate(subs->stream->chip, fmt->iface, alts, fmt, rate);
-		if (ret < 0)
-			return ret;
-		subs->cur_rate = rate;
-	}
+	subs->interface = fmt->iface;
+	subs->altset_idx = fmt->altset_idx;
+	subs->need_setup_ep = true;
 
-	if (changed) {
-		mutex_lock(&subs->stream->chip->shutdown_mutex);
-		/* format changed */
-		stop_endpoints(subs, 0, 0, 0);
-		ret = snd_usb_endpoint_set_params(subs->data_endpoint, hw_params, fmt,
-						  subs->sync_endpoint);
-		if (ret < 0)
-			goto unlock;
-
-		if (subs->sync_endpoint)
-			ret = snd_usb_endpoint_set_params(subs->sync_endpoint,
-							  hw_params, fmt, NULL);
-unlock:
-		mutex_unlock(&subs->stream->chip->shutdown_mutex);
-	}
-
-	if (ret == 0) {
-		subs->interface = fmt->iface;
-		subs->altset_idx = fmt->altset_idx;
-	}
-
-	return ret;
+	return 0;
 }
 
 /*
@@ -537,6 +543,9 @@
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_usb_substream *subs = runtime->private_data;
+	struct usb_host_interface *alts;
+	struct usb_interface *iface;
+	int ret;
 
 	if (! subs->cur_audiofmt) {
 		snd_printk(KERN_ERR "usbaudio: no format is specified!\n");
@@ -546,6 +555,27 @@
 	if (snd_BUG_ON(!subs->data_endpoint))
 		return -EIO;
 
+	ret = set_format(subs, subs->cur_audiofmt);
+	if (ret < 0)
+		return ret;
+
+	iface = usb_ifnum_to_if(subs->dev, subs->cur_audiofmt->iface);
+	alts = &iface->altsetting[subs->cur_audiofmt->altset_idx];
+	ret = snd_usb_init_sample_rate(subs->stream->chip,
+				       subs->cur_audiofmt->iface,
+				       alts,
+				       subs->cur_audiofmt,
+				       subs->cur_rate);
+	if (ret < 0)
+		return ret;
+
+	if (subs->need_setup_ep) {
+		ret = configure_endpoint(subs);
+		if (ret < 0)
+			return ret;
+		subs->need_setup_ep = false;
+	}
+
 	/* some unit conversions in runtime */
 	subs->data_endpoint->maxframesize =
 		bytes_to_frames(runtime, subs->data_endpoint->maxpacksize);
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index 79780fa..88d8ceb 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -2780,6 +2780,105 @@
 
 	}
 },
+{
+	/* Tascam US122 MKII - playback-only support */
+	.match_flags = USB_DEVICE_ID_MATCH_DEVICE,
+	.idVendor = 0x0644,
+	.idProduct = 0x8021,
+	.bInterfaceClass = USB_CLASS_AUDIO,
+	.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
+		.vendor_name = "TASCAM",
+		.product_name = "US122 MKII",
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_COMPOSITE,
+		.data = (const struct snd_usb_audio_quirk[]) {
+			{
+				.ifnum = 0,
+				.type = QUIRK_IGNORE_INTERFACE
+			},
+			{
+				.ifnum = 1,
+				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
+				.data = &(const struct audioformat) {
+					.formats = SNDRV_PCM_FMTBIT_S24_3LE,
+					.channels = 2,
+					.iface = 1,
+					.altsetting = 1,
+					.altset_idx = 1,
+					.attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
+					.endpoint = 0x02,
+					.ep_attr = USB_ENDPOINT_XFER_ISOC,
+					.rates = SNDRV_PCM_RATE_44100 |
+						 SNDRV_PCM_RATE_48000 |
+						 SNDRV_PCM_RATE_88200 |
+						 SNDRV_PCM_RATE_96000,
+					.rate_min = 44100,
+					.rate_max = 96000,
+					.nr_rates = 4,
+					.rate_table = (unsigned int[]) {
+						44100, 48000, 88200, 96000
+					}
+				}
+			},
+			{
+				.ifnum = -1
+			}
+		}
+	}
+},
+
+/* Microsoft XboxLive Headset/Xbox Communicator */
+{
+	USB_DEVICE(0x045e, 0x0283),
+	.bInterfaceClass = USB_CLASS_PER_INTERFACE,
+	.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
+		.vendor_name = "Microsoft",
+		.product_name = "XboxLive Headset/Xbox Communicator",
+		.ifnum = QUIRK_ANY_INTERFACE,
+		.type = QUIRK_COMPOSITE,
+		.data = &(const struct snd_usb_audio_quirk[]) {
+			{
+				/* playback */
+				.ifnum = 0,
+				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
+				.data = &(const struct audioformat) {
+					.formats = SNDRV_PCM_FMTBIT_S16_LE,
+					.channels = 1,
+					.iface = 0,
+					.altsetting = 0,
+					.altset_idx = 0,
+					.attributes = 0,
+					.endpoint = 0x04,
+					.ep_attr = 0x05,
+					.rates = SNDRV_PCM_RATE_CONTINUOUS,
+					.rate_min = 22050,
+					.rate_max = 22050
+				}
+			},
+			{
+				/* capture */
+				.ifnum = 1,
+				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
+				.data = &(const struct audioformat) {
+					.formats = SNDRV_PCM_FMTBIT_S16_LE,
+					.channels = 1,
+					.iface = 1,
+					.altsetting = 0,
+					.altset_idx = 0,
+					.attributes = 0,
+					.endpoint = 0x85,
+					.ep_attr = 0x05,
+					.rates = SNDRV_PCM_RATE_CONTINUOUS,
+					.rate_min = 16000,
+					.rate_max = 16000
+				}
+			},
+			{
+				.ifnum = -1
+			}
+		}
+	}
+},
 
 {
 	/*
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 2781726..0f58b4b 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -761,3 +761,27 @@
 	}
 }
 
+void snd_usb_endpoint_start_quirk(struct snd_usb_endpoint *ep)
+{
+	/*
+	 * "Playback Design" products send bogus feedback data at the start
+	 * of the stream. Ignore them.
+	 */
+	if ((le16_to_cpu(ep->chip->dev->descriptor.idVendor) == 0x23ba) &&
+	    ep->type == SND_USB_ENDPOINT_TYPE_SYNC)
+		ep->skip_packets = 4;
+}
+
+void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe,
+			   __u8 request, __u8 requesttype, __u16 value,
+			   __u16 index, void *data, __u16 size)
+{
+	/*
+	 * "Playback Design" products need a 20ms delay after each
+	 * class compliant request
+	 */
+	if ((le16_to_cpu(dev->descriptor.idVendor) == 0x23ba) &&
+	    (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS)
+		mdelay(20);
+}
+
diff --git a/sound/usb/quirks.h b/sound/usb/quirks.h
index 03e5e94..0ca9e91 100644
--- a/sound/usb/quirks.h
+++ b/sound/usb/quirks.h
@@ -1,6 +1,10 @@
 #ifndef __USBAUDIO_QUIRKS_H
 #define __USBAUDIO_QUIRKS_H
 
+struct audioformat;
+struct snd_usb_endpoint;
+struct snd_usb_substream;
+
 int snd_usb_create_quirk(struct snd_usb_audio *chip,
 			 struct usb_interface *iface,
 			 struct usb_driver *driver,
@@ -20,4 +24,10 @@
 int snd_usb_is_big_endian_format(struct snd_usb_audio *chip,
 				 struct audioformat *fp);
 
+void snd_usb_endpoint_start_quirk(struct snd_usb_endpoint *ep);
+
+void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe,
+			   __u8 request, __u8 requesttype, __u16 value,
+			   __u16 index, void *data, __u16 size);
+
 #endif /* __USBAUDIO_QUIRKS_H */
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index c4fd3b1..d0323a6 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -262,7 +262,7 @@
 	}
 
 	area->vm_ops = &usb_stream_hwdep_vm_ops;
-	area->vm_flags |= VM_RESERVED;
+	area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 	area->vm_private_data = us122l;
 	atomic_inc(&us122l->mmap_count);
 out:
diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c
index 04aafb4..0b34dbc 100644
--- a/sound/usb/usx2y/usX2Yhwdep.c
+++ b/sound/usb/usx2y/usX2Yhwdep.c
@@ -82,7 +82,7 @@
 		us428->us428ctls_sharedmem->CtlSnapShotLast = -2;
 	}
 	area->vm_ops = &us428ctls_vm_ops;
-	area->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
+	area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 	area->vm_private_data = hw->private_data;
 	return 0;
 }
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
index 8e40b6e..cc56007 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -723,7 +723,7 @@
 		return -ENODEV;
 	}
 	area->vm_ops = &snd_usX2Y_hwdep_pcm_vm_ops;
-	area->vm_flags |= VM_RESERVED | VM_DONTEXPAND;
+	area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
 	area->vm_private_data = hw->private_data;
 	return 0;
 }
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index e5e71e7..86258c2 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -72,7 +72,7 @@
 	override ARCH := x86
 	IS_X86_64 := 0
 	ifeq (, $(findstring m32,$(EXTRA_CFLAGS)))
-		IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -xc - | tail -n 1)
+		IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -x c - | tail -n 1)
 	endif
 	ifeq (${IS_X86_64}, 1)
 		RAW_ARCH := x86_64
diff --git a/tools/power/acpi/Makefile b/tools/power/acpi/Makefile
new file mode 100644
index 0000000..6b9cf7a
--- /dev/null
+++ b/tools/power/acpi/Makefile
@@ -0,0 +1,18 @@
+PROG= acpidump
+SRCS=	acpidump.c
+KERNEL_INCLUDE := ../../../include
+CFLAGS += -Wall -Wstrict-prototypes -Wdeclaration-after-statement -Os -s -D_LINUX -DDEFINE_ALTERNATE_TYPES -I$(KERNEL_INCLUDE) 
+
+all: acpidump
+$(PROG) : $(SRCS)
+	$(CC) $(CFLAGS) $(SRCS) -o $(PROG)
+
+CLEANFILES= $(PROG)
+
+clean : 
+	rm -f $(CLEANFILES) $(patsubst %.c,%.o, $(SRCS)) *~
+
+install :
+	install acpidump /usr/bin/acpidump
+	install acpidump.8 /usr/share/man/man8
+
diff --git a/tools/power/acpi/acpidump.8 b/tools/power/acpi/acpidump.8
new file mode 100644
index 0000000..adfa991
--- /dev/null
+++ b/tools/power/acpi/acpidump.8
@@ -0,0 +1,59 @@
+.TH ACPIDUMP 8
+.SH NAME
+acpidump \- Dump system's ACPI tables to an ASCII file.
+.SH SYNOPSIS
+.ft B
+.B acpidump > acpidump.out
+.SH DESCRIPTION
+\fBacpidump \fP dumps the systems ACPI tables to an ASCII file
+appropriate for attaching to a bug report.
+
+Subsequently, they can be processed by utilities in the ACPICA package.
+.SS Options
+no options worth worrying about.
+.PP
+.SH EXAMPLE
+
+.nf
+# acpidump > acpidump.out
+
+$ acpixtract -a acpidump.out
+        Acpi table [DSDT] -  15974 bytes written to DSDT.dat
+        Acpi table [FACS] -     64 bytes written to FACS.dat
+        Acpi table [FACP] -    116 bytes written to FACP.dat
+        Acpi table [APIC] -    120 bytes written to APIC.dat
+        Acpi table [MCFG] -     60 bytes written to MCFG.dat
+        Acpi table [SSDT] -    444 bytes written to SSDT1.dat
+        Acpi table [SSDT] -    439 bytes written to SSDT2.dat
+        Acpi table [SSDT] -    439 bytes written to SSDT3.dat
+        Acpi table [SSDT] -    439 bytes written to SSDT4.dat
+        Acpi table [SSDT] -    439 bytes written to SSDT5.dat
+        Acpi table [RSDT] -     76 bytes written to RSDT.dat
+        Acpi table [RSDP] -     20 bytes written to RSDP.dat
+
+$ iasl -d *.dat
+...
+.fi
+creates *.dsl, a human readable form which can be edited
+and compiled using iasl.
+
+
+.SH NOTES
+
+.B "acpidump "
+must be run as root.
+
+.SH REFERENCES
+ACPICA: https://acpica.org/
+
+.SH FILES
+.ta
+.nf
+/dev/mem
+/sys/firmware/acpi/tables/dynamic/*
+.fi
+
+.PP
+.SH AUTHOR
+.nf
+Written by Len Brown <len.brown@intel.com>
diff --git a/tools/power/acpi/acpidump.c b/tools/power/acpi/acpidump.c
new file mode 100644
index 0000000..0777987
--- /dev/null
+++ b/tools/power/acpi/acpidump.c
@@ -0,0 +1,560 @@
+/*
+ * (c) Alexey Starikovskiy, Intel, 2005-2006.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#ifdef DEFINE_ALTERNATE_TYPES
+/* hack to enable building old application with new headers -lenb */
+#define acpi_fadt_descriptor acpi_table_fadt
+#define acpi_rsdp_descriptor acpi_table_rsdp
+#define DSDT_SIG ACPI_SIG_DSDT
+#define FACS_SIG ACPI_SIG_FACS
+#define FADT_SIG ACPI_SIG_FADT
+#define xfirmware_ctrl Xfacs
+#define firmware_ctrl facs
+
+typedef int				s32;
+typedef unsigned char			u8;
+typedef unsigned short			u16;
+typedef unsigned int			u32;
+typedef unsigned long long		u64;
+typedef long long			s64;
+#endif
+
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+
+#include <sys/types.h>
+#include <dirent.h>
+
+#include <acpi/acconfig.h>
+#include <acpi/platform/acenv.h>
+#include <acpi/actypes.h>
+#include <acpi/actbl.h>
+
+static inline u8 checksum(u8 * buffer, u32 length)
+{
+	u8 sum = 0, *i = buffer;
+	buffer += length;
+	for (; i < buffer; sum += *(i++));
+	return sum;
+}
+
+static unsigned long psz, addr, length;
+static int print, connect, skip;
+static u8 select_sig[4];
+
+static unsigned long read_efi_systab( void )
+{
+	char buffer[80];
+	unsigned long addr;
+	FILE *f = fopen("/sys/firmware/efi/systab", "r");
+	if (f) {
+		while (fgets(buffer, 80, f)) {
+			if (sscanf(buffer, "ACPI20=0x%lx", &addr) == 1)
+				return addr;
+		}
+		fclose(f);
+	}
+	return 0;
+}
+
+static u8 *acpi_map_memory(unsigned long where, unsigned length)
+{
+	unsigned long offset;
+	u8 *there;
+	int fd = open("/dev/mem", O_RDONLY);
+	if (fd < 0) {
+		fprintf(stderr, "acpi_os_map_memory: cannot open /dev/mem\n");
+		exit(1);
+	}
+	offset = where % psz;
+	there = mmap(NULL, length + offset, PROT_READ, MAP_PRIVATE,
+			 fd, where - offset);
+	close(fd);
+	if (there == MAP_FAILED) return 0;
+	return (there + offset);
+}
+
+static void acpi_unmap_memory(u8 * there, unsigned length)
+{
+	unsigned long offset = (unsigned long)there % psz;
+	munmap(there - offset, length + offset);
+}
+
+static struct acpi_table_header *acpi_map_table(unsigned long where, char *sig)
+{
+	unsigned size;
+	struct acpi_table_header *tbl = (struct acpi_table_header *)
+	    acpi_map_memory(where, sizeof(struct acpi_table_header));
+	if (!tbl || (sig && memcmp(sig, tbl->signature, 4))) return 0;
+	size = tbl->length;
+	acpi_unmap_memory((u8 *) tbl, sizeof(struct acpi_table_header));
+	return (struct acpi_table_header *)acpi_map_memory(where, size);
+}
+
+static void acpi_unmap_table(struct acpi_table_header *tbl)
+{
+	acpi_unmap_memory((u8 *)tbl, tbl->length);
+}
+
+static struct acpi_rsdp_descriptor *acpi_scan_for_rsdp(u8 *begin, u32 length)
+{
+	struct acpi_rsdp_descriptor *rsdp;
+	u8 *i, *end = begin + length;
+	/* Search from given start address for the requested length */
+	for (i = begin; i < end; i += ACPI_RSDP_SCAN_STEP) {
+		/* The signature and checksum must both be correct */
+		if (memcmp((char *)i, "RSD PTR ", 8)) continue;
+		rsdp = (struct acpi_rsdp_descriptor *)i;
+		/* Signature matches, check the appropriate checksum */
+		if (!checksum((u8 *) rsdp, (rsdp->revision < 2) ?
+			      ACPI_RSDP_CHECKSUM_LENGTH :
+			      ACPI_RSDP_XCHECKSUM_LENGTH))
+			/* Checksum valid, we have found a valid RSDP */
+			return rsdp;
+	}
+	/* Searched entire block, no RSDP was found */
+	return 0;
+}
+
+/*
+ * Output data
+ */
+static void acpi_show_data(int fd, u8 * data, int size)
+{
+	char buffer[256];
+	int len;
+	int i, remain = size;
+	while (remain > 0) {
+		len = snprintf(buffer, 256, "  %04x:", size - remain);
+		for (i = 0; i < 16 && i < remain; i++) {
+			len +=
+			    snprintf(&buffer[len], 256 - len, " %02x", data[i]);
+		}
+		for (; i < 16; i++) {
+			len += snprintf(&buffer[len], 256 - len, "   ");
+		}
+		len += snprintf(&buffer[len], 256 - len, "  ");
+		for (i = 0; i < 16 && i < remain; i++) {
+			buffer[len++] = (isprint(data[i])) ? data[i] : '.';
+		}
+		buffer[len++] = '\n';
+		write(fd, buffer, len);
+		data += 16;
+		remain -= 16;
+	}
+}
+
+/*
+ * Output ACPI table
+ */
+static void acpi_show_table(int fd, struct acpi_table_header *table, unsigned long addr)
+{
+	char buff[80];
+	int len = snprintf(buff, 80, "%.4s @ %p\n", table->signature, (void *)addr);
+	write(fd, buff, len);
+	acpi_show_data(fd, (u8 *) table, table->length);
+	buff[0] = '\n';
+	write(fd, buff, 1);
+}
+
+static void write_table(int fd, struct acpi_table_header *tbl, unsigned long addr)
+{
+	static int select_done = 0;
+	if (!select_sig[0]) {
+		if (print) {
+			acpi_show_table(fd, tbl, addr);
+		} else {
+			write(fd, tbl, tbl->length);
+		}
+	} else if (!select_done && !memcmp(select_sig, tbl->signature, 4)) {
+		if (skip > 0) {
+			--skip;
+			return;
+		}
+		if (print) {
+			acpi_show_table(fd, tbl, addr);
+		} else {
+			write(fd, tbl, tbl->length);
+		}
+		select_done = 1;
+	}
+}
+
+static void acpi_dump_FADT(int fd, struct acpi_table_header *tbl, unsigned long xaddr) {
+	struct acpi_fadt_descriptor x;
+	unsigned long addr;
+	size_t len = sizeof(struct acpi_fadt_descriptor);
+	if (len > tbl->length) len = tbl->length;
+	memcpy(&x, tbl, len);
+	x.header.length = len;
+	if (checksum((u8 *)tbl, len)) {
+		fprintf(stderr, "Wrong checksum for FADT!\n");
+	}
+	if (x.header.length >= 148 && x.Xdsdt) {
+		addr = (unsigned long)x.Xdsdt;
+		if (connect) {
+			x.Xdsdt = lseek(fd, 0, SEEK_CUR);
+		}
+	} else if (x.header.length >= 44 && x.dsdt) {
+		addr = (unsigned long)x.dsdt;
+		if (connect) {
+			x.dsdt = lseek(fd, 0, SEEK_CUR);
+		}
+	} else {
+		fprintf(stderr, "No DSDT in FADT!\n");
+		goto no_dsdt;
+	}
+	tbl = acpi_map_table(addr, DSDT_SIG);
+	if (!tbl) goto no_dsdt;
+	if (checksum((u8 *)tbl, tbl->length))
+		fprintf(stderr, "Wrong checksum for DSDT!\n");
+	write_table(fd, tbl, addr);
+	acpi_unmap_table(tbl);
+no_dsdt:
+	if (x.header.length >= 140 && x.xfirmware_ctrl) {
+		addr = (unsigned long)x.xfirmware_ctrl;
+		if (connect) {
+			x.xfirmware_ctrl = lseek(fd, 0, SEEK_CUR);
+		}
+	} else if (x.header.length >= 40 && x.firmware_ctrl) {
+		addr = (unsigned long)x.firmware_ctrl;
+		if (connect) {
+			x.firmware_ctrl = lseek(fd, 0, SEEK_CUR);
+		}
+	} else {
+		fprintf(stderr, "No FACS in FADT!\n");
+		goto no_facs;
+	}
+	tbl = acpi_map_table(addr, FACS_SIG);
+	if (!tbl) goto no_facs;
+	/* do not checksum FACS */
+	write_table(fd, tbl, addr);
+	acpi_unmap_table(tbl);
+no_facs:
+	write_table(fd, (struct acpi_table_header *)&x, xaddr);
+}
+
+static int acpi_dump_SDT(int fd, struct acpi_rsdp_descriptor *rsdp)
+{
+	struct acpi_table_header *sdt, *tbl = 0;
+	int xsdt = 1, i, num;
+	char *offset;
+	unsigned long addr;
+	if (rsdp->revision > 1 && rsdp->xsdt_physical_address) {
+		tbl = acpi_map_table(rsdp->xsdt_physical_address, "XSDT");
+	}
+	if (!tbl && rsdp->rsdt_physical_address) {
+		xsdt = 0;
+		tbl = acpi_map_table(rsdp->rsdt_physical_address, "RSDT");
+	}
+	if (!tbl) return 0;
+	sdt = malloc(tbl->length);
+	memcpy(sdt, tbl, tbl->length);
+	acpi_unmap_table(tbl);
+	if (checksum((u8 *)sdt, sdt->length))
+		fprintf(stderr, "Wrong checksum for %s!\n", (xsdt)?"XSDT":"RSDT");
+	num = (sdt->length - sizeof(struct acpi_table_header))/((xsdt)?sizeof(u64):sizeof(u32));
+	offset = (char *)sdt + sizeof(struct acpi_table_header);
+	for (i = 0; i < num; ++i, offset += ((xsdt) ? sizeof(u64) : sizeof(u32))) {
+		addr = (xsdt) ? (unsigned long)(*(u64 *)offset):
+				(unsigned long)(*(u32 *)offset);
+		if (!addr) continue;
+		tbl = acpi_map_table(addr, 0);
+		if (!tbl) continue;
+		if (!memcmp(tbl->signature, FADT_SIG, 4)) {
+			acpi_dump_FADT(fd, tbl, addr);
+		} else {
+			if (checksum((u8 *)tbl, tbl->length))
+				fprintf(stderr, "Wrong checksum for generic table!\n");
+			write_table(fd, tbl, addr);
+		}
+		acpi_unmap_table(tbl);
+		if (connect) {
+			if (xsdt)
+				(*(u64*)offset) = lseek(fd, 0, SEEK_CUR);
+			else
+				(*(u32*)offset) = lseek(fd, 0, SEEK_CUR);
+		}
+	}
+	if (xsdt) {
+		addr = (unsigned long)rsdp->xsdt_physical_address;
+		if (connect) {
+			rsdp->xsdt_physical_address = lseek(fd, 0, SEEK_CUR);
+		}
+	} else {
+		addr = (unsigned long)rsdp->rsdt_physical_address;
+		if (connect) {
+			rsdp->rsdt_physical_address = lseek(fd, 0, SEEK_CUR);
+		}
+	}
+	write_table(fd, sdt, addr);
+	free (sdt);
+	return 1;
+}
+
+#define DYNAMIC_SSDT	"/sys/firmware/acpi/tables/dynamic"
+
+static void acpi_dump_dynamic_SSDT(int fd)
+{
+	struct stat file_stat;
+	char filename[256], *ptr;
+	DIR *tabledir;
+	struct dirent *entry;
+	FILE *fp;
+	int count, readcount, length;
+	struct acpi_table_header table_header, *ptable;
+
+	if (stat(DYNAMIC_SSDT, &file_stat) == -1) {
+		/* The directory doesn't exist */
+		return;
+	}
+	tabledir = opendir(DYNAMIC_SSDT);
+	if(!tabledir){
+		/*can't open the directory */
+		return;
+         }
+
+	while ((entry = readdir(tabledir)) != 0){
+		/* skip the file of . /.. */
+		if (entry->d_name[0] == '.')
+			continue;
+
+		sprintf(filename, "%s/%s", DYNAMIC_SSDT, entry->d_name);
+		fp = fopen(filename, "r");
+		if (fp == NULL) {
+			fprintf(stderr, "Can't open the file of %s\n",
+						filename);
+			continue;
+		}
+		/* Read the Table header to parse the table length */
+		count = fread(&table_header, 1, sizeof(struct acpi_table_header), fp);
+		if (count < sizeof(table_header)) {
+			/* the length is lessn than ACPI table header. skip it */
+			fclose(fp);
+			continue;
+		}
+		length = table_header.length;
+		ptr = malloc(table_header.length);
+		fseek(fp, 0, SEEK_SET);
+		readcount = 0;
+		while(!feof(fp) && readcount < length) {
+			count = fread(ptr + readcount, 1, 256, fp);
+			readcount += count;
+		}
+		fclose(fp);
+		ptable = (struct acpi_table_header *) ptr;
+		if (checksum((u8 *) ptable, ptable->length))
+			fprintf(stderr, "Wrong checksum "
+					"for dynamic SSDT table!\n");
+		write_table(fd, ptable, 0);
+		free(ptr);
+	}
+	closedir(tabledir);
+	return;
+}
+
+static void usage(const char *progname)
+{
+	puts("Usage:");
+	printf("%s [--addr 0x1234][--table DSDT][--output filename]"
+		"[--binary][--length 0x456][--help]\n", progname);
+	puts("\t--addr 0x1234 or -a 0x1234 -- look for tables at this physical address");
+	puts("\t--table DSDT or -t DSDT -- only dump table with DSDT signature");
+	puts("\t--output filename or -o filename -- redirect output from stdin to filename");
+	puts("\t--binary or -b -- dump data in binary form rather than in hex-dump format");
+	puts("\t--length 0x456 or -l 0x456 -- works only with --addr, dump physical memory"
+		"\n\t\tregion without trying to understand it's contents");
+	puts("\t--skip 2 or -s 2 -- skip 2 tables of the given name and output only 3rd one");
+	puts("\t--help or -h -- this help message");
+	exit(0);
+}
+
+static struct option long_options[] = {
+	{"addr", 1, 0, 0},
+	{"table", 1, 0, 0},
+	{"output", 1, 0, 0},
+	{"binary", 0, 0, 0},
+	{"length", 1, 0, 0},
+	{"skip", 1, 0, 0},
+	{"help", 0, 0, 0},
+	{0, 0, 0, 0}
+};
+int main(int argc, char **argv)
+{
+	int option_index, c, fd;
+	u8 *raw;
+	struct acpi_rsdp_descriptor rsdpx, *x = 0;
+	char *filename = 0;
+	char buff[80];
+	memset(select_sig, 0, 4);
+	print = 1;
+	connect = 0;
+	addr = length = 0;
+	skip = 0;
+	while (1) {
+		option_index = 0;
+		c = getopt_long(argc, argv, "a:t:o:bl:s:h",
+				    long_options, &option_index);
+		if (c == -1)
+			break;
+
+		switch (c) {
+		case 0:
+			switch (option_index) {
+			case 0:
+				addr = strtoul(optarg, (char **)NULL, 16);
+				break;
+			case 1:
+				memcpy(select_sig, optarg, 4);
+				break;
+			case 2:
+				filename = optarg;
+				break;
+			case 3:
+				print = 0;
+				break;
+			case 4:
+				length = strtoul(optarg, (char **)NULL, 16);
+				break;
+			case 5:
+				skip = strtoul(optarg, (char **)NULL, 10);
+				break;
+			case 6:
+				usage(argv[0]);
+				exit(0);
+			}
+			break;
+		case 'a':
+			addr = strtoul(optarg, (char **)NULL, 16);
+			break;
+		case 't':
+			memcpy(select_sig, optarg, 4);
+			break;
+		case 'o':
+			filename = optarg;
+			break;
+		case 'b':
+			print = 0;
+			break;
+		case 'l':
+			length = strtoul(optarg, (char **)NULL, 16);
+			break;
+		case 's':
+			skip = strtoul(optarg, (char **)NULL, 10);
+			break;
+		case 'h':
+			usage(argv[0]);
+			exit(0);
+		default:
+			printf("Unknown option!\n");
+			usage(argv[0]);
+			exit(0);
+		}
+	}
+
+	fd = STDOUT_FILENO;
+	if (filename) {
+		fd = creat(filename, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+		if (fd < 0)
+			return fd;
+	}
+
+	if (!select_sig[0] && !print) {
+		connect = 1;
+	}
+
+	psz = sysconf(_SC_PAGESIZE);
+	if (length && addr) {
+		/* We know length and address, it means we just want a memory dump */
+		if (!(raw = acpi_map_memory(addr, length)))
+			goto not_found;
+		write(fd, raw, length);
+		acpi_unmap_memory(raw, length);
+		close(fd);
+		return 0;
+	}
+
+	length = sizeof(struct acpi_rsdp_descriptor);
+	if (!addr) {
+		addr = read_efi_systab();
+		if (!addr) {
+			addr = ACPI_HI_RSDP_WINDOW_BASE;
+			length = ACPI_HI_RSDP_WINDOW_SIZE;
+		}
+	}
+
+	if (!(raw = acpi_map_memory(addr, length)) ||
+	    !(x = acpi_scan_for_rsdp(raw, length)))
+		goto not_found;
+
+	/* Find RSDP and print all found tables */
+	memcpy(&rsdpx, x, sizeof(struct acpi_rsdp_descriptor));
+	acpi_unmap_memory(raw, length);
+	if (connect) {
+		lseek(fd, sizeof(struct acpi_rsdp_descriptor), SEEK_SET);
+	}
+	if (!acpi_dump_SDT(fd, &rsdpx))
+		goto not_found;
+	if (connect) {
+		lseek(fd, 0, SEEK_SET);
+		write(fd, x, (rsdpx.revision < 2) ?
+			ACPI_RSDP_CHECKSUM_LENGTH : ACPI_RSDP_XCHECKSUM_LENGTH);
+	} else if (!select_sig[0] || !memcmp("RSD PTR ", select_sig, 4)) {
+		addr += (long)x - (long)raw;
+		length = snprintf(buff, 80, "RSD PTR @ %p\n", (void *)addr);
+		write(fd, buff, length);
+		acpi_show_data(fd, (u8 *) & rsdpx, (rsdpx.revision < 2) ?
+				ACPI_RSDP_CHECKSUM_LENGTH : ACPI_RSDP_XCHECKSUM_LENGTH);
+		buff[0] = '\n';
+		write(fd, buff, 1);
+	}
+	acpi_dump_dynamic_SSDT(fd);
+	close(fd);
+	return 0;
+not_found:
+	close(fd);
+	fprintf(stderr, "ACPI tables were not found. If you know location "
+		"of RSD PTR table (from dmesg, etc), "
+		"supply it with either --addr or -a option\n");
+	return 1;
+}
diff --git a/tools/power/cpupower/Makefile b/tools/power/cpupower/Makefile
index a93e06c..cf397bd 100644
--- a/tools/power/cpupower/Makefile
+++ b/tools/power/cpupower/Makefile
@@ -111,7 +111,7 @@
 export CROSS CC AR STRIP RANLIB CFLAGS LDFLAGS LIB_OBJS
 
 # check if compiler option is supported
-cc-supports = ${shell if $(CC) ${1} -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; fi;}
+cc-supports = ${shell if $(CC) ${1} -S -o /dev/null -x c /dev/null > /dev/null 2>&1; then echo "$(1)"; fi;}
 
 # use '-Os' optimization if available, else use -O2
 OPTIMIZATION := $(call cc-supports,-Os,-O2)
diff --git a/tools/power/x86/turbostat/turbostat.8 b/tools/power/x86/turbostat/turbostat.8
index 74e4450..e4d0690 100644
--- a/tools/power/x86/turbostat/turbostat.8
+++ b/tools/power/x86/turbostat/turbostat.8
@@ -4,15 +4,11 @@
 .SH SYNOPSIS
 .ft B
 .B turbostat
-.RB [ "\-s" ]
-.RB [ "\-v" ]
-.RB [ "\-M MSR#" ]
+.RB [ Options ]
 .RB command
 .br
 .B turbostat
-.RB [ "\-s" ]
-.RB [ "\-v" ]
-.RB [ "\-M MSR#" ]
+.RB [ Options ]
 .RB [ "\-i interval_sec" ]
 .SH DESCRIPTION
 \fBturbostat \fP reports processor topology, frequency
@@ -27,16 +23,23 @@
 on processors that additionally support C-state residency counters.
 
 .SS Options
-The \fB-s\fP option limits output to a 1-line system summary for each interval.
+The \fB-p\fP option limits output to the 1st thread in 1st core of each package.
 .PP
-The \fB-c\fP option limits output to the 1st thread in each core.
+The \fB-P\fP option limits output to the 1st thread in each Package.
 .PP
-The \fB-p\fP option limits output to the 1st thread in each package.
+The \fB-S\fP option limits output to a 1-line System Summary for each interval.
 .PP
 The \fB-v\fP option increases verbosity.
 .PP
-The \fB-M MSR#\fP option dumps the specified MSR,
-in addition to the usual frequency and idle statistics.
+The \fB-s\fP option prints the SMI counter, equivalent to "-c 0x34"
+.PP
+The \fB-c MSR#\fP option includes the delta of the specified 32-bit MSR counter.
+.PP
+The \fB-C MSR#\fP option includes the delta of the specified 64-bit MSR counter.
+.PP
+The \fB-m MSR#\fP option includes the the specified 32-bit MSR value.
+.PP
+The \fB-M MSR#\fP option includes the the specified 64-bit MSR value.
 .PP
 The \fB-i interval_sec\fP option prints statistics every \fiinterval_sec\fP seconds.
 The default is 5 seconds.
@@ -150,6 +153,29 @@
 the arithmetic average of the GHz column above is lower.
 This is a weighted average, where the weight is %c0.  ie. it is the total number of
 un-halted cycles elapsed per time divided by the number of CPUs.
+.SH SMI COUNTING EXAMPLE
+On Intel Nehalem and newer processors, MSR 0x34 is a System Management Mode Interrupt (SMI) counter.
+Using the -m option, you can display how many SMIs have fired since reset, or if there
+are SMIs during the measurement interval, you can display the delta using the -d option.
+.nf
+[root@x980 ~]# turbostat -m 0x34
+cor CPU    %c0  GHz  TSC   MSR 0x034    %c1    %c3    %c6   %pc3   %pc6
+          1.41 1.82 3.38  0x00000000   8.92  37.82  51.85  17.37   0.55
+  0   0   3.73 2.03 3.38  0x00000055   1.72  48.25  46.31  17.38   0.55
+  0   6   0.14 1.63 3.38  0x00000056   5.30
+  1   2   2.51 1.80 3.38  0x00000056  15.65  29.33  52.52
+  1   8   0.10 1.65 3.38  0x00000056  18.05
+  2   4   1.16 1.68 3.38  0x00000056   5.87  24.47  68.50
+  2  10   0.10 1.63 3.38  0x00000056   6.93
+  8   1   3.84 1.91 3.38  0x00000056   1.36  50.65  44.16
+  8   7   0.08 1.64 3.38  0x00000056   5.12
+  9   3   1.82 1.73 3.38  0x00000056   7.59  24.21  66.38
+  9   9   0.09 1.68 3.38  0x00000056   9.32
+ 10   5   1.66 1.65 3.38  0x00000056  15.10  50.00  33.23
+ 10  11   1.72 1.65 3.38  0x00000056  15.05
+^C
+[root@x980 ~]# 
+.fi
 .SH NOTES
 
 .B "turbostat "
@@ -165,6 +191,13 @@
 as \fBacpi-cpufreq \fPperiodically cleared the APERF and MPERF
 in those kernels.
 
+If the TSC column does not make sense, then
+the other numbers will also make no sense.
+Turbostat is lightweight, and its data collection is not atomic.
+These issues are usually caused by an extremely short measurement
+interval (much less than 1 second), or system activity that prevents
+turbostat from being able to run on all CPUS to quickly collect data.
+
 The APERF, MPERF MSRs are defined to count non-halted cycles.
 Although it is not guaranteed by the architecture, turbostat assumes
 that they count at TSC rate, which is true on all processors tested to date.
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index 861d771..2655ae9 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -35,9 +35,9 @@
 #include <ctype.h>
 #include <sched.h>
 
-#define MSR_TSC	0x10
 #define MSR_NEHALEM_PLATFORM_INFO	0xCE
 #define MSR_NEHALEM_TURBO_RATIO_LIMIT	0x1AD
+#define MSR_IVT_TURBO_RATIO_LIMIT	0x1AE
 #define MSR_APERF	0xE8
 #define MSR_MPERF	0xE7
 #define MSR_PKG_C2_RESIDENCY	0x60D	/* SNB only */
@@ -62,7 +62,11 @@
 unsigned int has_invariant_tsc;
 unsigned int do_nehalem_platform_info;
 unsigned int do_nehalem_turbo_ratio_limit;
-unsigned int extra_msr_offset;
+unsigned int do_ivt_turbo_ratio_limit;
+unsigned int extra_msr_offset32;
+unsigned int extra_msr_offset64;
+unsigned int extra_delta_offset32;
+unsigned int extra_delta_offset64;
 double bclk;
 unsigned int show_pkg;
 unsigned int show_core;
@@ -83,7 +87,10 @@
 	unsigned long long aperf;
 	unsigned long long mperf;
 	unsigned long long c1;	/* derived */
-	unsigned long long extra_msr;
+	unsigned long long extra_msr64;
+	unsigned long long extra_delta64;
+	unsigned long long extra_msr32;
+	unsigned long long extra_delta32;
 	unsigned int cpu_id;
 	unsigned int flags;
 #define CPU_IS_FIRST_THREAD_IN_CORE	0x2
@@ -222,6 +229,14 @@
 	if (has_aperf)
 		outp += sprintf(outp, "  GHz");
 	outp += sprintf(outp, "  TSC");
+	if (extra_delta_offset32)
+		outp += sprintf(outp, "  count 0x%03X", extra_delta_offset32);
+	if (extra_delta_offset64)
+		outp += sprintf(outp, "  COUNT 0x%03X", extra_delta_offset64);
+	if (extra_msr_offset32)
+		outp += sprintf(outp, "   MSR 0x%03X", extra_msr_offset32);
+	if (extra_msr_offset64)
+		outp += sprintf(outp, "           MSR 0x%03X", extra_msr_offset64);
 	if (do_nhm_cstates)
 		outp += sprintf(outp, "    %%c1");
 	if (do_nhm_cstates)
@@ -238,8 +253,6 @@
 		outp += sprintf(outp, "   %%pc6");
 	if (do_snb_cstates)
 		outp += sprintf(outp, "   %%pc7");
-	if (extra_msr_offset)
-		outp += sprintf(outp, "        MSR 0x%x ", extra_msr_offset);
 
 	outp += sprintf(outp, "\n");
 }
@@ -255,8 +268,14 @@
 		fprintf(stderr, "aperf: %016llX\n", t->aperf);
 		fprintf(stderr, "mperf: %016llX\n", t->mperf);
 		fprintf(stderr, "c1: %016llX\n", t->c1);
+		fprintf(stderr, "msr0x%x: %08llX\n",
+			extra_delta_offset32, t->extra_delta32);
 		fprintf(stderr, "msr0x%x: %016llX\n",
-			extra_msr_offset, t->extra_msr);
+			extra_delta_offset64, t->extra_delta64);
+		fprintf(stderr, "msr0x%x: %08llX\n",
+			extra_msr_offset32, t->extra_msr32);
+		fprintf(stderr, "msr0x%x: %016llX\n",
+			extra_msr_offset64, t->extra_msr64);
 	}
 
 	if (c) {
@@ -360,6 +379,21 @@
 	/* TSC */
 	outp += sprintf(outp, "%5.2f", 1.0 * t->tsc/units/interval_float);
 
+	/* delta */
+	if (extra_delta_offset32)
+		outp += sprintf(outp, "  %11llu", t->extra_delta32);
+
+	/* DELTA */
+	if (extra_delta_offset64)
+		outp += sprintf(outp, "  %11llu", t->extra_delta64);
+	/* msr */
+	if (extra_msr_offset32)
+		outp += sprintf(outp, "  0x%08llx", t->extra_msr32);
+
+	/* MSR */
+	if (extra_msr_offset64)
+		outp += sprintf(outp, "  0x%016llx", t->extra_msr64);
+
 	if (do_nhm_cstates) {
 		if (!skip_c1)
 			outp += sprintf(outp, " %6.2f", 100.0 * t->c1/t->tsc);
@@ -391,8 +425,6 @@
 	if (do_snb_cstates)
 		outp += sprintf(outp, " %6.2f", 100.0 * p->pc7/t->tsc);
 done:
-	if (extra_msr_offset)
-		outp += sprintf(outp, "  0x%016llx", t->extra_msr);
 	outp += sprintf(outp, "\n");
 
 	return 0;
@@ -502,10 +534,16 @@
 		old->mperf = 1;	/* divide by 0 protection */
 	}
 
+	old->extra_delta32 = new->extra_delta32 - old->extra_delta32;
+	old->extra_delta32 &= 0xFFFFFFFF;
+
+	old->extra_delta64 = new->extra_delta64 - old->extra_delta64;
+
 	/*
-	 * for "extra msr", just copy the latest w/o subtracting
+	 * Extra MSR is just a snapshot, simply copy latest w/o subtracting
 	 */
-	old->extra_msr = new->extra_msr;
+	old->extra_msr32 = new->extra_msr32;
+	old->extra_msr64 = new->extra_msr64;
 }
 
 int delta_cpu(struct thread_data *t, struct core_data *c,
@@ -533,6 +571,9 @@
 	t->mperf = 0;
 	t->c1 = 0;
 
+	t->extra_delta32 = 0;
+	t->extra_delta64 = 0;
+
 	/* tells format_counters to dump all fields from this set */
 	t->flags = CPU_IS_FIRST_THREAD_IN_CORE | CPU_IS_FIRST_CORE_IN_PACKAGE;
 
@@ -553,6 +594,9 @@
 	average.threads.mperf += t->mperf;
 	average.threads.c1 += t->c1;
 
+	average.threads.extra_delta32 += t->extra_delta32;
+	average.threads.extra_delta64 += t->extra_delta64;
+
 	/* sum per-core values only for 1st thread in core */
 	if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
 		return 0;
@@ -588,6 +632,11 @@
 	average.threads.mperf /= topo.num_cpus;
 	average.threads.c1 /= topo.num_cpus;
 
+	average.threads.extra_delta32 /= topo.num_cpus;
+	average.threads.extra_delta32 &= 0xFFFFFFFF;
+
+	average.threads.extra_delta64 /= topo.num_cpus;
+
 	average.cores.c3 /= topo.num_cores;
 	average.cores.c6 /= topo.num_cores;
 	average.cores.c7 /= topo.num_cores;
@@ -629,8 +678,24 @@
 			return -4;
 	}
 
-	if (extra_msr_offset)
-		if (get_msr(cpu, extra_msr_offset, &t->extra_msr))
+	if (extra_delta_offset32) {
+		if (get_msr(cpu, extra_delta_offset32, &t->extra_delta32))
+			return -5;
+		t->extra_delta32 &= 0xFFFFFFFF;
+	}
+
+	if (extra_delta_offset64)
+		if (get_msr(cpu, extra_delta_offset64, &t->extra_delta64))
+			return -5;
+
+	if (extra_msr_offset32) {
+		if (get_msr(cpu, extra_msr_offset32, &t->extra_msr32))
+			return -5;
+		t->extra_msr32 &= 0xFFFFFFFF;
+	}
+
+	if (extra_msr_offset64)
+		if (get_msr(cpu, extra_msr_offset64, &t->extra_msr64))
 			return -5;
 
 	/* collect core counters only for 1st thread in core */
@@ -677,6 +742,9 @@
 
 	get_msr(0, MSR_NEHALEM_PLATFORM_INFO, &msr);
 
+	if (verbose > 1)
+		fprintf(stderr, "MSR_NEHALEM_PLATFORM_INFO: 0x%llx\n", msr);
+
 	ratio = (msr >> 40) & 0xFF;
 	fprintf(stderr, "%d * %.0f = %.0f MHz max efficiency\n",
 		ratio, bclk, ratio * bclk);
@@ -685,14 +753,84 @@
 	fprintf(stderr, "%d * %.0f = %.0f MHz TSC frequency\n",
 		ratio, bclk, ratio * bclk);
 
+	if (!do_ivt_turbo_ratio_limit)
+		goto print_nhm_turbo_ratio_limits;
+
+	get_msr(0, MSR_IVT_TURBO_RATIO_LIMIT, &msr);
+
 	if (verbose > 1)
-		fprintf(stderr, "MSR_NEHALEM_PLATFORM_INFO: 0x%llx\n", msr);
+		fprintf(stderr, "MSR_IVT_TURBO_RATIO_LIMIT: 0x%llx\n", msr);
+
+	ratio = (msr >> 56) & 0xFF;
+	if (ratio)
+		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 16 active cores\n",
+			ratio, bclk, ratio * bclk);
+
+	ratio = (msr >> 48) & 0xFF;
+	if (ratio)
+		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 15 active cores\n",
+			ratio, bclk, ratio * bclk);
+
+	ratio = (msr >> 40) & 0xFF;
+	if (ratio)
+		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 14 active cores\n",
+			ratio, bclk, ratio * bclk);
+
+	ratio = (msr >> 32) & 0xFF;
+	if (ratio)
+		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 13 active cores\n",
+			ratio, bclk, ratio * bclk);
+
+	ratio = (msr >> 24) & 0xFF;
+	if (ratio)
+		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 12 active cores\n",
+			ratio, bclk, ratio * bclk);
+
+	ratio = (msr >> 16) & 0xFF;
+	if (ratio)
+		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 11 active cores\n",
+			ratio, bclk, ratio * bclk);
+
+	ratio = (msr >> 8) & 0xFF;
+	if (ratio)
+		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 10 active cores\n",
+			ratio, bclk, ratio * bclk);
+
+	ratio = (msr >> 0) & 0xFF;
+	if (ratio)
+		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 9 active cores\n",
+			ratio, bclk, ratio * bclk);
+
+print_nhm_turbo_ratio_limits:
 
 	if (!do_nehalem_turbo_ratio_limit)
 		return;
 
 	get_msr(0, MSR_NEHALEM_TURBO_RATIO_LIMIT, &msr);
 
+	if (verbose > 1)
+		fprintf(stderr, "MSR_NEHALEM_TURBO_RATIO_LIMIT: 0x%llx\n", msr);
+
+	ratio = (msr >> 56) & 0xFF;
+	if (ratio)
+		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 8 active cores\n",
+			ratio, bclk, ratio * bclk);
+
+	ratio = (msr >> 48) & 0xFF;
+	if (ratio)
+		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 7 active cores\n",
+			ratio, bclk, ratio * bclk);
+
+	ratio = (msr >> 40) & 0xFF;
+	if (ratio)
+		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 6 active cores\n",
+			ratio, bclk, ratio * bclk);
+
+	ratio = (msr >> 32) & 0xFF;
+	if (ratio)
+		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 5 active cores\n",
+			ratio, bclk, ratio * bclk);
+
 	ratio = (msr >> 24) & 0xFF;
 	if (ratio)
 		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 4 active cores\n",
@@ -712,7 +850,6 @@
 	if (ratio)
 		fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 1 active cores\n",
 			ratio, bclk, ratio * bclk);
-
 }
 
 void free_all_buffers(void)
@@ -1038,7 +1175,7 @@
 	case 0x2A:	/* SNB */
 	case 0x2D:	/* SNB Xeon */
 	case 0x3A:	/* IVB */
-	case 0x3D:	/* IVB Xeon */
+	case 0x3E:	/* IVB Xeon */
 		return 1;
 	case 0x2E:	/* Nehalem-EX Xeon - Beckton */
 	case 0x2F:	/* Westmere-EX Xeon - Eagleton */
@@ -1046,6 +1183,22 @@
 		return 0;
 	}
 }
+int has_ivt_turbo_ratio_limit(unsigned int family, unsigned int model)
+{
+	if (!genuine_intel)
+		return 0;
+
+	if (family != 6)
+		return 0;
+
+	switch (model) {
+	case 0x3E:	/* IVB Xeon */
+		return 1;
+	default:
+		return 0;
+	}
+}
+
 
 int is_snb(unsigned int family, unsigned int model)
 {
@@ -1056,7 +1209,7 @@
 	case 0x2A:
 	case 0x2D:
 	case 0x3A:	/* IVB */
-	case 0x3D:	/* IVB Xeon */
+	case 0x3E:	/* IVB Xeon */
 		return 1;
 	}
 	return 0;
@@ -1145,12 +1298,13 @@
 	bclk = discover_bclk(family, model);
 
 	do_nehalem_turbo_ratio_limit = has_nehalem_turbo_ratio_limit(family, model);
+	do_ivt_turbo_ratio_limit = has_ivt_turbo_ratio_limit(family, model);
 }
 
 
 void usage()
 {
-	fprintf(stderr, "%s: [-v] [-M MSR#] [-i interval_sec | command ...]\n",
+	fprintf(stderr, "%s: [-v][-p|-P|-S][-c MSR# | -s]][-C MSR#][-m MSR#][-M MSR#][-i interval_sec | command ...]\n",
 		progname);
 	exit(1);
 }
@@ -1440,15 +1594,15 @@
 
 	progname = argv[0];
 
-	while ((opt = getopt(argc, argv, "+cpsvi:M:")) != -1) {
+	while ((opt = getopt(argc, argv, "+pPSvisc:sC:m:M:")) != -1) {
 		switch (opt) {
-		case 'c':
+		case 'p':
 			show_core_only++;
 			break;
-		case 'p':
+		case 'P':
 			show_pkg_only++;
 			break;
-		case 's':
+		case 'S':
 			summary_only++;
 			break;
 		case 'v':
@@ -1457,10 +1611,20 @@
 		case 'i':
 			interval_sec = atoi(optarg);
 			break;
+		case 'c':
+			sscanf(optarg, "%x", &extra_delta_offset32);
+			break;
+		case 's':
+			extra_delta_offset32 = 0x34;	/* SMI counter */
+			break;
+		case 'C':
+			sscanf(optarg, "%x", &extra_delta_offset64);
+			break;
+		case 'm':
+			sscanf(optarg, "%x", &extra_msr_offset32);
+			break;
 		case 'M':
-			sscanf(optarg, "%x", &extra_msr_offset);
-			if (verbose > 1)
-				fprintf(stderr, "MSR 0x%X\n", extra_msr_offset);
+			sscanf(optarg, "%x", &extra_msr_offset64);
 			break;
 		default:
 			usage();
@@ -1473,7 +1637,7 @@
 	cmdline(argc, argv);
 
 	if (verbose > 1)
-		fprintf(stderr, "turbostat v2.0 May 16, 2012"
+		fprintf(stderr, "turbostat v2.1 October 6, 2012"
 			" - Len Brown <lenb@kernel.org>\n");
 
 	turbostat_init();
diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
index c05bcd2..b51d787 100755
--- a/tools/testing/ktest/ktest.pl
+++ b/tools/testing/ktest/ktest.pl
@@ -1873,10 +1873,10 @@
 	apply_min_config;
     }
 
-    if (!run_command "$make oldnoconfig") {
-	# Perhaps oldnoconfig doesn't exist in this version of the kernel
+    if (!run_command "$make olddefconfig") {
+	# Perhaps olddefconfig doesn't exist in this version of the kernel
 	# try a yes '' | oldconfig
-	doprint "oldnoconfig failed, trying yes '' | make oldconfig\n";
+	doprint "olddefconfig failed, trying yes '' | make oldconfig\n";
 	run_command "yes '' | $make oldconfig" or
 	    dodie "failed make config oldconfig";
     }
@@ -1929,7 +1929,7 @@
 
     # old config can ask questions
     if ($type eq "oldconfig") {
-	$type = "oldnoconfig";
+	$type = "olddefconfig";
 
 	# allow for empty configs
 	run_command "touch $output_config";
@@ -1959,7 +1959,7 @@
 	load_force_config($minconfig);
     }
 
-    if ($type ne "oldnoconfig") {
+    if ($type ne "olddefconfig") {
 	run_command "$make $type" or
 	    dodie "failed make config";
     }
@@ -2458,8 +2458,7 @@
 
 # config_off holds the set of configs that the bad config had disabled.
 # We need to record them and set them in the .config when running
-# oldnoconfig, because oldnoconfig does not turn off new symbols, but
-# instead just keeps the defaults.
+# olddefconfig, because olddefconfig keeps the defaults.
 my %config_off;
 
 # config_off_tmp holds a set of configs to turn off for now
@@ -3250,7 +3249,7 @@
     }
 
     # Remove this config from the list of configs
-    # do a make oldnoconfig and then read the resulting
+    # do a make olddefconfig and then read the resulting
     # .config to make sure it is missing the config that
     # we had before
     my %configs = %min_configs;